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"
33 #include "trace-tcg.h"
36 #define MIPS_DEBUG_DISAS 0
37 //#define MIPS_DEBUG_SIGN_EXTENSIONS
39 /* MIPS major opcodes */
40 #define MASK_OP_MAJOR(op) (op & (0x3F << 26))
43 /* indirect opcode tables */
44 OPC_SPECIAL = (0x00 << 26),
45 OPC_REGIMM = (0x01 << 26),
46 OPC_CP0 = (0x10 << 26),
47 OPC_CP1 = (0x11 << 26),
48 OPC_CP2 = (0x12 << 26),
49 OPC_CP3 = (0x13 << 26),
50 OPC_SPECIAL2 = (0x1C << 26),
51 OPC_SPECIAL3 = (0x1F << 26),
52 /* arithmetic with immediate */
53 OPC_ADDI = (0x08 << 26),
54 OPC_ADDIU = (0x09 << 26),
55 OPC_SLTI = (0x0A << 26),
56 OPC_SLTIU = (0x0B << 26),
57 /* logic with immediate */
58 OPC_ANDI = (0x0C << 26),
59 OPC_ORI = (0x0D << 26),
60 OPC_XORI = (0x0E << 26),
61 OPC_LUI = (0x0F << 26),
62 /* arithmetic with immediate */
63 OPC_DADDI = (0x18 << 26),
64 OPC_DADDIU = (0x19 << 26),
65 /* Jump and branches */
67 OPC_JAL = (0x03 << 26),
68 OPC_BEQ = (0x04 << 26), /* Unconditional if rs = rt = 0 (B) */
69 OPC_BEQL = (0x14 << 26),
70 OPC_BNE = (0x05 << 26),
71 OPC_BNEL = (0x15 << 26),
72 OPC_BLEZ = (0x06 << 26),
73 OPC_BLEZL = (0x16 << 26),
74 OPC_BGTZ = (0x07 << 26),
75 OPC_BGTZL = (0x17 << 26),
76 OPC_JALX = (0x1D << 26),
77 OPC_DAUI = (0x1D << 26),
79 OPC_LDL = (0x1A << 26),
80 OPC_LDR = (0x1B << 26),
81 OPC_LB = (0x20 << 26),
82 OPC_LH = (0x21 << 26),
83 OPC_LWL = (0x22 << 26),
84 OPC_LW = (0x23 << 26),
85 OPC_LWPC = OPC_LW | 0x5,
86 OPC_LBU = (0x24 << 26),
87 OPC_LHU = (0x25 << 26),
88 OPC_LWR = (0x26 << 26),
89 OPC_LWU = (0x27 << 26),
90 OPC_SB = (0x28 << 26),
91 OPC_SH = (0x29 << 26),
92 OPC_SWL = (0x2A << 26),
93 OPC_SW = (0x2B << 26),
94 OPC_SDL = (0x2C << 26),
95 OPC_SDR = (0x2D << 26),
96 OPC_SWR = (0x2E << 26),
97 OPC_LL = (0x30 << 26),
98 OPC_LLD = (0x34 << 26),
99 OPC_LD = (0x37 << 26),
100 OPC_LDPC = OPC_LD | 0x5,
101 OPC_SC = (0x38 << 26),
102 OPC_SCD = (0x3C << 26),
103 OPC_SD = (0x3F << 26),
104 /* Floating point load/store */
105 OPC_LWC1 = (0x31 << 26),
106 OPC_LWC2 = (0x32 << 26),
107 OPC_LDC1 = (0x35 << 26),
108 OPC_LDC2 = (0x36 << 26),
109 OPC_SWC1 = (0x39 << 26),
110 OPC_SWC2 = (0x3A << 26),
111 OPC_SDC1 = (0x3D << 26),
112 OPC_SDC2 = (0x3E << 26),
113 /* Compact Branches */
114 OPC_BLEZALC = (0x06 << 26),
115 OPC_BGEZALC = (0x06 << 26),
116 OPC_BGEUC = (0x06 << 26),
117 OPC_BGTZALC = (0x07 << 26),
118 OPC_BLTZALC = (0x07 << 26),
119 OPC_BLTUC = (0x07 << 26),
120 OPC_BOVC = (0x08 << 26),
121 OPC_BEQZALC = (0x08 << 26),
122 OPC_BEQC = (0x08 << 26),
123 OPC_BLEZC = (0x16 << 26),
124 OPC_BGEZC = (0x16 << 26),
125 OPC_BGEC = (0x16 << 26),
126 OPC_BGTZC = (0x17 << 26),
127 OPC_BLTZC = (0x17 << 26),
128 OPC_BLTC = (0x17 << 26),
129 OPC_BNVC = (0x18 << 26),
130 OPC_BNEZALC = (0x18 << 26),
131 OPC_BNEC = (0x18 << 26),
132 OPC_BC = (0x32 << 26),
133 OPC_BEQZC = (0x36 << 26),
134 OPC_JIC = (0x36 << 26),
135 OPC_BALC = (0x3A << 26),
136 OPC_BNEZC = (0x3E << 26),
137 OPC_JIALC = (0x3E << 26),
138 /* MDMX ASE specific */
139 OPC_MDMX = (0x1E << 26),
140 /* MSA ASE, same as MDMX */
142 /* Cache and prefetch */
143 OPC_CACHE = (0x2F << 26),
144 OPC_PREF = (0x33 << 26),
145 /* PC-relative address computation / loads */
146 OPC_PCREL = (0x3B << 26),
149 /* PC-relative address computation / loads */
150 #define MASK_OPC_PCREL_TOP2BITS(op) (MASK_OP_MAJOR(op) | (op & (3 << 19)))
151 #define MASK_OPC_PCREL_TOP5BITS(op) (MASK_OP_MAJOR(op) | (op & (0x1f << 16)))
153 /* Instructions determined by bits 19 and 20 */
154 OPC_ADDIUPC = OPC_PCREL | (0 << 19),
155 R6_OPC_LWPC = OPC_PCREL | (1 << 19),
156 OPC_LWUPC = OPC_PCREL | (2 << 19),
158 /* Instructions determined by bits 16 ... 20 */
159 OPC_AUIPC = OPC_PCREL | (0x1e << 16),
160 OPC_ALUIPC = OPC_PCREL | (0x1f << 16),
163 R6_OPC_LDPC = OPC_PCREL | (6 << 18),
166 /* MIPS special opcodes */
167 #define MASK_SPECIAL(op) MASK_OP_MAJOR(op) | (op & 0x3F)
171 OPC_SLL = 0x00 | OPC_SPECIAL,
172 /* NOP is SLL r0, r0, 0 */
173 /* SSNOP is SLL r0, r0, 1 */
174 /* EHB is SLL r0, r0, 3 */
175 OPC_SRL = 0x02 | OPC_SPECIAL, /* also ROTR */
176 OPC_ROTR = OPC_SRL | (1 << 21),
177 OPC_SRA = 0x03 | OPC_SPECIAL,
178 OPC_SLLV = 0x04 | OPC_SPECIAL,
179 OPC_SRLV = 0x06 | OPC_SPECIAL, /* also ROTRV */
180 OPC_ROTRV = OPC_SRLV | (1 << 6),
181 OPC_SRAV = 0x07 | OPC_SPECIAL,
182 OPC_DSLLV = 0x14 | OPC_SPECIAL,
183 OPC_DSRLV = 0x16 | OPC_SPECIAL, /* also DROTRV */
184 OPC_DROTRV = OPC_DSRLV | (1 << 6),
185 OPC_DSRAV = 0x17 | OPC_SPECIAL,
186 OPC_DSLL = 0x38 | OPC_SPECIAL,
187 OPC_DSRL = 0x3A | OPC_SPECIAL, /* also DROTR */
188 OPC_DROTR = OPC_DSRL | (1 << 21),
189 OPC_DSRA = 0x3B | OPC_SPECIAL,
190 OPC_DSLL32 = 0x3C | OPC_SPECIAL,
191 OPC_DSRL32 = 0x3E | OPC_SPECIAL, /* also DROTR32 */
192 OPC_DROTR32 = OPC_DSRL32 | (1 << 21),
193 OPC_DSRA32 = 0x3F | OPC_SPECIAL,
194 /* Multiplication / division */
195 OPC_MULT = 0x18 | OPC_SPECIAL,
196 OPC_MULTU = 0x19 | OPC_SPECIAL,
197 OPC_DIV = 0x1A | OPC_SPECIAL,
198 OPC_DIVU = 0x1B | OPC_SPECIAL,
199 OPC_DMULT = 0x1C | OPC_SPECIAL,
200 OPC_DMULTU = 0x1D | OPC_SPECIAL,
201 OPC_DDIV = 0x1E | OPC_SPECIAL,
202 OPC_DDIVU = 0x1F | OPC_SPECIAL,
204 /* 2 registers arithmetic / logic */
205 OPC_ADD = 0x20 | OPC_SPECIAL,
206 OPC_ADDU = 0x21 | OPC_SPECIAL,
207 OPC_SUB = 0x22 | OPC_SPECIAL,
208 OPC_SUBU = 0x23 | OPC_SPECIAL,
209 OPC_AND = 0x24 | OPC_SPECIAL,
210 OPC_OR = 0x25 | OPC_SPECIAL,
211 OPC_XOR = 0x26 | OPC_SPECIAL,
212 OPC_NOR = 0x27 | OPC_SPECIAL,
213 OPC_SLT = 0x2A | OPC_SPECIAL,
214 OPC_SLTU = 0x2B | OPC_SPECIAL,
215 OPC_DADD = 0x2C | OPC_SPECIAL,
216 OPC_DADDU = 0x2D | OPC_SPECIAL,
217 OPC_DSUB = 0x2E | OPC_SPECIAL,
218 OPC_DSUBU = 0x2F | OPC_SPECIAL,
220 OPC_JR = 0x08 | OPC_SPECIAL, /* Also JR.HB */
221 OPC_JALR = 0x09 | OPC_SPECIAL, /* Also JALR.HB */
223 OPC_TGE = 0x30 | OPC_SPECIAL,
224 OPC_TGEU = 0x31 | OPC_SPECIAL,
225 OPC_TLT = 0x32 | OPC_SPECIAL,
226 OPC_TLTU = 0x33 | OPC_SPECIAL,
227 OPC_TEQ = 0x34 | OPC_SPECIAL,
228 OPC_TNE = 0x36 | OPC_SPECIAL,
229 /* HI / LO registers load & stores */
230 OPC_MFHI = 0x10 | OPC_SPECIAL,
231 OPC_MTHI = 0x11 | OPC_SPECIAL,
232 OPC_MFLO = 0x12 | OPC_SPECIAL,
233 OPC_MTLO = 0x13 | OPC_SPECIAL,
234 /* Conditional moves */
235 OPC_MOVZ = 0x0A | OPC_SPECIAL,
236 OPC_MOVN = 0x0B | OPC_SPECIAL,
238 OPC_SELEQZ = 0x35 | OPC_SPECIAL,
239 OPC_SELNEZ = 0x37 | OPC_SPECIAL,
241 OPC_MOVCI = 0x01 | OPC_SPECIAL,
244 OPC_PMON = 0x05 | OPC_SPECIAL, /* unofficial */
245 OPC_SYSCALL = 0x0C | OPC_SPECIAL,
246 OPC_BREAK = 0x0D | OPC_SPECIAL,
247 OPC_SPIM = 0x0E | OPC_SPECIAL, /* unofficial */
248 OPC_SYNC = 0x0F | OPC_SPECIAL,
250 OPC_SPECIAL28_RESERVED = 0x28 | OPC_SPECIAL,
251 OPC_SPECIAL29_RESERVED = 0x29 | OPC_SPECIAL,
252 OPC_SPECIAL39_RESERVED = 0x39 | OPC_SPECIAL,
253 OPC_SPECIAL3D_RESERVED = 0x3D | OPC_SPECIAL,
256 /* R6 Multiply and Divide instructions have the same Opcode
257 and function field as legacy OPC_MULT[U]/OPC_DIV[U] */
258 #define MASK_R6_MULDIV(op) (MASK_SPECIAL(op) | (op & (0x7ff)))
261 R6_OPC_MUL = OPC_MULT | (2 << 6),
262 R6_OPC_MUH = OPC_MULT | (3 << 6),
263 R6_OPC_MULU = OPC_MULTU | (2 << 6),
264 R6_OPC_MUHU = OPC_MULTU | (3 << 6),
265 R6_OPC_DIV = OPC_DIV | (2 << 6),
266 R6_OPC_MOD = OPC_DIV | (3 << 6),
267 R6_OPC_DIVU = OPC_DIVU | (2 << 6),
268 R6_OPC_MODU = OPC_DIVU | (3 << 6),
270 R6_OPC_DMUL = OPC_DMULT | (2 << 6),
271 R6_OPC_DMUH = OPC_DMULT | (3 << 6),
272 R6_OPC_DMULU = OPC_DMULTU | (2 << 6),
273 R6_OPC_DMUHU = OPC_DMULTU | (3 << 6),
274 R6_OPC_DDIV = OPC_DDIV | (2 << 6),
275 R6_OPC_DMOD = OPC_DDIV | (3 << 6),
276 R6_OPC_DDIVU = OPC_DDIVU | (2 << 6),
277 R6_OPC_DMODU = OPC_DDIVU | (3 << 6),
279 R6_OPC_CLZ = 0x10 | OPC_SPECIAL,
280 R6_OPC_CLO = 0x11 | OPC_SPECIAL,
281 R6_OPC_DCLZ = 0x12 | OPC_SPECIAL,
282 R6_OPC_DCLO = 0x13 | OPC_SPECIAL,
283 R6_OPC_SDBBP = 0x0e | OPC_SPECIAL,
285 OPC_LSA = 0x05 | OPC_SPECIAL,
286 OPC_DLSA = 0x15 | OPC_SPECIAL,
289 /* Multiplication variants of the vr54xx. */
290 #define MASK_MUL_VR54XX(op) MASK_SPECIAL(op) | (op & (0x1F << 6))
293 OPC_VR54XX_MULS = (0x03 << 6) | OPC_MULT,
294 OPC_VR54XX_MULSU = (0x03 << 6) | OPC_MULTU,
295 OPC_VR54XX_MACC = (0x05 << 6) | OPC_MULT,
296 OPC_VR54XX_MACCU = (0x05 << 6) | OPC_MULTU,
297 OPC_VR54XX_MSAC = (0x07 << 6) | OPC_MULT,
298 OPC_VR54XX_MSACU = (0x07 << 6) | OPC_MULTU,
299 OPC_VR54XX_MULHI = (0x09 << 6) | OPC_MULT,
300 OPC_VR54XX_MULHIU = (0x09 << 6) | OPC_MULTU,
301 OPC_VR54XX_MULSHI = (0x0B << 6) | OPC_MULT,
302 OPC_VR54XX_MULSHIU = (0x0B << 6) | OPC_MULTU,
303 OPC_VR54XX_MACCHI = (0x0D << 6) | OPC_MULT,
304 OPC_VR54XX_MACCHIU = (0x0D << 6) | OPC_MULTU,
305 OPC_VR54XX_MSACHI = (0x0F << 6) | OPC_MULT,
306 OPC_VR54XX_MSACHIU = (0x0F << 6) | OPC_MULTU,
309 /* REGIMM (rt field) opcodes */
310 #define MASK_REGIMM(op) MASK_OP_MAJOR(op) | (op & (0x1F << 16))
313 OPC_BLTZ = (0x00 << 16) | OPC_REGIMM,
314 OPC_BLTZL = (0x02 << 16) | OPC_REGIMM,
315 OPC_BGEZ = (0x01 << 16) | OPC_REGIMM,
316 OPC_BGEZL = (0x03 << 16) | OPC_REGIMM,
317 OPC_BLTZAL = (0x10 << 16) | OPC_REGIMM,
318 OPC_BLTZALL = (0x12 << 16) | OPC_REGIMM,
319 OPC_BGEZAL = (0x11 << 16) | OPC_REGIMM,
320 OPC_BGEZALL = (0x13 << 16) | OPC_REGIMM,
321 OPC_TGEI = (0x08 << 16) | OPC_REGIMM,
322 OPC_TGEIU = (0x09 << 16) | OPC_REGIMM,
323 OPC_TLTI = (0x0A << 16) | OPC_REGIMM,
324 OPC_TLTIU = (0x0B << 16) | OPC_REGIMM,
325 OPC_TEQI = (0x0C << 16) | OPC_REGIMM,
326 OPC_TNEI = (0x0E << 16) | OPC_REGIMM,
327 OPC_SYNCI = (0x1F << 16) | OPC_REGIMM,
329 OPC_DAHI = (0x06 << 16) | OPC_REGIMM,
330 OPC_DATI = (0x1e << 16) | OPC_REGIMM,
333 /* Special2 opcodes */
334 #define MASK_SPECIAL2(op) MASK_OP_MAJOR(op) | (op & 0x3F)
337 /* Multiply & xxx operations */
338 OPC_MADD = 0x00 | OPC_SPECIAL2,
339 OPC_MADDU = 0x01 | OPC_SPECIAL2,
340 OPC_MUL = 0x02 | OPC_SPECIAL2,
341 OPC_MSUB = 0x04 | OPC_SPECIAL2,
342 OPC_MSUBU = 0x05 | OPC_SPECIAL2,
344 OPC_MULT_G_2F = 0x10 | OPC_SPECIAL2,
345 OPC_DMULT_G_2F = 0x11 | OPC_SPECIAL2,
346 OPC_MULTU_G_2F = 0x12 | OPC_SPECIAL2,
347 OPC_DMULTU_G_2F = 0x13 | OPC_SPECIAL2,
348 OPC_DIV_G_2F = 0x14 | OPC_SPECIAL2,
349 OPC_DDIV_G_2F = 0x15 | OPC_SPECIAL2,
350 OPC_DIVU_G_2F = 0x16 | OPC_SPECIAL2,
351 OPC_DDIVU_G_2F = 0x17 | OPC_SPECIAL2,
352 OPC_MOD_G_2F = 0x1c | OPC_SPECIAL2,
353 OPC_DMOD_G_2F = 0x1d | OPC_SPECIAL2,
354 OPC_MODU_G_2F = 0x1e | OPC_SPECIAL2,
355 OPC_DMODU_G_2F = 0x1f | OPC_SPECIAL2,
357 OPC_CLZ = 0x20 | OPC_SPECIAL2,
358 OPC_CLO = 0x21 | OPC_SPECIAL2,
359 OPC_DCLZ = 0x24 | OPC_SPECIAL2,
360 OPC_DCLO = 0x25 | OPC_SPECIAL2,
362 OPC_SDBBP = 0x3F | OPC_SPECIAL2,
365 /* Special3 opcodes */
366 #define MASK_SPECIAL3(op) MASK_OP_MAJOR(op) | (op & 0x3F)
369 OPC_EXT = 0x00 | OPC_SPECIAL3,
370 OPC_DEXTM = 0x01 | OPC_SPECIAL3,
371 OPC_DEXTU = 0x02 | OPC_SPECIAL3,
372 OPC_DEXT = 0x03 | OPC_SPECIAL3,
373 OPC_INS = 0x04 | OPC_SPECIAL3,
374 OPC_DINSM = 0x05 | OPC_SPECIAL3,
375 OPC_DINSU = 0x06 | OPC_SPECIAL3,
376 OPC_DINS = 0x07 | OPC_SPECIAL3,
377 OPC_FORK = 0x08 | OPC_SPECIAL3,
378 OPC_YIELD = 0x09 | OPC_SPECIAL3,
379 OPC_BSHFL = 0x20 | OPC_SPECIAL3,
380 OPC_DBSHFL = 0x24 | OPC_SPECIAL3,
381 OPC_RDHWR = 0x3B | OPC_SPECIAL3,
384 OPC_MULT_G_2E = 0x18 | OPC_SPECIAL3,
385 OPC_MULTU_G_2E = 0x19 | OPC_SPECIAL3,
386 OPC_DIV_G_2E = 0x1A | OPC_SPECIAL3,
387 OPC_DIVU_G_2E = 0x1B | OPC_SPECIAL3,
388 OPC_DMULT_G_2E = 0x1C | OPC_SPECIAL3,
389 OPC_DMULTU_G_2E = 0x1D | OPC_SPECIAL3,
390 OPC_DDIV_G_2E = 0x1E | OPC_SPECIAL3,
391 OPC_DDIVU_G_2E = 0x1F | OPC_SPECIAL3,
392 OPC_MOD_G_2E = 0x22 | OPC_SPECIAL3,
393 OPC_MODU_G_2E = 0x23 | OPC_SPECIAL3,
394 OPC_DMOD_G_2E = 0x26 | OPC_SPECIAL3,
395 OPC_DMODU_G_2E = 0x27 | OPC_SPECIAL3,
398 OPC_LX_DSP = 0x0A | OPC_SPECIAL3,
399 /* MIPS DSP Arithmetic */
400 OPC_ADDU_QB_DSP = 0x10 | OPC_SPECIAL3,
401 OPC_ADDU_OB_DSP = 0x14 | OPC_SPECIAL3,
402 OPC_ABSQ_S_PH_DSP = 0x12 | OPC_SPECIAL3,
403 OPC_ABSQ_S_QH_DSP = 0x16 | OPC_SPECIAL3,
404 /* OPC_ADDUH_QB_DSP is same as OPC_MULT_G_2E. */
405 /* OPC_ADDUH_QB_DSP = 0x18 | OPC_SPECIAL3, */
406 OPC_CMPU_EQ_QB_DSP = 0x11 | OPC_SPECIAL3,
407 OPC_CMPU_EQ_OB_DSP = 0x15 | OPC_SPECIAL3,
408 /* MIPS DSP GPR-Based Shift Sub-class */
409 OPC_SHLL_QB_DSP = 0x13 | OPC_SPECIAL3,
410 OPC_SHLL_OB_DSP = 0x17 | OPC_SPECIAL3,
411 /* MIPS DSP Multiply Sub-class insns */
412 /* OPC_MUL_PH_DSP is same as OPC_ADDUH_QB_DSP. */
413 /* OPC_MUL_PH_DSP = 0x18 | OPC_SPECIAL3, */
414 OPC_DPA_W_PH_DSP = 0x30 | OPC_SPECIAL3,
415 OPC_DPAQ_W_QH_DSP = 0x34 | OPC_SPECIAL3,
416 /* DSP Bit/Manipulation Sub-class */
417 OPC_INSV_DSP = 0x0C | OPC_SPECIAL3,
418 OPC_DINSV_DSP = 0x0D | OPC_SPECIAL3,
419 /* MIPS DSP Append Sub-class */
420 OPC_APPEND_DSP = 0x31 | OPC_SPECIAL3,
421 OPC_DAPPEND_DSP = 0x35 | OPC_SPECIAL3,
422 /* MIPS DSP Accumulator and DSPControl Access Sub-class */
423 OPC_EXTR_W_DSP = 0x38 | OPC_SPECIAL3,
424 OPC_DEXTR_W_DSP = 0x3C | OPC_SPECIAL3,
427 R6_OPC_PREF = 0x35 | OPC_SPECIAL3,
428 R6_OPC_CACHE = 0x25 | OPC_SPECIAL3,
429 R6_OPC_LL = 0x36 | OPC_SPECIAL3,
430 R6_OPC_SC = 0x26 | OPC_SPECIAL3,
431 R6_OPC_LLD = 0x37 | OPC_SPECIAL3,
432 R6_OPC_SCD = 0x27 | OPC_SPECIAL3,
436 #define MASK_BSHFL(op) MASK_SPECIAL3(op) | (op & (0x1F << 6))
439 OPC_WSBH = (0x02 << 6) | OPC_BSHFL,
440 OPC_SEB = (0x10 << 6) | OPC_BSHFL,
441 OPC_SEH = (0x18 << 6) | OPC_BSHFL,
442 OPC_ALIGN = (0x08 << 6) | OPC_BSHFL, /* 010.bp */
443 OPC_ALIGN_END = (0x0B << 6) | OPC_BSHFL, /* 010.00 to 010.11 */
444 OPC_BITSWAP = (0x00 << 6) | OPC_BSHFL /* 00000 */
448 #define MASK_DBSHFL(op) MASK_SPECIAL3(op) | (op & (0x1F << 6))
451 OPC_DSBH = (0x02 << 6) | OPC_DBSHFL,
452 OPC_DSHD = (0x05 << 6) | OPC_DBSHFL,
453 OPC_DALIGN = (0x08 << 6) | OPC_DBSHFL, /* 01.bp */
454 OPC_DALIGN_END = (0x0F << 6) | OPC_DBSHFL, /* 01.000 to 01.111 */
455 OPC_DBITSWAP = (0x00 << 6) | OPC_DBSHFL, /* 00000 */
458 /* MIPS DSP REGIMM opcodes */
460 OPC_BPOSGE32 = (0x1C << 16) | OPC_REGIMM,
461 OPC_BPOSGE64 = (0x1D << 16) | OPC_REGIMM,
464 #define MASK_LX(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
467 OPC_LBUX = (0x06 << 6) | OPC_LX_DSP,
468 OPC_LHX = (0x04 << 6) | OPC_LX_DSP,
469 OPC_LWX = (0x00 << 6) | OPC_LX_DSP,
470 OPC_LDX = (0x08 << 6) | OPC_LX_DSP,
473 #define MASK_ADDU_QB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
475 /* MIPS DSP Arithmetic Sub-class */
476 OPC_ADDQ_PH = (0x0A << 6) | OPC_ADDU_QB_DSP,
477 OPC_ADDQ_S_PH = (0x0E << 6) | OPC_ADDU_QB_DSP,
478 OPC_ADDQ_S_W = (0x16 << 6) | OPC_ADDU_QB_DSP,
479 OPC_ADDU_QB = (0x00 << 6) | OPC_ADDU_QB_DSP,
480 OPC_ADDU_S_QB = (0x04 << 6) | OPC_ADDU_QB_DSP,
481 OPC_ADDU_PH = (0x08 << 6) | OPC_ADDU_QB_DSP,
482 OPC_ADDU_S_PH = (0x0C << 6) | OPC_ADDU_QB_DSP,
483 OPC_SUBQ_PH = (0x0B << 6) | OPC_ADDU_QB_DSP,
484 OPC_SUBQ_S_PH = (0x0F << 6) | OPC_ADDU_QB_DSP,
485 OPC_SUBQ_S_W = (0x17 << 6) | OPC_ADDU_QB_DSP,
486 OPC_SUBU_QB = (0x01 << 6) | OPC_ADDU_QB_DSP,
487 OPC_SUBU_S_QB = (0x05 << 6) | OPC_ADDU_QB_DSP,
488 OPC_SUBU_PH = (0x09 << 6) | OPC_ADDU_QB_DSP,
489 OPC_SUBU_S_PH = (0x0D << 6) | OPC_ADDU_QB_DSP,
490 OPC_ADDSC = (0x10 << 6) | OPC_ADDU_QB_DSP,
491 OPC_ADDWC = (0x11 << 6) | OPC_ADDU_QB_DSP,
492 OPC_MODSUB = (0x12 << 6) | OPC_ADDU_QB_DSP,
493 OPC_RADDU_W_QB = (0x14 << 6) | OPC_ADDU_QB_DSP,
494 /* MIPS DSP Multiply Sub-class insns */
495 OPC_MULEU_S_PH_QBL = (0x06 << 6) | OPC_ADDU_QB_DSP,
496 OPC_MULEU_S_PH_QBR = (0x07 << 6) | OPC_ADDU_QB_DSP,
497 OPC_MULQ_RS_PH = (0x1F << 6) | OPC_ADDU_QB_DSP,
498 OPC_MULEQ_S_W_PHL = (0x1C << 6) | OPC_ADDU_QB_DSP,
499 OPC_MULEQ_S_W_PHR = (0x1D << 6) | OPC_ADDU_QB_DSP,
500 OPC_MULQ_S_PH = (0x1E << 6) | OPC_ADDU_QB_DSP,
503 #define OPC_ADDUH_QB_DSP OPC_MULT_G_2E
504 #define MASK_ADDUH_QB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
506 /* MIPS DSP Arithmetic Sub-class */
507 OPC_ADDUH_QB = (0x00 << 6) | OPC_ADDUH_QB_DSP,
508 OPC_ADDUH_R_QB = (0x02 << 6) | OPC_ADDUH_QB_DSP,
509 OPC_ADDQH_PH = (0x08 << 6) | OPC_ADDUH_QB_DSP,
510 OPC_ADDQH_R_PH = (0x0A << 6) | OPC_ADDUH_QB_DSP,
511 OPC_ADDQH_W = (0x10 << 6) | OPC_ADDUH_QB_DSP,
512 OPC_ADDQH_R_W = (0x12 << 6) | OPC_ADDUH_QB_DSP,
513 OPC_SUBUH_QB = (0x01 << 6) | OPC_ADDUH_QB_DSP,
514 OPC_SUBUH_R_QB = (0x03 << 6) | OPC_ADDUH_QB_DSP,
515 OPC_SUBQH_PH = (0x09 << 6) | OPC_ADDUH_QB_DSP,
516 OPC_SUBQH_R_PH = (0x0B << 6) | OPC_ADDUH_QB_DSP,
517 OPC_SUBQH_W = (0x11 << 6) | OPC_ADDUH_QB_DSP,
518 OPC_SUBQH_R_W = (0x13 << 6) | OPC_ADDUH_QB_DSP,
519 /* MIPS DSP Multiply Sub-class insns */
520 OPC_MUL_PH = (0x0C << 6) | OPC_ADDUH_QB_DSP,
521 OPC_MUL_S_PH = (0x0E << 6) | OPC_ADDUH_QB_DSP,
522 OPC_MULQ_S_W = (0x16 << 6) | OPC_ADDUH_QB_DSP,
523 OPC_MULQ_RS_W = (0x17 << 6) | OPC_ADDUH_QB_DSP,
526 #define MASK_ABSQ_S_PH(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
528 /* MIPS DSP Arithmetic Sub-class */
529 OPC_ABSQ_S_QB = (0x01 << 6) | OPC_ABSQ_S_PH_DSP,
530 OPC_ABSQ_S_PH = (0x09 << 6) | OPC_ABSQ_S_PH_DSP,
531 OPC_ABSQ_S_W = (0x11 << 6) | OPC_ABSQ_S_PH_DSP,
532 OPC_PRECEQ_W_PHL = (0x0C << 6) | OPC_ABSQ_S_PH_DSP,
533 OPC_PRECEQ_W_PHR = (0x0D << 6) | OPC_ABSQ_S_PH_DSP,
534 OPC_PRECEQU_PH_QBL = (0x04 << 6) | OPC_ABSQ_S_PH_DSP,
535 OPC_PRECEQU_PH_QBR = (0x05 << 6) | OPC_ABSQ_S_PH_DSP,
536 OPC_PRECEQU_PH_QBLA = (0x06 << 6) | OPC_ABSQ_S_PH_DSP,
537 OPC_PRECEQU_PH_QBRA = (0x07 << 6) | OPC_ABSQ_S_PH_DSP,
538 OPC_PRECEU_PH_QBL = (0x1C << 6) | OPC_ABSQ_S_PH_DSP,
539 OPC_PRECEU_PH_QBR = (0x1D << 6) | OPC_ABSQ_S_PH_DSP,
540 OPC_PRECEU_PH_QBLA = (0x1E << 6) | OPC_ABSQ_S_PH_DSP,
541 OPC_PRECEU_PH_QBRA = (0x1F << 6) | OPC_ABSQ_S_PH_DSP,
542 /* DSP Bit/Manipulation Sub-class */
543 OPC_BITREV = (0x1B << 6) | OPC_ABSQ_S_PH_DSP,
544 OPC_REPL_QB = (0x02 << 6) | OPC_ABSQ_S_PH_DSP,
545 OPC_REPLV_QB = (0x03 << 6) | OPC_ABSQ_S_PH_DSP,
546 OPC_REPL_PH = (0x0A << 6) | OPC_ABSQ_S_PH_DSP,
547 OPC_REPLV_PH = (0x0B << 6) | OPC_ABSQ_S_PH_DSP,
550 #define MASK_CMPU_EQ_QB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
552 /* MIPS DSP Arithmetic Sub-class */
553 OPC_PRECR_QB_PH = (0x0D << 6) | OPC_CMPU_EQ_QB_DSP,
554 OPC_PRECRQ_QB_PH = (0x0C << 6) | OPC_CMPU_EQ_QB_DSP,
555 OPC_PRECR_SRA_PH_W = (0x1E << 6) | OPC_CMPU_EQ_QB_DSP,
556 OPC_PRECR_SRA_R_PH_W = (0x1F << 6) | OPC_CMPU_EQ_QB_DSP,
557 OPC_PRECRQ_PH_W = (0x14 << 6) | OPC_CMPU_EQ_QB_DSP,
558 OPC_PRECRQ_RS_PH_W = (0x15 << 6) | OPC_CMPU_EQ_QB_DSP,
559 OPC_PRECRQU_S_QB_PH = (0x0F << 6) | OPC_CMPU_EQ_QB_DSP,
560 /* DSP Compare-Pick Sub-class */
561 OPC_CMPU_EQ_QB = (0x00 << 6) | OPC_CMPU_EQ_QB_DSP,
562 OPC_CMPU_LT_QB = (0x01 << 6) | OPC_CMPU_EQ_QB_DSP,
563 OPC_CMPU_LE_QB = (0x02 << 6) | OPC_CMPU_EQ_QB_DSP,
564 OPC_CMPGU_EQ_QB = (0x04 << 6) | OPC_CMPU_EQ_QB_DSP,
565 OPC_CMPGU_LT_QB = (0x05 << 6) | OPC_CMPU_EQ_QB_DSP,
566 OPC_CMPGU_LE_QB = (0x06 << 6) | OPC_CMPU_EQ_QB_DSP,
567 OPC_CMPGDU_EQ_QB = (0x18 << 6) | OPC_CMPU_EQ_QB_DSP,
568 OPC_CMPGDU_LT_QB = (0x19 << 6) | OPC_CMPU_EQ_QB_DSP,
569 OPC_CMPGDU_LE_QB = (0x1A << 6) | OPC_CMPU_EQ_QB_DSP,
570 OPC_CMP_EQ_PH = (0x08 << 6) | OPC_CMPU_EQ_QB_DSP,
571 OPC_CMP_LT_PH = (0x09 << 6) | OPC_CMPU_EQ_QB_DSP,
572 OPC_CMP_LE_PH = (0x0A << 6) | OPC_CMPU_EQ_QB_DSP,
573 OPC_PICK_QB = (0x03 << 6) | OPC_CMPU_EQ_QB_DSP,
574 OPC_PICK_PH = (0x0B << 6) | OPC_CMPU_EQ_QB_DSP,
575 OPC_PACKRL_PH = (0x0E << 6) | OPC_CMPU_EQ_QB_DSP,
578 #define MASK_SHLL_QB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
580 /* MIPS DSP GPR-Based Shift Sub-class */
581 OPC_SHLL_QB = (0x00 << 6) | OPC_SHLL_QB_DSP,
582 OPC_SHLLV_QB = (0x02 << 6) | OPC_SHLL_QB_DSP,
583 OPC_SHLL_PH = (0x08 << 6) | OPC_SHLL_QB_DSP,
584 OPC_SHLLV_PH = (0x0A << 6) | OPC_SHLL_QB_DSP,
585 OPC_SHLL_S_PH = (0x0C << 6) | OPC_SHLL_QB_DSP,
586 OPC_SHLLV_S_PH = (0x0E << 6) | OPC_SHLL_QB_DSP,
587 OPC_SHLL_S_W = (0x14 << 6) | OPC_SHLL_QB_DSP,
588 OPC_SHLLV_S_W = (0x16 << 6) | OPC_SHLL_QB_DSP,
589 OPC_SHRL_QB = (0x01 << 6) | OPC_SHLL_QB_DSP,
590 OPC_SHRLV_QB = (0x03 << 6) | OPC_SHLL_QB_DSP,
591 OPC_SHRL_PH = (0x19 << 6) | OPC_SHLL_QB_DSP,
592 OPC_SHRLV_PH = (0x1B << 6) | OPC_SHLL_QB_DSP,
593 OPC_SHRA_QB = (0x04 << 6) | OPC_SHLL_QB_DSP,
594 OPC_SHRA_R_QB = (0x05 << 6) | OPC_SHLL_QB_DSP,
595 OPC_SHRAV_QB = (0x06 << 6) | OPC_SHLL_QB_DSP,
596 OPC_SHRAV_R_QB = (0x07 << 6) | OPC_SHLL_QB_DSP,
597 OPC_SHRA_PH = (0x09 << 6) | OPC_SHLL_QB_DSP,
598 OPC_SHRAV_PH = (0x0B << 6) | OPC_SHLL_QB_DSP,
599 OPC_SHRA_R_PH = (0x0D << 6) | OPC_SHLL_QB_DSP,
600 OPC_SHRAV_R_PH = (0x0F << 6) | OPC_SHLL_QB_DSP,
601 OPC_SHRA_R_W = (0x15 << 6) | OPC_SHLL_QB_DSP,
602 OPC_SHRAV_R_W = (0x17 << 6) | OPC_SHLL_QB_DSP,
605 #define MASK_DPA_W_PH(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
607 /* MIPS DSP Multiply Sub-class insns */
608 OPC_DPAU_H_QBL = (0x03 << 6) | OPC_DPA_W_PH_DSP,
609 OPC_DPAU_H_QBR = (0x07 << 6) | OPC_DPA_W_PH_DSP,
610 OPC_DPSU_H_QBL = (0x0B << 6) | OPC_DPA_W_PH_DSP,
611 OPC_DPSU_H_QBR = (0x0F << 6) | OPC_DPA_W_PH_DSP,
612 OPC_DPA_W_PH = (0x00 << 6) | OPC_DPA_W_PH_DSP,
613 OPC_DPAX_W_PH = (0x08 << 6) | OPC_DPA_W_PH_DSP,
614 OPC_DPAQ_S_W_PH = (0x04 << 6) | OPC_DPA_W_PH_DSP,
615 OPC_DPAQX_S_W_PH = (0x18 << 6) | OPC_DPA_W_PH_DSP,
616 OPC_DPAQX_SA_W_PH = (0x1A << 6) | OPC_DPA_W_PH_DSP,
617 OPC_DPS_W_PH = (0x01 << 6) | OPC_DPA_W_PH_DSP,
618 OPC_DPSX_W_PH = (0x09 << 6) | OPC_DPA_W_PH_DSP,
619 OPC_DPSQ_S_W_PH = (0x05 << 6) | OPC_DPA_W_PH_DSP,
620 OPC_DPSQX_S_W_PH = (0x19 << 6) | OPC_DPA_W_PH_DSP,
621 OPC_DPSQX_SA_W_PH = (0x1B << 6) | OPC_DPA_W_PH_DSP,
622 OPC_MULSAQ_S_W_PH = (0x06 << 6) | OPC_DPA_W_PH_DSP,
623 OPC_DPAQ_SA_L_W = (0x0C << 6) | OPC_DPA_W_PH_DSP,
624 OPC_DPSQ_SA_L_W = (0x0D << 6) | OPC_DPA_W_PH_DSP,
625 OPC_MAQ_S_W_PHL = (0x14 << 6) | OPC_DPA_W_PH_DSP,
626 OPC_MAQ_S_W_PHR = (0x16 << 6) | OPC_DPA_W_PH_DSP,
627 OPC_MAQ_SA_W_PHL = (0x10 << 6) | OPC_DPA_W_PH_DSP,
628 OPC_MAQ_SA_W_PHR = (0x12 << 6) | OPC_DPA_W_PH_DSP,
629 OPC_MULSA_W_PH = (0x02 << 6) | OPC_DPA_W_PH_DSP,
632 #define MASK_INSV(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
634 /* DSP Bit/Manipulation Sub-class */
635 OPC_INSV = (0x00 << 6) | OPC_INSV_DSP,
638 #define MASK_APPEND(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
640 /* MIPS DSP Append Sub-class */
641 OPC_APPEND = (0x00 << 6) | OPC_APPEND_DSP,
642 OPC_PREPEND = (0x01 << 6) | OPC_APPEND_DSP,
643 OPC_BALIGN = (0x10 << 6) | OPC_APPEND_DSP,
646 #define MASK_EXTR_W(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
648 /* MIPS DSP Accumulator and DSPControl Access Sub-class */
649 OPC_EXTR_W = (0x00 << 6) | OPC_EXTR_W_DSP,
650 OPC_EXTR_R_W = (0x04 << 6) | OPC_EXTR_W_DSP,
651 OPC_EXTR_RS_W = (0x06 << 6) | OPC_EXTR_W_DSP,
652 OPC_EXTR_S_H = (0x0E << 6) | OPC_EXTR_W_DSP,
653 OPC_EXTRV_S_H = (0x0F << 6) | OPC_EXTR_W_DSP,
654 OPC_EXTRV_W = (0x01 << 6) | OPC_EXTR_W_DSP,
655 OPC_EXTRV_R_W = (0x05 << 6) | OPC_EXTR_W_DSP,
656 OPC_EXTRV_RS_W = (0x07 << 6) | OPC_EXTR_W_DSP,
657 OPC_EXTP = (0x02 << 6) | OPC_EXTR_W_DSP,
658 OPC_EXTPV = (0x03 << 6) | OPC_EXTR_W_DSP,
659 OPC_EXTPDP = (0x0A << 6) | OPC_EXTR_W_DSP,
660 OPC_EXTPDPV = (0x0B << 6) | OPC_EXTR_W_DSP,
661 OPC_SHILO = (0x1A << 6) | OPC_EXTR_W_DSP,
662 OPC_SHILOV = (0x1B << 6) | OPC_EXTR_W_DSP,
663 OPC_MTHLIP = (0x1F << 6) | OPC_EXTR_W_DSP,
664 OPC_WRDSP = (0x13 << 6) | OPC_EXTR_W_DSP,
665 OPC_RDDSP = (0x12 << 6) | OPC_EXTR_W_DSP,
668 #define MASK_ABSQ_S_QH(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
670 /* MIPS DSP Arithmetic Sub-class */
671 OPC_PRECEQ_L_PWL = (0x14 << 6) | OPC_ABSQ_S_QH_DSP,
672 OPC_PRECEQ_L_PWR = (0x15 << 6) | OPC_ABSQ_S_QH_DSP,
673 OPC_PRECEQ_PW_QHL = (0x0C << 6) | OPC_ABSQ_S_QH_DSP,
674 OPC_PRECEQ_PW_QHR = (0x0D << 6) | OPC_ABSQ_S_QH_DSP,
675 OPC_PRECEQ_PW_QHLA = (0x0E << 6) | OPC_ABSQ_S_QH_DSP,
676 OPC_PRECEQ_PW_QHRA = (0x0F << 6) | OPC_ABSQ_S_QH_DSP,
677 OPC_PRECEQU_QH_OBL = (0x04 << 6) | OPC_ABSQ_S_QH_DSP,
678 OPC_PRECEQU_QH_OBR = (0x05 << 6) | OPC_ABSQ_S_QH_DSP,
679 OPC_PRECEQU_QH_OBLA = (0x06 << 6) | OPC_ABSQ_S_QH_DSP,
680 OPC_PRECEQU_QH_OBRA = (0x07 << 6) | OPC_ABSQ_S_QH_DSP,
681 OPC_PRECEU_QH_OBL = (0x1C << 6) | OPC_ABSQ_S_QH_DSP,
682 OPC_PRECEU_QH_OBR = (0x1D << 6) | OPC_ABSQ_S_QH_DSP,
683 OPC_PRECEU_QH_OBLA = (0x1E << 6) | OPC_ABSQ_S_QH_DSP,
684 OPC_PRECEU_QH_OBRA = (0x1F << 6) | OPC_ABSQ_S_QH_DSP,
685 OPC_ABSQ_S_OB = (0x01 << 6) | OPC_ABSQ_S_QH_DSP,
686 OPC_ABSQ_S_PW = (0x11 << 6) | OPC_ABSQ_S_QH_DSP,
687 OPC_ABSQ_S_QH = (0x09 << 6) | OPC_ABSQ_S_QH_DSP,
688 /* DSP Bit/Manipulation Sub-class */
689 OPC_REPL_OB = (0x02 << 6) | OPC_ABSQ_S_QH_DSP,
690 OPC_REPL_PW = (0x12 << 6) | OPC_ABSQ_S_QH_DSP,
691 OPC_REPL_QH = (0x0A << 6) | OPC_ABSQ_S_QH_DSP,
692 OPC_REPLV_OB = (0x03 << 6) | OPC_ABSQ_S_QH_DSP,
693 OPC_REPLV_PW = (0x13 << 6) | OPC_ABSQ_S_QH_DSP,
694 OPC_REPLV_QH = (0x0B << 6) | OPC_ABSQ_S_QH_DSP,
697 #define MASK_ADDU_OB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
699 /* MIPS DSP Multiply Sub-class insns */
700 OPC_MULEQ_S_PW_QHL = (0x1C << 6) | OPC_ADDU_OB_DSP,
701 OPC_MULEQ_S_PW_QHR = (0x1D << 6) | OPC_ADDU_OB_DSP,
702 OPC_MULEU_S_QH_OBL = (0x06 << 6) | OPC_ADDU_OB_DSP,
703 OPC_MULEU_S_QH_OBR = (0x07 << 6) | OPC_ADDU_OB_DSP,
704 OPC_MULQ_RS_QH = (0x1F << 6) | OPC_ADDU_OB_DSP,
705 /* MIPS DSP Arithmetic Sub-class */
706 OPC_RADDU_L_OB = (0x14 << 6) | OPC_ADDU_OB_DSP,
707 OPC_SUBQ_PW = (0x13 << 6) | OPC_ADDU_OB_DSP,
708 OPC_SUBQ_S_PW = (0x17 << 6) | OPC_ADDU_OB_DSP,
709 OPC_SUBQ_QH = (0x0B << 6) | OPC_ADDU_OB_DSP,
710 OPC_SUBQ_S_QH = (0x0F << 6) | OPC_ADDU_OB_DSP,
711 OPC_SUBU_OB = (0x01 << 6) | OPC_ADDU_OB_DSP,
712 OPC_SUBU_S_OB = (0x05 << 6) | OPC_ADDU_OB_DSP,
713 OPC_SUBU_QH = (0x09 << 6) | OPC_ADDU_OB_DSP,
714 OPC_SUBU_S_QH = (0x0D << 6) | OPC_ADDU_OB_DSP,
715 OPC_SUBUH_OB = (0x19 << 6) | OPC_ADDU_OB_DSP,
716 OPC_SUBUH_R_OB = (0x1B << 6) | OPC_ADDU_OB_DSP,
717 OPC_ADDQ_PW = (0x12 << 6) | OPC_ADDU_OB_DSP,
718 OPC_ADDQ_S_PW = (0x16 << 6) | OPC_ADDU_OB_DSP,
719 OPC_ADDQ_QH = (0x0A << 6) | OPC_ADDU_OB_DSP,
720 OPC_ADDQ_S_QH = (0x0E << 6) | OPC_ADDU_OB_DSP,
721 OPC_ADDU_OB = (0x00 << 6) | OPC_ADDU_OB_DSP,
722 OPC_ADDU_S_OB = (0x04 << 6) | OPC_ADDU_OB_DSP,
723 OPC_ADDU_QH = (0x08 << 6) | OPC_ADDU_OB_DSP,
724 OPC_ADDU_S_QH = (0x0C << 6) | OPC_ADDU_OB_DSP,
725 OPC_ADDUH_OB = (0x18 << 6) | OPC_ADDU_OB_DSP,
726 OPC_ADDUH_R_OB = (0x1A << 6) | OPC_ADDU_OB_DSP,
729 #define MASK_CMPU_EQ_OB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
731 /* DSP Compare-Pick Sub-class */
732 OPC_CMP_EQ_PW = (0x10 << 6) | OPC_CMPU_EQ_OB_DSP,
733 OPC_CMP_LT_PW = (0x11 << 6) | OPC_CMPU_EQ_OB_DSP,
734 OPC_CMP_LE_PW = (0x12 << 6) | OPC_CMPU_EQ_OB_DSP,
735 OPC_CMP_EQ_QH = (0x08 << 6) | OPC_CMPU_EQ_OB_DSP,
736 OPC_CMP_LT_QH = (0x09 << 6) | OPC_CMPU_EQ_OB_DSP,
737 OPC_CMP_LE_QH = (0x0A << 6) | OPC_CMPU_EQ_OB_DSP,
738 OPC_CMPGDU_EQ_OB = (0x18 << 6) | OPC_CMPU_EQ_OB_DSP,
739 OPC_CMPGDU_LT_OB = (0x19 << 6) | OPC_CMPU_EQ_OB_DSP,
740 OPC_CMPGDU_LE_OB = (0x1A << 6) | OPC_CMPU_EQ_OB_DSP,
741 OPC_CMPGU_EQ_OB = (0x04 << 6) | OPC_CMPU_EQ_OB_DSP,
742 OPC_CMPGU_LT_OB = (0x05 << 6) | OPC_CMPU_EQ_OB_DSP,
743 OPC_CMPGU_LE_OB = (0x06 << 6) | OPC_CMPU_EQ_OB_DSP,
744 OPC_CMPU_EQ_OB = (0x00 << 6) | OPC_CMPU_EQ_OB_DSP,
745 OPC_CMPU_LT_OB = (0x01 << 6) | OPC_CMPU_EQ_OB_DSP,
746 OPC_CMPU_LE_OB = (0x02 << 6) | OPC_CMPU_EQ_OB_DSP,
747 OPC_PACKRL_PW = (0x0E << 6) | OPC_CMPU_EQ_OB_DSP,
748 OPC_PICK_OB = (0x03 << 6) | OPC_CMPU_EQ_OB_DSP,
749 OPC_PICK_PW = (0x13 << 6) | OPC_CMPU_EQ_OB_DSP,
750 OPC_PICK_QH = (0x0B << 6) | OPC_CMPU_EQ_OB_DSP,
751 /* MIPS DSP Arithmetic Sub-class */
752 OPC_PRECR_OB_QH = (0x0D << 6) | OPC_CMPU_EQ_OB_DSP,
753 OPC_PRECR_SRA_QH_PW = (0x1E << 6) | OPC_CMPU_EQ_OB_DSP,
754 OPC_PRECR_SRA_R_QH_PW = (0x1F << 6) | OPC_CMPU_EQ_OB_DSP,
755 OPC_PRECRQ_OB_QH = (0x0C << 6) | OPC_CMPU_EQ_OB_DSP,
756 OPC_PRECRQ_PW_L = (0x1C << 6) | OPC_CMPU_EQ_OB_DSP,
757 OPC_PRECRQ_QH_PW = (0x14 << 6) | OPC_CMPU_EQ_OB_DSP,
758 OPC_PRECRQ_RS_QH_PW = (0x15 << 6) | OPC_CMPU_EQ_OB_DSP,
759 OPC_PRECRQU_S_OB_QH = (0x0F << 6) | OPC_CMPU_EQ_OB_DSP,
762 #define MASK_DAPPEND(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
764 /* DSP Append Sub-class */
765 OPC_DAPPEND = (0x00 << 6) | OPC_DAPPEND_DSP,
766 OPC_PREPENDD = (0x03 << 6) | OPC_DAPPEND_DSP,
767 OPC_PREPENDW = (0x01 << 6) | OPC_DAPPEND_DSP,
768 OPC_DBALIGN = (0x10 << 6) | OPC_DAPPEND_DSP,
771 #define MASK_DEXTR_W(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
773 /* MIPS DSP Accumulator and DSPControl Access Sub-class */
774 OPC_DMTHLIP = (0x1F << 6) | OPC_DEXTR_W_DSP,
775 OPC_DSHILO = (0x1A << 6) | OPC_DEXTR_W_DSP,
776 OPC_DEXTP = (0x02 << 6) | OPC_DEXTR_W_DSP,
777 OPC_DEXTPDP = (0x0A << 6) | OPC_DEXTR_W_DSP,
778 OPC_DEXTPDPV = (0x0B << 6) | OPC_DEXTR_W_DSP,
779 OPC_DEXTPV = (0x03 << 6) | OPC_DEXTR_W_DSP,
780 OPC_DEXTR_L = (0x10 << 6) | OPC_DEXTR_W_DSP,
781 OPC_DEXTR_R_L = (0x14 << 6) | OPC_DEXTR_W_DSP,
782 OPC_DEXTR_RS_L = (0x16 << 6) | OPC_DEXTR_W_DSP,
783 OPC_DEXTR_W = (0x00 << 6) | OPC_DEXTR_W_DSP,
784 OPC_DEXTR_R_W = (0x04 << 6) | OPC_DEXTR_W_DSP,
785 OPC_DEXTR_RS_W = (0x06 << 6) | OPC_DEXTR_W_DSP,
786 OPC_DEXTR_S_H = (0x0E << 6) | OPC_DEXTR_W_DSP,
787 OPC_DEXTRV_L = (0x11 << 6) | OPC_DEXTR_W_DSP,
788 OPC_DEXTRV_R_L = (0x15 << 6) | OPC_DEXTR_W_DSP,
789 OPC_DEXTRV_RS_L = (0x17 << 6) | OPC_DEXTR_W_DSP,
790 OPC_DEXTRV_S_H = (0x0F << 6) | OPC_DEXTR_W_DSP,
791 OPC_DEXTRV_W = (0x01 << 6) | OPC_DEXTR_W_DSP,
792 OPC_DEXTRV_R_W = (0x05 << 6) | OPC_DEXTR_W_DSP,
793 OPC_DEXTRV_RS_W = (0x07 << 6) | OPC_DEXTR_W_DSP,
794 OPC_DSHILOV = (0x1B << 6) | OPC_DEXTR_W_DSP,
797 #define MASK_DINSV(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
799 /* DSP Bit/Manipulation Sub-class */
800 OPC_DINSV = (0x00 << 6) | OPC_DINSV_DSP,
803 #define MASK_DPAQ_W_QH(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
805 /* MIPS DSP Multiply Sub-class insns */
806 OPC_DMADD = (0x19 << 6) | OPC_DPAQ_W_QH_DSP,
807 OPC_DMADDU = (0x1D << 6) | OPC_DPAQ_W_QH_DSP,
808 OPC_DMSUB = (0x1B << 6) | OPC_DPAQ_W_QH_DSP,
809 OPC_DMSUBU = (0x1F << 6) | OPC_DPAQ_W_QH_DSP,
810 OPC_DPA_W_QH = (0x00 << 6) | OPC_DPAQ_W_QH_DSP,
811 OPC_DPAQ_S_W_QH = (0x04 << 6) | OPC_DPAQ_W_QH_DSP,
812 OPC_DPAQ_SA_L_PW = (0x0C << 6) | OPC_DPAQ_W_QH_DSP,
813 OPC_DPAU_H_OBL = (0x03 << 6) | OPC_DPAQ_W_QH_DSP,
814 OPC_DPAU_H_OBR = (0x07 << 6) | OPC_DPAQ_W_QH_DSP,
815 OPC_DPS_W_QH = (0x01 << 6) | OPC_DPAQ_W_QH_DSP,
816 OPC_DPSQ_S_W_QH = (0x05 << 6) | OPC_DPAQ_W_QH_DSP,
817 OPC_DPSQ_SA_L_PW = (0x0D << 6) | OPC_DPAQ_W_QH_DSP,
818 OPC_DPSU_H_OBL = (0x0B << 6) | OPC_DPAQ_W_QH_DSP,
819 OPC_DPSU_H_OBR = (0x0F << 6) | OPC_DPAQ_W_QH_DSP,
820 OPC_MAQ_S_L_PWL = (0x1C << 6) | OPC_DPAQ_W_QH_DSP,
821 OPC_MAQ_S_L_PWR = (0x1E << 6) | OPC_DPAQ_W_QH_DSP,
822 OPC_MAQ_S_W_QHLL = (0x14 << 6) | OPC_DPAQ_W_QH_DSP,
823 OPC_MAQ_SA_W_QHLL = (0x10 << 6) | OPC_DPAQ_W_QH_DSP,
824 OPC_MAQ_S_W_QHLR = (0x15 << 6) | OPC_DPAQ_W_QH_DSP,
825 OPC_MAQ_SA_W_QHLR = (0x11 << 6) | OPC_DPAQ_W_QH_DSP,
826 OPC_MAQ_S_W_QHRL = (0x16 << 6) | OPC_DPAQ_W_QH_DSP,
827 OPC_MAQ_SA_W_QHRL = (0x12 << 6) | OPC_DPAQ_W_QH_DSP,
828 OPC_MAQ_S_W_QHRR = (0x17 << 6) | OPC_DPAQ_W_QH_DSP,
829 OPC_MAQ_SA_W_QHRR = (0x13 << 6) | OPC_DPAQ_W_QH_DSP,
830 OPC_MULSAQ_S_L_PW = (0x0E << 6) | OPC_DPAQ_W_QH_DSP,
831 OPC_MULSAQ_S_W_QH = (0x06 << 6) | OPC_DPAQ_W_QH_DSP,
834 #define MASK_SHLL_OB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
836 /* MIPS DSP GPR-Based Shift Sub-class */
837 OPC_SHLL_PW = (0x10 << 6) | OPC_SHLL_OB_DSP,
838 OPC_SHLL_S_PW = (0x14 << 6) | OPC_SHLL_OB_DSP,
839 OPC_SHLLV_OB = (0x02 << 6) | OPC_SHLL_OB_DSP,
840 OPC_SHLLV_PW = (0x12 << 6) | OPC_SHLL_OB_DSP,
841 OPC_SHLLV_S_PW = (0x16 << 6) | OPC_SHLL_OB_DSP,
842 OPC_SHLLV_QH = (0x0A << 6) | OPC_SHLL_OB_DSP,
843 OPC_SHLLV_S_QH = (0x0E << 6) | OPC_SHLL_OB_DSP,
844 OPC_SHRA_PW = (0x11 << 6) | OPC_SHLL_OB_DSP,
845 OPC_SHRA_R_PW = (0x15 << 6) | OPC_SHLL_OB_DSP,
846 OPC_SHRAV_OB = (0x06 << 6) | OPC_SHLL_OB_DSP,
847 OPC_SHRAV_R_OB = (0x07 << 6) | OPC_SHLL_OB_DSP,
848 OPC_SHRAV_PW = (0x13 << 6) | OPC_SHLL_OB_DSP,
849 OPC_SHRAV_R_PW = (0x17 << 6) | OPC_SHLL_OB_DSP,
850 OPC_SHRAV_QH = (0x0B << 6) | OPC_SHLL_OB_DSP,
851 OPC_SHRAV_R_QH = (0x0F << 6) | OPC_SHLL_OB_DSP,
852 OPC_SHRLV_OB = (0x03 << 6) | OPC_SHLL_OB_DSP,
853 OPC_SHRLV_QH = (0x1B << 6) | OPC_SHLL_OB_DSP,
854 OPC_SHLL_OB = (0x00 << 6) | OPC_SHLL_OB_DSP,
855 OPC_SHLL_QH = (0x08 << 6) | OPC_SHLL_OB_DSP,
856 OPC_SHLL_S_QH = (0x0C << 6) | OPC_SHLL_OB_DSP,
857 OPC_SHRA_OB = (0x04 << 6) | OPC_SHLL_OB_DSP,
858 OPC_SHRA_R_OB = (0x05 << 6) | OPC_SHLL_OB_DSP,
859 OPC_SHRA_QH = (0x09 << 6) | OPC_SHLL_OB_DSP,
860 OPC_SHRA_R_QH = (0x0D << 6) | OPC_SHLL_OB_DSP,
861 OPC_SHRL_OB = (0x01 << 6) | OPC_SHLL_OB_DSP,
862 OPC_SHRL_QH = (0x19 << 6) | OPC_SHLL_OB_DSP,
865 /* Coprocessor 0 (rs field) */
866 #define MASK_CP0(op) MASK_OP_MAJOR(op) | (op & (0x1F << 21))
869 OPC_MFC0 = (0x00 << 21) | OPC_CP0,
870 OPC_DMFC0 = (0x01 << 21) | OPC_CP0,
871 OPC_MTC0 = (0x04 << 21) | OPC_CP0,
872 OPC_DMTC0 = (0x05 << 21) | OPC_CP0,
873 OPC_MFTR = (0x08 << 21) | OPC_CP0,
874 OPC_RDPGPR = (0x0A << 21) | OPC_CP0,
875 OPC_MFMC0 = (0x0B << 21) | OPC_CP0,
876 OPC_MTTR = (0x0C << 21) | OPC_CP0,
877 OPC_WRPGPR = (0x0E << 21) | OPC_CP0,
878 OPC_C0 = (0x10 << 21) | OPC_CP0,
879 OPC_C0_FIRST = (0x10 << 21) | OPC_CP0,
880 OPC_C0_LAST = (0x1F << 21) | OPC_CP0,
884 #define MASK_MFMC0(op) MASK_CP0(op) | (op & 0xFFFF)
887 OPC_DMT = 0x01 | (0 << 5) | (0x0F << 6) | (0x01 << 11) | OPC_MFMC0,
888 OPC_EMT = 0x01 | (1 << 5) | (0x0F << 6) | (0x01 << 11) | OPC_MFMC0,
889 OPC_DVPE = 0x01 | (0 << 5) | OPC_MFMC0,
890 OPC_EVPE = 0x01 | (1 << 5) | OPC_MFMC0,
891 OPC_DI = (0 << 5) | (0x0C << 11) | OPC_MFMC0,
892 OPC_EI = (1 << 5) | (0x0C << 11) | OPC_MFMC0,
895 /* Coprocessor 0 (with rs == C0) */
896 #define MASK_C0(op) MASK_CP0(op) | (op & 0x3F)
899 OPC_TLBR = 0x01 | OPC_C0,
900 OPC_TLBWI = 0x02 | OPC_C0,
901 OPC_TLBINV = 0x03 | OPC_C0,
902 OPC_TLBINVF = 0x04 | OPC_C0,
903 OPC_TLBWR = 0x06 | OPC_C0,
904 OPC_TLBP = 0x08 | OPC_C0,
905 OPC_RFE = 0x10 | OPC_C0,
906 OPC_ERET = 0x18 | OPC_C0,
907 OPC_DERET = 0x1F | OPC_C0,
908 OPC_WAIT = 0x20 | OPC_C0,
911 /* Coprocessor 1 (rs field) */
912 #define MASK_CP1(op) MASK_OP_MAJOR(op) | (op & (0x1F << 21))
914 /* Values for the fmt field in FP instructions */
916 /* 0 - 15 are reserved */
917 FMT_S = 16, /* single fp */
918 FMT_D = 17, /* double fp */
919 FMT_E = 18, /* extended fp */
920 FMT_Q = 19, /* quad fp */
921 FMT_W = 20, /* 32-bit fixed */
922 FMT_L = 21, /* 64-bit fixed */
923 FMT_PS = 22, /* paired single fp */
924 /* 23 - 31 are reserved */
928 OPC_MFC1 = (0x00 << 21) | OPC_CP1,
929 OPC_DMFC1 = (0x01 << 21) | OPC_CP1,
930 OPC_CFC1 = (0x02 << 21) | OPC_CP1,
931 OPC_MFHC1 = (0x03 << 21) | OPC_CP1,
932 OPC_MTC1 = (0x04 << 21) | OPC_CP1,
933 OPC_DMTC1 = (0x05 << 21) | OPC_CP1,
934 OPC_CTC1 = (0x06 << 21) | OPC_CP1,
935 OPC_MTHC1 = (0x07 << 21) | OPC_CP1,
936 OPC_BC1 = (0x08 << 21) | OPC_CP1, /* bc */
937 OPC_BC1ANY2 = (0x09 << 21) | OPC_CP1,
938 OPC_BC1ANY4 = (0x0A << 21) | OPC_CP1,
939 OPC_BZ_V = (0x0B << 21) | OPC_CP1,
940 OPC_BNZ_V = (0x0F << 21) | OPC_CP1,
941 OPC_S_FMT = (FMT_S << 21) | OPC_CP1,
942 OPC_D_FMT = (FMT_D << 21) | OPC_CP1,
943 OPC_E_FMT = (FMT_E << 21) | OPC_CP1,
944 OPC_Q_FMT = (FMT_Q << 21) | OPC_CP1,
945 OPC_W_FMT = (FMT_W << 21) | OPC_CP1,
946 OPC_L_FMT = (FMT_L << 21) | OPC_CP1,
947 OPC_PS_FMT = (FMT_PS << 21) | OPC_CP1,
948 OPC_BC1EQZ = (0x09 << 21) | OPC_CP1,
949 OPC_BC1NEZ = (0x0D << 21) | OPC_CP1,
950 OPC_BZ_B = (0x18 << 21) | OPC_CP1,
951 OPC_BZ_H = (0x19 << 21) | OPC_CP1,
952 OPC_BZ_W = (0x1A << 21) | OPC_CP1,
953 OPC_BZ_D = (0x1B << 21) | OPC_CP1,
954 OPC_BNZ_B = (0x1C << 21) | OPC_CP1,
955 OPC_BNZ_H = (0x1D << 21) | OPC_CP1,
956 OPC_BNZ_W = (0x1E << 21) | OPC_CP1,
957 OPC_BNZ_D = (0x1F << 21) | OPC_CP1,
960 #define MASK_CP1_FUNC(op) MASK_CP1(op) | (op & 0x3F)
961 #define MASK_BC1(op) MASK_CP1(op) | (op & (0x3 << 16))
964 OPC_BC1F = (0x00 << 16) | OPC_BC1,
965 OPC_BC1T = (0x01 << 16) | OPC_BC1,
966 OPC_BC1FL = (0x02 << 16) | OPC_BC1,
967 OPC_BC1TL = (0x03 << 16) | OPC_BC1,
971 OPC_BC1FANY2 = (0x00 << 16) | OPC_BC1ANY2,
972 OPC_BC1TANY2 = (0x01 << 16) | OPC_BC1ANY2,
976 OPC_BC1FANY4 = (0x00 << 16) | OPC_BC1ANY4,
977 OPC_BC1TANY4 = (0x01 << 16) | OPC_BC1ANY4,
980 #define MASK_CP2(op) MASK_OP_MAJOR(op) | (op & (0x1F << 21))
983 OPC_MFC2 = (0x00 << 21) | OPC_CP2,
984 OPC_DMFC2 = (0x01 << 21) | OPC_CP2,
985 OPC_CFC2 = (0x02 << 21) | OPC_CP2,
986 OPC_MFHC2 = (0x03 << 21) | OPC_CP2,
987 OPC_MTC2 = (0x04 << 21) | OPC_CP2,
988 OPC_DMTC2 = (0x05 << 21) | OPC_CP2,
989 OPC_CTC2 = (0x06 << 21) | OPC_CP2,
990 OPC_MTHC2 = (0x07 << 21) | OPC_CP2,
991 OPC_BC2 = (0x08 << 21) | OPC_CP2,
992 OPC_BC2EQZ = (0x09 << 21) | OPC_CP2,
993 OPC_BC2NEZ = (0x0D << 21) | OPC_CP2,
996 #define MASK_LMI(op) (MASK_OP_MAJOR(op) | (op & (0x1F << 21)) | (op & 0x1F))
999 OPC_PADDSH = (24 << 21) | (0x00) | OPC_CP2,
1000 OPC_PADDUSH = (25 << 21) | (0x00) | OPC_CP2,
1001 OPC_PADDH = (26 << 21) | (0x00) | OPC_CP2,
1002 OPC_PADDW = (27 << 21) | (0x00) | OPC_CP2,
1003 OPC_PADDSB = (28 << 21) | (0x00) | OPC_CP2,
1004 OPC_PADDUSB = (29 << 21) | (0x00) | OPC_CP2,
1005 OPC_PADDB = (30 << 21) | (0x00) | OPC_CP2,
1006 OPC_PADDD = (31 << 21) | (0x00) | OPC_CP2,
1008 OPC_PSUBSH = (24 << 21) | (0x01) | OPC_CP2,
1009 OPC_PSUBUSH = (25 << 21) | (0x01) | OPC_CP2,
1010 OPC_PSUBH = (26 << 21) | (0x01) | OPC_CP2,
1011 OPC_PSUBW = (27 << 21) | (0x01) | OPC_CP2,
1012 OPC_PSUBSB = (28 << 21) | (0x01) | OPC_CP2,
1013 OPC_PSUBUSB = (29 << 21) | (0x01) | OPC_CP2,
1014 OPC_PSUBB = (30 << 21) | (0x01) | OPC_CP2,
1015 OPC_PSUBD = (31 << 21) | (0x01) | OPC_CP2,
1017 OPC_PSHUFH = (24 << 21) | (0x02) | OPC_CP2,
1018 OPC_PACKSSWH = (25 << 21) | (0x02) | OPC_CP2,
1019 OPC_PACKSSHB = (26 << 21) | (0x02) | OPC_CP2,
1020 OPC_PACKUSHB = (27 << 21) | (0x02) | OPC_CP2,
1021 OPC_XOR_CP2 = (28 << 21) | (0x02) | OPC_CP2,
1022 OPC_NOR_CP2 = (29 << 21) | (0x02) | OPC_CP2,
1023 OPC_AND_CP2 = (30 << 21) | (0x02) | OPC_CP2,
1024 OPC_PANDN = (31 << 21) | (0x02) | OPC_CP2,
1026 OPC_PUNPCKLHW = (24 << 21) | (0x03) | OPC_CP2,
1027 OPC_PUNPCKHHW = (25 << 21) | (0x03) | OPC_CP2,
1028 OPC_PUNPCKLBH = (26 << 21) | (0x03) | OPC_CP2,
1029 OPC_PUNPCKHBH = (27 << 21) | (0x03) | OPC_CP2,
1030 OPC_PINSRH_0 = (28 << 21) | (0x03) | OPC_CP2,
1031 OPC_PINSRH_1 = (29 << 21) | (0x03) | OPC_CP2,
1032 OPC_PINSRH_2 = (30 << 21) | (0x03) | OPC_CP2,
1033 OPC_PINSRH_3 = (31 << 21) | (0x03) | OPC_CP2,
1035 OPC_PAVGH = (24 << 21) | (0x08) | OPC_CP2,
1036 OPC_PAVGB = (25 << 21) | (0x08) | OPC_CP2,
1037 OPC_PMAXSH = (26 << 21) | (0x08) | OPC_CP2,
1038 OPC_PMINSH = (27 << 21) | (0x08) | OPC_CP2,
1039 OPC_PMAXUB = (28 << 21) | (0x08) | OPC_CP2,
1040 OPC_PMINUB = (29 << 21) | (0x08) | OPC_CP2,
1042 OPC_PCMPEQW = (24 << 21) | (0x09) | OPC_CP2,
1043 OPC_PCMPGTW = (25 << 21) | (0x09) | OPC_CP2,
1044 OPC_PCMPEQH = (26 << 21) | (0x09) | OPC_CP2,
1045 OPC_PCMPGTH = (27 << 21) | (0x09) | OPC_CP2,
1046 OPC_PCMPEQB = (28 << 21) | (0x09) | OPC_CP2,
1047 OPC_PCMPGTB = (29 << 21) | (0x09) | OPC_CP2,
1049 OPC_PSLLW = (24 << 21) | (0x0A) | OPC_CP2,
1050 OPC_PSLLH = (25 << 21) | (0x0A) | OPC_CP2,
1051 OPC_PMULLH = (26 << 21) | (0x0A) | OPC_CP2,
1052 OPC_PMULHH = (27 << 21) | (0x0A) | OPC_CP2,
1053 OPC_PMULUW = (28 << 21) | (0x0A) | OPC_CP2,
1054 OPC_PMULHUH = (29 << 21) | (0x0A) | OPC_CP2,
1056 OPC_PSRLW = (24 << 21) | (0x0B) | OPC_CP2,
1057 OPC_PSRLH = (25 << 21) | (0x0B) | OPC_CP2,
1058 OPC_PSRAW = (26 << 21) | (0x0B) | OPC_CP2,
1059 OPC_PSRAH = (27 << 21) | (0x0B) | OPC_CP2,
1060 OPC_PUNPCKLWD = (28 << 21) | (0x0B) | OPC_CP2,
1061 OPC_PUNPCKHWD = (29 << 21) | (0x0B) | OPC_CP2,
1063 OPC_ADDU_CP2 = (24 << 21) | (0x0C) | OPC_CP2,
1064 OPC_OR_CP2 = (25 << 21) | (0x0C) | OPC_CP2,
1065 OPC_ADD_CP2 = (26 << 21) | (0x0C) | OPC_CP2,
1066 OPC_DADD_CP2 = (27 << 21) | (0x0C) | OPC_CP2,
1067 OPC_SEQU_CP2 = (28 << 21) | (0x0C) | OPC_CP2,
1068 OPC_SEQ_CP2 = (29 << 21) | (0x0C) | OPC_CP2,
1070 OPC_SUBU_CP2 = (24 << 21) | (0x0D) | OPC_CP2,
1071 OPC_PASUBUB = (25 << 21) | (0x0D) | OPC_CP2,
1072 OPC_SUB_CP2 = (26 << 21) | (0x0D) | OPC_CP2,
1073 OPC_DSUB_CP2 = (27 << 21) | (0x0D) | OPC_CP2,
1074 OPC_SLTU_CP2 = (28 << 21) | (0x0D) | OPC_CP2,
1075 OPC_SLT_CP2 = (29 << 21) | (0x0D) | OPC_CP2,
1077 OPC_SLL_CP2 = (24 << 21) | (0x0E) | OPC_CP2,
1078 OPC_DSLL_CP2 = (25 << 21) | (0x0E) | OPC_CP2,
1079 OPC_PEXTRH = (26 << 21) | (0x0E) | OPC_CP2,
1080 OPC_PMADDHW = (27 << 21) | (0x0E) | OPC_CP2,
1081 OPC_SLEU_CP2 = (28 << 21) | (0x0E) | OPC_CP2,
1082 OPC_SLE_CP2 = (29 << 21) | (0x0E) | OPC_CP2,
1084 OPC_SRL_CP2 = (24 << 21) | (0x0F) | OPC_CP2,
1085 OPC_DSRL_CP2 = (25 << 21) | (0x0F) | OPC_CP2,
1086 OPC_SRA_CP2 = (26 << 21) | (0x0F) | OPC_CP2,
1087 OPC_DSRA_CP2 = (27 << 21) | (0x0F) | OPC_CP2,
1088 OPC_BIADD = (28 << 21) | (0x0F) | OPC_CP2,
1089 OPC_PMOVMSKB = (29 << 21) | (0x0F) | OPC_CP2,
1093 #define MASK_CP3(op) MASK_OP_MAJOR(op) | (op & 0x3F)
1096 OPC_LWXC1 = 0x00 | OPC_CP3,
1097 OPC_LDXC1 = 0x01 | OPC_CP3,
1098 OPC_LUXC1 = 0x05 | OPC_CP3,
1099 OPC_SWXC1 = 0x08 | OPC_CP3,
1100 OPC_SDXC1 = 0x09 | OPC_CP3,
1101 OPC_SUXC1 = 0x0D | OPC_CP3,
1102 OPC_PREFX = 0x0F | OPC_CP3,
1103 OPC_ALNV_PS = 0x1E | OPC_CP3,
1104 OPC_MADD_S = 0x20 | OPC_CP3,
1105 OPC_MADD_D = 0x21 | OPC_CP3,
1106 OPC_MADD_PS = 0x26 | OPC_CP3,
1107 OPC_MSUB_S = 0x28 | OPC_CP3,
1108 OPC_MSUB_D = 0x29 | OPC_CP3,
1109 OPC_MSUB_PS = 0x2E | OPC_CP3,
1110 OPC_NMADD_S = 0x30 | OPC_CP3,
1111 OPC_NMADD_D = 0x31 | OPC_CP3,
1112 OPC_NMADD_PS= 0x36 | OPC_CP3,
1113 OPC_NMSUB_S = 0x38 | OPC_CP3,
1114 OPC_NMSUB_D = 0x39 | OPC_CP3,
1115 OPC_NMSUB_PS= 0x3E | OPC_CP3,
1119 #define MASK_MSA_MINOR(op) (MASK_OP_MAJOR(op) | (op & 0x3F))
1121 OPC_MSA_I8_00 = 0x00 | OPC_MSA,
1122 OPC_MSA_I8_01 = 0x01 | OPC_MSA,
1123 OPC_MSA_I8_02 = 0x02 | OPC_MSA,
1124 OPC_MSA_I5_06 = 0x06 | OPC_MSA,
1125 OPC_MSA_I5_07 = 0x07 | OPC_MSA,
1126 OPC_MSA_BIT_09 = 0x09 | OPC_MSA,
1127 OPC_MSA_BIT_0A = 0x0A | OPC_MSA,
1128 OPC_MSA_3R_0D = 0x0D | OPC_MSA,
1129 OPC_MSA_3R_0E = 0x0E | OPC_MSA,
1130 OPC_MSA_3R_0F = 0x0F | OPC_MSA,
1131 OPC_MSA_3R_10 = 0x10 | OPC_MSA,
1132 OPC_MSA_3R_11 = 0x11 | OPC_MSA,
1133 OPC_MSA_3R_12 = 0x12 | OPC_MSA,
1134 OPC_MSA_3R_13 = 0x13 | OPC_MSA,
1135 OPC_MSA_3R_14 = 0x14 | OPC_MSA,
1136 OPC_MSA_3R_15 = 0x15 | OPC_MSA,
1137 OPC_MSA_ELM = 0x19 | OPC_MSA,
1138 OPC_MSA_3RF_1A = 0x1A | OPC_MSA,
1139 OPC_MSA_3RF_1B = 0x1B | OPC_MSA,
1140 OPC_MSA_3RF_1C = 0x1C | OPC_MSA,
1141 OPC_MSA_VEC = 0x1E | OPC_MSA,
1143 /* MI10 instruction */
1144 OPC_LD_B = (0x20) | OPC_MSA,
1145 OPC_LD_H = (0x21) | OPC_MSA,
1146 OPC_LD_W = (0x22) | OPC_MSA,
1147 OPC_LD_D = (0x23) | OPC_MSA,
1148 OPC_ST_B = (0x24) | OPC_MSA,
1149 OPC_ST_H = (0x25) | OPC_MSA,
1150 OPC_ST_W = (0x26) | OPC_MSA,
1151 OPC_ST_D = (0x27) | OPC_MSA,
1155 /* I5 instruction df(bits 22..21) = _b, _h, _w, _d */
1156 OPC_ADDVI_df = (0x0 << 23) | OPC_MSA_I5_06,
1157 OPC_CEQI_df = (0x0 << 23) | OPC_MSA_I5_07,
1158 OPC_SUBVI_df = (0x1 << 23) | OPC_MSA_I5_06,
1159 OPC_MAXI_S_df = (0x2 << 23) | OPC_MSA_I5_06,
1160 OPC_CLTI_S_df = (0x2 << 23) | OPC_MSA_I5_07,
1161 OPC_MAXI_U_df = (0x3 << 23) | OPC_MSA_I5_06,
1162 OPC_CLTI_U_df = (0x3 << 23) | OPC_MSA_I5_07,
1163 OPC_MINI_S_df = (0x4 << 23) | OPC_MSA_I5_06,
1164 OPC_CLEI_S_df = (0x4 << 23) | OPC_MSA_I5_07,
1165 OPC_MINI_U_df = (0x5 << 23) | OPC_MSA_I5_06,
1166 OPC_CLEI_U_df = (0x5 << 23) | OPC_MSA_I5_07,
1167 OPC_LDI_df = (0x6 << 23) | OPC_MSA_I5_07,
1169 /* I8 instruction */
1170 OPC_ANDI_B = (0x0 << 24) | OPC_MSA_I8_00,
1171 OPC_BMNZI_B = (0x0 << 24) | OPC_MSA_I8_01,
1172 OPC_SHF_B = (0x0 << 24) | OPC_MSA_I8_02,
1173 OPC_ORI_B = (0x1 << 24) | OPC_MSA_I8_00,
1174 OPC_BMZI_B = (0x1 << 24) | OPC_MSA_I8_01,
1175 OPC_SHF_H = (0x1 << 24) | OPC_MSA_I8_02,
1176 OPC_NORI_B = (0x2 << 24) | OPC_MSA_I8_00,
1177 OPC_BSELI_B = (0x2 << 24) | OPC_MSA_I8_01,
1178 OPC_SHF_W = (0x2 << 24) | OPC_MSA_I8_02,
1179 OPC_XORI_B = (0x3 << 24) | OPC_MSA_I8_00,
1181 /* VEC/2R/2RF instruction */
1182 OPC_AND_V = (0x00 << 21) | OPC_MSA_VEC,
1183 OPC_OR_V = (0x01 << 21) | OPC_MSA_VEC,
1184 OPC_NOR_V = (0x02 << 21) | OPC_MSA_VEC,
1185 OPC_XOR_V = (0x03 << 21) | OPC_MSA_VEC,
1186 OPC_BMNZ_V = (0x04 << 21) | OPC_MSA_VEC,
1187 OPC_BMZ_V = (0x05 << 21) | OPC_MSA_VEC,
1188 OPC_BSEL_V = (0x06 << 21) | OPC_MSA_VEC,
1190 OPC_MSA_2R = (0x18 << 21) | OPC_MSA_VEC,
1191 OPC_MSA_2RF = (0x19 << 21) | OPC_MSA_VEC,
1193 /* 2R instruction df(bits 17..16) = _b, _h, _w, _d */
1194 OPC_FILL_df = (0x00 << 18) | OPC_MSA_2R,
1195 OPC_PCNT_df = (0x01 << 18) | OPC_MSA_2R,
1196 OPC_NLOC_df = (0x02 << 18) | OPC_MSA_2R,
1197 OPC_NLZC_df = (0x03 << 18) | OPC_MSA_2R,
1199 /* 2RF instruction df(bit 16) = _w, _d */
1200 OPC_FCLASS_df = (0x00 << 17) | OPC_MSA_2RF,
1201 OPC_FTRUNC_S_df = (0x01 << 17) | OPC_MSA_2RF,
1202 OPC_FTRUNC_U_df = (0x02 << 17) | OPC_MSA_2RF,
1203 OPC_FSQRT_df = (0x03 << 17) | OPC_MSA_2RF,
1204 OPC_FRSQRT_df = (0x04 << 17) | OPC_MSA_2RF,
1205 OPC_FRCP_df = (0x05 << 17) | OPC_MSA_2RF,
1206 OPC_FRINT_df = (0x06 << 17) | OPC_MSA_2RF,
1207 OPC_FLOG2_df = (0x07 << 17) | OPC_MSA_2RF,
1208 OPC_FEXUPL_df = (0x08 << 17) | OPC_MSA_2RF,
1209 OPC_FEXUPR_df = (0x09 << 17) | OPC_MSA_2RF,
1210 OPC_FFQL_df = (0x0A << 17) | OPC_MSA_2RF,
1211 OPC_FFQR_df = (0x0B << 17) | OPC_MSA_2RF,
1212 OPC_FTINT_S_df = (0x0C << 17) | OPC_MSA_2RF,
1213 OPC_FTINT_U_df = (0x0D << 17) | OPC_MSA_2RF,
1214 OPC_FFINT_S_df = (0x0E << 17) | OPC_MSA_2RF,
1215 OPC_FFINT_U_df = (0x0F << 17) | OPC_MSA_2RF,
1217 /* 3R instruction df(bits 22..21) = _b, _h, _w, d */
1218 OPC_SLL_df = (0x0 << 23) | OPC_MSA_3R_0D,
1219 OPC_ADDV_df = (0x0 << 23) | OPC_MSA_3R_0E,
1220 OPC_CEQ_df = (0x0 << 23) | OPC_MSA_3R_0F,
1221 OPC_ADD_A_df = (0x0 << 23) | OPC_MSA_3R_10,
1222 OPC_SUBS_S_df = (0x0 << 23) | OPC_MSA_3R_11,
1223 OPC_MULV_df = (0x0 << 23) | OPC_MSA_3R_12,
1224 OPC_DOTP_S_df = (0x0 << 23) | OPC_MSA_3R_13,
1225 OPC_SLD_df = (0x0 << 23) | OPC_MSA_3R_14,
1226 OPC_VSHF_df = (0x0 << 23) | OPC_MSA_3R_15,
1227 OPC_SRA_df = (0x1 << 23) | OPC_MSA_3R_0D,
1228 OPC_SUBV_df = (0x1 << 23) | OPC_MSA_3R_0E,
1229 OPC_ADDS_A_df = (0x1 << 23) | OPC_MSA_3R_10,
1230 OPC_SUBS_U_df = (0x1 << 23) | OPC_MSA_3R_11,
1231 OPC_MADDV_df = (0x1 << 23) | OPC_MSA_3R_12,
1232 OPC_DOTP_U_df = (0x1 << 23) | OPC_MSA_3R_13,
1233 OPC_SPLAT_df = (0x1 << 23) | OPC_MSA_3R_14,
1234 OPC_SRAR_df = (0x1 << 23) | OPC_MSA_3R_15,
1235 OPC_SRL_df = (0x2 << 23) | OPC_MSA_3R_0D,
1236 OPC_MAX_S_df = (0x2 << 23) | OPC_MSA_3R_0E,
1237 OPC_CLT_S_df = (0x2 << 23) | OPC_MSA_3R_0F,
1238 OPC_ADDS_S_df = (0x2 << 23) | OPC_MSA_3R_10,
1239 OPC_SUBSUS_U_df = (0x2 << 23) | OPC_MSA_3R_11,
1240 OPC_MSUBV_df = (0x2 << 23) | OPC_MSA_3R_12,
1241 OPC_DPADD_S_df = (0x2 << 23) | OPC_MSA_3R_13,
1242 OPC_PCKEV_df = (0x2 << 23) | OPC_MSA_3R_14,
1243 OPC_SRLR_df = (0x2 << 23) | OPC_MSA_3R_15,
1244 OPC_BCLR_df = (0x3 << 23) | OPC_MSA_3R_0D,
1245 OPC_MAX_U_df = (0x3 << 23) | OPC_MSA_3R_0E,
1246 OPC_CLT_U_df = (0x3 << 23) | OPC_MSA_3R_0F,
1247 OPC_ADDS_U_df = (0x3 << 23) | OPC_MSA_3R_10,
1248 OPC_SUBSUU_S_df = (0x3 << 23) | OPC_MSA_3R_11,
1249 OPC_DPADD_U_df = (0x3 << 23) | OPC_MSA_3R_13,
1250 OPC_PCKOD_df = (0x3 << 23) | OPC_MSA_3R_14,
1251 OPC_BSET_df = (0x4 << 23) | OPC_MSA_3R_0D,
1252 OPC_MIN_S_df = (0x4 << 23) | OPC_MSA_3R_0E,
1253 OPC_CLE_S_df = (0x4 << 23) | OPC_MSA_3R_0F,
1254 OPC_AVE_S_df = (0x4 << 23) | OPC_MSA_3R_10,
1255 OPC_ASUB_S_df = (0x4 << 23) | OPC_MSA_3R_11,
1256 OPC_DIV_S_df = (0x4 << 23) | OPC_MSA_3R_12,
1257 OPC_DPSUB_S_df = (0x4 << 23) | OPC_MSA_3R_13,
1258 OPC_ILVL_df = (0x4 << 23) | OPC_MSA_3R_14,
1259 OPC_HADD_S_df = (0x4 << 23) | OPC_MSA_3R_15,
1260 OPC_BNEG_df = (0x5 << 23) | OPC_MSA_3R_0D,
1261 OPC_MIN_U_df = (0x5 << 23) | OPC_MSA_3R_0E,
1262 OPC_CLE_U_df = (0x5 << 23) | OPC_MSA_3R_0F,
1263 OPC_AVE_U_df = (0x5 << 23) | OPC_MSA_3R_10,
1264 OPC_ASUB_U_df = (0x5 << 23) | OPC_MSA_3R_11,
1265 OPC_DIV_U_df = (0x5 << 23) | OPC_MSA_3R_12,
1266 OPC_DPSUB_U_df = (0x5 << 23) | OPC_MSA_3R_13,
1267 OPC_ILVR_df = (0x5 << 23) | OPC_MSA_3R_14,
1268 OPC_HADD_U_df = (0x5 << 23) | OPC_MSA_3R_15,
1269 OPC_BINSL_df = (0x6 << 23) | OPC_MSA_3R_0D,
1270 OPC_MAX_A_df = (0x6 << 23) | OPC_MSA_3R_0E,
1271 OPC_AVER_S_df = (0x6 << 23) | OPC_MSA_3R_10,
1272 OPC_MOD_S_df = (0x6 << 23) | OPC_MSA_3R_12,
1273 OPC_ILVEV_df = (0x6 << 23) | OPC_MSA_3R_14,
1274 OPC_HSUB_S_df = (0x6 << 23) | OPC_MSA_3R_15,
1275 OPC_BINSR_df = (0x7 << 23) | OPC_MSA_3R_0D,
1276 OPC_MIN_A_df = (0x7 << 23) | OPC_MSA_3R_0E,
1277 OPC_AVER_U_df = (0x7 << 23) | OPC_MSA_3R_10,
1278 OPC_MOD_U_df = (0x7 << 23) | OPC_MSA_3R_12,
1279 OPC_ILVOD_df = (0x7 << 23) | OPC_MSA_3R_14,
1280 OPC_HSUB_U_df = (0x7 << 23) | OPC_MSA_3R_15,
1282 /* ELM instructions df(bits 21..16) = _b, _h, _w, _d */
1283 OPC_SLDI_df = (0x0 << 22) | (0x00 << 16) | OPC_MSA_ELM,
1284 OPC_CTCMSA = (0x0 << 22) | (0x3E << 16) | OPC_MSA_ELM,
1285 OPC_SPLATI_df = (0x1 << 22) | (0x00 << 16) | OPC_MSA_ELM,
1286 OPC_CFCMSA = (0x1 << 22) | (0x3E << 16) | OPC_MSA_ELM,
1287 OPC_COPY_S_df = (0x2 << 22) | (0x00 << 16) | OPC_MSA_ELM,
1288 OPC_MOVE_V = (0x2 << 22) | (0x3E << 16) | OPC_MSA_ELM,
1289 OPC_COPY_U_df = (0x3 << 22) | (0x00 << 16) | OPC_MSA_ELM,
1290 OPC_INSERT_df = (0x4 << 22) | (0x00 << 16) | OPC_MSA_ELM,
1291 OPC_INSVE_df = (0x5 << 22) | (0x00 << 16) | OPC_MSA_ELM,
1293 /* 3RF instruction _df(bit 21) = _w, _d */
1294 OPC_FCAF_df = (0x0 << 22) | OPC_MSA_3RF_1A,
1295 OPC_FADD_df = (0x0 << 22) | OPC_MSA_3RF_1B,
1296 OPC_FCUN_df = (0x1 << 22) | OPC_MSA_3RF_1A,
1297 OPC_FSUB_df = (0x1 << 22) | OPC_MSA_3RF_1B,
1298 OPC_FCOR_df = (0x1 << 22) | OPC_MSA_3RF_1C,
1299 OPC_FCEQ_df = (0x2 << 22) | OPC_MSA_3RF_1A,
1300 OPC_FMUL_df = (0x2 << 22) | OPC_MSA_3RF_1B,
1301 OPC_FCUNE_df = (0x2 << 22) | OPC_MSA_3RF_1C,
1302 OPC_FCUEQ_df = (0x3 << 22) | OPC_MSA_3RF_1A,
1303 OPC_FDIV_df = (0x3 << 22) | OPC_MSA_3RF_1B,
1304 OPC_FCNE_df = (0x3 << 22) | OPC_MSA_3RF_1C,
1305 OPC_FCLT_df = (0x4 << 22) | OPC_MSA_3RF_1A,
1306 OPC_FMADD_df = (0x4 << 22) | OPC_MSA_3RF_1B,
1307 OPC_MUL_Q_df = (0x4 << 22) | OPC_MSA_3RF_1C,
1308 OPC_FCULT_df = (0x5 << 22) | OPC_MSA_3RF_1A,
1309 OPC_FMSUB_df = (0x5 << 22) | OPC_MSA_3RF_1B,
1310 OPC_MADD_Q_df = (0x5 << 22) | OPC_MSA_3RF_1C,
1311 OPC_FCLE_df = (0x6 << 22) | OPC_MSA_3RF_1A,
1312 OPC_MSUB_Q_df = (0x6 << 22) | OPC_MSA_3RF_1C,
1313 OPC_FCULE_df = (0x7 << 22) | OPC_MSA_3RF_1A,
1314 OPC_FEXP2_df = (0x7 << 22) | OPC_MSA_3RF_1B,
1315 OPC_FSAF_df = (0x8 << 22) | OPC_MSA_3RF_1A,
1316 OPC_FEXDO_df = (0x8 << 22) | OPC_MSA_3RF_1B,
1317 OPC_FSUN_df = (0x9 << 22) | OPC_MSA_3RF_1A,
1318 OPC_FSOR_df = (0x9 << 22) | OPC_MSA_3RF_1C,
1319 OPC_FSEQ_df = (0xA << 22) | OPC_MSA_3RF_1A,
1320 OPC_FTQ_df = (0xA << 22) | OPC_MSA_3RF_1B,
1321 OPC_FSUNE_df = (0xA << 22) | OPC_MSA_3RF_1C,
1322 OPC_FSUEQ_df = (0xB << 22) | OPC_MSA_3RF_1A,
1323 OPC_FSNE_df = (0xB << 22) | OPC_MSA_3RF_1C,
1324 OPC_FSLT_df = (0xC << 22) | OPC_MSA_3RF_1A,
1325 OPC_FMIN_df = (0xC << 22) | OPC_MSA_3RF_1B,
1326 OPC_MULR_Q_df = (0xC << 22) | OPC_MSA_3RF_1C,
1327 OPC_FSULT_df = (0xD << 22) | OPC_MSA_3RF_1A,
1328 OPC_FMIN_A_df = (0xD << 22) | OPC_MSA_3RF_1B,
1329 OPC_MADDR_Q_df = (0xD << 22) | OPC_MSA_3RF_1C,
1330 OPC_FSLE_df = (0xE << 22) | OPC_MSA_3RF_1A,
1331 OPC_FMAX_df = (0xE << 22) | OPC_MSA_3RF_1B,
1332 OPC_MSUBR_Q_df = (0xE << 22) | OPC_MSA_3RF_1C,
1333 OPC_FSULE_df = (0xF << 22) | OPC_MSA_3RF_1A,
1334 OPC_FMAX_A_df = (0xF << 22) | OPC_MSA_3RF_1B,
1336 /* BIT instruction df(bits 22..16) = _B _H _W _D */
1337 OPC_SLLI_df = (0x0 << 23) | OPC_MSA_BIT_09,
1338 OPC_SAT_S_df = (0x0 << 23) | OPC_MSA_BIT_0A,
1339 OPC_SRAI_df = (0x1 << 23) | OPC_MSA_BIT_09,
1340 OPC_SAT_U_df = (0x1 << 23) | OPC_MSA_BIT_0A,
1341 OPC_SRLI_df = (0x2 << 23) | OPC_MSA_BIT_09,
1342 OPC_SRARI_df = (0x2 << 23) | OPC_MSA_BIT_0A,
1343 OPC_BCLRI_df = (0x3 << 23) | OPC_MSA_BIT_09,
1344 OPC_SRLRI_df = (0x3 << 23) | OPC_MSA_BIT_0A,
1345 OPC_BSETI_df = (0x4 << 23) | OPC_MSA_BIT_09,
1346 OPC_BNEGI_df = (0x5 << 23) | OPC_MSA_BIT_09,
1347 OPC_BINSLI_df = (0x6 << 23) | OPC_MSA_BIT_09,
1348 OPC_BINSRI_df = (0x7 << 23) | OPC_MSA_BIT_09,
1351 /* global register indices */
1352 static TCGv_ptr cpu_env;
1353 static TCGv cpu_gpr[32], cpu_PC;
1354 static TCGv cpu_HI[MIPS_DSP_ACC], cpu_LO[MIPS_DSP_ACC];
1355 static TCGv cpu_dspctrl, btarget, bcond;
1356 static TCGv_i32 hflags;
1357 static TCGv_i32 fpu_fcr0, fpu_fcr31;
1358 static TCGv_i64 fpu_f64[32];
1359 static TCGv_i64 msa_wr_d[64];
1361 static uint32_t gen_opc_hflags[OPC_BUF_SIZE];
1362 static target_ulong gen_opc_btarget[OPC_BUF_SIZE];
1364 #include "exec/gen-icount.h"
1366 #define gen_helper_0e0i(name, arg) do { \
1367 TCGv_i32 helper_tmp = tcg_const_i32(arg); \
1368 gen_helper_##name(cpu_env, helper_tmp); \
1369 tcg_temp_free_i32(helper_tmp); \
1372 #define gen_helper_0e1i(name, arg1, arg2) do { \
1373 TCGv_i32 helper_tmp = tcg_const_i32(arg2); \
1374 gen_helper_##name(cpu_env, arg1, helper_tmp); \
1375 tcg_temp_free_i32(helper_tmp); \
1378 #define gen_helper_1e0i(name, ret, arg1) do { \
1379 TCGv_i32 helper_tmp = tcg_const_i32(arg1); \
1380 gen_helper_##name(ret, cpu_env, helper_tmp); \
1381 tcg_temp_free_i32(helper_tmp); \
1384 #define gen_helper_1e1i(name, ret, arg1, arg2) do { \
1385 TCGv_i32 helper_tmp = tcg_const_i32(arg2); \
1386 gen_helper_##name(ret, cpu_env, arg1, helper_tmp); \
1387 tcg_temp_free_i32(helper_tmp); \
1390 #define gen_helper_0e2i(name, arg1, arg2, arg3) do { \
1391 TCGv_i32 helper_tmp = tcg_const_i32(arg3); \
1392 gen_helper_##name(cpu_env, arg1, arg2, helper_tmp); \
1393 tcg_temp_free_i32(helper_tmp); \
1396 #define gen_helper_1e2i(name, ret, arg1, arg2, arg3) do { \
1397 TCGv_i32 helper_tmp = tcg_const_i32(arg3); \
1398 gen_helper_##name(ret, cpu_env, arg1, arg2, helper_tmp); \
1399 tcg_temp_free_i32(helper_tmp); \
1402 #define gen_helper_0e3i(name, arg1, arg2, arg3, arg4) do { \
1403 TCGv_i32 helper_tmp = tcg_const_i32(arg4); \
1404 gen_helper_##name(cpu_env, arg1, arg2, arg3, helper_tmp); \
1405 tcg_temp_free_i32(helper_tmp); \
1408 typedef struct DisasContext {
1409 struct TranslationBlock *tb;
1410 target_ulong pc, saved_pc;
1412 int singlestep_enabled;
1414 int32_t CP0_Config1;
1415 /* Routine used to access memory */
1417 TCGMemOp default_tcg_memop_mask;
1418 uint32_t hflags, saved_hflags;
1420 target_ulong btarget;
1430 BS_NONE = 0, /* We go out of the TB without reaching a branch or an
1431 * exception condition */
1432 BS_STOP = 1, /* We want to stop translation for any reason */
1433 BS_BRANCH = 2, /* We reached a branch condition */
1434 BS_EXCP = 3, /* We reached an exception condition */
1437 static const char * const regnames[] = {
1438 "r0", "at", "v0", "v1", "a0", "a1", "a2", "a3",
1439 "t0", "t1", "t2", "t3", "t4", "t5", "t6", "t7",
1440 "s0", "s1", "s2", "s3", "s4", "s5", "s6", "s7",
1441 "t8", "t9", "k0", "k1", "gp", "sp", "s8", "ra",
1444 static const char * const regnames_HI[] = {
1445 "HI0", "HI1", "HI2", "HI3",
1448 static const char * const regnames_LO[] = {
1449 "LO0", "LO1", "LO2", "LO3",
1452 static const char * const fregnames[] = {
1453 "f0", "f1", "f2", "f3", "f4", "f5", "f6", "f7",
1454 "f8", "f9", "f10", "f11", "f12", "f13", "f14", "f15",
1455 "f16", "f17", "f18", "f19", "f20", "f21", "f22", "f23",
1456 "f24", "f25", "f26", "f27", "f28", "f29", "f30", "f31",
1459 static const char * const msaregnames[] = {
1460 "w0.d0", "w0.d1", "w1.d0", "w1.d1",
1461 "w2.d0", "w2.d1", "w3.d0", "w3.d1",
1462 "w4.d0", "w4.d1", "w5.d0", "w5.d1",
1463 "w6.d0", "w6.d1", "w7.d0", "w7.d1",
1464 "w8.d0", "w8.d1", "w9.d0", "w9.d1",
1465 "w10.d0", "w10.d1", "w11.d0", "w11.d1",
1466 "w12.d0", "w12.d1", "w13.d0", "w13.d1",
1467 "w14.d0", "w14.d1", "w15.d0", "w15.d1",
1468 "w16.d0", "w16.d1", "w17.d0", "w17.d1",
1469 "w18.d0", "w18.d1", "w19.d0", "w19.d1",
1470 "w20.d0", "w20.d1", "w21.d0", "w21.d1",
1471 "w22.d0", "w22.d1", "w23.d0", "w23.d1",
1472 "w24.d0", "w24.d1", "w25.d0", "w25.d1",
1473 "w26.d0", "w26.d1", "w27.d0", "w27.d1",
1474 "w28.d0", "w28.d1", "w29.d0", "w29.d1",
1475 "w30.d0", "w30.d1", "w31.d0", "w31.d1",
1478 #define MIPS_DEBUG(fmt, ...) \
1480 if (MIPS_DEBUG_DISAS) { \
1481 qemu_log_mask(CPU_LOG_TB_IN_ASM, \
1482 TARGET_FMT_lx ": %08x " fmt "\n", \
1483 ctx->pc, ctx->opcode , ## __VA_ARGS__); \
1487 #define LOG_DISAS(...) \
1489 if (MIPS_DEBUG_DISAS) { \
1490 qemu_log_mask(CPU_LOG_TB_IN_ASM, ## __VA_ARGS__); \
1494 #define MIPS_INVAL(op) \
1495 MIPS_DEBUG("Invalid %s %03x %03x %03x", op, ctx->opcode >> 26, \
1496 ctx->opcode & 0x3F, ((ctx->opcode >> 16) & 0x1F))
1498 /* General purpose registers moves. */
1499 static inline void gen_load_gpr (TCGv t, int reg)
1502 tcg_gen_movi_tl(t, 0);
1504 tcg_gen_mov_tl(t, cpu_gpr[reg]);
1507 static inline void gen_store_gpr (TCGv t, int reg)
1510 tcg_gen_mov_tl(cpu_gpr[reg], t);
1513 /* Moves to/from shadow registers. */
1514 static inline void gen_load_srsgpr (int from, int to)
1516 TCGv t0 = tcg_temp_new();
1519 tcg_gen_movi_tl(t0, 0);
1521 TCGv_i32 t2 = tcg_temp_new_i32();
1522 TCGv_ptr addr = tcg_temp_new_ptr();
1524 tcg_gen_ld_i32(t2, cpu_env, offsetof(CPUMIPSState, CP0_SRSCtl));
1525 tcg_gen_shri_i32(t2, t2, CP0SRSCtl_PSS);
1526 tcg_gen_andi_i32(t2, t2, 0xf);
1527 tcg_gen_muli_i32(t2, t2, sizeof(target_ulong) * 32);
1528 tcg_gen_ext_i32_ptr(addr, t2);
1529 tcg_gen_add_ptr(addr, cpu_env, addr);
1531 tcg_gen_ld_tl(t0, addr, sizeof(target_ulong) * from);
1532 tcg_temp_free_ptr(addr);
1533 tcg_temp_free_i32(t2);
1535 gen_store_gpr(t0, to);
1539 static inline void gen_store_srsgpr (int from, int to)
1542 TCGv t0 = tcg_temp_new();
1543 TCGv_i32 t2 = tcg_temp_new_i32();
1544 TCGv_ptr addr = tcg_temp_new_ptr();
1546 gen_load_gpr(t0, from);
1547 tcg_gen_ld_i32(t2, cpu_env, offsetof(CPUMIPSState, CP0_SRSCtl));
1548 tcg_gen_shri_i32(t2, t2, CP0SRSCtl_PSS);
1549 tcg_gen_andi_i32(t2, t2, 0xf);
1550 tcg_gen_muli_i32(t2, t2, sizeof(target_ulong) * 32);
1551 tcg_gen_ext_i32_ptr(addr, t2);
1552 tcg_gen_add_ptr(addr, cpu_env, addr);
1554 tcg_gen_st_tl(t0, addr, sizeof(target_ulong) * to);
1555 tcg_temp_free_ptr(addr);
1556 tcg_temp_free_i32(t2);
1562 static inline void gen_save_pc(target_ulong pc)
1564 tcg_gen_movi_tl(cpu_PC, pc);
1567 static inline void save_cpu_state(DisasContext *ctx, int do_save_pc)
1569 LOG_DISAS("hflags %08x saved %08x\n", ctx->hflags, ctx->saved_hflags);
1570 if (do_save_pc && ctx->pc != ctx->saved_pc) {
1571 gen_save_pc(ctx->pc);
1572 ctx->saved_pc = ctx->pc;
1574 if (ctx->hflags != ctx->saved_hflags) {
1575 tcg_gen_movi_i32(hflags, ctx->hflags);
1576 ctx->saved_hflags = ctx->hflags;
1577 switch (ctx->hflags & MIPS_HFLAG_BMASK_BASE) {
1583 tcg_gen_movi_tl(btarget, ctx->btarget);
1589 static inline void restore_cpu_state(CPUMIPSState *env, DisasContext *ctx)
1591 ctx->saved_hflags = ctx->hflags;
1592 switch (ctx->hflags & MIPS_HFLAG_BMASK_BASE) {
1598 ctx->btarget = env->btarget;
1603 static inline void generate_exception_err(DisasContext *ctx, int excp, int err)
1605 TCGv_i32 texcp = tcg_const_i32(excp);
1606 TCGv_i32 terr = tcg_const_i32(err);
1607 save_cpu_state(ctx, 1);
1608 gen_helper_raise_exception_err(cpu_env, texcp, terr);
1609 tcg_temp_free_i32(terr);
1610 tcg_temp_free_i32(texcp);
1613 static inline void generate_exception(DisasContext *ctx, int excp)
1615 save_cpu_state(ctx, 1);
1616 gen_helper_0e0i(raise_exception, excp);
1619 /* Floating point register moves. */
1620 static void gen_load_fpr32(DisasContext *ctx, TCGv_i32 t, int reg)
1622 if (ctx->hflags & MIPS_HFLAG_FRE) {
1623 generate_exception(ctx, EXCP_RI);
1625 tcg_gen_trunc_i64_i32(t, fpu_f64[reg]);
1628 static void gen_store_fpr32(DisasContext *ctx, TCGv_i32 t, int reg)
1631 if (ctx->hflags & MIPS_HFLAG_FRE) {
1632 generate_exception(ctx, EXCP_RI);
1634 t64 = tcg_temp_new_i64();
1635 tcg_gen_extu_i32_i64(t64, t);
1636 tcg_gen_deposit_i64(fpu_f64[reg], fpu_f64[reg], t64, 0, 32);
1637 tcg_temp_free_i64(t64);
1640 static void gen_load_fpr32h(DisasContext *ctx, TCGv_i32 t, int reg)
1642 if (ctx->hflags & MIPS_HFLAG_F64) {
1643 TCGv_i64 t64 = tcg_temp_new_i64();
1644 tcg_gen_shri_i64(t64, fpu_f64[reg], 32);
1645 tcg_gen_trunc_i64_i32(t, t64);
1646 tcg_temp_free_i64(t64);
1648 gen_load_fpr32(ctx, t, reg | 1);
1652 static void gen_store_fpr32h(DisasContext *ctx, TCGv_i32 t, int reg)
1654 if (ctx->hflags & MIPS_HFLAG_F64) {
1655 TCGv_i64 t64 = tcg_temp_new_i64();
1656 tcg_gen_extu_i32_i64(t64, t);
1657 tcg_gen_deposit_i64(fpu_f64[reg], fpu_f64[reg], t64, 32, 32);
1658 tcg_temp_free_i64(t64);
1660 gen_store_fpr32(ctx, t, reg | 1);
1664 static void gen_load_fpr64(DisasContext *ctx, TCGv_i64 t, int reg)
1666 if (ctx->hflags & MIPS_HFLAG_F64) {
1667 tcg_gen_mov_i64(t, fpu_f64[reg]);
1669 tcg_gen_concat32_i64(t, fpu_f64[reg & ~1], fpu_f64[reg | 1]);
1673 static void gen_store_fpr64(DisasContext *ctx, TCGv_i64 t, int reg)
1675 if (ctx->hflags & MIPS_HFLAG_F64) {
1676 tcg_gen_mov_i64(fpu_f64[reg], t);
1679 tcg_gen_deposit_i64(fpu_f64[reg & ~1], fpu_f64[reg & ~1], t, 0, 32);
1680 t0 = tcg_temp_new_i64();
1681 tcg_gen_shri_i64(t0, t, 32);
1682 tcg_gen_deposit_i64(fpu_f64[reg | 1], fpu_f64[reg | 1], t0, 0, 32);
1683 tcg_temp_free_i64(t0);
1687 static inline int get_fp_bit (int cc)
1695 /* Addresses computation */
1696 static inline void gen_op_addr_add (DisasContext *ctx, TCGv ret, TCGv arg0, TCGv arg1)
1698 tcg_gen_add_tl(ret, arg0, arg1);
1700 #if defined(TARGET_MIPS64)
1701 if (ctx->hflags & MIPS_HFLAG_AWRAP) {
1702 tcg_gen_ext32s_i64(ret, ret);
1707 /* Addresses computation (translation time) */
1708 static target_long addr_add(DisasContext *ctx, target_long base,
1711 target_long sum = base + offset;
1713 #if defined(TARGET_MIPS64)
1714 if (ctx->hflags & MIPS_HFLAG_AWRAP) {
1721 static inline void check_cp0_enabled(DisasContext *ctx)
1723 if (unlikely(!(ctx->hflags & MIPS_HFLAG_CP0)))
1724 generate_exception_err(ctx, EXCP_CpU, 0);
1727 static inline void check_cp1_enabled(DisasContext *ctx)
1729 if (unlikely(!(ctx->hflags & MIPS_HFLAG_FPU)))
1730 generate_exception_err(ctx, EXCP_CpU, 1);
1733 /* Verify that the processor is running with COP1X instructions enabled.
1734 This is associated with the nabla symbol in the MIPS32 and MIPS64
1737 static inline void check_cop1x(DisasContext *ctx)
1739 if (unlikely(!(ctx->hflags & MIPS_HFLAG_COP1X)))
1740 generate_exception(ctx, EXCP_RI);
1743 /* Verify that the processor is running with 64-bit floating-point
1744 operations enabled. */
1746 static inline void check_cp1_64bitmode(DisasContext *ctx)
1748 if (unlikely(~ctx->hflags & (MIPS_HFLAG_F64 | MIPS_HFLAG_COP1X)))
1749 generate_exception(ctx, EXCP_RI);
1753 * Verify if floating point register is valid; an operation is not defined
1754 * if bit 0 of any register specification is set and the FR bit in the
1755 * Status register equals zero, since the register numbers specify an
1756 * even-odd pair of adjacent coprocessor general registers. When the FR bit
1757 * in the Status register equals one, both even and odd register numbers
1758 * are valid. This limitation exists only for 64 bit wide (d,l,ps) registers.
1760 * Multiple 64 bit wide registers can be checked by calling
1761 * gen_op_cp1_registers(freg1 | freg2 | ... | fregN);
1763 static inline void check_cp1_registers(DisasContext *ctx, int regs)
1765 if (unlikely(!(ctx->hflags & MIPS_HFLAG_F64) && (regs & 1)))
1766 generate_exception(ctx, EXCP_RI);
1769 /* Verify that the processor is running with DSP instructions enabled.
1770 This is enabled by CP0 Status register MX(24) bit.
1773 static inline void check_dsp(DisasContext *ctx)
1775 if (unlikely(!(ctx->hflags & MIPS_HFLAG_DSP))) {
1776 if (ctx->insn_flags & ASE_DSP) {
1777 generate_exception(ctx, EXCP_DSPDIS);
1779 generate_exception(ctx, EXCP_RI);
1784 static inline void check_dspr2(DisasContext *ctx)
1786 if (unlikely(!(ctx->hflags & MIPS_HFLAG_DSPR2))) {
1787 if (ctx->insn_flags & ASE_DSP) {
1788 generate_exception(ctx, EXCP_DSPDIS);
1790 generate_exception(ctx, EXCP_RI);
1795 /* This code generates a "reserved instruction" exception if the
1796 CPU does not support the instruction set corresponding to flags. */
1797 static inline void check_insn(DisasContext *ctx, int flags)
1799 if (unlikely(!(ctx->insn_flags & flags))) {
1800 generate_exception(ctx, EXCP_RI);
1804 /* This code generates a "reserved instruction" exception if the
1805 CPU has corresponding flag set which indicates that the instruction
1806 has been removed. */
1807 static inline void check_insn_opc_removed(DisasContext *ctx, int flags)
1809 if (unlikely(ctx->insn_flags & flags)) {
1810 generate_exception(ctx, EXCP_RI);
1814 #ifdef TARGET_MIPS64
1815 /* This code generates a "reserved instruction" exception if 64-bit
1816 instructions are not enabled. */
1817 static inline void check_mips_64(DisasContext *ctx)
1819 if (unlikely(!(ctx->hflags & MIPS_HFLAG_64)))
1820 generate_exception(ctx, EXCP_RI);
1824 /* Define small wrappers for gen_load_fpr* so that we have a uniform
1825 calling interface for 32 and 64-bit FPRs. No sense in changing
1826 all callers for gen_load_fpr32 when we need the CTX parameter for
1828 #define gen_ldcmp_fpr32(ctx, x, y) gen_load_fpr32(ctx, x, y)
1829 #define gen_ldcmp_fpr64(ctx, x, y) gen_load_fpr64(ctx, x, y)
1830 #define FOP_CONDS(type, abs, fmt, ifmt, bits) \
1831 static inline void gen_cmp ## type ## _ ## fmt(DisasContext *ctx, int n, \
1832 int ft, int fs, int cc) \
1834 TCGv_i##bits fp0 = tcg_temp_new_i##bits (); \
1835 TCGv_i##bits fp1 = tcg_temp_new_i##bits (); \
1838 check_cp1_64bitmode(ctx); \
1844 check_cp1_registers(ctx, fs | ft); \
1852 gen_ldcmp_fpr##bits (ctx, fp0, fs); \
1853 gen_ldcmp_fpr##bits (ctx, fp1, ft); \
1855 case 0: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _f, fp0, fp1, cc); break;\
1856 case 1: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _un, fp0, fp1, cc); break;\
1857 case 2: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _eq, fp0, fp1, cc); break;\
1858 case 3: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ueq, fp0, fp1, cc); break;\
1859 case 4: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _olt, fp0, fp1, cc); break;\
1860 case 5: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ult, fp0, fp1, cc); break;\
1861 case 6: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ole, fp0, fp1, cc); break;\
1862 case 7: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ule, fp0, fp1, cc); break;\
1863 case 8: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _sf, fp0, fp1, cc); break;\
1864 case 9: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ngle, fp0, fp1, cc); break;\
1865 case 10: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _seq, fp0, fp1, cc); break;\
1866 case 11: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ngl, fp0, fp1, cc); break;\
1867 case 12: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _lt, fp0, fp1, cc); break;\
1868 case 13: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _nge, fp0, fp1, cc); break;\
1869 case 14: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _le, fp0, fp1, cc); break;\
1870 case 15: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ngt, fp0, fp1, cc); break;\
1873 tcg_temp_free_i##bits (fp0); \
1874 tcg_temp_free_i##bits (fp1); \
1877 FOP_CONDS(, 0, d, FMT_D, 64)
1878 FOP_CONDS(abs, 1, d, FMT_D, 64)
1879 FOP_CONDS(, 0, s, FMT_S, 32)
1880 FOP_CONDS(abs, 1, s, FMT_S, 32)
1881 FOP_CONDS(, 0, ps, FMT_PS, 64)
1882 FOP_CONDS(abs, 1, ps, FMT_PS, 64)
1885 #define FOP_CONDNS(fmt, ifmt, bits, STORE) \
1886 static inline void gen_r6_cmp_ ## fmt(DisasContext * ctx, int n, \
1887 int ft, int fs, int fd) \
1889 TCGv_i ## bits fp0 = tcg_temp_new_i ## bits(); \
1890 TCGv_i ## bits fp1 = tcg_temp_new_i ## bits(); \
1891 if (ifmt == FMT_D) { \
1892 check_cp1_registers(ctx, fs | ft | fd); \
1894 gen_ldcmp_fpr ## bits(ctx, fp0, fs); \
1895 gen_ldcmp_fpr ## bits(ctx, fp1, ft); \
1898 gen_helper_r6_cmp_ ## fmt ## _af(fp0, cpu_env, fp0, fp1); \
1901 gen_helper_r6_cmp_ ## fmt ## _un(fp0, cpu_env, fp0, fp1); \
1904 gen_helper_r6_cmp_ ## fmt ## _eq(fp0, cpu_env, fp0, fp1); \
1907 gen_helper_r6_cmp_ ## fmt ## _ueq(fp0, cpu_env, fp0, fp1); \
1910 gen_helper_r6_cmp_ ## fmt ## _lt(fp0, cpu_env, fp0, fp1); \
1913 gen_helper_r6_cmp_ ## fmt ## _ult(fp0, cpu_env, fp0, fp1); \
1916 gen_helper_r6_cmp_ ## fmt ## _le(fp0, cpu_env, fp0, fp1); \
1919 gen_helper_r6_cmp_ ## fmt ## _ule(fp0, cpu_env, fp0, fp1); \
1922 gen_helper_r6_cmp_ ## fmt ## _saf(fp0, cpu_env, fp0, fp1); \
1925 gen_helper_r6_cmp_ ## fmt ## _sun(fp0, cpu_env, fp0, fp1); \
1928 gen_helper_r6_cmp_ ## fmt ## _seq(fp0, cpu_env, fp0, fp1); \
1931 gen_helper_r6_cmp_ ## fmt ## _sueq(fp0, cpu_env, fp0, fp1); \
1934 gen_helper_r6_cmp_ ## fmt ## _slt(fp0, cpu_env, fp0, fp1); \
1937 gen_helper_r6_cmp_ ## fmt ## _sult(fp0, cpu_env, fp0, fp1); \
1940 gen_helper_r6_cmp_ ## fmt ## _sle(fp0, cpu_env, fp0, fp1); \
1943 gen_helper_r6_cmp_ ## fmt ## _sule(fp0, cpu_env, fp0, fp1); \
1946 gen_helper_r6_cmp_ ## fmt ## _or(fp0, cpu_env, fp0, fp1); \
1949 gen_helper_r6_cmp_ ## fmt ## _une(fp0, cpu_env, fp0, fp1); \
1952 gen_helper_r6_cmp_ ## fmt ## _ne(fp0, cpu_env, fp0, fp1); \
1955 gen_helper_r6_cmp_ ## fmt ## _sor(fp0, cpu_env, fp0, fp1); \
1958 gen_helper_r6_cmp_ ## fmt ## _sune(fp0, cpu_env, fp0, fp1); \
1961 gen_helper_r6_cmp_ ## fmt ## _sne(fp0, cpu_env, fp0, fp1); \
1967 tcg_temp_free_i ## bits (fp0); \
1968 tcg_temp_free_i ## bits (fp1); \
1971 FOP_CONDNS(d, FMT_D, 64, gen_store_fpr64(ctx, fp0, fd))
1972 FOP_CONDNS(s, FMT_S, 32, gen_store_fpr32(ctx, fp0, fd))
1974 #undef gen_ldcmp_fpr32
1975 #undef gen_ldcmp_fpr64
1977 /* load/store instructions. */
1978 #ifdef CONFIG_USER_ONLY
1979 #define OP_LD_ATOMIC(insn,fname) \
1980 static inline void op_ld_##insn(TCGv ret, TCGv arg1, DisasContext *ctx) \
1982 TCGv t0 = tcg_temp_new(); \
1983 tcg_gen_mov_tl(t0, arg1); \
1984 tcg_gen_qemu_##fname(ret, arg1, ctx->mem_idx); \
1985 tcg_gen_st_tl(t0, cpu_env, offsetof(CPUMIPSState, lladdr)); \
1986 tcg_gen_st_tl(ret, cpu_env, offsetof(CPUMIPSState, llval)); \
1987 tcg_temp_free(t0); \
1990 #define OP_LD_ATOMIC(insn,fname) \
1991 static inline void op_ld_##insn(TCGv ret, TCGv arg1, DisasContext *ctx) \
1993 gen_helper_1e1i(insn, ret, arg1, ctx->mem_idx); \
1996 OP_LD_ATOMIC(ll,ld32s);
1997 #if defined(TARGET_MIPS64)
1998 OP_LD_ATOMIC(lld,ld64);
2002 #ifdef CONFIG_USER_ONLY
2003 #define OP_ST_ATOMIC(insn,fname,ldname,almask) \
2004 static inline void op_st_##insn(TCGv arg1, TCGv arg2, int rt, DisasContext *ctx) \
2006 TCGv t0 = tcg_temp_new(); \
2007 TCGLabel *l1 = gen_new_label(); \
2008 TCGLabel *l2 = gen_new_label(); \
2010 tcg_gen_andi_tl(t0, arg2, almask); \
2011 tcg_gen_brcondi_tl(TCG_COND_EQ, t0, 0, l1); \
2012 tcg_gen_st_tl(arg2, cpu_env, offsetof(CPUMIPSState, CP0_BadVAddr)); \
2013 generate_exception(ctx, EXCP_AdES); \
2014 gen_set_label(l1); \
2015 tcg_gen_ld_tl(t0, cpu_env, offsetof(CPUMIPSState, lladdr)); \
2016 tcg_gen_brcond_tl(TCG_COND_NE, arg2, t0, l2); \
2017 tcg_gen_movi_tl(t0, rt | ((almask << 3) & 0x20)); \
2018 tcg_gen_st_tl(t0, cpu_env, offsetof(CPUMIPSState, llreg)); \
2019 tcg_gen_st_tl(arg1, cpu_env, offsetof(CPUMIPSState, llnewval)); \
2020 gen_helper_0e0i(raise_exception, EXCP_SC); \
2021 gen_set_label(l2); \
2022 tcg_gen_movi_tl(t0, 0); \
2023 gen_store_gpr(t0, rt); \
2024 tcg_temp_free(t0); \
2027 #define OP_ST_ATOMIC(insn,fname,ldname,almask) \
2028 static inline void op_st_##insn(TCGv arg1, TCGv arg2, int rt, DisasContext *ctx) \
2030 TCGv t0 = tcg_temp_new(); \
2031 gen_helper_1e2i(insn, t0, arg1, arg2, ctx->mem_idx); \
2032 gen_store_gpr(t0, rt); \
2033 tcg_temp_free(t0); \
2036 OP_ST_ATOMIC(sc,st32,ld32s,0x3);
2037 #if defined(TARGET_MIPS64)
2038 OP_ST_ATOMIC(scd,st64,ld64,0x7);
2042 static void gen_base_offset_addr (DisasContext *ctx, TCGv addr,
2043 int base, int16_t offset)
2046 tcg_gen_movi_tl(addr, offset);
2047 } else if (offset == 0) {
2048 gen_load_gpr(addr, base);
2050 tcg_gen_movi_tl(addr, offset);
2051 gen_op_addr_add(ctx, addr, cpu_gpr[base], addr);
2055 static target_ulong pc_relative_pc (DisasContext *ctx)
2057 target_ulong pc = ctx->pc;
2059 if (ctx->hflags & MIPS_HFLAG_BMASK) {
2060 int branch_bytes = ctx->hflags & MIPS_HFLAG_BDS16 ? 2 : 4;
2065 pc &= ~(target_ulong)3;
2070 static void gen_ld(DisasContext *ctx, uint32_t opc,
2071 int rt, int base, int16_t offset)
2073 const char *opn = "ld";
2076 if (rt == 0 && ctx->insn_flags & (INSN_LOONGSON2E | INSN_LOONGSON2F)) {
2077 /* Loongson CPU uses a load to zero register for prefetch.
2078 We emulate it as a NOP. On other CPU we must perform the
2079 actual memory access. */
2084 t0 = tcg_temp_new();
2085 gen_base_offset_addr(ctx, t0, base, offset);
2088 #if defined(TARGET_MIPS64)
2090 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TEUL |
2091 ctx->default_tcg_memop_mask);
2092 gen_store_gpr(t0, rt);
2096 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TEQ |
2097 ctx->default_tcg_memop_mask);
2098 gen_store_gpr(t0, rt);
2103 save_cpu_state(ctx, 1);
2104 op_ld_lld(t0, t0, ctx);
2105 gen_store_gpr(t0, rt);
2109 t1 = tcg_temp_new();
2110 tcg_gen_andi_tl(t1, t0, 7);
2111 #ifndef TARGET_WORDS_BIGENDIAN
2112 tcg_gen_xori_tl(t1, t1, 7);
2114 tcg_gen_shli_tl(t1, t1, 3);
2115 tcg_gen_andi_tl(t0, t0, ~7);
2116 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TEQ);
2117 tcg_gen_shl_tl(t0, t0, t1);
2118 tcg_gen_xori_tl(t1, t1, 63);
2119 t2 = tcg_const_tl(0x7fffffffffffffffull);
2120 tcg_gen_shr_tl(t2, t2, t1);
2121 gen_load_gpr(t1, rt);
2122 tcg_gen_and_tl(t1, t1, t2);
2124 tcg_gen_or_tl(t0, t0, t1);
2126 gen_store_gpr(t0, rt);
2130 t1 = tcg_temp_new();
2131 tcg_gen_andi_tl(t1, t0, 7);
2132 #ifdef TARGET_WORDS_BIGENDIAN
2133 tcg_gen_xori_tl(t1, t1, 7);
2135 tcg_gen_shli_tl(t1, t1, 3);
2136 tcg_gen_andi_tl(t0, t0, ~7);
2137 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TEQ);
2138 tcg_gen_shr_tl(t0, t0, t1);
2139 tcg_gen_xori_tl(t1, t1, 63);
2140 t2 = tcg_const_tl(0xfffffffffffffffeull);
2141 tcg_gen_shl_tl(t2, t2, t1);
2142 gen_load_gpr(t1, rt);
2143 tcg_gen_and_tl(t1, t1, t2);
2145 tcg_gen_or_tl(t0, t0, t1);
2147 gen_store_gpr(t0, rt);
2151 t1 = tcg_const_tl(pc_relative_pc(ctx));
2152 gen_op_addr_add(ctx, t0, t0, t1);
2154 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TEQ);
2155 gen_store_gpr(t0, rt);
2160 t1 = tcg_const_tl(pc_relative_pc(ctx));
2161 gen_op_addr_add(ctx, t0, t0, t1);
2163 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TESL);
2164 gen_store_gpr(t0, rt);
2168 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TESL |
2169 ctx->default_tcg_memop_mask);
2170 gen_store_gpr(t0, rt);
2174 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TESW |
2175 ctx->default_tcg_memop_mask);
2176 gen_store_gpr(t0, rt);
2180 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TEUW |
2181 ctx->default_tcg_memop_mask);
2182 gen_store_gpr(t0, rt);
2186 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_SB);
2187 gen_store_gpr(t0, rt);
2191 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_UB);
2192 gen_store_gpr(t0, rt);
2196 t1 = tcg_temp_new();
2197 tcg_gen_andi_tl(t1, t0, 3);
2198 #ifndef TARGET_WORDS_BIGENDIAN
2199 tcg_gen_xori_tl(t1, t1, 3);
2201 tcg_gen_shli_tl(t1, t1, 3);
2202 tcg_gen_andi_tl(t0, t0, ~3);
2203 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TEUL);
2204 tcg_gen_shl_tl(t0, t0, t1);
2205 tcg_gen_xori_tl(t1, t1, 31);
2206 t2 = tcg_const_tl(0x7fffffffull);
2207 tcg_gen_shr_tl(t2, t2, t1);
2208 gen_load_gpr(t1, rt);
2209 tcg_gen_and_tl(t1, t1, t2);
2211 tcg_gen_or_tl(t0, t0, t1);
2213 tcg_gen_ext32s_tl(t0, t0);
2214 gen_store_gpr(t0, rt);
2218 t1 = tcg_temp_new();
2219 tcg_gen_andi_tl(t1, t0, 3);
2220 #ifdef TARGET_WORDS_BIGENDIAN
2221 tcg_gen_xori_tl(t1, t1, 3);
2223 tcg_gen_shli_tl(t1, t1, 3);
2224 tcg_gen_andi_tl(t0, t0, ~3);
2225 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TEUL);
2226 tcg_gen_shr_tl(t0, t0, t1);
2227 tcg_gen_xori_tl(t1, t1, 31);
2228 t2 = tcg_const_tl(0xfffffffeull);
2229 tcg_gen_shl_tl(t2, t2, t1);
2230 gen_load_gpr(t1, rt);
2231 tcg_gen_and_tl(t1, t1, t2);
2233 tcg_gen_or_tl(t0, t0, t1);
2235 tcg_gen_ext32s_tl(t0, t0);
2236 gen_store_gpr(t0, rt);
2241 save_cpu_state(ctx, 1);
2242 op_ld_ll(t0, t0, ctx);
2243 gen_store_gpr(t0, rt);
2247 (void)opn; /* avoid a compiler warning */
2248 MIPS_DEBUG("%s %s, %d(%s)", opn, regnames[rt], offset, regnames[base]);
2253 static void gen_st (DisasContext *ctx, uint32_t opc, int rt,
2254 int base, int16_t offset)
2256 const char *opn = "st";
2257 TCGv t0 = tcg_temp_new();
2258 TCGv t1 = tcg_temp_new();
2260 gen_base_offset_addr(ctx, t0, base, offset);
2261 gen_load_gpr(t1, rt);
2263 #if defined(TARGET_MIPS64)
2265 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEQ |
2266 ctx->default_tcg_memop_mask);
2270 save_cpu_state(ctx, 1);
2271 gen_helper_0e2i(sdl, t1, t0, ctx->mem_idx);
2275 save_cpu_state(ctx, 1);
2276 gen_helper_0e2i(sdr, t1, t0, ctx->mem_idx);
2281 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL |
2282 ctx->default_tcg_memop_mask);
2286 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUW |
2287 ctx->default_tcg_memop_mask);
2291 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_8);
2295 save_cpu_state(ctx, 1);
2296 gen_helper_0e2i(swl, t1, t0, ctx->mem_idx);
2300 save_cpu_state(ctx, 1);
2301 gen_helper_0e2i(swr, t1, t0, ctx->mem_idx);
2305 (void)opn; /* avoid a compiler warning */
2306 MIPS_DEBUG("%s %s, %d(%s)", opn, regnames[rt], offset, regnames[base]);
2312 /* Store conditional */
2313 static void gen_st_cond (DisasContext *ctx, uint32_t opc, int rt,
2314 int base, int16_t offset)
2316 const char *opn = "st_cond";
2319 #ifdef CONFIG_USER_ONLY
2320 t0 = tcg_temp_local_new();
2321 t1 = tcg_temp_local_new();
2323 t0 = tcg_temp_new();
2324 t1 = tcg_temp_new();
2326 gen_base_offset_addr(ctx, t0, base, offset);
2327 gen_load_gpr(t1, rt);
2329 #if defined(TARGET_MIPS64)
2332 save_cpu_state(ctx, 1);
2333 op_st_scd(t1, t0, rt, ctx);
2339 save_cpu_state(ctx, 1);
2340 op_st_sc(t1, t0, rt, ctx);
2344 (void)opn; /* avoid a compiler warning */
2345 MIPS_DEBUG("%s %s, %d(%s)", opn, regnames[rt], offset, regnames[base]);
2350 /* Load and store */
2351 static void gen_flt_ldst (DisasContext *ctx, uint32_t opc, int ft,
2352 int base, int16_t offset)
2354 const char *opn = "flt_ldst";
2355 TCGv t0 = tcg_temp_new();
2357 gen_base_offset_addr(ctx, t0, base, offset);
2358 /* Don't do NOP if destination is zero: we must perform the actual
2363 TCGv_i32 fp0 = tcg_temp_new_i32();
2364 tcg_gen_qemu_ld_i32(fp0, t0, ctx->mem_idx, MO_TESL |
2365 ctx->default_tcg_memop_mask);
2366 gen_store_fpr32(ctx, fp0, ft);
2367 tcg_temp_free_i32(fp0);
2373 TCGv_i32 fp0 = tcg_temp_new_i32();
2374 gen_load_fpr32(ctx, fp0, ft);
2375 tcg_gen_qemu_st_i32(fp0, t0, ctx->mem_idx, MO_TEUL |
2376 ctx->default_tcg_memop_mask);
2377 tcg_temp_free_i32(fp0);
2383 TCGv_i64 fp0 = tcg_temp_new_i64();
2384 tcg_gen_qemu_ld_i64(fp0, t0, ctx->mem_idx, MO_TEQ |
2385 ctx->default_tcg_memop_mask);
2386 gen_store_fpr64(ctx, fp0, ft);
2387 tcg_temp_free_i64(fp0);
2393 TCGv_i64 fp0 = tcg_temp_new_i64();
2394 gen_load_fpr64(ctx, fp0, ft);
2395 tcg_gen_qemu_st_i64(fp0, t0, ctx->mem_idx, MO_TEQ |
2396 ctx->default_tcg_memop_mask);
2397 tcg_temp_free_i64(fp0);
2403 generate_exception(ctx, EXCP_RI);
2406 (void)opn; /* avoid a compiler warning */
2407 MIPS_DEBUG("%s %s, %d(%s)", opn, fregnames[ft], offset, regnames[base]);
2412 static void gen_cop1_ldst(DisasContext *ctx, uint32_t op, int rt,
2413 int rs, int16_t imm)
2415 if (ctx->CP0_Config1 & (1 << CP0C1_FP)) {
2416 check_cp1_enabled(ctx);
2420 check_insn(ctx, ISA_MIPS2);
2423 gen_flt_ldst(ctx, op, rt, rs, imm);
2426 generate_exception_err(ctx, EXCP_CpU, 1);
2430 /* Arithmetic with immediate operand */
2431 static void gen_arith_imm(DisasContext *ctx, uint32_t opc,
2432 int rt, int rs, int16_t imm)
2434 target_ulong uimm = (target_long)imm; /* Sign extend to 32/64 bits */
2435 const char *opn = "imm arith";
2437 if (rt == 0 && opc != OPC_ADDI && opc != OPC_DADDI) {
2438 /* If no destination, treat it as a NOP.
2439 For addi, we must generate the overflow exception when needed. */
2446 TCGv t0 = tcg_temp_local_new();
2447 TCGv t1 = tcg_temp_new();
2448 TCGv t2 = tcg_temp_new();
2449 TCGLabel *l1 = gen_new_label();
2451 gen_load_gpr(t1, rs);
2452 tcg_gen_addi_tl(t0, t1, uimm);
2453 tcg_gen_ext32s_tl(t0, t0);
2455 tcg_gen_xori_tl(t1, t1, ~uimm);
2456 tcg_gen_xori_tl(t2, t0, uimm);
2457 tcg_gen_and_tl(t1, t1, t2);
2459 tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
2461 /* operands of same sign, result different sign */
2462 generate_exception(ctx, EXCP_OVERFLOW);
2464 tcg_gen_ext32s_tl(t0, t0);
2465 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);
2479 #if defined(TARGET_MIPS64)
2482 TCGv t0 = tcg_temp_local_new();
2483 TCGv t1 = tcg_temp_new();
2484 TCGv t2 = tcg_temp_new();
2485 TCGLabel *l1 = gen_new_label();
2487 gen_load_gpr(t1, rs);
2488 tcg_gen_addi_tl(t0, t1, uimm);
2490 tcg_gen_xori_tl(t1, t1, ~uimm);
2491 tcg_gen_xori_tl(t2, t0, uimm);
2492 tcg_gen_and_tl(t1, t1, t2);
2494 tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
2496 /* operands of same sign, result different sign */
2497 generate_exception(ctx, EXCP_OVERFLOW);
2499 gen_store_gpr(t0, rt);
2506 tcg_gen_addi_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
2508 tcg_gen_movi_tl(cpu_gpr[rt], uimm);
2514 (void)opn; /* avoid a compiler warning */
2515 MIPS_DEBUG("%s %s, %s, " TARGET_FMT_lx, opn, regnames[rt], regnames[rs], uimm);
2518 /* Logic with immediate operand */
2519 static void gen_logic_imm(DisasContext *ctx, uint32_t opc,
2520 int rt, int rs, int16_t imm)
2525 /* If no destination, treat it as a NOP. */
2529 uimm = (uint16_t)imm;
2532 if (likely(rs != 0))
2533 tcg_gen_andi_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
2535 tcg_gen_movi_tl(cpu_gpr[rt], 0);
2536 MIPS_DEBUG("andi %s, %s, " TARGET_FMT_lx, regnames[rt],
2537 regnames[rs], uimm);
2541 tcg_gen_ori_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
2543 tcg_gen_movi_tl(cpu_gpr[rt], uimm);
2544 MIPS_DEBUG("ori %s, %s, " TARGET_FMT_lx, regnames[rt],
2545 regnames[rs], uimm);
2548 if (likely(rs != 0))
2549 tcg_gen_xori_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
2551 tcg_gen_movi_tl(cpu_gpr[rt], uimm);
2552 MIPS_DEBUG("xori %s, %s, " TARGET_FMT_lx, regnames[rt],
2553 regnames[rs], uimm);
2556 if (rs != 0 && (ctx->insn_flags & ISA_MIPS32R6)) {
2558 tcg_gen_addi_tl(cpu_gpr[rt], cpu_gpr[rs], imm << 16);
2559 tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]);
2560 MIPS_DEBUG("aui %s, %s, %04x", regnames[rt], regnames[rs], imm);
2562 tcg_gen_movi_tl(cpu_gpr[rt], imm << 16);
2563 MIPS_DEBUG("lui %s, " TARGET_FMT_lx, regnames[rt], uimm);
2568 MIPS_DEBUG("Unknown logical immediate opcode %08x", opc);
2573 /* Set on less than with immediate operand */
2574 static void gen_slt_imm(DisasContext *ctx, uint32_t opc,
2575 int rt, int rs, int16_t imm)
2577 target_ulong uimm = (target_long)imm; /* Sign extend to 32/64 bits */
2578 const char *opn = "imm arith";
2582 /* If no destination, treat it as a NOP. */
2586 t0 = tcg_temp_new();
2587 gen_load_gpr(t0, rs);
2590 tcg_gen_setcondi_tl(TCG_COND_LT, cpu_gpr[rt], t0, uimm);
2594 tcg_gen_setcondi_tl(TCG_COND_LTU, cpu_gpr[rt], t0, uimm);
2598 (void)opn; /* avoid a compiler warning */
2599 MIPS_DEBUG("%s %s, %s, " TARGET_FMT_lx, opn, regnames[rt], regnames[rs], uimm);
2603 /* Shifts with immediate operand */
2604 static void gen_shift_imm(DisasContext *ctx, uint32_t opc,
2605 int rt, int rs, int16_t imm)
2607 target_ulong uimm = ((uint16_t)imm) & 0x1f;
2608 const char *opn = "imm shift";
2612 /* If no destination, treat it as a NOP. */
2617 t0 = tcg_temp_new();
2618 gen_load_gpr(t0, rs);
2621 tcg_gen_shli_tl(t0, t0, uimm);
2622 tcg_gen_ext32s_tl(cpu_gpr[rt], t0);
2626 tcg_gen_sari_tl(cpu_gpr[rt], t0, uimm);
2631 tcg_gen_ext32u_tl(t0, t0);
2632 tcg_gen_shri_tl(cpu_gpr[rt], t0, uimm);
2634 tcg_gen_ext32s_tl(cpu_gpr[rt], t0);
2640 TCGv_i32 t1 = tcg_temp_new_i32();
2642 tcg_gen_trunc_tl_i32(t1, t0);
2643 tcg_gen_rotri_i32(t1, t1, uimm);
2644 tcg_gen_ext_i32_tl(cpu_gpr[rt], t1);
2645 tcg_temp_free_i32(t1);
2647 tcg_gen_ext32s_tl(cpu_gpr[rt], t0);
2651 #if defined(TARGET_MIPS64)
2653 tcg_gen_shli_tl(cpu_gpr[rt], t0, uimm);
2657 tcg_gen_sari_tl(cpu_gpr[rt], t0, uimm);
2661 tcg_gen_shri_tl(cpu_gpr[rt], t0, uimm);
2666 tcg_gen_rotri_tl(cpu_gpr[rt], t0, uimm);
2668 tcg_gen_mov_tl(cpu_gpr[rt], t0);
2673 tcg_gen_shli_tl(cpu_gpr[rt], t0, uimm + 32);
2677 tcg_gen_sari_tl(cpu_gpr[rt], t0, uimm + 32);
2681 tcg_gen_shri_tl(cpu_gpr[rt], t0, uimm + 32);
2685 tcg_gen_rotri_tl(cpu_gpr[rt], t0, uimm + 32);
2690 (void)opn; /* avoid a compiler warning */
2691 MIPS_DEBUG("%s %s, %s, " TARGET_FMT_lx, opn, regnames[rt], regnames[rs], uimm);
2696 static void gen_arith(DisasContext *ctx, uint32_t opc,
2697 int rd, int rs, int rt)
2699 const char *opn = "arith";
2701 if (rd == 0 && opc != OPC_ADD && opc != OPC_SUB
2702 && opc != OPC_DADD && opc != OPC_DSUB) {
2703 /* If no destination, treat it as a NOP.
2704 For add & sub, we must generate the overflow exception when needed. */
2712 TCGv t0 = tcg_temp_local_new();
2713 TCGv t1 = tcg_temp_new();
2714 TCGv t2 = tcg_temp_new();
2715 TCGLabel *l1 = gen_new_label();
2717 gen_load_gpr(t1, rs);
2718 gen_load_gpr(t2, rt);
2719 tcg_gen_add_tl(t0, t1, t2);
2720 tcg_gen_ext32s_tl(t0, t0);
2721 tcg_gen_xor_tl(t1, t1, t2);
2722 tcg_gen_xor_tl(t2, t0, t2);
2723 tcg_gen_andc_tl(t1, t2, t1);
2725 tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
2727 /* operands of same sign, result different sign */
2728 generate_exception(ctx, EXCP_OVERFLOW);
2730 gen_store_gpr(t0, rd);
2736 if (rs != 0 && rt != 0) {
2737 tcg_gen_add_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2738 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
2739 } else if (rs == 0 && rt != 0) {
2740 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rt]);
2741 } else if (rs != 0 && rt == 0) {
2742 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
2744 tcg_gen_movi_tl(cpu_gpr[rd], 0);
2750 TCGv t0 = tcg_temp_local_new();
2751 TCGv t1 = tcg_temp_new();
2752 TCGv t2 = tcg_temp_new();
2753 TCGLabel *l1 = gen_new_label();
2755 gen_load_gpr(t1, rs);
2756 gen_load_gpr(t2, rt);
2757 tcg_gen_sub_tl(t0, t1, t2);
2758 tcg_gen_ext32s_tl(t0, t0);
2759 tcg_gen_xor_tl(t2, t1, t2);
2760 tcg_gen_xor_tl(t1, t0, t1);
2761 tcg_gen_and_tl(t1, t1, t2);
2763 tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
2765 /* operands of different sign, first operand and result different sign */
2766 generate_exception(ctx, EXCP_OVERFLOW);
2768 gen_store_gpr(t0, rd);
2774 if (rs != 0 && rt != 0) {
2775 tcg_gen_sub_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2776 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
2777 } else if (rs == 0 && rt != 0) {
2778 tcg_gen_neg_tl(cpu_gpr[rd], cpu_gpr[rt]);
2779 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
2780 } else if (rs != 0 && rt == 0) {
2781 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
2783 tcg_gen_movi_tl(cpu_gpr[rd], 0);
2787 #if defined(TARGET_MIPS64)
2790 TCGv t0 = tcg_temp_local_new();
2791 TCGv t1 = tcg_temp_new();
2792 TCGv t2 = tcg_temp_new();
2793 TCGLabel *l1 = gen_new_label();
2795 gen_load_gpr(t1, rs);
2796 gen_load_gpr(t2, rt);
2797 tcg_gen_add_tl(t0, t1, t2);
2798 tcg_gen_xor_tl(t1, t1, t2);
2799 tcg_gen_xor_tl(t2, t0, t2);
2800 tcg_gen_andc_tl(t1, t2, t1);
2802 tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
2804 /* operands of same sign, result different sign */
2805 generate_exception(ctx, EXCP_OVERFLOW);
2807 gen_store_gpr(t0, rd);
2813 if (rs != 0 && rt != 0) {
2814 tcg_gen_add_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2815 } else if (rs == 0 && rt != 0) {
2816 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rt]);
2817 } else if (rs != 0 && rt == 0) {
2818 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
2820 tcg_gen_movi_tl(cpu_gpr[rd], 0);
2826 TCGv t0 = tcg_temp_local_new();
2827 TCGv t1 = tcg_temp_new();
2828 TCGv t2 = tcg_temp_new();
2829 TCGLabel *l1 = gen_new_label();
2831 gen_load_gpr(t1, rs);
2832 gen_load_gpr(t2, rt);
2833 tcg_gen_sub_tl(t0, t1, t2);
2834 tcg_gen_xor_tl(t2, t1, t2);
2835 tcg_gen_xor_tl(t1, t0, t1);
2836 tcg_gen_and_tl(t1, t1, t2);
2838 tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
2840 /* operands of different sign, first operand and result different sign */
2841 generate_exception(ctx, EXCP_OVERFLOW);
2843 gen_store_gpr(t0, rd);
2849 if (rs != 0 && rt != 0) {
2850 tcg_gen_sub_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2851 } else if (rs == 0 && rt != 0) {
2852 tcg_gen_neg_tl(cpu_gpr[rd], cpu_gpr[rt]);
2853 } else if (rs != 0 && rt == 0) {
2854 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
2856 tcg_gen_movi_tl(cpu_gpr[rd], 0);
2862 if (likely(rs != 0 && rt != 0)) {
2863 tcg_gen_mul_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2864 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
2866 tcg_gen_movi_tl(cpu_gpr[rd], 0);
2871 (void)opn; /* avoid a compiler warning */
2872 MIPS_DEBUG("%s %s, %s, %s", opn, regnames[rd], regnames[rs], regnames[rt]);
2875 /* Conditional move */
2876 static void gen_cond_move(DisasContext *ctx, uint32_t opc,
2877 int rd, int rs, int rt)
2879 const char *opn = "cond move";
2883 /* If no destination, treat it as a NOP. */
2888 t0 = tcg_temp_new();
2889 gen_load_gpr(t0, rt);
2890 t1 = tcg_const_tl(0);
2891 t2 = tcg_temp_new();
2892 gen_load_gpr(t2, rs);
2895 tcg_gen_movcond_tl(TCG_COND_NE, cpu_gpr[rd], t0, t1, t2, cpu_gpr[rd]);
2899 tcg_gen_movcond_tl(TCG_COND_EQ, cpu_gpr[rd], t0, t1, t2, cpu_gpr[rd]);
2903 tcg_gen_movcond_tl(TCG_COND_NE, cpu_gpr[rd], t0, t1, t2, t1);
2907 tcg_gen_movcond_tl(TCG_COND_EQ, cpu_gpr[rd], t0, t1, t2, t1);
2915 (void)opn; /* avoid a compiler warning */
2916 MIPS_DEBUG("%s %s, %s, %s", opn, regnames[rd], regnames[rs], regnames[rt]);
2920 static void gen_logic(DisasContext *ctx, uint32_t opc,
2921 int rd, int rs, int rt)
2923 const char *opn = "logic";
2926 /* If no destination, treat it as a NOP. */
2933 if (likely(rs != 0 && rt != 0)) {
2934 tcg_gen_and_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2936 tcg_gen_movi_tl(cpu_gpr[rd], 0);
2941 if (rs != 0 && rt != 0) {
2942 tcg_gen_nor_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2943 } else if (rs == 0 && rt != 0) {
2944 tcg_gen_not_tl(cpu_gpr[rd], cpu_gpr[rt]);
2945 } else if (rs != 0 && rt == 0) {
2946 tcg_gen_not_tl(cpu_gpr[rd], cpu_gpr[rs]);
2948 tcg_gen_movi_tl(cpu_gpr[rd], ~((target_ulong)0));
2953 if (likely(rs != 0 && rt != 0)) {
2954 tcg_gen_or_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2955 } else if (rs == 0 && rt != 0) {
2956 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rt]);
2957 } else if (rs != 0 && rt == 0) {
2958 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
2960 tcg_gen_movi_tl(cpu_gpr[rd], 0);
2965 if (likely(rs != 0 && rt != 0)) {
2966 tcg_gen_xor_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2967 } else if (rs == 0 && rt != 0) {
2968 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rt]);
2969 } else if (rs != 0 && rt == 0) {
2970 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
2972 tcg_gen_movi_tl(cpu_gpr[rd], 0);
2977 (void)opn; /* avoid a compiler warning */
2978 MIPS_DEBUG("%s %s, %s, %s", opn, regnames[rd], regnames[rs], regnames[rt]);
2981 /* Set on lower than */
2982 static void gen_slt(DisasContext *ctx, uint32_t opc,
2983 int rd, int rs, int rt)
2985 const char *opn = "slt";
2989 /* If no destination, treat it as a NOP. */
2994 t0 = tcg_temp_new();
2995 t1 = tcg_temp_new();
2996 gen_load_gpr(t0, rs);
2997 gen_load_gpr(t1, rt);
3000 tcg_gen_setcond_tl(TCG_COND_LT, cpu_gpr[rd], t0, t1);
3004 tcg_gen_setcond_tl(TCG_COND_LTU, cpu_gpr[rd], t0, t1);
3008 (void)opn; /* avoid a compiler warning */
3009 MIPS_DEBUG("%s %s, %s, %s", opn, regnames[rd], regnames[rs], regnames[rt]);
3015 static void gen_shift(DisasContext *ctx, uint32_t opc,
3016 int rd, int rs, int rt)
3018 const char *opn = "shifts";
3022 /* If no destination, treat it as a NOP.
3023 For add & sub, we must generate the overflow exception when needed. */
3028 t0 = tcg_temp_new();
3029 t1 = tcg_temp_new();
3030 gen_load_gpr(t0, rs);
3031 gen_load_gpr(t1, rt);
3034 tcg_gen_andi_tl(t0, t0, 0x1f);
3035 tcg_gen_shl_tl(t0, t1, t0);
3036 tcg_gen_ext32s_tl(cpu_gpr[rd], t0);
3040 tcg_gen_andi_tl(t0, t0, 0x1f);
3041 tcg_gen_sar_tl(cpu_gpr[rd], t1, t0);
3045 tcg_gen_ext32u_tl(t1, t1);
3046 tcg_gen_andi_tl(t0, t0, 0x1f);
3047 tcg_gen_shr_tl(t0, t1, t0);
3048 tcg_gen_ext32s_tl(cpu_gpr[rd], t0);
3053 TCGv_i32 t2 = tcg_temp_new_i32();
3054 TCGv_i32 t3 = tcg_temp_new_i32();
3056 tcg_gen_trunc_tl_i32(t2, t0);
3057 tcg_gen_trunc_tl_i32(t3, t1);
3058 tcg_gen_andi_i32(t2, t2, 0x1f);
3059 tcg_gen_rotr_i32(t2, t3, t2);
3060 tcg_gen_ext_i32_tl(cpu_gpr[rd], t2);
3061 tcg_temp_free_i32(t2);
3062 tcg_temp_free_i32(t3);
3066 #if defined(TARGET_MIPS64)
3068 tcg_gen_andi_tl(t0, t0, 0x3f);
3069 tcg_gen_shl_tl(cpu_gpr[rd], t1, t0);
3073 tcg_gen_andi_tl(t0, t0, 0x3f);
3074 tcg_gen_sar_tl(cpu_gpr[rd], t1, t0);
3078 tcg_gen_andi_tl(t0, t0, 0x3f);
3079 tcg_gen_shr_tl(cpu_gpr[rd], t1, t0);
3083 tcg_gen_andi_tl(t0, t0, 0x3f);
3084 tcg_gen_rotr_tl(cpu_gpr[rd], t1, t0);
3089 (void)opn; /* avoid a compiler warning */
3090 MIPS_DEBUG("%s %s, %s, %s", opn, regnames[rd], regnames[rs], regnames[rt]);
3095 /* Arithmetic on HI/LO registers */
3096 static void gen_HILO(DisasContext *ctx, uint32_t opc, int acc, int reg)
3098 const char *opn = "hilo";
3100 if (reg == 0 && (opc == OPC_MFHI || opc == OPC_MFLO)) {
3112 #if defined(TARGET_MIPS64)
3114 tcg_gen_ext32s_tl(cpu_gpr[reg], cpu_HI[acc]);
3118 tcg_gen_mov_tl(cpu_gpr[reg], cpu_HI[acc]);
3123 #if defined(TARGET_MIPS64)
3125 tcg_gen_ext32s_tl(cpu_gpr[reg], cpu_LO[acc]);
3129 tcg_gen_mov_tl(cpu_gpr[reg], cpu_LO[acc]);
3135 #if defined(TARGET_MIPS64)
3137 tcg_gen_ext32s_tl(cpu_HI[acc], cpu_gpr[reg]);
3141 tcg_gen_mov_tl(cpu_HI[acc], cpu_gpr[reg]);
3144 tcg_gen_movi_tl(cpu_HI[acc], 0);
3150 #if defined(TARGET_MIPS64)
3152 tcg_gen_ext32s_tl(cpu_LO[acc], cpu_gpr[reg]);
3156 tcg_gen_mov_tl(cpu_LO[acc], cpu_gpr[reg]);
3159 tcg_gen_movi_tl(cpu_LO[acc], 0);
3164 (void)opn; /* avoid a compiler warning */
3165 MIPS_DEBUG("%s %s", opn, regnames[reg]);
3168 static inline void gen_r6_ld(target_long addr, int reg, int memidx,
3171 TCGv t0 = tcg_const_tl(addr);
3172 tcg_gen_qemu_ld_tl(t0, t0, memidx, memop);
3173 gen_store_gpr(t0, reg);
3177 static inline void gen_pcrel(DisasContext *ctx, int rs, int16_t imm)
3182 switch (MASK_OPC_PCREL_TOP2BITS(ctx->opcode)) {
3185 offset = sextract32(ctx->opcode << 2, 0, 21);
3186 addr = addr_add(ctx, ctx->pc, offset);
3187 tcg_gen_movi_tl(cpu_gpr[rs], addr);
3191 offset = sextract32(ctx->opcode << 2, 0, 21);
3192 addr = addr_add(ctx, ctx->pc, offset);
3193 gen_r6_ld(addr, rs, ctx->mem_idx, MO_TESL);
3195 #if defined(TARGET_MIPS64)
3198 offset = sextract32(ctx->opcode << 2, 0, 21);
3199 addr = addr_add(ctx, ctx->pc, offset);
3200 gen_r6_ld(addr, rs, ctx->mem_idx, MO_TEUL);
3204 switch (MASK_OPC_PCREL_TOP5BITS(ctx->opcode)) {
3208 addr = addr_add(ctx, ctx->pc, offset);
3209 tcg_gen_movi_tl(cpu_gpr[rs], addr);
3215 addr = ~0xFFFF & addr_add(ctx, ctx->pc, offset);
3216 tcg_gen_movi_tl(cpu_gpr[rs], addr);
3219 #if defined(TARGET_MIPS64)
3220 case R6_OPC_LDPC: /* bits 16 and 17 are part of immediate */
3221 case R6_OPC_LDPC + (1 << 16):
3222 case R6_OPC_LDPC + (2 << 16):
3223 case R6_OPC_LDPC + (3 << 16):
3225 offset = sextract32(ctx->opcode << 3, 0, 21);
3226 addr = addr_add(ctx, (ctx->pc & ~0x7), offset);
3227 gen_r6_ld(addr, rs, ctx->mem_idx, MO_TEQ);
3231 MIPS_INVAL("OPC_PCREL");
3232 generate_exception(ctx, EXCP_RI);
3239 static void gen_r6_muldiv(DisasContext *ctx, int opc, int rd, int rs, int rt)
3241 const char *opn = "r6 mul/div";
3250 t0 = tcg_temp_new();
3251 t1 = tcg_temp_new();
3253 gen_load_gpr(t0, rs);
3254 gen_load_gpr(t1, rt);
3259 TCGv t2 = tcg_temp_new();
3260 TCGv t3 = tcg_temp_new();
3261 tcg_gen_ext32s_tl(t0, t0);
3262 tcg_gen_ext32s_tl(t1, t1);
3263 tcg_gen_setcondi_tl(TCG_COND_EQ, t2, t0, INT_MIN);
3264 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, -1);
3265 tcg_gen_and_tl(t2, t2, t3);
3266 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, 0);
3267 tcg_gen_or_tl(t2, t2, t3);
3268 tcg_gen_movi_tl(t3, 0);
3269 tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, t3, t2, t1);
3270 tcg_gen_div_tl(cpu_gpr[rd], t0, t1);
3271 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3279 TCGv t2 = tcg_temp_new();
3280 TCGv t3 = tcg_temp_new();
3281 tcg_gen_ext32s_tl(t0, t0);
3282 tcg_gen_ext32s_tl(t1, t1);
3283 tcg_gen_setcondi_tl(TCG_COND_EQ, t2, t0, INT_MIN);
3284 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, -1);
3285 tcg_gen_and_tl(t2, t2, t3);
3286 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, 0);
3287 tcg_gen_or_tl(t2, t2, t3);
3288 tcg_gen_movi_tl(t3, 0);
3289 tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, t3, t2, t1);
3290 tcg_gen_rem_tl(cpu_gpr[rd], t0, t1);
3291 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3299 TCGv t2 = tcg_const_tl(0);
3300 TCGv t3 = tcg_const_tl(1);
3301 tcg_gen_ext32u_tl(t0, t0);
3302 tcg_gen_ext32u_tl(t1, t1);
3303 tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1, t2, t3, t1);
3304 tcg_gen_divu_tl(cpu_gpr[rd], t0, t1);
3305 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3313 TCGv t2 = tcg_const_tl(0);
3314 TCGv t3 = tcg_const_tl(1);
3315 tcg_gen_ext32u_tl(t0, t0);
3316 tcg_gen_ext32u_tl(t1, t1);
3317 tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1, t2, t3, t1);
3318 tcg_gen_remu_tl(cpu_gpr[rd], t0, t1);
3319 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3327 TCGv_i32 t2 = tcg_temp_new_i32();
3328 TCGv_i32 t3 = tcg_temp_new_i32();
3329 tcg_gen_trunc_tl_i32(t2, t0);
3330 tcg_gen_trunc_tl_i32(t3, t1);
3331 tcg_gen_mul_i32(t2, t2, t3);
3332 tcg_gen_ext_i32_tl(cpu_gpr[rd], t2);
3333 tcg_temp_free_i32(t2);
3334 tcg_temp_free_i32(t3);
3340 TCGv_i32 t2 = tcg_temp_new_i32();
3341 TCGv_i32 t3 = tcg_temp_new_i32();
3342 tcg_gen_trunc_tl_i32(t2, t0);
3343 tcg_gen_trunc_tl_i32(t3, t1);
3344 tcg_gen_muls2_i32(t2, t3, t2, t3);
3345 tcg_gen_ext_i32_tl(cpu_gpr[rd], t3);
3346 tcg_temp_free_i32(t2);
3347 tcg_temp_free_i32(t3);
3353 TCGv_i32 t2 = tcg_temp_new_i32();
3354 TCGv_i32 t3 = tcg_temp_new_i32();
3355 tcg_gen_trunc_tl_i32(t2, t0);
3356 tcg_gen_trunc_tl_i32(t3, t1);
3357 tcg_gen_mul_i32(t2, t2, t3);
3358 tcg_gen_ext_i32_tl(cpu_gpr[rd], t2);
3359 tcg_temp_free_i32(t2);
3360 tcg_temp_free_i32(t3);
3366 TCGv_i32 t2 = tcg_temp_new_i32();
3367 TCGv_i32 t3 = tcg_temp_new_i32();
3368 tcg_gen_trunc_tl_i32(t2, t0);
3369 tcg_gen_trunc_tl_i32(t3, t1);
3370 tcg_gen_mulu2_i32(t2, t3, t2, t3);
3371 tcg_gen_ext_i32_tl(cpu_gpr[rd], t3);
3372 tcg_temp_free_i32(t2);
3373 tcg_temp_free_i32(t3);
3377 #if defined(TARGET_MIPS64)
3380 TCGv t2 = tcg_temp_new();
3381 TCGv t3 = tcg_temp_new();
3382 tcg_gen_setcondi_tl(TCG_COND_EQ, t2, t0, -1LL << 63);
3383 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, -1LL);
3384 tcg_gen_and_tl(t2, t2, t3);
3385 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, 0);
3386 tcg_gen_or_tl(t2, t2, t3);
3387 tcg_gen_movi_tl(t3, 0);
3388 tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, t3, t2, t1);
3389 tcg_gen_div_tl(cpu_gpr[rd], t0, t1);
3397 TCGv t2 = tcg_temp_new();
3398 TCGv t3 = tcg_temp_new();
3399 tcg_gen_setcondi_tl(TCG_COND_EQ, t2, t0, -1LL << 63);
3400 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, -1LL);
3401 tcg_gen_and_tl(t2, t2, t3);
3402 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, 0);
3403 tcg_gen_or_tl(t2, t2, t3);
3404 tcg_gen_movi_tl(t3, 0);
3405 tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, t3, t2, t1);
3406 tcg_gen_rem_tl(cpu_gpr[rd], t0, t1);
3414 TCGv t2 = tcg_const_tl(0);
3415 TCGv t3 = tcg_const_tl(1);
3416 tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1, t2, t3, t1);
3417 tcg_gen_divu_i64(cpu_gpr[rd], t0, t1);
3425 TCGv t2 = tcg_const_tl(0);
3426 TCGv t3 = tcg_const_tl(1);
3427 tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1, t2, t3, t1);
3428 tcg_gen_remu_i64(cpu_gpr[rd], t0, t1);
3435 tcg_gen_mul_i64(cpu_gpr[rd], t0, t1);
3440 TCGv t2 = tcg_temp_new();
3441 tcg_gen_muls2_i64(t2, cpu_gpr[rd], t0, t1);
3447 tcg_gen_mul_i64(cpu_gpr[rd], t0, t1);
3452 TCGv t2 = tcg_temp_new();
3453 tcg_gen_mulu2_i64(t2, cpu_gpr[rd], t0, t1);
3461 generate_exception(ctx, EXCP_RI);
3464 (void)opn; /* avoid a compiler warning */
3465 MIPS_DEBUG("%s %s %s", opn, regnames[rs], regnames[rt]);
3471 static void gen_muldiv(DisasContext *ctx, uint32_t opc,
3472 int acc, int rs, int rt)
3474 const char *opn = "mul/div";
3477 t0 = tcg_temp_new();
3478 t1 = tcg_temp_new();
3480 gen_load_gpr(t0, rs);
3481 gen_load_gpr(t1, rt);
3490 TCGv t2 = tcg_temp_new();
3491 TCGv t3 = tcg_temp_new();
3492 tcg_gen_ext32s_tl(t0, t0);
3493 tcg_gen_ext32s_tl(t1, t1);
3494 tcg_gen_setcondi_tl(TCG_COND_EQ, t2, t0, INT_MIN);
3495 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, -1);
3496 tcg_gen_and_tl(t2, t2, t3);
3497 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, 0);
3498 tcg_gen_or_tl(t2, t2, t3);
3499 tcg_gen_movi_tl(t3, 0);
3500 tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, t3, t2, t1);
3501 tcg_gen_div_tl(cpu_LO[acc], t0, t1);
3502 tcg_gen_rem_tl(cpu_HI[acc], t0, t1);
3503 tcg_gen_ext32s_tl(cpu_LO[acc], cpu_LO[acc]);
3504 tcg_gen_ext32s_tl(cpu_HI[acc], cpu_HI[acc]);
3512 TCGv t2 = tcg_const_tl(0);
3513 TCGv t3 = tcg_const_tl(1);
3514 tcg_gen_ext32u_tl(t0, t0);
3515 tcg_gen_ext32u_tl(t1, t1);
3516 tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1, t2, t3, t1);
3517 tcg_gen_divu_tl(cpu_LO[acc], t0, t1);
3518 tcg_gen_remu_tl(cpu_HI[acc], t0, t1);
3519 tcg_gen_ext32s_tl(cpu_LO[acc], cpu_LO[acc]);
3520 tcg_gen_ext32s_tl(cpu_HI[acc], cpu_HI[acc]);
3528 TCGv_i32 t2 = tcg_temp_new_i32();
3529 TCGv_i32 t3 = tcg_temp_new_i32();
3530 tcg_gen_trunc_tl_i32(t2, t0);
3531 tcg_gen_trunc_tl_i32(t3, t1);
3532 tcg_gen_muls2_i32(t2, t3, t2, t3);
3533 tcg_gen_ext_i32_tl(cpu_LO[acc], t2);
3534 tcg_gen_ext_i32_tl(cpu_HI[acc], t3);
3535 tcg_temp_free_i32(t2);
3536 tcg_temp_free_i32(t3);
3542 TCGv_i32 t2 = tcg_temp_new_i32();
3543 TCGv_i32 t3 = tcg_temp_new_i32();
3544 tcg_gen_trunc_tl_i32(t2, t0);
3545 tcg_gen_trunc_tl_i32(t3, t1);
3546 tcg_gen_mulu2_i32(t2, t3, t2, t3);
3547 tcg_gen_ext_i32_tl(cpu_LO[acc], t2);
3548 tcg_gen_ext_i32_tl(cpu_HI[acc], t3);
3549 tcg_temp_free_i32(t2);
3550 tcg_temp_free_i32(t3);
3554 #if defined(TARGET_MIPS64)
3557 TCGv t2 = tcg_temp_new();
3558 TCGv t3 = tcg_temp_new();
3559 tcg_gen_setcondi_tl(TCG_COND_EQ, t2, t0, -1LL << 63);
3560 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, -1LL);
3561 tcg_gen_and_tl(t2, t2, t3);
3562 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, 0);
3563 tcg_gen_or_tl(t2, t2, t3);
3564 tcg_gen_movi_tl(t3, 0);
3565 tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, t3, t2, t1);
3566 tcg_gen_div_tl(cpu_LO[acc], t0, t1);
3567 tcg_gen_rem_tl(cpu_HI[acc], t0, t1);
3575 TCGv t2 = tcg_const_tl(0);
3576 TCGv t3 = tcg_const_tl(1);
3577 tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1, t2, t3, t1);
3578 tcg_gen_divu_i64(cpu_LO[acc], t0, t1);
3579 tcg_gen_remu_i64(cpu_HI[acc], t0, t1);
3586 tcg_gen_muls2_i64(cpu_LO[acc], cpu_HI[acc], t0, t1);
3590 tcg_gen_mulu2_i64(cpu_LO[acc], cpu_HI[acc], t0, t1);
3596 TCGv_i64 t2 = tcg_temp_new_i64();
3597 TCGv_i64 t3 = tcg_temp_new_i64();
3599 tcg_gen_ext_tl_i64(t2, t0);
3600 tcg_gen_ext_tl_i64(t3, t1);
3601 tcg_gen_mul_i64(t2, t2, t3);
3602 tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]);
3603 tcg_gen_add_i64(t2, t2, t3);
3604 tcg_temp_free_i64(t3);
3605 tcg_gen_trunc_i64_tl(t0, t2);
3606 tcg_gen_shri_i64(t2, t2, 32);
3607 tcg_gen_trunc_i64_tl(t1, t2);
3608 tcg_temp_free_i64(t2);
3609 tcg_gen_ext32s_tl(cpu_LO[acc], t0);
3610 tcg_gen_ext32s_tl(cpu_HI[acc], t1);
3616 TCGv_i64 t2 = tcg_temp_new_i64();
3617 TCGv_i64 t3 = tcg_temp_new_i64();
3619 tcg_gen_ext32u_tl(t0, t0);
3620 tcg_gen_ext32u_tl(t1, t1);
3621 tcg_gen_extu_tl_i64(t2, t0);
3622 tcg_gen_extu_tl_i64(t3, t1);
3623 tcg_gen_mul_i64(t2, t2, t3);
3624 tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]);
3625 tcg_gen_add_i64(t2, t2, t3);
3626 tcg_temp_free_i64(t3);
3627 tcg_gen_trunc_i64_tl(t0, t2);
3628 tcg_gen_shri_i64(t2, t2, 32);
3629 tcg_gen_trunc_i64_tl(t1, t2);
3630 tcg_temp_free_i64(t2);
3631 tcg_gen_ext32s_tl(cpu_LO[acc], t0);
3632 tcg_gen_ext32s_tl(cpu_HI[acc], t1);
3638 TCGv_i64 t2 = tcg_temp_new_i64();
3639 TCGv_i64 t3 = tcg_temp_new_i64();
3641 tcg_gen_ext_tl_i64(t2, t0);
3642 tcg_gen_ext_tl_i64(t3, t1);
3643 tcg_gen_mul_i64(t2, t2, t3);
3644 tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]);
3645 tcg_gen_sub_i64(t2, t3, t2);
3646 tcg_temp_free_i64(t3);
3647 tcg_gen_trunc_i64_tl(t0, t2);
3648 tcg_gen_shri_i64(t2, t2, 32);
3649 tcg_gen_trunc_i64_tl(t1, t2);
3650 tcg_temp_free_i64(t2);
3651 tcg_gen_ext32s_tl(cpu_LO[acc], t0);
3652 tcg_gen_ext32s_tl(cpu_HI[acc], t1);
3658 TCGv_i64 t2 = tcg_temp_new_i64();
3659 TCGv_i64 t3 = tcg_temp_new_i64();
3661 tcg_gen_ext32u_tl(t0, t0);
3662 tcg_gen_ext32u_tl(t1, t1);
3663 tcg_gen_extu_tl_i64(t2, t0);
3664 tcg_gen_extu_tl_i64(t3, t1);
3665 tcg_gen_mul_i64(t2, t2, t3);
3666 tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]);
3667 tcg_gen_sub_i64(t2, t3, t2);
3668 tcg_temp_free_i64(t3);
3669 tcg_gen_trunc_i64_tl(t0, t2);
3670 tcg_gen_shri_i64(t2, t2, 32);
3671 tcg_gen_trunc_i64_tl(t1, t2);
3672 tcg_temp_free_i64(t2);
3673 tcg_gen_ext32s_tl(cpu_LO[acc], t0);
3674 tcg_gen_ext32s_tl(cpu_HI[acc], t1);
3680 generate_exception(ctx, EXCP_RI);
3683 (void)opn; /* avoid a compiler warning */
3684 MIPS_DEBUG("%s %s %s", opn, regnames[rs], regnames[rt]);
3690 static void gen_mul_vr54xx (DisasContext *ctx, uint32_t opc,
3691 int rd, int rs, int rt)
3693 const char *opn = "mul vr54xx";
3694 TCGv t0 = tcg_temp_new();
3695 TCGv t1 = tcg_temp_new();
3697 gen_load_gpr(t0, rs);
3698 gen_load_gpr(t1, rt);
3701 case OPC_VR54XX_MULS:
3702 gen_helper_muls(t0, cpu_env, t0, t1);
3705 case OPC_VR54XX_MULSU:
3706 gen_helper_mulsu(t0, cpu_env, t0, t1);
3709 case OPC_VR54XX_MACC:
3710 gen_helper_macc(t0, cpu_env, t0, t1);
3713 case OPC_VR54XX_MACCU:
3714 gen_helper_maccu(t0, cpu_env, t0, t1);
3717 case OPC_VR54XX_MSAC:
3718 gen_helper_msac(t0, cpu_env, t0, t1);
3721 case OPC_VR54XX_MSACU:
3722 gen_helper_msacu(t0, cpu_env, t0, t1);
3725 case OPC_VR54XX_MULHI:
3726 gen_helper_mulhi(t0, cpu_env, t0, t1);
3729 case OPC_VR54XX_MULHIU:
3730 gen_helper_mulhiu(t0, cpu_env, t0, t1);
3733 case OPC_VR54XX_MULSHI:
3734 gen_helper_mulshi(t0, cpu_env, t0, t1);
3737 case OPC_VR54XX_MULSHIU:
3738 gen_helper_mulshiu(t0, cpu_env, t0, t1);
3741 case OPC_VR54XX_MACCHI:
3742 gen_helper_macchi(t0, cpu_env, t0, t1);
3745 case OPC_VR54XX_MACCHIU:
3746 gen_helper_macchiu(t0, cpu_env, t0, t1);
3749 case OPC_VR54XX_MSACHI:
3750 gen_helper_msachi(t0, cpu_env, t0, t1);
3753 case OPC_VR54XX_MSACHIU:
3754 gen_helper_msachiu(t0, cpu_env, t0, t1);
3758 MIPS_INVAL("mul vr54xx");
3759 generate_exception(ctx, EXCP_RI);
3762 gen_store_gpr(t0, rd);
3763 (void)opn; /* avoid a compiler warning */
3764 MIPS_DEBUG("%s %s, %s, %s", opn, regnames[rd], regnames[rs], regnames[rt]);
3771 static void gen_cl (DisasContext *ctx, uint32_t opc,
3774 const char *opn = "CLx";
3782 t0 = tcg_temp_new();
3783 gen_load_gpr(t0, rs);
3787 gen_helper_clo(cpu_gpr[rd], t0);
3792 gen_helper_clz(cpu_gpr[rd], t0);
3795 #if defined(TARGET_MIPS64)
3798 gen_helper_dclo(cpu_gpr[rd], t0);
3803 gen_helper_dclz(cpu_gpr[rd], t0);
3808 (void)opn; /* avoid a compiler warning */
3809 MIPS_DEBUG("%s %s, %s", opn, regnames[rd], regnames[rs]);
3813 /* Godson integer instructions */
3814 static void gen_loongson_integer(DisasContext *ctx, uint32_t opc,
3815 int rd, int rs, int rt)
3817 const char *opn = "loongson";
3829 case OPC_MULTU_G_2E:
3830 case OPC_MULTU_G_2F:
3831 #if defined(TARGET_MIPS64)
3832 case OPC_DMULT_G_2E:
3833 case OPC_DMULT_G_2F:
3834 case OPC_DMULTU_G_2E:
3835 case OPC_DMULTU_G_2F:
3837 t0 = tcg_temp_new();
3838 t1 = tcg_temp_new();
3841 t0 = tcg_temp_local_new();
3842 t1 = tcg_temp_local_new();
3846 gen_load_gpr(t0, rs);
3847 gen_load_gpr(t1, rt);
3852 tcg_gen_mul_tl(cpu_gpr[rd], t0, t1);
3853 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3856 case OPC_MULTU_G_2E:
3857 case OPC_MULTU_G_2F:
3858 tcg_gen_ext32u_tl(t0, t0);
3859 tcg_gen_ext32u_tl(t1, t1);
3860 tcg_gen_mul_tl(cpu_gpr[rd], t0, t1);
3861 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3867 TCGLabel *l1 = gen_new_label();
3868 TCGLabel *l2 = gen_new_label();
3869 TCGLabel *l3 = gen_new_label();
3870 tcg_gen_ext32s_tl(t0, t0);
3871 tcg_gen_ext32s_tl(t1, t1);
3872 tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
3873 tcg_gen_movi_tl(cpu_gpr[rd], 0);
3876 tcg_gen_brcondi_tl(TCG_COND_NE, t0, INT_MIN, l2);
3877 tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1, l2);
3878 tcg_gen_mov_tl(cpu_gpr[rd], t0);
3881 tcg_gen_div_tl(cpu_gpr[rd], t0, t1);
3882 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3890 TCGLabel *l1 = gen_new_label();
3891 TCGLabel *l2 = gen_new_label();
3892 tcg_gen_ext32u_tl(t0, t0);
3893 tcg_gen_ext32u_tl(t1, t1);
3894 tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
3895 tcg_gen_movi_tl(cpu_gpr[rd], 0);
3898 tcg_gen_divu_tl(cpu_gpr[rd], t0, t1);
3899 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3907 TCGLabel *l1 = gen_new_label();
3908 TCGLabel *l2 = gen_new_label();
3909 TCGLabel *l3 = gen_new_label();
3910 tcg_gen_ext32u_tl(t0, t0);
3911 tcg_gen_ext32u_tl(t1, t1);
3912 tcg_gen_brcondi_tl(TCG_COND_EQ, t1, 0, l1);
3913 tcg_gen_brcondi_tl(TCG_COND_NE, t0, INT_MIN, l2);
3914 tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1, l2);
3916 tcg_gen_movi_tl(cpu_gpr[rd], 0);
3919 tcg_gen_rem_tl(cpu_gpr[rd], t0, t1);
3920 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3928 TCGLabel *l1 = gen_new_label();
3929 TCGLabel *l2 = gen_new_label();
3930 tcg_gen_ext32u_tl(t0, t0);
3931 tcg_gen_ext32u_tl(t1, t1);
3932 tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
3933 tcg_gen_movi_tl(cpu_gpr[rd], 0);
3936 tcg_gen_remu_tl(cpu_gpr[rd], t0, t1);
3937 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3942 #if defined(TARGET_MIPS64)
3943 case OPC_DMULT_G_2E:
3944 case OPC_DMULT_G_2F:
3945 tcg_gen_mul_tl(cpu_gpr[rd], t0, t1);
3948 case OPC_DMULTU_G_2E:
3949 case OPC_DMULTU_G_2F:
3950 tcg_gen_mul_tl(cpu_gpr[rd], t0, t1);
3956 TCGLabel *l1 = gen_new_label();
3957 TCGLabel *l2 = gen_new_label();
3958 TCGLabel *l3 = gen_new_label();
3959 tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
3960 tcg_gen_movi_tl(cpu_gpr[rd], 0);
3963 tcg_gen_brcondi_tl(TCG_COND_NE, t0, -1LL << 63, l2);
3964 tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1LL, l2);
3965 tcg_gen_mov_tl(cpu_gpr[rd], t0);
3968 tcg_gen_div_tl(cpu_gpr[rd], t0, t1);
3973 case OPC_DDIVU_G_2E:
3974 case OPC_DDIVU_G_2F:
3976 TCGLabel *l1 = gen_new_label();
3977 TCGLabel *l2 = gen_new_label();
3978 tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
3979 tcg_gen_movi_tl(cpu_gpr[rd], 0);
3982 tcg_gen_divu_tl(cpu_gpr[rd], t0, t1);
3990 TCGLabel *l1 = gen_new_label();
3991 TCGLabel *l2 = gen_new_label();
3992 TCGLabel *l3 = gen_new_label();
3993 tcg_gen_brcondi_tl(TCG_COND_EQ, t1, 0, l1);
3994 tcg_gen_brcondi_tl(TCG_COND_NE, t0, -1LL << 63, l2);
3995 tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1LL, l2);
3997 tcg_gen_movi_tl(cpu_gpr[rd], 0);
4000 tcg_gen_rem_tl(cpu_gpr[rd], t0, t1);
4005 case OPC_DMODU_G_2E:
4006 case OPC_DMODU_G_2F:
4008 TCGLabel *l1 = gen_new_label();
4009 TCGLabel *l2 = gen_new_label();
4010 tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
4011 tcg_gen_movi_tl(cpu_gpr[rd], 0);
4014 tcg_gen_remu_tl(cpu_gpr[rd], t0, t1);
4022 (void)opn; /* avoid a compiler warning */
4023 MIPS_DEBUG("%s %s, %s", opn, regnames[rd], regnames[rs]);
4028 /* Loongson multimedia instructions */
4029 static void gen_loongson_multimedia(DisasContext *ctx, int rd, int rs, int rt)
4031 const char *opn = "loongson_cp2";
4032 uint32_t opc, shift_max;
4035 opc = MASK_LMI(ctx->opcode);
4041 t0 = tcg_temp_local_new_i64();
4042 t1 = tcg_temp_local_new_i64();
4045 t0 = tcg_temp_new_i64();
4046 t1 = tcg_temp_new_i64();
4050 gen_load_fpr64(ctx, t0, rs);
4051 gen_load_fpr64(ctx, t1, rt);
4053 #define LMI_HELPER(UP, LO) \
4054 case OPC_##UP: gen_helper_##LO(t0, t0, t1); opn = #LO; break
4055 #define LMI_HELPER_1(UP, LO) \
4056 case OPC_##UP: gen_helper_##LO(t0, t0); opn = #LO; break
4057 #define LMI_DIRECT(UP, LO, OP) \
4058 case OPC_##UP: tcg_gen_##OP##_i64(t0, t0, t1); opn = #LO; break
4061 LMI_HELPER(PADDSH, paddsh);
4062 LMI_HELPER(PADDUSH, paddush);
4063 LMI_HELPER(PADDH, paddh);
4064 LMI_HELPER(PADDW, paddw);
4065 LMI_HELPER(PADDSB, paddsb);
4066 LMI_HELPER(PADDUSB, paddusb);
4067 LMI_HELPER(PADDB, paddb);
4069 LMI_HELPER(PSUBSH, psubsh);
4070 LMI_HELPER(PSUBUSH, psubush);
4071 LMI_HELPER(PSUBH, psubh);
4072 LMI_HELPER(PSUBW, psubw);
4073 LMI_HELPER(PSUBSB, psubsb);
4074 LMI_HELPER(PSUBUSB, psubusb);
4075 LMI_HELPER(PSUBB, psubb);
4077 LMI_HELPER(PSHUFH, pshufh);
4078 LMI_HELPER(PACKSSWH, packsswh);
4079 LMI_HELPER(PACKSSHB, packsshb);
4080 LMI_HELPER(PACKUSHB, packushb);
4082 LMI_HELPER(PUNPCKLHW, punpcklhw);
4083 LMI_HELPER(PUNPCKHHW, punpckhhw);
4084 LMI_HELPER(PUNPCKLBH, punpcklbh);
4085 LMI_HELPER(PUNPCKHBH, punpckhbh);
4086 LMI_HELPER(PUNPCKLWD, punpcklwd);
4087 LMI_HELPER(PUNPCKHWD, punpckhwd);
4089 LMI_HELPER(PAVGH, pavgh);
4090 LMI_HELPER(PAVGB, pavgb);
4091 LMI_HELPER(PMAXSH, pmaxsh);
4092 LMI_HELPER(PMINSH, pminsh);
4093 LMI_HELPER(PMAXUB, pmaxub);
4094 LMI_HELPER(PMINUB, pminub);
4096 LMI_HELPER(PCMPEQW, pcmpeqw);
4097 LMI_HELPER(PCMPGTW, pcmpgtw);
4098 LMI_HELPER(PCMPEQH, pcmpeqh);
4099 LMI_HELPER(PCMPGTH, pcmpgth);
4100 LMI_HELPER(PCMPEQB, pcmpeqb);
4101 LMI_HELPER(PCMPGTB, pcmpgtb);
4103 LMI_HELPER(PSLLW, psllw);
4104 LMI_HELPER(PSLLH, psllh);
4105 LMI_HELPER(PSRLW, psrlw);
4106 LMI_HELPER(PSRLH, psrlh);
4107 LMI_HELPER(PSRAW, psraw);
4108 LMI_HELPER(PSRAH, psrah);
4110 LMI_HELPER(PMULLH, pmullh);
4111 LMI_HELPER(PMULHH, pmulhh);
4112 LMI_HELPER(PMULHUH, pmulhuh);
4113 LMI_HELPER(PMADDHW, pmaddhw);
4115 LMI_HELPER(PASUBUB, pasubub);
4116 LMI_HELPER_1(BIADD, biadd);
4117 LMI_HELPER_1(PMOVMSKB, pmovmskb);
4119 LMI_DIRECT(PADDD, paddd, add);
4120 LMI_DIRECT(PSUBD, psubd, sub);
4121 LMI_DIRECT(XOR_CP2, xor, xor);
4122 LMI_DIRECT(NOR_CP2, nor, nor);
4123 LMI_DIRECT(AND_CP2, and, and);
4124 LMI_DIRECT(PANDN, pandn, andc);
4125 LMI_DIRECT(OR, or, or);
4128 tcg_gen_deposit_i64(t0, t0, t1, 0, 16);
4132 tcg_gen_deposit_i64(t0, t0, t1, 16, 16);
4136 tcg_gen_deposit_i64(t0, t0, t1, 32, 16);
4140 tcg_gen_deposit_i64(t0, t0, t1, 48, 16);
4145 tcg_gen_andi_i64(t1, t1, 3);
4146 tcg_gen_shli_i64(t1, t1, 4);
4147 tcg_gen_shr_i64(t0, t0, t1);
4148 tcg_gen_ext16u_i64(t0, t0);
4153 tcg_gen_add_i64(t0, t0, t1);
4154 tcg_gen_ext32s_i64(t0, t0);
4158 tcg_gen_sub_i64(t0, t0, t1);
4159 tcg_gen_ext32s_i64(t0, t0);
4188 /* Make sure shift count isn't TCG undefined behaviour. */
4189 tcg_gen_andi_i64(t1, t1, shift_max - 1);
4194 tcg_gen_shl_i64(t0, t0, t1);
4198 /* Since SRA is UndefinedResult without sign-extended inputs,
4199 we can treat SRA and DSRA the same. */
4200 tcg_gen_sar_i64(t0, t0, t1);
4203 /* We want to shift in zeros for SRL; zero-extend first. */
4204 tcg_gen_ext32u_i64(t0, t0);
4207 tcg_gen_shr_i64(t0, t0, t1);
4211 if (shift_max == 32) {
4212 tcg_gen_ext32s_i64(t0, t0);
4215 /* Shifts larger than MAX produce zero. */
4216 tcg_gen_setcondi_i64(TCG_COND_LTU, t1, t1, shift_max);
4217 tcg_gen_neg_i64(t1, t1);
4218 tcg_gen_and_i64(t0, t0, t1);
4224 TCGv_i64 t2 = tcg_temp_new_i64();
4225 TCGLabel *lab = gen_new_label();
4227 tcg_gen_mov_i64(t2, t0);
4228 tcg_gen_add_i64(t0, t1, t2);
4229 if (opc == OPC_ADD_CP2) {
4230 tcg_gen_ext32s_i64(t0, t0);
4232 tcg_gen_xor_i64(t1, t1, t2);
4233 tcg_gen_xor_i64(t2, t2, t0);
4234 tcg_gen_andc_i64(t1, t2, t1);
4235 tcg_temp_free_i64(t2);
4236 tcg_gen_brcondi_i64(TCG_COND_GE, t1, 0, lab);
4237 generate_exception(ctx, EXCP_OVERFLOW);
4240 opn = (opc == OPC_ADD_CP2 ? "add" : "dadd");
4247 TCGv_i64 t2 = tcg_temp_new_i64();
4248 TCGLabel *lab = gen_new_label();
4250 tcg_gen_mov_i64(t2, t0);
4251 tcg_gen_sub_i64(t0, t1, t2);
4252 if (opc == OPC_SUB_CP2) {
4253 tcg_gen_ext32s_i64(t0, t0);
4255 tcg_gen_xor_i64(t1, t1, t2);
4256 tcg_gen_xor_i64(t2, t2, t0);
4257 tcg_gen_and_i64(t1, t1, t2);
4258 tcg_temp_free_i64(t2);
4259 tcg_gen_brcondi_i64(TCG_COND_GE, t1, 0, lab);
4260 generate_exception(ctx, EXCP_OVERFLOW);
4263 opn = (opc == OPC_SUB_CP2 ? "sub" : "dsub");
4268 tcg_gen_ext32u_i64(t0, t0);
4269 tcg_gen_ext32u_i64(t1, t1);
4270 tcg_gen_mul_i64(t0, t0, t1);
4280 /* ??? Document is unclear: Set FCC[CC]. Does that mean the
4281 FD field is the CC field? */
4284 generate_exception(ctx, EXCP_RI);
4291 gen_store_fpr64(ctx, t0, rd);
4293 (void)opn; /* avoid a compiler warning */
4294 MIPS_DEBUG("%s %s, %s, %s", opn,
4295 fregnames[rd], fregnames[rs], fregnames[rt]);
4296 tcg_temp_free_i64(t0);
4297 tcg_temp_free_i64(t1);
4301 static void gen_trap (DisasContext *ctx, uint32_t opc,
4302 int rs, int rt, int16_t imm)
4305 TCGv t0 = tcg_temp_new();
4306 TCGv t1 = tcg_temp_new();
4309 /* Load needed operands */
4317 /* Compare two registers */
4319 gen_load_gpr(t0, rs);
4320 gen_load_gpr(t1, rt);
4330 /* Compare register to immediate */
4331 if (rs != 0 || imm != 0) {
4332 gen_load_gpr(t0, rs);
4333 tcg_gen_movi_tl(t1, (int32_t)imm);
4340 case OPC_TEQ: /* rs == rs */
4341 case OPC_TEQI: /* r0 == 0 */
4342 case OPC_TGE: /* rs >= rs */
4343 case OPC_TGEI: /* r0 >= 0 */
4344 case OPC_TGEU: /* rs >= rs unsigned */
4345 case OPC_TGEIU: /* r0 >= 0 unsigned */
4347 generate_exception(ctx, EXCP_TRAP);
4349 case OPC_TLT: /* rs < rs */
4350 case OPC_TLTI: /* r0 < 0 */
4351 case OPC_TLTU: /* rs < rs unsigned */
4352 case OPC_TLTIU: /* r0 < 0 unsigned */
4353 case OPC_TNE: /* rs != rs */
4354 case OPC_TNEI: /* r0 != 0 */
4355 /* Never trap: treat as NOP. */
4359 TCGLabel *l1 = gen_new_label();
4364 tcg_gen_brcond_tl(TCG_COND_NE, t0, t1, l1);
4368 tcg_gen_brcond_tl(TCG_COND_LT, t0, t1, l1);
4372 tcg_gen_brcond_tl(TCG_COND_LTU, t0, t1, l1);
4376 tcg_gen_brcond_tl(TCG_COND_GE, t0, t1, l1);
4380 tcg_gen_brcond_tl(TCG_COND_GEU, t0, t1, l1);
4384 tcg_gen_brcond_tl(TCG_COND_EQ, t0, t1, l1);
4387 generate_exception(ctx, EXCP_TRAP);
4394 static inline void gen_goto_tb(DisasContext *ctx, int n, target_ulong dest)
4396 TranslationBlock *tb;
4398 if ((tb->pc & TARGET_PAGE_MASK) == (dest & TARGET_PAGE_MASK) &&
4399 likely(!ctx->singlestep_enabled)) {
4402 tcg_gen_exit_tb((uintptr_t)tb + n);
4405 if (ctx->singlestep_enabled) {
4406 save_cpu_state(ctx, 0);
4407 gen_helper_0e0i(raise_exception, EXCP_DEBUG);
4413 /* Branches (before delay slot) */
4414 static void gen_compute_branch (DisasContext *ctx, uint32_t opc,
4416 int rs, int rt, int32_t offset,
4419 target_ulong btgt = -1;
4421 int bcond_compute = 0;
4422 TCGv t0 = tcg_temp_new();
4423 TCGv t1 = tcg_temp_new();
4425 if (ctx->hflags & MIPS_HFLAG_BMASK) {
4426 #ifdef MIPS_DEBUG_DISAS
4427 LOG_DISAS("Branch in delay / forbidden slot at PC 0x"
4428 TARGET_FMT_lx "\n", ctx->pc);
4430 generate_exception(ctx, EXCP_RI);
4434 /* Load needed operands */
4440 /* Compare two registers */
4442 gen_load_gpr(t0, rs);
4443 gen_load_gpr(t1, rt);
4446 btgt = ctx->pc + insn_bytes + offset;
4460 /* Compare to zero */
4462 gen_load_gpr(t0, rs);
4465 btgt = ctx->pc + insn_bytes + offset;
4468 #if defined(TARGET_MIPS64)
4470 tcg_gen_andi_tl(t0, cpu_dspctrl, 0x7F);
4472 tcg_gen_andi_tl(t0, cpu_dspctrl, 0x3F);
4475 btgt = ctx->pc + insn_bytes + offset;
4480 /* Jump to immediate */
4481 btgt = ((ctx->pc + insn_bytes) & (int32_t)0xF0000000) | (uint32_t)offset;
4485 /* Jump to register */
4486 if (offset != 0 && offset != 16) {
4487 /* Hint = 0 is JR/JALR, hint 16 is JR.HB/JALR.HB, the
4488 others are reserved. */
4489 MIPS_INVAL("jump hint");
4490 generate_exception(ctx, EXCP_RI);
4493 gen_load_gpr(btarget, rs);
4496 MIPS_INVAL("branch/jump");
4497 generate_exception(ctx, EXCP_RI);
4500 if (bcond_compute == 0) {
4501 /* No condition to be computed */
4503 case OPC_BEQ: /* rx == rx */
4504 case OPC_BEQL: /* rx == rx likely */
4505 case OPC_BGEZ: /* 0 >= 0 */
4506 case OPC_BGEZL: /* 0 >= 0 likely */
4507 case OPC_BLEZ: /* 0 <= 0 */
4508 case OPC_BLEZL: /* 0 <= 0 likely */
4510 ctx->hflags |= MIPS_HFLAG_B;
4511 MIPS_DEBUG("balways");
4513 case OPC_BGEZAL: /* 0 >= 0 */
4514 case OPC_BGEZALL: /* 0 >= 0 likely */
4515 /* Always take and link */
4517 ctx->hflags |= MIPS_HFLAG_B;
4518 MIPS_DEBUG("balways and link");
4520 case OPC_BNE: /* rx != rx */
4521 case OPC_BGTZ: /* 0 > 0 */
4522 case OPC_BLTZ: /* 0 < 0 */
4524 MIPS_DEBUG("bnever (NOP)");
4526 case OPC_BLTZAL: /* 0 < 0 */
4527 /* Handle as an unconditional branch to get correct delay
4530 btgt = ctx->pc + insn_bytes + delayslot_size;
4531 ctx->hflags |= MIPS_HFLAG_B;
4532 MIPS_DEBUG("bnever and link");
4534 case OPC_BLTZALL: /* 0 < 0 likely */
4535 tcg_gen_movi_tl(cpu_gpr[31], ctx->pc + 8);
4536 /* Skip the instruction in the delay slot */
4537 MIPS_DEBUG("bnever, link and skip");
4540 case OPC_BNEL: /* rx != rx likely */
4541 case OPC_BGTZL: /* 0 > 0 likely */
4542 case OPC_BLTZL: /* 0 < 0 likely */
4543 /* Skip the instruction in the delay slot */
4544 MIPS_DEBUG("bnever and skip");
4548 ctx->hflags |= MIPS_HFLAG_B;
4549 MIPS_DEBUG("j " TARGET_FMT_lx, btgt);
4552 ctx->hflags |= MIPS_HFLAG_BX;
4556 ctx->hflags |= MIPS_HFLAG_B;
4557 MIPS_DEBUG("jal " TARGET_FMT_lx, btgt);
4560 ctx->hflags |= MIPS_HFLAG_BR;
4561 MIPS_DEBUG("jr %s", regnames[rs]);
4565 ctx->hflags |= MIPS_HFLAG_BR;
4566 MIPS_DEBUG("jalr %s, %s", regnames[rt], regnames[rs]);
4569 MIPS_INVAL("branch/jump");
4570 generate_exception(ctx, EXCP_RI);
4576 tcg_gen_setcond_tl(TCG_COND_EQ, bcond, t0, t1);
4577 MIPS_DEBUG("beq %s, %s, " TARGET_FMT_lx,
4578 regnames[rs], regnames[rt], btgt);
4581 tcg_gen_setcond_tl(TCG_COND_EQ, bcond, t0, t1);
4582 MIPS_DEBUG("beql %s, %s, " TARGET_FMT_lx,
4583 regnames[rs], regnames[rt], btgt);
4586 tcg_gen_setcond_tl(TCG_COND_NE, bcond, t0, t1);
4587 MIPS_DEBUG("bne %s, %s, " TARGET_FMT_lx,
4588 regnames[rs], regnames[rt], btgt);
4591 tcg_gen_setcond_tl(TCG_COND_NE, bcond, t0, t1);
4592 MIPS_DEBUG("bnel %s, %s, " TARGET_FMT_lx,
4593 regnames[rs], regnames[rt], btgt);
4596 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 0);
4597 MIPS_DEBUG("bgez %s, " TARGET_FMT_lx, regnames[rs], btgt);
4600 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 0);
4601 MIPS_DEBUG("bgezl %s, " TARGET_FMT_lx, regnames[rs], btgt);
4604 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 0);
4605 MIPS_DEBUG("bgezal %s, " TARGET_FMT_lx, regnames[rs], btgt);
4609 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 0);
4611 MIPS_DEBUG("bgezall %s, " TARGET_FMT_lx, regnames[rs], btgt);
4614 tcg_gen_setcondi_tl(TCG_COND_GT, bcond, t0, 0);
4615 MIPS_DEBUG("bgtz %s, " TARGET_FMT_lx, regnames[rs], btgt);
4618 tcg_gen_setcondi_tl(TCG_COND_GT, bcond, t0, 0);
4619 MIPS_DEBUG("bgtzl %s, " TARGET_FMT_lx, regnames[rs], btgt);
4622 tcg_gen_setcondi_tl(TCG_COND_LE, bcond, t0, 0);
4623 MIPS_DEBUG("blez %s, " TARGET_FMT_lx, regnames[rs], btgt);
4626 tcg_gen_setcondi_tl(TCG_COND_LE, bcond, t0, 0);
4627 MIPS_DEBUG("blezl %s, " TARGET_FMT_lx, regnames[rs], btgt);
4630 tcg_gen_setcondi_tl(TCG_COND_LT, bcond, t0, 0);
4631 MIPS_DEBUG("bltz %s, " TARGET_FMT_lx, regnames[rs], btgt);
4634 tcg_gen_setcondi_tl(TCG_COND_LT, bcond, t0, 0);
4635 MIPS_DEBUG("bltzl %s, " TARGET_FMT_lx, regnames[rs], btgt);
4638 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 32);
4639 MIPS_DEBUG("bposge32 " TARGET_FMT_lx, btgt);
4641 #if defined(TARGET_MIPS64)
4643 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 64);
4644 MIPS_DEBUG("bposge64 " TARGET_FMT_lx, btgt);
4648 tcg_gen_setcondi_tl(TCG_COND_LT, bcond, t0, 0);
4650 MIPS_DEBUG("bltzal %s, " TARGET_FMT_lx, regnames[rs], btgt);
4652 ctx->hflags |= MIPS_HFLAG_BC;
4655 tcg_gen_setcondi_tl(TCG_COND_LT, bcond, t0, 0);
4657 MIPS_DEBUG("bltzall %s, " TARGET_FMT_lx, regnames[rs], btgt);
4659 ctx->hflags |= MIPS_HFLAG_BL;
4662 MIPS_INVAL("conditional branch/jump");
4663 generate_exception(ctx, EXCP_RI);
4667 MIPS_DEBUG("enter ds: link %d cond %02x target " TARGET_FMT_lx,
4668 blink, ctx->hflags, btgt);
4670 ctx->btarget = btgt;
4672 switch (delayslot_size) {
4674 ctx->hflags |= MIPS_HFLAG_BDS16;
4677 ctx->hflags |= MIPS_HFLAG_BDS32;
4682 int post_delay = insn_bytes + delayslot_size;
4683 int lowbit = !!(ctx->hflags & MIPS_HFLAG_M16);
4685 tcg_gen_movi_tl(cpu_gpr[blink], ctx->pc + post_delay + lowbit);
4689 if (insn_bytes == 2)
4690 ctx->hflags |= MIPS_HFLAG_B16;
4695 /* special3 bitfield operations */
4696 static void gen_bitops (DisasContext *ctx, uint32_t opc, int rt,
4697 int rs, int lsb, int msb)
4699 TCGv t0 = tcg_temp_new();
4700 TCGv t1 = tcg_temp_new();
4702 gen_load_gpr(t1, rs);
4707 tcg_gen_shri_tl(t0, t1, lsb);
4709 tcg_gen_andi_tl(t0, t0, (1 << (msb + 1)) - 1);
4711 tcg_gen_ext32s_tl(t0, t0);
4714 #if defined(TARGET_MIPS64)
4716 tcg_gen_shri_tl(t0, t1, lsb);
4718 tcg_gen_andi_tl(t0, t0, (1ULL << (msb + 1 + 32)) - 1);
4722 tcg_gen_shri_tl(t0, t1, lsb + 32);
4723 tcg_gen_andi_tl(t0, t0, (1ULL << (msb + 1)) - 1);
4726 tcg_gen_shri_tl(t0, t1, lsb);
4727 tcg_gen_andi_tl(t0, t0, (1ULL << (msb + 1)) - 1);
4733 gen_load_gpr(t0, rt);
4734 tcg_gen_deposit_tl(t0, t0, t1, lsb, msb - lsb + 1);
4735 tcg_gen_ext32s_tl(t0, t0);
4737 #if defined(TARGET_MIPS64)
4739 gen_load_gpr(t0, rt);
4740 tcg_gen_deposit_tl(t0, t0, t1, lsb, msb + 32 - lsb + 1);
4743 gen_load_gpr(t0, rt);
4744 tcg_gen_deposit_tl(t0, t0, t1, lsb + 32, msb - lsb + 1);
4747 gen_load_gpr(t0, rt);
4748 tcg_gen_deposit_tl(t0, t0, t1, lsb, msb - lsb + 1);
4753 MIPS_INVAL("bitops");
4754 generate_exception(ctx, EXCP_RI);
4759 gen_store_gpr(t0, rt);
4764 static void gen_bshfl (DisasContext *ctx, uint32_t op2, int rt, int rd)
4769 /* If no destination, treat it as a NOP. */
4774 t0 = tcg_temp_new();
4775 gen_load_gpr(t0, rt);
4779 TCGv t1 = tcg_temp_new();
4781 tcg_gen_shri_tl(t1, t0, 8);
4782 tcg_gen_andi_tl(t1, t1, 0x00FF00FF);
4783 tcg_gen_shli_tl(t0, t0, 8);
4784 tcg_gen_andi_tl(t0, t0, ~0x00FF00FF);
4785 tcg_gen_or_tl(t0, t0, t1);
4787 tcg_gen_ext32s_tl(cpu_gpr[rd], t0);
4791 tcg_gen_ext8s_tl(cpu_gpr[rd], t0);
4794 tcg_gen_ext16s_tl(cpu_gpr[rd], t0);
4796 #if defined(TARGET_MIPS64)
4799 TCGv t1 = tcg_temp_new();
4801 tcg_gen_shri_tl(t1, t0, 8);
4802 tcg_gen_andi_tl(t1, t1, 0x00FF00FF00FF00FFULL);
4803 tcg_gen_shli_tl(t0, t0, 8);
4804 tcg_gen_andi_tl(t0, t0, ~0x00FF00FF00FF00FFULL);
4805 tcg_gen_or_tl(cpu_gpr[rd], t0, t1);
4811 TCGv t1 = tcg_temp_new();
4813 tcg_gen_shri_tl(t1, t0, 16);
4814 tcg_gen_andi_tl(t1, t1, 0x0000FFFF0000FFFFULL);
4815 tcg_gen_shli_tl(t0, t0, 16);
4816 tcg_gen_andi_tl(t0, t0, ~0x0000FFFF0000FFFFULL);
4817 tcg_gen_or_tl(t0, t0, t1);
4818 tcg_gen_shri_tl(t1, t0, 32);
4819 tcg_gen_shli_tl(t0, t0, 32);
4820 tcg_gen_or_tl(cpu_gpr[rd], t0, t1);
4826 MIPS_INVAL("bsfhl");
4827 generate_exception(ctx, EXCP_RI);
4834 #ifndef CONFIG_USER_ONLY
4835 /* CP0 (MMU and control) */
4836 static inline void gen_move_low32(TCGv ret, TCGv_i64 arg)
4838 #if defined(TARGET_MIPS64)
4839 tcg_gen_ext32s_tl(ret, arg);
4841 tcg_gen_trunc_i64_tl(ret, arg);
4845 static inline void gen_mfc0_load32 (TCGv arg, target_ulong off)
4847 TCGv_i32 t0 = tcg_temp_new_i32();
4849 tcg_gen_ld_i32(t0, cpu_env, off);
4850 tcg_gen_ext_i32_tl(arg, t0);
4851 tcg_temp_free_i32(t0);
4854 static inline void gen_mfc0_load64 (TCGv arg, target_ulong off)
4856 tcg_gen_ld_tl(arg, cpu_env, off);
4857 tcg_gen_ext32s_tl(arg, arg);
4860 static inline void gen_mtc0_store32 (TCGv arg, target_ulong off)
4862 TCGv_i32 t0 = tcg_temp_new_i32();
4864 tcg_gen_trunc_tl_i32(t0, arg);
4865 tcg_gen_st_i32(t0, cpu_env, off);
4866 tcg_temp_free_i32(t0);
4869 static inline void gen_mtc0_store64 (TCGv arg, target_ulong off)
4871 tcg_gen_ext32s_tl(arg, arg);
4872 tcg_gen_st_tl(arg, cpu_env, off);
4875 static inline void gen_mfc0_unimplemented(DisasContext *ctx, TCGv arg)
4877 if (ctx->insn_flags & ISA_MIPS32R6) {
4878 tcg_gen_movi_tl(arg, 0);
4880 tcg_gen_movi_tl(arg, ~0);
4884 #define CP0_CHECK(c) \
4887 goto cp0_unimplemented; \
4891 static void gen_mfc0(DisasContext *ctx, TCGv arg, int reg, int sel)
4893 const char *rn = "invalid";
4896 check_insn(ctx, ISA_MIPS32);
4902 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Index));
4906 CP0_CHECK(ctx->insn_flags & ASE_MT);
4907 gen_helper_mfc0_mvpcontrol(arg, cpu_env);
4911 CP0_CHECK(ctx->insn_flags & ASE_MT);
4912 gen_helper_mfc0_mvpconf0(arg, cpu_env);
4916 CP0_CHECK(ctx->insn_flags & ASE_MT);
4917 gen_helper_mfc0_mvpconf1(arg, cpu_env);
4921 goto cp0_unimplemented;
4927 CP0_CHECK(!(ctx->insn_flags & ISA_MIPS32R6));
4928 gen_helper_mfc0_random(arg, cpu_env);
4932 CP0_CHECK(ctx->insn_flags & ASE_MT);
4933 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEControl));
4937 CP0_CHECK(ctx->insn_flags & ASE_MT);
4938 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEConf0));
4942 CP0_CHECK(ctx->insn_flags & ASE_MT);
4943 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEConf1));
4947 CP0_CHECK(ctx->insn_flags & ASE_MT);
4948 gen_mfc0_load64(arg, offsetof(CPUMIPSState, CP0_YQMask));
4952 CP0_CHECK(ctx->insn_flags & ASE_MT);
4953 gen_mfc0_load64(arg, offsetof(CPUMIPSState, CP0_VPESchedule));
4957 CP0_CHECK(ctx->insn_flags & ASE_MT);
4958 gen_mfc0_load64(arg, offsetof(CPUMIPSState, CP0_VPEScheFBack));
4959 rn = "VPEScheFBack";
4962 CP0_CHECK(ctx->insn_flags & ASE_MT);
4963 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEOpt));
4967 goto cp0_unimplemented;
4974 TCGv_i64 tmp = tcg_temp_new_i64();
4975 tcg_gen_ld_i64(tmp, cpu_env,
4976 offsetof(CPUMIPSState, CP0_EntryLo0));
4977 #if defined(TARGET_MIPS64)
4979 /* Move RI/XI fields to bits 31:30 */
4980 tcg_gen_shri_tl(arg, tmp, CP0EnLo_XI);
4981 tcg_gen_deposit_tl(tmp, tmp, arg, 30, 2);
4984 gen_move_low32(arg, tmp);
4985 tcg_temp_free_i64(tmp);
4990 CP0_CHECK(ctx->insn_flags & ASE_MT);
4991 gen_helper_mfc0_tcstatus(arg, cpu_env);
4995 CP0_CHECK(ctx->insn_flags & ASE_MT);
4996 gen_helper_mfc0_tcbind(arg, cpu_env);
5000 CP0_CHECK(ctx->insn_flags & ASE_MT);
5001 gen_helper_mfc0_tcrestart(arg, cpu_env);
5005 CP0_CHECK(ctx->insn_flags & ASE_MT);
5006 gen_helper_mfc0_tchalt(arg, cpu_env);
5010 CP0_CHECK(ctx->insn_flags & ASE_MT);
5011 gen_helper_mfc0_tccontext(arg, cpu_env);
5015 CP0_CHECK(ctx->insn_flags & ASE_MT);
5016 gen_helper_mfc0_tcschedule(arg, cpu_env);
5020 CP0_CHECK(ctx->insn_flags & ASE_MT);
5021 gen_helper_mfc0_tcschefback(arg, cpu_env);
5025 goto cp0_unimplemented;
5032 TCGv_i64 tmp = tcg_temp_new_i64();
5033 tcg_gen_ld_i64(tmp, cpu_env,
5034 offsetof(CPUMIPSState, CP0_EntryLo1));
5035 #if defined(TARGET_MIPS64)
5037 /* Move RI/XI fields to bits 31:30 */
5038 tcg_gen_shri_tl(arg, tmp, CP0EnLo_XI);
5039 tcg_gen_deposit_tl(tmp, tmp, arg, 30, 2);
5042 gen_move_low32(arg, tmp);
5043 tcg_temp_free_i64(tmp);
5048 goto cp0_unimplemented;
5054 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_Context));
5055 tcg_gen_ext32s_tl(arg, arg);
5059 // gen_helper_mfc0_contextconfig(arg); /* SmartMIPS ASE */
5060 rn = "ContextConfig";
5061 goto cp0_unimplemented;
5064 CP0_CHECK(ctx->ulri);
5065 tcg_gen_ld32s_tl(arg, cpu_env,
5066 offsetof(CPUMIPSState, active_tc.CP0_UserLocal));
5070 goto cp0_unimplemented;
5076 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PageMask));
5080 check_insn(ctx, ISA_MIPS32R2);
5081 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PageGrain));
5085 goto cp0_unimplemented;
5091 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Wired));
5095 check_insn(ctx, ISA_MIPS32R2);
5096 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf0));
5100 check_insn(ctx, ISA_MIPS32R2);
5101 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf1));
5105 check_insn(ctx, ISA_MIPS32R2);
5106 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf2));
5110 check_insn(ctx, ISA_MIPS32R2);
5111 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf3));
5115 check_insn(ctx, ISA_MIPS32R2);
5116 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf4));
5120 goto cp0_unimplemented;
5126 check_insn(ctx, ISA_MIPS32R2);
5127 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_HWREna));
5131 goto cp0_unimplemented;
5137 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_BadVAddr));
5138 tcg_gen_ext32s_tl(arg, arg);
5143 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_BadInstr));
5148 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_BadInstrP));
5152 goto cp0_unimplemented;
5158 /* Mark as an IO operation because we read the time. */
5159 if (ctx->tb->cflags & CF_USE_ICOUNT) {
5162 gen_helper_mfc0_count(arg, cpu_env);
5163 if (ctx->tb->cflags & CF_USE_ICOUNT) {
5166 /* Break the TB to be able to take timer interrupts immediately
5167 after reading count. */
5168 ctx->bstate = BS_STOP;
5171 /* 6,7 are implementation dependent */
5173 goto cp0_unimplemented;
5179 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EntryHi));
5180 tcg_gen_ext32s_tl(arg, arg);
5184 goto cp0_unimplemented;
5190 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Compare));
5193 /* 6,7 are implementation dependent */
5195 goto cp0_unimplemented;
5201 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Status));
5205 check_insn(ctx, ISA_MIPS32R2);
5206 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_IntCtl));
5210 check_insn(ctx, ISA_MIPS32R2);
5211 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSCtl));
5215 check_insn(ctx, ISA_MIPS32R2);
5216 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSMap));
5220 goto cp0_unimplemented;
5226 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Cause));
5230 goto cp0_unimplemented;
5236 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EPC));
5237 tcg_gen_ext32s_tl(arg, arg);
5241 goto cp0_unimplemented;
5247 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PRid));
5251 check_insn(ctx, ISA_MIPS32R2);
5252 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_EBase));
5256 goto cp0_unimplemented;
5262 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config0));
5266 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config1));
5270 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config2));
5274 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config3));
5278 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config4));
5282 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config5));
5285 /* 6,7 are implementation dependent */
5287 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config6));
5291 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config7));
5295 goto cp0_unimplemented;
5301 gen_helper_mfc0_lladdr(arg, cpu_env);
5305 goto cp0_unimplemented;
5311 gen_helper_1e0i(mfc0_watchlo, arg, sel);
5315 goto cp0_unimplemented;
5321 gen_helper_1e0i(mfc0_watchhi, arg, sel);
5325 goto cp0_unimplemented;
5331 #if defined(TARGET_MIPS64)
5332 check_insn(ctx, ISA_MIPS3);
5333 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_XContext));
5334 tcg_gen_ext32s_tl(arg, arg);
5339 goto cp0_unimplemented;
5343 /* Officially reserved, but sel 0 is used for R1x000 framemask */
5344 CP0_CHECK(!(ctx->insn_flags & ISA_MIPS32R6));
5347 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Framemask));
5351 goto cp0_unimplemented;
5355 tcg_gen_movi_tl(arg, 0); /* unimplemented */
5356 rn = "'Diagnostic"; /* implementation dependent */
5361 gen_helper_mfc0_debug(arg, cpu_env); /* EJTAG support */
5365 // gen_helper_mfc0_tracecontrol(arg); /* PDtrace support */
5366 rn = "TraceControl";
5369 // gen_helper_mfc0_tracecontrol2(arg); /* PDtrace support */
5370 rn = "TraceControl2";
5373 // gen_helper_mfc0_usertracedata(arg); /* PDtrace support */
5374 rn = "UserTraceData";
5377 // gen_helper_mfc0_tracebpc(arg); /* PDtrace support */
5381 goto cp0_unimplemented;
5388 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_DEPC));
5389 tcg_gen_ext32s_tl(arg, arg);
5393 goto cp0_unimplemented;
5399 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Performance0));
5400 rn = "Performance0";
5403 // gen_helper_mfc0_performance1(arg);
5404 rn = "Performance1";
5407 // gen_helper_mfc0_performance2(arg);
5408 rn = "Performance2";
5411 // gen_helper_mfc0_performance3(arg);
5412 rn = "Performance3";
5415 // gen_helper_mfc0_performance4(arg);
5416 rn = "Performance4";
5419 // gen_helper_mfc0_performance5(arg);
5420 rn = "Performance5";
5423 // gen_helper_mfc0_performance6(arg);
5424 rn = "Performance6";
5427 // gen_helper_mfc0_performance7(arg);
5428 rn = "Performance7";
5431 goto cp0_unimplemented;
5435 tcg_gen_movi_tl(arg, 0); /* unimplemented */
5441 tcg_gen_movi_tl(arg, 0); /* unimplemented */
5445 goto cp0_unimplemented;
5455 TCGv_i64 tmp = tcg_temp_new_i64();
5456 tcg_gen_ld_i64(tmp, cpu_env, offsetof(CPUMIPSState, CP0_TagLo));
5457 gen_move_low32(arg, tmp);
5458 tcg_temp_free_i64(tmp);
5466 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DataLo));
5470 goto cp0_unimplemented;
5479 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_TagHi));
5486 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DataHi));
5490 goto cp0_unimplemented;
5496 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_ErrorEPC));
5497 tcg_gen_ext32s_tl(arg, arg);
5501 goto cp0_unimplemented;
5508 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DESAVE));
5512 CP0_CHECK(ctx->kscrexist & (1 << sel));
5513 tcg_gen_ld_tl(arg, cpu_env,
5514 offsetof(CPUMIPSState, CP0_KScratch[sel-2]));
5515 tcg_gen_ext32s_tl(arg, arg);
5519 goto cp0_unimplemented;
5523 goto cp0_unimplemented;
5525 (void)rn; /* avoid a compiler warning */
5526 LOG_DISAS("mfc0 %s (reg %d sel %d)\n", rn, reg, sel);
5530 LOG_DISAS("mfc0 %s (reg %d sel %d)\n", rn, reg, sel);
5531 gen_mfc0_unimplemented(ctx, arg);
5534 static void gen_mtc0(DisasContext *ctx, TCGv arg, int reg, int sel)
5536 const char *rn = "invalid";
5539 check_insn(ctx, ISA_MIPS32);
5541 if (ctx->tb->cflags & CF_USE_ICOUNT) {
5549 gen_helper_mtc0_index(cpu_env, arg);
5553 CP0_CHECK(ctx->insn_flags & ASE_MT);
5554 gen_helper_mtc0_mvpcontrol(cpu_env, arg);
5558 CP0_CHECK(ctx->insn_flags & ASE_MT);
5563 CP0_CHECK(ctx->insn_flags & ASE_MT);
5568 goto cp0_unimplemented;
5578 CP0_CHECK(ctx->insn_flags & ASE_MT);
5579 gen_helper_mtc0_vpecontrol(cpu_env, arg);
5583 CP0_CHECK(ctx->insn_flags & ASE_MT);
5584 gen_helper_mtc0_vpeconf0(cpu_env, arg);
5588 CP0_CHECK(ctx->insn_flags & ASE_MT);
5589 gen_helper_mtc0_vpeconf1(cpu_env, arg);
5593 CP0_CHECK(ctx->insn_flags & ASE_MT);
5594 gen_helper_mtc0_yqmask(cpu_env, arg);
5598 CP0_CHECK(ctx->insn_flags & ASE_MT);
5599 gen_mtc0_store64(arg, offsetof(CPUMIPSState, CP0_VPESchedule));
5603 CP0_CHECK(ctx->insn_flags & ASE_MT);
5604 gen_mtc0_store64(arg, offsetof(CPUMIPSState, CP0_VPEScheFBack));
5605 rn = "VPEScheFBack";
5608 CP0_CHECK(ctx->insn_flags & ASE_MT);
5609 gen_helper_mtc0_vpeopt(cpu_env, arg);
5613 goto cp0_unimplemented;
5619 gen_helper_mtc0_entrylo0(cpu_env, arg);
5623 CP0_CHECK(ctx->insn_flags & ASE_MT);
5624 gen_helper_mtc0_tcstatus(cpu_env, arg);
5628 CP0_CHECK(ctx->insn_flags & ASE_MT);
5629 gen_helper_mtc0_tcbind(cpu_env, arg);
5633 CP0_CHECK(ctx->insn_flags & ASE_MT);
5634 gen_helper_mtc0_tcrestart(cpu_env, arg);
5638 CP0_CHECK(ctx->insn_flags & ASE_MT);
5639 gen_helper_mtc0_tchalt(cpu_env, arg);
5643 CP0_CHECK(ctx->insn_flags & ASE_MT);
5644 gen_helper_mtc0_tccontext(cpu_env, arg);
5648 CP0_CHECK(ctx->insn_flags & ASE_MT);
5649 gen_helper_mtc0_tcschedule(cpu_env, arg);
5653 CP0_CHECK(ctx->insn_flags & ASE_MT);
5654 gen_helper_mtc0_tcschefback(cpu_env, arg);
5658 goto cp0_unimplemented;
5664 gen_helper_mtc0_entrylo1(cpu_env, arg);
5668 goto cp0_unimplemented;
5674 gen_helper_mtc0_context(cpu_env, arg);
5678 // gen_helper_mtc0_contextconfig(cpu_env, arg); /* SmartMIPS ASE */
5679 rn = "ContextConfig";
5680 goto cp0_unimplemented;
5683 CP0_CHECK(ctx->ulri);
5684 tcg_gen_st_tl(arg, cpu_env,
5685 offsetof(CPUMIPSState, active_tc.CP0_UserLocal));
5689 goto cp0_unimplemented;
5695 gen_helper_mtc0_pagemask(cpu_env, arg);
5699 check_insn(ctx, ISA_MIPS32R2);
5700 gen_helper_mtc0_pagegrain(cpu_env, arg);
5704 goto cp0_unimplemented;
5710 gen_helper_mtc0_wired(cpu_env, arg);
5714 check_insn(ctx, ISA_MIPS32R2);
5715 gen_helper_mtc0_srsconf0(cpu_env, arg);
5719 check_insn(ctx, ISA_MIPS32R2);
5720 gen_helper_mtc0_srsconf1(cpu_env, arg);
5724 check_insn(ctx, ISA_MIPS32R2);
5725 gen_helper_mtc0_srsconf2(cpu_env, arg);
5729 check_insn(ctx, ISA_MIPS32R2);
5730 gen_helper_mtc0_srsconf3(cpu_env, arg);
5734 check_insn(ctx, ISA_MIPS32R2);
5735 gen_helper_mtc0_srsconf4(cpu_env, arg);
5739 goto cp0_unimplemented;
5745 check_insn(ctx, ISA_MIPS32R2);
5746 gen_helper_mtc0_hwrena(cpu_env, arg);
5747 ctx->bstate = BS_STOP;
5751 goto cp0_unimplemented;
5769 goto cp0_unimplemented;
5775 gen_helper_mtc0_count(cpu_env, arg);
5778 /* 6,7 are implementation dependent */
5780 goto cp0_unimplemented;
5786 gen_helper_mtc0_entryhi(cpu_env, arg);
5790 goto cp0_unimplemented;
5796 gen_helper_mtc0_compare(cpu_env, arg);
5799 /* 6,7 are implementation dependent */
5801 goto cp0_unimplemented;
5807 save_cpu_state(ctx, 1);
5808 gen_helper_mtc0_status(cpu_env, arg);
5809 /* BS_STOP isn't good enough here, hflags may have changed. */
5810 gen_save_pc(ctx->pc + 4);
5811 ctx->bstate = BS_EXCP;
5815 check_insn(ctx, ISA_MIPS32R2);
5816 gen_helper_mtc0_intctl(cpu_env, arg);
5817 /* Stop translation as we may have switched the execution mode */
5818 ctx->bstate = BS_STOP;
5822 check_insn(ctx, ISA_MIPS32R2);
5823 gen_helper_mtc0_srsctl(cpu_env, arg);
5824 /* Stop translation as we may have switched the execution mode */
5825 ctx->bstate = BS_STOP;
5829 check_insn(ctx, ISA_MIPS32R2);
5830 gen_mtc0_store32(arg, offsetof(CPUMIPSState, CP0_SRSMap));
5831 /* Stop translation as we may have switched the execution mode */
5832 ctx->bstate = BS_STOP;
5836 goto cp0_unimplemented;
5842 save_cpu_state(ctx, 1);
5843 gen_helper_mtc0_cause(cpu_env, arg);
5847 goto cp0_unimplemented;
5853 gen_mtc0_store64(arg, offsetof(CPUMIPSState, CP0_EPC));
5857 goto cp0_unimplemented;
5867 check_insn(ctx, ISA_MIPS32R2);
5868 gen_helper_mtc0_ebase(cpu_env, arg);
5872 goto cp0_unimplemented;
5878 gen_helper_mtc0_config0(cpu_env, arg);
5880 /* Stop translation as we may have switched the execution mode */
5881 ctx->bstate = BS_STOP;
5884 /* ignored, read only */
5888 gen_helper_mtc0_config2(cpu_env, arg);
5890 /* Stop translation as we may have switched the execution mode */
5891 ctx->bstate = BS_STOP;
5894 gen_helper_mtc0_config3(cpu_env, arg);
5896 /* Stop translation as we may have switched the execution mode */
5897 ctx->bstate = BS_STOP;
5900 gen_helper_mtc0_config4(cpu_env, arg);
5902 ctx->bstate = BS_STOP;
5905 gen_helper_mtc0_config5(cpu_env, arg);
5907 /* Stop translation as we may have switched the execution mode */
5908 ctx->bstate = BS_STOP;
5910 /* 6,7 are implementation dependent */
5920 rn = "Invalid config selector";
5921 goto cp0_unimplemented;
5927 gen_helper_mtc0_lladdr(cpu_env, arg);
5931 goto cp0_unimplemented;
5937 gen_helper_0e1i(mtc0_watchlo, arg, sel);
5941 goto cp0_unimplemented;
5947 gen_helper_0e1i(mtc0_watchhi, arg, sel);
5951 goto cp0_unimplemented;
5957 #if defined(TARGET_MIPS64)
5958 check_insn(ctx, ISA_MIPS3);
5959 gen_helper_mtc0_xcontext(cpu_env, arg);
5964 goto cp0_unimplemented;
5968 /* Officially reserved, but sel 0 is used for R1x000 framemask */
5969 CP0_CHECK(!(ctx->insn_flags & ISA_MIPS32R6));
5972 gen_helper_mtc0_framemask(cpu_env, arg);
5976 goto cp0_unimplemented;
5981 rn = "Diagnostic"; /* implementation dependent */
5986 gen_helper_mtc0_debug(cpu_env, arg); /* EJTAG support */
5987 /* BS_STOP isn't good enough here, hflags may have changed. */
5988 gen_save_pc(ctx->pc + 4);
5989 ctx->bstate = BS_EXCP;
5993 // gen_helper_mtc0_tracecontrol(cpu_env, arg); /* PDtrace support */
5994 rn = "TraceControl";
5995 /* Stop translation as we may have switched the execution mode */
5996 ctx->bstate = BS_STOP;
5999 // gen_helper_mtc0_tracecontrol2(cpu_env, arg); /* PDtrace support */
6000 rn = "TraceControl2";
6001 /* Stop translation as we may have switched the execution mode */
6002 ctx->bstate = BS_STOP;
6005 /* Stop translation as we may have switched the execution mode */
6006 ctx->bstate = BS_STOP;
6007 // gen_helper_mtc0_usertracedata(cpu_env, arg); /* PDtrace support */
6008 rn = "UserTraceData";
6009 /* Stop translation as we may have switched the execution mode */
6010 ctx->bstate = BS_STOP;
6013 // gen_helper_mtc0_tracebpc(cpu_env, arg); /* PDtrace support */
6014 /* Stop translation as we may have switched the execution mode */
6015 ctx->bstate = BS_STOP;
6019 goto cp0_unimplemented;
6026 gen_mtc0_store64(arg, offsetof(CPUMIPSState, CP0_DEPC));
6030 goto cp0_unimplemented;
6036 gen_helper_mtc0_performance0(cpu_env, arg);
6037 rn = "Performance0";
6040 // gen_helper_mtc0_performance1(arg);
6041 rn = "Performance1";
6044 // gen_helper_mtc0_performance2(arg);
6045 rn = "Performance2";
6048 // gen_helper_mtc0_performance3(arg);
6049 rn = "Performance3";
6052 // gen_helper_mtc0_performance4(arg);
6053 rn = "Performance4";
6056 // gen_helper_mtc0_performance5(arg);
6057 rn = "Performance5";
6060 // gen_helper_mtc0_performance6(arg);
6061 rn = "Performance6";
6064 // gen_helper_mtc0_performance7(arg);
6065 rn = "Performance7";
6068 goto cp0_unimplemented;
6082 goto cp0_unimplemented;
6091 gen_helper_mtc0_taglo(cpu_env, arg);
6098 gen_helper_mtc0_datalo(cpu_env, arg);
6102 goto cp0_unimplemented;
6111 gen_helper_mtc0_taghi(cpu_env, arg);
6118 gen_helper_mtc0_datahi(cpu_env, arg);
6123 goto cp0_unimplemented;
6129 gen_mtc0_store64(arg, offsetof(CPUMIPSState, CP0_ErrorEPC));
6133 goto cp0_unimplemented;
6140 gen_mtc0_store32(arg, offsetof(CPUMIPSState, CP0_DESAVE));
6144 CP0_CHECK(ctx->kscrexist & (1 << sel));
6145 tcg_gen_st_tl(arg, cpu_env,
6146 offsetof(CPUMIPSState, CP0_KScratch[sel-2]));
6150 goto cp0_unimplemented;
6152 /* Stop translation as we may have switched the execution mode */
6153 ctx->bstate = BS_STOP;
6156 goto cp0_unimplemented;
6158 (void)rn; /* avoid a compiler warning */
6159 LOG_DISAS("mtc0 %s (reg %d sel %d)\n", rn, reg, sel);
6160 /* For simplicity assume that all writes can cause interrupts. */
6161 if (ctx->tb->cflags & CF_USE_ICOUNT) {
6163 ctx->bstate = BS_STOP;
6168 LOG_DISAS("mtc0 %s (reg %d sel %d)\n", rn, reg, sel);
6171 #if defined(TARGET_MIPS64)
6172 static void gen_dmfc0(DisasContext *ctx, TCGv arg, int reg, int sel)
6174 const char *rn = "invalid";
6177 check_insn(ctx, ISA_MIPS64);
6183 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Index));
6187 CP0_CHECK(ctx->insn_flags & ASE_MT);
6188 gen_helper_mfc0_mvpcontrol(arg, cpu_env);
6192 CP0_CHECK(ctx->insn_flags & ASE_MT);
6193 gen_helper_mfc0_mvpconf0(arg, cpu_env);
6197 CP0_CHECK(ctx->insn_flags & ASE_MT);
6198 gen_helper_mfc0_mvpconf1(arg, cpu_env);
6202 goto cp0_unimplemented;
6208 CP0_CHECK(!(ctx->insn_flags & ISA_MIPS32R6));
6209 gen_helper_mfc0_random(arg, cpu_env);
6213 CP0_CHECK(ctx->insn_flags & ASE_MT);
6214 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEControl));
6218 CP0_CHECK(ctx->insn_flags & ASE_MT);
6219 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEConf0));
6223 CP0_CHECK(ctx->insn_flags & ASE_MT);
6224 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEConf1));
6228 CP0_CHECK(ctx->insn_flags & ASE_MT);
6229 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_YQMask));
6233 CP0_CHECK(ctx->insn_flags & ASE_MT);
6234 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_VPESchedule));
6238 CP0_CHECK(ctx->insn_flags & ASE_MT);
6239 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_VPEScheFBack));
6240 rn = "VPEScheFBack";
6243 CP0_CHECK(ctx->insn_flags & ASE_MT);
6244 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEOpt));
6248 goto cp0_unimplemented;
6254 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EntryLo0));
6258 CP0_CHECK(ctx->insn_flags & ASE_MT);
6259 gen_helper_mfc0_tcstatus(arg, cpu_env);
6263 CP0_CHECK(ctx->insn_flags & ASE_MT);
6264 gen_helper_mfc0_tcbind(arg, cpu_env);
6268 CP0_CHECK(ctx->insn_flags & ASE_MT);
6269 gen_helper_dmfc0_tcrestart(arg, cpu_env);
6273 CP0_CHECK(ctx->insn_flags & ASE_MT);
6274 gen_helper_dmfc0_tchalt(arg, cpu_env);
6278 CP0_CHECK(ctx->insn_flags & ASE_MT);
6279 gen_helper_dmfc0_tccontext(arg, cpu_env);
6283 CP0_CHECK(ctx->insn_flags & ASE_MT);
6284 gen_helper_dmfc0_tcschedule(arg, cpu_env);
6288 CP0_CHECK(ctx->insn_flags & ASE_MT);
6289 gen_helper_dmfc0_tcschefback(arg, cpu_env);
6293 goto cp0_unimplemented;
6299 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EntryLo1));
6303 goto cp0_unimplemented;
6309 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_Context));
6313 // gen_helper_dmfc0_contextconfig(arg); /* SmartMIPS ASE */
6314 rn = "ContextConfig";
6315 goto cp0_unimplemented;
6318 CP0_CHECK(ctx->ulri);
6319 tcg_gen_ld_tl(arg, cpu_env,
6320 offsetof(CPUMIPSState, active_tc.CP0_UserLocal));
6324 goto cp0_unimplemented;
6330 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PageMask));
6334 check_insn(ctx, ISA_MIPS32R2);
6335 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PageGrain));
6339 goto cp0_unimplemented;
6345 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Wired));
6349 check_insn(ctx, ISA_MIPS32R2);
6350 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf0));
6354 check_insn(ctx, ISA_MIPS32R2);
6355 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf1));
6359 check_insn(ctx, ISA_MIPS32R2);
6360 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf2));
6364 check_insn(ctx, ISA_MIPS32R2);
6365 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf3));
6369 check_insn(ctx, ISA_MIPS32R2);
6370 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf4));
6374 goto cp0_unimplemented;
6380 check_insn(ctx, ISA_MIPS32R2);
6381 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_HWREna));
6385 goto cp0_unimplemented;
6391 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_BadVAddr));
6396 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_BadInstr));
6401 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_BadInstrP));
6405 goto cp0_unimplemented;
6411 /* Mark as an IO operation because we read the time. */
6412 if (ctx->tb->cflags & CF_USE_ICOUNT) {
6415 gen_helper_mfc0_count(arg, cpu_env);
6416 if (ctx->tb->cflags & CF_USE_ICOUNT) {
6419 /* Break the TB to be able to take timer interrupts immediately
6420 after reading count. */
6421 ctx->bstate = BS_STOP;
6424 /* 6,7 are implementation dependent */
6426 goto cp0_unimplemented;
6432 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EntryHi));
6436 goto cp0_unimplemented;
6442 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Compare));
6445 /* 6,7 are implementation dependent */
6447 goto cp0_unimplemented;
6453 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Status));
6457 check_insn(ctx, ISA_MIPS32R2);
6458 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_IntCtl));
6462 check_insn(ctx, ISA_MIPS32R2);
6463 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSCtl));
6467 check_insn(ctx, ISA_MIPS32R2);
6468 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSMap));
6472 goto cp0_unimplemented;
6478 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Cause));
6482 goto cp0_unimplemented;
6488 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EPC));
6492 goto cp0_unimplemented;
6498 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PRid));
6502 check_insn(ctx, ISA_MIPS32R2);
6503 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_EBase));
6507 goto cp0_unimplemented;
6513 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config0));
6517 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config1));
6521 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config2));
6525 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config3));
6529 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config4));
6533 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config5));
6536 /* 6,7 are implementation dependent */
6538 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config6));
6542 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config7));
6546 goto cp0_unimplemented;
6552 gen_helper_dmfc0_lladdr(arg, cpu_env);
6556 goto cp0_unimplemented;
6562 gen_helper_1e0i(dmfc0_watchlo, arg, sel);
6566 goto cp0_unimplemented;
6572 gen_helper_1e0i(mfc0_watchhi, arg, sel);
6576 goto cp0_unimplemented;
6582 check_insn(ctx, ISA_MIPS3);
6583 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_XContext));
6587 goto cp0_unimplemented;
6591 /* Officially reserved, but sel 0 is used for R1x000 framemask */
6592 CP0_CHECK(!(ctx->insn_flags & ISA_MIPS32R6));
6595 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Framemask));
6599 goto cp0_unimplemented;
6603 tcg_gen_movi_tl(arg, 0); /* unimplemented */
6604 rn = "'Diagnostic"; /* implementation dependent */
6609 gen_helper_mfc0_debug(arg, cpu_env); /* EJTAG support */
6613 // gen_helper_dmfc0_tracecontrol(arg, cpu_env); /* PDtrace support */
6614 rn = "TraceControl";
6617 // gen_helper_dmfc0_tracecontrol2(arg, cpu_env); /* PDtrace support */
6618 rn = "TraceControl2";
6621 // gen_helper_dmfc0_usertracedata(arg, cpu_env); /* PDtrace support */
6622 rn = "UserTraceData";
6625 // gen_helper_dmfc0_tracebpc(arg, cpu_env); /* PDtrace support */
6629 goto cp0_unimplemented;
6636 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_DEPC));
6640 goto cp0_unimplemented;
6646 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Performance0));
6647 rn = "Performance0";
6650 // gen_helper_dmfc0_performance1(arg);
6651 rn = "Performance1";
6654 // gen_helper_dmfc0_performance2(arg);
6655 rn = "Performance2";
6658 // gen_helper_dmfc0_performance3(arg);
6659 rn = "Performance3";
6662 // gen_helper_dmfc0_performance4(arg);
6663 rn = "Performance4";
6666 // gen_helper_dmfc0_performance5(arg);
6667 rn = "Performance5";
6670 // gen_helper_dmfc0_performance6(arg);
6671 rn = "Performance6";
6674 // gen_helper_dmfc0_performance7(arg);
6675 rn = "Performance7";
6678 goto cp0_unimplemented;
6682 tcg_gen_movi_tl(arg, 0); /* unimplemented */
6689 tcg_gen_movi_tl(arg, 0); /* unimplemented */
6693 goto cp0_unimplemented;
6702 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_TagLo));
6709 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DataLo));
6713 goto cp0_unimplemented;
6722 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_TagHi));
6729 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DataHi));
6733 goto cp0_unimplemented;
6739 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_ErrorEPC));
6743 goto cp0_unimplemented;
6750 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DESAVE));
6754 CP0_CHECK(ctx->kscrexist & (1 << sel));
6755 tcg_gen_ld_tl(arg, cpu_env,
6756 offsetof(CPUMIPSState, CP0_KScratch[sel-2]));
6760 goto cp0_unimplemented;
6764 goto cp0_unimplemented;
6766 (void)rn; /* avoid a compiler warning */
6767 LOG_DISAS("dmfc0 %s (reg %d sel %d)\n", rn, reg, sel);
6771 LOG_DISAS("dmfc0 %s (reg %d sel %d)\n", rn, reg, sel);
6772 gen_mfc0_unimplemented(ctx, arg);
6775 static void gen_dmtc0(DisasContext *ctx, TCGv arg, int reg, int sel)
6777 const char *rn = "invalid";
6780 check_insn(ctx, ISA_MIPS64);
6782 if (ctx->tb->cflags & CF_USE_ICOUNT) {
6790 gen_helper_mtc0_index(cpu_env, arg);
6794 CP0_CHECK(ctx->insn_flags & ASE_MT);
6795 gen_helper_mtc0_mvpcontrol(cpu_env, arg);
6799 CP0_CHECK(ctx->insn_flags & ASE_MT);
6804 CP0_CHECK(ctx->insn_flags & ASE_MT);
6809 goto cp0_unimplemented;
6819 CP0_CHECK(ctx->insn_flags & ASE_MT);
6820 gen_helper_mtc0_vpecontrol(cpu_env, arg);
6824 CP0_CHECK(ctx->insn_flags & ASE_MT);
6825 gen_helper_mtc0_vpeconf0(cpu_env, arg);
6829 CP0_CHECK(ctx->insn_flags & ASE_MT);
6830 gen_helper_mtc0_vpeconf1(cpu_env, arg);
6834 CP0_CHECK(ctx->insn_flags & ASE_MT);
6835 gen_helper_mtc0_yqmask(cpu_env, arg);
6839 CP0_CHECK(ctx->insn_flags & ASE_MT);
6840 tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_VPESchedule));
6844 CP0_CHECK(ctx->insn_flags & ASE_MT);
6845 tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_VPEScheFBack));
6846 rn = "VPEScheFBack";
6849 CP0_CHECK(ctx->insn_flags & ASE_MT);
6850 gen_helper_mtc0_vpeopt(cpu_env, arg);
6854 goto cp0_unimplemented;
6860 gen_helper_dmtc0_entrylo0(cpu_env, arg);
6864 CP0_CHECK(ctx->insn_flags & ASE_MT);
6865 gen_helper_mtc0_tcstatus(cpu_env, arg);
6869 CP0_CHECK(ctx->insn_flags & ASE_MT);
6870 gen_helper_mtc0_tcbind(cpu_env, arg);
6874 CP0_CHECK(ctx->insn_flags & ASE_MT);
6875 gen_helper_mtc0_tcrestart(cpu_env, arg);
6879 CP0_CHECK(ctx->insn_flags & ASE_MT);
6880 gen_helper_mtc0_tchalt(cpu_env, arg);
6884 CP0_CHECK(ctx->insn_flags & ASE_MT);
6885 gen_helper_mtc0_tccontext(cpu_env, arg);
6889 CP0_CHECK(ctx->insn_flags & ASE_MT);
6890 gen_helper_mtc0_tcschedule(cpu_env, arg);
6894 CP0_CHECK(ctx->insn_flags & ASE_MT);
6895 gen_helper_mtc0_tcschefback(cpu_env, arg);
6899 goto cp0_unimplemented;
6905 gen_helper_dmtc0_entrylo1(cpu_env, arg);
6909 goto cp0_unimplemented;
6915 gen_helper_mtc0_context(cpu_env, arg);
6919 // gen_helper_mtc0_contextconfig(cpu_env, arg); /* SmartMIPS ASE */
6920 rn = "ContextConfig";
6921 goto cp0_unimplemented;
6924 CP0_CHECK(ctx->ulri);
6925 tcg_gen_st_tl(arg, cpu_env,
6926 offsetof(CPUMIPSState, active_tc.CP0_UserLocal));
6930 goto cp0_unimplemented;
6936 gen_helper_mtc0_pagemask(cpu_env, arg);
6940 check_insn(ctx, ISA_MIPS32R2);
6941 gen_helper_mtc0_pagegrain(cpu_env, arg);
6945 goto cp0_unimplemented;
6951 gen_helper_mtc0_wired(cpu_env, arg);
6955 check_insn(ctx, ISA_MIPS32R2);
6956 gen_helper_mtc0_srsconf0(cpu_env, arg);
6960 check_insn(ctx, ISA_MIPS32R2);
6961 gen_helper_mtc0_srsconf1(cpu_env, arg);
6965 check_insn(ctx, ISA_MIPS32R2);
6966 gen_helper_mtc0_srsconf2(cpu_env, arg);
6970 check_insn(ctx, ISA_MIPS32R2);
6971 gen_helper_mtc0_srsconf3(cpu_env, arg);
6975 check_insn(ctx, ISA_MIPS32R2);
6976 gen_helper_mtc0_srsconf4(cpu_env, arg);
6980 goto cp0_unimplemented;
6986 check_insn(ctx, ISA_MIPS32R2);
6987 gen_helper_mtc0_hwrena(cpu_env, arg);
6988 ctx->bstate = BS_STOP;
6992 goto cp0_unimplemented;
7010 goto cp0_unimplemented;
7016 gen_helper_mtc0_count(cpu_env, arg);
7019 /* 6,7 are implementation dependent */
7021 goto cp0_unimplemented;
7023 /* Stop translation as we may have switched the execution mode */
7024 ctx->bstate = BS_STOP;
7029 gen_helper_mtc0_entryhi(cpu_env, arg);
7033 goto cp0_unimplemented;
7039 gen_helper_mtc0_compare(cpu_env, arg);
7042 /* 6,7 are implementation dependent */
7044 goto cp0_unimplemented;
7046 /* Stop translation as we may have switched the execution mode */
7047 ctx->bstate = BS_STOP;
7052 save_cpu_state(ctx, 1);
7053 gen_helper_mtc0_status(cpu_env, arg);
7054 /* BS_STOP isn't good enough here, hflags may have changed. */
7055 gen_save_pc(ctx->pc + 4);
7056 ctx->bstate = BS_EXCP;
7060 check_insn(ctx, ISA_MIPS32R2);
7061 gen_helper_mtc0_intctl(cpu_env, arg);
7062 /* Stop translation as we may have switched the execution mode */
7063 ctx->bstate = BS_STOP;
7067 check_insn(ctx, ISA_MIPS32R2);
7068 gen_helper_mtc0_srsctl(cpu_env, arg);
7069 /* Stop translation as we may have switched the execution mode */
7070 ctx->bstate = BS_STOP;
7074 check_insn(ctx, ISA_MIPS32R2);
7075 gen_mtc0_store32(arg, offsetof(CPUMIPSState, CP0_SRSMap));
7076 /* Stop translation as we may have switched the execution mode */
7077 ctx->bstate = BS_STOP;
7081 goto cp0_unimplemented;
7087 save_cpu_state(ctx, 1);
7088 /* Mark as an IO operation because we may trigger a software
7090 if (ctx->tb->cflags & CF_USE_ICOUNT) {
7093 gen_helper_mtc0_cause(cpu_env, arg);
7094 if (ctx->tb->cflags & CF_USE_ICOUNT) {
7097 /* Stop translation as we may have triggered an intetrupt */
7098 ctx->bstate = BS_STOP;
7102 goto cp0_unimplemented;
7108 tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EPC));
7112 goto cp0_unimplemented;
7122 check_insn(ctx, ISA_MIPS32R2);
7123 gen_helper_mtc0_ebase(cpu_env, arg);
7127 goto cp0_unimplemented;
7133 gen_helper_mtc0_config0(cpu_env, arg);
7135 /* Stop translation as we may have switched the execution mode */
7136 ctx->bstate = BS_STOP;
7139 /* ignored, read only */
7143 gen_helper_mtc0_config2(cpu_env, arg);
7145 /* Stop translation as we may have switched the execution mode */
7146 ctx->bstate = BS_STOP;
7149 gen_helper_mtc0_config3(cpu_env, arg);
7151 /* Stop translation as we may have switched the execution mode */
7152 ctx->bstate = BS_STOP;
7155 /* currently ignored */
7159 gen_helper_mtc0_config5(cpu_env, arg);
7161 /* Stop translation as we may have switched the execution mode */
7162 ctx->bstate = BS_STOP;
7164 /* 6,7 are implementation dependent */
7166 rn = "Invalid config selector";
7167 goto cp0_unimplemented;
7173 gen_helper_mtc0_lladdr(cpu_env, arg);
7177 goto cp0_unimplemented;
7183 gen_helper_0e1i(mtc0_watchlo, arg, sel);
7187 goto cp0_unimplemented;
7193 gen_helper_0e1i(mtc0_watchhi, arg, sel);
7197 goto cp0_unimplemented;
7203 check_insn(ctx, ISA_MIPS3);
7204 gen_helper_mtc0_xcontext(cpu_env, arg);
7208 goto cp0_unimplemented;
7212 /* Officially reserved, but sel 0 is used for R1x000 framemask */
7213 CP0_CHECK(!(ctx->insn_flags & ISA_MIPS32R6));
7216 gen_helper_mtc0_framemask(cpu_env, arg);
7220 goto cp0_unimplemented;
7225 rn = "Diagnostic"; /* implementation dependent */
7230 gen_helper_mtc0_debug(cpu_env, arg); /* EJTAG support */
7231 /* BS_STOP isn't good enough here, hflags may have changed. */
7232 gen_save_pc(ctx->pc + 4);
7233 ctx->bstate = BS_EXCP;
7237 // gen_helper_mtc0_tracecontrol(cpu_env, arg); /* PDtrace support */
7238 /* Stop translation as we may have switched the execution mode */
7239 ctx->bstate = BS_STOP;
7240 rn = "TraceControl";
7243 // gen_helper_mtc0_tracecontrol2(cpu_env, arg); /* PDtrace support */
7244 /* Stop translation as we may have switched the execution mode */
7245 ctx->bstate = BS_STOP;
7246 rn = "TraceControl2";
7249 // gen_helper_mtc0_usertracedata(cpu_env, arg); /* PDtrace support */
7250 /* Stop translation as we may have switched the execution mode */
7251 ctx->bstate = BS_STOP;
7252 rn = "UserTraceData";
7255 // gen_helper_mtc0_tracebpc(cpu_env, arg); /* PDtrace support */
7256 /* Stop translation as we may have switched the execution mode */
7257 ctx->bstate = BS_STOP;
7261 goto cp0_unimplemented;
7268 tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_DEPC));
7272 goto cp0_unimplemented;
7278 gen_helper_mtc0_performance0(cpu_env, arg);
7279 rn = "Performance0";
7282 // gen_helper_mtc0_performance1(cpu_env, arg);
7283 rn = "Performance1";
7286 // gen_helper_mtc0_performance2(cpu_env, arg);
7287 rn = "Performance2";
7290 // gen_helper_mtc0_performance3(cpu_env, arg);
7291 rn = "Performance3";
7294 // gen_helper_mtc0_performance4(cpu_env, arg);
7295 rn = "Performance4";
7298 // gen_helper_mtc0_performance5(cpu_env, arg);
7299 rn = "Performance5";
7302 // gen_helper_mtc0_performance6(cpu_env, arg);
7303 rn = "Performance6";
7306 // gen_helper_mtc0_performance7(cpu_env, arg);
7307 rn = "Performance7";
7310 goto cp0_unimplemented;
7324 goto cp0_unimplemented;
7333 gen_helper_mtc0_taglo(cpu_env, arg);
7340 gen_helper_mtc0_datalo(cpu_env, arg);
7344 goto cp0_unimplemented;
7353 gen_helper_mtc0_taghi(cpu_env, arg);
7360 gen_helper_mtc0_datahi(cpu_env, arg);
7365 goto cp0_unimplemented;
7371 tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_ErrorEPC));
7375 goto cp0_unimplemented;
7382 gen_mtc0_store32(arg, offsetof(CPUMIPSState, CP0_DESAVE));
7386 CP0_CHECK(ctx->kscrexist & (1 << sel));
7387 tcg_gen_st_tl(arg, cpu_env,
7388 offsetof(CPUMIPSState, CP0_KScratch[sel-2]));
7392 goto cp0_unimplemented;
7394 /* Stop translation as we may have switched the execution mode */
7395 ctx->bstate = BS_STOP;
7398 goto cp0_unimplemented;
7400 (void)rn; /* avoid a compiler warning */
7401 LOG_DISAS("dmtc0 %s (reg %d sel %d)\n", rn, reg, sel);
7402 /* For simplicity assume that all writes can cause interrupts. */
7403 if (ctx->tb->cflags & CF_USE_ICOUNT) {
7405 ctx->bstate = BS_STOP;
7410 LOG_DISAS("dmtc0 %s (reg %d sel %d)\n", rn, reg, sel);
7412 #endif /* TARGET_MIPS64 */
7414 static void gen_mftr(CPUMIPSState *env, DisasContext *ctx, int rt, int rd,
7415 int u, int sel, int h)
7417 int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
7418 TCGv t0 = tcg_temp_local_new();
7420 if ((env->CP0_VPEConf0 & (1 << CP0VPEC0_MVP)) == 0 &&
7421 ((env->tcs[other_tc].CP0_TCBind & (0xf << CP0TCBd_CurVPE)) !=
7422 (env->active_tc.CP0_TCBind & (0xf << CP0TCBd_CurVPE))))
7423 tcg_gen_movi_tl(t0, -1);
7424 else if ((env->CP0_VPEControl & (0xff << CP0VPECo_TargTC)) >
7425 (env->mvp->CP0_MVPConf0 & (0xff << CP0MVPC0_PTC)))
7426 tcg_gen_movi_tl(t0, -1);
7432 gen_helper_mftc0_vpecontrol(t0, cpu_env);
7435 gen_helper_mftc0_vpeconf0(t0, cpu_env);
7445 gen_helper_mftc0_tcstatus(t0, cpu_env);
7448 gen_helper_mftc0_tcbind(t0, cpu_env);
7451 gen_helper_mftc0_tcrestart(t0, cpu_env);
7454 gen_helper_mftc0_tchalt(t0, cpu_env);
7457 gen_helper_mftc0_tccontext(t0, cpu_env);
7460 gen_helper_mftc0_tcschedule(t0, cpu_env);
7463 gen_helper_mftc0_tcschefback(t0, cpu_env);
7466 gen_mfc0(ctx, t0, rt, sel);
7473 gen_helper_mftc0_entryhi(t0, cpu_env);
7476 gen_mfc0(ctx, t0, rt, sel);
7482 gen_helper_mftc0_status(t0, cpu_env);
7485 gen_mfc0(ctx, t0, rt, sel);
7491 gen_helper_mftc0_cause(t0, cpu_env);
7501 gen_helper_mftc0_epc(t0, cpu_env);
7511 gen_helper_mftc0_ebase(t0, cpu_env);
7521 gen_helper_mftc0_configx(t0, cpu_env, tcg_const_tl(sel));
7531 gen_helper_mftc0_debug(t0, cpu_env);
7534 gen_mfc0(ctx, t0, rt, sel);
7539 gen_mfc0(ctx, t0, rt, sel);
7541 } else switch (sel) {
7542 /* GPR registers. */
7544 gen_helper_1e0i(mftgpr, t0, rt);
7546 /* Auxiliary CPU registers */
7550 gen_helper_1e0i(mftlo, t0, 0);
7553 gen_helper_1e0i(mfthi, t0, 0);
7556 gen_helper_1e0i(mftacx, t0, 0);
7559 gen_helper_1e0i(mftlo, t0, 1);
7562 gen_helper_1e0i(mfthi, t0, 1);
7565 gen_helper_1e0i(mftacx, t0, 1);
7568 gen_helper_1e0i(mftlo, t0, 2);
7571 gen_helper_1e0i(mfthi, t0, 2);
7574 gen_helper_1e0i(mftacx, t0, 2);
7577 gen_helper_1e0i(mftlo, t0, 3);
7580 gen_helper_1e0i(mfthi, t0, 3);
7583 gen_helper_1e0i(mftacx, t0, 3);
7586 gen_helper_mftdsp(t0, cpu_env);
7592 /* Floating point (COP1). */
7594 /* XXX: For now we support only a single FPU context. */
7596 TCGv_i32 fp0 = tcg_temp_new_i32();
7598 gen_load_fpr32(ctx, fp0, rt);
7599 tcg_gen_ext_i32_tl(t0, fp0);
7600 tcg_temp_free_i32(fp0);
7602 TCGv_i32 fp0 = tcg_temp_new_i32();
7604 gen_load_fpr32h(ctx, fp0, rt);
7605 tcg_gen_ext_i32_tl(t0, fp0);
7606 tcg_temp_free_i32(fp0);
7610 /* XXX: For now we support only a single FPU context. */
7611 gen_helper_1e0i(cfc1, t0, rt);
7613 /* COP2: Not implemented. */
7620 LOG_DISAS("mftr (reg %d u %d sel %d h %d)\n", rt, u, sel, h);
7621 gen_store_gpr(t0, rd);
7627 LOG_DISAS("mftr (reg %d u %d sel %d h %d)\n", rt, u, sel, h);
7628 generate_exception(ctx, EXCP_RI);
7631 static void gen_mttr(CPUMIPSState *env, DisasContext *ctx, int rd, int rt,
7632 int u, int sel, int h)
7634 int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
7635 TCGv t0 = tcg_temp_local_new();
7637 gen_load_gpr(t0, rt);
7638 if ((env->CP0_VPEConf0 & (1 << CP0VPEC0_MVP)) == 0 &&
7639 ((env->tcs[other_tc].CP0_TCBind & (0xf << CP0TCBd_CurVPE)) !=
7640 (env->active_tc.CP0_TCBind & (0xf << CP0TCBd_CurVPE))))
7642 else if ((env->CP0_VPEControl & (0xff << CP0VPECo_TargTC)) >
7643 (env->mvp->CP0_MVPConf0 & (0xff << CP0MVPC0_PTC)))
7650 gen_helper_mttc0_vpecontrol(cpu_env, t0);
7653 gen_helper_mttc0_vpeconf0(cpu_env, t0);
7663 gen_helper_mttc0_tcstatus(cpu_env, t0);
7666 gen_helper_mttc0_tcbind(cpu_env, t0);
7669 gen_helper_mttc0_tcrestart(cpu_env, t0);
7672 gen_helper_mttc0_tchalt(cpu_env, t0);
7675 gen_helper_mttc0_tccontext(cpu_env, t0);
7678 gen_helper_mttc0_tcschedule(cpu_env, t0);
7681 gen_helper_mttc0_tcschefback(cpu_env, t0);
7684 gen_mtc0(ctx, t0, rd, sel);
7691 gen_helper_mttc0_entryhi(cpu_env, t0);
7694 gen_mtc0(ctx, t0, rd, sel);
7700 gen_helper_mttc0_status(cpu_env, t0);
7703 gen_mtc0(ctx, t0, rd, sel);
7709 gen_helper_mttc0_cause(cpu_env, t0);
7719 gen_helper_mttc0_ebase(cpu_env, t0);
7729 gen_helper_mttc0_debug(cpu_env, t0);
7732 gen_mtc0(ctx, t0, rd, sel);
7737 gen_mtc0(ctx, t0, rd, sel);
7739 } else switch (sel) {
7740 /* GPR registers. */
7742 gen_helper_0e1i(mttgpr, t0, rd);
7744 /* Auxiliary CPU registers */
7748 gen_helper_0e1i(mttlo, t0, 0);
7751 gen_helper_0e1i(mtthi, t0, 0);
7754 gen_helper_0e1i(mttacx, t0, 0);
7757 gen_helper_0e1i(mttlo, t0, 1);
7760 gen_helper_0e1i(mtthi, t0, 1);
7763 gen_helper_0e1i(mttacx, t0, 1);
7766 gen_helper_0e1i(mttlo, t0, 2);
7769 gen_helper_0e1i(mtthi, t0, 2);
7772 gen_helper_0e1i(mttacx, t0, 2);
7775 gen_helper_0e1i(mttlo, t0, 3);
7778 gen_helper_0e1i(mtthi, t0, 3);
7781 gen_helper_0e1i(mttacx, t0, 3);
7784 gen_helper_mttdsp(cpu_env, t0);
7790 /* Floating point (COP1). */
7792 /* XXX: For now we support only a single FPU context. */
7794 TCGv_i32 fp0 = tcg_temp_new_i32();
7796 tcg_gen_trunc_tl_i32(fp0, t0);
7797 gen_store_fpr32(ctx, fp0, rd);
7798 tcg_temp_free_i32(fp0);
7800 TCGv_i32 fp0 = tcg_temp_new_i32();
7802 tcg_gen_trunc_tl_i32(fp0, t0);
7803 gen_store_fpr32h(ctx, fp0, rd);
7804 tcg_temp_free_i32(fp0);
7808 /* XXX: For now we support only a single FPU context. */
7809 save_cpu_state(ctx, 1);
7811 TCGv_i32 fs_tmp = tcg_const_i32(rd);
7813 gen_helper_0e2i(ctc1, t0, fs_tmp, rt);
7814 tcg_temp_free_i32(fs_tmp);
7816 /* Stop translation as we may have changed hflags */
7817 ctx->bstate = BS_STOP;
7819 /* COP2: Not implemented. */
7826 LOG_DISAS("mttr (reg %d u %d sel %d h %d)\n", rd, u, sel, h);
7832 LOG_DISAS("mttr (reg %d u %d sel %d h %d)\n", rd, u, sel, h);
7833 generate_exception(ctx, EXCP_RI);
7836 static void gen_cp0 (CPUMIPSState *env, DisasContext *ctx, uint32_t opc, int rt, int rd)
7838 const char *opn = "ldst";
7840 check_cp0_enabled(ctx);
7847 gen_mfc0(ctx, cpu_gpr[rt], rd, ctx->opcode & 0x7);
7852 TCGv t0 = tcg_temp_new();
7854 gen_load_gpr(t0, rt);
7855 gen_mtc0(ctx, t0, rd, ctx->opcode & 0x7);
7860 #if defined(TARGET_MIPS64)
7862 check_insn(ctx, ISA_MIPS3);
7867 gen_dmfc0(ctx, cpu_gpr[rt], rd, ctx->opcode & 0x7);
7871 check_insn(ctx, ISA_MIPS3);
7873 TCGv t0 = tcg_temp_new();
7875 gen_load_gpr(t0, rt);
7876 gen_dmtc0(ctx, t0, rd, ctx->opcode & 0x7);
7883 check_insn(ctx, ASE_MT);
7888 gen_mftr(env, ctx, rt, rd, (ctx->opcode >> 5) & 1,
7889 ctx->opcode & 0x7, (ctx->opcode >> 4) & 1);
7893 check_insn(ctx, ASE_MT);
7894 gen_mttr(env, ctx, rd, rt, (ctx->opcode >> 5) & 1,
7895 ctx->opcode & 0x7, (ctx->opcode >> 4) & 1);
7900 if (!env->tlb->helper_tlbwi)
7902 gen_helper_tlbwi(cpu_env);
7907 if (!env->tlb->helper_tlbinv) {
7910 gen_helper_tlbinv(cpu_env);
7911 } /* treat as nop if TLBINV not supported */
7916 if (!env->tlb->helper_tlbinvf) {
7919 gen_helper_tlbinvf(cpu_env);
7920 } /* treat as nop if TLBINV not supported */
7924 if (!env->tlb->helper_tlbwr)
7926 gen_helper_tlbwr(cpu_env);
7930 if (!env->tlb->helper_tlbp)
7932 gen_helper_tlbp(cpu_env);
7936 if (!env->tlb->helper_tlbr)
7938 gen_helper_tlbr(cpu_env);
7940 case OPC_ERET: /* OPC_ERETNC */
7941 if ((ctx->insn_flags & ISA_MIPS32R6) &&
7942 (ctx->hflags & MIPS_HFLAG_BMASK)) {
7943 MIPS_DEBUG("CTI in delay / forbidden slot");
7946 int bit_shift = (ctx->hflags & MIPS_HFLAG_M16) ? 16 : 6;
7947 if (ctx->opcode & (1 << bit_shift)) {
7950 check_insn(ctx, ISA_MIPS32R5);
7951 gen_helper_eretnc(cpu_env);
7955 check_insn(ctx, ISA_MIPS2);
7956 gen_helper_eret(cpu_env);
7958 ctx->bstate = BS_EXCP;
7963 check_insn(ctx, ISA_MIPS32);
7964 if ((ctx->insn_flags & ISA_MIPS32R6) &&
7965 (ctx->hflags & MIPS_HFLAG_BMASK)) {
7966 MIPS_DEBUG("CTI in delay / forbidden slot");
7969 if (!(ctx->hflags & MIPS_HFLAG_DM)) {
7971 generate_exception(ctx, EXCP_RI);
7973 gen_helper_deret(cpu_env);
7974 ctx->bstate = BS_EXCP;
7979 check_insn(ctx, ISA_MIPS3 | ISA_MIPS32);
7980 if ((ctx->insn_flags & ISA_MIPS32R6) &&
7981 (ctx->hflags & MIPS_HFLAG_BMASK)) {
7982 MIPS_DEBUG("CTI in delay / forbidden slot");
7985 /* If we get an exception, we want to restart at next instruction */
7987 save_cpu_state(ctx, 1);
7989 gen_helper_wait(cpu_env);
7990 ctx->bstate = BS_EXCP;
7995 generate_exception(ctx, EXCP_RI);
7998 (void)opn; /* avoid a compiler warning */
7999 MIPS_DEBUG("%s %s %d", opn, regnames[rt], rd);
8001 #endif /* !CONFIG_USER_ONLY */
8003 /* CP1 Branches (before delay slot) */
8004 static void gen_compute_branch1(DisasContext *ctx, uint32_t op,
8005 int32_t cc, int32_t offset)
8007 target_ulong btarget;
8008 const char *opn = "cp1 cond branch";
8009 TCGv_i32 t0 = tcg_temp_new_i32();
8011 if ((ctx->insn_flags & ISA_MIPS32R6) && (ctx->hflags & MIPS_HFLAG_BMASK)) {
8012 MIPS_DEBUG("CTI in delay / forbidden slot");
8013 generate_exception(ctx, EXCP_RI);
8018 check_insn(ctx, ISA_MIPS4 | ISA_MIPS32);
8020 btarget = ctx->pc + 4 + offset;
8024 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
8025 tcg_gen_not_i32(t0, t0);
8026 tcg_gen_andi_i32(t0, t0, 1);
8027 tcg_gen_extu_i32_tl(bcond, t0);
8031 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
8032 tcg_gen_not_i32(t0, t0);
8033 tcg_gen_andi_i32(t0, t0, 1);
8034 tcg_gen_extu_i32_tl(bcond, t0);
8038 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
8039 tcg_gen_andi_i32(t0, t0, 1);
8040 tcg_gen_extu_i32_tl(bcond, t0);
8044 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
8045 tcg_gen_andi_i32(t0, t0, 1);
8046 tcg_gen_extu_i32_tl(bcond, t0);
8049 ctx->hflags |= MIPS_HFLAG_BL;
8053 TCGv_i32 t1 = tcg_temp_new_i32();
8054 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
8055 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+1));
8056 tcg_gen_nand_i32(t0, t0, t1);
8057 tcg_temp_free_i32(t1);
8058 tcg_gen_andi_i32(t0, t0, 1);
8059 tcg_gen_extu_i32_tl(bcond, t0);
8065 TCGv_i32 t1 = tcg_temp_new_i32();
8066 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
8067 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+1));
8068 tcg_gen_or_i32(t0, t0, t1);
8069 tcg_temp_free_i32(t1);
8070 tcg_gen_andi_i32(t0, t0, 1);
8071 tcg_gen_extu_i32_tl(bcond, t0);
8077 TCGv_i32 t1 = tcg_temp_new_i32();
8078 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
8079 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+1));
8080 tcg_gen_and_i32(t0, t0, t1);
8081 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+2));
8082 tcg_gen_and_i32(t0, t0, t1);
8083 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+3));
8084 tcg_gen_nand_i32(t0, t0, t1);
8085 tcg_temp_free_i32(t1);
8086 tcg_gen_andi_i32(t0, t0, 1);
8087 tcg_gen_extu_i32_tl(bcond, t0);
8093 TCGv_i32 t1 = tcg_temp_new_i32();
8094 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
8095 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+1));
8096 tcg_gen_or_i32(t0, t0, t1);
8097 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+2));
8098 tcg_gen_or_i32(t0, t0, t1);
8099 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+3));
8100 tcg_gen_or_i32(t0, t0, t1);
8101 tcg_temp_free_i32(t1);
8102 tcg_gen_andi_i32(t0, t0, 1);
8103 tcg_gen_extu_i32_tl(bcond, t0);
8107 ctx->hflags |= MIPS_HFLAG_BC;
8111 generate_exception (ctx, EXCP_RI);
8114 (void)opn; /* avoid a compiler warning */
8115 MIPS_DEBUG("%s: cond %02x target " TARGET_FMT_lx, opn,
8116 ctx->hflags, btarget);
8117 ctx->btarget = btarget;
8118 ctx->hflags |= MIPS_HFLAG_BDS32;
8120 tcg_temp_free_i32(t0);
8123 /* R6 CP1 Branches */
8124 static void gen_compute_branch1_r6(DisasContext *ctx, uint32_t op,
8125 int32_t ft, int32_t offset)
8127 target_ulong btarget;
8128 const char *opn = "cp1 cond branch";
8129 TCGv_i64 t0 = tcg_temp_new_i64();
8131 if (ctx->hflags & MIPS_HFLAG_BMASK) {
8132 #ifdef MIPS_DEBUG_DISAS
8133 LOG_DISAS("Branch in delay / forbidden slot at PC 0x" TARGET_FMT_lx
8136 generate_exception(ctx, EXCP_RI);
8140 gen_load_fpr64(ctx, t0, ft);
8141 tcg_gen_andi_i64(t0, t0, 1);
8143 btarget = addr_add(ctx, ctx->pc + 4, offset);
8147 tcg_gen_xori_i64(t0, t0, 1);
8149 ctx->hflags |= MIPS_HFLAG_BC;
8152 /* t0 already set */
8154 ctx->hflags |= MIPS_HFLAG_BC;
8158 generate_exception(ctx, EXCP_RI);
8162 tcg_gen_trunc_i64_tl(bcond, t0);
8164 (void)opn; /* avoid a compiler warning */
8165 MIPS_DEBUG("%s: cond %02x target " TARGET_FMT_lx, opn,
8166 ctx->hflags, btarget);
8167 ctx->btarget = btarget;
8168 ctx->hflags |= MIPS_HFLAG_BDS32;
8171 tcg_temp_free_i64(t0);
8174 /* Coprocessor 1 (FPU) */
8176 #define FOP(func, fmt) (((fmt) << 21) | (func))
8179 OPC_ADD_S = FOP(0, FMT_S),
8180 OPC_SUB_S = FOP(1, FMT_S),
8181 OPC_MUL_S = FOP(2, FMT_S),
8182 OPC_DIV_S = FOP(3, FMT_S),
8183 OPC_SQRT_S = FOP(4, FMT_S),
8184 OPC_ABS_S = FOP(5, FMT_S),
8185 OPC_MOV_S = FOP(6, FMT_S),
8186 OPC_NEG_S = FOP(7, FMT_S),
8187 OPC_ROUND_L_S = FOP(8, FMT_S),
8188 OPC_TRUNC_L_S = FOP(9, FMT_S),
8189 OPC_CEIL_L_S = FOP(10, FMT_S),
8190 OPC_FLOOR_L_S = FOP(11, FMT_S),
8191 OPC_ROUND_W_S = FOP(12, FMT_S),
8192 OPC_TRUNC_W_S = FOP(13, FMT_S),
8193 OPC_CEIL_W_S = FOP(14, FMT_S),
8194 OPC_FLOOR_W_S = FOP(15, FMT_S),
8195 OPC_SEL_S = FOP(16, FMT_S),
8196 OPC_MOVCF_S = FOP(17, FMT_S),
8197 OPC_MOVZ_S = FOP(18, FMT_S),
8198 OPC_MOVN_S = FOP(19, FMT_S),
8199 OPC_SELEQZ_S = FOP(20, FMT_S),
8200 OPC_RECIP_S = FOP(21, FMT_S),
8201 OPC_RSQRT_S = FOP(22, FMT_S),
8202 OPC_SELNEZ_S = FOP(23, FMT_S),
8203 OPC_MADDF_S = FOP(24, FMT_S),
8204 OPC_MSUBF_S = FOP(25, FMT_S),
8205 OPC_RINT_S = FOP(26, FMT_S),
8206 OPC_CLASS_S = FOP(27, FMT_S),
8207 OPC_MIN_S = FOP(28, FMT_S),
8208 OPC_RECIP2_S = FOP(28, FMT_S),
8209 OPC_MINA_S = FOP(29, FMT_S),
8210 OPC_RECIP1_S = FOP(29, FMT_S),
8211 OPC_MAX_S = FOP(30, FMT_S),
8212 OPC_RSQRT1_S = FOP(30, FMT_S),
8213 OPC_MAXA_S = FOP(31, FMT_S),
8214 OPC_RSQRT2_S = FOP(31, FMT_S),
8215 OPC_CVT_D_S = FOP(33, FMT_S),
8216 OPC_CVT_W_S = FOP(36, FMT_S),
8217 OPC_CVT_L_S = FOP(37, FMT_S),
8218 OPC_CVT_PS_S = FOP(38, FMT_S),
8219 OPC_CMP_F_S = FOP (48, FMT_S),
8220 OPC_CMP_UN_S = FOP (49, FMT_S),
8221 OPC_CMP_EQ_S = FOP (50, FMT_S),
8222 OPC_CMP_UEQ_S = FOP (51, FMT_S),
8223 OPC_CMP_OLT_S = FOP (52, FMT_S),
8224 OPC_CMP_ULT_S = FOP (53, FMT_S),
8225 OPC_CMP_OLE_S = FOP (54, FMT_S),
8226 OPC_CMP_ULE_S = FOP (55, FMT_S),
8227 OPC_CMP_SF_S = FOP (56, FMT_S),
8228 OPC_CMP_NGLE_S = FOP (57, FMT_S),
8229 OPC_CMP_SEQ_S = FOP (58, FMT_S),
8230 OPC_CMP_NGL_S = FOP (59, FMT_S),
8231 OPC_CMP_LT_S = FOP (60, FMT_S),
8232 OPC_CMP_NGE_S = FOP (61, FMT_S),
8233 OPC_CMP_LE_S = FOP (62, FMT_S),
8234 OPC_CMP_NGT_S = FOP (63, FMT_S),
8236 OPC_ADD_D = FOP(0, FMT_D),
8237 OPC_SUB_D = FOP(1, FMT_D),
8238 OPC_MUL_D = FOP(2, FMT_D),
8239 OPC_DIV_D = FOP(3, FMT_D),
8240 OPC_SQRT_D = FOP(4, FMT_D),
8241 OPC_ABS_D = FOP(5, FMT_D),
8242 OPC_MOV_D = FOP(6, FMT_D),
8243 OPC_NEG_D = FOP(7, FMT_D),
8244 OPC_ROUND_L_D = FOP(8, FMT_D),
8245 OPC_TRUNC_L_D = FOP(9, FMT_D),
8246 OPC_CEIL_L_D = FOP(10, FMT_D),
8247 OPC_FLOOR_L_D = FOP(11, FMT_D),
8248 OPC_ROUND_W_D = FOP(12, FMT_D),
8249 OPC_TRUNC_W_D = FOP(13, FMT_D),
8250 OPC_CEIL_W_D = FOP(14, FMT_D),
8251 OPC_FLOOR_W_D = FOP(15, FMT_D),
8252 OPC_SEL_D = FOP(16, FMT_D),
8253 OPC_MOVCF_D = FOP(17, FMT_D),
8254 OPC_MOVZ_D = FOP(18, FMT_D),
8255 OPC_MOVN_D = FOP(19, FMT_D),
8256 OPC_SELEQZ_D = FOP(20, FMT_D),
8257 OPC_RECIP_D = FOP(21, FMT_D),
8258 OPC_RSQRT_D = FOP(22, FMT_D),
8259 OPC_SELNEZ_D = FOP(23, FMT_D),
8260 OPC_MADDF_D = FOP(24, FMT_D),
8261 OPC_MSUBF_D = FOP(25, FMT_D),
8262 OPC_RINT_D = FOP(26, FMT_D),
8263 OPC_CLASS_D = FOP(27, FMT_D),
8264 OPC_MIN_D = FOP(28, FMT_D),
8265 OPC_RECIP2_D = FOP(28, FMT_D),
8266 OPC_MINA_D = FOP(29, FMT_D),
8267 OPC_RECIP1_D = FOP(29, FMT_D),
8268 OPC_MAX_D = FOP(30, FMT_D),
8269 OPC_RSQRT1_D = FOP(30, FMT_D),
8270 OPC_MAXA_D = FOP(31, FMT_D),
8271 OPC_RSQRT2_D = FOP(31, FMT_D),
8272 OPC_CVT_S_D = FOP(32, FMT_D),
8273 OPC_CVT_W_D = FOP(36, FMT_D),
8274 OPC_CVT_L_D = FOP(37, FMT_D),
8275 OPC_CMP_F_D = FOP (48, FMT_D),
8276 OPC_CMP_UN_D = FOP (49, FMT_D),
8277 OPC_CMP_EQ_D = FOP (50, FMT_D),
8278 OPC_CMP_UEQ_D = FOP (51, FMT_D),
8279 OPC_CMP_OLT_D = FOP (52, FMT_D),
8280 OPC_CMP_ULT_D = FOP (53, FMT_D),
8281 OPC_CMP_OLE_D = FOP (54, FMT_D),
8282 OPC_CMP_ULE_D = FOP (55, FMT_D),
8283 OPC_CMP_SF_D = FOP (56, FMT_D),
8284 OPC_CMP_NGLE_D = FOP (57, FMT_D),
8285 OPC_CMP_SEQ_D = FOP (58, FMT_D),
8286 OPC_CMP_NGL_D = FOP (59, FMT_D),
8287 OPC_CMP_LT_D = FOP (60, FMT_D),
8288 OPC_CMP_NGE_D = FOP (61, FMT_D),
8289 OPC_CMP_LE_D = FOP (62, FMT_D),
8290 OPC_CMP_NGT_D = FOP (63, FMT_D),
8292 OPC_CVT_S_W = FOP(32, FMT_W),
8293 OPC_CVT_D_W = FOP(33, FMT_W),
8294 OPC_CVT_S_L = FOP(32, FMT_L),
8295 OPC_CVT_D_L = FOP(33, FMT_L),
8296 OPC_CVT_PS_PW = FOP(38, FMT_W),
8298 OPC_ADD_PS = FOP(0, FMT_PS),
8299 OPC_SUB_PS = FOP(1, FMT_PS),
8300 OPC_MUL_PS = FOP(2, FMT_PS),
8301 OPC_DIV_PS = FOP(3, FMT_PS),
8302 OPC_ABS_PS = FOP(5, FMT_PS),
8303 OPC_MOV_PS = FOP(6, FMT_PS),
8304 OPC_NEG_PS = FOP(7, FMT_PS),
8305 OPC_MOVCF_PS = FOP(17, FMT_PS),
8306 OPC_MOVZ_PS = FOP(18, FMT_PS),
8307 OPC_MOVN_PS = FOP(19, FMT_PS),
8308 OPC_ADDR_PS = FOP(24, FMT_PS),
8309 OPC_MULR_PS = FOP(26, FMT_PS),
8310 OPC_RECIP2_PS = FOP(28, FMT_PS),
8311 OPC_RECIP1_PS = FOP(29, FMT_PS),
8312 OPC_RSQRT1_PS = FOP(30, FMT_PS),
8313 OPC_RSQRT2_PS = FOP(31, FMT_PS),
8315 OPC_CVT_S_PU = FOP(32, FMT_PS),
8316 OPC_CVT_PW_PS = FOP(36, FMT_PS),
8317 OPC_CVT_S_PL = FOP(40, FMT_PS),
8318 OPC_PLL_PS = FOP(44, FMT_PS),
8319 OPC_PLU_PS = FOP(45, FMT_PS),
8320 OPC_PUL_PS = FOP(46, FMT_PS),
8321 OPC_PUU_PS = FOP(47, FMT_PS),
8322 OPC_CMP_F_PS = FOP (48, FMT_PS),
8323 OPC_CMP_UN_PS = FOP (49, FMT_PS),
8324 OPC_CMP_EQ_PS = FOP (50, FMT_PS),
8325 OPC_CMP_UEQ_PS = FOP (51, FMT_PS),
8326 OPC_CMP_OLT_PS = FOP (52, FMT_PS),
8327 OPC_CMP_ULT_PS = FOP (53, FMT_PS),
8328 OPC_CMP_OLE_PS = FOP (54, FMT_PS),
8329 OPC_CMP_ULE_PS = FOP (55, FMT_PS),
8330 OPC_CMP_SF_PS = FOP (56, FMT_PS),
8331 OPC_CMP_NGLE_PS = FOP (57, FMT_PS),
8332 OPC_CMP_SEQ_PS = FOP (58, FMT_PS),
8333 OPC_CMP_NGL_PS = FOP (59, FMT_PS),
8334 OPC_CMP_LT_PS = FOP (60, FMT_PS),
8335 OPC_CMP_NGE_PS = FOP (61, FMT_PS),
8336 OPC_CMP_LE_PS = FOP (62, FMT_PS),
8337 OPC_CMP_NGT_PS = FOP (63, FMT_PS),
8341 R6_OPC_CMP_AF_S = FOP(0, FMT_W),
8342 R6_OPC_CMP_UN_S = FOP(1, FMT_W),
8343 R6_OPC_CMP_EQ_S = FOP(2, FMT_W),
8344 R6_OPC_CMP_UEQ_S = FOP(3, FMT_W),
8345 R6_OPC_CMP_LT_S = FOP(4, FMT_W),
8346 R6_OPC_CMP_ULT_S = FOP(5, FMT_W),
8347 R6_OPC_CMP_LE_S = FOP(6, FMT_W),
8348 R6_OPC_CMP_ULE_S = FOP(7, FMT_W),
8349 R6_OPC_CMP_SAF_S = FOP(8, FMT_W),
8350 R6_OPC_CMP_SUN_S = FOP(9, FMT_W),
8351 R6_OPC_CMP_SEQ_S = FOP(10, FMT_W),
8352 R6_OPC_CMP_SEUQ_S = FOP(11, FMT_W),
8353 R6_OPC_CMP_SLT_S = FOP(12, FMT_W),
8354 R6_OPC_CMP_SULT_S = FOP(13, FMT_W),
8355 R6_OPC_CMP_SLE_S = FOP(14, FMT_W),
8356 R6_OPC_CMP_SULE_S = FOP(15, FMT_W),
8357 R6_OPC_CMP_OR_S = FOP(17, FMT_W),
8358 R6_OPC_CMP_UNE_S = FOP(18, FMT_W),
8359 R6_OPC_CMP_NE_S = FOP(19, FMT_W),
8360 R6_OPC_CMP_SOR_S = FOP(25, FMT_W),
8361 R6_OPC_CMP_SUNE_S = FOP(26, FMT_W),
8362 R6_OPC_CMP_SNE_S = FOP(27, FMT_W),
8364 R6_OPC_CMP_AF_D = FOP(0, FMT_L),
8365 R6_OPC_CMP_UN_D = FOP(1, FMT_L),
8366 R6_OPC_CMP_EQ_D = FOP(2, FMT_L),
8367 R6_OPC_CMP_UEQ_D = FOP(3, FMT_L),
8368 R6_OPC_CMP_LT_D = FOP(4, FMT_L),
8369 R6_OPC_CMP_ULT_D = FOP(5, FMT_L),
8370 R6_OPC_CMP_LE_D = FOP(6, FMT_L),
8371 R6_OPC_CMP_ULE_D = FOP(7, FMT_L),
8372 R6_OPC_CMP_SAF_D = FOP(8, FMT_L),
8373 R6_OPC_CMP_SUN_D = FOP(9, FMT_L),
8374 R6_OPC_CMP_SEQ_D = FOP(10, FMT_L),
8375 R6_OPC_CMP_SEUQ_D = FOP(11, FMT_L),
8376 R6_OPC_CMP_SLT_D = FOP(12, FMT_L),
8377 R6_OPC_CMP_SULT_D = FOP(13, FMT_L),
8378 R6_OPC_CMP_SLE_D = FOP(14, FMT_L),
8379 R6_OPC_CMP_SULE_D = FOP(15, FMT_L),
8380 R6_OPC_CMP_OR_D = FOP(17, FMT_L),
8381 R6_OPC_CMP_UNE_D = FOP(18, FMT_L),
8382 R6_OPC_CMP_NE_D = FOP(19, FMT_L),
8383 R6_OPC_CMP_SOR_D = FOP(25, FMT_L),
8384 R6_OPC_CMP_SUNE_D = FOP(26, FMT_L),
8385 R6_OPC_CMP_SNE_D = FOP(27, FMT_L),
8387 static void gen_cp1 (DisasContext *ctx, uint32_t opc, int rt, int fs)
8389 const char *opn = "cp1 move";
8390 TCGv t0 = tcg_temp_new();
8395 TCGv_i32 fp0 = tcg_temp_new_i32();
8397 gen_load_fpr32(ctx, fp0, fs);
8398 tcg_gen_ext_i32_tl(t0, fp0);
8399 tcg_temp_free_i32(fp0);
8401 gen_store_gpr(t0, rt);
8405 gen_load_gpr(t0, rt);
8407 TCGv_i32 fp0 = tcg_temp_new_i32();
8409 tcg_gen_trunc_tl_i32(fp0, t0);
8410 gen_store_fpr32(ctx, fp0, fs);
8411 tcg_temp_free_i32(fp0);
8416 gen_helper_1e0i(cfc1, t0, fs);
8417 gen_store_gpr(t0, rt);
8421 gen_load_gpr(t0, rt);
8422 save_cpu_state(ctx, 1);
8424 TCGv_i32 fs_tmp = tcg_const_i32(fs);
8426 gen_helper_0e2i(ctc1, t0, fs_tmp, rt);
8427 tcg_temp_free_i32(fs_tmp);
8429 /* Stop translation as we may have changed hflags */
8430 ctx->bstate = BS_STOP;
8433 #if defined(TARGET_MIPS64)
8435 gen_load_fpr64(ctx, t0, fs);
8436 gen_store_gpr(t0, rt);
8440 gen_load_gpr(t0, rt);
8441 gen_store_fpr64(ctx, t0, fs);
8447 TCGv_i32 fp0 = tcg_temp_new_i32();
8449 gen_load_fpr32h(ctx, fp0, fs);
8450 tcg_gen_ext_i32_tl(t0, fp0);
8451 tcg_temp_free_i32(fp0);
8453 gen_store_gpr(t0, rt);
8457 gen_load_gpr(t0, rt);
8459 TCGv_i32 fp0 = tcg_temp_new_i32();
8461 tcg_gen_trunc_tl_i32(fp0, t0);
8462 gen_store_fpr32h(ctx, fp0, fs);
8463 tcg_temp_free_i32(fp0);
8469 generate_exception (ctx, EXCP_RI);
8472 (void)opn; /* avoid a compiler warning */
8473 MIPS_DEBUG("%s %s %s", opn, regnames[rt], fregnames[fs]);
8479 static void gen_movci (DisasContext *ctx, int rd, int rs, int cc, int tf)
8495 l1 = gen_new_label();
8496 t0 = tcg_temp_new_i32();
8497 tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc));
8498 tcg_gen_brcondi_i32(cond, t0, 0, l1);
8499 tcg_temp_free_i32(t0);
8501 tcg_gen_movi_tl(cpu_gpr[rd], 0);
8503 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
8508 static inline void gen_movcf_s(DisasContext *ctx, int fs, int fd, int cc,
8512 TCGv_i32 t0 = tcg_temp_new_i32();
8513 TCGLabel *l1 = gen_new_label();
8520 tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc));
8521 tcg_gen_brcondi_i32(cond, t0, 0, l1);
8522 gen_load_fpr32(ctx, t0, fs);
8523 gen_store_fpr32(ctx, t0, fd);
8525 tcg_temp_free_i32(t0);
8528 static inline void gen_movcf_d (DisasContext *ctx, int fs, int fd, int cc, int tf)
8531 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 tcg_temp_free_i32(t0);
8543 fp0 = tcg_temp_new_i64();
8544 gen_load_fpr64(ctx, fp0, fs);
8545 gen_store_fpr64(ctx, fp0, fd);
8546 tcg_temp_free_i64(fp0);
8550 static inline void gen_movcf_ps(DisasContext *ctx, int fs, int fd,
8554 TCGv_i32 t0 = tcg_temp_new_i32();
8555 TCGLabel *l1 = gen_new_label();
8556 TCGLabel *l2 = gen_new_label();
8563 tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc));
8564 tcg_gen_brcondi_i32(cond, t0, 0, l1);
8565 gen_load_fpr32(ctx, t0, fs);
8566 gen_store_fpr32(ctx, t0, fd);
8569 tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc+1));
8570 tcg_gen_brcondi_i32(cond, t0, 0, l2);
8571 gen_load_fpr32h(ctx, t0, fs);
8572 gen_store_fpr32h(ctx, t0, fd);
8573 tcg_temp_free_i32(t0);
8577 static void gen_sel_s(DisasContext *ctx, enum fopcode op1, int fd, int ft,
8580 TCGv_i32 t1 = tcg_const_i32(0);
8581 TCGv_i32 fp0 = tcg_temp_new_i32();
8582 TCGv_i32 fp1 = tcg_temp_new_i32();
8583 TCGv_i32 fp2 = tcg_temp_new_i32();
8584 gen_load_fpr32(ctx, fp0, fd);
8585 gen_load_fpr32(ctx, fp1, ft);
8586 gen_load_fpr32(ctx, fp2, fs);
8590 tcg_gen_andi_i32(fp0, fp0, 1);
8591 tcg_gen_movcond_i32(TCG_COND_NE, fp0, fp0, t1, fp1, fp2);
8594 tcg_gen_andi_i32(fp1, fp1, 1);
8595 tcg_gen_movcond_i32(TCG_COND_EQ, fp0, fp1, t1, fp2, t1);
8598 tcg_gen_andi_i32(fp1, fp1, 1);
8599 tcg_gen_movcond_i32(TCG_COND_NE, fp0, fp1, t1, fp2, t1);
8602 MIPS_INVAL("gen_sel_s");
8603 generate_exception (ctx, EXCP_RI);
8607 gen_store_fpr32(ctx, fp0, fd);
8608 tcg_temp_free_i32(fp2);
8609 tcg_temp_free_i32(fp1);
8610 tcg_temp_free_i32(fp0);
8611 tcg_temp_free_i32(t1);
8614 static void gen_sel_d(DisasContext *ctx, enum fopcode op1, int fd, int ft,
8617 TCGv_i64 t1 = tcg_const_i64(0);
8618 TCGv_i64 fp0 = tcg_temp_new_i64();
8619 TCGv_i64 fp1 = tcg_temp_new_i64();
8620 TCGv_i64 fp2 = tcg_temp_new_i64();
8621 gen_load_fpr64(ctx, fp0, fd);
8622 gen_load_fpr64(ctx, fp1, ft);
8623 gen_load_fpr64(ctx, fp2, fs);
8627 tcg_gen_andi_i64(fp0, fp0, 1);
8628 tcg_gen_movcond_i64(TCG_COND_NE, fp0, fp0, t1, fp1, fp2);
8631 tcg_gen_andi_i64(fp1, fp1, 1);
8632 tcg_gen_movcond_i64(TCG_COND_EQ, fp0, fp1, t1, fp2, t1);
8635 tcg_gen_andi_i64(fp1, fp1, 1);
8636 tcg_gen_movcond_i64(TCG_COND_NE, fp0, fp1, t1, fp2, t1);
8639 MIPS_INVAL("gen_sel_d");
8640 generate_exception (ctx, EXCP_RI);
8644 gen_store_fpr64(ctx, fp0, fd);
8645 tcg_temp_free_i64(fp2);
8646 tcg_temp_free_i64(fp1);
8647 tcg_temp_free_i64(fp0);
8648 tcg_temp_free_i64(t1);
8651 static void gen_farith (DisasContext *ctx, enum fopcode op1,
8652 int ft, int fs, int fd, int cc)
8654 const char *opn = "farith";
8655 const char *condnames[] = {
8673 const char *condnames_abs[] = {
8691 enum { BINOP, CMPOP, OTHEROP } optype = OTHEROP;
8692 uint32_t func = ctx->opcode & 0x3f;
8697 TCGv_i32 fp0 = tcg_temp_new_i32();
8698 TCGv_i32 fp1 = tcg_temp_new_i32();
8700 gen_load_fpr32(ctx, fp0, fs);
8701 gen_load_fpr32(ctx, fp1, ft);
8702 gen_helper_float_add_s(fp0, cpu_env, fp0, fp1);
8703 tcg_temp_free_i32(fp1);
8704 gen_store_fpr32(ctx, fp0, fd);
8705 tcg_temp_free_i32(fp0);
8712 TCGv_i32 fp0 = tcg_temp_new_i32();
8713 TCGv_i32 fp1 = tcg_temp_new_i32();
8715 gen_load_fpr32(ctx, fp0, fs);
8716 gen_load_fpr32(ctx, fp1, ft);
8717 gen_helper_float_sub_s(fp0, cpu_env, fp0, fp1);
8718 tcg_temp_free_i32(fp1);
8719 gen_store_fpr32(ctx, fp0, fd);
8720 tcg_temp_free_i32(fp0);
8727 TCGv_i32 fp0 = tcg_temp_new_i32();
8728 TCGv_i32 fp1 = tcg_temp_new_i32();
8730 gen_load_fpr32(ctx, fp0, fs);
8731 gen_load_fpr32(ctx, fp1, ft);
8732 gen_helper_float_mul_s(fp0, cpu_env, fp0, fp1);
8733 tcg_temp_free_i32(fp1);
8734 gen_store_fpr32(ctx, fp0, fd);
8735 tcg_temp_free_i32(fp0);
8742 TCGv_i32 fp0 = tcg_temp_new_i32();
8743 TCGv_i32 fp1 = tcg_temp_new_i32();
8745 gen_load_fpr32(ctx, fp0, fs);
8746 gen_load_fpr32(ctx, fp1, ft);
8747 gen_helper_float_div_s(fp0, cpu_env, fp0, fp1);
8748 tcg_temp_free_i32(fp1);
8749 gen_store_fpr32(ctx, fp0, fd);
8750 tcg_temp_free_i32(fp0);
8757 TCGv_i32 fp0 = tcg_temp_new_i32();
8759 gen_load_fpr32(ctx, fp0, fs);
8760 gen_helper_float_sqrt_s(fp0, cpu_env, fp0);
8761 gen_store_fpr32(ctx, fp0, fd);
8762 tcg_temp_free_i32(fp0);
8768 TCGv_i32 fp0 = tcg_temp_new_i32();
8770 gen_load_fpr32(ctx, fp0, fs);
8771 gen_helper_float_abs_s(fp0, fp0);
8772 gen_store_fpr32(ctx, fp0, fd);
8773 tcg_temp_free_i32(fp0);
8779 TCGv_i32 fp0 = tcg_temp_new_i32();
8781 gen_load_fpr32(ctx, fp0, fs);
8782 gen_store_fpr32(ctx, fp0, fd);
8783 tcg_temp_free_i32(fp0);
8789 TCGv_i32 fp0 = tcg_temp_new_i32();
8791 gen_load_fpr32(ctx, fp0, fs);
8792 gen_helper_float_chs_s(fp0, fp0);
8793 gen_store_fpr32(ctx, fp0, fd);
8794 tcg_temp_free_i32(fp0);
8799 check_cp1_64bitmode(ctx);
8801 TCGv_i32 fp32 = tcg_temp_new_i32();
8802 TCGv_i64 fp64 = tcg_temp_new_i64();
8804 gen_load_fpr32(ctx, fp32, fs);
8805 gen_helper_float_roundl_s(fp64, cpu_env, fp32);
8806 tcg_temp_free_i32(fp32);
8807 gen_store_fpr64(ctx, fp64, fd);
8808 tcg_temp_free_i64(fp64);
8813 check_cp1_64bitmode(ctx);
8815 TCGv_i32 fp32 = tcg_temp_new_i32();
8816 TCGv_i64 fp64 = tcg_temp_new_i64();
8818 gen_load_fpr32(ctx, fp32, fs);
8819 gen_helper_float_truncl_s(fp64, cpu_env, fp32);
8820 tcg_temp_free_i32(fp32);
8821 gen_store_fpr64(ctx, fp64, fd);
8822 tcg_temp_free_i64(fp64);
8827 check_cp1_64bitmode(ctx);
8829 TCGv_i32 fp32 = tcg_temp_new_i32();
8830 TCGv_i64 fp64 = tcg_temp_new_i64();
8832 gen_load_fpr32(ctx, fp32, fs);
8833 gen_helper_float_ceill_s(fp64, cpu_env, fp32);
8834 tcg_temp_free_i32(fp32);
8835 gen_store_fpr64(ctx, fp64, fd);
8836 tcg_temp_free_i64(fp64);
8841 check_cp1_64bitmode(ctx);
8843 TCGv_i32 fp32 = tcg_temp_new_i32();
8844 TCGv_i64 fp64 = tcg_temp_new_i64();
8846 gen_load_fpr32(ctx, fp32, fs);
8847 gen_helper_float_floorl_s(fp64, cpu_env, fp32);
8848 tcg_temp_free_i32(fp32);
8849 gen_store_fpr64(ctx, fp64, fd);
8850 tcg_temp_free_i64(fp64);
8856 TCGv_i32 fp0 = tcg_temp_new_i32();
8858 gen_load_fpr32(ctx, fp0, fs);
8859 gen_helper_float_roundw_s(fp0, cpu_env, fp0);
8860 gen_store_fpr32(ctx, fp0, fd);
8861 tcg_temp_free_i32(fp0);
8867 TCGv_i32 fp0 = tcg_temp_new_i32();
8869 gen_load_fpr32(ctx, fp0, fs);
8870 gen_helper_float_truncw_s(fp0, cpu_env, fp0);
8871 gen_store_fpr32(ctx, fp0, fd);
8872 tcg_temp_free_i32(fp0);
8878 TCGv_i32 fp0 = tcg_temp_new_i32();
8880 gen_load_fpr32(ctx, fp0, fs);
8881 gen_helper_float_ceilw_s(fp0, cpu_env, fp0);
8882 gen_store_fpr32(ctx, fp0, fd);
8883 tcg_temp_free_i32(fp0);
8889 TCGv_i32 fp0 = tcg_temp_new_i32();
8891 gen_load_fpr32(ctx, fp0, fs);
8892 gen_helper_float_floorw_s(fp0, cpu_env, fp0);
8893 gen_store_fpr32(ctx, fp0, fd);
8894 tcg_temp_free_i32(fp0);
8899 check_insn(ctx, ISA_MIPS32R6);
8900 gen_sel_s(ctx, op1, fd, ft, fs);
8904 check_insn(ctx, ISA_MIPS32R6);
8905 gen_sel_s(ctx, op1, fd, ft, fs);
8909 check_insn(ctx, ISA_MIPS32R6);
8910 gen_sel_s(ctx, op1, fd, ft, fs);
8914 check_insn_opc_removed(ctx, ISA_MIPS32R6);
8915 gen_movcf_s(ctx, fs, fd, (ft >> 2) & 0x7, ft & 0x1);
8919 check_insn_opc_removed(ctx, ISA_MIPS32R6);
8921 TCGLabel *l1 = gen_new_label();
8925 tcg_gen_brcondi_tl(TCG_COND_NE, cpu_gpr[ft], 0, l1);
8927 fp0 = tcg_temp_new_i32();
8928 gen_load_fpr32(ctx, fp0, fs);
8929 gen_store_fpr32(ctx, fp0, fd);
8930 tcg_temp_free_i32(fp0);
8936 check_insn_opc_removed(ctx, ISA_MIPS32R6);
8938 TCGLabel *l1 = gen_new_label();
8942 tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_gpr[ft], 0, l1);
8943 fp0 = tcg_temp_new_i32();
8944 gen_load_fpr32(ctx, fp0, fs);
8945 gen_store_fpr32(ctx, fp0, fd);
8946 tcg_temp_free_i32(fp0);
8955 TCGv_i32 fp0 = tcg_temp_new_i32();
8957 gen_load_fpr32(ctx, fp0, fs);
8958 gen_helper_float_recip_s(fp0, cpu_env, fp0);
8959 gen_store_fpr32(ctx, fp0, fd);
8960 tcg_temp_free_i32(fp0);
8967 TCGv_i32 fp0 = tcg_temp_new_i32();
8969 gen_load_fpr32(ctx, fp0, fs);
8970 gen_helper_float_rsqrt_s(fp0, cpu_env, fp0);
8971 gen_store_fpr32(ctx, fp0, fd);
8972 tcg_temp_free_i32(fp0);
8977 check_insn(ctx, ISA_MIPS32R6);
8979 TCGv_i32 fp0 = tcg_temp_new_i32();
8980 TCGv_i32 fp1 = tcg_temp_new_i32();
8981 TCGv_i32 fp2 = tcg_temp_new_i32();
8982 gen_load_fpr32(ctx, fp0, fs);
8983 gen_load_fpr32(ctx, fp1, ft);
8984 gen_load_fpr32(ctx, fp2, fd);
8985 gen_helper_float_maddf_s(fp2, cpu_env, fp0, fp1, fp2);
8986 gen_store_fpr32(ctx, fp2, fd);
8987 tcg_temp_free_i32(fp2);
8988 tcg_temp_free_i32(fp1);
8989 tcg_temp_free_i32(fp0);
8994 check_insn(ctx, ISA_MIPS32R6);
8996 TCGv_i32 fp0 = tcg_temp_new_i32();
8997 TCGv_i32 fp1 = tcg_temp_new_i32();
8998 TCGv_i32 fp2 = tcg_temp_new_i32();
8999 gen_load_fpr32(ctx, fp0, fs);
9000 gen_load_fpr32(ctx, fp1, ft);
9001 gen_load_fpr32(ctx, fp2, fd);
9002 gen_helper_float_msubf_s(fp2, cpu_env, fp0, fp1, fp2);
9003 gen_store_fpr32(ctx, fp2, fd);
9004 tcg_temp_free_i32(fp2);
9005 tcg_temp_free_i32(fp1);
9006 tcg_temp_free_i32(fp0);
9011 check_insn(ctx, ISA_MIPS32R6);
9013 TCGv_i32 fp0 = tcg_temp_new_i32();
9014 gen_load_fpr32(ctx, fp0, fs);
9015 gen_helper_float_rint_s(fp0, cpu_env, fp0);
9016 gen_store_fpr32(ctx, fp0, fd);
9017 tcg_temp_free_i32(fp0);
9022 check_insn(ctx, ISA_MIPS32R6);
9024 TCGv_i32 fp0 = tcg_temp_new_i32();
9025 gen_load_fpr32(ctx, fp0, fs);
9026 gen_helper_float_class_s(fp0, fp0);
9027 gen_store_fpr32(ctx, fp0, fd);
9028 tcg_temp_free_i32(fp0);
9032 case OPC_MIN_S: /* OPC_RECIP2_S */
9033 if (ctx->insn_flags & ISA_MIPS32R6) {
9035 TCGv_i32 fp0 = tcg_temp_new_i32();
9036 TCGv_i32 fp1 = tcg_temp_new_i32();
9037 TCGv_i32 fp2 = tcg_temp_new_i32();
9038 gen_load_fpr32(ctx, fp0, fs);
9039 gen_load_fpr32(ctx, fp1, ft);
9040 gen_helper_float_min_s(fp2, cpu_env, fp0, fp1);
9041 gen_store_fpr32(ctx, fp2, fd);
9042 tcg_temp_free_i32(fp2);
9043 tcg_temp_free_i32(fp1);
9044 tcg_temp_free_i32(fp0);
9048 check_cp1_64bitmode(ctx);
9050 TCGv_i32 fp0 = tcg_temp_new_i32();
9051 TCGv_i32 fp1 = tcg_temp_new_i32();
9053 gen_load_fpr32(ctx, fp0, fs);
9054 gen_load_fpr32(ctx, fp1, ft);
9055 gen_helper_float_recip2_s(fp0, cpu_env, fp0, fp1);
9056 tcg_temp_free_i32(fp1);
9057 gen_store_fpr32(ctx, fp0, fd);
9058 tcg_temp_free_i32(fp0);
9063 case OPC_MINA_S: /* OPC_RECIP1_S */
9064 if (ctx->insn_flags & ISA_MIPS32R6) {
9066 TCGv_i32 fp0 = tcg_temp_new_i32();
9067 TCGv_i32 fp1 = tcg_temp_new_i32();
9068 TCGv_i32 fp2 = tcg_temp_new_i32();
9069 gen_load_fpr32(ctx, fp0, fs);
9070 gen_load_fpr32(ctx, fp1, ft);
9071 gen_helper_float_mina_s(fp2, cpu_env, fp0, fp1);
9072 gen_store_fpr32(ctx, fp2, fd);
9073 tcg_temp_free_i32(fp2);
9074 tcg_temp_free_i32(fp1);
9075 tcg_temp_free_i32(fp0);
9079 check_cp1_64bitmode(ctx);
9081 TCGv_i32 fp0 = tcg_temp_new_i32();
9083 gen_load_fpr32(ctx, fp0, fs);
9084 gen_helper_float_recip1_s(fp0, cpu_env, fp0);
9085 gen_store_fpr32(ctx, fp0, fd);
9086 tcg_temp_free_i32(fp0);
9091 case OPC_MAX_S: /* OPC_RSQRT1_S */
9092 if (ctx->insn_flags & ISA_MIPS32R6) {
9094 TCGv_i32 fp0 = tcg_temp_new_i32();
9095 TCGv_i32 fp1 = tcg_temp_new_i32();
9096 gen_load_fpr32(ctx, fp0, fs);
9097 gen_load_fpr32(ctx, fp1, ft);
9098 gen_helper_float_max_s(fp1, cpu_env, fp0, fp1);
9099 gen_store_fpr32(ctx, fp1, fd);
9100 tcg_temp_free_i32(fp1);
9101 tcg_temp_free_i32(fp0);
9105 check_cp1_64bitmode(ctx);
9107 TCGv_i32 fp0 = tcg_temp_new_i32();
9109 gen_load_fpr32(ctx, fp0, fs);
9110 gen_helper_float_rsqrt1_s(fp0, cpu_env, fp0);
9111 gen_store_fpr32(ctx, fp0, fd);
9112 tcg_temp_free_i32(fp0);
9117 case OPC_MAXA_S: /* OPC_RSQRT2_S */
9118 if (ctx->insn_flags & ISA_MIPS32R6) {
9120 TCGv_i32 fp0 = tcg_temp_new_i32();
9121 TCGv_i32 fp1 = tcg_temp_new_i32();
9122 gen_load_fpr32(ctx, fp0, fs);
9123 gen_load_fpr32(ctx, fp1, ft);
9124 gen_helper_float_maxa_s(fp1, cpu_env, fp0, fp1);
9125 gen_store_fpr32(ctx, fp1, fd);
9126 tcg_temp_free_i32(fp1);
9127 tcg_temp_free_i32(fp0);
9131 check_cp1_64bitmode(ctx);
9133 TCGv_i32 fp0 = tcg_temp_new_i32();
9134 TCGv_i32 fp1 = tcg_temp_new_i32();
9136 gen_load_fpr32(ctx, fp0, fs);
9137 gen_load_fpr32(ctx, fp1, ft);
9138 gen_helper_float_rsqrt2_s(fp0, cpu_env, fp0, fp1);
9139 tcg_temp_free_i32(fp1);
9140 gen_store_fpr32(ctx, fp0, fd);
9141 tcg_temp_free_i32(fp0);
9147 check_cp1_registers(ctx, fd);
9149 TCGv_i32 fp32 = tcg_temp_new_i32();
9150 TCGv_i64 fp64 = tcg_temp_new_i64();
9152 gen_load_fpr32(ctx, fp32, fs);
9153 gen_helper_float_cvtd_s(fp64, cpu_env, fp32);
9154 tcg_temp_free_i32(fp32);
9155 gen_store_fpr64(ctx, fp64, fd);
9156 tcg_temp_free_i64(fp64);
9162 TCGv_i32 fp0 = tcg_temp_new_i32();
9164 gen_load_fpr32(ctx, fp0, fs);
9165 gen_helper_float_cvtw_s(fp0, cpu_env, fp0);
9166 gen_store_fpr32(ctx, fp0, fd);
9167 tcg_temp_free_i32(fp0);
9172 check_cp1_64bitmode(ctx);
9174 TCGv_i32 fp32 = tcg_temp_new_i32();
9175 TCGv_i64 fp64 = tcg_temp_new_i64();
9177 gen_load_fpr32(ctx, fp32, fs);
9178 gen_helper_float_cvtl_s(fp64, cpu_env, fp32);
9179 tcg_temp_free_i32(fp32);
9180 gen_store_fpr64(ctx, fp64, fd);
9181 tcg_temp_free_i64(fp64);
9186 check_insn_opc_removed(ctx, ISA_MIPS32R6);
9187 check_cp1_64bitmode(ctx);
9189 TCGv_i64 fp64 = tcg_temp_new_i64();
9190 TCGv_i32 fp32_0 = tcg_temp_new_i32();
9191 TCGv_i32 fp32_1 = tcg_temp_new_i32();
9193 gen_load_fpr32(ctx, fp32_0, fs);
9194 gen_load_fpr32(ctx, fp32_1, ft);
9195 tcg_gen_concat_i32_i64(fp64, fp32_1, fp32_0);
9196 tcg_temp_free_i32(fp32_1);
9197 tcg_temp_free_i32(fp32_0);
9198 gen_store_fpr64(ctx, fp64, fd);
9199 tcg_temp_free_i64(fp64);
9212 case OPC_CMP_NGLE_S:
9219 check_insn_opc_removed(ctx, ISA_MIPS32R6);
9220 if (ctx->opcode & (1 << 6)) {
9221 gen_cmpabs_s(ctx, func-48, ft, fs, cc);
9222 opn = condnames_abs[func-48];
9224 gen_cmp_s(ctx, func-48, ft, fs, cc);
9225 opn = condnames[func-48];
9229 check_cp1_registers(ctx, fs | ft | fd);
9231 TCGv_i64 fp0 = tcg_temp_new_i64();
9232 TCGv_i64 fp1 = tcg_temp_new_i64();
9234 gen_load_fpr64(ctx, fp0, fs);
9235 gen_load_fpr64(ctx, fp1, ft);
9236 gen_helper_float_add_d(fp0, cpu_env, fp0, fp1);
9237 tcg_temp_free_i64(fp1);
9238 gen_store_fpr64(ctx, fp0, fd);
9239 tcg_temp_free_i64(fp0);
9245 check_cp1_registers(ctx, fs | ft | fd);
9247 TCGv_i64 fp0 = tcg_temp_new_i64();
9248 TCGv_i64 fp1 = tcg_temp_new_i64();
9250 gen_load_fpr64(ctx, fp0, fs);
9251 gen_load_fpr64(ctx, fp1, ft);
9252 gen_helper_float_sub_d(fp0, cpu_env, fp0, fp1);
9253 tcg_temp_free_i64(fp1);
9254 gen_store_fpr64(ctx, fp0, fd);
9255 tcg_temp_free_i64(fp0);
9261 check_cp1_registers(ctx, fs | ft | fd);
9263 TCGv_i64 fp0 = tcg_temp_new_i64();
9264 TCGv_i64 fp1 = tcg_temp_new_i64();
9266 gen_load_fpr64(ctx, fp0, fs);
9267 gen_load_fpr64(ctx, fp1, ft);
9268 gen_helper_float_mul_d(fp0, cpu_env, fp0, fp1);
9269 tcg_temp_free_i64(fp1);
9270 gen_store_fpr64(ctx, fp0, fd);
9271 tcg_temp_free_i64(fp0);
9277 check_cp1_registers(ctx, fs | ft | fd);
9279 TCGv_i64 fp0 = tcg_temp_new_i64();
9280 TCGv_i64 fp1 = tcg_temp_new_i64();
9282 gen_load_fpr64(ctx, fp0, fs);
9283 gen_load_fpr64(ctx, fp1, ft);
9284 gen_helper_float_div_d(fp0, cpu_env, fp0, fp1);
9285 tcg_temp_free_i64(fp1);
9286 gen_store_fpr64(ctx, fp0, fd);
9287 tcg_temp_free_i64(fp0);
9293 check_cp1_registers(ctx, fs | fd);
9295 TCGv_i64 fp0 = tcg_temp_new_i64();
9297 gen_load_fpr64(ctx, fp0, fs);
9298 gen_helper_float_sqrt_d(fp0, cpu_env, fp0);
9299 gen_store_fpr64(ctx, fp0, fd);
9300 tcg_temp_free_i64(fp0);
9305 check_cp1_registers(ctx, fs | fd);
9307 TCGv_i64 fp0 = tcg_temp_new_i64();
9309 gen_load_fpr64(ctx, fp0, fs);
9310 gen_helper_float_abs_d(fp0, fp0);
9311 gen_store_fpr64(ctx, fp0, fd);
9312 tcg_temp_free_i64(fp0);
9317 check_cp1_registers(ctx, fs | fd);
9319 TCGv_i64 fp0 = tcg_temp_new_i64();
9321 gen_load_fpr64(ctx, fp0, fs);
9322 gen_store_fpr64(ctx, fp0, fd);
9323 tcg_temp_free_i64(fp0);
9328 check_cp1_registers(ctx, fs | fd);
9330 TCGv_i64 fp0 = tcg_temp_new_i64();
9332 gen_load_fpr64(ctx, fp0, fs);
9333 gen_helper_float_chs_d(fp0, fp0);
9334 gen_store_fpr64(ctx, fp0, fd);
9335 tcg_temp_free_i64(fp0);
9340 check_cp1_64bitmode(ctx);
9342 TCGv_i64 fp0 = tcg_temp_new_i64();
9344 gen_load_fpr64(ctx, fp0, fs);
9345 gen_helper_float_roundl_d(fp0, cpu_env, fp0);
9346 gen_store_fpr64(ctx, fp0, fd);
9347 tcg_temp_free_i64(fp0);
9352 check_cp1_64bitmode(ctx);
9354 TCGv_i64 fp0 = tcg_temp_new_i64();
9356 gen_load_fpr64(ctx, fp0, fs);
9357 gen_helper_float_truncl_d(fp0, cpu_env, fp0);
9358 gen_store_fpr64(ctx, fp0, fd);
9359 tcg_temp_free_i64(fp0);
9364 check_cp1_64bitmode(ctx);
9366 TCGv_i64 fp0 = tcg_temp_new_i64();
9368 gen_load_fpr64(ctx, fp0, fs);
9369 gen_helper_float_ceill_d(fp0, cpu_env, fp0);
9370 gen_store_fpr64(ctx, fp0, fd);
9371 tcg_temp_free_i64(fp0);
9376 check_cp1_64bitmode(ctx);
9378 TCGv_i64 fp0 = tcg_temp_new_i64();
9380 gen_load_fpr64(ctx, fp0, fs);
9381 gen_helper_float_floorl_d(fp0, cpu_env, fp0);
9382 gen_store_fpr64(ctx, fp0, fd);
9383 tcg_temp_free_i64(fp0);
9388 check_cp1_registers(ctx, fs);
9390 TCGv_i32 fp32 = tcg_temp_new_i32();
9391 TCGv_i64 fp64 = tcg_temp_new_i64();
9393 gen_load_fpr64(ctx, fp64, fs);
9394 gen_helper_float_roundw_d(fp32, cpu_env, fp64);
9395 tcg_temp_free_i64(fp64);
9396 gen_store_fpr32(ctx, fp32, fd);
9397 tcg_temp_free_i32(fp32);
9402 check_cp1_registers(ctx, fs);
9404 TCGv_i32 fp32 = tcg_temp_new_i32();
9405 TCGv_i64 fp64 = tcg_temp_new_i64();
9407 gen_load_fpr64(ctx, fp64, fs);
9408 gen_helper_float_truncw_d(fp32, cpu_env, fp64);
9409 tcg_temp_free_i64(fp64);
9410 gen_store_fpr32(ctx, fp32, fd);
9411 tcg_temp_free_i32(fp32);
9416 check_cp1_registers(ctx, fs);
9418 TCGv_i32 fp32 = tcg_temp_new_i32();
9419 TCGv_i64 fp64 = tcg_temp_new_i64();
9421 gen_load_fpr64(ctx, fp64, fs);
9422 gen_helper_float_ceilw_d(fp32, cpu_env, fp64);
9423 tcg_temp_free_i64(fp64);
9424 gen_store_fpr32(ctx, fp32, fd);
9425 tcg_temp_free_i32(fp32);
9430 check_cp1_registers(ctx, fs);
9432 TCGv_i32 fp32 = tcg_temp_new_i32();
9433 TCGv_i64 fp64 = tcg_temp_new_i64();
9435 gen_load_fpr64(ctx, fp64, fs);
9436 gen_helper_float_floorw_d(fp32, cpu_env, fp64);
9437 tcg_temp_free_i64(fp64);
9438 gen_store_fpr32(ctx, fp32, fd);
9439 tcg_temp_free_i32(fp32);
9444 check_insn(ctx, ISA_MIPS32R6);
9445 gen_sel_d(ctx, op1, fd, ft, fs);
9449 check_insn(ctx, ISA_MIPS32R6);
9450 gen_sel_d(ctx, op1, fd, ft, fs);
9454 check_insn(ctx, ISA_MIPS32R6);
9455 gen_sel_d(ctx, op1, fd, ft, fs);
9459 check_insn_opc_removed(ctx, ISA_MIPS32R6);
9460 gen_movcf_d(ctx, fs, fd, (ft >> 2) & 0x7, ft & 0x1);
9464 check_insn_opc_removed(ctx, ISA_MIPS32R6);
9466 TCGLabel *l1 = gen_new_label();
9470 tcg_gen_brcondi_tl(TCG_COND_NE, cpu_gpr[ft], 0, l1);
9472 fp0 = tcg_temp_new_i64();
9473 gen_load_fpr64(ctx, fp0, fs);
9474 gen_store_fpr64(ctx, fp0, fd);
9475 tcg_temp_free_i64(fp0);
9481 check_insn_opc_removed(ctx, ISA_MIPS32R6);
9483 TCGLabel *l1 = gen_new_label();
9487 tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_gpr[ft], 0, l1);
9488 fp0 = tcg_temp_new_i64();
9489 gen_load_fpr64(ctx, fp0, fs);
9490 gen_store_fpr64(ctx, fp0, fd);
9491 tcg_temp_free_i64(fp0);
9498 check_cp1_64bitmode(ctx);
9500 TCGv_i64 fp0 = tcg_temp_new_i64();
9502 gen_load_fpr64(ctx, fp0, fs);
9503 gen_helper_float_recip_d(fp0, cpu_env, fp0);
9504 gen_store_fpr64(ctx, fp0, fd);
9505 tcg_temp_free_i64(fp0);
9510 check_cp1_64bitmode(ctx);
9512 TCGv_i64 fp0 = tcg_temp_new_i64();
9514 gen_load_fpr64(ctx, fp0, fs);
9515 gen_helper_float_rsqrt_d(fp0, cpu_env, fp0);
9516 gen_store_fpr64(ctx, fp0, fd);
9517 tcg_temp_free_i64(fp0);
9522 check_insn(ctx, ISA_MIPS32R6);
9524 TCGv_i64 fp0 = tcg_temp_new_i64();
9525 TCGv_i64 fp1 = tcg_temp_new_i64();
9526 TCGv_i64 fp2 = tcg_temp_new_i64();
9527 gen_load_fpr64(ctx, fp0, fs);
9528 gen_load_fpr64(ctx, fp1, ft);
9529 gen_load_fpr64(ctx, fp2, fd);
9530 gen_helper_float_maddf_d(fp2, cpu_env, fp0, fp1, fp2);
9531 gen_store_fpr64(ctx, fp2, fd);
9532 tcg_temp_free_i64(fp2);
9533 tcg_temp_free_i64(fp1);
9534 tcg_temp_free_i64(fp0);
9539 check_insn(ctx, ISA_MIPS32R6);
9541 TCGv_i64 fp0 = tcg_temp_new_i64();
9542 TCGv_i64 fp1 = tcg_temp_new_i64();
9543 TCGv_i64 fp2 = tcg_temp_new_i64();
9544 gen_load_fpr64(ctx, fp0, fs);
9545 gen_load_fpr64(ctx, fp1, ft);
9546 gen_load_fpr64(ctx, fp2, fd);
9547 gen_helper_float_msubf_d(fp2, cpu_env, fp0, fp1, fp2);
9548 gen_store_fpr64(ctx, fp2, fd);
9549 tcg_temp_free_i64(fp2);
9550 tcg_temp_free_i64(fp1);
9551 tcg_temp_free_i64(fp0);
9556 check_insn(ctx, ISA_MIPS32R6);
9558 TCGv_i64 fp0 = tcg_temp_new_i64();
9559 gen_load_fpr64(ctx, fp0, fs);
9560 gen_helper_float_rint_d(fp0, cpu_env, fp0);
9561 gen_store_fpr64(ctx, fp0, fd);
9562 tcg_temp_free_i64(fp0);
9567 check_insn(ctx, ISA_MIPS32R6);
9569 TCGv_i64 fp0 = tcg_temp_new_i64();
9570 gen_load_fpr64(ctx, fp0, fs);
9571 gen_helper_float_class_d(fp0, fp0);
9572 gen_store_fpr64(ctx, fp0, fd);
9573 tcg_temp_free_i64(fp0);
9577 case OPC_MIN_D: /* OPC_RECIP2_D */
9578 if (ctx->insn_flags & ISA_MIPS32R6) {
9580 TCGv_i64 fp0 = tcg_temp_new_i64();
9581 TCGv_i64 fp1 = tcg_temp_new_i64();
9582 gen_load_fpr64(ctx, fp0, fs);
9583 gen_load_fpr64(ctx, fp1, ft);
9584 gen_helper_float_min_d(fp1, cpu_env, fp0, fp1);
9585 gen_store_fpr64(ctx, fp1, fd);
9586 tcg_temp_free_i64(fp1);
9587 tcg_temp_free_i64(fp0);
9591 check_cp1_64bitmode(ctx);
9593 TCGv_i64 fp0 = tcg_temp_new_i64();
9594 TCGv_i64 fp1 = tcg_temp_new_i64();
9596 gen_load_fpr64(ctx, fp0, fs);
9597 gen_load_fpr64(ctx, fp1, ft);
9598 gen_helper_float_recip2_d(fp0, cpu_env, fp0, fp1);
9599 tcg_temp_free_i64(fp1);
9600 gen_store_fpr64(ctx, fp0, fd);
9601 tcg_temp_free_i64(fp0);
9606 case OPC_MINA_D: /* OPC_RECIP1_D */
9607 if (ctx->insn_flags & ISA_MIPS32R6) {
9609 TCGv_i64 fp0 = tcg_temp_new_i64();
9610 TCGv_i64 fp1 = tcg_temp_new_i64();
9611 gen_load_fpr64(ctx, fp0, fs);
9612 gen_load_fpr64(ctx, fp1, ft);
9613 gen_helper_float_mina_d(fp1, cpu_env, fp0, fp1);
9614 gen_store_fpr64(ctx, fp1, fd);
9615 tcg_temp_free_i64(fp1);
9616 tcg_temp_free_i64(fp0);
9620 check_cp1_64bitmode(ctx);
9622 TCGv_i64 fp0 = tcg_temp_new_i64();
9624 gen_load_fpr64(ctx, fp0, fs);
9625 gen_helper_float_recip1_d(fp0, cpu_env, fp0);
9626 gen_store_fpr64(ctx, fp0, fd);
9627 tcg_temp_free_i64(fp0);
9632 case OPC_MAX_D: /* OPC_RSQRT1_D */
9633 if (ctx->insn_flags & ISA_MIPS32R6) {
9635 TCGv_i64 fp0 = tcg_temp_new_i64();
9636 TCGv_i64 fp1 = tcg_temp_new_i64();
9637 gen_load_fpr64(ctx, fp0, fs);
9638 gen_load_fpr64(ctx, fp1, ft);
9639 gen_helper_float_max_d(fp1, cpu_env, fp0, fp1);
9640 gen_store_fpr64(ctx, fp1, fd);
9641 tcg_temp_free_i64(fp1);
9642 tcg_temp_free_i64(fp0);
9646 check_cp1_64bitmode(ctx);
9648 TCGv_i64 fp0 = tcg_temp_new_i64();
9650 gen_load_fpr64(ctx, fp0, fs);
9651 gen_helper_float_rsqrt1_d(fp0, cpu_env, fp0);
9652 gen_store_fpr64(ctx, fp0, fd);
9653 tcg_temp_free_i64(fp0);
9658 case OPC_MAXA_D: /* OPC_RSQRT2_D */
9659 if (ctx->insn_flags & ISA_MIPS32R6) {
9661 TCGv_i64 fp0 = tcg_temp_new_i64();
9662 TCGv_i64 fp1 = tcg_temp_new_i64();
9663 gen_load_fpr64(ctx, fp0, fs);
9664 gen_load_fpr64(ctx, fp1, ft);
9665 gen_helper_float_maxa_d(fp1, cpu_env, fp0, fp1);
9666 gen_store_fpr64(ctx, fp1, fd);
9667 tcg_temp_free_i64(fp1);
9668 tcg_temp_free_i64(fp0);
9672 check_cp1_64bitmode(ctx);
9674 TCGv_i64 fp0 = tcg_temp_new_i64();
9675 TCGv_i64 fp1 = tcg_temp_new_i64();
9677 gen_load_fpr64(ctx, fp0, fs);
9678 gen_load_fpr64(ctx, fp1, ft);
9679 gen_helper_float_rsqrt2_d(fp0, cpu_env, fp0, fp1);
9680 tcg_temp_free_i64(fp1);
9681 gen_store_fpr64(ctx, fp0, fd);
9682 tcg_temp_free_i64(fp0);
9696 case OPC_CMP_NGLE_D:
9703 check_insn_opc_removed(ctx, ISA_MIPS32R6);
9704 if (ctx->opcode & (1 << 6)) {
9705 gen_cmpabs_d(ctx, func-48, ft, fs, cc);
9706 opn = condnames_abs[func-48];
9708 gen_cmp_d(ctx, func-48, ft, fs, cc);
9709 opn = condnames[func-48];
9713 check_cp1_registers(ctx, fs);
9715 TCGv_i32 fp32 = tcg_temp_new_i32();
9716 TCGv_i64 fp64 = tcg_temp_new_i64();
9718 gen_load_fpr64(ctx, fp64, fs);
9719 gen_helper_float_cvts_d(fp32, cpu_env, fp64);
9720 tcg_temp_free_i64(fp64);
9721 gen_store_fpr32(ctx, fp32, fd);
9722 tcg_temp_free_i32(fp32);
9727 check_cp1_registers(ctx, fs);
9729 TCGv_i32 fp32 = tcg_temp_new_i32();
9730 TCGv_i64 fp64 = tcg_temp_new_i64();
9732 gen_load_fpr64(ctx, fp64, fs);
9733 gen_helper_float_cvtw_d(fp32, cpu_env, fp64);
9734 tcg_temp_free_i64(fp64);
9735 gen_store_fpr32(ctx, fp32, fd);
9736 tcg_temp_free_i32(fp32);
9741 check_cp1_64bitmode(ctx);
9743 TCGv_i64 fp0 = tcg_temp_new_i64();
9745 gen_load_fpr64(ctx, fp0, fs);
9746 gen_helper_float_cvtl_d(fp0, cpu_env, fp0);
9747 gen_store_fpr64(ctx, fp0, fd);
9748 tcg_temp_free_i64(fp0);
9754 TCGv_i32 fp0 = tcg_temp_new_i32();
9756 gen_load_fpr32(ctx, fp0, fs);
9757 gen_helper_float_cvts_w(fp0, cpu_env, fp0);
9758 gen_store_fpr32(ctx, fp0, fd);
9759 tcg_temp_free_i32(fp0);
9764 check_cp1_registers(ctx, fd);
9766 TCGv_i32 fp32 = tcg_temp_new_i32();
9767 TCGv_i64 fp64 = tcg_temp_new_i64();
9769 gen_load_fpr32(ctx, fp32, fs);
9770 gen_helper_float_cvtd_w(fp64, cpu_env, fp32);
9771 tcg_temp_free_i32(fp32);
9772 gen_store_fpr64(ctx, fp64, fd);
9773 tcg_temp_free_i64(fp64);
9778 check_cp1_64bitmode(ctx);
9780 TCGv_i32 fp32 = tcg_temp_new_i32();
9781 TCGv_i64 fp64 = tcg_temp_new_i64();
9783 gen_load_fpr64(ctx, fp64, fs);
9784 gen_helper_float_cvts_l(fp32, cpu_env, fp64);
9785 tcg_temp_free_i64(fp64);
9786 gen_store_fpr32(ctx, fp32, fd);
9787 tcg_temp_free_i32(fp32);
9792 check_cp1_64bitmode(ctx);
9794 TCGv_i64 fp0 = tcg_temp_new_i64();
9796 gen_load_fpr64(ctx, fp0, fs);
9797 gen_helper_float_cvtd_l(fp0, cpu_env, fp0);
9798 gen_store_fpr64(ctx, fp0, fd);
9799 tcg_temp_free_i64(fp0);
9804 check_insn_opc_removed(ctx, ISA_MIPS32R6);
9805 check_cp1_64bitmode(ctx);
9807 TCGv_i64 fp0 = tcg_temp_new_i64();
9809 gen_load_fpr64(ctx, fp0, fs);
9810 gen_helper_float_cvtps_pw(fp0, cpu_env, fp0);
9811 gen_store_fpr64(ctx, fp0, fd);
9812 tcg_temp_free_i64(fp0);
9817 check_cp1_64bitmode(ctx);
9819 TCGv_i64 fp0 = tcg_temp_new_i64();
9820 TCGv_i64 fp1 = tcg_temp_new_i64();
9822 gen_load_fpr64(ctx, fp0, fs);
9823 gen_load_fpr64(ctx, fp1, ft);
9824 gen_helper_float_add_ps(fp0, cpu_env, fp0, fp1);
9825 tcg_temp_free_i64(fp1);
9826 gen_store_fpr64(ctx, fp0, fd);
9827 tcg_temp_free_i64(fp0);
9832 check_cp1_64bitmode(ctx);
9834 TCGv_i64 fp0 = tcg_temp_new_i64();
9835 TCGv_i64 fp1 = tcg_temp_new_i64();
9837 gen_load_fpr64(ctx, fp0, fs);
9838 gen_load_fpr64(ctx, fp1, ft);
9839 gen_helper_float_sub_ps(fp0, cpu_env, fp0, fp1);
9840 tcg_temp_free_i64(fp1);
9841 gen_store_fpr64(ctx, fp0, fd);
9842 tcg_temp_free_i64(fp0);
9847 check_cp1_64bitmode(ctx);
9849 TCGv_i64 fp0 = tcg_temp_new_i64();
9850 TCGv_i64 fp1 = tcg_temp_new_i64();
9852 gen_load_fpr64(ctx, fp0, fs);
9853 gen_load_fpr64(ctx, fp1, ft);
9854 gen_helper_float_mul_ps(fp0, cpu_env, fp0, fp1);
9855 tcg_temp_free_i64(fp1);
9856 gen_store_fpr64(ctx, fp0, fd);
9857 tcg_temp_free_i64(fp0);
9862 check_cp1_64bitmode(ctx);
9864 TCGv_i64 fp0 = tcg_temp_new_i64();
9866 gen_load_fpr64(ctx, fp0, fs);
9867 gen_helper_float_abs_ps(fp0, fp0);
9868 gen_store_fpr64(ctx, fp0, fd);
9869 tcg_temp_free_i64(fp0);
9874 check_cp1_64bitmode(ctx);
9876 TCGv_i64 fp0 = tcg_temp_new_i64();
9878 gen_load_fpr64(ctx, fp0, fs);
9879 gen_store_fpr64(ctx, fp0, fd);
9880 tcg_temp_free_i64(fp0);
9885 check_cp1_64bitmode(ctx);
9887 TCGv_i64 fp0 = tcg_temp_new_i64();
9889 gen_load_fpr64(ctx, fp0, fs);
9890 gen_helper_float_chs_ps(fp0, fp0);
9891 gen_store_fpr64(ctx, fp0, fd);
9892 tcg_temp_free_i64(fp0);
9897 check_cp1_64bitmode(ctx);
9898 gen_movcf_ps(ctx, fs, fd, (ft >> 2) & 0x7, ft & 0x1);
9902 check_cp1_64bitmode(ctx);
9904 TCGLabel *l1 = gen_new_label();
9908 tcg_gen_brcondi_tl(TCG_COND_NE, cpu_gpr[ft], 0, l1);
9909 fp0 = tcg_temp_new_i64();
9910 gen_load_fpr64(ctx, fp0, fs);
9911 gen_store_fpr64(ctx, fp0, fd);
9912 tcg_temp_free_i64(fp0);
9918 check_cp1_64bitmode(ctx);
9920 TCGLabel *l1 = gen_new_label();
9924 tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_gpr[ft], 0, l1);
9925 fp0 = tcg_temp_new_i64();
9926 gen_load_fpr64(ctx, fp0, fs);
9927 gen_store_fpr64(ctx, fp0, fd);
9928 tcg_temp_free_i64(fp0);
9935 check_cp1_64bitmode(ctx);
9937 TCGv_i64 fp0 = tcg_temp_new_i64();
9938 TCGv_i64 fp1 = tcg_temp_new_i64();
9940 gen_load_fpr64(ctx, fp0, ft);
9941 gen_load_fpr64(ctx, fp1, fs);
9942 gen_helper_float_addr_ps(fp0, cpu_env, fp0, fp1);
9943 tcg_temp_free_i64(fp1);
9944 gen_store_fpr64(ctx, fp0, fd);
9945 tcg_temp_free_i64(fp0);
9950 check_cp1_64bitmode(ctx);
9952 TCGv_i64 fp0 = tcg_temp_new_i64();
9953 TCGv_i64 fp1 = tcg_temp_new_i64();
9955 gen_load_fpr64(ctx, fp0, ft);
9956 gen_load_fpr64(ctx, fp1, fs);
9957 gen_helper_float_mulr_ps(fp0, cpu_env, fp0, fp1);
9958 tcg_temp_free_i64(fp1);
9959 gen_store_fpr64(ctx, fp0, fd);
9960 tcg_temp_free_i64(fp0);
9965 check_cp1_64bitmode(ctx);
9967 TCGv_i64 fp0 = tcg_temp_new_i64();
9968 TCGv_i64 fp1 = tcg_temp_new_i64();
9970 gen_load_fpr64(ctx, fp0, fs);
9971 gen_load_fpr64(ctx, fp1, ft);
9972 gen_helper_float_recip2_ps(fp0, cpu_env, fp0, fp1);
9973 tcg_temp_free_i64(fp1);
9974 gen_store_fpr64(ctx, fp0, fd);
9975 tcg_temp_free_i64(fp0);
9980 check_cp1_64bitmode(ctx);
9982 TCGv_i64 fp0 = tcg_temp_new_i64();
9984 gen_load_fpr64(ctx, fp0, fs);
9985 gen_helper_float_recip1_ps(fp0, cpu_env, fp0);
9986 gen_store_fpr64(ctx, fp0, fd);
9987 tcg_temp_free_i64(fp0);
9992 check_cp1_64bitmode(ctx);
9994 TCGv_i64 fp0 = tcg_temp_new_i64();
9996 gen_load_fpr64(ctx, fp0, fs);
9997 gen_helper_float_rsqrt1_ps(fp0, cpu_env, fp0);
9998 gen_store_fpr64(ctx, fp0, fd);
9999 tcg_temp_free_i64(fp0);
10003 case OPC_RSQRT2_PS:
10004 check_cp1_64bitmode(ctx);
10006 TCGv_i64 fp0 = tcg_temp_new_i64();
10007 TCGv_i64 fp1 = tcg_temp_new_i64();
10009 gen_load_fpr64(ctx, fp0, fs);
10010 gen_load_fpr64(ctx, fp1, ft);
10011 gen_helper_float_rsqrt2_ps(fp0, cpu_env, fp0, fp1);
10012 tcg_temp_free_i64(fp1);
10013 gen_store_fpr64(ctx, fp0, fd);
10014 tcg_temp_free_i64(fp0);
10019 check_cp1_64bitmode(ctx);
10021 TCGv_i32 fp0 = tcg_temp_new_i32();
10023 gen_load_fpr32h(ctx, fp0, fs);
10024 gen_helper_float_cvts_pu(fp0, cpu_env, fp0);
10025 gen_store_fpr32(ctx, fp0, fd);
10026 tcg_temp_free_i32(fp0);
10030 case OPC_CVT_PW_PS:
10031 check_cp1_64bitmode(ctx);
10033 TCGv_i64 fp0 = tcg_temp_new_i64();
10035 gen_load_fpr64(ctx, fp0, fs);
10036 gen_helper_float_cvtpw_ps(fp0, cpu_env, fp0);
10037 gen_store_fpr64(ctx, fp0, fd);
10038 tcg_temp_free_i64(fp0);
10043 check_cp1_64bitmode(ctx);
10045 TCGv_i32 fp0 = tcg_temp_new_i32();
10047 gen_load_fpr32(ctx, fp0, fs);
10048 gen_helper_float_cvts_pl(fp0, cpu_env, fp0);
10049 gen_store_fpr32(ctx, fp0, fd);
10050 tcg_temp_free_i32(fp0);
10055 check_cp1_64bitmode(ctx);
10057 TCGv_i32 fp0 = tcg_temp_new_i32();
10058 TCGv_i32 fp1 = tcg_temp_new_i32();
10060 gen_load_fpr32(ctx, fp0, fs);
10061 gen_load_fpr32(ctx, fp1, ft);
10062 gen_store_fpr32h(ctx, fp0, fd);
10063 gen_store_fpr32(ctx, fp1, fd);
10064 tcg_temp_free_i32(fp0);
10065 tcg_temp_free_i32(fp1);
10070 check_cp1_64bitmode(ctx);
10072 TCGv_i32 fp0 = tcg_temp_new_i32();
10073 TCGv_i32 fp1 = tcg_temp_new_i32();
10075 gen_load_fpr32(ctx, fp0, fs);
10076 gen_load_fpr32h(ctx, fp1, ft);
10077 gen_store_fpr32(ctx, fp1, fd);
10078 gen_store_fpr32h(ctx, fp0, fd);
10079 tcg_temp_free_i32(fp0);
10080 tcg_temp_free_i32(fp1);
10085 check_cp1_64bitmode(ctx);
10087 TCGv_i32 fp0 = tcg_temp_new_i32();
10088 TCGv_i32 fp1 = tcg_temp_new_i32();
10090 gen_load_fpr32h(ctx, fp0, fs);
10091 gen_load_fpr32(ctx, fp1, ft);
10092 gen_store_fpr32(ctx, fp1, fd);
10093 gen_store_fpr32h(ctx, fp0, fd);
10094 tcg_temp_free_i32(fp0);
10095 tcg_temp_free_i32(fp1);
10100 check_cp1_64bitmode(ctx);
10102 TCGv_i32 fp0 = tcg_temp_new_i32();
10103 TCGv_i32 fp1 = tcg_temp_new_i32();
10105 gen_load_fpr32h(ctx, fp0, fs);
10106 gen_load_fpr32h(ctx, fp1, ft);
10107 gen_store_fpr32(ctx, fp1, fd);
10108 gen_store_fpr32h(ctx, fp0, fd);
10109 tcg_temp_free_i32(fp0);
10110 tcg_temp_free_i32(fp1);
10115 case OPC_CMP_UN_PS:
10116 case OPC_CMP_EQ_PS:
10117 case OPC_CMP_UEQ_PS:
10118 case OPC_CMP_OLT_PS:
10119 case OPC_CMP_ULT_PS:
10120 case OPC_CMP_OLE_PS:
10121 case OPC_CMP_ULE_PS:
10122 case OPC_CMP_SF_PS:
10123 case OPC_CMP_NGLE_PS:
10124 case OPC_CMP_SEQ_PS:
10125 case OPC_CMP_NGL_PS:
10126 case OPC_CMP_LT_PS:
10127 case OPC_CMP_NGE_PS:
10128 case OPC_CMP_LE_PS:
10129 case OPC_CMP_NGT_PS:
10130 if (ctx->opcode & (1 << 6)) {
10131 gen_cmpabs_ps(ctx, func-48, ft, fs, cc);
10132 opn = condnames_abs[func-48];
10134 gen_cmp_ps(ctx, func-48, ft, fs, cc);
10135 opn = condnames[func-48];
10140 generate_exception (ctx, EXCP_RI);
10143 (void)opn; /* avoid a compiler warning */
10146 MIPS_DEBUG("%s %s, %s, %s", opn, fregnames[fd], fregnames[fs], fregnames[ft]);
10149 MIPS_DEBUG("%s %s,%s", opn, fregnames[fs], fregnames[ft]);
10152 MIPS_DEBUG("%s %s,%s", opn, fregnames[fd], fregnames[fs]);
10157 /* Coprocessor 3 (FPU) */
10158 static void gen_flt3_ldst (DisasContext *ctx, uint32_t opc,
10159 int fd, int fs, int base, int index)
10161 const char *opn = "extended float load/store";
10163 TCGv t0 = tcg_temp_new();
10166 gen_load_gpr(t0, index);
10167 } else if (index == 0) {
10168 gen_load_gpr(t0, base);
10170 gen_op_addr_add(ctx, t0, cpu_gpr[base], cpu_gpr[index]);
10172 /* Don't do NOP if destination is zero: we must perform the actual
10178 TCGv_i32 fp0 = tcg_temp_new_i32();
10180 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TESL);
10181 tcg_gen_trunc_tl_i32(fp0, t0);
10182 gen_store_fpr32(ctx, fp0, fd);
10183 tcg_temp_free_i32(fp0);
10189 check_cp1_registers(ctx, fd);
10191 TCGv_i64 fp0 = tcg_temp_new_i64();
10192 tcg_gen_qemu_ld_i64(fp0, t0, ctx->mem_idx, MO_TEQ);
10193 gen_store_fpr64(ctx, fp0, fd);
10194 tcg_temp_free_i64(fp0);
10199 check_cp1_64bitmode(ctx);
10200 tcg_gen_andi_tl(t0, t0, ~0x7);
10202 TCGv_i64 fp0 = tcg_temp_new_i64();
10204 tcg_gen_qemu_ld_i64(fp0, t0, ctx->mem_idx, MO_TEQ);
10205 gen_store_fpr64(ctx, fp0, fd);
10206 tcg_temp_free_i64(fp0);
10213 TCGv_i32 fp0 = tcg_temp_new_i32();
10214 gen_load_fpr32(ctx, fp0, fs);
10215 tcg_gen_qemu_st_i32(fp0, t0, ctx->mem_idx, MO_TEUL);
10216 tcg_temp_free_i32(fp0);
10223 check_cp1_registers(ctx, fs);
10225 TCGv_i64 fp0 = tcg_temp_new_i64();
10226 gen_load_fpr64(ctx, fp0, fs);
10227 tcg_gen_qemu_st_i64(fp0, t0, ctx->mem_idx, MO_TEQ);
10228 tcg_temp_free_i64(fp0);
10234 check_cp1_64bitmode(ctx);
10235 tcg_gen_andi_tl(t0, t0, ~0x7);
10237 TCGv_i64 fp0 = tcg_temp_new_i64();
10238 gen_load_fpr64(ctx, fp0, fs);
10239 tcg_gen_qemu_st_i64(fp0, t0, ctx->mem_idx, MO_TEQ);
10240 tcg_temp_free_i64(fp0);
10247 (void)opn; (void)store; /* avoid compiler warnings */
10248 MIPS_DEBUG("%s %s, %s(%s)", opn, fregnames[store ? fs : fd],
10249 regnames[index], regnames[base]);
10252 static void gen_flt3_arith (DisasContext *ctx, uint32_t opc,
10253 int fd, int fr, int fs, int ft)
10255 const char *opn = "flt3_arith";
10259 check_cp1_64bitmode(ctx);
10261 TCGv t0 = tcg_temp_local_new();
10262 TCGv_i32 fp = tcg_temp_new_i32();
10263 TCGv_i32 fph = tcg_temp_new_i32();
10264 TCGLabel *l1 = gen_new_label();
10265 TCGLabel *l2 = gen_new_label();
10267 gen_load_gpr(t0, fr);
10268 tcg_gen_andi_tl(t0, t0, 0x7);
10270 tcg_gen_brcondi_tl(TCG_COND_NE, t0, 0, l1);
10271 gen_load_fpr32(ctx, fp, fs);
10272 gen_load_fpr32h(ctx, fph, fs);
10273 gen_store_fpr32(ctx, fp, fd);
10274 gen_store_fpr32h(ctx, fph, fd);
10277 tcg_gen_brcondi_tl(TCG_COND_NE, t0, 4, l2);
10279 #ifdef TARGET_WORDS_BIGENDIAN
10280 gen_load_fpr32(ctx, fp, fs);
10281 gen_load_fpr32h(ctx, fph, ft);
10282 gen_store_fpr32h(ctx, fp, fd);
10283 gen_store_fpr32(ctx, fph, fd);
10285 gen_load_fpr32h(ctx, fph, fs);
10286 gen_load_fpr32(ctx, fp, ft);
10287 gen_store_fpr32(ctx, fph, fd);
10288 gen_store_fpr32h(ctx, fp, fd);
10291 tcg_temp_free_i32(fp);
10292 tcg_temp_free_i32(fph);
10299 TCGv_i32 fp0 = tcg_temp_new_i32();
10300 TCGv_i32 fp1 = tcg_temp_new_i32();
10301 TCGv_i32 fp2 = tcg_temp_new_i32();
10303 gen_load_fpr32(ctx, fp0, fs);
10304 gen_load_fpr32(ctx, fp1, ft);
10305 gen_load_fpr32(ctx, fp2, fr);
10306 gen_helper_float_madd_s(fp2, cpu_env, fp0, fp1, fp2);
10307 tcg_temp_free_i32(fp0);
10308 tcg_temp_free_i32(fp1);
10309 gen_store_fpr32(ctx, fp2, fd);
10310 tcg_temp_free_i32(fp2);
10316 check_cp1_registers(ctx, fd | fs | ft | fr);
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_madd_d(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);
10334 check_cp1_64bitmode(ctx);
10336 TCGv_i64 fp0 = tcg_temp_new_i64();
10337 TCGv_i64 fp1 = tcg_temp_new_i64();
10338 TCGv_i64 fp2 = tcg_temp_new_i64();
10340 gen_load_fpr64(ctx, fp0, fs);
10341 gen_load_fpr64(ctx, fp1, ft);
10342 gen_load_fpr64(ctx, fp2, fr);
10343 gen_helper_float_madd_ps(fp2, cpu_env, fp0, fp1, fp2);
10344 tcg_temp_free_i64(fp0);
10345 tcg_temp_free_i64(fp1);
10346 gen_store_fpr64(ctx, fp2, fd);
10347 tcg_temp_free_i64(fp2);
10354 TCGv_i32 fp0 = tcg_temp_new_i32();
10355 TCGv_i32 fp1 = tcg_temp_new_i32();
10356 TCGv_i32 fp2 = tcg_temp_new_i32();
10358 gen_load_fpr32(ctx, fp0, fs);
10359 gen_load_fpr32(ctx, fp1, ft);
10360 gen_load_fpr32(ctx, fp2, fr);
10361 gen_helper_float_msub_s(fp2, cpu_env, fp0, fp1, fp2);
10362 tcg_temp_free_i32(fp0);
10363 tcg_temp_free_i32(fp1);
10364 gen_store_fpr32(ctx, fp2, fd);
10365 tcg_temp_free_i32(fp2);
10371 check_cp1_registers(ctx, fd | fs | ft | fr);
10373 TCGv_i64 fp0 = tcg_temp_new_i64();
10374 TCGv_i64 fp1 = tcg_temp_new_i64();
10375 TCGv_i64 fp2 = tcg_temp_new_i64();
10377 gen_load_fpr64(ctx, fp0, fs);
10378 gen_load_fpr64(ctx, fp1, ft);
10379 gen_load_fpr64(ctx, fp2, fr);
10380 gen_helper_float_msub_d(fp2, cpu_env, fp0, fp1, fp2);
10381 tcg_temp_free_i64(fp0);
10382 tcg_temp_free_i64(fp1);
10383 gen_store_fpr64(ctx, fp2, fd);
10384 tcg_temp_free_i64(fp2);
10389 check_cp1_64bitmode(ctx);
10391 TCGv_i64 fp0 = tcg_temp_new_i64();
10392 TCGv_i64 fp1 = tcg_temp_new_i64();
10393 TCGv_i64 fp2 = tcg_temp_new_i64();
10395 gen_load_fpr64(ctx, fp0, fs);
10396 gen_load_fpr64(ctx, fp1, ft);
10397 gen_load_fpr64(ctx, fp2, fr);
10398 gen_helper_float_msub_ps(fp2, cpu_env, fp0, fp1, fp2);
10399 tcg_temp_free_i64(fp0);
10400 tcg_temp_free_i64(fp1);
10401 gen_store_fpr64(ctx, fp2, fd);
10402 tcg_temp_free_i64(fp2);
10409 TCGv_i32 fp0 = tcg_temp_new_i32();
10410 TCGv_i32 fp1 = tcg_temp_new_i32();
10411 TCGv_i32 fp2 = tcg_temp_new_i32();
10413 gen_load_fpr32(ctx, fp0, fs);
10414 gen_load_fpr32(ctx, fp1, ft);
10415 gen_load_fpr32(ctx, fp2, fr);
10416 gen_helper_float_nmadd_s(fp2, cpu_env, fp0, fp1, fp2);
10417 tcg_temp_free_i32(fp0);
10418 tcg_temp_free_i32(fp1);
10419 gen_store_fpr32(ctx, fp2, fd);
10420 tcg_temp_free_i32(fp2);
10426 check_cp1_registers(ctx, fd | fs | ft | fr);
10428 TCGv_i64 fp0 = tcg_temp_new_i64();
10429 TCGv_i64 fp1 = tcg_temp_new_i64();
10430 TCGv_i64 fp2 = tcg_temp_new_i64();
10432 gen_load_fpr64(ctx, fp0, fs);
10433 gen_load_fpr64(ctx, fp1, ft);
10434 gen_load_fpr64(ctx, fp2, fr);
10435 gen_helper_float_nmadd_d(fp2, cpu_env, fp0, fp1, fp2);
10436 tcg_temp_free_i64(fp0);
10437 tcg_temp_free_i64(fp1);
10438 gen_store_fpr64(ctx, fp2, fd);
10439 tcg_temp_free_i64(fp2);
10444 check_cp1_64bitmode(ctx);
10446 TCGv_i64 fp0 = tcg_temp_new_i64();
10447 TCGv_i64 fp1 = tcg_temp_new_i64();
10448 TCGv_i64 fp2 = tcg_temp_new_i64();
10450 gen_load_fpr64(ctx, fp0, fs);
10451 gen_load_fpr64(ctx, fp1, ft);
10452 gen_load_fpr64(ctx, fp2, fr);
10453 gen_helper_float_nmadd_ps(fp2, cpu_env, fp0, fp1, fp2);
10454 tcg_temp_free_i64(fp0);
10455 tcg_temp_free_i64(fp1);
10456 gen_store_fpr64(ctx, fp2, fd);
10457 tcg_temp_free_i64(fp2);
10464 TCGv_i32 fp0 = tcg_temp_new_i32();
10465 TCGv_i32 fp1 = tcg_temp_new_i32();
10466 TCGv_i32 fp2 = tcg_temp_new_i32();
10468 gen_load_fpr32(ctx, fp0, fs);
10469 gen_load_fpr32(ctx, fp1, ft);
10470 gen_load_fpr32(ctx, fp2, fr);
10471 gen_helper_float_nmsub_s(fp2, cpu_env, fp0, fp1, fp2);
10472 tcg_temp_free_i32(fp0);
10473 tcg_temp_free_i32(fp1);
10474 gen_store_fpr32(ctx, fp2, fd);
10475 tcg_temp_free_i32(fp2);
10481 check_cp1_registers(ctx, fd | fs | ft | fr);
10483 TCGv_i64 fp0 = tcg_temp_new_i64();
10484 TCGv_i64 fp1 = tcg_temp_new_i64();
10485 TCGv_i64 fp2 = tcg_temp_new_i64();
10487 gen_load_fpr64(ctx, fp0, fs);
10488 gen_load_fpr64(ctx, fp1, ft);
10489 gen_load_fpr64(ctx, fp2, fr);
10490 gen_helper_float_nmsub_d(fp2, cpu_env, fp0, fp1, fp2);
10491 tcg_temp_free_i64(fp0);
10492 tcg_temp_free_i64(fp1);
10493 gen_store_fpr64(ctx, fp2, fd);
10494 tcg_temp_free_i64(fp2);
10499 check_cp1_64bitmode(ctx);
10501 TCGv_i64 fp0 = tcg_temp_new_i64();
10502 TCGv_i64 fp1 = tcg_temp_new_i64();
10503 TCGv_i64 fp2 = tcg_temp_new_i64();
10505 gen_load_fpr64(ctx, fp0, fs);
10506 gen_load_fpr64(ctx, fp1, ft);
10507 gen_load_fpr64(ctx, fp2, fr);
10508 gen_helper_float_nmsub_ps(fp2, cpu_env, fp0, fp1, fp2);
10509 tcg_temp_free_i64(fp0);
10510 tcg_temp_free_i64(fp1);
10511 gen_store_fpr64(ctx, fp2, fd);
10512 tcg_temp_free_i64(fp2);
10518 generate_exception (ctx, EXCP_RI);
10521 (void)opn; /* avoid a compiler warning */
10522 MIPS_DEBUG("%s %s, %s, %s, %s", opn, fregnames[fd], fregnames[fr],
10523 fregnames[fs], fregnames[ft]);
10526 static void gen_rdhwr(DisasContext *ctx, int rt, int rd)
10530 #if !defined(CONFIG_USER_ONLY)
10531 /* The Linux kernel will emulate rdhwr if it's not supported natively.
10532 Therefore only check the ISA in system mode. */
10533 check_insn(ctx, ISA_MIPS32R2);
10535 t0 = tcg_temp_new();
10539 save_cpu_state(ctx, 1);
10540 gen_helper_rdhwr_cpunum(t0, cpu_env);
10541 gen_store_gpr(t0, rt);
10544 save_cpu_state(ctx, 1);
10545 gen_helper_rdhwr_synci_step(t0, cpu_env);
10546 gen_store_gpr(t0, rt);
10549 save_cpu_state(ctx, 1);
10550 gen_helper_rdhwr_cc(t0, cpu_env);
10551 gen_store_gpr(t0, rt);
10554 save_cpu_state(ctx, 1);
10555 gen_helper_rdhwr_ccres(t0, cpu_env);
10556 gen_store_gpr(t0, rt);
10559 #if defined(CONFIG_USER_ONLY)
10560 tcg_gen_ld_tl(t0, cpu_env,
10561 offsetof(CPUMIPSState, active_tc.CP0_UserLocal));
10562 gen_store_gpr(t0, rt);
10565 if ((ctx->hflags & MIPS_HFLAG_CP0) ||
10566 (ctx->hflags & MIPS_HFLAG_HWRENA_ULR)) {
10567 tcg_gen_ld_tl(t0, cpu_env,
10568 offsetof(CPUMIPSState, active_tc.CP0_UserLocal));
10569 gen_store_gpr(t0, rt);
10571 generate_exception(ctx, EXCP_RI);
10575 default: /* Invalid */
10576 MIPS_INVAL("rdhwr");
10577 generate_exception(ctx, EXCP_RI);
10583 static inline void clear_branch_hflags(DisasContext *ctx)
10585 ctx->hflags &= ~MIPS_HFLAG_BMASK;
10586 if (ctx->bstate == BS_NONE) {
10587 save_cpu_state(ctx, 0);
10589 /* it is not safe to save ctx->hflags as hflags may be changed
10590 in execution time by the instruction in delay / forbidden slot. */
10591 tcg_gen_andi_i32(hflags, hflags, ~MIPS_HFLAG_BMASK);
10595 static void gen_branch(DisasContext *ctx, int insn_bytes)
10597 if (ctx->hflags & MIPS_HFLAG_BMASK) {
10598 int proc_hflags = ctx->hflags & MIPS_HFLAG_BMASK;
10599 /* Branches completion */
10600 clear_branch_hflags(ctx);
10601 ctx->bstate = BS_BRANCH;
10602 /* FIXME: Need to clear can_do_io. */
10603 switch (proc_hflags & MIPS_HFLAG_BMASK_BASE) {
10604 case MIPS_HFLAG_FBNSLOT:
10605 MIPS_DEBUG("forbidden slot");
10606 gen_goto_tb(ctx, 0, ctx->pc + insn_bytes);
10609 /* unconditional branch */
10610 MIPS_DEBUG("unconditional branch");
10611 if (proc_hflags & MIPS_HFLAG_BX) {
10612 tcg_gen_xori_i32(hflags, hflags, MIPS_HFLAG_M16);
10614 gen_goto_tb(ctx, 0, ctx->btarget);
10616 case MIPS_HFLAG_BL:
10617 /* blikely taken case */
10618 MIPS_DEBUG("blikely branch taken");
10619 gen_goto_tb(ctx, 0, ctx->btarget);
10621 case MIPS_HFLAG_BC:
10622 /* Conditional branch */
10623 MIPS_DEBUG("conditional branch");
10625 TCGLabel *l1 = gen_new_label();
10627 tcg_gen_brcondi_tl(TCG_COND_NE, bcond, 0, l1);
10628 gen_goto_tb(ctx, 1, ctx->pc + insn_bytes);
10630 gen_goto_tb(ctx, 0, ctx->btarget);
10633 case MIPS_HFLAG_BR:
10634 /* unconditional branch to register */
10635 MIPS_DEBUG("branch to register");
10636 if (ctx->insn_flags & (ASE_MIPS16 | ASE_MICROMIPS)) {
10637 TCGv t0 = tcg_temp_new();
10638 TCGv_i32 t1 = tcg_temp_new_i32();
10640 tcg_gen_andi_tl(t0, btarget, 0x1);
10641 tcg_gen_trunc_tl_i32(t1, t0);
10643 tcg_gen_andi_i32(hflags, hflags, ~(uint32_t)MIPS_HFLAG_M16);
10644 tcg_gen_shli_i32(t1, t1, MIPS_HFLAG_M16_SHIFT);
10645 tcg_gen_or_i32(hflags, hflags, t1);
10646 tcg_temp_free_i32(t1);
10648 tcg_gen_andi_tl(cpu_PC, btarget, ~(target_ulong)0x1);
10650 tcg_gen_mov_tl(cpu_PC, btarget);
10652 if (ctx->singlestep_enabled) {
10653 save_cpu_state(ctx, 0);
10654 gen_helper_0e0i(raise_exception, EXCP_DEBUG);
10656 tcg_gen_exit_tb(0);
10659 fprintf(stderr, "unknown branch 0x%x\n", proc_hflags);
10665 /* ISA extensions (ASEs) */
10666 /* MIPS16 extension to MIPS32 */
10668 /* MIPS16 major opcodes */
10670 M16_OPC_ADDIUSP = 0x00,
10671 M16_OPC_ADDIUPC = 0x01,
10673 M16_OPC_JAL = 0x03,
10674 M16_OPC_BEQZ = 0x04,
10675 M16_OPC_BNEQZ = 0x05,
10676 M16_OPC_SHIFT = 0x06,
10678 M16_OPC_RRIA = 0x08,
10679 M16_OPC_ADDIU8 = 0x09,
10680 M16_OPC_SLTI = 0x0a,
10681 M16_OPC_SLTIU = 0x0b,
10684 M16_OPC_CMPI = 0x0e,
10688 M16_OPC_LWSP = 0x12,
10690 M16_OPC_LBU = 0x14,
10691 M16_OPC_LHU = 0x15,
10692 M16_OPC_LWPC = 0x16,
10693 M16_OPC_LWU = 0x17,
10696 M16_OPC_SWSP = 0x1a,
10698 M16_OPC_RRR = 0x1c,
10700 M16_OPC_EXTEND = 0x1e,
10704 /* I8 funct field */
10723 /* RR funct field */
10757 /* I64 funct field */
10765 I64_DADDIUPC = 0x6,
10769 /* RR ry field for CNVT */
10771 RR_RY_CNVT_ZEB = 0x0,
10772 RR_RY_CNVT_ZEH = 0x1,
10773 RR_RY_CNVT_ZEW = 0x2,
10774 RR_RY_CNVT_SEB = 0x4,
10775 RR_RY_CNVT_SEH = 0x5,
10776 RR_RY_CNVT_SEW = 0x6,
10779 static int xlat (int r)
10781 static int map[] = { 16, 17, 2, 3, 4, 5, 6, 7 };
10786 static void gen_mips16_save (DisasContext *ctx,
10787 int xsregs, int aregs,
10788 int do_ra, int do_s0, int do_s1,
10791 TCGv t0 = tcg_temp_new();
10792 TCGv t1 = tcg_temp_new();
10793 TCGv t2 = tcg_temp_new();
10823 generate_exception(ctx, EXCP_RI);
10829 gen_base_offset_addr(ctx, t0, 29, 12);
10830 gen_load_gpr(t1, 7);
10831 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL);
10834 gen_base_offset_addr(ctx, t0, 29, 8);
10835 gen_load_gpr(t1, 6);
10836 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL);
10839 gen_base_offset_addr(ctx, t0, 29, 4);
10840 gen_load_gpr(t1, 5);
10841 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL);
10844 gen_base_offset_addr(ctx, t0, 29, 0);
10845 gen_load_gpr(t1, 4);
10846 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL);
10849 gen_load_gpr(t0, 29);
10851 #define DECR_AND_STORE(reg) do { \
10852 tcg_gen_movi_tl(t2, -4); \
10853 gen_op_addr_add(ctx, t0, t0, t2); \
10854 gen_load_gpr(t1, reg); \
10855 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL); \
10859 DECR_AND_STORE(31);
10864 DECR_AND_STORE(30);
10867 DECR_AND_STORE(23);
10870 DECR_AND_STORE(22);
10873 DECR_AND_STORE(21);
10876 DECR_AND_STORE(20);
10879 DECR_AND_STORE(19);
10882 DECR_AND_STORE(18);
10886 DECR_AND_STORE(17);
10889 DECR_AND_STORE(16);
10919 generate_exception(ctx, EXCP_RI);
10935 #undef DECR_AND_STORE
10937 tcg_gen_movi_tl(t2, -framesize);
10938 gen_op_addr_add(ctx, cpu_gpr[29], cpu_gpr[29], t2);
10944 static void gen_mips16_restore (DisasContext *ctx,
10945 int xsregs, int aregs,
10946 int do_ra, int do_s0, int do_s1,
10950 TCGv t0 = tcg_temp_new();
10951 TCGv t1 = tcg_temp_new();
10952 TCGv t2 = tcg_temp_new();
10954 tcg_gen_movi_tl(t2, framesize);
10955 gen_op_addr_add(ctx, t0, cpu_gpr[29], t2);
10957 #define DECR_AND_LOAD(reg) do { \
10958 tcg_gen_movi_tl(t2, -4); \
10959 gen_op_addr_add(ctx, t0, t0, t2); \
10960 tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_TESL); \
10961 gen_store_gpr(t1, reg); \
11025 generate_exception(ctx, EXCP_RI);
11041 #undef DECR_AND_LOAD
11043 tcg_gen_movi_tl(t2, framesize);
11044 gen_op_addr_add(ctx, cpu_gpr[29], cpu_gpr[29], t2);
11050 static void gen_addiupc (DisasContext *ctx, int rx, int imm,
11051 int is_64_bit, int extended)
11055 if (extended && (ctx->hflags & MIPS_HFLAG_BMASK)) {
11056 generate_exception(ctx, EXCP_RI);
11060 t0 = tcg_temp_new();
11062 tcg_gen_movi_tl(t0, pc_relative_pc(ctx));
11063 tcg_gen_addi_tl(cpu_gpr[rx], t0, imm);
11065 tcg_gen_ext32s_tl(cpu_gpr[rx], cpu_gpr[rx]);
11071 #if defined(TARGET_MIPS64)
11072 static void decode_i64_mips16 (DisasContext *ctx,
11073 int ry, int funct, int16_t offset,
11078 check_insn(ctx, ISA_MIPS3);
11079 check_mips_64(ctx);
11080 offset = extended ? offset : offset << 3;
11081 gen_ld(ctx, OPC_LD, ry, 29, offset);
11084 check_insn(ctx, ISA_MIPS3);
11085 check_mips_64(ctx);
11086 offset = extended ? offset : offset << 3;
11087 gen_st(ctx, OPC_SD, ry, 29, offset);
11090 check_insn(ctx, ISA_MIPS3);
11091 check_mips_64(ctx);
11092 offset = extended ? offset : (ctx->opcode & 0xff) << 3;
11093 gen_st(ctx, OPC_SD, 31, 29, offset);
11096 check_insn(ctx, ISA_MIPS3);
11097 check_mips_64(ctx);
11098 offset = extended ? offset : ((int8_t)ctx->opcode) << 3;
11099 gen_arith_imm(ctx, OPC_DADDIU, 29, 29, offset);
11102 check_insn(ctx, ISA_MIPS3);
11103 check_mips_64(ctx);
11104 if (extended && (ctx->hflags & MIPS_HFLAG_BMASK)) {
11105 generate_exception(ctx, EXCP_RI);
11107 offset = extended ? offset : offset << 3;
11108 gen_ld(ctx, OPC_LDPC, ry, 0, offset);
11112 check_insn(ctx, ISA_MIPS3);
11113 check_mips_64(ctx);
11114 offset = extended ? offset : ((int8_t)(offset << 3)) >> 3;
11115 gen_arith_imm(ctx, OPC_DADDIU, ry, ry, offset);
11118 check_insn(ctx, ISA_MIPS3);
11119 check_mips_64(ctx);
11120 offset = extended ? offset : offset << 2;
11121 gen_addiupc(ctx, ry, offset, 1, extended);
11124 check_insn(ctx, ISA_MIPS3);
11125 check_mips_64(ctx);
11126 offset = extended ? offset : offset << 2;
11127 gen_arith_imm(ctx, OPC_DADDIU, ry, 29, offset);
11133 static int decode_extended_mips16_opc (CPUMIPSState *env, DisasContext *ctx)
11135 int extend = cpu_lduw_code(env, ctx->pc + 2);
11136 int op, rx, ry, funct, sa;
11137 int16_t imm, offset;
11139 ctx->opcode = (ctx->opcode << 16) | extend;
11140 op = (ctx->opcode >> 11) & 0x1f;
11141 sa = (ctx->opcode >> 22) & 0x1f;
11142 funct = (ctx->opcode >> 8) & 0x7;
11143 rx = xlat((ctx->opcode >> 8) & 0x7);
11144 ry = xlat((ctx->opcode >> 5) & 0x7);
11145 offset = imm = (int16_t) (((ctx->opcode >> 16) & 0x1f) << 11
11146 | ((ctx->opcode >> 21) & 0x3f) << 5
11147 | (ctx->opcode & 0x1f));
11149 /* The extended opcodes cleverly reuse the opcodes from their 16-bit
11152 case M16_OPC_ADDIUSP:
11153 gen_arith_imm(ctx, OPC_ADDIU, rx, 29, imm);
11155 case M16_OPC_ADDIUPC:
11156 gen_addiupc(ctx, rx, imm, 0, 1);
11159 gen_compute_branch(ctx, OPC_BEQ, 4, 0, 0, offset << 1, 0);
11160 /* No delay slot, so just process as a normal instruction */
11163 gen_compute_branch(ctx, OPC_BEQ, 4, rx, 0, offset << 1, 0);
11164 /* No delay slot, so just process as a normal instruction */
11166 case M16_OPC_BNEQZ:
11167 gen_compute_branch(ctx, OPC_BNE, 4, rx, 0, offset << 1, 0);
11168 /* No delay slot, so just process as a normal instruction */
11170 case M16_OPC_SHIFT:
11171 switch (ctx->opcode & 0x3) {
11173 gen_shift_imm(ctx, OPC_SLL, rx, ry, sa);
11176 #if defined(TARGET_MIPS64)
11177 check_mips_64(ctx);
11178 gen_shift_imm(ctx, OPC_DSLL, rx, ry, sa);
11180 generate_exception(ctx, EXCP_RI);
11184 gen_shift_imm(ctx, OPC_SRL, rx, ry, sa);
11187 gen_shift_imm(ctx, OPC_SRA, rx, ry, sa);
11191 #if defined(TARGET_MIPS64)
11193 check_insn(ctx, ISA_MIPS3);
11194 check_mips_64(ctx);
11195 gen_ld(ctx, OPC_LD, ry, rx, offset);
11199 imm = ctx->opcode & 0xf;
11200 imm = imm | ((ctx->opcode >> 20) & 0x7f) << 4;
11201 imm = imm | ((ctx->opcode >> 16) & 0xf) << 11;
11202 imm = (int16_t) (imm << 1) >> 1;
11203 if ((ctx->opcode >> 4) & 0x1) {
11204 #if defined(TARGET_MIPS64)
11205 check_mips_64(ctx);
11206 gen_arith_imm(ctx, OPC_DADDIU, ry, rx, imm);
11208 generate_exception(ctx, EXCP_RI);
11211 gen_arith_imm(ctx, OPC_ADDIU, ry, rx, imm);
11214 case M16_OPC_ADDIU8:
11215 gen_arith_imm(ctx, OPC_ADDIU, rx, rx, imm);
11218 gen_slt_imm(ctx, OPC_SLTI, 24, rx, imm);
11220 case M16_OPC_SLTIU:
11221 gen_slt_imm(ctx, OPC_SLTIU, 24, rx, imm);
11226 gen_compute_branch(ctx, OPC_BEQ, 4, 24, 0, offset << 1, 0);
11229 gen_compute_branch(ctx, OPC_BNE, 4, 24, 0, offset << 1, 0);
11232 gen_st(ctx, OPC_SW, 31, 29, imm);
11235 gen_arith_imm(ctx, OPC_ADDIU, 29, 29, imm);
11238 check_insn(ctx, ISA_MIPS32);
11240 int xsregs = (ctx->opcode >> 24) & 0x7;
11241 int aregs = (ctx->opcode >> 16) & 0xf;
11242 int do_ra = (ctx->opcode >> 6) & 0x1;
11243 int do_s0 = (ctx->opcode >> 5) & 0x1;
11244 int do_s1 = (ctx->opcode >> 4) & 0x1;
11245 int framesize = (((ctx->opcode >> 20) & 0xf) << 4
11246 | (ctx->opcode & 0xf)) << 3;
11248 if (ctx->opcode & (1 << 7)) {
11249 gen_mips16_save(ctx, xsregs, aregs,
11250 do_ra, do_s0, do_s1,
11253 gen_mips16_restore(ctx, xsregs, aregs,
11254 do_ra, do_s0, do_s1,
11260 generate_exception(ctx, EXCP_RI);
11265 tcg_gen_movi_tl(cpu_gpr[rx], (uint16_t) imm);
11268 tcg_gen_xori_tl(cpu_gpr[24], cpu_gpr[rx], (uint16_t) imm);
11270 #if defined(TARGET_MIPS64)
11272 check_insn(ctx, ISA_MIPS3);
11273 check_mips_64(ctx);
11274 gen_st(ctx, OPC_SD, ry, rx, offset);
11278 gen_ld(ctx, OPC_LB, ry, rx, offset);
11281 gen_ld(ctx, OPC_LH, ry, rx, offset);
11284 gen_ld(ctx, OPC_LW, rx, 29, offset);
11287 gen_ld(ctx, OPC_LW, ry, rx, offset);
11290 gen_ld(ctx, OPC_LBU, ry, rx, offset);
11293 gen_ld(ctx, OPC_LHU, ry, rx, offset);
11296 gen_ld(ctx, OPC_LWPC, rx, 0, offset);
11298 #if defined(TARGET_MIPS64)
11300 check_insn(ctx, ISA_MIPS3);
11301 check_mips_64(ctx);
11302 gen_ld(ctx, OPC_LWU, ry, rx, offset);
11306 gen_st(ctx, OPC_SB, ry, rx, offset);
11309 gen_st(ctx, OPC_SH, ry, rx, offset);
11312 gen_st(ctx, OPC_SW, rx, 29, offset);
11315 gen_st(ctx, OPC_SW, ry, rx, offset);
11317 #if defined(TARGET_MIPS64)
11319 decode_i64_mips16(ctx, ry, funct, offset, 1);
11323 generate_exception(ctx, EXCP_RI);
11330 static int decode_mips16_opc (CPUMIPSState *env, DisasContext *ctx)
11334 int op, cnvt_op, op1, offset;
11338 op = (ctx->opcode >> 11) & 0x1f;
11339 sa = (ctx->opcode >> 2) & 0x7;
11340 sa = sa == 0 ? 8 : sa;
11341 rx = xlat((ctx->opcode >> 8) & 0x7);
11342 cnvt_op = (ctx->opcode >> 5) & 0x7;
11343 ry = xlat((ctx->opcode >> 5) & 0x7);
11344 op1 = offset = ctx->opcode & 0x1f;
11349 case M16_OPC_ADDIUSP:
11351 int16_t imm = ((uint8_t) ctx->opcode) << 2;
11353 gen_arith_imm(ctx, OPC_ADDIU, rx, 29, imm);
11356 case M16_OPC_ADDIUPC:
11357 gen_addiupc(ctx, rx, ((uint8_t) ctx->opcode) << 2, 0, 0);
11360 offset = (ctx->opcode & 0x7ff) << 1;
11361 offset = (int16_t)(offset << 4) >> 4;
11362 gen_compute_branch(ctx, OPC_BEQ, 2, 0, 0, offset, 0);
11363 /* No delay slot, so just process as a normal instruction */
11366 offset = cpu_lduw_code(env, ctx->pc + 2);
11367 offset = (((ctx->opcode & 0x1f) << 21)
11368 | ((ctx->opcode >> 5) & 0x1f) << 16
11370 op = ((ctx->opcode >> 10) & 0x1) ? OPC_JALX : OPC_JAL;
11371 gen_compute_branch(ctx, op, 4, rx, ry, offset, 2);
11375 gen_compute_branch(ctx, OPC_BEQ, 2, rx, 0,
11376 ((int8_t)ctx->opcode) << 1, 0);
11377 /* No delay slot, so just process as a normal instruction */
11379 case M16_OPC_BNEQZ:
11380 gen_compute_branch(ctx, OPC_BNE, 2, rx, 0,
11381 ((int8_t)ctx->opcode) << 1, 0);
11382 /* No delay slot, so just process as a normal instruction */
11384 case M16_OPC_SHIFT:
11385 switch (ctx->opcode & 0x3) {
11387 gen_shift_imm(ctx, OPC_SLL, rx, ry, sa);
11390 #if defined(TARGET_MIPS64)
11391 check_insn(ctx, ISA_MIPS3);
11392 check_mips_64(ctx);
11393 gen_shift_imm(ctx, OPC_DSLL, rx, ry, sa);
11395 generate_exception(ctx, EXCP_RI);
11399 gen_shift_imm(ctx, OPC_SRL, rx, ry, sa);
11402 gen_shift_imm(ctx, OPC_SRA, rx, ry, sa);
11406 #if defined(TARGET_MIPS64)
11408 check_insn(ctx, ISA_MIPS3);
11409 check_mips_64(ctx);
11410 gen_ld(ctx, OPC_LD, ry, rx, offset << 3);
11415 int16_t imm = (int8_t)((ctx->opcode & 0xf) << 4) >> 4;
11417 if ((ctx->opcode >> 4) & 1) {
11418 #if defined(TARGET_MIPS64)
11419 check_insn(ctx, ISA_MIPS3);
11420 check_mips_64(ctx);
11421 gen_arith_imm(ctx, OPC_DADDIU, ry, rx, imm);
11423 generate_exception(ctx, EXCP_RI);
11426 gen_arith_imm(ctx, OPC_ADDIU, ry, rx, imm);
11430 case M16_OPC_ADDIU8:
11432 int16_t imm = (int8_t) ctx->opcode;
11434 gen_arith_imm(ctx, OPC_ADDIU, rx, rx, imm);
11439 int16_t imm = (uint8_t) ctx->opcode;
11440 gen_slt_imm(ctx, OPC_SLTI, 24, rx, imm);
11443 case M16_OPC_SLTIU:
11445 int16_t imm = (uint8_t) ctx->opcode;
11446 gen_slt_imm(ctx, OPC_SLTIU, 24, rx, imm);
11453 funct = (ctx->opcode >> 8) & 0x7;
11456 gen_compute_branch(ctx, OPC_BEQ, 2, 24, 0,
11457 ((int8_t)ctx->opcode) << 1, 0);
11460 gen_compute_branch(ctx, OPC_BNE, 2, 24, 0,
11461 ((int8_t)ctx->opcode) << 1, 0);
11464 gen_st(ctx, OPC_SW, 31, 29, (ctx->opcode & 0xff) << 2);
11467 gen_arith_imm(ctx, OPC_ADDIU, 29, 29,
11468 ((int8_t)ctx->opcode) << 3);
11471 check_insn(ctx, ISA_MIPS32);
11473 int do_ra = ctx->opcode & (1 << 6);
11474 int do_s0 = ctx->opcode & (1 << 5);
11475 int do_s1 = ctx->opcode & (1 << 4);
11476 int framesize = ctx->opcode & 0xf;
11478 if (framesize == 0) {
11481 framesize = framesize << 3;
11484 if (ctx->opcode & (1 << 7)) {
11485 gen_mips16_save(ctx, 0, 0,
11486 do_ra, do_s0, do_s1, framesize);
11488 gen_mips16_restore(ctx, 0, 0,
11489 do_ra, do_s0, do_s1, framesize);
11495 int rz = xlat(ctx->opcode & 0x7);
11497 reg32 = (((ctx->opcode >> 3) & 0x3) << 3) |
11498 ((ctx->opcode >> 5) & 0x7);
11499 gen_arith(ctx, OPC_ADDU, reg32, rz, 0);
11503 reg32 = ctx->opcode & 0x1f;
11504 gen_arith(ctx, OPC_ADDU, ry, reg32, 0);
11507 generate_exception(ctx, EXCP_RI);
11514 int16_t imm = (uint8_t) ctx->opcode;
11516 gen_arith_imm(ctx, OPC_ADDIU, rx, 0, imm);
11521 int16_t imm = (uint8_t) ctx->opcode;
11522 gen_logic_imm(ctx, OPC_XORI, 24, rx, imm);
11525 #if defined(TARGET_MIPS64)
11527 check_insn(ctx, ISA_MIPS3);
11528 check_mips_64(ctx);
11529 gen_st(ctx, OPC_SD, ry, rx, offset << 3);
11533 gen_ld(ctx, OPC_LB, ry, rx, offset);
11536 gen_ld(ctx, OPC_LH, ry, rx, offset << 1);
11539 gen_ld(ctx, OPC_LW, rx, 29, ((uint8_t)ctx->opcode) << 2);
11542 gen_ld(ctx, OPC_LW, ry, rx, offset << 2);
11545 gen_ld(ctx, OPC_LBU, ry, rx, offset);
11548 gen_ld(ctx, OPC_LHU, ry, rx, offset << 1);
11551 gen_ld(ctx, OPC_LWPC, rx, 0, ((uint8_t)ctx->opcode) << 2);
11553 #if defined (TARGET_MIPS64)
11555 check_insn(ctx, ISA_MIPS3);
11556 check_mips_64(ctx);
11557 gen_ld(ctx, OPC_LWU, ry, rx, offset << 2);
11561 gen_st(ctx, OPC_SB, ry, rx, offset);
11564 gen_st(ctx, OPC_SH, ry, rx, offset << 1);
11567 gen_st(ctx, OPC_SW, rx, 29, ((uint8_t)ctx->opcode) << 2);
11570 gen_st(ctx, OPC_SW, ry, rx, offset << 2);
11574 int rz = xlat((ctx->opcode >> 2) & 0x7);
11577 switch (ctx->opcode & 0x3) {
11579 mips32_op = OPC_ADDU;
11582 mips32_op = OPC_SUBU;
11584 #if defined(TARGET_MIPS64)
11586 mips32_op = OPC_DADDU;
11587 check_insn(ctx, ISA_MIPS3);
11588 check_mips_64(ctx);
11591 mips32_op = OPC_DSUBU;
11592 check_insn(ctx, ISA_MIPS3);
11593 check_mips_64(ctx);
11597 generate_exception(ctx, EXCP_RI);
11601 gen_arith(ctx, mips32_op, rz, rx, ry);
11610 int nd = (ctx->opcode >> 7) & 0x1;
11611 int link = (ctx->opcode >> 6) & 0x1;
11612 int ra = (ctx->opcode >> 5) & 0x1;
11615 check_insn(ctx, ISA_MIPS32);
11624 gen_compute_branch(ctx, op, 2, ra ? 31 : rx, 31, 0,
11629 /* XXX: not clear which exception should be raised
11630 * when in debug mode...
11632 check_insn(ctx, ISA_MIPS32);
11633 if (!(ctx->hflags & MIPS_HFLAG_DM)) {
11634 generate_exception(ctx, EXCP_DBp);
11636 generate_exception(ctx, EXCP_DBp);
11640 gen_slt(ctx, OPC_SLT, 24, rx, ry);
11643 gen_slt(ctx, OPC_SLTU, 24, rx, ry);
11646 generate_exception(ctx, EXCP_BREAK);
11649 gen_shift(ctx, OPC_SLLV, ry, rx, ry);
11652 gen_shift(ctx, OPC_SRLV, ry, rx, ry);
11655 gen_shift(ctx, OPC_SRAV, ry, rx, ry);
11657 #if defined (TARGET_MIPS64)
11659 check_insn(ctx, ISA_MIPS3);
11660 check_mips_64(ctx);
11661 gen_shift_imm(ctx, OPC_DSRL, ry, ry, sa);
11665 gen_logic(ctx, OPC_XOR, 24, rx, ry);
11668 gen_arith(ctx, OPC_SUBU, rx, 0, ry);
11671 gen_logic(ctx, OPC_AND, rx, rx, ry);
11674 gen_logic(ctx, OPC_OR, rx, rx, ry);
11677 gen_logic(ctx, OPC_XOR, rx, rx, ry);
11680 gen_logic(ctx, OPC_NOR, rx, ry, 0);
11683 gen_HILO(ctx, OPC_MFHI, 0, rx);
11686 check_insn(ctx, ISA_MIPS32);
11688 case RR_RY_CNVT_ZEB:
11689 tcg_gen_ext8u_tl(cpu_gpr[rx], cpu_gpr[rx]);
11691 case RR_RY_CNVT_ZEH:
11692 tcg_gen_ext16u_tl(cpu_gpr[rx], cpu_gpr[rx]);
11694 case RR_RY_CNVT_SEB:
11695 tcg_gen_ext8s_tl(cpu_gpr[rx], cpu_gpr[rx]);
11697 case RR_RY_CNVT_SEH:
11698 tcg_gen_ext16s_tl(cpu_gpr[rx], cpu_gpr[rx]);
11700 #if defined (TARGET_MIPS64)
11701 case RR_RY_CNVT_ZEW:
11702 check_insn(ctx, ISA_MIPS64);
11703 check_mips_64(ctx);
11704 tcg_gen_ext32u_tl(cpu_gpr[rx], cpu_gpr[rx]);
11706 case RR_RY_CNVT_SEW:
11707 check_insn(ctx, ISA_MIPS64);
11708 check_mips_64(ctx);
11709 tcg_gen_ext32s_tl(cpu_gpr[rx], cpu_gpr[rx]);
11713 generate_exception(ctx, EXCP_RI);
11718 gen_HILO(ctx, OPC_MFLO, 0, rx);
11720 #if defined (TARGET_MIPS64)
11722 check_insn(ctx, ISA_MIPS3);
11723 check_mips_64(ctx);
11724 gen_shift_imm(ctx, OPC_DSRA, ry, ry, sa);
11727 check_insn(ctx, ISA_MIPS3);
11728 check_mips_64(ctx);
11729 gen_shift(ctx, OPC_DSLLV, ry, rx, ry);
11732 check_insn(ctx, ISA_MIPS3);
11733 check_mips_64(ctx);
11734 gen_shift(ctx, OPC_DSRLV, ry, rx, ry);
11737 check_insn(ctx, ISA_MIPS3);
11738 check_mips_64(ctx);
11739 gen_shift(ctx, OPC_DSRAV, ry, rx, ry);
11743 gen_muldiv(ctx, OPC_MULT, 0, rx, ry);
11746 gen_muldiv(ctx, OPC_MULTU, 0, rx, ry);
11749 gen_muldiv(ctx, OPC_DIV, 0, rx, ry);
11752 gen_muldiv(ctx, OPC_DIVU, 0, rx, ry);
11754 #if defined (TARGET_MIPS64)
11756 check_insn(ctx, ISA_MIPS3);
11757 check_mips_64(ctx);
11758 gen_muldiv(ctx, OPC_DMULT, 0, rx, ry);
11761 check_insn(ctx, ISA_MIPS3);
11762 check_mips_64(ctx);
11763 gen_muldiv(ctx, OPC_DMULTU, 0, rx, ry);
11766 check_insn(ctx, ISA_MIPS3);
11767 check_mips_64(ctx);
11768 gen_muldiv(ctx, OPC_DDIV, 0, rx, ry);
11771 check_insn(ctx, ISA_MIPS3);
11772 check_mips_64(ctx);
11773 gen_muldiv(ctx, OPC_DDIVU, 0, rx, ry);
11777 generate_exception(ctx, EXCP_RI);
11781 case M16_OPC_EXTEND:
11782 decode_extended_mips16_opc(env, ctx);
11785 #if defined(TARGET_MIPS64)
11787 funct = (ctx->opcode >> 8) & 0x7;
11788 decode_i64_mips16(ctx, ry, funct, offset, 0);
11792 generate_exception(ctx, EXCP_RI);
11799 /* microMIPS extension to MIPS32/MIPS64 */
11802 * microMIPS32/microMIPS64 major opcodes
11804 * 1. MIPS Architecture for Programmers Volume II-B:
11805 * The microMIPS32 Instruction Set (Revision 3.05)
11807 * Table 6.2 microMIPS32 Encoding of Major Opcode Field
11809 * 2. MIPS Architecture For Programmers Volume II-A:
11810 * The MIPS64 Instruction Set (Revision 3.51)
11838 POOL32S = 0x16, /* MIPS64 */
11839 DADDIU32 = 0x17, /* MIPS64 */
11841 /* 0x1f is reserved */
11850 /* 0x20 is reserved */
11860 /* 0x28 and 0x29 are reserved */
11870 /* 0x30 and 0x31 are reserved */
11877 SD32 = 0x36, /* MIPS64 */
11878 LD32 = 0x37, /* MIPS64 */
11880 /* 0x38 and 0x39 are reserved */
11891 /* POOL32A encoding of minor opcode field */
11894 /* These opcodes are distinguished only by bits 9..6; those bits are
11895 * what are recorded below. */
11921 /* The following can be distinguished by their lower 6 bits. */
11927 /* POOL32AXF encoding of minor opcode field extension */
11930 * 1. MIPS Architecture for Programmers Volume II-B:
11931 * The microMIPS32 Instruction Set (Revision 3.05)
11933 * Table 6.5 POOL32Axf Encoding of Minor Opcode Extension Field
11935 * 2. MIPS Architecture for Programmers VolumeIV-e:
11936 * The MIPS DSP Application-Specific Extension
11937 * to the microMIPS32 Architecture (Revision 2.34)
11939 * Table 5.5 POOL32Axf Encoding of Minor Opcode Extension Field
11954 /* begin of microMIPS32 DSP */
11956 /* bits 13..12 for 0x01 */
11962 /* bits 13..12 for 0x2a */
11968 /* bits 13..12 for 0x32 */
11972 /* end of microMIPS32 DSP */
11974 /* bits 15..12 for 0x2c */
11990 /* bits 15..12 for 0x34 */
11998 /* bits 15..12 for 0x3c */
12000 JR = 0x0, /* alias */
12005 /* bits 15..12 for 0x05 */
12009 /* bits 15..12 for 0x0d */
12019 /* bits 15..12 for 0x15 */
12025 /* bits 15..12 for 0x1d */
12029 /* bits 15..12 for 0x2d */
12034 /* bits 15..12 for 0x35 */
12041 /* POOL32B encoding of minor opcode field (bits 15..12) */
12057 /* POOL32C encoding of minor opcode field (bits 15..12) */
12065 /* 0xa is reserved */
12072 /* 0x6 is reserved */
12078 /* POOL32F encoding of minor opcode field (bits 5..0) */
12081 /* These are the bit 7..6 values */
12092 /* These are the bit 8..6 values */
12136 CABS_COND_FMT = 0x1c, /* MIPS3D */
12140 /* POOL32Fxf encoding of minor opcode extension field */
12178 /* POOL32I encoding of minor opcode field (bits 25..21) */
12203 /* These overlap and are distinguished by bit16 of the instruction */
12212 /* POOL16A encoding of minor opcode field */
12219 /* POOL16B encoding of minor opcode field */
12226 /* POOL16C encoding of minor opcode field */
12246 /* POOL16D encoding of minor opcode field */
12253 /* POOL16E encoding of minor opcode field */
12260 static int mmreg (int r)
12262 static const int map[] = { 16, 17, 2, 3, 4, 5, 6, 7 };
12267 /* Used for 16-bit store instructions. */
12268 static int mmreg2 (int r)
12270 static const int map[] = { 0, 17, 2, 3, 4, 5, 6, 7 };
12275 #define uMIPS_RD(op) ((op >> 7) & 0x7)
12276 #define uMIPS_RS(op) ((op >> 4) & 0x7)
12277 #define uMIPS_RS2(op) uMIPS_RS(op)
12278 #define uMIPS_RS1(op) ((op >> 1) & 0x7)
12279 #define uMIPS_RD5(op) ((op >> 5) & 0x1f)
12280 #define uMIPS_RS5(op) (op & 0x1f)
12282 /* Signed immediate */
12283 #define SIMM(op, start, width) \
12284 ((int32_t)(((op >> start) & ((~0U) >> (32-width))) \
12287 /* Zero-extended immediate */
12288 #define ZIMM(op, start, width) ((op >> start) & ((~0U) >> (32-width)))
12290 static void gen_addiur1sp(DisasContext *ctx)
12292 int rd = mmreg(uMIPS_RD(ctx->opcode));
12294 gen_arith_imm(ctx, OPC_ADDIU, rd, 29, ((ctx->opcode >> 1) & 0x3f) << 2);
12297 static void gen_addiur2(DisasContext *ctx)
12299 static const int decoded_imm[] = { 1, 4, 8, 12, 16, 20, 24, -1 };
12300 int rd = mmreg(uMIPS_RD(ctx->opcode));
12301 int rs = mmreg(uMIPS_RS(ctx->opcode));
12303 gen_arith_imm(ctx, OPC_ADDIU, rd, rs, decoded_imm[ZIMM(ctx->opcode, 1, 3)]);
12306 static void gen_addiusp(DisasContext *ctx)
12308 int encoded = ZIMM(ctx->opcode, 1, 9);
12311 if (encoded <= 1) {
12312 decoded = 256 + encoded;
12313 } else if (encoded <= 255) {
12315 } else if (encoded <= 509) {
12316 decoded = encoded - 512;
12318 decoded = encoded - 768;
12321 gen_arith_imm(ctx, OPC_ADDIU, 29, 29, decoded << 2);
12324 static void gen_addius5(DisasContext *ctx)
12326 int imm = SIMM(ctx->opcode, 1, 4);
12327 int rd = (ctx->opcode >> 5) & 0x1f;
12329 gen_arith_imm(ctx, OPC_ADDIU, rd, rd, imm);
12332 static void gen_andi16(DisasContext *ctx)
12334 static const int decoded_imm[] = { 128, 1, 2, 3, 4, 7, 8, 15, 16,
12335 31, 32, 63, 64, 255, 32768, 65535 };
12336 int rd = mmreg(uMIPS_RD(ctx->opcode));
12337 int rs = mmreg(uMIPS_RS(ctx->opcode));
12338 int encoded = ZIMM(ctx->opcode, 0, 4);
12340 gen_logic_imm(ctx, OPC_ANDI, rd, rs, decoded_imm[encoded]);
12343 static void gen_ldst_multiple (DisasContext *ctx, uint32_t opc, int reglist,
12344 int base, int16_t offset)
12346 const char *opn = "ldst_multiple";
12350 if (ctx->hflags & MIPS_HFLAG_BMASK) {
12351 generate_exception(ctx, EXCP_RI);
12355 t0 = tcg_temp_new();
12357 gen_base_offset_addr(ctx, t0, base, offset);
12359 t1 = tcg_const_tl(reglist);
12360 t2 = tcg_const_i32(ctx->mem_idx);
12362 save_cpu_state(ctx, 1);
12365 gen_helper_lwm(cpu_env, t0, t1, t2);
12369 gen_helper_swm(cpu_env, t0, t1, t2);
12372 #ifdef TARGET_MIPS64
12374 gen_helper_ldm(cpu_env, t0, t1, t2);
12378 gen_helper_sdm(cpu_env, t0, t1, t2);
12384 MIPS_DEBUG("%s, %x, %d(%s)", opn, reglist, offset, regnames[base]);
12387 tcg_temp_free_i32(t2);
12391 static void gen_pool16c_insn(DisasContext *ctx)
12393 int rd = mmreg((ctx->opcode >> 3) & 0x7);
12394 int rs = mmreg(ctx->opcode & 0x7);
12396 switch (((ctx->opcode) >> 4) & 0x3f) {
12401 gen_logic(ctx, OPC_NOR, rd, rs, 0);
12407 gen_logic(ctx, OPC_XOR, rd, rd, rs);
12413 gen_logic(ctx, OPC_AND, rd, rd, rs);
12419 gen_logic(ctx, OPC_OR, rd, rd, rs);
12426 static const int lwm_convert[] = { 0x11, 0x12, 0x13, 0x14 };
12427 int offset = ZIMM(ctx->opcode, 0, 4);
12429 gen_ldst_multiple(ctx, LWM32, lwm_convert[(ctx->opcode >> 4) & 0x3],
12438 static const int swm_convert[] = { 0x11, 0x12, 0x13, 0x14 };
12439 int offset = ZIMM(ctx->opcode, 0, 4);
12441 gen_ldst_multiple(ctx, SWM32, swm_convert[(ctx->opcode >> 4) & 0x3],
12448 int reg = ctx->opcode & 0x1f;
12450 gen_compute_branch(ctx, OPC_JR, 2, reg, 0, 0, 4);
12456 int reg = ctx->opcode & 0x1f;
12457 gen_compute_branch(ctx, OPC_JR, 2, reg, 0, 0, 0);
12458 /* Let normal delay slot handling in our caller take us
12459 to the branch target. */
12464 gen_compute_branch(ctx, OPC_JALR, 2, ctx->opcode & 0x1f, 31, 0, 4);
12465 ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
12469 gen_compute_branch(ctx, OPC_JALR, 2, ctx->opcode & 0x1f, 31, 0, 2);
12470 ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
12474 gen_HILO(ctx, OPC_MFHI, 0, uMIPS_RS5(ctx->opcode));
12478 gen_HILO(ctx, OPC_MFLO, 0, uMIPS_RS5(ctx->opcode));
12481 generate_exception(ctx, EXCP_BREAK);
12484 /* XXX: not clear which exception should be raised
12485 * when in debug mode...
12487 check_insn(ctx, ISA_MIPS32);
12488 if (!(ctx->hflags & MIPS_HFLAG_DM)) {
12489 generate_exception(ctx, EXCP_DBp);
12491 generate_exception(ctx, EXCP_DBp);
12494 case JRADDIUSP + 0:
12495 case JRADDIUSP + 1:
12497 int imm = ZIMM(ctx->opcode, 0, 5);
12498 gen_compute_branch(ctx, OPC_JR, 2, 31, 0, 0, 0);
12499 gen_arith_imm(ctx, OPC_ADDIU, 29, 29, imm << 2);
12500 /* Let normal delay slot handling in our caller take us
12501 to the branch target. */
12505 generate_exception(ctx, EXCP_RI);
12510 static void gen_ldxs (DisasContext *ctx, int base, int index, int rd)
12512 TCGv t0 = tcg_temp_new();
12513 TCGv t1 = tcg_temp_new();
12515 gen_load_gpr(t0, base);
12518 gen_load_gpr(t1, index);
12519 tcg_gen_shli_tl(t1, t1, 2);
12520 gen_op_addr_add(ctx, t0, t1, t0);
12523 tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_TESL);
12524 gen_store_gpr(t1, rd);
12530 static void gen_ldst_pair (DisasContext *ctx, uint32_t opc, int rd,
12531 int base, int16_t offset)
12533 const char *opn = "ldst_pair";
12536 if (ctx->hflags & MIPS_HFLAG_BMASK || rd == 31) {
12537 generate_exception(ctx, EXCP_RI);
12541 t0 = tcg_temp_new();
12542 t1 = tcg_temp_new();
12544 gen_base_offset_addr(ctx, t0, base, offset);
12549 generate_exception(ctx, EXCP_RI);
12552 tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_TESL);
12553 gen_store_gpr(t1, rd);
12554 tcg_gen_movi_tl(t1, 4);
12555 gen_op_addr_add(ctx, t0, t0, t1);
12556 tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_TESL);
12557 gen_store_gpr(t1, rd+1);
12561 gen_load_gpr(t1, rd);
12562 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL);
12563 tcg_gen_movi_tl(t1, 4);
12564 gen_op_addr_add(ctx, t0, t0, t1);
12565 gen_load_gpr(t1, rd+1);
12566 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL);
12569 #ifdef TARGET_MIPS64
12572 generate_exception(ctx, EXCP_RI);
12575 tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_TEQ);
12576 gen_store_gpr(t1, rd);
12577 tcg_gen_movi_tl(t1, 8);
12578 gen_op_addr_add(ctx, t0, t0, t1);
12579 tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_TEQ);
12580 gen_store_gpr(t1, rd+1);
12584 gen_load_gpr(t1, rd);
12585 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEQ);
12586 tcg_gen_movi_tl(t1, 8);
12587 gen_op_addr_add(ctx, t0, t0, t1);
12588 gen_load_gpr(t1, rd+1);
12589 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEQ);
12594 (void)opn; /* avoid a compiler warning */
12595 MIPS_DEBUG("%s, %s, %d(%s)", opn, regnames[rd], offset, regnames[base]);
12600 static void gen_pool32axf (CPUMIPSState *env, DisasContext *ctx, int rt, int rs)
12602 int extension = (ctx->opcode >> 6) & 0x3f;
12603 int minor = (ctx->opcode >> 12) & 0xf;
12604 uint32_t mips32_op;
12606 switch (extension) {
12608 mips32_op = OPC_TEQ;
12611 mips32_op = OPC_TGE;
12614 mips32_op = OPC_TGEU;
12617 mips32_op = OPC_TLT;
12620 mips32_op = OPC_TLTU;
12623 mips32_op = OPC_TNE;
12625 gen_trap(ctx, mips32_op, rs, rt, -1);
12627 #ifndef CONFIG_USER_ONLY
12630 check_cp0_enabled(ctx);
12632 /* Treat as NOP. */
12635 gen_mfc0(ctx, cpu_gpr[rt], rs, (ctx->opcode >> 11) & 0x7);
12639 check_cp0_enabled(ctx);
12641 TCGv t0 = tcg_temp_new();
12643 gen_load_gpr(t0, rt);
12644 gen_mtc0(ctx, t0, rs, (ctx->opcode >> 11) & 0x7);
12650 switch (minor & 3) {
12652 gen_muldiv(ctx, OPC_MADD, (ctx->opcode >> 14) & 3, rs, rt);
12655 gen_muldiv(ctx, OPC_MADDU, (ctx->opcode >> 14) & 3, rs, rt);
12658 gen_muldiv(ctx, OPC_MSUB, (ctx->opcode >> 14) & 3, rs, rt);
12661 gen_muldiv(ctx, OPC_MSUBU, (ctx->opcode >> 14) & 3, rs, rt);
12664 goto pool32axf_invalid;
12668 switch (minor & 3) {
12670 gen_muldiv(ctx, OPC_MULT, (ctx->opcode >> 14) & 3, rs, rt);
12673 gen_muldiv(ctx, OPC_MULTU, (ctx->opcode >> 14) & 3, rs, rt);
12676 goto pool32axf_invalid;
12682 gen_bshfl(ctx, OPC_SEB, rs, rt);
12685 gen_bshfl(ctx, OPC_SEH, rs, rt);
12688 mips32_op = OPC_CLO;
12691 mips32_op = OPC_CLZ;
12693 check_insn(ctx, ISA_MIPS32);
12694 gen_cl(ctx, mips32_op, rt, rs);
12697 gen_rdhwr(ctx, rt, rs);
12700 gen_bshfl(ctx, OPC_WSBH, rs, rt);
12703 mips32_op = OPC_MULT;
12706 mips32_op = OPC_MULTU;
12709 mips32_op = OPC_DIV;
12712 mips32_op = OPC_DIVU;
12715 check_insn(ctx, ISA_MIPS32);
12716 gen_muldiv(ctx, mips32_op, 0, rs, rt);
12719 mips32_op = OPC_MADD;
12722 mips32_op = OPC_MADDU;
12725 mips32_op = OPC_MSUB;
12728 mips32_op = OPC_MSUBU;
12730 check_insn(ctx, ISA_MIPS32);
12731 gen_muldiv(ctx, mips32_op, 0, rs, rt);
12734 goto pool32axf_invalid;
12745 generate_exception_err(ctx, EXCP_CpU, 2);
12748 goto pool32axf_invalid;
12755 gen_compute_branch(ctx, OPC_JALR, 4, rs, rt, 0, 4);
12756 ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
12760 gen_compute_branch(ctx, OPC_JALR, 4, rs, rt, 0, 2);
12761 ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
12764 goto pool32axf_invalid;
12770 check_cp0_enabled(ctx);
12771 check_insn(ctx, ISA_MIPS32R2);
12772 gen_load_srsgpr(rt, rs);
12775 check_cp0_enabled(ctx);
12776 check_insn(ctx, ISA_MIPS32R2);
12777 gen_store_srsgpr(rt, rs);
12780 goto pool32axf_invalid;
12783 #ifndef CONFIG_USER_ONLY
12787 mips32_op = OPC_TLBP;
12790 mips32_op = OPC_TLBR;
12793 mips32_op = OPC_TLBWI;
12796 mips32_op = OPC_TLBWR;
12799 mips32_op = OPC_WAIT;
12802 mips32_op = OPC_DERET;
12805 mips32_op = OPC_ERET;
12807 gen_cp0(env, ctx, mips32_op, rt, rs);
12810 goto pool32axf_invalid;
12816 check_cp0_enabled(ctx);
12818 TCGv t0 = tcg_temp_new();
12820 save_cpu_state(ctx, 1);
12821 gen_helper_di(t0, cpu_env);
12822 gen_store_gpr(t0, rs);
12823 /* Stop translation as we may have switched the execution mode */
12824 ctx->bstate = BS_STOP;
12829 check_cp0_enabled(ctx);
12831 TCGv t0 = tcg_temp_new();
12833 save_cpu_state(ctx, 1);
12834 gen_helper_ei(t0, cpu_env);
12835 gen_store_gpr(t0, rs);
12836 /* Stop translation as we may have switched the execution mode */
12837 ctx->bstate = BS_STOP;
12842 goto pool32axf_invalid;
12852 generate_exception(ctx, EXCP_SYSCALL);
12853 ctx->bstate = BS_STOP;
12856 check_insn(ctx, ISA_MIPS32);
12857 if (!(ctx->hflags & MIPS_HFLAG_DM)) {
12858 generate_exception(ctx, EXCP_DBp);
12860 generate_exception(ctx, EXCP_DBp);
12864 goto pool32axf_invalid;
12868 switch (minor & 3) {
12870 gen_HILO(ctx, OPC_MFHI, minor >> 2, rs);
12873 gen_HILO(ctx, OPC_MFLO, minor >> 2, rs);
12876 gen_HILO(ctx, OPC_MTHI, minor >> 2, rs);
12879 gen_HILO(ctx, OPC_MTLO, minor >> 2, rs);
12882 goto pool32axf_invalid;
12888 gen_HILO(ctx, OPC_MFHI, 0, rs);
12891 gen_HILO(ctx, OPC_MFLO, 0, rs);
12894 gen_HILO(ctx, OPC_MTHI, 0, rs);
12897 gen_HILO(ctx, OPC_MTLO, 0, rs);
12900 goto pool32axf_invalid;
12905 MIPS_INVAL("pool32axf");
12906 generate_exception(ctx, EXCP_RI);
12911 /* Values for microMIPS fmt field. Variable-width, depending on which
12912 formats the instruction supports. */
12931 static void gen_pool32fxf(DisasContext *ctx, int rt, int rs)
12933 int extension = (ctx->opcode >> 6) & 0x3ff;
12934 uint32_t mips32_op;
12936 #define FLOAT_1BIT_FMT(opc, fmt) (fmt << 8) | opc
12937 #define FLOAT_2BIT_FMT(opc, fmt) (fmt << 7) | opc
12938 #define COND_FLOAT_MOV(opc, cond) (cond << 7) | opc
12940 switch (extension) {
12941 case FLOAT_1BIT_FMT(CFC1, 0):
12942 mips32_op = OPC_CFC1;
12944 case FLOAT_1BIT_FMT(CTC1, 0):
12945 mips32_op = OPC_CTC1;
12947 case FLOAT_1BIT_FMT(MFC1, 0):
12948 mips32_op = OPC_MFC1;
12950 case FLOAT_1BIT_FMT(MTC1, 0):
12951 mips32_op = OPC_MTC1;
12953 case FLOAT_1BIT_FMT(MFHC1, 0):
12954 mips32_op = OPC_MFHC1;
12956 case FLOAT_1BIT_FMT(MTHC1, 0):
12957 mips32_op = OPC_MTHC1;
12959 gen_cp1(ctx, mips32_op, rt, rs);
12962 /* Reciprocal square root */
12963 case FLOAT_1BIT_FMT(RSQRT_FMT, FMT_SD_S):
12964 mips32_op = OPC_RSQRT_S;
12966 case FLOAT_1BIT_FMT(RSQRT_FMT, FMT_SD_D):
12967 mips32_op = OPC_RSQRT_D;
12971 case FLOAT_1BIT_FMT(SQRT_FMT, FMT_SD_S):
12972 mips32_op = OPC_SQRT_S;
12974 case FLOAT_1BIT_FMT(SQRT_FMT, FMT_SD_D):
12975 mips32_op = OPC_SQRT_D;
12979 case FLOAT_1BIT_FMT(RECIP_FMT, FMT_SD_S):
12980 mips32_op = OPC_RECIP_S;
12982 case FLOAT_1BIT_FMT(RECIP_FMT, FMT_SD_D):
12983 mips32_op = OPC_RECIP_D;
12987 case FLOAT_1BIT_FMT(FLOOR_L, FMT_SD_S):
12988 mips32_op = OPC_FLOOR_L_S;
12990 case FLOAT_1BIT_FMT(FLOOR_L, FMT_SD_D):
12991 mips32_op = OPC_FLOOR_L_D;
12993 case FLOAT_1BIT_FMT(FLOOR_W, FMT_SD_S):
12994 mips32_op = OPC_FLOOR_W_S;
12996 case FLOAT_1BIT_FMT(FLOOR_W, FMT_SD_D):
12997 mips32_op = OPC_FLOOR_W_D;
13001 case FLOAT_1BIT_FMT(CEIL_L, FMT_SD_S):
13002 mips32_op = OPC_CEIL_L_S;
13004 case FLOAT_1BIT_FMT(CEIL_L, FMT_SD_D):
13005 mips32_op = OPC_CEIL_L_D;
13007 case FLOAT_1BIT_FMT(CEIL_W, FMT_SD_S):
13008 mips32_op = OPC_CEIL_W_S;
13010 case FLOAT_1BIT_FMT(CEIL_W, FMT_SD_D):
13011 mips32_op = OPC_CEIL_W_D;
13015 case FLOAT_1BIT_FMT(TRUNC_L, FMT_SD_S):
13016 mips32_op = OPC_TRUNC_L_S;
13018 case FLOAT_1BIT_FMT(TRUNC_L, FMT_SD_D):
13019 mips32_op = OPC_TRUNC_L_D;
13021 case FLOAT_1BIT_FMT(TRUNC_W, FMT_SD_S):
13022 mips32_op = OPC_TRUNC_W_S;
13024 case FLOAT_1BIT_FMT(TRUNC_W, FMT_SD_D):
13025 mips32_op = OPC_TRUNC_W_D;
13029 case FLOAT_1BIT_FMT(ROUND_L, FMT_SD_S):
13030 mips32_op = OPC_ROUND_L_S;
13032 case FLOAT_1BIT_FMT(ROUND_L, FMT_SD_D):
13033 mips32_op = OPC_ROUND_L_D;
13035 case FLOAT_1BIT_FMT(ROUND_W, FMT_SD_S):
13036 mips32_op = OPC_ROUND_W_S;
13038 case FLOAT_1BIT_FMT(ROUND_W, FMT_SD_D):
13039 mips32_op = OPC_ROUND_W_D;
13042 /* Integer to floating-point conversion */
13043 case FLOAT_1BIT_FMT(CVT_L, FMT_SD_S):
13044 mips32_op = OPC_CVT_L_S;
13046 case FLOAT_1BIT_FMT(CVT_L, FMT_SD_D):
13047 mips32_op = OPC_CVT_L_D;
13049 case FLOAT_1BIT_FMT(CVT_W, FMT_SD_S):
13050 mips32_op = OPC_CVT_W_S;
13052 case FLOAT_1BIT_FMT(CVT_W, FMT_SD_D):
13053 mips32_op = OPC_CVT_W_D;
13056 /* Paired-foo conversions */
13057 case FLOAT_1BIT_FMT(CVT_S_PL, 0):
13058 mips32_op = OPC_CVT_S_PL;
13060 case FLOAT_1BIT_FMT(CVT_S_PU, 0):
13061 mips32_op = OPC_CVT_S_PU;
13063 case FLOAT_1BIT_FMT(CVT_PW_PS, 0):
13064 mips32_op = OPC_CVT_PW_PS;
13066 case FLOAT_1BIT_FMT(CVT_PS_PW, 0):
13067 mips32_op = OPC_CVT_PS_PW;
13070 /* Floating-point moves */
13071 case FLOAT_2BIT_FMT(MOV_FMT, FMT_SDPS_S):
13072 mips32_op = OPC_MOV_S;
13074 case FLOAT_2BIT_FMT(MOV_FMT, FMT_SDPS_D):
13075 mips32_op = OPC_MOV_D;
13077 case FLOAT_2BIT_FMT(MOV_FMT, FMT_SDPS_PS):
13078 mips32_op = OPC_MOV_PS;
13081 /* Absolute value */
13082 case FLOAT_2BIT_FMT(ABS_FMT, FMT_SDPS_S):
13083 mips32_op = OPC_ABS_S;
13085 case FLOAT_2BIT_FMT(ABS_FMT, FMT_SDPS_D):
13086 mips32_op = OPC_ABS_D;
13088 case FLOAT_2BIT_FMT(ABS_FMT, FMT_SDPS_PS):
13089 mips32_op = OPC_ABS_PS;
13093 case FLOAT_2BIT_FMT(NEG_FMT, FMT_SDPS_S):
13094 mips32_op = OPC_NEG_S;
13096 case FLOAT_2BIT_FMT(NEG_FMT, FMT_SDPS_D):
13097 mips32_op = OPC_NEG_D;
13099 case FLOAT_2BIT_FMT(NEG_FMT, FMT_SDPS_PS):
13100 mips32_op = OPC_NEG_PS;
13103 /* Reciprocal square root step */
13104 case FLOAT_2BIT_FMT(RSQRT1_FMT, FMT_SDPS_S):
13105 mips32_op = OPC_RSQRT1_S;
13107 case FLOAT_2BIT_FMT(RSQRT1_FMT, FMT_SDPS_D):
13108 mips32_op = OPC_RSQRT1_D;
13110 case FLOAT_2BIT_FMT(RSQRT1_FMT, FMT_SDPS_PS):
13111 mips32_op = OPC_RSQRT1_PS;
13114 /* Reciprocal step */
13115 case FLOAT_2BIT_FMT(RECIP1_FMT, FMT_SDPS_S):
13116 mips32_op = OPC_RECIP1_S;
13118 case FLOAT_2BIT_FMT(RECIP1_FMT, FMT_SDPS_D):
13119 mips32_op = OPC_RECIP1_S;
13121 case FLOAT_2BIT_FMT(RECIP1_FMT, FMT_SDPS_PS):
13122 mips32_op = OPC_RECIP1_PS;
13125 /* Conversions from double */
13126 case FLOAT_2BIT_FMT(CVT_D, FMT_SWL_S):
13127 mips32_op = OPC_CVT_D_S;
13129 case FLOAT_2BIT_FMT(CVT_D, FMT_SWL_W):
13130 mips32_op = OPC_CVT_D_W;
13132 case FLOAT_2BIT_FMT(CVT_D, FMT_SWL_L):
13133 mips32_op = OPC_CVT_D_L;
13136 /* Conversions from single */
13137 case FLOAT_2BIT_FMT(CVT_S, FMT_DWL_D):
13138 mips32_op = OPC_CVT_S_D;
13140 case FLOAT_2BIT_FMT(CVT_S, FMT_DWL_W):
13141 mips32_op = OPC_CVT_S_W;
13143 case FLOAT_2BIT_FMT(CVT_S, FMT_DWL_L):
13144 mips32_op = OPC_CVT_S_L;
13146 gen_farith(ctx, mips32_op, -1, rs, rt, 0);
13149 /* Conditional moves on floating-point codes */
13150 case COND_FLOAT_MOV(MOVT, 0):
13151 case COND_FLOAT_MOV(MOVT, 1):
13152 case COND_FLOAT_MOV(MOVT, 2):
13153 case COND_FLOAT_MOV(MOVT, 3):
13154 case COND_FLOAT_MOV(MOVT, 4):
13155 case COND_FLOAT_MOV(MOVT, 5):
13156 case COND_FLOAT_MOV(MOVT, 6):
13157 case COND_FLOAT_MOV(MOVT, 7):
13158 gen_movci(ctx, rt, rs, (ctx->opcode >> 13) & 0x7, 1);
13160 case COND_FLOAT_MOV(MOVF, 0):
13161 case COND_FLOAT_MOV(MOVF, 1):
13162 case COND_FLOAT_MOV(MOVF, 2):
13163 case COND_FLOAT_MOV(MOVF, 3):
13164 case COND_FLOAT_MOV(MOVF, 4):
13165 case COND_FLOAT_MOV(MOVF, 5):
13166 case COND_FLOAT_MOV(MOVF, 6):
13167 case COND_FLOAT_MOV(MOVF, 7):
13168 gen_movci(ctx, rt, rs, (ctx->opcode >> 13) & 0x7, 0);
13171 MIPS_INVAL("pool32fxf");
13172 generate_exception(ctx, EXCP_RI);
13177 static void decode_micromips32_opc (CPUMIPSState *env, DisasContext *ctx,
13182 int rt, rs, rd, rr;
13184 uint32_t op, minor, mips32_op;
13185 uint32_t cond, fmt, cc;
13187 insn = cpu_lduw_code(env, ctx->pc + 2);
13188 ctx->opcode = (ctx->opcode << 16) | insn;
13190 rt = (ctx->opcode >> 21) & 0x1f;
13191 rs = (ctx->opcode >> 16) & 0x1f;
13192 rd = (ctx->opcode >> 11) & 0x1f;
13193 rr = (ctx->opcode >> 6) & 0x1f;
13194 imm = (int16_t) ctx->opcode;
13196 op = (ctx->opcode >> 26) & 0x3f;
13199 minor = ctx->opcode & 0x3f;
13202 minor = (ctx->opcode >> 6) & 0xf;
13205 mips32_op = OPC_SLL;
13208 mips32_op = OPC_SRA;
13211 mips32_op = OPC_SRL;
13214 mips32_op = OPC_ROTR;
13216 gen_shift_imm(ctx, mips32_op, rt, rs, rd);
13219 goto pool32a_invalid;
13223 minor = (ctx->opcode >> 6) & 0xf;
13227 mips32_op = OPC_ADD;
13230 mips32_op = OPC_ADDU;
13233 mips32_op = OPC_SUB;
13236 mips32_op = OPC_SUBU;
13239 mips32_op = OPC_MUL;
13241 gen_arith(ctx, mips32_op, rd, rs, rt);
13245 mips32_op = OPC_SLLV;
13248 mips32_op = OPC_SRLV;
13251 mips32_op = OPC_SRAV;
13254 mips32_op = OPC_ROTRV;
13256 gen_shift(ctx, mips32_op, rd, rs, rt);
13258 /* Logical operations */
13260 mips32_op = OPC_AND;
13263 mips32_op = OPC_OR;
13266 mips32_op = OPC_NOR;
13269 mips32_op = OPC_XOR;
13271 gen_logic(ctx, mips32_op, rd, rs, rt);
13273 /* Set less than */
13275 mips32_op = OPC_SLT;
13278 mips32_op = OPC_SLTU;
13280 gen_slt(ctx, mips32_op, rd, rs, rt);
13283 goto pool32a_invalid;
13287 minor = (ctx->opcode >> 6) & 0xf;
13289 /* Conditional moves */
13291 mips32_op = OPC_MOVN;
13294 mips32_op = OPC_MOVZ;
13296 gen_cond_move(ctx, mips32_op, rd, rs, rt);
13299 gen_ldxs(ctx, rs, rt, rd);
13302 goto pool32a_invalid;
13306 gen_bitops(ctx, OPC_INS, rt, rs, rr, rd);
13309 gen_bitops(ctx, OPC_EXT, rt, rs, rr, rd);
13312 gen_pool32axf(env, ctx, rt, rs);
13315 generate_exception(ctx, EXCP_BREAK);
13319 MIPS_INVAL("pool32a");
13320 generate_exception(ctx, EXCP_RI);
13325 minor = (ctx->opcode >> 12) & 0xf;
13328 check_cp0_enabled(ctx);
13329 /* Treat as no-op. */
13333 /* COP2: Not implemented. */
13334 generate_exception_err(ctx, EXCP_CpU, 2);
13336 #ifdef TARGET_MIPS64
13339 check_insn(ctx, ISA_MIPS3);
13340 check_mips_64(ctx);
13345 gen_ldst_pair(ctx, minor, rt, rs, SIMM(ctx->opcode, 0, 12));
13347 #ifdef TARGET_MIPS64
13350 check_insn(ctx, ISA_MIPS3);
13351 check_mips_64(ctx);
13356 gen_ldst_multiple(ctx, minor, rt, rs, SIMM(ctx->opcode, 0, 12));
13359 MIPS_INVAL("pool32b");
13360 generate_exception(ctx, EXCP_RI);
13365 if (ctx->CP0_Config1 & (1 << CP0C1_FP)) {
13366 minor = ctx->opcode & 0x3f;
13367 check_cp1_enabled(ctx);
13370 mips32_op = OPC_ALNV_PS;
13373 mips32_op = OPC_MADD_S;
13376 mips32_op = OPC_MADD_D;
13379 mips32_op = OPC_MADD_PS;
13382 mips32_op = OPC_MSUB_S;
13385 mips32_op = OPC_MSUB_D;
13388 mips32_op = OPC_MSUB_PS;
13391 mips32_op = OPC_NMADD_S;
13394 mips32_op = OPC_NMADD_D;
13397 mips32_op = OPC_NMADD_PS;
13400 mips32_op = OPC_NMSUB_S;
13403 mips32_op = OPC_NMSUB_D;
13406 mips32_op = OPC_NMSUB_PS;
13408 gen_flt3_arith(ctx, mips32_op, rd, rr, rs, rt);
13410 case CABS_COND_FMT:
13411 cond = (ctx->opcode >> 6) & 0xf;
13412 cc = (ctx->opcode >> 13) & 0x7;
13413 fmt = (ctx->opcode >> 10) & 0x3;
13416 gen_cmpabs_s(ctx, cond, rt, rs, cc);
13419 gen_cmpabs_d(ctx, cond, rt, rs, cc);
13422 gen_cmpabs_ps(ctx, cond, rt, rs, cc);
13425 goto pool32f_invalid;
13429 cond = (ctx->opcode >> 6) & 0xf;
13430 cc = (ctx->opcode >> 13) & 0x7;
13431 fmt = (ctx->opcode >> 10) & 0x3;
13434 gen_cmp_s(ctx, cond, rt, rs, cc);
13437 gen_cmp_d(ctx, cond, rt, rs, cc);
13440 gen_cmp_ps(ctx, cond, rt, rs, cc);
13443 goto pool32f_invalid;
13447 gen_pool32fxf(ctx, rt, rs);
13451 switch ((ctx->opcode >> 6) & 0x7) {
13453 mips32_op = OPC_PLL_PS;
13456 mips32_op = OPC_PLU_PS;
13459 mips32_op = OPC_PUL_PS;
13462 mips32_op = OPC_PUU_PS;
13465 mips32_op = OPC_CVT_PS_S;
13467 gen_farith(ctx, mips32_op, rt, rs, rd, 0);
13470 goto pool32f_invalid;
13475 switch ((ctx->opcode >> 6) & 0x7) {
13477 mips32_op = OPC_LWXC1;
13480 mips32_op = OPC_SWXC1;
13483 mips32_op = OPC_LDXC1;
13486 mips32_op = OPC_SDXC1;
13489 mips32_op = OPC_LUXC1;
13492 mips32_op = OPC_SUXC1;
13494 gen_flt3_ldst(ctx, mips32_op, rd, rd, rt, rs);
13497 goto pool32f_invalid;
13502 fmt = (ctx->opcode >> 9) & 0x3;
13503 switch ((ctx->opcode >> 6) & 0x7) {
13507 mips32_op = OPC_RSQRT2_S;
13510 mips32_op = OPC_RSQRT2_D;
13513 mips32_op = OPC_RSQRT2_PS;
13516 goto pool32f_invalid;
13522 mips32_op = OPC_RECIP2_S;
13525 mips32_op = OPC_RECIP2_D;
13528 mips32_op = OPC_RECIP2_PS;
13531 goto pool32f_invalid;
13535 mips32_op = OPC_ADDR_PS;
13538 mips32_op = OPC_MULR_PS;
13540 gen_farith(ctx, mips32_op, rt, rs, rd, 0);
13543 goto pool32f_invalid;
13547 /* MOV[FT].fmt and PREFX */
13548 cc = (ctx->opcode >> 13) & 0x7;
13549 fmt = (ctx->opcode >> 9) & 0x3;
13550 switch ((ctx->opcode >> 6) & 0x7) {
13554 gen_movcf_s(ctx, rs, rt, cc, 0);
13557 gen_movcf_d(ctx, rs, rt, cc, 0);
13560 gen_movcf_ps(ctx, rs, rt, cc, 0);
13563 goto pool32f_invalid;
13569 gen_movcf_s(ctx, rs, rt, cc, 1);
13572 gen_movcf_d(ctx, rs, rt, cc, 1);
13575 gen_movcf_ps(ctx, rs, rt, cc, 1);
13578 goto pool32f_invalid;
13584 goto pool32f_invalid;
13587 #define FINSN_3ARG_SDPS(prfx) \
13588 switch ((ctx->opcode >> 8) & 0x3) { \
13590 mips32_op = OPC_##prfx##_S; \
13593 mips32_op = OPC_##prfx##_D; \
13595 case FMT_SDPS_PS: \
13596 mips32_op = OPC_##prfx##_PS; \
13599 goto pool32f_invalid; \
13602 /* regular FP ops */
13603 switch ((ctx->opcode >> 6) & 0x3) {
13605 FINSN_3ARG_SDPS(ADD);
13608 FINSN_3ARG_SDPS(SUB);
13611 FINSN_3ARG_SDPS(MUL);
13614 fmt = (ctx->opcode >> 8) & 0x3;
13616 mips32_op = OPC_DIV_D;
13617 } else if (fmt == 0) {
13618 mips32_op = OPC_DIV_S;
13620 goto pool32f_invalid;
13624 goto pool32f_invalid;
13629 switch ((ctx->opcode >> 6) & 0x3) {
13631 FINSN_3ARG_SDPS(MOVN);
13634 FINSN_3ARG_SDPS(MOVZ);
13637 goto pool32f_invalid;
13641 gen_farith(ctx, mips32_op, rt, rs, rd, 0);
13645 MIPS_INVAL("pool32f");
13646 generate_exception(ctx, EXCP_RI);
13650 generate_exception_err(ctx, EXCP_CpU, 1);
13654 minor = (ctx->opcode >> 21) & 0x1f;
13657 gen_compute_branch(ctx, OPC_BLTZ, 4, rs, -1, imm << 1, 4);
13660 gen_compute_branch(ctx, OPC_BLTZAL, 4, rs, -1, imm << 1, 4);
13661 ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
13664 gen_compute_branch(ctx, OPC_BLTZAL, 4, rs, -1, imm << 1, 2);
13665 ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
13668 gen_compute_branch(ctx, OPC_BGEZ, 4, rs, -1, imm << 1, 4);
13671 gen_compute_branch(ctx, OPC_BGEZAL, 4, rs, -1, imm << 1, 4);
13672 ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
13675 gen_compute_branch(ctx, OPC_BGEZAL, 4, rs, -1, imm << 1, 2);
13676 ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
13679 gen_compute_branch(ctx, OPC_BLEZ, 4, rs, -1, imm << 1, 4);
13682 gen_compute_branch(ctx, OPC_BGTZ, 4, rs, -1, imm << 1, 4);
13687 mips32_op = OPC_TLTI;
13690 mips32_op = OPC_TGEI;
13693 mips32_op = OPC_TLTIU;
13696 mips32_op = OPC_TGEIU;
13699 mips32_op = OPC_TNEI;
13702 mips32_op = OPC_TEQI;
13704 gen_trap(ctx, mips32_op, rs, -1, imm);
13709 gen_compute_branch(ctx, minor == BNEZC ? OPC_BNE : OPC_BEQ,
13710 4, rs, 0, imm << 1, 0);
13711 /* Compact branches don't have a delay slot, so just let
13712 the normal delay slot handling take us to the branch
13716 gen_logic_imm(ctx, OPC_LUI, rs, 0, imm);
13719 /* Break the TB to be able to sync copied instructions
13721 ctx->bstate = BS_STOP;
13725 /* COP2: Not implemented. */
13726 generate_exception_err(ctx, EXCP_CpU, 2);
13729 mips32_op = (ctx->opcode & (1 << 16)) ? OPC_BC1FANY2 : OPC_BC1F;
13732 mips32_op = (ctx->opcode & (1 << 16)) ? OPC_BC1TANY2 : OPC_BC1T;
13735 mips32_op = OPC_BC1FANY4;
13738 mips32_op = OPC_BC1TANY4;
13741 check_insn(ctx, ASE_MIPS3D);
13744 if (env->CP0_Config1 & (1 << CP0C1_FP)) {
13745 check_cp1_enabled(ctx);
13746 gen_compute_branch1(ctx, mips32_op,
13747 (ctx->opcode >> 18) & 0x7, imm << 1);
13749 generate_exception_err(ctx, EXCP_CpU, 1);
13754 /* MIPS DSP: not implemented */
13757 MIPS_INVAL("pool32i");
13758 generate_exception(ctx, EXCP_RI);
13763 minor = (ctx->opcode >> 12) & 0xf;
13766 mips32_op = OPC_LWL;
13769 mips32_op = OPC_SWL;
13772 mips32_op = OPC_LWR;
13775 mips32_op = OPC_SWR;
13777 #if defined(TARGET_MIPS64)
13779 check_insn(ctx, ISA_MIPS3);
13780 check_mips_64(ctx);
13781 mips32_op = OPC_LDL;
13784 check_insn(ctx, ISA_MIPS3);
13785 check_mips_64(ctx);
13786 mips32_op = OPC_SDL;
13789 check_insn(ctx, ISA_MIPS3);
13790 check_mips_64(ctx);
13791 mips32_op = OPC_LDR;
13794 check_insn(ctx, ISA_MIPS3);
13795 check_mips_64(ctx);
13796 mips32_op = OPC_SDR;
13799 check_insn(ctx, ISA_MIPS3);
13800 check_mips_64(ctx);
13801 mips32_op = OPC_LWU;
13804 check_insn(ctx, ISA_MIPS3);
13805 check_mips_64(ctx);
13806 mips32_op = OPC_LLD;
13810 mips32_op = OPC_LL;
13813 gen_ld(ctx, mips32_op, rt, rs, SIMM(ctx->opcode, 0, 12));
13816 gen_st(ctx, mips32_op, rt, rs, SIMM(ctx->opcode, 0, 12));
13819 gen_st_cond(ctx, OPC_SC, rt, rs, SIMM(ctx->opcode, 0, 12));
13821 #if defined(TARGET_MIPS64)
13823 check_insn(ctx, ISA_MIPS3);
13824 check_mips_64(ctx);
13825 gen_st_cond(ctx, OPC_SCD, rt, rs, SIMM(ctx->opcode, 0, 12));
13829 /* Treat as no-op */
13832 MIPS_INVAL("pool32c");
13833 generate_exception(ctx, EXCP_RI);
13838 mips32_op = OPC_ADDI;
13841 mips32_op = OPC_ADDIU;
13843 gen_arith_imm(ctx, mips32_op, rt, rs, imm);
13846 /* Logical operations */
13848 mips32_op = OPC_ORI;
13851 mips32_op = OPC_XORI;
13854 mips32_op = OPC_ANDI;
13856 gen_logic_imm(ctx, mips32_op, rt, rs, imm);
13859 /* Set less than immediate */
13861 mips32_op = OPC_SLTI;
13864 mips32_op = OPC_SLTIU;
13866 gen_slt_imm(ctx, mips32_op, rt, rs, imm);
13869 offset = (int32_t)(ctx->opcode & 0x3FFFFFF) << 2;
13870 gen_compute_branch(ctx, OPC_JALX, 4, rt, rs, offset, 4);
13871 ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
13874 offset = (int32_t)(ctx->opcode & 0x3FFFFFF) << 1;
13875 gen_compute_branch(ctx, OPC_JAL, 4, rt, rs, offset, 2);
13876 ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
13879 gen_compute_branch(ctx, OPC_BEQ, 4, rt, rs, imm << 1, 4);
13882 gen_compute_branch(ctx, OPC_BNE, 4, rt, rs, imm << 1, 4);
13885 gen_compute_branch(ctx, OPC_J, 4, rt, rs,
13886 (int32_t)(ctx->opcode & 0x3FFFFFF) << 1, 4);
13889 gen_compute_branch(ctx, OPC_JAL, 4, rt, rs,
13890 (int32_t)(ctx->opcode & 0x3FFFFFF) << 1, 4);
13891 ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
13893 /* Floating point (COP1) */
13895 mips32_op = OPC_LWC1;
13898 mips32_op = OPC_LDC1;
13901 mips32_op = OPC_SWC1;
13904 mips32_op = OPC_SDC1;
13906 gen_cop1_ldst(ctx, mips32_op, rt, rs, imm);
13910 int reg = mmreg(ZIMM(ctx->opcode, 23, 3));
13911 int offset = SIMM(ctx->opcode, 0, 23) << 2;
13913 gen_addiupc(ctx, reg, offset, 0, 0);
13916 /* Loads and stores */
13918 mips32_op = OPC_LB;
13921 mips32_op = OPC_LBU;
13924 mips32_op = OPC_LH;
13927 mips32_op = OPC_LHU;
13930 mips32_op = OPC_LW;
13932 #ifdef TARGET_MIPS64
13934 check_insn(ctx, ISA_MIPS3);
13935 check_mips_64(ctx);
13936 mips32_op = OPC_LD;
13939 check_insn(ctx, ISA_MIPS3);
13940 check_mips_64(ctx);
13941 mips32_op = OPC_SD;
13945 mips32_op = OPC_SB;
13948 mips32_op = OPC_SH;
13951 mips32_op = OPC_SW;
13954 gen_ld(ctx, mips32_op, rt, rs, imm);
13957 gen_st(ctx, mips32_op, rt, rs, imm);
13960 generate_exception(ctx, EXCP_RI);
13965 static int decode_micromips_opc (CPUMIPSState *env, DisasContext *ctx)
13969 /* make sure instructions are on a halfword boundary */
13970 if (ctx->pc & 0x1) {
13971 env->CP0_BadVAddr = ctx->pc;
13972 generate_exception(ctx, EXCP_AdEL);
13973 ctx->bstate = BS_STOP;
13977 op = (ctx->opcode >> 10) & 0x3f;
13978 /* Enforce properly-sized instructions in a delay slot */
13979 if (ctx->hflags & MIPS_HFLAG_BDS_STRICT) {
13980 switch (op & 0x7) { /* MSB-3..MSB-5 */
13982 /* POOL32A, POOL32B, POOL32I, POOL32C */
13984 /* ADDI32, ADDIU32, ORI32, XORI32, SLTI32, SLTIU32, ANDI32, JALX32 */
13986 /* LBU32, LHU32, POOL32F, JALS32, BEQ32, BNE32, J32, JAL32 */
13988 /* SB32, SH32, ADDIUPC, SWC132, SDC132, SW32 */
13990 /* LB32, LH32, LWC132, LDC132, LW32 */
13991 if (ctx->hflags & MIPS_HFLAG_BDS16) {
13992 generate_exception(ctx, EXCP_RI);
13993 /* Just stop translation; the user is confused. */
13994 ctx->bstate = BS_STOP;
13999 /* POOL16A, POOL16B, POOL16C, LWGP16, POOL16F */
14001 /* LBU16, LHU16, LWSP16, LW16, SB16, SH16, SWSP16, SW16 */
14003 /* MOVE16, ANDI16, POOL16D, POOL16E, BEQZ16, BNEZ16, B16, LI16 */
14004 if (ctx->hflags & MIPS_HFLAG_BDS32) {
14005 generate_exception(ctx, EXCP_RI);
14006 /* Just stop translation; the user is confused. */
14007 ctx->bstate = BS_STOP;
14017 int rd = mmreg(uMIPS_RD(ctx->opcode));
14018 int rs1 = mmreg(uMIPS_RS1(ctx->opcode));
14019 int rs2 = mmreg(uMIPS_RS2(ctx->opcode));
14022 switch (ctx->opcode & 0x1) {
14031 gen_arith(ctx, opc, rd, rs1, rs2);
14036 int rd = mmreg(uMIPS_RD(ctx->opcode));
14037 int rs = mmreg(uMIPS_RS(ctx->opcode));
14038 int amount = (ctx->opcode >> 1) & 0x7;
14040 amount = amount == 0 ? 8 : amount;
14042 switch (ctx->opcode & 0x1) {
14051 gen_shift_imm(ctx, opc, rd, rs, amount);
14055 gen_pool16c_insn(ctx);
14059 int rd = mmreg(uMIPS_RD(ctx->opcode));
14060 int rb = 28; /* GP */
14061 int16_t offset = SIMM(ctx->opcode, 0, 7) << 2;
14063 gen_ld(ctx, OPC_LW, rd, rb, offset);
14067 if (ctx->opcode & 1) {
14068 generate_exception(ctx, EXCP_RI);
14071 int enc_dest = uMIPS_RD(ctx->opcode);
14072 int enc_rt = uMIPS_RS2(ctx->opcode);
14073 int enc_rs = uMIPS_RS1(ctx->opcode);
14074 int rd, rs, re, rt;
14075 static const int rd_enc[] = { 5, 5, 6, 4, 4, 4, 4, 4 };
14076 static const int re_enc[] = { 6, 7, 7, 21, 22, 5, 6, 7 };
14077 static const int rs_rt_enc[] = { 0, 17, 2, 3, 16, 18, 19, 20 };
14079 rd = rd_enc[enc_dest];
14080 re = re_enc[enc_dest];
14081 rs = rs_rt_enc[enc_rs];
14082 rt = rs_rt_enc[enc_rt];
14084 gen_arith(ctx, OPC_ADDU, rd, rs, 0);
14085 gen_arith(ctx, OPC_ADDU, re, rt, 0);
14090 int rd = mmreg(uMIPS_RD(ctx->opcode));
14091 int rb = mmreg(uMIPS_RS(ctx->opcode));
14092 int16_t offset = ZIMM(ctx->opcode, 0, 4);
14093 offset = (offset == 0xf ? -1 : offset);
14095 gen_ld(ctx, OPC_LBU, rd, rb, offset);
14100 int rd = mmreg(uMIPS_RD(ctx->opcode));
14101 int rb = mmreg(uMIPS_RS(ctx->opcode));
14102 int16_t offset = ZIMM(ctx->opcode, 0, 4) << 1;
14104 gen_ld(ctx, OPC_LHU, rd, rb, offset);
14109 int rd = (ctx->opcode >> 5) & 0x1f;
14110 int rb = 29; /* SP */
14111 int16_t offset = ZIMM(ctx->opcode, 0, 5) << 2;
14113 gen_ld(ctx, OPC_LW, rd, rb, offset);
14118 int rd = mmreg(uMIPS_RD(ctx->opcode));
14119 int rb = mmreg(uMIPS_RS(ctx->opcode));
14120 int16_t offset = ZIMM(ctx->opcode, 0, 4) << 2;
14122 gen_ld(ctx, OPC_LW, rd, rb, offset);
14127 int rd = mmreg2(uMIPS_RD(ctx->opcode));
14128 int rb = mmreg(uMIPS_RS(ctx->opcode));
14129 int16_t offset = ZIMM(ctx->opcode, 0, 4);
14131 gen_st(ctx, OPC_SB, rd, rb, offset);
14136 int rd = mmreg2(uMIPS_RD(ctx->opcode));
14137 int rb = mmreg(uMIPS_RS(ctx->opcode));
14138 int16_t offset = ZIMM(ctx->opcode, 0, 4) << 1;
14140 gen_st(ctx, OPC_SH, rd, rb, offset);
14145 int rd = (ctx->opcode >> 5) & 0x1f;
14146 int rb = 29; /* SP */
14147 int16_t offset = ZIMM(ctx->opcode, 0, 5) << 2;
14149 gen_st(ctx, OPC_SW, rd, rb, offset);
14154 int rd = mmreg2(uMIPS_RD(ctx->opcode));
14155 int rb = mmreg(uMIPS_RS(ctx->opcode));
14156 int16_t offset = ZIMM(ctx->opcode, 0, 4) << 2;
14158 gen_st(ctx, OPC_SW, rd, rb, offset);
14163 int rd = uMIPS_RD5(ctx->opcode);
14164 int rs = uMIPS_RS5(ctx->opcode);
14166 gen_arith(ctx, OPC_ADDU, rd, rs, 0);
14173 switch (ctx->opcode & 0x1) {
14183 switch (ctx->opcode & 0x1) {
14188 gen_addiur1sp(ctx);
14193 gen_compute_branch(ctx, OPC_BEQ, 2, 0, 0,
14194 SIMM(ctx->opcode, 0, 10) << 1, 4);
14198 gen_compute_branch(ctx, op == BNEZ16 ? OPC_BNE : OPC_BEQ, 2,
14199 mmreg(uMIPS_RD(ctx->opcode)),
14200 0, SIMM(ctx->opcode, 0, 7) << 1, 4);
14204 int reg = mmreg(uMIPS_RD(ctx->opcode));
14205 int imm = ZIMM(ctx->opcode, 0, 7);
14207 imm = (imm == 0x7f ? -1 : imm);
14208 tcg_gen_movi_tl(cpu_gpr[reg], imm);
14218 generate_exception(ctx, EXCP_RI);
14221 decode_micromips32_opc (env, ctx, op);
14228 /* SmartMIPS extension to MIPS32 */
14230 #if defined(TARGET_MIPS64)
14232 /* MDMX extension to MIPS64 */
14236 /* MIPSDSP functions. */
14237 static void gen_mipsdsp_ld(DisasContext *ctx, uint32_t opc,
14238 int rd, int base, int offset)
14240 const char *opn = "ldx";
14244 t0 = tcg_temp_new();
14247 gen_load_gpr(t0, offset);
14248 } else if (offset == 0) {
14249 gen_load_gpr(t0, base);
14251 gen_op_addr_add(ctx, t0, cpu_gpr[base], cpu_gpr[offset]);
14256 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_UB);
14257 gen_store_gpr(t0, rd);
14261 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TESW);
14262 gen_store_gpr(t0, rd);
14266 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TESL);
14267 gen_store_gpr(t0, rd);
14270 #if defined(TARGET_MIPS64)
14272 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TEQ);
14273 gen_store_gpr(t0, rd);
14278 (void)opn; /* avoid a compiler warning */
14279 MIPS_DEBUG("%s %s, %s(%s)", opn,
14280 regnames[rd], regnames[offset], regnames[base]);
14284 static void gen_mipsdsp_arith(DisasContext *ctx, uint32_t op1, uint32_t op2,
14285 int ret, int v1, int v2)
14287 const char *opn = "mipsdsp arith";
14292 /* Treat as NOP. */
14297 v1_t = tcg_temp_new();
14298 v2_t = tcg_temp_new();
14300 gen_load_gpr(v1_t, v1);
14301 gen_load_gpr(v2_t, v2);
14304 /* OPC_MULT_G_2E is equal OPC_ADDUH_QB_DSP */
14305 case OPC_MULT_G_2E:
14309 gen_helper_adduh_qb(cpu_gpr[ret], v1_t, v2_t);
14311 case OPC_ADDUH_R_QB:
14312 gen_helper_adduh_r_qb(cpu_gpr[ret], v1_t, v2_t);
14315 gen_helper_addqh_ph(cpu_gpr[ret], v1_t, v2_t);
14317 case OPC_ADDQH_R_PH:
14318 gen_helper_addqh_r_ph(cpu_gpr[ret], v1_t, v2_t);
14321 gen_helper_addqh_w(cpu_gpr[ret], v1_t, v2_t);
14323 case OPC_ADDQH_R_W:
14324 gen_helper_addqh_r_w(cpu_gpr[ret], v1_t, v2_t);
14327 gen_helper_subuh_qb(cpu_gpr[ret], v1_t, v2_t);
14329 case OPC_SUBUH_R_QB:
14330 gen_helper_subuh_r_qb(cpu_gpr[ret], v1_t, v2_t);
14333 gen_helper_subqh_ph(cpu_gpr[ret], v1_t, v2_t);
14335 case OPC_SUBQH_R_PH:
14336 gen_helper_subqh_r_ph(cpu_gpr[ret], v1_t, v2_t);
14339 gen_helper_subqh_w(cpu_gpr[ret], v1_t, v2_t);
14341 case OPC_SUBQH_R_W:
14342 gen_helper_subqh_r_w(cpu_gpr[ret], v1_t, v2_t);
14346 case OPC_ABSQ_S_PH_DSP:
14348 case OPC_ABSQ_S_QB:
14350 gen_helper_absq_s_qb(cpu_gpr[ret], v2_t, cpu_env);
14352 case OPC_ABSQ_S_PH:
14354 gen_helper_absq_s_ph(cpu_gpr[ret], v2_t, cpu_env);
14358 gen_helper_absq_s_w(cpu_gpr[ret], v2_t, cpu_env);
14360 case OPC_PRECEQ_W_PHL:
14362 tcg_gen_andi_tl(cpu_gpr[ret], v2_t, 0xFFFF0000);
14363 tcg_gen_ext32s_tl(cpu_gpr[ret], cpu_gpr[ret]);
14365 case OPC_PRECEQ_W_PHR:
14367 tcg_gen_andi_tl(cpu_gpr[ret], v2_t, 0x0000FFFF);
14368 tcg_gen_shli_tl(cpu_gpr[ret], cpu_gpr[ret], 16);
14369 tcg_gen_ext32s_tl(cpu_gpr[ret], cpu_gpr[ret]);
14371 case OPC_PRECEQU_PH_QBL:
14373 gen_helper_precequ_ph_qbl(cpu_gpr[ret], v2_t);
14375 case OPC_PRECEQU_PH_QBR:
14377 gen_helper_precequ_ph_qbr(cpu_gpr[ret], v2_t);
14379 case OPC_PRECEQU_PH_QBLA:
14381 gen_helper_precequ_ph_qbla(cpu_gpr[ret], v2_t);
14383 case OPC_PRECEQU_PH_QBRA:
14385 gen_helper_precequ_ph_qbra(cpu_gpr[ret], v2_t);
14387 case OPC_PRECEU_PH_QBL:
14389 gen_helper_preceu_ph_qbl(cpu_gpr[ret], v2_t);
14391 case OPC_PRECEU_PH_QBR:
14393 gen_helper_preceu_ph_qbr(cpu_gpr[ret], v2_t);
14395 case OPC_PRECEU_PH_QBLA:
14397 gen_helper_preceu_ph_qbla(cpu_gpr[ret], v2_t);
14399 case OPC_PRECEU_PH_QBRA:
14401 gen_helper_preceu_ph_qbra(cpu_gpr[ret], v2_t);
14405 case OPC_ADDU_QB_DSP:
14409 gen_helper_addq_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
14411 case OPC_ADDQ_S_PH:
14413 gen_helper_addq_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
14417 gen_helper_addq_s_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
14421 gen_helper_addu_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
14423 case OPC_ADDU_S_QB:
14425 gen_helper_addu_s_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
14429 gen_helper_addu_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
14431 case OPC_ADDU_S_PH:
14433 gen_helper_addu_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
14437 gen_helper_subq_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
14439 case OPC_SUBQ_S_PH:
14441 gen_helper_subq_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
14445 gen_helper_subq_s_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
14449 gen_helper_subu_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
14451 case OPC_SUBU_S_QB:
14453 gen_helper_subu_s_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
14457 gen_helper_subu_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
14459 case OPC_SUBU_S_PH:
14461 gen_helper_subu_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
14465 gen_helper_addsc(cpu_gpr[ret], v1_t, v2_t, cpu_env);
14469 gen_helper_addwc(cpu_gpr[ret], v1_t, v2_t, cpu_env);
14473 gen_helper_modsub(cpu_gpr[ret], v1_t, v2_t);
14475 case OPC_RADDU_W_QB:
14477 gen_helper_raddu_w_qb(cpu_gpr[ret], v1_t);
14481 case OPC_CMPU_EQ_QB_DSP:
14483 case OPC_PRECR_QB_PH:
14485 gen_helper_precr_qb_ph(cpu_gpr[ret], v1_t, v2_t);
14487 case OPC_PRECRQ_QB_PH:
14489 gen_helper_precrq_qb_ph(cpu_gpr[ret], v1_t, v2_t);
14491 case OPC_PRECR_SRA_PH_W:
14494 TCGv_i32 sa_t = tcg_const_i32(v2);
14495 gen_helper_precr_sra_ph_w(cpu_gpr[ret], sa_t, v1_t,
14497 tcg_temp_free_i32(sa_t);
14500 case OPC_PRECR_SRA_R_PH_W:
14503 TCGv_i32 sa_t = tcg_const_i32(v2);
14504 gen_helper_precr_sra_r_ph_w(cpu_gpr[ret], sa_t, v1_t,
14506 tcg_temp_free_i32(sa_t);
14509 case OPC_PRECRQ_PH_W:
14511 gen_helper_precrq_ph_w(cpu_gpr[ret], v1_t, v2_t);
14513 case OPC_PRECRQ_RS_PH_W:
14515 gen_helper_precrq_rs_ph_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
14517 case OPC_PRECRQU_S_QB_PH:
14519 gen_helper_precrqu_s_qb_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
14523 #ifdef TARGET_MIPS64
14524 case OPC_ABSQ_S_QH_DSP:
14526 case OPC_PRECEQ_L_PWL:
14528 tcg_gen_andi_tl(cpu_gpr[ret], v2_t, 0xFFFFFFFF00000000ull);
14530 case OPC_PRECEQ_L_PWR:
14532 tcg_gen_shli_tl(cpu_gpr[ret], v2_t, 32);
14534 case OPC_PRECEQ_PW_QHL:
14536 gen_helper_preceq_pw_qhl(cpu_gpr[ret], v2_t);
14538 case OPC_PRECEQ_PW_QHR:
14540 gen_helper_preceq_pw_qhr(cpu_gpr[ret], v2_t);
14542 case OPC_PRECEQ_PW_QHLA:
14544 gen_helper_preceq_pw_qhla(cpu_gpr[ret], v2_t);
14546 case OPC_PRECEQ_PW_QHRA:
14548 gen_helper_preceq_pw_qhra(cpu_gpr[ret], v2_t);
14550 case OPC_PRECEQU_QH_OBL:
14552 gen_helper_precequ_qh_obl(cpu_gpr[ret], v2_t);
14554 case OPC_PRECEQU_QH_OBR:
14556 gen_helper_precequ_qh_obr(cpu_gpr[ret], v2_t);
14558 case OPC_PRECEQU_QH_OBLA:
14560 gen_helper_precequ_qh_obla(cpu_gpr[ret], v2_t);
14562 case OPC_PRECEQU_QH_OBRA:
14564 gen_helper_precequ_qh_obra(cpu_gpr[ret], v2_t);
14566 case OPC_PRECEU_QH_OBL:
14568 gen_helper_preceu_qh_obl(cpu_gpr[ret], v2_t);
14570 case OPC_PRECEU_QH_OBR:
14572 gen_helper_preceu_qh_obr(cpu_gpr[ret], v2_t);
14574 case OPC_PRECEU_QH_OBLA:
14576 gen_helper_preceu_qh_obla(cpu_gpr[ret], v2_t);
14578 case OPC_PRECEU_QH_OBRA:
14580 gen_helper_preceu_qh_obra(cpu_gpr[ret], v2_t);
14582 case OPC_ABSQ_S_OB:
14584 gen_helper_absq_s_ob(cpu_gpr[ret], v2_t, cpu_env);
14586 case OPC_ABSQ_S_PW:
14588 gen_helper_absq_s_pw(cpu_gpr[ret], v2_t, cpu_env);
14590 case OPC_ABSQ_S_QH:
14592 gen_helper_absq_s_qh(cpu_gpr[ret], v2_t, cpu_env);
14596 case OPC_ADDU_OB_DSP:
14598 case OPC_RADDU_L_OB:
14600 gen_helper_raddu_l_ob(cpu_gpr[ret], v1_t);
14604 gen_helper_subq_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
14606 case OPC_SUBQ_S_PW:
14608 gen_helper_subq_s_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
14612 gen_helper_subq_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
14614 case OPC_SUBQ_S_QH:
14616 gen_helper_subq_s_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
14620 gen_helper_subu_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
14622 case OPC_SUBU_S_OB:
14624 gen_helper_subu_s_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
14628 gen_helper_subu_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
14630 case OPC_SUBU_S_QH:
14632 gen_helper_subu_s_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
14636 gen_helper_subuh_ob(cpu_gpr[ret], v1_t, v2_t);
14638 case OPC_SUBUH_R_OB:
14640 gen_helper_subuh_r_ob(cpu_gpr[ret], v1_t, v2_t);
14644 gen_helper_addq_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
14646 case OPC_ADDQ_S_PW:
14648 gen_helper_addq_s_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
14652 gen_helper_addq_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
14654 case OPC_ADDQ_S_QH:
14656 gen_helper_addq_s_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
14660 gen_helper_addu_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
14662 case OPC_ADDU_S_OB:
14664 gen_helper_addu_s_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
14668 gen_helper_addu_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
14670 case OPC_ADDU_S_QH:
14672 gen_helper_addu_s_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
14676 gen_helper_adduh_ob(cpu_gpr[ret], v1_t, v2_t);
14678 case OPC_ADDUH_R_OB:
14680 gen_helper_adduh_r_ob(cpu_gpr[ret], v1_t, v2_t);
14684 case OPC_CMPU_EQ_OB_DSP:
14686 case OPC_PRECR_OB_QH:
14688 gen_helper_precr_ob_qh(cpu_gpr[ret], v1_t, v2_t);
14690 case OPC_PRECR_SRA_QH_PW:
14693 TCGv_i32 ret_t = tcg_const_i32(ret);
14694 gen_helper_precr_sra_qh_pw(v2_t, v1_t, v2_t, ret_t);
14695 tcg_temp_free_i32(ret_t);
14698 case OPC_PRECR_SRA_R_QH_PW:
14701 TCGv_i32 sa_v = tcg_const_i32(ret);
14702 gen_helper_precr_sra_r_qh_pw(v2_t, v1_t, v2_t, sa_v);
14703 tcg_temp_free_i32(sa_v);
14706 case OPC_PRECRQ_OB_QH:
14708 gen_helper_precrq_ob_qh(cpu_gpr[ret], v1_t, v2_t);
14710 case OPC_PRECRQ_PW_L:
14712 gen_helper_precrq_pw_l(cpu_gpr[ret], v1_t, v2_t);
14714 case OPC_PRECRQ_QH_PW:
14716 gen_helper_precrq_qh_pw(cpu_gpr[ret], v1_t, v2_t);
14718 case OPC_PRECRQ_RS_QH_PW:
14720 gen_helper_precrq_rs_qh_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
14722 case OPC_PRECRQU_S_OB_QH:
14724 gen_helper_precrqu_s_ob_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
14731 tcg_temp_free(v1_t);
14732 tcg_temp_free(v2_t);
14734 (void)opn; /* avoid a compiler warning */
14735 MIPS_DEBUG("%s", opn);
14738 static void gen_mipsdsp_shift(DisasContext *ctx, uint32_t opc,
14739 int ret, int v1, int v2)
14742 const char *opn = "mipsdsp shift";
14748 /* Treat as NOP. */
14753 t0 = tcg_temp_new();
14754 v1_t = tcg_temp_new();
14755 v2_t = tcg_temp_new();
14757 tcg_gen_movi_tl(t0, v1);
14758 gen_load_gpr(v1_t, v1);
14759 gen_load_gpr(v2_t, v2);
14762 case OPC_SHLL_QB_DSP:
14764 op2 = MASK_SHLL_QB(ctx->opcode);
14768 gen_helper_shll_qb(cpu_gpr[ret], t0, v2_t, cpu_env);
14772 gen_helper_shll_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
14776 gen_helper_shll_ph(cpu_gpr[ret], t0, v2_t, cpu_env);
14780 gen_helper_shll_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
14782 case OPC_SHLL_S_PH:
14784 gen_helper_shll_s_ph(cpu_gpr[ret], t0, v2_t, cpu_env);
14786 case OPC_SHLLV_S_PH:
14788 gen_helper_shll_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
14792 gen_helper_shll_s_w(cpu_gpr[ret], t0, v2_t, cpu_env);
14794 case OPC_SHLLV_S_W:
14796 gen_helper_shll_s_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
14800 gen_helper_shrl_qb(cpu_gpr[ret], t0, v2_t);
14804 gen_helper_shrl_qb(cpu_gpr[ret], v1_t, v2_t);
14808 gen_helper_shrl_ph(cpu_gpr[ret], t0, v2_t);
14812 gen_helper_shrl_ph(cpu_gpr[ret], v1_t, v2_t);
14816 gen_helper_shra_qb(cpu_gpr[ret], t0, v2_t);
14818 case OPC_SHRA_R_QB:
14820 gen_helper_shra_r_qb(cpu_gpr[ret], t0, v2_t);
14824 gen_helper_shra_qb(cpu_gpr[ret], v1_t, v2_t);
14826 case OPC_SHRAV_R_QB:
14828 gen_helper_shra_r_qb(cpu_gpr[ret], v1_t, v2_t);
14832 gen_helper_shra_ph(cpu_gpr[ret], t0, v2_t);
14834 case OPC_SHRA_R_PH:
14836 gen_helper_shra_r_ph(cpu_gpr[ret], t0, v2_t);
14840 gen_helper_shra_ph(cpu_gpr[ret], v1_t, v2_t);
14842 case OPC_SHRAV_R_PH:
14844 gen_helper_shra_r_ph(cpu_gpr[ret], v1_t, v2_t);
14848 gen_helper_shra_r_w(cpu_gpr[ret], t0, v2_t);
14850 case OPC_SHRAV_R_W:
14852 gen_helper_shra_r_w(cpu_gpr[ret], v1_t, v2_t);
14854 default: /* Invalid */
14855 MIPS_INVAL("MASK SHLL.QB");
14856 generate_exception(ctx, EXCP_RI);
14861 #ifdef TARGET_MIPS64
14862 case OPC_SHLL_OB_DSP:
14863 op2 = MASK_SHLL_OB(ctx->opcode);
14867 gen_helper_shll_pw(cpu_gpr[ret], v2_t, t0, cpu_env);
14871 gen_helper_shll_pw(cpu_gpr[ret], v2_t, v1_t, cpu_env);
14873 case OPC_SHLL_S_PW:
14875 gen_helper_shll_s_pw(cpu_gpr[ret], v2_t, t0, cpu_env);
14877 case OPC_SHLLV_S_PW:
14879 gen_helper_shll_s_pw(cpu_gpr[ret], v2_t, v1_t, cpu_env);
14883 gen_helper_shll_ob(cpu_gpr[ret], v2_t, t0, cpu_env);
14887 gen_helper_shll_ob(cpu_gpr[ret], v2_t, v1_t, cpu_env);
14891 gen_helper_shll_qh(cpu_gpr[ret], v2_t, t0, cpu_env);
14895 gen_helper_shll_qh(cpu_gpr[ret], v2_t, v1_t, cpu_env);
14897 case OPC_SHLL_S_QH:
14899 gen_helper_shll_s_qh(cpu_gpr[ret], v2_t, t0, cpu_env);
14901 case OPC_SHLLV_S_QH:
14903 gen_helper_shll_s_qh(cpu_gpr[ret], v2_t, v1_t, cpu_env);
14907 gen_helper_shra_ob(cpu_gpr[ret], v2_t, t0);
14911 gen_helper_shra_ob(cpu_gpr[ret], v2_t, v1_t);
14913 case OPC_SHRA_R_OB:
14915 gen_helper_shra_r_ob(cpu_gpr[ret], v2_t, t0);
14917 case OPC_SHRAV_R_OB:
14919 gen_helper_shra_r_ob(cpu_gpr[ret], v2_t, v1_t);
14923 gen_helper_shra_pw(cpu_gpr[ret], v2_t, t0);
14927 gen_helper_shra_pw(cpu_gpr[ret], v2_t, v1_t);
14929 case OPC_SHRA_R_PW:
14931 gen_helper_shra_r_pw(cpu_gpr[ret], v2_t, t0);
14933 case OPC_SHRAV_R_PW:
14935 gen_helper_shra_r_pw(cpu_gpr[ret], v2_t, v1_t);
14939 gen_helper_shra_qh(cpu_gpr[ret], v2_t, t0);
14943 gen_helper_shra_qh(cpu_gpr[ret], v2_t, v1_t);
14945 case OPC_SHRA_R_QH:
14947 gen_helper_shra_r_qh(cpu_gpr[ret], v2_t, t0);
14949 case OPC_SHRAV_R_QH:
14951 gen_helper_shra_r_qh(cpu_gpr[ret], v2_t, v1_t);
14955 gen_helper_shrl_ob(cpu_gpr[ret], v2_t, t0);
14959 gen_helper_shrl_ob(cpu_gpr[ret], v2_t, v1_t);
14963 gen_helper_shrl_qh(cpu_gpr[ret], v2_t, t0);
14967 gen_helper_shrl_qh(cpu_gpr[ret], v2_t, v1_t);
14969 default: /* Invalid */
14970 MIPS_INVAL("MASK SHLL.OB");
14971 generate_exception(ctx, EXCP_RI);
14979 tcg_temp_free(v1_t);
14980 tcg_temp_free(v2_t);
14981 (void)opn; /* avoid a compiler warning */
14982 MIPS_DEBUG("%s", opn);
14985 static void gen_mipsdsp_multiply(DisasContext *ctx, uint32_t op1, uint32_t op2,
14986 int ret, int v1, int v2, int check_ret)
14988 const char *opn = "mipsdsp multiply";
14993 if ((ret == 0) && (check_ret == 1)) {
14994 /* Treat as NOP. */
14999 t0 = tcg_temp_new_i32();
15000 v1_t = tcg_temp_new();
15001 v2_t = tcg_temp_new();
15003 tcg_gen_movi_i32(t0, ret);
15004 gen_load_gpr(v1_t, v1);
15005 gen_load_gpr(v2_t, v2);
15008 /* OPC_MULT_G_2E, OPC_ADDUH_QB_DSP, OPC_MUL_PH_DSP have
15009 * the same mask and op1. */
15010 case OPC_MULT_G_2E:
15014 gen_helper_mul_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15017 gen_helper_mul_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15020 gen_helper_mulq_s_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15022 case OPC_MULQ_RS_W:
15023 gen_helper_mulq_rs_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15027 case OPC_DPA_W_PH_DSP:
15029 case OPC_DPAU_H_QBL:
15031 gen_helper_dpau_h_qbl(t0, v1_t, v2_t, cpu_env);
15033 case OPC_DPAU_H_QBR:
15035 gen_helper_dpau_h_qbr(t0, v1_t, v2_t, cpu_env);
15037 case OPC_DPSU_H_QBL:
15039 gen_helper_dpsu_h_qbl(t0, v1_t, v2_t, cpu_env);
15041 case OPC_DPSU_H_QBR:
15043 gen_helper_dpsu_h_qbr(t0, v1_t, v2_t, cpu_env);
15047 gen_helper_dpa_w_ph(t0, v1_t, v2_t, cpu_env);
15049 case OPC_DPAX_W_PH:
15051 gen_helper_dpax_w_ph(t0, v1_t, v2_t, cpu_env);
15053 case OPC_DPAQ_S_W_PH:
15055 gen_helper_dpaq_s_w_ph(t0, v1_t, v2_t, cpu_env);
15057 case OPC_DPAQX_S_W_PH:
15059 gen_helper_dpaqx_s_w_ph(t0, v1_t, v2_t, cpu_env);
15061 case OPC_DPAQX_SA_W_PH:
15063 gen_helper_dpaqx_sa_w_ph(t0, v1_t, v2_t, cpu_env);
15067 gen_helper_dps_w_ph(t0, v1_t, v2_t, cpu_env);
15069 case OPC_DPSX_W_PH:
15071 gen_helper_dpsx_w_ph(t0, v1_t, v2_t, cpu_env);
15073 case OPC_DPSQ_S_W_PH:
15075 gen_helper_dpsq_s_w_ph(t0, v1_t, v2_t, cpu_env);
15077 case OPC_DPSQX_S_W_PH:
15079 gen_helper_dpsqx_s_w_ph(t0, v1_t, v2_t, cpu_env);
15081 case OPC_DPSQX_SA_W_PH:
15083 gen_helper_dpsqx_sa_w_ph(t0, v1_t, v2_t, cpu_env);
15085 case OPC_MULSAQ_S_W_PH:
15087 gen_helper_mulsaq_s_w_ph(t0, v1_t, v2_t, cpu_env);
15089 case OPC_DPAQ_SA_L_W:
15091 gen_helper_dpaq_sa_l_w(t0, v1_t, v2_t, cpu_env);
15093 case OPC_DPSQ_SA_L_W:
15095 gen_helper_dpsq_sa_l_w(t0, v1_t, v2_t, cpu_env);
15097 case OPC_MAQ_S_W_PHL:
15099 gen_helper_maq_s_w_phl(t0, v1_t, v2_t, cpu_env);
15101 case OPC_MAQ_S_W_PHR:
15103 gen_helper_maq_s_w_phr(t0, v1_t, v2_t, cpu_env);
15105 case OPC_MAQ_SA_W_PHL:
15107 gen_helper_maq_sa_w_phl(t0, v1_t, v2_t, cpu_env);
15109 case OPC_MAQ_SA_W_PHR:
15111 gen_helper_maq_sa_w_phr(t0, v1_t, v2_t, cpu_env);
15113 case OPC_MULSA_W_PH:
15115 gen_helper_mulsa_w_ph(t0, v1_t, v2_t, cpu_env);
15119 #ifdef TARGET_MIPS64
15120 case OPC_DPAQ_W_QH_DSP:
15122 int ac = ret & 0x03;
15123 tcg_gen_movi_i32(t0, ac);
15128 gen_helper_dmadd(v1_t, v2_t, t0, cpu_env);
15132 gen_helper_dmaddu(v1_t, v2_t, t0, cpu_env);
15136 gen_helper_dmsub(v1_t, v2_t, t0, cpu_env);
15140 gen_helper_dmsubu(v1_t, v2_t, t0, cpu_env);
15144 gen_helper_dpa_w_qh(v1_t, v2_t, t0, cpu_env);
15146 case OPC_DPAQ_S_W_QH:
15148 gen_helper_dpaq_s_w_qh(v1_t, v2_t, t0, cpu_env);
15150 case OPC_DPAQ_SA_L_PW:
15152 gen_helper_dpaq_sa_l_pw(v1_t, v2_t, t0, cpu_env);
15154 case OPC_DPAU_H_OBL:
15156 gen_helper_dpau_h_obl(v1_t, v2_t, t0, cpu_env);
15158 case OPC_DPAU_H_OBR:
15160 gen_helper_dpau_h_obr(v1_t, v2_t, t0, cpu_env);
15164 gen_helper_dps_w_qh(v1_t, v2_t, t0, cpu_env);
15166 case OPC_DPSQ_S_W_QH:
15168 gen_helper_dpsq_s_w_qh(v1_t, v2_t, t0, cpu_env);
15170 case OPC_DPSQ_SA_L_PW:
15172 gen_helper_dpsq_sa_l_pw(v1_t, v2_t, t0, cpu_env);
15174 case OPC_DPSU_H_OBL:
15176 gen_helper_dpsu_h_obl(v1_t, v2_t, t0, cpu_env);
15178 case OPC_DPSU_H_OBR:
15180 gen_helper_dpsu_h_obr(v1_t, v2_t, t0, cpu_env);
15182 case OPC_MAQ_S_L_PWL:
15184 gen_helper_maq_s_l_pwl(v1_t, v2_t, t0, cpu_env);
15186 case OPC_MAQ_S_L_PWR:
15188 gen_helper_maq_s_l_pwr(v1_t, v2_t, t0, cpu_env);
15190 case OPC_MAQ_S_W_QHLL:
15192 gen_helper_maq_s_w_qhll(v1_t, v2_t, t0, cpu_env);
15194 case OPC_MAQ_SA_W_QHLL:
15196 gen_helper_maq_sa_w_qhll(v1_t, v2_t, t0, cpu_env);
15198 case OPC_MAQ_S_W_QHLR:
15200 gen_helper_maq_s_w_qhlr(v1_t, v2_t, t0, cpu_env);
15202 case OPC_MAQ_SA_W_QHLR:
15204 gen_helper_maq_sa_w_qhlr(v1_t, v2_t, t0, cpu_env);
15206 case OPC_MAQ_S_W_QHRL:
15208 gen_helper_maq_s_w_qhrl(v1_t, v2_t, t0, cpu_env);
15210 case OPC_MAQ_SA_W_QHRL:
15212 gen_helper_maq_sa_w_qhrl(v1_t, v2_t, t0, cpu_env);
15214 case OPC_MAQ_S_W_QHRR:
15216 gen_helper_maq_s_w_qhrr(v1_t, v2_t, t0, cpu_env);
15218 case OPC_MAQ_SA_W_QHRR:
15220 gen_helper_maq_sa_w_qhrr(v1_t, v2_t, t0, cpu_env);
15222 case OPC_MULSAQ_S_L_PW:
15224 gen_helper_mulsaq_s_l_pw(v1_t, v2_t, t0, cpu_env);
15226 case OPC_MULSAQ_S_W_QH:
15228 gen_helper_mulsaq_s_w_qh(v1_t, v2_t, t0, cpu_env);
15234 case OPC_ADDU_QB_DSP:
15236 case OPC_MULEU_S_PH_QBL:
15238 gen_helper_muleu_s_ph_qbl(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15240 case OPC_MULEU_S_PH_QBR:
15242 gen_helper_muleu_s_ph_qbr(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15244 case OPC_MULQ_RS_PH:
15246 gen_helper_mulq_rs_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15248 case OPC_MULEQ_S_W_PHL:
15250 gen_helper_muleq_s_w_phl(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15252 case OPC_MULEQ_S_W_PHR:
15254 gen_helper_muleq_s_w_phr(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15256 case OPC_MULQ_S_PH:
15258 gen_helper_mulq_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15262 #ifdef TARGET_MIPS64
15263 case OPC_ADDU_OB_DSP:
15265 case OPC_MULEQ_S_PW_QHL:
15267 gen_helper_muleq_s_pw_qhl(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15269 case OPC_MULEQ_S_PW_QHR:
15271 gen_helper_muleq_s_pw_qhr(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15273 case OPC_MULEU_S_QH_OBL:
15275 gen_helper_muleu_s_qh_obl(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15277 case OPC_MULEU_S_QH_OBR:
15279 gen_helper_muleu_s_qh_obr(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15281 case OPC_MULQ_RS_QH:
15283 gen_helper_mulq_rs_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15290 tcg_temp_free_i32(t0);
15291 tcg_temp_free(v1_t);
15292 tcg_temp_free(v2_t);
15294 (void)opn; /* avoid a compiler warning */
15295 MIPS_DEBUG("%s", opn);
15299 static void gen_mipsdsp_bitinsn(DisasContext *ctx, uint32_t op1, uint32_t op2,
15302 const char *opn = "mipsdsp Bit/ Manipulation";
15308 /* Treat as NOP. */
15313 t0 = tcg_temp_new();
15314 val_t = tcg_temp_new();
15315 gen_load_gpr(val_t, val);
15318 case OPC_ABSQ_S_PH_DSP:
15322 gen_helper_bitrev(cpu_gpr[ret], val_t);
15327 target_long result;
15328 imm = (ctx->opcode >> 16) & 0xFF;
15329 result = (uint32_t)imm << 24 |
15330 (uint32_t)imm << 16 |
15331 (uint32_t)imm << 8 |
15333 result = (int32_t)result;
15334 tcg_gen_movi_tl(cpu_gpr[ret], result);
15339 tcg_gen_ext8u_tl(cpu_gpr[ret], val_t);
15340 tcg_gen_shli_tl(t0, cpu_gpr[ret], 8);
15341 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
15342 tcg_gen_shli_tl(t0, cpu_gpr[ret], 16);
15343 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
15344 tcg_gen_ext32s_tl(cpu_gpr[ret], cpu_gpr[ret]);
15349 imm = (ctx->opcode >> 16) & 0x03FF;
15350 imm = (int16_t)(imm << 6) >> 6;
15351 tcg_gen_movi_tl(cpu_gpr[ret], \
15352 (target_long)((int32_t)imm << 16 | \
15358 tcg_gen_ext16u_tl(cpu_gpr[ret], val_t);
15359 tcg_gen_shli_tl(t0, cpu_gpr[ret], 16);
15360 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
15361 tcg_gen_ext32s_tl(cpu_gpr[ret], cpu_gpr[ret]);
15365 #ifdef TARGET_MIPS64
15366 case OPC_ABSQ_S_QH_DSP:
15373 imm = (ctx->opcode >> 16) & 0xFF;
15374 temp = ((uint64_t)imm << 8) | (uint64_t)imm;
15375 temp = (temp << 16) | temp;
15376 temp = (temp << 32) | temp;
15377 tcg_gen_movi_tl(cpu_gpr[ret], temp);
15385 imm = (ctx->opcode >> 16) & 0x03FF;
15386 imm = (int16_t)(imm << 6) >> 6;
15387 temp = ((target_long)imm << 32) \
15388 | ((target_long)imm & 0xFFFFFFFF);
15389 tcg_gen_movi_tl(cpu_gpr[ret], temp);
15397 imm = (ctx->opcode >> 16) & 0x03FF;
15398 imm = (int16_t)(imm << 6) >> 6;
15400 temp = ((uint64_t)(uint16_t)imm << 48) |
15401 ((uint64_t)(uint16_t)imm << 32) |
15402 ((uint64_t)(uint16_t)imm << 16) |
15403 (uint64_t)(uint16_t)imm;
15404 tcg_gen_movi_tl(cpu_gpr[ret], temp);
15409 tcg_gen_ext8u_tl(cpu_gpr[ret], val_t);
15410 tcg_gen_shli_tl(t0, cpu_gpr[ret], 8);
15411 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
15412 tcg_gen_shli_tl(t0, cpu_gpr[ret], 16);
15413 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
15414 tcg_gen_shli_tl(t0, cpu_gpr[ret], 32);
15415 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
15419 tcg_gen_ext32u_i64(cpu_gpr[ret], val_t);
15420 tcg_gen_shli_tl(t0, cpu_gpr[ret], 32);
15421 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
15425 tcg_gen_ext16u_tl(cpu_gpr[ret], val_t);
15426 tcg_gen_shli_tl(t0, cpu_gpr[ret], 16);
15427 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
15428 tcg_gen_shli_tl(t0, cpu_gpr[ret], 32);
15429 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
15436 tcg_temp_free(val_t);
15438 (void)opn; /* avoid a compiler warning */
15439 MIPS_DEBUG("%s", opn);
15442 static void gen_mipsdsp_add_cmp_pick(DisasContext *ctx,
15443 uint32_t op1, uint32_t op2,
15444 int ret, int v1, int v2, int check_ret)
15446 const char *opn = "mipsdsp add compare pick";
15451 if ((ret == 0) && (check_ret == 1)) {
15452 /* Treat as NOP. */
15457 t1 = tcg_temp_new();
15458 v1_t = tcg_temp_new();
15459 v2_t = tcg_temp_new();
15461 gen_load_gpr(v1_t, v1);
15462 gen_load_gpr(v2_t, v2);
15465 case OPC_CMPU_EQ_QB_DSP:
15467 case OPC_CMPU_EQ_QB:
15469 gen_helper_cmpu_eq_qb(v1_t, v2_t, cpu_env);
15471 case OPC_CMPU_LT_QB:
15473 gen_helper_cmpu_lt_qb(v1_t, v2_t, cpu_env);
15475 case OPC_CMPU_LE_QB:
15477 gen_helper_cmpu_le_qb(v1_t, v2_t, cpu_env);
15479 case OPC_CMPGU_EQ_QB:
15481 gen_helper_cmpgu_eq_qb(cpu_gpr[ret], v1_t, v2_t);
15483 case OPC_CMPGU_LT_QB:
15485 gen_helper_cmpgu_lt_qb(cpu_gpr[ret], v1_t, v2_t);
15487 case OPC_CMPGU_LE_QB:
15489 gen_helper_cmpgu_le_qb(cpu_gpr[ret], v1_t, v2_t);
15491 case OPC_CMPGDU_EQ_QB:
15493 gen_helper_cmpgu_eq_qb(t1, v1_t, v2_t);
15494 tcg_gen_mov_tl(cpu_gpr[ret], t1);
15495 tcg_gen_andi_tl(cpu_dspctrl, cpu_dspctrl, 0xF0FFFFFF);
15496 tcg_gen_shli_tl(t1, t1, 24);
15497 tcg_gen_or_tl(cpu_dspctrl, cpu_dspctrl, t1);
15499 case OPC_CMPGDU_LT_QB:
15501 gen_helper_cmpgu_lt_qb(t1, v1_t, v2_t);
15502 tcg_gen_mov_tl(cpu_gpr[ret], t1);
15503 tcg_gen_andi_tl(cpu_dspctrl, cpu_dspctrl, 0xF0FFFFFF);
15504 tcg_gen_shli_tl(t1, t1, 24);
15505 tcg_gen_or_tl(cpu_dspctrl, cpu_dspctrl, t1);
15507 case OPC_CMPGDU_LE_QB:
15509 gen_helper_cmpgu_le_qb(t1, v1_t, v2_t);
15510 tcg_gen_mov_tl(cpu_gpr[ret], t1);
15511 tcg_gen_andi_tl(cpu_dspctrl, cpu_dspctrl, 0xF0FFFFFF);
15512 tcg_gen_shli_tl(t1, t1, 24);
15513 tcg_gen_or_tl(cpu_dspctrl, cpu_dspctrl, t1);
15515 case OPC_CMP_EQ_PH:
15517 gen_helper_cmp_eq_ph(v1_t, v2_t, cpu_env);
15519 case OPC_CMP_LT_PH:
15521 gen_helper_cmp_lt_ph(v1_t, v2_t, cpu_env);
15523 case OPC_CMP_LE_PH:
15525 gen_helper_cmp_le_ph(v1_t, v2_t, cpu_env);
15529 gen_helper_pick_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15533 gen_helper_pick_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15535 case OPC_PACKRL_PH:
15537 gen_helper_packrl_ph(cpu_gpr[ret], v1_t, v2_t);
15541 #ifdef TARGET_MIPS64
15542 case OPC_CMPU_EQ_OB_DSP:
15544 case OPC_CMP_EQ_PW:
15546 gen_helper_cmp_eq_pw(v1_t, v2_t, cpu_env);
15548 case OPC_CMP_LT_PW:
15550 gen_helper_cmp_lt_pw(v1_t, v2_t, cpu_env);
15552 case OPC_CMP_LE_PW:
15554 gen_helper_cmp_le_pw(v1_t, v2_t, cpu_env);
15556 case OPC_CMP_EQ_QH:
15558 gen_helper_cmp_eq_qh(v1_t, v2_t, cpu_env);
15560 case OPC_CMP_LT_QH:
15562 gen_helper_cmp_lt_qh(v1_t, v2_t, cpu_env);
15564 case OPC_CMP_LE_QH:
15566 gen_helper_cmp_le_qh(v1_t, v2_t, cpu_env);
15568 case OPC_CMPGDU_EQ_OB:
15570 gen_helper_cmpgdu_eq_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15572 case OPC_CMPGDU_LT_OB:
15574 gen_helper_cmpgdu_lt_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15576 case OPC_CMPGDU_LE_OB:
15578 gen_helper_cmpgdu_le_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15580 case OPC_CMPGU_EQ_OB:
15582 gen_helper_cmpgu_eq_ob(cpu_gpr[ret], v1_t, v2_t);
15584 case OPC_CMPGU_LT_OB:
15586 gen_helper_cmpgu_lt_ob(cpu_gpr[ret], v1_t, v2_t);
15588 case OPC_CMPGU_LE_OB:
15590 gen_helper_cmpgu_le_ob(cpu_gpr[ret], v1_t, v2_t);
15592 case OPC_CMPU_EQ_OB:
15594 gen_helper_cmpu_eq_ob(v1_t, v2_t, cpu_env);
15596 case OPC_CMPU_LT_OB:
15598 gen_helper_cmpu_lt_ob(v1_t, v2_t, cpu_env);
15600 case OPC_CMPU_LE_OB:
15602 gen_helper_cmpu_le_ob(v1_t, v2_t, cpu_env);
15604 case OPC_PACKRL_PW:
15606 gen_helper_packrl_pw(cpu_gpr[ret], v1_t, v2_t);
15610 gen_helper_pick_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15614 gen_helper_pick_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15618 gen_helper_pick_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15626 tcg_temp_free(v1_t);
15627 tcg_temp_free(v2_t);
15629 (void)opn; /* avoid a compiler warning */
15630 MIPS_DEBUG("%s", opn);
15633 static void gen_mipsdsp_append(CPUMIPSState *env, DisasContext *ctx,
15634 uint32_t op1, int rt, int rs, int sa)
15636 const char *opn = "mipsdsp append/dappend";
15642 /* Treat as NOP. */
15647 t0 = tcg_temp_new();
15648 gen_load_gpr(t0, rs);
15651 case OPC_APPEND_DSP:
15652 switch (MASK_APPEND(ctx->opcode)) {
15655 tcg_gen_deposit_tl(cpu_gpr[rt], t0, cpu_gpr[rt], sa, 32 - sa);
15657 tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]);
15661 tcg_gen_ext32u_tl(cpu_gpr[rt], cpu_gpr[rt]);
15662 tcg_gen_shri_tl(cpu_gpr[rt], cpu_gpr[rt], sa);
15663 tcg_gen_shli_tl(t0, t0, 32 - sa);
15664 tcg_gen_or_tl(cpu_gpr[rt], cpu_gpr[rt], t0);
15666 tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]);
15670 if (sa != 0 && sa != 2) {
15671 tcg_gen_shli_tl(cpu_gpr[rt], cpu_gpr[rt], 8 * sa);
15672 tcg_gen_ext32u_tl(t0, t0);
15673 tcg_gen_shri_tl(t0, t0, 8 * (4 - sa));
15674 tcg_gen_or_tl(cpu_gpr[rt], cpu_gpr[rt], t0);
15676 tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]);
15678 default: /* Invalid */
15679 MIPS_INVAL("MASK APPEND");
15680 generate_exception(ctx, EXCP_RI);
15684 #ifdef TARGET_MIPS64
15685 case OPC_DAPPEND_DSP:
15686 switch (MASK_DAPPEND(ctx->opcode)) {
15689 tcg_gen_deposit_tl(cpu_gpr[rt], t0, cpu_gpr[rt], sa, 64 - sa);
15693 tcg_gen_shri_tl(cpu_gpr[rt], cpu_gpr[rt], 0x20 | sa);
15694 tcg_gen_shli_tl(t0, t0, 64 - (0x20 | sa));
15695 tcg_gen_or_tl(cpu_gpr[rt], t0, t0);
15699 tcg_gen_shri_tl(cpu_gpr[rt], cpu_gpr[rt], sa);
15700 tcg_gen_shli_tl(t0, t0, 64 - sa);
15701 tcg_gen_or_tl(cpu_gpr[rt], cpu_gpr[rt], t0);
15706 if (sa != 0 && sa != 2 && sa != 4) {
15707 tcg_gen_shli_tl(cpu_gpr[rt], cpu_gpr[rt], 8 * sa);
15708 tcg_gen_shri_tl(t0, t0, 8 * (8 - sa));
15709 tcg_gen_or_tl(cpu_gpr[rt], cpu_gpr[rt], t0);
15712 default: /* Invalid */
15713 MIPS_INVAL("MASK DAPPEND");
15714 generate_exception(ctx, EXCP_RI);
15721 (void)opn; /* avoid a compiler warning */
15722 MIPS_DEBUG("%s", opn);
15725 static void gen_mipsdsp_accinsn(DisasContext *ctx, uint32_t op1, uint32_t op2,
15726 int ret, int v1, int v2, int check_ret)
15729 const char *opn = "mipsdsp accumulator";
15736 if ((ret == 0) && (check_ret == 1)) {
15737 /* Treat as NOP. */
15742 t0 = tcg_temp_new();
15743 t1 = tcg_temp_new();
15744 v1_t = tcg_temp_new();
15745 v2_t = tcg_temp_new();
15747 gen_load_gpr(v1_t, v1);
15748 gen_load_gpr(v2_t, v2);
15751 case OPC_EXTR_W_DSP:
15755 tcg_gen_movi_tl(t0, v2);
15756 tcg_gen_movi_tl(t1, v1);
15757 gen_helper_extr_w(cpu_gpr[ret], t0, t1, cpu_env);
15760 tcg_gen_movi_tl(t0, v2);
15761 tcg_gen_movi_tl(t1, v1);
15762 gen_helper_extr_r_w(cpu_gpr[ret], t0, t1, cpu_env);
15764 case OPC_EXTR_RS_W:
15765 tcg_gen_movi_tl(t0, v2);
15766 tcg_gen_movi_tl(t1, v1);
15767 gen_helper_extr_rs_w(cpu_gpr[ret], t0, t1, cpu_env);
15770 tcg_gen_movi_tl(t0, v2);
15771 tcg_gen_movi_tl(t1, v1);
15772 gen_helper_extr_s_h(cpu_gpr[ret], t0, t1, cpu_env);
15774 case OPC_EXTRV_S_H:
15775 tcg_gen_movi_tl(t0, v2);
15776 gen_helper_extr_s_h(cpu_gpr[ret], t0, v1_t, cpu_env);
15779 tcg_gen_movi_tl(t0, v2);
15780 gen_helper_extr_w(cpu_gpr[ret], t0, v1_t, cpu_env);
15782 case OPC_EXTRV_R_W:
15783 tcg_gen_movi_tl(t0, v2);
15784 gen_helper_extr_r_w(cpu_gpr[ret], t0, v1_t, cpu_env);
15786 case OPC_EXTRV_RS_W:
15787 tcg_gen_movi_tl(t0, v2);
15788 gen_helper_extr_rs_w(cpu_gpr[ret], t0, v1_t, cpu_env);
15791 tcg_gen_movi_tl(t0, v2);
15792 tcg_gen_movi_tl(t1, v1);
15793 gen_helper_extp(cpu_gpr[ret], t0, t1, cpu_env);
15796 tcg_gen_movi_tl(t0, v2);
15797 gen_helper_extp(cpu_gpr[ret], t0, v1_t, cpu_env);
15800 tcg_gen_movi_tl(t0, v2);
15801 tcg_gen_movi_tl(t1, v1);
15802 gen_helper_extpdp(cpu_gpr[ret], t0, t1, cpu_env);
15805 tcg_gen_movi_tl(t0, v2);
15806 gen_helper_extpdp(cpu_gpr[ret], t0, v1_t, cpu_env);
15809 imm = (ctx->opcode >> 20) & 0x3F;
15810 tcg_gen_movi_tl(t0, ret);
15811 tcg_gen_movi_tl(t1, imm);
15812 gen_helper_shilo(t0, t1, cpu_env);
15815 tcg_gen_movi_tl(t0, ret);
15816 gen_helper_shilo(t0, v1_t, cpu_env);
15819 tcg_gen_movi_tl(t0, ret);
15820 gen_helper_mthlip(t0, v1_t, cpu_env);
15823 imm = (ctx->opcode >> 11) & 0x3FF;
15824 tcg_gen_movi_tl(t0, imm);
15825 gen_helper_wrdsp(v1_t, t0, cpu_env);
15828 imm = (ctx->opcode >> 16) & 0x03FF;
15829 tcg_gen_movi_tl(t0, imm);
15830 gen_helper_rddsp(cpu_gpr[ret], t0, cpu_env);
15834 #ifdef TARGET_MIPS64
15835 case OPC_DEXTR_W_DSP:
15839 tcg_gen_movi_tl(t0, ret);
15840 gen_helper_dmthlip(v1_t, t0, cpu_env);
15844 int shift = (ctx->opcode >> 19) & 0x7F;
15845 int ac = (ctx->opcode >> 11) & 0x03;
15846 tcg_gen_movi_tl(t0, shift);
15847 tcg_gen_movi_tl(t1, ac);
15848 gen_helper_dshilo(t0, t1, cpu_env);
15853 int ac = (ctx->opcode >> 11) & 0x03;
15854 tcg_gen_movi_tl(t0, ac);
15855 gen_helper_dshilo(v1_t, t0, cpu_env);
15859 tcg_gen_movi_tl(t0, v2);
15860 tcg_gen_movi_tl(t1, v1);
15862 gen_helper_dextp(cpu_gpr[ret], t0, t1, cpu_env);
15865 tcg_gen_movi_tl(t0, v2);
15866 gen_helper_dextp(cpu_gpr[ret], t0, v1_t, cpu_env);
15869 tcg_gen_movi_tl(t0, v2);
15870 tcg_gen_movi_tl(t1, v1);
15871 gen_helper_dextpdp(cpu_gpr[ret], t0, t1, cpu_env);
15874 tcg_gen_movi_tl(t0, v2);
15875 gen_helper_dextpdp(cpu_gpr[ret], t0, v1_t, cpu_env);
15878 tcg_gen_movi_tl(t0, v2);
15879 tcg_gen_movi_tl(t1, v1);
15880 gen_helper_dextr_l(cpu_gpr[ret], t0, t1, cpu_env);
15882 case OPC_DEXTR_R_L:
15883 tcg_gen_movi_tl(t0, v2);
15884 tcg_gen_movi_tl(t1, v1);
15885 gen_helper_dextr_r_l(cpu_gpr[ret], t0, t1, cpu_env);
15887 case OPC_DEXTR_RS_L:
15888 tcg_gen_movi_tl(t0, v2);
15889 tcg_gen_movi_tl(t1, v1);
15890 gen_helper_dextr_rs_l(cpu_gpr[ret], t0, t1, cpu_env);
15893 tcg_gen_movi_tl(t0, v2);
15894 tcg_gen_movi_tl(t1, v1);
15895 gen_helper_dextr_w(cpu_gpr[ret], t0, t1, cpu_env);
15897 case OPC_DEXTR_R_W:
15898 tcg_gen_movi_tl(t0, v2);
15899 tcg_gen_movi_tl(t1, v1);
15900 gen_helper_dextr_r_w(cpu_gpr[ret], t0, t1, cpu_env);
15902 case OPC_DEXTR_RS_W:
15903 tcg_gen_movi_tl(t0, v2);
15904 tcg_gen_movi_tl(t1, v1);
15905 gen_helper_dextr_rs_w(cpu_gpr[ret], t0, t1, cpu_env);
15907 case OPC_DEXTR_S_H:
15908 tcg_gen_movi_tl(t0, v2);
15909 tcg_gen_movi_tl(t1, v1);
15910 gen_helper_dextr_s_h(cpu_gpr[ret], t0, t1, cpu_env);
15912 case OPC_DEXTRV_S_H:
15913 tcg_gen_movi_tl(t0, v2);
15914 tcg_gen_movi_tl(t1, v1);
15915 gen_helper_dextr_s_h(cpu_gpr[ret], t0, t1, cpu_env);
15918 tcg_gen_movi_tl(t0, v2);
15919 gen_helper_dextr_l(cpu_gpr[ret], t0, v1_t, cpu_env);
15921 case OPC_DEXTRV_R_L:
15922 tcg_gen_movi_tl(t0, v2);
15923 gen_helper_dextr_r_l(cpu_gpr[ret], t0, v1_t, cpu_env);
15925 case OPC_DEXTRV_RS_L:
15926 tcg_gen_movi_tl(t0, v2);
15927 gen_helper_dextr_rs_l(cpu_gpr[ret], t0, v1_t, cpu_env);
15930 tcg_gen_movi_tl(t0, v2);
15931 gen_helper_dextr_w(cpu_gpr[ret], t0, v1_t, cpu_env);
15933 case OPC_DEXTRV_R_W:
15934 tcg_gen_movi_tl(t0, v2);
15935 gen_helper_dextr_r_w(cpu_gpr[ret], t0, v1_t, cpu_env);
15937 case OPC_DEXTRV_RS_W:
15938 tcg_gen_movi_tl(t0, v2);
15939 gen_helper_dextr_rs_w(cpu_gpr[ret], t0, v1_t, cpu_env);
15948 tcg_temp_free(v1_t);
15949 tcg_temp_free(v2_t);
15951 (void)opn; /* avoid a compiler warning */
15952 MIPS_DEBUG("%s", opn);
15955 /* End MIPSDSP functions. */
15957 /* Compact Branches */
15958 static void gen_compute_compact_branch(DisasContext *ctx, uint32_t opc,
15959 int rs, int rt, int32_t offset)
15961 int bcond_compute = 0;
15962 TCGv t0 = tcg_temp_new();
15963 TCGv t1 = tcg_temp_new();
15965 if (ctx->hflags & MIPS_HFLAG_BMASK) {
15966 #ifdef MIPS_DEBUG_DISAS
15967 LOG_DISAS("Branch in delay / forbidden slot at PC 0x" TARGET_FMT_lx
15970 generate_exception(ctx, EXCP_RI);
15974 /* Load needed operands and calculate btarget */
15976 /* compact branch */
15977 case OPC_BOVC: /* OPC_BEQZALC, OPC_BEQC */
15978 case OPC_BNVC: /* OPC_BNEZALC, OPC_BNEC */
15979 gen_load_gpr(t0, rs);
15980 gen_load_gpr(t1, rt);
15982 ctx->btarget = addr_add(ctx, ctx->pc + 4, offset);
15983 if (rs <= rt && rs == 0) {
15984 /* OPC_BEQZALC, OPC_BNEZALC */
15985 tcg_gen_movi_tl(cpu_gpr[31], ctx->pc + 4);
15988 case OPC_BLEZC: /* OPC_BGEZC, OPC_BGEC */
15989 case OPC_BGTZC: /* OPC_BLTZC, OPC_BLTC */
15990 gen_load_gpr(t0, rs);
15991 gen_load_gpr(t1, rt);
15993 ctx->btarget = addr_add(ctx, ctx->pc + 4, offset);
15995 case OPC_BLEZALC: /* OPC_BGEZALC, OPC_BGEUC */
15996 case OPC_BGTZALC: /* OPC_BLTZALC, OPC_BLTUC */
15997 if (rs == 0 || rs == rt) {
15998 /* OPC_BLEZALC, OPC_BGEZALC */
15999 /* OPC_BGTZALC, OPC_BLTZALC */
16000 tcg_gen_movi_tl(cpu_gpr[31], ctx->pc + 4);
16002 gen_load_gpr(t0, rs);
16003 gen_load_gpr(t1, rt);
16005 ctx->btarget = addr_add(ctx, ctx->pc + 4, offset);
16009 ctx->btarget = addr_add(ctx, ctx->pc + 4, offset);
16014 /* OPC_BEQZC, OPC_BNEZC */
16015 gen_load_gpr(t0, rs);
16017 ctx->btarget = addr_add(ctx, ctx->pc + 4, offset);
16019 /* OPC_JIC, OPC_JIALC */
16020 TCGv tbase = tcg_temp_new();
16021 TCGv toffset = tcg_temp_new();
16023 gen_load_gpr(tbase, rt);
16024 tcg_gen_movi_tl(toffset, offset);
16025 gen_op_addr_add(ctx, btarget, tbase, toffset);
16026 tcg_temp_free(tbase);
16027 tcg_temp_free(toffset);
16031 MIPS_INVAL("Compact branch/jump");
16032 generate_exception(ctx, EXCP_RI);
16036 if (bcond_compute == 0) {
16037 /* Uncoditional compact branch */
16040 tcg_gen_movi_tl(cpu_gpr[31], ctx->pc + 4);
16043 ctx->hflags |= MIPS_HFLAG_BR;
16046 tcg_gen_movi_tl(cpu_gpr[31], ctx->pc + 4);
16049 ctx->hflags |= MIPS_HFLAG_B;
16052 MIPS_INVAL("Compact branch/jump");
16053 generate_exception(ctx, EXCP_RI);
16057 /* Generating branch here as compact branches don't have delay slot */
16058 gen_branch(ctx, 4);
16060 /* Conditional compact branch */
16061 TCGLabel *fs = gen_new_label();
16062 save_cpu_state(ctx, 0);
16065 case OPC_BLEZALC: /* OPC_BGEZALC, OPC_BGEUC */
16066 if (rs == 0 && rt != 0) {
16068 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LE), t1, 0, fs);
16069 } else if (rs != 0 && rt != 0 && rs == rt) {
16071 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GE), t1, 0, fs);
16074 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_GEU), t0, t1, fs);
16077 case OPC_BGTZALC: /* OPC_BLTZALC, OPC_BLTUC */
16078 if (rs == 0 && rt != 0) {
16080 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GT), t1, 0, fs);
16081 } else if (rs != 0 && rt != 0 && rs == rt) {
16083 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LT), t1, 0, fs);
16086 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_LTU), t0, t1, fs);
16089 case OPC_BLEZC: /* OPC_BGEZC, OPC_BGEC */
16090 if (rs == 0 && rt != 0) {
16092 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LE), t1, 0, fs);
16093 } else if (rs != 0 && rt != 0 && rs == rt) {
16095 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GE), t1, 0, fs);
16098 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_GE), t0, t1, fs);
16101 case OPC_BGTZC: /* OPC_BLTZC, OPC_BLTC */
16102 if (rs == 0 && rt != 0) {
16104 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GT), t1, 0, fs);
16105 } else if (rs != 0 && rt != 0 && rs == rt) {
16107 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LT), t1, 0, fs);
16110 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_LT), t0, t1, fs);
16113 case OPC_BOVC: /* OPC_BEQZALC, OPC_BEQC */
16114 case OPC_BNVC: /* OPC_BNEZALC, OPC_BNEC */
16116 /* OPC_BOVC, OPC_BNVC */
16117 TCGv t2 = tcg_temp_new();
16118 TCGv t3 = tcg_temp_new();
16119 TCGv t4 = tcg_temp_new();
16120 TCGv input_overflow = tcg_temp_new();
16122 gen_load_gpr(t0, rs);
16123 gen_load_gpr(t1, rt);
16124 tcg_gen_ext32s_tl(t2, t0);
16125 tcg_gen_setcond_tl(TCG_COND_NE, input_overflow, t2, t0);
16126 tcg_gen_ext32s_tl(t3, t1);
16127 tcg_gen_setcond_tl(TCG_COND_NE, t4, t3, t1);
16128 tcg_gen_or_tl(input_overflow, input_overflow, t4);
16130 tcg_gen_add_tl(t4, t2, t3);
16131 tcg_gen_ext32s_tl(t4, t4);
16132 tcg_gen_xor_tl(t2, t2, t3);
16133 tcg_gen_xor_tl(t3, t4, t3);
16134 tcg_gen_andc_tl(t2, t3, t2);
16135 tcg_gen_setcondi_tl(TCG_COND_LT, t4, t2, 0);
16136 tcg_gen_or_tl(t4, t4, input_overflow);
16137 if (opc == OPC_BOVC) {
16139 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_NE), t4, 0, fs);
16142 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_EQ), t4, 0, fs);
16144 tcg_temp_free(input_overflow);
16148 } else if (rs < rt && rs == 0) {
16149 /* OPC_BEQZALC, OPC_BNEZALC */
16150 if (opc == OPC_BEQZALC) {
16152 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_EQ), t1, 0, fs);
16155 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_NE), t1, 0, fs);
16158 /* OPC_BEQC, OPC_BNEC */
16159 if (opc == OPC_BEQC) {
16161 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_EQ), t0, t1, fs);
16164 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_NE), t0, t1, fs);
16169 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_EQ), t0, 0, fs);
16172 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_NE), t0, 0, fs);
16175 MIPS_INVAL("Compact conditional branch/jump");
16176 generate_exception(ctx, EXCP_RI);
16180 /* Generating branch here as compact branches don't have delay slot */
16181 gen_goto_tb(ctx, 1, ctx->btarget);
16184 ctx->hflags |= MIPS_HFLAG_FBNSLOT;
16185 MIPS_DEBUG("Compact conditional branch");
16193 static void decode_opc_special_r6(CPUMIPSState *env, DisasContext *ctx)
16195 int rs, rt, rd, sa;
16198 rs = (ctx->opcode >> 21) & 0x1f;
16199 rt = (ctx->opcode >> 16) & 0x1f;
16200 rd = (ctx->opcode >> 11) & 0x1f;
16201 sa = (ctx->opcode >> 6) & 0x1f;
16203 op1 = MASK_SPECIAL(ctx->opcode);
16207 int imm2 = extract32(ctx->opcode, 6, 3);
16208 TCGv t0 = tcg_temp_new();
16209 TCGv t1 = tcg_temp_new();
16210 gen_load_gpr(t0, rs);
16211 gen_load_gpr(t1, rt);
16212 tcg_gen_shli_tl(t0, t0, imm2 + 1);
16213 tcg_gen_add_tl(t0, t0, t1);
16214 tcg_gen_ext32s_tl(cpu_gpr[rd], t0);
16219 case OPC_MULT ... OPC_DIVU:
16220 op2 = MASK_R6_MULDIV(ctx->opcode);
16230 gen_r6_muldiv(ctx, op2, rd, rs, rt);
16233 MIPS_INVAL("special_r6 muldiv");
16234 generate_exception(ctx, EXCP_RI);
16240 gen_cond_move(ctx, op1, rd, rs, rt);
16244 if (rt == 0 && sa == 1) {
16245 /* Major opcode and function field is shared with preR6 MFHI/MTHI.
16246 We need additionally to check other fields */
16247 gen_cl(ctx, op1, rd, rs);
16249 generate_exception(ctx, EXCP_RI);
16253 if (ctx->hflags & MIPS_HFLAG_SBRI) {
16254 generate_exception(ctx, EXCP_RI);
16256 generate_exception(ctx, EXCP_DBp);
16259 #if defined(TARGET_MIPS64)
16261 check_mips_64(ctx);
16263 int imm2 = extract32(ctx->opcode, 6, 3);
16264 TCGv t0 = tcg_temp_new();
16265 TCGv t1 = tcg_temp_new();
16266 gen_load_gpr(t0, rs);
16267 gen_load_gpr(t1, rt);
16268 tcg_gen_shli_tl(t0, t0, imm2 + 1);
16269 tcg_gen_add_tl(cpu_gpr[rd], t0, t1);
16276 if (rt == 0 && sa == 1) {
16277 /* Major opcode and function field is shared with preR6 MFHI/MTHI.
16278 We need additionally to check other fields */
16279 check_mips_64(ctx);
16280 gen_cl(ctx, op1, rd, rs);
16282 generate_exception(ctx, EXCP_RI);
16285 case OPC_DMULT ... OPC_DDIVU:
16286 op2 = MASK_R6_MULDIV(ctx->opcode);
16296 check_mips_64(ctx);
16297 gen_r6_muldiv(ctx, op2, rd, rs, rt);
16300 MIPS_INVAL("special_r6 muldiv");
16301 generate_exception(ctx, EXCP_RI);
16306 default: /* Invalid */
16307 MIPS_INVAL("special_r6");
16308 generate_exception(ctx, EXCP_RI);
16313 static void decode_opc_special_legacy(CPUMIPSState *env, DisasContext *ctx)
16315 int rs, rt, rd, sa;
16318 rs = (ctx->opcode >> 21) & 0x1f;
16319 rt = (ctx->opcode >> 16) & 0x1f;
16320 rd = (ctx->opcode >> 11) & 0x1f;
16321 sa = (ctx->opcode >> 6) & 0x1f;
16323 op1 = MASK_SPECIAL(ctx->opcode);
16325 case OPC_MOVN: /* Conditional move */
16327 check_insn(ctx, ISA_MIPS4 | ISA_MIPS32 |
16328 INSN_LOONGSON2E | INSN_LOONGSON2F);
16329 gen_cond_move(ctx, op1, rd, rs, rt);
16331 case OPC_MFHI: /* Move from HI/LO */
16333 gen_HILO(ctx, op1, rs & 3, rd);
16336 case OPC_MTLO: /* Move to HI/LO */
16337 gen_HILO(ctx, op1, rd & 3, rs);
16340 check_insn(ctx, ISA_MIPS4 | ISA_MIPS32);
16341 if (env->CP0_Config1 & (1 << CP0C1_FP)) {
16342 check_cp1_enabled(ctx);
16343 gen_movci(ctx, rd, rs, (ctx->opcode >> 18) & 0x7,
16344 (ctx->opcode >> 16) & 1);
16346 generate_exception_err(ctx, EXCP_CpU, 1);
16352 check_insn(ctx, INSN_VR54XX);
16353 op1 = MASK_MUL_VR54XX(ctx->opcode);
16354 gen_mul_vr54xx(ctx, op1, rd, rs, rt);
16356 gen_muldiv(ctx, op1, rd & 3, rs, rt);
16361 gen_muldiv(ctx, op1, 0, rs, rt);
16363 #if defined(TARGET_MIPS64)
16364 case OPC_DMULT ... OPC_DDIVU:
16365 check_insn(ctx, ISA_MIPS3);
16366 check_mips_64(ctx);
16367 gen_muldiv(ctx, op1, 0, rs, rt);
16371 gen_compute_branch(ctx, op1, 4, rs, rd, sa, 4);
16374 #ifdef MIPS_STRICT_STANDARD
16375 MIPS_INVAL("SPIM");
16376 generate_exception(ctx, EXCP_RI);
16378 /* Implemented as RI exception for now. */
16379 MIPS_INVAL("spim (unofficial)");
16380 generate_exception(ctx, EXCP_RI);
16383 default: /* Invalid */
16384 MIPS_INVAL("special_legacy");
16385 generate_exception(ctx, EXCP_RI);
16390 static void decode_opc_special(CPUMIPSState *env, DisasContext *ctx)
16392 int rs, rt, rd, sa;
16395 rs = (ctx->opcode >> 21) & 0x1f;
16396 rt = (ctx->opcode >> 16) & 0x1f;
16397 rd = (ctx->opcode >> 11) & 0x1f;
16398 sa = (ctx->opcode >> 6) & 0x1f;
16400 op1 = MASK_SPECIAL(ctx->opcode);
16402 case OPC_SLL: /* Shift with immediate */
16403 if (sa == 5 && rd == 0 &&
16404 rs == 0 && rt == 0) { /* PAUSE */
16405 if ((ctx->insn_flags & ISA_MIPS32R6) &&
16406 (ctx->hflags & MIPS_HFLAG_BMASK)) {
16407 MIPS_DEBUG("CTI in delay / forbidden slot");
16408 generate_exception(ctx, EXCP_RI);
16414 gen_shift_imm(ctx, op1, rd, rt, sa);
16417 switch ((ctx->opcode >> 21) & 0x1f) {
16419 /* rotr is decoded as srl on non-R2 CPUs */
16420 if (ctx->insn_flags & ISA_MIPS32R2) {
16425 gen_shift_imm(ctx, op1, rd, rt, sa);
16428 generate_exception(ctx, EXCP_RI);
16432 case OPC_ADD ... OPC_SUBU:
16433 gen_arith(ctx, op1, rd, rs, rt);
16435 case OPC_SLLV: /* Shifts */
16437 gen_shift(ctx, op1, rd, rs, rt);
16440 switch ((ctx->opcode >> 6) & 0x1f) {
16442 /* rotrv is decoded as srlv on non-R2 CPUs */
16443 if (ctx->insn_flags & ISA_MIPS32R2) {
16448 gen_shift(ctx, op1, rd, rs, rt);
16451 generate_exception(ctx, EXCP_RI);
16455 case OPC_SLT: /* Set on less than */
16457 gen_slt(ctx, op1, rd, rs, rt);
16459 case OPC_AND: /* Logic*/
16463 gen_logic(ctx, op1, rd, rs, rt);
16466 gen_compute_branch(ctx, op1, 4, rs, rd, sa, 4);
16468 case OPC_TGE ... OPC_TEQ: /* Traps */
16470 check_insn(ctx, ISA_MIPS2);
16471 gen_trap(ctx, op1, rs, rt, -1);
16473 case OPC_LSA: /* OPC_PMON */
16474 if ((ctx->insn_flags & ISA_MIPS32R6) ||
16475 (env->CP0_Config3 & (1 << CP0C3_MSAP))) {
16476 decode_opc_special_r6(env, ctx);
16478 /* Pmon entry point, also R4010 selsl */
16479 #ifdef MIPS_STRICT_STANDARD
16480 MIPS_INVAL("PMON / selsl");
16481 generate_exception(ctx, EXCP_RI);
16483 gen_helper_0e0i(pmon, sa);
16488 generate_exception(ctx, EXCP_SYSCALL);
16489 ctx->bstate = BS_STOP;
16492 generate_exception(ctx, EXCP_BREAK);
16495 check_insn(ctx, ISA_MIPS2);
16496 /* Treat as NOP. */
16499 #if defined(TARGET_MIPS64)
16500 /* MIPS64 specific opcodes */
16505 check_insn(ctx, ISA_MIPS3);
16506 check_mips_64(ctx);
16507 gen_shift_imm(ctx, op1, rd, rt, sa);
16510 switch ((ctx->opcode >> 21) & 0x1f) {
16512 /* drotr is decoded as dsrl on non-R2 CPUs */
16513 if (ctx->insn_flags & ISA_MIPS32R2) {
16518 check_insn(ctx, ISA_MIPS3);
16519 check_mips_64(ctx);
16520 gen_shift_imm(ctx, op1, rd, rt, sa);
16523 generate_exception(ctx, EXCP_RI);
16528 switch ((ctx->opcode >> 21) & 0x1f) {
16530 /* drotr32 is decoded as dsrl32 on non-R2 CPUs */
16531 if (ctx->insn_flags & ISA_MIPS32R2) {
16536 check_insn(ctx, ISA_MIPS3);
16537 check_mips_64(ctx);
16538 gen_shift_imm(ctx, op1, rd, rt, sa);
16541 generate_exception(ctx, EXCP_RI);
16545 case OPC_DADD ... OPC_DSUBU:
16546 check_insn(ctx, ISA_MIPS3);
16547 check_mips_64(ctx);
16548 gen_arith(ctx, op1, rd, rs, rt);
16552 check_insn(ctx, ISA_MIPS3);
16553 check_mips_64(ctx);
16554 gen_shift(ctx, op1, rd, rs, rt);
16557 switch ((ctx->opcode >> 6) & 0x1f) {
16559 /* drotrv is decoded as dsrlv on non-R2 CPUs */
16560 if (ctx->insn_flags & ISA_MIPS32R2) {
16565 check_insn(ctx, ISA_MIPS3);
16566 check_mips_64(ctx);
16567 gen_shift(ctx, op1, rd, rs, rt);
16570 generate_exception(ctx, EXCP_RI);
16575 if ((ctx->insn_flags & ISA_MIPS32R6) ||
16576 (env->CP0_Config3 & (1 << CP0C3_MSAP))) {
16577 decode_opc_special_r6(env, ctx);
16582 if (ctx->insn_flags & ISA_MIPS32R6) {
16583 decode_opc_special_r6(env, ctx);
16585 decode_opc_special_legacy(env, ctx);
16590 static void decode_opc_special2_legacy(CPUMIPSState *env, DisasContext *ctx)
16595 check_insn_opc_removed(ctx, ISA_MIPS32R6);
16597 rs = (ctx->opcode >> 21) & 0x1f;
16598 rt = (ctx->opcode >> 16) & 0x1f;
16599 rd = (ctx->opcode >> 11) & 0x1f;
16601 op1 = MASK_SPECIAL2(ctx->opcode);
16603 case OPC_MADD ... OPC_MADDU: /* Multiply and add/sub */
16604 case OPC_MSUB ... OPC_MSUBU:
16605 check_insn(ctx, ISA_MIPS32);
16606 gen_muldiv(ctx, op1, rd & 3, rs, rt);
16609 gen_arith(ctx, op1, rd, rs, rt);
16612 case OPC_DIVU_G_2F:
16613 case OPC_MULT_G_2F:
16614 case OPC_MULTU_G_2F:
16616 case OPC_MODU_G_2F:
16617 check_insn(ctx, INSN_LOONGSON2F);
16618 gen_loongson_integer(ctx, op1, rd, rs, rt);
16622 check_insn(ctx, ISA_MIPS32);
16623 gen_cl(ctx, op1, rd, rs);
16626 /* XXX: not clear which exception should be raised
16627 * when in debug mode...
16629 check_insn(ctx, ISA_MIPS32);
16630 if (!(ctx->hflags & MIPS_HFLAG_DM)) {
16631 generate_exception(ctx, EXCP_DBp);
16633 generate_exception(ctx, EXCP_DBp);
16635 /* Treat as NOP. */
16637 #if defined(TARGET_MIPS64)
16640 check_insn(ctx, ISA_MIPS64);
16641 check_mips_64(ctx);
16642 gen_cl(ctx, op1, rd, rs);
16644 case OPC_DMULT_G_2F:
16645 case OPC_DMULTU_G_2F:
16646 case OPC_DDIV_G_2F:
16647 case OPC_DDIVU_G_2F:
16648 case OPC_DMOD_G_2F:
16649 case OPC_DMODU_G_2F:
16650 check_insn(ctx, INSN_LOONGSON2F);
16651 gen_loongson_integer(ctx, op1, rd, rs, rt);
16654 default: /* Invalid */
16655 MIPS_INVAL("special2_legacy");
16656 generate_exception(ctx, EXCP_RI);
16661 static void decode_opc_special3_r6(CPUMIPSState *env, DisasContext *ctx)
16663 int rs, rt, rd, sa;
16667 rs = (ctx->opcode >> 21) & 0x1f;
16668 rt = (ctx->opcode >> 16) & 0x1f;
16669 rd = (ctx->opcode >> 11) & 0x1f;
16670 sa = (ctx->opcode >> 6) & 0x1f;
16671 imm = (int16_t)ctx->opcode >> 7;
16673 op1 = MASK_SPECIAL3(ctx->opcode);
16677 /* hint codes 24-31 are reserved and signal RI */
16678 generate_exception(ctx, EXCP_RI);
16680 /* Treat as NOP. */
16683 /* Treat as NOP. */
16686 gen_st_cond(ctx, op1, rt, rs, imm);
16689 gen_ld(ctx, op1, rt, rs, imm);
16694 /* Treat as NOP. */
16697 TCGv t0 = tcg_temp_new();
16698 gen_load_gpr(t0, rt);
16700 op2 = MASK_BSHFL(ctx->opcode);
16702 case OPC_ALIGN ... OPC_ALIGN_END:
16705 tcg_gen_mov_tl(cpu_gpr[rd], t0);
16707 TCGv t1 = tcg_temp_new();
16708 TCGv_i64 t2 = tcg_temp_new_i64();
16709 gen_load_gpr(t1, rs);
16710 tcg_gen_concat_tl_i64(t2, t1, t0);
16711 tcg_gen_shri_i64(t2, t2, 8 * (4 - sa));
16712 #if defined(TARGET_MIPS64)
16713 tcg_gen_ext32s_i64(cpu_gpr[rd], t2);
16715 tcg_gen_trunc_i64_i32(cpu_gpr[rd], t2);
16717 tcg_temp_free_i64(t2);
16722 gen_helper_bitswap(cpu_gpr[rd], t0);
16728 #if defined(TARGET_MIPS64)
16730 gen_st_cond(ctx, op1, rt, rs, imm);
16733 gen_ld(ctx, op1, rt, rs, imm);
16736 check_mips_64(ctx);
16739 /* Treat as NOP. */
16742 TCGv t0 = tcg_temp_new();
16743 gen_load_gpr(t0, rt);
16745 op2 = MASK_DBSHFL(ctx->opcode);
16747 case OPC_DALIGN ... OPC_DALIGN_END:
16750 tcg_gen_mov_tl(cpu_gpr[rd], t0);
16752 TCGv t1 = tcg_temp_new();
16753 gen_load_gpr(t1, rs);
16754 tcg_gen_shli_tl(t0, t0, 8 * sa);
16755 tcg_gen_shri_tl(t1, t1, 8 * (8 - sa));
16756 tcg_gen_or_tl(cpu_gpr[rd], t1, t0);
16761 gen_helper_dbitswap(cpu_gpr[rd], t0);
16768 default: /* Invalid */
16769 MIPS_INVAL("special3_r6");
16770 generate_exception(ctx, EXCP_RI);
16775 static void decode_opc_special3_legacy(CPUMIPSState *env, DisasContext *ctx)
16780 rs = (ctx->opcode >> 21) & 0x1f;
16781 rt = (ctx->opcode >> 16) & 0x1f;
16782 rd = (ctx->opcode >> 11) & 0x1f;
16784 op1 = MASK_SPECIAL3(ctx->opcode);
16786 case OPC_DIV_G_2E ... OPC_DIVU_G_2E:
16787 case OPC_MOD_G_2E ... OPC_MODU_G_2E:
16788 case OPC_MULT_G_2E ... OPC_MULTU_G_2E:
16789 /* OPC_MULT_G_2E, OPC_ADDUH_QB_DSP, OPC_MUL_PH_DSP have
16790 * the same mask and op1. */
16791 if ((ctx->insn_flags & ASE_DSPR2) && (op1 == OPC_MULT_G_2E)) {
16792 op2 = MASK_ADDUH_QB(ctx->opcode);
16795 case OPC_ADDUH_R_QB:
16797 case OPC_ADDQH_R_PH:
16799 case OPC_ADDQH_R_W:
16801 case OPC_SUBUH_R_QB:
16803 case OPC_SUBQH_R_PH:
16805 case OPC_SUBQH_R_W:
16806 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
16811 case OPC_MULQ_RS_W:
16812 gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 1);
16815 MIPS_INVAL("MASK ADDUH.QB");
16816 generate_exception(ctx, EXCP_RI);
16819 } else if (ctx->insn_flags & INSN_LOONGSON2E) {
16820 gen_loongson_integer(ctx, op1, rd, rs, rt);
16822 generate_exception(ctx, EXCP_RI);
16826 op2 = MASK_LX(ctx->opcode);
16828 #if defined(TARGET_MIPS64)
16834 gen_mipsdsp_ld(ctx, op2, rd, rs, rt);
16836 default: /* Invalid */
16837 MIPS_INVAL("MASK LX");
16838 generate_exception(ctx, EXCP_RI);
16842 case OPC_ABSQ_S_PH_DSP:
16843 op2 = MASK_ABSQ_S_PH(ctx->opcode);
16845 case OPC_ABSQ_S_QB:
16846 case OPC_ABSQ_S_PH:
16848 case OPC_PRECEQ_W_PHL:
16849 case OPC_PRECEQ_W_PHR:
16850 case OPC_PRECEQU_PH_QBL:
16851 case OPC_PRECEQU_PH_QBR:
16852 case OPC_PRECEQU_PH_QBLA:
16853 case OPC_PRECEQU_PH_QBRA:
16854 case OPC_PRECEU_PH_QBL:
16855 case OPC_PRECEU_PH_QBR:
16856 case OPC_PRECEU_PH_QBLA:
16857 case OPC_PRECEU_PH_QBRA:
16858 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
16865 gen_mipsdsp_bitinsn(ctx, op1, op2, rd, rt);
16868 MIPS_INVAL("MASK ABSQ_S.PH");
16869 generate_exception(ctx, EXCP_RI);
16873 case OPC_ADDU_QB_DSP:
16874 op2 = MASK_ADDU_QB(ctx->opcode);
16877 case OPC_ADDQ_S_PH:
16880 case OPC_ADDU_S_QB:
16882 case OPC_ADDU_S_PH:
16884 case OPC_SUBQ_S_PH:
16887 case OPC_SUBU_S_QB:
16889 case OPC_SUBU_S_PH:
16893 case OPC_RADDU_W_QB:
16894 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
16896 case OPC_MULEU_S_PH_QBL:
16897 case OPC_MULEU_S_PH_QBR:
16898 case OPC_MULQ_RS_PH:
16899 case OPC_MULEQ_S_W_PHL:
16900 case OPC_MULEQ_S_W_PHR:
16901 case OPC_MULQ_S_PH:
16902 gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 1);
16904 default: /* Invalid */
16905 MIPS_INVAL("MASK ADDU.QB");
16906 generate_exception(ctx, EXCP_RI);
16911 case OPC_CMPU_EQ_QB_DSP:
16912 op2 = MASK_CMPU_EQ_QB(ctx->opcode);
16914 case OPC_PRECR_SRA_PH_W:
16915 case OPC_PRECR_SRA_R_PH_W:
16916 gen_mipsdsp_arith(ctx, op1, op2, rt, rs, rd);
16918 case OPC_PRECR_QB_PH:
16919 case OPC_PRECRQ_QB_PH:
16920 case OPC_PRECRQ_PH_W:
16921 case OPC_PRECRQ_RS_PH_W:
16922 case OPC_PRECRQU_S_QB_PH:
16923 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
16925 case OPC_CMPU_EQ_QB:
16926 case OPC_CMPU_LT_QB:
16927 case OPC_CMPU_LE_QB:
16928 case OPC_CMP_EQ_PH:
16929 case OPC_CMP_LT_PH:
16930 case OPC_CMP_LE_PH:
16931 gen_mipsdsp_add_cmp_pick(ctx, op1, op2, rd, rs, rt, 0);
16933 case OPC_CMPGU_EQ_QB:
16934 case OPC_CMPGU_LT_QB:
16935 case OPC_CMPGU_LE_QB:
16936 case OPC_CMPGDU_EQ_QB:
16937 case OPC_CMPGDU_LT_QB:
16938 case OPC_CMPGDU_LE_QB:
16941 case OPC_PACKRL_PH:
16942 gen_mipsdsp_add_cmp_pick(ctx, op1, op2, rd, rs, rt, 1);
16944 default: /* Invalid */
16945 MIPS_INVAL("MASK CMPU.EQ.QB");
16946 generate_exception(ctx, EXCP_RI);
16950 case OPC_SHLL_QB_DSP:
16951 gen_mipsdsp_shift(ctx, op1, rd, rs, rt);
16953 case OPC_DPA_W_PH_DSP:
16954 op2 = MASK_DPA_W_PH(ctx->opcode);
16956 case OPC_DPAU_H_QBL:
16957 case OPC_DPAU_H_QBR:
16958 case OPC_DPSU_H_QBL:
16959 case OPC_DPSU_H_QBR:
16961 case OPC_DPAX_W_PH:
16962 case OPC_DPAQ_S_W_PH:
16963 case OPC_DPAQX_S_W_PH:
16964 case OPC_DPAQX_SA_W_PH:
16966 case OPC_DPSX_W_PH:
16967 case OPC_DPSQ_S_W_PH:
16968 case OPC_DPSQX_S_W_PH:
16969 case OPC_DPSQX_SA_W_PH:
16970 case OPC_MULSAQ_S_W_PH:
16971 case OPC_DPAQ_SA_L_W:
16972 case OPC_DPSQ_SA_L_W:
16973 case OPC_MAQ_S_W_PHL:
16974 case OPC_MAQ_S_W_PHR:
16975 case OPC_MAQ_SA_W_PHL:
16976 case OPC_MAQ_SA_W_PHR:
16977 case OPC_MULSA_W_PH:
16978 gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 0);
16980 default: /* Invalid */
16981 MIPS_INVAL("MASK DPAW.PH");
16982 generate_exception(ctx, EXCP_RI);
16987 op2 = MASK_INSV(ctx->opcode);
16999 t0 = tcg_temp_new();
17000 t1 = tcg_temp_new();
17002 gen_load_gpr(t0, rt);
17003 gen_load_gpr(t1, rs);
17005 gen_helper_insv(cpu_gpr[rt], cpu_env, t1, t0);
17011 default: /* Invalid */
17012 MIPS_INVAL("MASK INSV");
17013 generate_exception(ctx, EXCP_RI);
17017 case OPC_APPEND_DSP:
17018 gen_mipsdsp_append(env, ctx, op1, rt, rs, rd);
17020 case OPC_EXTR_W_DSP:
17021 op2 = MASK_EXTR_W(ctx->opcode);
17025 case OPC_EXTR_RS_W:
17027 case OPC_EXTRV_S_H:
17029 case OPC_EXTRV_R_W:
17030 case OPC_EXTRV_RS_W:
17035 gen_mipsdsp_accinsn(ctx, op1, op2, rt, rs, rd, 1);
17038 gen_mipsdsp_accinsn(ctx, op1, op2, rd, rs, rt, 1);
17044 gen_mipsdsp_accinsn(ctx, op1, op2, rd, rs, rt, 0);
17046 default: /* Invalid */
17047 MIPS_INVAL("MASK EXTR.W");
17048 generate_exception(ctx, EXCP_RI);
17052 #if defined(TARGET_MIPS64)
17053 case OPC_DDIV_G_2E ... OPC_DDIVU_G_2E:
17054 case OPC_DMULT_G_2E ... OPC_DMULTU_G_2E:
17055 case OPC_DMOD_G_2E ... OPC_DMODU_G_2E:
17056 check_insn(ctx, INSN_LOONGSON2E);
17057 gen_loongson_integer(ctx, op1, rd, rs, rt);
17059 case OPC_ABSQ_S_QH_DSP:
17060 op2 = MASK_ABSQ_S_QH(ctx->opcode);
17062 case OPC_PRECEQ_L_PWL:
17063 case OPC_PRECEQ_L_PWR:
17064 case OPC_PRECEQ_PW_QHL:
17065 case OPC_PRECEQ_PW_QHR:
17066 case OPC_PRECEQ_PW_QHLA:
17067 case OPC_PRECEQ_PW_QHRA:
17068 case OPC_PRECEQU_QH_OBL:
17069 case OPC_PRECEQU_QH_OBR:
17070 case OPC_PRECEQU_QH_OBLA:
17071 case OPC_PRECEQU_QH_OBRA:
17072 case OPC_PRECEU_QH_OBL:
17073 case OPC_PRECEU_QH_OBR:
17074 case OPC_PRECEU_QH_OBLA:
17075 case OPC_PRECEU_QH_OBRA:
17076 case OPC_ABSQ_S_OB:
17077 case OPC_ABSQ_S_PW:
17078 case OPC_ABSQ_S_QH:
17079 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
17087 gen_mipsdsp_bitinsn(ctx, op1, op2, rd, rt);
17089 default: /* Invalid */
17090 MIPS_INVAL("MASK ABSQ_S.QH");
17091 generate_exception(ctx, EXCP_RI);
17095 case OPC_ADDU_OB_DSP:
17096 op2 = MASK_ADDU_OB(ctx->opcode);
17098 case OPC_RADDU_L_OB:
17100 case OPC_SUBQ_S_PW:
17102 case OPC_SUBQ_S_QH:
17104 case OPC_SUBU_S_OB:
17106 case OPC_SUBU_S_QH:
17108 case OPC_SUBUH_R_OB:
17110 case OPC_ADDQ_S_PW:
17112 case OPC_ADDQ_S_QH:
17114 case OPC_ADDU_S_OB:
17116 case OPC_ADDU_S_QH:
17118 case OPC_ADDUH_R_OB:
17119 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
17121 case OPC_MULEQ_S_PW_QHL:
17122 case OPC_MULEQ_S_PW_QHR:
17123 case OPC_MULEU_S_QH_OBL:
17124 case OPC_MULEU_S_QH_OBR:
17125 case OPC_MULQ_RS_QH:
17126 gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 1);
17128 default: /* Invalid */
17129 MIPS_INVAL("MASK ADDU.OB");
17130 generate_exception(ctx, EXCP_RI);
17134 case OPC_CMPU_EQ_OB_DSP:
17135 op2 = MASK_CMPU_EQ_OB(ctx->opcode);
17137 case OPC_PRECR_SRA_QH_PW:
17138 case OPC_PRECR_SRA_R_QH_PW:
17139 /* Return value is rt. */
17140 gen_mipsdsp_arith(ctx, op1, op2, rt, rs, rd);
17142 case OPC_PRECR_OB_QH:
17143 case OPC_PRECRQ_OB_QH:
17144 case OPC_PRECRQ_PW_L:
17145 case OPC_PRECRQ_QH_PW:
17146 case OPC_PRECRQ_RS_QH_PW:
17147 case OPC_PRECRQU_S_OB_QH:
17148 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
17150 case OPC_CMPU_EQ_OB:
17151 case OPC_CMPU_LT_OB:
17152 case OPC_CMPU_LE_OB:
17153 case OPC_CMP_EQ_QH:
17154 case OPC_CMP_LT_QH:
17155 case OPC_CMP_LE_QH:
17156 case OPC_CMP_EQ_PW:
17157 case OPC_CMP_LT_PW:
17158 case OPC_CMP_LE_PW:
17159 gen_mipsdsp_add_cmp_pick(ctx, op1, op2, rd, rs, rt, 0);
17161 case OPC_CMPGDU_EQ_OB:
17162 case OPC_CMPGDU_LT_OB:
17163 case OPC_CMPGDU_LE_OB:
17164 case OPC_CMPGU_EQ_OB:
17165 case OPC_CMPGU_LT_OB:
17166 case OPC_CMPGU_LE_OB:
17167 case OPC_PACKRL_PW:
17171 gen_mipsdsp_add_cmp_pick(ctx, op1, op2, rd, rs, rt, 1);
17173 default: /* Invalid */
17174 MIPS_INVAL("MASK CMPU_EQ.OB");
17175 generate_exception(ctx, EXCP_RI);
17179 case OPC_DAPPEND_DSP:
17180 gen_mipsdsp_append(env, ctx, op1, rt, rs, rd);
17182 case OPC_DEXTR_W_DSP:
17183 op2 = MASK_DEXTR_W(ctx->opcode);
17190 case OPC_DEXTR_R_L:
17191 case OPC_DEXTR_RS_L:
17193 case OPC_DEXTR_R_W:
17194 case OPC_DEXTR_RS_W:
17195 case OPC_DEXTR_S_H:
17197 case OPC_DEXTRV_R_L:
17198 case OPC_DEXTRV_RS_L:
17199 case OPC_DEXTRV_S_H:
17201 case OPC_DEXTRV_R_W:
17202 case OPC_DEXTRV_RS_W:
17203 gen_mipsdsp_accinsn(ctx, op1, op2, rt, rs, rd, 1);
17208 gen_mipsdsp_accinsn(ctx, op1, op2, rd, rs, rt, 0);
17210 default: /* Invalid */
17211 MIPS_INVAL("MASK EXTR.W");
17212 generate_exception(ctx, EXCP_RI);
17216 case OPC_DPAQ_W_QH_DSP:
17217 op2 = MASK_DPAQ_W_QH(ctx->opcode);
17219 case OPC_DPAU_H_OBL:
17220 case OPC_DPAU_H_OBR:
17221 case OPC_DPSU_H_OBL:
17222 case OPC_DPSU_H_OBR:
17224 case OPC_DPAQ_S_W_QH:
17226 case OPC_DPSQ_S_W_QH:
17227 case OPC_MULSAQ_S_W_QH:
17228 case OPC_DPAQ_SA_L_PW:
17229 case OPC_DPSQ_SA_L_PW:
17230 case OPC_MULSAQ_S_L_PW:
17231 gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 0);
17233 case OPC_MAQ_S_W_QHLL:
17234 case OPC_MAQ_S_W_QHLR:
17235 case OPC_MAQ_S_W_QHRL:
17236 case OPC_MAQ_S_W_QHRR:
17237 case OPC_MAQ_SA_W_QHLL:
17238 case OPC_MAQ_SA_W_QHLR:
17239 case OPC_MAQ_SA_W_QHRL:
17240 case OPC_MAQ_SA_W_QHRR:
17241 case OPC_MAQ_S_L_PWL:
17242 case OPC_MAQ_S_L_PWR:
17247 gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 0);
17249 default: /* Invalid */
17250 MIPS_INVAL("MASK DPAQ.W.QH");
17251 generate_exception(ctx, EXCP_RI);
17255 case OPC_DINSV_DSP:
17256 op2 = MASK_INSV(ctx->opcode);
17268 t0 = tcg_temp_new();
17269 t1 = tcg_temp_new();
17271 gen_load_gpr(t0, rt);
17272 gen_load_gpr(t1, rs);
17274 gen_helper_dinsv(cpu_gpr[rt], cpu_env, t1, t0);
17280 default: /* Invalid */
17281 MIPS_INVAL("MASK DINSV");
17282 generate_exception(ctx, EXCP_RI);
17286 case OPC_SHLL_OB_DSP:
17287 gen_mipsdsp_shift(ctx, op1, rd, rs, rt);
17290 default: /* Invalid */
17291 MIPS_INVAL("special3_legacy");
17292 generate_exception(ctx, EXCP_RI);
17297 static void decode_opc_special3(CPUMIPSState *env, DisasContext *ctx)
17299 int rs, rt, rd, sa;
17302 rs = (ctx->opcode >> 21) & 0x1f;
17303 rt = (ctx->opcode >> 16) & 0x1f;
17304 rd = (ctx->opcode >> 11) & 0x1f;
17305 sa = (ctx->opcode >> 6) & 0x1f;
17307 op1 = MASK_SPECIAL3(ctx->opcode);
17311 check_insn(ctx, ISA_MIPS32R2);
17312 gen_bitops(ctx, op1, rt, rs, sa, rd);
17315 op2 = MASK_BSHFL(ctx->opcode);
17317 case OPC_ALIGN ... OPC_ALIGN_END:
17319 check_insn(ctx, ISA_MIPS32R6);
17320 decode_opc_special3_r6(env, ctx);
17323 check_insn(ctx, ISA_MIPS32R2);
17324 gen_bshfl(ctx, op2, rt, rd);
17328 #if defined(TARGET_MIPS64)
17329 case OPC_DEXTM ... OPC_DEXT:
17330 case OPC_DINSM ... OPC_DINS:
17331 check_insn(ctx, ISA_MIPS64R2);
17332 check_mips_64(ctx);
17333 gen_bitops(ctx, op1, rt, rs, sa, rd);
17336 op2 = MASK_DBSHFL(ctx->opcode);
17338 case OPC_DALIGN ... OPC_DALIGN_END:
17340 check_insn(ctx, ISA_MIPS32R6);
17341 decode_opc_special3_r6(env, ctx);
17344 check_insn(ctx, ISA_MIPS64R2);
17345 check_mips_64(ctx);
17346 op2 = MASK_DBSHFL(ctx->opcode);
17347 gen_bshfl(ctx, op2, rt, rd);
17353 gen_rdhwr(ctx, rt, rd);
17356 check_insn(ctx, ASE_MT);
17358 TCGv t0 = tcg_temp_new();
17359 TCGv t1 = tcg_temp_new();
17361 gen_load_gpr(t0, rt);
17362 gen_load_gpr(t1, rs);
17363 gen_helper_fork(t0, t1);
17369 check_insn(ctx, ASE_MT);
17371 TCGv t0 = tcg_temp_new();
17373 save_cpu_state(ctx, 1);
17374 gen_load_gpr(t0, rs);
17375 gen_helper_yield(t0, cpu_env, t0);
17376 gen_store_gpr(t0, rd);
17381 if (ctx->insn_flags & ISA_MIPS32R6) {
17382 decode_opc_special3_r6(env, ctx);
17384 decode_opc_special3_legacy(env, ctx);
17389 /* MIPS SIMD Architecture (MSA) */
17390 static inline int check_msa_access(DisasContext *ctx)
17392 if (unlikely((ctx->hflags & MIPS_HFLAG_FPU) &&
17393 !(ctx->hflags & MIPS_HFLAG_F64))) {
17394 generate_exception(ctx, EXCP_RI);
17398 if (unlikely(!(ctx->hflags & MIPS_HFLAG_MSA))) {
17399 if (ctx->insn_flags & ASE_MSA) {
17400 generate_exception(ctx, EXCP_MSADIS);
17403 generate_exception(ctx, EXCP_RI);
17410 static void gen_check_zero_element(TCGv tresult, uint8_t df, uint8_t wt)
17412 /* generates tcg ops to check if any element is 0 */
17413 /* Note this function only works with MSA_WRLEN = 128 */
17414 uint64_t eval_zero_or_big = 0;
17415 uint64_t eval_big = 0;
17416 TCGv_i64 t0 = tcg_temp_new_i64();
17417 TCGv_i64 t1 = tcg_temp_new_i64();
17420 eval_zero_or_big = 0x0101010101010101ULL;
17421 eval_big = 0x8080808080808080ULL;
17424 eval_zero_or_big = 0x0001000100010001ULL;
17425 eval_big = 0x8000800080008000ULL;
17428 eval_zero_or_big = 0x0000000100000001ULL;
17429 eval_big = 0x8000000080000000ULL;
17432 eval_zero_or_big = 0x0000000000000001ULL;
17433 eval_big = 0x8000000000000000ULL;
17436 tcg_gen_subi_i64(t0, msa_wr_d[wt<<1], eval_zero_or_big);
17437 tcg_gen_andc_i64(t0, t0, msa_wr_d[wt<<1]);
17438 tcg_gen_andi_i64(t0, t0, eval_big);
17439 tcg_gen_subi_i64(t1, msa_wr_d[(wt<<1)+1], eval_zero_or_big);
17440 tcg_gen_andc_i64(t1, t1, msa_wr_d[(wt<<1)+1]);
17441 tcg_gen_andi_i64(t1, t1, eval_big);
17442 tcg_gen_or_i64(t0, t0, t1);
17443 /* if all bits are zero then all elements are not zero */
17444 /* if some bit is non-zero then some element is zero */
17445 tcg_gen_setcondi_i64(TCG_COND_NE, t0, t0, 0);
17446 tcg_gen_trunc_i64_tl(tresult, t0);
17447 tcg_temp_free_i64(t0);
17448 tcg_temp_free_i64(t1);
17451 static void gen_msa_branch(CPUMIPSState *env, DisasContext *ctx, uint32_t op1)
17453 uint8_t df = (ctx->opcode >> 21) & 0x3;
17454 uint8_t wt = (ctx->opcode >> 16) & 0x1f;
17455 int64_t s16 = (int16_t)ctx->opcode;
17457 check_msa_access(ctx);
17459 if (ctx->insn_flags & ISA_MIPS32R6 && ctx->hflags & MIPS_HFLAG_BMASK) {
17460 MIPS_DEBUG("CTI in delay / forbidden slot");
17461 generate_exception(ctx, EXCP_RI);
17468 TCGv_i64 t0 = tcg_temp_new_i64();
17469 tcg_gen_or_i64(t0, msa_wr_d[wt<<1], msa_wr_d[(wt<<1)+1]);
17470 tcg_gen_setcondi_i64((op1 == OPC_BZ_V) ?
17471 TCG_COND_EQ : TCG_COND_NE, t0, t0, 0);
17472 tcg_gen_trunc_i64_tl(bcond, t0);
17473 tcg_temp_free_i64(t0);
17480 gen_check_zero_element(bcond, df, wt);
17486 gen_check_zero_element(bcond, df, wt);
17487 tcg_gen_setcondi_tl(TCG_COND_EQ, bcond, bcond, 0);
17491 ctx->btarget = ctx->pc + (s16 << 2) + 4;
17493 ctx->hflags |= MIPS_HFLAG_BC;
17494 ctx->hflags |= MIPS_HFLAG_BDS32;
17497 static void gen_msa_i8(CPUMIPSState *env, DisasContext *ctx)
17499 #define MASK_MSA_I8(op) (MASK_MSA_MINOR(op) | (op & (0x03 << 24)))
17500 uint8_t i8 = (ctx->opcode >> 16) & 0xff;
17501 uint8_t ws = (ctx->opcode >> 11) & 0x1f;
17502 uint8_t wd = (ctx->opcode >> 6) & 0x1f;
17504 TCGv_i32 twd = tcg_const_i32(wd);
17505 TCGv_i32 tws = tcg_const_i32(ws);
17506 TCGv_i32 ti8 = tcg_const_i32(i8);
17508 switch (MASK_MSA_I8(ctx->opcode)) {
17510 gen_helper_msa_andi_b(cpu_env, twd, tws, ti8);
17513 gen_helper_msa_ori_b(cpu_env, twd, tws, ti8);
17516 gen_helper_msa_nori_b(cpu_env, twd, tws, ti8);
17519 gen_helper_msa_xori_b(cpu_env, twd, tws, ti8);
17522 gen_helper_msa_bmnzi_b(cpu_env, twd, tws, ti8);
17525 gen_helper_msa_bmzi_b(cpu_env, twd, tws, ti8);
17528 gen_helper_msa_bseli_b(cpu_env, twd, tws, ti8);
17534 uint8_t df = (ctx->opcode >> 24) & 0x3;
17535 if (df == DF_DOUBLE) {
17536 generate_exception(ctx, EXCP_RI);
17538 TCGv_i32 tdf = tcg_const_i32(df);
17539 gen_helper_msa_shf_df(cpu_env, tdf, twd, tws, ti8);
17540 tcg_temp_free_i32(tdf);
17545 MIPS_INVAL("MSA instruction");
17546 generate_exception(ctx, EXCP_RI);
17550 tcg_temp_free_i32(twd);
17551 tcg_temp_free_i32(tws);
17552 tcg_temp_free_i32(ti8);
17555 static void gen_msa_i5(CPUMIPSState *env, DisasContext *ctx)
17557 #define MASK_MSA_I5(op) (MASK_MSA_MINOR(op) | (op & (0x7 << 23)))
17558 uint8_t df = (ctx->opcode >> 21) & 0x3;
17559 int8_t s5 = (int8_t) sextract32(ctx->opcode, 16, 5);
17560 uint8_t u5 = (ctx->opcode >> 16) & 0x1f;
17561 uint8_t ws = (ctx->opcode >> 11) & 0x1f;
17562 uint8_t wd = (ctx->opcode >> 6) & 0x1f;
17564 TCGv_i32 tdf = tcg_const_i32(df);
17565 TCGv_i32 twd = tcg_const_i32(wd);
17566 TCGv_i32 tws = tcg_const_i32(ws);
17567 TCGv_i32 timm = tcg_temp_new_i32();
17568 tcg_gen_movi_i32(timm, u5);
17570 switch (MASK_MSA_I5(ctx->opcode)) {
17572 gen_helper_msa_addvi_df(cpu_env, tdf, twd, tws, timm);
17575 gen_helper_msa_subvi_df(cpu_env, tdf, twd, tws, timm);
17577 case OPC_MAXI_S_df:
17578 tcg_gen_movi_i32(timm, s5);
17579 gen_helper_msa_maxi_s_df(cpu_env, tdf, twd, tws, timm);
17581 case OPC_MAXI_U_df:
17582 gen_helper_msa_maxi_u_df(cpu_env, tdf, twd, tws, timm);
17584 case OPC_MINI_S_df:
17585 tcg_gen_movi_i32(timm, s5);
17586 gen_helper_msa_mini_s_df(cpu_env, tdf, twd, tws, timm);
17588 case OPC_MINI_U_df:
17589 gen_helper_msa_mini_u_df(cpu_env, tdf, twd, tws, timm);
17592 tcg_gen_movi_i32(timm, s5);
17593 gen_helper_msa_ceqi_df(cpu_env, tdf, twd, tws, timm);
17595 case OPC_CLTI_S_df:
17596 tcg_gen_movi_i32(timm, s5);
17597 gen_helper_msa_clti_s_df(cpu_env, tdf, twd, tws, timm);
17599 case OPC_CLTI_U_df:
17600 gen_helper_msa_clti_u_df(cpu_env, tdf, twd, tws, timm);
17602 case OPC_CLEI_S_df:
17603 tcg_gen_movi_i32(timm, s5);
17604 gen_helper_msa_clei_s_df(cpu_env, tdf, twd, tws, timm);
17606 case OPC_CLEI_U_df:
17607 gen_helper_msa_clei_u_df(cpu_env, tdf, twd, tws, timm);
17611 int32_t s10 = sextract32(ctx->opcode, 11, 10);
17612 tcg_gen_movi_i32(timm, s10);
17613 gen_helper_msa_ldi_df(cpu_env, tdf, twd, timm);
17617 MIPS_INVAL("MSA instruction");
17618 generate_exception(ctx, EXCP_RI);
17622 tcg_temp_free_i32(tdf);
17623 tcg_temp_free_i32(twd);
17624 tcg_temp_free_i32(tws);
17625 tcg_temp_free_i32(timm);
17628 static void gen_msa_bit(CPUMIPSState *env, DisasContext *ctx)
17630 #define MASK_MSA_BIT(op) (MASK_MSA_MINOR(op) | (op & (0x7 << 23)))
17631 uint8_t dfm = (ctx->opcode >> 16) & 0x7f;
17632 uint32_t df = 0, m = 0;
17633 uint8_t ws = (ctx->opcode >> 11) & 0x1f;
17634 uint8_t wd = (ctx->opcode >> 6) & 0x1f;
17641 if ((dfm & 0x40) == 0x00) {
17644 } else if ((dfm & 0x60) == 0x40) {
17647 } else if ((dfm & 0x70) == 0x60) {
17650 } else if ((dfm & 0x78) == 0x70) {
17654 generate_exception(ctx, EXCP_RI);
17658 tdf = tcg_const_i32(df);
17659 tm = tcg_const_i32(m);
17660 twd = tcg_const_i32(wd);
17661 tws = tcg_const_i32(ws);
17663 switch (MASK_MSA_BIT(ctx->opcode)) {
17665 gen_helper_msa_slli_df(cpu_env, tdf, twd, tws, tm);
17668 gen_helper_msa_srai_df(cpu_env, tdf, twd, tws, tm);
17671 gen_helper_msa_srli_df(cpu_env, tdf, twd, tws, tm);
17674 gen_helper_msa_bclri_df(cpu_env, tdf, twd, tws, tm);
17677 gen_helper_msa_bseti_df(cpu_env, tdf, twd, tws, tm);
17680 gen_helper_msa_bnegi_df(cpu_env, tdf, twd, tws, tm);
17682 case OPC_BINSLI_df:
17683 gen_helper_msa_binsli_df(cpu_env, tdf, twd, tws, tm);
17685 case OPC_BINSRI_df:
17686 gen_helper_msa_binsri_df(cpu_env, tdf, twd, tws, tm);
17689 gen_helper_msa_sat_s_df(cpu_env, tdf, twd, tws, tm);
17692 gen_helper_msa_sat_u_df(cpu_env, tdf, twd, tws, tm);
17695 gen_helper_msa_srari_df(cpu_env, tdf, twd, tws, tm);
17698 gen_helper_msa_srlri_df(cpu_env, tdf, twd, tws, tm);
17701 MIPS_INVAL("MSA instruction");
17702 generate_exception(ctx, EXCP_RI);
17706 tcg_temp_free_i32(tdf);
17707 tcg_temp_free_i32(tm);
17708 tcg_temp_free_i32(twd);
17709 tcg_temp_free_i32(tws);
17712 static void gen_msa_3r(CPUMIPSState *env, DisasContext *ctx)
17714 #define MASK_MSA_3R(op) (MASK_MSA_MINOR(op) | (op & (0x7 << 23)))
17715 uint8_t df = (ctx->opcode >> 21) & 0x3;
17716 uint8_t wt = (ctx->opcode >> 16) & 0x1f;
17717 uint8_t ws = (ctx->opcode >> 11) & 0x1f;
17718 uint8_t wd = (ctx->opcode >> 6) & 0x1f;
17720 TCGv_i32 tdf = tcg_const_i32(df);
17721 TCGv_i32 twd = tcg_const_i32(wd);
17722 TCGv_i32 tws = tcg_const_i32(ws);
17723 TCGv_i32 twt = tcg_const_i32(wt);
17725 switch (MASK_MSA_3R(ctx->opcode)) {
17727 gen_helper_msa_sll_df(cpu_env, tdf, twd, tws, twt);
17730 gen_helper_msa_addv_df(cpu_env, tdf, twd, tws, twt);
17733 gen_helper_msa_ceq_df(cpu_env, tdf, twd, tws, twt);
17736 gen_helper_msa_add_a_df(cpu_env, tdf, twd, tws, twt);
17738 case OPC_SUBS_S_df:
17739 gen_helper_msa_subs_s_df(cpu_env, tdf, twd, tws, twt);
17742 gen_helper_msa_mulv_df(cpu_env, tdf, twd, tws, twt);
17745 gen_helper_msa_sld_df(cpu_env, tdf, twd, tws, twt);
17748 gen_helper_msa_vshf_df(cpu_env, tdf, twd, tws, twt);
17751 gen_helper_msa_sra_df(cpu_env, tdf, twd, tws, twt);
17754 gen_helper_msa_subv_df(cpu_env, tdf, twd, tws, twt);
17756 case OPC_ADDS_A_df:
17757 gen_helper_msa_adds_a_df(cpu_env, tdf, twd, tws, twt);
17759 case OPC_SUBS_U_df:
17760 gen_helper_msa_subs_u_df(cpu_env, tdf, twd, tws, twt);
17763 gen_helper_msa_maddv_df(cpu_env, tdf, twd, tws, twt);
17766 gen_helper_msa_splat_df(cpu_env, tdf, twd, tws, twt);
17769 gen_helper_msa_srar_df(cpu_env, tdf, twd, tws, twt);
17772 gen_helper_msa_srl_df(cpu_env, tdf, twd, tws, twt);
17775 gen_helper_msa_max_s_df(cpu_env, tdf, twd, tws, twt);
17778 gen_helper_msa_clt_s_df(cpu_env, tdf, twd, tws, twt);
17780 case OPC_ADDS_S_df:
17781 gen_helper_msa_adds_s_df(cpu_env, tdf, twd, tws, twt);
17783 case OPC_SUBSUS_U_df:
17784 gen_helper_msa_subsus_u_df(cpu_env, tdf, twd, tws, twt);
17787 gen_helper_msa_msubv_df(cpu_env, tdf, twd, tws, twt);
17790 gen_helper_msa_pckev_df(cpu_env, tdf, twd, tws, twt);
17793 gen_helper_msa_srlr_df(cpu_env, tdf, twd, tws, twt);
17796 gen_helper_msa_bclr_df(cpu_env, tdf, twd, tws, twt);
17799 gen_helper_msa_max_u_df(cpu_env, tdf, twd, tws, twt);
17802 gen_helper_msa_clt_u_df(cpu_env, tdf, twd, tws, twt);
17804 case OPC_ADDS_U_df:
17805 gen_helper_msa_adds_u_df(cpu_env, tdf, twd, tws, twt);
17807 case OPC_SUBSUU_S_df:
17808 gen_helper_msa_subsuu_s_df(cpu_env, tdf, twd, tws, twt);
17811 gen_helper_msa_pckod_df(cpu_env, tdf, twd, tws, twt);
17814 gen_helper_msa_bset_df(cpu_env, tdf, twd, tws, twt);
17817 gen_helper_msa_min_s_df(cpu_env, tdf, twd, tws, twt);
17820 gen_helper_msa_cle_s_df(cpu_env, tdf, twd, tws, twt);
17823 gen_helper_msa_ave_s_df(cpu_env, tdf, twd, tws, twt);
17825 case OPC_ASUB_S_df:
17826 gen_helper_msa_asub_s_df(cpu_env, tdf, twd, tws, twt);
17829 gen_helper_msa_div_s_df(cpu_env, tdf, twd, tws, twt);
17832 gen_helper_msa_ilvl_df(cpu_env, tdf, twd, tws, twt);
17835 gen_helper_msa_bneg_df(cpu_env, tdf, twd, tws, twt);
17838 gen_helper_msa_min_u_df(cpu_env, tdf, twd, tws, twt);
17841 gen_helper_msa_cle_u_df(cpu_env, tdf, twd, tws, twt);
17844 gen_helper_msa_ave_u_df(cpu_env, tdf, twd, tws, twt);
17846 case OPC_ASUB_U_df:
17847 gen_helper_msa_asub_u_df(cpu_env, tdf, twd, tws, twt);
17850 gen_helper_msa_div_u_df(cpu_env, tdf, twd, tws, twt);
17853 gen_helper_msa_ilvr_df(cpu_env, tdf, twd, tws, twt);
17856 gen_helper_msa_binsl_df(cpu_env, tdf, twd, tws, twt);
17859 gen_helper_msa_max_a_df(cpu_env, tdf, twd, tws, twt);
17861 case OPC_AVER_S_df:
17862 gen_helper_msa_aver_s_df(cpu_env, tdf, twd, tws, twt);
17865 gen_helper_msa_mod_s_df(cpu_env, tdf, twd, tws, twt);
17868 gen_helper_msa_ilvev_df(cpu_env, tdf, twd, tws, twt);
17871 gen_helper_msa_binsr_df(cpu_env, tdf, twd, tws, twt);
17874 gen_helper_msa_min_a_df(cpu_env, tdf, twd, tws, twt);
17876 case OPC_AVER_U_df:
17877 gen_helper_msa_aver_u_df(cpu_env, tdf, twd, tws, twt);
17880 gen_helper_msa_mod_u_df(cpu_env, tdf, twd, tws, twt);
17883 gen_helper_msa_ilvod_df(cpu_env, tdf, twd, tws, twt);
17886 case OPC_DOTP_S_df:
17887 case OPC_DOTP_U_df:
17888 case OPC_DPADD_S_df:
17889 case OPC_DPADD_U_df:
17890 case OPC_DPSUB_S_df:
17891 case OPC_HADD_S_df:
17892 case OPC_DPSUB_U_df:
17893 case OPC_HADD_U_df:
17894 case OPC_HSUB_S_df:
17895 case OPC_HSUB_U_df:
17896 if (df == DF_BYTE) {
17897 generate_exception(ctx, EXCP_RI);
17899 switch (MASK_MSA_3R(ctx->opcode)) {
17900 case OPC_DOTP_S_df:
17901 gen_helper_msa_dotp_s_df(cpu_env, tdf, twd, tws, twt);
17903 case OPC_DOTP_U_df:
17904 gen_helper_msa_dotp_u_df(cpu_env, tdf, twd, tws, twt);
17906 case OPC_DPADD_S_df:
17907 gen_helper_msa_dpadd_s_df(cpu_env, tdf, twd, tws, twt);
17909 case OPC_DPADD_U_df:
17910 gen_helper_msa_dpadd_u_df(cpu_env, tdf, twd, tws, twt);
17912 case OPC_DPSUB_S_df:
17913 gen_helper_msa_dpsub_s_df(cpu_env, tdf, twd, tws, twt);
17915 case OPC_HADD_S_df:
17916 gen_helper_msa_hadd_s_df(cpu_env, tdf, twd, tws, twt);
17918 case OPC_DPSUB_U_df:
17919 gen_helper_msa_dpsub_u_df(cpu_env, tdf, twd, tws, twt);
17921 case OPC_HADD_U_df:
17922 gen_helper_msa_hadd_u_df(cpu_env, tdf, twd, tws, twt);
17924 case OPC_HSUB_S_df:
17925 gen_helper_msa_hsub_s_df(cpu_env, tdf, twd, tws, twt);
17927 case OPC_HSUB_U_df:
17928 gen_helper_msa_hsub_u_df(cpu_env, tdf, twd, tws, twt);
17933 MIPS_INVAL("MSA instruction");
17934 generate_exception(ctx, EXCP_RI);
17937 tcg_temp_free_i32(twd);
17938 tcg_temp_free_i32(tws);
17939 tcg_temp_free_i32(twt);
17940 tcg_temp_free_i32(tdf);
17943 static void gen_msa_elm_3e(CPUMIPSState *env, DisasContext *ctx)
17945 #define MASK_MSA_ELM_DF3E(op) (MASK_MSA_MINOR(op) | (op & (0x3FF << 16)))
17946 uint8_t source = (ctx->opcode >> 11) & 0x1f;
17947 uint8_t dest = (ctx->opcode >> 6) & 0x1f;
17948 TCGv telm = tcg_temp_new();
17949 TCGv_i32 tsr = tcg_const_i32(source);
17950 TCGv_i32 tdt = tcg_const_i32(dest);
17952 switch (MASK_MSA_ELM_DF3E(ctx->opcode)) {
17954 gen_load_gpr(telm, source);
17955 gen_helper_msa_ctcmsa(cpu_env, telm, tdt);
17958 gen_helper_msa_cfcmsa(telm, cpu_env, tsr);
17959 gen_store_gpr(telm, dest);
17962 gen_helper_msa_move_v(cpu_env, tdt, tsr);
17965 MIPS_INVAL("MSA instruction");
17966 generate_exception(ctx, EXCP_RI);
17970 tcg_temp_free(telm);
17971 tcg_temp_free_i32(tdt);
17972 tcg_temp_free_i32(tsr);
17975 static void gen_msa_elm_df(CPUMIPSState *env, DisasContext *ctx, uint32_t df,
17978 #define MASK_MSA_ELM(op) (MASK_MSA_MINOR(op) | (op & (0xf << 22)))
17979 uint8_t ws = (ctx->opcode >> 11) & 0x1f;
17980 uint8_t wd = (ctx->opcode >> 6) & 0x1f;
17982 TCGv_i32 tws = tcg_const_i32(ws);
17983 TCGv_i32 twd = tcg_const_i32(wd);
17984 TCGv_i32 tn = tcg_const_i32(n);
17985 TCGv_i32 tdf = tcg_const_i32(df);
17987 switch (MASK_MSA_ELM(ctx->opcode)) {
17989 gen_helper_msa_sldi_df(cpu_env, tdf, twd, tws, tn);
17991 case OPC_SPLATI_df:
17992 gen_helper_msa_splati_df(cpu_env, tdf, twd, tws, tn);
17995 gen_helper_msa_insve_df(cpu_env, tdf, twd, tws, tn);
17997 case OPC_COPY_S_df:
17998 case OPC_COPY_U_df:
17999 case OPC_INSERT_df:
18000 #if !defined(TARGET_MIPS64)
18001 /* Double format valid only for MIPS64 */
18002 if (df == DF_DOUBLE) {
18003 generate_exception(ctx, EXCP_RI);
18007 switch (MASK_MSA_ELM(ctx->opcode)) {
18008 case OPC_COPY_S_df:
18009 gen_helper_msa_copy_s_df(cpu_env, tdf, twd, tws, tn);
18011 case OPC_COPY_U_df:
18012 gen_helper_msa_copy_u_df(cpu_env, tdf, twd, tws, tn);
18014 case OPC_INSERT_df:
18015 gen_helper_msa_insert_df(cpu_env, tdf, twd, tws, tn);
18020 MIPS_INVAL("MSA instruction");
18021 generate_exception(ctx, EXCP_RI);
18023 tcg_temp_free_i32(twd);
18024 tcg_temp_free_i32(tws);
18025 tcg_temp_free_i32(tn);
18026 tcg_temp_free_i32(tdf);
18029 static void gen_msa_elm(CPUMIPSState *env, DisasContext *ctx)
18031 uint8_t dfn = (ctx->opcode >> 16) & 0x3f;
18032 uint32_t df = 0, n = 0;
18034 if ((dfn & 0x30) == 0x00) {
18037 } else if ((dfn & 0x38) == 0x20) {
18040 } else if ((dfn & 0x3c) == 0x30) {
18043 } else if ((dfn & 0x3e) == 0x38) {
18046 } else if (dfn == 0x3E) {
18047 /* CTCMSA, CFCMSA, MOVE.V */
18048 gen_msa_elm_3e(env, ctx);
18051 generate_exception(ctx, EXCP_RI);
18055 gen_msa_elm_df(env, ctx, df, n);
18058 static void gen_msa_3rf(CPUMIPSState *env, DisasContext *ctx)
18060 #define MASK_MSA_3RF(op) (MASK_MSA_MINOR(op) | (op & (0xf << 22)))
18061 uint8_t df = (ctx->opcode >> 21) & 0x1;
18062 uint8_t wt = (ctx->opcode >> 16) & 0x1f;
18063 uint8_t ws = (ctx->opcode >> 11) & 0x1f;
18064 uint8_t wd = (ctx->opcode >> 6) & 0x1f;
18066 TCGv_i32 twd = tcg_const_i32(wd);
18067 TCGv_i32 tws = tcg_const_i32(ws);
18068 TCGv_i32 twt = tcg_const_i32(wt);
18069 TCGv_i32 tdf = tcg_temp_new_i32();
18071 /* adjust df value for floating-point instruction */
18072 tcg_gen_movi_i32(tdf, df + 2);
18074 switch (MASK_MSA_3RF(ctx->opcode)) {
18076 gen_helper_msa_fcaf_df(cpu_env, tdf, twd, tws, twt);
18079 gen_helper_msa_fadd_df(cpu_env, tdf, twd, tws, twt);
18082 gen_helper_msa_fcun_df(cpu_env, tdf, twd, tws, twt);
18085 gen_helper_msa_fsub_df(cpu_env, tdf, twd, tws, twt);
18088 gen_helper_msa_fcor_df(cpu_env, tdf, twd, tws, twt);
18091 gen_helper_msa_fceq_df(cpu_env, tdf, twd, tws, twt);
18094 gen_helper_msa_fmul_df(cpu_env, tdf, twd, tws, twt);
18097 gen_helper_msa_fcune_df(cpu_env, tdf, twd, tws, twt);
18100 gen_helper_msa_fcueq_df(cpu_env, tdf, twd, tws, twt);
18103 gen_helper_msa_fdiv_df(cpu_env, tdf, twd, tws, twt);
18106 gen_helper_msa_fcne_df(cpu_env, tdf, twd, tws, twt);
18109 gen_helper_msa_fclt_df(cpu_env, tdf, twd, tws, twt);
18112 gen_helper_msa_fmadd_df(cpu_env, tdf, twd, tws, twt);
18115 tcg_gen_movi_i32(tdf, df + 1);
18116 gen_helper_msa_mul_q_df(cpu_env, tdf, twd, tws, twt);
18119 gen_helper_msa_fcult_df(cpu_env, tdf, twd, tws, twt);
18122 gen_helper_msa_fmsub_df(cpu_env, tdf, twd, tws, twt);
18124 case OPC_MADD_Q_df:
18125 tcg_gen_movi_i32(tdf, df + 1);
18126 gen_helper_msa_madd_q_df(cpu_env, tdf, twd, tws, twt);
18129 gen_helper_msa_fcle_df(cpu_env, tdf, twd, tws, twt);
18131 case OPC_MSUB_Q_df:
18132 tcg_gen_movi_i32(tdf, df + 1);
18133 gen_helper_msa_msub_q_df(cpu_env, tdf, twd, tws, twt);
18136 gen_helper_msa_fcule_df(cpu_env, tdf, twd, tws, twt);
18139 gen_helper_msa_fexp2_df(cpu_env, tdf, twd, tws, twt);
18142 gen_helper_msa_fsaf_df(cpu_env, tdf, twd, tws, twt);
18145 gen_helper_msa_fexdo_df(cpu_env, tdf, twd, tws, twt);
18148 gen_helper_msa_fsun_df(cpu_env, tdf, twd, tws, twt);
18151 gen_helper_msa_fsor_df(cpu_env, tdf, twd, tws, twt);
18154 gen_helper_msa_fseq_df(cpu_env, tdf, twd, tws, twt);
18157 gen_helper_msa_ftq_df(cpu_env, tdf, twd, tws, twt);
18160 gen_helper_msa_fsune_df(cpu_env, tdf, twd, tws, twt);
18163 gen_helper_msa_fsueq_df(cpu_env, tdf, twd, tws, twt);
18166 gen_helper_msa_fsne_df(cpu_env, tdf, twd, tws, twt);
18169 gen_helper_msa_fslt_df(cpu_env, tdf, twd, tws, twt);
18172 gen_helper_msa_fmin_df(cpu_env, tdf, twd, tws, twt);
18174 case OPC_MULR_Q_df:
18175 tcg_gen_movi_i32(tdf, df + 1);
18176 gen_helper_msa_mulr_q_df(cpu_env, tdf, twd, tws, twt);
18179 gen_helper_msa_fsult_df(cpu_env, tdf, twd, tws, twt);
18181 case OPC_FMIN_A_df:
18182 gen_helper_msa_fmin_a_df(cpu_env, tdf, twd, tws, twt);
18184 case OPC_MADDR_Q_df:
18185 tcg_gen_movi_i32(tdf, df + 1);
18186 gen_helper_msa_maddr_q_df(cpu_env, tdf, twd, tws, twt);
18189 gen_helper_msa_fsle_df(cpu_env, tdf, twd, tws, twt);
18192 gen_helper_msa_fmax_df(cpu_env, tdf, twd, tws, twt);
18194 case OPC_MSUBR_Q_df:
18195 tcg_gen_movi_i32(tdf, df + 1);
18196 gen_helper_msa_msubr_q_df(cpu_env, tdf, twd, tws, twt);
18199 gen_helper_msa_fsule_df(cpu_env, tdf, twd, tws, twt);
18201 case OPC_FMAX_A_df:
18202 gen_helper_msa_fmax_a_df(cpu_env, tdf, twd, tws, twt);
18205 MIPS_INVAL("MSA instruction");
18206 generate_exception(ctx, EXCP_RI);
18210 tcg_temp_free_i32(twd);
18211 tcg_temp_free_i32(tws);
18212 tcg_temp_free_i32(twt);
18213 tcg_temp_free_i32(tdf);
18216 static void gen_msa_2r(CPUMIPSState *env, DisasContext *ctx)
18218 #define MASK_MSA_2R(op) (MASK_MSA_MINOR(op) | (op & (0x1f << 21)) | \
18219 (op & (0x7 << 18)))
18220 uint8_t wt = (ctx->opcode >> 16) & 0x1f;
18221 uint8_t ws = (ctx->opcode >> 11) & 0x1f;
18222 uint8_t wd = (ctx->opcode >> 6) & 0x1f;
18223 uint8_t df = (ctx->opcode >> 16) & 0x3;
18224 TCGv_i32 twd = tcg_const_i32(wd);
18225 TCGv_i32 tws = tcg_const_i32(ws);
18226 TCGv_i32 twt = tcg_const_i32(wt);
18227 TCGv_i32 tdf = tcg_const_i32(df);
18229 switch (MASK_MSA_2R(ctx->opcode)) {
18231 #if !defined(TARGET_MIPS64)
18232 /* Double format valid only for MIPS64 */
18233 if (df == DF_DOUBLE) {
18234 generate_exception(ctx, EXCP_RI);
18238 gen_helper_msa_fill_df(cpu_env, tdf, twd, tws); /* trs */
18241 gen_helper_msa_pcnt_df(cpu_env, tdf, twd, tws);
18244 gen_helper_msa_nloc_df(cpu_env, tdf, twd, tws);
18247 gen_helper_msa_nlzc_df(cpu_env, tdf, twd, tws);
18250 MIPS_INVAL("MSA instruction");
18251 generate_exception(ctx, EXCP_RI);
18255 tcg_temp_free_i32(twd);
18256 tcg_temp_free_i32(tws);
18257 tcg_temp_free_i32(twt);
18258 tcg_temp_free_i32(tdf);
18261 static void gen_msa_2rf(CPUMIPSState *env, DisasContext *ctx)
18263 #define MASK_MSA_2RF(op) (MASK_MSA_MINOR(op) | (op & (0x1f << 21)) | \
18264 (op & (0xf << 17)))
18265 uint8_t wt = (ctx->opcode >> 16) & 0x1f;
18266 uint8_t ws = (ctx->opcode >> 11) & 0x1f;
18267 uint8_t wd = (ctx->opcode >> 6) & 0x1f;
18268 uint8_t df = (ctx->opcode >> 16) & 0x1;
18269 TCGv_i32 twd = tcg_const_i32(wd);
18270 TCGv_i32 tws = tcg_const_i32(ws);
18271 TCGv_i32 twt = tcg_const_i32(wt);
18272 /* adjust df value for floating-point instruction */
18273 TCGv_i32 tdf = tcg_const_i32(df + 2);
18275 switch (MASK_MSA_2RF(ctx->opcode)) {
18276 case OPC_FCLASS_df:
18277 gen_helper_msa_fclass_df(cpu_env, tdf, twd, tws);
18279 case OPC_FTRUNC_S_df:
18280 gen_helper_msa_ftrunc_s_df(cpu_env, tdf, twd, tws);
18282 case OPC_FTRUNC_U_df:
18283 gen_helper_msa_ftrunc_u_df(cpu_env, tdf, twd, tws);
18286 gen_helper_msa_fsqrt_df(cpu_env, tdf, twd, tws);
18288 case OPC_FRSQRT_df:
18289 gen_helper_msa_frsqrt_df(cpu_env, tdf, twd, tws);
18292 gen_helper_msa_frcp_df(cpu_env, tdf, twd, tws);
18295 gen_helper_msa_frint_df(cpu_env, tdf, twd, tws);
18298 gen_helper_msa_flog2_df(cpu_env, tdf, twd, tws);
18300 case OPC_FEXUPL_df:
18301 gen_helper_msa_fexupl_df(cpu_env, tdf, twd, tws);
18303 case OPC_FEXUPR_df:
18304 gen_helper_msa_fexupr_df(cpu_env, tdf, twd, tws);
18307 gen_helper_msa_ffql_df(cpu_env, tdf, twd, tws);
18310 gen_helper_msa_ffqr_df(cpu_env, tdf, twd, tws);
18312 case OPC_FTINT_S_df:
18313 gen_helper_msa_ftint_s_df(cpu_env, tdf, twd, tws);
18315 case OPC_FTINT_U_df:
18316 gen_helper_msa_ftint_u_df(cpu_env, tdf, twd, tws);
18318 case OPC_FFINT_S_df:
18319 gen_helper_msa_ffint_s_df(cpu_env, tdf, twd, tws);
18321 case OPC_FFINT_U_df:
18322 gen_helper_msa_ffint_u_df(cpu_env, tdf, twd, tws);
18326 tcg_temp_free_i32(twd);
18327 tcg_temp_free_i32(tws);
18328 tcg_temp_free_i32(twt);
18329 tcg_temp_free_i32(tdf);
18332 static void gen_msa_vec_v(CPUMIPSState *env, DisasContext *ctx)
18334 #define MASK_MSA_VEC(op) (MASK_MSA_MINOR(op) | (op & (0x1f << 21)))
18335 uint8_t wt = (ctx->opcode >> 16) & 0x1f;
18336 uint8_t ws = (ctx->opcode >> 11) & 0x1f;
18337 uint8_t wd = (ctx->opcode >> 6) & 0x1f;
18338 TCGv_i32 twd = tcg_const_i32(wd);
18339 TCGv_i32 tws = tcg_const_i32(ws);
18340 TCGv_i32 twt = tcg_const_i32(wt);
18342 switch (MASK_MSA_VEC(ctx->opcode)) {
18344 gen_helper_msa_and_v(cpu_env, twd, tws, twt);
18347 gen_helper_msa_or_v(cpu_env, twd, tws, twt);
18350 gen_helper_msa_nor_v(cpu_env, twd, tws, twt);
18353 gen_helper_msa_xor_v(cpu_env, twd, tws, twt);
18356 gen_helper_msa_bmnz_v(cpu_env, twd, tws, twt);
18359 gen_helper_msa_bmz_v(cpu_env, twd, tws, twt);
18362 gen_helper_msa_bsel_v(cpu_env, twd, tws, twt);
18365 MIPS_INVAL("MSA instruction");
18366 generate_exception(ctx, EXCP_RI);
18370 tcg_temp_free_i32(twd);
18371 tcg_temp_free_i32(tws);
18372 tcg_temp_free_i32(twt);
18375 static void gen_msa_vec(CPUMIPSState *env, DisasContext *ctx)
18377 switch (MASK_MSA_VEC(ctx->opcode)) {
18385 gen_msa_vec_v(env, ctx);
18388 gen_msa_2r(env, ctx);
18391 gen_msa_2rf(env, ctx);
18394 MIPS_INVAL("MSA instruction");
18395 generate_exception(ctx, EXCP_RI);
18400 static void gen_msa(CPUMIPSState *env, DisasContext *ctx)
18402 uint32_t opcode = ctx->opcode;
18403 check_insn(ctx, ASE_MSA);
18404 check_msa_access(ctx);
18406 switch (MASK_MSA_MINOR(opcode)) {
18407 case OPC_MSA_I8_00:
18408 case OPC_MSA_I8_01:
18409 case OPC_MSA_I8_02:
18410 gen_msa_i8(env, ctx);
18412 case OPC_MSA_I5_06:
18413 case OPC_MSA_I5_07:
18414 gen_msa_i5(env, ctx);
18416 case OPC_MSA_BIT_09:
18417 case OPC_MSA_BIT_0A:
18418 gen_msa_bit(env, ctx);
18420 case OPC_MSA_3R_0D:
18421 case OPC_MSA_3R_0E:
18422 case OPC_MSA_3R_0F:
18423 case OPC_MSA_3R_10:
18424 case OPC_MSA_3R_11:
18425 case OPC_MSA_3R_12:
18426 case OPC_MSA_3R_13:
18427 case OPC_MSA_3R_14:
18428 case OPC_MSA_3R_15:
18429 gen_msa_3r(env, ctx);
18432 gen_msa_elm(env, ctx);
18434 case OPC_MSA_3RF_1A:
18435 case OPC_MSA_3RF_1B:
18436 case OPC_MSA_3RF_1C:
18437 gen_msa_3rf(env, ctx);
18440 gen_msa_vec(env, ctx);
18451 int32_t s10 = sextract32(ctx->opcode, 16, 10);
18452 uint8_t rs = (ctx->opcode >> 11) & 0x1f;
18453 uint8_t wd = (ctx->opcode >> 6) & 0x1f;
18454 uint8_t df = (ctx->opcode >> 0) & 0x3;
18456 TCGv_i32 twd = tcg_const_i32(wd);
18457 TCGv taddr = tcg_temp_new();
18458 gen_base_offset_addr(ctx, taddr, rs, s10 << df);
18460 switch (MASK_MSA_MINOR(opcode)) {
18462 gen_helper_msa_ld_b(cpu_env, twd, taddr);
18465 gen_helper_msa_ld_h(cpu_env, twd, taddr);
18468 gen_helper_msa_ld_w(cpu_env, twd, taddr);
18471 gen_helper_msa_ld_d(cpu_env, twd, taddr);
18474 gen_helper_msa_st_b(cpu_env, twd, taddr);
18477 gen_helper_msa_st_h(cpu_env, twd, taddr);
18480 gen_helper_msa_st_w(cpu_env, twd, taddr);
18483 gen_helper_msa_st_d(cpu_env, twd, taddr);
18487 tcg_temp_free_i32(twd);
18488 tcg_temp_free(taddr);
18492 MIPS_INVAL("MSA instruction");
18493 generate_exception(ctx, EXCP_RI);
18499 static void decode_opc(CPUMIPSState *env, DisasContext *ctx)
18502 int rs, rt, rd, sa;
18506 /* make sure instructions are on a word boundary */
18507 if (ctx->pc & 0x3) {
18508 env->CP0_BadVAddr = ctx->pc;
18509 generate_exception_err(ctx, EXCP_AdEL, EXCP_INST_NOTAVAIL);
18510 ctx->bstate = BS_STOP;
18514 /* Handle blikely not taken case */
18515 if ((ctx->hflags & MIPS_HFLAG_BMASK_BASE) == MIPS_HFLAG_BL) {
18516 TCGLabel *l1 = gen_new_label();
18518 MIPS_DEBUG("blikely condition (" TARGET_FMT_lx ")", ctx->pc + 4);
18519 tcg_gen_brcondi_tl(TCG_COND_NE, bcond, 0, l1);
18520 tcg_gen_movi_i32(hflags, ctx->hflags & ~MIPS_HFLAG_BMASK);
18521 gen_goto_tb(ctx, 1, ctx->pc + 4);
18525 if (unlikely(qemu_loglevel_mask(CPU_LOG_TB_OP | CPU_LOG_TB_OP_OPT))) {
18526 tcg_gen_debug_insn_start(ctx->pc);
18529 op = MASK_OP_MAJOR(ctx->opcode);
18530 rs = (ctx->opcode >> 21) & 0x1f;
18531 rt = (ctx->opcode >> 16) & 0x1f;
18532 rd = (ctx->opcode >> 11) & 0x1f;
18533 sa = (ctx->opcode >> 6) & 0x1f;
18534 imm = (int16_t)ctx->opcode;
18537 decode_opc_special(env, ctx);
18540 decode_opc_special2_legacy(env, ctx);
18543 decode_opc_special3(env, ctx);
18546 op1 = MASK_REGIMM(ctx->opcode);
18548 case OPC_BLTZL: /* REGIMM branches */
18552 check_insn(ctx, ISA_MIPS2);
18553 check_insn_opc_removed(ctx, ISA_MIPS32R6);
18557 gen_compute_branch(ctx, op1, 4, rs, -1, imm << 2, 4);
18561 if (ctx->insn_flags & ISA_MIPS32R6) {
18563 /* OPC_NAL, OPC_BAL */
18564 gen_compute_branch(ctx, op1, 4, 0, -1, imm << 2, 4);
18566 generate_exception(ctx, EXCP_RI);
18569 gen_compute_branch(ctx, op1, 4, rs, -1, imm << 2, 4);
18572 case OPC_TGEI ... OPC_TEQI: /* REGIMM traps */
18574 check_insn(ctx, ISA_MIPS2);
18575 check_insn_opc_removed(ctx, ISA_MIPS32R6);
18576 gen_trap(ctx, op1, rs, -1, imm);
18579 check_insn(ctx, ISA_MIPS32R2);
18580 /* Break the TB to be able to sync copied instructions
18582 ctx->bstate = BS_STOP;
18584 case OPC_BPOSGE32: /* MIPS DSP branch */
18585 #if defined(TARGET_MIPS64)
18589 gen_compute_branch(ctx, op1, 4, -1, -2, (int32_t)imm << 2, 4);
18591 #if defined(TARGET_MIPS64)
18593 check_insn(ctx, ISA_MIPS32R6);
18594 check_mips_64(ctx);
18596 tcg_gen_addi_tl(cpu_gpr[rs], cpu_gpr[rs], (int64_t)imm << 32);
18598 MIPS_DEBUG("dahi %s, %04x", regnames[rs], imm);
18601 check_insn(ctx, ISA_MIPS32R6);
18602 check_mips_64(ctx);
18604 tcg_gen_addi_tl(cpu_gpr[rs], cpu_gpr[rs], (int64_t)imm << 48);
18606 MIPS_DEBUG("dati %s, %04x", regnames[rs], imm);
18609 default: /* Invalid */
18610 MIPS_INVAL("regimm");
18611 generate_exception(ctx, EXCP_RI);
18616 check_cp0_enabled(ctx);
18617 op1 = MASK_CP0(ctx->opcode);
18623 #if defined(TARGET_MIPS64)
18627 #ifndef CONFIG_USER_ONLY
18628 gen_cp0(env, ctx, op1, rt, rd);
18629 #endif /* !CONFIG_USER_ONLY */
18631 case OPC_C0_FIRST ... OPC_C0_LAST:
18632 #ifndef CONFIG_USER_ONLY
18633 gen_cp0(env, ctx, MASK_C0(ctx->opcode), rt, rd);
18634 #endif /* !CONFIG_USER_ONLY */
18637 #ifndef CONFIG_USER_ONLY
18640 TCGv t0 = tcg_temp_new();
18642 op2 = MASK_MFMC0(ctx->opcode);
18645 check_insn(ctx, ASE_MT);
18646 gen_helper_dmt(t0);
18647 gen_store_gpr(t0, rt);
18650 check_insn(ctx, ASE_MT);
18651 gen_helper_emt(t0);
18652 gen_store_gpr(t0, rt);
18655 check_insn(ctx, ASE_MT);
18656 gen_helper_dvpe(t0, cpu_env);
18657 gen_store_gpr(t0, rt);
18660 check_insn(ctx, ASE_MT);
18661 gen_helper_evpe(t0, cpu_env);
18662 gen_store_gpr(t0, rt);
18665 check_insn(ctx, ISA_MIPS32R2);
18666 save_cpu_state(ctx, 1);
18667 gen_helper_di(t0, cpu_env);
18668 gen_store_gpr(t0, rt);
18669 /* Stop translation as we may have switched
18670 the execution mode. */
18671 ctx->bstate = BS_STOP;
18674 check_insn(ctx, ISA_MIPS32R2);
18675 save_cpu_state(ctx, 1);
18676 gen_helper_ei(t0, cpu_env);
18677 gen_store_gpr(t0, rt);
18678 /* Stop translation as we may have switched
18679 the execution mode. */
18680 ctx->bstate = BS_STOP;
18682 default: /* Invalid */
18683 MIPS_INVAL("mfmc0");
18684 generate_exception(ctx, EXCP_RI);
18689 #endif /* !CONFIG_USER_ONLY */
18692 check_insn(ctx, ISA_MIPS32R2);
18693 gen_load_srsgpr(rt, rd);
18696 check_insn(ctx, ISA_MIPS32R2);
18697 gen_store_srsgpr(rt, rd);
18701 generate_exception(ctx, EXCP_RI);
18705 case OPC_BOVC: /* OPC_BEQZALC, OPC_BEQC, OPC_ADDI */
18706 if (ctx->insn_flags & ISA_MIPS32R6) {
18707 /* OPC_BOVC, OPC_BEQZALC, OPC_BEQC */
18708 gen_compute_compact_branch(ctx, op, rs, rt, imm << 2);
18711 /* Arithmetic with immediate opcode */
18712 gen_arith_imm(ctx, op, rt, rs, imm);
18716 gen_arith_imm(ctx, op, rt, rs, imm);
18718 case OPC_SLTI: /* Set on less than with immediate opcode */
18720 gen_slt_imm(ctx, op, rt, rs, imm);
18722 case OPC_ANDI: /* Arithmetic with immediate opcode */
18723 case OPC_LUI: /* OPC_AUI */
18726 gen_logic_imm(ctx, op, rt, rs, imm);
18728 case OPC_J ... OPC_JAL: /* Jump */
18729 offset = (int32_t)(ctx->opcode & 0x3FFFFFF) << 2;
18730 gen_compute_branch(ctx, op, 4, rs, rt, offset, 4);
18733 case OPC_BLEZC: /* OPC_BGEZC, OPC_BGEC, OPC_BLEZL */
18734 if (ctx->insn_flags & ISA_MIPS32R6) {
18736 generate_exception(ctx, EXCP_RI);
18739 /* OPC_BLEZC, OPC_BGEZC, OPC_BGEC */
18740 gen_compute_compact_branch(ctx, op, rs, rt, imm << 2);
18743 gen_compute_branch(ctx, op, 4, rs, rt, imm << 2, 4);
18746 case OPC_BGTZC: /* OPC_BLTZC, OPC_BLTC, OPC_BGTZL */
18747 if (ctx->insn_flags & ISA_MIPS32R6) {
18749 generate_exception(ctx, EXCP_RI);
18752 /* OPC_BGTZC, OPC_BLTZC, OPC_BLTC */
18753 gen_compute_compact_branch(ctx, op, rs, rt, imm << 2);
18756 gen_compute_branch(ctx, op, 4, rs, rt, imm << 2, 4);
18759 case OPC_BLEZALC: /* OPC_BGEZALC, OPC_BGEUC, OPC_BLEZ */
18762 gen_compute_branch(ctx, op, 4, rs, rt, imm << 2, 4);
18764 check_insn(ctx, ISA_MIPS32R6);
18765 /* OPC_BLEZALC, OPC_BGEZALC, OPC_BGEUC */
18766 gen_compute_compact_branch(ctx, op, rs, rt, imm << 2);
18769 case OPC_BGTZALC: /* OPC_BLTZALC, OPC_BLTUC, OPC_BGTZ */
18772 gen_compute_branch(ctx, op, 4, rs, rt, imm << 2, 4);
18774 check_insn(ctx, ISA_MIPS32R6);
18775 /* OPC_BGTZALC, OPC_BLTZALC, OPC_BLTUC */
18776 gen_compute_compact_branch(ctx, op, rs, rt, imm << 2);
18781 check_insn(ctx, ISA_MIPS2);
18782 check_insn_opc_removed(ctx, ISA_MIPS32R6);
18786 gen_compute_branch(ctx, op, 4, rs, rt, imm << 2, 4);
18788 case OPC_LL: /* Load and stores */
18789 check_insn(ctx, ISA_MIPS2);
18793 check_insn_opc_removed(ctx, ISA_MIPS32R6);
18795 case OPC_LB ... OPC_LH:
18796 case OPC_LW ... OPC_LHU:
18797 gen_ld(ctx, op, rt, rs, imm);
18801 check_insn_opc_removed(ctx, ISA_MIPS32R6);
18803 case OPC_SB ... OPC_SH:
18805 gen_st(ctx, op, rt, rs, imm);
18808 check_insn(ctx, ISA_MIPS2);
18809 check_insn_opc_removed(ctx, ISA_MIPS32R6);
18810 gen_st_cond(ctx, op, rt, rs, imm);
18813 check_insn_opc_removed(ctx, ISA_MIPS32R6);
18814 check_cp0_enabled(ctx);
18815 check_insn(ctx, ISA_MIPS3 | ISA_MIPS32);
18816 /* Treat as NOP. */
18819 check_insn_opc_removed(ctx, ISA_MIPS32R6);
18820 check_insn(ctx, ISA_MIPS4 | ISA_MIPS32);
18821 /* Treat as NOP. */
18824 /* Floating point (COP1). */
18829 gen_cop1_ldst(ctx, op, rt, rs, imm);
18833 op1 = MASK_CP1(ctx->opcode);
18838 check_cp1_enabled(ctx);
18839 check_insn(ctx, ISA_MIPS32R2);
18844 check_cp1_enabled(ctx);
18845 gen_cp1(ctx, op1, rt, rd);
18847 #if defined(TARGET_MIPS64)
18850 check_cp1_enabled(ctx);
18851 check_insn(ctx, ISA_MIPS3);
18852 check_mips_64(ctx);
18853 gen_cp1(ctx, op1, rt, rd);
18856 case OPC_BC1EQZ: /* OPC_BC1ANY2 */
18857 check_cp1_enabled(ctx);
18858 if (ctx->insn_flags & ISA_MIPS32R6) {
18860 gen_compute_branch1_r6(ctx, MASK_CP1(ctx->opcode),
18865 check_insn(ctx, ASE_MIPS3D);
18866 gen_compute_branch1(ctx, MASK_BC1(ctx->opcode),
18867 (rt >> 2) & 0x7, imm << 2);
18871 check_cp1_enabled(ctx);
18872 check_insn(ctx, ISA_MIPS32R6);
18873 gen_compute_branch1_r6(ctx, MASK_CP1(ctx->opcode),
18877 check_cp1_enabled(ctx);
18878 check_insn_opc_removed(ctx, ISA_MIPS32R6);
18880 check_insn(ctx, ASE_MIPS3D);
18883 check_cp1_enabled(ctx);
18884 check_insn_opc_removed(ctx, ISA_MIPS32R6);
18885 gen_compute_branch1(ctx, MASK_BC1(ctx->opcode),
18886 (rt >> 2) & 0x7, imm << 2);
18889 check_cp1_enabled(ctx);
18890 check_insn_opc_removed(ctx, ISA_MIPS32R6);
18894 check_cp1_enabled(ctx);
18895 gen_farith(ctx, ctx->opcode & FOP(0x3f, 0x1f), rt, rd, sa,
18901 int r6_op = ctx->opcode & FOP(0x3f, 0x1f);
18902 check_cp1_enabled(ctx);
18903 if (ctx->insn_flags & ISA_MIPS32R6) {
18905 case R6_OPC_CMP_AF_S:
18906 case R6_OPC_CMP_UN_S:
18907 case R6_OPC_CMP_EQ_S:
18908 case R6_OPC_CMP_UEQ_S:
18909 case R6_OPC_CMP_LT_S:
18910 case R6_OPC_CMP_ULT_S:
18911 case R6_OPC_CMP_LE_S:
18912 case R6_OPC_CMP_ULE_S:
18913 case R6_OPC_CMP_SAF_S:
18914 case R6_OPC_CMP_SUN_S:
18915 case R6_OPC_CMP_SEQ_S:
18916 case R6_OPC_CMP_SEUQ_S:
18917 case R6_OPC_CMP_SLT_S:
18918 case R6_OPC_CMP_SULT_S:
18919 case R6_OPC_CMP_SLE_S:
18920 case R6_OPC_CMP_SULE_S:
18921 case R6_OPC_CMP_OR_S:
18922 case R6_OPC_CMP_UNE_S:
18923 case R6_OPC_CMP_NE_S:
18924 case R6_OPC_CMP_SOR_S:
18925 case R6_OPC_CMP_SUNE_S:
18926 case R6_OPC_CMP_SNE_S:
18927 gen_r6_cmp_s(ctx, ctx->opcode & 0x1f, rt, rd, sa);
18929 case R6_OPC_CMP_AF_D:
18930 case R6_OPC_CMP_UN_D:
18931 case R6_OPC_CMP_EQ_D:
18932 case R6_OPC_CMP_UEQ_D:
18933 case R6_OPC_CMP_LT_D:
18934 case R6_OPC_CMP_ULT_D:
18935 case R6_OPC_CMP_LE_D:
18936 case R6_OPC_CMP_ULE_D:
18937 case R6_OPC_CMP_SAF_D:
18938 case R6_OPC_CMP_SUN_D:
18939 case R6_OPC_CMP_SEQ_D:
18940 case R6_OPC_CMP_SEUQ_D:
18941 case R6_OPC_CMP_SLT_D:
18942 case R6_OPC_CMP_SULT_D:
18943 case R6_OPC_CMP_SLE_D:
18944 case R6_OPC_CMP_SULE_D:
18945 case R6_OPC_CMP_OR_D:
18946 case R6_OPC_CMP_UNE_D:
18947 case R6_OPC_CMP_NE_D:
18948 case R6_OPC_CMP_SOR_D:
18949 case R6_OPC_CMP_SUNE_D:
18950 case R6_OPC_CMP_SNE_D:
18951 gen_r6_cmp_d(ctx, ctx->opcode & 0x1f, rt, rd, sa);
18954 gen_farith(ctx, ctx->opcode & FOP(0x3f, 0x1f),
18955 rt, rd, sa, (imm >> 8) & 0x7);
18960 gen_farith(ctx, ctx->opcode & FOP(0x3f, 0x1f), rt, rd, sa,
18975 check_insn(ctx, ASE_MSA);
18976 gen_msa_branch(env, ctx, op1);
18980 generate_exception(ctx, EXCP_RI);
18985 /* Compact branches [R6] and COP2 [non-R6] */
18986 case OPC_BC: /* OPC_LWC2 */
18987 case OPC_BALC: /* OPC_SWC2 */
18988 if (ctx->insn_flags & ISA_MIPS32R6) {
18989 /* OPC_BC, OPC_BALC */
18990 gen_compute_compact_branch(ctx, op, 0, 0,
18991 sextract32(ctx->opcode << 2, 0, 28));
18993 /* OPC_LWC2, OPC_SWC2 */
18994 /* COP2: Not implemented. */
18995 generate_exception_err(ctx, EXCP_CpU, 2);
18998 case OPC_BEQZC: /* OPC_JIC, OPC_LDC2 */
18999 case OPC_BNEZC: /* OPC_JIALC, OPC_SDC2 */
19000 if (ctx->insn_flags & ISA_MIPS32R6) {
19002 /* OPC_BEQZC, OPC_BNEZC */
19003 gen_compute_compact_branch(ctx, op, rs, 0,
19004 sextract32(ctx->opcode << 2, 0, 23));
19006 /* OPC_JIC, OPC_JIALC */
19007 gen_compute_compact_branch(ctx, op, 0, rt, imm);
19010 /* OPC_LWC2, OPC_SWC2 */
19011 /* COP2: Not implemented. */
19012 generate_exception_err(ctx, EXCP_CpU, 2);
19016 check_insn(ctx, INSN_LOONGSON2F);
19017 /* Note that these instructions use different fields. */
19018 gen_loongson_multimedia(ctx, sa, rd, rt);
19022 check_insn_opc_removed(ctx, ISA_MIPS32R6);
19023 if (ctx->CP0_Config1 & (1 << CP0C1_FP)) {
19024 check_cp1_enabled(ctx);
19025 op1 = MASK_CP3(ctx->opcode);
19029 check_insn(ctx, ISA_MIPS5 | ISA_MIPS32R2);
19035 check_insn(ctx, ISA_MIPS4 | ISA_MIPS32R2);
19036 gen_flt3_ldst(ctx, op1, sa, rd, rs, rt);
19039 check_insn(ctx, ISA_MIPS4 | ISA_MIPS32R2);
19040 /* Treat as NOP. */
19043 check_insn(ctx, ISA_MIPS5 | ISA_MIPS32R2);
19057 check_insn(ctx, ISA_MIPS4 | ISA_MIPS32R2);
19058 gen_flt3_arith(ctx, op1, sa, rs, rd, rt);
19062 generate_exception (ctx, EXCP_RI);
19066 generate_exception_err(ctx, EXCP_CpU, 1);
19070 #if defined(TARGET_MIPS64)
19071 /* MIPS64 opcodes */
19072 case OPC_LDL ... OPC_LDR:
19074 check_insn_opc_removed(ctx, ISA_MIPS32R6);
19078 check_insn(ctx, ISA_MIPS3);
19079 check_mips_64(ctx);
19080 gen_ld(ctx, op, rt, rs, imm);
19082 case OPC_SDL ... OPC_SDR:
19083 check_insn_opc_removed(ctx, ISA_MIPS32R6);
19086 check_insn(ctx, ISA_MIPS3);
19087 check_mips_64(ctx);
19088 gen_st(ctx, op, rt, rs, imm);
19091 check_insn_opc_removed(ctx, ISA_MIPS32R6);
19092 check_insn(ctx, ISA_MIPS3);
19093 check_mips_64(ctx);
19094 gen_st_cond(ctx, op, rt, rs, imm);
19096 case OPC_BNVC: /* OPC_BNEZALC, OPC_BNEC, OPC_DADDI */
19097 if (ctx->insn_flags & ISA_MIPS32R6) {
19098 /* OPC_BNVC, OPC_BNEZALC, OPC_BNEC */
19099 gen_compute_compact_branch(ctx, op, rs, rt, imm << 2);
19102 check_insn(ctx, ISA_MIPS3);
19103 check_mips_64(ctx);
19104 gen_arith_imm(ctx, op, rt, rs, imm);
19108 check_insn(ctx, ISA_MIPS3);
19109 check_mips_64(ctx);
19110 gen_arith_imm(ctx, op, rt, rs, imm);
19113 case OPC_BNVC: /* OPC_BNEZALC, OPC_BNEC */
19114 if (ctx->insn_flags & ISA_MIPS32R6) {
19115 gen_compute_compact_branch(ctx, op, rs, rt, imm << 2);
19117 MIPS_INVAL("major opcode");
19118 generate_exception(ctx, EXCP_RI);
19122 case OPC_DAUI: /* OPC_JALX */
19123 if (ctx->insn_flags & ISA_MIPS32R6) {
19124 #if defined(TARGET_MIPS64)
19126 check_mips_64(ctx);
19128 TCGv t0 = tcg_temp_new();
19129 gen_load_gpr(t0, rs);
19130 tcg_gen_addi_tl(cpu_gpr[rt], t0, imm << 16);
19133 MIPS_DEBUG("daui %s, %s, %04x", regnames[rt], regnames[rs], imm);
19135 generate_exception(ctx, EXCP_RI);
19136 MIPS_INVAL("major opcode");
19140 check_insn(ctx, ASE_MIPS16 | ASE_MICROMIPS);
19141 offset = (int32_t)(ctx->opcode & 0x3FFFFFF) << 2;
19142 gen_compute_branch(ctx, op, 4, rs, rt, offset, 4);
19145 case OPC_MSA: /* OPC_MDMX */
19146 /* MDMX: Not implemented. */
19150 check_insn(ctx, ISA_MIPS32R6);
19151 gen_pcrel(ctx, rs, imm);
19153 default: /* Invalid */
19154 MIPS_INVAL("major opcode");
19155 generate_exception(ctx, EXCP_RI);
19161 gen_intermediate_code_internal(MIPSCPU *cpu, TranslationBlock *tb,
19164 CPUState *cs = CPU(cpu);
19165 CPUMIPSState *env = &cpu->env;
19167 target_ulong pc_start;
19168 target_ulong next_page_start;
19177 qemu_log("search pc %d\n", search_pc);
19180 next_page_start = (pc_start & TARGET_PAGE_MASK) + TARGET_PAGE_SIZE;
19183 ctx.singlestep_enabled = cs->singlestep_enabled;
19184 ctx.insn_flags = env->insn_flags;
19185 ctx.CP0_Config1 = env->CP0_Config1;
19187 ctx.bstate = BS_NONE;
19188 ctx.kscrexist = (env->CP0_Config4 >> CP0C4_KScrExist) & 0xff;
19189 ctx.rxi = (env->CP0_Config3 >> CP0C3_RXI) & 1;
19190 ctx.ie = (env->CP0_Config4 >> CP0C4_IE) & 3;
19191 ctx.bi = (env->CP0_Config3 >> CP0C3_BI) & 1;
19192 ctx.bp = (env->CP0_Config3 >> CP0C3_BP) & 1;
19193 /* Restore delay slot state from the tb context. */
19194 ctx.hflags = (uint32_t)tb->flags; /* FIXME: maybe use 64 bits here? */
19195 ctx.ulri = (env->CP0_Config3 >> CP0C3_ULRI) & 1;
19196 restore_cpu_state(env, &ctx);
19197 #ifdef CONFIG_USER_ONLY
19198 ctx.mem_idx = MIPS_HFLAG_UM;
19200 ctx.mem_idx = ctx.hflags & MIPS_HFLAG_KSU;
19202 ctx.default_tcg_memop_mask = (ctx.insn_flags & ISA_MIPS32R6) ?
19203 MO_UNALN : MO_ALIGN;
19205 max_insns = tb->cflags & CF_COUNT_MASK;
19206 if (max_insns == 0)
19207 max_insns = CF_COUNT_MASK;
19208 LOG_DISAS("\ntb %p idx %d hflags %04x\n", tb, ctx.mem_idx, ctx.hflags);
19210 while (ctx.bstate == BS_NONE) {
19211 if (unlikely(!QTAILQ_EMPTY(&cs->breakpoints))) {
19212 QTAILQ_FOREACH(bp, &cs->breakpoints, entry) {
19213 if (bp->pc == ctx.pc) {
19214 save_cpu_state(&ctx, 1);
19215 ctx.bstate = BS_BRANCH;
19216 gen_helper_0e0i(raise_exception, EXCP_DEBUG);
19217 /* Include the breakpoint location or the tb won't
19218 * be flushed when it must be. */
19220 goto done_generating;
19226 j = tcg_op_buf_count();
19230 tcg_ctx.gen_opc_instr_start[lj++] = 0;
19232 tcg_ctx.gen_opc_pc[lj] = ctx.pc;
19233 gen_opc_hflags[lj] = ctx.hflags & MIPS_HFLAG_BMASK;
19234 gen_opc_btarget[lj] = ctx.btarget;
19235 tcg_ctx.gen_opc_instr_start[lj] = 1;
19236 tcg_ctx.gen_opc_icount[lj] = num_insns;
19238 if (num_insns + 1 == max_insns && (tb->cflags & CF_LAST_IO))
19241 is_slot = ctx.hflags & MIPS_HFLAG_BMASK;
19242 if (!(ctx.hflags & MIPS_HFLAG_M16)) {
19243 ctx.opcode = cpu_ldl_code(env, ctx.pc);
19245 decode_opc(env, &ctx);
19246 } else if (ctx.insn_flags & ASE_MICROMIPS) {
19247 ctx.opcode = cpu_lduw_code(env, ctx.pc);
19248 insn_bytes = decode_micromips_opc(env, &ctx);
19249 } else if (ctx.insn_flags & ASE_MIPS16) {
19250 ctx.opcode = cpu_lduw_code(env, ctx.pc);
19251 insn_bytes = decode_mips16_opc(env, &ctx);
19253 generate_exception(&ctx, EXCP_RI);
19254 ctx.bstate = BS_STOP;
19258 if (ctx.hflags & MIPS_HFLAG_BMASK) {
19259 if (!(ctx.hflags & (MIPS_HFLAG_BDS16 | MIPS_HFLAG_BDS32 |
19260 MIPS_HFLAG_FBNSLOT))) {
19261 /* force to generate branch as there is neither delay nor
19267 gen_branch(&ctx, insn_bytes);
19269 ctx.pc += insn_bytes;
19273 /* Execute a branch and its delay slot as a single instruction.
19274 This is what GDB expects and is consistent with what the
19275 hardware does (e.g. if a delay slot instruction faults, the
19276 reported PC is the PC of the branch). */
19277 if (cs->singlestep_enabled && (ctx.hflags & MIPS_HFLAG_BMASK) == 0) {
19281 if (ctx.pc >= next_page_start) {
19285 if (tcg_op_buf_full()) {
19289 if (num_insns >= max_insns)
19295 if (tb->cflags & CF_LAST_IO) {
19298 if (cs->singlestep_enabled && ctx.bstate != BS_BRANCH) {
19299 save_cpu_state(&ctx, ctx.bstate != BS_EXCP);
19300 gen_helper_0e0i(raise_exception, EXCP_DEBUG);
19302 switch (ctx.bstate) {
19304 gen_goto_tb(&ctx, 0, ctx.pc);
19307 save_cpu_state(&ctx, 0);
19308 gen_goto_tb(&ctx, 0, ctx.pc);
19311 tcg_gen_exit_tb(0);
19319 gen_tb_end(tb, num_insns);
19322 j = tcg_op_buf_count();
19325 tcg_ctx.gen_opc_instr_start[lj++] = 0;
19327 tb->size = ctx.pc - pc_start;
19328 tb->icount = num_insns;
19332 if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM)) {
19333 qemu_log("IN: %s\n", lookup_symbol(pc_start));
19334 log_target_disas(env, pc_start, ctx.pc - pc_start, 0);
19340 void gen_intermediate_code (CPUMIPSState *env, struct TranslationBlock *tb)
19342 gen_intermediate_code_internal(mips_env_get_cpu(env), tb, false);
19345 void gen_intermediate_code_pc (CPUMIPSState *env, struct TranslationBlock *tb)
19347 gen_intermediate_code_internal(mips_env_get_cpu(env), tb, true);
19350 static void fpu_dump_state(CPUMIPSState *env, FILE *f, fprintf_function fpu_fprintf,
19354 int is_fpu64 = !!(env->hflags & MIPS_HFLAG_F64);
19356 #define printfpr(fp) \
19359 fpu_fprintf(f, "w:%08x d:%016" PRIx64 \
19360 " fd:%13g fs:%13g psu: %13g\n", \
19361 (fp)->w[FP_ENDIAN_IDX], (fp)->d, \
19362 (double)(fp)->fd, \
19363 (double)(fp)->fs[FP_ENDIAN_IDX], \
19364 (double)(fp)->fs[!FP_ENDIAN_IDX]); \
19367 tmp.w[FP_ENDIAN_IDX] = (fp)->w[FP_ENDIAN_IDX]; \
19368 tmp.w[!FP_ENDIAN_IDX] = ((fp) + 1)->w[FP_ENDIAN_IDX]; \
19369 fpu_fprintf(f, "w:%08x d:%016" PRIx64 \
19370 " fd:%13g fs:%13g psu:%13g\n", \
19371 tmp.w[FP_ENDIAN_IDX], tmp.d, \
19373 (double)tmp.fs[FP_ENDIAN_IDX], \
19374 (double)tmp.fs[!FP_ENDIAN_IDX]); \
19379 fpu_fprintf(f, "CP1 FCR0 0x%08x FCR31 0x%08x SR.FR %d fp_status 0x%02x\n",
19380 env->active_fpu.fcr0, env->active_fpu.fcr31, is_fpu64,
19381 get_float_exception_flags(&env->active_fpu.fp_status));
19382 for (i = 0; i < 32; (is_fpu64) ? i++ : (i += 2)) {
19383 fpu_fprintf(f, "%3s: ", fregnames[i]);
19384 printfpr(&env->active_fpu.fpr[i]);
19390 #if defined(TARGET_MIPS64) && defined(MIPS_DEBUG_SIGN_EXTENSIONS)
19391 /* Debug help: The architecture requires 32bit code to maintain proper
19392 sign-extended values on 64bit machines. */
19394 #define SIGN_EXT_P(val) ((((val) & ~0x7fffffff) == 0) || (((val) & ~0x7fffffff) == ~0x7fffffff))
19397 cpu_mips_check_sign_extensions (CPUMIPSState *env, FILE *f,
19398 fprintf_function cpu_fprintf,
19403 if (!SIGN_EXT_P(env->active_tc.PC))
19404 cpu_fprintf(f, "BROKEN: pc=0x" TARGET_FMT_lx "\n", env->active_tc.PC);
19405 if (!SIGN_EXT_P(env->active_tc.HI[0]))
19406 cpu_fprintf(f, "BROKEN: HI=0x" TARGET_FMT_lx "\n", env->active_tc.HI[0]);
19407 if (!SIGN_EXT_P(env->active_tc.LO[0]))
19408 cpu_fprintf(f, "BROKEN: LO=0x" TARGET_FMT_lx "\n", env->active_tc.LO[0]);
19409 if (!SIGN_EXT_P(env->btarget))
19410 cpu_fprintf(f, "BROKEN: btarget=0x" TARGET_FMT_lx "\n", env->btarget);
19412 for (i = 0; i < 32; i++) {
19413 if (!SIGN_EXT_P(env->active_tc.gpr[i]))
19414 cpu_fprintf(f, "BROKEN: %s=0x" TARGET_FMT_lx "\n", regnames[i], env->active_tc.gpr[i]);
19417 if (!SIGN_EXT_P(env->CP0_EPC))
19418 cpu_fprintf(f, "BROKEN: EPC=0x" TARGET_FMT_lx "\n", env->CP0_EPC);
19419 if (!SIGN_EXT_P(env->lladdr))
19420 cpu_fprintf(f, "BROKEN: LLAddr=0x" TARGET_FMT_lx "\n", env->lladdr);
19424 void mips_cpu_dump_state(CPUState *cs, FILE *f, fprintf_function cpu_fprintf,
19427 MIPSCPU *cpu = MIPS_CPU(cs);
19428 CPUMIPSState *env = &cpu->env;
19431 cpu_fprintf(f, "pc=0x" TARGET_FMT_lx " HI=0x" TARGET_FMT_lx
19432 " LO=0x" TARGET_FMT_lx " ds %04x "
19433 TARGET_FMT_lx " " TARGET_FMT_ld "\n",
19434 env->active_tc.PC, env->active_tc.HI[0], env->active_tc.LO[0],
19435 env->hflags, env->btarget, env->bcond);
19436 for (i = 0; i < 32; i++) {
19438 cpu_fprintf(f, "GPR%02d:", i);
19439 cpu_fprintf(f, " %s " TARGET_FMT_lx, regnames[i], env->active_tc.gpr[i]);
19441 cpu_fprintf(f, "\n");
19444 cpu_fprintf(f, "CP0 Status 0x%08x Cause 0x%08x EPC 0x" TARGET_FMT_lx "\n",
19445 env->CP0_Status, env->CP0_Cause, env->CP0_EPC);
19446 cpu_fprintf(f, " Config0 0x%08x Config1 0x%08x LLAddr 0x%016"
19448 env->CP0_Config0, env->CP0_Config1, env->lladdr);
19449 cpu_fprintf(f, " Config2 0x%08x Config3 0x%08x\n",
19450 env->CP0_Config2, env->CP0_Config3);
19451 cpu_fprintf(f, " Config4 0x%08x Config5 0x%08x\n",
19452 env->CP0_Config4, env->CP0_Config5);
19453 if (env->hflags & MIPS_HFLAG_FPU)
19454 fpu_dump_state(env, f, cpu_fprintf, flags);
19455 #if defined(TARGET_MIPS64) && defined(MIPS_DEBUG_SIGN_EXTENSIONS)
19456 cpu_mips_check_sign_extensions(env, f, cpu_fprintf, flags);
19460 void mips_tcg_init(void)
19465 /* Initialize various static tables. */
19469 cpu_env = tcg_global_reg_new_ptr(TCG_AREG0, "env");
19470 TCGV_UNUSED(cpu_gpr[0]);
19471 for (i = 1; i < 32; i++)
19472 cpu_gpr[i] = tcg_global_mem_new(TCG_AREG0,
19473 offsetof(CPUMIPSState, active_tc.gpr[i]),
19476 for (i = 0; i < 32; i++) {
19477 int off = offsetof(CPUMIPSState, active_fpu.fpr[i].wr.d[0]);
19479 tcg_global_mem_new_i64(TCG_AREG0, off, msaregnames[i * 2]);
19480 /* The scalar floating-point unit (FPU) registers are mapped on
19481 * the MSA vector registers. */
19482 fpu_f64[i] = msa_wr_d[i * 2];
19483 off = offsetof(CPUMIPSState, active_fpu.fpr[i].wr.d[1]);
19484 msa_wr_d[i * 2 + 1] =
19485 tcg_global_mem_new_i64(TCG_AREG0, off, msaregnames[i * 2 + 1]);
19488 cpu_PC = tcg_global_mem_new(TCG_AREG0,
19489 offsetof(CPUMIPSState, active_tc.PC), "PC");
19490 for (i = 0; i < MIPS_DSP_ACC; i++) {
19491 cpu_HI[i] = tcg_global_mem_new(TCG_AREG0,
19492 offsetof(CPUMIPSState, active_tc.HI[i]),
19494 cpu_LO[i] = tcg_global_mem_new(TCG_AREG0,
19495 offsetof(CPUMIPSState, active_tc.LO[i]),
19498 cpu_dspctrl = tcg_global_mem_new(TCG_AREG0,
19499 offsetof(CPUMIPSState, active_tc.DSPControl),
19501 bcond = tcg_global_mem_new(TCG_AREG0,
19502 offsetof(CPUMIPSState, bcond), "bcond");
19503 btarget = tcg_global_mem_new(TCG_AREG0,
19504 offsetof(CPUMIPSState, btarget), "btarget");
19505 hflags = tcg_global_mem_new_i32(TCG_AREG0,
19506 offsetof(CPUMIPSState, hflags), "hflags");
19508 fpu_fcr0 = tcg_global_mem_new_i32(TCG_AREG0,
19509 offsetof(CPUMIPSState, active_fpu.fcr0),
19511 fpu_fcr31 = tcg_global_mem_new_i32(TCG_AREG0,
19512 offsetof(CPUMIPSState, active_fpu.fcr31),
19518 #include "translate_init.c"
19520 MIPSCPU *cpu_mips_init(const char *cpu_model)
19524 const mips_def_t *def;
19526 def = cpu_mips_find_by_name(cpu_model);
19529 cpu = MIPS_CPU(object_new(TYPE_MIPS_CPU));
19531 env->cpu_model = def;
19533 #ifndef CONFIG_USER_ONLY
19534 mmu_init(env, def);
19536 fpu_init(env, def);
19537 mvp_init(env, def);
19539 object_property_set_bool(OBJECT(cpu), true, "realized", NULL);
19544 void cpu_state_reset(CPUMIPSState *env)
19546 MIPSCPU *cpu = mips_env_get_cpu(env);
19547 CPUState *cs = CPU(cpu);
19549 /* Reset registers to their default values */
19550 env->CP0_PRid = env->cpu_model->CP0_PRid;
19551 env->CP0_Config0 = env->cpu_model->CP0_Config0;
19552 #ifdef TARGET_WORDS_BIGENDIAN
19553 env->CP0_Config0 |= (1 << CP0C0_BE);
19555 env->CP0_Config1 = env->cpu_model->CP0_Config1;
19556 env->CP0_Config2 = env->cpu_model->CP0_Config2;
19557 env->CP0_Config3 = env->cpu_model->CP0_Config3;
19558 env->CP0_Config4 = env->cpu_model->CP0_Config4;
19559 env->CP0_Config4_rw_bitmask = env->cpu_model->CP0_Config4_rw_bitmask;
19560 env->CP0_Config5 = env->cpu_model->CP0_Config5;
19561 env->CP0_Config5_rw_bitmask = env->cpu_model->CP0_Config5_rw_bitmask;
19562 env->CP0_Config6 = env->cpu_model->CP0_Config6;
19563 env->CP0_Config7 = env->cpu_model->CP0_Config7;
19564 env->CP0_LLAddr_rw_bitmask = env->cpu_model->CP0_LLAddr_rw_bitmask
19565 << env->cpu_model->CP0_LLAddr_shift;
19566 env->CP0_LLAddr_shift = env->cpu_model->CP0_LLAddr_shift;
19567 env->SYNCI_Step = env->cpu_model->SYNCI_Step;
19568 env->CCRes = env->cpu_model->CCRes;
19569 env->CP0_Status_rw_bitmask = env->cpu_model->CP0_Status_rw_bitmask;
19570 env->CP0_TCStatus_rw_bitmask = env->cpu_model->CP0_TCStatus_rw_bitmask;
19571 env->CP0_SRSCtl = env->cpu_model->CP0_SRSCtl;
19572 env->current_tc = 0;
19573 env->SEGBITS = env->cpu_model->SEGBITS;
19574 env->SEGMask = (target_ulong)((1ULL << env->cpu_model->SEGBITS) - 1);
19575 #if defined(TARGET_MIPS64)
19576 if (env->cpu_model->insn_flags & ISA_MIPS3) {
19577 env->SEGMask |= 3ULL << 62;
19580 env->PABITS = env->cpu_model->PABITS;
19581 env->PAMask = (1ULL << env->cpu_model->PABITS) - 1;
19582 env->CP0_SRSConf0_rw_bitmask = env->cpu_model->CP0_SRSConf0_rw_bitmask;
19583 env->CP0_SRSConf0 = env->cpu_model->CP0_SRSConf0;
19584 env->CP0_SRSConf1_rw_bitmask = env->cpu_model->CP0_SRSConf1_rw_bitmask;
19585 env->CP0_SRSConf1 = env->cpu_model->CP0_SRSConf1;
19586 env->CP0_SRSConf2_rw_bitmask = env->cpu_model->CP0_SRSConf2_rw_bitmask;
19587 env->CP0_SRSConf2 = env->cpu_model->CP0_SRSConf2;
19588 env->CP0_SRSConf3_rw_bitmask = env->cpu_model->CP0_SRSConf3_rw_bitmask;
19589 env->CP0_SRSConf3 = env->cpu_model->CP0_SRSConf3;
19590 env->CP0_SRSConf4_rw_bitmask = env->cpu_model->CP0_SRSConf4_rw_bitmask;
19591 env->CP0_SRSConf4 = env->cpu_model->CP0_SRSConf4;
19592 env->CP0_PageGrain_rw_bitmask = env->cpu_model->CP0_PageGrain_rw_bitmask;
19593 env->CP0_PageGrain = env->cpu_model->CP0_PageGrain;
19594 env->active_fpu.fcr0 = env->cpu_model->CP1_fcr0;
19595 env->msair = env->cpu_model->MSAIR;
19596 env->insn_flags = env->cpu_model->insn_flags;
19598 #if defined(CONFIG_USER_ONLY)
19599 env->CP0_Status = (MIPS_HFLAG_UM << CP0St_KSU);
19600 # ifdef TARGET_MIPS64
19601 /* Enable 64-bit register mode. */
19602 env->CP0_Status |= (1 << CP0St_PX);
19604 # ifdef TARGET_ABI_MIPSN64
19605 /* Enable 64-bit address mode. */
19606 env->CP0_Status |= (1 << CP0St_UX);
19608 /* Enable access to the CPUNum, SYNCI_Step, CC, and CCRes RDHWR
19609 hardware registers. */
19610 env->CP0_HWREna |= 0x0000000F;
19611 if (env->CP0_Config1 & (1 << CP0C1_FP)) {
19612 env->CP0_Status |= (1 << CP0St_CU1);
19614 if (env->CP0_Config3 & (1 << CP0C3_DSPP)) {
19615 env->CP0_Status |= (1 << CP0St_MX);
19617 # if defined(TARGET_MIPS64)
19618 /* For MIPS64, init FR bit to 1 if FPU unit is there and bit is writable. */
19619 if ((env->CP0_Config1 & (1 << CP0C1_FP)) &&
19620 (env->CP0_Status_rw_bitmask & (1 << CP0St_FR))) {
19621 env->CP0_Status |= (1 << CP0St_FR);
19625 if (env->hflags & MIPS_HFLAG_BMASK) {
19626 /* If the exception was raised from a delay slot,
19627 come back to the jump. */
19628 env->CP0_ErrorEPC = (env->active_tc.PC
19629 - (env->hflags & MIPS_HFLAG_B16 ? 2 : 4));
19631 env->CP0_ErrorEPC = env->active_tc.PC;
19633 env->active_tc.PC = (int32_t)0xBFC00000;
19634 env->CP0_Random = env->tlb->nb_tlb - 1;
19635 env->tlb->tlb_in_use = env->tlb->nb_tlb;
19636 env->CP0_Wired = 0;
19637 env->CP0_EBase = (cs->cpu_index & 0x3FF);
19638 if (kvm_enabled()) {
19639 env->CP0_EBase |= 0x40000000;
19641 env->CP0_EBase |= 0x80000000;
19643 env->CP0_Status = (1 << CP0St_BEV) | (1 << CP0St_ERL);
19644 /* vectored interrupts not implemented, timer on int 7,
19645 no performance counters. */
19646 env->CP0_IntCtl = 0xe0000000;
19650 for (i = 0; i < 7; i++) {
19651 env->CP0_WatchLo[i] = 0;
19652 env->CP0_WatchHi[i] = 0x80000000;
19654 env->CP0_WatchLo[7] = 0;
19655 env->CP0_WatchHi[7] = 0;
19657 /* Count register increments in debug mode, EJTAG version 1 */
19658 env->CP0_Debug = (1 << CP0DB_CNT) | (0x1 << CP0DB_VER);
19660 cpu_mips_store_count(env, 1);
19662 if (env->CP0_Config3 & (1 << CP0C3_MT)) {
19665 /* Only TC0 on VPE 0 starts as active. */
19666 for (i = 0; i < ARRAY_SIZE(env->tcs); i++) {
19667 env->tcs[i].CP0_TCBind = cs->cpu_index << CP0TCBd_CurVPE;
19668 env->tcs[i].CP0_TCHalt = 1;
19670 env->active_tc.CP0_TCHalt = 1;
19673 if (cs->cpu_index == 0) {
19674 /* VPE0 starts up enabled. */
19675 env->mvp->CP0_MVPControl |= (1 << CP0MVPCo_EVP);
19676 env->CP0_VPEConf0 |= (1 << CP0VPEC0_MVP) | (1 << CP0VPEC0_VPA);
19678 /* TC0 starts up unhalted. */
19680 env->active_tc.CP0_TCHalt = 0;
19681 env->tcs[0].CP0_TCHalt = 0;
19682 /* With thread 0 active. */
19683 env->active_tc.CP0_TCStatus = (1 << CP0TCSt_A);
19684 env->tcs[0].CP0_TCStatus = (1 << CP0TCSt_A);
19688 if ((env->insn_flags & ISA_MIPS32R6) &&
19689 (env->active_fpu.fcr0 & (1 << FCR0_F64))) {
19690 /* Status.FR = 0 mode in 64-bit FPU not allowed in R6 */
19691 env->CP0_Status |= (1 << CP0St_FR);
19695 if (env->CP0_Config3 & (1 << CP0C3_MSAP)) {
19699 compute_hflags(env);
19700 restore_rounding_mode(env);
19701 restore_flush_mode(env);
19702 cs->exception_index = EXCP_NONE;
19705 void restore_state_to_opc(CPUMIPSState *env, TranslationBlock *tb, int pc_pos)
19707 env->active_tc.PC = tcg_ctx.gen_opc_pc[pc_pos];
19708 env->hflags &= ~MIPS_HFLAG_BMASK;
19709 env->hflags |= gen_opc_hflags[pc_pos];
19710 switch (env->hflags & MIPS_HFLAG_BMASK_BASE) {
19711 case MIPS_HFLAG_BR:
19713 case MIPS_HFLAG_BC:
19714 case MIPS_HFLAG_BL:
19716 env->btarget = gen_opc_btarget[pc_pos];