smbios: fix typo
[qemu.git] / target-mips / translate.c
blobddfb9244d7e340769df360a59cc1bd9a00956d37
1 /*
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/>.
24 #include "qemu/osdep.h"
25 #include "cpu.h"
26 #include "disas/disas.h"
27 #include "tcg-op.h"
28 #include "exec/cpu_ldst.h"
30 #include "exec/helper-proto.h"
31 #include "exec/helper-gen.h"
32 #include "sysemu/kvm.h"
33 #include "exec/semihost.h"
35 #include "trace-tcg.h"
36 #include "exec/log.h"
38 #define MIPS_DEBUG_DISAS 0
40 /* MIPS major opcodes */
41 #define MASK_OP_MAJOR(op) (op & (0x3F << 26))
43 enum {
44 /* indirect opcode tables */
45 OPC_SPECIAL = (0x00 << 26),
46 OPC_REGIMM = (0x01 << 26),
47 OPC_CP0 = (0x10 << 26),
48 OPC_CP1 = (0x11 << 26),
49 OPC_CP2 = (0x12 << 26),
50 OPC_CP3 = (0x13 << 26),
51 OPC_SPECIAL2 = (0x1C << 26),
52 OPC_SPECIAL3 = (0x1F << 26),
53 /* arithmetic with immediate */
54 OPC_ADDI = (0x08 << 26),
55 OPC_ADDIU = (0x09 << 26),
56 OPC_SLTI = (0x0A << 26),
57 OPC_SLTIU = (0x0B << 26),
58 /* logic with immediate */
59 OPC_ANDI = (0x0C << 26),
60 OPC_ORI = (0x0D << 26),
61 OPC_XORI = (0x0E << 26),
62 OPC_LUI = (0x0F << 26),
63 /* arithmetic with immediate */
64 OPC_DADDI = (0x18 << 26),
65 OPC_DADDIU = (0x19 << 26),
66 /* Jump and branches */
67 OPC_J = (0x02 << 26),
68 OPC_JAL = (0x03 << 26),
69 OPC_BEQ = (0x04 << 26), /* Unconditional if rs = rt = 0 (B) */
70 OPC_BEQL = (0x14 << 26),
71 OPC_BNE = (0x05 << 26),
72 OPC_BNEL = (0x15 << 26),
73 OPC_BLEZ = (0x06 << 26),
74 OPC_BLEZL = (0x16 << 26),
75 OPC_BGTZ = (0x07 << 26),
76 OPC_BGTZL = (0x17 << 26),
77 OPC_JALX = (0x1D << 26),
78 OPC_DAUI = (0x1D << 26),
79 /* Load and stores */
80 OPC_LDL = (0x1A << 26),
81 OPC_LDR = (0x1B << 26),
82 OPC_LB = (0x20 << 26),
83 OPC_LH = (0x21 << 26),
84 OPC_LWL = (0x22 << 26),
85 OPC_LW = (0x23 << 26),
86 OPC_LWPC = OPC_LW | 0x5,
87 OPC_LBU = (0x24 << 26),
88 OPC_LHU = (0x25 << 26),
89 OPC_LWR = (0x26 << 26),
90 OPC_LWU = (0x27 << 26),
91 OPC_SB = (0x28 << 26),
92 OPC_SH = (0x29 << 26),
93 OPC_SWL = (0x2A << 26),
94 OPC_SW = (0x2B << 26),
95 OPC_SDL = (0x2C << 26),
96 OPC_SDR = (0x2D << 26),
97 OPC_SWR = (0x2E << 26),
98 OPC_LL = (0x30 << 26),
99 OPC_LLD = (0x34 << 26),
100 OPC_LD = (0x37 << 26),
101 OPC_LDPC = OPC_LD | 0x5,
102 OPC_SC = (0x38 << 26),
103 OPC_SCD = (0x3C << 26),
104 OPC_SD = (0x3F << 26),
105 /* Floating point load/store */
106 OPC_LWC1 = (0x31 << 26),
107 OPC_LWC2 = (0x32 << 26),
108 OPC_LDC1 = (0x35 << 26),
109 OPC_LDC2 = (0x36 << 26),
110 OPC_SWC1 = (0x39 << 26),
111 OPC_SWC2 = (0x3A << 26),
112 OPC_SDC1 = (0x3D << 26),
113 OPC_SDC2 = (0x3E << 26),
114 /* Compact Branches */
115 OPC_BLEZALC = (0x06 << 26),
116 OPC_BGEZALC = (0x06 << 26),
117 OPC_BGEUC = (0x06 << 26),
118 OPC_BGTZALC = (0x07 << 26),
119 OPC_BLTZALC = (0x07 << 26),
120 OPC_BLTUC = (0x07 << 26),
121 OPC_BOVC = (0x08 << 26),
122 OPC_BEQZALC = (0x08 << 26),
123 OPC_BEQC = (0x08 << 26),
124 OPC_BLEZC = (0x16 << 26),
125 OPC_BGEZC = (0x16 << 26),
126 OPC_BGEC = (0x16 << 26),
127 OPC_BGTZC = (0x17 << 26),
128 OPC_BLTZC = (0x17 << 26),
129 OPC_BLTC = (0x17 << 26),
130 OPC_BNVC = (0x18 << 26),
131 OPC_BNEZALC = (0x18 << 26),
132 OPC_BNEC = (0x18 << 26),
133 OPC_BC = (0x32 << 26),
134 OPC_BEQZC = (0x36 << 26),
135 OPC_JIC = (0x36 << 26),
136 OPC_BALC = (0x3A << 26),
137 OPC_BNEZC = (0x3E << 26),
138 OPC_JIALC = (0x3E << 26),
139 /* MDMX ASE specific */
140 OPC_MDMX = (0x1E << 26),
141 /* MSA ASE, same as MDMX */
142 OPC_MSA = OPC_MDMX,
143 /* Cache and prefetch */
144 OPC_CACHE = (0x2F << 26),
145 OPC_PREF = (0x33 << 26),
146 /* PC-relative address computation / loads */
147 OPC_PCREL = (0x3B << 26),
150 /* PC-relative address computation / loads */
151 #define MASK_OPC_PCREL_TOP2BITS(op) (MASK_OP_MAJOR(op) | (op & (3 << 19)))
152 #define MASK_OPC_PCREL_TOP5BITS(op) (MASK_OP_MAJOR(op) | (op & (0x1f << 16)))
153 enum {
154 /* Instructions determined by bits 19 and 20 */
155 OPC_ADDIUPC = OPC_PCREL | (0 << 19),
156 R6_OPC_LWPC = OPC_PCREL | (1 << 19),
157 OPC_LWUPC = OPC_PCREL | (2 << 19),
159 /* Instructions determined by bits 16 ... 20 */
160 OPC_AUIPC = OPC_PCREL | (0x1e << 16),
161 OPC_ALUIPC = OPC_PCREL | (0x1f << 16),
163 /* Other */
164 R6_OPC_LDPC = OPC_PCREL | (6 << 18),
167 /* MIPS special opcodes */
168 #define MASK_SPECIAL(op) MASK_OP_MAJOR(op) | (op & 0x3F)
170 enum {
171 /* Shifts */
172 OPC_SLL = 0x00 | OPC_SPECIAL,
173 /* NOP is SLL r0, r0, 0 */
174 /* SSNOP is SLL r0, r0, 1 */
175 /* EHB is SLL r0, r0, 3 */
176 OPC_SRL = 0x02 | OPC_SPECIAL, /* also ROTR */
177 OPC_ROTR = OPC_SRL | (1 << 21),
178 OPC_SRA = 0x03 | OPC_SPECIAL,
179 OPC_SLLV = 0x04 | OPC_SPECIAL,
180 OPC_SRLV = 0x06 | OPC_SPECIAL, /* also ROTRV */
181 OPC_ROTRV = OPC_SRLV | (1 << 6),
182 OPC_SRAV = 0x07 | OPC_SPECIAL,
183 OPC_DSLLV = 0x14 | OPC_SPECIAL,
184 OPC_DSRLV = 0x16 | OPC_SPECIAL, /* also DROTRV */
185 OPC_DROTRV = OPC_DSRLV | (1 << 6),
186 OPC_DSRAV = 0x17 | OPC_SPECIAL,
187 OPC_DSLL = 0x38 | OPC_SPECIAL,
188 OPC_DSRL = 0x3A | OPC_SPECIAL, /* also DROTR */
189 OPC_DROTR = OPC_DSRL | (1 << 21),
190 OPC_DSRA = 0x3B | OPC_SPECIAL,
191 OPC_DSLL32 = 0x3C | OPC_SPECIAL,
192 OPC_DSRL32 = 0x3E | OPC_SPECIAL, /* also DROTR32 */
193 OPC_DROTR32 = OPC_DSRL32 | (1 << 21),
194 OPC_DSRA32 = 0x3F | OPC_SPECIAL,
195 /* Multiplication / division */
196 OPC_MULT = 0x18 | OPC_SPECIAL,
197 OPC_MULTU = 0x19 | OPC_SPECIAL,
198 OPC_DIV = 0x1A | OPC_SPECIAL,
199 OPC_DIVU = 0x1B | OPC_SPECIAL,
200 OPC_DMULT = 0x1C | OPC_SPECIAL,
201 OPC_DMULTU = 0x1D | OPC_SPECIAL,
202 OPC_DDIV = 0x1E | OPC_SPECIAL,
203 OPC_DDIVU = 0x1F | OPC_SPECIAL,
205 /* 2 registers arithmetic / logic */
206 OPC_ADD = 0x20 | OPC_SPECIAL,
207 OPC_ADDU = 0x21 | OPC_SPECIAL,
208 OPC_SUB = 0x22 | OPC_SPECIAL,
209 OPC_SUBU = 0x23 | OPC_SPECIAL,
210 OPC_AND = 0x24 | OPC_SPECIAL,
211 OPC_OR = 0x25 | OPC_SPECIAL,
212 OPC_XOR = 0x26 | OPC_SPECIAL,
213 OPC_NOR = 0x27 | OPC_SPECIAL,
214 OPC_SLT = 0x2A | OPC_SPECIAL,
215 OPC_SLTU = 0x2B | OPC_SPECIAL,
216 OPC_DADD = 0x2C | OPC_SPECIAL,
217 OPC_DADDU = 0x2D | OPC_SPECIAL,
218 OPC_DSUB = 0x2E | OPC_SPECIAL,
219 OPC_DSUBU = 0x2F | OPC_SPECIAL,
220 /* Jumps */
221 OPC_JR = 0x08 | OPC_SPECIAL, /* Also JR.HB */
222 OPC_JALR = 0x09 | OPC_SPECIAL, /* Also JALR.HB */
223 /* Traps */
224 OPC_TGE = 0x30 | OPC_SPECIAL,
225 OPC_TGEU = 0x31 | OPC_SPECIAL,
226 OPC_TLT = 0x32 | OPC_SPECIAL,
227 OPC_TLTU = 0x33 | OPC_SPECIAL,
228 OPC_TEQ = 0x34 | OPC_SPECIAL,
229 OPC_TNE = 0x36 | OPC_SPECIAL,
230 /* HI / LO registers load & stores */
231 OPC_MFHI = 0x10 | OPC_SPECIAL,
232 OPC_MTHI = 0x11 | OPC_SPECIAL,
233 OPC_MFLO = 0x12 | OPC_SPECIAL,
234 OPC_MTLO = 0x13 | OPC_SPECIAL,
235 /* Conditional moves */
236 OPC_MOVZ = 0x0A | OPC_SPECIAL,
237 OPC_MOVN = 0x0B | OPC_SPECIAL,
239 OPC_SELEQZ = 0x35 | OPC_SPECIAL,
240 OPC_SELNEZ = 0x37 | OPC_SPECIAL,
242 OPC_MOVCI = 0x01 | OPC_SPECIAL,
244 /* Special */
245 OPC_PMON = 0x05 | OPC_SPECIAL, /* unofficial */
246 OPC_SYSCALL = 0x0C | OPC_SPECIAL,
247 OPC_BREAK = 0x0D | OPC_SPECIAL,
248 OPC_SPIM = 0x0E | OPC_SPECIAL, /* unofficial */
249 OPC_SYNC = 0x0F | OPC_SPECIAL,
251 OPC_SPECIAL28_RESERVED = 0x28 | OPC_SPECIAL,
252 OPC_SPECIAL29_RESERVED = 0x29 | OPC_SPECIAL,
253 OPC_SPECIAL39_RESERVED = 0x39 | OPC_SPECIAL,
254 OPC_SPECIAL3D_RESERVED = 0x3D | OPC_SPECIAL,
257 /* R6 Multiply and Divide instructions have the same Opcode
258 and function field as legacy OPC_MULT[U]/OPC_DIV[U] */
259 #define MASK_R6_MULDIV(op) (MASK_SPECIAL(op) | (op & (0x7ff)))
261 enum {
262 R6_OPC_MUL = OPC_MULT | (2 << 6),
263 R6_OPC_MUH = OPC_MULT | (3 << 6),
264 R6_OPC_MULU = OPC_MULTU | (2 << 6),
265 R6_OPC_MUHU = OPC_MULTU | (3 << 6),
266 R6_OPC_DIV = OPC_DIV | (2 << 6),
267 R6_OPC_MOD = OPC_DIV | (3 << 6),
268 R6_OPC_DIVU = OPC_DIVU | (2 << 6),
269 R6_OPC_MODU = OPC_DIVU | (3 << 6),
271 R6_OPC_DMUL = OPC_DMULT | (2 << 6),
272 R6_OPC_DMUH = OPC_DMULT | (3 << 6),
273 R6_OPC_DMULU = OPC_DMULTU | (2 << 6),
274 R6_OPC_DMUHU = OPC_DMULTU | (3 << 6),
275 R6_OPC_DDIV = OPC_DDIV | (2 << 6),
276 R6_OPC_DMOD = OPC_DDIV | (3 << 6),
277 R6_OPC_DDIVU = OPC_DDIVU | (2 << 6),
278 R6_OPC_DMODU = OPC_DDIVU | (3 << 6),
280 R6_OPC_CLZ = 0x10 | OPC_SPECIAL,
281 R6_OPC_CLO = 0x11 | OPC_SPECIAL,
282 R6_OPC_DCLZ = 0x12 | OPC_SPECIAL,
283 R6_OPC_DCLO = 0x13 | OPC_SPECIAL,
284 R6_OPC_SDBBP = 0x0e | OPC_SPECIAL,
286 OPC_LSA = 0x05 | OPC_SPECIAL,
287 OPC_DLSA = 0x15 | OPC_SPECIAL,
290 /* Multiplication variants of the vr54xx. */
291 #define MASK_MUL_VR54XX(op) MASK_SPECIAL(op) | (op & (0x1F << 6))
293 enum {
294 OPC_VR54XX_MULS = (0x03 << 6) | OPC_MULT,
295 OPC_VR54XX_MULSU = (0x03 << 6) | OPC_MULTU,
296 OPC_VR54XX_MACC = (0x05 << 6) | OPC_MULT,
297 OPC_VR54XX_MACCU = (0x05 << 6) | OPC_MULTU,
298 OPC_VR54XX_MSAC = (0x07 << 6) | OPC_MULT,
299 OPC_VR54XX_MSACU = (0x07 << 6) | OPC_MULTU,
300 OPC_VR54XX_MULHI = (0x09 << 6) | OPC_MULT,
301 OPC_VR54XX_MULHIU = (0x09 << 6) | OPC_MULTU,
302 OPC_VR54XX_MULSHI = (0x0B << 6) | OPC_MULT,
303 OPC_VR54XX_MULSHIU = (0x0B << 6) | OPC_MULTU,
304 OPC_VR54XX_MACCHI = (0x0D << 6) | OPC_MULT,
305 OPC_VR54XX_MACCHIU = (0x0D << 6) | OPC_MULTU,
306 OPC_VR54XX_MSACHI = (0x0F << 6) | OPC_MULT,
307 OPC_VR54XX_MSACHIU = (0x0F << 6) | OPC_MULTU,
310 /* REGIMM (rt field) opcodes */
311 #define MASK_REGIMM(op) MASK_OP_MAJOR(op) | (op & (0x1F << 16))
313 enum {
314 OPC_BLTZ = (0x00 << 16) | OPC_REGIMM,
315 OPC_BLTZL = (0x02 << 16) | OPC_REGIMM,
316 OPC_BGEZ = (0x01 << 16) | OPC_REGIMM,
317 OPC_BGEZL = (0x03 << 16) | OPC_REGIMM,
318 OPC_BLTZAL = (0x10 << 16) | OPC_REGIMM,
319 OPC_BLTZALL = (0x12 << 16) | OPC_REGIMM,
320 OPC_BGEZAL = (0x11 << 16) | OPC_REGIMM,
321 OPC_BGEZALL = (0x13 << 16) | OPC_REGIMM,
322 OPC_TGEI = (0x08 << 16) | OPC_REGIMM,
323 OPC_TGEIU = (0x09 << 16) | OPC_REGIMM,
324 OPC_TLTI = (0x0A << 16) | OPC_REGIMM,
325 OPC_TLTIU = (0x0B << 16) | OPC_REGIMM,
326 OPC_TEQI = (0x0C << 16) | OPC_REGIMM,
327 OPC_TNEI = (0x0E << 16) | OPC_REGIMM,
328 OPC_SIGRIE = (0x17 << 16) | OPC_REGIMM,
329 OPC_SYNCI = (0x1F << 16) | OPC_REGIMM,
331 OPC_DAHI = (0x06 << 16) | OPC_REGIMM,
332 OPC_DATI = (0x1e << 16) | OPC_REGIMM,
335 /* Special2 opcodes */
336 #define MASK_SPECIAL2(op) MASK_OP_MAJOR(op) | (op & 0x3F)
338 enum {
339 /* Multiply & xxx operations */
340 OPC_MADD = 0x00 | OPC_SPECIAL2,
341 OPC_MADDU = 0x01 | OPC_SPECIAL2,
342 OPC_MUL = 0x02 | OPC_SPECIAL2,
343 OPC_MSUB = 0x04 | OPC_SPECIAL2,
344 OPC_MSUBU = 0x05 | OPC_SPECIAL2,
345 /* Loongson 2F */
346 OPC_MULT_G_2F = 0x10 | OPC_SPECIAL2,
347 OPC_DMULT_G_2F = 0x11 | OPC_SPECIAL2,
348 OPC_MULTU_G_2F = 0x12 | OPC_SPECIAL2,
349 OPC_DMULTU_G_2F = 0x13 | OPC_SPECIAL2,
350 OPC_DIV_G_2F = 0x14 | OPC_SPECIAL2,
351 OPC_DDIV_G_2F = 0x15 | OPC_SPECIAL2,
352 OPC_DIVU_G_2F = 0x16 | OPC_SPECIAL2,
353 OPC_DDIVU_G_2F = 0x17 | OPC_SPECIAL2,
354 OPC_MOD_G_2F = 0x1c | OPC_SPECIAL2,
355 OPC_DMOD_G_2F = 0x1d | OPC_SPECIAL2,
356 OPC_MODU_G_2F = 0x1e | OPC_SPECIAL2,
357 OPC_DMODU_G_2F = 0x1f | OPC_SPECIAL2,
358 /* Misc */
359 OPC_CLZ = 0x20 | OPC_SPECIAL2,
360 OPC_CLO = 0x21 | OPC_SPECIAL2,
361 OPC_DCLZ = 0x24 | OPC_SPECIAL2,
362 OPC_DCLO = 0x25 | OPC_SPECIAL2,
363 /* Special */
364 OPC_SDBBP = 0x3F | OPC_SPECIAL2,
367 /* Special3 opcodes */
368 #define MASK_SPECIAL3(op) MASK_OP_MAJOR(op) | (op & 0x3F)
370 enum {
371 OPC_EXT = 0x00 | OPC_SPECIAL3,
372 OPC_DEXTM = 0x01 | OPC_SPECIAL3,
373 OPC_DEXTU = 0x02 | OPC_SPECIAL3,
374 OPC_DEXT = 0x03 | OPC_SPECIAL3,
375 OPC_INS = 0x04 | OPC_SPECIAL3,
376 OPC_DINSM = 0x05 | OPC_SPECIAL3,
377 OPC_DINSU = 0x06 | OPC_SPECIAL3,
378 OPC_DINS = 0x07 | OPC_SPECIAL3,
379 OPC_FORK = 0x08 | OPC_SPECIAL3,
380 OPC_YIELD = 0x09 | OPC_SPECIAL3,
381 OPC_BSHFL = 0x20 | OPC_SPECIAL3,
382 OPC_DBSHFL = 0x24 | OPC_SPECIAL3,
383 OPC_RDHWR = 0x3B | OPC_SPECIAL3,
385 /* Loongson 2E */
386 OPC_MULT_G_2E = 0x18 | OPC_SPECIAL3,
387 OPC_MULTU_G_2E = 0x19 | OPC_SPECIAL3,
388 OPC_DIV_G_2E = 0x1A | OPC_SPECIAL3,
389 OPC_DIVU_G_2E = 0x1B | OPC_SPECIAL3,
390 OPC_DMULT_G_2E = 0x1C | OPC_SPECIAL3,
391 OPC_DMULTU_G_2E = 0x1D | OPC_SPECIAL3,
392 OPC_DDIV_G_2E = 0x1E | OPC_SPECIAL3,
393 OPC_DDIVU_G_2E = 0x1F | OPC_SPECIAL3,
394 OPC_MOD_G_2E = 0x22 | OPC_SPECIAL3,
395 OPC_MODU_G_2E = 0x23 | OPC_SPECIAL3,
396 OPC_DMOD_G_2E = 0x26 | OPC_SPECIAL3,
397 OPC_DMODU_G_2E = 0x27 | OPC_SPECIAL3,
399 /* MIPS DSP Load */
400 OPC_LX_DSP = 0x0A | OPC_SPECIAL3,
401 /* MIPS DSP Arithmetic */
402 OPC_ADDU_QB_DSP = 0x10 | OPC_SPECIAL3,
403 OPC_ADDU_OB_DSP = 0x14 | OPC_SPECIAL3,
404 OPC_ABSQ_S_PH_DSP = 0x12 | OPC_SPECIAL3,
405 OPC_ABSQ_S_QH_DSP = 0x16 | OPC_SPECIAL3,
406 /* OPC_ADDUH_QB_DSP is same as OPC_MULT_G_2E. */
407 /* OPC_ADDUH_QB_DSP = 0x18 | OPC_SPECIAL3, */
408 OPC_CMPU_EQ_QB_DSP = 0x11 | OPC_SPECIAL3,
409 OPC_CMPU_EQ_OB_DSP = 0x15 | OPC_SPECIAL3,
410 /* MIPS DSP GPR-Based Shift Sub-class */
411 OPC_SHLL_QB_DSP = 0x13 | OPC_SPECIAL3,
412 OPC_SHLL_OB_DSP = 0x17 | OPC_SPECIAL3,
413 /* MIPS DSP Multiply Sub-class insns */
414 /* OPC_MUL_PH_DSP is same as OPC_ADDUH_QB_DSP. */
415 /* OPC_MUL_PH_DSP = 0x18 | OPC_SPECIAL3, */
416 OPC_DPA_W_PH_DSP = 0x30 | OPC_SPECIAL3,
417 OPC_DPAQ_W_QH_DSP = 0x34 | OPC_SPECIAL3,
418 /* DSP Bit/Manipulation Sub-class */
419 OPC_INSV_DSP = 0x0C | OPC_SPECIAL3,
420 OPC_DINSV_DSP = 0x0D | OPC_SPECIAL3,
421 /* MIPS DSP Append Sub-class */
422 OPC_APPEND_DSP = 0x31 | OPC_SPECIAL3,
423 OPC_DAPPEND_DSP = 0x35 | OPC_SPECIAL3,
424 /* MIPS DSP Accumulator and DSPControl Access Sub-class */
425 OPC_EXTR_W_DSP = 0x38 | OPC_SPECIAL3,
426 OPC_DEXTR_W_DSP = 0x3C | OPC_SPECIAL3,
428 /* R6 */
429 R6_OPC_PREF = 0x35 | OPC_SPECIAL3,
430 R6_OPC_CACHE = 0x25 | OPC_SPECIAL3,
431 R6_OPC_LL = 0x36 | OPC_SPECIAL3,
432 R6_OPC_SC = 0x26 | OPC_SPECIAL3,
433 R6_OPC_LLD = 0x37 | OPC_SPECIAL3,
434 R6_OPC_SCD = 0x27 | OPC_SPECIAL3,
437 /* BSHFL opcodes */
438 #define MASK_BSHFL(op) MASK_SPECIAL3(op) | (op & (0x1F << 6))
440 enum {
441 OPC_WSBH = (0x02 << 6) | OPC_BSHFL,
442 OPC_SEB = (0x10 << 6) | OPC_BSHFL,
443 OPC_SEH = (0x18 << 6) | OPC_BSHFL,
444 OPC_ALIGN = (0x08 << 6) | OPC_BSHFL, /* 010.bp */
445 OPC_ALIGN_END = (0x0B << 6) | OPC_BSHFL, /* 010.00 to 010.11 */
446 OPC_BITSWAP = (0x00 << 6) | OPC_BSHFL /* 00000 */
449 /* DBSHFL opcodes */
450 #define MASK_DBSHFL(op) MASK_SPECIAL3(op) | (op & (0x1F << 6))
452 enum {
453 OPC_DSBH = (0x02 << 6) | OPC_DBSHFL,
454 OPC_DSHD = (0x05 << 6) | OPC_DBSHFL,
455 OPC_DALIGN = (0x08 << 6) | OPC_DBSHFL, /* 01.bp */
456 OPC_DALIGN_END = (0x0F << 6) | OPC_DBSHFL, /* 01.000 to 01.111 */
457 OPC_DBITSWAP = (0x00 << 6) | OPC_DBSHFL, /* 00000 */
460 /* MIPS DSP REGIMM opcodes */
461 enum {
462 OPC_BPOSGE32 = (0x1C << 16) | OPC_REGIMM,
463 OPC_BPOSGE64 = (0x1D << 16) | OPC_REGIMM,
466 #define MASK_LX(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
467 /* MIPS DSP Load */
468 enum {
469 OPC_LBUX = (0x06 << 6) | OPC_LX_DSP,
470 OPC_LHX = (0x04 << 6) | OPC_LX_DSP,
471 OPC_LWX = (0x00 << 6) | OPC_LX_DSP,
472 OPC_LDX = (0x08 << 6) | OPC_LX_DSP,
475 #define MASK_ADDU_QB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
476 enum {
477 /* MIPS DSP Arithmetic Sub-class */
478 OPC_ADDQ_PH = (0x0A << 6) | OPC_ADDU_QB_DSP,
479 OPC_ADDQ_S_PH = (0x0E << 6) | OPC_ADDU_QB_DSP,
480 OPC_ADDQ_S_W = (0x16 << 6) | OPC_ADDU_QB_DSP,
481 OPC_ADDU_QB = (0x00 << 6) | OPC_ADDU_QB_DSP,
482 OPC_ADDU_S_QB = (0x04 << 6) | OPC_ADDU_QB_DSP,
483 OPC_ADDU_PH = (0x08 << 6) | OPC_ADDU_QB_DSP,
484 OPC_ADDU_S_PH = (0x0C << 6) | OPC_ADDU_QB_DSP,
485 OPC_SUBQ_PH = (0x0B << 6) | OPC_ADDU_QB_DSP,
486 OPC_SUBQ_S_PH = (0x0F << 6) | OPC_ADDU_QB_DSP,
487 OPC_SUBQ_S_W = (0x17 << 6) | OPC_ADDU_QB_DSP,
488 OPC_SUBU_QB = (0x01 << 6) | OPC_ADDU_QB_DSP,
489 OPC_SUBU_S_QB = (0x05 << 6) | OPC_ADDU_QB_DSP,
490 OPC_SUBU_PH = (0x09 << 6) | OPC_ADDU_QB_DSP,
491 OPC_SUBU_S_PH = (0x0D << 6) | OPC_ADDU_QB_DSP,
492 OPC_ADDSC = (0x10 << 6) | OPC_ADDU_QB_DSP,
493 OPC_ADDWC = (0x11 << 6) | OPC_ADDU_QB_DSP,
494 OPC_MODSUB = (0x12 << 6) | OPC_ADDU_QB_DSP,
495 OPC_RADDU_W_QB = (0x14 << 6) | OPC_ADDU_QB_DSP,
496 /* MIPS DSP Multiply Sub-class insns */
497 OPC_MULEU_S_PH_QBL = (0x06 << 6) | OPC_ADDU_QB_DSP,
498 OPC_MULEU_S_PH_QBR = (0x07 << 6) | OPC_ADDU_QB_DSP,
499 OPC_MULQ_RS_PH = (0x1F << 6) | OPC_ADDU_QB_DSP,
500 OPC_MULEQ_S_W_PHL = (0x1C << 6) | OPC_ADDU_QB_DSP,
501 OPC_MULEQ_S_W_PHR = (0x1D << 6) | OPC_ADDU_QB_DSP,
502 OPC_MULQ_S_PH = (0x1E << 6) | OPC_ADDU_QB_DSP,
505 #define OPC_ADDUH_QB_DSP OPC_MULT_G_2E
506 #define MASK_ADDUH_QB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
507 enum {
508 /* MIPS DSP Arithmetic Sub-class */
509 OPC_ADDUH_QB = (0x00 << 6) | OPC_ADDUH_QB_DSP,
510 OPC_ADDUH_R_QB = (0x02 << 6) | OPC_ADDUH_QB_DSP,
511 OPC_ADDQH_PH = (0x08 << 6) | OPC_ADDUH_QB_DSP,
512 OPC_ADDQH_R_PH = (0x0A << 6) | OPC_ADDUH_QB_DSP,
513 OPC_ADDQH_W = (0x10 << 6) | OPC_ADDUH_QB_DSP,
514 OPC_ADDQH_R_W = (0x12 << 6) | OPC_ADDUH_QB_DSP,
515 OPC_SUBUH_QB = (0x01 << 6) | OPC_ADDUH_QB_DSP,
516 OPC_SUBUH_R_QB = (0x03 << 6) | OPC_ADDUH_QB_DSP,
517 OPC_SUBQH_PH = (0x09 << 6) | OPC_ADDUH_QB_DSP,
518 OPC_SUBQH_R_PH = (0x0B << 6) | OPC_ADDUH_QB_DSP,
519 OPC_SUBQH_W = (0x11 << 6) | OPC_ADDUH_QB_DSP,
520 OPC_SUBQH_R_W = (0x13 << 6) | OPC_ADDUH_QB_DSP,
521 /* MIPS DSP Multiply Sub-class insns */
522 OPC_MUL_PH = (0x0C << 6) | OPC_ADDUH_QB_DSP,
523 OPC_MUL_S_PH = (0x0E << 6) | OPC_ADDUH_QB_DSP,
524 OPC_MULQ_S_W = (0x16 << 6) | OPC_ADDUH_QB_DSP,
525 OPC_MULQ_RS_W = (0x17 << 6) | OPC_ADDUH_QB_DSP,
528 #define MASK_ABSQ_S_PH(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
529 enum {
530 /* MIPS DSP Arithmetic Sub-class */
531 OPC_ABSQ_S_QB = (0x01 << 6) | OPC_ABSQ_S_PH_DSP,
532 OPC_ABSQ_S_PH = (0x09 << 6) | OPC_ABSQ_S_PH_DSP,
533 OPC_ABSQ_S_W = (0x11 << 6) | OPC_ABSQ_S_PH_DSP,
534 OPC_PRECEQ_W_PHL = (0x0C << 6) | OPC_ABSQ_S_PH_DSP,
535 OPC_PRECEQ_W_PHR = (0x0D << 6) | OPC_ABSQ_S_PH_DSP,
536 OPC_PRECEQU_PH_QBL = (0x04 << 6) | OPC_ABSQ_S_PH_DSP,
537 OPC_PRECEQU_PH_QBR = (0x05 << 6) | OPC_ABSQ_S_PH_DSP,
538 OPC_PRECEQU_PH_QBLA = (0x06 << 6) | OPC_ABSQ_S_PH_DSP,
539 OPC_PRECEQU_PH_QBRA = (0x07 << 6) | OPC_ABSQ_S_PH_DSP,
540 OPC_PRECEU_PH_QBL = (0x1C << 6) | OPC_ABSQ_S_PH_DSP,
541 OPC_PRECEU_PH_QBR = (0x1D << 6) | OPC_ABSQ_S_PH_DSP,
542 OPC_PRECEU_PH_QBLA = (0x1E << 6) | OPC_ABSQ_S_PH_DSP,
543 OPC_PRECEU_PH_QBRA = (0x1F << 6) | OPC_ABSQ_S_PH_DSP,
544 /* DSP Bit/Manipulation Sub-class */
545 OPC_BITREV = (0x1B << 6) | OPC_ABSQ_S_PH_DSP,
546 OPC_REPL_QB = (0x02 << 6) | OPC_ABSQ_S_PH_DSP,
547 OPC_REPLV_QB = (0x03 << 6) | OPC_ABSQ_S_PH_DSP,
548 OPC_REPL_PH = (0x0A << 6) | OPC_ABSQ_S_PH_DSP,
549 OPC_REPLV_PH = (0x0B << 6) | OPC_ABSQ_S_PH_DSP,
552 #define MASK_CMPU_EQ_QB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
553 enum {
554 /* MIPS DSP Arithmetic Sub-class */
555 OPC_PRECR_QB_PH = (0x0D << 6) | OPC_CMPU_EQ_QB_DSP,
556 OPC_PRECRQ_QB_PH = (0x0C << 6) | OPC_CMPU_EQ_QB_DSP,
557 OPC_PRECR_SRA_PH_W = (0x1E << 6) | OPC_CMPU_EQ_QB_DSP,
558 OPC_PRECR_SRA_R_PH_W = (0x1F << 6) | OPC_CMPU_EQ_QB_DSP,
559 OPC_PRECRQ_PH_W = (0x14 << 6) | OPC_CMPU_EQ_QB_DSP,
560 OPC_PRECRQ_RS_PH_W = (0x15 << 6) | OPC_CMPU_EQ_QB_DSP,
561 OPC_PRECRQU_S_QB_PH = (0x0F << 6) | OPC_CMPU_EQ_QB_DSP,
562 /* DSP Compare-Pick Sub-class */
563 OPC_CMPU_EQ_QB = (0x00 << 6) | OPC_CMPU_EQ_QB_DSP,
564 OPC_CMPU_LT_QB = (0x01 << 6) | OPC_CMPU_EQ_QB_DSP,
565 OPC_CMPU_LE_QB = (0x02 << 6) | OPC_CMPU_EQ_QB_DSP,
566 OPC_CMPGU_EQ_QB = (0x04 << 6) | OPC_CMPU_EQ_QB_DSP,
567 OPC_CMPGU_LT_QB = (0x05 << 6) | OPC_CMPU_EQ_QB_DSP,
568 OPC_CMPGU_LE_QB = (0x06 << 6) | OPC_CMPU_EQ_QB_DSP,
569 OPC_CMPGDU_EQ_QB = (0x18 << 6) | OPC_CMPU_EQ_QB_DSP,
570 OPC_CMPGDU_LT_QB = (0x19 << 6) | OPC_CMPU_EQ_QB_DSP,
571 OPC_CMPGDU_LE_QB = (0x1A << 6) | OPC_CMPU_EQ_QB_DSP,
572 OPC_CMP_EQ_PH = (0x08 << 6) | OPC_CMPU_EQ_QB_DSP,
573 OPC_CMP_LT_PH = (0x09 << 6) | OPC_CMPU_EQ_QB_DSP,
574 OPC_CMP_LE_PH = (0x0A << 6) | OPC_CMPU_EQ_QB_DSP,
575 OPC_PICK_QB = (0x03 << 6) | OPC_CMPU_EQ_QB_DSP,
576 OPC_PICK_PH = (0x0B << 6) | OPC_CMPU_EQ_QB_DSP,
577 OPC_PACKRL_PH = (0x0E << 6) | OPC_CMPU_EQ_QB_DSP,
580 #define MASK_SHLL_QB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
581 enum {
582 /* MIPS DSP GPR-Based Shift Sub-class */
583 OPC_SHLL_QB = (0x00 << 6) | OPC_SHLL_QB_DSP,
584 OPC_SHLLV_QB = (0x02 << 6) | OPC_SHLL_QB_DSP,
585 OPC_SHLL_PH = (0x08 << 6) | OPC_SHLL_QB_DSP,
586 OPC_SHLLV_PH = (0x0A << 6) | OPC_SHLL_QB_DSP,
587 OPC_SHLL_S_PH = (0x0C << 6) | OPC_SHLL_QB_DSP,
588 OPC_SHLLV_S_PH = (0x0E << 6) | OPC_SHLL_QB_DSP,
589 OPC_SHLL_S_W = (0x14 << 6) | OPC_SHLL_QB_DSP,
590 OPC_SHLLV_S_W = (0x16 << 6) | OPC_SHLL_QB_DSP,
591 OPC_SHRL_QB = (0x01 << 6) | OPC_SHLL_QB_DSP,
592 OPC_SHRLV_QB = (0x03 << 6) | OPC_SHLL_QB_DSP,
593 OPC_SHRL_PH = (0x19 << 6) | OPC_SHLL_QB_DSP,
594 OPC_SHRLV_PH = (0x1B << 6) | OPC_SHLL_QB_DSP,
595 OPC_SHRA_QB = (0x04 << 6) | OPC_SHLL_QB_DSP,
596 OPC_SHRA_R_QB = (0x05 << 6) | OPC_SHLL_QB_DSP,
597 OPC_SHRAV_QB = (0x06 << 6) | OPC_SHLL_QB_DSP,
598 OPC_SHRAV_R_QB = (0x07 << 6) | OPC_SHLL_QB_DSP,
599 OPC_SHRA_PH = (0x09 << 6) | OPC_SHLL_QB_DSP,
600 OPC_SHRAV_PH = (0x0B << 6) | OPC_SHLL_QB_DSP,
601 OPC_SHRA_R_PH = (0x0D << 6) | OPC_SHLL_QB_DSP,
602 OPC_SHRAV_R_PH = (0x0F << 6) | OPC_SHLL_QB_DSP,
603 OPC_SHRA_R_W = (0x15 << 6) | OPC_SHLL_QB_DSP,
604 OPC_SHRAV_R_W = (0x17 << 6) | OPC_SHLL_QB_DSP,
607 #define MASK_DPA_W_PH(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
608 enum {
609 /* MIPS DSP Multiply Sub-class insns */
610 OPC_DPAU_H_QBL = (0x03 << 6) | OPC_DPA_W_PH_DSP,
611 OPC_DPAU_H_QBR = (0x07 << 6) | OPC_DPA_W_PH_DSP,
612 OPC_DPSU_H_QBL = (0x0B << 6) | OPC_DPA_W_PH_DSP,
613 OPC_DPSU_H_QBR = (0x0F << 6) | OPC_DPA_W_PH_DSP,
614 OPC_DPA_W_PH = (0x00 << 6) | OPC_DPA_W_PH_DSP,
615 OPC_DPAX_W_PH = (0x08 << 6) | OPC_DPA_W_PH_DSP,
616 OPC_DPAQ_S_W_PH = (0x04 << 6) | OPC_DPA_W_PH_DSP,
617 OPC_DPAQX_S_W_PH = (0x18 << 6) | OPC_DPA_W_PH_DSP,
618 OPC_DPAQX_SA_W_PH = (0x1A << 6) | OPC_DPA_W_PH_DSP,
619 OPC_DPS_W_PH = (0x01 << 6) | OPC_DPA_W_PH_DSP,
620 OPC_DPSX_W_PH = (0x09 << 6) | OPC_DPA_W_PH_DSP,
621 OPC_DPSQ_S_W_PH = (0x05 << 6) | OPC_DPA_W_PH_DSP,
622 OPC_DPSQX_S_W_PH = (0x19 << 6) | OPC_DPA_W_PH_DSP,
623 OPC_DPSQX_SA_W_PH = (0x1B << 6) | OPC_DPA_W_PH_DSP,
624 OPC_MULSAQ_S_W_PH = (0x06 << 6) | OPC_DPA_W_PH_DSP,
625 OPC_DPAQ_SA_L_W = (0x0C << 6) | OPC_DPA_W_PH_DSP,
626 OPC_DPSQ_SA_L_W = (0x0D << 6) | OPC_DPA_W_PH_DSP,
627 OPC_MAQ_S_W_PHL = (0x14 << 6) | OPC_DPA_W_PH_DSP,
628 OPC_MAQ_S_W_PHR = (0x16 << 6) | OPC_DPA_W_PH_DSP,
629 OPC_MAQ_SA_W_PHL = (0x10 << 6) | OPC_DPA_W_PH_DSP,
630 OPC_MAQ_SA_W_PHR = (0x12 << 6) | OPC_DPA_W_PH_DSP,
631 OPC_MULSA_W_PH = (0x02 << 6) | OPC_DPA_W_PH_DSP,
634 #define MASK_INSV(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
635 enum {
636 /* DSP Bit/Manipulation Sub-class */
637 OPC_INSV = (0x00 << 6) | OPC_INSV_DSP,
640 #define MASK_APPEND(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
641 enum {
642 /* MIPS DSP Append Sub-class */
643 OPC_APPEND = (0x00 << 6) | OPC_APPEND_DSP,
644 OPC_PREPEND = (0x01 << 6) | OPC_APPEND_DSP,
645 OPC_BALIGN = (0x10 << 6) | OPC_APPEND_DSP,
648 #define MASK_EXTR_W(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
649 enum {
650 /* MIPS DSP Accumulator and DSPControl Access Sub-class */
651 OPC_EXTR_W = (0x00 << 6) | OPC_EXTR_W_DSP,
652 OPC_EXTR_R_W = (0x04 << 6) | OPC_EXTR_W_DSP,
653 OPC_EXTR_RS_W = (0x06 << 6) | OPC_EXTR_W_DSP,
654 OPC_EXTR_S_H = (0x0E << 6) | OPC_EXTR_W_DSP,
655 OPC_EXTRV_S_H = (0x0F << 6) | OPC_EXTR_W_DSP,
656 OPC_EXTRV_W = (0x01 << 6) | OPC_EXTR_W_DSP,
657 OPC_EXTRV_R_W = (0x05 << 6) | OPC_EXTR_W_DSP,
658 OPC_EXTRV_RS_W = (0x07 << 6) | OPC_EXTR_W_DSP,
659 OPC_EXTP = (0x02 << 6) | OPC_EXTR_W_DSP,
660 OPC_EXTPV = (0x03 << 6) | OPC_EXTR_W_DSP,
661 OPC_EXTPDP = (0x0A << 6) | OPC_EXTR_W_DSP,
662 OPC_EXTPDPV = (0x0B << 6) | OPC_EXTR_W_DSP,
663 OPC_SHILO = (0x1A << 6) | OPC_EXTR_W_DSP,
664 OPC_SHILOV = (0x1B << 6) | OPC_EXTR_W_DSP,
665 OPC_MTHLIP = (0x1F << 6) | OPC_EXTR_W_DSP,
666 OPC_WRDSP = (0x13 << 6) | OPC_EXTR_W_DSP,
667 OPC_RDDSP = (0x12 << 6) | OPC_EXTR_W_DSP,
670 #define MASK_ABSQ_S_QH(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
671 enum {
672 /* MIPS DSP Arithmetic Sub-class */
673 OPC_PRECEQ_L_PWL = (0x14 << 6) | OPC_ABSQ_S_QH_DSP,
674 OPC_PRECEQ_L_PWR = (0x15 << 6) | OPC_ABSQ_S_QH_DSP,
675 OPC_PRECEQ_PW_QHL = (0x0C << 6) | OPC_ABSQ_S_QH_DSP,
676 OPC_PRECEQ_PW_QHR = (0x0D << 6) | OPC_ABSQ_S_QH_DSP,
677 OPC_PRECEQ_PW_QHLA = (0x0E << 6) | OPC_ABSQ_S_QH_DSP,
678 OPC_PRECEQ_PW_QHRA = (0x0F << 6) | OPC_ABSQ_S_QH_DSP,
679 OPC_PRECEQU_QH_OBL = (0x04 << 6) | OPC_ABSQ_S_QH_DSP,
680 OPC_PRECEQU_QH_OBR = (0x05 << 6) | OPC_ABSQ_S_QH_DSP,
681 OPC_PRECEQU_QH_OBLA = (0x06 << 6) | OPC_ABSQ_S_QH_DSP,
682 OPC_PRECEQU_QH_OBRA = (0x07 << 6) | OPC_ABSQ_S_QH_DSP,
683 OPC_PRECEU_QH_OBL = (0x1C << 6) | OPC_ABSQ_S_QH_DSP,
684 OPC_PRECEU_QH_OBR = (0x1D << 6) | OPC_ABSQ_S_QH_DSP,
685 OPC_PRECEU_QH_OBLA = (0x1E << 6) | OPC_ABSQ_S_QH_DSP,
686 OPC_PRECEU_QH_OBRA = (0x1F << 6) | OPC_ABSQ_S_QH_DSP,
687 OPC_ABSQ_S_OB = (0x01 << 6) | OPC_ABSQ_S_QH_DSP,
688 OPC_ABSQ_S_PW = (0x11 << 6) | OPC_ABSQ_S_QH_DSP,
689 OPC_ABSQ_S_QH = (0x09 << 6) | OPC_ABSQ_S_QH_DSP,
690 /* DSP Bit/Manipulation Sub-class */
691 OPC_REPL_OB = (0x02 << 6) | OPC_ABSQ_S_QH_DSP,
692 OPC_REPL_PW = (0x12 << 6) | OPC_ABSQ_S_QH_DSP,
693 OPC_REPL_QH = (0x0A << 6) | OPC_ABSQ_S_QH_DSP,
694 OPC_REPLV_OB = (0x03 << 6) | OPC_ABSQ_S_QH_DSP,
695 OPC_REPLV_PW = (0x13 << 6) | OPC_ABSQ_S_QH_DSP,
696 OPC_REPLV_QH = (0x0B << 6) | OPC_ABSQ_S_QH_DSP,
699 #define MASK_ADDU_OB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
700 enum {
701 /* MIPS DSP Multiply Sub-class insns */
702 OPC_MULEQ_S_PW_QHL = (0x1C << 6) | OPC_ADDU_OB_DSP,
703 OPC_MULEQ_S_PW_QHR = (0x1D << 6) | OPC_ADDU_OB_DSP,
704 OPC_MULEU_S_QH_OBL = (0x06 << 6) | OPC_ADDU_OB_DSP,
705 OPC_MULEU_S_QH_OBR = (0x07 << 6) | OPC_ADDU_OB_DSP,
706 OPC_MULQ_RS_QH = (0x1F << 6) | OPC_ADDU_OB_DSP,
707 /* MIPS DSP Arithmetic Sub-class */
708 OPC_RADDU_L_OB = (0x14 << 6) | OPC_ADDU_OB_DSP,
709 OPC_SUBQ_PW = (0x13 << 6) | OPC_ADDU_OB_DSP,
710 OPC_SUBQ_S_PW = (0x17 << 6) | OPC_ADDU_OB_DSP,
711 OPC_SUBQ_QH = (0x0B << 6) | OPC_ADDU_OB_DSP,
712 OPC_SUBQ_S_QH = (0x0F << 6) | OPC_ADDU_OB_DSP,
713 OPC_SUBU_OB = (0x01 << 6) | OPC_ADDU_OB_DSP,
714 OPC_SUBU_S_OB = (0x05 << 6) | OPC_ADDU_OB_DSP,
715 OPC_SUBU_QH = (0x09 << 6) | OPC_ADDU_OB_DSP,
716 OPC_SUBU_S_QH = (0x0D << 6) | OPC_ADDU_OB_DSP,
717 OPC_SUBUH_OB = (0x19 << 6) | OPC_ADDU_OB_DSP,
718 OPC_SUBUH_R_OB = (0x1B << 6) | OPC_ADDU_OB_DSP,
719 OPC_ADDQ_PW = (0x12 << 6) | OPC_ADDU_OB_DSP,
720 OPC_ADDQ_S_PW = (0x16 << 6) | OPC_ADDU_OB_DSP,
721 OPC_ADDQ_QH = (0x0A << 6) | OPC_ADDU_OB_DSP,
722 OPC_ADDQ_S_QH = (0x0E << 6) | OPC_ADDU_OB_DSP,
723 OPC_ADDU_OB = (0x00 << 6) | OPC_ADDU_OB_DSP,
724 OPC_ADDU_S_OB = (0x04 << 6) | OPC_ADDU_OB_DSP,
725 OPC_ADDU_QH = (0x08 << 6) | OPC_ADDU_OB_DSP,
726 OPC_ADDU_S_QH = (0x0C << 6) | OPC_ADDU_OB_DSP,
727 OPC_ADDUH_OB = (0x18 << 6) | OPC_ADDU_OB_DSP,
728 OPC_ADDUH_R_OB = (0x1A << 6) | OPC_ADDU_OB_DSP,
731 #define MASK_CMPU_EQ_OB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
732 enum {
733 /* DSP Compare-Pick Sub-class */
734 OPC_CMP_EQ_PW = (0x10 << 6) | OPC_CMPU_EQ_OB_DSP,
735 OPC_CMP_LT_PW = (0x11 << 6) | OPC_CMPU_EQ_OB_DSP,
736 OPC_CMP_LE_PW = (0x12 << 6) | OPC_CMPU_EQ_OB_DSP,
737 OPC_CMP_EQ_QH = (0x08 << 6) | OPC_CMPU_EQ_OB_DSP,
738 OPC_CMP_LT_QH = (0x09 << 6) | OPC_CMPU_EQ_OB_DSP,
739 OPC_CMP_LE_QH = (0x0A << 6) | OPC_CMPU_EQ_OB_DSP,
740 OPC_CMPGDU_EQ_OB = (0x18 << 6) | OPC_CMPU_EQ_OB_DSP,
741 OPC_CMPGDU_LT_OB = (0x19 << 6) | OPC_CMPU_EQ_OB_DSP,
742 OPC_CMPGDU_LE_OB = (0x1A << 6) | OPC_CMPU_EQ_OB_DSP,
743 OPC_CMPGU_EQ_OB = (0x04 << 6) | OPC_CMPU_EQ_OB_DSP,
744 OPC_CMPGU_LT_OB = (0x05 << 6) | OPC_CMPU_EQ_OB_DSP,
745 OPC_CMPGU_LE_OB = (0x06 << 6) | OPC_CMPU_EQ_OB_DSP,
746 OPC_CMPU_EQ_OB = (0x00 << 6) | OPC_CMPU_EQ_OB_DSP,
747 OPC_CMPU_LT_OB = (0x01 << 6) | OPC_CMPU_EQ_OB_DSP,
748 OPC_CMPU_LE_OB = (0x02 << 6) | OPC_CMPU_EQ_OB_DSP,
749 OPC_PACKRL_PW = (0x0E << 6) | OPC_CMPU_EQ_OB_DSP,
750 OPC_PICK_OB = (0x03 << 6) | OPC_CMPU_EQ_OB_DSP,
751 OPC_PICK_PW = (0x13 << 6) | OPC_CMPU_EQ_OB_DSP,
752 OPC_PICK_QH = (0x0B << 6) | OPC_CMPU_EQ_OB_DSP,
753 /* MIPS DSP Arithmetic Sub-class */
754 OPC_PRECR_OB_QH = (0x0D << 6) | OPC_CMPU_EQ_OB_DSP,
755 OPC_PRECR_SRA_QH_PW = (0x1E << 6) | OPC_CMPU_EQ_OB_DSP,
756 OPC_PRECR_SRA_R_QH_PW = (0x1F << 6) | OPC_CMPU_EQ_OB_DSP,
757 OPC_PRECRQ_OB_QH = (0x0C << 6) | OPC_CMPU_EQ_OB_DSP,
758 OPC_PRECRQ_PW_L = (0x1C << 6) | OPC_CMPU_EQ_OB_DSP,
759 OPC_PRECRQ_QH_PW = (0x14 << 6) | OPC_CMPU_EQ_OB_DSP,
760 OPC_PRECRQ_RS_QH_PW = (0x15 << 6) | OPC_CMPU_EQ_OB_DSP,
761 OPC_PRECRQU_S_OB_QH = (0x0F << 6) | OPC_CMPU_EQ_OB_DSP,
764 #define MASK_DAPPEND(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
765 enum {
766 /* DSP Append Sub-class */
767 OPC_DAPPEND = (0x00 << 6) | OPC_DAPPEND_DSP,
768 OPC_PREPENDD = (0x03 << 6) | OPC_DAPPEND_DSP,
769 OPC_PREPENDW = (0x01 << 6) | OPC_DAPPEND_DSP,
770 OPC_DBALIGN = (0x10 << 6) | OPC_DAPPEND_DSP,
773 #define MASK_DEXTR_W(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
774 enum {
775 /* MIPS DSP Accumulator and DSPControl Access Sub-class */
776 OPC_DMTHLIP = (0x1F << 6) | OPC_DEXTR_W_DSP,
777 OPC_DSHILO = (0x1A << 6) | OPC_DEXTR_W_DSP,
778 OPC_DEXTP = (0x02 << 6) | OPC_DEXTR_W_DSP,
779 OPC_DEXTPDP = (0x0A << 6) | OPC_DEXTR_W_DSP,
780 OPC_DEXTPDPV = (0x0B << 6) | OPC_DEXTR_W_DSP,
781 OPC_DEXTPV = (0x03 << 6) | OPC_DEXTR_W_DSP,
782 OPC_DEXTR_L = (0x10 << 6) | OPC_DEXTR_W_DSP,
783 OPC_DEXTR_R_L = (0x14 << 6) | OPC_DEXTR_W_DSP,
784 OPC_DEXTR_RS_L = (0x16 << 6) | OPC_DEXTR_W_DSP,
785 OPC_DEXTR_W = (0x00 << 6) | OPC_DEXTR_W_DSP,
786 OPC_DEXTR_R_W = (0x04 << 6) | OPC_DEXTR_W_DSP,
787 OPC_DEXTR_RS_W = (0x06 << 6) | OPC_DEXTR_W_DSP,
788 OPC_DEXTR_S_H = (0x0E << 6) | OPC_DEXTR_W_DSP,
789 OPC_DEXTRV_L = (0x11 << 6) | OPC_DEXTR_W_DSP,
790 OPC_DEXTRV_R_L = (0x15 << 6) | OPC_DEXTR_W_DSP,
791 OPC_DEXTRV_RS_L = (0x17 << 6) | OPC_DEXTR_W_DSP,
792 OPC_DEXTRV_S_H = (0x0F << 6) | OPC_DEXTR_W_DSP,
793 OPC_DEXTRV_W = (0x01 << 6) | OPC_DEXTR_W_DSP,
794 OPC_DEXTRV_R_W = (0x05 << 6) | OPC_DEXTR_W_DSP,
795 OPC_DEXTRV_RS_W = (0x07 << 6) | OPC_DEXTR_W_DSP,
796 OPC_DSHILOV = (0x1B << 6) | OPC_DEXTR_W_DSP,
799 #define MASK_DINSV(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
800 enum {
801 /* DSP Bit/Manipulation Sub-class */
802 OPC_DINSV = (0x00 << 6) | OPC_DINSV_DSP,
805 #define MASK_DPAQ_W_QH(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
806 enum {
807 /* MIPS DSP Multiply Sub-class insns */
808 OPC_DMADD = (0x19 << 6) | OPC_DPAQ_W_QH_DSP,
809 OPC_DMADDU = (0x1D << 6) | OPC_DPAQ_W_QH_DSP,
810 OPC_DMSUB = (0x1B << 6) | OPC_DPAQ_W_QH_DSP,
811 OPC_DMSUBU = (0x1F << 6) | OPC_DPAQ_W_QH_DSP,
812 OPC_DPA_W_QH = (0x00 << 6) | OPC_DPAQ_W_QH_DSP,
813 OPC_DPAQ_S_W_QH = (0x04 << 6) | OPC_DPAQ_W_QH_DSP,
814 OPC_DPAQ_SA_L_PW = (0x0C << 6) | OPC_DPAQ_W_QH_DSP,
815 OPC_DPAU_H_OBL = (0x03 << 6) | OPC_DPAQ_W_QH_DSP,
816 OPC_DPAU_H_OBR = (0x07 << 6) | OPC_DPAQ_W_QH_DSP,
817 OPC_DPS_W_QH = (0x01 << 6) | OPC_DPAQ_W_QH_DSP,
818 OPC_DPSQ_S_W_QH = (0x05 << 6) | OPC_DPAQ_W_QH_DSP,
819 OPC_DPSQ_SA_L_PW = (0x0D << 6) | OPC_DPAQ_W_QH_DSP,
820 OPC_DPSU_H_OBL = (0x0B << 6) | OPC_DPAQ_W_QH_DSP,
821 OPC_DPSU_H_OBR = (0x0F << 6) | OPC_DPAQ_W_QH_DSP,
822 OPC_MAQ_S_L_PWL = (0x1C << 6) | OPC_DPAQ_W_QH_DSP,
823 OPC_MAQ_S_L_PWR = (0x1E << 6) | OPC_DPAQ_W_QH_DSP,
824 OPC_MAQ_S_W_QHLL = (0x14 << 6) | OPC_DPAQ_W_QH_DSP,
825 OPC_MAQ_SA_W_QHLL = (0x10 << 6) | OPC_DPAQ_W_QH_DSP,
826 OPC_MAQ_S_W_QHLR = (0x15 << 6) | OPC_DPAQ_W_QH_DSP,
827 OPC_MAQ_SA_W_QHLR = (0x11 << 6) | OPC_DPAQ_W_QH_DSP,
828 OPC_MAQ_S_W_QHRL = (0x16 << 6) | OPC_DPAQ_W_QH_DSP,
829 OPC_MAQ_SA_W_QHRL = (0x12 << 6) | OPC_DPAQ_W_QH_DSP,
830 OPC_MAQ_S_W_QHRR = (0x17 << 6) | OPC_DPAQ_W_QH_DSP,
831 OPC_MAQ_SA_W_QHRR = (0x13 << 6) | OPC_DPAQ_W_QH_DSP,
832 OPC_MULSAQ_S_L_PW = (0x0E << 6) | OPC_DPAQ_W_QH_DSP,
833 OPC_MULSAQ_S_W_QH = (0x06 << 6) | OPC_DPAQ_W_QH_DSP,
836 #define MASK_SHLL_OB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
837 enum {
838 /* MIPS DSP GPR-Based Shift Sub-class */
839 OPC_SHLL_PW = (0x10 << 6) | OPC_SHLL_OB_DSP,
840 OPC_SHLL_S_PW = (0x14 << 6) | OPC_SHLL_OB_DSP,
841 OPC_SHLLV_OB = (0x02 << 6) | OPC_SHLL_OB_DSP,
842 OPC_SHLLV_PW = (0x12 << 6) | OPC_SHLL_OB_DSP,
843 OPC_SHLLV_S_PW = (0x16 << 6) | OPC_SHLL_OB_DSP,
844 OPC_SHLLV_QH = (0x0A << 6) | OPC_SHLL_OB_DSP,
845 OPC_SHLLV_S_QH = (0x0E << 6) | OPC_SHLL_OB_DSP,
846 OPC_SHRA_PW = (0x11 << 6) | OPC_SHLL_OB_DSP,
847 OPC_SHRA_R_PW = (0x15 << 6) | OPC_SHLL_OB_DSP,
848 OPC_SHRAV_OB = (0x06 << 6) | OPC_SHLL_OB_DSP,
849 OPC_SHRAV_R_OB = (0x07 << 6) | OPC_SHLL_OB_DSP,
850 OPC_SHRAV_PW = (0x13 << 6) | OPC_SHLL_OB_DSP,
851 OPC_SHRAV_R_PW = (0x17 << 6) | OPC_SHLL_OB_DSP,
852 OPC_SHRAV_QH = (0x0B << 6) | OPC_SHLL_OB_DSP,
853 OPC_SHRAV_R_QH = (0x0F << 6) | OPC_SHLL_OB_DSP,
854 OPC_SHRLV_OB = (0x03 << 6) | OPC_SHLL_OB_DSP,
855 OPC_SHRLV_QH = (0x1B << 6) | OPC_SHLL_OB_DSP,
856 OPC_SHLL_OB = (0x00 << 6) | OPC_SHLL_OB_DSP,
857 OPC_SHLL_QH = (0x08 << 6) | OPC_SHLL_OB_DSP,
858 OPC_SHLL_S_QH = (0x0C << 6) | OPC_SHLL_OB_DSP,
859 OPC_SHRA_OB = (0x04 << 6) | OPC_SHLL_OB_DSP,
860 OPC_SHRA_R_OB = (0x05 << 6) | OPC_SHLL_OB_DSP,
861 OPC_SHRA_QH = (0x09 << 6) | OPC_SHLL_OB_DSP,
862 OPC_SHRA_R_QH = (0x0D << 6) | OPC_SHLL_OB_DSP,
863 OPC_SHRL_OB = (0x01 << 6) | OPC_SHLL_OB_DSP,
864 OPC_SHRL_QH = (0x19 << 6) | OPC_SHLL_OB_DSP,
867 /* Coprocessor 0 (rs field) */
868 #define MASK_CP0(op) MASK_OP_MAJOR(op) | (op & (0x1F << 21))
870 enum {
871 OPC_MFC0 = (0x00 << 21) | OPC_CP0,
872 OPC_DMFC0 = (0x01 << 21) | OPC_CP0,
873 OPC_MFHC0 = (0x02 << 21) | OPC_CP0,
874 OPC_MTC0 = (0x04 << 21) | OPC_CP0,
875 OPC_DMTC0 = (0x05 << 21) | OPC_CP0,
876 OPC_MTHC0 = (0x06 << 21) | OPC_CP0,
877 OPC_MFTR = (0x08 << 21) | OPC_CP0,
878 OPC_RDPGPR = (0x0A << 21) | OPC_CP0,
879 OPC_MFMC0 = (0x0B << 21) | OPC_CP0,
880 OPC_MTTR = (0x0C << 21) | OPC_CP0,
881 OPC_WRPGPR = (0x0E << 21) | OPC_CP0,
882 OPC_C0 = (0x10 << 21) | OPC_CP0,
883 OPC_C0_FIRST = (0x10 << 21) | OPC_CP0,
884 OPC_C0_LAST = (0x1F << 21) | OPC_CP0,
887 /* MFMC0 opcodes */
888 #define MASK_MFMC0(op) MASK_CP0(op) | (op & 0xFFFF)
890 enum {
891 OPC_DMT = 0x01 | (0 << 5) | (0x0F << 6) | (0x01 << 11) | OPC_MFMC0,
892 OPC_EMT = 0x01 | (1 << 5) | (0x0F << 6) | (0x01 << 11) | OPC_MFMC0,
893 OPC_DVPE = 0x01 | (0 << 5) | OPC_MFMC0,
894 OPC_EVPE = 0x01 | (1 << 5) | OPC_MFMC0,
895 OPC_DI = (0 << 5) | (0x0C << 11) | OPC_MFMC0,
896 OPC_EI = (1 << 5) | (0x0C << 11) | OPC_MFMC0,
897 OPC_DVP = 0x04 | (0 << 3) | (1 << 5) | (0 << 11) | OPC_MFMC0,
898 OPC_EVP = 0x04 | (0 << 3) | (0 << 5) | (0 << 11) | OPC_MFMC0,
901 /* Coprocessor 0 (with rs == C0) */
902 #define MASK_C0(op) MASK_CP0(op) | (op & 0x3F)
904 enum {
905 OPC_TLBR = 0x01 | OPC_C0,
906 OPC_TLBWI = 0x02 | OPC_C0,
907 OPC_TLBINV = 0x03 | OPC_C0,
908 OPC_TLBINVF = 0x04 | OPC_C0,
909 OPC_TLBWR = 0x06 | OPC_C0,
910 OPC_TLBP = 0x08 | OPC_C0,
911 OPC_RFE = 0x10 | OPC_C0,
912 OPC_ERET = 0x18 | OPC_C0,
913 OPC_DERET = 0x1F | OPC_C0,
914 OPC_WAIT = 0x20 | OPC_C0,
917 /* Coprocessor 1 (rs field) */
918 #define MASK_CP1(op) MASK_OP_MAJOR(op) | (op & (0x1F << 21))
920 /* Values for the fmt field in FP instructions */
921 enum {
922 /* 0 - 15 are reserved */
923 FMT_S = 16, /* single fp */
924 FMT_D = 17, /* double fp */
925 FMT_E = 18, /* extended fp */
926 FMT_Q = 19, /* quad fp */
927 FMT_W = 20, /* 32-bit fixed */
928 FMT_L = 21, /* 64-bit fixed */
929 FMT_PS = 22, /* paired single fp */
930 /* 23 - 31 are reserved */
933 enum {
934 OPC_MFC1 = (0x00 << 21) | OPC_CP1,
935 OPC_DMFC1 = (0x01 << 21) | OPC_CP1,
936 OPC_CFC1 = (0x02 << 21) | OPC_CP1,
937 OPC_MFHC1 = (0x03 << 21) | OPC_CP1,
938 OPC_MTC1 = (0x04 << 21) | OPC_CP1,
939 OPC_DMTC1 = (0x05 << 21) | OPC_CP1,
940 OPC_CTC1 = (0x06 << 21) | OPC_CP1,
941 OPC_MTHC1 = (0x07 << 21) | OPC_CP1,
942 OPC_BC1 = (0x08 << 21) | OPC_CP1, /* bc */
943 OPC_BC1ANY2 = (0x09 << 21) | OPC_CP1,
944 OPC_BC1ANY4 = (0x0A << 21) | OPC_CP1,
945 OPC_BZ_V = (0x0B << 21) | OPC_CP1,
946 OPC_BNZ_V = (0x0F << 21) | OPC_CP1,
947 OPC_S_FMT = (FMT_S << 21) | OPC_CP1,
948 OPC_D_FMT = (FMT_D << 21) | OPC_CP1,
949 OPC_E_FMT = (FMT_E << 21) | OPC_CP1,
950 OPC_Q_FMT = (FMT_Q << 21) | OPC_CP1,
951 OPC_W_FMT = (FMT_W << 21) | OPC_CP1,
952 OPC_L_FMT = (FMT_L << 21) | OPC_CP1,
953 OPC_PS_FMT = (FMT_PS << 21) | OPC_CP1,
954 OPC_BC1EQZ = (0x09 << 21) | OPC_CP1,
955 OPC_BC1NEZ = (0x0D << 21) | OPC_CP1,
956 OPC_BZ_B = (0x18 << 21) | OPC_CP1,
957 OPC_BZ_H = (0x19 << 21) | OPC_CP1,
958 OPC_BZ_W = (0x1A << 21) | OPC_CP1,
959 OPC_BZ_D = (0x1B << 21) | OPC_CP1,
960 OPC_BNZ_B = (0x1C << 21) | OPC_CP1,
961 OPC_BNZ_H = (0x1D << 21) | OPC_CP1,
962 OPC_BNZ_W = (0x1E << 21) | OPC_CP1,
963 OPC_BNZ_D = (0x1F << 21) | OPC_CP1,
966 #define MASK_CP1_FUNC(op) MASK_CP1(op) | (op & 0x3F)
967 #define MASK_BC1(op) MASK_CP1(op) | (op & (0x3 << 16))
969 enum {
970 OPC_BC1F = (0x00 << 16) | OPC_BC1,
971 OPC_BC1T = (0x01 << 16) | OPC_BC1,
972 OPC_BC1FL = (0x02 << 16) | OPC_BC1,
973 OPC_BC1TL = (0x03 << 16) | OPC_BC1,
976 enum {
977 OPC_BC1FANY2 = (0x00 << 16) | OPC_BC1ANY2,
978 OPC_BC1TANY2 = (0x01 << 16) | OPC_BC1ANY2,
981 enum {
982 OPC_BC1FANY4 = (0x00 << 16) | OPC_BC1ANY4,
983 OPC_BC1TANY4 = (0x01 << 16) | OPC_BC1ANY4,
986 #define MASK_CP2(op) MASK_OP_MAJOR(op) | (op & (0x1F << 21))
988 enum {
989 OPC_MFC2 = (0x00 << 21) | OPC_CP2,
990 OPC_DMFC2 = (0x01 << 21) | OPC_CP2,
991 OPC_CFC2 = (0x02 << 21) | OPC_CP2,
992 OPC_MFHC2 = (0x03 << 21) | OPC_CP2,
993 OPC_MTC2 = (0x04 << 21) | OPC_CP2,
994 OPC_DMTC2 = (0x05 << 21) | OPC_CP2,
995 OPC_CTC2 = (0x06 << 21) | OPC_CP2,
996 OPC_MTHC2 = (0x07 << 21) | OPC_CP2,
997 OPC_BC2 = (0x08 << 21) | OPC_CP2,
998 OPC_BC2EQZ = (0x09 << 21) | OPC_CP2,
999 OPC_BC2NEZ = (0x0D << 21) | OPC_CP2,
1002 #define MASK_LMI(op) (MASK_OP_MAJOR(op) | (op & (0x1F << 21)) | (op & 0x1F))
1004 enum {
1005 OPC_PADDSH = (24 << 21) | (0x00) | OPC_CP2,
1006 OPC_PADDUSH = (25 << 21) | (0x00) | OPC_CP2,
1007 OPC_PADDH = (26 << 21) | (0x00) | OPC_CP2,
1008 OPC_PADDW = (27 << 21) | (0x00) | OPC_CP2,
1009 OPC_PADDSB = (28 << 21) | (0x00) | OPC_CP2,
1010 OPC_PADDUSB = (29 << 21) | (0x00) | OPC_CP2,
1011 OPC_PADDB = (30 << 21) | (0x00) | OPC_CP2,
1012 OPC_PADDD = (31 << 21) | (0x00) | OPC_CP2,
1014 OPC_PSUBSH = (24 << 21) | (0x01) | OPC_CP2,
1015 OPC_PSUBUSH = (25 << 21) | (0x01) | OPC_CP2,
1016 OPC_PSUBH = (26 << 21) | (0x01) | OPC_CP2,
1017 OPC_PSUBW = (27 << 21) | (0x01) | OPC_CP2,
1018 OPC_PSUBSB = (28 << 21) | (0x01) | OPC_CP2,
1019 OPC_PSUBUSB = (29 << 21) | (0x01) | OPC_CP2,
1020 OPC_PSUBB = (30 << 21) | (0x01) | OPC_CP2,
1021 OPC_PSUBD = (31 << 21) | (0x01) | OPC_CP2,
1023 OPC_PSHUFH = (24 << 21) | (0x02) | OPC_CP2,
1024 OPC_PACKSSWH = (25 << 21) | (0x02) | OPC_CP2,
1025 OPC_PACKSSHB = (26 << 21) | (0x02) | OPC_CP2,
1026 OPC_PACKUSHB = (27 << 21) | (0x02) | OPC_CP2,
1027 OPC_XOR_CP2 = (28 << 21) | (0x02) | OPC_CP2,
1028 OPC_NOR_CP2 = (29 << 21) | (0x02) | OPC_CP2,
1029 OPC_AND_CP2 = (30 << 21) | (0x02) | OPC_CP2,
1030 OPC_PANDN = (31 << 21) | (0x02) | OPC_CP2,
1032 OPC_PUNPCKLHW = (24 << 21) | (0x03) | OPC_CP2,
1033 OPC_PUNPCKHHW = (25 << 21) | (0x03) | OPC_CP2,
1034 OPC_PUNPCKLBH = (26 << 21) | (0x03) | OPC_CP2,
1035 OPC_PUNPCKHBH = (27 << 21) | (0x03) | OPC_CP2,
1036 OPC_PINSRH_0 = (28 << 21) | (0x03) | OPC_CP2,
1037 OPC_PINSRH_1 = (29 << 21) | (0x03) | OPC_CP2,
1038 OPC_PINSRH_2 = (30 << 21) | (0x03) | OPC_CP2,
1039 OPC_PINSRH_3 = (31 << 21) | (0x03) | OPC_CP2,
1041 OPC_PAVGH = (24 << 21) | (0x08) | OPC_CP2,
1042 OPC_PAVGB = (25 << 21) | (0x08) | OPC_CP2,
1043 OPC_PMAXSH = (26 << 21) | (0x08) | OPC_CP2,
1044 OPC_PMINSH = (27 << 21) | (0x08) | OPC_CP2,
1045 OPC_PMAXUB = (28 << 21) | (0x08) | OPC_CP2,
1046 OPC_PMINUB = (29 << 21) | (0x08) | OPC_CP2,
1048 OPC_PCMPEQW = (24 << 21) | (0x09) | OPC_CP2,
1049 OPC_PCMPGTW = (25 << 21) | (0x09) | OPC_CP2,
1050 OPC_PCMPEQH = (26 << 21) | (0x09) | OPC_CP2,
1051 OPC_PCMPGTH = (27 << 21) | (0x09) | OPC_CP2,
1052 OPC_PCMPEQB = (28 << 21) | (0x09) | OPC_CP2,
1053 OPC_PCMPGTB = (29 << 21) | (0x09) | OPC_CP2,
1055 OPC_PSLLW = (24 << 21) | (0x0A) | OPC_CP2,
1056 OPC_PSLLH = (25 << 21) | (0x0A) | OPC_CP2,
1057 OPC_PMULLH = (26 << 21) | (0x0A) | OPC_CP2,
1058 OPC_PMULHH = (27 << 21) | (0x0A) | OPC_CP2,
1059 OPC_PMULUW = (28 << 21) | (0x0A) | OPC_CP2,
1060 OPC_PMULHUH = (29 << 21) | (0x0A) | OPC_CP2,
1062 OPC_PSRLW = (24 << 21) | (0x0B) | OPC_CP2,
1063 OPC_PSRLH = (25 << 21) | (0x0B) | OPC_CP2,
1064 OPC_PSRAW = (26 << 21) | (0x0B) | OPC_CP2,
1065 OPC_PSRAH = (27 << 21) | (0x0B) | OPC_CP2,
1066 OPC_PUNPCKLWD = (28 << 21) | (0x0B) | OPC_CP2,
1067 OPC_PUNPCKHWD = (29 << 21) | (0x0B) | OPC_CP2,
1069 OPC_ADDU_CP2 = (24 << 21) | (0x0C) | OPC_CP2,
1070 OPC_OR_CP2 = (25 << 21) | (0x0C) | OPC_CP2,
1071 OPC_ADD_CP2 = (26 << 21) | (0x0C) | OPC_CP2,
1072 OPC_DADD_CP2 = (27 << 21) | (0x0C) | OPC_CP2,
1073 OPC_SEQU_CP2 = (28 << 21) | (0x0C) | OPC_CP2,
1074 OPC_SEQ_CP2 = (29 << 21) | (0x0C) | OPC_CP2,
1076 OPC_SUBU_CP2 = (24 << 21) | (0x0D) | OPC_CP2,
1077 OPC_PASUBUB = (25 << 21) | (0x0D) | OPC_CP2,
1078 OPC_SUB_CP2 = (26 << 21) | (0x0D) | OPC_CP2,
1079 OPC_DSUB_CP2 = (27 << 21) | (0x0D) | OPC_CP2,
1080 OPC_SLTU_CP2 = (28 << 21) | (0x0D) | OPC_CP2,
1081 OPC_SLT_CP2 = (29 << 21) | (0x0D) | OPC_CP2,
1083 OPC_SLL_CP2 = (24 << 21) | (0x0E) | OPC_CP2,
1084 OPC_DSLL_CP2 = (25 << 21) | (0x0E) | OPC_CP2,
1085 OPC_PEXTRH = (26 << 21) | (0x0E) | OPC_CP2,
1086 OPC_PMADDHW = (27 << 21) | (0x0E) | OPC_CP2,
1087 OPC_SLEU_CP2 = (28 << 21) | (0x0E) | OPC_CP2,
1088 OPC_SLE_CP2 = (29 << 21) | (0x0E) | OPC_CP2,
1090 OPC_SRL_CP2 = (24 << 21) | (0x0F) | OPC_CP2,
1091 OPC_DSRL_CP2 = (25 << 21) | (0x0F) | OPC_CP2,
1092 OPC_SRA_CP2 = (26 << 21) | (0x0F) | OPC_CP2,
1093 OPC_DSRA_CP2 = (27 << 21) | (0x0F) | OPC_CP2,
1094 OPC_BIADD = (28 << 21) | (0x0F) | OPC_CP2,
1095 OPC_PMOVMSKB = (29 << 21) | (0x0F) | OPC_CP2,
1099 #define MASK_CP3(op) MASK_OP_MAJOR(op) | (op & 0x3F)
1101 enum {
1102 OPC_LWXC1 = 0x00 | OPC_CP3,
1103 OPC_LDXC1 = 0x01 | OPC_CP3,
1104 OPC_LUXC1 = 0x05 | OPC_CP3,
1105 OPC_SWXC1 = 0x08 | OPC_CP3,
1106 OPC_SDXC1 = 0x09 | OPC_CP3,
1107 OPC_SUXC1 = 0x0D | OPC_CP3,
1108 OPC_PREFX = 0x0F | OPC_CP3,
1109 OPC_ALNV_PS = 0x1E | OPC_CP3,
1110 OPC_MADD_S = 0x20 | OPC_CP3,
1111 OPC_MADD_D = 0x21 | OPC_CP3,
1112 OPC_MADD_PS = 0x26 | OPC_CP3,
1113 OPC_MSUB_S = 0x28 | OPC_CP3,
1114 OPC_MSUB_D = 0x29 | OPC_CP3,
1115 OPC_MSUB_PS = 0x2E | OPC_CP3,
1116 OPC_NMADD_S = 0x30 | OPC_CP3,
1117 OPC_NMADD_D = 0x31 | OPC_CP3,
1118 OPC_NMADD_PS= 0x36 | OPC_CP3,
1119 OPC_NMSUB_S = 0x38 | OPC_CP3,
1120 OPC_NMSUB_D = 0x39 | OPC_CP3,
1121 OPC_NMSUB_PS= 0x3E | OPC_CP3,
1124 /* MSA Opcodes */
1125 #define MASK_MSA_MINOR(op) (MASK_OP_MAJOR(op) | (op & 0x3F))
1126 enum {
1127 OPC_MSA_I8_00 = 0x00 | OPC_MSA,
1128 OPC_MSA_I8_01 = 0x01 | OPC_MSA,
1129 OPC_MSA_I8_02 = 0x02 | OPC_MSA,
1130 OPC_MSA_I5_06 = 0x06 | OPC_MSA,
1131 OPC_MSA_I5_07 = 0x07 | OPC_MSA,
1132 OPC_MSA_BIT_09 = 0x09 | OPC_MSA,
1133 OPC_MSA_BIT_0A = 0x0A | OPC_MSA,
1134 OPC_MSA_3R_0D = 0x0D | OPC_MSA,
1135 OPC_MSA_3R_0E = 0x0E | OPC_MSA,
1136 OPC_MSA_3R_0F = 0x0F | OPC_MSA,
1137 OPC_MSA_3R_10 = 0x10 | OPC_MSA,
1138 OPC_MSA_3R_11 = 0x11 | OPC_MSA,
1139 OPC_MSA_3R_12 = 0x12 | OPC_MSA,
1140 OPC_MSA_3R_13 = 0x13 | OPC_MSA,
1141 OPC_MSA_3R_14 = 0x14 | OPC_MSA,
1142 OPC_MSA_3R_15 = 0x15 | OPC_MSA,
1143 OPC_MSA_ELM = 0x19 | OPC_MSA,
1144 OPC_MSA_3RF_1A = 0x1A | OPC_MSA,
1145 OPC_MSA_3RF_1B = 0x1B | OPC_MSA,
1146 OPC_MSA_3RF_1C = 0x1C | OPC_MSA,
1147 OPC_MSA_VEC = 0x1E | OPC_MSA,
1149 /* MI10 instruction */
1150 OPC_LD_B = (0x20) | OPC_MSA,
1151 OPC_LD_H = (0x21) | OPC_MSA,
1152 OPC_LD_W = (0x22) | OPC_MSA,
1153 OPC_LD_D = (0x23) | OPC_MSA,
1154 OPC_ST_B = (0x24) | OPC_MSA,
1155 OPC_ST_H = (0x25) | OPC_MSA,
1156 OPC_ST_W = (0x26) | OPC_MSA,
1157 OPC_ST_D = (0x27) | OPC_MSA,
1160 enum {
1161 /* I5 instruction df(bits 22..21) = _b, _h, _w, _d */
1162 OPC_ADDVI_df = (0x0 << 23) | OPC_MSA_I5_06,
1163 OPC_CEQI_df = (0x0 << 23) | OPC_MSA_I5_07,
1164 OPC_SUBVI_df = (0x1 << 23) | OPC_MSA_I5_06,
1165 OPC_MAXI_S_df = (0x2 << 23) | OPC_MSA_I5_06,
1166 OPC_CLTI_S_df = (0x2 << 23) | OPC_MSA_I5_07,
1167 OPC_MAXI_U_df = (0x3 << 23) | OPC_MSA_I5_06,
1168 OPC_CLTI_U_df = (0x3 << 23) | OPC_MSA_I5_07,
1169 OPC_MINI_S_df = (0x4 << 23) | OPC_MSA_I5_06,
1170 OPC_CLEI_S_df = (0x4 << 23) | OPC_MSA_I5_07,
1171 OPC_MINI_U_df = (0x5 << 23) | OPC_MSA_I5_06,
1172 OPC_CLEI_U_df = (0x5 << 23) | OPC_MSA_I5_07,
1173 OPC_LDI_df = (0x6 << 23) | OPC_MSA_I5_07,
1175 /* I8 instruction */
1176 OPC_ANDI_B = (0x0 << 24) | OPC_MSA_I8_00,
1177 OPC_BMNZI_B = (0x0 << 24) | OPC_MSA_I8_01,
1178 OPC_SHF_B = (0x0 << 24) | OPC_MSA_I8_02,
1179 OPC_ORI_B = (0x1 << 24) | OPC_MSA_I8_00,
1180 OPC_BMZI_B = (0x1 << 24) | OPC_MSA_I8_01,
1181 OPC_SHF_H = (0x1 << 24) | OPC_MSA_I8_02,
1182 OPC_NORI_B = (0x2 << 24) | OPC_MSA_I8_00,
1183 OPC_BSELI_B = (0x2 << 24) | OPC_MSA_I8_01,
1184 OPC_SHF_W = (0x2 << 24) | OPC_MSA_I8_02,
1185 OPC_XORI_B = (0x3 << 24) | OPC_MSA_I8_00,
1187 /* VEC/2R/2RF instruction */
1188 OPC_AND_V = (0x00 << 21) | OPC_MSA_VEC,
1189 OPC_OR_V = (0x01 << 21) | OPC_MSA_VEC,
1190 OPC_NOR_V = (0x02 << 21) | OPC_MSA_VEC,
1191 OPC_XOR_V = (0x03 << 21) | OPC_MSA_VEC,
1192 OPC_BMNZ_V = (0x04 << 21) | OPC_MSA_VEC,
1193 OPC_BMZ_V = (0x05 << 21) | OPC_MSA_VEC,
1194 OPC_BSEL_V = (0x06 << 21) | OPC_MSA_VEC,
1196 OPC_MSA_2R = (0x18 << 21) | OPC_MSA_VEC,
1197 OPC_MSA_2RF = (0x19 << 21) | OPC_MSA_VEC,
1199 /* 2R instruction df(bits 17..16) = _b, _h, _w, _d */
1200 OPC_FILL_df = (0x00 << 18) | OPC_MSA_2R,
1201 OPC_PCNT_df = (0x01 << 18) | OPC_MSA_2R,
1202 OPC_NLOC_df = (0x02 << 18) | OPC_MSA_2R,
1203 OPC_NLZC_df = (0x03 << 18) | OPC_MSA_2R,
1205 /* 2RF instruction df(bit 16) = _w, _d */
1206 OPC_FCLASS_df = (0x00 << 17) | OPC_MSA_2RF,
1207 OPC_FTRUNC_S_df = (0x01 << 17) | OPC_MSA_2RF,
1208 OPC_FTRUNC_U_df = (0x02 << 17) | OPC_MSA_2RF,
1209 OPC_FSQRT_df = (0x03 << 17) | OPC_MSA_2RF,
1210 OPC_FRSQRT_df = (0x04 << 17) | OPC_MSA_2RF,
1211 OPC_FRCP_df = (0x05 << 17) | OPC_MSA_2RF,
1212 OPC_FRINT_df = (0x06 << 17) | OPC_MSA_2RF,
1213 OPC_FLOG2_df = (0x07 << 17) | OPC_MSA_2RF,
1214 OPC_FEXUPL_df = (0x08 << 17) | OPC_MSA_2RF,
1215 OPC_FEXUPR_df = (0x09 << 17) | OPC_MSA_2RF,
1216 OPC_FFQL_df = (0x0A << 17) | OPC_MSA_2RF,
1217 OPC_FFQR_df = (0x0B << 17) | OPC_MSA_2RF,
1218 OPC_FTINT_S_df = (0x0C << 17) | OPC_MSA_2RF,
1219 OPC_FTINT_U_df = (0x0D << 17) | OPC_MSA_2RF,
1220 OPC_FFINT_S_df = (0x0E << 17) | OPC_MSA_2RF,
1221 OPC_FFINT_U_df = (0x0F << 17) | OPC_MSA_2RF,
1223 /* 3R instruction df(bits 22..21) = _b, _h, _w, d */
1224 OPC_SLL_df = (0x0 << 23) | OPC_MSA_3R_0D,
1225 OPC_ADDV_df = (0x0 << 23) | OPC_MSA_3R_0E,
1226 OPC_CEQ_df = (0x0 << 23) | OPC_MSA_3R_0F,
1227 OPC_ADD_A_df = (0x0 << 23) | OPC_MSA_3R_10,
1228 OPC_SUBS_S_df = (0x0 << 23) | OPC_MSA_3R_11,
1229 OPC_MULV_df = (0x0 << 23) | OPC_MSA_3R_12,
1230 OPC_DOTP_S_df = (0x0 << 23) | OPC_MSA_3R_13,
1231 OPC_SLD_df = (0x0 << 23) | OPC_MSA_3R_14,
1232 OPC_VSHF_df = (0x0 << 23) | OPC_MSA_3R_15,
1233 OPC_SRA_df = (0x1 << 23) | OPC_MSA_3R_0D,
1234 OPC_SUBV_df = (0x1 << 23) | OPC_MSA_3R_0E,
1235 OPC_ADDS_A_df = (0x1 << 23) | OPC_MSA_3R_10,
1236 OPC_SUBS_U_df = (0x1 << 23) | OPC_MSA_3R_11,
1237 OPC_MADDV_df = (0x1 << 23) | OPC_MSA_3R_12,
1238 OPC_DOTP_U_df = (0x1 << 23) | OPC_MSA_3R_13,
1239 OPC_SPLAT_df = (0x1 << 23) | OPC_MSA_3R_14,
1240 OPC_SRAR_df = (0x1 << 23) | OPC_MSA_3R_15,
1241 OPC_SRL_df = (0x2 << 23) | OPC_MSA_3R_0D,
1242 OPC_MAX_S_df = (0x2 << 23) | OPC_MSA_3R_0E,
1243 OPC_CLT_S_df = (0x2 << 23) | OPC_MSA_3R_0F,
1244 OPC_ADDS_S_df = (0x2 << 23) | OPC_MSA_3R_10,
1245 OPC_SUBSUS_U_df = (0x2 << 23) | OPC_MSA_3R_11,
1246 OPC_MSUBV_df = (0x2 << 23) | OPC_MSA_3R_12,
1247 OPC_DPADD_S_df = (0x2 << 23) | OPC_MSA_3R_13,
1248 OPC_PCKEV_df = (0x2 << 23) | OPC_MSA_3R_14,
1249 OPC_SRLR_df = (0x2 << 23) | OPC_MSA_3R_15,
1250 OPC_BCLR_df = (0x3 << 23) | OPC_MSA_3R_0D,
1251 OPC_MAX_U_df = (0x3 << 23) | OPC_MSA_3R_0E,
1252 OPC_CLT_U_df = (0x3 << 23) | OPC_MSA_3R_0F,
1253 OPC_ADDS_U_df = (0x3 << 23) | OPC_MSA_3R_10,
1254 OPC_SUBSUU_S_df = (0x3 << 23) | OPC_MSA_3R_11,
1255 OPC_DPADD_U_df = (0x3 << 23) | OPC_MSA_3R_13,
1256 OPC_PCKOD_df = (0x3 << 23) | OPC_MSA_3R_14,
1257 OPC_BSET_df = (0x4 << 23) | OPC_MSA_3R_0D,
1258 OPC_MIN_S_df = (0x4 << 23) | OPC_MSA_3R_0E,
1259 OPC_CLE_S_df = (0x4 << 23) | OPC_MSA_3R_0F,
1260 OPC_AVE_S_df = (0x4 << 23) | OPC_MSA_3R_10,
1261 OPC_ASUB_S_df = (0x4 << 23) | OPC_MSA_3R_11,
1262 OPC_DIV_S_df = (0x4 << 23) | OPC_MSA_3R_12,
1263 OPC_DPSUB_S_df = (0x4 << 23) | OPC_MSA_3R_13,
1264 OPC_ILVL_df = (0x4 << 23) | OPC_MSA_3R_14,
1265 OPC_HADD_S_df = (0x4 << 23) | OPC_MSA_3R_15,
1266 OPC_BNEG_df = (0x5 << 23) | OPC_MSA_3R_0D,
1267 OPC_MIN_U_df = (0x5 << 23) | OPC_MSA_3R_0E,
1268 OPC_CLE_U_df = (0x5 << 23) | OPC_MSA_3R_0F,
1269 OPC_AVE_U_df = (0x5 << 23) | OPC_MSA_3R_10,
1270 OPC_ASUB_U_df = (0x5 << 23) | OPC_MSA_3R_11,
1271 OPC_DIV_U_df = (0x5 << 23) | OPC_MSA_3R_12,
1272 OPC_DPSUB_U_df = (0x5 << 23) | OPC_MSA_3R_13,
1273 OPC_ILVR_df = (0x5 << 23) | OPC_MSA_3R_14,
1274 OPC_HADD_U_df = (0x5 << 23) | OPC_MSA_3R_15,
1275 OPC_BINSL_df = (0x6 << 23) | OPC_MSA_3R_0D,
1276 OPC_MAX_A_df = (0x6 << 23) | OPC_MSA_3R_0E,
1277 OPC_AVER_S_df = (0x6 << 23) | OPC_MSA_3R_10,
1278 OPC_MOD_S_df = (0x6 << 23) | OPC_MSA_3R_12,
1279 OPC_ILVEV_df = (0x6 << 23) | OPC_MSA_3R_14,
1280 OPC_HSUB_S_df = (0x6 << 23) | OPC_MSA_3R_15,
1281 OPC_BINSR_df = (0x7 << 23) | OPC_MSA_3R_0D,
1282 OPC_MIN_A_df = (0x7 << 23) | OPC_MSA_3R_0E,
1283 OPC_AVER_U_df = (0x7 << 23) | OPC_MSA_3R_10,
1284 OPC_MOD_U_df = (0x7 << 23) | OPC_MSA_3R_12,
1285 OPC_ILVOD_df = (0x7 << 23) | OPC_MSA_3R_14,
1286 OPC_HSUB_U_df = (0x7 << 23) | OPC_MSA_3R_15,
1288 /* ELM instructions df(bits 21..16) = _b, _h, _w, _d */
1289 OPC_SLDI_df = (0x0 << 22) | (0x00 << 16) | OPC_MSA_ELM,
1290 OPC_CTCMSA = (0x0 << 22) | (0x3E << 16) | OPC_MSA_ELM,
1291 OPC_SPLATI_df = (0x1 << 22) | (0x00 << 16) | OPC_MSA_ELM,
1292 OPC_CFCMSA = (0x1 << 22) | (0x3E << 16) | OPC_MSA_ELM,
1293 OPC_COPY_S_df = (0x2 << 22) | (0x00 << 16) | OPC_MSA_ELM,
1294 OPC_MOVE_V = (0x2 << 22) | (0x3E << 16) | OPC_MSA_ELM,
1295 OPC_COPY_U_df = (0x3 << 22) | (0x00 << 16) | OPC_MSA_ELM,
1296 OPC_INSERT_df = (0x4 << 22) | (0x00 << 16) | OPC_MSA_ELM,
1297 OPC_INSVE_df = (0x5 << 22) | (0x00 << 16) | OPC_MSA_ELM,
1299 /* 3RF instruction _df(bit 21) = _w, _d */
1300 OPC_FCAF_df = (0x0 << 22) | OPC_MSA_3RF_1A,
1301 OPC_FADD_df = (0x0 << 22) | OPC_MSA_3RF_1B,
1302 OPC_FCUN_df = (0x1 << 22) | OPC_MSA_3RF_1A,
1303 OPC_FSUB_df = (0x1 << 22) | OPC_MSA_3RF_1B,
1304 OPC_FCOR_df = (0x1 << 22) | OPC_MSA_3RF_1C,
1305 OPC_FCEQ_df = (0x2 << 22) | OPC_MSA_3RF_1A,
1306 OPC_FMUL_df = (0x2 << 22) | OPC_MSA_3RF_1B,
1307 OPC_FCUNE_df = (0x2 << 22) | OPC_MSA_3RF_1C,
1308 OPC_FCUEQ_df = (0x3 << 22) | OPC_MSA_3RF_1A,
1309 OPC_FDIV_df = (0x3 << 22) | OPC_MSA_3RF_1B,
1310 OPC_FCNE_df = (0x3 << 22) | OPC_MSA_3RF_1C,
1311 OPC_FCLT_df = (0x4 << 22) | OPC_MSA_3RF_1A,
1312 OPC_FMADD_df = (0x4 << 22) | OPC_MSA_3RF_1B,
1313 OPC_MUL_Q_df = (0x4 << 22) | OPC_MSA_3RF_1C,
1314 OPC_FCULT_df = (0x5 << 22) | OPC_MSA_3RF_1A,
1315 OPC_FMSUB_df = (0x5 << 22) | OPC_MSA_3RF_1B,
1316 OPC_MADD_Q_df = (0x5 << 22) | OPC_MSA_3RF_1C,
1317 OPC_FCLE_df = (0x6 << 22) | OPC_MSA_3RF_1A,
1318 OPC_MSUB_Q_df = (0x6 << 22) | OPC_MSA_3RF_1C,
1319 OPC_FCULE_df = (0x7 << 22) | OPC_MSA_3RF_1A,
1320 OPC_FEXP2_df = (0x7 << 22) | OPC_MSA_3RF_1B,
1321 OPC_FSAF_df = (0x8 << 22) | OPC_MSA_3RF_1A,
1322 OPC_FEXDO_df = (0x8 << 22) | OPC_MSA_3RF_1B,
1323 OPC_FSUN_df = (0x9 << 22) | OPC_MSA_3RF_1A,
1324 OPC_FSOR_df = (0x9 << 22) | OPC_MSA_3RF_1C,
1325 OPC_FSEQ_df = (0xA << 22) | OPC_MSA_3RF_1A,
1326 OPC_FTQ_df = (0xA << 22) | OPC_MSA_3RF_1B,
1327 OPC_FSUNE_df = (0xA << 22) | OPC_MSA_3RF_1C,
1328 OPC_FSUEQ_df = (0xB << 22) | OPC_MSA_3RF_1A,
1329 OPC_FSNE_df = (0xB << 22) | OPC_MSA_3RF_1C,
1330 OPC_FSLT_df = (0xC << 22) | OPC_MSA_3RF_1A,
1331 OPC_FMIN_df = (0xC << 22) | OPC_MSA_3RF_1B,
1332 OPC_MULR_Q_df = (0xC << 22) | OPC_MSA_3RF_1C,
1333 OPC_FSULT_df = (0xD << 22) | OPC_MSA_3RF_1A,
1334 OPC_FMIN_A_df = (0xD << 22) | OPC_MSA_3RF_1B,
1335 OPC_MADDR_Q_df = (0xD << 22) | OPC_MSA_3RF_1C,
1336 OPC_FSLE_df = (0xE << 22) | OPC_MSA_3RF_1A,
1337 OPC_FMAX_df = (0xE << 22) | OPC_MSA_3RF_1B,
1338 OPC_MSUBR_Q_df = (0xE << 22) | OPC_MSA_3RF_1C,
1339 OPC_FSULE_df = (0xF << 22) | OPC_MSA_3RF_1A,
1340 OPC_FMAX_A_df = (0xF << 22) | OPC_MSA_3RF_1B,
1342 /* BIT instruction df(bits 22..16) = _B _H _W _D */
1343 OPC_SLLI_df = (0x0 << 23) | OPC_MSA_BIT_09,
1344 OPC_SAT_S_df = (0x0 << 23) | OPC_MSA_BIT_0A,
1345 OPC_SRAI_df = (0x1 << 23) | OPC_MSA_BIT_09,
1346 OPC_SAT_U_df = (0x1 << 23) | OPC_MSA_BIT_0A,
1347 OPC_SRLI_df = (0x2 << 23) | OPC_MSA_BIT_09,
1348 OPC_SRARI_df = (0x2 << 23) | OPC_MSA_BIT_0A,
1349 OPC_BCLRI_df = (0x3 << 23) | OPC_MSA_BIT_09,
1350 OPC_SRLRI_df = (0x3 << 23) | OPC_MSA_BIT_0A,
1351 OPC_BSETI_df = (0x4 << 23) | OPC_MSA_BIT_09,
1352 OPC_BNEGI_df = (0x5 << 23) | OPC_MSA_BIT_09,
1353 OPC_BINSLI_df = (0x6 << 23) | OPC_MSA_BIT_09,
1354 OPC_BINSRI_df = (0x7 << 23) | OPC_MSA_BIT_09,
1357 /* global register indices */
1358 static TCGv_env cpu_env;
1359 static TCGv cpu_gpr[32], cpu_PC;
1360 static TCGv cpu_HI[MIPS_DSP_ACC], cpu_LO[MIPS_DSP_ACC];
1361 static TCGv cpu_dspctrl, btarget, bcond;
1362 static TCGv_i32 hflags;
1363 static TCGv_i32 fpu_fcr0, fpu_fcr31;
1364 static TCGv_i64 fpu_f64[32];
1365 static TCGv_i64 msa_wr_d[64];
1367 #include "exec/gen-icount.h"
1369 #define gen_helper_0e0i(name, arg) do { \
1370 TCGv_i32 helper_tmp = tcg_const_i32(arg); \
1371 gen_helper_##name(cpu_env, helper_tmp); \
1372 tcg_temp_free_i32(helper_tmp); \
1373 } while(0)
1375 #define gen_helper_0e1i(name, arg1, arg2) do { \
1376 TCGv_i32 helper_tmp = tcg_const_i32(arg2); \
1377 gen_helper_##name(cpu_env, arg1, helper_tmp); \
1378 tcg_temp_free_i32(helper_tmp); \
1379 } while(0)
1381 #define gen_helper_1e0i(name, ret, arg1) do { \
1382 TCGv_i32 helper_tmp = tcg_const_i32(arg1); \
1383 gen_helper_##name(ret, cpu_env, helper_tmp); \
1384 tcg_temp_free_i32(helper_tmp); \
1385 } while(0)
1387 #define gen_helper_1e1i(name, ret, arg1, arg2) do { \
1388 TCGv_i32 helper_tmp = tcg_const_i32(arg2); \
1389 gen_helper_##name(ret, cpu_env, arg1, helper_tmp); \
1390 tcg_temp_free_i32(helper_tmp); \
1391 } while(0)
1393 #define gen_helper_0e2i(name, arg1, arg2, arg3) do { \
1394 TCGv_i32 helper_tmp = tcg_const_i32(arg3); \
1395 gen_helper_##name(cpu_env, arg1, arg2, helper_tmp); \
1396 tcg_temp_free_i32(helper_tmp); \
1397 } while(0)
1399 #define gen_helper_1e2i(name, ret, arg1, arg2, arg3) do { \
1400 TCGv_i32 helper_tmp = tcg_const_i32(arg3); \
1401 gen_helper_##name(ret, cpu_env, arg1, arg2, helper_tmp); \
1402 tcg_temp_free_i32(helper_tmp); \
1403 } while(0)
1405 #define gen_helper_0e3i(name, arg1, arg2, arg3, arg4) do { \
1406 TCGv_i32 helper_tmp = tcg_const_i32(arg4); \
1407 gen_helper_##name(cpu_env, arg1, arg2, arg3, helper_tmp); \
1408 tcg_temp_free_i32(helper_tmp); \
1409 } while(0)
1411 typedef struct DisasContext {
1412 struct TranslationBlock *tb;
1413 target_ulong pc, saved_pc;
1414 uint32_t opcode;
1415 int singlestep_enabled;
1416 int insn_flags;
1417 int32_t CP0_Config1;
1418 /* Routine used to access memory */
1419 int mem_idx;
1420 TCGMemOp default_tcg_memop_mask;
1421 uint32_t hflags, saved_hflags;
1422 int bstate;
1423 target_ulong btarget;
1424 bool ulri;
1425 int kscrexist;
1426 bool rxi;
1427 int ie;
1428 bool bi;
1429 bool bp;
1430 uint64_t PAMask;
1431 bool mvh;
1432 int CP0_LLAddr_shift;
1433 bool ps;
1434 bool vp;
1435 bool cmgcr;
1436 bool mrp;
1437 } DisasContext;
1439 enum {
1440 BS_NONE = 0, /* We go out of the TB without reaching a branch or an
1441 * exception condition */
1442 BS_STOP = 1, /* We want to stop translation for any reason */
1443 BS_BRANCH = 2, /* We reached a branch condition */
1444 BS_EXCP = 3, /* We reached an exception condition */
1447 static const char * const regnames[] = {
1448 "r0", "at", "v0", "v1", "a0", "a1", "a2", "a3",
1449 "t0", "t1", "t2", "t3", "t4", "t5", "t6", "t7",
1450 "s0", "s1", "s2", "s3", "s4", "s5", "s6", "s7",
1451 "t8", "t9", "k0", "k1", "gp", "sp", "s8", "ra",
1454 static const char * const regnames_HI[] = {
1455 "HI0", "HI1", "HI2", "HI3",
1458 static const char * const regnames_LO[] = {
1459 "LO0", "LO1", "LO2", "LO3",
1462 static const char * const fregnames[] = {
1463 "f0", "f1", "f2", "f3", "f4", "f5", "f6", "f7",
1464 "f8", "f9", "f10", "f11", "f12", "f13", "f14", "f15",
1465 "f16", "f17", "f18", "f19", "f20", "f21", "f22", "f23",
1466 "f24", "f25", "f26", "f27", "f28", "f29", "f30", "f31",
1469 static const char * const msaregnames[] = {
1470 "w0.d0", "w0.d1", "w1.d0", "w1.d1",
1471 "w2.d0", "w2.d1", "w3.d0", "w3.d1",
1472 "w4.d0", "w4.d1", "w5.d0", "w5.d1",
1473 "w6.d0", "w6.d1", "w7.d0", "w7.d1",
1474 "w8.d0", "w8.d1", "w9.d0", "w9.d1",
1475 "w10.d0", "w10.d1", "w11.d0", "w11.d1",
1476 "w12.d0", "w12.d1", "w13.d0", "w13.d1",
1477 "w14.d0", "w14.d1", "w15.d0", "w15.d1",
1478 "w16.d0", "w16.d1", "w17.d0", "w17.d1",
1479 "w18.d0", "w18.d1", "w19.d0", "w19.d1",
1480 "w20.d0", "w20.d1", "w21.d0", "w21.d1",
1481 "w22.d0", "w22.d1", "w23.d0", "w23.d1",
1482 "w24.d0", "w24.d1", "w25.d0", "w25.d1",
1483 "w26.d0", "w26.d1", "w27.d0", "w27.d1",
1484 "w28.d0", "w28.d1", "w29.d0", "w29.d1",
1485 "w30.d0", "w30.d1", "w31.d0", "w31.d1",
1488 #define LOG_DISAS(...) \
1489 do { \
1490 if (MIPS_DEBUG_DISAS) { \
1491 qemu_log_mask(CPU_LOG_TB_IN_ASM, ## __VA_ARGS__); \
1493 } while (0)
1495 #define MIPS_INVAL(op) \
1496 do { \
1497 if (MIPS_DEBUG_DISAS) { \
1498 qemu_log_mask(CPU_LOG_TB_IN_ASM, \
1499 TARGET_FMT_lx ": %08x Invalid %s %03x %03x %03x\n", \
1500 ctx->pc, ctx->opcode, op, ctx->opcode >> 26, \
1501 ctx->opcode & 0x3F, ((ctx->opcode >> 16) & 0x1F)); \
1503 } while (0)
1505 /* General purpose registers moves. */
1506 static inline void gen_load_gpr (TCGv t, int reg)
1508 if (reg == 0)
1509 tcg_gen_movi_tl(t, 0);
1510 else
1511 tcg_gen_mov_tl(t, cpu_gpr[reg]);
1514 static inline void gen_store_gpr (TCGv t, int reg)
1516 if (reg != 0)
1517 tcg_gen_mov_tl(cpu_gpr[reg], t);
1520 /* Moves to/from shadow registers. */
1521 static inline void gen_load_srsgpr (int from, int to)
1523 TCGv t0 = tcg_temp_new();
1525 if (from == 0)
1526 tcg_gen_movi_tl(t0, 0);
1527 else {
1528 TCGv_i32 t2 = tcg_temp_new_i32();
1529 TCGv_ptr addr = tcg_temp_new_ptr();
1531 tcg_gen_ld_i32(t2, cpu_env, offsetof(CPUMIPSState, CP0_SRSCtl));
1532 tcg_gen_shri_i32(t2, t2, CP0SRSCtl_PSS);
1533 tcg_gen_andi_i32(t2, t2, 0xf);
1534 tcg_gen_muli_i32(t2, t2, sizeof(target_ulong) * 32);
1535 tcg_gen_ext_i32_ptr(addr, t2);
1536 tcg_gen_add_ptr(addr, cpu_env, addr);
1538 tcg_gen_ld_tl(t0, addr, sizeof(target_ulong) * from);
1539 tcg_temp_free_ptr(addr);
1540 tcg_temp_free_i32(t2);
1542 gen_store_gpr(t0, to);
1543 tcg_temp_free(t0);
1546 static inline void gen_store_srsgpr (int from, int to)
1548 if (to != 0) {
1549 TCGv t0 = tcg_temp_new();
1550 TCGv_i32 t2 = tcg_temp_new_i32();
1551 TCGv_ptr addr = tcg_temp_new_ptr();
1553 gen_load_gpr(t0, from);
1554 tcg_gen_ld_i32(t2, cpu_env, offsetof(CPUMIPSState, CP0_SRSCtl));
1555 tcg_gen_shri_i32(t2, t2, CP0SRSCtl_PSS);
1556 tcg_gen_andi_i32(t2, t2, 0xf);
1557 tcg_gen_muli_i32(t2, t2, sizeof(target_ulong) * 32);
1558 tcg_gen_ext_i32_ptr(addr, t2);
1559 tcg_gen_add_ptr(addr, cpu_env, addr);
1561 tcg_gen_st_tl(t0, addr, sizeof(target_ulong) * to);
1562 tcg_temp_free_ptr(addr);
1563 tcg_temp_free_i32(t2);
1564 tcg_temp_free(t0);
1568 /* Tests */
1569 static inline void gen_save_pc(target_ulong pc)
1571 tcg_gen_movi_tl(cpu_PC, pc);
1574 static inline void save_cpu_state(DisasContext *ctx, int do_save_pc)
1576 LOG_DISAS("hflags %08x saved %08x\n", ctx->hflags, ctx->saved_hflags);
1577 if (do_save_pc && ctx->pc != ctx->saved_pc) {
1578 gen_save_pc(ctx->pc);
1579 ctx->saved_pc = ctx->pc;
1581 if (ctx->hflags != ctx->saved_hflags) {
1582 tcg_gen_movi_i32(hflags, ctx->hflags);
1583 ctx->saved_hflags = ctx->hflags;
1584 switch (ctx->hflags & MIPS_HFLAG_BMASK_BASE) {
1585 case MIPS_HFLAG_BR:
1586 break;
1587 case MIPS_HFLAG_BC:
1588 case MIPS_HFLAG_BL:
1589 case MIPS_HFLAG_B:
1590 tcg_gen_movi_tl(btarget, ctx->btarget);
1591 break;
1596 static inline void restore_cpu_state(CPUMIPSState *env, DisasContext *ctx)
1598 ctx->saved_hflags = ctx->hflags;
1599 switch (ctx->hflags & MIPS_HFLAG_BMASK_BASE) {
1600 case MIPS_HFLAG_BR:
1601 break;
1602 case MIPS_HFLAG_BC:
1603 case MIPS_HFLAG_BL:
1604 case MIPS_HFLAG_B:
1605 ctx->btarget = env->btarget;
1606 break;
1610 static inline void generate_exception_err(DisasContext *ctx, int excp, int err)
1612 TCGv_i32 texcp = tcg_const_i32(excp);
1613 TCGv_i32 terr = tcg_const_i32(err);
1614 save_cpu_state(ctx, 1);
1615 gen_helper_raise_exception_err(cpu_env, texcp, terr);
1616 tcg_temp_free_i32(terr);
1617 tcg_temp_free_i32(texcp);
1618 ctx->bstate = BS_EXCP;
1621 static inline void generate_exception(DisasContext *ctx, int excp)
1623 gen_helper_0e0i(raise_exception, excp);
1626 static inline void generate_exception_end(DisasContext *ctx, int excp)
1628 generate_exception_err(ctx, excp, 0);
1631 /* Floating point register moves. */
1632 static void gen_load_fpr32(DisasContext *ctx, TCGv_i32 t, int reg)
1634 if (ctx->hflags & MIPS_HFLAG_FRE) {
1635 generate_exception(ctx, EXCP_RI);
1637 tcg_gen_extrl_i64_i32(t, fpu_f64[reg]);
1640 static void gen_store_fpr32(DisasContext *ctx, TCGv_i32 t, int reg)
1642 TCGv_i64 t64;
1643 if (ctx->hflags & MIPS_HFLAG_FRE) {
1644 generate_exception(ctx, EXCP_RI);
1646 t64 = tcg_temp_new_i64();
1647 tcg_gen_extu_i32_i64(t64, t);
1648 tcg_gen_deposit_i64(fpu_f64[reg], fpu_f64[reg], t64, 0, 32);
1649 tcg_temp_free_i64(t64);
1652 static void gen_load_fpr32h(DisasContext *ctx, TCGv_i32 t, int reg)
1654 if (ctx->hflags & MIPS_HFLAG_F64) {
1655 tcg_gen_extrh_i64_i32(t, fpu_f64[reg]);
1656 } else {
1657 gen_load_fpr32(ctx, t, reg | 1);
1661 static void gen_store_fpr32h(DisasContext *ctx, TCGv_i32 t, int reg)
1663 if (ctx->hflags & MIPS_HFLAG_F64) {
1664 TCGv_i64 t64 = tcg_temp_new_i64();
1665 tcg_gen_extu_i32_i64(t64, t);
1666 tcg_gen_deposit_i64(fpu_f64[reg], fpu_f64[reg], t64, 32, 32);
1667 tcg_temp_free_i64(t64);
1668 } else {
1669 gen_store_fpr32(ctx, t, reg | 1);
1673 static void gen_load_fpr64(DisasContext *ctx, TCGv_i64 t, int reg)
1675 if (ctx->hflags & MIPS_HFLAG_F64) {
1676 tcg_gen_mov_i64(t, fpu_f64[reg]);
1677 } else {
1678 tcg_gen_concat32_i64(t, fpu_f64[reg & ~1], fpu_f64[reg | 1]);
1682 static void gen_store_fpr64(DisasContext *ctx, TCGv_i64 t, int reg)
1684 if (ctx->hflags & MIPS_HFLAG_F64) {
1685 tcg_gen_mov_i64(fpu_f64[reg], t);
1686 } else {
1687 TCGv_i64 t0;
1688 tcg_gen_deposit_i64(fpu_f64[reg & ~1], fpu_f64[reg & ~1], t, 0, 32);
1689 t0 = tcg_temp_new_i64();
1690 tcg_gen_shri_i64(t0, t, 32);
1691 tcg_gen_deposit_i64(fpu_f64[reg | 1], fpu_f64[reg | 1], t0, 0, 32);
1692 tcg_temp_free_i64(t0);
1696 static inline int get_fp_bit (int cc)
1698 if (cc)
1699 return 24 + cc;
1700 else
1701 return 23;
1704 /* Addresses computation */
1705 static inline void gen_op_addr_add (DisasContext *ctx, TCGv ret, TCGv arg0, TCGv arg1)
1707 tcg_gen_add_tl(ret, arg0, arg1);
1709 #if defined(TARGET_MIPS64)
1710 if (ctx->hflags & MIPS_HFLAG_AWRAP) {
1711 tcg_gen_ext32s_i64(ret, ret);
1713 #endif
1716 /* Addresses computation (translation time) */
1717 static target_long addr_add(DisasContext *ctx, target_long base,
1718 target_long offset)
1720 target_long sum = base + offset;
1722 #if defined(TARGET_MIPS64)
1723 if (ctx->hflags & MIPS_HFLAG_AWRAP) {
1724 sum = (int32_t)sum;
1726 #endif
1727 return sum;
1730 /* Sign-extract the low 32-bits to a target_long. */
1731 static inline void gen_move_low32(TCGv ret, TCGv_i64 arg)
1733 #if defined(TARGET_MIPS64)
1734 tcg_gen_ext32s_i64(ret, arg);
1735 #else
1736 tcg_gen_extrl_i64_i32(ret, arg);
1737 #endif
1740 /* Sign-extract the high 32-bits to a target_long. */
1741 static inline void gen_move_high32(TCGv ret, TCGv_i64 arg)
1743 #if defined(TARGET_MIPS64)
1744 tcg_gen_sari_i64(ret, arg, 32);
1745 #else
1746 tcg_gen_extrh_i64_i32(ret, arg);
1747 #endif
1750 static inline void check_cp0_enabled(DisasContext *ctx)
1752 if (unlikely(!(ctx->hflags & MIPS_HFLAG_CP0)))
1753 generate_exception_err(ctx, EXCP_CpU, 0);
1756 static inline void check_cp1_enabled(DisasContext *ctx)
1758 if (unlikely(!(ctx->hflags & MIPS_HFLAG_FPU)))
1759 generate_exception_err(ctx, EXCP_CpU, 1);
1762 /* Verify that the processor is running with COP1X instructions enabled.
1763 This is associated with the nabla symbol in the MIPS32 and MIPS64
1764 opcode tables. */
1766 static inline void check_cop1x(DisasContext *ctx)
1768 if (unlikely(!(ctx->hflags & MIPS_HFLAG_COP1X)))
1769 generate_exception_end(ctx, EXCP_RI);
1772 /* Verify that the processor is running with 64-bit floating-point
1773 operations enabled. */
1775 static inline void check_cp1_64bitmode(DisasContext *ctx)
1777 if (unlikely(~ctx->hflags & (MIPS_HFLAG_F64 | MIPS_HFLAG_COP1X)))
1778 generate_exception_end(ctx, EXCP_RI);
1782 * Verify if floating point register is valid; an operation is not defined
1783 * if bit 0 of any register specification is set and the FR bit in the
1784 * Status register equals zero, since the register numbers specify an
1785 * even-odd pair of adjacent coprocessor general registers. When the FR bit
1786 * in the Status register equals one, both even and odd register numbers
1787 * are valid. This limitation exists only for 64 bit wide (d,l,ps) registers.
1789 * Multiple 64 bit wide registers can be checked by calling
1790 * gen_op_cp1_registers(freg1 | freg2 | ... | fregN);
1792 static inline void check_cp1_registers(DisasContext *ctx, int regs)
1794 if (unlikely(!(ctx->hflags & MIPS_HFLAG_F64) && (regs & 1)))
1795 generate_exception_end(ctx, EXCP_RI);
1798 /* Verify that the processor is running with DSP instructions enabled.
1799 This is enabled by CP0 Status register MX(24) bit.
1802 static inline void check_dsp(DisasContext *ctx)
1804 if (unlikely(!(ctx->hflags & MIPS_HFLAG_DSP))) {
1805 if (ctx->insn_flags & ASE_DSP) {
1806 generate_exception_end(ctx, EXCP_DSPDIS);
1807 } else {
1808 generate_exception_end(ctx, EXCP_RI);
1813 static inline void check_dspr2(DisasContext *ctx)
1815 if (unlikely(!(ctx->hflags & MIPS_HFLAG_DSPR2))) {
1816 if (ctx->insn_flags & ASE_DSP) {
1817 generate_exception_end(ctx, EXCP_DSPDIS);
1818 } else {
1819 generate_exception_end(ctx, EXCP_RI);
1824 /* This code generates a "reserved instruction" exception if the
1825 CPU does not support the instruction set corresponding to flags. */
1826 static inline void check_insn(DisasContext *ctx, int flags)
1828 if (unlikely(!(ctx->insn_flags & flags))) {
1829 generate_exception_end(ctx, EXCP_RI);
1833 /* This code generates a "reserved instruction" exception if the
1834 CPU has corresponding flag set which indicates that the instruction
1835 has been removed. */
1836 static inline void check_insn_opc_removed(DisasContext *ctx, int flags)
1838 if (unlikely(ctx->insn_flags & flags)) {
1839 generate_exception_end(ctx, EXCP_RI);
1843 /* This code generates a "reserved instruction" exception if the
1844 CPU does not support 64-bit paired-single (PS) floating point data type */
1845 static inline void check_ps(DisasContext *ctx)
1847 if (unlikely(!ctx->ps)) {
1848 generate_exception(ctx, EXCP_RI);
1850 check_cp1_64bitmode(ctx);
1853 #ifdef TARGET_MIPS64
1854 /* This code generates a "reserved instruction" exception if 64-bit
1855 instructions are not enabled. */
1856 static inline void check_mips_64(DisasContext *ctx)
1858 if (unlikely(!(ctx->hflags & MIPS_HFLAG_64)))
1859 generate_exception_end(ctx, EXCP_RI);
1861 #endif
1863 #ifndef CONFIG_USER_ONLY
1864 static inline void check_mvh(DisasContext *ctx)
1866 if (unlikely(!ctx->mvh)) {
1867 generate_exception(ctx, EXCP_RI);
1870 #endif
1872 /* Define small wrappers for gen_load_fpr* so that we have a uniform
1873 calling interface for 32 and 64-bit FPRs. No sense in changing
1874 all callers for gen_load_fpr32 when we need the CTX parameter for
1875 this one use. */
1876 #define gen_ldcmp_fpr32(ctx, x, y) gen_load_fpr32(ctx, x, y)
1877 #define gen_ldcmp_fpr64(ctx, x, y) gen_load_fpr64(ctx, x, y)
1878 #define FOP_CONDS(type, abs, fmt, ifmt, bits) \
1879 static inline void gen_cmp ## type ## _ ## fmt(DisasContext *ctx, int n, \
1880 int ft, int fs, int cc) \
1882 TCGv_i##bits fp0 = tcg_temp_new_i##bits (); \
1883 TCGv_i##bits fp1 = tcg_temp_new_i##bits (); \
1884 switch (ifmt) { \
1885 case FMT_PS: \
1886 check_ps(ctx); \
1887 break; \
1888 case FMT_D: \
1889 if (abs) { \
1890 check_cop1x(ctx); \
1892 check_cp1_registers(ctx, fs | ft); \
1893 break; \
1894 case FMT_S: \
1895 if (abs) { \
1896 check_cop1x(ctx); \
1898 break; \
1900 gen_ldcmp_fpr##bits (ctx, fp0, fs); \
1901 gen_ldcmp_fpr##bits (ctx, fp1, ft); \
1902 switch (n) { \
1903 case 0: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _f, fp0, fp1, cc); break;\
1904 case 1: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _un, fp0, fp1, cc); break;\
1905 case 2: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _eq, fp0, fp1, cc); break;\
1906 case 3: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ueq, fp0, fp1, cc); break;\
1907 case 4: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _olt, fp0, fp1, cc); break;\
1908 case 5: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ult, fp0, fp1, cc); break;\
1909 case 6: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ole, fp0, fp1, cc); break;\
1910 case 7: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ule, fp0, fp1, cc); break;\
1911 case 8: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _sf, fp0, fp1, cc); break;\
1912 case 9: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ngle, fp0, fp1, cc); break;\
1913 case 10: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _seq, fp0, fp1, cc); break;\
1914 case 11: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ngl, fp0, fp1, cc); break;\
1915 case 12: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _lt, fp0, fp1, cc); break;\
1916 case 13: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _nge, fp0, fp1, cc); break;\
1917 case 14: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _le, fp0, fp1, cc); break;\
1918 case 15: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ngt, fp0, fp1, cc); break;\
1919 default: abort(); \
1921 tcg_temp_free_i##bits (fp0); \
1922 tcg_temp_free_i##bits (fp1); \
1925 FOP_CONDS(, 0, d, FMT_D, 64)
1926 FOP_CONDS(abs, 1, d, FMT_D, 64)
1927 FOP_CONDS(, 0, s, FMT_S, 32)
1928 FOP_CONDS(abs, 1, s, FMT_S, 32)
1929 FOP_CONDS(, 0, ps, FMT_PS, 64)
1930 FOP_CONDS(abs, 1, ps, FMT_PS, 64)
1931 #undef FOP_CONDS
1933 #define FOP_CONDNS(fmt, ifmt, bits, STORE) \
1934 static inline void gen_r6_cmp_ ## fmt(DisasContext * ctx, int n, \
1935 int ft, int fs, int fd) \
1937 TCGv_i ## bits fp0 = tcg_temp_new_i ## bits(); \
1938 TCGv_i ## bits fp1 = tcg_temp_new_i ## bits(); \
1939 if (ifmt == FMT_D) { \
1940 check_cp1_registers(ctx, fs | ft | fd); \
1942 gen_ldcmp_fpr ## bits(ctx, fp0, fs); \
1943 gen_ldcmp_fpr ## bits(ctx, fp1, ft); \
1944 switch (n) { \
1945 case 0: \
1946 gen_helper_r6_cmp_ ## fmt ## _af(fp0, cpu_env, fp0, fp1); \
1947 break; \
1948 case 1: \
1949 gen_helper_r6_cmp_ ## fmt ## _un(fp0, cpu_env, fp0, fp1); \
1950 break; \
1951 case 2: \
1952 gen_helper_r6_cmp_ ## fmt ## _eq(fp0, cpu_env, fp0, fp1); \
1953 break; \
1954 case 3: \
1955 gen_helper_r6_cmp_ ## fmt ## _ueq(fp0, cpu_env, fp0, fp1); \
1956 break; \
1957 case 4: \
1958 gen_helper_r6_cmp_ ## fmt ## _lt(fp0, cpu_env, fp0, fp1); \
1959 break; \
1960 case 5: \
1961 gen_helper_r6_cmp_ ## fmt ## _ult(fp0, cpu_env, fp0, fp1); \
1962 break; \
1963 case 6: \
1964 gen_helper_r6_cmp_ ## fmt ## _le(fp0, cpu_env, fp0, fp1); \
1965 break; \
1966 case 7: \
1967 gen_helper_r6_cmp_ ## fmt ## _ule(fp0, cpu_env, fp0, fp1); \
1968 break; \
1969 case 8: \
1970 gen_helper_r6_cmp_ ## fmt ## _saf(fp0, cpu_env, fp0, fp1); \
1971 break; \
1972 case 9: \
1973 gen_helper_r6_cmp_ ## fmt ## _sun(fp0, cpu_env, fp0, fp1); \
1974 break; \
1975 case 10: \
1976 gen_helper_r6_cmp_ ## fmt ## _seq(fp0, cpu_env, fp0, fp1); \
1977 break; \
1978 case 11: \
1979 gen_helper_r6_cmp_ ## fmt ## _sueq(fp0, cpu_env, fp0, fp1); \
1980 break; \
1981 case 12: \
1982 gen_helper_r6_cmp_ ## fmt ## _slt(fp0, cpu_env, fp0, fp1); \
1983 break; \
1984 case 13: \
1985 gen_helper_r6_cmp_ ## fmt ## _sult(fp0, cpu_env, fp0, fp1); \
1986 break; \
1987 case 14: \
1988 gen_helper_r6_cmp_ ## fmt ## _sle(fp0, cpu_env, fp0, fp1); \
1989 break; \
1990 case 15: \
1991 gen_helper_r6_cmp_ ## fmt ## _sule(fp0, cpu_env, fp0, fp1); \
1992 break; \
1993 case 17: \
1994 gen_helper_r6_cmp_ ## fmt ## _or(fp0, cpu_env, fp0, fp1); \
1995 break; \
1996 case 18: \
1997 gen_helper_r6_cmp_ ## fmt ## _une(fp0, cpu_env, fp0, fp1); \
1998 break; \
1999 case 19: \
2000 gen_helper_r6_cmp_ ## fmt ## _ne(fp0, cpu_env, fp0, fp1); \
2001 break; \
2002 case 25: \
2003 gen_helper_r6_cmp_ ## fmt ## _sor(fp0, cpu_env, fp0, fp1); \
2004 break; \
2005 case 26: \
2006 gen_helper_r6_cmp_ ## fmt ## _sune(fp0, cpu_env, fp0, fp1); \
2007 break; \
2008 case 27: \
2009 gen_helper_r6_cmp_ ## fmt ## _sne(fp0, cpu_env, fp0, fp1); \
2010 break; \
2011 default: \
2012 abort(); \
2014 STORE; \
2015 tcg_temp_free_i ## bits (fp0); \
2016 tcg_temp_free_i ## bits (fp1); \
2019 FOP_CONDNS(d, FMT_D, 64, gen_store_fpr64(ctx, fp0, fd))
2020 FOP_CONDNS(s, FMT_S, 32, gen_store_fpr32(ctx, fp0, fd))
2021 #undef FOP_CONDNS
2022 #undef gen_ldcmp_fpr32
2023 #undef gen_ldcmp_fpr64
2025 /* load/store instructions. */
2026 #ifdef CONFIG_USER_ONLY
2027 #define OP_LD_ATOMIC(insn,fname) \
2028 static inline void op_ld_##insn(TCGv ret, TCGv arg1, DisasContext *ctx) \
2030 TCGv t0 = tcg_temp_new(); \
2031 tcg_gen_mov_tl(t0, arg1); \
2032 tcg_gen_qemu_##fname(ret, arg1, ctx->mem_idx); \
2033 tcg_gen_st_tl(t0, cpu_env, offsetof(CPUMIPSState, lladdr)); \
2034 tcg_gen_st_tl(ret, cpu_env, offsetof(CPUMIPSState, llval)); \
2035 tcg_temp_free(t0); \
2037 #else
2038 #define OP_LD_ATOMIC(insn,fname) \
2039 static inline void op_ld_##insn(TCGv ret, TCGv arg1, DisasContext *ctx) \
2041 gen_helper_1e1i(insn, ret, arg1, ctx->mem_idx); \
2043 #endif
2044 OP_LD_ATOMIC(ll,ld32s);
2045 #if defined(TARGET_MIPS64)
2046 OP_LD_ATOMIC(lld,ld64);
2047 #endif
2048 #undef OP_LD_ATOMIC
2050 #ifdef CONFIG_USER_ONLY
2051 #define OP_ST_ATOMIC(insn,fname,ldname,almask) \
2052 static inline void op_st_##insn(TCGv arg1, TCGv arg2, int rt, DisasContext *ctx) \
2054 TCGv t0 = tcg_temp_new(); \
2055 TCGLabel *l1 = gen_new_label(); \
2056 TCGLabel *l2 = gen_new_label(); \
2058 tcg_gen_andi_tl(t0, arg2, almask); \
2059 tcg_gen_brcondi_tl(TCG_COND_EQ, t0, 0, l1); \
2060 tcg_gen_st_tl(arg2, cpu_env, offsetof(CPUMIPSState, CP0_BadVAddr)); \
2061 generate_exception(ctx, EXCP_AdES); \
2062 gen_set_label(l1); \
2063 tcg_gen_ld_tl(t0, cpu_env, offsetof(CPUMIPSState, lladdr)); \
2064 tcg_gen_brcond_tl(TCG_COND_NE, arg2, t0, l2); \
2065 tcg_gen_movi_tl(t0, rt | ((almask << 3) & 0x20)); \
2066 tcg_gen_st_tl(t0, cpu_env, offsetof(CPUMIPSState, llreg)); \
2067 tcg_gen_st_tl(arg1, cpu_env, offsetof(CPUMIPSState, llnewval)); \
2068 generate_exception_end(ctx, EXCP_SC); \
2069 gen_set_label(l2); \
2070 tcg_gen_movi_tl(t0, 0); \
2071 gen_store_gpr(t0, rt); \
2072 tcg_temp_free(t0); \
2074 #else
2075 #define OP_ST_ATOMIC(insn,fname,ldname,almask) \
2076 static inline void op_st_##insn(TCGv arg1, TCGv arg2, int rt, DisasContext *ctx) \
2078 TCGv t0 = tcg_temp_new(); \
2079 gen_helper_1e2i(insn, t0, arg1, arg2, ctx->mem_idx); \
2080 gen_store_gpr(t0, rt); \
2081 tcg_temp_free(t0); \
2083 #endif
2084 OP_ST_ATOMIC(sc,st32,ld32s,0x3);
2085 #if defined(TARGET_MIPS64)
2086 OP_ST_ATOMIC(scd,st64,ld64,0x7);
2087 #endif
2088 #undef OP_ST_ATOMIC
2090 static void gen_base_offset_addr (DisasContext *ctx, TCGv addr,
2091 int base, int16_t offset)
2093 if (base == 0) {
2094 tcg_gen_movi_tl(addr, offset);
2095 } else if (offset == 0) {
2096 gen_load_gpr(addr, base);
2097 } else {
2098 tcg_gen_movi_tl(addr, offset);
2099 gen_op_addr_add(ctx, addr, cpu_gpr[base], addr);
2103 static target_ulong pc_relative_pc (DisasContext *ctx)
2105 target_ulong pc = ctx->pc;
2107 if (ctx->hflags & MIPS_HFLAG_BMASK) {
2108 int branch_bytes = ctx->hflags & MIPS_HFLAG_BDS16 ? 2 : 4;
2110 pc -= branch_bytes;
2113 pc &= ~(target_ulong)3;
2114 return pc;
2117 /* Load */
2118 static void gen_ld(DisasContext *ctx, uint32_t opc,
2119 int rt, int base, int16_t offset)
2121 TCGv t0, t1, t2;
2123 if (rt == 0 && ctx->insn_flags & (INSN_LOONGSON2E | INSN_LOONGSON2F)) {
2124 /* Loongson CPU uses a load to zero register for prefetch.
2125 We emulate it as a NOP. On other CPU we must perform the
2126 actual memory access. */
2127 return;
2130 t0 = tcg_temp_new();
2131 gen_base_offset_addr(ctx, t0, base, offset);
2133 switch (opc) {
2134 #if defined(TARGET_MIPS64)
2135 case OPC_LWU:
2136 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TEUL |
2137 ctx->default_tcg_memop_mask);
2138 gen_store_gpr(t0, rt);
2139 break;
2140 case OPC_LD:
2141 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TEQ |
2142 ctx->default_tcg_memop_mask);
2143 gen_store_gpr(t0, rt);
2144 break;
2145 case OPC_LLD:
2146 case R6_OPC_LLD:
2147 op_ld_lld(t0, t0, ctx);
2148 gen_store_gpr(t0, rt);
2149 break;
2150 case OPC_LDL:
2151 t1 = tcg_temp_new();
2152 /* Do a byte access to possibly trigger a page
2153 fault with the unaligned address. */
2154 tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_UB);
2155 tcg_gen_andi_tl(t1, t0, 7);
2156 #ifndef TARGET_WORDS_BIGENDIAN
2157 tcg_gen_xori_tl(t1, t1, 7);
2158 #endif
2159 tcg_gen_shli_tl(t1, t1, 3);
2160 tcg_gen_andi_tl(t0, t0, ~7);
2161 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TEQ);
2162 tcg_gen_shl_tl(t0, t0, t1);
2163 t2 = tcg_const_tl(-1);
2164 tcg_gen_shl_tl(t2, t2, t1);
2165 gen_load_gpr(t1, rt);
2166 tcg_gen_andc_tl(t1, t1, t2);
2167 tcg_temp_free(t2);
2168 tcg_gen_or_tl(t0, t0, t1);
2169 tcg_temp_free(t1);
2170 gen_store_gpr(t0, rt);
2171 break;
2172 case OPC_LDR:
2173 t1 = tcg_temp_new();
2174 /* Do a byte access to possibly trigger a page
2175 fault with the unaligned address. */
2176 tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_UB);
2177 tcg_gen_andi_tl(t1, t0, 7);
2178 #ifdef TARGET_WORDS_BIGENDIAN
2179 tcg_gen_xori_tl(t1, t1, 7);
2180 #endif
2181 tcg_gen_shli_tl(t1, t1, 3);
2182 tcg_gen_andi_tl(t0, t0, ~7);
2183 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TEQ);
2184 tcg_gen_shr_tl(t0, t0, t1);
2185 tcg_gen_xori_tl(t1, t1, 63);
2186 t2 = tcg_const_tl(0xfffffffffffffffeull);
2187 tcg_gen_shl_tl(t2, t2, t1);
2188 gen_load_gpr(t1, rt);
2189 tcg_gen_and_tl(t1, t1, t2);
2190 tcg_temp_free(t2);
2191 tcg_gen_or_tl(t0, t0, t1);
2192 tcg_temp_free(t1);
2193 gen_store_gpr(t0, rt);
2194 break;
2195 case OPC_LDPC:
2196 t1 = tcg_const_tl(pc_relative_pc(ctx));
2197 gen_op_addr_add(ctx, t0, t0, t1);
2198 tcg_temp_free(t1);
2199 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TEQ);
2200 gen_store_gpr(t0, rt);
2201 break;
2202 #endif
2203 case OPC_LWPC:
2204 t1 = tcg_const_tl(pc_relative_pc(ctx));
2205 gen_op_addr_add(ctx, t0, t0, t1);
2206 tcg_temp_free(t1);
2207 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TESL);
2208 gen_store_gpr(t0, rt);
2209 break;
2210 case OPC_LW:
2211 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TESL |
2212 ctx->default_tcg_memop_mask);
2213 gen_store_gpr(t0, rt);
2214 break;
2215 case OPC_LH:
2216 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TESW |
2217 ctx->default_tcg_memop_mask);
2218 gen_store_gpr(t0, rt);
2219 break;
2220 case OPC_LHU:
2221 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TEUW |
2222 ctx->default_tcg_memop_mask);
2223 gen_store_gpr(t0, rt);
2224 break;
2225 case OPC_LB:
2226 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_SB);
2227 gen_store_gpr(t0, rt);
2228 break;
2229 case OPC_LBU:
2230 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_UB);
2231 gen_store_gpr(t0, rt);
2232 break;
2233 case OPC_LWL:
2234 t1 = tcg_temp_new();
2235 /* Do a byte access to possibly trigger a page
2236 fault with the unaligned address. */
2237 tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_UB);
2238 tcg_gen_andi_tl(t1, t0, 3);
2239 #ifndef TARGET_WORDS_BIGENDIAN
2240 tcg_gen_xori_tl(t1, t1, 3);
2241 #endif
2242 tcg_gen_shli_tl(t1, t1, 3);
2243 tcg_gen_andi_tl(t0, t0, ~3);
2244 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TEUL);
2245 tcg_gen_shl_tl(t0, t0, t1);
2246 t2 = tcg_const_tl(-1);
2247 tcg_gen_shl_tl(t2, t2, t1);
2248 gen_load_gpr(t1, rt);
2249 tcg_gen_andc_tl(t1, t1, t2);
2250 tcg_temp_free(t2);
2251 tcg_gen_or_tl(t0, t0, t1);
2252 tcg_temp_free(t1);
2253 tcg_gen_ext32s_tl(t0, t0);
2254 gen_store_gpr(t0, rt);
2255 break;
2256 case OPC_LWR:
2257 t1 = tcg_temp_new();
2258 /* Do a byte access to possibly trigger a page
2259 fault with the unaligned address. */
2260 tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_UB);
2261 tcg_gen_andi_tl(t1, t0, 3);
2262 #ifdef TARGET_WORDS_BIGENDIAN
2263 tcg_gen_xori_tl(t1, t1, 3);
2264 #endif
2265 tcg_gen_shli_tl(t1, t1, 3);
2266 tcg_gen_andi_tl(t0, t0, ~3);
2267 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TEUL);
2268 tcg_gen_shr_tl(t0, t0, t1);
2269 tcg_gen_xori_tl(t1, t1, 31);
2270 t2 = tcg_const_tl(0xfffffffeull);
2271 tcg_gen_shl_tl(t2, t2, t1);
2272 gen_load_gpr(t1, rt);
2273 tcg_gen_and_tl(t1, t1, t2);
2274 tcg_temp_free(t2);
2275 tcg_gen_or_tl(t0, t0, t1);
2276 tcg_temp_free(t1);
2277 tcg_gen_ext32s_tl(t0, t0);
2278 gen_store_gpr(t0, rt);
2279 break;
2280 case OPC_LL:
2281 case R6_OPC_LL:
2282 op_ld_ll(t0, t0, ctx);
2283 gen_store_gpr(t0, rt);
2284 break;
2286 tcg_temp_free(t0);
2289 /* Store */
2290 static void gen_st (DisasContext *ctx, uint32_t opc, int rt,
2291 int base, int16_t offset)
2293 TCGv t0 = tcg_temp_new();
2294 TCGv t1 = tcg_temp_new();
2296 gen_base_offset_addr(ctx, t0, base, offset);
2297 gen_load_gpr(t1, rt);
2298 switch (opc) {
2299 #if defined(TARGET_MIPS64)
2300 case OPC_SD:
2301 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEQ |
2302 ctx->default_tcg_memop_mask);
2303 break;
2304 case OPC_SDL:
2305 gen_helper_0e2i(sdl, t1, t0, ctx->mem_idx);
2306 break;
2307 case OPC_SDR:
2308 gen_helper_0e2i(sdr, t1, t0, ctx->mem_idx);
2309 break;
2310 #endif
2311 case OPC_SW:
2312 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL |
2313 ctx->default_tcg_memop_mask);
2314 break;
2315 case OPC_SH:
2316 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUW |
2317 ctx->default_tcg_memop_mask);
2318 break;
2319 case OPC_SB:
2320 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_8);
2321 break;
2322 case OPC_SWL:
2323 gen_helper_0e2i(swl, t1, t0, ctx->mem_idx);
2324 break;
2325 case OPC_SWR:
2326 gen_helper_0e2i(swr, t1, t0, ctx->mem_idx);
2327 break;
2329 tcg_temp_free(t0);
2330 tcg_temp_free(t1);
2334 /* Store conditional */
2335 static void gen_st_cond (DisasContext *ctx, uint32_t opc, int rt,
2336 int base, int16_t offset)
2338 TCGv t0, t1;
2340 #ifdef CONFIG_USER_ONLY
2341 t0 = tcg_temp_local_new();
2342 t1 = tcg_temp_local_new();
2343 #else
2344 t0 = tcg_temp_new();
2345 t1 = tcg_temp_new();
2346 #endif
2347 gen_base_offset_addr(ctx, t0, base, offset);
2348 gen_load_gpr(t1, rt);
2349 switch (opc) {
2350 #if defined(TARGET_MIPS64)
2351 case OPC_SCD:
2352 case R6_OPC_SCD:
2353 op_st_scd(t1, t0, rt, ctx);
2354 break;
2355 #endif
2356 case OPC_SC:
2357 case R6_OPC_SC:
2358 op_st_sc(t1, t0, rt, ctx);
2359 break;
2361 tcg_temp_free(t1);
2362 tcg_temp_free(t0);
2365 /* Load and store */
2366 static void gen_flt_ldst (DisasContext *ctx, uint32_t opc, int ft,
2367 int base, int16_t offset)
2369 TCGv t0 = tcg_temp_new();
2371 gen_base_offset_addr(ctx, t0, base, offset);
2372 /* Don't do NOP if destination is zero: we must perform the actual
2373 memory access. */
2374 switch (opc) {
2375 case OPC_LWC1:
2377 TCGv_i32 fp0 = tcg_temp_new_i32();
2378 tcg_gen_qemu_ld_i32(fp0, t0, ctx->mem_idx, MO_TESL |
2379 ctx->default_tcg_memop_mask);
2380 gen_store_fpr32(ctx, fp0, ft);
2381 tcg_temp_free_i32(fp0);
2383 break;
2384 case OPC_SWC1:
2386 TCGv_i32 fp0 = tcg_temp_new_i32();
2387 gen_load_fpr32(ctx, fp0, ft);
2388 tcg_gen_qemu_st_i32(fp0, t0, ctx->mem_idx, MO_TEUL |
2389 ctx->default_tcg_memop_mask);
2390 tcg_temp_free_i32(fp0);
2392 break;
2393 case OPC_LDC1:
2395 TCGv_i64 fp0 = tcg_temp_new_i64();
2396 tcg_gen_qemu_ld_i64(fp0, t0, ctx->mem_idx, MO_TEQ |
2397 ctx->default_tcg_memop_mask);
2398 gen_store_fpr64(ctx, fp0, ft);
2399 tcg_temp_free_i64(fp0);
2401 break;
2402 case OPC_SDC1:
2404 TCGv_i64 fp0 = tcg_temp_new_i64();
2405 gen_load_fpr64(ctx, fp0, ft);
2406 tcg_gen_qemu_st_i64(fp0, t0, ctx->mem_idx, MO_TEQ |
2407 ctx->default_tcg_memop_mask);
2408 tcg_temp_free_i64(fp0);
2410 break;
2411 default:
2412 MIPS_INVAL("flt_ldst");
2413 generate_exception_end(ctx, EXCP_RI);
2414 goto out;
2416 out:
2417 tcg_temp_free(t0);
2420 static void gen_cop1_ldst(DisasContext *ctx, uint32_t op, int rt,
2421 int rs, int16_t imm)
2423 if (ctx->CP0_Config1 & (1 << CP0C1_FP)) {
2424 check_cp1_enabled(ctx);
2425 switch (op) {
2426 case OPC_LDC1:
2427 case OPC_SDC1:
2428 check_insn(ctx, ISA_MIPS2);
2429 /* Fallthrough */
2430 default:
2431 gen_flt_ldst(ctx, op, rt, rs, imm);
2433 } else {
2434 generate_exception_err(ctx, EXCP_CpU, 1);
2438 /* Arithmetic with immediate operand */
2439 static void gen_arith_imm(DisasContext *ctx, uint32_t opc,
2440 int rt, int rs, int16_t imm)
2442 target_ulong uimm = (target_long)imm; /* Sign extend to 32/64 bits */
2444 if (rt == 0 && opc != OPC_ADDI && opc != OPC_DADDI) {
2445 /* If no destination, treat it as a NOP.
2446 For addi, we must generate the overflow exception when needed. */
2447 return;
2449 switch (opc) {
2450 case OPC_ADDI:
2452 TCGv t0 = tcg_temp_local_new();
2453 TCGv t1 = tcg_temp_new();
2454 TCGv t2 = tcg_temp_new();
2455 TCGLabel *l1 = gen_new_label();
2457 gen_load_gpr(t1, rs);
2458 tcg_gen_addi_tl(t0, t1, uimm);
2459 tcg_gen_ext32s_tl(t0, t0);
2461 tcg_gen_xori_tl(t1, t1, ~uimm);
2462 tcg_gen_xori_tl(t2, t0, uimm);
2463 tcg_gen_and_tl(t1, t1, t2);
2464 tcg_temp_free(t2);
2465 tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
2466 tcg_temp_free(t1);
2467 /* operands of same sign, result different sign */
2468 generate_exception(ctx, EXCP_OVERFLOW);
2469 gen_set_label(l1);
2470 tcg_gen_ext32s_tl(t0, t0);
2471 gen_store_gpr(t0, rt);
2472 tcg_temp_free(t0);
2474 break;
2475 case OPC_ADDIU:
2476 if (rs != 0) {
2477 tcg_gen_addi_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
2478 tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]);
2479 } else {
2480 tcg_gen_movi_tl(cpu_gpr[rt], uimm);
2482 break;
2483 #if defined(TARGET_MIPS64)
2484 case OPC_DADDI:
2486 TCGv t0 = tcg_temp_local_new();
2487 TCGv t1 = tcg_temp_new();
2488 TCGv t2 = tcg_temp_new();
2489 TCGLabel *l1 = gen_new_label();
2491 gen_load_gpr(t1, rs);
2492 tcg_gen_addi_tl(t0, t1, uimm);
2494 tcg_gen_xori_tl(t1, t1, ~uimm);
2495 tcg_gen_xori_tl(t2, t0, uimm);
2496 tcg_gen_and_tl(t1, t1, t2);
2497 tcg_temp_free(t2);
2498 tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
2499 tcg_temp_free(t1);
2500 /* operands of same sign, result different sign */
2501 generate_exception(ctx, EXCP_OVERFLOW);
2502 gen_set_label(l1);
2503 gen_store_gpr(t0, rt);
2504 tcg_temp_free(t0);
2506 break;
2507 case OPC_DADDIU:
2508 if (rs != 0) {
2509 tcg_gen_addi_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
2510 } else {
2511 tcg_gen_movi_tl(cpu_gpr[rt], uimm);
2513 break;
2514 #endif
2518 /* Logic with immediate operand */
2519 static void gen_logic_imm(DisasContext *ctx, uint32_t opc,
2520 int rt, int rs, int16_t imm)
2522 target_ulong uimm;
2524 if (rt == 0) {
2525 /* If no destination, treat it as a NOP. */
2526 return;
2528 uimm = (uint16_t)imm;
2529 switch (opc) {
2530 case OPC_ANDI:
2531 if (likely(rs != 0))
2532 tcg_gen_andi_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
2533 else
2534 tcg_gen_movi_tl(cpu_gpr[rt], 0);
2535 break;
2536 case OPC_ORI:
2537 if (rs != 0)
2538 tcg_gen_ori_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
2539 else
2540 tcg_gen_movi_tl(cpu_gpr[rt], uimm);
2541 break;
2542 case OPC_XORI:
2543 if (likely(rs != 0))
2544 tcg_gen_xori_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
2545 else
2546 tcg_gen_movi_tl(cpu_gpr[rt], uimm);
2547 break;
2548 case OPC_LUI:
2549 if (rs != 0 && (ctx->insn_flags & ISA_MIPS32R6)) {
2550 /* OPC_AUI */
2551 tcg_gen_addi_tl(cpu_gpr[rt], cpu_gpr[rs], imm << 16);
2552 tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]);
2553 } else {
2554 tcg_gen_movi_tl(cpu_gpr[rt], imm << 16);
2556 break;
2558 default:
2559 break;
2563 /* Set on less than with immediate operand */
2564 static void gen_slt_imm(DisasContext *ctx, uint32_t opc,
2565 int rt, int rs, int16_t imm)
2567 target_ulong uimm = (target_long)imm; /* Sign extend to 32/64 bits */
2568 TCGv t0;
2570 if (rt == 0) {
2571 /* If no destination, treat it as a NOP. */
2572 return;
2574 t0 = tcg_temp_new();
2575 gen_load_gpr(t0, rs);
2576 switch (opc) {
2577 case OPC_SLTI:
2578 tcg_gen_setcondi_tl(TCG_COND_LT, cpu_gpr[rt], t0, uimm);
2579 break;
2580 case OPC_SLTIU:
2581 tcg_gen_setcondi_tl(TCG_COND_LTU, cpu_gpr[rt], t0, uimm);
2582 break;
2584 tcg_temp_free(t0);
2587 /* Shifts with immediate operand */
2588 static void gen_shift_imm(DisasContext *ctx, uint32_t opc,
2589 int rt, int rs, int16_t imm)
2591 target_ulong uimm = ((uint16_t)imm) & 0x1f;
2592 TCGv t0;
2594 if (rt == 0) {
2595 /* If no destination, treat it as a NOP. */
2596 return;
2599 t0 = tcg_temp_new();
2600 gen_load_gpr(t0, rs);
2601 switch (opc) {
2602 case OPC_SLL:
2603 tcg_gen_shli_tl(t0, t0, uimm);
2604 tcg_gen_ext32s_tl(cpu_gpr[rt], t0);
2605 break;
2606 case OPC_SRA:
2607 tcg_gen_sari_tl(cpu_gpr[rt], t0, uimm);
2608 break;
2609 case OPC_SRL:
2610 if (uimm != 0) {
2611 tcg_gen_ext32u_tl(t0, t0);
2612 tcg_gen_shri_tl(cpu_gpr[rt], t0, uimm);
2613 } else {
2614 tcg_gen_ext32s_tl(cpu_gpr[rt], t0);
2616 break;
2617 case OPC_ROTR:
2618 if (uimm != 0) {
2619 TCGv_i32 t1 = tcg_temp_new_i32();
2621 tcg_gen_trunc_tl_i32(t1, t0);
2622 tcg_gen_rotri_i32(t1, t1, uimm);
2623 tcg_gen_ext_i32_tl(cpu_gpr[rt], t1);
2624 tcg_temp_free_i32(t1);
2625 } else {
2626 tcg_gen_ext32s_tl(cpu_gpr[rt], t0);
2628 break;
2629 #if defined(TARGET_MIPS64)
2630 case OPC_DSLL:
2631 tcg_gen_shli_tl(cpu_gpr[rt], t0, uimm);
2632 break;
2633 case OPC_DSRA:
2634 tcg_gen_sari_tl(cpu_gpr[rt], t0, uimm);
2635 break;
2636 case OPC_DSRL:
2637 tcg_gen_shri_tl(cpu_gpr[rt], t0, uimm);
2638 break;
2639 case OPC_DROTR:
2640 if (uimm != 0) {
2641 tcg_gen_rotri_tl(cpu_gpr[rt], t0, uimm);
2642 } else {
2643 tcg_gen_mov_tl(cpu_gpr[rt], t0);
2645 break;
2646 case OPC_DSLL32:
2647 tcg_gen_shli_tl(cpu_gpr[rt], t0, uimm + 32);
2648 break;
2649 case OPC_DSRA32:
2650 tcg_gen_sari_tl(cpu_gpr[rt], t0, uimm + 32);
2651 break;
2652 case OPC_DSRL32:
2653 tcg_gen_shri_tl(cpu_gpr[rt], t0, uimm + 32);
2654 break;
2655 case OPC_DROTR32:
2656 tcg_gen_rotri_tl(cpu_gpr[rt], t0, uimm + 32);
2657 break;
2658 #endif
2660 tcg_temp_free(t0);
2663 /* Arithmetic */
2664 static void gen_arith(DisasContext *ctx, uint32_t opc,
2665 int rd, int rs, int rt)
2667 if (rd == 0 && opc != OPC_ADD && opc != OPC_SUB
2668 && opc != OPC_DADD && opc != OPC_DSUB) {
2669 /* If no destination, treat it as a NOP.
2670 For add & sub, we must generate the overflow exception when needed. */
2671 return;
2674 switch (opc) {
2675 case OPC_ADD:
2677 TCGv t0 = tcg_temp_local_new();
2678 TCGv t1 = tcg_temp_new();
2679 TCGv t2 = tcg_temp_new();
2680 TCGLabel *l1 = gen_new_label();
2682 gen_load_gpr(t1, rs);
2683 gen_load_gpr(t2, rt);
2684 tcg_gen_add_tl(t0, t1, t2);
2685 tcg_gen_ext32s_tl(t0, t0);
2686 tcg_gen_xor_tl(t1, t1, t2);
2687 tcg_gen_xor_tl(t2, t0, t2);
2688 tcg_gen_andc_tl(t1, t2, t1);
2689 tcg_temp_free(t2);
2690 tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
2691 tcg_temp_free(t1);
2692 /* operands of same sign, result different sign */
2693 generate_exception(ctx, EXCP_OVERFLOW);
2694 gen_set_label(l1);
2695 gen_store_gpr(t0, rd);
2696 tcg_temp_free(t0);
2698 break;
2699 case OPC_ADDU:
2700 if (rs != 0 && rt != 0) {
2701 tcg_gen_add_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2702 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
2703 } else if (rs == 0 && rt != 0) {
2704 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rt]);
2705 } else if (rs != 0 && rt == 0) {
2706 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
2707 } else {
2708 tcg_gen_movi_tl(cpu_gpr[rd], 0);
2710 break;
2711 case OPC_SUB:
2713 TCGv t0 = tcg_temp_local_new();
2714 TCGv t1 = tcg_temp_new();
2715 TCGv t2 = tcg_temp_new();
2716 TCGLabel *l1 = gen_new_label();
2718 gen_load_gpr(t1, rs);
2719 gen_load_gpr(t2, rt);
2720 tcg_gen_sub_tl(t0, t1, t2);
2721 tcg_gen_ext32s_tl(t0, t0);
2722 tcg_gen_xor_tl(t2, t1, t2);
2723 tcg_gen_xor_tl(t1, t0, t1);
2724 tcg_gen_and_tl(t1, t1, t2);
2725 tcg_temp_free(t2);
2726 tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
2727 tcg_temp_free(t1);
2728 /* operands of different sign, first operand and result different sign */
2729 generate_exception(ctx, EXCP_OVERFLOW);
2730 gen_set_label(l1);
2731 gen_store_gpr(t0, rd);
2732 tcg_temp_free(t0);
2734 break;
2735 case OPC_SUBU:
2736 if (rs != 0 && rt != 0) {
2737 tcg_gen_sub_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_neg_tl(cpu_gpr[rd], cpu_gpr[rt]);
2741 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
2742 } else if (rs != 0 && rt == 0) {
2743 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
2744 } else {
2745 tcg_gen_movi_tl(cpu_gpr[rd], 0);
2747 break;
2748 #if defined(TARGET_MIPS64)
2749 case OPC_DADD:
2751 TCGv t0 = tcg_temp_local_new();
2752 TCGv t1 = tcg_temp_new();
2753 TCGv t2 = tcg_temp_new();
2754 TCGLabel *l1 = gen_new_label();
2756 gen_load_gpr(t1, rs);
2757 gen_load_gpr(t2, rt);
2758 tcg_gen_add_tl(t0, t1, t2);
2759 tcg_gen_xor_tl(t1, t1, t2);
2760 tcg_gen_xor_tl(t2, t0, t2);
2761 tcg_gen_andc_tl(t1, t2, t1);
2762 tcg_temp_free(t2);
2763 tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
2764 tcg_temp_free(t1);
2765 /* operands of same sign, result different sign */
2766 generate_exception(ctx, EXCP_OVERFLOW);
2767 gen_set_label(l1);
2768 gen_store_gpr(t0, rd);
2769 tcg_temp_free(t0);
2771 break;
2772 case OPC_DADDU:
2773 if (rs != 0 && rt != 0) {
2774 tcg_gen_add_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2775 } else if (rs == 0 && rt != 0) {
2776 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rt]);
2777 } else if (rs != 0 && rt == 0) {
2778 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
2779 } else {
2780 tcg_gen_movi_tl(cpu_gpr[rd], 0);
2782 break;
2783 case OPC_DSUB:
2785 TCGv t0 = tcg_temp_local_new();
2786 TCGv t1 = tcg_temp_new();
2787 TCGv t2 = tcg_temp_new();
2788 TCGLabel *l1 = gen_new_label();
2790 gen_load_gpr(t1, rs);
2791 gen_load_gpr(t2, rt);
2792 tcg_gen_sub_tl(t0, t1, t2);
2793 tcg_gen_xor_tl(t2, t1, t2);
2794 tcg_gen_xor_tl(t1, t0, t1);
2795 tcg_gen_and_tl(t1, t1, t2);
2796 tcg_temp_free(t2);
2797 tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
2798 tcg_temp_free(t1);
2799 /* operands of different sign, first operand and result different sign */
2800 generate_exception(ctx, EXCP_OVERFLOW);
2801 gen_set_label(l1);
2802 gen_store_gpr(t0, rd);
2803 tcg_temp_free(t0);
2805 break;
2806 case OPC_DSUBU:
2807 if (rs != 0 && rt != 0) {
2808 tcg_gen_sub_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2809 } else if (rs == 0 && rt != 0) {
2810 tcg_gen_neg_tl(cpu_gpr[rd], cpu_gpr[rt]);
2811 } else if (rs != 0 && rt == 0) {
2812 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
2813 } else {
2814 tcg_gen_movi_tl(cpu_gpr[rd], 0);
2816 break;
2817 #endif
2818 case OPC_MUL:
2819 if (likely(rs != 0 && rt != 0)) {
2820 tcg_gen_mul_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2821 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
2822 } else {
2823 tcg_gen_movi_tl(cpu_gpr[rd], 0);
2825 break;
2829 /* Conditional move */
2830 static void gen_cond_move(DisasContext *ctx, uint32_t opc,
2831 int rd, int rs, int rt)
2833 TCGv t0, t1, t2;
2835 if (rd == 0) {
2836 /* If no destination, treat it as a NOP. */
2837 return;
2840 t0 = tcg_temp_new();
2841 gen_load_gpr(t0, rt);
2842 t1 = tcg_const_tl(0);
2843 t2 = tcg_temp_new();
2844 gen_load_gpr(t2, rs);
2845 switch (opc) {
2846 case OPC_MOVN:
2847 tcg_gen_movcond_tl(TCG_COND_NE, cpu_gpr[rd], t0, t1, t2, cpu_gpr[rd]);
2848 break;
2849 case OPC_MOVZ:
2850 tcg_gen_movcond_tl(TCG_COND_EQ, cpu_gpr[rd], t0, t1, t2, cpu_gpr[rd]);
2851 break;
2852 case OPC_SELNEZ:
2853 tcg_gen_movcond_tl(TCG_COND_NE, cpu_gpr[rd], t0, t1, t2, t1);
2854 break;
2855 case OPC_SELEQZ:
2856 tcg_gen_movcond_tl(TCG_COND_EQ, cpu_gpr[rd], t0, t1, t2, t1);
2857 break;
2859 tcg_temp_free(t2);
2860 tcg_temp_free(t1);
2861 tcg_temp_free(t0);
2864 /* Logic */
2865 static void gen_logic(DisasContext *ctx, uint32_t opc,
2866 int rd, int rs, int rt)
2868 if (rd == 0) {
2869 /* If no destination, treat it as a NOP. */
2870 return;
2873 switch (opc) {
2874 case OPC_AND:
2875 if (likely(rs != 0 && rt != 0)) {
2876 tcg_gen_and_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2877 } else {
2878 tcg_gen_movi_tl(cpu_gpr[rd], 0);
2880 break;
2881 case OPC_NOR:
2882 if (rs != 0 && rt != 0) {
2883 tcg_gen_nor_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2884 } else if (rs == 0 && rt != 0) {
2885 tcg_gen_not_tl(cpu_gpr[rd], cpu_gpr[rt]);
2886 } else if (rs != 0 && rt == 0) {
2887 tcg_gen_not_tl(cpu_gpr[rd], cpu_gpr[rs]);
2888 } else {
2889 tcg_gen_movi_tl(cpu_gpr[rd], ~((target_ulong)0));
2891 break;
2892 case OPC_OR:
2893 if (likely(rs != 0 && rt != 0)) {
2894 tcg_gen_or_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2895 } else if (rs == 0 && rt != 0) {
2896 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rt]);
2897 } else if (rs != 0 && rt == 0) {
2898 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
2899 } else {
2900 tcg_gen_movi_tl(cpu_gpr[rd], 0);
2902 break;
2903 case OPC_XOR:
2904 if (likely(rs != 0 && rt != 0)) {
2905 tcg_gen_xor_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2906 } else if (rs == 0 && rt != 0) {
2907 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rt]);
2908 } else if (rs != 0 && rt == 0) {
2909 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
2910 } else {
2911 tcg_gen_movi_tl(cpu_gpr[rd], 0);
2913 break;
2917 /* Set on lower than */
2918 static void gen_slt(DisasContext *ctx, uint32_t opc,
2919 int rd, int rs, int rt)
2921 TCGv t0, t1;
2923 if (rd == 0) {
2924 /* If no destination, treat it as a NOP. */
2925 return;
2928 t0 = tcg_temp_new();
2929 t1 = tcg_temp_new();
2930 gen_load_gpr(t0, rs);
2931 gen_load_gpr(t1, rt);
2932 switch (opc) {
2933 case OPC_SLT:
2934 tcg_gen_setcond_tl(TCG_COND_LT, cpu_gpr[rd], t0, t1);
2935 break;
2936 case OPC_SLTU:
2937 tcg_gen_setcond_tl(TCG_COND_LTU, cpu_gpr[rd], t0, t1);
2938 break;
2940 tcg_temp_free(t0);
2941 tcg_temp_free(t1);
2944 /* Shifts */
2945 static void gen_shift(DisasContext *ctx, uint32_t opc,
2946 int rd, int rs, int rt)
2948 TCGv t0, t1;
2950 if (rd == 0) {
2951 /* If no destination, treat it as a NOP.
2952 For add & sub, we must generate the overflow exception when needed. */
2953 return;
2956 t0 = tcg_temp_new();
2957 t1 = tcg_temp_new();
2958 gen_load_gpr(t0, rs);
2959 gen_load_gpr(t1, rt);
2960 switch (opc) {
2961 case OPC_SLLV:
2962 tcg_gen_andi_tl(t0, t0, 0x1f);
2963 tcg_gen_shl_tl(t0, t1, t0);
2964 tcg_gen_ext32s_tl(cpu_gpr[rd], t0);
2965 break;
2966 case OPC_SRAV:
2967 tcg_gen_andi_tl(t0, t0, 0x1f);
2968 tcg_gen_sar_tl(cpu_gpr[rd], t1, t0);
2969 break;
2970 case OPC_SRLV:
2971 tcg_gen_ext32u_tl(t1, t1);
2972 tcg_gen_andi_tl(t0, t0, 0x1f);
2973 tcg_gen_shr_tl(t0, t1, t0);
2974 tcg_gen_ext32s_tl(cpu_gpr[rd], t0);
2975 break;
2976 case OPC_ROTRV:
2978 TCGv_i32 t2 = tcg_temp_new_i32();
2979 TCGv_i32 t3 = tcg_temp_new_i32();
2981 tcg_gen_trunc_tl_i32(t2, t0);
2982 tcg_gen_trunc_tl_i32(t3, t1);
2983 tcg_gen_andi_i32(t2, t2, 0x1f);
2984 tcg_gen_rotr_i32(t2, t3, t2);
2985 tcg_gen_ext_i32_tl(cpu_gpr[rd], t2);
2986 tcg_temp_free_i32(t2);
2987 tcg_temp_free_i32(t3);
2989 break;
2990 #if defined(TARGET_MIPS64)
2991 case OPC_DSLLV:
2992 tcg_gen_andi_tl(t0, t0, 0x3f);
2993 tcg_gen_shl_tl(cpu_gpr[rd], t1, t0);
2994 break;
2995 case OPC_DSRAV:
2996 tcg_gen_andi_tl(t0, t0, 0x3f);
2997 tcg_gen_sar_tl(cpu_gpr[rd], t1, t0);
2998 break;
2999 case OPC_DSRLV:
3000 tcg_gen_andi_tl(t0, t0, 0x3f);
3001 tcg_gen_shr_tl(cpu_gpr[rd], t1, t0);
3002 break;
3003 case OPC_DROTRV:
3004 tcg_gen_andi_tl(t0, t0, 0x3f);
3005 tcg_gen_rotr_tl(cpu_gpr[rd], t1, t0);
3006 break;
3007 #endif
3009 tcg_temp_free(t0);
3010 tcg_temp_free(t1);
3013 /* Arithmetic on HI/LO registers */
3014 static void gen_HILO(DisasContext *ctx, uint32_t opc, int acc, int reg)
3016 if (reg == 0 && (opc == OPC_MFHI || opc == OPC_MFLO)) {
3017 /* Treat as NOP. */
3018 return;
3021 if (acc != 0) {
3022 check_dsp(ctx);
3025 switch (opc) {
3026 case OPC_MFHI:
3027 #if defined(TARGET_MIPS64)
3028 if (acc != 0) {
3029 tcg_gen_ext32s_tl(cpu_gpr[reg], cpu_HI[acc]);
3030 } else
3031 #endif
3033 tcg_gen_mov_tl(cpu_gpr[reg], cpu_HI[acc]);
3035 break;
3036 case OPC_MFLO:
3037 #if defined(TARGET_MIPS64)
3038 if (acc != 0) {
3039 tcg_gen_ext32s_tl(cpu_gpr[reg], cpu_LO[acc]);
3040 } else
3041 #endif
3043 tcg_gen_mov_tl(cpu_gpr[reg], cpu_LO[acc]);
3045 break;
3046 case OPC_MTHI:
3047 if (reg != 0) {
3048 #if defined(TARGET_MIPS64)
3049 if (acc != 0) {
3050 tcg_gen_ext32s_tl(cpu_HI[acc], cpu_gpr[reg]);
3051 } else
3052 #endif
3054 tcg_gen_mov_tl(cpu_HI[acc], cpu_gpr[reg]);
3056 } else {
3057 tcg_gen_movi_tl(cpu_HI[acc], 0);
3059 break;
3060 case OPC_MTLO:
3061 if (reg != 0) {
3062 #if defined(TARGET_MIPS64)
3063 if (acc != 0) {
3064 tcg_gen_ext32s_tl(cpu_LO[acc], cpu_gpr[reg]);
3065 } else
3066 #endif
3068 tcg_gen_mov_tl(cpu_LO[acc], cpu_gpr[reg]);
3070 } else {
3071 tcg_gen_movi_tl(cpu_LO[acc], 0);
3073 break;
3077 static inline void gen_r6_ld(target_long addr, int reg, int memidx,
3078 TCGMemOp memop)
3080 TCGv t0 = tcg_const_tl(addr);
3081 tcg_gen_qemu_ld_tl(t0, t0, memidx, memop);
3082 gen_store_gpr(t0, reg);
3083 tcg_temp_free(t0);
3086 static inline void gen_pcrel(DisasContext *ctx, int opc, target_ulong pc,
3087 int rs)
3089 target_long offset;
3090 target_long addr;
3092 switch (MASK_OPC_PCREL_TOP2BITS(opc)) {
3093 case OPC_ADDIUPC:
3094 if (rs != 0) {
3095 offset = sextract32(ctx->opcode << 2, 0, 21);
3096 addr = addr_add(ctx, pc, offset);
3097 tcg_gen_movi_tl(cpu_gpr[rs], addr);
3099 break;
3100 case R6_OPC_LWPC:
3101 offset = sextract32(ctx->opcode << 2, 0, 21);
3102 addr = addr_add(ctx, pc, offset);
3103 gen_r6_ld(addr, rs, ctx->mem_idx, MO_TESL);
3104 break;
3105 #if defined(TARGET_MIPS64)
3106 case OPC_LWUPC:
3107 check_mips_64(ctx);
3108 offset = sextract32(ctx->opcode << 2, 0, 21);
3109 addr = addr_add(ctx, pc, offset);
3110 gen_r6_ld(addr, rs, ctx->mem_idx, MO_TEUL);
3111 break;
3112 #endif
3113 default:
3114 switch (MASK_OPC_PCREL_TOP5BITS(opc)) {
3115 case OPC_AUIPC:
3116 if (rs != 0) {
3117 offset = sextract32(ctx->opcode, 0, 16) << 16;
3118 addr = addr_add(ctx, pc, offset);
3119 tcg_gen_movi_tl(cpu_gpr[rs], addr);
3121 break;
3122 case OPC_ALUIPC:
3123 if (rs != 0) {
3124 offset = sextract32(ctx->opcode, 0, 16) << 16;
3125 addr = ~0xFFFF & addr_add(ctx, pc, offset);
3126 tcg_gen_movi_tl(cpu_gpr[rs], addr);
3128 break;
3129 #if defined(TARGET_MIPS64)
3130 case R6_OPC_LDPC: /* bits 16 and 17 are part of immediate */
3131 case R6_OPC_LDPC + (1 << 16):
3132 case R6_OPC_LDPC + (2 << 16):
3133 case R6_OPC_LDPC + (3 << 16):
3134 check_mips_64(ctx);
3135 offset = sextract32(ctx->opcode << 3, 0, 21);
3136 addr = addr_add(ctx, (pc & ~0x7), offset);
3137 gen_r6_ld(addr, rs, ctx->mem_idx, MO_TEQ);
3138 break;
3139 #endif
3140 default:
3141 MIPS_INVAL("OPC_PCREL");
3142 generate_exception_end(ctx, EXCP_RI);
3143 break;
3145 break;
3149 static void gen_r6_muldiv(DisasContext *ctx, int opc, int rd, int rs, int rt)
3151 TCGv t0, t1;
3153 if (rd == 0) {
3154 /* Treat as NOP. */
3155 return;
3158 t0 = tcg_temp_new();
3159 t1 = tcg_temp_new();
3161 gen_load_gpr(t0, rs);
3162 gen_load_gpr(t1, rt);
3164 switch (opc) {
3165 case R6_OPC_DIV:
3167 TCGv t2 = tcg_temp_new();
3168 TCGv t3 = tcg_temp_new();
3169 tcg_gen_ext32s_tl(t0, t0);
3170 tcg_gen_ext32s_tl(t1, t1);
3171 tcg_gen_setcondi_tl(TCG_COND_EQ, t2, t0, INT_MIN);
3172 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, -1);
3173 tcg_gen_and_tl(t2, t2, t3);
3174 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, 0);
3175 tcg_gen_or_tl(t2, t2, t3);
3176 tcg_gen_movi_tl(t3, 0);
3177 tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, t3, t2, t1);
3178 tcg_gen_div_tl(cpu_gpr[rd], t0, t1);
3179 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3180 tcg_temp_free(t3);
3181 tcg_temp_free(t2);
3183 break;
3184 case R6_OPC_MOD:
3186 TCGv t2 = tcg_temp_new();
3187 TCGv t3 = tcg_temp_new();
3188 tcg_gen_ext32s_tl(t0, t0);
3189 tcg_gen_ext32s_tl(t1, t1);
3190 tcg_gen_setcondi_tl(TCG_COND_EQ, t2, t0, INT_MIN);
3191 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, -1);
3192 tcg_gen_and_tl(t2, t2, t3);
3193 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, 0);
3194 tcg_gen_or_tl(t2, t2, t3);
3195 tcg_gen_movi_tl(t3, 0);
3196 tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, t3, t2, t1);
3197 tcg_gen_rem_tl(cpu_gpr[rd], t0, t1);
3198 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3199 tcg_temp_free(t3);
3200 tcg_temp_free(t2);
3202 break;
3203 case R6_OPC_DIVU:
3205 TCGv t2 = tcg_const_tl(0);
3206 TCGv t3 = tcg_const_tl(1);
3207 tcg_gen_ext32u_tl(t0, t0);
3208 tcg_gen_ext32u_tl(t1, t1);
3209 tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1, t2, t3, t1);
3210 tcg_gen_divu_tl(cpu_gpr[rd], t0, t1);
3211 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3212 tcg_temp_free(t3);
3213 tcg_temp_free(t2);
3215 break;
3216 case R6_OPC_MODU:
3218 TCGv t2 = tcg_const_tl(0);
3219 TCGv t3 = tcg_const_tl(1);
3220 tcg_gen_ext32u_tl(t0, t0);
3221 tcg_gen_ext32u_tl(t1, t1);
3222 tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1, t2, t3, t1);
3223 tcg_gen_remu_tl(cpu_gpr[rd], t0, t1);
3224 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3225 tcg_temp_free(t3);
3226 tcg_temp_free(t2);
3228 break;
3229 case R6_OPC_MUL:
3231 TCGv_i32 t2 = tcg_temp_new_i32();
3232 TCGv_i32 t3 = tcg_temp_new_i32();
3233 tcg_gen_trunc_tl_i32(t2, t0);
3234 tcg_gen_trunc_tl_i32(t3, t1);
3235 tcg_gen_mul_i32(t2, t2, t3);
3236 tcg_gen_ext_i32_tl(cpu_gpr[rd], t2);
3237 tcg_temp_free_i32(t2);
3238 tcg_temp_free_i32(t3);
3240 break;
3241 case R6_OPC_MUH:
3243 TCGv_i32 t2 = tcg_temp_new_i32();
3244 TCGv_i32 t3 = tcg_temp_new_i32();
3245 tcg_gen_trunc_tl_i32(t2, t0);
3246 tcg_gen_trunc_tl_i32(t3, t1);
3247 tcg_gen_muls2_i32(t2, t3, t2, t3);
3248 tcg_gen_ext_i32_tl(cpu_gpr[rd], t3);
3249 tcg_temp_free_i32(t2);
3250 tcg_temp_free_i32(t3);
3252 break;
3253 case R6_OPC_MULU:
3255 TCGv_i32 t2 = tcg_temp_new_i32();
3256 TCGv_i32 t3 = tcg_temp_new_i32();
3257 tcg_gen_trunc_tl_i32(t2, t0);
3258 tcg_gen_trunc_tl_i32(t3, t1);
3259 tcg_gen_mul_i32(t2, t2, t3);
3260 tcg_gen_ext_i32_tl(cpu_gpr[rd], t2);
3261 tcg_temp_free_i32(t2);
3262 tcg_temp_free_i32(t3);
3264 break;
3265 case R6_OPC_MUHU:
3267 TCGv_i32 t2 = tcg_temp_new_i32();
3268 TCGv_i32 t3 = tcg_temp_new_i32();
3269 tcg_gen_trunc_tl_i32(t2, t0);
3270 tcg_gen_trunc_tl_i32(t3, t1);
3271 tcg_gen_mulu2_i32(t2, t3, t2, t3);
3272 tcg_gen_ext_i32_tl(cpu_gpr[rd], t3);
3273 tcg_temp_free_i32(t2);
3274 tcg_temp_free_i32(t3);
3276 break;
3277 #if defined(TARGET_MIPS64)
3278 case R6_OPC_DDIV:
3280 TCGv t2 = tcg_temp_new();
3281 TCGv t3 = tcg_temp_new();
3282 tcg_gen_setcondi_tl(TCG_COND_EQ, t2, t0, -1LL << 63);
3283 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, -1LL);
3284 tcg_gen_and_tl(t2, t2, t3);
3285 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, 0);
3286 tcg_gen_or_tl(t2, t2, t3);
3287 tcg_gen_movi_tl(t3, 0);
3288 tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, t3, t2, t1);
3289 tcg_gen_div_tl(cpu_gpr[rd], t0, t1);
3290 tcg_temp_free(t3);
3291 tcg_temp_free(t2);
3293 break;
3294 case R6_OPC_DMOD:
3296 TCGv t2 = tcg_temp_new();
3297 TCGv t3 = tcg_temp_new();
3298 tcg_gen_setcondi_tl(TCG_COND_EQ, t2, t0, -1LL << 63);
3299 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, -1LL);
3300 tcg_gen_and_tl(t2, t2, t3);
3301 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, 0);
3302 tcg_gen_or_tl(t2, t2, t3);
3303 tcg_gen_movi_tl(t3, 0);
3304 tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, t3, t2, t1);
3305 tcg_gen_rem_tl(cpu_gpr[rd], t0, t1);
3306 tcg_temp_free(t3);
3307 tcg_temp_free(t2);
3309 break;
3310 case R6_OPC_DDIVU:
3312 TCGv t2 = tcg_const_tl(0);
3313 TCGv t3 = tcg_const_tl(1);
3314 tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1, t2, t3, t1);
3315 tcg_gen_divu_i64(cpu_gpr[rd], t0, t1);
3316 tcg_temp_free(t3);
3317 tcg_temp_free(t2);
3319 break;
3320 case R6_OPC_DMODU:
3322 TCGv t2 = tcg_const_tl(0);
3323 TCGv t3 = tcg_const_tl(1);
3324 tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1, t2, t3, t1);
3325 tcg_gen_remu_i64(cpu_gpr[rd], t0, t1);
3326 tcg_temp_free(t3);
3327 tcg_temp_free(t2);
3329 break;
3330 case R6_OPC_DMUL:
3331 tcg_gen_mul_i64(cpu_gpr[rd], t0, t1);
3332 break;
3333 case R6_OPC_DMUH:
3335 TCGv t2 = tcg_temp_new();
3336 tcg_gen_muls2_i64(t2, cpu_gpr[rd], t0, t1);
3337 tcg_temp_free(t2);
3339 break;
3340 case R6_OPC_DMULU:
3341 tcg_gen_mul_i64(cpu_gpr[rd], t0, t1);
3342 break;
3343 case R6_OPC_DMUHU:
3345 TCGv t2 = tcg_temp_new();
3346 tcg_gen_mulu2_i64(t2, cpu_gpr[rd], t0, t1);
3347 tcg_temp_free(t2);
3349 break;
3350 #endif
3351 default:
3352 MIPS_INVAL("r6 mul/div");
3353 generate_exception_end(ctx, EXCP_RI);
3354 goto out;
3356 out:
3357 tcg_temp_free(t0);
3358 tcg_temp_free(t1);
3361 static void gen_muldiv(DisasContext *ctx, uint32_t opc,
3362 int acc, int rs, int rt)
3364 TCGv t0, t1;
3366 t0 = tcg_temp_new();
3367 t1 = tcg_temp_new();
3369 gen_load_gpr(t0, rs);
3370 gen_load_gpr(t1, rt);
3372 if (acc != 0) {
3373 check_dsp(ctx);
3376 switch (opc) {
3377 case OPC_DIV:
3379 TCGv t2 = tcg_temp_new();
3380 TCGv t3 = tcg_temp_new();
3381 tcg_gen_ext32s_tl(t0, t0);
3382 tcg_gen_ext32s_tl(t1, t1);
3383 tcg_gen_setcondi_tl(TCG_COND_EQ, t2, t0, INT_MIN);
3384 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, -1);
3385 tcg_gen_and_tl(t2, t2, t3);
3386 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, 0);
3387 tcg_gen_or_tl(t2, t2, t3);
3388 tcg_gen_movi_tl(t3, 0);
3389 tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, t3, t2, t1);
3390 tcg_gen_div_tl(cpu_LO[acc], t0, t1);
3391 tcg_gen_rem_tl(cpu_HI[acc], t0, t1);
3392 tcg_gen_ext32s_tl(cpu_LO[acc], cpu_LO[acc]);
3393 tcg_gen_ext32s_tl(cpu_HI[acc], cpu_HI[acc]);
3394 tcg_temp_free(t3);
3395 tcg_temp_free(t2);
3397 break;
3398 case OPC_DIVU:
3400 TCGv t2 = tcg_const_tl(0);
3401 TCGv t3 = tcg_const_tl(1);
3402 tcg_gen_ext32u_tl(t0, t0);
3403 tcg_gen_ext32u_tl(t1, t1);
3404 tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1, t2, t3, t1);
3405 tcg_gen_divu_tl(cpu_LO[acc], t0, t1);
3406 tcg_gen_remu_tl(cpu_HI[acc], t0, t1);
3407 tcg_gen_ext32s_tl(cpu_LO[acc], cpu_LO[acc]);
3408 tcg_gen_ext32s_tl(cpu_HI[acc], cpu_HI[acc]);
3409 tcg_temp_free(t3);
3410 tcg_temp_free(t2);
3412 break;
3413 case OPC_MULT:
3415 TCGv_i32 t2 = tcg_temp_new_i32();
3416 TCGv_i32 t3 = tcg_temp_new_i32();
3417 tcg_gen_trunc_tl_i32(t2, t0);
3418 tcg_gen_trunc_tl_i32(t3, t1);
3419 tcg_gen_muls2_i32(t2, t3, t2, t3);
3420 tcg_gen_ext_i32_tl(cpu_LO[acc], t2);
3421 tcg_gen_ext_i32_tl(cpu_HI[acc], t3);
3422 tcg_temp_free_i32(t2);
3423 tcg_temp_free_i32(t3);
3425 break;
3426 case OPC_MULTU:
3428 TCGv_i32 t2 = tcg_temp_new_i32();
3429 TCGv_i32 t3 = tcg_temp_new_i32();
3430 tcg_gen_trunc_tl_i32(t2, t0);
3431 tcg_gen_trunc_tl_i32(t3, t1);
3432 tcg_gen_mulu2_i32(t2, t3, t2, t3);
3433 tcg_gen_ext_i32_tl(cpu_LO[acc], t2);
3434 tcg_gen_ext_i32_tl(cpu_HI[acc], t3);
3435 tcg_temp_free_i32(t2);
3436 tcg_temp_free_i32(t3);
3438 break;
3439 #if defined(TARGET_MIPS64)
3440 case OPC_DDIV:
3442 TCGv t2 = tcg_temp_new();
3443 TCGv t3 = tcg_temp_new();
3444 tcg_gen_setcondi_tl(TCG_COND_EQ, t2, t0, -1LL << 63);
3445 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, -1LL);
3446 tcg_gen_and_tl(t2, t2, t3);
3447 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, 0);
3448 tcg_gen_or_tl(t2, t2, t3);
3449 tcg_gen_movi_tl(t3, 0);
3450 tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, t3, t2, t1);
3451 tcg_gen_div_tl(cpu_LO[acc], t0, t1);
3452 tcg_gen_rem_tl(cpu_HI[acc], t0, t1);
3453 tcg_temp_free(t3);
3454 tcg_temp_free(t2);
3456 break;
3457 case OPC_DDIVU:
3459 TCGv t2 = tcg_const_tl(0);
3460 TCGv t3 = tcg_const_tl(1);
3461 tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1, t2, t3, t1);
3462 tcg_gen_divu_i64(cpu_LO[acc], t0, t1);
3463 tcg_gen_remu_i64(cpu_HI[acc], t0, t1);
3464 tcg_temp_free(t3);
3465 tcg_temp_free(t2);
3467 break;
3468 case OPC_DMULT:
3469 tcg_gen_muls2_i64(cpu_LO[acc], cpu_HI[acc], t0, t1);
3470 break;
3471 case OPC_DMULTU:
3472 tcg_gen_mulu2_i64(cpu_LO[acc], cpu_HI[acc], t0, t1);
3473 break;
3474 #endif
3475 case OPC_MADD:
3477 TCGv_i64 t2 = tcg_temp_new_i64();
3478 TCGv_i64 t3 = tcg_temp_new_i64();
3480 tcg_gen_ext_tl_i64(t2, t0);
3481 tcg_gen_ext_tl_i64(t3, t1);
3482 tcg_gen_mul_i64(t2, t2, t3);
3483 tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]);
3484 tcg_gen_add_i64(t2, t2, t3);
3485 tcg_temp_free_i64(t3);
3486 gen_move_low32(cpu_LO[acc], t2);
3487 gen_move_high32(cpu_HI[acc], t2);
3488 tcg_temp_free_i64(t2);
3490 break;
3491 case OPC_MADDU:
3493 TCGv_i64 t2 = tcg_temp_new_i64();
3494 TCGv_i64 t3 = tcg_temp_new_i64();
3496 tcg_gen_ext32u_tl(t0, t0);
3497 tcg_gen_ext32u_tl(t1, t1);
3498 tcg_gen_extu_tl_i64(t2, t0);
3499 tcg_gen_extu_tl_i64(t3, t1);
3500 tcg_gen_mul_i64(t2, t2, t3);
3501 tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]);
3502 tcg_gen_add_i64(t2, t2, t3);
3503 tcg_temp_free_i64(t3);
3504 gen_move_low32(cpu_LO[acc], t2);
3505 gen_move_high32(cpu_HI[acc], t2);
3506 tcg_temp_free_i64(t2);
3508 break;
3509 case OPC_MSUB:
3511 TCGv_i64 t2 = tcg_temp_new_i64();
3512 TCGv_i64 t3 = tcg_temp_new_i64();
3514 tcg_gen_ext_tl_i64(t2, t0);
3515 tcg_gen_ext_tl_i64(t3, t1);
3516 tcg_gen_mul_i64(t2, t2, t3);
3517 tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]);
3518 tcg_gen_sub_i64(t2, t3, t2);
3519 tcg_temp_free_i64(t3);
3520 gen_move_low32(cpu_LO[acc], t2);
3521 gen_move_high32(cpu_HI[acc], t2);
3522 tcg_temp_free_i64(t2);
3524 break;
3525 case OPC_MSUBU:
3527 TCGv_i64 t2 = tcg_temp_new_i64();
3528 TCGv_i64 t3 = tcg_temp_new_i64();
3530 tcg_gen_ext32u_tl(t0, t0);
3531 tcg_gen_ext32u_tl(t1, t1);
3532 tcg_gen_extu_tl_i64(t2, t0);
3533 tcg_gen_extu_tl_i64(t3, t1);
3534 tcg_gen_mul_i64(t2, t2, t3);
3535 tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]);
3536 tcg_gen_sub_i64(t2, t3, t2);
3537 tcg_temp_free_i64(t3);
3538 gen_move_low32(cpu_LO[acc], t2);
3539 gen_move_high32(cpu_HI[acc], t2);
3540 tcg_temp_free_i64(t2);
3542 break;
3543 default:
3544 MIPS_INVAL("mul/div");
3545 generate_exception_end(ctx, EXCP_RI);
3546 goto out;
3548 out:
3549 tcg_temp_free(t0);
3550 tcg_temp_free(t1);
3553 static void gen_mul_vr54xx (DisasContext *ctx, uint32_t opc,
3554 int rd, int rs, int rt)
3556 TCGv t0 = tcg_temp_new();
3557 TCGv t1 = tcg_temp_new();
3559 gen_load_gpr(t0, rs);
3560 gen_load_gpr(t1, rt);
3562 switch (opc) {
3563 case OPC_VR54XX_MULS:
3564 gen_helper_muls(t0, cpu_env, t0, t1);
3565 break;
3566 case OPC_VR54XX_MULSU:
3567 gen_helper_mulsu(t0, cpu_env, t0, t1);
3568 break;
3569 case OPC_VR54XX_MACC:
3570 gen_helper_macc(t0, cpu_env, t0, t1);
3571 break;
3572 case OPC_VR54XX_MACCU:
3573 gen_helper_maccu(t0, cpu_env, t0, t1);
3574 break;
3575 case OPC_VR54XX_MSAC:
3576 gen_helper_msac(t0, cpu_env, t0, t1);
3577 break;
3578 case OPC_VR54XX_MSACU:
3579 gen_helper_msacu(t0, cpu_env, t0, t1);
3580 break;
3581 case OPC_VR54XX_MULHI:
3582 gen_helper_mulhi(t0, cpu_env, t0, t1);
3583 break;
3584 case OPC_VR54XX_MULHIU:
3585 gen_helper_mulhiu(t0, cpu_env, t0, t1);
3586 break;
3587 case OPC_VR54XX_MULSHI:
3588 gen_helper_mulshi(t0, cpu_env, t0, t1);
3589 break;
3590 case OPC_VR54XX_MULSHIU:
3591 gen_helper_mulshiu(t0, cpu_env, t0, t1);
3592 break;
3593 case OPC_VR54XX_MACCHI:
3594 gen_helper_macchi(t0, cpu_env, t0, t1);
3595 break;
3596 case OPC_VR54XX_MACCHIU:
3597 gen_helper_macchiu(t0, cpu_env, t0, t1);
3598 break;
3599 case OPC_VR54XX_MSACHI:
3600 gen_helper_msachi(t0, cpu_env, t0, t1);
3601 break;
3602 case OPC_VR54XX_MSACHIU:
3603 gen_helper_msachiu(t0, cpu_env, t0, t1);
3604 break;
3605 default:
3606 MIPS_INVAL("mul vr54xx");
3607 generate_exception_end(ctx, EXCP_RI);
3608 goto out;
3610 gen_store_gpr(t0, rd);
3612 out:
3613 tcg_temp_free(t0);
3614 tcg_temp_free(t1);
3617 static void gen_cl (DisasContext *ctx, uint32_t opc,
3618 int rd, int rs)
3620 TCGv t0;
3622 if (rd == 0) {
3623 /* Treat as NOP. */
3624 return;
3626 t0 = tcg_temp_new();
3627 gen_load_gpr(t0, rs);
3628 switch (opc) {
3629 case OPC_CLO:
3630 case R6_OPC_CLO:
3631 gen_helper_clo(cpu_gpr[rd], t0);
3632 break;
3633 case OPC_CLZ:
3634 case R6_OPC_CLZ:
3635 gen_helper_clz(cpu_gpr[rd], t0);
3636 break;
3637 #if defined(TARGET_MIPS64)
3638 case OPC_DCLO:
3639 case R6_OPC_DCLO:
3640 gen_helper_dclo(cpu_gpr[rd], t0);
3641 break;
3642 case OPC_DCLZ:
3643 case R6_OPC_DCLZ:
3644 gen_helper_dclz(cpu_gpr[rd], t0);
3645 break;
3646 #endif
3648 tcg_temp_free(t0);
3651 /* Godson integer instructions */
3652 static void gen_loongson_integer(DisasContext *ctx, uint32_t opc,
3653 int rd, int rs, int rt)
3655 TCGv t0, t1;
3657 if (rd == 0) {
3658 /* Treat as NOP. */
3659 return;
3662 switch (opc) {
3663 case OPC_MULT_G_2E:
3664 case OPC_MULT_G_2F:
3665 case OPC_MULTU_G_2E:
3666 case OPC_MULTU_G_2F:
3667 #if defined(TARGET_MIPS64)
3668 case OPC_DMULT_G_2E:
3669 case OPC_DMULT_G_2F:
3670 case OPC_DMULTU_G_2E:
3671 case OPC_DMULTU_G_2F:
3672 #endif
3673 t0 = tcg_temp_new();
3674 t1 = tcg_temp_new();
3675 break;
3676 default:
3677 t0 = tcg_temp_local_new();
3678 t1 = tcg_temp_local_new();
3679 break;
3682 gen_load_gpr(t0, rs);
3683 gen_load_gpr(t1, rt);
3685 switch (opc) {
3686 case OPC_MULT_G_2E:
3687 case OPC_MULT_G_2F:
3688 tcg_gen_mul_tl(cpu_gpr[rd], t0, t1);
3689 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3690 break;
3691 case OPC_MULTU_G_2E:
3692 case OPC_MULTU_G_2F:
3693 tcg_gen_ext32u_tl(t0, t0);
3694 tcg_gen_ext32u_tl(t1, t1);
3695 tcg_gen_mul_tl(cpu_gpr[rd], t0, t1);
3696 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3697 break;
3698 case OPC_DIV_G_2E:
3699 case OPC_DIV_G_2F:
3701 TCGLabel *l1 = gen_new_label();
3702 TCGLabel *l2 = gen_new_label();
3703 TCGLabel *l3 = gen_new_label();
3704 tcg_gen_ext32s_tl(t0, t0);
3705 tcg_gen_ext32s_tl(t1, t1);
3706 tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
3707 tcg_gen_movi_tl(cpu_gpr[rd], 0);
3708 tcg_gen_br(l3);
3709 gen_set_label(l1);
3710 tcg_gen_brcondi_tl(TCG_COND_NE, t0, INT_MIN, l2);
3711 tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1, l2);
3712 tcg_gen_mov_tl(cpu_gpr[rd], t0);
3713 tcg_gen_br(l3);
3714 gen_set_label(l2);
3715 tcg_gen_div_tl(cpu_gpr[rd], t0, t1);
3716 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3717 gen_set_label(l3);
3719 break;
3720 case OPC_DIVU_G_2E:
3721 case OPC_DIVU_G_2F:
3723 TCGLabel *l1 = gen_new_label();
3724 TCGLabel *l2 = gen_new_label();
3725 tcg_gen_ext32u_tl(t0, t0);
3726 tcg_gen_ext32u_tl(t1, t1);
3727 tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
3728 tcg_gen_movi_tl(cpu_gpr[rd], 0);
3729 tcg_gen_br(l2);
3730 gen_set_label(l1);
3731 tcg_gen_divu_tl(cpu_gpr[rd], t0, t1);
3732 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3733 gen_set_label(l2);
3735 break;
3736 case OPC_MOD_G_2E:
3737 case OPC_MOD_G_2F:
3739 TCGLabel *l1 = gen_new_label();
3740 TCGLabel *l2 = gen_new_label();
3741 TCGLabel *l3 = gen_new_label();
3742 tcg_gen_ext32u_tl(t0, t0);
3743 tcg_gen_ext32u_tl(t1, t1);
3744 tcg_gen_brcondi_tl(TCG_COND_EQ, t1, 0, l1);
3745 tcg_gen_brcondi_tl(TCG_COND_NE, t0, INT_MIN, l2);
3746 tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1, l2);
3747 gen_set_label(l1);
3748 tcg_gen_movi_tl(cpu_gpr[rd], 0);
3749 tcg_gen_br(l3);
3750 gen_set_label(l2);
3751 tcg_gen_rem_tl(cpu_gpr[rd], t0, t1);
3752 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3753 gen_set_label(l3);
3755 break;
3756 case OPC_MODU_G_2E:
3757 case OPC_MODU_G_2F:
3759 TCGLabel *l1 = gen_new_label();
3760 TCGLabel *l2 = gen_new_label();
3761 tcg_gen_ext32u_tl(t0, t0);
3762 tcg_gen_ext32u_tl(t1, t1);
3763 tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
3764 tcg_gen_movi_tl(cpu_gpr[rd], 0);
3765 tcg_gen_br(l2);
3766 gen_set_label(l1);
3767 tcg_gen_remu_tl(cpu_gpr[rd], t0, t1);
3768 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3769 gen_set_label(l2);
3771 break;
3772 #if defined(TARGET_MIPS64)
3773 case OPC_DMULT_G_2E:
3774 case OPC_DMULT_G_2F:
3775 tcg_gen_mul_tl(cpu_gpr[rd], t0, t1);
3776 break;
3777 case OPC_DMULTU_G_2E:
3778 case OPC_DMULTU_G_2F:
3779 tcg_gen_mul_tl(cpu_gpr[rd], t0, t1);
3780 break;
3781 case OPC_DDIV_G_2E:
3782 case OPC_DDIV_G_2F:
3784 TCGLabel *l1 = gen_new_label();
3785 TCGLabel *l2 = gen_new_label();
3786 TCGLabel *l3 = gen_new_label();
3787 tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
3788 tcg_gen_movi_tl(cpu_gpr[rd], 0);
3789 tcg_gen_br(l3);
3790 gen_set_label(l1);
3791 tcg_gen_brcondi_tl(TCG_COND_NE, t0, -1LL << 63, l2);
3792 tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1LL, l2);
3793 tcg_gen_mov_tl(cpu_gpr[rd], t0);
3794 tcg_gen_br(l3);
3795 gen_set_label(l2);
3796 tcg_gen_div_tl(cpu_gpr[rd], t0, t1);
3797 gen_set_label(l3);
3799 break;
3800 case OPC_DDIVU_G_2E:
3801 case OPC_DDIVU_G_2F:
3803 TCGLabel *l1 = gen_new_label();
3804 TCGLabel *l2 = gen_new_label();
3805 tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
3806 tcg_gen_movi_tl(cpu_gpr[rd], 0);
3807 tcg_gen_br(l2);
3808 gen_set_label(l1);
3809 tcg_gen_divu_tl(cpu_gpr[rd], t0, t1);
3810 gen_set_label(l2);
3812 break;
3813 case OPC_DMOD_G_2E:
3814 case OPC_DMOD_G_2F:
3816 TCGLabel *l1 = gen_new_label();
3817 TCGLabel *l2 = gen_new_label();
3818 TCGLabel *l3 = gen_new_label();
3819 tcg_gen_brcondi_tl(TCG_COND_EQ, t1, 0, l1);
3820 tcg_gen_brcondi_tl(TCG_COND_NE, t0, -1LL << 63, l2);
3821 tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1LL, l2);
3822 gen_set_label(l1);
3823 tcg_gen_movi_tl(cpu_gpr[rd], 0);
3824 tcg_gen_br(l3);
3825 gen_set_label(l2);
3826 tcg_gen_rem_tl(cpu_gpr[rd], t0, t1);
3827 gen_set_label(l3);
3829 break;
3830 case OPC_DMODU_G_2E:
3831 case OPC_DMODU_G_2F:
3833 TCGLabel *l1 = gen_new_label();
3834 TCGLabel *l2 = gen_new_label();
3835 tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
3836 tcg_gen_movi_tl(cpu_gpr[rd], 0);
3837 tcg_gen_br(l2);
3838 gen_set_label(l1);
3839 tcg_gen_remu_tl(cpu_gpr[rd], t0, t1);
3840 gen_set_label(l2);
3842 break;
3843 #endif
3846 tcg_temp_free(t0);
3847 tcg_temp_free(t1);
3850 /* Loongson multimedia instructions */
3851 static void gen_loongson_multimedia(DisasContext *ctx, int rd, int rs, int rt)
3853 uint32_t opc, shift_max;
3854 TCGv_i64 t0, t1;
3856 opc = MASK_LMI(ctx->opcode);
3857 switch (opc) {
3858 case OPC_ADD_CP2:
3859 case OPC_SUB_CP2:
3860 case OPC_DADD_CP2:
3861 case OPC_DSUB_CP2:
3862 t0 = tcg_temp_local_new_i64();
3863 t1 = tcg_temp_local_new_i64();
3864 break;
3865 default:
3866 t0 = tcg_temp_new_i64();
3867 t1 = tcg_temp_new_i64();
3868 break;
3871 gen_load_fpr64(ctx, t0, rs);
3872 gen_load_fpr64(ctx, t1, rt);
3874 #define LMI_HELPER(UP, LO) \
3875 case OPC_##UP: gen_helper_##LO(t0, t0, t1); break
3876 #define LMI_HELPER_1(UP, LO) \
3877 case OPC_##UP: gen_helper_##LO(t0, t0); break
3878 #define LMI_DIRECT(UP, LO, OP) \
3879 case OPC_##UP: tcg_gen_##OP##_i64(t0, t0, t1); break
3881 switch (opc) {
3882 LMI_HELPER(PADDSH, paddsh);
3883 LMI_HELPER(PADDUSH, paddush);
3884 LMI_HELPER(PADDH, paddh);
3885 LMI_HELPER(PADDW, paddw);
3886 LMI_HELPER(PADDSB, paddsb);
3887 LMI_HELPER(PADDUSB, paddusb);
3888 LMI_HELPER(PADDB, paddb);
3890 LMI_HELPER(PSUBSH, psubsh);
3891 LMI_HELPER(PSUBUSH, psubush);
3892 LMI_HELPER(PSUBH, psubh);
3893 LMI_HELPER(PSUBW, psubw);
3894 LMI_HELPER(PSUBSB, psubsb);
3895 LMI_HELPER(PSUBUSB, psubusb);
3896 LMI_HELPER(PSUBB, psubb);
3898 LMI_HELPER(PSHUFH, pshufh);
3899 LMI_HELPER(PACKSSWH, packsswh);
3900 LMI_HELPER(PACKSSHB, packsshb);
3901 LMI_HELPER(PACKUSHB, packushb);
3903 LMI_HELPER(PUNPCKLHW, punpcklhw);
3904 LMI_HELPER(PUNPCKHHW, punpckhhw);
3905 LMI_HELPER(PUNPCKLBH, punpcklbh);
3906 LMI_HELPER(PUNPCKHBH, punpckhbh);
3907 LMI_HELPER(PUNPCKLWD, punpcklwd);
3908 LMI_HELPER(PUNPCKHWD, punpckhwd);
3910 LMI_HELPER(PAVGH, pavgh);
3911 LMI_HELPER(PAVGB, pavgb);
3912 LMI_HELPER(PMAXSH, pmaxsh);
3913 LMI_HELPER(PMINSH, pminsh);
3914 LMI_HELPER(PMAXUB, pmaxub);
3915 LMI_HELPER(PMINUB, pminub);
3917 LMI_HELPER(PCMPEQW, pcmpeqw);
3918 LMI_HELPER(PCMPGTW, pcmpgtw);
3919 LMI_HELPER(PCMPEQH, pcmpeqh);
3920 LMI_HELPER(PCMPGTH, pcmpgth);
3921 LMI_HELPER(PCMPEQB, pcmpeqb);
3922 LMI_HELPER(PCMPGTB, pcmpgtb);
3924 LMI_HELPER(PSLLW, psllw);
3925 LMI_HELPER(PSLLH, psllh);
3926 LMI_HELPER(PSRLW, psrlw);
3927 LMI_HELPER(PSRLH, psrlh);
3928 LMI_HELPER(PSRAW, psraw);
3929 LMI_HELPER(PSRAH, psrah);
3931 LMI_HELPER(PMULLH, pmullh);
3932 LMI_HELPER(PMULHH, pmulhh);
3933 LMI_HELPER(PMULHUH, pmulhuh);
3934 LMI_HELPER(PMADDHW, pmaddhw);
3936 LMI_HELPER(PASUBUB, pasubub);
3937 LMI_HELPER_1(BIADD, biadd);
3938 LMI_HELPER_1(PMOVMSKB, pmovmskb);
3940 LMI_DIRECT(PADDD, paddd, add);
3941 LMI_DIRECT(PSUBD, psubd, sub);
3942 LMI_DIRECT(XOR_CP2, xor, xor);
3943 LMI_DIRECT(NOR_CP2, nor, nor);
3944 LMI_DIRECT(AND_CP2, and, and);
3945 LMI_DIRECT(PANDN, pandn, andc);
3946 LMI_DIRECT(OR, or, or);
3948 case OPC_PINSRH_0:
3949 tcg_gen_deposit_i64(t0, t0, t1, 0, 16);
3950 break;
3951 case OPC_PINSRH_1:
3952 tcg_gen_deposit_i64(t0, t0, t1, 16, 16);
3953 break;
3954 case OPC_PINSRH_2:
3955 tcg_gen_deposit_i64(t0, t0, t1, 32, 16);
3956 break;
3957 case OPC_PINSRH_3:
3958 tcg_gen_deposit_i64(t0, t0, t1, 48, 16);
3959 break;
3961 case OPC_PEXTRH:
3962 tcg_gen_andi_i64(t1, t1, 3);
3963 tcg_gen_shli_i64(t1, t1, 4);
3964 tcg_gen_shr_i64(t0, t0, t1);
3965 tcg_gen_ext16u_i64(t0, t0);
3966 break;
3968 case OPC_ADDU_CP2:
3969 tcg_gen_add_i64(t0, t0, t1);
3970 tcg_gen_ext32s_i64(t0, t0);
3971 break;
3972 case OPC_SUBU_CP2:
3973 tcg_gen_sub_i64(t0, t0, t1);
3974 tcg_gen_ext32s_i64(t0, t0);
3975 break;
3977 case OPC_SLL_CP2:
3978 shift_max = 32;
3979 goto do_shift;
3980 case OPC_SRL_CP2:
3981 shift_max = 32;
3982 goto do_shift;
3983 case OPC_SRA_CP2:
3984 shift_max = 32;
3985 goto do_shift;
3986 case OPC_DSLL_CP2:
3987 shift_max = 64;
3988 goto do_shift;
3989 case OPC_DSRL_CP2:
3990 shift_max = 64;
3991 goto do_shift;
3992 case OPC_DSRA_CP2:
3993 shift_max = 64;
3994 goto do_shift;
3995 do_shift:
3996 /* Make sure shift count isn't TCG undefined behaviour. */
3997 tcg_gen_andi_i64(t1, t1, shift_max - 1);
3999 switch (opc) {
4000 case OPC_SLL_CP2:
4001 case OPC_DSLL_CP2:
4002 tcg_gen_shl_i64(t0, t0, t1);
4003 break;
4004 case OPC_SRA_CP2:
4005 case OPC_DSRA_CP2:
4006 /* Since SRA is UndefinedResult without sign-extended inputs,
4007 we can treat SRA and DSRA the same. */
4008 tcg_gen_sar_i64(t0, t0, t1);
4009 break;
4010 case OPC_SRL_CP2:
4011 /* We want to shift in zeros for SRL; zero-extend first. */
4012 tcg_gen_ext32u_i64(t0, t0);
4013 /* FALLTHRU */
4014 case OPC_DSRL_CP2:
4015 tcg_gen_shr_i64(t0, t0, t1);
4016 break;
4019 if (shift_max == 32) {
4020 tcg_gen_ext32s_i64(t0, t0);
4023 /* Shifts larger than MAX produce zero. */
4024 tcg_gen_setcondi_i64(TCG_COND_LTU, t1, t1, shift_max);
4025 tcg_gen_neg_i64(t1, t1);
4026 tcg_gen_and_i64(t0, t0, t1);
4027 break;
4029 case OPC_ADD_CP2:
4030 case OPC_DADD_CP2:
4032 TCGv_i64 t2 = tcg_temp_new_i64();
4033 TCGLabel *lab = gen_new_label();
4035 tcg_gen_mov_i64(t2, t0);
4036 tcg_gen_add_i64(t0, t1, t2);
4037 if (opc == OPC_ADD_CP2) {
4038 tcg_gen_ext32s_i64(t0, t0);
4040 tcg_gen_xor_i64(t1, t1, t2);
4041 tcg_gen_xor_i64(t2, t2, t0);
4042 tcg_gen_andc_i64(t1, t2, t1);
4043 tcg_temp_free_i64(t2);
4044 tcg_gen_brcondi_i64(TCG_COND_GE, t1, 0, lab);
4045 generate_exception(ctx, EXCP_OVERFLOW);
4046 gen_set_label(lab);
4047 break;
4050 case OPC_SUB_CP2:
4051 case OPC_DSUB_CP2:
4053 TCGv_i64 t2 = tcg_temp_new_i64();
4054 TCGLabel *lab = gen_new_label();
4056 tcg_gen_mov_i64(t2, t0);
4057 tcg_gen_sub_i64(t0, t1, t2);
4058 if (opc == OPC_SUB_CP2) {
4059 tcg_gen_ext32s_i64(t0, t0);
4061 tcg_gen_xor_i64(t1, t1, t2);
4062 tcg_gen_xor_i64(t2, t2, t0);
4063 tcg_gen_and_i64(t1, t1, t2);
4064 tcg_temp_free_i64(t2);
4065 tcg_gen_brcondi_i64(TCG_COND_GE, t1, 0, lab);
4066 generate_exception(ctx, EXCP_OVERFLOW);
4067 gen_set_label(lab);
4068 break;
4071 case OPC_PMULUW:
4072 tcg_gen_ext32u_i64(t0, t0);
4073 tcg_gen_ext32u_i64(t1, t1);
4074 tcg_gen_mul_i64(t0, t0, t1);
4075 break;
4077 case OPC_SEQU_CP2:
4078 case OPC_SEQ_CP2:
4079 case OPC_SLTU_CP2:
4080 case OPC_SLT_CP2:
4081 case OPC_SLEU_CP2:
4082 case OPC_SLE_CP2:
4083 /* ??? Document is unclear: Set FCC[CC]. Does that mean the
4084 FD field is the CC field? */
4085 default:
4086 MIPS_INVAL("loongson_cp2");
4087 generate_exception_end(ctx, EXCP_RI);
4088 return;
4091 #undef LMI_HELPER
4092 #undef LMI_DIRECT
4094 gen_store_fpr64(ctx, t0, rd);
4096 tcg_temp_free_i64(t0);
4097 tcg_temp_free_i64(t1);
4100 /* Traps */
4101 static void gen_trap (DisasContext *ctx, uint32_t opc,
4102 int rs, int rt, int16_t imm)
4104 int cond;
4105 TCGv t0 = tcg_temp_new();
4106 TCGv t1 = tcg_temp_new();
4108 cond = 0;
4109 /* Load needed operands */
4110 switch (opc) {
4111 case OPC_TEQ:
4112 case OPC_TGE:
4113 case OPC_TGEU:
4114 case OPC_TLT:
4115 case OPC_TLTU:
4116 case OPC_TNE:
4117 /* Compare two registers */
4118 if (rs != rt) {
4119 gen_load_gpr(t0, rs);
4120 gen_load_gpr(t1, rt);
4121 cond = 1;
4123 break;
4124 case OPC_TEQI:
4125 case OPC_TGEI:
4126 case OPC_TGEIU:
4127 case OPC_TLTI:
4128 case OPC_TLTIU:
4129 case OPC_TNEI:
4130 /* Compare register to immediate */
4131 if (rs != 0 || imm != 0) {
4132 gen_load_gpr(t0, rs);
4133 tcg_gen_movi_tl(t1, (int32_t)imm);
4134 cond = 1;
4136 break;
4138 if (cond == 0) {
4139 switch (opc) {
4140 case OPC_TEQ: /* rs == rs */
4141 case OPC_TEQI: /* r0 == 0 */
4142 case OPC_TGE: /* rs >= rs */
4143 case OPC_TGEI: /* r0 >= 0 */
4144 case OPC_TGEU: /* rs >= rs unsigned */
4145 case OPC_TGEIU: /* r0 >= 0 unsigned */
4146 /* Always trap */
4147 generate_exception_end(ctx, EXCP_TRAP);
4148 break;
4149 case OPC_TLT: /* rs < rs */
4150 case OPC_TLTI: /* r0 < 0 */
4151 case OPC_TLTU: /* rs < rs unsigned */
4152 case OPC_TLTIU: /* r0 < 0 unsigned */
4153 case OPC_TNE: /* rs != rs */
4154 case OPC_TNEI: /* r0 != 0 */
4155 /* Never trap: treat as NOP. */
4156 break;
4158 } else {
4159 TCGLabel *l1 = gen_new_label();
4161 switch (opc) {
4162 case OPC_TEQ:
4163 case OPC_TEQI:
4164 tcg_gen_brcond_tl(TCG_COND_NE, t0, t1, l1);
4165 break;
4166 case OPC_TGE:
4167 case OPC_TGEI:
4168 tcg_gen_brcond_tl(TCG_COND_LT, t0, t1, l1);
4169 break;
4170 case OPC_TGEU:
4171 case OPC_TGEIU:
4172 tcg_gen_brcond_tl(TCG_COND_LTU, t0, t1, l1);
4173 break;
4174 case OPC_TLT:
4175 case OPC_TLTI:
4176 tcg_gen_brcond_tl(TCG_COND_GE, t0, t1, l1);
4177 break;
4178 case OPC_TLTU:
4179 case OPC_TLTIU:
4180 tcg_gen_brcond_tl(TCG_COND_GEU, t0, t1, l1);
4181 break;
4182 case OPC_TNE:
4183 case OPC_TNEI:
4184 tcg_gen_brcond_tl(TCG_COND_EQ, t0, t1, l1);
4185 break;
4187 generate_exception(ctx, EXCP_TRAP);
4188 gen_set_label(l1);
4190 tcg_temp_free(t0);
4191 tcg_temp_free(t1);
4194 static inline bool use_goto_tb(DisasContext *ctx, target_ulong dest)
4196 if (unlikely(ctx->singlestep_enabled)) {
4197 return false;
4200 #ifndef CONFIG_USER_ONLY
4201 return (ctx->tb->pc & TARGET_PAGE_MASK) == (dest & TARGET_PAGE_MASK);
4202 #else
4203 return true;
4204 #endif
4207 static inline void gen_goto_tb(DisasContext *ctx, int n, target_ulong dest)
4209 if (use_goto_tb(ctx, dest)) {
4210 tcg_gen_goto_tb(n);
4211 gen_save_pc(dest);
4212 tcg_gen_exit_tb((uintptr_t)ctx->tb + n);
4213 } else {
4214 gen_save_pc(dest);
4215 if (ctx->singlestep_enabled) {
4216 save_cpu_state(ctx, 0);
4217 gen_helper_raise_exception_debug(cpu_env);
4219 tcg_gen_exit_tb(0);
4223 /* Branches (before delay slot) */
4224 static void gen_compute_branch (DisasContext *ctx, uint32_t opc,
4225 int insn_bytes,
4226 int rs, int rt, int32_t offset,
4227 int delayslot_size)
4229 target_ulong btgt = -1;
4230 int blink = 0;
4231 int bcond_compute = 0;
4232 TCGv t0 = tcg_temp_new();
4233 TCGv t1 = tcg_temp_new();
4235 if (ctx->hflags & MIPS_HFLAG_BMASK) {
4236 #ifdef MIPS_DEBUG_DISAS
4237 LOG_DISAS("Branch in delay / forbidden slot at PC 0x"
4238 TARGET_FMT_lx "\n", ctx->pc);
4239 #endif
4240 generate_exception_end(ctx, EXCP_RI);
4241 goto out;
4244 /* Load needed operands */
4245 switch (opc) {
4246 case OPC_BEQ:
4247 case OPC_BEQL:
4248 case OPC_BNE:
4249 case OPC_BNEL:
4250 /* Compare two registers */
4251 if (rs != rt) {
4252 gen_load_gpr(t0, rs);
4253 gen_load_gpr(t1, rt);
4254 bcond_compute = 1;
4256 btgt = ctx->pc + insn_bytes + offset;
4257 break;
4258 case OPC_BGEZ:
4259 case OPC_BGEZAL:
4260 case OPC_BGEZALL:
4261 case OPC_BGEZL:
4262 case OPC_BGTZ:
4263 case OPC_BGTZL:
4264 case OPC_BLEZ:
4265 case OPC_BLEZL:
4266 case OPC_BLTZ:
4267 case OPC_BLTZAL:
4268 case OPC_BLTZALL:
4269 case OPC_BLTZL:
4270 /* Compare to zero */
4271 if (rs != 0) {
4272 gen_load_gpr(t0, rs);
4273 bcond_compute = 1;
4275 btgt = ctx->pc + insn_bytes + offset;
4276 break;
4277 case OPC_BPOSGE32:
4278 #if defined(TARGET_MIPS64)
4279 case OPC_BPOSGE64:
4280 tcg_gen_andi_tl(t0, cpu_dspctrl, 0x7F);
4281 #else
4282 tcg_gen_andi_tl(t0, cpu_dspctrl, 0x3F);
4283 #endif
4284 bcond_compute = 1;
4285 btgt = ctx->pc + insn_bytes + offset;
4286 break;
4287 case OPC_J:
4288 case OPC_JAL:
4289 case OPC_JALX:
4290 /* Jump to immediate */
4291 btgt = ((ctx->pc + insn_bytes) & (int32_t)0xF0000000) | (uint32_t)offset;
4292 break;
4293 case OPC_JR:
4294 case OPC_JALR:
4295 /* Jump to register */
4296 if (offset != 0 && offset != 16) {
4297 /* Hint = 0 is JR/JALR, hint 16 is JR.HB/JALR.HB, the
4298 others are reserved. */
4299 MIPS_INVAL("jump hint");
4300 generate_exception_end(ctx, EXCP_RI);
4301 goto out;
4303 gen_load_gpr(btarget, rs);
4304 break;
4305 default:
4306 MIPS_INVAL("branch/jump");
4307 generate_exception_end(ctx, EXCP_RI);
4308 goto out;
4310 if (bcond_compute == 0) {
4311 /* No condition to be computed */
4312 switch (opc) {
4313 case OPC_BEQ: /* rx == rx */
4314 case OPC_BEQL: /* rx == rx likely */
4315 case OPC_BGEZ: /* 0 >= 0 */
4316 case OPC_BGEZL: /* 0 >= 0 likely */
4317 case OPC_BLEZ: /* 0 <= 0 */
4318 case OPC_BLEZL: /* 0 <= 0 likely */
4319 /* Always take */
4320 ctx->hflags |= MIPS_HFLAG_B;
4321 break;
4322 case OPC_BGEZAL: /* 0 >= 0 */
4323 case OPC_BGEZALL: /* 0 >= 0 likely */
4324 /* Always take and link */
4325 blink = 31;
4326 ctx->hflags |= MIPS_HFLAG_B;
4327 break;
4328 case OPC_BNE: /* rx != rx */
4329 case OPC_BGTZ: /* 0 > 0 */
4330 case OPC_BLTZ: /* 0 < 0 */
4331 /* Treat as NOP. */
4332 goto out;
4333 case OPC_BLTZAL: /* 0 < 0 */
4334 /* Handle as an unconditional branch to get correct delay
4335 slot checking. */
4336 blink = 31;
4337 btgt = ctx->pc + insn_bytes + delayslot_size;
4338 ctx->hflags |= MIPS_HFLAG_B;
4339 break;
4340 case OPC_BLTZALL: /* 0 < 0 likely */
4341 tcg_gen_movi_tl(cpu_gpr[31], ctx->pc + 8);
4342 /* Skip the instruction in the delay slot */
4343 ctx->pc += 4;
4344 goto out;
4345 case OPC_BNEL: /* rx != rx likely */
4346 case OPC_BGTZL: /* 0 > 0 likely */
4347 case OPC_BLTZL: /* 0 < 0 likely */
4348 /* Skip the instruction in the delay slot */
4349 ctx->pc += 4;
4350 goto out;
4351 case OPC_J:
4352 ctx->hflags |= MIPS_HFLAG_B;
4353 break;
4354 case OPC_JALX:
4355 ctx->hflags |= MIPS_HFLAG_BX;
4356 /* Fallthrough */
4357 case OPC_JAL:
4358 blink = 31;
4359 ctx->hflags |= MIPS_HFLAG_B;
4360 break;
4361 case OPC_JR:
4362 ctx->hflags |= MIPS_HFLAG_BR;
4363 break;
4364 case OPC_JALR:
4365 blink = rt;
4366 ctx->hflags |= MIPS_HFLAG_BR;
4367 break;
4368 default:
4369 MIPS_INVAL("branch/jump");
4370 generate_exception_end(ctx, EXCP_RI);
4371 goto out;
4373 } else {
4374 switch (opc) {
4375 case OPC_BEQ:
4376 tcg_gen_setcond_tl(TCG_COND_EQ, bcond, t0, t1);
4377 goto not_likely;
4378 case OPC_BEQL:
4379 tcg_gen_setcond_tl(TCG_COND_EQ, bcond, t0, t1);
4380 goto likely;
4381 case OPC_BNE:
4382 tcg_gen_setcond_tl(TCG_COND_NE, bcond, t0, t1);
4383 goto not_likely;
4384 case OPC_BNEL:
4385 tcg_gen_setcond_tl(TCG_COND_NE, bcond, t0, t1);
4386 goto likely;
4387 case OPC_BGEZ:
4388 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 0);
4389 goto not_likely;
4390 case OPC_BGEZL:
4391 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 0);
4392 goto likely;
4393 case OPC_BGEZAL:
4394 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 0);
4395 blink = 31;
4396 goto not_likely;
4397 case OPC_BGEZALL:
4398 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 0);
4399 blink = 31;
4400 goto likely;
4401 case OPC_BGTZ:
4402 tcg_gen_setcondi_tl(TCG_COND_GT, bcond, t0, 0);
4403 goto not_likely;
4404 case OPC_BGTZL:
4405 tcg_gen_setcondi_tl(TCG_COND_GT, bcond, t0, 0);
4406 goto likely;
4407 case OPC_BLEZ:
4408 tcg_gen_setcondi_tl(TCG_COND_LE, bcond, t0, 0);
4409 goto not_likely;
4410 case OPC_BLEZL:
4411 tcg_gen_setcondi_tl(TCG_COND_LE, bcond, t0, 0);
4412 goto likely;
4413 case OPC_BLTZ:
4414 tcg_gen_setcondi_tl(TCG_COND_LT, bcond, t0, 0);
4415 goto not_likely;
4416 case OPC_BLTZL:
4417 tcg_gen_setcondi_tl(TCG_COND_LT, bcond, t0, 0);
4418 goto likely;
4419 case OPC_BPOSGE32:
4420 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 32);
4421 goto not_likely;
4422 #if defined(TARGET_MIPS64)
4423 case OPC_BPOSGE64:
4424 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 64);
4425 goto not_likely;
4426 #endif
4427 case OPC_BLTZAL:
4428 tcg_gen_setcondi_tl(TCG_COND_LT, bcond, t0, 0);
4429 blink = 31;
4430 not_likely:
4431 ctx->hflags |= MIPS_HFLAG_BC;
4432 break;
4433 case OPC_BLTZALL:
4434 tcg_gen_setcondi_tl(TCG_COND_LT, bcond, t0, 0);
4435 blink = 31;
4436 likely:
4437 ctx->hflags |= MIPS_HFLAG_BL;
4438 break;
4439 default:
4440 MIPS_INVAL("conditional branch/jump");
4441 generate_exception_end(ctx, EXCP_RI);
4442 goto out;
4446 ctx->btarget = btgt;
4448 switch (delayslot_size) {
4449 case 2:
4450 ctx->hflags |= MIPS_HFLAG_BDS16;
4451 break;
4452 case 4:
4453 ctx->hflags |= MIPS_HFLAG_BDS32;
4454 break;
4457 if (blink > 0) {
4458 int post_delay = insn_bytes + delayslot_size;
4459 int lowbit = !!(ctx->hflags & MIPS_HFLAG_M16);
4461 tcg_gen_movi_tl(cpu_gpr[blink], ctx->pc + post_delay + lowbit);
4464 out:
4465 if (insn_bytes == 2)
4466 ctx->hflags |= MIPS_HFLAG_B16;
4467 tcg_temp_free(t0);
4468 tcg_temp_free(t1);
4471 /* special3 bitfield operations */
4472 static void gen_bitops (DisasContext *ctx, uint32_t opc, int rt,
4473 int rs, int lsb, int msb)
4475 TCGv t0 = tcg_temp_new();
4476 TCGv t1 = tcg_temp_new();
4478 gen_load_gpr(t1, rs);
4479 switch (opc) {
4480 case OPC_EXT:
4481 if (lsb + msb > 31) {
4482 goto fail;
4484 tcg_gen_shri_tl(t0, t1, lsb);
4485 if (msb != 31) {
4486 tcg_gen_andi_tl(t0, t0, (1U << (msb + 1)) - 1);
4487 } else {
4488 tcg_gen_ext32s_tl(t0, t0);
4490 break;
4491 #if defined(TARGET_MIPS64)
4492 case OPC_DEXTU:
4493 lsb += 32;
4494 goto do_dext;
4495 case OPC_DEXTM:
4496 msb += 32;
4497 goto do_dext;
4498 case OPC_DEXT:
4499 do_dext:
4500 if (lsb + msb > 63) {
4501 goto fail;
4503 tcg_gen_shri_tl(t0, t1, lsb);
4504 if (msb != 63) {
4505 tcg_gen_andi_tl(t0, t0, (1ULL << (msb + 1)) - 1);
4507 break;
4508 #endif
4509 case OPC_INS:
4510 if (lsb > msb) {
4511 goto fail;
4513 gen_load_gpr(t0, rt);
4514 tcg_gen_deposit_tl(t0, t0, t1, lsb, msb - lsb + 1);
4515 tcg_gen_ext32s_tl(t0, t0);
4516 break;
4517 #if defined(TARGET_MIPS64)
4518 case OPC_DINSU:
4519 lsb += 32;
4520 /* FALLTHRU */
4521 case OPC_DINSM:
4522 msb += 32;
4523 /* FALLTHRU */
4524 case OPC_DINS:
4525 if (lsb > msb) {
4526 goto fail;
4528 gen_load_gpr(t0, rt);
4529 tcg_gen_deposit_tl(t0, t0, t1, lsb, msb - lsb + 1);
4530 break;
4531 #endif
4532 default:
4533 fail:
4534 MIPS_INVAL("bitops");
4535 generate_exception_end(ctx, EXCP_RI);
4536 tcg_temp_free(t0);
4537 tcg_temp_free(t1);
4538 return;
4540 gen_store_gpr(t0, rt);
4541 tcg_temp_free(t0);
4542 tcg_temp_free(t1);
4545 static void gen_bshfl (DisasContext *ctx, uint32_t op2, int rt, int rd)
4547 TCGv t0;
4549 if (rd == 0) {
4550 /* If no destination, treat it as a NOP. */
4551 return;
4554 t0 = tcg_temp_new();
4555 gen_load_gpr(t0, rt);
4556 switch (op2) {
4557 case OPC_WSBH:
4559 TCGv t1 = tcg_temp_new();
4561 tcg_gen_shri_tl(t1, t0, 8);
4562 tcg_gen_andi_tl(t1, t1, 0x00FF00FF);
4563 tcg_gen_shli_tl(t0, t0, 8);
4564 tcg_gen_andi_tl(t0, t0, ~0x00FF00FF);
4565 tcg_gen_or_tl(t0, t0, t1);
4566 tcg_temp_free(t1);
4567 tcg_gen_ext32s_tl(cpu_gpr[rd], t0);
4569 break;
4570 case OPC_SEB:
4571 tcg_gen_ext8s_tl(cpu_gpr[rd], t0);
4572 break;
4573 case OPC_SEH:
4574 tcg_gen_ext16s_tl(cpu_gpr[rd], t0);
4575 break;
4576 #if defined(TARGET_MIPS64)
4577 case OPC_DSBH:
4579 TCGv t1 = tcg_temp_new();
4581 tcg_gen_shri_tl(t1, t0, 8);
4582 tcg_gen_andi_tl(t1, t1, 0x00FF00FF00FF00FFULL);
4583 tcg_gen_shli_tl(t0, t0, 8);
4584 tcg_gen_andi_tl(t0, t0, ~0x00FF00FF00FF00FFULL);
4585 tcg_gen_or_tl(cpu_gpr[rd], t0, t1);
4586 tcg_temp_free(t1);
4588 break;
4589 case OPC_DSHD:
4591 TCGv t1 = tcg_temp_new();
4593 tcg_gen_shri_tl(t1, t0, 16);
4594 tcg_gen_andi_tl(t1, t1, 0x0000FFFF0000FFFFULL);
4595 tcg_gen_shli_tl(t0, t0, 16);
4596 tcg_gen_andi_tl(t0, t0, ~0x0000FFFF0000FFFFULL);
4597 tcg_gen_or_tl(t0, t0, t1);
4598 tcg_gen_shri_tl(t1, t0, 32);
4599 tcg_gen_shli_tl(t0, t0, 32);
4600 tcg_gen_or_tl(cpu_gpr[rd], t0, t1);
4601 tcg_temp_free(t1);
4603 break;
4604 #endif
4605 default:
4606 MIPS_INVAL("bsfhl");
4607 generate_exception_end(ctx, EXCP_RI);
4608 tcg_temp_free(t0);
4609 return;
4611 tcg_temp_free(t0);
4614 static void gen_lsa(DisasContext *ctx, int opc, int rd, int rs, int rt,
4615 int imm2)
4617 TCGv t0;
4618 TCGv t1;
4619 if (rd == 0) {
4620 /* Treat as NOP. */
4621 return;
4623 t0 = tcg_temp_new();
4624 t1 = tcg_temp_new();
4625 gen_load_gpr(t0, rs);
4626 gen_load_gpr(t1, rt);
4627 tcg_gen_shli_tl(t0, t0, imm2 + 1);
4628 tcg_gen_add_tl(cpu_gpr[rd], t0, t1);
4629 if (opc == OPC_LSA) {
4630 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
4633 tcg_temp_free(t1);
4634 tcg_temp_free(t0);
4636 return;
4639 static void gen_align(DisasContext *ctx, int opc, int rd, int rs, int rt,
4640 int bp)
4642 TCGv t0;
4643 if (rd == 0) {
4644 /* Treat as NOP. */
4645 return;
4647 t0 = tcg_temp_new();
4648 gen_load_gpr(t0, rt);
4649 if (bp == 0) {
4650 switch (opc) {
4651 case OPC_ALIGN:
4652 tcg_gen_ext32s_tl(cpu_gpr[rd], t0);
4653 break;
4654 #if defined(TARGET_MIPS64)
4655 case OPC_DALIGN:
4656 tcg_gen_mov_tl(cpu_gpr[rd], t0);
4657 break;
4658 #endif
4660 } else {
4661 TCGv t1 = tcg_temp_new();
4662 gen_load_gpr(t1, rs);
4663 switch (opc) {
4664 case OPC_ALIGN:
4666 TCGv_i64 t2 = tcg_temp_new_i64();
4667 tcg_gen_concat_tl_i64(t2, t1, t0);
4668 tcg_gen_shri_i64(t2, t2, 8 * (4 - bp));
4669 gen_move_low32(cpu_gpr[rd], t2);
4670 tcg_temp_free_i64(t2);
4672 break;
4673 #if defined(TARGET_MIPS64)
4674 case OPC_DALIGN:
4675 tcg_gen_shli_tl(t0, t0, 8 * bp);
4676 tcg_gen_shri_tl(t1, t1, 8 * (8 - bp));
4677 tcg_gen_or_tl(cpu_gpr[rd], t1, t0);
4678 break;
4679 #endif
4681 tcg_temp_free(t1);
4684 tcg_temp_free(t0);
4687 static void gen_bitswap(DisasContext *ctx, int opc, int rd, int rt)
4689 TCGv t0;
4690 if (rd == 0) {
4691 /* Treat as NOP. */
4692 return;
4694 t0 = tcg_temp_new();
4695 gen_load_gpr(t0, rt);
4696 switch (opc) {
4697 case OPC_BITSWAP:
4698 gen_helper_bitswap(cpu_gpr[rd], t0);
4699 break;
4700 #if defined(TARGET_MIPS64)
4701 case OPC_DBITSWAP:
4702 gen_helper_dbitswap(cpu_gpr[rd], t0);
4703 break;
4704 #endif
4706 tcg_temp_free(t0);
4709 #ifndef CONFIG_USER_ONLY
4710 /* CP0 (MMU and control) */
4711 static inline void gen_mthc0_entrylo(TCGv arg, target_ulong off)
4713 TCGv_i64 t0 = tcg_temp_new_i64();
4714 TCGv_i64 t1 = tcg_temp_new_i64();
4716 tcg_gen_ext_tl_i64(t0, arg);
4717 tcg_gen_ld_i64(t1, cpu_env, off);
4718 #if defined(TARGET_MIPS64)
4719 tcg_gen_deposit_i64(t1, t1, t0, 30, 32);
4720 #else
4721 tcg_gen_concat32_i64(t1, t1, t0);
4722 #endif
4723 tcg_gen_st_i64(t1, cpu_env, off);
4724 tcg_temp_free_i64(t1);
4725 tcg_temp_free_i64(t0);
4728 static inline void gen_mthc0_store64(TCGv arg, target_ulong off)
4730 TCGv_i64 t0 = tcg_temp_new_i64();
4731 TCGv_i64 t1 = tcg_temp_new_i64();
4733 tcg_gen_ext_tl_i64(t0, arg);
4734 tcg_gen_ld_i64(t1, cpu_env, off);
4735 tcg_gen_concat32_i64(t1, t1, t0);
4736 tcg_gen_st_i64(t1, cpu_env, off);
4737 tcg_temp_free_i64(t1);
4738 tcg_temp_free_i64(t0);
4741 static inline void gen_mfhc0_entrylo(TCGv arg, target_ulong off)
4743 TCGv_i64 t0 = tcg_temp_new_i64();
4745 tcg_gen_ld_i64(t0, cpu_env, off);
4746 #if defined(TARGET_MIPS64)
4747 tcg_gen_shri_i64(t0, t0, 30);
4748 #else
4749 tcg_gen_shri_i64(t0, t0, 32);
4750 #endif
4751 gen_move_low32(arg, t0);
4752 tcg_temp_free_i64(t0);
4755 static inline void gen_mfhc0_load64(TCGv arg, target_ulong off, int shift)
4757 TCGv_i64 t0 = tcg_temp_new_i64();
4759 tcg_gen_ld_i64(t0, cpu_env, off);
4760 tcg_gen_shri_i64(t0, t0, 32 + shift);
4761 gen_move_low32(arg, t0);
4762 tcg_temp_free_i64(t0);
4765 static inline void gen_mfc0_load32 (TCGv arg, target_ulong off)
4767 TCGv_i32 t0 = tcg_temp_new_i32();
4769 tcg_gen_ld_i32(t0, cpu_env, off);
4770 tcg_gen_ext_i32_tl(arg, t0);
4771 tcg_temp_free_i32(t0);
4774 static inline void gen_mfc0_load64 (TCGv arg, target_ulong off)
4776 tcg_gen_ld_tl(arg, cpu_env, off);
4777 tcg_gen_ext32s_tl(arg, arg);
4780 static inline void gen_mtc0_store32 (TCGv arg, target_ulong off)
4782 TCGv_i32 t0 = tcg_temp_new_i32();
4784 tcg_gen_trunc_tl_i32(t0, arg);
4785 tcg_gen_st_i32(t0, cpu_env, off);
4786 tcg_temp_free_i32(t0);
4789 #define CP0_CHECK(c) \
4790 do { \
4791 if (!(c)) { \
4792 goto cp0_unimplemented; \
4794 } while (0)
4796 static void gen_mfhc0(DisasContext *ctx, TCGv arg, int reg, int sel)
4798 const char *rn = "invalid";
4800 CP0_CHECK(ctx->hflags & MIPS_HFLAG_ELPA);
4802 switch (reg) {
4803 case 2:
4804 switch (sel) {
4805 case 0:
4806 gen_mfhc0_entrylo(arg, offsetof(CPUMIPSState, CP0_EntryLo0));
4807 rn = "EntryLo0";
4808 break;
4809 default:
4810 goto cp0_unimplemented;
4812 break;
4813 case 3:
4814 switch (sel) {
4815 case 0:
4816 gen_mfhc0_entrylo(arg, offsetof(CPUMIPSState, CP0_EntryLo1));
4817 rn = "EntryLo1";
4818 break;
4819 default:
4820 goto cp0_unimplemented;
4822 break;
4823 case 17:
4824 switch (sel) {
4825 case 0:
4826 gen_mfhc0_load64(arg, offsetof(CPUMIPSState, lladdr),
4827 ctx->CP0_LLAddr_shift);
4828 rn = "LLAddr";
4829 break;
4830 case 1:
4831 CP0_CHECK(ctx->mrp);
4832 gen_helper_mfhc0_maar(arg, cpu_env);
4833 rn = "MAAR";
4834 break;
4835 default:
4836 goto cp0_unimplemented;
4838 break;
4839 case 28:
4840 switch (sel) {
4841 case 0:
4842 case 2:
4843 case 4:
4844 case 6:
4845 gen_mfhc0_load64(arg, offsetof(CPUMIPSState, CP0_TagLo), 0);
4846 rn = "TagLo";
4847 break;
4848 default:
4849 goto cp0_unimplemented;
4851 break;
4852 default:
4853 goto cp0_unimplemented;
4856 (void)rn; /* avoid a compiler warning */
4857 LOG_DISAS("mfhc0 %s (reg %d sel %d)\n", rn, reg, sel);
4858 return;
4860 cp0_unimplemented:
4861 LOG_DISAS("mfhc0 %s (reg %d sel %d)\n", rn, reg, sel);
4862 tcg_gen_movi_tl(arg, 0);
4865 static void gen_mthc0(DisasContext *ctx, TCGv arg, int reg, int sel)
4867 const char *rn = "invalid";
4868 uint64_t mask = ctx->PAMask >> 36;
4870 CP0_CHECK(ctx->hflags & MIPS_HFLAG_ELPA);
4872 switch (reg) {
4873 case 2:
4874 switch (sel) {
4875 case 0:
4876 tcg_gen_andi_tl(arg, arg, mask);
4877 gen_mthc0_entrylo(arg, offsetof(CPUMIPSState, CP0_EntryLo0));
4878 rn = "EntryLo0";
4879 break;
4880 default:
4881 goto cp0_unimplemented;
4883 break;
4884 case 3:
4885 switch (sel) {
4886 case 0:
4887 tcg_gen_andi_tl(arg, arg, mask);
4888 gen_mthc0_entrylo(arg, offsetof(CPUMIPSState, CP0_EntryLo1));
4889 rn = "EntryLo1";
4890 break;
4891 default:
4892 goto cp0_unimplemented;
4894 break;
4895 case 17:
4896 switch (sel) {
4897 case 0:
4898 /* LLAddr is read-only (the only exception is bit 0 if LLB is
4899 supported); the CP0_LLAddr_rw_bitmask does not seem to be
4900 relevant for modern MIPS cores supporting MTHC0, therefore
4901 treating MTHC0 to LLAddr as NOP. */
4902 rn = "LLAddr";
4903 break;
4904 case 1:
4905 CP0_CHECK(ctx->mrp);
4906 gen_helper_mthc0_maar(cpu_env, arg);
4907 rn = "MAAR";
4908 break;
4909 default:
4910 goto cp0_unimplemented;
4912 break;
4913 case 28:
4914 switch (sel) {
4915 case 0:
4916 case 2:
4917 case 4:
4918 case 6:
4919 tcg_gen_andi_tl(arg, arg, mask);
4920 gen_mthc0_store64(arg, offsetof(CPUMIPSState, CP0_TagLo));
4921 rn = "TagLo";
4922 break;
4923 default:
4924 goto cp0_unimplemented;
4926 break;
4927 default:
4928 goto cp0_unimplemented;
4931 (void)rn; /* avoid a compiler warning */
4932 cp0_unimplemented:
4933 LOG_DISAS("mthc0 %s (reg %d sel %d)\n", rn, reg, sel);
4936 static inline void gen_mfc0_unimplemented(DisasContext *ctx, TCGv arg)
4938 if (ctx->insn_flags & ISA_MIPS32R6) {
4939 tcg_gen_movi_tl(arg, 0);
4940 } else {
4941 tcg_gen_movi_tl(arg, ~0);
4945 static void gen_mfc0(DisasContext *ctx, TCGv arg, int reg, int sel)
4947 const char *rn = "invalid";
4949 if (sel != 0)
4950 check_insn(ctx, ISA_MIPS32);
4952 switch (reg) {
4953 case 0:
4954 switch (sel) {
4955 case 0:
4956 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Index));
4957 rn = "Index";
4958 break;
4959 case 1:
4960 CP0_CHECK(ctx->insn_flags & ASE_MT);
4961 gen_helper_mfc0_mvpcontrol(arg, cpu_env);
4962 rn = "MVPControl";
4963 break;
4964 case 2:
4965 CP0_CHECK(ctx->insn_flags & ASE_MT);
4966 gen_helper_mfc0_mvpconf0(arg, cpu_env);
4967 rn = "MVPConf0";
4968 break;
4969 case 3:
4970 CP0_CHECK(ctx->insn_flags & ASE_MT);
4971 gen_helper_mfc0_mvpconf1(arg, cpu_env);
4972 rn = "MVPConf1";
4973 break;
4974 case 4:
4975 CP0_CHECK(ctx->vp);
4976 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPControl));
4977 rn = "VPControl";
4978 break;
4979 default:
4980 goto cp0_unimplemented;
4982 break;
4983 case 1:
4984 switch (sel) {
4985 case 0:
4986 CP0_CHECK(!(ctx->insn_flags & ISA_MIPS32R6));
4987 gen_helper_mfc0_random(arg, cpu_env);
4988 rn = "Random";
4989 break;
4990 case 1:
4991 CP0_CHECK(ctx->insn_flags & ASE_MT);
4992 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEControl));
4993 rn = "VPEControl";
4994 break;
4995 case 2:
4996 CP0_CHECK(ctx->insn_flags & ASE_MT);
4997 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEConf0));
4998 rn = "VPEConf0";
4999 break;
5000 case 3:
5001 CP0_CHECK(ctx->insn_flags & ASE_MT);
5002 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEConf1));
5003 rn = "VPEConf1";
5004 break;
5005 case 4:
5006 CP0_CHECK(ctx->insn_flags & ASE_MT);
5007 gen_mfc0_load64(arg, offsetof(CPUMIPSState, CP0_YQMask));
5008 rn = "YQMask";
5009 break;
5010 case 5:
5011 CP0_CHECK(ctx->insn_flags & ASE_MT);
5012 gen_mfc0_load64(arg, offsetof(CPUMIPSState, CP0_VPESchedule));
5013 rn = "VPESchedule";
5014 break;
5015 case 6:
5016 CP0_CHECK(ctx->insn_flags & ASE_MT);
5017 gen_mfc0_load64(arg, offsetof(CPUMIPSState, CP0_VPEScheFBack));
5018 rn = "VPEScheFBack";
5019 break;
5020 case 7:
5021 CP0_CHECK(ctx->insn_flags & ASE_MT);
5022 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEOpt));
5023 rn = "VPEOpt";
5024 break;
5025 default:
5026 goto cp0_unimplemented;
5028 break;
5029 case 2:
5030 switch (sel) {
5031 case 0:
5033 TCGv_i64 tmp = tcg_temp_new_i64();
5034 tcg_gen_ld_i64(tmp, cpu_env,
5035 offsetof(CPUMIPSState, CP0_EntryLo0));
5036 #if defined(TARGET_MIPS64)
5037 if (ctx->rxi) {
5038 /* Move RI/XI fields to bits 31:30 */
5039 tcg_gen_shri_tl(arg, tmp, CP0EnLo_XI);
5040 tcg_gen_deposit_tl(tmp, tmp, arg, 30, 2);
5042 #endif
5043 gen_move_low32(arg, tmp);
5044 tcg_temp_free_i64(tmp);
5046 rn = "EntryLo0";
5047 break;
5048 case 1:
5049 CP0_CHECK(ctx->insn_flags & ASE_MT);
5050 gen_helper_mfc0_tcstatus(arg, cpu_env);
5051 rn = "TCStatus";
5052 break;
5053 case 2:
5054 CP0_CHECK(ctx->insn_flags & ASE_MT);
5055 gen_helper_mfc0_tcbind(arg, cpu_env);
5056 rn = "TCBind";
5057 break;
5058 case 3:
5059 CP0_CHECK(ctx->insn_flags & ASE_MT);
5060 gen_helper_mfc0_tcrestart(arg, cpu_env);
5061 rn = "TCRestart";
5062 break;
5063 case 4:
5064 CP0_CHECK(ctx->insn_flags & ASE_MT);
5065 gen_helper_mfc0_tchalt(arg, cpu_env);
5066 rn = "TCHalt";
5067 break;
5068 case 5:
5069 CP0_CHECK(ctx->insn_flags & ASE_MT);
5070 gen_helper_mfc0_tccontext(arg, cpu_env);
5071 rn = "TCContext";
5072 break;
5073 case 6:
5074 CP0_CHECK(ctx->insn_flags & ASE_MT);
5075 gen_helper_mfc0_tcschedule(arg, cpu_env);
5076 rn = "TCSchedule";
5077 break;
5078 case 7:
5079 CP0_CHECK(ctx->insn_flags & ASE_MT);
5080 gen_helper_mfc0_tcschefback(arg, cpu_env);
5081 rn = "TCScheFBack";
5082 break;
5083 default:
5084 goto cp0_unimplemented;
5086 break;
5087 case 3:
5088 switch (sel) {
5089 case 0:
5091 TCGv_i64 tmp = tcg_temp_new_i64();
5092 tcg_gen_ld_i64(tmp, cpu_env,
5093 offsetof(CPUMIPSState, CP0_EntryLo1));
5094 #if defined(TARGET_MIPS64)
5095 if (ctx->rxi) {
5096 /* Move RI/XI fields to bits 31:30 */
5097 tcg_gen_shri_tl(arg, tmp, CP0EnLo_XI);
5098 tcg_gen_deposit_tl(tmp, tmp, arg, 30, 2);
5100 #endif
5101 gen_move_low32(arg, tmp);
5102 tcg_temp_free_i64(tmp);
5104 rn = "EntryLo1";
5105 break;
5106 case 1:
5107 CP0_CHECK(ctx->vp);
5108 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_GlobalNumber));
5109 rn = "GlobalNumber";
5110 break;
5111 default:
5112 goto cp0_unimplemented;
5114 break;
5115 case 4:
5116 switch (sel) {
5117 case 0:
5118 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_Context));
5119 tcg_gen_ext32s_tl(arg, arg);
5120 rn = "Context";
5121 break;
5122 case 1:
5123 // gen_helper_mfc0_contextconfig(arg); /* SmartMIPS ASE */
5124 rn = "ContextConfig";
5125 goto cp0_unimplemented;
5126 // break;
5127 case 2:
5128 CP0_CHECK(ctx->ulri);
5129 tcg_gen_ld32s_tl(arg, cpu_env,
5130 offsetof(CPUMIPSState, active_tc.CP0_UserLocal));
5131 rn = "UserLocal";
5132 break;
5133 default:
5134 goto cp0_unimplemented;
5136 break;
5137 case 5:
5138 switch (sel) {
5139 case 0:
5140 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PageMask));
5141 rn = "PageMask";
5142 break;
5143 case 1:
5144 check_insn(ctx, ISA_MIPS32R2);
5145 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PageGrain));
5146 rn = "PageGrain";
5147 break;
5148 default:
5149 goto cp0_unimplemented;
5151 break;
5152 case 6:
5153 switch (sel) {
5154 case 0:
5155 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Wired));
5156 rn = "Wired";
5157 break;
5158 case 1:
5159 check_insn(ctx, ISA_MIPS32R2);
5160 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf0));
5161 rn = "SRSConf0";
5162 break;
5163 case 2:
5164 check_insn(ctx, ISA_MIPS32R2);
5165 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf1));
5166 rn = "SRSConf1";
5167 break;
5168 case 3:
5169 check_insn(ctx, ISA_MIPS32R2);
5170 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf2));
5171 rn = "SRSConf2";
5172 break;
5173 case 4:
5174 check_insn(ctx, ISA_MIPS32R2);
5175 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf3));
5176 rn = "SRSConf3";
5177 break;
5178 case 5:
5179 check_insn(ctx, ISA_MIPS32R2);
5180 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf4));
5181 rn = "SRSConf4";
5182 break;
5183 default:
5184 goto cp0_unimplemented;
5186 break;
5187 case 7:
5188 switch (sel) {
5189 case 0:
5190 check_insn(ctx, ISA_MIPS32R2);
5191 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_HWREna));
5192 rn = "HWREna";
5193 break;
5194 default:
5195 goto cp0_unimplemented;
5197 break;
5198 case 8:
5199 switch (sel) {
5200 case 0:
5201 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_BadVAddr));
5202 tcg_gen_ext32s_tl(arg, arg);
5203 rn = "BadVAddr";
5204 break;
5205 case 1:
5206 CP0_CHECK(ctx->bi);
5207 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_BadInstr));
5208 rn = "BadInstr";
5209 break;
5210 case 2:
5211 CP0_CHECK(ctx->bp);
5212 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_BadInstrP));
5213 rn = "BadInstrP";
5214 break;
5215 default:
5216 goto cp0_unimplemented;
5218 break;
5219 case 9:
5220 switch (sel) {
5221 case 0:
5222 /* Mark as an IO operation because we read the time. */
5223 if (ctx->tb->cflags & CF_USE_ICOUNT) {
5224 gen_io_start();
5226 gen_helper_mfc0_count(arg, cpu_env);
5227 if (ctx->tb->cflags & CF_USE_ICOUNT) {
5228 gen_io_end();
5230 /* Break the TB to be able to take timer interrupts immediately
5231 after reading count. */
5232 ctx->bstate = BS_STOP;
5233 rn = "Count";
5234 break;
5235 /* 6,7 are implementation dependent */
5236 default:
5237 goto cp0_unimplemented;
5239 break;
5240 case 10:
5241 switch (sel) {
5242 case 0:
5243 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EntryHi));
5244 tcg_gen_ext32s_tl(arg, arg);
5245 rn = "EntryHi";
5246 break;
5247 default:
5248 goto cp0_unimplemented;
5250 break;
5251 case 11:
5252 switch (sel) {
5253 case 0:
5254 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Compare));
5255 rn = "Compare";
5256 break;
5257 /* 6,7 are implementation dependent */
5258 default:
5259 goto cp0_unimplemented;
5261 break;
5262 case 12:
5263 switch (sel) {
5264 case 0:
5265 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Status));
5266 rn = "Status";
5267 break;
5268 case 1:
5269 check_insn(ctx, ISA_MIPS32R2);
5270 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_IntCtl));
5271 rn = "IntCtl";
5272 break;
5273 case 2:
5274 check_insn(ctx, ISA_MIPS32R2);
5275 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSCtl));
5276 rn = "SRSCtl";
5277 break;
5278 case 3:
5279 check_insn(ctx, ISA_MIPS32R2);
5280 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSMap));
5281 rn = "SRSMap";
5282 break;
5283 default:
5284 goto cp0_unimplemented;
5286 break;
5287 case 13:
5288 switch (sel) {
5289 case 0:
5290 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Cause));
5291 rn = "Cause";
5292 break;
5293 default:
5294 goto cp0_unimplemented;
5296 break;
5297 case 14:
5298 switch (sel) {
5299 case 0:
5300 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EPC));
5301 tcg_gen_ext32s_tl(arg, arg);
5302 rn = "EPC";
5303 break;
5304 default:
5305 goto cp0_unimplemented;
5307 break;
5308 case 15:
5309 switch (sel) {
5310 case 0:
5311 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PRid));
5312 rn = "PRid";
5313 break;
5314 case 1:
5315 check_insn(ctx, ISA_MIPS32R2);
5316 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_EBase));
5317 rn = "EBase";
5318 break;
5319 case 3:
5320 check_insn(ctx, ISA_MIPS32R2);
5321 CP0_CHECK(ctx->cmgcr);
5322 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_CMGCRBase));
5323 tcg_gen_ext32s_tl(arg, arg);
5324 rn = "CMGCRBase";
5325 break;
5326 default:
5327 goto cp0_unimplemented;
5329 break;
5330 case 16:
5331 switch (sel) {
5332 case 0:
5333 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config0));
5334 rn = "Config";
5335 break;
5336 case 1:
5337 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config1));
5338 rn = "Config1";
5339 break;
5340 case 2:
5341 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config2));
5342 rn = "Config2";
5343 break;
5344 case 3:
5345 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config3));
5346 rn = "Config3";
5347 break;
5348 case 4:
5349 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config4));
5350 rn = "Config4";
5351 break;
5352 case 5:
5353 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config5));
5354 rn = "Config5";
5355 break;
5356 /* 6,7 are implementation dependent */
5357 case 6:
5358 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config6));
5359 rn = "Config6";
5360 break;
5361 case 7:
5362 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config7));
5363 rn = "Config7";
5364 break;
5365 default:
5366 goto cp0_unimplemented;
5368 break;
5369 case 17:
5370 switch (sel) {
5371 case 0:
5372 gen_helper_mfc0_lladdr(arg, cpu_env);
5373 rn = "LLAddr";
5374 break;
5375 case 1:
5376 CP0_CHECK(ctx->mrp);
5377 gen_helper_mfc0_maar(arg, cpu_env);
5378 rn = "MAAR";
5379 break;
5380 case 2:
5381 CP0_CHECK(ctx->mrp);
5382 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_MAARI));
5383 rn = "MAARI";
5384 break;
5385 default:
5386 goto cp0_unimplemented;
5388 break;
5389 case 18:
5390 switch (sel) {
5391 case 0 ... 7:
5392 gen_helper_1e0i(mfc0_watchlo, arg, sel);
5393 rn = "WatchLo";
5394 break;
5395 default:
5396 goto cp0_unimplemented;
5398 break;
5399 case 19:
5400 switch (sel) {
5401 case 0 ...7:
5402 gen_helper_1e0i(mfc0_watchhi, arg, sel);
5403 rn = "WatchHi";
5404 break;
5405 default:
5406 goto cp0_unimplemented;
5408 break;
5409 case 20:
5410 switch (sel) {
5411 case 0:
5412 #if defined(TARGET_MIPS64)
5413 check_insn(ctx, ISA_MIPS3);
5414 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_XContext));
5415 tcg_gen_ext32s_tl(arg, arg);
5416 rn = "XContext";
5417 break;
5418 #endif
5419 default:
5420 goto cp0_unimplemented;
5422 break;
5423 case 21:
5424 /* Officially reserved, but sel 0 is used for R1x000 framemask */
5425 CP0_CHECK(!(ctx->insn_flags & ISA_MIPS32R6));
5426 switch (sel) {
5427 case 0:
5428 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Framemask));
5429 rn = "Framemask";
5430 break;
5431 default:
5432 goto cp0_unimplemented;
5434 break;
5435 case 22:
5436 tcg_gen_movi_tl(arg, 0); /* unimplemented */
5437 rn = "'Diagnostic"; /* implementation dependent */
5438 break;
5439 case 23:
5440 switch (sel) {
5441 case 0:
5442 gen_helper_mfc0_debug(arg, cpu_env); /* EJTAG support */
5443 rn = "Debug";
5444 break;
5445 case 1:
5446 // gen_helper_mfc0_tracecontrol(arg); /* PDtrace support */
5447 rn = "TraceControl";
5448 // break;
5449 case 2:
5450 // gen_helper_mfc0_tracecontrol2(arg); /* PDtrace support */
5451 rn = "TraceControl2";
5452 // break;
5453 case 3:
5454 // gen_helper_mfc0_usertracedata(arg); /* PDtrace support */
5455 rn = "UserTraceData";
5456 // break;
5457 case 4:
5458 // gen_helper_mfc0_tracebpc(arg); /* PDtrace support */
5459 rn = "TraceBPC";
5460 // break;
5461 default:
5462 goto cp0_unimplemented;
5464 break;
5465 case 24:
5466 switch (sel) {
5467 case 0:
5468 /* EJTAG support */
5469 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_DEPC));
5470 tcg_gen_ext32s_tl(arg, arg);
5471 rn = "DEPC";
5472 break;
5473 default:
5474 goto cp0_unimplemented;
5476 break;
5477 case 25:
5478 switch (sel) {
5479 case 0:
5480 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Performance0));
5481 rn = "Performance0";
5482 break;
5483 case 1:
5484 // gen_helper_mfc0_performance1(arg);
5485 rn = "Performance1";
5486 // break;
5487 case 2:
5488 // gen_helper_mfc0_performance2(arg);
5489 rn = "Performance2";
5490 // break;
5491 case 3:
5492 // gen_helper_mfc0_performance3(arg);
5493 rn = "Performance3";
5494 // break;
5495 case 4:
5496 // gen_helper_mfc0_performance4(arg);
5497 rn = "Performance4";
5498 // break;
5499 case 5:
5500 // gen_helper_mfc0_performance5(arg);
5501 rn = "Performance5";
5502 // break;
5503 case 6:
5504 // gen_helper_mfc0_performance6(arg);
5505 rn = "Performance6";
5506 // break;
5507 case 7:
5508 // gen_helper_mfc0_performance7(arg);
5509 rn = "Performance7";
5510 // break;
5511 default:
5512 goto cp0_unimplemented;
5514 break;
5515 case 26:
5516 switch (sel) {
5517 case 0:
5518 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_ErrCtl));
5519 rn = "ErrCtl";
5520 break;
5521 default:
5522 goto cp0_unimplemented;
5524 break;
5525 case 27:
5526 switch (sel) {
5527 case 0 ... 3:
5528 tcg_gen_movi_tl(arg, 0); /* unimplemented */
5529 rn = "CacheErr";
5530 break;
5531 default:
5532 goto cp0_unimplemented;
5534 break;
5535 case 28:
5536 switch (sel) {
5537 case 0:
5538 case 2:
5539 case 4:
5540 case 6:
5542 TCGv_i64 tmp = tcg_temp_new_i64();
5543 tcg_gen_ld_i64(tmp, cpu_env, offsetof(CPUMIPSState, CP0_TagLo));
5544 gen_move_low32(arg, tmp);
5545 tcg_temp_free_i64(tmp);
5547 rn = "TagLo";
5548 break;
5549 case 1:
5550 case 3:
5551 case 5:
5552 case 7:
5553 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DataLo));
5554 rn = "DataLo";
5555 break;
5556 default:
5557 goto cp0_unimplemented;
5559 break;
5560 case 29:
5561 switch (sel) {
5562 case 0:
5563 case 2:
5564 case 4:
5565 case 6:
5566 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_TagHi));
5567 rn = "TagHi";
5568 break;
5569 case 1:
5570 case 3:
5571 case 5:
5572 case 7:
5573 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DataHi));
5574 rn = "DataHi";
5575 break;
5576 default:
5577 goto cp0_unimplemented;
5579 break;
5580 case 30:
5581 switch (sel) {
5582 case 0:
5583 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_ErrorEPC));
5584 tcg_gen_ext32s_tl(arg, arg);
5585 rn = "ErrorEPC";
5586 break;
5587 default:
5588 goto cp0_unimplemented;
5590 break;
5591 case 31:
5592 switch (sel) {
5593 case 0:
5594 /* EJTAG support */
5595 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DESAVE));
5596 rn = "DESAVE";
5597 break;
5598 case 2 ... 7:
5599 CP0_CHECK(ctx->kscrexist & (1 << sel));
5600 tcg_gen_ld_tl(arg, cpu_env,
5601 offsetof(CPUMIPSState, CP0_KScratch[sel-2]));
5602 tcg_gen_ext32s_tl(arg, arg);
5603 rn = "KScratch";
5604 break;
5605 default:
5606 goto cp0_unimplemented;
5608 break;
5609 default:
5610 goto cp0_unimplemented;
5612 (void)rn; /* avoid a compiler warning */
5613 LOG_DISAS("mfc0 %s (reg %d sel %d)\n", rn, reg, sel);
5614 return;
5616 cp0_unimplemented:
5617 LOG_DISAS("mfc0 %s (reg %d sel %d)\n", rn, reg, sel);
5618 gen_mfc0_unimplemented(ctx, arg);
5621 static void gen_mtc0(DisasContext *ctx, TCGv arg, int reg, int sel)
5623 const char *rn = "invalid";
5625 if (sel != 0)
5626 check_insn(ctx, ISA_MIPS32);
5628 if (ctx->tb->cflags & CF_USE_ICOUNT) {
5629 gen_io_start();
5632 switch (reg) {
5633 case 0:
5634 switch (sel) {
5635 case 0:
5636 gen_helper_mtc0_index(cpu_env, arg);
5637 rn = "Index";
5638 break;
5639 case 1:
5640 CP0_CHECK(ctx->insn_flags & ASE_MT);
5641 gen_helper_mtc0_mvpcontrol(cpu_env, arg);
5642 rn = "MVPControl";
5643 break;
5644 case 2:
5645 CP0_CHECK(ctx->insn_flags & ASE_MT);
5646 /* ignored */
5647 rn = "MVPConf0";
5648 break;
5649 case 3:
5650 CP0_CHECK(ctx->insn_flags & ASE_MT);
5651 /* ignored */
5652 rn = "MVPConf1";
5653 break;
5654 case 4:
5655 CP0_CHECK(ctx->vp);
5656 /* ignored */
5657 rn = "VPControl";
5658 break;
5659 default:
5660 goto cp0_unimplemented;
5662 break;
5663 case 1:
5664 switch (sel) {
5665 case 0:
5666 /* ignored */
5667 rn = "Random";
5668 break;
5669 case 1:
5670 CP0_CHECK(ctx->insn_flags & ASE_MT);
5671 gen_helper_mtc0_vpecontrol(cpu_env, arg);
5672 rn = "VPEControl";
5673 break;
5674 case 2:
5675 CP0_CHECK(ctx->insn_flags & ASE_MT);
5676 gen_helper_mtc0_vpeconf0(cpu_env, arg);
5677 rn = "VPEConf0";
5678 break;
5679 case 3:
5680 CP0_CHECK(ctx->insn_flags & ASE_MT);
5681 gen_helper_mtc0_vpeconf1(cpu_env, arg);
5682 rn = "VPEConf1";
5683 break;
5684 case 4:
5685 CP0_CHECK(ctx->insn_flags & ASE_MT);
5686 gen_helper_mtc0_yqmask(cpu_env, arg);
5687 rn = "YQMask";
5688 break;
5689 case 5:
5690 CP0_CHECK(ctx->insn_flags & ASE_MT);
5691 tcg_gen_st_tl(arg, cpu_env,
5692 offsetof(CPUMIPSState, CP0_VPESchedule));
5693 rn = "VPESchedule";
5694 break;
5695 case 6:
5696 CP0_CHECK(ctx->insn_flags & ASE_MT);
5697 tcg_gen_st_tl(arg, cpu_env,
5698 offsetof(CPUMIPSState, CP0_VPEScheFBack));
5699 rn = "VPEScheFBack";
5700 break;
5701 case 7:
5702 CP0_CHECK(ctx->insn_flags & ASE_MT);
5703 gen_helper_mtc0_vpeopt(cpu_env, arg);
5704 rn = "VPEOpt";
5705 break;
5706 default:
5707 goto cp0_unimplemented;
5709 break;
5710 case 2:
5711 switch (sel) {
5712 case 0:
5713 gen_helper_mtc0_entrylo0(cpu_env, arg);
5714 rn = "EntryLo0";
5715 break;
5716 case 1:
5717 CP0_CHECK(ctx->insn_flags & ASE_MT);
5718 gen_helper_mtc0_tcstatus(cpu_env, arg);
5719 rn = "TCStatus";
5720 break;
5721 case 2:
5722 CP0_CHECK(ctx->insn_flags & ASE_MT);
5723 gen_helper_mtc0_tcbind(cpu_env, arg);
5724 rn = "TCBind";
5725 break;
5726 case 3:
5727 CP0_CHECK(ctx->insn_flags & ASE_MT);
5728 gen_helper_mtc0_tcrestart(cpu_env, arg);
5729 rn = "TCRestart";
5730 break;
5731 case 4:
5732 CP0_CHECK(ctx->insn_flags & ASE_MT);
5733 gen_helper_mtc0_tchalt(cpu_env, arg);
5734 rn = "TCHalt";
5735 break;
5736 case 5:
5737 CP0_CHECK(ctx->insn_flags & ASE_MT);
5738 gen_helper_mtc0_tccontext(cpu_env, arg);
5739 rn = "TCContext";
5740 break;
5741 case 6:
5742 CP0_CHECK(ctx->insn_flags & ASE_MT);
5743 gen_helper_mtc0_tcschedule(cpu_env, arg);
5744 rn = "TCSchedule";
5745 break;
5746 case 7:
5747 CP0_CHECK(ctx->insn_flags & ASE_MT);
5748 gen_helper_mtc0_tcschefback(cpu_env, arg);
5749 rn = "TCScheFBack";
5750 break;
5751 default:
5752 goto cp0_unimplemented;
5754 break;
5755 case 3:
5756 switch (sel) {
5757 case 0:
5758 gen_helper_mtc0_entrylo1(cpu_env, arg);
5759 rn = "EntryLo1";
5760 break;
5761 case 1:
5762 CP0_CHECK(ctx->vp);
5763 /* ignored */
5764 rn = "GlobalNumber";
5765 break;
5766 default:
5767 goto cp0_unimplemented;
5769 break;
5770 case 4:
5771 switch (sel) {
5772 case 0:
5773 gen_helper_mtc0_context(cpu_env, arg);
5774 rn = "Context";
5775 break;
5776 case 1:
5777 // gen_helper_mtc0_contextconfig(cpu_env, arg); /* SmartMIPS ASE */
5778 rn = "ContextConfig";
5779 goto cp0_unimplemented;
5780 // break;
5781 case 2:
5782 CP0_CHECK(ctx->ulri);
5783 tcg_gen_st_tl(arg, cpu_env,
5784 offsetof(CPUMIPSState, active_tc.CP0_UserLocal));
5785 rn = "UserLocal";
5786 break;
5787 default:
5788 goto cp0_unimplemented;
5790 break;
5791 case 5:
5792 switch (sel) {
5793 case 0:
5794 gen_helper_mtc0_pagemask(cpu_env, arg);
5795 rn = "PageMask";
5796 break;
5797 case 1:
5798 check_insn(ctx, ISA_MIPS32R2);
5799 gen_helper_mtc0_pagegrain(cpu_env, arg);
5800 rn = "PageGrain";
5801 ctx->bstate = BS_STOP;
5802 break;
5803 default:
5804 goto cp0_unimplemented;
5806 break;
5807 case 6:
5808 switch (sel) {
5809 case 0:
5810 gen_helper_mtc0_wired(cpu_env, arg);
5811 rn = "Wired";
5812 break;
5813 case 1:
5814 check_insn(ctx, ISA_MIPS32R2);
5815 gen_helper_mtc0_srsconf0(cpu_env, arg);
5816 rn = "SRSConf0";
5817 break;
5818 case 2:
5819 check_insn(ctx, ISA_MIPS32R2);
5820 gen_helper_mtc0_srsconf1(cpu_env, arg);
5821 rn = "SRSConf1";
5822 break;
5823 case 3:
5824 check_insn(ctx, ISA_MIPS32R2);
5825 gen_helper_mtc0_srsconf2(cpu_env, arg);
5826 rn = "SRSConf2";
5827 break;
5828 case 4:
5829 check_insn(ctx, ISA_MIPS32R2);
5830 gen_helper_mtc0_srsconf3(cpu_env, arg);
5831 rn = "SRSConf3";
5832 break;
5833 case 5:
5834 check_insn(ctx, ISA_MIPS32R2);
5835 gen_helper_mtc0_srsconf4(cpu_env, arg);
5836 rn = "SRSConf4";
5837 break;
5838 default:
5839 goto cp0_unimplemented;
5841 break;
5842 case 7:
5843 switch (sel) {
5844 case 0:
5845 check_insn(ctx, ISA_MIPS32R2);
5846 gen_helper_mtc0_hwrena(cpu_env, arg);
5847 ctx->bstate = BS_STOP;
5848 rn = "HWREna";
5849 break;
5850 default:
5851 goto cp0_unimplemented;
5853 break;
5854 case 8:
5855 switch (sel) {
5856 case 0:
5857 /* ignored */
5858 rn = "BadVAddr";
5859 break;
5860 case 1:
5861 /* ignored */
5862 rn = "BadInstr";
5863 break;
5864 case 2:
5865 /* ignored */
5866 rn = "BadInstrP";
5867 break;
5868 default:
5869 goto cp0_unimplemented;
5871 break;
5872 case 9:
5873 switch (sel) {
5874 case 0:
5875 gen_helper_mtc0_count(cpu_env, arg);
5876 rn = "Count";
5877 break;
5878 /* 6,7 are implementation dependent */
5879 default:
5880 goto cp0_unimplemented;
5882 break;
5883 case 10:
5884 switch (sel) {
5885 case 0:
5886 gen_helper_mtc0_entryhi(cpu_env, arg);
5887 rn = "EntryHi";
5888 break;
5889 default:
5890 goto cp0_unimplemented;
5892 break;
5893 case 11:
5894 switch (sel) {
5895 case 0:
5896 gen_helper_mtc0_compare(cpu_env, arg);
5897 rn = "Compare";
5898 break;
5899 /* 6,7 are implementation dependent */
5900 default:
5901 goto cp0_unimplemented;
5903 break;
5904 case 12:
5905 switch (sel) {
5906 case 0:
5907 save_cpu_state(ctx, 1);
5908 gen_helper_mtc0_status(cpu_env, arg);
5909 /* BS_STOP isn't good enough here, hflags may have changed. */
5910 gen_save_pc(ctx->pc + 4);
5911 ctx->bstate = BS_EXCP;
5912 rn = "Status";
5913 break;
5914 case 1:
5915 check_insn(ctx, ISA_MIPS32R2);
5916 gen_helper_mtc0_intctl(cpu_env, arg);
5917 /* Stop translation as we may have switched the execution mode */
5918 ctx->bstate = BS_STOP;
5919 rn = "IntCtl";
5920 break;
5921 case 2:
5922 check_insn(ctx, ISA_MIPS32R2);
5923 gen_helper_mtc0_srsctl(cpu_env, arg);
5924 /* Stop translation as we may have switched the execution mode */
5925 ctx->bstate = BS_STOP;
5926 rn = "SRSCtl";
5927 break;
5928 case 3:
5929 check_insn(ctx, ISA_MIPS32R2);
5930 gen_mtc0_store32(arg, offsetof(CPUMIPSState, CP0_SRSMap));
5931 /* Stop translation as we may have switched the execution mode */
5932 ctx->bstate = BS_STOP;
5933 rn = "SRSMap";
5934 break;
5935 default:
5936 goto cp0_unimplemented;
5938 break;
5939 case 13:
5940 switch (sel) {
5941 case 0:
5942 save_cpu_state(ctx, 1);
5943 gen_helper_mtc0_cause(cpu_env, arg);
5944 rn = "Cause";
5945 break;
5946 default:
5947 goto cp0_unimplemented;
5949 break;
5950 case 14:
5951 switch (sel) {
5952 case 0:
5953 tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EPC));
5954 rn = "EPC";
5955 break;
5956 default:
5957 goto cp0_unimplemented;
5959 break;
5960 case 15:
5961 switch (sel) {
5962 case 0:
5963 /* ignored */
5964 rn = "PRid";
5965 break;
5966 case 1:
5967 check_insn(ctx, ISA_MIPS32R2);
5968 gen_helper_mtc0_ebase(cpu_env, arg);
5969 rn = "EBase";
5970 break;
5971 default:
5972 goto cp0_unimplemented;
5974 break;
5975 case 16:
5976 switch (sel) {
5977 case 0:
5978 gen_helper_mtc0_config0(cpu_env, arg);
5979 rn = "Config";
5980 /* Stop translation as we may have switched the execution mode */
5981 ctx->bstate = BS_STOP;
5982 break;
5983 case 1:
5984 /* ignored, read only */
5985 rn = "Config1";
5986 break;
5987 case 2:
5988 gen_helper_mtc0_config2(cpu_env, arg);
5989 rn = "Config2";
5990 /* Stop translation as we may have switched the execution mode */
5991 ctx->bstate = BS_STOP;
5992 break;
5993 case 3:
5994 gen_helper_mtc0_config3(cpu_env, arg);
5995 rn = "Config3";
5996 /* Stop translation as we may have switched the execution mode */
5997 ctx->bstate = BS_STOP;
5998 break;
5999 case 4:
6000 gen_helper_mtc0_config4(cpu_env, arg);
6001 rn = "Config4";
6002 ctx->bstate = BS_STOP;
6003 break;
6004 case 5:
6005 gen_helper_mtc0_config5(cpu_env, arg);
6006 rn = "Config5";
6007 /* Stop translation as we may have switched the execution mode */
6008 ctx->bstate = BS_STOP;
6009 break;
6010 /* 6,7 are implementation dependent */
6011 case 6:
6012 /* ignored */
6013 rn = "Config6";
6014 break;
6015 case 7:
6016 /* ignored */
6017 rn = "Config7";
6018 break;
6019 default:
6020 rn = "Invalid config selector";
6021 goto cp0_unimplemented;
6023 break;
6024 case 17:
6025 switch (sel) {
6026 case 0:
6027 gen_helper_mtc0_lladdr(cpu_env, arg);
6028 rn = "LLAddr";
6029 break;
6030 case 1:
6031 CP0_CHECK(ctx->mrp);
6032 gen_helper_mtc0_maar(cpu_env, arg);
6033 rn = "MAAR";
6034 break;
6035 case 2:
6036 CP0_CHECK(ctx->mrp);
6037 gen_helper_mtc0_maari(cpu_env, arg);
6038 rn = "MAARI";
6039 break;
6040 default:
6041 goto cp0_unimplemented;
6043 break;
6044 case 18:
6045 switch (sel) {
6046 case 0 ... 7:
6047 gen_helper_0e1i(mtc0_watchlo, arg, sel);
6048 rn = "WatchLo";
6049 break;
6050 default:
6051 goto cp0_unimplemented;
6053 break;
6054 case 19:
6055 switch (sel) {
6056 case 0 ... 7:
6057 gen_helper_0e1i(mtc0_watchhi, arg, sel);
6058 rn = "WatchHi";
6059 break;
6060 default:
6061 goto cp0_unimplemented;
6063 break;
6064 case 20:
6065 switch (sel) {
6066 case 0:
6067 #if defined(TARGET_MIPS64)
6068 check_insn(ctx, ISA_MIPS3);
6069 gen_helper_mtc0_xcontext(cpu_env, arg);
6070 rn = "XContext";
6071 break;
6072 #endif
6073 default:
6074 goto cp0_unimplemented;
6076 break;
6077 case 21:
6078 /* Officially reserved, but sel 0 is used for R1x000 framemask */
6079 CP0_CHECK(!(ctx->insn_flags & ISA_MIPS32R6));
6080 switch (sel) {
6081 case 0:
6082 gen_helper_mtc0_framemask(cpu_env, arg);
6083 rn = "Framemask";
6084 break;
6085 default:
6086 goto cp0_unimplemented;
6088 break;
6089 case 22:
6090 /* ignored */
6091 rn = "Diagnostic"; /* implementation dependent */
6092 break;
6093 case 23:
6094 switch (sel) {
6095 case 0:
6096 gen_helper_mtc0_debug(cpu_env, arg); /* EJTAG support */
6097 /* BS_STOP isn't good enough here, hflags may have changed. */
6098 gen_save_pc(ctx->pc + 4);
6099 ctx->bstate = BS_EXCP;
6100 rn = "Debug";
6101 break;
6102 case 1:
6103 // gen_helper_mtc0_tracecontrol(cpu_env, arg); /* PDtrace support */
6104 rn = "TraceControl";
6105 /* Stop translation as we may have switched the execution mode */
6106 ctx->bstate = BS_STOP;
6107 // break;
6108 case 2:
6109 // gen_helper_mtc0_tracecontrol2(cpu_env, arg); /* PDtrace support */
6110 rn = "TraceControl2";
6111 /* Stop translation as we may have switched the execution mode */
6112 ctx->bstate = BS_STOP;
6113 // break;
6114 case 3:
6115 /* Stop translation as we may have switched the execution mode */
6116 ctx->bstate = BS_STOP;
6117 // gen_helper_mtc0_usertracedata(cpu_env, arg); /* PDtrace support */
6118 rn = "UserTraceData";
6119 /* Stop translation as we may have switched the execution mode */
6120 ctx->bstate = BS_STOP;
6121 // break;
6122 case 4:
6123 // gen_helper_mtc0_tracebpc(cpu_env, arg); /* PDtrace support */
6124 /* Stop translation as we may have switched the execution mode */
6125 ctx->bstate = BS_STOP;
6126 rn = "TraceBPC";
6127 // break;
6128 default:
6129 goto cp0_unimplemented;
6131 break;
6132 case 24:
6133 switch (sel) {
6134 case 0:
6135 /* EJTAG support */
6136 tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_DEPC));
6137 rn = "DEPC";
6138 break;
6139 default:
6140 goto cp0_unimplemented;
6142 break;
6143 case 25:
6144 switch (sel) {
6145 case 0:
6146 gen_helper_mtc0_performance0(cpu_env, arg);
6147 rn = "Performance0";
6148 break;
6149 case 1:
6150 // gen_helper_mtc0_performance1(arg);
6151 rn = "Performance1";
6152 // break;
6153 case 2:
6154 // gen_helper_mtc0_performance2(arg);
6155 rn = "Performance2";
6156 // break;
6157 case 3:
6158 // gen_helper_mtc0_performance3(arg);
6159 rn = "Performance3";
6160 // break;
6161 case 4:
6162 // gen_helper_mtc0_performance4(arg);
6163 rn = "Performance4";
6164 // break;
6165 case 5:
6166 // gen_helper_mtc0_performance5(arg);
6167 rn = "Performance5";
6168 // break;
6169 case 6:
6170 // gen_helper_mtc0_performance6(arg);
6171 rn = "Performance6";
6172 // break;
6173 case 7:
6174 // gen_helper_mtc0_performance7(arg);
6175 rn = "Performance7";
6176 // break;
6177 default:
6178 goto cp0_unimplemented;
6180 break;
6181 case 26:
6182 switch (sel) {
6183 case 0:
6184 gen_helper_mtc0_errctl(cpu_env, arg);
6185 ctx->bstate = BS_STOP;
6186 rn = "ErrCtl";
6187 break;
6188 default:
6189 goto cp0_unimplemented;
6191 break;
6192 case 27:
6193 switch (sel) {
6194 case 0 ... 3:
6195 /* ignored */
6196 rn = "CacheErr";
6197 break;
6198 default:
6199 goto cp0_unimplemented;
6201 break;
6202 case 28:
6203 switch (sel) {
6204 case 0:
6205 case 2:
6206 case 4:
6207 case 6:
6208 gen_helper_mtc0_taglo(cpu_env, arg);
6209 rn = "TagLo";
6210 break;
6211 case 1:
6212 case 3:
6213 case 5:
6214 case 7:
6215 gen_helper_mtc0_datalo(cpu_env, arg);
6216 rn = "DataLo";
6217 break;
6218 default:
6219 goto cp0_unimplemented;
6221 break;
6222 case 29:
6223 switch (sel) {
6224 case 0:
6225 case 2:
6226 case 4:
6227 case 6:
6228 gen_helper_mtc0_taghi(cpu_env, arg);
6229 rn = "TagHi";
6230 break;
6231 case 1:
6232 case 3:
6233 case 5:
6234 case 7:
6235 gen_helper_mtc0_datahi(cpu_env, arg);
6236 rn = "DataHi";
6237 break;
6238 default:
6239 rn = "invalid sel";
6240 goto cp0_unimplemented;
6242 break;
6243 case 30:
6244 switch (sel) {
6245 case 0:
6246 tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_ErrorEPC));
6247 rn = "ErrorEPC";
6248 break;
6249 default:
6250 goto cp0_unimplemented;
6252 break;
6253 case 31:
6254 switch (sel) {
6255 case 0:
6256 /* EJTAG support */
6257 gen_mtc0_store32(arg, offsetof(CPUMIPSState, CP0_DESAVE));
6258 rn = "DESAVE";
6259 break;
6260 case 2 ... 7:
6261 CP0_CHECK(ctx->kscrexist & (1 << sel));
6262 tcg_gen_st_tl(arg, cpu_env,
6263 offsetof(CPUMIPSState, CP0_KScratch[sel-2]));
6264 rn = "KScratch";
6265 break;
6266 default:
6267 goto cp0_unimplemented;
6269 /* Stop translation as we may have switched the execution mode */
6270 ctx->bstate = BS_STOP;
6271 break;
6272 default:
6273 goto cp0_unimplemented;
6275 (void)rn; /* avoid a compiler warning */
6276 LOG_DISAS("mtc0 %s (reg %d sel %d)\n", rn, reg, sel);
6277 /* For simplicity assume that all writes can cause interrupts. */
6278 if (ctx->tb->cflags & CF_USE_ICOUNT) {
6279 gen_io_end();
6280 ctx->bstate = BS_STOP;
6282 return;
6284 cp0_unimplemented:
6285 LOG_DISAS("mtc0 %s (reg %d sel %d)\n", rn, reg, sel);
6288 #if defined(TARGET_MIPS64)
6289 static void gen_dmfc0(DisasContext *ctx, TCGv arg, int reg, int sel)
6291 const char *rn = "invalid";
6293 if (sel != 0)
6294 check_insn(ctx, ISA_MIPS64);
6296 switch (reg) {
6297 case 0:
6298 switch (sel) {
6299 case 0:
6300 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Index));
6301 rn = "Index";
6302 break;
6303 case 1:
6304 CP0_CHECK(ctx->insn_flags & ASE_MT);
6305 gen_helper_mfc0_mvpcontrol(arg, cpu_env);
6306 rn = "MVPControl";
6307 break;
6308 case 2:
6309 CP0_CHECK(ctx->insn_flags & ASE_MT);
6310 gen_helper_mfc0_mvpconf0(arg, cpu_env);
6311 rn = "MVPConf0";
6312 break;
6313 case 3:
6314 CP0_CHECK(ctx->insn_flags & ASE_MT);
6315 gen_helper_mfc0_mvpconf1(arg, cpu_env);
6316 rn = "MVPConf1";
6317 break;
6318 case 4:
6319 CP0_CHECK(ctx->vp);
6320 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPControl));
6321 rn = "VPControl";
6322 break;
6323 default:
6324 goto cp0_unimplemented;
6326 break;
6327 case 1:
6328 switch (sel) {
6329 case 0:
6330 CP0_CHECK(!(ctx->insn_flags & ISA_MIPS32R6));
6331 gen_helper_mfc0_random(arg, cpu_env);
6332 rn = "Random";
6333 break;
6334 case 1:
6335 CP0_CHECK(ctx->insn_flags & ASE_MT);
6336 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEControl));
6337 rn = "VPEControl";
6338 break;
6339 case 2:
6340 CP0_CHECK(ctx->insn_flags & ASE_MT);
6341 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEConf0));
6342 rn = "VPEConf0";
6343 break;
6344 case 3:
6345 CP0_CHECK(ctx->insn_flags & ASE_MT);
6346 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEConf1));
6347 rn = "VPEConf1";
6348 break;
6349 case 4:
6350 CP0_CHECK(ctx->insn_flags & ASE_MT);
6351 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_YQMask));
6352 rn = "YQMask";
6353 break;
6354 case 5:
6355 CP0_CHECK(ctx->insn_flags & ASE_MT);
6356 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_VPESchedule));
6357 rn = "VPESchedule";
6358 break;
6359 case 6:
6360 CP0_CHECK(ctx->insn_flags & ASE_MT);
6361 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_VPEScheFBack));
6362 rn = "VPEScheFBack";
6363 break;
6364 case 7:
6365 CP0_CHECK(ctx->insn_flags & ASE_MT);
6366 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEOpt));
6367 rn = "VPEOpt";
6368 break;
6369 default:
6370 goto cp0_unimplemented;
6372 break;
6373 case 2:
6374 switch (sel) {
6375 case 0:
6376 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EntryLo0));
6377 rn = "EntryLo0";
6378 break;
6379 case 1:
6380 CP0_CHECK(ctx->insn_flags & ASE_MT);
6381 gen_helper_mfc0_tcstatus(arg, cpu_env);
6382 rn = "TCStatus";
6383 break;
6384 case 2:
6385 CP0_CHECK(ctx->insn_flags & ASE_MT);
6386 gen_helper_mfc0_tcbind(arg, cpu_env);
6387 rn = "TCBind";
6388 break;
6389 case 3:
6390 CP0_CHECK(ctx->insn_flags & ASE_MT);
6391 gen_helper_dmfc0_tcrestart(arg, cpu_env);
6392 rn = "TCRestart";
6393 break;
6394 case 4:
6395 CP0_CHECK(ctx->insn_flags & ASE_MT);
6396 gen_helper_dmfc0_tchalt(arg, cpu_env);
6397 rn = "TCHalt";
6398 break;
6399 case 5:
6400 CP0_CHECK(ctx->insn_flags & ASE_MT);
6401 gen_helper_dmfc0_tccontext(arg, cpu_env);
6402 rn = "TCContext";
6403 break;
6404 case 6:
6405 CP0_CHECK(ctx->insn_flags & ASE_MT);
6406 gen_helper_dmfc0_tcschedule(arg, cpu_env);
6407 rn = "TCSchedule";
6408 break;
6409 case 7:
6410 CP0_CHECK(ctx->insn_flags & ASE_MT);
6411 gen_helper_dmfc0_tcschefback(arg, cpu_env);
6412 rn = "TCScheFBack";
6413 break;
6414 default:
6415 goto cp0_unimplemented;
6417 break;
6418 case 3:
6419 switch (sel) {
6420 case 0:
6421 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EntryLo1));
6422 rn = "EntryLo1";
6423 break;
6424 case 1:
6425 CP0_CHECK(ctx->vp);
6426 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_GlobalNumber));
6427 rn = "GlobalNumber";
6428 break;
6429 default:
6430 goto cp0_unimplemented;
6432 break;
6433 case 4:
6434 switch (sel) {
6435 case 0:
6436 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_Context));
6437 rn = "Context";
6438 break;
6439 case 1:
6440 // gen_helper_dmfc0_contextconfig(arg); /* SmartMIPS ASE */
6441 rn = "ContextConfig";
6442 goto cp0_unimplemented;
6443 // break;
6444 case 2:
6445 CP0_CHECK(ctx->ulri);
6446 tcg_gen_ld_tl(arg, cpu_env,
6447 offsetof(CPUMIPSState, active_tc.CP0_UserLocal));
6448 rn = "UserLocal";
6449 break;
6450 default:
6451 goto cp0_unimplemented;
6453 break;
6454 case 5:
6455 switch (sel) {
6456 case 0:
6457 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PageMask));
6458 rn = "PageMask";
6459 break;
6460 case 1:
6461 check_insn(ctx, ISA_MIPS32R2);
6462 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PageGrain));
6463 rn = "PageGrain";
6464 break;
6465 default:
6466 goto cp0_unimplemented;
6468 break;
6469 case 6:
6470 switch (sel) {
6471 case 0:
6472 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Wired));
6473 rn = "Wired";
6474 break;
6475 case 1:
6476 check_insn(ctx, ISA_MIPS32R2);
6477 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf0));
6478 rn = "SRSConf0";
6479 break;
6480 case 2:
6481 check_insn(ctx, ISA_MIPS32R2);
6482 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf1));
6483 rn = "SRSConf1";
6484 break;
6485 case 3:
6486 check_insn(ctx, ISA_MIPS32R2);
6487 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf2));
6488 rn = "SRSConf2";
6489 break;
6490 case 4:
6491 check_insn(ctx, ISA_MIPS32R2);
6492 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf3));
6493 rn = "SRSConf3";
6494 break;
6495 case 5:
6496 check_insn(ctx, ISA_MIPS32R2);
6497 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf4));
6498 rn = "SRSConf4";
6499 break;
6500 default:
6501 goto cp0_unimplemented;
6503 break;
6504 case 7:
6505 switch (sel) {
6506 case 0:
6507 check_insn(ctx, ISA_MIPS32R2);
6508 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_HWREna));
6509 rn = "HWREna";
6510 break;
6511 default:
6512 goto cp0_unimplemented;
6514 break;
6515 case 8:
6516 switch (sel) {
6517 case 0:
6518 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_BadVAddr));
6519 rn = "BadVAddr";
6520 break;
6521 case 1:
6522 CP0_CHECK(ctx->bi);
6523 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_BadInstr));
6524 rn = "BadInstr";
6525 break;
6526 case 2:
6527 CP0_CHECK(ctx->bp);
6528 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_BadInstrP));
6529 rn = "BadInstrP";
6530 break;
6531 default:
6532 goto cp0_unimplemented;
6534 break;
6535 case 9:
6536 switch (sel) {
6537 case 0:
6538 /* Mark as an IO operation because we read the time. */
6539 if (ctx->tb->cflags & CF_USE_ICOUNT) {
6540 gen_io_start();
6542 gen_helper_mfc0_count(arg, cpu_env);
6543 if (ctx->tb->cflags & CF_USE_ICOUNT) {
6544 gen_io_end();
6546 /* Break the TB to be able to take timer interrupts immediately
6547 after reading count. */
6548 ctx->bstate = BS_STOP;
6549 rn = "Count";
6550 break;
6551 /* 6,7 are implementation dependent */
6552 default:
6553 goto cp0_unimplemented;
6555 break;
6556 case 10:
6557 switch (sel) {
6558 case 0:
6559 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EntryHi));
6560 rn = "EntryHi";
6561 break;
6562 default:
6563 goto cp0_unimplemented;
6565 break;
6566 case 11:
6567 switch (sel) {
6568 case 0:
6569 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Compare));
6570 rn = "Compare";
6571 break;
6572 /* 6,7 are implementation dependent */
6573 default:
6574 goto cp0_unimplemented;
6576 break;
6577 case 12:
6578 switch (sel) {
6579 case 0:
6580 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Status));
6581 rn = "Status";
6582 break;
6583 case 1:
6584 check_insn(ctx, ISA_MIPS32R2);
6585 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_IntCtl));
6586 rn = "IntCtl";
6587 break;
6588 case 2:
6589 check_insn(ctx, ISA_MIPS32R2);
6590 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSCtl));
6591 rn = "SRSCtl";
6592 break;
6593 case 3:
6594 check_insn(ctx, ISA_MIPS32R2);
6595 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSMap));
6596 rn = "SRSMap";
6597 break;
6598 default:
6599 goto cp0_unimplemented;
6601 break;
6602 case 13:
6603 switch (sel) {
6604 case 0:
6605 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Cause));
6606 rn = "Cause";
6607 break;
6608 default:
6609 goto cp0_unimplemented;
6611 break;
6612 case 14:
6613 switch (sel) {
6614 case 0:
6615 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EPC));
6616 rn = "EPC";
6617 break;
6618 default:
6619 goto cp0_unimplemented;
6621 break;
6622 case 15:
6623 switch (sel) {
6624 case 0:
6625 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PRid));
6626 rn = "PRid";
6627 break;
6628 case 1:
6629 check_insn(ctx, ISA_MIPS32R2);
6630 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_EBase));
6631 rn = "EBase";
6632 break;
6633 case 3:
6634 check_insn(ctx, ISA_MIPS32R2);
6635 CP0_CHECK(ctx->cmgcr);
6636 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_CMGCRBase));
6637 rn = "CMGCRBase";
6638 break;
6639 default:
6640 goto cp0_unimplemented;
6642 break;
6643 case 16:
6644 switch (sel) {
6645 case 0:
6646 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config0));
6647 rn = "Config";
6648 break;
6649 case 1:
6650 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config1));
6651 rn = "Config1";
6652 break;
6653 case 2:
6654 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config2));
6655 rn = "Config2";
6656 break;
6657 case 3:
6658 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config3));
6659 rn = "Config3";
6660 break;
6661 case 4:
6662 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config4));
6663 rn = "Config4";
6664 break;
6665 case 5:
6666 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config5));
6667 rn = "Config5";
6668 break;
6669 /* 6,7 are implementation dependent */
6670 case 6:
6671 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config6));
6672 rn = "Config6";
6673 break;
6674 case 7:
6675 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config7));
6676 rn = "Config7";
6677 break;
6678 default:
6679 goto cp0_unimplemented;
6681 break;
6682 case 17:
6683 switch (sel) {
6684 case 0:
6685 gen_helper_dmfc0_lladdr(arg, cpu_env);
6686 rn = "LLAddr";
6687 break;
6688 case 1:
6689 CP0_CHECK(ctx->mrp);
6690 gen_helper_dmfc0_maar(arg, cpu_env);
6691 rn = "MAAR";
6692 break;
6693 case 2:
6694 CP0_CHECK(ctx->mrp);
6695 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_MAARI));
6696 rn = "MAARI";
6697 break;
6698 default:
6699 goto cp0_unimplemented;
6701 break;
6702 case 18:
6703 switch (sel) {
6704 case 0 ... 7:
6705 gen_helper_1e0i(dmfc0_watchlo, arg, sel);
6706 rn = "WatchLo";
6707 break;
6708 default:
6709 goto cp0_unimplemented;
6711 break;
6712 case 19:
6713 switch (sel) {
6714 case 0 ... 7:
6715 gen_helper_1e0i(mfc0_watchhi, arg, sel);
6716 rn = "WatchHi";
6717 break;
6718 default:
6719 goto cp0_unimplemented;
6721 break;
6722 case 20:
6723 switch (sel) {
6724 case 0:
6725 check_insn(ctx, ISA_MIPS3);
6726 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_XContext));
6727 rn = "XContext";
6728 break;
6729 default:
6730 goto cp0_unimplemented;
6732 break;
6733 case 21:
6734 /* Officially reserved, but sel 0 is used for R1x000 framemask */
6735 CP0_CHECK(!(ctx->insn_flags & ISA_MIPS32R6));
6736 switch (sel) {
6737 case 0:
6738 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Framemask));
6739 rn = "Framemask";
6740 break;
6741 default:
6742 goto cp0_unimplemented;
6744 break;
6745 case 22:
6746 tcg_gen_movi_tl(arg, 0); /* unimplemented */
6747 rn = "'Diagnostic"; /* implementation dependent */
6748 break;
6749 case 23:
6750 switch (sel) {
6751 case 0:
6752 gen_helper_mfc0_debug(arg, cpu_env); /* EJTAG support */
6753 rn = "Debug";
6754 break;
6755 case 1:
6756 // gen_helper_dmfc0_tracecontrol(arg, cpu_env); /* PDtrace support */
6757 rn = "TraceControl";
6758 // break;
6759 case 2:
6760 // gen_helper_dmfc0_tracecontrol2(arg, cpu_env); /* PDtrace support */
6761 rn = "TraceControl2";
6762 // break;
6763 case 3:
6764 // gen_helper_dmfc0_usertracedata(arg, cpu_env); /* PDtrace support */
6765 rn = "UserTraceData";
6766 // break;
6767 case 4:
6768 // gen_helper_dmfc0_tracebpc(arg, cpu_env); /* PDtrace support */
6769 rn = "TraceBPC";
6770 // break;
6771 default:
6772 goto cp0_unimplemented;
6774 break;
6775 case 24:
6776 switch (sel) {
6777 case 0:
6778 /* EJTAG support */
6779 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_DEPC));
6780 rn = "DEPC";
6781 break;
6782 default:
6783 goto cp0_unimplemented;
6785 break;
6786 case 25:
6787 switch (sel) {
6788 case 0:
6789 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Performance0));
6790 rn = "Performance0";
6791 break;
6792 case 1:
6793 // gen_helper_dmfc0_performance1(arg);
6794 rn = "Performance1";
6795 // break;
6796 case 2:
6797 // gen_helper_dmfc0_performance2(arg);
6798 rn = "Performance2";
6799 // break;
6800 case 3:
6801 // gen_helper_dmfc0_performance3(arg);
6802 rn = "Performance3";
6803 // break;
6804 case 4:
6805 // gen_helper_dmfc0_performance4(arg);
6806 rn = "Performance4";
6807 // break;
6808 case 5:
6809 // gen_helper_dmfc0_performance5(arg);
6810 rn = "Performance5";
6811 // break;
6812 case 6:
6813 // gen_helper_dmfc0_performance6(arg);
6814 rn = "Performance6";
6815 // break;
6816 case 7:
6817 // gen_helper_dmfc0_performance7(arg);
6818 rn = "Performance7";
6819 // break;
6820 default:
6821 goto cp0_unimplemented;
6823 break;
6824 case 26:
6825 switch (sel) {
6826 case 0:
6827 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_ErrCtl));
6828 rn = "ErrCtl";
6829 break;
6830 default:
6831 goto cp0_unimplemented;
6833 break;
6834 case 27:
6835 switch (sel) {
6836 /* ignored */
6837 case 0 ... 3:
6838 tcg_gen_movi_tl(arg, 0); /* unimplemented */
6839 rn = "CacheErr";
6840 break;
6841 default:
6842 goto cp0_unimplemented;
6844 break;
6845 case 28:
6846 switch (sel) {
6847 case 0:
6848 case 2:
6849 case 4:
6850 case 6:
6851 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_TagLo));
6852 rn = "TagLo";
6853 break;
6854 case 1:
6855 case 3:
6856 case 5:
6857 case 7:
6858 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DataLo));
6859 rn = "DataLo";
6860 break;
6861 default:
6862 goto cp0_unimplemented;
6864 break;
6865 case 29:
6866 switch (sel) {
6867 case 0:
6868 case 2:
6869 case 4:
6870 case 6:
6871 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_TagHi));
6872 rn = "TagHi";
6873 break;
6874 case 1:
6875 case 3:
6876 case 5:
6877 case 7:
6878 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DataHi));
6879 rn = "DataHi";
6880 break;
6881 default:
6882 goto cp0_unimplemented;
6884 break;
6885 case 30:
6886 switch (sel) {
6887 case 0:
6888 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_ErrorEPC));
6889 rn = "ErrorEPC";
6890 break;
6891 default:
6892 goto cp0_unimplemented;
6894 break;
6895 case 31:
6896 switch (sel) {
6897 case 0:
6898 /* EJTAG support */
6899 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DESAVE));
6900 rn = "DESAVE";
6901 break;
6902 case 2 ... 7:
6903 CP0_CHECK(ctx->kscrexist & (1 << sel));
6904 tcg_gen_ld_tl(arg, cpu_env,
6905 offsetof(CPUMIPSState, CP0_KScratch[sel-2]));
6906 rn = "KScratch";
6907 break;
6908 default:
6909 goto cp0_unimplemented;
6911 break;
6912 default:
6913 goto cp0_unimplemented;
6915 (void)rn; /* avoid a compiler warning */
6916 LOG_DISAS("dmfc0 %s (reg %d sel %d)\n", rn, reg, sel);
6917 return;
6919 cp0_unimplemented:
6920 LOG_DISAS("dmfc0 %s (reg %d sel %d)\n", rn, reg, sel);
6921 gen_mfc0_unimplemented(ctx, arg);
6924 static void gen_dmtc0(DisasContext *ctx, TCGv arg, int reg, int sel)
6926 const char *rn = "invalid";
6928 if (sel != 0)
6929 check_insn(ctx, ISA_MIPS64);
6931 if (ctx->tb->cflags & CF_USE_ICOUNT) {
6932 gen_io_start();
6935 switch (reg) {
6936 case 0:
6937 switch (sel) {
6938 case 0:
6939 gen_helper_mtc0_index(cpu_env, arg);
6940 rn = "Index";
6941 break;
6942 case 1:
6943 CP0_CHECK(ctx->insn_flags & ASE_MT);
6944 gen_helper_mtc0_mvpcontrol(cpu_env, arg);
6945 rn = "MVPControl";
6946 break;
6947 case 2:
6948 CP0_CHECK(ctx->insn_flags & ASE_MT);
6949 /* ignored */
6950 rn = "MVPConf0";
6951 break;
6952 case 3:
6953 CP0_CHECK(ctx->insn_flags & ASE_MT);
6954 /* ignored */
6955 rn = "MVPConf1";
6956 break;
6957 case 4:
6958 CP0_CHECK(ctx->vp);
6959 /* ignored */
6960 rn = "VPControl";
6961 break;
6962 default:
6963 goto cp0_unimplemented;
6965 break;
6966 case 1:
6967 switch (sel) {
6968 case 0:
6969 /* ignored */
6970 rn = "Random";
6971 break;
6972 case 1:
6973 CP0_CHECK(ctx->insn_flags & ASE_MT);
6974 gen_helper_mtc0_vpecontrol(cpu_env, arg);
6975 rn = "VPEControl";
6976 break;
6977 case 2:
6978 CP0_CHECK(ctx->insn_flags & ASE_MT);
6979 gen_helper_mtc0_vpeconf0(cpu_env, arg);
6980 rn = "VPEConf0";
6981 break;
6982 case 3:
6983 CP0_CHECK(ctx->insn_flags & ASE_MT);
6984 gen_helper_mtc0_vpeconf1(cpu_env, arg);
6985 rn = "VPEConf1";
6986 break;
6987 case 4:
6988 CP0_CHECK(ctx->insn_flags & ASE_MT);
6989 gen_helper_mtc0_yqmask(cpu_env, arg);
6990 rn = "YQMask";
6991 break;
6992 case 5:
6993 CP0_CHECK(ctx->insn_flags & ASE_MT);
6994 tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_VPESchedule));
6995 rn = "VPESchedule";
6996 break;
6997 case 6:
6998 CP0_CHECK(ctx->insn_flags & ASE_MT);
6999 tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_VPEScheFBack));
7000 rn = "VPEScheFBack";
7001 break;
7002 case 7:
7003 CP0_CHECK(ctx->insn_flags & ASE_MT);
7004 gen_helper_mtc0_vpeopt(cpu_env, arg);
7005 rn = "VPEOpt";
7006 break;
7007 default:
7008 goto cp0_unimplemented;
7010 break;
7011 case 2:
7012 switch (sel) {
7013 case 0:
7014 gen_helper_dmtc0_entrylo0(cpu_env, arg);
7015 rn = "EntryLo0";
7016 break;
7017 case 1:
7018 CP0_CHECK(ctx->insn_flags & ASE_MT);
7019 gen_helper_mtc0_tcstatus(cpu_env, arg);
7020 rn = "TCStatus";
7021 break;
7022 case 2:
7023 CP0_CHECK(ctx->insn_flags & ASE_MT);
7024 gen_helper_mtc0_tcbind(cpu_env, arg);
7025 rn = "TCBind";
7026 break;
7027 case 3:
7028 CP0_CHECK(ctx->insn_flags & ASE_MT);
7029 gen_helper_mtc0_tcrestart(cpu_env, arg);
7030 rn = "TCRestart";
7031 break;
7032 case 4:
7033 CP0_CHECK(ctx->insn_flags & ASE_MT);
7034 gen_helper_mtc0_tchalt(cpu_env, arg);
7035 rn = "TCHalt";
7036 break;
7037 case 5:
7038 CP0_CHECK(ctx->insn_flags & ASE_MT);
7039 gen_helper_mtc0_tccontext(cpu_env, arg);
7040 rn = "TCContext";
7041 break;
7042 case 6:
7043 CP0_CHECK(ctx->insn_flags & ASE_MT);
7044 gen_helper_mtc0_tcschedule(cpu_env, arg);
7045 rn = "TCSchedule";
7046 break;
7047 case 7:
7048 CP0_CHECK(ctx->insn_flags & ASE_MT);
7049 gen_helper_mtc0_tcschefback(cpu_env, arg);
7050 rn = "TCScheFBack";
7051 break;
7052 default:
7053 goto cp0_unimplemented;
7055 break;
7056 case 3:
7057 switch (sel) {
7058 case 0:
7059 gen_helper_dmtc0_entrylo1(cpu_env, arg);
7060 rn = "EntryLo1";
7061 break;
7062 case 1:
7063 CP0_CHECK(ctx->vp);
7064 /* ignored */
7065 rn = "GlobalNumber";
7066 break;
7067 default:
7068 goto cp0_unimplemented;
7070 break;
7071 case 4:
7072 switch (sel) {
7073 case 0:
7074 gen_helper_mtc0_context(cpu_env, arg);
7075 rn = "Context";
7076 break;
7077 case 1:
7078 // gen_helper_mtc0_contextconfig(cpu_env, arg); /* SmartMIPS ASE */
7079 rn = "ContextConfig";
7080 goto cp0_unimplemented;
7081 // break;
7082 case 2:
7083 CP0_CHECK(ctx->ulri);
7084 tcg_gen_st_tl(arg, cpu_env,
7085 offsetof(CPUMIPSState, active_tc.CP0_UserLocal));
7086 rn = "UserLocal";
7087 break;
7088 default:
7089 goto cp0_unimplemented;
7091 break;
7092 case 5:
7093 switch (sel) {
7094 case 0:
7095 gen_helper_mtc0_pagemask(cpu_env, arg);
7096 rn = "PageMask";
7097 break;
7098 case 1:
7099 check_insn(ctx, ISA_MIPS32R2);
7100 gen_helper_mtc0_pagegrain(cpu_env, arg);
7101 rn = "PageGrain";
7102 break;
7103 default:
7104 goto cp0_unimplemented;
7106 break;
7107 case 6:
7108 switch (sel) {
7109 case 0:
7110 gen_helper_mtc0_wired(cpu_env, arg);
7111 rn = "Wired";
7112 break;
7113 case 1:
7114 check_insn(ctx, ISA_MIPS32R2);
7115 gen_helper_mtc0_srsconf0(cpu_env, arg);
7116 rn = "SRSConf0";
7117 break;
7118 case 2:
7119 check_insn(ctx, ISA_MIPS32R2);
7120 gen_helper_mtc0_srsconf1(cpu_env, arg);
7121 rn = "SRSConf1";
7122 break;
7123 case 3:
7124 check_insn(ctx, ISA_MIPS32R2);
7125 gen_helper_mtc0_srsconf2(cpu_env, arg);
7126 rn = "SRSConf2";
7127 break;
7128 case 4:
7129 check_insn(ctx, ISA_MIPS32R2);
7130 gen_helper_mtc0_srsconf3(cpu_env, arg);
7131 rn = "SRSConf3";
7132 break;
7133 case 5:
7134 check_insn(ctx, ISA_MIPS32R2);
7135 gen_helper_mtc0_srsconf4(cpu_env, arg);
7136 rn = "SRSConf4";
7137 break;
7138 default:
7139 goto cp0_unimplemented;
7141 break;
7142 case 7:
7143 switch (sel) {
7144 case 0:
7145 check_insn(ctx, ISA_MIPS32R2);
7146 gen_helper_mtc0_hwrena(cpu_env, arg);
7147 ctx->bstate = BS_STOP;
7148 rn = "HWREna";
7149 break;
7150 default:
7151 goto cp0_unimplemented;
7153 break;
7154 case 8:
7155 switch (sel) {
7156 case 0:
7157 /* ignored */
7158 rn = "BadVAddr";
7159 break;
7160 case 1:
7161 /* ignored */
7162 rn = "BadInstr";
7163 break;
7164 case 2:
7165 /* ignored */
7166 rn = "BadInstrP";
7167 break;
7168 default:
7169 goto cp0_unimplemented;
7171 break;
7172 case 9:
7173 switch (sel) {
7174 case 0:
7175 gen_helper_mtc0_count(cpu_env, arg);
7176 rn = "Count";
7177 break;
7178 /* 6,7 are implementation dependent */
7179 default:
7180 goto cp0_unimplemented;
7182 /* Stop translation as we may have switched the execution mode */
7183 ctx->bstate = BS_STOP;
7184 break;
7185 case 10:
7186 switch (sel) {
7187 case 0:
7188 gen_helper_mtc0_entryhi(cpu_env, arg);
7189 rn = "EntryHi";
7190 break;
7191 default:
7192 goto cp0_unimplemented;
7194 break;
7195 case 11:
7196 switch (sel) {
7197 case 0:
7198 gen_helper_mtc0_compare(cpu_env, arg);
7199 rn = "Compare";
7200 break;
7201 /* 6,7 are implementation dependent */
7202 default:
7203 goto cp0_unimplemented;
7205 /* Stop translation as we may have switched the execution mode */
7206 ctx->bstate = BS_STOP;
7207 break;
7208 case 12:
7209 switch (sel) {
7210 case 0:
7211 save_cpu_state(ctx, 1);
7212 gen_helper_mtc0_status(cpu_env, arg);
7213 /* BS_STOP isn't good enough here, hflags may have changed. */
7214 gen_save_pc(ctx->pc + 4);
7215 ctx->bstate = BS_EXCP;
7216 rn = "Status";
7217 break;
7218 case 1:
7219 check_insn(ctx, ISA_MIPS32R2);
7220 gen_helper_mtc0_intctl(cpu_env, arg);
7221 /* Stop translation as we may have switched the execution mode */
7222 ctx->bstate = BS_STOP;
7223 rn = "IntCtl";
7224 break;
7225 case 2:
7226 check_insn(ctx, ISA_MIPS32R2);
7227 gen_helper_mtc0_srsctl(cpu_env, arg);
7228 /* Stop translation as we may have switched the execution mode */
7229 ctx->bstate = BS_STOP;
7230 rn = "SRSCtl";
7231 break;
7232 case 3:
7233 check_insn(ctx, ISA_MIPS32R2);
7234 gen_mtc0_store32(arg, offsetof(CPUMIPSState, CP0_SRSMap));
7235 /* Stop translation as we may have switched the execution mode */
7236 ctx->bstate = BS_STOP;
7237 rn = "SRSMap";
7238 break;
7239 default:
7240 goto cp0_unimplemented;
7242 break;
7243 case 13:
7244 switch (sel) {
7245 case 0:
7246 save_cpu_state(ctx, 1);
7247 /* Mark as an IO operation because we may trigger a software
7248 interrupt. */
7249 if (ctx->tb->cflags & CF_USE_ICOUNT) {
7250 gen_io_start();
7252 gen_helper_mtc0_cause(cpu_env, arg);
7253 if (ctx->tb->cflags & CF_USE_ICOUNT) {
7254 gen_io_end();
7256 /* Stop translation as we may have triggered an intetrupt */
7257 ctx->bstate = BS_STOP;
7258 rn = "Cause";
7259 break;
7260 default:
7261 goto cp0_unimplemented;
7263 break;
7264 case 14:
7265 switch (sel) {
7266 case 0:
7267 tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EPC));
7268 rn = "EPC";
7269 break;
7270 default:
7271 goto cp0_unimplemented;
7273 break;
7274 case 15:
7275 switch (sel) {
7276 case 0:
7277 /* ignored */
7278 rn = "PRid";
7279 break;
7280 case 1:
7281 check_insn(ctx, ISA_MIPS32R2);
7282 gen_helper_mtc0_ebase(cpu_env, arg);
7283 rn = "EBase";
7284 break;
7285 default:
7286 goto cp0_unimplemented;
7288 break;
7289 case 16:
7290 switch (sel) {
7291 case 0:
7292 gen_helper_mtc0_config0(cpu_env, arg);
7293 rn = "Config";
7294 /* Stop translation as we may have switched the execution mode */
7295 ctx->bstate = BS_STOP;
7296 break;
7297 case 1:
7298 /* ignored, read only */
7299 rn = "Config1";
7300 break;
7301 case 2:
7302 gen_helper_mtc0_config2(cpu_env, arg);
7303 rn = "Config2";
7304 /* Stop translation as we may have switched the execution mode */
7305 ctx->bstate = BS_STOP;
7306 break;
7307 case 3:
7308 gen_helper_mtc0_config3(cpu_env, arg);
7309 rn = "Config3";
7310 /* Stop translation as we may have switched the execution mode */
7311 ctx->bstate = BS_STOP;
7312 break;
7313 case 4:
7314 /* currently ignored */
7315 rn = "Config4";
7316 break;
7317 case 5:
7318 gen_helper_mtc0_config5(cpu_env, arg);
7319 rn = "Config5";
7320 /* Stop translation as we may have switched the execution mode */
7321 ctx->bstate = BS_STOP;
7322 break;
7323 /* 6,7 are implementation dependent */
7324 default:
7325 rn = "Invalid config selector";
7326 goto cp0_unimplemented;
7328 break;
7329 case 17:
7330 switch (sel) {
7331 case 0:
7332 gen_helper_mtc0_lladdr(cpu_env, arg);
7333 rn = "LLAddr";
7334 break;
7335 case 1:
7336 CP0_CHECK(ctx->mrp);
7337 gen_helper_mtc0_maar(cpu_env, arg);
7338 rn = "MAAR";
7339 break;
7340 case 2:
7341 CP0_CHECK(ctx->mrp);
7342 gen_helper_mtc0_maari(cpu_env, arg);
7343 rn = "MAARI";
7344 break;
7345 default:
7346 goto cp0_unimplemented;
7348 break;
7349 case 18:
7350 switch (sel) {
7351 case 0 ... 7:
7352 gen_helper_0e1i(mtc0_watchlo, arg, sel);
7353 rn = "WatchLo";
7354 break;
7355 default:
7356 goto cp0_unimplemented;
7358 break;
7359 case 19:
7360 switch (sel) {
7361 case 0 ... 7:
7362 gen_helper_0e1i(mtc0_watchhi, arg, sel);
7363 rn = "WatchHi";
7364 break;
7365 default:
7366 goto cp0_unimplemented;
7368 break;
7369 case 20:
7370 switch (sel) {
7371 case 0:
7372 check_insn(ctx, ISA_MIPS3);
7373 gen_helper_mtc0_xcontext(cpu_env, arg);
7374 rn = "XContext";
7375 break;
7376 default:
7377 goto cp0_unimplemented;
7379 break;
7380 case 21:
7381 /* Officially reserved, but sel 0 is used for R1x000 framemask */
7382 CP0_CHECK(!(ctx->insn_flags & ISA_MIPS32R6));
7383 switch (sel) {
7384 case 0:
7385 gen_helper_mtc0_framemask(cpu_env, arg);
7386 rn = "Framemask";
7387 break;
7388 default:
7389 goto cp0_unimplemented;
7391 break;
7392 case 22:
7393 /* ignored */
7394 rn = "Diagnostic"; /* implementation dependent */
7395 break;
7396 case 23:
7397 switch (sel) {
7398 case 0:
7399 gen_helper_mtc0_debug(cpu_env, arg); /* EJTAG support */
7400 /* BS_STOP isn't good enough here, hflags may have changed. */
7401 gen_save_pc(ctx->pc + 4);
7402 ctx->bstate = BS_EXCP;
7403 rn = "Debug";
7404 break;
7405 case 1:
7406 // gen_helper_mtc0_tracecontrol(cpu_env, arg); /* PDtrace support */
7407 /* Stop translation as we may have switched the execution mode */
7408 ctx->bstate = BS_STOP;
7409 rn = "TraceControl";
7410 // break;
7411 case 2:
7412 // gen_helper_mtc0_tracecontrol2(cpu_env, arg); /* PDtrace support */
7413 /* Stop translation as we may have switched the execution mode */
7414 ctx->bstate = BS_STOP;
7415 rn = "TraceControl2";
7416 // break;
7417 case 3:
7418 // gen_helper_mtc0_usertracedata(cpu_env, arg); /* PDtrace support */
7419 /* Stop translation as we may have switched the execution mode */
7420 ctx->bstate = BS_STOP;
7421 rn = "UserTraceData";
7422 // break;
7423 case 4:
7424 // gen_helper_mtc0_tracebpc(cpu_env, arg); /* PDtrace support */
7425 /* Stop translation as we may have switched the execution mode */
7426 ctx->bstate = BS_STOP;
7427 rn = "TraceBPC";
7428 // break;
7429 default:
7430 goto cp0_unimplemented;
7432 break;
7433 case 24:
7434 switch (sel) {
7435 case 0:
7436 /* EJTAG support */
7437 tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_DEPC));
7438 rn = "DEPC";
7439 break;
7440 default:
7441 goto cp0_unimplemented;
7443 break;
7444 case 25:
7445 switch (sel) {
7446 case 0:
7447 gen_helper_mtc0_performance0(cpu_env, arg);
7448 rn = "Performance0";
7449 break;
7450 case 1:
7451 // gen_helper_mtc0_performance1(cpu_env, arg);
7452 rn = "Performance1";
7453 // break;
7454 case 2:
7455 // gen_helper_mtc0_performance2(cpu_env, arg);
7456 rn = "Performance2";
7457 // break;
7458 case 3:
7459 // gen_helper_mtc0_performance3(cpu_env, arg);
7460 rn = "Performance3";
7461 // break;
7462 case 4:
7463 // gen_helper_mtc0_performance4(cpu_env, arg);
7464 rn = "Performance4";
7465 // break;
7466 case 5:
7467 // gen_helper_mtc0_performance5(cpu_env, arg);
7468 rn = "Performance5";
7469 // break;
7470 case 6:
7471 // gen_helper_mtc0_performance6(cpu_env, arg);
7472 rn = "Performance6";
7473 // break;
7474 case 7:
7475 // gen_helper_mtc0_performance7(cpu_env, arg);
7476 rn = "Performance7";
7477 // break;
7478 default:
7479 goto cp0_unimplemented;
7481 break;
7482 case 26:
7483 switch (sel) {
7484 case 0:
7485 gen_helper_mtc0_errctl(cpu_env, arg);
7486 ctx->bstate = BS_STOP;
7487 rn = "ErrCtl";
7488 break;
7489 default:
7490 goto cp0_unimplemented;
7492 break;
7493 case 27:
7494 switch (sel) {
7495 case 0 ... 3:
7496 /* ignored */
7497 rn = "CacheErr";
7498 break;
7499 default:
7500 goto cp0_unimplemented;
7502 break;
7503 case 28:
7504 switch (sel) {
7505 case 0:
7506 case 2:
7507 case 4:
7508 case 6:
7509 gen_helper_mtc0_taglo(cpu_env, arg);
7510 rn = "TagLo";
7511 break;
7512 case 1:
7513 case 3:
7514 case 5:
7515 case 7:
7516 gen_helper_mtc0_datalo(cpu_env, arg);
7517 rn = "DataLo";
7518 break;
7519 default:
7520 goto cp0_unimplemented;
7522 break;
7523 case 29:
7524 switch (sel) {
7525 case 0:
7526 case 2:
7527 case 4:
7528 case 6:
7529 gen_helper_mtc0_taghi(cpu_env, arg);
7530 rn = "TagHi";
7531 break;
7532 case 1:
7533 case 3:
7534 case 5:
7535 case 7:
7536 gen_helper_mtc0_datahi(cpu_env, arg);
7537 rn = "DataHi";
7538 break;
7539 default:
7540 rn = "invalid sel";
7541 goto cp0_unimplemented;
7543 break;
7544 case 30:
7545 switch (sel) {
7546 case 0:
7547 tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_ErrorEPC));
7548 rn = "ErrorEPC";
7549 break;
7550 default:
7551 goto cp0_unimplemented;
7553 break;
7554 case 31:
7555 switch (sel) {
7556 case 0:
7557 /* EJTAG support */
7558 gen_mtc0_store32(arg, offsetof(CPUMIPSState, CP0_DESAVE));
7559 rn = "DESAVE";
7560 break;
7561 case 2 ... 7:
7562 CP0_CHECK(ctx->kscrexist & (1 << sel));
7563 tcg_gen_st_tl(arg, cpu_env,
7564 offsetof(CPUMIPSState, CP0_KScratch[sel-2]));
7565 rn = "KScratch";
7566 break;
7567 default:
7568 goto cp0_unimplemented;
7570 /* Stop translation as we may have switched the execution mode */
7571 ctx->bstate = BS_STOP;
7572 break;
7573 default:
7574 goto cp0_unimplemented;
7576 (void)rn; /* avoid a compiler warning */
7577 LOG_DISAS("dmtc0 %s (reg %d sel %d)\n", rn, reg, sel);
7578 /* For simplicity assume that all writes can cause interrupts. */
7579 if (ctx->tb->cflags & CF_USE_ICOUNT) {
7580 gen_io_end();
7581 ctx->bstate = BS_STOP;
7583 return;
7585 cp0_unimplemented:
7586 LOG_DISAS("dmtc0 %s (reg %d sel %d)\n", rn, reg, sel);
7588 #endif /* TARGET_MIPS64 */
7590 static void gen_mftr(CPUMIPSState *env, DisasContext *ctx, int rt, int rd,
7591 int u, int sel, int h)
7593 int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
7594 TCGv t0 = tcg_temp_local_new();
7596 if ((env->CP0_VPEConf0 & (1 << CP0VPEC0_MVP)) == 0 &&
7597 ((env->tcs[other_tc].CP0_TCBind & (0xf << CP0TCBd_CurVPE)) !=
7598 (env->active_tc.CP0_TCBind & (0xf << CP0TCBd_CurVPE))))
7599 tcg_gen_movi_tl(t0, -1);
7600 else if ((env->CP0_VPEControl & (0xff << CP0VPECo_TargTC)) >
7601 (env->mvp->CP0_MVPConf0 & (0xff << CP0MVPC0_PTC)))
7602 tcg_gen_movi_tl(t0, -1);
7603 else if (u == 0) {
7604 switch (rt) {
7605 case 1:
7606 switch (sel) {
7607 case 1:
7608 gen_helper_mftc0_vpecontrol(t0, cpu_env);
7609 break;
7610 case 2:
7611 gen_helper_mftc0_vpeconf0(t0, cpu_env);
7612 break;
7613 default:
7614 goto die;
7615 break;
7617 break;
7618 case 2:
7619 switch (sel) {
7620 case 1:
7621 gen_helper_mftc0_tcstatus(t0, cpu_env);
7622 break;
7623 case 2:
7624 gen_helper_mftc0_tcbind(t0, cpu_env);
7625 break;
7626 case 3:
7627 gen_helper_mftc0_tcrestart(t0, cpu_env);
7628 break;
7629 case 4:
7630 gen_helper_mftc0_tchalt(t0, cpu_env);
7631 break;
7632 case 5:
7633 gen_helper_mftc0_tccontext(t0, cpu_env);
7634 break;
7635 case 6:
7636 gen_helper_mftc0_tcschedule(t0, cpu_env);
7637 break;
7638 case 7:
7639 gen_helper_mftc0_tcschefback(t0, cpu_env);
7640 break;
7641 default:
7642 gen_mfc0(ctx, t0, rt, sel);
7643 break;
7645 break;
7646 case 10:
7647 switch (sel) {
7648 case 0:
7649 gen_helper_mftc0_entryhi(t0, cpu_env);
7650 break;
7651 default:
7652 gen_mfc0(ctx, t0, rt, sel);
7653 break;
7655 case 12:
7656 switch (sel) {
7657 case 0:
7658 gen_helper_mftc0_status(t0, cpu_env);
7659 break;
7660 default:
7661 gen_mfc0(ctx, t0, rt, sel);
7662 break;
7664 case 13:
7665 switch (sel) {
7666 case 0:
7667 gen_helper_mftc0_cause(t0, cpu_env);
7668 break;
7669 default:
7670 goto die;
7671 break;
7673 break;
7674 case 14:
7675 switch (sel) {
7676 case 0:
7677 gen_helper_mftc0_epc(t0, cpu_env);
7678 break;
7679 default:
7680 goto die;
7681 break;
7683 break;
7684 case 15:
7685 switch (sel) {
7686 case 1:
7687 gen_helper_mftc0_ebase(t0, cpu_env);
7688 break;
7689 default:
7690 goto die;
7691 break;
7693 break;
7694 case 16:
7695 switch (sel) {
7696 case 0 ... 7:
7697 gen_helper_mftc0_configx(t0, cpu_env, tcg_const_tl(sel));
7698 break;
7699 default:
7700 goto die;
7701 break;
7703 break;
7704 case 23:
7705 switch (sel) {
7706 case 0:
7707 gen_helper_mftc0_debug(t0, cpu_env);
7708 break;
7709 default:
7710 gen_mfc0(ctx, t0, rt, sel);
7711 break;
7713 break;
7714 default:
7715 gen_mfc0(ctx, t0, rt, sel);
7717 } else switch (sel) {
7718 /* GPR registers. */
7719 case 0:
7720 gen_helper_1e0i(mftgpr, t0, rt);
7721 break;
7722 /* Auxiliary CPU registers */
7723 case 1:
7724 switch (rt) {
7725 case 0:
7726 gen_helper_1e0i(mftlo, t0, 0);
7727 break;
7728 case 1:
7729 gen_helper_1e0i(mfthi, t0, 0);
7730 break;
7731 case 2:
7732 gen_helper_1e0i(mftacx, t0, 0);
7733 break;
7734 case 4:
7735 gen_helper_1e0i(mftlo, t0, 1);
7736 break;
7737 case 5:
7738 gen_helper_1e0i(mfthi, t0, 1);
7739 break;
7740 case 6:
7741 gen_helper_1e0i(mftacx, t0, 1);
7742 break;
7743 case 8:
7744 gen_helper_1e0i(mftlo, t0, 2);
7745 break;
7746 case 9:
7747 gen_helper_1e0i(mfthi, t0, 2);
7748 break;
7749 case 10:
7750 gen_helper_1e0i(mftacx, t0, 2);
7751 break;
7752 case 12:
7753 gen_helper_1e0i(mftlo, t0, 3);
7754 break;
7755 case 13:
7756 gen_helper_1e0i(mfthi, t0, 3);
7757 break;
7758 case 14:
7759 gen_helper_1e0i(mftacx, t0, 3);
7760 break;
7761 case 16:
7762 gen_helper_mftdsp(t0, cpu_env);
7763 break;
7764 default:
7765 goto die;
7767 break;
7768 /* Floating point (COP1). */
7769 case 2:
7770 /* XXX: For now we support only a single FPU context. */
7771 if (h == 0) {
7772 TCGv_i32 fp0 = tcg_temp_new_i32();
7774 gen_load_fpr32(ctx, fp0, rt);
7775 tcg_gen_ext_i32_tl(t0, fp0);
7776 tcg_temp_free_i32(fp0);
7777 } else {
7778 TCGv_i32 fp0 = tcg_temp_new_i32();
7780 gen_load_fpr32h(ctx, fp0, rt);
7781 tcg_gen_ext_i32_tl(t0, fp0);
7782 tcg_temp_free_i32(fp0);
7784 break;
7785 case 3:
7786 /* XXX: For now we support only a single FPU context. */
7787 gen_helper_1e0i(cfc1, t0, rt);
7788 break;
7789 /* COP2: Not implemented. */
7790 case 4:
7791 case 5:
7792 /* fall through */
7793 default:
7794 goto die;
7796 LOG_DISAS("mftr (reg %d u %d sel %d h %d)\n", rt, u, sel, h);
7797 gen_store_gpr(t0, rd);
7798 tcg_temp_free(t0);
7799 return;
7801 die:
7802 tcg_temp_free(t0);
7803 LOG_DISAS("mftr (reg %d u %d sel %d h %d)\n", rt, u, sel, h);
7804 generate_exception_end(ctx, EXCP_RI);
7807 static void gen_mttr(CPUMIPSState *env, DisasContext *ctx, int rd, int rt,
7808 int u, int sel, int h)
7810 int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
7811 TCGv t0 = tcg_temp_local_new();
7813 gen_load_gpr(t0, rt);
7814 if ((env->CP0_VPEConf0 & (1 << CP0VPEC0_MVP)) == 0 &&
7815 ((env->tcs[other_tc].CP0_TCBind & (0xf << CP0TCBd_CurVPE)) !=
7816 (env->active_tc.CP0_TCBind & (0xf << CP0TCBd_CurVPE))))
7817 /* NOP */ ;
7818 else if ((env->CP0_VPEControl & (0xff << CP0VPECo_TargTC)) >
7819 (env->mvp->CP0_MVPConf0 & (0xff << CP0MVPC0_PTC)))
7820 /* NOP */ ;
7821 else if (u == 0) {
7822 switch (rd) {
7823 case 1:
7824 switch (sel) {
7825 case 1:
7826 gen_helper_mttc0_vpecontrol(cpu_env, t0);
7827 break;
7828 case 2:
7829 gen_helper_mttc0_vpeconf0(cpu_env, t0);
7830 break;
7831 default:
7832 goto die;
7833 break;
7835 break;
7836 case 2:
7837 switch (sel) {
7838 case 1:
7839 gen_helper_mttc0_tcstatus(cpu_env, t0);
7840 break;
7841 case 2:
7842 gen_helper_mttc0_tcbind(cpu_env, t0);
7843 break;
7844 case 3:
7845 gen_helper_mttc0_tcrestart(cpu_env, t0);
7846 break;
7847 case 4:
7848 gen_helper_mttc0_tchalt(cpu_env, t0);
7849 break;
7850 case 5:
7851 gen_helper_mttc0_tccontext(cpu_env, t0);
7852 break;
7853 case 6:
7854 gen_helper_mttc0_tcschedule(cpu_env, t0);
7855 break;
7856 case 7:
7857 gen_helper_mttc0_tcschefback(cpu_env, t0);
7858 break;
7859 default:
7860 gen_mtc0(ctx, t0, rd, sel);
7861 break;
7863 break;
7864 case 10:
7865 switch (sel) {
7866 case 0:
7867 gen_helper_mttc0_entryhi(cpu_env, t0);
7868 break;
7869 default:
7870 gen_mtc0(ctx, t0, rd, sel);
7871 break;
7873 case 12:
7874 switch (sel) {
7875 case 0:
7876 gen_helper_mttc0_status(cpu_env, t0);
7877 break;
7878 default:
7879 gen_mtc0(ctx, t0, rd, sel);
7880 break;
7882 case 13:
7883 switch (sel) {
7884 case 0:
7885 gen_helper_mttc0_cause(cpu_env, t0);
7886 break;
7887 default:
7888 goto die;
7889 break;
7891 break;
7892 case 15:
7893 switch (sel) {
7894 case 1:
7895 gen_helper_mttc0_ebase(cpu_env, t0);
7896 break;
7897 default:
7898 goto die;
7899 break;
7901 break;
7902 case 23:
7903 switch (sel) {
7904 case 0:
7905 gen_helper_mttc0_debug(cpu_env, t0);
7906 break;
7907 default:
7908 gen_mtc0(ctx, t0, rd, sel);
7909 break;
7911 break;
7912 default:
7913 gen_mtc0(ctx, t0, rd, sel);
7915 } else switch (sel) {
7916 /* GPR registers. */
7917 case 0:
7918 gen_helper_0e1i(mttgpr, t0, rd);
7919 break;
7920 /* Auxiliary CPU registers */
7921 case 1:
7922 switch (rd) {
7923 case 0:
7924 gen_helper_0e1i(mttlo, t0, 0);
7925 break;
7926 case 1:
7927 gen_helper_0e1i(mtthi, t0, 0);
7928 break;
7929 case 2:
7930 gen_helper_0e1i(mttacx, t0, 0);
7931 break;
7932 case 4:
7933 gen_helper_0e1i(mttlo, t0, 1);
7934 break;
7935 case 5:
7936 gen_helper_0e1i(mtthi, t0, 1);
7937 break;
7938 case 6:
7939 gen_helper_0e1i(mttacx, t0, 1);
7940 break;
7941 case 8:
7942 gen_helper_0e1i(mttlo, t0, 2);
7943 break;
7944 case 9:
7945 gen_helper_0e1i(mtthi, t0, 2);
7946 break;
7947 case 10:
7948 gen_helper_0e1i(mttacx, t0, 2);
7949 break;
7950 case 12:
7951 gen_helper_0e1i(mttlo, t0, 3);
7952 break;
7953 case 13:
7954 gen_helper_0e1i(mtthi, t0, 3);
7955 break;
7956 case 14:
7957 gen_helper_0e1i(mttacx, t0, 3);
7958 break;
7959 case 16:
7960 gen_helper_mttdsp(cpu_env, t0);
7961 break;
7962 default:
7963 goto die;
7965 break;
7966 /* Floating point (COP1). */
7967 case 2:
7968 /* XXX: For now we support only a single FPU context. */
7969 if (h == 0) {
7970 TCGv_i32 fp0 = tcg_temp_new_i32();
7972 tcg_gen_trunc_tl_i32(fp0, t0);
7973 gen_store_fpr32(ctx, fp0, rd);
7974 tcg_temp_free_i32(fp0);
7975 } else {
7976 TCGv_i32 fp0 = tcg_temp_new_i32();
7978 tcg_gen_trunc_tl_i32(fp0, t0);
7979 gen_store_fpr32h(ctx, fp0, rd);
7980 tcg_temp_free_i32(fp0);
7982 break;
7983 case 3:
7984 /* XXX: For now we support only a single FPU context. */
7986 TCGv_i32 fs_tmp = tcg_const_i32(rd);
7988 gen_helper_0e2i(ctc1, t0, fs_tmp, rt);
7989 tcg_temp_free_i32(fs_tmp);
7991 /* Stop translation as we may have changed hflags */
7992 ctx->bstate = BS_STOP;
7993 break;
7994 /* COP2: Not implemented. */
7995 case 4:
7996 case 5:
7997 /* fall through */
7998 default:
7999 goto die;
8001 LOG_DISAS("mttr (reg %d u %d sel %d h %d)\n", rd, u, sel, h);
8002 tcg_temp_free(t0);
8003 return;
8005 die:
8006 tcg_temp_free(t0);
8007 LOG_DISAS("mttr (reg %d u %d sel %d h %d)\n", rd, u, sel, h);
8008 generate_exception_end(ctx, EXCP_RI);
8011 static void gen_cp0 (CPUMIPSState *env, DisasContext *ctx, uint32_t opc, int rt, int rd)
8013 const char *opn = "ldst";
8015 check_cp0_enabled(ctx);
8016 switch (opc) {
8017 case OPC_MFC0:
8018 if (rt == 0) {
8019 /* Treat as NOP. */
8020 return;
8022 gen_mfc0(ctx, cpu_gpr[rt], rd, ctx->opcode & 0x7);
8023 opn = "mfc0";
8024 break;
8025 case OPC_MTC0:
8027 TCGv t0 = tcg_temp_new();
8029 gen_load_gpr(t0, rt);
8030 gen_mtc0(ctx, t0, rd, ctx->opcode & 0x7);
8031 tcg_temp_free(t0);
8033 opn = "mtc0";
8034 break;
8035 #if defined(TARGET_MIPS64)
8036 case OPC_DMFC0:
8037 check_insn(ctx, ISA_MIPS3);
8038 if (rt == 0) {
8039 /* Treat as NOP. */
8040 return;
8042 gen_dmfc0(ctx, cpu_gpr[rt], rd, ctx->opcode & 0x7);
8043 opn = "dmfc0";
8044 break;
8045 case OPC_DMTC0:
8046 check_insn(ctx, ISA_MIPS3);
8048 TCGv t0 = tcg_temp_new();
8050 gen_load_gpr(t0, rt);
8051 gen_dmtc0(ctx, t0, rd, ctx->opcode & 0x7);
8052 tcg_temp_free(t0);
8054 opn = "dmtc0";
8055 break;
8056 #endif
8057 case OPC_MFHC0:
8058 check_mvh(ctx);
8059 if (rt == 0) {
8060 /* Treat as NOP. */
8061 return;
8063 gen_mfhc0(ctx, cpu_gpr[rt], rd, ctx->opcode & 0x7);
8064 opn = "mfhc0";
8065 break;
8066 case OPC_MTHC0:
8067 check_mvh(ctx);
8069 TCGv t0 = tcg_temp_new();
8070 gen_load_gpr(t0, rt);
8071 gen_mthc0(ctx, t0, rd, ctx->opcode & 0x7);
8072 tcg_temp_free(t0);
8074 opn = "mthc0";
8075 break;
8076 case OPC_MFTR:
8077 check_insn(ctx, ASE_MT);
8078 if (rd == 0) {
8079 /* Treat as NOP. */
8080 return;
8082 gen_mftr(env, ctx, rt, rd, (ctx->opcode >> 5) & 1,
8083 ctx->opcode & 0x7, (ctx->opcode >> 4) & 1);
8084 opn = "mftr";
8085 break;
8086 case OPC_MTTR:
8087 check_insn(ctx, ASE_MT);
8088 gen_mttr(env, ctx, rd, rt, (ctx->opcode >> 5) & 1,
8089 ctx->opcode & 0x7, (ctx->opcode >> 4) & 1);
8090 opn = "mttr";
8091 break;
8092 case OPC_TLBWI:
8093 opn = "tlbwi";
8094 if (!env->tlb->helper_tlbwi)
8095 goto die;
8096 gen_helper_tlbwi(cpu_env);
8097 break;
8098 case OPC_TLBINV:
8099 opn = "tlbinv";
8100 if (ctx->ie >= 2) {
8101 if (!env->tlb->helper_tlbinv) {
8102 goto die;
8104 gen_helper_tlbinv(cpu_env);
8105 } /* treat as nop if TLBINV not supported */
8106 break;
8107 case OPC_TLBINVF:
8108 opn = "tlbinvf";
8109 if (ctx->ie >= 2) {
8110 if (!env->tlb->helper_tlbinvf) {
8111 goto die;
8113 gen_helper_tlbinvf(cpu_env);
8114 } /* treat as nop if TLBINV not supported */
8115 break;
8116 case OPC_TLBWR:
8117 opn = "tlbwr";
8118 if (!env->tlb->helper_tlbwr)
8119 goto die;
8120 gen_helper_tlbwr(cpu_env);
8121 break;
8122 case OPC_TLBP:
8123 opn = "tlbp";
8124 if (!env->tlb->helper_tlbp)
8125 goto die;
8126 gen_helper_tlbp(cpu_env);
8127 break;
8128 case OPC_TLBR:
8129 opn = "tlbr";
8130 if (!env->tlb->helper_tlbr)
8131 goto die;
8132 gen_helper_tlbr(cpu_env);
8133 break;
8134 case OPC_ERET: /* OPC_ERETNC */
8135 if ((ctx->insn_flags & ISA_MIPS32R6) &&
8136 (ctx->hflags & MIPS_HFLAG_BMASK)) {
8137 goto die;
8138 } else {
8139 int bit_shift = (ctx->hflags & MIPS_HFLAG_M16) ? 16 : 6;
8140 if (ctx->opcode & (1 << bit_shift)) {
8141 /* OPC_ERETNC */
8142 opn = "eretnc";
8143 check_insn(ctx, ISA_MIPS32R5);
8144 gen_helper_eretnc(cpu_env);
8145 } else {
8146 /* OPC_ERET */
8147 opn = "eret";
8148 check_insn(ctx, ISA_MIPS2);
8149 gen_helper_eret(cpu_env);
8151 ctx->bstate = BS_EXCP;
8153 break;
8154 case OPC_DERET:
8155 opn = "deret";
8156 check_insn(ctx, ISA_MIPS32);
8157 if ((ctx->insn_flags & ISA_MIPS32R6) &&
8158 (ctx->hflags & MIPS_HFLAG_BMASK)) {
8159 goto die;
8161 if (!(ctx->hflags & MIPS_HFLAG_DM)) {
8162 MIPS_INVAL(opn);
8163 generate_exception_end(ctx, EXCP_RI);
8164 } else {
8165 gen_helper_deret(cpu_env);
8166 ctx->bstate = BS_EXCP;
8168 break;
8169 case OPC_WAIT:
8170 opn = "wait";
8171 check_insn(ctx, ISA_MIPS3 | ISA_MIPS32);
8172 if ((ctx->insn_flags & ISA_MIPS32R6) &&
8173 (ctx->hflags & MIPS_HFLAG_BMASK)) {
8174 goto die;
8176 /* If we get an exception, we want to restart at next instruction */
8177 ctx->pc += 4;
8178 save_cpu_state(ctx, 1);
8179 ctx->pc -= 4;
8180 gen_helper_wait(cpu_env);
8181 ctx->bstate = BS_EXCP;
8182 break;
8183 default:
8184 die:
8185 MIPS_INVAL(opn);
8186 generate_exception_end(ctx, EXCP_RI);
8187 return;
8189 (void)opn; /* avoid a compiler warning */
8191 #endif /* !CONFIG_USER_ONLY */
8193 /* CP1 Branches (before delay slot) */
8194 static void gen_compute_branch1(DisasContext *ctx, uint32_t op,
8195 int32_t cc, int32_t offset)
8197 target_ulong btarget;
8198 TCGv_i32 t0 = tcg_temp_new_i32();
8200 if ((ctx->insn_flags & ISA_MIPS32R6) && (ctx->hflags & MIPS_HFLAG_BMASK)) {
8201 generate_exception_end(ctx, EXCP_RI);
8202 goto out;
8205 if (cc != 0)
8206 check_insn(ctx, ISA_MIPS4 | ISA_MIPS32);
8208 btarget = ctx->pc + 4 + offset;
8210 switch (op) {
8211 case OPC_BC1F:
8212 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
8213 tcg_gen_not_i32(t0, t0);
8214 tcg_gen_andi_i32(t0, t0, 1);
8215 tcg_gen_extu_i32_tl(bcond, t0);
8216 goto not_likely;
8217 case OPC_BC1FL:
8218 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
8219 tcg_gen_not_i32(t0, t0);
8220 tcg_gen_andi_i32(t0, t0, 1);
8221 tcg_gen_extu_i32_tl(bcond, t0);
8222 goto likely;
8223 case OPC_BC1T:
8224 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
8225 tcg_gen_andi_i32(t0, t0, 1);
8226 tcg_gen_extu_i32_tl(bcond, t0);
8227 goto not_likely;
8228 case OPC_BC1TL:
8229 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
8230 tcg_gen_andi_i32(t0, t0, 1);
8231 tcg_gen_extu_i32_tl(bcond, t0);
8232 likely:
8233 ctx->hflags |= MIPS_HFLAG_BL;
8234 break;
8235 case OPC_BC1FANY2:
8237 TCGv_i32 t1 = tcg_temp_new_i32();
8238 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
8239 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+1));
8240 tcg_gen_nand_i32(t0, t0, t1);
8241 tcg_temp_free_i32(t1);
8242 tcg_gen_andi_i32(t0, t0, 1);
8243 tcg_gen_extu_i32_tl(bcond, t0);
8245 goto not_likely;
8246 case OPC_BC1TANY2:
8248 TCGv_i32 t1 = tcg_temp_new_i32();
8249 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
8250 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+1));
8251 tcg_gen_or_i32(t0, t0, t1);
8252 tcg_temp_free_i32(t1);
8253 tcg_gen_andi_i32(t0, t0, 1);
8254 tcg_gen_extu_i32_tl(bcond, t0);
8256 goto not_likely;
8257 case OPC_BC1FANY4:
8259 TCGv_i32 t1 = tcg_temp_new_i32();
8260 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
8261 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+1));
8262 tcg_gen_and_i32(t0, t0, t1);
8263 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+2));
8264 tcg_gen_and_i32(t0, t0, t1);
8265 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+3));
8266 tcg_gen_nand_i32(t0, t0, t1);
8267 tcg_temp_free_i32(t1);
8268 tcg_gen_andi_i32(t0, t0, 1);
8269 tcg_gen_extu_i32_tl(bcond, t0);
8271 goto not_likely;
8272 case OPC_BC1TANY4:
8274 TCGv_i32 t1 = tcg_temp_new_i32();
8275 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
8276 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+1));
8277 tcg_gen_or_i32(t0, t0, t1);
8278 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+2));
8279 tcg_gen_or_i32(t0, t0, t1);
8280 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+3));
8281 tcg_gen_or_i32(t0, t0, t1);
8282 tcg_temp_free_i32(t1);
8283 tcg_gen_andi_i32(t0, t0, 1);
8284 tcg_gen_extu_i32_tl(bcond, t0);
8286 not_likely:
8287 ctx->hflags |= MIPS_HFLAG_BC;
8288 break;
8289 default:
8290 MIPS_INVAL("cp1 cond branch");
8291 generate_exception_end(ctx, EXCP_RI);
8292 goto out;
8294 ctx->btarget = btarget;
8295 ctx->hflags |= MIPS_HFLAG_BDS32;
8296 out:
8297 tcg_temp_free_i32(t0);
8300 /* R6 CP1 Branches */
8301 static void gen_compute_branch1_r6(DisasContext *ctx, uint32_t op,
8302 int32_t ft, int32_t offset,
8303 int delayslot_size)
8305 target_ulong btarget;
8306 TCGv_i64 t0 = tcg_temp_new_i64();
8308 if (ctx->hflags & MIPS_HFLAG_BMASK) {
8309 #ifdef MIPS_DEBUG_DISAS
8310 LOG_DISAS("Branch in delay / forbidden slot at PC 0x" TARGET_FMT_lx
8311 "\n", ctx->pc);
8312 #endif
8313 generate_exception_end(ctx, EXCP_RI);
8314 goto out;
8317 gen_load_fpr64(ctx, t0, ft);
8318 tcg_gen_andi_i64(t0, t0, 1);
8320 btarget = addr_add(ctx, ctx->pc + 4, offset);
8322 switch (op) {
8323 case OPC_BC1EQZ:
8324 tcg_gen_xori_i64(t0, t0, 1);
8325 ctx->hflags |= MIPS_HFLAG_BC;
8326 break;
8327 case OPC_BC1NEZ:
8328 /* t0 already set */
8329 ctx->hflags |= MIPS_HFLAG_BC;
8330 break;
8331 default:
8332 MIPS_INVAL("cp1 cond branch");
8333 generate_exception_end(ctx, EXCP_RI);
8334 goto out;
8337 tcg_gen_trunc_i64_tl(bcond, t0);
8339 ctx->btarget = btarget;
8341 switch (delayslot_size) {
8342 case 2:
8343 ctx->hflags |= MIPS_HFLAG_BDS16;
8344 break;
8345 case 4:
8346 ctx->hflags |= MIPS_HFLAG_BDS32;
8347 break;
8350 out:
8351 tcg_temp_free_i64(t0);
8354 /* Coprocessor 1 (FPU) */
8356 #define FOP(func, fmt) (((fmt) << 21) | (func))
8358 enum fopcode {
8359 OPC_ADD_S = FOP(0, FMT_S),
8360 OPC_SUB_S = FOP(1, FMT_S),
8361 OPC_MUL_S = FOP(2, FMT_S),
8362 OPC_DIV_S = FOP(3, FMT_S),
8363 OPC_SQRT_S = FOP(4, FMT_S),
8364 OPC_ABS_S = FOP(5, FMT_S),
8365 OPC_MOV_S = FOP(6, FMT_S),
8366 OPC_NEG_S = FOP(7, FMT_S),
8367 OPC_ROUND_L_S = FOP(8, FMT_S),
8368 OPC_TRUNC_L_S = FOP(9, FMT_S),
8369 OPC_CEIL_L_S = FOP(10, FMT_S),
8370 OPC_FLOOR_L_S = FOP(11, FMT_S),
8371 OPC_ROUND_W_S = FOP(12, FMT_S),
8372 OPC_TRUNC_W_S = FOP(13, FMT_S),
8373 OPC_CEIL_W_S = FOP(14, FMT_S),
8374 OPC_FLOOR_W_S = FOP(15, FMT_S),
8375 OPC_SEL_S = FOP(16, FMT_S),
8376 OPC_MOVCF_S = FOP(17, FMT_S),
8377 OPC_MOVZ_S = FOP(18, FMT_S),
8378 OPC_MOVN_S = FOP(19, FMT_S),
8379 OPC_SELEQZ_S = FOP(20, FMT_S),
8380 OPC_RECIP_S = FOP(21, FMT_S),
8381 OPC_RSQRT_S = FOP(22, FMT_S),
8382 OPC_SELNEZ_S = FOP(23, FMT_S),
8383 OPC_MADDF_S = FOP(24, FMT_S),
8384 OPC_MSUBF_S = FOP(25, FMT_S),
8385 OPC_RINT_S = FOP(26, FMT_S),
8386 OPC_CLASS_S = FOP(27, FMT_S),
8387 OPC_MIN_S = FOP(28, FMT_S),
8388 OPC_RECIP2_S = FOP(28, FMT_S),
8389 OPC_MINA_S = FOP(29, FMT_S),
8390 OPC_RECIP1_S = FOP(29, FMT_S),
8391 OPC_MAX_S = FOP(30, FMT_S),
8392 OPC_RSQRT1_S = FOP(30, FMT_S),
8393 OPC_MAXA_S = FOP(31, FMT_S),
8394 OPC_RSQRT2_S = FOP(31, FMT_S),
8395 OPC_CVT_D_S = FOP(33, FMT_S),
8396 OPC_CVT_W_S = FOP(36, FMT_S),
8397 OPC_CVT_L_S = FOP(37, FMT_S),
8398 OPC_CVT_PS_S = FOP(38, FMT_S),
8399 OPC_CMP_F_S = FOP (48, FMT_S),
8400 OPC_CMP_UN_S = FOP (49, FMT_S),
8401 OPC_CMP_EQ_S = FOP (50, FMT_S),
8402 OPC_CMP_UEQ_S = FOP (51, FMT_S),
8403 OPC_CMP_OLT_S = FOP (52, FMT_S),
8404 OPC_CMP_ULT_S = FOP (53, FMT_S),
8405 OPC_CMP_OLE_S = FOP (54, FMT_S),
8406 OPC_CMP_ULE_S = FOP (55, FMT_S),
8407 OPC_CMP_SF_S = FOP (56, FMT_S),
8408 OPC_CMP_NGLE_S = FOP (57, FMT_S),
8409 OPC_CMP_SEQ_S = FOP (58, FMT_S),
8410 OPC_CMP_NGL_S = FOP (59, FMT_S),
8411 OPC_CMP_LT_S = FOP (60, FMT_S),
8412 OPC_CMP_NGE_S = FOP (61, FMT_S),
8413 OPC_CMP_LE_S = FOP (62, FMT_S),
8414 OPC_CMP_NGT_S = FOP (63, FMT_S),
8416 OPC_ADD_D = FOP(0, FMT_D),
8417 OPC_SUB_D = FOP(1, FMT_D),
8418 OPC_MUL_D = FOP(2, FMT_D),
8419 OPC_DIV_D = FOP(3, FMT_D),
8420 OPC_SQRT_D = FOP(4, FMT_D),
8421 OPC_ABS_D = FOP(5, FMT_D),
8422 OPC_MOV_D = FOP(6, FMT_D),
8423 OPC_NEG_D = FOP(7, FMT_D),
8424 OPC_ROUND_L_D = FOP(8, FMT_D),
8425 OPC_TRUNC_L_D = FOP(9, FMT_D),
8426 OPC_CEIL_L_D = FOP(10, FMT_D),
8427 OPC_FLOOR_L_D = FOP(11, FMT_D),
8428 OPC_ROUND_W_D = FOP(12, FMT_D),
8429 OPC_TRUNC_W_D = FOP(13, FMT_D),
8430 OPC_CEIL_W_D = FOP(14, FMT_D),
8431 OPC_FLOOR_W_D = FOP(15, FMT_D),
8432 OPC_SEL_D = FOP(16, FMT_D),
8433 OPC_MOVCF_D = FOP(17, FMT_D),
8434 OPC_MOVZ_D = FOP(18, FMT_D),
8435 OPC_MOVN_D = FOP(19, FMT_D),
8436 OPC_SELEQZ_D = FOP(20, FMT_D),
8437 OPC_RECIP_D = FOP(21, FMT_D),
8438 OPC_RSQRT_D = FOP(22, FMT_D),
8439 OPC_SELNEZ_D = FOP(23, FMT_D),
8440 OPC_MADDF_D = FOP(24, FMT_D),
8441 OPC_MSUBF_D = FOP(25, FMT_D),
8442 OPC_RINT_D = FOP(26, FMT_D),
8443 OPC_CLASS_D = FOP(27, FMT_D),
8444 OPC_MIN_D = FOP(28, FMT_D),
8445 OPC_RECIP2_D = FOP(28, FMT_D),
8446 OPC_MINA_D = FOP(29, FMT_D),
8447 OPC_RECIP1_D = FOP(29, FMT_D),
8448 OPC_MAX_D = FOP(30, FMT_D),
8449 OPC_RSQRT1_D = FOP(30, FMT_D),
8450 OPC_MAXA_D = FOP(31, FMT_D),
8451 OPC_RSQRT2_D = FOP(31, FMT_D),
8452 OPC_CVT_S_D = FOP(32, FMT_D),
8453 OPC_CVT_W_D = FOP(36, FMT_D),
8454 OPC_CVT_L_D = FOP(37, FMT_D),
8455 OPC_CMP_F_D = FOP (48, FMT_D),
8456 OPC_CMP_UN_D = FOP (49, FMT_D),
8457 OPC_CMP_EQ_D = FOP (50, FMT_D),
8458 OPC_CMP_UEQ_D = FOP (51, FMT_D),
8459 OPC_CMP_OLT_D = FOP (52, FMT_D),
8460 OPC_CMP_ULT_D = FOP (53, FMT_D),
8461 OPC_CMP_OLE_D = FOP (54, FMT_D),
8462 OPC_CMP_ULE_D = FOP (55, FMT_D),
8463 OPC_CMP_SF_D = FOP (56, FMT_D),
8464 OPC_CMP_NGLE_D = FOP (57, FMT_D),
8465 OPC_CMP_SEQ_D = FOP (58, FMT_D),
8466 OPC_CMP_NGL_D = FOP (59, FMT_D),
8467 OPC_CMP_LT_D = FOP (60, FMT_D),
8468 OPC_CMP_NGE_D = FOP (61, FMT_D),
8469 OPC_CMP_LE_D = FOP (62, FMT_D),
8470 OPC_CMP_NGT_D = FOP (63, FMT_D),
8472 OPC_CVT_S_W = FOP(32, FMT_W),
8473 OPC_CVT_D_W = FOP(33, FMT_W),
8474 OPC_CVT_S_L = FOP(32, FMT_L),
8475 OPC_CVT_D_L = FOP(33, FMT_L),
8476 OPC_CVT_PS_PW = FOP(38, FMT_W),
8478 OPC_ADD_PS = FOP(0, FMT_PS),
8479 OPC_SUB_PS = FOP(1, FMT_PS),
8480 OPC_MUL_PS = FOP(2, FMT_PS),
8481 OPC_DIV_PS = FOP(3, FMT_PS),
8482 OPC_ABS_PS = FOP(5, FMT_PS),
8483 OPC_MOV_PS = FOP(6, FMT_PS),
8484 OPC_NEG_PS = FOP(7, FMT_PS),
8485 OPC_MOVCF_PS = FOP(17, FMT_PS),
8486 OPC_MOVZ_PS = FOP(18, FMT_PS),
8487 OPC_MOVN_PS = FOP(19, FMT_PS),
8488 OPC_ADDR_PS = FOP(24, FMT_PS),
8489 OPC_MULR_PS = FOP(26, FMT_PS),
8490 OPC_RECIP2_PS = FOP(28, FMT_PS),
8491 OPC_RECIP1_PS = FOP(29, FMT_PS),
8492 OPC_RSQRT1_PS = FOP(30, FMT_PS),
8493 OPC_RSQRT2_PS = FOP(31, FMT_PS),
8495 OPC_CVT_S_PU = FOP(32, FMT_PS),
8496 OPC_CVT_PW_PS = FOP(36, FMT_PS),
8497 OPC_CVT_S_PL = FOP(40, FMT_PS),
8498 OPC_PLL_PS = FOP(44, FMT_PS),
8499 OPC_PLU_PS = FOP(45, FMT_PS),
8500 OPC_PUL_PS = FOP(46, FMT_PS),
8501 OPC_PUU_PS = FOP(47, FMT_PS),
8502 OPC_CMP_F_PS = FOP (48, FMT_PS),
8503 OPC_CMP_UN_PS = FOP (49, FMT_PS),
8504 OPC_CMP_EQ_PS = FOP (50, FMT_PS),
8505 OPC_CMP_UEQ_PS = FOP (51, FMT_PS),
8506 OPC_CMP_OLT_PS = FOP (52, FMT_PS),
8507 OPC_CMP_ULT_PS = FOP (53, FMT_PS),
8508 OPC_CMP_OLE_PS = FOP (54, FMT_PS),
8509 OPC_CMP_ULE_PS = FOP (55, FMT_PS),
8510 OPC_CMP_SF_PS = FOP (56, FMT_PS),
8511 OPC_CMP_NGLE_PS = FOP (57, FMT_PS),
8512 OPC_CMP_SEQ_PS = FOP (58, FMT_PS),
8513 OPC_CMP_NGL_PS = FOP (59, FMT_PS),
8514 OPC_CMP_LT_PS = FOP (60, FMT_PS),
8515 OPC_CMP_NGE_PS = FOP (61, FMT_PS),
8516 OPC_CMP_LE_PS = FOP (62, FMT_PS),
8517 OPC_CMP_NGT_PS = FOP (63, FMT_PS),
8520 enum r6_f_cmp_op {
8521 R6_OPC_CMP_AF_S = FOP(0, FMT_W),
8522 R6_OPC_CMP_UN_S = FOP(1, FMT_W),
8523 R6_OPC_CMP_EQ_S = FOP(2, FMT_W),
8524 R6_OPC_CMP_UEQ_S = FOP(3, FMT_W),
8525 R6_OPC_CMP_LT_S = FOP(4, FMT_W),
8526 R6_OPC_CMP_ULT_S = FOP(5, FMT_W),
8527 R6_OPC_CMP_LE_S = FOP(6, FMT_W),
8528 R6_OPC_CMP_ULE_S = FOP(7, FMT_W),
8529 R6_OPC_CMP_SAF_S = FOP(8, FMT_W),
8530 R6_OPC_CMP_SUN_S = FOP(9, FMT_W),
8531 R6_OPC_CMP_SEQ_S = FOP(10, FMT_W),
8532 R6_OPC_CMP_SEUQ_S = FOP(11, FMT_W),
8533 R6_OPC_CMP_SLT_S = FOP(12, FMT_W),
8534 R6_OPC_CMP_SULT_S = FOP(13, FMT_W),
8535 R6_OPC_CMP_SLE_S = FOP(14, FMT_W),
8536 R6_OPC_CMP_SULE_S = FOP(15, FMT_W),
8537 R6_OPC_CMP_OR_S = FOP(17, FMT_W),
8538 R6_OPC_CMP_UNE_S = FOP(18, FMT_W),
8539 R6_OPC_CMP_NE_S = FOP(19, FMT_W),
8540 R6_OPC_CMP_SOR_S = FOP(25, FMT_W),
8541 R6_OPC_CMP_SUNE_S = FOP(26, FMT_W),
8542 R6_OPC_CMP_SNE_S = FOP(27, FMT_W),
8544 R6_OPC_CMP_AF_D = FOP(0, FMT_L),
8545 R6_OPC_CMP_UN_D = FOP(1, FMT_L),
8546 R6_OPC_CMP_EQ_D = FOP(2, FMT_L),
8547 R6_OPC_CMP_UEQ_D = FOP(3, FMT_L),
8548 R6_OPC_CMP_LT_D = FOP(4, FMT_L),
8549 R6_OPC_CMP_ULT_D = FOP(5, FMT_L),
8550 R6_OPC_CMP_LE_D = FOP(6, FMT_L),
8551 R6_OPC_CMP_ULE_D = FOP(7, FMT_L),
8552 R6_OPC_CMP_SAF_D = FOP(8, FMT_L),
8553 R6_OPC_CMP_SUN_D = FOP(9, FMT_L),
8554 R6_OPC_CMP_SEQ_D = FOP(10, FMT_L),
8555 R6_OPC_CMP_SEUQ_D = FOP(11, FMT_L),
8556 R6_OPC_CMP_SLT_D = FOP(12, FMT_L),
8557 R6_OPC_CMP_SULT_D = FOP(13, FMT_L),
8558 R6_OPC_CMP_SLE_D = FOP(14, FMT_L),
8559 R6_OPC_CMP_SULE_D = FOP(15, FMT_L),
8560 R6_OPC_CMP_OR_D = FOP(17, FMT_L),
8561 R6_OPC_CMP_UNE_D = FOP(18, FMT_L),
8562 R6_OPC_CMP_NE_D = FOP(19, FMT_L),
8563 R6_OPC_CMP_SOR_D = FOP(25, FMT_L),
8564 R6_OPC_CMP_SUNE_D = FOP(26, FMT_L),
8565 R6_OPC_CMP_SNE_D = FOP(27, FMT_L),
8567 static void gen_cp1 (DisasContext *ctx, uint32_t opc, int rt, int fs)
8569 TCGv t0 = tcg_temp_new();
8571 switch (opc) {
8572 case OPC_MFC1:
8574 TCGv_i32 fp0 = tcg_temp_new_i32();
8576 gen_load_fpr32(ctx, fp0, fs);
8577 tcg_gen_ext_i32_tl(t0, fp0);
8578 tcg_temp_free_i32(fp0);
8580 gen_store_gpr(t0, rt);
8581 break;
8582 case OPC_MTC1:
8583 gen_load_gpr(t0, rt);
8585 TCGv_i32 fp0 = tcg_temp_new_i32();
8587 tcg_gen_trunc_tl_i32(fp0, t0);
8588 gen_store_fpr32(ctx, fp0, fs);
8589 tcg_temp_free_i32(fp0);
8591 break;
8592 case OPC_CFC1:
8593 gen_helper_1e0i(cfc1, t0, fs);
8594 gen_store_gpr(t0, rt);
8595 break;
8596 case OPC_CTC1:
8597 gen_load_gpr(t0, rt);
8598 save_cpu_state(ctx, 0);
8600 TCGv_i32 fs_tmp = tcg_const_i32(fs);
8602 gen_helper_0e2i(ctc1, t0, fs_tmp, rt);
8603 tcg_temp_free_i32(fs_tmp);
8605 /* Stop translation as we may have changed hflags */
8606 ctx->bstate = BS_STOP;
8607 break;
8608 #if defined(TARGET_MIPS64)
8609 case OPC_DMFC1:
8610 gen_load_fpr64(ctx, t0, fs);
8611 gen_store_gpr(t0, rt);
8612 break;
8613 case OPC_DMTC1:
8614 gen_load_gpr(t0, rt);
8615 gen_store_fpr64(ctx, t0, fs);
8616 break;
8617 #endif
8618 case OPC_MFHC1:
8620 TCGv_i32 fp0 = tcg_temp_new_i32();
8622 gen_load_fpr32h(ctx, fp0, fs);
8623 tcg_gen_ext_i32_tl(t0, fp0);
8624 tcg_temp_free_i32(fp0);
8626 gen_store_gpr(t0, rt);
8627 break;
8628 case OPC_MTHC1:
8629 gen_load_gpr(t0, rt);
8631 TCGv_i32 fp0 = tcg_temp_new_i32();
8633 tcg_gen_trunc_tl_i32(fp0, t0);
8634 gen_store_fpr32h(ctx, fp0, fs);
8635 tcg_temp_free_i32(fp0);
8637 break;
8638 default:
8639 MIPS_INVAL("cp1 move");
8640 generate_exception_end(ctx, EXCP_RI);
8641 goto out;
8644 out:
8645 tcg_temp_free(t0);
8648 static void gen_movci (DisasContext *ctx, int rd, int rs, int cc, int tf)
8650 TCGLabel *l1;
8651 TCGCond cond;
8652 TCGv_i32 t0;
8654 if (rd == 0) {
8655 /* Treat as NOP. */
8656 return;
8659 if (tf)
8660 cond = TCG_COND_EQ;
8661 else
8662 cond = TCG_COND_NE;
8664 l1 = gen_new_label();
8665 t0 = tcg_temp_new_i32();
8666 tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc));
8667 tcg_gen_brcondi_i32(cond, t0, 0, l1);
8668 tcg_temp_free_i32(t0);
8669 if (rs == 0) {
8670 tcg_gen_movi_tl(cpu_gpr[rd], 0);
8671 } else {
8672 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
8674 gen_set_label(l1);
8677 static inline void gen_movcf_s(DisasContext *ctx, int fs, int fd, int cc,
8678 int tf)
8680 int cond;
8681 TCGv_i32 t0 = tcg_temp_new_i32();
8682 TCGLabel *l1 = gen_new_label();
8684 if (tf)
8685 cond = TCG_COND_EQ;
8686 else
8687 cond = TCG_COND_NE;
8689 tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc));
8690 tcg_gen_brcondi_i32(cond, t0, 0, l1);
8691 gen_load_fpr32(ctx, t0, fs);
8692 gen_store_fpr32(ctx, t0, fd);
8693 gen_set_label(l1);
8694 tcg_temp_free_i32(t0);
8697 static inline void gen_movcf_d (DisasContext *ctx, int fs, int fd, int cc, int tf)
8699 int cond;
8700 TCGv_i32 t0 = tcg_temp_new_i32();
8701 TCGv_i64 fp0;
8702 TCGLabel *l1 = gen_new_label();
8704 if (tf)
8705 cond = TCG_COND_EQ;
8706 else
8707 cond = TCG_COND_NE;
8709 tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc));
8710 tcg_gen_brcondi_i32(cond, t0, 0, l1);
8711 tcg_temp_free_i32(t0);
8712 fp0 = tcg_temp_new_i64();
8713 gen_load_fpr64(ctx, fp0, fs);
8714 gen_store_fpr64(ctx, fp0, fd);
8715 tcg_temp_free_i64(fp0);
8716 gen_set_label(l1);
8719 static inline void gen_movcf_ps(DisasContext *ctx, int fs, int fd,
8720 int cc, int tf)
8722 int cond;
8723 TCGv_i32 t0 = tcg_temp_new_i32();
8724 TCGLabel *l1 = gen_new_label();
8725 TCGLabel *l2 = gen_new_label();
8727 if (tf)
8728 cond = TCG_COND_EQ;
8729 else
8730 cond = TCG_COND_NE;
8732 tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc));
8733 tcg_gen_brcondi_i32(cond, t0, 0, l1);
8734 gen_load_fpr32(ctx, t0, fs);
8735 gen_store_fpr32(ctx, t0, fd);
8736 gen_set_label(l1);
8738 tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc+1));
8739 tcg_gen_brcondi_i32(cond, t0, 0, l2);
8740 gen_load_fpr32h(ctx, t0, fs);
8741 gen_store_fpr32h(ctx, t0, fd);
8742 tcg_temp_free_i32(t0);
8743 gen_set_label(l2);
8746 static void gen_sel_s(DisasContext *ctx, enum fopcode op1, int fd, int ft,
8747 int fs)
8749 TCGv_i32 t1 = tcg_const_i32(0);
8750 TCGv_i32 fp0 = tcg_temp_new_i32();
8751 TCGv_i32 fp1 = tcg_temp_new_i32();
8752 TCGv_i32 fp2 = tcg_temp_new_i32();
8753 gen_load_fpr32(ctx, fp0, fd);
8754 gen_load_fpr32(ctx, fp1, ft);
8755 gen_load_fpr32(ctx, fp2, fs);
8757 switch (op1) {
8758 case OPC_SEL_S:
8759 tcg_gen_andi_i32(fp0, fp0, 1);
8760 tcg_gen_movcond_i32(TCG_COND_NE, fp0, fp0, t1, fp1, fp2);
8761 break;
8762 case OPC_SELEQZ_S:
8763 tcg_gen_andi_i32(fp1, fp1, 1);
8764 tcg_gen_movcond_i32(TCG_COND_EQ, fp0, fp1, t1, fp2, t1);
8765 break;
8766 case OPC_SELNEZ_S:
8767 tcg_gen_andi_i32(fp1, fp1, 1);
8768 tcg_gen_movcond_i32(TCG_COND_NE, fp0, fp1, t1, fp2, t1);
8769 break;
8770 default:
8771 MIPS_INVAL("gen_sel_s");
8772 generate_exception_end(ctx, EXCP_RI);
8773 break;
8776 gen_store_fpr32(ctx, fp0, fd);
8777 tcg_temp_free_i32(fp2);
8778 tcg_temp_free_i32(fp1);
8779 tcg_temp_free_i32(fp0);
8780 tcg_temp_free_i32(t1);
8783 static void gen_sel_d(DisasContext *ctx, enum fopcode op1, int fd, int ft,
8784 int fs)
8786 TCGv_i64 t1 = tcg_const_i64(0);
8787 TCGv_i64 fp0 = tcg_temp_new_i64();
8788 TCGv_i64 fp1 = tcg_temp_new_i64();
8789 TCGv_i64 fp2 = tcg_temp_new_i64();
8790 gen_load_fpr64(ctx, fp0, fd);
8791 gen_load_fpr64(ctx, fp1, ft);
8792 gen_load_fpr64(ctx, fp2, fs);
8794 switch (op1) {
8795 case OPC_SEL_D:
8796 tcg_gen_andi_i64(fp0, fp0, 1);
8797 tcg_gen_movcond_i64(TCG_COND_NE, fp0, fp0, t1, fp1, fp2);
8798 break;
8799 case OPC_SELEQZ_D:
8800 tcg_gen_andi_i64(fp1, fp1, 1);
8801 tcg_gen_movcond_i64(TCG_COND_EQ, fp0, fp1, t1, fp2, t1);
8802 break;
8803 case OPC_SELNEZ_D:
8804 tcg_gen_andi_i64(fp1, fp1, 1);
8805 tcg_gen_movcond_i64(TCG_COND_NE, fp0, fp1, t1, fp2, t1);
8806 break;
8807 default:
8808 MIPS_INVAL("gen_sel_d");
8809 generate_exception_end(ctx, EXCP_RI);
8810 break;
8813 gen_store_fpr64(ctx, fp0, fd);
8814 tcg_temp_free_i64(fp2);
8815 tcg_temp_free_i64(fp1);
8816 tcg_temp_free_i64(fp0);
8817 tcg_temp_free_i64(t1);
8820 static void gen_farith (DisasContext *ctx, enum fopcode op1,
8821 int ft, int fs, int fd, int cc)
8823 uint32_t func = ctx->opcode & 0x3f;
8824 switch (op1) {
8825 case OPC_ADD_S:
8827 TCGv_i32 fp0 = tcg_temp_new_i32();
8828 TCGv_i32 fp1 = tcg_temp_new_i32();
8830 gen_load_fpr32(ctx, fp0, fs);
8831 gen_load_fpr32(ctx, fp1, ft);
8832 gen_helper_float_add_s(fp0, cpu_env, fp0, fp1);
8833 tcg_temp_free_i32(fp1);
8834 gen_store_fpr32(ctx, fp0, fd);
8835 tcg_temp_free_i32(fp0);
8837 break;
8838 case OPC_SUB_S:
8840 TCGv_i32 fp0 = tcg_temp_new_i32();
8841 TCGv_i32 fp1 = tcg_temp_new_i32();
8843 gen_load_fpr32(ctx, fp0, fs);
8844 gen_load_fpr32(ctx, fp1, ft);
8845 gen_helper_float_sub_s(fp0, cpu_env, fp0, fp1);
8846 tcg_temp_free_i32(fp1);
8847 gen_store_fpr32(ctx, fp0, fd);
8848 tcg_temp_free_i32(fp0);
8850 break;
8851 case OPC_MUL_S:
8853 TCGv_i32 fp0 = tcg_temp_new_i32();
8854 TCGv_i32 fp1 = tcg_temp_new_i32();
8856 gen_load_fpr32(ctx, fp0, fs);
8857 gen_load_fpr32(ctx, fp1, ft);
8858 gen_helper_float_mul_s(fp0, cpu_env, fp0, fp1);
8859 tcg_temp_free_i32(fp1);
8860 gen_store_fpr32(ctx, fp0, fd);
8861 tcg_temp_free_i32(fp0);
8863 break;
8864 case OPC_DIV_S:
8866 TCGv_i32 fp0 = tcg_temp_new_i32();
8867 TCGv_i32 fp1 = tcg_temp_new_i32();
8869 gen_load_fpr32(ctx, fp0, fs);
8870 gen_load_fpr32(ctx, fp1, ft);
8871 gen_helper_float_div_s(fp0, cpu_env, fp0, fp1);
8872 tcg_temp_free_i32(fp1);
8873 gen_store_fpr32(ctx, fp0, fd);
8874 tcg_temp_free_i32(fp0);
8876 break;
8877 case OPC_SQRT_S:
8879 TCGv_i32 fp0 = tcg_temp_new_i32();
8881 gen_load_fpr32(ctx, fp0, fs);
8882 gen_helper_float_sqrt_s(fp0, cpu_env, fp0);
8883 gen_store_fpr32(ctx, fp0, fd);
8884 tcg_temp_free_i32(fp0);
8886 break;
8887 case OPC_ABS_S:
8889 TCGv_i32 fp0 = tcg_temp_new_i32();
8891 gen_load_fpr32(ctx, fp0, fs);
8892 gen_helper_float_abs_s(fp0, fp0);
8893 gen_store_fpr32(ctx, fp0, fd);
8894 tcg_temp_free_i32(fp0);
8896 break;
8897 case OPC_MOV_S:
8899 TCGv_i32 fp0 = tcg_temp_new_i32();
8901 gen_load_fpr32(ctx, fp0, fs);
8902 gen_store_fpr32(ctx, fp0, fd);
8903 tcg_temp_free_i32(fp0);
8905 break;
8906 case OPC_NEG_S:
8908 TCGv_i32 fp0 = tcg_temp_new_i32();
8910 gen_load_fpr32(ctx, fp0, fs);
8911 gen_helper_float_chs_s(fp0, fp0);
8912 gen_store_fpr32(ctx, fp0, fd);
8913 tcg_temp_free_i32(fp0);
8915 break;
8916 case OPC_ROUND_L_S:
8917 check_cp1_64bitmode(ctx);
8919 TCGv_i32 fp32 = tcg_temp_new_i32();
8920 TCGv_i64 fp64 = tcg_temp_new_i64();
8922 gen_load_fpr32(ctx, fp32, fs);
8923 gen_helper_float_roundl_s(fp64, cpu_env, fp32);
8924 tcg_temp_free_i32(fp32);
8925 gen_store_fpr64(ctx, fp64, fd);
8926 tcg_temp_free_i64(fp64);
8928 break;
8929 case OPC_TRUNC_L_S:
8930 check_cp1_64bitmode(ctx);
8932 TCGv_i32 fp32 = tcg_temp_new_i32();
8933 TCGv_i64 fp64 = tcg_temp_new_i64();
8935 gen_load_fpr32(ctx, fp32, fs);
8936 gen_helper_float_truncl_s(fp64, cpu_env, fp32);
8937 tcg_temp_free_i32(fp32);
8938 gen_store_fpr64(ctx, fp64, fd);
8939 tcg_temp_free_i64(fp64);
8941 break;
8942 case OPC_CEIL_L_S:
8943 check_cp1_64bitmode(ctx);
8945 TCGv_i32 fp32 = tcg_temp_new_i32();
8946 TCGv_i64 fp64 = tcg_temp_new_i64();
8948 gen_load_fpr32(ctx, fp32, fs);
8949 gen_helper_float_ceill_s(fp64, cpu_env, fp32);
8950 tcg_temp_free_i32(fp32);
8951 gen_store_fpr64(ctx, fp64, fd);
8952 tcg_temp_free_i64(fp64);
8954 break;
8955 case OPC_FLOOR_L_S:
8956 check_cp1_64bitmode(ctx);
8958 TCGv_i32 fp32 = tcg_temp_new_i32();
8959 TCGv_i64 fp64 = tcg_temp_new_i64();
8961 gen_load_fpr32(ctx, fp32, fs);
8962 gen_helper_float_floorl_s(fp64, cpu_env, fp32);
8963 tcg_temp_free_i32(fp32);
8964 gen_store_fpr64(ctx, fp64, fd);
8965 tcg_temp_free_i64(fp64);
8967 break;
8968 case OPC_ROUND_W_S:
8970 TCGv_i32 fp0 = tcg_temp_new_i32();
8972 gen_load_fpr32(ctx, fp0, fs);
8973 gen_helper_float_roundw_s(fp0, cpu_env, fp0);
8974 gen_store_fpr32(ctx, fp0, fd);
8975 tcg_temp_free_i32(fp0);
8977 break;
8978 case OPC_TRUNC_W_S:
8980 TCGv_i32 fp0 = tcg_temp_new_i32();
8982 gen_load_fpr32(ctx, fp0, fs);
8983 gen_helper_float_truncw_s(fp0, cpu_env, fp0);
8984 gen_store_fpr32(ctx, fp0, fd);
8985 tcg_temp_free_i32(fp0);
8987 break;
8988 case OPC_CEIL_W_S:
8990 TCGv_i32 fp0 = tcg_temp_new_i32();
8992 gen_load_fpr32(ctx, fp0, fs);
8993 gen_helper_float_ceilw_s(fp0, cpu_env, fp0);
8994 gen_store_fpr32(ctx, fp0, fd);
8995 tcg_temp_free_i32(fp0);
8997 break;
8998 case OPC_FLOOR_W_S:
9000 TCGv_i32 fp0 = tcg_temp_new_i32();
9002 gen_load_fpr32(ctx, fp0, fs);
9003 gen_helper_float_floorw_s(fp0, cpu_env, fp0);
9004 gen_store_fpr32(ctx, fp0, fd);
9005 tcg_temp_free_i32(fp0);
9007 break;
9008 case OPC_SEL_S:
9009 check_insn(ctx, ISA_MIPS32R6);
9010 gen_sel_s(ctx, op1, fd, ft, fs);
9011 break;
9012 case OPC_SELEQZ_S:
9013 check_insn(ctx, ISA_MIPS32R6);
9014 gen_sel_s(ctx, op1, fd, ft, fs);
9015 break;
9016 case OPC_SELNEZ_S:
9017 check_insn(ctx, ISA_MIPS32R6);
9018 gen_sel_s(ctx, op1, fd, ft, fs);
9019 break;
9020 case OPC_MOVCF_S:
9021 check_insn_opc_removed(ctx, ISA_MIPS32R6);
9022 gen_movcf_s(ctx, fs, fd, (ft >> 2) & 0x7, ft & 0x1);
9023 break;
9024 case OPC_MOVZ_S:
9025 check_insn_opc_removed(ctx, ISA_MIPS32R6);
9027 TCGLabel *l1 = gen_new_label();
9028 TCGv_i32 fp0;
9030 if (ft != 0) {
9031 tcg_gen_brcondi_tl(TCG_COND_NE, cpu_gpr[ft], 0, l1);
9033 fp0 = tcg_temp_new_i32();
9034 gen_load_fpr32(ctx, fp0, fs);
9035 gen_store_fpr32(ctx, fp0, fd);
9036 tcg_temp_free_i32(fp0);
9037 gen_set_label(l1);
9039 break;
9040 case OPC_MOVN_S:
9041 check_insn_opc_removed(ctx, ISA_MIPS32R6);
9043 TCGLabel *l1 = gen_new_label();
9044 TCGv_i32 fp0;
9046 if (ft != 0) {
9047 tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_gpr[ft], 0, l1);
9048 fp0 = tcg_temp_new_i32();
9049 gen_load_fpr32(ctx, fp0, fs);
9050 gen_store_fpr32(ctx, fp0, fd);
9051 tcg_temp_free_i32(fp0);
9052 gen_set_label(l1);
9055 break;
9056 case OPC_RECIP_S:
9058 TCGv_i32 fp0 = tcg_temp_new_i32();
9060 gen_load_fpr32(ctx, fp0, fs);
9061 gen_helper_float_recip_s(fp0, cpu_env, fp0);
9062 gen_store_fpr32(ctx, fp0, fd);
9063 tcg_temp_free_i32(fp0);
9065 break;
9066 case OPC_RSQRT_S:
9068 TCGv_i32 fp0 = tcg_temp_new_i32();
9070 gen_load_fpr32(ctx, fp0, fs);
9071 gen_helper_float_rsqrt_s(fp0, cpu_env, fp0);
9072 gen_store_fpr32(ctx, fp0, fd);
9073 tcg_temp_free_i32(fp0);
9075 break;
9076 case OPC_MADDF_S:
9077 check_insn(ctx, ISA_MIPS32R6);
9079 TCGv_i32 fp0 = tcg_temp_new_i32();
9080 TCGv_i32 fp1 = tcg_temp_new_i32();
9081 TCGv_i32 fp2 = tcg_temp_new_i32();
9082 gen_load_fpr32(ctx, fp0, fs);
9083 gen_load_fpr32(ctx, fp1, ft);
9084 gen_load_fpr32(ctx, fp2, fd);
9085 gen_helper_float_maddf_s(fp2, cpu_env, fp0, fp1, fp2);
9086 gen_store_fpr32(ctx, fp2, fd);
9087 tcg_temp_free_i32(fp2);
9088 tcg_temp_free_i32(fp1);
9089 tcg_temp_free_i32(fp0);
9091 break;
9092 case OPC_MSUBF_S:
9093 check_insn(ctx, ISA_MIPS32R6);
9095 TCGv_i32 fp0 = tcg_temp_new_i32();
9096 TCGv_i32 fp1 = tcg_temp_new_i32();
9097 TCGv_i32 fp2 = tcg_temp_new_i32();
9098 gen_load_fpr32(ctx, fp0, fs);
9099 gen_load_fpr32(ctx, fp1, ft);
9100 gen_load_fpr32(ctx, fp2, fd);
9101 gen_helper_float_msubf_s(fp2, cpu_env, fp0, fp1, fp2);
9102 gen_store_fpr32(ctx, fp2, fd);
9103 tcg_temp_free_i32(fp2);
9104 tcg_temp_free_i32(fp1);
9105 tcg_temp_free_i32(fp0);
9107 break;
9108 case OPC_RINT_S:
9109 check_insn(ctx, ISA_MIPS32R6);
9111 TCGv_i32 fp0 = tcg_temp_new_i32();
9112 gen_load_fpr32(ctx, fp0, fs);
9113 gen_helper_float_rint_s(fp0, cpu_env, fp0);
9114 gen_store_fpr32(ctx, fp0, fd);
9115 tcg_temp_free_i32(fp0);
9117 break;
9118 case OPC_CLASS_S:
9119 check_insn(ctx, ISA_MIPS32R6);
9121 TCGv_i32 fp0 = tcg_temp_new_i32();
9122 gen_load_fpr32(ctx, fp0, fs);
9123 gen_helper_float_class_s(fp0, fp0);
9124 gen_store_fpr32(ctx, fp0, fd);
9125 tcg_temp_free_i32(fp0);
9127 break;
9128 case OPC_MIN_S: /* OPC_RECIP2_S */
9129 if (ctx->insn_flags & ISA_MIPS32R6) {
9130 /* OPC_MIN_S */
9131 TCGv_i32 fp0 = tcg_temp_new_i32();
9132 TCGv_i32 fp1 = tcg_temp_new_i32();
9133 TCGv_i32 fp2 = tcg_temp_new_i32();
9134 gen_load_fpr32(ctx, fp0, fs);
9135 gen_load_fpr32(ctx, fp1, ft);
9136 gen_helper_float_min_s(fp2, cpu_env, fp0, fp1);
9137 gen_store_fpr32(ctx, fp2, fd);
9138 tcg_temp_free_i32(fp2);
9139 tcg_temp_free_i32(fp1);
9140 tcg_temp_free_i32(fp0);
9141 } else {
9142 /* OPC_RECIP2_S */
9143 check_cp1_64bitmode(ctx);
9145 TCGv_i32 fp0 = tcg_temp_new_i32();
9146 TCGv_i32 fp1 = tcg_temp_new_i32();
9148 gen_load_fpr32(ctx, fp0, fs);
9149 gen_load_fpr32(ctx, fp1, ft);
9150 gen_helper_float_recip2_s(fp0, cpu_env, fp0, fp1);
9151 tcg_temp_free_i32(fp1);
9152 gen_store_fpr32(ctx, fp0, fd);
9153 tcg_temp_free_i32(fp0);
9156 break;
9157 case OPC_MINA_S: /* OPC_RECIP1_S */
9158 if (ctx->insn_flags & ISA_MIPS32R6) {
9159 /* OPC_MINA_S */
9160 TCGv_i32 fp0 = tcg_temp_new_i32();
9161 TCGv_i32 fp1 = tcg_temp_new_i32();
9162 TCGv_i32 fp2 = tcg_temp_new_i32();
9163 gen_load_fpr32(ctx, fp0, fs);
9164 gen_load_fpr32(ctx, fp1, ft);
9165 gen_helper_float_mina_s(fp2, cpu_env, fp0, fp1);
9166 gen_store_fpr32(ctx, fp2, fd);
9167 tcg_temp_free_i32(fp2);
9168 tcg_temp_free_i32(fp1);
9169 tcg_temp_free_i32(fp0);
9170 } else {
9171 /* OPC_RECIP1_S */
9172 check_cp1_64bitmode(ctx);
9174 TCGv_i32 fp0 = tcg_temp_new_i32();
9176 gen_load_fpr32(ctx, fp0, fs);
9177 gen_helper_float_recip1_s(fp0, cpu_env, fp0);
9178 gen_store_fpr32(ctx, fp0, fd);
9179 tcg_temp_free_i32(fp0);
9182 break;
9183 case OPC_MAX_S: /* OPC_RSQRT1_S */
9184 if (ctx->insn_flags & ISA_MIPS32R6) {
9185 /* OPC_MAX_S */
9186 TCGv_i32 fp0 = tcg_temp_new_i32();
9187 TCGv_i32 fp1 = tcg_temp_new_i32();
9188 gen_load_fpr32(ctx, fp0, fs);
9189 gen_load_fpr32(ctx, fp1, ft);
9190 gen_helper_float_max_s(fp1, cpu_env, fp0, fp1);
9191 gen_store_fpr32(ctx, fp1, fd);
9192 tcg_temp_free_i32(fp1);
9193 tcg_temp_free_i32(fp0);
9194 } else {
9195 /* OPC_RSQRT1_S */
9196 check_cp1_64bitmode(ctx);
9198 TCGv_i32 fp0 = tcg_temp_new_i32();
9200 gen_load_fpr32(ctx, fp0, fs);
9201 gen_helper_float_rsqrt1_s(fp0, cpu_env, fp0);
9202 gen_store_fpr32(ctx, fp0, fd);
9203 tcg_temp_free_i32(fp0);
9206 break;
9207 case OPC_MAXA_S: /* OPC_RSQRT2_S */
9208 if (ctx->insn_flags & ISA_MIPS32R6) {
9209 /* OPC_MAXA_S */
9210 TCGv_i32 fp0 = tcg_temp_new_i32();
9211 TCGv_i32 fp1 = tcg_temp_new_i32();
9212 gen_load_fpr32(ctx, fp0, fs);
9213 gen_load_fpr32(ctx, fp1, ft);
9214 gen_helper_float_maxa_s(fp1, cpu_env, fp0, fp1);
9215 gen_store_fpr32(ctx, fp1, fd);
9216 tcg_temp_free_i32(fp1);
9217 tcg_temp_free_i32(fp0);
9218 } else {
9219 /* OPC_RSQRT2_S */
9220 check_cp1_64bitmode(ctx);
9222 TCGv_i32 fp0 = tcg_temp_new_i32();
9223 TCGv_i32 fp1 = tcg_temp_new_i32();
9225 gen_load_fpr32(ctx, fp0, fs);
9226 gen_load_fpr32(ctx, fp1, ft);
9227 gen_helper_float_rsqrt2_s(fp0, cpu_env, fp0, fp1);
9228 tcg_temp_free_i32(fp1);
9229 gen_store_fpr32(ctx, fp0, fd);
9230 tcg_temp_free_i32(fp0);
9233 break;
9234 case OPC_CVT_D_S:
9235 check_cp1_registers(ctx, fd);
9237 TCGv_i32 fp32 = tcg_temp_new_i32();
9238 TCGv_i64 fp64 = tcg_temp_new_i64();
9240 gen_load_fpr32(ctx, fp32, fs);
9241 gen_helper_float_cvtd_s(fp64, cpu_env, fp32);
9242 tcg_temp_free_i32(fp32);
9243 gen_store_fpr64(ctx, fp64, fd);
9244 tcg_temp_free_i64(fp64);
9246 break;
9247 case OPC_CVT_W_S:
9249 TCGv_i32 fp0 = tcg_temp_new_i32();
9251 gen_load_fpr32(ctx, fp0, fs);
9252 gen_helper_float_cvtw_s(fp0, cpu_env, fp0);
9253 gen_store_fpr32(ctx, fp0, fd);
9254 tcg_temp_free_i32(fp0);
9256 break;
9257 case OPC_CVT_L_S:
9258 check_cp1_64bitmode(ctx);
9260 TCGv_i32 fp32 = tcg_temp_new_i32();
9261 TCGv_i64 fp64 = tcg_temp_new_i64();
9263 gen_load_fpr32(ctx, fp32, fs);
9264 gen_helper_float_cvtl_s(fp64, cpu_env, fp32);
9265 tcg_temp_free_i32(fp32);
9266 gen_store_fpr64(ctx, fp64, fd);
9267 tcg_temp_free_i64(fp64);
9269 break;
9270 case OPC_CVT_PS_S:
9271 check_ps(ctx);
9273 TCGv_i64 fp64 = tcg_temp_new_i64();
9274 TCGv_i32 fp32_0 = tcg_temp_new_i32();
9275 TCGv_i32 fp32_1 = tcg_temp_new_i32();
9277 gen_load_fpr32(ctx, fp32_0, fs);
9278 gen_load_fpr32(ctx, fp32_1, ft);
9279 tcg_gen_concat_i32_i64(fp64, fp32_1, fp32_0);
9280 tcg_temp_free_i32(fp32_1);
9281 tcg_temp_free_i32(fp32_0);
9282 gen_store_fpr64(ctx, fp64, fd);
9283 tcg_temp_free_i64(fp64);
9285 break;
9286 case OPC_CMP_F_S:
9287 case OPC_CMP_UN_S:
9288 case OPC_CMP_EQ_S:
9289 case OPC_CMP_UEQ_S:
9290 case OPC_CMP_OLT_S:
9291 case OPC_CMP_ULT_S:
9292 case OPC_CMP_OLE_S:
9293 case OPC_CMP_ULE_S:
9294 case OPC_CMP_SF_S:
9295 case OPC_CMP_NGLE_S:
9296 case OPC_CMP_SEQ_S:
9297 case OPC_CMP_NGL_S:
9298 case OPC_CMP_LT_S:
9299 case OPC_CMP_NGE_S:
9300 case OPC_CMP_LE_S:
9301 case OPC_CMP_NGT_S:
9302 check_insn_opc_removed(ctx, ISA_MIPS32R6);
9303 if (ctx->opcode & (1 << 6)) {
9304 gen_cmpabs_s(ctx, func-48, ft, fs, cc);
9305 } else {
9306 gen_cmp_s(ctx, func-48, ft, fs, cc);
9308 break;
9309 case OPC_ADD_D:
9310 check_cp1_registers(ctx, fs | ft | fd);
9312 TCGv_i64 fp0 = tcg_temp_new_i64();
9313 TCGv_i64 fp1 = tcg_temp_new_i64();
9315 gen_load_fpr64(ctx, fp0, fs);
9316 gen_load_fpr64(ctx, fp1, ft);
9317 gen_helper_float_add_d(fp0, cpu_env, fp0, fp1);
9318 tcg_temp_free_i64(fp1);
9319 gen_store_fpr64(ctx, fp0, fd);
9320 tcg_temp_free_i64(fp0);
9322 break;
9323 case OPC_SUB_D:
9324 check_cp1_registers(ctx, fs | ft | fd);
9326 TCGv_i64 fp0 = tcg_temp_new_i64();
9327 TCGv_i64 fp1 = tcg_temp_new_i64();
9329 gen_load_fpr64(ctx, fp0, fs);
9330 gen_load_fpr64(ctx, fp1, ft);
9331 gen_helper_float_sub_d(fp0, cpu_env, fp0, fp1);
9332 tcg_temp_free_i64(fp1);
9333 gen_store_fpr64(ctx, fp0, fd);
9334 tcg_temp_free_i64(fp0);
9336 break;
9337 case OPC_MUL_D:
9338 check_cp1_registers(ctx, fs | ft | fd);
9340 TCGv_i64 fp0 = tcg_temp_new_i64();
9341 TCGv_i64 fp1 = tcg_temp_new_i64();
9343 gen_load_fpr64(ctx, fp0, fs);
9344 gen_load_fpr64(ctx, fp1, ft);
9345 gen_helper_float_mul_d(fp0, cpu_env, fp0, fp1);
9346 tcg_temp_free_i64(fp1);
9347 gen_store_fpr64(ctx, fp0, fd);
9348 tcg_temp_free_i64(fp0);
9350 break;
9351 case OPC_DIV_D:
9352 check_cp1_registers(ctx, fs | ft | fd);
9354 TCGv_i64 fp0 = tcg_temp_new_i64();
9355 TCGv_i64 fp1 = tcg_temp_new_i64();
9357 gen_load_fpr64(ctx, fp0, fs);
9358 gen_load_fpr64(ctx, fp1, ft);
9359 gen_helper_float_div_d(fp0, cpu_env, fp0, fp1);
9360 tcg_temp_free_i64(fp1);
9361 gen_store_fpr64(ctx, fp0, fd);
9362 tcg_temp_free_i64(fp0);
9364 break;
9365 case OPC_SQRT_D:
9366 check_cp1_registers(ctx, fs | fd);
9368 TCGv_i64 fp0 = tcg_temp_new_i64();
9370 gen_load_fpr64(ctx, fp0, fs);
9371 gen_helper_float_sqrt_d(fp0, cpu_env, fp0);
9372 gen_store_fpr64(ctx, fp0, fd);
9373 tcg_temp_free_i64(fp0);
9375 break;
9376 case OPC_ABS_D:
9377 check_cp1_registers(ctx, fs | fd);
9379 TCGv_i64 fp0 = tcg_temp_new_i64();
9381 gen_load_fpr64(ctx, fp0, fs);
9382 gen_helper_float_abs_d(fp0, fp0);
9383 gen_store_fpr64(ctx, fp0, fd);
9384 tcg_temp_free_i64(fp0);
9386 break;
9387 case OPC_MOV_D:
9388 check_cp1_registers(ctx, fs | fd);
9390 TCGv_i64 fp0 = tcg_temp_new_i64();
9392 gen_load_fpr64(ctx, fp0, fs);
9393 gen_store_fpr64(ctx, fp0, fd);
9394 tcg_temp_free_i64(fp0);
9396 break;
9397 case OPC_NEG_D:
9398 check_cp1_registers(ctx, fs | fd);
9400 TCGv_i64 fp0 = tcg_temp_new_i64();
9402 gen_load_fpr64(ctx, fp0, fs);
9403 gen_helper_float_chs_d(fp0, fp0);
9404 gen_store_fpr64(ctx, fp0, fd);
9405 tcg_temp_free_i64(fp0);
9407 break;
9408 case OPC_ROUND_L_D:
9409 check_cp1_64bitmode(ctx);
9411 TCGv_i64 fp0 = tcg_temp_new_i64();
9413 gen_load_fpr64(ctx, fp0, fs);
9414 gen_helper_float_roundl_d(fp0, cpu_env, fp0);
9415 gen_store_fpr64(ctx, fp0, fd);
9416 tcg_temp_free_i64(fp0);
9418 break;
9419 case OPC_TRUNC_L_D:
9420 check_cp1_64bitmode(ctx);
9422 TCGv_i64 fp0 = tcg_temp_new_i64();
9424 gen_load_fpr64(ctx, fp0, fs);
9425 gen_helper_float_truncl_d(fp0, cpu_env, fp0);
9426 gen_store_fpr64(ctx, fp0, fd);
9427 tcg_temp_free_i64(fp0);
9429 break;
9430 case OPC_CEIL_L_D:
9431 check_cp1_64bitmode(ctx);
9433 TCGv_i64 fp0 = tcg_temp_new_i64();
9435 gen_load_fpr64(ctx, fp0, fs);
9436 gen_helper_float_ceill_d(fp0, cpu_env, fp0);
9437 gen_store_fpr64(ctx, fp0, fd);
9438 tcg_temp_free_i64(fp0);
9440 break;
9441 case OPC_FLOOR_L_D:
9442 check_cp1_64bitmode(ctx);
9444 TCGv_i64 fp0 = tcg_temp_new_i64();
9446 gen_load_fpr64(ctx, fp0, fs);
9447 gen_helper_float_floorl_d(fp0, cpu_env, fp0);
9448 gen_store_fpr64(ctx, fp0, fd);
9449 tcg_temp_free_i64(fp0);
9451 break;
9452 case OPC_ROUND_W_D:
9453 check_cp1_registers(ctx, fs);
9455 TCGv_i32 fp32 = tcg_temp_new_i32();
9456 TCGv_i64 fp64 = tcg_temp_new_i64();
9458 gen_load_fpr64(ctx, fp64, fs);
9459 gen_helper_float_roundw_d(fp32, cpu_env, fp64);
9460 tcg_temp_free_i64(fp64);
9461 gen_store_fpr32(ctx, fp32, fd);
9462 tcg_temp_free_i32(fp32);
9464 break;
9465 case OPC_TRUNC_W_D:
9466 check_cp1_registers(ctx, fs);
9468 TCGv_i32 fp32 = tcg_temp_new_i32();
9469 TCGv_i64 fp64 = tcg_temp_new_i64();
9471 gen_load_fpr64(ctx, fp64, fs);
9472 gen_helper_float_truncw_d(fp32, cpu_env, fp64);
9473 tcg_temp_free_i64(fp64);
9474 gen_store_fpr32(ctx, fp32, fd);
9475 tcg_temp_free_i32(fp32);
9477 break;
9478 case OPC_CEIL_W_D:
9479 check_cp1_registers(ctx, fs);
9481 TCGv_i32 fp32 = tcg_temp_new_i32();
9482 TCGv_i64 fp64 = tcg_temp_new_i64();
9484 gen_load_fpr64(ctx, fp64, fs);
9485 gen_helper_float_ceilw_d(fp32, cpu_env, fp64);
9486 tcg_temp_free_i64(fp64);
9487 gen_store_fpr32(ctx, fp32, fd);
9488 tcg_temp_free_i32(fp32);
9490 break;
9491 case OPC_FLOOR_W_D:
9492 check_cp1_registers(ctx, fs);
9494 TCGv_i32 fp32 = tcg_temp_new_i32();
9495 TCGv_i64 fp64 = tcg_temp_new_i64();
9497 gen_load_fpr64(ctx, fp64, fs);
9498 gen_helper_float_floorw_d(fp32, cpu_env, fp64);
9499 tcg_temp_free_i64(fp64);
9500 gen_store_fpr32(ctx, fp32, fd);
9501 tcg_temp_free_i32(fp32);
9503 break;
9504 case OPC_SEL_D:
9505 check_insn(ctx, ISA_MIPS32R6);
9506 gen_sel_d(ctx, op1, fd, ft, fs);
9507 break;
9508 case OPC_SELEQZ_D:
9509 check_insn(ctx, ISA_MIPS32R6);
9510 gen_sel_d(ctx, op1, fd, ft, fs);
9511 break;
9512 case OPC_SELNEZ_D:
9513 check_insn(ctx, ISA_MIPS32R6);
9514 gen_sel_d(ctx, op1, fd, ft, fs);
9515 break;
9516 case OPC_MOVCF_D:
9517 check_insn_opc_removed(ctx, ISA_MIPS32R6);
9518 gen_movcf_d(ctx, fs, fd, (ft >> 2) & 0x7, ft & 0x1);
9519 break;
9520 case OPC_MOVZ_D:
9521 check_insn_opc_removed(ctx, ISA_MIPS32R6);
9523 TCGLabel *l1 = gen_new_label();
9524 TCGv_i64 fp0;
9526 if (ft != 0) {
9527 tcg_gen_brcondi_tl(TCG_COND_NE, cpu_gpr[ft], 0, l1);
9529 fp0 = tcg_temp_new_i64();
9530 gen_load_fpr64(ctx, fp0, fs);
9531 gen_store_fpr64(ctx, fp0, fd);
9532 tcg_temp_free_i64(fp0);
9533 gen_set_label(l1);
9535 break;
9536 case OPC_MOVN_D:
9537 check_insn_opc_removed(ctx, ISA_MIPS32R6);
9539 TCGLabel *l1 = gen_new_label();
9540 TCGv_i64 fp0;
9542 if (ft != 0) {
9543 tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_gpr[ft], 0, l1);
9544 fp0 = tcg_temp_new_i64();
9545 gen_load_fpr64(ctx, fp0, fs);
9546 gen_store_fpr64(ctx, fp0, fd);
9547 tcg_temp_free_i64(fp0);
9548 gen_set_label(l1);
9551 break;
9552 case OPC_RECIP_D:
9553 check_cp1_registers(ctx, fs | fd);
9555 TCGv_i64 fp0 = tcg_temp_new_i64();
9557 gen_load_fpr64(ctx, fp0, fs);
9558 gen_helper_float_recip_d(fp0, cpu_env, fp0);
9559 gen_store_fpr64(ctx, fp0, fd);
9560 tcg_temp_free_i64(fp0);
9562 break;
9563 case OPC_RSQRT_D:
9564 check_cp1_registers(ctx, fs | fd);
9566 TCGv_i64 fp0 = tcg_temp_new_i64();
9568 gen_load_fpr64(ctx, fp0, fs);
9569 gen_helper_float_rsqrt_d(fp0, cpu_env, fp0);
9570 gen_store_fpr64(ctx, fp0, fd);
9571 tcg_temp_free_i64(fp0);
9573 break;
9574 case OPC_MADDF_D:
9575 check_insn(ctx, ISA_MIPS32R6);
9577 TCGv_i64 fp0 = tcg_temp_new_i64();
9578 TCGv_i64 fp1 = tcg_temp_new_i64();
9579 TCGv_i64 fp2 = tcg_temp_new_i64();
9580 gen_load_fpr64(ctx, fp0, fs);
9581 gen_load_fpr64(ctx, fp1, ft);
9582 gen_load_fpr64(ctx, fp2, fd);
9583 gen_helper_float_maddf_d(fp2, cpu_env, fp0, fp1, fp2);
9584 gen_store_fpr64(ctx, fp2, fd);
9585 tcg_temp_free_i64(fp2);
9586 tcg_temp_free_i64(fp1);
9587 tcg_temp_free_i64(fp0);
9589 break;
9590 case OPC_MSUBF_D:
9591 check_insn(ctx, ISA_MIPS32R6);
9593 TCGv_i64 fp0 = tcg_temp_new_i64();
9594 TCGv_i64 fp1 = tcg_temp_new_i64();
9595 TCGv_i64 fp2 = tcg_temp_new_i64();
9596 gen_load_fpr64(ctx, fp0, fs);
9597 gen_load_fpr64(ctx, fp1, ft);
9598 gen_load_fpr64(ctx, fp2, fd);
9599 gen_helper_float_msubf_d(fp2, cpu_env, fp0, fp1, fp2);
9600 gen_store_fpr64(ctx, fp2, fd);
9601 tcg_temp_free_i64(fp2);
9602 tcg_temp_free_i64(fp1);
9603 tcg_temp_free_i64(fp0);
9605 break;
9606 case OPC_RINT_D:
9607 check_insn(ctx, ISA_MIPS32R6);
9609 TCGv_i64 fp0 = tcg_temp_new_i64();
9610 gen_load_fpr64(ctx, fp0, fs);
9611 gen_helper_float_rint_d(fp0, cpu_env, fp0);
9612 gen_store_fpr64(ctx, fp0, fd);
9613 tcg_temp_free_i64(fp0);
9615 break;
9616 case OPC_CLASS_D:
9617 check_insn(ctx, ISA_MIPS32R6);
9619 TCGv_i64 fp0 = tcg_temp_new_i64();
9620 gen_load_fpr64(ctx, fp0, fs);
9621 gen_helper_float_class_d(fp0, fp0);
9622 gen_store_fpr64(ctx, fp0, fd);
9623 tcg_temp_free_i64(fp0);
9625 break;
9626 case OPC_MIN_D: /* OPC_RECIP2_D */
9627 if (ctx->insn_flags & ISA_MIPS32R6) {
9628 /* OPC_MIN_D */
9629 TCGv_i64 fp0 = tcg_temp_new_i64();
9630 TCGv_i64 fp1 = tcg_temp_new_i64();
9631 gen_load_fpr64(ctx, fp0, fs);
9632 gen_load_fpr64(ctx, fp1, ft);
9633 gen_helper_float_min_d(fp1, cpu_env, fp0, fp1);
9634 gen_store_fpr64(ctx, fp1, fd);
9635 tcg_temp_free_i64(fp1);
9636 tcg_temp_free_i64(fp0);
9637 } else {
9638 /* OPC_RECIP2_D */
9639 check_cp1_64bitmode(ctx);
9641 TCGv_i64 fp0 = tcg_temp_new_i64();
9642 TCGv_i64 fp1 = tcg_temp_new_i64();
9644 gen_load_fpr64(ctx, fp0, fs);
9645 gen_load_fpr64(ctx, fp1, ft);
9646 gen_helper_float_recip2_d(fp0, cpu_env, fp0, fp1);
9647 tcg_temp_free_i64(fp1);
9648 gen_store_fpr64(ctx, fp0, fd);
9649 tcg_temp_free_i64(fp0);
9652 break;
9653 case OPC_MINA_D: /* OPC_RECIP1_D */
9654 if (ctx->insn_flags & ISA_MIPS32R6) {
9655 /* OPC_MINA_D */
9656 TCGv_i64 fp0 = tcg_temp_new_i64();
9657 TCGv_i64 fp1 = tcg_temp_new_i64();
9658 gen_load_fpr64(ctx, fp0, fs);
9659 gen_load_fpr64(ctx, fp1, ft);
9660 gen_helper_float_mina_d(fp1, cpu_env, fp0, fp1);
9661 gen_store_fpr64(ctx, fp1, fd);
9662 tcg_temp_free_i64(fp1);
9663 tcg_temp_free_i64(fp0);
9664 } else {
9665 /* OPC_RECIP1_D */
9666 check_cp1_64bitmode(ctx);
9668 TCGv_i64 fp0 = tcg_temp_new_i64();
9670 gen_load_fpr64(ctx, fp0, fs);
9671 gen_helper_float_recip1_d(fp0, cpu_env, fp0);
9672 gen_store_fpr64(ctx, fp0, fd);
9673 tcg_temp_free_i64(fp0);
9676 break;
9677 case OPC_MAX_D: /* OPC_RSQRT1_D */
9678 if (ctx->insn_flags & ISA_MIPS32R6) {
9679 /* OPC_MAX_D */
9680 TCGv_i64 fp0 = tcg_temp_new_i64();
9681 TCGv_i64 fp1 = tcg_temp_new_i64();
9682 gen_load_fpr64(ctx, fp0, fs);
9683 gen_load_fpr64(ctx, fp1, ft);
9684 gen_helper_float_max_d(fp1, cpu_env, fp0, fp1);
9685 gen_store_fpr64(ctx, fp1, fd);
9686 tcg_temp_free_i64(fp1);
9687 tcg_temp_free_i64(fp0);
9688 } else {
9689 /* OPC_RSQRT1_D */
9690 check_cp1_64bitmode(ctx);
9692 TCGv_i64 fp0 = tcg_temp_new_i64();
9694 gen_load_fpr64(ctx, fp0, fs);
9695 gen_helper_float_rsqrt1_d(fp0, cpu_env, fp0);
9696 gen_store_fpr64(ctx, fp0, fd);
9697 tcg_temp_free_i64(fp0);
9700 break;
9701 case OPC_MAXA_D: /* OPC_RSQRT2_D */
9702 if (ctx->insn_flags & ISA_MIPS32R6) {
9703 /* OPC_MAXA_D */
9704 TCGv_i64 fp0 = tcg_temp_new_i64();
9705 TCGv_i64 fp1 = tcg_temp_new_i64();
9706 gen_load_fpr64(ctx, fp0, fs);
9707 gen_load_fpr64(ctx, fp1, ft);
9708 gen_helper_float_maxa_d(fp1, cpu_env, fp0, fp1);
9709 gen_store_fpr64(ctx, fp1, fd);
9710 tcg_temp_free_i64(fp1);
9711 tcg_temp_free_i64(fp0);
9712 } else {
9713 /* OPC_RSQRT2_D */
9714 check_cp1_64bitmode(ctx);
9716 TCGv_i64 fp0 = tcg_temp_new_i64();
9717 TCGv_i64 fp1 = tcg_temp_new_i64();
9719 gen_load_fpr64(ctx, fp0, fs);
9720 gen_load_fpr64(ctx, fp1, ft);
9721 gen_helper_float_rsqrt2_d(fp0, cpu_env, fp0, fp1);
9722 tcg_temp_free_i64(fp1);
9723 gen_store_fpr64(ctx, fp0, fd);
9724 tcg_temp_free_i64(fp0);
9727 break;
9728 case OPC_CMP_F_D:
9729 case OPC_CMP_UN_D:
9730 case OPC_CMP_EQ_D:
9731 case OPC_CMP_UEQ_D:
9732 case OPC_CMP_OLT_D:
9733 case OPC_CMP_ULT_D:
9734 case OPC_CMP_OLE_D:
9735 case OPC_CMP_ULE_D:
9736 case OPC_CMP_SF_D:
9737 case OPC_CMP_NGLE_D:
9738 case OPC_CMP_SEQ_D:
9739 case OPC_CMP_NGL_D:
9740 case OPC_CMP_LT_D:
9741 case OPC_CMP_NGE_D:
9742 case OPC_CMP_LE_D:
9743 case OPC_CMP_NGT_D:
9744 check_insn_opc_removed(ctx, ISA_MIPS32R6);
9745 if (ctx->opcode & (1 << 6)) {
9746 gen_cmpabs_d(ctx, func-48, ft, fs, cc);
9747 } else {
9748 gen_cmp_d(ctx, func-48, ft, fs, cc);
9750 break;
9751 case OPC_CVT_S_D:
9752 check_cp1_registers(ctx, fs);
9754 TCGv_i32 fp32 = tcg_temp_new_i32();
9755 TCGv_i64 fp64 = tcg_temp_new_i64();
9757 gen_load_fpr64(ctx, fp64, fs);
9758 gen_helper_float_cvts_d(fp32, cpu_env, fp64);
9759 tcg_temp_free_i64(fp64);
9760 gen_store_fpr32(ctx, fp32, fd);
9761 tcg_temp_free_i32(fp32);
9763 break;
9764 case OPC_CVT_W_D:
9765 check_cp1_registers(ctx, fs);
9767 TCGv_i32 fp32 = tcg_temp_new_i32();
9768 TCGv_i64 fp64 = tcg_temp_new_i64();
9770 gen_load_fpr64(ctx, fp64, fs);
9771 gen_helper_float_cvtw_d(fp32, cpu_env, fp64);
9772 tcg_temp_free_i64(fp64);
9773 gen_store_fpr32(ctx, fp32, fd);
9774 tcg_temp_free_i32(fp32);
9776 break;
9777 case OPC_CVT_L_D:
9778 check_cp1_64bitmode(ctx);
9780 TCGv_i64 fp0 = tcg_temp_new_i64();
9782 gen_load_fpr64(ctx, fp0, fs);
9783 gen_helper_float_cvtl_d(fp0, cpu_env, fp0);
9784 gen_store_fpr64(ctx, fp0, fd);
9785 tcg_temp_free_i64(fp0);
9787 break;
9788 case OPC_CVT_S_W:
9790 TCGv_i32 fp0 = tcg_temp_new_i32();
9792 gen_load_fpr32(ctx, fp0, fs);
9793 gen_helper_float_cvts_w(fp0, cpu_env, fp0);
9794 gen_store_fpr32(ctx, fp0, fd);
9795 tcg_temp_free_i32(fp0);
9797 break;
9798 case OPC_CVT_D_W:
9799 check_cp1_registers(ctx, fd);
9801 TCGv_i32 fp32 = tcg_temp_new_i32();
9802 TCGv_i64 fp64 = tcg_temp_new_i64();
9804 gen_load_fpr32(ctx, fp32, fs);
9805 gen_helper_float_cvtd_w(fp64, cpu_env, fp32);
9806 tcg_temp_free_i32(fp32);
9807 gen_store_fpr64(ctx, fp64, fd);
9808 tcg_temp_free_i64(fp64);
9810 break;
9811 case OPC_CVT_S_L:
9812 check_cp1_64bitmode(ctx);
9814 TCGv_i32 fp32 = tcg_temp_new_i32();
9815 TCGv_i64 fp64 = tcg_temp_new_i64();
9817 gen_load_fpr64(ctx, fp64, fs);
9818 gen_helper_float_cvts_l(fp32, cpu_env, fp64);
9819 tcg_temp_free_i64(fp64);
9820 gen_store_fpr32(ctx, fp32, fd);
9821 tcg_temp_free_i32(fp32);
9823 break;
9824 case OPC_CVT_D_L:
9825 check_cp1_64bitmode(ctx);
9827 TCGv_i64 fp0 = tcg_temp_new_i64();
9829 gen_load_fpr64(ctx, fp0, fs);
9830 gen_helper_float_cvtd_l(fp0, cpu_env, fp0);
9831 gen_store_fpr64(ctx, fp0, fd);
9832 tcg_temp_free_i64(fp0);
9834 break;
9835 case OPC_CVT_PS_PW:
9836 check_ps(ctx);
9838 TCGv_i64 fp0 = tcg_temp_new_i64();
9840 gen_load_fpr64(ctx, fp0, fs);
9841 gen_helper_float_cvtps_pw(fp0, cpu_env, fp0);
9842 gen_store_fpr64(ctx, fp0, fd);
9843 tcg_temp_free_i64(fp0);
9845 break;
9846 case OPC_ADD_PS:
9847 check_ps(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_add_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);
9859 break;
9860 case OPC_SUB_PS:
9861 check_ps(ctx);
9863 TCGv_i64 fp0 = tcg_temp_new_i64();
9864 TCGv_i64 fp1 = tcg_temp_new_i64();
9866 gen_load_fpr64(ctx, fp0, fs);
9867 gen_load_fpr64(ctx, fp1, ft);
9868 gen_helper_float_sub_ps(fp0, cpu_env, fp0, fp1);
9869 tcg_temp_free_i64(fp1);
9870 gen_store_fpr64(ctx, fp0, fd);
9871 tcg_temp_free_i64(fp0);
9873 break;
9874 case OPC_MUL_PS:
9875 check_ps(ctx);
9877 TCGv_i64 fp0 = tcg_temp_new_i64();
9878 TCGv_i64 fp1 = tcg_temp_new_i64();
9880 gen_load_fpr64(ctx, fp0, fs);
9881 gen_load_fpr64(ctx, fp1, ft);
9882 gen_helper_float_mul_ps(fp0, cpu_env, fp0, fp1);
9883 tcg_temp_free_i64(fp1);
9884 gen_store_fpr64(ctx, fp0, fd);
9885 tcg_temp_free_i64(fp0);
9887 break;
9888 case OPC_ABS_PS:
9889 check_ps(ctx);
9891 TCGv_i64 fp0 = tcg_temp_new_i64();
9893 gen_load_fpr64(ctx, fp0, fs);
9894 gen_helper_float_abs_ps(fp0, fp0);
9895 gen_store_fpr64(ctx, fp0, fd);
9896 tcg_temp_free_i64(fp0);
9898 break;
9899 case OPC_MOV_PS:
9900 check_ps(ctx);
9902 TCGv_i64 fp0 = tcg_temp_new_i64();
9904 gen_load_fpr64(ctx, fp0, fs);
9905 gen_store_fpr64(ctx, fp0, fd);
9906 tcg_temp_free_i64(fp0);
9908 break;
9909 case OPC_NEG_PS:
9910 check_ps(ctx);
9912 TCGv_i64 fp0 = tcg_temp_new_i64();
9914 gen_load_fpr64(ctx, fp0, fs);
9915 gen_helper_float_chs_ps(fp0, fp0);
9916 gen_store_fpr64(ctx, fp0, fd);
9917 tcg_temp_free_i64(fp0);
9919 break;
9920 case OPC_MOVCF_PS:
9921 check_ps(ctx);
9922 gen_movcf_ps(ctx, fs, fd, (ft >> 2) & 0x7, ft & 0x1);
9923 break;
9924 case OPC_MOVZ_PS:
9925 check_ps(ctx);
9927 TCGLabel *l1 = gen_new_label();
9928 TCGv_i64 fp0;
9930 if (ft != 0)
9931 tcg_gen_brcondi_tl(TCG_COND_NE, cpu_gpr[ft], 0, l1);
9932 fp0 = tcg_temp_new_i64();
9933 gen_load_fpr64(ctx, fp0, fs);
9934 gen_store_fpr64(ctx, fp0, fd);
9935 tcg_temp_free_i64(fp0);
9936 gen_set_label(l1);
9938 break;
9939 case OPC_MOVN_PS:
9940 check_ps(ctx);
9942 TCGLabel *l1 = gen_new_label();
9943 TCGv_i64 fp0;
9945 if (ft != 0) {
9946 tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_gpr[ft], 0, l1);
9947 fp0 = tcg_temp_new_i64();
9948 gen_load_fpr64(ctx, fp0, fs);
9949 gen_store_fpr64(ctx, fp0, fd);
9950 tcg_temp_free_i64(fp0);
9951 gen_set_label(l1);
9954 break;
9955 case OPC_ADDR_PS:
9956 check_ps(ctx);
9958 TCGv_i64 fp0 = tcg_temp_new_i64();
9959 TCGv_i64 fp1 = tcg_temp_new_i64();
9961 gen_load_fpr64(ctx, fp0, ft);
9962 gen_load_fpr64(ctx, fp1, fs);
9963 gen_helper_float_addr_ps(fp0, cpu_env, fp0, fp1);
9964 tcg_temp_free_i64(fp1);
9965 gen_store_fpr64(ctx, fp0, fd);
9966 tcg_temp_free_i64(fp0);
9968 break;
9969 case OPC_MULR_PS:
9970 check_ps(ctx);
9972 TCGv_i64 fp0 = tcg_temp_new_i64();
9973 TCGv_i64 fp1 = tcg_temp_new_i64();
9975 gen_load_fpr64(ctx, fp0, ft);
9976 gen_load_fpr64(ctx, fp1, fs);
9977 gen_helper_float_mulr_ps(fp0, cpu_env, fp0, fp1);
9978 tcg_temp_free_i64(fp1);
9979 gen_store_fpr64(ctx, fp0, fd);
9980 tcg_temp_free_i64(fp0);
9982 break;
9983 case OPC_RECIP2_PS:
9984 check_ps(ctx);
9986 TCGv_i64 fp0 = tcg_temp_new_i64();
9987 TCGv_i64 fp1 = tcg_temp_new_i64();
9989 gen_load_fpr64(ctx, fp0, fs);
9990 gen_load_fpr64(ctx, fp1, ft);
9991 gen_helper_float_recip2_ps(fp0, cpu_env, fp0, fp1);
9992 tcg_temp_free_i64(fp1);
9993 gen_store_fpr64(ctx, fp0, fd);
9994 tcg_temp_free_i64(fp0);
9996 break;
9997 case OPC_RECIP1_PS:
9998 check_ps(ctx);
10000 TCGv_i64 fp0 = tcg_temp_new_i64();
10002 gen_load_fpr64(ctx, fp0, fs);
10003 gen_helper_float_recip1_ps(fp0, cpu_env, fp0);
10004 gen_store_fpr64(ctx, fp0, fd);
10005 tcg_temp_free_i64(fp0);
10007 break;
10008 case OPC_RSQRT1_PS:
10009 check_ps(ctx);
10011 TCGv_i64 fp0 = tcg_temp_new_i64();
10013 gen_load_fpr64(ctx, fp0, fs);
10014 gen_helper_float_rsqrt1_ps(fp0, cpu_env, fp0);
10015 gen_store_fpr64(ctx, fp0, fd);
10016 tcg_temp_free_i64(fp0);
10018 break;
10019 case OPC_RSQRT2_PS:
10020 check_ps(ctx);
10022 TCGv_i64 fp0 = tcg_temp_new_i64();
10023 TCGv_i64 fp1 = tcg_temp_new_i64();
10025 gen_load_fpr64(ctx, fp0, fs);
10026 gen_load_fpr64(ctx, fp1, ft);
10027 gen_helper_float_rsqrt2_ps(fp0, cpu_env, fp0, fp1);
10028 tcg_temp_free_i64(fp1);
10029 gen_store_fpr64(ctx, fp0, fd);
10030 tcg_temp_free_i64(fp0);
10032 break;
10033 case OPC_CVT_S_PU:
10034 check_cp1_64bitmode(ctx);
10036 TCGv_i32 fp0 = tcg_temp_new_i32();
10038 gen_load_fpr32h(ctx, fp0, fs);
10039 gen_helper_float_cvts_pu(fp0, cpu_env, fp0);
10040 gen_store_fpr32(ctx, fp0, fd);
10041 tcg_temp_free_i32(fp0);
10043 break;
10044 case OPC_CVT_PW_PS:
10045 check_ps(ctx);
10047 TCGv_i64 fp0 = tcg_temp_new_i64();
10049 gen_load_fpr64(ctx, fp0, fs);
10050 gen_helper_float_cvtpw_ps(fp0, cpu_env, fp0);
10051 gen_store_fpr64(ctx, fp0, fd);
10052 tcg_temp_free_i64(fp0);
10054 break;
10055 case OPC_CVT_S_PL:
10056 check_cp1_64bitmode(ctx);
10058 TCGv_i32 fp0 = tcg_temp_new_i32();
10060 gen_load_fpr32(ctx, fp0, fs);
10061 gen_helper_float_cvts_pl(fp0, cpu_env, fp0);
10062 gen_store_fpr32(ctx, fp0, fd);
10063 tcg_temp_free_i32(fp0);
10065 break;
10066 case OPC_PLL_PS:
10067 check_ps(ctx);
10069 TCGv_i32 fp0 = tcg_temp_new_i32();
10070 TCGv_i32 fp1 = tcg_temp_new_i32();
10072 gen_load_fpr32(ctx, fp0, fs);
10073 gen_load_fpr32(ctx, fp1, ft);
10074 gen_store_fpr32h(ctx, fp0, fd);
10075 gen_store_fpr32(ctx, fp1, fd);
10076 tcg_temp_free_i32(fp0);
10077 tcg_temp_free_i32(fp1);
10079 break;
10080 case OPC_PLU_PS:
10081 check_ps(ctx);
10083 TCGv_i32 fp0 = tcg_temp_new_i32();
10084 TCGv_i32 fp1 = tcg_temp_new_i32();
10086 gen_load_fpr32(ctx, fp0, fs);
10087 gen_load_fpr32h(ctx, fp1, ft);
10088 gen_store_fpr32(ctx, fp1, fd);
10089 gen_store_fpr32h(ctx, fp0, fd);
10090 tcg_temp_free_i32(fp0);
10091 tcg_temp_free_i32(fp1);
10093 break;
10094 case OPC_PUL_PS:
10095 check_ps(ctx);
10097 TCGv_i32 fp0 = tcg_temp_new_i32();
10098 TCGv_i32 fp1 = tcg_temp_new_i32();
10100 gen_load_fpr32h(ctx, fp0, fs);
10101 gen_load_fpr32(ctx, fp1, ft);
10102 gen_store_fpr32(ctx, fp1, fd);
10103 gen_store_fpr32h(ctx, fp0, fd);
10104 tcg_temp_free_i32(fp0);
10105 tcg_temp_free_i32(fp1);
10107 break;
10108 case OPC_PUU_PS:
10109 check_ps(ctx);
10111 TCGv_i32 fp0 = tcg_temp_new_i32();
10112 TCGv_i32 fp1 = tcg_temp_new_i32();
10114 gen_load_fpr32h(ctx, fp0, fs);
10115 gen_load_fpr32h(ctx, fp1, ft);
10116 gen_store_fpr32(ctx, fp1, fd);
10117 gen_store_fpr32h(ctx, fp0, fd);
10118 tcg_temp_free_i32(fp0);
10119 tcg_temp_free_i32(fp1);
10121 break;
10122 case OPC_CMP_F_PS:
10123 case OPC_CMP_UN_PS:
10124 case OPC_CMP_EQ_PS:
10125 case OPC_CMP_UEQ_PS:
10126 case OPC_CMP_OLT_PS:
10127 case OPC_CMP_ULT_PS:
10128 case OPC_CMP_OLE_PS:
10129 case OPC_CMP_ULE_PS:
10130 case OPC_CMP_SF_PS:
10131 case OPC_CMP_NGLE_PS:
10132 case OPC_CMP_SEQ_PS:
10133 case OPC_CMP_NGL_PS:
10134 case OPC_CMP_LT_PS:
10135 case OPC_CMP_NGE_PS:
10136 case OPC_CMP_LE_PS:
10137 case OPC_CMP_NGT_PS:
10138 if (ctx->opcode & (1 << 6)) {
10139 gen_cmpabs_ps(ctx, func-48, ft, fs, cc);
10140 } else {
10141 gen_cmp_ps(ctx, func-48, ft, fs, cc);
10143 break;
10144 default:
10145 MIPS_INVAL("farith");
10146 generate_exception_end(ctx, EXCP_RI);
10147 return;
10151 /* Coprocessor 3 (FPU) */
10152 static void gen_flt3_ldst (DisasContext *ctx, uint32_t opc,
10153 int fd, int fs, int base, int index)
10155 TCGv t0 = tcg_temp_new();
10157 if (base == 0) {
10158 gen_load_gpr(t0, index);
10159 } else if (index == 0) {
10160 gen_load_gpr(t0, base);
10161 } else {
10162 gen_op_addr_add(ctx, t0, cpu_gpr[base], cpu_gpr[index]);
10164 /* Don't do NOP if destination is zero: we must perform the actual
10165 memory access. */
10166 switch (opc) {
10167 case OPC_LWXC1:
10168 check_cop1x(ctx);
10170 TCGv_i32 fp0 = tcg_temp_new_i32();
10172 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TESL);
10173 tcg_gen_trunc_tl_i32(fp0, t0);
10174 gen_store_fpr32(ctx, fp0, fd);
10175 tcg_temp_free_i32(fp0);
10177 break;
10178 case OPC_LDXC1:
10179 check_cop1x(ctx);
10180 check_cp1_registers(ctx, fd);
10182 TCGv_i64 fp0 = tcg_temp_new_i64();
10183 tcg_gen_qemu_ld_i64(fp0, t0, ctx->mem_idx, MO_TEQ);
10184 gen_store_fpr64(ctx, fp0, fd);
10185 tcg_temp_free_i64(fp0);
10187 break;
10188 case OPC_LUXC1:
10189 check_cp1_64bitmode(ctx);
10190 tcg_gen_andi_tl(t0, t0, ~0x7);
10192 TCGv_i64 fp0 = tcg_temp_new_i64();
10194 tcg_gen_qemu_ld_i64(fp0, t0, ctx->mem_idx, MO_TEQ);
10195 gen_store_fpr64(ctx, fp0, fd);
10196 tcg_temp_free_i64(fp0);
10198 break;
10199 case OPC_SWXC1:
10200 check_cop1x(ctx);
10202 TCGv_i32 fp0 = tcg_temp_new_i32();
10203 gen_load_fpr32(ctx, fp0, fs);
10204 tcg_gen_qemu_st_i32(fp0, t0, ctx->mem_idx, MO_TEUL);
10205 tcg_temp_free_i32(fp0);
10207 break;
10208 case OPC_SDXC1:
10209 check_cop1x(ctx);
10210 check_cp1_registers(ctx, fs);
10212 TCGv_i64 fp0 = tcg_temp_new_i64();
10213 gen_load_fpr64(ctx, fp0, fs);
10214 tcg_gen_qemu_st_i64(fp0, t0, ctx->mem_idx, MO_TEQ);
10215 tcg_temp_free_i64(fp0);
10217 break;
10218 case OPC_SUXC1:
10219 check_cp1_64bitmode(ctx);
10220 tcg_gen_andi_tl(t0, t0, ~0x7);
10222 TCGv_i64 fp0 = tcg_temp_new_i64();
10223 gen_load_fpr64(ctx, fp0, fs);
10224 tcg_gen_qemu_st_i64(fp0, t0, ctx->mem_idx, MO_TEQ);
10225 tcg_temp_free_i64(fp0);
10227 break;
10229 tcg_temp_free(t0);
10232 static void gen_flt3_arith (DisasContext *ctx, uint32_t opc,
10233 int fd, int fr, int fs, int ft)
10235 switch (opc) {
10236 case OPC_ALNV_PS:
10237 check_ps(ctx);
10239 TCGv t0 = tcg_temp_local_new();
10240 TCGv_i32 fp = tcg_temp_new_i32();
10241 TCGv_i32 fph = tcg_temp_new_i32();
10242 TCGLabel *l1 = gen_new_label();
10243 TCGLabel *l2 = gen_new_label();
10245 gen_load_gpr(t0, fr);
10246 tcg_gen_andi_tl(t0, t0, 0x7);
10248 tcg_gen_brcondi_tl(TCG_COND_NE, t0, 0, l1);
10249 gen_load_fpr32(ctx, fp, fs);
10250 gen_load_fpr32h(ctx, fph, fs);
10251 gen_store_fpr32(ctx, fp, fd);
10252 gen_store_fpr32h(ctx, fph, fd);
10253 tcg_gen_br(l2);
10254 gen_set_label(l1);
10255 tcg_gen_brcondi_tl(TCG_COND_NE, t0, 4, l2);
10256 tcg_temp_free(t0);
10257 #ifdef TARGET_WORDS_BIGENDIAN
10258 gen_load_fpr32(ctx, fp, fs);
10259 gen_load_fpr32h(ctx, fph, ft);
10260 gen_store_fpr32h(ctx, fp, fd);
10261 gen_store_fpr32(ctx, fph, fd);
10262 #else
10263 gen_load_fpr32h(ctx, fph, fs);
10264 gen_load_fpr32(ctx, fp, ft);
10265 gen_store_fpr32(ctx, fph, fd);
10266 gen_store_fpr32h(ctx, fp, fd);
10267 #endif
10268 gen_set_label(l2);
10269 tcg_temp_free_i32(fp);
10270 tcg_temp_free_i32(fph);
10272 break;
10273 case OPC_MADD_S:
10274 check_cop1x(ctx);
10276 TCGv_i32 fp0 = tcg_temp_new_i32();
10277 TCGv_i32 fp1 = tcg_temp_new_i32();
10278 TCGv_i32 fp2 = tcg_temp_new_i32();
10280 gen_load_fpr32(ctx, fp0, fs);
10281 gen_load_fpr32(ctx, fp1, ft);
10282 gen_load_fpr32(ctx, fp2, fr);
10283 gen_helper_float_madd_s(fp2, cpu_env, fp0, fp1, fp2);
10284 tcg_temp_free_i32(fp0);
10285 tcg_temp_free_i32(fp1);
10286 gen_store_fpr32(ctx, fp2, fd);
10287 tcg_temp_free_i32(fp2);
10289 break;
10290 case OPC_MADD_D:
10291 check_cop1x(ctx);
10292 check_cp1_registers(ctx, fd | fs | ft | fr);
10294 TCGv_i64 fp0 = tcg_temp_new_i64();
10295 TCGv_i64 fp1 = tcg_temp_new_i64();
10296 TCGv_i64 fp2 = tcg_temp_new_i64();
10298 gen_load_fpr64(ctx, fp0, fs);
10299 gen_load_fpr64(ctx, fp1, ft);
10300 gen_load_fpr64(ctx, fp2, fr);
10301 gen_helper_float_madd_d(fp2, cpu_env, fp0, fp1, fp2);
10302 tcg_temp_free_i64(fp0);
10303 tcg_temp_free_i64(fp1);
10304 gen_store_fpr64(ctx, fp2, fd);
10305 tcg_temp_free_i64(fp2);
10307 break;
10308 case OPC_MADD_PS:
10309 check_ps(ctx);
10311 TCGv_i64 fp0 = tcg_temp_new_i64();
10312 TCGv_i64 fp1 = tcg_temp_new_i64();
10313 TCGv_i64 fp2 = tcg_temp_new_i64();
10315 gen_load_fpr64(ctx, fp0, fs);
10316 gen_load_fpr64(ctx, fp1, ft);
10317 gen_load_fpr64(ctx, fp2, fr);
10318 gen_helper_float_madd_ps(fp2, cpu_env, fp0, fp1, fp2);
10319 tcg_temp_free_i64(fp0);
10320 tcg_temp_free_i64(fp1);
10321 gen_store_fpr64(ctx, fp2, fd);
10322 tcg_temp_free_i64(fp2);
10324 break;
10325 case OPC_MSUB_S:
10326 check_cop1x(ctx);
10328 TCGv_i32 fp0 = tcg_temp_new_i32();
10329 TCGv_i32 fp1 = tcg_temp_new_i32();
10330 TCGv_i32 fp2 = tcg_temp_new_i32();
10332 gen_load_fpr32(ctx, fp0, fs);
10333 gen_load_fpr32(ctx, fp1, ft);
10334 gen_load_fpr32(ctx, fp2, fr);
10335 gen_helper_float_msub_s(fp2, cpu_env, fp0, fp1, fp2);
10336 tcg_temp_free_i32(fp0);
10337 tcg_temp_free_i32(fp1);
10338 gen_store_fpr32(ctx, fp2, fd);
10339 tcg_temp_free_i32(fp2);
10341 break;
10342 case OPC_MSUB_D:
10343 check_cop1x(ctx);
10344 check_cp1_registers(ctx, fd | fs | ft | fr);
10346 TCGv_i64 fp0 = tcg_temp_new_i64();
10347 TCGv_i64 fp1 = tcg_temp_new_i64();
10348 TCGv_i64 fp2 = tcg_temp_new_i64();
10350 gen_load_fpr64(ctx, fp0, fs);
10351 gen_load_fpr64(ctx, fp1, ft);
10352 gen_load_fpr64(ctx, fp2, fr);
10353 gen_helper_float_msub_d(fp2, cpu_env, fp0, fp1, fp2);
10354 tcg_temp_free_i64(fp0);
10355 tcg_temp_free_i64(fp1);
10356 gen_store_fpr64(ctx, fp2, fd);
10357 tcg_temp_free_i64(fp2);
10359 break;
10360 case OPC_MSUB_PS:
10361 check_ps(ctx);
10363 TCGv_i64 fp0 = tcg_temp_new_i64();
10364 TCGv_i64 fp1 = tcg_temp_new_i64();
10365 TCGv_i64 fp2 = tcg_temp_new_i64();
10367 gen_load_fpr64(ctx, fp0, fs);
10368 gen_load_fpr64(ctx, fp1, ft);
10369 gen_load_fpr64(ctx, fp2, fr);
10370 gen_helper_float_msub_ps(fp2, cpu_env, fp0, fp1, fp2);
10371 tcg_temp_free_i64(fp0);
10372 tcg_temp_free_i64(fp1);
10373 gen_store_fpr64(ctx, fp2, fd);
10374 tcg_temp_free_i64(fp2);
10376 break;
10377 case OPC_NMADD_S:
10378 check_cop1x(ctx);
10380 TCGv_i32 fp0 = tcg_temp_new_i32();
10381 TCGv_i32 fp1 = tcg_temp_new_i32();
10382 TCGv_i32 fp2 = tcg_temp_new_i32();
10384 gen_load_fpr32(ctx, fp0, fs);
10385 gen_load_fpr32(ctx, fp1, ft);
10386 gen_load_fpr32(ctx, fp2, fr);
10387 gen_helper_float_nmadd_s(fp2, cpu_env, fp0, fp1, fp2);
10388 tcg_temp_free_i32(fp0);
10389 tcg_temp_free_i32(fp1);
10390 gen_store_fpr32(ctx, fp2, fd);
10391 tcg_temp_free_i32(fp2);
10393 break;
10394 case OPC_NMADD_D:
10395 check_cop1x(ctx);
10396 check_cp1_registers(ctx, fd | fs | ft | fr);
10398 TCGv_i64 fp0 = tcg_temp_new_i64();
10399 TCGv_i64 fp1 = tcg_temp_new_i64();
10400 TCGv_i64 fp2 = tcg_temp_new_i64();
10402 gen_load_fpr64(ctx, fp0, fs);
10403 gen_load_fpr64(ctx, fp1, ft);
10404 gen_load_fpr64(ctx, fp2, fr);
10405 gen_helper_float_nmadd_d(fp2, cpu_env, fp0, fp1, fp2);
10406 tcg_temp_free_i64(fp0);
10407 tcg_temp_free_i64(fp1);
10408 gen_store_fpr64(ctx, fp2, fd);
10409 tcg_temp_free_i64(fp2);
10411 break;
10412 case OPC_NMADD_PS:
10413 check_ps(ctx);
10415 TCGv_i64 fp0 = tcg_temp_new_i64();
10416 TCGv_i64 fp1 = tcg_temp_new_i64();
10417 TCGv_i64 fp2 = tcg_temp_new_i64();
10419 gen_load_fpr64(ctx, fp0, fs);
10420 gen_load_fpr64(ctx, fp1, ft);
10421 gen_load_fpr64(ctx, fp2, fr);
10422 gen_helper_float_nmadd_ps(fp2, cpu_env, fp0, fp1, fp2);
10423 tcg_temp_free_i64(fp0);
10424 tcg_temp_free_i64(fp1);
10425 gen_store_fpr64(ctx, fp2, fd);
10426 tcg_temp_free_i64(fp2);
10428 break;
10429 case OPC_NMSUB_S:
10430 check_cop1x(ctx);
10432 TCGv_i32 fp0 = tcg_temp_new_i32();
10433 TCGv_i32 fp1 = tcg_temp_new_i32();
10434 TCGv_i32 fp2 = tcg_temp_new_i32();
10436 gen_load_fpr32(ctx, fp0, fs);
10437 gen_load_fpr32(ctx, fp1, ft);
10438 gen_load_fpr32(ctx, fp2, fr);
10439 gen_helper_float_nmsub_s(fp2, cpu_env, fp0, fp1, fp2);
10440 tcg_temp_free_i32(fp0);
10441 tcg_temp_free_i32(fp1);
10442 gen_store_fpr32(ctx, fp2, fd);
10443 tcg_temp_free_i32(fp2);
10445 break;
10446 case OPC_NMSUB_D:
10447 check_cop1x(ctx);
10448 check_cp1_registers(ctx, fd | fs | ft | fr);
10450 TCGv_i64 fp0 = tcg_temp_new_i64();
10451 TCGv_i64 fp1 = tcg_temp_new_i64();
10452 TCGv_i64 fp2 = tcg_temp_new_i64();
10454 gen_load_fpr64(ctx, fp0, fs);
10455 gen_load_fpr64(ctx, fp1, ft);
10456 gen_load_fpr64(ctx, fp2, fr);
10457 gen_helper_float_nmsub_d(fp2, cpu_env, fp0, fp1, fp2);
10458 tcg_temp_free_i64(fp0);
10459 tcg_temp_free_i64(fp1);
10460 gen_store_fpr64(ctx, fp2, fd);
10461 tcg_temp_free_i64(fp2);
10463 break;
10464 case OPC_NMSUB_PS:
10465 check_ps(ctx);
10467 TCGv_i64 fp0 = tcg_temp_new_i64();
10468 TCGv_i64 fp1 = tcg_temp_new_i64();
10469 TCGv_i64 fp2 = tcg_temp_new_i64();
10471 gen_load_fpr64(ctx, fp0, fs);
10472 gen_load_fpr64(ctx, fp1, ft);
10473 gen_load_fpr64(ctx, fp2, fr);
10474 gen_helper_float_nmsub_ps(fp2, cpu_env, fp0, fp1, fp2);
10475 tcg_temp_free_i64(fp0);
10476 tcg_temp_free_i64(fp1);
10477 gen_store_fpr64(ctx, fp2, fd);
10478 tcg_temp_free_i64(fp2);
10480 break;
10481 default:
10482 MIPS_INVAL("flt3_arith");
10483 generate_exception_end(ctx, EXCP_RI);
10484 return;
10488 static void gen_rdhwr(DisasContext *ctx, int rt, int rd, int sel)
10490 TCGv t0;
10492 #if !defined(CONFIG_USER_ONLY)
10493 /* The Linux kernel will emulate rdhwr if it's not supported natively.
10494 Therefore only check the ISA in system mode. */
10495 check_insn(ctx, ISA_MIPS32R2);
10496 #endif
10497 t0 = tcg_temp_new();
10499 switch (rd) {
10500 case 0:
10501 gen_helper_rdhwr_cpunum(t0, cpu_env);
10502 gen_store_gpr(t0, rt);
10503 break;
10504 case 1:
10505 gen_helper_rdhwr_synci_step(t0, cpu_env);
10506 gen_store_gpr(t0, rt);
10507 break;
10508 case 2:
10509 gen_helper_rdhwr_cc(t0, cpu_env);
10510 gen_store_gpr(t0, rt);
10511 break;
10512 case 3:
10513 gen_helper_rdhwr_ccres(t0, cpu_env);
10514 gen_store_gpr(t0, rt);
10515 break;
10516 case 4:
10517 check_insn(ctx, ISA_MIPS32R6);
10518 if (sel != 0) {
10519 /* Performance counter registers are not implemented other than
10520 * control register 0.
10522 generate_exception(ctx, EXCP_RI);
10524 gen_helper_rdhwr_performance(t0, cpu_env);
10525 gen_store_gpr(t0, rt);
10526 break;
10527 case 5:
10528 check_insn(ctx, ISA_MIPS32R6);
10529 gen_helper_rdhwr_xnp(t0, cpu_env);
10530 gen_store_gpr(t0, rt);
10531 break;
10532 case 29:
10533 #if defined(CONFIG_USER_ONLY)
10534 tcg_gen_ld_tl(t0, cpu_env,
10535 offsetof(CPUMIPSState, active_tc.CP0_UserLocal));
10536 gen_store_gpr(t0, rt);
10537 break;
10538 #else
10539 if ((ctx->hflags & MIPS_HFLAG_CP0) ||
10540 (ctx->hflags & MIPS_HFLAG_HWRENA_ULR)) {
10541 tcg_gen_ld_tl(t0, cpu_env,
10542 offsetof(CPUMIPSState, active_tc.CP0_UserLocal));
10543 gen_store_gpr(t0, rt);
10544 } else {
10545 generate_exception_end(ctx, EXCP_RI);
10547 break;
10548 #endif
10549 default: /* Invalid */
10550 MIPS_INVAL("rdhwr");
10551 generate_exception_end(ctx, EXCP_RI);
10552 break;
10554 tcg_temp_free(t0);
10557 static inline void clear_branch_hflags(DisasContext *ctx)
10559 ctx->hflags &= ~MIPS_HFLAG_BMASK;
10560 if (ctx->bstate == BS_NONE) {
10561 save_cpu_state(ctx, 0);
10562 } else {
10563 /* it is not safe to save ctx->hflags as hflags may be changed
10564 in execution time by the instruction in delay / forbidden slot. */
10565 tcg_gen_andi_i32(hflags, hflags, ~MIPS_HFLAG_BMASK);
10569 static void gen_branch(DisasContext *ctx, int insn_bytes)
10571 if (ctx->hflags & MIPS_HFLAG_BMASK) {
10572 int proc_hflags = ctx->hflags & MIPS_HFLAG_BMASK;
10573 /* Branches completion */
10574 clear_branch_hflags(ctx);
10575 ctx->bstate = BS_BRANCH;
10576 /* FIXME: Need to clear can_do_io. */
10577 switch (proc_hflags & MIPS_HFLAG_BMASK_BASE) {
10578 case MIPS_HFLAG_FBNSLOT:
10579 gen_goto_tb(ctx, 0, ctx->pc + insn_bytes);
10580 break;
10581 case MIPS_HFLAG_B:
10582 /* unconditional branch */
10583 if (proc_hflags & MIPS_HFLAG_BX) {
10584 tcg_gen_xori_i32(hflags, hflags, MIPS_HFLAG_M16);
10586 gen_goto_tb(ctx, 0, ctx->btarget);
10587 break;
10588 case MIPS_HFLAG_BL:
10589 /* blikely taken case */
10590 gen_goto_tb(ctx, 0, ctx->btarget);
10591 break;
10592 case MIPS_HFLAG_BC:
10593 /* Conditional branch */
10595 TCGLabel *l1 = gen_new_label();
10597 tcg_gen_brcondi_tl(TCG_COND_NE, bcond, 0, l1);
10598 gen_goto_tb(ctx, 1, ctx->pc + insn_bytes);
10599 gen_set_label(l1);
10600 gen_goto_tb(ctx, 0, ctx->btarget);
10602 break;
10603 case MIPS_HFLAG_BR:
10604 /* unconditional branch to register */
10605 if (ctx->insn_flags & (ASE_MIPS16 | ASE_MICROMIPS)) {
10606 TCGv t0 = tcg_temp_new();
10607 TCGv_i32 t1 = tcg_temp_new_i32();
10609 tcg_gen_andi_tl(t0, btarget, 0x1);
10610 tcg_gen_trunc_tl_i32(t1, t0);
10611 tcg_temp_free(t0);
10612 tcg_gen_andi_i32(hflags, hflags, ~(uint32_t)MIPS_HFLAG_M16);
10613 tcg_gen_shli_i32(t1, t1, MIPS_HFLAG_M16_SHIFT);
10614 tcg_gen_or_i32(hflags, hflags, t1);
10615 tcg_temp_free_i32(t1);
10617 tcg_gen_andi_tl(cpu_PC, btarget, ~(target_ulong)0x1);
10618 } else {
10619 tcg_gen_mov_tl(cpu_PC, btarget);
10621 if (ctx->singlestep_enabled) {
10622 save_cpu_state(ctx, 0);
10623 gen_helper_raise_exception_debug(cpu_env);
10625 tcg_gen_exit_tb(0);
10626 break;
10627 default:
10628 fprintf(stderr, "unknown branch 0x%x\n", proc_hflags);
10629 abort();
10634 /* Compact Branches */
10635 static void gen_compute_compact_branch(DisasContext *ctx, uint32_t opc,
10636 int rs, int rt, int32_t offset)
10638 int bcond_compute = 0;
10639 TCGv t0 = tcg_temp_new();
10640 TCGv t1 = tcg_temp_new();
10641 int m16_lowbit = (ctx->hflags & MIPS_HFLAG_M16) != 0;
10643 if (ctx->hflags & MIPS_HFLAG_BMASK) {
10644 #ifdef MIPS_DEBUG_DISAS
10645 LOG_DISAS("Branch in delay / forbidden slot at PC 0x" TARGET_FMT_lx
10646 "\n", ctx->pc);
10647 #endif
10648 generate_exception_end(ctx, EXCP_RI);
10649 goto out;
10652 /* Load needed operands and calculate btarget */
10653 switch (opc) {
10654 /* compact branch */
10655 case OPC_BOVC: /* OPC_BEQZALC, OPC_BEQC */
10656 case OPC_BNVC: /* OPC_BNEZALC, OPC_BNEC */
10657 gen_load_gpr(t0, rs);
10658 gen_load_gpr(t1, rt);
10659 bcond_compute = 1;
10660 ctx->btarget = addr_add(ctx, ctx->pc + 4, offset);
10661 if (rs <= rt && rs == 0) {
10662 /* OPC_BEQZALC, OPC_BNEZALC */
10663 tcg_gen_movi_tl(cpu_gpr[31], ctx->pc + 4 + m16_lowbit);
10665 break;
10666 case OPC_BLEZC: /* OPC_BGEZC, OPC_BGEC */
10667 case OPC_BGTZC: /* OPC_BLTZC, OPC_BLTC */
10668 gen_load_gpr(t0, rs);
10669 gen_load_gpr(t1, rt);
10670 bcond_compute = 1;
10671 ctx->btarget = addr_add(ctx, ctx->pc + 4, offset);
10672 break;
10673 case OPC_BLEZALC: /* OPC_BGEZALC, OPC_BGEUC */
10674 case OPC_BGTZALC: /* OPC_BLTZALC, OPC_BLTUC */
10675 if (rs == 0 || rs == rt) {
10676 /* OPC_BLEZALC, OPC_BGEZALC */
10677 /* OPC_BGTZALC, OPC_BLTZALC */
10678 tcg_gen_movi_tl(cpu_gpr[31], ctx->pc + 4 + m16_lowbit);
10680 gen_load_gpr(t0, rs);
10681 gen_load_gpr(t1, rt);
10682 bcond_compute = 1;
10683 ctx->btarget = addr_add(ctx, ctx->pc + 4, offset);
10684 break;
10685 case OPC_BC:
10686 case OPC_BALC:
10687 ctx->btarget = addr_add(ctx, ctx->pc + 4, offset);
10688 break;
10689 case OPC_BEQZC:
10690 case OPC_BNEZC:
10691 if (rs != 0) {
10692 /* OPC_BEQZC, OPC_BNEZC */
10693 gen_load_gpr(t0, rs);
10694 bcond_compute = 1;
10695 ctx->btarget = addr_add(ctx, ctx->pc + 4, offset);
10696 } else {
10697 /* OPC_JIC, OPC_JIALC */
10698 TCGv tbase = tcg_temp_new();
10699 TCGv toffset = tcg_temp_new();
10701 gen_load_gpr(tbase, rt);
10702 tcg_gen_movi_tl(toffset, offset);
10703 gen_op_addr_add(ctx, btarget, tbase, toffset);
10704 tcg_temp_free(tbase);
10705 tcg_temp_free(toffset);
10707 break;
10708 default:
10709 MIPS_INVAL("Compact branch/jump");
10710 generate_exception_end(ctx, EXCP_RI);
10711 goto out;
10714 if (bcond_compute == 0) {
10715 /* Uncoditional compact branch */
10716 switch (opc) {
10717 case OPC_JIALC:
10718 tcg_gen_movi_tl(cpu_gpr[31], ctx->pc + 4 + m16_lowbit);
10719 /* Fallthrough */
10720 case OPC_JIC:
10721 ctx->hflags |= MIPS_HFLAG_BR;
10722 break;
10723 case OPC_BALC:
10724 tcg_gen_movi_tl(cpu_gpr[31], ctx->pc + 4 + m16_lowbit);
10725 /* Fallthrough */
10726 case OPC_BC:
10727 ctx->hflags |= MIPS_HFLAG_B;
10728 break;
10729 default:
10730 MIPS_INVAL("Compact branch/jump");
10731 generate_exception_end(ctx, EXCP_RI);
10732 goto out;
10735 /* Generating branch here as compact branches don't have delay slot */
10736 gen_branch(ctx, 4);
10737 } else {
10738 /* Conditional compact branch */
10739 TCGLabel *fs = gen_new_label();
10740 save_cpu_state(ctx, 0);
10742 switch (opc) {
10743 case OPC_BLEZALC: /* OPC_BGEZALC, OPC_BGEUC */
10744 if (rs == 0 && rt != 0) {
10745 /* OPC_BLEZALC */
10746 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LE), t1, 0, fs);
10747 } else if (rs != 0 && rt != 0 && rs == rt) {
10748 /* OPC_BGEZALC */
10749 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GE), t1, 0, fs);
10750 } else {
10751 /* OPC_BGEUC */
10752 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_GEU), t0, t1, fs);
10754 break;
10755 case OPC_BGTZALC: /* OPC_BLTZALC, OPC_BLTUC */
10756 if (rs == 0 && rt != 0) {
10757 /* OPC_BGTZALC */
10758 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GT), t1, 0, fs);
10759 } else if (rs != 0 && rt != 0 && rs == rt) {
10760 /* OPC_BLTZALC */
10761 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LT), t1, 0, fs);
10762 } else {
10763 /* OPC_BLTUC */
10764 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_LTU), t0, t1, fs);
10766 break;
10767 case OPC_BLEZC: /* OPC_BGEZC, OPC_BGEC */
10768 if (rs == 0 && rt != 0) {
10769 /* OPC_BLEZC */
10770 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LE), t1, 0, fs);
10771 } else if (rs != 0 && rt != 0 && rs == rt) {
10772 /* OPC_BGEZC */
10773 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GE), t1, 0, fs);
10774 } else {
10775 /* OPC_BGEC */
10776 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_GE), t0, t1, fs);
10778 break;
10779 case OPC_BGTZC: /* OPC_BLTZC, OPC_BLTC */
10780 if (rs == 0 && rt != 0) {
10781 /* OPC_BGTZC */
10782 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GT), t1, 0, fs);
10783 } else if (rs != 0 && rt != 0 && rs == rt) {
10784 /* OPC_BLTZC */
10785 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LT), t1, 0, fs);
10786 } else {
10787 /* OPC_BLTC */
10788 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_LT), t0, t1, fs);
10790 break;
10791 case OPC_BOVC: /* OPC_BEQZALC, OPC_BEQC */
10792 case OPC_BNVC: /* OPC_BNEZALC, OPC_BNEC */
10793 if (rs >= rt) {
10794 /* OPC_BOVC, OPC_BNVC */
10795 TCGv t2 = tcg_temp_new();
10796 TCGv t3 = tcg_temp_new();
10797 TCGv t4 = tcg_temp_new();
10798 TCGv input_overflow = tcg_temp_new();
10800 gen_load_gpr(t0, rs);
10801 gen_load_gpr(t1, rt);
10802 tcg_gen_ext32s_tl(t2, t0);
10803 tcg_gen_setcond_tl(TCG_COND_NE, input_overflow, t2, t0);
10804 tcg_gen_ext32s_tl(t3, t1);
10805 tcg_gen_setcond_tl(TCG_COND_NE, t4, t3, t1);
10806 tcg_gen_or_tl(input_overflow, input_overflow, t4);
10808 tcg_gen_add_tl(t4, t2, t3);
10809 tcg_gen_ext32s_tl(t4, t4);
10810 tcg_gen_xor_tl(t2, t2, t3);
10811 tcg_gen_xor_tl(t3, t4, t3);
10812 tcg_gen_andc_tl(t2, t3, t2);
10813 tcg_gen_setcondi_tl(TCG_COND_LT, t4, t2, 0);
10814 tcg_gen_or_tl(t4, t4, input_overflow);
10815 if (opc == OPC_BOVC) {
10816 /* OPC_BOVC */
10817 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_NE), t4, 0, fs);
10818 } else {
10819 /* OPC_BNVC */
10820 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_EQ), t4, 0, fs);
10822 tcg_temp_free(input_overflow);
10823 tcg_temp_free(t4);
10824 tcg_temp_free(t3);
10825 tcg_temp_free(t2);
10826 } else if (rs < rt && rs == 0) {
10827 /* OPC_BEQZALC, OPC_BNEZALC */
10828 if (opc == OPC_BEQZALC) {
10829 /* OPC_BEQZALC */
10830 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_EQ), t1, 0, fs);
10831 } else {
10832 /* OPC_BNEZALC */
10833 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_NE), t1, 0, fs);
10835 } else {
10836 /* OPC_BEQC, OPC_BNEC */
10837 if (opc == OPC_BEQC) {
10838 /* OPC_BEQC */
10839 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_EQ), t0, t1, fs);
10840 } else {
10841 /* OPC_BNEC */
10842 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_NE), t0, t1, fs);
10845 break;
10846 case OPC_BEQZC:
10847 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_EQ), t0, 0, fs);
10848 break;
10849 case OPC_BNEZC:
10850 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_NE), t0, 0, fs);
10851 break;
10852 default:
10853 MIPS_INVAL("Compact conditional branch/jump");
10854 generate_exception_end(ctx, EXCP_RI);
10855 goto out;
10858 /* Generating branch here as compact branches don't have delay slot */
10859 gen_goto_tb(ctx, 1, ctx->btarget);
10860 gen_set_label(fs);
10862 ctx->hflags |= MIPS_HFLAG_FBNSLOT;
10865 out:
10866 tcg_temp_free(t0);
10867 tcg_temp_free(t1);
10870 /* ISA extensions (ASEs) */
10871 /* MIPS16 extension to MIPS32 */
10873 /* MIPS16 major opcodes */
10874 enum {
10875 M16_OPC_ADDIUSP = 0x00,
10876 M16_OPC_ADDIUPC = 0x01,
10877 M16_OPC_B = 0x02,
10878 M16_OPC_JAL = 0x03,
10879 M16_OPC_BEQZ = 0x04,
10880 M16_OPC_BNEQZ = 0x05,
10881 M16_OPC_SHIFT = 0x06,
10882 M16_OPC_LD = 0x07,
10883 M16_OPC_RRIA = 0x08,
10884 M16_OPC_ADDIU8 = 0x09,
10885 M16_OPC_SLTI = 0x0a,
10886 M16_OPC_SLTIU = 0x0b,
10887 M16_OPC_I8 = 0x0c,
10888 M16_OPC_LI = 0x0d,
10889 M16_OPC_CMPI = 0x0e,
10890 M16_OPC_SD = 0x0f,
10891 M16_OPC_LB = 0x10,
10892 M16_OPC_LH = 0x11,
10893 M16_OPC_LWSP = 0x12,
10894 M16_OPC_LW = 0x13,
10895 M16_OPC_LBU = 0x14,
10896 M16_OPC_LHU = 0x15,
10897 M16_OPC_LWPC = 0x16,
10898 M16_OPC_LWU = 0x17,
10899 M16_OPC_SB = 0x18,
10900 M16_OPC_SH = 0x19,
10901 M16_OPC_SWSP = 0x1a,
10902 M16_OPC_SW = 0x1b,
10903 M16_OPC_RRR = 0x1c,
10904 M16_OPC_RR = 0x1d,
10905 M16_OPC_EXTEND = 0x1e,
10906 M16_OPC_I64 = 0x1f
10909 /* I8 funct field */
10910 enum {
10911 I8_BTEQZ = 0x0,
10912 I8_BTNEZ = 0x1,
10913 I8_SWRASP = 0x2,
10914 I8_ADJSP = 0x3,
10915 I8_SVRS = 0x4,
10916 I8_MOV32R = 0x5,
10917 I8_MOVR32 = 0x7
10920 /* RRR f field */
10921 enum {
10922 RRR_DADDU = 0x0,
10923 RRR_ADDU = 0x1,
10924 RRR_DSUBU = 0x2,
10925 RRR_SUBU = 0x3
10928 /* RR funct field */
10929 enum {
10930 RR_JR = 0x00,
10931 RR_SDBBP = 0x01,
10932 RR_SLT = 0x02,
10933 RR_SLTU = 0x03,
10934 RR_SLLV = 0x04,
10935 RR_BREAK = 0x05,
10936 RR_SRLV = 0x06,
10937 RR_SRAV = 0x07,
10938 RR_DSRL = 0x08,
10939 RR_CMP = 0x0a,
10940 RR_NEG = 0x0b,
10941 RR_AND = 0x0c,
10942 RR_OR = 0x0d,
10943 RR_XOR = 0x0e,
10944 RR_NOT = 0x0f,
10945 RR_MFHI = 0x10,
10946 RR_CNVT = 0x11,
10947 RR_MFLO = 0x12,
10948 RR_DSRA = 0x13,
10949 RR_DSLLV = 0x14,
10950 RR_DSRLV = 0x16,
10951 RR_DSRAV = 0x17,
10952 RR_MULT = 0x18,
10953 RR_MULTU = 0x19,
10954 RR_DIV = 0x1a,
10955 RR_DIVU = 0x1b,
10956 RR_DMULT = 0x1c,
10957 RR_DMULTU = 0x1d,
10958 RR_DDIV = 0x1e,
10959 RR_DDIVU = 0x1f
10962 /* I64 funct field */
10963 enum {
10964 I64_LDSP = 0x0,
10965 I64_SDSP = 0x1,
10966 I64_SDRASP = 0x2,
10967 I64_DADJSP = 0x3,
10968 I64_LDPC = 0x4,
10969 I64_DADDIU5 = 0x5,
10970 I64_DADDIUPC = 0x6,
10971 I64_DADDIUSP = 0x7
10974 /* RR ry field for CNVT */
10975 enum {
10976 RR_RY_CNVT_ZEB = 0x0,
10977 RR_RY_CNVT_ZEH = 0x1,
10978 RR_RY_CNVT_ZEW = 0x2,
10979 RR_RY_CNVT_SEB = 0x4,
10980 RR_RY_CNVT_SEH = 0x5,
10981 RR_RY_CNVT_SEW = 0x6,
10984 static int xlat (int r)
10986 static int map[] = { 16, 17, 2, 3, 4, 5, 6, 7 };
10988 return map[r];
10991 static void gen_mips16_save (DisasContext *ctx,
10992 int xsregs, int aregs,
10993 int do_ra, int do_s0, int do_s1,
10994 int framesize)
10996 TCGv t0 = tcg_temp_new();
10997 TCGv t1 = tcg_temp_new();
10998 TCGv t2 = tcg_temp_new();
10999 int args, astatic;
11001 switch (aregs) {
11002 case 0:
11003 case 1:
11004 case 2:
11005 case 3:
11006 case 11:
11007 args = 0;
11008 break;
11009 case 4:
11010 case 5:
11011 case 6:
11012 case 7:
11013 args = 1;
11014 break;
11015 case 8:
11016 case 9:
11017 case 10:
11018 args = 2;
11019 break;
11020 case 12:
11021 case 13:
11022 args = 3;
11023 break;
11024 case 14:
11025 args = 4;
11026 break;
11027 default:
11028 generate_exception_end(ctx, EXCP_RI);
11029 return;
11032 switch (args) {
11033 case 4:
11034 gen_base_offset_addr(ctx, t0, 29, 12);
11035 gen_load_gpr(t1, 7);
11036 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL);
11037 /* Fall through */
11038 case 3:
11039 gen_base_offset_addr(ctx, t0, 29, 8);
11040 gen_load_gpr(t1, 6);
11041 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL);
11042 /* Fall through */
11043 case 2:
11044 gen_base_offset_addr(ctx, t0, 29, 4);
11045 gen_load_gpr(t1, 5);
11046 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL);
11047 /* Fall through */
11048 case 1:
11049 gen_base_offset_addr(ctx, t0, 29, 0);
11050 gen_load_gpr(t1, 4);
11051 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL);
11054 gen_load_gpr(t0, 29);
11056 #define DECR_AND_STORE(reg) do { \
11057 tcg_gen_movi_tl(t2, -4); \
11058 gen_op_addr_add(ctx, t0, t0, t2); \
11059 gen_load_gpr(t1, reg); \
11060 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL); \
11061 } while (0)
11063 if (do_ra) {
11064 DECR_AND_STORE(31);
11067 switch (xsregs) {
11068 case 7:
11069 DECR_AND_STORE(30);
11070 /* Fall through */
11071 case 6:
11072 DECR_AND_STORE(23);
11073 /* Fall through */
11074 case 5:
11075 DECR_AND_STORE(22);
11076 /* Fall through */
11077 case 4:
11078 DECR_AND_STORE(21);
11079 /* Fall through */
11080 case 3:
11081 DECR_AND_STORE(20);
11082 /* Fall through */
11083 case 2:
11084 DECR_AND_STORE(19);
11085 /* Fall through */
11086 case 1:
11087 DECR_AND_STORE(18);
11090 if (do_s1) {
11091 DECR_AND_STORE(17);
11093 if (do_s0) {
11094 DECR_AND_STORE(16);
11097 switch (aregs) {
11098 case 0:
11099 case 4:
11100 case 8:
11101 case 12:
11102 case 14:
11103 astatic = 0;
11104 break;
11105 case 1:
11106 case 5:
11107 case 9:
11108 case 13:
11109 astatic = 1;
11110 break;
11111 case 2:
11112 case 6:
11113 case 10:
11114 astatic = 2;
11115 break;
11116 case 3:
11117 case 7:
11118 astatic = 3;
11119 break;
11120 case 11:
11121 astatic = 4;
11122 break;
11123 default:
11124 generate_exception_end(ctx, EXCP_RI);
11125 return;
11128 if (astatic > 0) {
11129 DECR_AND_STORE(7);
11130 if (astatic > 1) {
11131 DECR_AND_STORE(6);
11132 if (astatic > 2) {
11133 DECR_AND_STORE(5);
11134 if (astatic > 3) {
11135 DECR_AND_STORE(4);
11140 #undef DECR_AND_STORE
11142 tcg_gen_movi_tl(t2, -framesize);
11143 gen_op_addr_add(ctx, cpu_gpr[29], cpu_gpr[29], t2);
11144 tcg_temp_free(t0);
11145 tcg_temp_free(t1);
11146 tcg_temp_free(t2);
11149 static void gen_mips16_restore (DisasContext *ctx,
11150 int xsregs, int aregs,
11151 int do_ra, int do_s0, int do_s1,
11152 int framesize)
11154 int astatic;
11155 TCGv t0 = tcg_temp_new();
11156 TCGv t1 = tcg_temp_new();
11157 TCGv t2 = tcg_temp_new();
11159 tcg_gen_movi_tl(t2, framesize);
11160 gen_op_addr_add(ctx, t0, cpu_gpr[29], t2);
11162 #define DECR_AND_LOAD(reg) do { \
11163 tcg_gen_movi_tl(t2, -4); \
11164 gen_op_addr_add(ctx, t0, t0, t2); \
11165 tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_TESL); \
11166 gen_store_gpr(t1, reg); \
11167 } while (0)
11169 if (do_ra) {
11170 DECR_AND_LOAD(31);
11173 switch (xsregs) {
11174 case 7:
11175 DECR_AND_LOAD(30);
11176 /* Fall through */
11177 case 6:
11178 DECR_AND_LOAD(23);
11179 /* Fall through */
11180 case 5:
11181 DECR_AND_LOAD(22);
11182 /* Fall through */
11183 case 4:
11184 DECR_AND_LOAD(21);
11185 /* Fall through */
11186 case 3:
11187 DECR_AND_LOAD(20);
11188 /* Fall through */
11189 case 2:
11190 DECR_AND_LOAD(19);
11191 /* Fall through */
11192 case 1:
11193 DECR_AND_LOAD(18);
11196 if (do_s1) {
11197 DECR_AND_LOAD(17);
11199 if (do_s0) {
11200 DECR_AND_LOAD(16);
11203 switch (aregs) {
11204 case 0:
11205 case 4:
11206 case 8:
11207 case 12:
11208 case 14:
11209 astatic = 0;
11210 break;
11211 case 1:
11212 case 5:
11213 case 9:
11214 case 13:
11215 astatic = 1;
11216 break;
11217 case 2:
11218 case 6:
11219 case 10:
11220 astatic = 2;
11221 break;
11222 case 3:
11223 case 7:
11224 astatic = 3;
11225 break;
11226 case 11:
11227 astatic = 4;
11228 break;
11229 default:
11230 generate_exception_end(ctx, EXCP_RI);
11231 return;
11234 if (astatic > 0) {
11235 DECR_AND_LOAD(7);
11236 if (astatic > 1) {
11237 DECR_AND_LOAD(6);
11238 if (astatic > 2) {
11239 DECR_AND_LOAD(5);
11240 if (astatic > 3) {
11241 DECR_AND_LOAD(4);
11246 #undef DECR_AND_LOAD
11248 tcg_gen_movi_tl(t2, framesize);
11249 gen_op_addr_add(ctx, cpu_gpr[29], cpu_gpr[29], t2);
11250 tcg_temp_free(t0);
11251 tcg_temp_free(t1);
11252 tcg_temp_free(t2);
11255 static void gen_addiupc (DisasContext *ctx, int rx, int imm,
11256 int is_64_bit, int extended)
11258 TCGv t0;
11260 if (extended && (ctx->hflags & MIPS_HFLAG_BMASK)) {
11261 generate_exception_end(ctx, EXCP_RI);
11262 return;
11265 t0 = tcg_temp_new();
11267 tcg_gen_movi_tl(t0, pc_relative_pc(ctx));
11268 tcg_gen_addi_tl(cpu_gpr[rx], t0, imm);
11269 if (!is_64_bit) {
11270 tcg_gen_ext32s_tl(cpu_gpr[rx], cpu_gpr[rx]);
11273 tcg_temp_free(t0);
11276 static void gen_cache_operation(DisasContext *ctx, uint32_t op, int base,
11277 int16_t offset)
11279 TCGv_i32 t0 = tcg_const_i32(op);
11280 TCGv t1 = tcg_temp_new();
11281 gen_base_offset_addr(ctx, t1, base, offset);
11282 gen_helper_cache(cpu_env, t1, t0);
11285 #if defined(TARGET_MIPS64)
11286 static void decode_i64_mips16 (DisasContext *ctx,
11287 int ry, int funct, int16_t offset,
11288 int extended)
11290 switch (funct) {
11291 case I64_LDSP:
11292 check_insn(ctx, ISA_MIPS3);
11293 check_mips_64(ctx);
11294 offset = extended ? offset : offset << 3;
11295 gen_ld(ctx, OPC_LD, ry, 29, offset);
11296 break;
11297 case I64_SDSP:
11298 check_insn(ctx, ISA_MIPS3);
11299 check_mips_64(ctx);
11300 offset = extended ? offset : offset << 3;
11301 gen_st(ctx, OPC_SD, ry, 29, offset);
11302 break;
11303 case I64_SDRASP:
11304 check_insn(ctx, ISA_MIPS3);
11305 check_mips_64(ctx);
11306 offset = extended ? offset : (ctx->opcode & 0xff) << 3;
11307 gen_st(ctx, OPC_SD, 31, 29, offset);
11308 break;
11309 case I64_DADJSP:
11310 check_insn(ctx, ISA_MIPS3);
11311 check_mips_64(ctx);
11312 offset = extended ? offset : ((int8_t)ctx->opcode) << 3;
11313 gen_arith_imm(ctx, OPC_DADDIU, 29, 29, offset);
11314 break;
11315 case I64_LDPC:
11316 check_insn(ctx, ISA_MIPS3);
11317 check_mips_64(ctx);
11318 if (extended && (ctx->hflags & MIPS_HFLAG_BMASK)) {
11319 generate_exception_end(ctx, EXCP_RI);
11320 } else {
11321 offset = extended ? offset : offset << 3;
11322 gen_ld(ctx, OPC_LDPC, ry, 0, offset);
11324 break;
11325 case I64_DADDIU5:
11326 check_insn(ctx, ISA_MIPS3);
11327 check_mips_64(ctx);
11328 offset = extended ? offset : ((int8_t)(offset << 3)) >> 3;
11329 gen_arith_imm(ctx, OPC_DADDIU, ry, ry, offset);
11330 break;
11331 case I64_DADDIUPC:
11332 check_insn(ctx, ISA_MIPS3);
11333 check_mips_64(ctx);
11334 offset = extended ? offset : offset << 2;
11335 gen_addiupc(ctx, ry, offset, 1, extended);
11336 break;
11337 case I64_DADDIUSP:
11338 check_insn(ctx, ISA_MIPS3);
11339 check_mips_64(ctx);
11340 offset = extended ? offset : offset << 2;
11341 gen_arith_imm(ctx, OPC_DADDIU, ry, 29, offset);
11342 break;
11345 #endif
11347 static int decode_extended_mips16_opc (CPUMIPSState *env, DisasContext *ctx)
11349 int extend = cpu_lduw_code(env, ctx->pc + 2);
11350 int op, rx, ry, funct, sa;
11351 int16_t imm, offset;
11353 ctx->opcode = (ctx->opcode << 16) | extend;
11354 op = (ctx->opcode >> 11) & 0x1f;
11355 sa = (ctx->opcode >> 22) & 0x1f;
11356 funct = (ctx->opcode >> 8) & 0x7;
11357 rx = xlat((ctx->opcode >> 8) & 0x7);
11358 ry = xlat((ctx->opcode >> 5) & 0x7);
11359 offset = imm = (int16_t) (((ctx->opcode >> 16) & 0x1f) << 11
11360 | ((ctx->opcode >> 21) & 0x3f) << 5
11361 | (ctx->opcode & 0x1f));
11363 /* The extended opcodes cleverly reuse the opcodes from their 16-bit
11364 counterparts. */
11365 switch (op) {
11366 case M16_OPC_ADDIUSP:
11367 gen_arith_imm(ctx, OPC_ADDIU, rx, 29, imm);
11368 break;
11369 case M16_OPC_ADDIUPC:
11370 gen_addiupc(ctx, rx, imm, 0, 1);
11371 break;
11372 case M16_OPC_B:
11373 gen_compute_branch(ctx, OPC_BEQ, 4, 0, 0, offset << 1, 0);
11374 /* No delay slot, so just process as a normal instruction */
11375 break;
11376 case M16_OPC_BEQZ:
11377 gen_compute_branch(ctx, OPC_BEQ, 4, rx, 0, offset << 1, 0);
11378 /* No delay slot, so just process as a normal instruction */
11379 break;
11380 case M16_OPC_BNEQZ:
11381 gen_compute_branch(ctx, OPC_BNE, 4, rx, 0, offset << 1, 0);
11382 /* No delay slot, so just process as a normal instruction */
11383 break;
11384 case M16_OPC_SHIFT:
11385 switch (ctx->opcode & 0x3) {
11386 case 0x0:
11387 gen_shift_imm(ctx, OPC_SLL, rx, ry, sa);
11388 break;
11389 case 0x1:
11390 #if defined(TARGET_MIPS64)
11391 check_mips_64(ctx);
11392 gen_shift_imm(ctx, OPC_DSLL, rx, ry, sa);
11393 #else
11394 generate_exception_end(ctx, EXCP_RI);
11395 #endif
11396 break;
11397 case 0x2:
11398 gen_shift_imm(ctx, OPC_SRL, rx, ry, sa);
11399 break;
11400 case 0x3:
11401 gen_shift_imm(ctx, OPC_SRA, rx, ry, sa);
11402 break;
11404 break;
11405 #if defined(TARGET_MIPS64)
11406 case M16_OPC_LD:
11407 check_insn(ctx, ISA_MIPS3);
11408 check_mips_64(ctx);
11409 gen_ld(ctx, OPC_LD, ry, rx, offset);
11410 break;
11411 #endif
11412 case M16_OPC_RRIA:
11413 imm = ctx->opcode & 0xf;
11414 imm = imm | ((ctx->opcode >> 20) & 0x7f) << 4;
11415 imm = imm | ((ctx->opcode >> 16) & 0xf) << 11;
11416 imm = (int16_t) (imm << 1) >> 1;
11417 if ((ctx->opcode >> 4) & 0x1) {
11418 #if defined(TARGET_MIPS64)
11419 check_mips_64(ctx);
11420 gen_arith_imm(ctx, OPC_DADDIU, ry, rx, imm);
11421 #else
11422 generate_exception_end(ctx, EXCP_RI);
11423 #endif
11424 } else {
11425 gen_arith_imm(ctx, OPC_ADDIU, ry, rx, imm);
11427 break;
11428 case M16_OPC_ADDIU8:
11429 gen_arith_imm(ctx, OPC_ADDIU, rx, rx, imm);
11430 break;
11431 case M16_OPC_SLTI:
11432 gen_slt_imm(ctx, OPC_SLTI, 24, rx, imm);
11433 break;
11434 case M16_OPC_SLTIU:
11435 gen_slt_imm(ctx, OPC_SLTIU, 24, rx, imm);
11436 break;
11437 case M16_OPC_I8:
11438 switch (funct) {
11439 case I8_BTEQZ:
11440 gen_compute_branch(ctx, OPC_BEQ, 4, 24, 0, offset << 1, 0);
11441 break;
11442 case I8_BTNEZ:
11443 gen_compute_branch(ctx, OPC_BNE, 4, 24, 0, offset << 1, 0);
11444 break;
11445 case I8_SWRASP:
11446 gen_st(ctx, OPC_SW, 31, 29, imm);
11447 break;
11448 case I8_ADJSP:
11449 gen_arith_imm(ctx, OPC_ADDIU, 29, 29, imm);
11450 break;
11451 case I8_SVRS:
11452 check_insn(ctx, ISA_MIPS32);
11454 int xsregs = (ctx->opcode >> 24) & 0x7;
11455 int aregs = (ctx->opcode >> 16) & 0xf;
11456 int do_ra = (ctx->opcode >> 6) & 0x1;
11457 int do_s0 = (ctx->opcode >> 5) & 0x1;
11458 int do_s1 = (ctx->opcode >> 4) & 0x1;
11459 int framesize = (((ctx->opcode >> 20) & 0xf) << 4
11460 | (ctx->opcode & 0xf)) << 3;
11462 if (ctx->opcode & (1 << 7)) {
11463 gen_mips16_save(ctx, xsregs, aregs,
11464 do_ra, do_s0, do_s1,
11465 framesize);
11466 } else {
11467 gen_mips16_restore(ctx, xsregs, aregs,
11468 do_ra, do_s0, do_s1,
11469 framesize);
11472 break;
11473 default:
11474 generate_exception_end(ctx, EXCP_RI);
11475 break;
11477 break;
11478 case M16_OPC_LI:
11479 tcg_gen_movi_tl(cpu_gpr[rx], (uint16_t) imm);
11480 break;
11481 case M16_OPC_CMPI:
11482 tcg_gen_xori_tl(cpu_gpr[24], cpu_gpr[rx], (uint16_t) imm);
11483 break;
11484 #if defined(TARGET_MIPS64)
11485 case M16_OPC_SD:
11486 check_insn(ctx, ISA_MIPS3);
11487 check_mips_64(ctx);
11488 gen_st(ctx, OPC_SD, ry, rx, offset);
11489 break;
11490 #endif
11491 case M16_OPC_LB:
11492 gen_ld(ctx, OPC_LB, ry, rx, offset);
11493 break;
11494 case M16_OPC_LH:
11495 gen_ld(ctx, OPC_LH, ry, rx, offset);
11496 break;
11497 case M16_OPC_LWSP:
11498 gen_ld(ctx, OPC_LW, rx, 29, offset);
11499 break;
11500 case M16_OPC_LW:
11501 gen_ld(ctx, OPC_LW, ry, rx, offset);
11502 break;
11503 case M16_OPC_LBU:
11504 gen_ld(ctx, OPC_LBU, ry, rx, offset);
11505 break;
11506 case M16_OPC_LHU:
11507 gen_ld(ctx, OPC_LHU, ry, rx, offset);
11508 break;
11509 case M16_OPC_LWPC:
11510 gen_ld(ctx, OPC_LWPC, rx, 0, offset);
11511 break;
11512 #if defined(TARGET_MIPS64)
11513 case M16_OPC_LWU:
11514 check_insn(ctx, ISA_MIPS3);
11515 check_mips_64(ctx);
11516 gen_ld(ctx, OPC_LWU, ry, rx, offset);
11517 break;
11518 #endif
11519 case M16_OPC_SB:
11520 gen_st(ctx, OPC_SB, ry, rx, offset);
11521 break;
11522 case M16_OPC_SH:
11523 gen_st(ctx, OPC_SH, ry, rx, offset);
11524 break;
11525 case M16_OPC_SWSP:
11526 gen_st(ctx, OPC_SW, rx, 29, offset);
11527 break;
11528 case M16_OPC_SW:
11529 gen_st(ctx, OPC_SW, ry, rx, offset);
11530 break;
11531 #if defined(TARGET_MIPS64)
11532 case M16_OPC_I64:
11533 decode_i64_mips16(ctx, ry, funct, offset, 1);
11534 break;
11535 #endif
11536 default:
11537 generate_exception_end(ctx, EXCP_RI);
11538 break;
11541 return 4;
11544 static inline bool is_uhi(int sdbbp_code)
11546 #ifdef CONFIG_USER_ONLY
11547 return false;
11548 #else
11549 return semihosting_enabled() && sdbbp_code == 1;
11550 #endif
11553 static int decode_mips16_opc (CPUMIPSState *env, DisasContext *ctx)
11555 int rx, ry;
11556 int sa;
11557 int op, cnvt_op, op1, offset;
11558 int funct;
11559 int n_bytes;
11561 op = (ctx->opcode >> 11) & 0x1f;
11562 sa = (ctx->opcode >> 2) & 0x7;
11563 sa = sa == 0 ? 8 : sa;
11564 rx = xlat((ctx->opcode >> 8) & 0x7);
11565 cnvt_op = (ctx->opcode >> 5) & 0x7;
11566 ry = xlat((ctx->opcode >> 5) & 0x7);
11567 op1 = offset = ctx->opcode & 0x1f;
11569 n_bytes = 2;
11571 switch (op) {
11572 case M16_OPC_ADDIUSP:
11574 int16_t imm = ((uint8_t) ctx->opcode) << 2;
11576 gen_arith_imm(ctx, OPC_ADDIU, rx, 29, imm);
11578 break;
11579 case M16_OPC_ADDIUPC:
11580 gen_addiupc(ctx, rx, ((uint8_t) ctx->opcode) << 2, 0, 0);
11581 break;
11582 case M16_OPC_B:
11583 offset = (ctx->opcode & 0x7ff) << 1;
11584 offset = (int16_t)(offset << 4) >> 4;
11585 gen_compute_branch(ctx, OPC_BEQ, 2, 0, 0, offset, 0);
11586 /* No delay slot, so just process as a normal instruction */
11587 break;
11588 case M16_OPC_JAL:
11589 offset = cpu_lduw_code(env, ctx->pc + 2);
11590 offset = (((ctx->opcode & 0x1f) << 21)
11591 | ((ctx->opcode >> 5) & 0x1f) << 16
11592 | offset) << 2;
11593 op = ((ctx->opcode >> 10) & 0x1) ? OPC_JALX : OPC_JAL;
11594 gen_compute_branch(ctx, op, 4, rx, ry, offset, 2);
11595 n_bytes = 4;
11596 break;
11597 case M16_OPC_BEQZ:
11598 gen_compute_branch(ctx, OPC_BEQ, 2, rx, 0,
11599 ((int8_t)ctx->opcode) << 1, 0);
11600 /* No delay slot, so just process as a normal instruction */
11601 break;
11602 case M16_OPC_BNEQZ:
11603 gen_compute_branch(ctx, OPC_BNE, 2, rx, 0,
11604 ((int8_t)ctx->opcode) << 1, 0);
11605 /* No delay slot, so just process as a normal instruction */
11606 break;
11607 case M16_OPC_SHIFT:
11608 switch (ctx->opcode & 0x3) {
11609 case 0x0:
11610 gen_shift_imm(ctx, OPC_SLL, rx, ry, sa);
11611 break;
11612 case 0x1:
11613 #if defined(TARGET_MIPS64)
11614 check_insn(ctx, ISA_MIPS3);
11615 check_mips_64(ctx);
11616 gen_shift_imm(ctx, OPC_DSLL, rx, ry, sa);
11617 #else
11618 generate_exception_end(ctx, EXCP_RI);
11619 #endif
11620 break;
11621 case 0x2:
11622 gen_shift_imm(ctx, OPC_SRL, rx, ry, sa);
11623 break;
11624 case 0x3:
11625 gen_shift_imm(ctx, OPC_SRA, rx, ry, sa);
11626 break;
11628 break;
11629 #if defined(TARGET_MIPS64)
11630 case M16_OPC_LD:
11631 check_insn(ctx, ISA_MIPS3);
11632 check_mips_64(ctx);
11633 gen_ld(ctx, OPC_LD, ry, rx, offset << 3);
11634 break;
11635 #endif
11636 case M16_OPC_RRIA:
11638 int16_t imm = (int8_t)((ctx->opcode & 0xf) << 4) >> 4;
11640 if ((ctx->opcode >> 4) & 1) {
11641 #if defined(TARGET_MIPS64)
11642 check_insn(ctx, ISA_MIPS3);
11643 check_mips_64(ctx);
11644 gen_arith_imm(ctx, OPC_DADDIU, ry, rx, imm);
11645 #else
11646 generate_exception_end(ctx, EXCP_RI);
11647 #endif
11648 } else {
11649 gen_arith_imm(ctx, OPC_ADDIU, ry, rx, imm);
11652 break;
11653 case M16_OPC_ADDIU8:
11655 int16_t imm = (int8_t) ctx->opcode;
11657 gen_arith_imm(ctx, OPC_ADDIU, rx, rx, imm);
11659 break;
11660 case M16_OPC_SLTI:
11662 int16_t imm = (uint8_t) ctx->opcode;
11663 gen_slt_imm(ctx, OPC_SLTI, 24, rx, imm);
11665 break;
11666 case M16_OPC_SLTIU:
11668 int16_t imm = (uint8_t) ctx->opcode;
11669 gen_slt_imm(ctx, OPC_SLTIU, 24, rx, imm);
11671 break;
11672 case M16_OPC_I8:
11674 int reg32;
11676 funct = (ctx->opcode >> 8) & 0x7;
11677 switch (funct) {
11678 case I8_BTEQZ:
11679 gen_compute_branch(ctx, OPC_BEQ, 2, 24, 0,
11680 ((int8_t)ctx->opcode) << 1, 0);
11681 break;
11682 case I8_BTNEZ:
11683 gen_compute_branch(ctx, OPC_BNE, 2, 24, 0,
11684 ((int8_t)ctx->opcode) << 1, 0);
11685 break;
11686 case I8_SWRASP:
11687 gen_st(ctx, OPC_SW, 31, 29, (ctx->opcode & 0xff) << 2);
11688 break;
11689 case I8_ADJSP:
11690 gen_arith_imm(ctx, OPC_ADDIU, 29, 29,
11691 ((int8_t)ctx->opcode) << 3);
11692 break;
11693 case I8_SVRS:
11694 check_insn(ctx, ISA_MIPS32);
11696 int do_ra = ctx->opcode & (1 << 6);
11697 int do_s0 = ctx->opcode & (1 << 5);
11698 int do_s1 = ctx->opcode & (1 << 4);
11699 int framesize = ctx->opcode & 0xf;
11701 if (framesize == 0) {
11702 framesize = 128;
11703 } else {
11704 framesize = framesize << 3;
11707 if (ctx->opcode & (1 << 7)) {
11708 gen_mips16_save(ctx, 0, 0,
11709 do_ra, do_s0, do_s1, framesize);
11710 } else {
11711 gen_mips16_restore(ctx, 0, 0,
11712 do_ra, do_s0, do_s1, framesize);
11715 break;
11716 case I8_MOV32R:
11718 int rz = xlat(ctx->opcode & 0x7);
11720 reg32 = (((ctx->opcode >> 3) & 0x3) << 3) |
11721 ((ctx->opcode >> 5) & 0x7);
11722 gen_arith(ctx, OPC_ADDU, reg32, rz, 0);
11724 break;
11725 case I8_MOVR32:
11726 reg32 = ctx->opcode & 0x1f;
11727 gen_arith(ctx, OPC_ADDU, ry, reg32, 0);
11728 break;
11729 default:
11730 generate_exception_end(ctx, EXCP_RI);
11731 break;
11734 break;
11735 case M16_OPC_LI:
11737 int16_t imm = (uint8_t) ctx->opcode;
11739 gen_arith_imm(ctx, OPC_ADDIU, rx, 0, imm);
11741 break;
11742 case M16_OPC_CMPI:
11744 int16_t imm = (uint8_t) ctx->opcode;
11745 gen_logic_imm(ctx, OPC_XORI, 24, rx, imm);
11747 break;
11748 #if defined(TARGET_MIPS64)
11749 case M16_OPC_SD:
11750 check_insn(ctx, ISA_MIPS3);
11751 check_mips_64(ctx);
11752 gen_st(ctx, OPC_SD, ry, rx, offset << 3);
11753 break;
11754 #endif
11755 case M16_OPC_LB:
11756 gen_ld(ctx, OPC_LB, ry, rx, offset);
11757 break;
11758 case M16_OPC_LH:
11759 gen_ld(ctx, OPC_LH, ry, rx, offset << 1);
11760 break;
11761 case M16_OPC_LWSP:
11762 gen_ld(ctx, OPC_LW, rx, 29, ((uint8_t)ctx->opcode) << 2);
11763 break;
11764 case M16_OPC_LW:
11765 gen_ld(ctx, OPC_LW, ry, rx, offset << 2);
11766 break;
11767 case M16_OPC_LBU:
11768 gen_ld(ctx, OPC_LBU, ry, rx, offset);
11769 break;
11770 case M16_OPC_LHU:
11771 gen_ld(ctx, OPC_LHU, ry, rx, offset << 1);
11772 break;
11773 case M16_OPC_LWPC:
11774 gen_ld(ctx, OPC_LWPC, rx, 0, ((uint8_t)ctx->opcode) << 2);
11775 break;
11776 #if defined (TARGET_MIPS64)
11777 case M16_OPC_LWU:
11778 check_insn(ctx, ISA_MIPS3);
11779 check_mips_64(ctx);
11780 gen_ld(ctx, OPC_LWU, ry, rx, offset << 2);
11781 break;
11782 #endif
11783 case M16_OPC_SB:
11784 gen_st(ctx, OPC_SB, ry, rx, offset);
11785 break;
11786 case M16_OPC_SH:
11787 gen_st(ctx, OPC_SH, ry, rx, offset << 1);
11788 break;
11789 case M16_OPC_SWSP:
11790 gen_st(ctx, OPC_SW, rx, 29, ((uint8_t)ctx->opcode) << 2);
11791 break;
11792 case M16_OPC_SW:
11793 gen_st(ctx, OPC_SW, ry, rx, offset << 2);
11794 break;
11795 case M16_OPC_RRR:
11797 int rz = xlat((ctx->opcode >> 2) & 0x7);
11798 int mips32_op;
11800 switch (ctx->opcode & 0x3) {
11801 case RRR_ADDU:
11802 mips32_op = OPC_ADDU;
11803 break;
11804 case RRR_SUBU:
11805 mips32_op = OPC_SUBU;
11806 break;
11807 #if defined(TARGET_MIPS64)
11808 case RRR_DADDU:
11809 mips32_op = OPC_DADDU;
11810 check_insn(ctx, ISA_MIPS3);
11811 check_mips_64(ctx);
11812 break;
11813 case RRR_DSUBU:
11814 mips32_op = OPC_DSUBU;
11815 check_insn(ctx, ISA_MIPS3);
11816 check_mips_64(ctx);
11817 break;
11818 #endif
11819 default:
11820 generate_exception_end(ctx, EXCP_RI);
11821 goto done;
11824 gen_arith(ctx, mips32_op, rz, rx, ry);
11825 done:
11828 break;
11829 case M16_OPC_RR:
11830 switch (op1) {
11831 case RR_JR:
11833 int nd = (ctx->opcode >> 7) & 0x1;
11834 int link = (ctx->opcode >> 6) & 0x1;
11835 int ra = (ctx->opcode >> 5) & 0x1;
11837 if (nd) {
11838 check_insn(ctx, ISA_MIPS32);
11841 if (link) {
11842 op = OPC_JALR;
11843 } else {
11844 op = OPC_JR;
11847 gen_compute_branch(ctx, op, 2, ra ? 31 : rx, 31, 0,
11848 (nd ? 0 : 2));
11850 break;
11851 case RR_SDBBP:
11852 if (is_uhi(extract32(ctx->opcode, 5, 6))) {
11853 gen_helper_do_semihosting(cpu_env);
11854 } else {
11855 /* XXX: not clear which exception should be raised
11856 * when in debug mode...
11858 check_insn(ctx, ISA_MIPS32);
11859 generate_exception_end(ctx, EXCP_DBp);
11861 break;
11862 case RR_SLT:
11863 gen_slt(ctx, OPC_SLT, 24, rx, ry);
11864 break;
11865 case RR_SLTU:
11866 gen_slt(ctx, OPC_SLTU, 24, rx, ry);
11867 break;
11868 case RR_BREAK:
11869 generate_exception_end(ctx, EXCP_BREAK);
11870 break;
11871 case RR_SLLV:
11872 gen_shift(ctx, OPC_SLLV, ry, rx, ry);
11873 break;
11874 case RR_SRLV:
11875 gen_shift(ctx, OPC_SRLV, ry, rx, ry);
11876 break;
11877 case RR_SRAV:
11878 gen_shift(ctx, OPC_SRAV, ry, rx, ry);
11879 break;
11880 #if defined (TARGET_MIPS64)
11881 case RR_DSRL:
11882 check_insn(ctx, ISA_MIPS3);
11883 check_mips_64(ctx);
11884 gen_shift_imm(ctx, OPC_DSRL, ry, ry, sa);
11885 break;
11886 #endif
11887 case RR_CMP:
11888 gen_logic(ctx, OPC_XOR, 24, rx, ry);
11889 break;
11890 case RR_NEG:
11891 gen_arith(ctx, OPC_SUBU, rx, 0, ry);
11892 break;
11893 case RR_AND:
11894 gen_logic(ctx, OPC_AND, rx, rx, ry);
11895 break;
11896 case RR_OR:
11897 gen_logic(ctx, OPC_OR, rx, rx, ry);
11898 break;
11899 case RR_XOR:
11900 gen_logic(ctx, OPC_XOR, rx, rx, ry);
11901 break;
11902 case RR_NOT:
11903 gen_logic(ctx, OPC_NOR, rx, ry, 0);
11904 break;
11905 case RR_MFHI:
11906 gen_HILO(ctx, OPC_MFHI, 0, rx);
11907 break;
11908 case RR_CNVT:
11909 check_insn(ctx, ISA_MIPS32);
11910 switch (cnvt_op) {
11911 case RR_RY_CNVT_ZEB:
11912 tcg_gen_ext8u_tl(cpu_gpr[rx], cpu_gpr[rx]);
11913 break;
11914 case RR_RY_CNVT_ZEH:
11915 tcg_gen_ext16u_tl(cpu_gpr[rx], cpu_gpr[rx]);
11916 break;
11917 case RR_RY_CNVT_SEB:
11918 tcg_gen_ext8s_tl(cpu_gpr[rx], cpu_gpr[rx]);
11919 break;
11920 case RR_RY_CNVT_SEH:
11921 tcg_gen_ext16s_tl(cpu_gpr[rx], cpu_gpr[rx]);
11922 break;
11923 #if defined (TARGET_MIPS64)
11924 case RR_RY_CNVT_ZEW:
11925 check_insn(ctx, ISA_MIPS64);
11926 check_mips_64(ctx);
11927 tcg_gen_ext32u_tl(cpu_gpr[rx], cpu_gpr[rx]);
11928 break;
11929 case RR_RY_CNVT_SEW:
11930 check_insn(ctx, ISA_MIPS64);
11931 check_mips_64(ctx);
11932 tcg_gen_ext32s_tl(cpu_gpr[rx], cpu_gpr[rx]);
11933 break;
11934 #endif
11935 default:
11936 generate_exception_end(ctx, EXCP_RI);
11937 break;
11939 break;
11940 case RR_MFLO:
11941 gen_HILO(ctx, OPC_MFLO, 0, rx);
11942 break;
11943 #if defined (TARGET_MIPS64)
11944 case RR_DSRA:
11945 check_insn(ctx, ISA_MIPS3);
11946 check_mips_64(ctx);
11947 gen_shift_imm(ctx, OPC_DSRA, ry, ry, sa);
11948 break;
11949 case RR_DSLLV:
11950 check_insn(ctx, ISA_MIPS3);
11951 check_mips_64(ctx);
11952 gen_shift(ctx, OPC_DSLLV, ry, rx, ry);
11953 break;
11954 case RR_DSRLV:
11955 check_insn(ctx, ISA_MIPS3);
11956 check_mips_64(ctx);
11957 gen_shift(ctx, OPC_DSRLV, ry, rx, ry);
11958 break;
11959 case RR_DSRAV:
11960 check_insn(ctx, ISA_MIPS3);
11961 check_mips_64(ctx);
11962 gen_shift(ctx, OPC_DSRAV, ry, rx, ry);
11963 break;
11964 #endif
11965 case RR_MULT:
11966 gen_muldiv(ctx, OPC_MULT, 0, rx, ry);
11967 break;
11968 case RR_MULTU:
11969 gen_muldiv(ctx, OPC_MULTU, 0, rx, ry);
11970 break;
11971 case RR_DIV:
11972 gen_muldiv(ctx, OPC_DIV, 0, rx, ry);
11973 break;
11974 case RR_DIVU:
11975 gen_muldiv(ctx, OPC_DIVU, 0, rx, ry);
11976 break;
11977 #if defined (TARGET_MIPS64)
11978 case RR_DMULT:
11979 check_insn(ctx, ISA_MIPS3);
11980 check_mips_64(ctx);
11981 gen_muldiv(ctx, OPC_DMULT, 0, rx, ry);
11982 break;
11983 case RR_DMULTU:
11984 check_insn(ctx, ISA_MIPS3);
11985 check_mips_64(ctx);
11986 gen_muldiv(ctx, OPC_DMULTU, 0, rx, ry);
11987 break;
11988 case RR_DDIV:
11989 check_insn(ctx, ISA_MIPS3);
11990 check_mips_64(ctx);
11991 gen_muldiv(ctx, OPC_DDIV, 0, rx, ry);
11992 break;
11993 case RR_DDIVU:
11994 check_insn(ctx, ISA_MIPS3);
11995 check_mips_64(ctx);
11996 gen_muldiv(ctx, OPC_DDIVU, 0, rx, ry);
11997 break;
11998 #endif
11999 default:
12000 generate_exception_end(ctx, EXCP_RI);
12001 break;
12003 break;
12004 case M16_OPC_EXTEND:
12005 decode_extended_mips16_opc(env, ctx);
12006 n_bytes = 4;
12007 break;
12008 #if defined(TARGET_MIPS64)
12009 case M16_OPC_I64:
12010 funct = (ctx->opcode >> 8) & 0x7;
12011 decode_i64_mips16(ctx, ry, funct, offset, 0);
12012 break;
12013 #endif
12014 default:
12015 generate_exception_end(ctx, EXCP_RI);
12016 break;
12019 return n_bytes;
12022 /* microMIPS extension to MIPS32/MIPS64 */
12025 * microMIPS32/microMIPS64 major opcodes
12027 * 1. MIPS Architecture for Programmers Volume II-B:
12028 * The microMIPS32 Instruction Set (Revision 3.05)
12030 * Table 6.2 microMIPS32 Encoding of Major Opcode Field
12032 * 2. MIPS Architecture For Programmers Volume II-A:
12033 * The MIPS64 Instruction Set (Revision 3.51)
12036 enum {
12037 POOL32A = 0x00,
12038 POOL16A = 0x01,
12039 LBU16 = 0x02,
12040 MOVE16 = 0x03,
12041 ADDI32 = 0x04,
12042 R6_LUI = 0x04,
12043 AUI = 0x04,
12044 LBU32 = 0x05,
12045 SB32 = 0x06,
12046 LB32 = 0x07,
12048 POOL32B = 0x08,
12049 POOL16B = 0x09,
12050 LHU16 = 0x0a,
12051 ANDI16 = 0x0b,
12052 ADDIU32 = 0x0c,
12053 LHU32 = 0x0d,
12054 SH32 = 0x0e,
12055 LH32 = 0x0f,
12057 POOL32I = 0x10,
12058 POOL16C = 0x11,
12059 LWSP16 = 0x12,
12060 POOL16D = 0x13,
12061 ORI32 = 0x14,
12062 POOL32F = 0x15,
12063 POOL32S = 0x16, /* MIPS64 */
12064 DADDIU32 = 0x17, /* MIPS64 */
12066 POOL32C = 0x18,
12067 LWGP16 = 0x19,
12068 LW16 = 0x1a,
12069 POOL16E = 0x1b,
12070 XORI32 = 0x1c,
12071 JALS32 = 0x1d,
12072 BOVC = 0x1d,
12073 BEQC = 0x1d,
12074 BEQZALC = 0x1d,
12075 ADDIUPC = 0x1e,
12076 PCREL = 0x1e,
12077 BNVC = 0x1f,
12078 BNEC = 0x1f,
12079 BNEZALC = 0x1f,
12081 R6_BEQZC = 0x20,
12082 JIC = 0x20,
12083 POOL16F = 0x21,
12084 SB16 = 0x22,
12085 BEQZ16 = 0x23,
12086 BEQZC16 = 0x23,
12087 SLTI32 = 0x24,
12088 BEQ32 = 0x25,
12089 BC = 0x25,
12090 SWC132 = 0x26,
12091 LWC132 = 0x27,
12093 /* 0x29 is reserved */
12094 RES_29 = 0x29,
12095 R6_BNEZC = 0x28,
12096 JIALC = 0x28,
12097 SH16 = 0x2a,
12098 BNEZ16 = 0x2b,
12099 BNEZC16 = 0x2b,
12100 SLTIU32 = 0x2c,
12101 BNE32 = 0x2d,
12102 BALC = 0x2d,
12103 SDC132 = 0x2e,
12104 LDC132 = 0x2f,
12106 /* 0x31 is reserved */
12107 RES_31 = 0x31,
12108 BLEZALC = 0x30,
12109 BGEZALC = 0x30,
12110 BGEUC = 0x30,
12111 SWSP16 = 0x32,
12112 B16 = 0x33,
12113 BC16 = 0x33,
12114 ANDI32 = 0x34,
12115 J32 = 0x35,
12116 BGTZC = 0x35,
12117 BLTZC = 0x35,
12118 BLTC = 0x35,
12119 SD32 = 0x36, /* MIPS64 */
12120 LD32 = 0x37, /* MIPS64 */
12122 /* 0x39 is reserved */
12123 RES_39 = 0x39,
12124 BGTZALC = 0x38,
12125 BLTZALC = 0x38,
12126 BLTUC = 0x38,
12127 SW16 = 0x3a,
12128 LI16 = 0x3b,
12129 JALX32 = 0x3c,
12130 JAL32 = 0x3d,
12131 BLEZC = 0x3d,
12132 BGEZC = 0x3d,
12133 BGEC = 0x3d,
12134 SW32 = 0x3e,
12135 LW32 = 0x3f
12138 /* PCREL Instructions perform PC-Relative address calculation. bits 20..16 */
12139 enum {
12140 ADDIUPC_00 = 0x00,
12141 ADDIUPC_07 = 0x07,
12142 AUIPC = 0x1e,
12143 ALUIPC = 0x1f,
12144 LWPC_08 = 0x08,
12145 LWPC_0F = 0x0F,
12148 /* POOL32A encoding of minor opcode field */
12150 enum {
12151 /* These opcodes are distinguished only by bits 9..6; those bits are
12152 * what are recorded below. */
12153 SLL32 = 0x0,
12154 SRL32 = 0x1,
12155 SRA = 0x2,
12156 ROTR = 0x3,
12157 SELEQZ = 0x5,
12158 SELNEZ = 0x6,
12159 R6_RDHWR = 0x7,
12161 SLLV = 0x0,
12162 SRLV = 0x1,
12163 SRAV = 0x2,
12164 ROTRV = 0x3,
12165 ADD = 0x4,
12166 ADDU32 = 0x5,
12167 SUB = 0x6,
12168 SUBU32 = 0x7,
12169 MUL = 0x8,
12170 AND = 0x9,
12171 OR32 = 0xa,
12172 NOR = 0xb,
12173 XOR32 = 0xc,
12174 SLT = 0xd,
12175 SLTU = 0xe,
12177 MOVN = 0x0,
12178 R6_MUL = 0x0,
12179 MOVZ = 0x1,
12180 MUH = 0x1,
12181 MULU = 0x2,
12182 MUHU = 0x3,
12183 LWXS = 0x4,
12184 R6_DIV = 0x4,
12185 MOD = 0x5,
12186 R6_DIVU = 0x6,
12187 MODU = 0x7,
12189 /* The following can be distinguished by their lower 6 bits. */
12190 BREAK32 = 0x07,
12191 INS = 0x0c,
12192 LSA = 0x0f,
12193 ALIGN = 0x1f,
12194 EXT = 0x2c,
12195 POOL32AXF = 0x3c,
12196 SIGRIE = 0x3f
12199 /* POOL32AXF encoding of minor opcode field extension */
12202 * 1. MIPS Architecture for Programmers Volume II-B:
12203 * The microMIPS32 Instruction Set (Revision 3.05)
12205 * Table 6.5 POOL32Axf Encoding of Minor Opcode Extension Field
12207 * 2. MIPS Architecture for Programmers VolumeIV-e:
12208 * The MIPS DSP Application-Specific Extension
12209 * to the microMIPS32 Architecture (Revision 2.34)
12211 * Table 5.5 POOL32Axf Encoding of Minor Opcode Extension Field
12214 enum {
12215 /* bits 11..6 */
12216 TEQ = 0x00,
12217 TGE = 0x08,
12218 TGEU = 0x10,
12219 TLT = 0x20,
12220 TLTU = 0x28,
12221 TNE = 0x30,
12223 MFC0 = 0x03,
12224 MTC0 = 0x0b,
12226 /* begin of microMIPS32 DSP */
12228 /* bits 13..12 for 0x01 */
12229 MFHI_ACC = 0x0,
12230 MFLO_ACC = 0x1,
12231 MTHI_ACC = 0x2,
12232 MTLO_ACC = 0x3,
12234 /* bits 13..12 for 0x2a */
12235 MADD_ACC = 0x0,
12236 MADDU_ACC = 0x1,
12237 MSUB_ACC = 0x2,
12238 MSUBU_ACC = 0x3,
12240 /* bits 13..12 for 0x32 */
12241 MULT_ACC = 0x0,
12242 MULTU_ACC = 0x1,
12244 /* end of microMIPS32 DSP */
12246 /* bits 15..12 for 0x2c */
12247 BITSWAP = 0x0,
12248 SEB = 0x2,
12249 SEH = 0x3,
12250 CLO = 0x4,
12251 CLZ = 0x5,
12252 RDHWR = 0x6,
12253 WSBH = 0x7,
12254 MULT = 0x8,
12255 MULTU = 0x9,
12256 DIV = 0xa,
12257 DIVU = 0xb,
12258 MADD = 0xc,
12259 MADDU = 0xd,
12260 MSUB = 0xe,
12261 MSUBU = 0xf,
12263 /* bits 15..12 for 0x34 */
12264 MFC2 = 0x4,
12265 MTC2 = 0x5,
12266 MFHC2 = 0x8,
12267 MTHC2 = 0x9,
12268 CFC2 = 0xc,
12269 CTC2 = 0xd,
12271 /* bits 15..12 for 0x3c */
12272 JALR = 0x0,
12273 JR = 0x0, /* alias */
12274 JALRC = 0x0,
12275 JRC = 0x0,
12276 JALR_HB = 0x1,
12277 JALRC_HB = 0x1,
12278 JALRS = 0x4,
12279 JALRS_HB = 0x5,
12281 /* bits 15..12 for 0x05 */
12282 RDPGPR = 0xe,
12283 WRPGPR = 0xf,
12285 /* bits 15..12 for 0x0d */
12286 TLBP = 0x0,
12287 TLBR = 0x1,
12288 TLBWI = 0x2,
12289 TLBWR = 0x3,
12290 TLBINV = 0x4,
12291 TLBINVF = 0x5,
12292 WAIT = 0x9,
12293 IRET = 0xd,
12294 DERET = 0xe,
12295 ERET = 0xf,
12297 /* bits 15..12 for 0x15 */
12298 DMT = 0x0,
12299 DVPE = 0x1,
12300 EMT = 0x2,
12301 EVPE = 0x3,
12303 /* bits 15..12 for 0x1d */
12304 DI = 0x4,
12305 EI = 0x5,
12307 /* bits 15..12 for 0x2d */
12308 SYNC = 0x6,
12309 SYSCALL = 0x8,
12310 SDBBP = 0xd,
12312 /* bits 15..12 for 0x35 */
12313 MFHI32 = 0x0,
12314 MFLO32 = 0x1,
12315 MTHI32 = 0x2,
12316 MTLO32 = 0x3,
12319 /* POOL32B encoding of minor opcode field (bits 15..12) */
12321 enum {
12322 LWC2 = 0x0,
12323 LWP = 0x1,
12324 LDP = 0x4,
12325 LWM32 = 0x5,
12326 CACHE = 0x6,
12327 LDM = 0x7,
12328 SWC2 = 0x8,
12329 SWP = 0x9,
12330 SDP = 0xc,
12331 SWM32 = 0xd,
12332 SDM = 0xf
12335 /* POOL32C encoding of minor opcode field (bits 15..12) */
12337 enum {
12338 LWL = 0x0,
12339 SWL = 0x8,
12340 LWR = 0x1,
12341 SWR = 0x9,
12342 PREF = 0x2,
12343 /* 0xa is reserved */
12344 LL = 0x3,
12345 SC = 0xb,
12346 LDL = 0x4,
12347 SDL = 0xc,
12348 LDR = 0x5,
12349 SDR = 0xd,
12350 /* 0x6 is reserved */
12351 LWU = 0xe,
12352 LLD = 0x7,
12353 SCD = 0xf
12356 /* POOL32F encoding of minor opcode field (bits 5..0) */
12358 enum {
12359 /* These are the bit 7..6 values */
12360 ADD_FMT = 0x0,
12362 SUB_FMT = 0x1,
12364 MUL_FMT = 0x2,
12366 DIV_FMT = 0x3,
12368 /* These are the bit 8..6 values */
12369 MOVN_FMT = 0x0,
12370 RSQRT2_FMT = 0x0,
12371 MOVF_FMT = 0x0,
12372 RINT_FMT = 0x0,
12373 SELNEZ_FMT = 0x0,
12375 MOVZ_FMT = 0x1,
12376 LWXC1 = 0x1,
12377 MOVT_FMT = 0x1,
12378 CLASS_FMT = 0x1,
12379 SELEQZ_FMT = 0x1,
12381 PLL_PS = 0x2,
12382 SWXC1 = 0x2,
12383 SEL_FMT = 0x2,
12385 PLU_PS = 0x3,
12386 LDXC1 = 0x3,
12388 MOVN_FMT_04 = 0x4,
12389 PUL_PS = 0x4,
12390 SDXC1 = 0x4,
12391 RECIP2_FMT = 0x4,
12393 MOVZ_FMT_05 = 0x05,
12394 PUU_PS = 0x5,
12395 LUXC1 = 0x5,
12397 CVT_PS_S = 0x6,
12398 SUXC1 = 0x6,
12399 ADDR_PS = 0x6,
12400 PREFX = 0x6,
12401 MADDF_FMT = 0x6,
12403 MULR_PS = 0x7,
12404 MSUBF_FMT = 0x7,
12406 MADD_S = 0x01,
12407 MADD_D = 0x09,
12408 MADD_PS = 0x11,
12409 ALNV_PS = 0x19,
12410 MSUB_S = 0x21,
12411 MSUB_D = 0x29,
12412 MSUB_PS = 0x31,
12414 NMADD_S = 0x02,
12415 NMADD_D = 0x0a,
12416 NMADD_PS = 0x12,
12417 NMSUB_S = 0x22,
12418 NMSUB_D = 0x2a,
12419 NMSUB_PS = 0x32,
12421 MIN_FMT = 0x3,
12422 MAX_FMT = 0xb,
12423 MINA_FMT = 0x23,
12424 MAXA_FMT = 0x2b,
12425 POOL32FXF = 0x3b,
12427 CABS_COND_FMT = 0x1c, /* MIPS3D */
12428 C_COND_FMT = 0x3c,
12430 CMP_CONDN_S = 0x5,
12431 CMP_CONDN_D = 0x15
12434 /* POOL32Fxf encoding of minor opcode extension field */
12436 enum {
12437 CVT_L = 0x04,
12438 RSQRT_FMT = 0x08,
12439 FLOOR_L = 0x0c,
12440 CVT_PW_PS = 0x1c,
12441 CVT_W = 0x24,
12442 SQRT_FMT = 0x28,
12443 FLOOR_W = 0x2c,
12444 CVT_PS_PW = 0x3c,
12445 CFC1 = 0x40,
12446 RECIP_FMT = 0x48,
12447 CEIL_L = 0x4c,
12448 CTC1 = 0x60,
12449 CEIL_W = 0x6c,
12450 MFC1 = 0x80,
12451 CVT_S_PL = 0x84,
12452 TRUNC_L = 0x8c,
12453 MTC1 = 0xa0,
12454 CVT_S_PU = 0xa4,
12455 TRUNC_W = 0xac,
12456 MFHC1 = 0xc0,
12457 ROUND_L = 0xcc,
12458 MTHC1 = 0xe0,
12459 ROUND_W = 0xec,
12461 MOV_FMT = 0x01,
12462 MOVF = 0x05,
12463 ABS_FMT = 0x0d,
12464 RSQRT1_FMT = 0x1d,
12465 MOVT = 0x25,
12466 NEG_FMT = 0x2d,
12467 CVT_D = 0x4d,
12468 RECIP1_FMT = 0x5d,
12469 CVT_S = 0x6d
12472 /* POOL32I encoding of minor opcode field (bits 25..21) */
12474 enum {
12475 BLTZ = 0x00,
12476 BLTZAL = 0x01,
12477 BGEZ = 0x02,
12478 BGEZAL = 0x03,
12479 BLEZ = 0x04,
12480 BNEZC = 0x05,
12481 BGTZ = 0x06,
12482 BEQZC = 0x07,
12483 TLTI = 0x08,
12484 BC1EQZC = 0x08,
12485 TGEI = 0x09,
12486 BC1NEZC = 0x09,
12487 TLTIU = 0x0a,
12488 BC2EQZC = 0x0a,
12489 TGEIU = 0x0b,
12490 BC2NEZC = 0x0a,
12491 TNEI = 0x0c,
12492 R6_SYNCI = 0x0c,
12493 LUI = 0x0d,
12494 TEQI = 0x0e,
12495 SYNCI = 0x10,
12496 BLTZALS = 0x11,
12497 BGEZALS = 0x13,
12498 BC2F = 0x14,
12499 BC2T = 0x15,
12500 BPOSGE64 = 0x1a,
12501 BPOSGE32 = 0x1b,
12502 /* These overlap and are distinguished by bit16 of the instruction */
12503 BC1F = 0x1c,
12504 BC1T = 0x1d,
12505 BC1ANY2F = 0x1c,
12506 BC1ANY2T = 0x1d,
12507 BC1ANY4F = 0x1e,
12508 BC1ANY4T = 0x1f
12511 /* POOL16A encoding of minor opcode field */
12513 enum {
12514 ADDU16 = 0x0,
12515 SUBU16 = 0x1
12518 /* POOL16B encoding of minor opcode field */
12520 enum {
12521 SLL16 = 0x0,
12522 SRL16 = 0x1
12525 /* POOL16C encoding of minor opcode field */
12527 enum {
12528 NOT16 = 0x00,
12529 XOR16 = 0x04,
12530 AND16 = 0x08,
12531 OR16 = 0x0c,
12532 LWM16 = 0x10,
12533 SWM16 = 0x14,
12534 JR16 = 0x18,
12535 JRC16 = 0x1a,
12536 JALR16 = 0x1c,
12537 JALR16S = 0x1e,
12538 MFHI16 = 0x20,
12539 MFLO16 = 0x24,
12540 BREAK16 = 0x28,
12541 SDBBP16 = 0x2c,
12542 JRADDIUSP = 0x30
12545 /* R6 POOL16C encoding of minor opcode field (bits 0..5) */
12547 enum {
12548 R6_NOT16 = 0x00,
12549 R6_AND16 = 0x01,
12550 R6_LWM16 = 0x02,
12551 R6_JRC16 = 0x03,
12552 MOVEP = 0x04,
12553 MOVEP_07 = 0x07,
12554 R6_XOR16 = 0x08,
12555 R6_OR16 = 0x09,
12556 R6_SWM16 = 0x0a,
12557 JALRC16 = 0x0b,
12558 MOVEP_0C = 0x0c,
12559 MOVEP_0F = 0x0f,
12560 JRCADDIUSP = 0x13,
12561 R6_BREAK16 = 0x1b,
12562 R6_SDBBP16 = 0x3b
12565 /* POOL16D encoding of minor opcode field */
12567 enum {
12568 ADDIUS5 = 0x0,
12569 ADDIUSP = 0x1
12572 /* POOL16E encoding of minor opcode field */
12574 enum {
12575 ADDIUR2 = 0x0,
12576 ADDIUR1SP = 0x1
12579 static int mmreg (int r)
12581 static const int map[] = { 16, 17, 2, 3, 4, 5, 6, 7 };
12583 return map[r];
12586 /* Used for 16-bit store instructions. */
12587 static int mmreg2 (int r)
12589 static const int map[] = { 0, 17, 2, 3, 4, 5, 6, 7 };
12591 return map[r];
12594 #define uMIPS_RD(op) ((op >> 7) & 0x7)
12595 #define uMIPS_RS(op) ((op >> 4) & 0x7)
12596 #define uMIPS_RS2(op) uMIPS_RS(op)
12597 #define uMIPS_RS1(op) ((op >> 1) & 0x7)
12598 #define uMIPS_RD5(op) ((op >> 5) & 0x1f)
12599 #define uMIPS_RS5(op) (op & 0x1f)
12601 /* Signed immediate */
12602 #define SIMM(op, start, width) \
12603 ((int32_t)(((op >> start) & ((~0U) >> (32-width))) \
12604 << (32-width)) \
12605 >> (32-width))
12606 /* Zero-extended immediate */
12607 #define ZIMM(op, start, width) ((op >> start) & ((~0U) >> (32-width)))
12609 static void gen_addiur1sp(DisasContext *ctx)
12611 int rd = mmreg(uMIPS_RD(ctx->opcode));
12613 gen_arith_imm(ctx, OPC_ADDIU, rd, 29, ((ctx->opcode >> 1) & 0x3f) << 2);
12616 static void gen_addiur2(DisasContext *ctx)
12618 static const int decoded_imm[] = { 1, 4, 8, 12, 16, 20, 24, -1 };
12619 int rd = mmreg(uMIPS_RD(ctx->opcode));
12620 int rs = mmreg(uMIPS_RS(ctx->opcode));
12622 gen_arith_imm(ctx, OPC_ADDIU, rd, rs, decoded_imm[ZIMM(ctx->opcode, 1, 3)]);
12625 static void gen_addiusp(DisasContext *ctx)
12627 int encoded = ZIMM(ctx->opcode, 1, 9);
12628 int decoded;
12630 if (encoded <= 1) {
12631 decoded = 256 + encoded;
12632 } else if (encoded <= 255) {
12633 decoded = encoded;
12634 } else if (encoded <= 509) {
12635 decoded = encoded - 512;
12636 } else {
12637 decoded = encoded - 768;
12640 gen_arith_imm(ctx, OPC_ADDIU, 29, 29, decoded << 2);
12643 static void gen_addius5(DisasContext *ctx)
12645 int imm = SIMM(ctx->opcode, 1, 4);
12646 int rd = (ctx->opcode >> 5) & 0x1f;
12648 gen_arith_imm(ctx, OPC_ADDIU, rd, rd, imm);
12651 static void gen_andi16(DisasContext *ctx)
12653 static const int decoded_imm[] = { 128, 1, 2, 3, 4, 7, 8, 15, 16,
12654 31, 32, 63, 64, 255, 32768, 65535 };
12655 int rd = mmreg(uMIPS_RD(ctx->opcode));
12656 int rs = mmreg(uMIPS_RS(ctx->opcode));
12657 int encoded = ZIMM(ctx->opcode, 0, 4);
12659 gen_logic_imm(ctx, OPC_ANDI, rd, rs, decoded_imm[encoded]);
12662 static void gen_ldst_multiple (DisasContext *ctx, uint32_t opc, int reglist,
12663 int base, int16_t offset)
12665 TCGv t0, t1;
12666 TCGv_i32 t2;
12668 if (ctx->hflags & MIPS_HFLAG_BMASK) {
12669 generate_exception_end(ctx, EXCP_RI);
12670 return;
12673 t0 = tcg_temp_new();
12675 gen_base_offset_addr(ctx, t0, base, offset);
12677 t1 = tcg_const_tl(reglist);
12678 t2 = tcg_const_i32(ctx->mem_idx);
12680 save_cpu_state(ctx, 1);
12681 switch (opc) {
12682 case LWM32:
12683 gen_helper_lwm(cpu_env, t0, t1, t2);
12684 break;
12685 case SWM32:
12686 gen_helper_swm(cpu_env, t0, t1, t2);
12687 break;
12688 #ifdef TARGET_MIPS64
12689 case LDM:
12690 gen_helper_ldm(cpu_env, t0, t1, t2);
12691 break;
12692 case SDM:
12693 gen_helper_sdm(cpu_env, t0, t1, t2);
12694 break;
12695 #endif
12697 tcg_temp_free(t0);
12698 tcg_temp_free(t1);
12699 tcg_temp_free_i32(t2);
12703 static void gen_pool16c_insn(DisasContext *ctx)
12705 int rd = mmreg((ctx->opcode >> 3) & 0x7);
12706 int rs = mmreg(ctx->opcode & 0x7);
12708 switch (((ctx->opcode) >> 4) & 0x3f) {
12709 case NOT16 + 0:
12710 case NOT16 + 1:
12711 case NOT16 + 2:
12712 case NOT16 + 3:
12713 gen_logic(ctx, OPC_NOR, rd, rs, 0);
12714 break;
12715 case XOR16 + 0:
12716 case XOR16 + 1:
12717 case XOR16 + 2:
12718 case XOR16 + 3:
12719 gen_logic(ctx, OPC_XOR, rd, rd, rs);
12720 break;
12721 case AND16 + 0:
12722 case AND16 + 1:
12723 case AND16 + 2:
12724 case AND16 + 3:
12725 gen_logic(ctx, OPC_AND, rd, rd, rs);
12726 break;
12727 case OR16 + 0:
12728 case OR16 + 1:
12729 case OR16 + 2:
12730 case OR16 + 3:
12731 gen_logic(ctx, OPC_OR, rd, rd, rs);
12732 break;
12733 case LWM16 + 0:
12734 case LWM16 + 1:
12735 case LWM16 + 2:
12736 case LWM16 + 3:
12738 static const int lwm_convert[] = { 0x11, 0x12, 0x13, 0x14 };
12739 int offset = ZIMM(ctx->opcode, 0, 4);
12741 gen_ldst_multiple(ctx, LWM32, lwm_convert[(ctx->opcode >> 4) & 0x3],
12742 29, offset << 2);
12744 break;
12745 case SWM16 + 0:
12746 case SWM16 + 1:
12747 case SWM16 + 2:
12748 case SWM16 + 3:
12750 static const int swm_convert[] = { 0x11, 0x12, 0x13, 0x14 };
12751 int offset = ZIMM(ctx->opcode, 0, 4);
12753 gen_ldst_multiple(ctx, SWM32, swm_convert[(ctx->opcode >> 4) & 0x3],
12754 29, offset << 2);
12756 break;
12757 case JR16 + 0:
12758 case JR16 + 1:
12760 int reg = ctx->opcode & 0x1f;
12762 gen_compute_branch(ctx, OPC_JR, 2, reg, 0, 0, 4);
12764 break;
12765 case JRC16 + 0:
12766 case JRC16 + 1:
12768 int reg = ctx->opcode & 0x1f;
12769 gen_compute_branch(ctx, OPC_JR, 2, reg, 0, 0, 0);
12770 /* Let normal delay slot handling in our caller take us
12771 to the branch target. */
12773 break;
12774 case JALR16 + 0:
12775 case JALR16 + 1:
12776 gen_compute_branch(ctx, OPC_JALR, 2, ctx->opcode & 0x1f, 31, 0, 4);
12777 ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
12778 break;
12779 case JALR16S + 0:
12780 case JALR16S + 1:
12781 gen_compute_branch(ctx, OPC_JALR, 2, ctx->opcode & 0x1f, 31, 0, 2);
12782 ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
12783 break;
12784 case MFHI16 + 0:
12785 case MFHI16 + 1:
12786 gen_HILO(ctx, OPC_MFHI, 0, uMIPS_RS5(ctx->opcode));
12787 break;
12788 case MFLO16 + 0:
12789 case MFLO16 + 1:
12790 gen_HILO(ctx, OPC_MFLO, 0, uMIPS_RS5(ctx->opcode));
12791 break;
12792 case BREAK16:
12793 generate_exception_end(ctx, EXCP_BREAK);
12794 break;
12795 case SDBBP16:
12796 if (is_uhi(extract32(ctx->opcode, 0, 4))) {
12797 gen_helper_do_semihosting(cpu_env);
12798 } else {
12799 /* XXX: not clear which exception should be raised
12800 * when in debug mode...
12802 check_insn(ctx, ISA_MIPS32);
12803 generate_exception_end(ctx, EXCP_DBp);
12805 break;
12806 case JRADDIUSP + 0:
12807 case JRADDIUSP + 1:
12809 int imm = ZIMM(ctx->opcode, 0, 5);
12810 gen_compute_branch(ctx, OPC_JR, 2, 31, 0, 0, 0);
12811 gen_arith_imm(ctx, OPC_ADDIU, 29, 29, imm << 2);
12812 /* Let normal delay slot handling in our caller take us
12813 to the branch target. */
12815 break;
12816 default:
12817 generate_exception_end(ctx, EXCP_RI);
12818 break;
12822 static inline void gen_movep(DisasContext *ctx, int enc_dest, int enc_rt,
12823 int enc_rs)
12825 int rd, rs, re, rt;
12826 static const int rd_enc[] = { 5, 5, 6, 4, 4, 4, 4, 4 };
12827 static const int re_enc[] = { 6, 7, 7, 21, 22, 5, 6, 7 };
12828 static const int rs_rt_enc[] = { 0, 17, 2, 3, 16, 18, 19, 20 };
12829 rd = rd_enc[enc_dest];
12830 re = re_enc[enc_dest];
12831 rs = rs_rt_enc[enc_rs];
12832 rt = rs_rt_enc[enc_rt];
12833 if (rs) {
12834 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
12835 } else {
12836 tcg_gen_movi_tl(cpu_gpr[rd], 0);
12838 if (rt) {
12839 tcg_gen_mov_tl(cpu_gpr[re], cpu_gpr[rt]);
12840 } else {
12841 tcg_gen_movi_tl(cpu_gpr[re], 0);
12845 static void gen_pool16c_r6_insn(DisasContext *ctx)
12847 int rt = mmreg((ctx->opcode >> 7) & 0x7);
12848 int rs = mmreg((ctx->opcode >> 4) & 0x7);
12850 switch (ctx->opcode & 0xf) {
12851 case R6_NOT16:
12852 gen_logic(ctx, OPC_NOR, rt, rs, 0);
12853 break;
12854 case R6_AND16:
12855 gen_logic(ctx, OPC_AND, rt, rt, rs);
12856 break;
12857 case R6_LWM16:
12859 int lwm_converted = 0x11 + extract32(ctx->opcode, 8, 2);
12860 int offset = extract32(ctx->opcode, 4, 4);
12861 gen_ldst_multiple(ctx, LWM32, lwm_converted, 29, offset << 2);
12863 break;
12864 case R6_JRC16: /* JRCADDIUSP */
12865 if ((ctx->opcode >> 4) & 1) {
12866 /* JRCADDIUSP */
12867 int imm = extract32(ctx->opcode, 5, 5);
12868 gen_compute_branch(ctx, OPC_JR, 2, 31, 0, 0, 0);
12869 gen_arith_imm(ctx, OPC_ADDIU, 29, 29, imm << 2);
12870 } else {
12871 /* JRC16 */
12872 int rs = extract32(ctx->opcode, 5, 5);
12873 gen_compute_branch(ctx, OPC_JR, 2, rs, 0, 0, 0);
12875 break;
12876 case MOVEP ... MOVEP_07:
12877 case MOVEP_0C ... MOVEP_0F:
12879 int enc_dest = uMIPS_RD(ctx->opcode);
12880 int enc_rt = uMIPS_RS2(ctx->opcode);
12881 int enc_rs = (ctx->opcode & 3) | ((ctx->opcode >> 1) & 4);
12882 gen_movep(ctx, enc_dest, enc_rt, enc_rs);
12884 break;
12885 case R6_XOR16:
12886 gen_logic(ctx, OPC_XOR, rt, rt, rs);
12887 break;
12888 case R6_OR16:
12889 gen_logic(ctx, OPC_OR, rt, rt, rs);
12890 break;
12891 case R6_SWM16:
12893 int swm_converted = 0x11 + extract32(ctx->opcode, 8, 2);
12894 int offset = extract32(ctx->opcode, 4, 4);
12895 gen_ldst_multiple(ctx, SWM32, swm_converted, 29, offset << 2);
12897 break;
12898 case JALRC16: /* BREAK16, SDBBP16 */
12899 switch (ctx->opcode & 0x3f) {
12900 case JALRC16:
12901 case JALRC16 + 0x20:
12902 /* JALRC16 */
12903 gen_compute_branch(ctx, OPC_JALR, 2, (ctx->opcode >> 5) & 0x1f,
12904 31, 0, 0);
12905 break;
12906 case R6_BREAK16:
12907 /* BREAK16 */
12908 generate_exception(ctx, EXCP_BREAK);
12909 break;
12910 case R6_SDBBP16:
12911 /* SDBBP16 */
12912 if (is_uhi(extract32(ctx->opcode, 6, 4))) {
12913 gen_helper_do_semihosting(cpu_env);
12914 } else {
12915 if (ctx->hflags & MIPS_HFLAG_SBRI) {
12916 generate_exception(ctx, EXCP_RI);
12917 } else {
12918 generate_exception(ctx, EXCP_DBp);
12921 break;
12923 break;
12924 default:
12925 generate_exception(ctx, EXCP_RI);
12926 break;
12930 static void gen_ldxs (DisasContext *ctx, int base, int index, int rd)
12932 TCGv t0 = tcg_temp_new();
12933 TCGv t1 = tcg_temp_new();
12935 gen_load_gpr(t0, base);
12937 if (index != 0) {
12938 gen_load_gpr(t1, index);
12939 tcg_gen_shli_tl(t1, t1, 2);
12940 gen_op_addr_add(ctx, t0, t1, t0);
12943 tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_TESL);
12944 gen_store_gpr(t1, rd);
12946 tcg_temp_free(t0);
12947 tcg_temp_free(t1);
12950 static void gen_ldst_pair (DisasContext *ctx, uint32_t opc, int rd,
12951 int base, int16_t offset)
12953 TCGv t0, t1;
12955 if (ctx->hflags & MIPS_HFLAG_BMASK || rd == 31) {
12956 generate_exception_end(ctx, EXCP_RI);
12957 return;
12960 t0 = tcg_temp_new();
12961 t1 = tcg_temp_new();
12963 gen_base_offset_addr(ctx, t0, base, offset);
12965 switch (opc) {
12966 case LWP:
12967 if (rd == base) {
12968 generate_exception_end(ctx, EXCP_RI);
12969 return;
12971 tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_TESL);
12972 gen_store_gpr(t1, rd);
12973 tcg_gen_movi_tl(t1, 4);
12974 gen_op_addr_add(ctx, t0, t0, t1);
12975 tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_TESL);
12976 gen_store_gpr(t1, rd+1);
12977 break;
12978 case SWP:
12979 gen_load_gpr(t1, rd);
12980 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL);
12981 tcg_gen_movi_tl(t1, 4);
12982 gen_op_addr_add(ctx, t0, t0, t1);
12983 gen_load_gpr(t1, rd+1);
12984 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL);
12985 break;
12986 #ifdef TARGET_MIPS64
12987 case LDP:
12988 if (rd == base) {
12989 generate_exception_end(ctx, EXCP_RI);
12990 return;
12992 tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_TEQ);
12993 gen_store_gpr(t1, rd);
12994 tcg_gen_movi_tl(t1, 8);
12995 gen_op_addr_add(ctx, t0, t0, t1);
12996 tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_TEQ);
12997 gen_store_gpr(t1, rd+1);
12998 break;
12999 case SDP:
13000 gen_load_gpr(t1, rd);
13001 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEQ);
13002 tcg_gen_movi_tl(t1, 8);
13003 gen_op_addr_add(ctx, t0, t0, t1);
13004 gen_load_gpr(t1, rd+1);
13005 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEQ);
13006 break;
13007 #endif
13009 tcg_temp_free(t0);
13010 tcg_temp_free(t1);
13013 static void gen_pool32axf (CPUMIPSState *env, DisasContext *ctx, int rt, int rs)
13015 int extension = (ctx->opcode >> 6) & 0x3f;
13016 int minor = (ctx->opcode >> 12) & 0xf;
13017 uint32_t mips32_op;
13019 switch (extension) {
13020 case TEQ:
13021 mips32_op = OPC_TEQ;
13022 goto do_trap;
13023 case TGE:
13024 mips32_op = OPC_TGE;
13025 goto do_trap;
13026 case TGEU:
13027 mips32_op = OPC_TGEU;
13028 goto do_trap;
13029 case TLT:
13030 mips32_op = OPC_TLT;
13031 goto do_trap;
13032 case TLTU:
13033 mips32_op = OPC_TLTU;
13034 goto do_trap;
13035 case TNE:
13036 mips32_op = OPC_TNE;
13037 do_trap:
13038 gen_trap(ctx, mips32_op, rs, rt, -1);
13039 break;
13040 #ifndef CONFIG_USER_ONLY
13041 case MFC0:
13042 case MFC0 + 32:
13043 check_cp0_enabled(ctx);
13044 if (rt == 0) {
13045 /* Treat as NOP. */
13046 break;
13048 gen_mfc0(ctx, cpu_gpr[rt], rs, (ctx->opcode >> 11) & 0x7);
13049 break;
13050 case MTC0:
13051 case MTC0 + 32:
13052 check_cp0_enabled(ctx);
13054 TCGv t0 = tcg_temp_new();
13056 gen_load_gpr(t0, rt);
13057 gen_mtc0(ctx, t0, rs, (ctx->opcode >> 11) & 0x7);
13058 tcg_temp_free(t0);
13060 break;
13061 #endif
13062 case 0x2a:
13063 switch (minor & 3) {
13064 case MADD_ACC:
13065 gen_muldiv(ctx, OPC_MADD, (ctx->opcode >> 14) & 3, rs, rt);
13066 break;
13067 case MADDU_ACC:
13068 gen_muldiv(ctx, OPC_MADDU, (ctx->opcode >> 14) & 3, rs, rt);
13069 break;
13070 case MSUB_ACC:
13071 gen_muldiv(ctx, OPC_MSUB, (ctx->opcode >> 14) & 3, rs, rt);
13072 break;
13073 case MSUBU_ACC:
13074 gen_muldiv(ctx, OPC_MSUBU, (ctx->opcode >> 14) & 3, rs, rt);
13075 break;
13076 default:
13077 goto pool32axf_invalid;
13079 break;
13080 case 0x32:
13081 switch (minor & 3) {
13082 case MULT_ACC:
13083 gen_muldiv(ctx, OPC_MULT, (ctx->opcode >> 14) & 3, rs, rt);
13084 break;
13085 case MULTU_ACC:
13086 gen_muldiv(ctx, OPC_MULTU, (ctx->opcode >> 14) & 3, rs, rt);
13087 break;
13088 default:
13089 goto pool32axf_invalid;
13091 break;
13092 case 0x2c:
13093 switch (minor) {
13094 case BITSWAP:
13095 check_insn(ctx, ISA_MIPS32R6);
13096 gen_bitswap(ctx, OPC_BITSWAP, rs, rt);
13097 break;
13098 case SEB:
13099 gen_bshfl(ctx, OPC_SEB, rs, rt);
13100 break;
13101 case SEH:
13102 gen_bshfl(ctx, OPC_SEH, rs, rt);
13103 break;
13104 case CLO:
13105 mips32_op = OPC_CLO;
13106 goto do_cl;
13107 case CLZ:
13108 mips32_op = OPC_CLZ;
13109 do_cl:
13110 check_insn(ctx, ISA_MIPS32);
13111 gen_cl(ctx, mips32_op, rt, rs);
13112 break;
13113 case RDHWR:
13114 check_insn_opc_removed(ctx, ISA_MIPS32R6);
13115 gen_rdhwr(ctx, rt, rs, 0);
13116 break;
13117 case WSBH:
13118 gen_bshfl(ctx, OPC_WSBH, rs, rt);
13119 break;
13120 case MULT:
13121 check_insn_opc_removed(ctx, ISA_MIPS32R6);
13122 mips32_op = OPC_MULT;
13123 goto do_mul;
13124 case MULTU:
13125 check_insn_opc_removed(ctx, ISA_MIPS32R6);
13126 mips32_op = OPC_MULTU;
13127 goto do_mul;
13128 case DIV:
13129 check_insn_opc_removed(ctx, ISA_MIPS32R6);
13130 mips32_op = OPC_DIV;
13131 goto do_div;
13132 case DIVU:
13133 check_insn_opc_removed(ctx, ISA_MIPS32R6);
13134 mips32_op = OPC_DIVU;
13135 goto do_div;
13136 do_div:
13137 check_insn(ctx, ISA_MIPS32);
13138 gen_muldiv(ctx, mips32_op, 0, rs, rt);
13139 break;
13140 case MADD:
13141 check_insn_opc_removed(ctx, ISA_MIPS32R6);
13142 mips32_op = OPC_MADD;
13143 goto do_mul;
13144 case MADDU:
13145 check_insn_opc_removed(ctx, ISA_MIPS32R6);
13146 mips32_op = OPC_MADDU;
13147 goto do_mul;
13148 case MSUB:
13149 check_insn_opc_removed(ctx, ISA_MIPS32R6);
13150 mips32_op = OPC_MSUB;
13151 goto do_mul;
13152 case MSUBU:
13153 check_insn_opc_removed(ctx, ISA_MIPS32R6);
13154 mips32_op = OPC_MSUBU;
13155 do_mul:
13156 check_insn(ctx, ISA_MIPS32);
13157 gen_muldiv(ctx, mips32_op, 0, rs, rt);
13158 break;
13159 default:
13160 goto pool32axf_invalid;
13162 break;
13163 case 0x34:
13164 switch (minor) {
13165 case MFC2:
13166 case MTC2:
13167 case MFHC2:
13168 case MTHC2:
13169 case CFC2:
13170 case CTC2:
13171 generate_exception_err(ctx, EXCP_CpU, 2);
13172 break;
13173 default:
13174 goto pool32axf_invalid;
13176 break;
13177 case 0x3c:
13178 switch (minor) {
13179 case JALR: /* JALRC */
13180 case JALR_HB: /* JALRC_HB */
13181 if (ctx->insn_flags & ISA_MIPS32R6) {
13182 /* JALRC, JALRC_HB */
13183 gen_compute_branch(ctx, OPC_JALR, 4, rs, rt, 0, 0);
13184 } else {
13185 /* JALR, JALR_HB */
13186 gen_compute_branch(ctx, OPC_JALR, 4, rs, rt, 0, 4);
13187 ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
13189 break;
13190 case JALRS:
13191 case JALRS_HB:
13192 check_insn_opc_removed(ctx, ISA_MIPS32R6);
13193 gen_compute_branch(ctx, OPC_JALR, 4, rs, rt, 0, 2);
13194 ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
13195 break;
13196 default:
13197 goto pool32axf_invalid;
13199 break;
13200 case 0x05:
13201 switch (minor) {
13202 case RDPGPR:
13203 check_cp0_enabled(ctx);
13204 check_insn(ctx, ISA_MIPS32R2);
13205 gen_load_srsgpr(rs, rt);
13206 break;
13207 case WRPGPR:
13208 check_cp0_enabled(ctx);
13209 check_insn(ctx, ISA_MIPS32R2);
13210 gen_store_srsgpr(rs, rt);
13211 break;
13212 default:
13213 goto pool32axf_invalid;
13215 break;
13216 #ifndef CONFIG_USER_ONLY
13217 case 0x0d:
13218 switch (minor) {
13219 case TLBP:
13220 mips32_op = OPC_TLBP;
13221 goto do_cp0;
13222 case TLBR:
13223 mips32_op = OPC_TLBR;
13224 goto do_cp0;
13225 case TLBWI:
13226 mips32_op = OPC_TLBWI;
13227 goto do_cp0;
13228 case TLBWR:
13229 mips32_op = OPC_TLBWR;
13230 goto do_cp0;
13231 case TLBINV:
13232 mips32_op = OPC_TLBINV;
13233 goto do_cp0;
13234 case TLBINVF:
13235 mips32_op = OPC_TLBINVF;
13236 goto do_cp0;
13237 case WAIT:
13238 mips32_op = OPC_WAIT;
13239 goto do_cp0;
13240 case DERET:
13241 mips32_op = OPC_DERET;
13242 goto do_cp0;
13243 case ERET:
13244 mips32_op = OPC_ERET;
13245 do_cp0:
13246 gen_cp0(env, ctx, mips32_op, rt, rs);
13247 break;
13248 default:
13249 goto pool32axf_invalid;
13251 break;
13252 case 0x1d:
13253 switch (minor) {
13254 case DI:
13255 check_cp0_enabled(ctx);
13257 TCGv t0 = tcg_temp_new();
13259 save_cpu_state(ctx, 1);
13260 gen_helper_di(t0, cpu_env);
13261 gen_store_gpr(t0, rs);
13262 /* Stop translation as we may have switched the execution mode */
13263 ctx->bstate = BS_STOP;
13264 tcg_temp_free(t0);
13266 break;
13267 case EI:
13268 check_cp0_enabled(ctx);
13270 TCGv t0 = tcg_temp_new();
13272 save_cpu_state(ctx, 1);
13273 gen_helper_ei(t0, cpu_env);
13274 gen_store_gpr(t0, rs);
13275 /* Stop translation as we may have switched the execution mode */
13276 ctx->bstate = BS_STOP;
13277 tcg_temp_free(t0);
13279 break;
13280 default:
13281 goto pool32axf_invalid;
13283 break;
13284 #endif
13285 case 0x2d:
13286 switch (minor) {
13287 case SYNC:
13288 /* NOP */
13289 break;
13290 case SYSCALL:
13291 generate_exception_end(ctx, EXCP_SYSCALL);
13292 break;
13293 case SDBBP:
13294 if (is_uhi(extract32(ctx->opcode, 16, 10))) {
13295 gen_helper_do_semihosting(cpu_env);
13296 } else {
13297 check_insn(ctx, ISA_MIPS32);
13298 if (ctx->hflags & MIPS_HFLAG_SBRI) {
13299 generate_exception_end(ctx, EXCP_RI);
13300 } else {
13301 generate_exception_end(ctx, EXCP_DBp);
13304 break;
13305 default:
13306 goto pool32axf_invalid;
13308 break;
13309 case 0x01:
13310 switch (minor & 3) {
13311 case MFHI_ACC:
13312 gen_HILO(ctx, OPC_MFHI, minor >> 2, rs);
13313 break;
13314 case MFLO_ACC:
13315 gen_HILO(ctx, OPC_MFLO, minor >> 2, rs);
13316 break;
13317 case MTHI_ACC:
13318 gen_HILO(ctx, OPC_MTHI, minor >> 2, rs);
13319 break;
13320 case MTLO_ACC:
13321 gen_HILO(ctx, OPC_MTLO, minor >> 2, rs);
13322 break;
13323 default:
13324 goto pool32axf_invalid;
13326 break;
13327 case 0x35:
13328 check_insn_opc_removed(ctx, ISA_MIPS32R6);
13329 switch (minor) {
13330 case MFHI32:
13331 gen_HILO(ctx, OPC_MFHI, 0, rs);
13332 break;
13333 case MFLO32:
13334 gen_HILO(ctx, OPC_MFLO, 0, rs);
13335 break;
13336 case MTHI32:
13337 gen_HILO(ctx, OPC_MTHI, 0, rs);
13338 break;
13339 case MTLO32:
13340 gen_HILO(ctx, OPC_MTLO, 0, rs);
13341 break;
13342 default:
13343 goto pool32axf_invalid;
13345 break;
13346 default:
13347 pool32axf_invalid:
13348 MIPS_INVAL("pool32axf");
13349 generate_exception_end(ctx, EXCP_RI);
13350 break;
13354 /* Values for microMIPS fmt field. Variable-width, depending on which
13355 formats the instruction supports. */
13357 enum {
13358 FMT_SD_S = 0,
13359 FMT_SD_D = 1,
13361 FMT_SDPS_S = 0,
13362 FMT_SDPS_D = 1,
13363 FMT_SDPS_PS = 2,
13365 FMT_SWL_S = 0,
13366 FMT_SWL_W = 1,
13367 FMT_SWL_L = 2,
13369 FMT_DWL_D = 0,
13370 FMT_DWL_W = 1,
13371 FMT_DWL_L = 2
13374 static void gen_pool32fxf(DisasContext *ctx, int rt, int rs)
13376 int extension = (ctx->opcode >> 6) & 0x3ff;
13377 uint32_t mips32_op;
13379 #define FLOAT_1BIT_FMT(opc, fmt) (fmt << 8) | opc
13380 #define FLOAT_2BIT_FMT(opc, fmt) (fmt << 7) | opc
13381 #define COND_FLOAT_MOV(opc, cond) (cond << 7) | opc
13383 switch (extension) {
13384 case FLOAT_1BIT_FMT(CFC1, 0):
13385 mips32_op = OPC_CFC1;
13386 goto do_cp1;
13387 case FLOAT_1BIT_FMT(CTC1, 0):
13388 mips32_op = OPC_CTC1;
13389 goto do_cp1;
13390 case FLOAT_1BIT_FMT(MFC1, 0):
13391 mips32_op = OPC_MFC1;
13392 goto do_cp1;
13393 case FLOAT_1BIT_FMT(MTC1, 0):
13394 mips32_op = OPC_MTC1;
13395 goto do_cp1;
13396 case FLOAT_1BIT_FMT(MFHC1, 0):
13397 mips32_op = OPC_MFHC1;
13398 goto do_cp1;
13399 case FLOAT_1BIT_FMT(MTHC1, 0):
13400 mips32_op = OPC_MTHC1;
13401 do_cp1:
13402 gen_cp1(ctx, mips32_op, rt, rs);
13403 break;
13405 /* Reciprocal square root */
13406 case FLOAT_1BIT_FMT(RSQRT_FMT, FMT_SD_S):
13407 mips32_op = OPC_RSQRT_S;
13408 goto do_unaryfp;
13409 case FLOAT_1BIT_FMT(RSQRT_FMT, FMT_SD_D):
13410 mips32_op = OPC_RSQRT_D;
13411 goto do_unaryfp;
13413 /* Square root */
13414 case FLOAT_1BIT_FMT(SQRT_FMT, FMT_SD_S):
13415 mips32_op = OPC_SQRT_S;
13416 goto do_unaryfp;
13417 case FLOAT_1BIT_FMT(SQRT_FMT, FMT_SD_D):
13418 mips32_op = OPC_SQRT_D;
13419 goto do_unaryfp;
13421 /* Reciprocal */
13422 case FLOAT_1BIT_FMT(RECIP_FMT, FMT_SD_S):
13423 mips32_op = OPC_RECIP_S;
13424 goto do_unaryfp;
13425 case FLOAT_1BIT_FMT(RECIP_FMT, FMT_SD_D):
13426 mips32_op = OPC_RECIP_D;
13427 goto do_unaryfp;
13429 /* Floor */
13430 case FLOAT_1BIT_FMT(FLOOR_L, FMT_SD_S):
13431 mips32_op = OPC_FLOOR_L_S;
13432 goto do_unaryfp;
13433 case FLOAT_1BIT_FMT(FLOOR_L, FMT_SD_D):
13434 mips32_op = OPC_FLOOR_L_D;
13435 goto do_unaryfp;
13436 case FLOAT_1BIT_FMT(FLOOR_W, FMT_SD_S):
13437 mips32_op = OPC_FLOOR_W_S;
13438 goto do_unaryfp;
13439 case FLOAT_1BIT_FMT(FLOOR_W, FMT_SD_D):
13440 mips32_op = OPC_FLOOR_W_D;
13441 goto do_unaryfp;
13443 /* Ceiling */
13444 case FLOAT_1BIT_FMT(CEIL_L, FMT_SD_S):
13445 mips32_op = OPC_CEIL_L_S;
13446 goto do_unaryfp;
13447 case FLOAT_1BIT_FMT(CEIL_L, FMT_SD_D):
13448 mips32_op = OPC_CEIL_L_D;
13449 goto do_unaryfp;
13450 case FLOAT_1BIT_FMT(CEIL_W, FMT_SD_S):
13451 mips32_op = OPC_CEIL_W_S;
13452 goto do_unaryfp;
13453 case FLOAT_1BIT_FMT(CEIL_W, FMT_SD_D):
13454 mips32_op = OPC_CEIL_W_D;
13455 goto do_unaryfp;
13457 /* Truncation */
13458 case FLOAT_1BIT_FMT(TRUNC_L, FMT_SD_S):
13459 mips32_op = OPC_TRUNC_L_S;
13460 goto do_unaryfp;
13461 case FLOAT_1BIT_FMT(TRUNC_L, FMT_SD_D):
13462 mips32_op = OPC_TRUNC_L_D;
13463 goto do_unaryfp;
13464 case FLOAT_1BIT_FMT(TRUNC_W, FMT_SD_S):
13465 mips32_op = OPC_TRUNC_W_S;
13466 goto do_unaryfp;
13467 case FLOAT_1BIT_FMT(TRUNC_W, FMT_SD_D):
13468 mips32_op = OPC_TRUNC_W_D;
13469 goto do_unaryfp;
13471 /* Round */
13472 case FLOAT_1BIT_FMT(ROUND_L, FMT_SD_S):
13473 mips32_op = OPC_ROUND_L_S;
13474 goto do_unaryfp;
13475 case FLOAT_1BIT_FMT(ROUND_L, FMT_SD_D):
13476 mips32_op = OPC_ROUND_L_D;
13477 goto do_unaryfp;
13478 case FLOAT_1BIT_FMT(ROUND_W, FMT_SD_S):
13479 mips32_op = OPC_ROUND_W_S;
13480 goto do_unaryfp;
13481 case FLOAT_1BIT_FMT(ROUND_W, FMT_SD_D):
13482 mips32_op = OPC_ROUND_W_D;
13483 goto do_unaryfp;
13485 /* Integer to floating-point conversion */
13486 case FLOAT_1BIT_FMT(CVT_L, FMT_SD_S):
13487 mips32_op = OPC_CVT_L_S;
13488 goto do_unaryfp;
13489 case FLOAT_1BIT_FMT(CVT_L, FMT_SD_D):
13490 mips32_op = OPC_CVT_L_D;
13491 goto do_unaryfp;
13492 case FLOAT_1BIT_FMT(CVT_W, FMT_SD_S):
13493 mips32_op = OPC_CVT_W_S;
13494 goto do_unaryfp;
13495 case FLOAT_1BIT_FMT(CVT_W, FMT_SD_D):
13496 mips32_op = OPC_CVT_W_D;
13497 goto do_unaryfp;
13499 /* Paired-foo conversions */
13500 case FLOAT_1BIT_FMT(CVT_S_PL, 0):
13501 mips32_op = OPC_CVT_S_PL;
13502 goto do_unaryfp;
13503 case FLOAT_1BIT_FMT(CVT_S_PU, 0):
13504 mips32_op = OPC_CVT_S_PU;
13505 goto do_unaryfp;
13506 case FLOAT_1BIT_FMT(CVT_PW_PS, 0):
13507 mips32_op = OPC_CVT_PW_PS;
13508 goto do_unaryfp;
13509 case FLOAT_1BIT_FMT(CVT_PS_PW, 0):
13510 mips32_op = OPC_CVT_PS_PW;
13511 goto do_unaryfp;
13513 /* Floating-point moves */
13514 case FLOAT_2BIT_FMT(MOV_FMT, FMT_SDPS_S):
13515 mips32_op = OPC_MOV_S;
13516 goto do_unaryfp;
13517 case FLOAT_2BIT_FMT(MOV_FMT, FMT_SDPS_D):
13518 mips32_op = OPC_MOV_D;
13519 goto do_unaryfp;
13520 case FLOAT_2BIT_FMT(MOV_FMT, FMT_SDPS_PS):
13521 mips32_op = OPC_MOV_PS;
13522 goto do_unaryfp;
13524 /* Absolute value */
13525 case FLOAT_2BIT_FMT(ABS_FMT, FMT_SDPS_S):
13526 mips32_op = OPC_ABS_S;
13527 goto do_unaryfp;
13528 case FLOAT_2BIT_FMT(ABS_FMT, FMT_SDPS_D):
13529 mips32_op = OPC_ABS_D;
13530 goto do_unaryfp;
13531 case FLOAT_2BIT_FMT(ABS_FMT, FMT_SDPS_PS):
13532 mips32_op = OPC_ABS_PS;
13533 goto do_unaryfp;
13535 /* Negation */
13536 case FLOAT_2BIT_FMT(NEG_FMT, FMT_SDPS_S):
13537 mips32_op = OPC_NEG_S;
13538 goto do_unaryfp;
13539 case FLOAT_2BIT_FMT(NEG_FMT, FMT_SDPS_D):
13540 mips32_op = OPC_NEG_D;
13541 goto do_unaryfp;
13542 case FLOAT_2BIT_FMT(NEG_FMT, FMT_SDPS_PS):
13543 mips32_op = OPC_NEG_PS;
13544 goto do_unaryfp;
13546 /* Reciprocal square root step */
13547 case FLOAT_2BIT_FMT(RSQRT1_FMT, FMT_SDPS_S):
13548 mips32_op = OPC_RSQRT1_S;
13549 goto do_unaryfp;
13550 case FLOAT_2BIT_FMT(RSQRT1_FMT, FMT_SDPS_D):
13551 mips32_op = OPC_RSQRT1_D;
13552 goto do_unaryfp;
13553 case FLOAT_2BIT_FMT(RSQRT1_FMT, FMT_SDPS_PS):
13554 mips32_op = OPC_RSQRT1_PS;
13555 goto do_unaryfp;
13557 /* Reciprocal step */
13558 case FLOAT_2BIT_FMT(RECIP1_FMT, FMT_SDPS_S):
13559 mips32_op = OPC_RECIP1_S;
13560 goto do_unaryfp;
13561 case FLOAT_2BIT_FMT(RECIP1_FMT, FMT_SDPS_D):
13562 mips32_op = OPC_RECIP1_S;
13563 goto do_unaryfp;
13564 case FLOAT_2BIT_FMT(RECIP1_FMT, FMT_SDPS_PS):
13565 mips32_op = OPC_RECIP1_PS;
13566 goto do_unaryfp;
13568 /* Conversions from double */
13569 case FLOAT_2BIT_FMT(CVT_D, FMT_SWL_S):
13570 mips32_op = OPC_CVT_D_S;
13571 goto do_unaryfp;
13572 case FLOAT_2BIT_FMT(CVT_D, FMT_SWL_W):
13573 mips32_op = OPC_CVT_D_W;
13574 goto do_unaryfp;
13575 case FLOAT_2BIT_FMT(CVT_D, FMT_SWL_L):
13576 mips32_op = OPC_CVT_D_L;
13577 goto do_unaryfp;
13579 /* Conversions from single */
13580 case FLOAT_2BIT_FMT(CVT_S, FMT_DWL_D):
13581 mips32_op = OPC_CVT_S_D;
13582 goto do_unaryfp;
13583 case FLOAT_2BIT_FMT(CVT_S, FMT_DWL_W):
13584 mips32_op = OPC_CVT_S_W;
13585 goto do_unaryfp;
13586 case FLOAT_2BIT_FMT(CVT_S, FMT_DWL_L):
13587 mips32_op = OPC_CVT_S_L;
13588 do_unaryfp:
13589 gen_farith(ctx, mips32_op, -1, rs, rt, 0);
13590 break;
13592 /* Conditional moves on floating-point codes */
13593 case COND_FLOAT_MOV(MOVT, 0):
13594 case COND_FLOAT_MOV(MOVT, 1):
13595 case COND_FLOAT_MOV(MOVT, 2):
13596 case COND_FLOAT_MOV(MOVT, 3):
13597 case COND_FLOAT_MOV(MOVT, 4):
13598 case COND_FLOAT_MOV(MOVT, 5):
13599 case COND_FLOAT_MOV(MOVT, 6):
13600 case COND_FLOAT_MOV(MOVT, 7):
13601 check_insn_opc_removed(ctx, ISA_MIPS32R6);
13602 gen_movci(ctx, rt, rs, (ctx->opcode >> 13) & 0x7, 1);
13603 break;
13604 case COND_FLOAT_MOV(MOVF, 0):
13605 case COND_FLOAT_MOV(MOVF, 1):
13606 case COND_FLOAT_MOV(MOVF, 2):
13607 case COND_FLOAT_MOV(MOVF, 3):
13608 case COND_FLOAT_MOV(MOVF, 4):
13609 case COND_FLOAT_MOV(MOVF, 5):
13610 case COND_FLOAT_MOV(MOVF, 6):
13611 case COND_FLOAT_MOV(MOVF, 7):
13612 check_insn_opc_removed(ctx, ISA_MIPS32R6);
13613 gen_movci(ctx, rt, rs, (ctx->opcode >> 13) & 0x7, 0);
13614 break;
13615 default:
13616 MIPS_INVAL("pool32fxf");
13617 generate_exception_end(ctx, EXCP_RI);
13618 break;
13622 static void decode_micromips32_opc(CPUMIPSState *env, DisasContext *ctx)
13624 int32_t offset;
13625 uint16_t insn;
13626 int rt, rs, rd, rr;
13627 int16_t imm;
13628 uint32_t op, minor, mips32_op;
13629 uint32_t cond, fmt, cc;
13631 insn = cpu_lduw_code(env, ctx->pc + 2);
13632 ctx->opcode = (ctx->opcode << 16) | insn;
13634 rt = (ctx->opcode >> 21) & 0x1f;
13635 rs = (ctx->opcode >> 16) & 0x1f;
13636 rd = (ctx->opcode >> 11) & 0x1f;
13637 rr = (ctx->opcode >> 6) & 0x1f;
13638 imm = (int16_t) ctx->opcode;
13640 op = (ctx->opcode >> 26) & 0x3f;
13641 switch (op) {
13642 case POOL32A:
13643 minor = ctx->opcode & 0x3f;
13644 switch (minor) {
13645 case 0x00:
13646 minor = (ctx->opcode >> 6) & 0xf;
13647 switch (minor) {
13648 case SLL32:
13649 mips32_op = OPC_SLL;
13650 goto do_shifti;
13651 case SRA:
13652 mips32_op = OPC_SRA;
13653 goto do_shifti;
13654 case SRL32:
13655 mips32_op = OPC_SRL;
13656 goto do_shifti;
13657 case ROTR:
13658 mips32_op = OPC_ROTR;
13659 do_shifti:
13660 gen_shift_imm(ctx, mips32_op, rt, rs, rd);
13661 break;
13662 case SELEQZ:
13663 check_insn(ctx, ISA_MIPS32R6);
13664 gen_cond_move(ctx, OPC_SELEQZ, rd, rs, rt);
13665 break;
13666 case SELNEZ:
13667 check_insn(ctx, ISA_MIPS32R6);
13668 gen_cond_move(ctx, OPC_SELNEZ, rd, rs, rt);
13669 break;
13670 case R6_RDHWR:
13671 check_insn(ctx, ISA_MIPS32R6);
13672 gen_rdhwr(ctx, rt, rs, extract32(ctx->opcode, 11, 3));
13673 break;
13674 default:
13675 goto pool32a_invalid;
13677 break;
13678 case 0x10:
13679 minor = (ctx->opcode >> 6) & 0xf;
13680 switch (minor) {
13681 /* Arithmetic */
13682 case ADD:
13683 mips32_op = OPC_ADD;
13684 goto do_arith;
13685 case ADDU32:
13686 mips32_op = OPC_ADDU;
13687 goto do_arith;
13688 case SUB:
13689 mips32_op = OPC_SUB;
13690 goto do_arith;
13691 case SUBU32:
13692 mips32_op = OPC_SUBU;
13693 goto do_arith;
13694 case MUL:
13695 check_insn_opc_removed(ctx, ISA_MIPS32R6);
13696 mips32_op = OPC_MUL;
13697 do_arith:
13698 gen_arith(ctx, mips32_op, rd, rs, rt);
13699 break;
13700 /* Shifts */
13701 case SLLV:
13702 mips32_op = OPC_SLLV;
13703 goto do_shift;
13704 case SRLV:
13705 mips32_op = OPC_SRLV;
13706 goto do_shift;
13707 case SRAV:
13708 mips32_op = OPC_SRAV;
13709 goto do_shift;
13710 case ROTRV:
13711 mips32_op = OPC_ROTRV;
13712 do_shift:
13713 gen_shift(ctx, mips32_op, rd, rs, rt);
13714 break;
13715 /* Logical operations */
13716 case AND:
13717 mips32_op = OPC_AND;
13718 goto do_logic;
13719 case OR32:
13720 mips32_op = OPC_OR;
13721 goto do_logic;
13722 case NOR:
13723 mips32_op = OPC_NOR;
13724 goto do_logic;
13725 case XOR32:
13726 mips32_op = OPC_XOR;
13727 do_logic:
13728 gen_logic(ctx, mips32_op, rd, rs, rt);
13729 break;
13730 /* Set less than */
13731 case SLT:
13732 mips32_op = OPC_SLT;
13733 goto do_slt;
13734 case SLTU:
13735 mips32_op = OPC_SLTU;
13736 do_slt:
13737 gen_slt(ctx, mips32_op, rd, rs, rt);
13738 break;
13739 default:
13740 goto pool32a_invalid;
13742 break;
13743 case 0x18:
13744 minor = (ctx->opcode >> 6) & 0xf;
13745 switch (minor) {
13746 /* Conditional moves */
13747 case MOVN: /* MUL */
13748 if (ctx->insn_flags & ISA_MIPS32R6) {
13749 /* MUL */
13750 gen_r6_muldiv(ctx, R6_OPC_MUL, rd, rs, rt);
13751 } else {
13752 /* MOVN */
13753 gen_cond_move(ctx, OPC_MOVN, rd, rs, rt);
13755 break;
13756 case MOVZ: /* MUH */
13757 if (ctx->insn_flags & ISA_MIPS32R6) {
13758 /* MUH */
13759 gen_r6_muldiv(ctx, R6_OPC_MUH, rd, rs, rt);
13760 } else {
13761 /* MOVZ */
13762 gen_cond_move(ctx, OPC_MOVZ, rd, rs, rt);
13764 break;
13765 case MULU:
13766 check_insn(ctx, ISA_MIPS32R6);
13767 gen_r6_muldiv(ctx, R6_OPC_MULU, rd, rs, rt);
13768 break;
13769 case MUHU:
13770 check_insn(ctx, ISA_MIPS32R6);
13771 gen_r6_muldiv(ctx, R6_OPC_MUHU, rd, rs, rt);
13772 break;
13773 case LWXS: /* DIV */
13774 if (ctx->insn_flags & ISA_MIPS32R6) {
13775 /* DIV */
13776 gen_r6_muldiv(ctx, R6_OPC_DIV, rd, rs, rt);
13777 } else {
13778 /* LWXS */
13779 gen_ldxs(ctx, rs, rt, rd);
13781 break;
13782 case MOD:
13783 check_insn(ctx, ISA_MIPS32R6);
13784 gen_r6_muldiv(ctx, R6_OPC_MOD, rd, rs, rt);
13785 break;
13786 case R6_DIVU:
13787 check_insn(ctx, ISA_MIPS32R6);
13788 gen_r6_muldiv(ctx, R6_OPC_DIVU, rd, rs, rt);
13789 break;
13790 case MODU:
13791 check_insn(ctx, ISA_MIPS32R6);
13792 gen_r6_muldiv(ctx, R6_OPC_MODU, rd, rs, rt);
13793 break;
13794 default:
13795 goto pool32a_invalid;
13797 break;
13798 case INS:
13799 gen_bitops(ctx, OPC_INS, rt, rs, rr, rd);
13800 return;
13801 case LSA:
13802 check_insn(ctx, ISA_MIPS32R6);
13803 gen_lsa(ctx, OPC_LSA, rd, rs, rt,
13804 extract32(ctx->opcode, 9, 2));
13805 break;
13806 case ALIGN:
13807 check_insn(ctx, ISA_MIPS32R6);
13808 gen_align(ctx, OPC_ALIGN, rd, rs, rt,
13809 extract32(ctx->opcode, 9, 2));
13810 break;
13811 case EXT:
13812 gen_bitops(ctx, OPC_EXT, rt, rs, rr, rd);
13813 return;
13814 case POOL32AXF:
13815 gen_pool32axf(env, ctx, rt, rs);
13816 break;
13817 case BREAK32:
13818 generate_exception_end(ctx, EXCP_BREAK);
13819 break;
13820 case SIGRIE:
13821 check_insn(ctx, ISA_MIPS32R6);
13822 generate_exception_end(ctx, EXCP_RI);
13823 break;
13824 default:
13825 pool32a_invalid:
13826 MIPS_INVAL("pool32a");
13827 generate_exception_end(ctx, EXCP_RI);
13828 break;
13830 break;
13831 case POOL32B:
13832 minor = (ctx->opcode >> 12) & 0xf;
13833 switch (minor) {
13834 case CACHE:
13835 check_cp0_enabled(ctx);
13836 if (ctx->hflags & MIPS_HFLAG_ITC_CACHE) {
13837 gen_cache_operation(ctx, rt, rs, imm);
13839 break;
13840 case LWC2:
13841 case SWC2:
13842 /* COP2: Not implemented. */
13843 generate_exception_err(ctx, EXCP_CpU, 2);
13844 break;
13845 #ifdef TARGET_MIPS64
13846 case LDP:
13847 case SDP:
13848 check_insn(ctx, ISA_MIPS3);
13849 check_mips_64(ctx);
13850 /* Fallthrough */
13851 #endif
13852 case LWP:
13853 case SWP:
13854 gen_ldst_pair(ctx, minor, rt, rs, SIMM(ctx->opcode, 0, 12));
13855 break;
13856 #ifdef TARGET_MIPS64
13857 case LDM:
13858 case SDM:
13859 check_insn(ctx, ISA_MIPS3);
13860 check_mips_64(ctx);
13861 /* Fallthrough */
13862 #endif
13863 case LWM32:
13864 case SWM32:
13865 gen_ldst_multiple(ctx, minor, rt, rs, SIMM(ctx->opcode, 0, 12));
13866 break;
13867 default:
13868 MIPS_INVAL("pool32b");
13869 generate_exception_end(ctx, EXCP_RI);
13870 break;
13872 break;
13873 case POOL32F:
13874 if (ctx->CP0_Config1 & (1 << CP0C1_FP)) {
13875 minor = ctx->opcode & 0x3f;
13876 check_cp1_enabled(ctx);
13877 switch (minor) {
13878 case ALNV_PS:
13879 check_insn_opc_removed(ctx, ISA_MIPS32R6);
13880 mips32_op = OPC_ALNV_PS;
13881 goto do_madd;
13882 case MADD_S:
13883 check_insn_opc_removed(ctx, ISA_MIPS32R6);
13884 mips32_op = OPC_MADD_S;
13885 goto do_madd;
13886 case MADD_D:
13887 check_insn_opc_removed(ctx, ISA_MIPS32R6);
13888 mips32_op = OPC_MADD_D;
13889 goto do_madd;
13890 case MADD_PS:
13891 check_insn_opc_removed(ctx, ISA_MIPS32R6);
13892 mips32_op = OPC_MADD_PS;
13893 goto do_madd;
13894 case MSUB_S:
13895 check_insn_opc_removed(ctx, ISA_MIPS32R6);
13896 mips32_op = OPC_MSUB_S;
13897 goto do_madd;
13898 case MSUB_D:
13899 check_insn_opc_removed(ctx, ISA_MIPS32R6);
13900 mips32_op = OPC_MSUB_D;
13901 goto do_madd;
13902 case MSUB_PS:
13903 check_insn_opc_removed(ctx, ISA_MIPS32R6);
13904 mips32_op = OPC_MSUB_PS;
13905 goto do_madd;
13906 case NMADD_S:
13907 check_insn_opc_removed(ctx, ISA_MIPS32R6);
13908 mips32_op = OPC_NMADD_S;
13909 goto do_madd;
13910 case NMADD_D:
13911 check_insn_opc_removed(ctx, ISA_MIPS32R6);
13912 mips32_op = OPC_NMADD_D;
13913 goto do_madd;
13914 case NMADD_PS:
13915 check_insn_opc_removed(ctx, ISA_MIPS32R6);
13916 mips32_op = OPC_NMADD_PS;
13917 goto do_madd;
13918 case NMSUB_S:
13919 check_insn_opc_removed(ctx, ISA_MIPS32R6);
13920 mips32_op = OPC_NMSUB_S;
13921 goto do_madd;
13922 case NMSUB_D:
13923 check_insn_opc_removed(ctx, ISA_MIPS32R6);
13924 mips32_op = OPC_NMSUB_D;
13925 goto do_madd;
13926 case NMSUB_PS:
13927 check_insn_opc_removed(ctx, ISA_MIPS32R6);
13928 mips32_op = OPC_NMSUB_PS;
13929 do_madd:
13930 gen_flt3_arith(ctx, mips32_op, rd, rr, rs, rt);
13931 break;
13932 case CABS_COND_FMT:
13933 check_insn_opc_removed(ctx, ISA_MIPS32R6);
13934 cond = (ctx->opcode >> 6) & 0xf;
13935 cc = (ctx->opcode >> 13) & 0x7;
13936 fmt = (ctx->opcode >> 10) & 0x3;
13937 switch (fmt) {
13938 case 0x0:
13939 gen_cmpabs_s(ctx, cond, rt, rs, cc);
13940 break;
13941 case 0x1:
13942 gen_cmpabs_d(ctx, cond, rt, rs, cc);
13943 break;
13944 case 0x2:
13945 gen_cmpabs_ps(ctx, cond, rt, rs, cc);
13946 break;
13947 default:
13948 goto pool32f_invalid;
13950 break;
13951 case C_COND_FMT:
13952 check_insn_opc_removed(ctx, ISA_MIPS32R6);
13953 cond = (ctx->opcode >> 6) & 0xf;
13954 cc = (ctx->opcode >> 13) & 0x7;
13955 fmt = (ctx->opcode >> 10) & 0x3;
13956 switch (fmt) {
13957 case 0x0:
13958 gen_cmp_s(ctx, cond, rt, rs, cc);
13959 break;
13960 case 0x1:
13961 gen_cmp_d(ctx, cond, rt, rs, cc);
13962 break;
13963 case 0x2:
13964 gen_cmp_ps(ctx, cond, rt, rs, cc);
13965 break;
13966 default:
13967 goto pool32f_invalid;
13969 break;
13970 case CMP_CONDN_S:
13971 check_insn(ctx, ISA_MIPS32R6);
13972 gen_r6_cmp_s(ctx, (ctx->opcode >> 6) & 0x1f, rt, rs, rd);
13973 break;
13974 case CMP_CONDN_D:
13975 check_insn(ctx, ISA_MIPS32R6);
13976 gen_r6_cmp_d(ctx, (ctx->opcode >> 6) & 0x1f, rt, rs, rd);
13977 break;
13978 case POOL32FXF:
13979 gen_pool32fxf(ctx, rt, rs);
13980 break;
13981 case 0x00:
13982 /* PLL foo */
13983 switch ((ctx->opcode >> 6) & 0x7) {
13984 case PLL_PS:
13985 mips32_op = OPC_PLL_PS;
13986 goto do_ps;
13987 case PLU_PS:
13988 mips32_op = OPC_PLU_PS;
13989 goto do_ps;
13990 case PUL_PS:
13991 mips32_op = OPC_PUL_PS;
13992 goto do_ps;
13993 case PUU_PS:
13994 mips32_op = OPC_PUU_PS;
13995 goto do_ps;
13996 case CVT_PS_S:
13997 check_insn_opc_removed(ctx, ISA_MIPS32R6);
13998 mips32_op = OPC_CVT_PS_S;
13999 do_ps:
14000 gen_farith(ctx, mips32_op, rt, rs, rd, 0);
14001 break;
14002 default:
14003 goto pool32f_invalid;
14005 break;
14006 case MIN_FMT:
14007 check_insn(ctx, ISA_MIPS32R6);
14008 switch ((ctx->opcode >> 9) & 0x3) {
14009 case FMT_SDPS_S:
14010 gen_farith(ctx, OPC_MIN_S, rt, rs, rd, 0);
14011 break;
14012 case FMT_SDPS_D:
14013 gen_farith(ctx, OPC_MIN_D, rt, rs, rd, 0);
14014 break;
14015 default:
14016 goto pool32f_invalid;
14018 break;
14019 case 0x08:
14020 /* [LS][WDU]XC1 */
14021 switch ((ctx->opcode >> 6) & 0x7) {
14022 case LWXC1:
14023 check_insn_opc_removed(ctx, ISA_MIPS32R6);
14024 mips32_op = OPC_LWXC1;
14025 goto do_ldst_cp1;
14026 case SWXC1:
14027 check_insn_opc_removed(ctx, ISA_MIPS32R6);
14028 mips32_op = OPC_SWXC1;
14029 goto do_ldst_cp1;
14030 case LDXC1:
14031 check_insn_opc_removed(ctx, ISA_MIPS32R6);
14032 mips32_op = OPC_LDXC1;
14033 goto do_ldst_cp1;
14034 case SDXC1:
14035 check_insn_opc_removed(ctx, ISA_MIPS32R6);
14036 mips32_op = OPC_SDXC1;
14037 goto do_ldst_cp1;
14038 case LUXC1:
14039 check_insn_opc_removed(ctx, ISA_MIPS32R6);
14040 mips32_op = OPC_LUXC1;
14041 goto do_ldst_cp1;
14042 case SUXC1:
14043 check_insn_opc_removed(ctx, ISA_MIPS32R6);
14044 mips32_op = OPC_SUXC1;
14045 do_ldst_cp1:
14046 gen_flt3_ldst(ctx, mips32_op, rd, rd, rt, rs);
14047 break;
14048 default:
14049 goto pool32f_invalid;
14051 break;
14052 case MAX_FMT:
14053 check_insn(ctx, ISA_MIPS32R6);
14054 switch ((ctx->opcode >> 9) & 0x3) {
14055 case FMT_SDPS_S:
14056 gen_farith(ctx, OPC_MAX_S, rt, rs, rd, 0);
14057 break;
14058 case FMT_SDPS_D:
14059 gen_farith(ctx, OPC_MAX_D, rt, rs, rd, 0);
14060 break;
14061 default:
14062 goto pool32f_invalid;
14064 break;
14065 case 0x18:
14066 /* 3D insns */
14067 check_insn_opc_removed(ctx, ISA_MIPS32R6);
14068 fmt = (ctx->opcode >> 9) & 0x3;
14069 switch ((ctx->opcode >> 6) & 0x7) {
14070 case RSQRT2_FMT:
14071 switch (fmt) {
14072 case FMT_SDPS_S:
14073 mips32_op = OPC_RSQRT2_S;
14074 goto do_3d;
14075 case FMT_SDPS_D:
14076 mips32_op = OPC_RSQRT2_D;
14077 goto do_3d;
14078 case FMT_SDPS_PS:
14079 mips32_op = OPC_RSQRT2_PS;
14080 goto do_3d;
14081 default:
14082 goto pool32f_invalid;
14084 break;
14085 case RECIP2_FMT:
14086 switch (fmt) {
14087 case FMT_SDPS_S:
14088 mips32_op = OPC_RECIP2_S;
14089 goto do_3d;
14090 case FMT_SDPS_D:
14091 mips32_op = OPC_RECIP2_D;
14092 goto do_3d;
14093 case FMT_SDPS_PS:
14094 mips32_op = OPC_RECIP2_PS;
14095 goto do_3d;
14096 default:
14097 goto pool32f_invalid;
14099 break;
14100 case ADDR_PS:
14101 mips32_op = OPC_ADDR_PS;
14102 goto do_3d;
14103 case MULR_PS:
14104 mips32_op = OPC_MULR_PS;
14105 do_3d:
14106 gen_farith(ctx, mips32_op, rt, rs, rd, 0);
14107 break;
14108 default:
14109 goto pool32f_invalid;
14111 break;
14112 case 0x20:
14113 /* MOV[FT].fmt, PREFX, RINT.fmt, CLASS.fmt*/
14114 cc = (ctx->opcode >> 13) & 0x7;
14115 fmt = (ctx->opcode >> 9) & 0x3;
14116 switch ((ctx->opcode >> 6) & 0x7) {
14117 case MOVF_FMT: /* RINT_FMT */
14118 if (ctx->insn_flags & ISA_MIPS32R6) {
14119 /* RINT_FMT */
14120 switch (fmt) {
14121 case FMT_SDPS_S:
14122 gen_farith(ctx, OPC_RINT_S, 0, rt, rs, 0);
14123 break;
14124 case FMT_SDPS_D:
14125 gen_farith(ctx, OPC_RINT_D, 0, rt, rs, 0);
14126 break;
14127 default:
14128 goto pool32f_invalid;
14130 } else {
14131 /* MOVF_FMT */
14132 switch (fmt) {
14133 case FMT_SDPS_S:
14134 gen_movcf_s(ctx, rs, rt, cc, 0);
14135 break;
14136 case FMT_SDPS_D:
14137 gen_movcf_d(ctx, rs, rt, cc, 0);
14138 break;
14139 case FMT_SDPS_PS:
14140 check_ps(ctx);
14141 gen_movcf_ps(ctx, rs, rt, cc, 0);
14142 break;
14143 default:
14144 goto pool32f_invalid;
14147 break;
14148 case MOVT_FMT: /* CLASS_FMT */
14149 if (ctx->insn_flags & ISA_MIPS32R6) {
14150 /* CLASS_FMT */
14151 switch (fmt) {
14152 case FMT_SDPS_S:
14153 gen_farith(ctx, OPC_CLASS_S, 0, rt, rs, 0);
14154 break;
14155 case FMT_SDPS_D:
14156 gen_farith(ctx, OPC_CLASS_D, 0, rt, rs, 0);
14157 break;
14158 default:
14159 goto pool32f_invalid;
14161 } else {
14162 /* MOVT_FMT */
14163 switch (fmt) {
14164 case FMT_SDPS_S:
14165 gen_movcf_s(ctx, rs, rt, cc, 1);
14166 break;
14167 case FMT_SDPS_D:
14168 gen_movcf_d(ctx, rs, rt, cc, 1);
14169 break;
14170 case FMT_SDPS_PS:
14171 check_ps(ctx);
14172 gen_movcf_ps(ctx, rs, rt, cc, 1);
14173 break;
14174 default:
14175 goto pool32f_invalid;
14178 break;
14179 case PREFX:
14180 check_insn_opc_removed(ctx, ISA_MIPS32R6);
14181 break;
14182 default:
14183 goto pool32f_invalid;
14185 break;
14186 #define FINSN_3ARG_SDPS(prfx) \
14187 switch ((ctx->opcode >> 8) & 0x3) { \
14188 case FMT_SDPS_S: \
14189 mips32_op = OPC_##prfx##_S; \
14190 goto do_fpop; \
14191 case FMT_SDPS_D: \
14192 mips32_op = OPC_##prfx##_D; \
14193 goto do_fpop; \
14194 case FMT_SDPS_PS: \
14195 check_ps(ctx); \
14196 mips32_op = OPC_##prfx##_PS; \
14197 goto do_fpop; \
14198 default: \
14199 goto pool32f_invalid; \
14201 case MINA_FMT:
14202 check_insn(ctx, ISA_MIPS32R6);
14203 switch ((ctx->opcode >> 9) & 0x3) {
14204 case FMT_SDPS_S:
14205 gen_farith(ctx, OPC_MINA_S, rt, rs, rd, 0);
14206 break;
14207 case FMT_SDPS_D:
14208 gen_farith(ctx, OPC_MINA_D, rt, rs, rd, 0);
14209 break;
14210 default:
14211 goto pool32f_invalid;
14213 break;
14214 case MAXA_FMT:
14215 check_insn(ctx, ISA_MIPS32R6);
14216 switch ((ctx->opcode >> 9) & 0x3) {
14217 case FMT_SDPS_S:
14218 gen_farith(ctx, OPC_MAXA_S, rt, rs, rd, 0);
14219 break;
14220 case FMT_SDPS_D:
14221 gen_farith(ctx, OPC_MAXA_D, rt, rs, rd, 0);
14222 break;
14223 default:
14224 goto pool32f_invalid;
14226 break;
14227 case 0x30:
14228 /* regular FP ops */
14229 switch ((ctx->opcode >> 6) & 0x3) {
14230 case ADD_FMT:
14231 FINSN_3ARG_SDPS(ADD);
14232 break;
14233 case SUB_FMT:
14234 FINSN_3ARG_SDPS(SUB);
14235 break;
14236 case MUL_FMT:
14237 FINSN_3ARG_SDPS(MUL);
14238 break;
14239 case DIV_FMT:
14240 fmt = (ctx->opcode >> 8) & 0x3;
14241 if (fmt == 1) {
14242 mips32_op = OPC_DIV_D;
14243 } else if (fmt == 0) {
14244 mips32_op = OPC_DIV_S;
14245 } else {
14246 goto pool32f_invalid;
14248 goto do_fpop;
14249 default:
14250 goto pool32f_invalid;
14252 break;
14253 case 0x38:
14254 /* cmovs */
14255 switch ((ctx->opcode >> 6) & 0x7) {
14256 case MOVN_FMT: /* SELNEZ_FMT */
14257 if (ctx->insn_flags & ISA_MIPS32R6) {
14258 /* SELNEZ_FMT */
14259 switch ((ctx->opcode >> 9) & 0x3) {
14260 case FMT_SDPS_S:
14261 gen_sel_s(ctx, OPC_SELNEZ_S, rd, rt, rs);
14262 break;
14263 case FMT_SDPS_D:
14264 gen_sel_d(ctx, OPC_SELNEZ_D, rd, rt, rs);
14265 break;
14266 default:
14267 goto pool32f_invalid;
14269 } else {
14270 /* MOVN_FMT */
14271 FINSN_3ARG_SDPS(MOVN);
14273 break;
14274 case MOVN_FMT_04:
14275 check_insn_opc_removed(ctx, ISA_MIPS32R6);
14276 FINSN_3ARG_SDPS(MOVN);
14277 break;
14278 case MOVZ_FMT: /* SELEQZ_FMT */
14279 if (ctx->insn_flags & ISA_MIPS32R6) {
14280 /* SELEQZ_FMT */
14281 switch ((ctx->opcode >> 9) & 0x3) {
14282 case FMT_SDPS_S:
14283 gen_sel_s(ctx, OPC_SELEQZ_S, rd, rt, rs);
14284 break;
14285 case FMT_SDPS_D:
14286 gen_sel_d(ctx, OPC_SELEQZ_D, rd, rt, rs);
14287 break;
14288 default:
14289 goto pool32f_invalid;
14291 } else {
14292 /* MOVZ_FMT */
14293 FINSN_3ARG_SDPS(MOVZ);
14295 break;
14296 case MOVZ_FMT_05:
14297 check_insn_opc_removed(ctx, ISA_MIPS32R6);
14298 FINSN_3ARG_SDPS(MOVZ);
14299 break;
14300 case SEL_FMT:
14301 check_insn(ctx, ISA_MIPS32R6);
14302 switch ((ctx->opcode >> 9) & 0x3) {
14303 case FMT_SDPS_S:
14304 gen_sel_s(ctx, OPC_SEL_S, rd, rt, rs);
14305 break;
14306 case FMT_SDPS_D:
14307 gen_sel_d(ctx, OPC_SEL_D, rd, rt, rs);
14308 break;
14309 default:
14310 goto pool32f_invalid;
14312 break;
14313 case MADDF_FMT:
14314 check_insn(ctx, ISA_MIPS32R6);
14315 switch ((ctx->opcode >> 9) & 0x3) {
14316 case FMT_SDPS_S:
14317 mips32_op = OPC_MADDF_S;
14318 goto do_fpop;
14319 case FMT_SDPS_D:
14320 mips32_op = OPC_MADDF_D;
14321 goto do_fpop;
14322 default:
14323 goto pool32f_invalid;
14325 break;
14326 case MSUBF_FMT:
14327 check_insn(ctx, ISA_MIPS32R6);
14328 switch ((ctx->opcode >> 9) & 0x3) {
14329 case FMT_SDPS_S:
14330 mips32_op = OPC_MSUBF_S;
14331 goto do_fpop;
14332 case FMT_SDPS_D:
14333 mips32_op = OPC_MSUBF_D;
14334 goto do_fpop;
14335 default:
14336 goto pool32f_invalid;
14338 break;
14339 default:
14340 goto pool32f_invalid;
14342 break;
14343 do_fpop:
14344 gen_farith(ctx, mips32_op, rt, rs, rd, 0);
14345 break;
14346 default:
14347 pool32f_invalid:
14348 MIPS_INVAL("pool32f");
14349 generate_exception_end(ctx, EXCP_RI);
14350 break;
14352 } else {
14353 generate_exception_err(ctx, EXCP_CpU, 1);
14355 break;
14356 case POOL32I:
14357 minor = (ctx->opcode >> 21) & 0x1f;
14358 switch (minor) {
14359 case BLTZ:
14360 check_insn_opc_removed(ctx, ISA_MIPS32R6);
14361 gen_compute_branch(ctx, OPC_BLTZ, 4, rs, -1, imm << 1, 4);
14362 break;
14363 case BLTZAL:
14364 check_insn_opc_removed(ctx, ISA_MIPS32R6);
14365 gen_compute_branch(ctx, OPC_BLTZAL, 4, rs, -1, imm << 1, 4);
14366 ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
14367 break;
14368 case BLTZALS:
14369 check_insn_opc_removed(ctx, ISA_MIPS32R6);
14370 gen_compute_branch(ctx, OPC_BLTZAL, 4, rs, -1, imm << 1, 2);
14371 ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
14372 break;
14373 case BGEZ:
14374 check_insn_opc_removed(ctx, ISA_MIPS32R6);
14375 gen_compute_branch(ctx, OPC_BGEZ, 4, rs, -1, imm << 1, 4);
14376 break;
14377 case BGEZAL:
14378 check_insn_opc_removed(ctx, ISA_MIPS32R6);
14379 gen_compute_branch(ctx, OPC_BGEZAL, 4, rs, -1, imm << 1, 4);
14380 ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
14381 break;
14382 case BGEZALS:
14383 check_insn_opc_removed(ctx, ISA_MIPS32R6);
14384 gen_compute_branch(ctx, OPC_BGEZAL, 4, rs, -1, imm << 1, 2);
14385 ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
14386 break;
14387 case BLEZ:
14388 check_insn_opc_removed(ctx, ISA_MIPS32R6);
14389 gen_compute_branch(ctx, OPC_BLEZ, 4, rs, -1, imm << 1, 4);
14390 break;
14391 case BGTZ:
14392 check_insn_opc_removed(ctx, ISA_MIPS32R6);
14393 gen_compute_branch(ctx, OPC_BGTZ, 4, rs, -1, imm << 1, 4);
14394 break;
14396 /* Traps */
14397 case TLTI: /* BC1EQZC */
14398 if (ctx->insn_flags & ISA_MIPS32R6) {
14399 /* BC1EQZC */
14400 check_cp1_enabled(ctx);
14401 gen_compute_branch1_r6(ctx, OPC_BC1EQZ, rs, imm << 1, 0);
14402 } else {
14403 /* TLTI */
14404 mips32_op = OPC_TLTI;
14405 goto do_trapi;
14407 break;
14408 case TGEI: /* BC1NEZC */
14409 if (ctx->insn_flags & ISA_MIPS32R6) {
14410 /* BC1NEZC */
14411 check_cp1_enabled(ctx);
14412 gen_compute_branch1_r6(ctx, OPC_BC1NEZ, rs, imm << 1, 0);
14413 } else {
14414 /* TGEI */
14415 mips32_op = OPC_TGEI;
14416 goto do_trapi;
14418 break;
14419 case TLTIU:
14420 check_insn_opc_removed(ctx, ISA_MIPS32R6);
14421 mips32_op = OPC_TLTIU;
14422 goto do_trapi;
14423 case TGEIU:
14424 check_insn_opc_removed(ctx, ISA_MIPS32R6);
14425 mips32_op = OPC_TGEIU;
14426 goto do_trapi;
14427 case TNEI: /* SYNCI */
14428 if (ctx->insn_flags & ISA_MIPS32R6) {
14429 /* SYNCI */
14430 /* Break the TB to be able to sync copied instructions
14431 immediately */
14432 ctx->bstate = BS_STOP;
14433 } else {
14434 /* TNEI */
14435 mips32_op = OPC_TNEI;
14436 goto do_trapi;
14438 break;
14439 case TEQI:
14440 check_insn_opc_removed(ctx, ISA_MIPS32R6);
14441 mips32_op = OPC_TEQI;
14442 do_trapi:
14443 gen_trap(ctx, mips32_op, rs, -1, imm);
14444 break;
14446 case BNEZC:
14447 case BEQZC:
14448 check_insn_opc_removed(ctx, ISA_MIPS32R6);
14449 gen_compute_branch(ctx, minor == BNEZC ? OPC_BNE : OPC_BEQ,
14450 4, rs, 0, imm << 1, 0);
14451 /* Compact branches don't have a delay slot, so just let
14452 the normal delay slot handling take us to the branch
14453 target. */
14454 break;
14455 case LUI:
14456 check_insn_opc_removed(ctx, ISA_MIPS32R6);
14457 gen_logic_imm(ctx, OPC_LUI, rs, 0, imm);
14458 break;
14459 case SYNCI:
14460 check_insn_opc_removed(ctx, ISA_MIPS32R6);
14461 /* Break the TB to be able to sync copied instructions
14462 immediately */
14463 ctx->bstate = BS_STOP;
14464 break;
14465 case BC2F:
14466 case BC2T:
14467 check_insn_opc_removed(ctx, ISA_MIPS32R6);
14468 /* COP2: Not implemented. */
14469 generate_exception_err(ctx, EXCP_CpU, 2);
14470 break;
14471 case BC1F:
14472 check_insn_opc_removed(ctx, ISA_MIPS32R6);
14473 mips32_op = (ctx->opcode & (1 << 16)) ? OPC_BC1FANY2 : OPC_BC1F;
14474 goto do_cp1branch;
14475 case BC1T:
14476 check_insn_opc_removed(ctx, ISA_MIPS32R6);
14477 mips32_op = (ctx->opcode & (1 << 16)) ? OPC_BC1TANY2 : OPC_BC1T;
14478 goto do_cp1branch;
14479 case BC1ANY4F:
14480 check_insn_opc_removed(ctx, ISA_MIPS32R6);
14481 mips32_op = OPC_BC1FANY4;
14482 goto do_cp1mips3d;
14483 case BC1ANY4T:
14484 check_insn_opc_removed(ctx, ISA_MIPS32R6);
14485 mips32_op = OPC_BC1TANY4;
14486 do_cp1mips3d:
14487 check_cop1x(ctx);
14488 check_insn(ctx, ASE_MIPS3D);
14489 /* Fall through */
14490 do_cp1branch:
14491 if (env->CP0_Config1 & (1 << CP0C1_FP)) {
14492 check_cp1_enabled(ctx);
14493 gen_compute_branch1(ctx, mips32_op,
14494 (ctx->opcode >> 18) & 0x7, imm << 1);
14495 } else {
14496 generate_exception_err(ctx, EXCP_CpU, 1);
14498 break;
14499 case BPOSGE64:
14500 case BPOSGE32:
14501 /* MIPS DSP: not implemented */
14502 /* Fall through */
14503 default:
14504 MIPS_INVAL("pool32i");
14505 generate_exception_end(ctx, EXCP_RI);
14506 break;
14508 break;
14509 case POOL32C:
14510 minor = (ctx->opcode >> 12) & 0xf;
14511 offset = sextract32(ctx->opcode, 0,
14512 (ctx->insn_flags & ISA_MIPS32R6) ? 9 : 12);
14513 switch (minor) {
14514 case LWL:
14515 check_insn_opc_removed(ctx, ISA_MIPS32R6);
14516 mips32_op = OPC_LWL;
14517 goto do_ld_lr;
14518 case SWL:
14519 check_insn_opc_removed(ctx, ISA_MIPS32R6);
14520 mips32_op = OPC_SWL;
14521 goto do_st_lr;
14522 case LWR:
14523 check_insn_opc_removed(ctx, ISA_MIPS32R6);
14524 mips32_op = OPC_LWR;
14525 goto do_ld_lr;
14526 case SWR:
14527 check_insn_opc_removed(ctx, ISA_MIPS32R6);
14528 mips32_op = OPC_SWR;
14529 goto do_st_lr;
14530 #if defined(TARGET_MIPS64)
14531 case LDL:
14532 check_insn(ctx, ISA_MIPS3);
14533 check_mips_64(ctx);
14534 check_insn_opc_removed(ctx, ISA_MIPS32R6);
14535 mips32_op = OPC_LDL;
14536 goto do_ld_lr;
14537 case SDL:
14538 check_insn(ctx, ISA_MIPS3);
14539 check_mips_64(ctx);
14540 check_insn_opc_removed(ctx, ISA_MIPS32R6);
14541 mips32_op = OPC_SDL;
14542 goto do_st_lr;
14543 case LDR:
14544 check_insn(ctx, ISA_MIPS3);
14545 check_mips_64(ctx);
14546 check_insn_opc_removed(ctx, ISA_MIPS32R6);
14547 mips32_op = OPC_LDR;
14548 goto do_ld_lr;
14549 case SDR:
14550 check_insn(ctx, ISA_MIPS3);
14551 check_mips_64(ctx);
14552 check_insn_opc_removed(ctx, ISA_MIPS32R6);
14553 mips32_op = OPC_SDR;
14554 goto do_st_lr;
14555 case LWU:
14556 check_insn(ctx, ISA_MIPS3);
14557 check_mips_64(ctx);
14558 mips32_op = OPC_LWU;
14559 goto do_ld_lr;
14560 case LLD:
14561 check_insn(ctx, ISA_MIPS3);
14562 check_mips_64(ctx);
14563 mips32_op = OPC_LLD;
14564 goto do_ld_lr;
14565 #endif
14566 case LL:
14567 mips32_op = OPC_LL;
14568 goto do_ld_lr;
14569 do_ld_lr:
14570 gen_ld(ctx, mips32_op, rt, rs, offset);
14571 break;
14572 do_st_lr:
14573 gen_st(ctx, mips32_op, rt, rs, SIMM(ctx->opcode, 0, 12));
14574 break;
14575 case SC:
14576 gen_st_cond(ctx, OPC_SC, rt, rs, offset);
14577 break;
14578 #if defined(TARGET_MIPS64)
14579 case SCD:
14580 check_insn(ctx, ISA_MIPS3);
14581 check_mips_64(ctx);
14582 gen_st_cond(ctx, OPC_SCD, rt, rs, offset);
14583 break;
14584 #endif
14585 case PREF:
14586 /* Treat as no-op */
14587 if ((ctx->insn_flags & ISA_MIPS32R6) && (rt >= 24)) {
14588 /* hint codes 24-31 are reserved and signal RI */
14589 generate_exception(ctx, EXCP_RI);
14591 break;
14592 default:
14593 MIPS_INVAL("pool32c");
14594 generate_exception_end(ctx, EXCP_RI);
14595 break;
14597 break;
14598 case ADDI32: /* AUI, LUI */
14599 if (ctx->insn_flags & ISA_MIPS32R6) {
14600 /* AUI, LUI */
14601 gen_logic_imm(ctx, OPC_LUI, rt, rs, imm);
14602 } else {
14603 /* ADDI32 */
14604 mips32_op = OPC_ADDI;
14605 goto do_addi;
14607 break;
14608 case ADDIU32:
14609 mips32_op = OPC_ADDIU;
14610 do_addi:
14611 gen_arith_imm(ctx, mips32_op, rt, rs, imm);
14612 break;
14614 /* Logical operations */
14615 case ORI32:
14616 mips32_op = OPC_ORI;
14617 goto do_logici;
14618 case XORI32:
14619 mips32_op = OPC_XORI;
14620 goto do_logici;
14621 case ANDI32:
14622 mips32_op = OPC_ANDI;
14623 do_logici:
14624 gen_logic_imm(ctx, mips32_op, rt, rs, imm);
14625 break;
14627 /* Set less than immediate */
14628 case SLTI32:
14629 mips32_op = OPC_SLTI;
14630 goto do_slti;
14631 case SLTIU32:
14632 mips32_op = OPC_SLTIU;
14633 do_slti:
14634 gen_slt_imm(ctx, mips32_op, rt, rs, imm);
14635 break;
14636 case JALX32:
14637 check_insn_opc_removed(ctx, ISA_MIPS32R6);
14638 offset = (int32_t)(ctx->opcode & 0x3FFFFFF) << 2;
14639 gen_compute_branch(ctx, OPC_JALX, 4, rt, rs, offset, 4);
14640 ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
14641 break;
14642 case JALS32: /* BOVC, BEQC, BEQZALC */
14643 if (ctx->insn_flags & ISA_MIPS32R6) {
14644 if (rs >= rt) {
14645 /* BOVC */
14646 mips32_op = OPC_BOVC;
14647 } else if (rs < rt && rs == 0) {
14648 /* BEQZALC */
14649 mips32_op = OPC_BEQZALC;
14650 } else {
14651 /* BEQC */
14652 mips32_op = OPC_BEQC;
14654 gen_compute_compact_branch(ctx, mips32_op, rs, rt, imm << 1);
14655 } else {
14656 /* JALS32 */
14657 offset = (int32_t)(ctx->opcode & 0x3FFFFFF) << 1;
14658 gen_compute_branch(ctx, OPC_JAL, 4, rt, rs, offset, 2);
14659 ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
14661 break;
14662 case BEQ32: /* BC */
14663 if (ctx->insn_flags & ISA_MIPS32R6) {
14664 /* BC */
14665 gen_compute_compact_branch(ctx, OPC_BC, 0, 0,
14666 sextract32(ctx->opcode << 1, 0, 27));
14667 } else {
14668 /* BEQ32 */
14669 gen_compute_branch(ctx, OPC_BEQ, 4, rt, rs, imm << 1, 4);
14671 break;
14672 case BNE32: /* BALC */
14673 if (ctx->insn_flags & ISA_MIPS32R6) {
14674 /* BALC */
14675 gen_compute_compact_branch(ctx, OPC_BALC, 0, 0,
14676 sextract32(ctx->opcode << 1, 0, 27));
14677 } else {
14678 /* BNE32 */
14679 gen_compute_branch(ctx, OPC_BNE, 4, rt, rs, imm << 1, 4);
14681 break;
14682 case J32: /* BGTZC, BLTZC, BLTC */
14683 if (ctx->insn_flags & ISA_MIPS32R6) {
14684 if (rs == 0 && rt != 0) {
14685 /* BGTZC */
14686 mips32_op = OPC_BGTZC;
14687 } else if (rs != 0 && rt != 0 && rs == rt) {
14688 /* BLTZC */
14689 mips32_op = OPC_BLTZC;
14690 } else {
14691 /* BLTC */
14692 mips32_op = OPC_BLTC;
14694 gen_compute_compact_branch(ctx, mips32_op, rs, rt, imm << 1);
14695 } else {
14696 /* J32 */
14697 gen_compute_branch(ctx, OPC_J, 4, rt, rs,
14698 (int32_t)(ctx->opcode & 0x3FFFFFF) << 1, 4);
14700 break;
14701 case JAL32: /* BLEZC, BGEZC, BGEC */
14702 if (ctx->insn_flags & ISA_MIPS32R6) {
14703 if (rs == 0 && rt != 0) {
14704 /* BLEZC */
14705 mips32_op = OPC_BLEZC;
14706 } else if (rs != 0 && rt != 0 && rs == rt) {
14707 /* BGEZC */
14708 mips32_op = OPC_BGEZC;
14709 } else {
14710 /* BGEC */
14711 mips32_op = OPC_BGEC;
14713 gen_compute_compact_branch(ctx, mips32_op, rs, rt, imm << 1);
14714 } else {
14715 /* JAL32 */
14716 gen_compute_branch(ctx, OPC_JAL, 4, rt, rs,
14717 (int32_t)(ctx->opcode & 0x3FFFFFF) << 1, 4);
14718 ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
14720 break;
14721 /* Floating point (COP1) */
14722 case LWC132:
14723 mips32_op = OPC_LWC1;
14724 goto do_cop1;
14725 case LDC132:
14726 mips32_op = OPC_LDC1;
14727 goto do_cop1;
14728 case SWC132:
14729 mips32_op = OPC_SWC1;
14730 goto do_cop1;
14731 case SDC132:
14732 mips32_op = OPC_SDC1;
14733 do_cop1:
14734 gen_cop1_ldst(ctx, mips32_op, rt, rs, imm);
14735 break;
14736 case ADDIUPC: /* PCREL: ADDIUPC, AUIPC, ALUIPC, LWPC */
14737 if (ctx->insn_flags & ISA_MIPS32R6) {
14738 /* PCREL: ADDIUPC, AUIPC, ALUIPC, LWPC */
14739 switch ((ctx->opcode >> 16) & 0x1f) {
14740 case ADDIUPC_00 ... ADDIUPC_07:
14741 gen_pcrel(ctx, OPC_ADDIUPC, ctx->pc & ~0x3, rt);
14742 break;
14743 case AUIPC:
14744 gen_pcrel(ctx, OPC_AUIPC, ctx->pc, rt);
14745 break;
14746 case ALUIPC:
14747 gen_pcrel(ctx, OPC_ALUIPC, ctx->pc, rt);
14748 break;
14749 case LWPC_08 ... LWPC_0F:
14750 gen_pcrel(ctx, R6_OPC_LWPC, ctx->pc & ~0x3, rt);
14751 break;
14752 default:
14753 generate_exception(ctx, EXCP_RI);
14754 break;
14756 } else {
14757 /* ADDIUPC */
14758 int reg = mmreg(ZIMM(ctx->opcode, 23, 3));
14759 int offset = SIMM(ctx->opcode, 0, 23) << 2;
14761 gen_addiupc(ctx, reg, offset, 0, 0);
14763 break;
14764 case BNVC: /* BNEC, BNEZALC */
14765 check_insn(ctx, ISA_MIPS32R6);
14766 if (rs >= rt) {
14767 /* BNVC */
14768 mips32_op = OPC_BNVC;
14769 } else if (rs < rt && rs == 0) {
14770 /* BNEZALC */
14771 mips32_op = OPC_BNEZALC;
14772 } else {
14773 /* BNEC */
14774 mips32_op = OPC_BNEC;
14776 gen_compute_compact_branch(ctx, mips32_op, rs, rt, imm << 1);
14777 break;
14778 case R6_BNEZC: /* JIALC */
14779 check_insn(ctx, ISA_MIPS32R6);
14780 if (rt != 0) {
14781 /* BNEZC */
14782 gen_compute_compact_branch(ctx, OPC_BNEZC, rt, 0,
14783 sextract32(ctx->opcode << 1, 0, 22));
14784 } else {
14785 /* JIALC */
14786 gen_compute_compact_branch(ctx, OPC_JIALC, 0, rs, imm);
14788 break;
14789 case R6_BEQZC: /* JIC */
14790 check_insn(ctx, ISA_MIPS32R6);
14791 if (rt != 0) {
14792 /* BEQZC */
14793 gen_compute_compact_branch(ctx, OPC_BEQZC, rt, 0,
14794 sextract32(ctx->opcode << 1, 0, 22));
14795 } else {
14796 /* JIC */
14797 gen_compute_compact_branch(ctx, OPC_JIC, 0, rs, imm);
14799 break;
14800 case BLEZALC: /* BGEZALC, BGEUC */
14801 check_insn(ctx, ISA_MIPS32R6);
14802 if (rs == 0 && rt != 0) {
14803 /* BLEZALC */
14804 mips32_op = OPC_BLEZALC;
14805 } else if (rs != 0 && rt != 0 && rs == rt) {
14806 /* BGEZALC */
14807 mips32_op = OPC_BGEZALC;
14808 } else {
14809 /* BGEUC */
14810 mips32_op = OPC_BGEUC;
14812 gen_compute_compact_branch(ctx, mips32_op, rs, rt, imm << 1);
14813 break;
14814 case BGTZALC: /* BLTZALC, BLTUC */
14815 check_insn(ctx, ISA_MIPS32R6);
14816 if (rs == 0 && rt != 0) {
14817 /* BGTZALC */
14818 mips32_op = OPC_BGTZALC;
14819 } else if (rs != 0 && rt != 0 && rs == rt) {
14820 /* BLTZALC */
14821 mips32_op = OPC_BLTZALC;
14822 } else {
14823 /* BLTUC */
14824 mips32_op = OPC_BLTUC;
14826 gen_compute_compact_branch(ctx, mips32_op, rs, rt, imm << 1);
14827 break;
14828 /* Loads and stores */
14829 case LB32:
14830 mips32_op = OPC_LB;
14831 goto do_ld;
14832 case LBU32:
14833 mips32_op = OPC_LBU;
14834 goto do_ld;
14835 case LH32:
14836 mips32_op = OPC_LH;
14837 goto do_ld;
14838 case LHU32:
14839 mips32_op = OPC_LHU;
14840 goto do_ld;
14841 case LW32:
14842 mips32_op = OPC_LW;
14843 goto do_ld;
14844 #ifdef TARGET_MIPS64
14845 case LD32:
14846 check_insn(ctx, ISA_MIPS3);
14847 check_mips_64(ctx);
14848 mips32_op = OPC_LD;
14849 goto do_ld;
14850 case SD32:
14851 check_insn(ctx, ISA_MIPS3);
14852 check_mips_64(ctx);
14853 mips32_op = OPC_SD;
14854 goto do_st;
14855 #endif
14856 case SB32:
14857 mips32_op = OPC_SB;
14858 goto do_st;
14859 case SH32:
14860 mips32_op = OPC_SH;
14861 goto do_st;
14862 case SW32:
14863 mips32_op = OPC_SW;
14864 goto do_st;
14865 do_ld:
14866 gen_ld(ctx, mips32_op, rt, rs, imm);
14867 break;
14868 do_st:
14869 gen_st(ctx, mips32_op, rt, rs, imm);
14870 break;
14871 default:
14872 generate_exception_end(ctx, EXCP_RI);
14873 break;
14877 static int decode_micromips_opc (CPUMIPSState *env, DisasContext *ctx)
14879 uint32_t op;
14881 /* make sure instructions are on a halfword boundary */
14882 if (ctx->pc & 0x1) {
14883 env->CP0_BadVAddr = ctx->pc;
14884 generate_exception_end(ctx, EXCP_AdEL);
14885 return 2;
14888 op = (ctx->opcode >> 10) & 0x3f;
14889 /* Enforce properly-sized instructions in a delay slot */
14890 if (ctx->hflags & MIPS_HFLAG_BDS_STRICT) {
14891 switch (op & 0x7) { /* MSB-3..MSB-5 */
14892 case 0:
14893 /* POOL32A, POOL32B, POOL32I, POOL32C */
14894 case 4:
14895 /* ADDI32, ADDIU32, ORI32, XORI32, SLTI32, SLTIU32, ANDI32, JALX32 */
14896 case 5:
14897 /* LBU32, LHU32, POOL32F, JALS32, BEQ32, BNE32, J32, JAL32 */
14898 case 6:
14899 /* SB32, SH32, ADDIUPC, SWC132, SDC132, SW32 */
14900 case 7:
14901 /* LB32, LH32, LWC132, LDC132, LW32 */
14902 if (ctx->hflags & MIPS_HFLAG_BDS16) {
14903 generate_exception_end(ctx, EXCP_RI);
14904 return 2;
14906 break;
14907 case 1:
14908 /* POOL16A, POOL16B, POOL16C, LWGP16, POOL16F */
14909 case 2:
14910 /* LBU16, LHU16, LWSP16, LW16, SB16, SH16, SWSP16, SW16 */
14911 case 3:
14912 /* MOVE16, ANDI16, POOL16D, POOL16E, BEQZ16, BNEZ16, B16, LI16 */
14913 if (ctx->hflags & MIPS_HFLAG_BDS32) {
14914 generate_exception_end(ctx, EXCP_RI);
14915 return 2;
14917 break;
14921 switch (op) {
14922 case POOL16A:
14924 int rd = mmreg(uMIPS_RD(ctx->opcode));
14925 int rs1 = mmreg(uMIPS_RS1(ctx->opcode));
14926 int rs2 = mmreg(uMIPS_RS2(ctx->opcode));
14927 uint32_t opc = 0;
14929 switch (ctx->opcode & 0x1) {
14930 case ADDU16:
14931 opc = OPC_ADDU;
14932 break;
14933 case SUBU16:
14934 opc = OPC_SUBU;
14935 break;
14937 if (ctx->insn_flags & ISA_MIPS32R6) {
14938 /* In the Release 6 the register number location in
14939 * the instruction encoding has changed.
14941 gen_arith(ctx, opc, rs1, rd, rs2);
14942 } else {
14943 gen_arith(ctx, opc, rd, rs1, rs2);
14946 break;
14947 case POOL16B:
14949 int rd = mmreg(uMIPS_RD(ctx->opcode));
14950 int rs = mmreg(uMIPS_RS(ctx->opcode));
14951 int amount = (ctx->opcode >> 1) & 0x7;
14952 uint32_t opc = 0;
14953 amount = amount == 0 ? 8 : amount;
14955 switch (ctx->opcode & 0x1) {
14956 case SLL16:
14957 opc = OPC_SLL;
14958 break;
14959 case SRL16:
14960 opc = OPC_SRL;
14961 break;
14964 gen_shift_imm(ctx, opc, rd, rs, amount);
14966 break;
14967 case POOL16C:
14968 if (ctx->insn_flags & ISA_MIPS32R6) {
14969 gen_pool16c_r6_insn(ctx);
14970 } else {
14971 gen_pool16c_insn(ctx);
14973 break;
14974 case LWGP16:
14976 int rd = mmreg(uMIPS_RD(ctx->opcode));
14977 int rb = 28; /* GP */
14978 int16_t offset = SIMM(ctx->opcode, 0, 7) << 2;
14980 gen_ld(ctx, OPC_LW, rd, rb, offset);
14982 break;
14983 case POOL16F:
14984 check_insn_opc_removed(ctx, ISA_MIPS32R6);
14985 if (ctx->opcode & 1) {
14986 generate_exception_end(ctx, EXCP_RI);
14987 } else {
14988 /* MOVEP */
14989 int enc_dest = uMIPS_RD(ctx->opcode);
14990 int enc_rt = uMIPS_RS2(ctx->opcode);
14991 int enc_rs = uMIPS_RS1(ctx->opcode);
14992 gen_movep(ctx, enc_dest, enc_rt, enc_rs);
14994 break;
14995 case LBU16:
14997 int rd = mmreg(uMIPS_RD(ctx->opcode));
14998 int rb = mmreg(uMIPS_RS(ctx->opcode));
14999 int16_t offset = ZIMM(ctx->opcode, 0, 4);
15000 offset = (offset == 0xf ? -1 : offset);
15002 gen_ld(ctx, OPC_LBU, rd, rb, offset);
15004 break;
15005 case LHU16:
15007 int rd = mmreg(uMIPS_RD(ctx->opcode));
15008 int rb = mmreg(uMIPS_RS(ctx->opcode));
15009 int16_t offset = ZIMM(ctx->opcode, 0, 4) << 1;
15011 gen_ld(ctx, OPC_LHU, rd, rb, offset);
15013 break;
15014 case LWSP16:
15016 int rd = (ctx->opcode >> 5) & 0x1f;
15017 int rb = 29; /* SP */
15018 int16_t offset = ZIMM(ctx->opcode, 0, 5) << 2;
15020 gen_ld(ctx, OPC_LW, rd, rb, offset);
15022 break;
15023 case LW16:
15025 int rd = mmreg(uMIPS_RD(ctx->opcode));
15026 int rb = mmreg(uMIPS_RS(ctx->opcode));
15027 int16_t offset = ZIMM(ctx->opcode, 0, 4) << 2;
15029 gen_ld(ctx, OPC_LW, rd, rb, offset);
15031 break;
15032 case SB16:
15034 int rd = mmreg2(uMIPS_RD(ctx->opcode));
15035 int rb = mmreg(uMIPS_RS(ctx->opcode));
15036 int16_t offset = ZIMM(ctx->opcode, 0, 4);
15038 gen_st(ctx, OPC_SB, rd, rb, offset);
15040 break;
15041 case SH16:
15043 int rd = mmreg2(uMIPS_RD(ctx->opcode));
15044 int rb = mmreg(uMIPS_RS(ctx->opcode));
15045 int16_t offset = ZIMM(ctx->opcode, 0, 4) << 1;
15047 gen_st(ctx, OPC_SH, rd, rb, offset);
15049 break;
15050 case SWSP16:
15052 int rd = (ctx->opcode >> 5) & 0x1f;
15053 int rb = 29; /* SP */
15054 int16_t offset = ZIMM(ctx->opcode, 0, 5) << 2;
15056 gen_st(ctx, OPC_SW, rd, rb, offset);
15058 break;
15059 case SW16:
15061 int rd = mmreg2(uMIPS_RD(ctx->opcode));
15062 int rb = mmreg(uMIPS_RS(ctx->opcode));
15063 int16_t offset = ZIMM(ctx->opcode, 0, 4) << 2;
15065 gen_st(ctx, OPC_SW, rd, rb, offset);
15067 break;
15068 case MOVE16:
15070 int rd = uMIPS_RD5(ctx->opcode);
15071 int rs = uMIPS_RS5(ctx->opcode);
15073 gen_arith(ctx, OPC_ADDU, rd, rs, 0);
15075 break;
15076 case ANDI16:
15077 gen_andi16(ctx);
15078 break;
15079 case POOL16D:
15080 switch (ctx->opcode & 0x1) {
15081 case ADDIUS5:
15082 gen_addius5(ctx);
15083 break;
15084 case ADDIUSP:
15085 gen_addiusp(ctx);
15086 break;
15088 break;
15089 case POOL16E:
15090 switch (ctx->opcode & 0x1) {
15091 case ADDIUR2:
15092 gen_addiur2(ctx);
15093 break;
15094 case ADDIUR1SP:
15095 gen_addiur1sp(ctx);
15096 break;
15098 break;
15099 case B16: /* BC16 */
15100 gen_compute_branch(ctx, OPC_BEQ, 2, 0, 0,
15101 sextract32(ctx->opcode, 0, 10) << 1,
15102 (ctx->insn_flags & ISA_MIPS32R6) ? 0 : 4);
15103 break;
15104 case BNEZ16: /* BNEZC16 */
15105 case BEQZ16: /* BEQZC16 */
15106 gen_compute_branch(ctx, op == BNEZ16 ? OPC_BNE : OPC_BEQ, 2,
15107 mmreg(uMIPS_RD(ctx->opcode)),
15108 0, sextract32(ctx->opcode, 0, 7) << 1,
15109 (ctx->insn_flags & ISA_MIPS32R6) ? 0 : 4);
15111 break;
15112 case LI16:
15114 int reg = mmreg(uMIPS_RD(ctx->opcode));
15115 int imm = ZIMM(ctx->opcode, 0, 7);
15117 imm = (imm == 0x7f ? -1 : imm);
15118 tcg_gen_movi_tl(cpu_gpr[reg], imm);
15120 break;
15121 case RES_29:
15122 case RES_31:
15123 case RES_39:
15124 generate_exception_end(ctx, EXCP_RI);
15125 break;
15126 default:
15127 decode_micromips32_opc(env, ctx);
15128 return 4;
15131 return 2;
15134 /* SmartMIPS extension to MIPS32 */
15136 #if defined(TARGET_MIPS64)
15138 /* MDMX extension to MIPS64 */
15140 #endif
15142 /* MIPSDSP functions. */
15143 static void gen_mipsdsp_ld(DisasContext *ctx, uint32_t opc,
15144 int rd, int base, int offset)
15146 TCGv t0;
15148 check_dsp(ctx);
15149 t0 = tcg_temp_new();
15151 if (base == 0) {
15152 gen_load_gpr(t0, offset);
15153 } else if (offset == 0) {
15154 gen_load_gpr(t0, base);
15155 } else {
15156 gen_op_addr_add(ctx, t0, cpu_gpr[base], cpu_gpr[offset]);
15159 switch (opc) {
15160 case OPC_LBUX:
15161 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_UB);
15162 gen_store_gpr(t0, rd);
15163 break;
15164 case OPC_LHX:
15165 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TESW);
15166 gen_store_gpr(t0, rd);
15167 break;
15168 case OPC_LWX:
15169 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TESL);
15170 gen_store_gpr(t0, rd);
15171 break;
15172 #if defined(TARGET_MIPS64)
15173 case OPC_LDX:
15174 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TEQ);
15175 gen_store_gpr(t0, rd);
15176 break;
15177 #endif
15179 tcg_temp_free(t0);
15182 static void gen_mipsdsp_arith(DisasContext *ctx, uint32_t op1, uint32_t op2,
15183 int ret, int v1, int v2)
15185 TCGv v1_t;
15186 TCGv v2_t;
15188 if (ret == 0) {
15189 /* Treat as NOP. */
15190 return;
15193 v1_t = tcg_temp_new();
15194 v2_t = tcg_temp_new();
15196 gen_load_gpr(v1_t, v1);
15197 gen_load_gpr(v2_t, v2);
15199 switch (op1) {
15200 /* OPC_MULT_G_2E is equal OPC_ADDUH_QB_DSP */
15201 case OPC_MULT_G_2E:
15202 check_dspr2(ctx);
15203 switch (op2) {
15204 case OPC_ADDUH_QB:
15205 gen_helper_adduh_qb(cpu_gpr[ret], v1_t, v2_t);
15206 break;
15207 case OPC_ADDUH_R_QB:
15208 gen_helper_adduh_r_qb(cpu_gpr[ret], v1_t, v2_t);
15209 break;
15210 case OPC_ADDQH_PH:
15211 gen_helper_addqh_ph(cpu_gpr[ret], v1_t, v2_t);
15212 break;
15213 case OPC_ADDQH_R_PH:
15214 gen_helper_addqh_r_ph(cpu_gpr[ret], v1_t, v2_t);
15215 break;
15216 case OPC_ADDQH_W:
15217 gen_helper_addqh_w(cpu_gpr[ret], v1_t, v2_t);
15218 break;
15219 case OPC_ADDQH_R_W:
15220 gen_helper_addqh_r_w(cpu_gpr[ret], v1_t, v2_t);
15221 break;
15222 case OPC_SUBUH_QB:
15223 gen_helper_subuh_qb(cpu_gpr[ret], v1_t, v2_t);
15224 break;
15225 case OPC_SUBUH_R_QB:
15226 gen_helper_subuh_r_qb(cpu_gpr[ret], v1_t, v2_t);
15227 break;
15228 case OPC_SUBQH_PH:
15229 gen_helper_subqh_ph(cpu_gpr[ret], v1_t, v2_t);
15230 break;
15231 case OPC_SUBQH_R_PH:
15232 gen_helper_subqh_r_ph(cpu_gpr[ret], v1_t, v2_t);
15233 break;
15234 case OPC_SUBQH_W:
15235 gen_helper_subqh_w(cpu_gpr[ret], v1_t, v2_t);
15236 break;
15237 case OPC_SUBQH_R_W:
15238 gen_helper_subqh_r_w(cpu_gpr[ret], v1_t, v2_t);
15239 break;
15241 break;
15242 case OPC_ABSQ_S_PH_DSP:
15243 switch (op2) {
15244 case OPC_ABSQ_S_QB:
15245 check_dspr2(ctx);
15246 gen_helper_absq_s_qb(cpu_gpr[ret], v2_t, cpu_env);
15247 break;
15248 case OPC_ABSQ_S_PH:
15249 check_dsp(ctx);
15250 gen_helper_absq_s_ph(cpu_gpr[ret], v2_t, cpu_env);
15251 break;
15252 case OPC_ABSQ_S_W:
15253 check_dsp(ctx);
15254 gen_helper_absq_s_w(cpu_gpr[ret], v2_t, cpu_env);
15255 break;
15256 case OPC_PRECEQ_W_PHL:
15257 check_dsp(ctx);
15258 tcg_gen_andi_tl(cpu_gpr[ret], v2_t, 0xFFFF0000);
15259 tcg_gen_ext32s_tl(cpu_gpr[ret], cpu_gpr[ret]);
15260 break;
15261 case OPC_PRECEQ_W_PHR:
15262 check_dsp(ctx);
15263 tcg_gen_andi_tl(cpu_gpr[ret], v2_t, 0x0000FFFF);
15264 tcg_gen_shli_tl(cpu_gpr[ret], cpu_gpr[ret], 16);
15265 tcg_gen_ext32s_tl(cpu_gpr[ret], cpu_gpr[ret]);
15266 break;
15267 case OPC_PRECEQU_PH_QBL:
15268 check_dsp(ctx);
15269 gen_helper_precequ_ph_qbl(cpu_gpr[ret], v2_t);
15270 break;
15271 case OPC_PRECEQU_PH_QBR:
15272 check_dsp(ctx);
15273 gen_helper_precequ_ph_qbr(cpu_gpr[ret], v2_t);
15274 break;
15275 case OPC_PRECEQU_PH_QBLA:
15276 check_dsp(ctx);
15277 gen_helper_precequ_ph_qbla(cpu_gpr[ret], v2_t);
15278 break;
15279 case OPC_PRECEQU_PH_QBRA:
15280 check_dsp(ctx);
15281 gen_helper_precequ_ph_qbra(cpu_gpr[ret], v2_t);
15282 break;
15283 case OPC_PRECEU_PH_QBL:
15284 check_dsp(ctx);
15285 gen_helper_preceu_ph_qbl(cpu_gpr[ret], v2_t);
15286 break;
15287 case OPC_PRECEU_PH_QBR:
15288 check_dsp(ctx);
15289 gen_helper_preceu_ph_qbr(cpu_gpr[ret], v2_t);
15290 break;
15291 case OPC_PRECEU_PH_QBLA:
15292 check_dsp(ctx);
15293 gen_helper_preceu_ph_qbla(cpu_gpr[ret], v2_t);
15294 break;
15295 case OPC_PRECEU_PH_QBRA:
15296 check_dsp(ctx);
15297 gen_helper_preceu_ph_qbra(cpu_gpr[ret], v2_t);
15298 break;
15300 break;
15301 case OPC_ADDU_QB_DSP:
15302 switch (op2) {
15303 case OPC_ADDQ_PH:
15304 check_dsp(ctx);
15305 gen_helper_addq_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15306 break;
15307 case OPC_ADDQ_S_PH:
15308 check_dsp(ctx);
15309 gen_helper_addq_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15310 break;
15311 case OPC_ADDQ_S_W:
15312 check_dsp(ctx);
15313 gen_helper_addq_s_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15314 break;
15315 case OPC_ADDU_QB:
15316 check_dsp(ctx);
15317 gen_helper_addu_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15318 break;
15319 case OPC_ADDU_S_QB:
15320 check_dsp(ctx);
15321 gen_helper_addu_s_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15322 break;
15323 case OPC_ADDU_PH:
15324 check_dspr2(ctx);
15325 gen_helper_addu_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15326 break;
15327 case OPC_ADDU_S_PH:
15328 check_dspr2(ctx);
15329 gen_helper_addu_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15330 break;
15331 case OPC_SUBQ_PH:
15332 check_dsp(ctx);
15333 gen_helper_subq_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15334 break;
15335 case OPC_SUBQ_S_PH:
15336 check_dsp(ctx);
15337 gen_helper_subq_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15338 break;
15339 case OPC_SUBQ_S_W:
15340 check_dsp(ctx);
15341 gen_helper_subq_s_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15342 break;
15343 case OPC_SUBU_QB:
15344 check_dsp(ctx);
15345 gen_helper_subu_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15346 break;
15347 case OPC_SUBU_S_QB:
15348 check_dsp(ctx);
15349 gen_helper_subu_s_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15350 break;
15351 case OPC_SUBU_PH:
15352 check_dspr2(ctx);
15353 gen_helper_subu_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15354 break;
15355 case OPC_SUBU_S_PH:
15356 check_dspr2(ctx);
15357 gen_helper_subu_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15358 break;
15359 case OPC_ADDSC:
15360 check_dsp(ctx);
15361 gen_helper_addsc(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15362 break;
15363 case OPC_ADDWC:
15364 check_dsp(ctx);
15365 gen_helper_addwc(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15366 break;
15367 case OPC_MODSUB:
15368 check_dsp(ctx);
15369 gen_helper_modsub(cpu_gpr[ret], v1_t, v2_t);
15370 break;
15371 case OPC_RADDU_W_QB:
15372 check_dsp(ctx);
15373 gen_helper_raddu_w_qb(cpu_gpr[ret], v1_t);
15374 break;
15376 break;
15377 case OPC_CMPU_EQ_QB_DSP:
15378 switch (op2) {
15379 case OPC_PRECR_QB_PH:
15380 check_dspr2(ctx);
15381 gen_helper_precr_qb_ph(cpu_gpr[ret], v1_t, v2_t);
15382 break;
15383 case OPC_PRECRQ_QB_PH:
15384 check_dsp(ctx);
15385 gen_helper_precrq_qb_ph(cpu_gpr[ret], v1_t, v2_t);
15386 break;
15387 case OPC_PRECR_SRA_PH_W:
15388 check_dspr2(ctx);
15390 TCGv_i32 sa_t = tcg_const_i32(v2);
15391 gen_helper_precr_sra_ph_w(cpu_gpr[ret], sa_t, v1_t,
15392 cpu_gpr[ret]);
15393 tcg_temp_free_i32(sa_t);
15394 break;
15396 case OPC_PRECR_SRA_R_PH_W:
15397 check_dspr2(ctx);
15399 TCGv_i32 sa_t = tcg_const_i32(v2);
15400 gen_helper_precr_sra_r_ph_w(cpu_gpr[ret], sa_t, v1_t,
15401 cpu_gpr[ret]);
15402 tcg_temp_free_i32(sa_t);
15403 break;
15405 case OPC_PRECRQ_PH_W:
15406 check_dsp(ctx);
15407 gen_helper_precrq_ph_w(cpu_gpr[ret], v1_t, v2_t);
15408 break;
15409 case OPC_PRECRQ_RS_PH_W:
15410 check_dsp(ctx);
15411 gen_helper_precrq_rs_ph_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15412 break;
15413 case OPC_PRECRQU_S_QB_PH:
15414 check_dsp(ctx);
15415 gen_helper_precrqu_s_qb_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15416 break;
15418 break;
15419 #ifdef TARGET_MIPS64
15420 case OPC_ABSQ_S_QH_DSP:
15421 switch (op2) {
15422 case OPC_PRECEQ_L_PWL:
15423 check_dsp(ctx);
15424 tcg_gen_andi_tl(cpu_gpr[ret], v2_t, 0xFFFFFFFF00000000ull);
15425 break;
15426 case OPC_PRECEQ_L_PWR:
15427 check_dsp(ctx);
15428 tcg_gen_shli_tl(cpu_gpr[ret], v2_t, 32);
15429 break;
15430 case OPC_PRECEQ_PW_QHL:
15431 check_dsp(ctx);
15432 gen_helper_preceq_pw_qhl(cpu_gpr[ret], v2_t);
15433 break;
15434 case OPC_PRECEQ_PW_QHR:
15435 check_dsp(ctx);
15436 gen_helper_preceq_pw_qhr(cpu_gpr[ret], v2_t);
15437 break;
15438 case OPC_PRECEQ_PW_QHLA:
15439 check_dsp(ctx);
15440 gen_helper_preceq_pw_qhla(cpu_gpr[ret], v2_t);
15441 break;
15442 case OPC_PRECEQ_PW_QHRA:
15443 check_dsp(ctx);
15444 gen_helper_preceq_pw_qhra(cpu_gpr[ret], v2_t);
15445 break;
15446 case OPC_PRECEQU_QH_OBL:
15447 check_dsp(ctx);
15448 gen_helper_precequ_qh_obl(cpu_gpr[ret], v2_t);
15449 break;
15450 case OPC_PRECEQU_QH_OBR:
15451 check_dsp(ctx);
15452 gen_helper_precequ_qh_obr(cpu_gpr[ret], v2_t);
15453 break;
15454 case OPC_PRECEQU_QH_OBLA:
15455 check_dsp(ctx);
15456 gen_helper_precequ_qh_obla(cpu_gpr[ret], v2_t);
15457 break;
15458 case OPC_PRECEQU_QH_OBRA:
15459 check_dsp(ctx);
15460 gen_helper_precequ_qh_obra(cpu_gpr[ret], v2_t);
15461 break;
15462 case OPC_PRECEU_QH_OBL:
15463 check_dsp(ctx);
15464 gen_helper_preceu_qh_obl(cpu_gpr[ret], v2_t);
15465 break;
15466 case OPC_PRECEU_QH_OBR:
15467 check_dsp(ctx);
15468 gen_helper_preceu_qh_obr(cpu_gpr[ret], v2_t);
15469 break;
15470 case OPC_PRECEU_QH_OBLA:
15471 check_dsp(ctx);
15472 gen_helper_preceu_qh_obla(cpu_gpr[ret], v2_t);
15473 break;
15474 case OPC_PRECEU_QH_OBRA:
15475 check_dsp(ctx);
15476 gen_helper_preceu_qh_obra(cpu_gpr[ret], v2_t);
15477 break;
15478 case OPC_ABSQ_S_OB:
15479 check_dspr2(ctx);
15480 gen_helper_absq_s_ob(cpu_gpr[ret], v2_t, cpu_env);
15481 break;
15482 case OPC_ABSQ_S_PW:
15483 check_dsp(ctx);
15484 gen_helper_absq_s_pw(cpu_gpr[ret], v2_t, cpu_env);
15485 break;
15486 case OPC_ABSQ_S_QH:
15487 check_dsp(ctx);
15488 gen_helper_absq_s_qh(cpu_gpr[ret], v2_t, cpu_env);
15489 break;
15491 break;
15492 case OPC_ADDU_OB_DSP:
15493 switch (op2) {
15494 case OPC_RADDU_L_OB:
15495 check_dsp(ctx);
15496 gen_helper_raddu_l_ob(cpu_gpr[ret], v1_t);
15497 break;
15498 case OPC_SUBQ_PW:
15499 check_dsp(ctx);
15500 gen_helper_subq_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15501 break;
15502 case OPC_SUBQ_S_PW:
15503 check_dsp(ctx);
15504 gen_helper_subq_s_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15505 break;
15506 case OPC_SUBQ_QH:
15507 check_dsp(ctx);
15508 gen_helper_subq_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15509 break;
15510 case OPC_SUBQ_S_QH:
15511 check_dsp(ctx);
15512 gen_helper_subq_s_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15513 break;
15514 case OPC_SUBU_OB:
15515 check_dsp(ctx);
15516 gen_helper_subu_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15517 break;
15518 case OPC_SUBU_S_OB:
15519 check_dsp(ctx);
15520 gen_helper_subu_s_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15521 break;
15522 case OPC_SUBU_QH:
15523 check_dspr2(ctx);
15524 gen_helper_subu_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15525 break;
15526 case OPC_SUBU_S_QH:
15527 check_dspr2(ctx);
15528 gen_helper_subu_s_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15529 break;
15530 case OPC_SUBUH_OB:
15531 check_dspr2(ctx);
15532 gen_helper_subuh_ob(cpu_gpr[ret], v1_t, v2_t);
15533 break;
15534 case OPC_SUBUH_R_OB:
15535 check_dspr2(ctx);
15536 gen_helper_subuh_r_ob(cpu_gpr[ret], v1_t, v2_t);
15537 break;
15538 case OPC_ADDQ_PW:
15539 check_dsp(ctx);
15540 gen_helper_addq_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15541 break;
15542 case OPC_ADDQ_S_PW:
15543 check_dsp(ctx);
15544 gen_helper_addq_s_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15545 break;
15546 case OPC_ADDQ_QH:
15547 check_dsp(ctx);
15548 gen_helper_addq_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15549 break;
15550 case OPC_ADDQ_S_QH:
15551 check_dsp(ctx);
15552 gen_helper_addq_s_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15553 break;
15554 case OPC_ADDU_OB:
15555 check_dsp(ctx);
15556 gen_helper_addu_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15557 break;
15558 case OPC_ADDU_S_OB:
15559 check_dsp(ctx);
15560 gen_helper_addu_s_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15561 break;
15562 case OPC_ADDU_QH:
15563 check_dspr2(ctx);
15564 gen_helper_addu_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15565 break;
15566 case OPC_ADDU_S_QH:
15567 check_dspr2(ctx);
15568 gen_helper_addu_s_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15569 break;
15570 case OPC_ADDUH_OB:
15571 check_dspr2(ctx);
15572 gen_helper_adduh_ob(cpu_gpr[ret], v1_t, v2_t);
15573 break;
15574 case OPC_ADDUH_R_OB:
15575 check_dspr2(ctx);
15576 gen_helper_adduh_r_ob(cpu_gpr[ret], v1_t, v2_t);
15577 break;
15579 break;
15580 case OPC_CMPU_EQ_OB_DSP:
15581 switch (op2) {
15582 case OPC_PRECR_OB_QH:
15583 check_dspr2(ctx);
15584 gen_helper_precr_ob_qh(cpu_gpr[ret], v1_t, v2_t);
15585 break;
15586 case OPC_PRECR_SRA_QH_PW:
15587 check_dspr2(ctx);
15589 TCGv_i32 ret_t = tcg_const_i32(ret);
15590 gen_helper_precr_sra_qh_pw(v2_t, v1_t, v2_t, ret_t);
15591 tcg_temp_free_i32(ret_t);
15592 break;
15594 case OPC_PRECR_SRA_R_QH_PW:
15595 check_dspr2(ctx);
15597 TCGv_i32 sa_v = tcg_const_i32(ret);
15598 gen_helper_precr_sra_r_qh_pw(v2_t, v1_t, v2_t, sa_v);
15599 tcg_temp_free_i32(sa_v);
15600 break;
15602 case OPC_PRECRQ_OB_QH:
15603 check_dsp(ctx);
15604 gen_helper_precrq_ob_qh(cpu_gpr[ret], v1_t, v2_t);
15605 break;
15606 case OPC_PRECRQ_PW_L:
15607 check_dsp(ctx);
15608 gen_helper_precrq_pw_l(cpu_gpr[ret], v1_t, v2_t);
15609 break;
15610 case OPC_PRECRQ_QH_PW:
15611 check_dsp(ctx);
15612 gen_helper_precrq_qh_pw(cpu_gpr[ret], v1_t, v2_t);
15613 break;
15614 case OPC_PRECRQ_RS_QH_PW:
15615 check_dsp(ctx);
15616 gen_helper_precrq_rs_qh_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15617 break;
15618 case OPC_PRECRQU_S_OB_QH:
15619 check_dsp(ctx);
15620 gen_helper_precrqu_s_ob_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15621 break;
15623 break;
15624 #endif
15627 tcg_temp_free(v1_t);
15628 tcg_temp_free(v2_t);
15631 static void gen_mipsdsp_shift(DisasContext *ctx, uint32_t opc,
15632 int ret, int v1, int v2)
15634 uint32_t op2;
15635 TCGv t0;
15636 TCGv v1_t;
15637 TCGv v2_t;
15639 if (ret == 0) {
15640 /* Treat as NOP. */
15641 return;
15644 t0 = tcg_temp_new();
15645 v1_t = tcg_temp_new();
15646 v2_t = tcg_temp_new();
15648 tcg_gen_movi_tl(t0, v1);
15649 gen_load_gpr(v1_t, v1);
15650 gen_load_gpr(v2_t, v2);
15652 switch (opc) {
15653 case OPC_SHLL_QB_DSP:
15655 op2 = MASK_SHLL_QB(ctx->opcode);
15656 switch (op2) {
15657 case OPC_SHLL_QB:
15658 check_dsp(ctx);
15659 gen_helper_shll_qb(cpu_gpr[ret], t0, v2_t, cpu_env);
15660 break;
15661 case OPC_SHLLV_QB:
15662 check_dsp(ctx);
15663 gen_helper_shll_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15664 break;
15665 case OPC_SHLL_PH:
15666 check_dsp(ctx);
15667 gen_helper_shll_ph(cpu_gpr[ret], t0, v2_t, cpu_env);
15668 break;
15669 case OPC_SHLLV_PH:
15670 check_dsp(ctx);
15671 gen_helper_shll_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15672 break;
15673 case OPC_SHLL_S_PH:
15674 check_dsp(ctx);
15675 gen_helper_shll_s_ph(cpu_gpr[ret], t0, v2_t, cpu_env);
15676 break;
15677 case OPC_SHLLV_S_PH:
15678 check_dsp(ctx);
15679 gen_helper_shll_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15680 break;
15681 case OPC_SHLL_S_W:
15682 check_dsp(ctx);
15683 gen_helper_shll_s_w(cpu_gpr[ret], t0, v2_t, cpu_env);
15684 break;
15685 case OPC_SHLLV_S_W:
15686 check_dsp(ctx);
15687 gen_helper_shll_s_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15688 break;
15689 case OPC_SHRL_QB:
15690 check_dsp(ctx);
15691 gen_helper_shrl_qb(cpu_gpr[ret], t0, v2_t);
15692 break;
15693 case OPC_SHRLV_QB:
15694 check_dsp(ctx);
15695 gen_helper_shrl_qb(cpu_gpr[ret], v1_t, v2_t);
15696 break;
15697 case OPC_SHRL_PH:
15698 check_dspr2(ctx);
15699 gen_helper_shrl_ph(cpu_gpr[ret], t0, v2_t);
15700 break;
15701 case OPC_SHRLV_PH:
15702 check_dspr2(ctx);
15703 gen_helper_shrl_ph(cpu_gpr[ret], v1_t, v2_t);
15704 break;
15705 case OPC_SHRA_QB:
15706 check_dspr2(ctx);
15707 gen_helper_shra_qb(cpu_gpr[ret], t0, v2_t);
15708 break;
15709 case OPC_SHRA_R_QB:
15710 check_dspr2(ctx);
15711 gen_helper_shra_r_qb(cpu_gpr[ret], t0, v2_t);
15712 break;
15713 case OPC_SHRAV_QB:
15714 check_dspr2(ctx);
15715 gen_helper_shra_qb(cpu_gpr[ret], v1_t, v2_t);
15716 break;
15717 case OPC_SHRAV_R_QB:
15718 check_dspr2(ctx);
15719 gen_helper_shra_r_qb(cpu_gpr[ret], v1_t, v2_t);
15720 break;
15721 case OPC_SHRA_PH:
15722 check_dsp(ctx);
15723 gen_helper_shra_ph(cpu_gpr[ret], t0, v2_t);
15724 break;
15725 case OPC_SHRA_R_PH:
15726 check_dsp(ctx);
15727 gen_helper_shra_r_ph(cpu_gpr[ret], t0, v2_t);
15728 break;
15729 case OPC_SHRAV_PH:
15730 check_dsp(ctx);
15731 gen_helper_shra_ph(cpu_gpr[ret], v1_t, v2_t);
15732 break;
15733 case OPC_SHRAV_R_PH:
15734 check_dsp(ctx);
15735 gen_helper_shra_r_ph(cpu_gpr[ret], v1_t, v2_t);
15736 break;
15737 case OPC_SHRA_R_W:
15738 check_dsp(ctx);
15739 gen_helper_shra_r_w(cpu_gpr[ret], t0, v2_t);
15740 break;
15741 case OPC_SHRAV_R_W:
15742 check_dsp(ctx);
15743 gen_helper_shra_r_w(cpu_gpr[ret], v1_t, v2_t);
15744 break;
15745 default: /* Invalid */
15746 MIPS_INVAL("MASK SHLL.QB");
15747 generate_exception_end(ctx, EXCP_RI);
15748 break;
15750 break;
15752 #ifdef TARGET_MIPS64
15753 case OPC_SHLL_OB_DSP:
15754 op2 = MASK_SHLL_OB(ctx->opcode);
15755 switch (op2) {
15756 case OPC_SHLL_PW:
15757 check_dsp(ctx);
15758 gen_helper_shll_pw(cpu_gpr[ret], v2_t, t0, cpu_env);
15759 break;
15760 case OPC_SHLLV_PW:
15761 check_dsp(ctx);
15762 gen_helper_shll_pw(cpu_gpr[ret], v2_t, v1_t, cpu_env);
15763 break;
15764 case OPC_SHLL_S_PW:
15765 check_dsp(ctx);
15766 gen_helper_shll_s_pw(cpu_gpr[ret], v2_t, t0, cpu_env);
15767 break;
15768 case OPC_SHLLV_S_PW:
15769 check_dsp(ctx);
15770 gen_helper_shll_s_pw(cpu_gpr[ret], v2_t, v1_t, cpu_env);
15771 break;
15772 case OPC_SHLL_OB:
15773 check_dsp(ctx);
15774 gen_helper_shll_ob(cpu_gpr[ret], v2_t, t0, cpu_env);
15775 break;
15776 case OPC_SHLLV_OB:
15777 check_dsp(ctx);
15778 gen_helper_shll_ob(cpu_gpr[ret], v2_t, v1_t, cpu_env);
15779 break;
15780 case OPC_SHLL_QH:
15781 check_dsp(ctx);
15782 gen_helper_shll_qh(cpu_gpr[ret], v2_t, t0, cpu_env);
15783 break;
15784 case OPC_SHLLV_QH:
15785 check_dsp(ctx);
15786 gen_helper_shll_qh(cpu_gpr[ret], v2_t, v1_t, cpu_env);
15787 break;
15788 case OPC_SHLL_S_QH:
15789 check_dsp(ctx);
15790 gen_helper_shll_s_qh(cpu_gpr[ret], v2_t, t0, cpu_env);
15791 break;
15792 case OPC_SHLLV_S_QH:
15793 check_dsp(ctx);
15794 gen_helper_shll_s_qh(cpu_gpr[ret], v2_t, v1_t, cpu_env);
15795 break;
15796 case OPC_SHRA_OB:
15797 check_dspr2(ctx);
15798 gen_helper_shra_ob(cpu_gpr[ret], v2_t, t0);
15799 break;
15800 case OPC_SHRAV_OB:
15801 check_dspr2(ctx);
15802 gen_helper_shra_ob(cpu_gpr[ret], v2_t, v1_t);
15803 break;
15804 case OPC_SHRA_R_OB:
15805 check_dspr2(ctx);
15806 gen_helper_shra_r_ob(cpu_gpr[ret], v2_t, t0);
15807 break;
15808 case OPC_SHRAV_R_OB:
15809 check_dspr2(ctx);
15810 gen_helper_shra_r_ob(cpu_gpr[ret], v2_t, v1_t);
15811 break;
15812 case OPC_SHRA_PW:
15813 check_dsp(ctx);
15814 gen_helper_shra_pw(cpu_gpr[ret], v2_t, t0);
15815 break;
15816 case OPC_SHRAV_PW:
15817 check_dsp(ctx);
15818 gen_helper_shra_pw(cpu_gpr[ret], v2_t, v1_t);
15819 break;
15820 case OPC_SHRA_R_PW:
15821 check_dsp(ctx);
15822 gen_helper_shra_r_pw(cpu_gpr[ret], v2_t, t0);
15823 break;
15824 case OPC_SHRAV_R_PW:
15825 check_dsp(ctx);
15826 gen_helper_shra_r_pw(cpu_gpr[ret], v2_t, v1_t);
15827 break;
15828 case OPC_SHRA_QH:
15829 check_dsp(ctx);
15830 gen_helper_shra_qh(cpu_gpr[ret], v2_t, t0);
15831 break;
15832 case OPC_SHRAV_QH:
15833 check_dsp(ctx);
15834 gen_helper_shra_qh(cpu_gpr[ret], v2_t, v1_t);
15835 break;
15836 case OPC_SHRA_R_QH:
15837 check_dsp(ctx);
15838 gen_helper_shra_r_qh(cpu_gpr[ret], v2_t, t0);
15839 break;
15840 case OPC_SHRAV_R_QH:
15841 check_dsp(ctx);
15842 gen_helper_shra_r_qh(cpu_gpr[ret], v2_t, v1_t);
15843 break;
15844 case OPC_SHRL_OB:
15845 check_dsp(ctx);
15846 gen_helper_shrl_ob(cpu_gpr[ret], v2_t, t0);
15847 break;
15848 case OPC_SHRLV_OB:
15849 check_dsp(ctx);
15850 gen_helper_shrl_ob(cpu_gpr[ret], v2_t, v1_t);
15851 break;
15852 case OPC_SHRL_QH:
15853 check_dspr2(ctx);
15854 gen_helper_shrl_qh(cpu_gpr[ret], v2_t, t0);
15855 break;
15856 case OPC_SHRLV_QH:
15857 check_dspr2(ctx);
15858 gen_helper_shrl_qh(cpu_gpr[ret], v2_t, v1_t);
15859 break;
15860 default: /* Invalid */
15861 MIPS_INVAL("MASK SHLL.OB");
15862 generate_exception_end(ctx, EXCP_RI);
15863 break;
15865 break;
15866 #endif
15869 tcg_temp_free(t0);
15870 tcg_temp_free(v1_t);
15871 tcg_temp_free(v2_t);
15874 static void gen_mipsdsp_multiply(DisasContext *ctx, uint32_t op1, uint32_t op2,
15875 int ret, int v1, int v2, int check_ret)
15877 TCGv_i32 t0;
15878 TCGv v1_t;
15879 TCGv v2_t;
15881 if ((ret == 0) && (check_ret == 1)) {
15882 /* Treat as NOP. */
15883 return;
15886 t0 = tcg_temp_new_i32();
15887 v1_t = tcg_temp_new();
15888 v2_t = tcg_temp_new();
15890 tcg_gen_movi_i32(t0, ret);
15891 gen_load_gpr(v1_t, v1);
15892 gen_load_gpr(v2_t, v2);
15894 switch (op1) {
15895 /* OPC_MULT_G_2E, OPC_ADDUH_QB_DSP, OPC_MUL_PH_DSP have
15896 * the same mask and op1. */
15897 case OPC_MULT_G_2E:
15898 check_dspr2(ctx);
15899 switch (op2) {
15900 case OPC_MUL_PH:
15901 gen_helper_mul_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15902 break;
15903 case OPC_MUL_S_PH:
15904 gen_helper_mul_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15905 break;
15906 case OPC_MULQ_S_W:
15907 gen_helper_mulq_s_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15908 break;
15909 case OPC_MULQ_RS_W:
15910 gen_helper_mulq_rs_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15911 break;
15913 break;
15914 case OPC_DPA_W_PH_DSP:
15915 switch (op2) {
15916 case OPC_DPAU_H_QBL:
15917 check_dsp(ctx);
15918 gen_helper_dpau_h_qbl(t0, v1_t, v2_t, cpu_env);
15919 break;
15920 case OPC_DPAU_H_QBR:
15921 check_dsp(ctx);
15922 gen_helper_dpau_h_qbr(t0, v1_t, v2_t, cpu_env);
15923 break;
15924 case OPC_DPSU_H_QBL:
15925 check_dsp(ctx);
15926 gen_helper_dpsu_h_qbl(t0, v1_t, v2_t, cpu_env);
15927 break;
15928 case OPC_DPSU_H_QBR:
15929 check_dsp(ctx);
15930 gen_helper_dpsu_h_qbr(t0, v1_t, v2_t, cpu_env);
15931 break;
15932 case OPC_DPA_W_PH:
15933 check_dspr2(ctx);
15934 gen_helper_dpa_w_ph(t0, v1_t, v2_t, cpu_env);
15935 break;
15936 case OPC_DPAX_W_PH:
15937 check_dspr2(ctx);
15938 gen_helper_dpax_w_ph(t0, v1_t, v2_t, cpu_env);
15939 break;
15940 case OPC_DPAQ_S_W_PH:
15941 check_dsp(ctx);
15942 gen_helper_dpaq_s_w_ph(t0, v1_t, v2_t, cpu_env);
15943 break;
15944 case OPC_DPAQX_S_W_PH:
15945 check_dspr2(ctx);
15946 gen_helper_dpaqx_s_w_ph(t0, v1_t, v2_t, cpu_env);
15947 break;
15948 case OPC_DPAQX_SA_W_PH:
15949 check_dspr2(ctx);
15950 gen_helper_dpaqx_sa_w_ph(t0, v1_t, v2_t, cpu_env);
15951 break;
15952 case OPC_DPS_W_PH:
15953 check_dspr2(ctx);
15954 gen_helper_dps_w_ph(t0, v1_t, v2_t, cpu_env);
15955 break;
15956 case OPC_DPSX_W_PH:
15957 check_dspr2(ctx);
15958 gen_helper_dpsx_w_ph(t0, v1_t, v2_t, cpu_env);
15959 break;
15960 case OPC_DPSQ_S_W_PH:
15961 check_dsp(ctx);
15962 gen_helper_dpsq_s_w_ph(t0, v1_t, v2_t, cpu_env);
15963 break;
15964 case OPC_DPSQX_S_W_PH:
15965 check_dspr2(ctx);
15966 gen_helper_dpsqx_s_w_ph(t0, v1_t, v2_t, cpu_env);
15967 break;
15968 case OPC_DPSQX_SA_W_PH:
15969 check_dspr2(ctx);
15970 gen_helper_dpsqx_sa_w_ph(t0, v1_t, v2_t, cpu_env);
15971 break;
15972 case OPC_MULSAQ_S_W_PH:
15973 check_dsp(ctx);
15974 gen_helper_mulsaq_s_w_ph(t0, v1_t, v2_t, cpu_env);
15975 break;
15976 case OPC_DPAQ_SA_L_W:
15977 check_dsp(ctx);
15978 gen_helper_dpaq_sa_l_w(t0, v1_t, v2_t, cpu_env);
15979 break;
15980 case OPC_DPSQ_SA_L_W:
15981 check_dsp(ctx);
15982 gen_helper_dpsq_sa_l_w(t0, v1_t, v2_t, cpu_env);
15983 break;
15984 case OPC_MAQ_S_W_PHL:
15985 check_dsp(ctx);
15986 gen_helper_maq_s_w_phl(t0, v1_t, v2_t, cpu_env);
15987 break;
15988 case OPC_MAQ_S_W_PHR:
15989 check_dsp(ctx);
15990 gen_helper_maq_s_w_phr(t0, v1_t, v2_t, cpu_env);
15991 break;
15992 case OPC_MAQ_SA_W_PHL:
15993 check_dsp(ctx);
15994 gen_helper_maq_sa_w_phl(t0, v1_t, v2_t, cpu_env);
15995 break;
15996 case OPC_MAQ_SA_W_PHR:
15997 check_dsp(ctx);
15998 gen_helper_maq_sa_w_phr(t0, v1_t, v2_t, cpu_env);
15999 break;
16000 case OPC_MULSA_W_PH:
16001 check_dspr2(ctx);
16002 gen_helper_mulsa_w_ph(t0, v1_t, v2_t, cpu_env);
16003 break;
16005 break;
16006 #ifdef TARGET_MIPS64
16007 case OPC_DPAQ_W_QH_DSP:
16009 int ac = ret & 0x03;
16010 tcg_gen_movi_i32(t0, ac);
16012 switch (op2) {
16013 case OPC_DMADD:
16014 check_dsp(ctx);
16015 gen_helper_dmadd(v1_t, v2_t, t0, cpu_env);
16016 break;
16017 case OPC_DMADDU:
16018 check_dsp(ctx);
16019 gen_helper_dmaddu(v1_t, v2_t, t0, cpu_env);
16020 break;
16021 case OPC_DMSUB:
16022 check_dsp(ctx);
16023 gen_helper_dmsub(v1_t, v2_t, t0, cpu_env);
16024 break;
16025 case OPC_DMSUBU:
16026 check_dsp(ctx);
16027 gen_helper_dmsubu(v1_t, v2_t, t0, cpu_env);
16028 break;
16029 case OPC_DPA_W_QH:
16030 check_dspr2(ctx);
16031 gen_helper_dpa_w_qh(v1_t, v2_t, t0, cpu_env);
16032 break;
16033 case OPC_DPAQ_S_W_QH:
16034 check_dsp(ctx);
16035 gen_helper_dpaq_s_w_qh(v1_t, v2_t, t0, cpu_env);
16036 break;
16037 case OPC_DPAQ_SA_L_PW:
16038 check_dsp(ctx);
16039 gen_helper_dpaq_sa_l_pw(v1_t, v2_t, t0, cpu_env);
16040 break;
16041 case OPC_DPAU_H_OBL:
16042 check_dsp(ctx);
16043 gen_helper_dpau_h_obl(v1_t, v2_t, t0, cpu_env);
16044 break;
16045 case OPC_DPAU_H_OBR:
16046 check_dsp(ctx);
16047 gen_helper_dpau_h_obr(v1_t, v2_t, t0, cpu_env);
16048 break;
16049 case OPC_DPS_W_QH:
16050 check_dspr2(ctx);
16051 gen_helper_dps_w_qh(v1_t, v2_t, t0, cpu_env);
16052 break;
16053 case OPC_DPSQ_S_W_QH:
16054 check_dsp(ctx);
16055 gen_helper_dpsq_s_w_qh(v1_t, v2_t, t0, cpu_env);
16056 break;
16057 case OPC_DPSQ_SA_L_PW:
16058 check_dsp(ctx);
16059 gen_helper_dpsq_sa_l_pw(v1_t, v2_t, t0, cpu_env);
16060 break;
16061 case OPC_DPSU_H_OBL:
16062 check_dsp(ctx);
16063 gen_helper_dpsu_h_obl(v1_t, v2_t, t0, cpu_env);
16064 break;
16065 case OPC_DPSU_H_OBR:
16066 check_dsp(ctx);
16067 gen_helper_dpsu_h_obr(v1_t, v2_t, t0, cpu_env);
16068 break;
16069 case OPC_MAQ_S_L_PWL:
16070 check_dsp(ctx);
16071 gen_helper_maq_s_l_pwl(v1_t, v2_t, t0, cpu_env);
16072 break;
16073 case OPC_MAQ_S_L_PWR:
16074 check_dsp(ctx);
16075 gen_helper_maq_s_l_pwr(v1_t, v2_t, t0, cpu_env);
16076 break;
16077 case OPC_MAQ_S_W_QHLL:
16078 check_dsp(ctx);
16079 gen_helper_maq_s_w_qhll(v1_t, v2_t, t0, cpu_env);
16080 break;
16081 case OPC_MAQ_SA_W_QHLL:
16082 check_dsp(ctx);
16083 gen_helper_maq_sa_w_qhll(v1_t, v2_t, t0, cpu_env);
16084 break;
16085 case OPC_MAQ_S_W_QHLR:
16086 check_dsp(ctx);
16087 gen_helper_maq_s_w_qhlr(v1_t, v2_t, t0, cpu_env);
16088 break;
16089 case OPC_MAQ_SA_W_QHLR:
16090 check_dsp(ctx);
16091 gen_helper_maq_sa_w_qhlr(v1_t, v2_t, t0, cpu_env);
16092 break;
16093 case OPC_MAQ_S_W_QHRL:
16094 check_dsp(ctx);
16095 gen_helper_maq_s_w_qhrl(v1_t, v2_t, t0, cpu_env);
16096 break;
16097 case OPC_MAQ_SA_W_QHRL:
16098 check_dsp(ctx);
16099 gen_helper_maq_sa_w_qhrl(v1_t, v2_t, t0, cpu_env);
16100 break;
16101 case OPC_MAQ_S_W_QHRR:
16102 check_dsp(ctx);
16103 gen_helper_maq_s_w_qhrr(v1_t, v2_t, t0, cpu_env);
16104 break;
16105 case OPC_MAQ_SA_W_QHRR:
16106 check_dsp(ctx);
16107 gen_helper_maq_sa_w_qhrr(v1_t, v2_t, t0, cpu_env);
16108 break;
16109 case OPC_MULSAQ_S_L_PW:
16110 check_dsp(ctx);
16111 gen_helper_mulsaq_s_l_pw(v1_t, v2_t, t0, cpu_env);
16112 break;
16113 case OPC_MULSAQ_S_W_QH:
16114 check_dsp(ctx);
16115 gen_helper_mulsaq_s_w_qh(v1_t, v2_t, t0, cpu_env);
16116 break;
16119 break;
16120 #endif
16121 case OPC_ADDU_QB_DSP:
16122 switch (op2) {
16123 case OPC_MULEU_S_PH_QBL:
16124 check_dsp(ctx);
16125 gen_helper_muleu_s_ph_qbl(cpu_gpr[ret], v1_t, v2_t, cpu_env);
16126 break;
16127 case OPC_MULEU_S_PH_QBR:
16128 check_dsp(ctx);
16129 gen_helper_muleu_s_ph_qbr(cpu_gpr[ret], v1_t, v2_t, cpu_env);
16130 break;
16131 case OPC_MULQ_RS_PH:
16132 check_dsp(ctx);
16133 gen_helper_mulq_rs_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
16134 break;
16135 case OPC_MULEQ_S_W_PHL:
16136 check_dsp(ctx);
16137 gen_helper_muleq_s_w_phl(cpu_gpr[ret], v1_t, v2_t, cpu_env);
16138 break;
16139 case OPC_MULEQ_S_W_PHR:
16140 check_dsp(ctx);
16141 gen_helper_muleq_s_w_phr(cpu_gpr[ret], v1_t, v2_t, cpu_env);
16142 break;
16143 case OPC_MULQ_S_PH:
16144 check_dspr2(ctx);
16145 gen_helper_mulq_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
16146 break;
16148 break;
16149 #ifdef TARGET_MIPS64
16150 case OPC_ADDU_OB_DSP:
16151 switch (op2) {
16152 case OPC_MULEQ_S_PW_QHL:
16153 check_dsp(ctx);
16154 gen_helper_muleq_s_pw_qhl(cpu_gpr[ret], v1_t, v2_t, cpu_env);
16155 break;
16156 case OPC_MULEQ_S_PW_QHR:
16157 check_dsp(ctx);
16158 gen_helper_muleq_s_pw_qhr(cpu_gpr[ret], v1_t, v2_t, cpu_env);
16159 break;
16160 case OPC_MULEU_S_QH_OBL:
16161 check_dsp(ctx);
16162 gen_helper_muleu_s_qh_obl(cpu_gpr[ret], v1_t, v2_t, cpu_env);
16163 break;
16164 case OPC_MULEU_S_QH_OBR:
16165 check_dsp(ctx);
16166 gen_helper_muleu_s_qh_obr(cpu_gpr[ret], v1_t, v2_t, cpu_env);
16167 break;
16168 case OPC_MULQ_RS_QH:
16169 check_dsp(ctx);
16170 gen_helper_mulq_rs_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
16171 break;
16173 break;
16174 #endif
16177 tcg_temp_free_i32(t0);
16178 tcg_temp_free(v1_t);
16179 tcg_temp_free(v2_t);
16182 static void gen_mipsdsp_bitinsn(DisasContext *ctx, uint32_t op1, uint32_t op2,
16183 int ret, int val)
16185 int16_t imm;
16186 TCGv t0;
16187 TCGv val_t;
16189 if (ret == 0) {
16190 /* Treat as NOP. */
16191 return;
16194 t0 = tcg_temp_new();
16195 val_t = tcg_temp_new();
16196 gen_load_gpr(val_t, val);
16198 switch (op1) {
16199 case OPC_ABSQ_S_PH_DSP:
16200 switch (op2) {
16201 case OPC_BITREV:
16202 check_dsp(ctx);
16203 gen_helper_bitrev(cpu_gpr[ret], val_t);
16204 break;
16205 case OPC_REPL_QB:
16206 check_dsp(ctx);
16208 target_long result;
16209 imm = (ctx->opcode >> 16) & 0xFF;
16210 result = (uint32_t)imm << 24 |
16211 (uint32_t)imm << 16 |
16212 (uint32_t)imm << 8 |
16213 (uint32_t)imm;
16214 result = (int32_t)result;
16215 tcg_gen_movi_tl(cpu_gpr[ret], result);
16217 break;
16218 case OPC_REPLV_QB:
16219 check_dsp(ctx);
16220 tcg_gen_ext8u_tl(cpu_gpr[ret], val_t);
16221 tcg_gen_shli_tl(t0, cpu_gpr[ret], 8);
16222 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
16223 tcg_gen_shli_tl(t0, cpu_gpr[ret], 16);
16224 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
16225 tcg_gen_ext32s_tl(cpu_gpr[ret], cpu_gpr[ret]);
16226 break;
16227 case OPC_REPL_PH:
16228 check_dsp(ctx);
16230 imm = (ctx->opcode >> 16) & 0x03FF;
16231 imm = (int16_t)(imm << 6) >> 6;
16232 tcg_gen_movi_tl(cpu_gpr[ret], \
16233 (target_long)((int32_t)imm << 16 | \
16234 (uint16_t)imm));
16236 break;
16237 case OPC_REPLV_PH:
16238 check_dsp(ctx);
16239 tcg_gen_ext16u_tl(cpu_gpr[ret], val_t);
16240 tcg_gen_shli_tl(t0, cpu_gpr[ret], 16);
16241 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
16242 tcg_gen_ext32s_tl(cpu_gpr[ret], cpu_gpr[ret]);
16243 break;
16245 break;
16246 #ifdef TARGET_MIPS64
16247 case OPC_ABSQ_S_QH_DSP:
16248 switch (op2) {
16249 case OPC_REPL_OB:
16250 check_dsp(ctx);
16252 target_long temp;
16254 imm = (ctx->opcode >> 16) & 0xFF;
16255 temp = ((uint64_t)imm << 8) | (uint64_t)imm;
16256 temp = (temp << 16) | temp;
16257 temp = (temp << 32) | temp;
16258 tcg_gen_movi_tl(cpu_gpr[ret], temp);
16259 break;
16261 case OPC_REPL_PW:
16262 check_dsp(ctx);
16264 target_long temp;
16266 imm = (ctx->opcode >> 16) & 0x03FF;
16267 imm = (int16_t)(imm << 6) >> 6;
16268 temp = ((target_long)imm << 32) \
16269 | ((target_long)imm & 0xFFFFFFFF);
16270 tcg_gen_movi_tl(cpu_gpr[ret], temp);
16271 break;
16273 case OPC_REPL_QH:
16274 check_dsp(ctx);
16276 target_long temp;
16278 imm = (ctx->opcode >> 16) & 0x03FF;
16279 imm = (int16_t)(imm << 6) >> 6;
16281 temp = ((uint64_t)(uint16_t)imm << 48) |
16282 ((uint64_t)(uint16_t)imm << 32) |
16283 ((uint64_t)(uint16_t)imm << 16) |
16284 (uint64_t)(uint16_t)imm;
16285 tcg_gen_movi_tl(cpu_gpr[ret], temp);
16286 break;
16288 case OPC_REPLV_OB:
16289 check_dsp(ctx);
16290 tcg_gen_ext8u_tl(cpu_gpr[ret], val_t);
16291 tcg_gen_shli_tl(t0, cpu_gpr[ret], 8);
16292 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
16293 tcg_gen_shli_tl(t0, cpu_gpr[ret], 16);
16294 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
16295 tcg_gen_shli_tl(t0, cpu_gpr[ret], 32);
16296 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
16297 break;
16298 case OPC_REPLV_PW:
16299 check_dsp(ctx);
16300 tcg_gen_ext32u_i64(cpu_gpr[ret], val_t);
16301 tcg_gen_shli_tl(t0, cpu_gpr[ret], 32);
16302 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
16303 break;
16304 case OPC_REPLV_QH:
16305 check_dsp(ctx);
16306 tcg_gen_ext16u_tl(cpu_gpr[ret], val_t);
16307 tcg_gen_shli_tl(t0, cpu_gpr[ret], 16);
16308 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
16309 tcg_gen_shli_tl(t0, cpu_gpr[ret], 32);
16310 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
16311 break;
16313 break;
16314 #endif
16316 tcg_temp_free(t0);
16317 tcg_temp_free(val_t);
16320 static void gen_mipsdsp_add_cmp_pick(DisasContext *ctx,
16321 uint32_t op1, uint32_t op2,
16322 int ret, int v1, int v2, int check_ret)
16324 TCGv t1;
16325 TCGv v1_t;
16326 TCGv v2_t;
16328 if ((ret == 0) && (check_ret == 1)) {
16329 /* Treat as NOP. */
16330 return;
16333 t1 = tcg_temp_new();
16334 v1_t = tcg_temp_new();
16335 v2_t = tcg_temp_new();
16337 gen_load_gpr(v1_t, v1);
16338 gen_load_gpr(v2_t, v2);
16340 switch (op1) {
16341 case OPC_CMPU_EQ_QB_DSP:
16342 switch (op2) {
16343 case OPC_CMPU_EQ_QB:
16344 check_dsp(ctx);
16345 gen_helper_cmpu_eq_qb(v1_t, v2_t, cpu_env);
16346 break;
16347 case OPC_CMPU_LT_QB:
16348 check_dsp(ctx);
16349 gen_helper_cmpu_lt_qb(v1_t, v2_t, cpu_env);
16350 break;
16351 case OPC_CMPU_LE_QB:
16352 check_dsp(ctx);
16353 gen_helper_cmpu_le_qb(v1_t, v2_t, cpu_env);
16354 break;
16355 case OPC_CMPGU_EQ_QB:
16356 check_dsp(ctx);
16357 gen_helper_cmpgu_eq_qb(cpu_gpr[ret], v1_t, v2_t);
16358 break;
16359 case OPC_CMPGU_LT_QB:
16360 check_dsp(ctx);
16361 gen_helper_cmpgu_lt_qb(cpu_gpr[ret], v1_t, v2_t);
16362 break;
16363 case OPC_CMPGU_LE_QB:
16364 check_dsp(ctx);
16365 gen_helper_cmpgu_le_qb(cpu_gpr[ret], v1_t, v2_t);
16366 break;
16367 case OPC_CMPGDU_EQ_QB:
16368 check_dspr2(ctx);
16369 gen_helper_cmpgu_eq_qb(t1, v1_t, v2_t);
16370 tcg_gen_mov_tl(cpu_gpr[ret], t1);
16371 tcg_gen_andi_tl(cpu_dspctrl, cpu_dspctrl, 0xF0FFFFFF);
16372 tcg_gen_shli_tl(t1, t1, 24);
16373 tcg_gen_or_tl(cpu_dspctrl, cpu_dspctrl, t1);
16374 break;
16375 case OPC_CMPGDU_LT_QB:
16376 check_dspr2(ctx);
16377 gen_helper_cmpgu_lt_qb(t1, v1_t, v2_t);
16378 tcg_gen_mov_tl(cpu_gpr[ret], t1);
16379 tcg_gen_andi_tl(cpu_dspctrl, cpu_dspctrl, 0xF0FFFFFF);
16380 tcg_gen_shli_tl(t1, t1, 24);
16381 tcg_gen_or_tl(cpu_dspctrl, cpu_dspctrl, t1);
16382 break;
16383 case OPC_CMPGDU_LE_QB:
16384 check_dspr2(ctx);
16385 gen_helper_cmpgu_le_qb(t1, v1_t, v2_t);
16386 tcg_gen_mov_tl(cpu_gpr[ret], t1);
16387 tcg_gen_andi_tl(cpu_dspctrl, cpu_dspctrl, 0xF0FFFFFF);
16388 tcg_gen_shli_tl(t1, t1, 24);
16389 tcg_gen_or_tl(cpu_dspctrl, cpu_dspctrl, t1);
16390 break;
16391 case OPC_CMP_EQ_PH:
16392 check_dsp(ctx);
16393 gen_helper_cmp_eq_ph(v1_t, v2_t, cpu_env);
16394 break;
16395 case OPC_CMP_LT_PH:
16396 check_dsp(ctx);
16397 gen_helper_cmp_lt_ph(v1_t, v2_t, cpu_env);
16398 break;
16399 case OPC_CMP_LE_PH:
16400 check_dsp(ctx);
16401 gen_helper_cmp_le_ph(v1_t, v2_t, cpu_env);
16402 break;
16403 case OPC_PICK_QB:
16404 check_dsp(ctx);
16405 gen_helper_pick_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
16406 break;
16407 case OPC_PICK_PH:
16408 check_dsp(ctx);
16409 gen_helper_pick_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
16410 break;
16411 case OPC_PACKRL_PH:
16412 check_dsp(ctx);
16413 gen_helper_packrl_ph(cpu_gpr[ret], v1_t, v2_t);
16414 break;
16416 break;
16417 #ifdef TARGET_MIPS64
16418 case OPC_CMPU_EQ_OB_DSP:
16419 switch (op2) {
16420 case OPC_CMP_EQ_PW:
16421 check_dsp(ctx);
16422 gen_helper_cmp_eq_pw(v1_t, v2_t, cpu_env);
16423 break;
16424 case OPC_CMP_LT_PW:
16425 check_dsp(ctx);
16426 gen_helper_cmp_lt_pw(v1_t, v2_t, cpu_env);
16427 break;
16428 case OPC_CMP_LE_PW:
16429 check_dsp(ctx);
16430 gen_helper_cmp_le_pw(v1_t, v2_t, cpu_env);
16431 break;
16432 case OPC_CMP_EQ_QH:
16433 check_dsp(ctx);
16434 gen_helper_cmp_eq_qh(v1_t, v2_t, cpu_env);
16435 break;
16436 case OPC_CMP_LT_QH:
16437 check_dsp(ctx);
16438 gen_helper_cmp_lt_qh(v1_t, v2_t, cpu_env);
16439 break;
16440 case OPC_CMP_LE_QH:
16441 check_dsp(ctx);
16442 gen_helper_cmp_le_qh(v1_t, v2_t, cpu_env);
16443 break;
16444 case OPC_CMPGDU_EQ_OB:
16445 check_dspr2(ctx);
16446 gen_helper_cmpgdu_eq_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
16447 break;
16448 case OPC_CMPGDU_LT_OB:
16449 check_dspr2(ctx);
16450 gen_helper_cmpgdu_lt_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
16451 break;
16452 case OPC_CMPGDU_LE_OB:
16453 check_dspr2(ctx);
16454 gen_helper_cmpgdu_le_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
16455 break;
16456 case OPC_CMPGU_EQ_OB:
16457 check_dsp(ctx);
16458 gen_helper_cmpgu_eq_ob(cpu_gpr[ret], v1_t, v2_t);
16459 break;
16460 case OPC_CMPGU_LT_OB:
16461 check_dsp(ctx);
16462 gen_helper_cmpgu_lt_ob(cpu_gpr[ret], v1_t, v2_t);
16463 break;
16464 case OPC_CMPGU_LE_OB:
16465 check_dsp(ctx);
16466 gen_helper_cmpgu_le_ob(cpu_gpr[ret], v1_t, v2_t);
16467 break;
16468 case OPC_CMPU_EQ_OB:
16469 check_dsp(ctx);
16470 gen_helper_cmpu_eq_ob(v1_t, v2_t, cpu_env);
16471 break;
16472 case OPC_CMPU_LT_OB:
16473 check_dsp(ctx);
16474 gen_helper_cmpu_lt_ob(v1_t, v2_t, cpu_env);
16475 break;
16476 case OPC_CMPU_LE_OB:
16477 check_dsp(ctx);
16478 gen_helper_cmpu_le_ob(v1_t, v2_t, cpu_env);
16479 break;
16480 case OPC_PACKRL_PW:
16481 check_dsp(ctx);
16482 gen_helper_packrl_pw(cpu_gpr[ret], v1_t, v2_t);
16483 break;
16484 case OPC_PICK_OB:
16485 check_dsp(ctx);
16486 gen_helper_pick_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
16487 break;
16488 case OPC_PICK_PW:
16489 check_dsp(ctx);
16490 gen_helper_pick_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
16491 break;
16492 case OPC_PICK_QH:
16493 check_dsp(ctx);
16494 gen_helper_pick_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
16495 break;
16497 break;
16498 #endif
16501 tcg_temp_free(t1);
16502 tcg_temp_free(v1_t);
16503 tcg_temp_free(v2_t);
16506 static void gen_mipsdsp_append(CPUMIPSState *env, DisasContext *ctx,
16507 uint32_t op1, int rt, int rs, int sa)
16509 TCGv t0;
16511 check_dspr2(ctx);
16513 if (rt == 0) {
16514 /* Treat as NOP. */
16515 return;
16518 t0 = tcg_temp_new();
16519 gen_load_gpr(t0, rs);
16521 switch (op1) {
16522 case OPC_APPEND_DSP:
16523 switch (MASK_APPEND(ctx->opcode)) {
16524 case OPC_APPEND:
16525 if (sa != 0) {
16526 tcg_gen_deposit_tl(cpu_gpr[rt], t0, cpu_gpr[rt], sa, 32 - sa);
16528 tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]);
16529 break;
16530 case OPC_PREPEND:
16531 if (sa != 0) {
16532 tcg_gen_ext32u_tl(cpu_gpr[rt], cpu_gpr[rt]);
16533 tcg_gen_shri_tl(cpu_gpr[rt], cpu_gpr[rt], sa);
16534 tcg_gen_shli_tl(t0, t0, 32 - sa);
16535 tcg_gen_or_tl(cpu_gpr[rt], cpu_gpr[rt], t0);
16537 tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]);
16538 break;
16539 case OPC_BALIGN:
16540 sa &= 3;
16541 if (sa != 0 && sa != 2) {
16542 tcg_gen_shli_tl(cpu_gpr[rt], cpu_gpr[rt], 8 * sa);
16543 tcg_gen_ext32u_tl(t0, t0);
16544 tcg_gen_shri_tl(t0, t0, 8 * (4 - sa));
16545 tcg_gen_or_tl(cpu_gpr[rt], cpu_gpr[rt], t0);
16547 tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]);
16548 break;
16549 default: /* Invalid */
16550 MIPS_INVAL("MASK APPEND");
16551 generate_exception_end(ctx, EXCP_RI);
16552 break;
16554 break;
16555 #ifdef TARGET_MIPS64
16556 case OPC_DAPPEND_DSP:
16557 switch (MASK_DAPPEND(ctx->opcode)) {
16558 case OPC_DAPPEND:
16559 if (sa != 0) {
16560 tcg_gen_deposit_tl(cpu_gpr[rt], t0, cpu_gpr[rt], sa, 64 - sa);
16562 break;
16563 case OPC_PREPENDD:
16564 tcg_gen_shri_tl(cpu_gpr[rt], cpu_gpr[rt], 0x20 | sa);
16565 tcg_gen_shli_tl(t0, t0, 64 - (0x20 | sa));
16566 tcg_gen_or_tl(cpu_gpr[rt], t0, t0);
16567 break;
16568 case OPC_PREPENDW:
16569 if (sa != 0) {
16570 tcg_gen_shri_tl(cpu_gpr[rt], cpu_gpr[rt], sa);
16571 tcg_gen_shli_tl(t0, t0, 64 - sa);
16572 tcg_gen_or_tl(cpu_gpr[rt], cpu_gpr[rt], t0);
16574 break;
16575 case OPC_DBALIGN:
16576 sa &= 7;
16577 if (sa != 0 && sa != 2 && sa != 4) {
16578 tcg_gen_shli_tl(cpu_gpr[rt], cpu_gpr[rt], 8 * sa);
16579 tcg_gen_shri_tl(t0, t0, 8 * (8 - sa));
16580 tcg_gen_or_tl(cpu_gpr[rt], cpu_gpr[rt], t0);
16582 break;
16583 default: /* Invalid */
16584 MIPS_INVAL("MASK DAPPEND");
16585 generate_exception_end(ctx, EXCP_RI);
16586 break;
16588 break;
16589 #endif
16591 tcg_temp_free(t0);
16594 static void gen_mipsdsp_accinsn(DisasContext *ctx, uint32_t op1, uint32_t op2,
16595 int ret, int v1, int v2, int check_ret)
16598 TCGv t0;
16599 TCGv t1;
16600 TCGv v1_t;
16601 TCGv v2_t;
16602 int16_t imm;
16604 if ((ret == 0) && (check_ret == 1)) {
16605 /* Treat as NOP. */
16606 return;
16609 t0 = tcg_temp_new();
16610 t1 = tcg_temp_new();
16611 v1_t = tcg_temp_new();
16612 v2_t = tcg_temp_new();
16614 gen_load_gpr(v1_t, v1);
16615 gen_load_gpr(v2_t, v2);
16617 switch (op1) {
16618 case OPC_EXTR_W_DSP:
16619 check_dsp(ctx);
16620 switch (op2) {
16621 case OPC_EXTR_W:
16622 tcg_gen_movi_tl(t0, v2);
16623 tcg_gen_movi_tl(t1, v1);
16624 gen_helper_extr_w(cpu_gpr[ret], t0, t1, cpu_env);
16625 break;
16626 case OPC_EXTR_R_W:
16627 tcg_gen_movi_tl(t0, v2);
16628 tcg_gen_movi_tl(t1, v1);
16629 gen_helper_extr_r_w(cpu_gpr[ret], t0, t1, cpu_env);
16630 break;
16631 case OPC_EXTR_RS_W:
16632 tcg_gen_movi_tl(t0, v2);
16633 tcg_gen_movi_tl(t1, v1);
16634 gen_helper_extr_rs_w(cpu_gpr[ret], t0, t1, cpu_env);
16635 break;
16636 case OPC_EXTR_S_H:
16637 tcg_gen_movi_tl(t0, v2);
16638 tcg_gen_movi_tl(t1, v1);
16639 gen_helper_extr_s_h(cpu_gpr[ret], t0, t1, cpu_env);
16640 break;
16641 case OPC_EXTRV_S_H:
16642 tcg_gen_movi_tl(t0, v2);
16643 gen_helper_extr_s_h(cpu_gpr[ret], t0, v1_t, cpu_env);
16644 break;
16645 case OPC_EXTRV_W:
16646 tcg_gen_movi_tl(t0, v2);
16647 gen_helper_extr_w(cpu_gpr[ret], t0, v1_t, cpu_env);
16648 break;
16649 case OPC_EXTRV_R_W:
16650 tcg_gen_movi_tl(t0, v2);
16651 gen_helper_extr_r_w(cpu_gpr[ret], t0, v1_t, cpu_env);
16652 break;
16653 case OPC_EXTRV_RS_W:
16654 tcg_gen_movi_tl(t0, v2);
16655 gen_helper_extr_rs_w(cpu_gpr[ret], t0, v1_t, cpu_env);
16656 break;
16657 case OPC_EXTP:
16658 tcg_gen_movi_tl(t0, v2);
16659 tcg_gen_movi_tl(t1, v1);
16660 gen_helper_extp(cpu_gpr[ret], t0, t1, cpu_env);
16661 break;
16662 case OPC_EXTPV:
16663 tcg_gen_movi_tl(t0, v2);
16664 gen_helper_extp(cpu_gpr[ret], t0, v1_t, cpu_env);
16665 break;
16666 case OPC_EXTPDP:
16667 tcg_gen_movi_tl(t0, v2);
16668 tcg_gen_movi_tl(t1, v1);
16669 gen_helper_extpdp(cpu_gpr[ret], t0, t1, cpu_env);
16670 break;
16671 case OPC_EXTPDPV:
16672 tcg_gen_movi_tl(t0, v2);
16673 gen_helper_extpdp(cpu_gpr[ret], t0, v1_t, cpu_env);
16674 break;
16675 case OPC_SHILO:
16676 imm = (ctx->opcode >> 20) & 0x3F;
16677 tcg_gen_movi_tl(t0, ret);
16678 tcg_gen_movi_tl(t1, imm);
16679 gen_helper_shilo(t0, t1, cpu_env);
16680 break;
16681 case OPC_SHILOV:
16682 tcg_gen_movi_tl(t0, ret);
16683 gen_helper_shilo(t0, v1_t, cpu_env);
16684 break;
16685 case OPC_MTHLIP:
16686 tcg_gen_movi_tl(t0, ret);
16687 gen_helper_mthlip(t0, v1_t, cpu_env);
16688 break;
16689 case OPC_WRDSP:
16690 imm = (ctx->opcode >> 11) & 0x3FF;
16691 tcg_gen_movi_tl(t0, imm);
16692 gen_helper_wrdsp(v1_t, t0, cpu_env);
16693 break;
16694 case OPC_RDDSP:
16695 imm = (ctx->opcode >> 16) & 0x03FF;
16696 tcg_gen_movi_tl(t0, imm);
16697 gen_helper_rddsp(cpu_gpr[ret], t0, cpu_env);
16698 break;
16700 break;
16701 #ifdef TARGET_MIPS64
16702 case OPC_DEXTR_W_DSP:
16703 check_dsp(ctx);
16704 switch (op2) {
16705 case OPC_DMTHLIP:
16706 tcg_gen_movi_tl(t0, ret);
16707 gen_helper_dmthlip(v1_t, t0, cpu_env);
16708 break;
16709 case OPC_DSHILO:
16711 int shift = (ctx->opcode >> 19) & 0x7F;
16712 int ac = (ctx->opcode >> 11) & 0x03;
16713 tcg_gen_movi_tl(t0, shift);
16714 tcg_gen_movi_tl(t1, ac);
16715 gen_helper_dshilo(t0, t1, cpu_env);
16716 break;
16718 case OPC_DSHILOV:
16720 int ac = (ctx->opcode >> 11) & 0x03;
16721 tcg_gen_movi_tl(t0, ac);
16722 gen_helper_dshilo(v1_t, t0, cpu_env);
16723 break;
16725 case OPC_DEXTP:
16726 tcg_gen_movi_tl(t0, v2);
16727 tcg_gen_movi_tl(t1, v1);
16729 gen_helper_dextp(cpu_gpr[ret], t0, t1, cpu_env);
16730 break;
16731 case OPC_DEXTPV:
16732 tcg_gen_movi_tl(t0, v2);
16733 gen_helper_dextp(cpu_gpr[ret], t0, v1_t, cpu_env);
16734 break;
16735 case OPC_DEXTPDP:
16736 tcg_gen_movi_tl(t0, v2);
16737 tcg_gen_movi_tl(t1, v1);
16738 gen_helper_dextpdp(cpu_gpr[ret], t0, t1, cpu_env);
16739 break;
16740 case OPC_DEXTPDPV:
16741 tcg_gen_movi_tl(t0, v2);
16742 gen_helper_dextpdp(cpu_gpr[ret], t0, v1_t, cpu_env);
16743 break;
16744 case OPC_DEXTR_L:
16745 tcg_gen_movi_tl(t0, v2);
16746 tcg_gen_movi_tl(t1, v1);
16747 gen_helper_dextr_l(cpu_gpr[ret], t0, t1, cpu_env);
16748 break;
16749 case OPC_DEXTR_R_L:
16750 tcg_gen_movi_tl(t0, v2);
16751 tcg_gen_movi_tl(t1, v1);
16752 gen_helper_dextr_r_l(cpu_gpr[ret], t0, t1, cpu_env);
16753 break;
16754 case OPC_DEXTR_RS_L:
16755 tcg_gen_movi_tl(t0, v2);
16756 tcg_gen_movi_tl(t1, v1);
16757 gen_helper_dextr_rs_l(cpu_gpr[ret], t0, t1, cpu_env);
16758 break;
16759 case OPC_DEXTR_W:
16760 tcg_gen_movi_tl(t0, v2);
16761 tcg_gen_movi_tl(t1, v1);
16762 gen_helper_dextr_w(cpu_gpr[ret], t0, t1, cpu_env);
16763 break;
16764 case OPC_DEXTR_R_W:
16765 tcg_gen_movi_tl(t0, v2);
16766 tcg_gen_movi_tl(t1, v1);
16767 gen_helper_dextr_r_w(cpu_gpr[ret], t0, t1, cpu_env);
16768 break;
16769 case OPC_DEXTR_RS_W:
16770 tcg_gen_movi_tl(t0, v2);
16771 tcg_gen_movi_tl(t1, v1);
16772 gen_helper_dextr_rs_w(cpu_gpr[ret], t0, t1, cpu_env);
16773 break;
16774 case OPC_DEXTR_S_H:
16775 tcg_gen_movi_tl(t0, v2);
16776 tcg_gen_movi_tl(t1, v1);
16777 gen_helper_dextr_s_h(cpu_gpr[ret], t0, t1, cpu_env);
16778 break;
16779 case OPC_DEXTRV_S_H:
16780 tcg_gen_movi_tl(t0, v2);
16781 tcg_gen_movi_tl(t1, v1);
16782 gen_helper_dextr_s_h(cpu_gpr[ret], t0, t1, cpu_env);
16783 break;
16784 case OPC_DEXTRV_L:
16785 tcg_gen_movi_tl(t0, v2);
16786 gen_helper_dextr_l(cpu_gpr[ret], t0, v1_t, cpu_env);
16787 break;
16788 case OPC_DEXTRV_R_L:
16789 tcg_gen_movi_tl(t0, v2);
16790 gen_helper_dextr_r_l(cpu_gpr[ret], t0, v1_t, cpu_env);
16791 break;
16792 case OPC_DEXTRV_RS_L:
16793 tcg_gen_movi_tl(t0, v2);
16794 gen_helper_dextr_rs_l(cpu_gpr[ret], t0, v1_t, cpu_env);
16795 break;
16796 case OPC_DEXTRV_W:
16797 tcg_gen_movi_tl(t0, v2);
16798 gen_helper_dextr_w(cpu_gpr[ret], t0, v1_t, cpu_env);
16799 break;
16800 case OPC_DEXTRV_R_W:
16801 tcg_gen_movi_tl(t0, v2);
16802 gen_helper_dextr_r_w(cpu_gpr[ret], t0, v1_t, cpu_env);
16803 break;
16804 case OPC_DEXTRV_RS_W:
16805 tcg_gen_movi_tl(t0, v2);
16806 gen_helper_dextr_rs_w(cpu_gpr[ret], t0, v1_t, cpu_env);
16807 break;
16809 break;
16810 #endif
16813 tcg_temp_free(t0);
16814 tcg_temp_free(t1);
16815 tcg_temp_free(v1_t);
16816 tcg_temp_free(v2_t);
16819 /* End MIPSDSP functions. */
16821 static void decode_opc_special_r6(CPUMIPSState *env, DisasContext *ctx)
16823 int rs, rt, rd, sa;
16824 uint32_t op1, op2;
16826 rs = (ctx->opcode >> 21) & 0x1f;
16827 rt = (ctx->opcode >> 16) & 0x1f;
16828 rd = (ctx->opcode >> 11) & 0x1f;
16829 sa = (ctx->opcode >> 6) & 0x1f;
16831 op1 = MASK_SPECIAL(ctx->opcode);
16832 switch (op1) {
16833 case OPC_LSA:
16834 gen_lsa(ctx, op1, rd, rs, rt, extract32(ctx->opcode, 6, 2));
16835 break;
16836 case OPC_MULT ... OPC_DIVU:
16837 op2 = MASK_R6_MULDIV(ctx->opcode);
16838 switch (op2) {
16839 case R6_OPC_MUL:
16840 case R6_OPC_MUH:
16841 case R6_OPC_MULU:
16842 case R6_OPC_MUHU:
16843 case R6_OPC_DIV:
16844 case R6_OPC_MOD:
16845 case R6_OPC_DIVU:
16846 case R6_OPC_MODU:
16847 gen_r6_muldiv(ctx, op2, rd, rs, rt);
16848 break;
16849 default:
16850 MIPS_INVAL("special_r6 muldiv");
16851 generate_exception_end(ctx, EXCP_RI);
16852 break;
16854 break;
16855 case OPC_SELEQZ:
16856 case OPC_SELNEZ:
16857 gen_cond_move(ctx, op1, rd, rs, rt);
16858 break;
16859 case R6_OPC_CLO:
16860 case R6_OPC_CLZ:
16861 if (rt == 0 && sa == 1) {
16862 /* Major opcode and function field is shared with preR6 MFHI/MTHI.
16863 We need additionally to check other fields */
16864 gen_cl(ctx, op1, rd, rs);
16865 } else {
16866 generate_exception_end(ctx, EXCP_RI);
16868 break;
16869 case R6_OPC_SDBBP:
16870 if (is_uhi(extract32(ctx->opcode, 6, 20))) {
16871 gen_helper_do_semihosting(cpu_env);
16872 } else {
16873 if (ctx->hflags & MIPS_HFLAG_SBRI) {
16874 generate_exception_end(ctx, EXCP_RI);
16875 } else {
16876 generate_exception_end(ctx, EXCP_DBp);
16879 break;
16880 #if defined(TARGET_MIPS64)
16881 case OPC_DLSA:
16882 check_mips_64(ctx);
16883 gen_lsa(ctx, op1, rd, rs, rt, extract32(ctx->opcode, 6, 2));
16884 break;
16885 case R6_OPC_DCLO:
16886 case R6_OPC_DCLZ:
16887 if (rt == 0 && sa == 1) {
16888 /* Major opcode and function field is shared with preR6 MFHI/MTHI.
16889 We need additionally to check other fields */
16890 check_mips_64(ctx);
16891 gen_cl(ctx, op1, rd, rs);
16892 } else {
16893 generate_exception_end(ctx, EXCP_RI);
16895 break;
16896 case OPC_DMULT ... OPC_DDIVU:
16897 op2 = MASK_R6_MULDIV(ctx->opcode);
16898 switch (op2) {
16899 case R6_OPC_DMUL:
16900 case R6_OPC_DMUH:
16901 case R6_OPC_DMULU:
16902 case R6_OPC_DMUHU:
16903 case R6_OPC_DDIV:
16904 case R6_OPC_DMOD:
16905 case R6_OPC_DDIVU:
16906 case R6_OPC_DMODU:
16907 check_mips_64(ctx);
16908 gen_r6_muldiv(ctx, op2, rd, rs, rt);
16909 break;
16910 default:
16911 MIPS_INVAL("special_r6 muldiv");
16912 generate_exception_end(ctx, EXCP_RI);
16913 break;
16915 break;
16916 #endif
16917 default: /* Invalid */
16918 MIPS_INVAL("special_r6");
16919 generate_exception_end(ctx, EXCP_RI);
16920 break;
16924 static void decode_opc_special_legacy(CPUMIPSState *env, DisasContext *ctx)
16926 int rs, rt, rd, sa;
16927 uint32_t op1;
16929 rs = (ctx->opcode >> 21) & 0x1f;
16930 rt = (ctx->opcode >> 16) & 0x1f;
16931 rd = (ctx->opcode >> 11) & 0x1f;
16932 sa = (ctx->opcode >> 6) & 0x1f;
16934 op1 = MASK_SPECIAL(ctx->opcode);
16935 switch (op1) {
16936 case OPC_MOVN: /* Conditional move */
16937 case OPC_MOVZ:
16938 check_insn(ctx, ISA_MIPS4 | ISA_MIPS32 |
16939 INSN_LOONGSON2E | INSN_LOONGSON2F);
16940 gen_cond_move(ctx, op1, rd, rs, rt);
16941 break;
16942 case OPC_MFHI: /* Move from HI/LO */
16943 case OPC_MFLO:
16944 gen_HILO(ctx, op1, rs & 3, rd);
16945 break;
16946 case OPC_MTHI:
16947 case OPC_MTLO: /* Move to HI/LO */
16948 gen_HILO(ctx, op1, rd & 3, rs);
16949 break;
16950 case OPC_MOVCI:
16951 check_insn(ctx, ISA_MIPS4 | ISA_MIPS32);
16952 if (env->CP0_Config1 & (1 << CP0C1_FP)) {
16953 check_cp1_enabled(ctx);
16954 gen_movci(ctx, rd, rs, (ctx->opcode >> 18) & 0x7,
16955 (ctx->opcode >> 16) & 1);
16956 } else {
16957 generate_exception_err(ctx, EXCP_CpU, 1);
16959 break;
16960 case OPC_MULT:
16961 case OPC_MULTU:
16962 if (sa) {
16963 check_insn(ctx, INSN_VR54XX);
16964 op1 = MASK_MUL_VR54XX(ctx->opcode);
16965 gen_mul_vr54xx(ctx, op1, rd, rs, rt);
16966 } else {
16967 gen_muldiv(ctx, op1, rd & 3, rs, rt);
16969 break;
16970 case OPC_DIV:
16971 case OPC_DIVU:
16972 gen_muldiv(ctx, op1, 0, rs, rt);
16973 break;
16974 #if defined(TARGET_MIPS64)
16975 case OPC_DMULT ... OPC_DDIVU:
16976 check_insn(ctx, ISA_MIPS3);
16977 check_mips_64(ctx);
16978 gen_muldiv(ctx, op1, 0, rs, rt);
16979 break;
16980 #endif
16981 case OPC_JR:
16982 gen_compute_branch(ctx, op1, 4, rs, rd, sa, 4);
16983 break;
16984 case OPC_SPIM:
16985 #ifdef MIPS_STRICT_STANDARD
16986 MIPS_INVAL("SPIM");
16987 generate_exception_end(ctx, EXCP_RI);
16988 #else
16989 /* Implemented as RI exception for now. */
16990 MIPS_INVAL("spim (unofficial)");
16991 generate_exception_end(ctx, EXCP_RI);
16992 #endif
16993 break;
16994 default: /* Invalid */
16995 MIPS_INVAL("special_legacy");
16996 generate_exception_end(ctx, EXCP_RI);
16997 break;
17001 static void decode_opc_special(CPUMIPSState *env, DisasContext *ctx)
17003 int rs, rt, rd, sa;
17004 uint32_t op1;
17006 rs = (ctx->opcode >> 21) & 0x1f;
17007 rt = (ctx->opcode >> 16) & 0x1f;
17008 rd = (ctx->opcode >> 11) & 0x1f;
17009 sa = (ctx->opcode >> 6) & 0x1f;
17011 op1 = MASK_SPECIAL(ctx->opcode);
17012 switch (op1) {
17013 case OPC_SLL: /* Shift with immediate */
17014 if (sa == 5 && rd == 0 &&
17015 rs == 0 && rt == 0) { /* PAUSE */
17016 if ((ctx->insn_flags & ISA_MIPS32R6) &&
17017 (ctx->hflags & MIPS_HFLAG_BMASK)) {
17018 generate_exception_end(ctx, EXCP_RI);
17019 break;
17022 /* Fallthrough */
17023 case OPC_SRA:
17024 gen_shift_imm(ctx, op1, rd, rt, sa);
17025 break;
17026 case OPC_SRL:
17027 switch ((ctx->opcode >> 21) & 0x1f) {
17028 case 1:
17029 /* rotr is decoded as srl on non-R2 CPUs */
17030 if (ctx->insn_flags & ISA_MIPS32R2) {
17031 op1 = OPC_ROTR;
17033 /* Fallthrough */
17034 case 0:
17035 gen_shift_imm(ctx, op1, rd, rt, sa);
17036 break;
17037 default:
17038 generate_exception_end(ctx, EXCP_RI);
17039 break;
17041 break;
17042 case OPC_ADD ... OPC_SUBU:
17043 gen_arith(ctx, op1, rd, rs, rt);
17044 break;
17045 case OPC_SLLV: /* Shifts */
17046 case OPC_SRAV:
17047 gen_shift(ctx, op1, rd, rs, rt);
17048 break;
17049 case OPC_SRLV:
17050 switch ((ctx->opcode >> 6) & 0x1f) {
17051 case 1:
17052 /* rotrv is decoded as srlv on non-R2 CPUs */
17053 if (ctx->insn_flags & ISA_MIPS32R2) {
17054 op1 = OPC_ROTRV;
17056 /* Fallthrough */
17057 case 0:
17058 gen_shift(ctx, op1, rd, rs, rt);
17059 break;
17060 default:
17061 generate_exception_end(ctx, EXCP_RI);
17062 break;
17064 break;
17065 case OPC_SLT: /* Set on less than */
17066 case OPC_SLTU:
17067 gen_slt(ctx, op1, rd, rs, rt);
17068 break;
17069 case OPC_AND: /* Logic*/
17070 case OPC_OR:
17071 case OPC_NOR:
17072 case OPC_XOR:
17073 gen_logic(ctx, op1, rd, rs, rt);
17074 break;
17075 case OPC_JALR:
17076 gen_compute_branch(ctx, op1, 4, rs, rd, sa, 4);
17077 break;
17078 case OPC_TGE ... OPC_TEQ: /* Traps */
17079 case OPC_TNE:
17080 check_insn(ctx, ISA_MIPS2);
17081 gen_trap(ctx, op1, rs, rt, -1);
17082 break;
17083 case OPC_LSA: /* OPC_PMON */
17084 if ((ctx->insn_flags & ISA_MIPS32R6) ||
17085 (env->CP0_Config3 & (1 << CP0C3_MSAP))) {
17086 decode_opc_special_r6(env, ctx);
17087 } else {
17088 /* Pmon entry point, also R4010 selsl */
17089 #ifdef MIPS_STRICT_STANDARD
17090 MIPS_INVAL("PMON / selsl");
17091 generate_exception_end(ctx, EXCP_RI);
17092 #else
17093 gen_helper_0e0i(pmon, sa);
17094 #endif
17096 break;
17097 case OPC_SYSCALL:
17098 generate_exception_end(ctx, EXCP_SYSCALL);
17099 break;
17100 case OPC_BREAK:
17101 generate_exception_end(ctx, EXCP_BREAK);
17102 break;
17103 case OPC_SYNC:
17104 check_insn(ctx, ISA_MIPS2);
17105 /* Treat as NOP. */
17106 break;
17108 #if defined(TARGET_MIPS64)
17109 /* MIPS64 specific opcodes */
17110 case OPC_DSLL:
17111 case OPC_DSRA:
17112 case OPC_DSLL32:
17113 case OPC_DSRA32:
17114 check_insn(ctx, ISA_MIPS3);
17115 check_mips_64(ctx);
17116 gen_shift_imm(ctx, op1, rd, rt, sa);
17117 break;
17118 case OPC_DSRL:
17119 switch ((ctx->opcode >> 21) & 0x1f) {
17120 case 1:
17121 /* drotr is decoded as dsrl on non-R2 CPUs */
17122 if (ctx->insn_flags & ISA_MIPS32R2) {
17123 op1 = OPC_DROTR;
17125 /* Fallthrough */
17126 case 0:
17127 check_insn(ctx, ISA_MIPS3);
17128 check_mips_64(ctx);
17129 gen_shift_imm(ctx, op1, rd, rt, sa);
17130 break;
17131 default:
17132 generate_exception_end(ctx, EXCP_RI);
17133 break;
17135 break;
17136 case OPC_DSRL32:
17137 switch ((ctx->opcode >> 21) & 0x1f) {
17138 case 1:
17139 /* drotr32 is decoded as dsrl32 on non-R2 CPUs */
17140 if (ctx->insn_flags & ISA_MIPS32R2) {
17141 op1 = OPC_DROTR32;
17143 /* Fallthrough */
17144 case 0:
17145 check_insn(ctx, ISA_MIPS3);
17146 check_mips_64(ctx);
17147 gen_shift_imm(ctx, op1, rd, rt, sa);
17148 break;
17149 default:
17150 generate_exception_end(ctx, EXCP_RI);
17151 break;
17153 break;
17154 case OPC_DADD ... OPC_DSUBU:
17155 check_insn(ctx, ISA_MIPS3);
17156 check_mips_64(ctx);
17157 gen_arith(ctx, op1, rd, rs, rt);
17158 break;
17159 case OPC_DSLLV:
17160 case OPC_DSRAV:
17161 check_insn(ctx, ISA_MIPS3);
17162 check_mips_64(ctx);
17163 gen_shift(ctx, op1, rd, rs, rt);
17164 break;
17165 case OPC_DSRLV:
17166 switch ((ctx->opcode >> 6) & 0x1f) {
17167 case 1:
17168 /* drotrv is decoded as dsrlv on non-R2 CPUs */
17169 if (ctx->insn_flags & ISA_MIPS32R2) {
17170 op1 = OPC_DROTRV;
17172 /* Fallthrough */
17173 case 0:
17174 check_insn(ctx, ISA_MIPS3);
17175 check_mips_64(ctx);
17176 gen_shift(ctx, op1, rd, rs, rt);
17177 break;
17178 default:
17179 generate_exception_end(ctx, EXCP_RI);
17180 break;
17182 break;
17183 case OPC_DLSA:
17184 if ((ctx->insn_flags & ISA_MIPS32R6) ||
17185 (env->CP0_Config3 & (1 << CP0C3_MSAP))) {
17186 decode_opc_special_r6(env, ctx);
17188 break;
17189 #endif
17190 default:
17191 if (ctx->insn_flags & ISA_MIPS32R6) {
17192 decode_opc_special_r6(env, ctx);
17193 } else {
17194 decode_opc_special_legacy(env, ctx);
17199 static void decode_opc_special2_legacy(CPUMIPSState *env, DisasContext *ctx)
17201 int rs, rt, rd;
17202 uint32_t op1;
17204 check_insn_opc_removed(ctx, ISA_MIPS32R6);
17206 rs = (ctx->opcode >> 21) & 0x1f;
17207 rt = (ctx->opcode >> 16) & 0x1f;
17208 rd = (ctx->opcode >> 11) & 0x1f;
17210 op1 = MASK_SPECIAL2(ctx->opcode);
17211 switch (op1) {
17212 case OPC_MADD ... OPC_MADDU: /* Multiply and add/sub */
17213 case OPC_MSUB ... OPC_MSUBU:
17214 check_insn(ctx, ISA_MIPS32);
17215 gen_muldiv(ctx, op1, rd & 3, rs, rt);
17216 break;
17217 case OPC_MUL:
17218 gen_arith(ctx, op1, rd, rs, rt);
17219 break;
17220 case OPC_DIV_G_2F:
17221 case OPC_DIVU_G_2F:
17222 case OPC_MULT_G_2F:
17223 case OPC_MULTU_G_2F:
17224 case OPC_MOD_G_2F:
17225 case OPC_MODU_G_2F:
17226 check_insn(ctx, INSN_LOONGSON2F);
17227 gen_loongson_integer(ctx, op1, rd, rs, rt);
17228 break;
17229 case OPC_CLO:
17230 case OPC_CLZ:
17231 check_insn(ctx, ISA_MIPS32);
17232 gen_cl(ctx, op1, rd, rs);
17233 break;
17234 case OPC_SDBBP:
17235 if (is_uhi(extract32(ctx->opcode, 6, 20))) {
17236 gen_helper_do_semihosting(cpu_env);
17237 } else {
17238 /* XXX: not clear which exception should be raised
17239 * when in debug mode...
17241 check_insn(ctx, ISA_MIPS32);
17242 generate_exception_end(ctx, EXCP_DBp);
17244 break;
17245 #if defined(TARGET_MIPS64)
17246 case OPC_DCLO:
17247 case OPC_DCLZ:
17248 check_insn(ctx, ISA_MIPS64);
17249 check_mips_64(ctx);
17250 gen_cl(ctx, op1, rd, rs);
17251 break;
17252 case OPC_DMULT_G_2F:
17253 case OPC_DMULTU_G_2F:
17254 case OPC_DDIV_G_2F:
17255 case OPC_DDIVU_G_2F:
17256 case OPC_DMOD_G_2F:
17257 case OPC_DMODU_G_2F:
17258 check_insn(ctx, INSN_LOONGSON2F);
17259 gen_loongson_integer(ctx, op1, rd, rs, rt);
17260 break;
17261 #endif
17262 default: /* Invalid */
17263 MIPS_INVAL("special2_legacy");
17264 generate_exception_end(ctx, EXCP_RI);
17265 break;
17269 static void decode_opc_special3_r6(CPUMIPSState *env, DisasContext *ctx)
17271 int rs, rt, rd, sa;
17272 uint32_t op1, op2;
17273 int16_t imm;
17275 rs = (ctx->opcode >> 21) & 0x1f;
17276 rt = (ctx->opcode >> 16) & 0x1f;
17277 rd = (ctx->opcode >> 11) & 0x1f;
17278 sa = (ctx->opcode >> 6) & 0x1f;
17279 imm = (int16_t)ctx->opcode >> 7;
17281 op1 = MASK_SPECIAL3(ctx->opcode);
17282 switch (op1) {
17283 case R6_OPC_PREF:
17284 if (rt >= 24) {
17285 /* hint codes 24-31 are reserved and signal RI */
17286 generate_exception_end(ctx, EXCP_RI);
17288 /* Treat as NOP. */
17289 break;
17290 case R6_OPC_CACHE:
17291 check_cp0_enabled(ctx);
17292 if (ctx->hflags & MIPS_HFLAG_ITC_CACHE) {
17293 gen_cache_operation(ctx, rt, rs, imm);
17295 break;
17296 case R6_OPC_SC:
17297 gen_st_cond(ctx, op1, rt, rs, imm);
17298 break;
17299 case R6_OPC_LL:
17300 gen_ld(ctx, op1, rt, rs, imm);
17301 break;
17302 case OPC_BSHFL:
17304 if (rd == 0) {
17305 /* Treat as NOP. */
17306 break;
17308 op2 = MASK_BSHFL(ctx->opcode);
17309 switch (op2) {
17310 case OPC_ALIGN ... OPC_ALIGN_END:
17311 gen_align(ctx, OPC_ALIGN, rd, rs, rt, sa & 3);
17312 break;
17313 case OPC_BITSWAP:
17314 gen_bitswap(ctx, op2, rd, rt);
17315 break;
17318 break;
17319 #if defined(TARGET_MIPS64)
17320 case R6_OPC_SCD:
17321 gen_st_cond(ctx, op1, rt, rs, imm);
17322 break;
17323 case R6_OPC_LLD:
17324 gen_ld(ctx, op1, rt, rs, imm);
17325 break;
17326 case OPC_DBSHFL:
17327 check_mips_64(ctx);
17329 if (rd == 0) {
17330 /* Treat as NOP. */
17331 break;
17333 op2 = MASK_DBSHFL(ctx->opcode);
17334 switch (op2) {
17335 case OPC_DALIGN ... OPC_DALIGN_END:
17336 gen_align(ctx, OPC_DALIGN, rd, rs, rt, sa & 7);
17337 break;
17338 case OPC_DBITSWAP:
17339 gen_bitswap(ctx, op2, rd, rt);
17340 break;
17344 break;
17345 #endif
17346 default: /* Invalid */
17347 MIPS_INVAL("special3_r6");
17348 generate_exception_end(ctx, EXCP_RI);
17349 break;
17353 static void decode_opc_special3_legacy(CPUMIPSState *env, DisasContext *ctx)
17355 int rs, rt, rd;
17356 uint32_t op1, op2;
17358 rs = (ctx->opcode >> 21) & 0x1f;
17359 rt = (ctx->opcode >> 16) & 0x1f;
17360 rd = (ctx->opcode >> 11) & 0x1f;
17362 op1 = MASK_SPECIAL3(ctx->opcode);
17363 switch (op1) {
17364 case OPC_DIV_G_2E ... OPC_DIVU_G_2E:
17365 case OPC_MOD_G_2E ... OPC_MODU_G_2E:
17366 case OPC_MULT_G_2E ... OPC_MULTU_G_2E:
17367 /* OPC_MULT_G_2E, OPC_ADDUH_QB_DSP, OPC_MUL_PH_DSP have
17368 * the same mask and op1. */
17369 if ((ctx->insn_flags & ASE_DSPR2) && (op1 == OPC_MULT_G_2E)) {
17370 op2 = MASK_ADDUH_QB(ctx->opcode);
17371 switch (op2) {
17372 case OPC_ADDUH_QB:
17373 case OPC_ADDUH_R_QB:
17374 case OPC_ADDQH_PH:
17375 case OPC_ADDQH_R_PH:
17376 case OPC_ADDQH_W:
17377 case OPC_ADDQH_R_W:
17378 case OPC_SUBUH_QB:
17379 case OPC_SUBUH_R_QB:
17380 case OPC_SUBQH_PH:
17381 case OPC_SUBQH_R_PH:
17382 case OPC_SUBQH_W:
17383 case OPC_SUBQH_R_W:
17384 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
17385 break;
17386 case OPC_MUL_PH:
17387 case OPC_MUL_S_PH:
17388 case OPC_MULQ_S_W:
17389 case OPC_MULQ_RS_W:
17390 gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 1);
17391 break;
17392 default:
17393 MIPS_INVAL("MASK ADDUH.QB");
17394 generate_exception_end(ctx, EXCP_RI);
17395 break;
17397 } else if (ctx->insn_flags & INSN_LOONGSON2E) {
17398 gen_loongson_integer(ctx, op1, rd, rs, rt);
17399 } else {
17400 generate_exception_end(ctx, EXCP_RI);
17402 break;
17403 case OPC_LX_DSP:
17404 op2 = MASK_LX(ctx->opcode);
17405 switch (op2) {
17406 #if defined(TARGET_MIPS64)
17407 case OPC_LDX:
17408 #endif
17409 case OPC_LBUX:
17410 case OPC_LHX:
17411 case OPC_LWX:
17412 gen_mipsdsp_ld(ctx, op2, rd, rs, rt);
17413 break;
17414 default: /* Invalid */
17415 MIPS_INVAL("MASK LX");
17416 generate_exception_end(ctx, EXCP_RI);
17417 break;
17419 break;
17420 case OPC_ABSQ_S_PH_DSP:
17421 op2 = MASK_ABSQ_S_PH(ctx->opcode);
17422 switch (op2) {
17423 case OPC_ABSQ_S_QB:
17424 case OPC_ABSQ_S_PH:
17425 case OPC_ABSQ_S_W:
17426 case OPC_PRECEQ_W_PHL:
17427 case OPC_PRECEQ_W_PHR:
17428 case OPC_PRECEQU_PH_QBL:
17429 case OPC_PRECEQU_PH_QBR:
17430 case OPC_PRECEQU_PH_QBLA:
17431 case OPC_PRECEQU_PH_QBRA:
17432 case OPC_PRECEU_PH_QBL:
17433 case OPC_PRECEU_PH_QBR:
17434 case OPC_PRECEU_PH_QBLA:
17435 case OPC_PRECEU_PH_QBRA:
17436 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
17437 break;
17438 case OPC_BITREV:
17439 case OPC_REPL_QB:
17440 case OPC_REPLV_QB:
17441 case OPC_REPL_PH:
17442 case OPC_REPLV_PH:
17443 gen_mipsdsp_bitinsn(ctx, op1, op2, rd, rt);
17444 break;
17445 default:
17446 MIPS_INVAL("MASK ABSQ_S.PH");
17447 generate_exception_end(ctx, EXCP_RI);
17448 break;
17450 break;
17451 case OPC_ADDU_QB_DSP:
17452 op2 = MASK_ADDU_QB(ctx->opcode);
17453 switch (op2) {
17454 case OPC_ADDQ_PH:
17455 case OPC_ADDQ_S_PH:
17456 case OPC_ADDQ_S_W:
17457 case OPC_ADDU_QB:
17458 case OPC_ADDU_S_QB:
17459 case OPC_ADDU_PH:
17460 case OPC_ADDU_S_PH:
17461 case OPC_SUBQ_PH:
17462 case OPC_SUBQ_S_PH:
17463 case OPC_SUBQ_S_W:
17464 case OPC_SUBU_QB:
17465 case OPC_SUBU_S_QB:
17466 case OPC_SUBU_PH:
17467 case OPC_SUBU_S_PH:
17468 case OPC_ADDSC:
17469 case OPC_ADDWC:
17470 case OPC_MODSUB:
17471 case OPC_RADDU_W_QB:
17472 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
17473 break;
17474 case OPC_MULEU_S_PH_QBL:
17475 case OPC_MULEU_S_PH_QBR:
17476 case OPC_MULQ_RS_PH:
17477 case OPC_MULEQ_S_W_PHL:
17478 case OPC_MULEQ_S_W_PHR:
17479 case OPC_MULQ_S_PH:
17480 gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 1);
17481 break;
17482 default: /* Invalid */
17483 MIPS_INVAL("MASK ADDU.QB");
17484 generate_exception_end(ctx, EXCP_RI);
17485 break;
17488 break;
17489 case OPC_CMPU_EQ_QB_DSP:
17490 op2 = MASK_CMPU_EQ_QB(ctx->opcode);
17491 switch (op2) {
17492 case OPC_PRECR_SRA_PH_W:
17493 case OPC_PRECR_SRA_R_PH_W:
17494 gen_mipsdsp_arith(ctx, op1, op2, rt, rs, rd);
17495 break;
17496 case OPC_PRECR_QB_PH:
17497 case OPC_PRECRQ_QB_PH:
17498 case OPC_PRECRQ_PH_W:
17499 case OPC_PRECRQ_RS_PH_W:
17500 case OPC_PRECRQU_S_QB_PH:
17501 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
17502 break;
17503 case OPC_CMPU_EQ_QB:
17504 case OPC_CMPU_LT_QB:
17505 case OPC_CMPU_LE_QB:
17506 case OPC_CMP_EQ_PH:
17507 case OPC_CMP_LT_PH:
17508 case OPC_CMP_LE_PH:
17509 gen_mipsdsp_add_cmp_pick(ctx, op1, op2, rd, rs, rt, 0);
17510 break;
17511 case OPC_CMPGU_EQ_QB:
17512 case OPC_CMPGU_LT_QB:
17513 case OPC_CMPGU_LE_QB:
17514 case OPC_CMPGDU_EQ_QB:
17515 case OPC_CMPGDU_LT_QB:
17516 case OPC_CMPGDU_LE_QB:
17517 case OPC_PICK_QB:
17518 case OPC_PICK_PH:
17519 case OPC_PACKRL_PH:
17520 gen_mipsdsp_add_cmp_pick(ctx, op1, op2, rd, rs, rt, 1);
17521 break;
17522 default: /* Invalid */
17523 MIPS_INVAL("MASK CMPU.EQ.QB");
17524 generate_exception_end(ctx, EXCP_RI);
17525 break;
17527 break;
17528 case OPC_SHLL_QB_DSP:
17529 gen_mipsdsp_shift(ctx, op1, rd, rs, rt);
17530 break;
17531 case OPC_DPA_W_PH_DSP:
17532 op2 = MASK_DPA_W_PH(ctx->opcode);
17533 switch (op2) {
17534 case OPC_DPAU_H_QBL:
17535 case OPC_DPAU_H_QBR:
17536 case OPC_DPSU_H_QBL:
17537 case OPC_DPSU_H_QBR:
17538 case OPC_DPA_W_PH:
17539 case OPC_DPAX_W_PH:
17540 case OPC_DPAQ_S_W_PH:
17541 case OPC_DPAQX_S_W_PH:
17542 case OPC_DPAQX_SA_W_PH:
17543 case OPC_DPS_W_PH:
17544 case OPC_DPSX_W_PH:
17545 case OPC_DPSQ_S_W_PH:
17546 case OPC_DPSQX_S_W_PH:
17547 case OPC_DPSQX_SA_W_PH:
17548 case OPC_MULSAQ_S_W_PH:
17549 case OPC_DPAQ_SA_L_W:
17550 case OPC_DPSQ_SA_L_W:
17551 case OPC_MAQ_S_W_PHL:
17552 case OPC_MAQ_S_W_PHR:
17553 case OPC_MAQ_SA_W_PHL:
17554 case OPC_MAQ_SA_W_PHR:
17555 case OPC_MULSA_W_PH:
17556 gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 0);
17557 break;
17558 default: /* Invalid */
17559 MIPS_INVAL("MASK DPAW.PH");
17560 generate_exception_end(ctx, EXCP_RI);
17561 break;
17563 break;
17564 case OPC_INSV_DSP:
17565 op2 = MASK_INSV(ctx->opcode);
17566 switch (op2) {
17567 case OPC_INSV:
17568 check_dsp(ctx);
17570 TCGv t0, t1;
17572 if (rt == 0) {
17573 break;
17576 t0 = tcg_temp_new();
17577 t1 = tcg_temp_new();
17579 gen_load_gpr(t0, rt);
17580 gen_load_gpr(t1, rs);
17582 gen_helper_insv(cpu_gpr[rt], cpu_env, t1, t0);
17584 tcg_temp_free(t0);
17585 tcg_temp_free(t1);
17586 break;
17588 default: /* Invalid */
17589 MIPS_INVAL("MASK INSV");
17590 generate_exception_end(ctx, EXCP_RI);
17591 break;
17593 break;
17594 case OPC_APPEND_DSP:
17595 gen_mipsdsp_append(env, ctx, op1, rt, rs, rd);
17596 break;
17597 case OPC_EXTR_W_DSP:
17598 op2 = MASK_EXTR_W(ctx->opcode);
17599 switch (op2) {
17600 case OPC_EXTR_W:
17601 case OPC_EXTR_R_W:
17602 case OPC_EXTR_RS_W:
17603 case OPC_EXTR_S_H:
17604 case OPC_EXTRV_S_H:
17605 case OPC_EXTRV_W:
17606 case OPC_EXTRV_R_W:
17607 case OPC_EXTRV_RS_W:
17608 case OPC_EXTP:
17609 case OPC_EXTPV:
17610 case OPC_EXTPDP:
17611 case OPC_EXTPDPV:
17612 gen_mipsdsp_accinsn(ctx, op1, op2, rt, rs, rd, 1);
17613 break;
17614 case OPC_RDDSP:
17615 gen_mipsdsp_accinsn(ctx, op1, op2, rd, rs, rt, 1);
17616 break;
17617 case OPC_SHILO:
17618 case OPC_SHILOV:
17619 case OPC_MTHLIP:
17620 case OPC_WRDSP:
17621 gen_mipsdsp_accinsn(ctx, op1, op2, rd, rs, rt, 0);
17622 break;
17623 default: /* Invalid */
17624 MIPS_INVAL("MASK EXTR.W");
17625 generate_exception_end(ctx, EXCP_RI);
17626 break;
17628 break;
17629 #if defined(TARGET_MIPS64)
17630 case OPC_DDIV_G_2E ... OPC_DDIVU_G_2E:
17631 case OPC_DMULT_G_2E ... OPC_DMULTU_G_2E:
17632 case OPC_DMOD_G_2E ... OPC_DMODU_G_2E:
17633 check_insn(ctx, INSN_LOONGSON2E);
17634 gen_loongson_integer(ctx, op1, rd, rs, rt);
17635 break;
17636 case OPC_ABSQ_S_QH_DSP:
17637 op2 = MASK_ABSQ_S_QH(ctx->opcode);
17638 switch (op2) {
17639 case OPC_PRECEQ_L_PWL:
17640 case OPC_PRECEQ_L_PWR:
17641 case OPC_PRECEQ_PW_QHL:
17642 case OPC_PRECEQ_PW_QHR:
17643 case OPC_PRECEQ_PW_QHLA:
17644 case OPC_PRECEQ_PW_QHRA:
17645 case OPC_PRECEQU_QH_OBL:
17646 case OPC_PRECEQU_QH_OBR:
17647 case OPC_PRECEQU_QH_OBLA:
17648 case OPC_PRECEQU_QH_OBRA:
17649 case OPC_PRECEU_QH_OBL:
17650 case OPC_PRECEU_QH_OBR:
17651 case OPC_PRECEU_QH_OBLA:
17652 case OPC_PRECEU_QH_OBRA:
17653 case OPC_ABSQ_S_OB:
17654 case OPC_ABSQ_S_PW:
17655 case OPC_ABSQ_S_QH:
17656 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
17657 break;
17658 case OPC_REPL_OB:
17659 case OPC_REPL_PW:
17660 case OPC_REPL_QH:
17661 case OPC_REPLV_OB:
17662 case OPC_REPLV_PW:
17663 case OPC_REPLV_QH:
17664 gen_mipsdsp_bitinsn(ctx, op1, op2, rd, rt);
17665 break;
17666 default: /* Invalid */
17667 MIPS_INVAL("MASK ABSQ_S.QH");
17668 generate_exception_end(ctx, EXCP_RI);
17669 break;
17671 break;
17672 case OPC_ADDU_OB_DSP:
17673 op2 = MASK_ADDU_OB(ctx->opcode);
17674 switch (op2) {
17675 case OPC_RADDU_L_OB:
17676 case OPC_SUBQ_PW:
17677 case OPC_SUBQ_S_PW:
17678 case OPC_SUBQ_QH:
17679 case OPC_SUBQ_S_QH:
17680 case OPC_SUBU_OB:
17681 case OPC_SUBU_S_OB:
17682 case OPC_SUBU_QH:
17683 case OPC_SUBU_S_QH:
17684 case OPC_SUBUH_OB:
17685 case OPC_SUBUH_R_OB:
17686 case OPC_ADDQ_PW:
17687 case OPC_ADDQ_S_PW:
17688 case OPC_ADDQ_QH:
17689 case OPC_ADDQ_S_QH:
17690 case OPC_ADDU_OB:
17691 case OPC_ADDU_S_OB:
17692 case OPC_ADDU_QH:
17693 case OPC_ADDU_S_QH:
17694 case OPC_ADDUH_OB:
17695 case OPC_ADDUH_R_OB:
17696 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
17697 break;
17698 case OPC_MULEQ_S_PW_QHL:
17699 case OPC_MULEQ_S_PW_QHR:
17700 case OPC_MULEU_S_QH_OBL:
17701 case OPC_MULEU_S_QH_OBR:
17702 case OPC_MULQ_RS_QH:
17703 gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 1);
17704 break;
17705 default: /* Invalid */
17706 MIPS_INVAL("MASK ADDU.OB");
17707 generate_exception_end(ctx, EXCP_RI);
17708 break;
17710 break;
17711 case OPC_CMPU_EQ_OB_DSP:
17712 op2 = MASK_CMPU_EQ_OB(ctx->opcode);
17713 switch (op2) {
17714 case OPC_PRECR_SRA_QH_PW:
17715 case OPC_PRECR_SRA_R_QH_PW:
17716 /* Return value is rt. */
17717 gen_mipsdsp_arith(ctx, op1, op2, rt, rs, rd);
17718 break;
17719 case OPC_PRECR_OB_QH:
17720 case OPC_PRECRQ_OB_QH:
17721 case OPC_PRECRQ_PW_L:
17722 case OPC_PRECRQ_QH_PW:
17723 case OPC_PRECRQ_RS_QH_PW:
17724 case OPC_PRECRQU_S_OB_QH:
17725 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
17726 break;
17727 case OPC_CMPU_EQ_OB:
17728 case OPC_CMPU_LT_OB:
17729 case OPC_CMPU_LE_OB:
17730 case OPC_CMP_EQ_QH:
17731 case OPC_CMP_LT_QH:
17732 case OPC_CMP_LE_QH:
17733 case OPC_CMP_EQ_PW:
17734 case OPC_CMP_LT_PW:
17735 case OPC_CMP_LE_PW:
17736 gen_mipsdsp_add_cmp_pick(ctx, op1, op2, rd, rs, rt, 0);
17737 break;
17738 case OPC_CMPGDU_EQ_OB:
17739 case OPC_CMPGDU_LT_OB:
17740 case OPC_CMPGDU_LE_OB:
17741 case OPC_CMPGU_EQ_OB:
17742 case OPC_CMPGU_LT_OB:
17743 case OPC_CMPGU_LE_OB:
17744 case OPC_PACKRL_PW:
17745 case OPC_PICK_OB:
17746 case OPC_PICK_PW:
17747 case OPC_PICK_QH:
17748 gen_mipsdsp_add_cmp_pick(ctx, op1, op2, rd, rs, rt, 1);
17749 break;
17750 default: /* Invalid */
17751 MIPS_INVAL("MASK CMPU_EQ.OB");
17752 generate_exception_end(ctx, EXCP_RI);
17753 break;
17755 break;
17756 case OPC_DAPPEND_DSP:
17757 gen_mipsdsp_append(env, ctx, op1, rt, rs, rd);
17758 break;
17759 case OPC_DEXTR_W_DSP:
17760 op2 = MASK_DEXTR_W(ctx->opcode);
17761 switch (op2) {
17762 case OPC_DEXTP:
17763 case OPC_DEXTPDP:
17764 case OPC_DEXTPDPV:
17765 case OPC_DEXTPV:
17766 case OPC_DEXTR_L:
17767 case OPC_DEXTR_R_L:
17768 case OPC_DEXTR_RS_L:
17769 case OPC_DEXTR_W:
17770 case OPC_DEXTR_R_W:
17771 case OPC_DEXTR_RS_W:
17772 case OPC_DEXTR_S_H:
17773 case OPC_DEXTRV_L:
17774 case OPC_DEXTRV_R_L:
17775 case OPC_DEXTRV_RS_L:
17776 case OPC_DEXTRV_S_H:
17777 case OPC_DEXTRV_W:
17778 case OPC_DEXTRV_R_W:
17779 case OPC_DEXTRV_RS_W:
17780 gen_mipsdsp_accinsn(ctx, op1, op2, rt, rs, rd, 1);
17781 break;
17782 case OPC_DMTHLIP:
17783 case OPC_DSHILO:
17784 case OPC_DSHILOV:
17785 gen_mipsdsp_accinsn(ctx, op1, op2, rd, rs, rt, 0);
17786 break;
17787 default: /* Invalid */
17788 MIPS_INVAL("MASK EXTR.W");
17789 generate_exception_end(ctx, EXCP_RI);
17790 break;
17792 break;
17793 case OPC_DPAQ_W_QH_DSP:
17794 op2 = MASK_DPAQ_W_QH(ctx->opcode);
17795 switch (op2) {
17796 case OPC_DPAU_H_OBL:
17797 case OPC_DPAU_H_OBR:
17798 case OPC_DPSU_H_OBL:
17799 case OPC_DPSU_H_OBR:
17800 case OPC_DPA_W_QH:
17801 case OPC_DPAQ_S_W_QH:
17802 case OPC_DPS_W_QH:
17803 case OPC_DPSQ_S_W_QH:
17804 case OPC_MULSAQ_S_W_QH:
17805 case OPC_DPAQ_SA_L_PW:
17806 case OPC_DPSQ_SA_L_PW:
17807 case OPC_MULSAQ_S_L_PW:
17808 gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 0);
17809 break;
17810 case OPC_MAQ_S_W_QHLL:
17811 case OPC_MAQ_S_W_QHLR:
17812 case OPC_MAQ_S_W_QHRL:
17813 case OPC_MAQ_S_W_QHRR:
17814 case OPC_MAQ_SA_W_QHLL:
17815 case OPC_MAQ_SA_W_QHLR:
17816 case OPC_MAQ_SA_W_QHRL:
17817 case OPC_MAQ_SA_W_QHRR:
17818 case OPC_MAQ_S_L_PWL:
17819 case OPC_MAQ_S_L_PWR:
17820 case OPC_DMADD:
17821 case OPC_DMADDU:
17822 case OPC_DMSUB:
17823 case OPC_DMSUBU:
17824 gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 0);
17825 break;
17826 default: /* Invalid */
17827 MIPS_INVAL("MASK DPAQ.W.QH");
17828 generate_exception_end(ctx, EXCP_RI);
17829 break;
17831 break;
17832 case OPC_DINSV_DSP:
17833 op2 = MASK_INSV(ctx->opcode);
17834 switch (op2) {
17835 case OPC_DINSV:
17837 TCGv t0, t1;
17839 if (rt == 0) {
17840 break;
17842 check_dsp(ctx);
17844 t0 = tcg_temp_new();
17845 t1 = tcg_temp_new();
17847 gen_load_gpr(t0, rt);
17848 gen_load_gpr(t1, rs);
17850 gen_helper_dinsv(cpu_gpr[rt], cpu_env, t1, t0);
17852 tcg_temp_free(t0);
17853 tcg_temp_free(t1);
17854 break;
17856 default: /* Invalid */
17857 MIPS_INVAL("MASK DINSV");
17858 generate_exception_end(ctx, EXCP_RI);
17859 break;
17861 break;
17862 case OPC_SHLL_OB_DSP:
17863 gen_mipsdsp_shift(ctx, op1, rd, rs, rt);
17864 break;
17865 #endif
17866 default: /* Invalid */
17867 MIPS_INVAL("special3_legacy");
17868 generate_exception_end(ctx, EXCP_RI);
17869 break;
17873 static void decode_opc_special3(CPUMIPSState *env, DisasContext *ctx)
17875 int rs, rt, rd, sa;
17876 uint32_t op1, op2;
17878 rs = (ctx->opcode >> 21) & 0x1f;
17879 rt = (ctx->opcode >> 16) & 0x1f;
17880 rd = (ctx->opcode >> 11) & 0x1f;
17881 sa = (ctx->opcode >> 6) & 0x1f;
17883 op1 = MASK_SPECIAL3(ctx->opcode);
17884 switch (op1) {
17885 case OPC_EXT:
17886 case OPC_INS:
17887 check_insn(ctx, ISA_MIPS32R2);
17888 gen_bitops(ctx, op1, rt, rs, sa, rd);
17889 break;
17890 case OPC_BSHFL:
17891 op2 = MASK_BSHFL(ctx->opcode);
17892 switch (op2) {
17893 case OPC_ALIGN ... OPC_ALIGN_END:
17894 case OPC_BITSWAP:
17895 check_insn(ctx, ISA_MIPS32R6);
17896 decode_opc_special3_r6(env, ctx);
17897 break;
17898 default:
17899 check_insn(ctx, ISA_MIPS32R2);
17900 gen_bshfl(ctx, op2, rt, rd);
17901 break;
17903 break;
17904 #if defined(TARGET_MIPS64)
17905 case OPC_DEXTM ... OPC_DEXT:
17906 case OPC_DINSM ... OPC_DINS:
17907 check_insn(ctx, ISA_MIPS64R2);
17908 check_mips_64(ctx);
17909 gen_bitops(ctx, op1, rt, rs, sa, rd);
17910 break;
17911 case OPC_DBSHFL:
17912 op2 = MASK_DBSHFL(ctx->opcode);
17913 switch (op2) {
17914 case OPC_DALIGN ... OPC_DALIGN_END:
17915 case OPC_DBITSWAP:
17916 check_insn(ctx, ISA_MIPS32R6);
17917 decode_opc_special3_r6(env, ctx);
17918 break;
17919 default:
17920 check_insn(ctx, ISA_MIPS64R2);
17921 check_mips_64(ctx);
17922 op2 = MASK_DBSHFL(ctx->opcode);
17923 gen_bshfl(ctx, op2, rt, rd);
17924 break;
17926 break;
17927 #endif
17928 case OPC_RDHWR:
17929 gen_rdhwr(ctx, rt, rd, extract32(ctx->opcode, 6, 3));
17930 break;
17931 case OPC_FORK:
17932 check_insn(ctx, ASE_MT);
17934 TCGv t0 = tcg_temp_new();
17935 TCGv t1 = tcg_temp_new();
17937 gen_load_gpr(t0, rt);
17938 gen_load_gpr(t1, rs);
17939 gen_helper_fork(t0, t1);
17940 tcg_temp_free(t0);
17941 tcg_temp_free(t1);
17943 break;
17944 case OPC_YIELD:
17945 check_insn(ctx, ASE_MT);
17947 TCGv t0 = tcg_temp_new();
17949 gen_load_gpr(t0, rs);
17950 gen_helper_yield(t0, cpu_env, t0);
17951 gen_store_gpr(t0, rd);
17952 tcg_temp_free(t0);
17954 break;
17955 default:
17956 if (ctx->insn_flags & ISA_MIPS32R6) {
17957 decode_opc_special3_r6(env, ctx);
17958 } else {
17959 decode_opc_special3_legacy(env, ctx);
17964 /* MIPS SIMD Architecture (MSA) */
17965 static inline int check_msa_access(DisasContext *ctx)
17967 if (unlikely((ctx->hflags & MIPS_HFLAG_FPU) &&
17968 !(ctx->hflags & MIPS_HFLAG_F64))) {
17969 generate_exception_end(ctx, EXCP_RI);
17970 return 0;
17973 if (unlikely(!(ctx->hflags & MIPS_HFLAG_MSA))) {
17974 if (ctx->insn_flags & ASE_MSA) {
17975 generate_exception_end(ctx, EXCP_MSADIS);
17976 return 0;
17977 } else {
17978 generate_exception_end(ctx, EXCP_RI);
17979 return 0;
17982 return 1;
17985 static void gen_check_zero_element(TCGv tresult, uint8_t df, uint8_t wt)
17987 /* generates tcg ops to check if any element is 0 */
17988 /* Note this function only works with MSA_WRLEN = 128 */
17989 uint64_t eval_zero_or_big = 0;
17990 uint64_t eval_big = 0;
17991 TCGv_i64 t0 = tcg_temp_new_i64();
17992 TCGv_i64 t1 = tcg_temp_new_i64();
17993 switch (df) {
17994 case DF_BYTE:
17995 eval_zero_or_big = 0x0101010101010101ULL;
17996 eval_big = 0x8080808080808080ULL;
17997 break;
17998 case DF_HALF:
17999 eval_zero_or_big = 0x0001000100010001ULL;
18000 eval_big = 0x8000800080008000ULL;
18001 break;
18002 case DF_WORD:
18003 eval_zero_or_big = 0x0000000100000001ULL;
18004 eval_big = 0x8000000080000000ULL;
18005 break;
18006 case DF_DOUBLE:
18007 eval_zero_or_big = 0x0000000000000001ULL;
18008 eval_big = 0x8000000000000000ULL;
18009 break;
18011 tcg_gen_subi_i64(t0, msa_wr_d[wt<<1], eval_zero_or_big);
18012 tcg_gen_andc_i64(t0, t0, msa_wr_d[wt<<1]);
18013 tcg_gen_andi_i64(t0, t0, eval_big);
18014 tcg_gen_subi_i64(t1, msa_wr_d[(wt<<1)+1], eval_zero_or_big);
18015 tcg_gen_andc_i64(t1, t1, msa_wr_d[(wt<<1)+1]);
18016 tcg_gen_andi_i64(t1, t1, eval_big);
18017 tcg_gen_or_i64(t0, t0, t1);
18018 /* if all bits are zero then all elements are not zero */
18019 /* if some bit is non-zero then some element is zero */
18020 tcg_gen_setcondi_i64(TCG_COND_NE, t0, t0, 0);
18021 tcg_gen_trunc_i64_tl(tresult, t0);
18022 tcg_temp_free_i64(t0);
18023 tcg_temp_free_i64(t1);
18026 static void gen_msa_branch(CPUMIPSState *env, DisasContext *ctx, uint32_t op1)
18028 uint8_t df = (ctx->opcode >> 21) & 0x3;
18029 uint8_t wt = (ctx->opcode >> 16) & 0x1f;
18030 int64_t s16 = (int16_t)ctx->opcode;
18032 check_msa_access(ctx);
18034 if (ctx->insn_flags & ISA_MIPS32R6 && ctx->hflags & MIPS_HFLAG_BMASK) {
18035 generate_exception_end(ctx, EXCP_RI);
18036 return;
18038 switch (op1) {
18039 case OPC_BZ_V:
18040 case OPC_BNZ_V:
18042 TCGv_i64 t0 = tcg_temp_new_i64();
18043 tcg_gen_or_i64(t0, msa_wr_d[wt<<1], msa_wr_d[(wt<<1)+1]);
18044 tcg_gen_setcondi_i64((op1 == OPC_BZ_V) ?
18045 TCG_COND_EQ : TCG_COND_NE, t0, t0, 0);
18046 tcg_gen_trunc_i64_tl(bcond, t0);
18047 tcg_temp_free_i64(t0);
18049 break;
18050 case OPC_BZ_B:
18051 case OPC_BZ_H:
18052 case OPC_BZ_W:
18053 case OPC_BZ_D:
18054 gen_check_zero_element(bcond, df, wt);
18055 break;
18056 case OPC_BNZ_B:
18057 case OPC_BNZ_H:
18058 case OPC_BNZ_W:
18059 case OPC_BNZ_D:
18060 gen_check_zero_element(bcond, df, wt);
18061 tcg_gen_setcondi_tl(TCG_COND_EQ, bcond, bcond, 0);
18062 break;
18065 ctx->btarget = ctx->pc + (s16 << 2) + 4;
18067 ctx->hflags |= MIPS_HFLAG_BC;
18068 ctx->hflags |= MIPS_HFLAG_BDS32;
18071 static void gen_msa_i8(CPUMIPSState *env, DisasContext *ctx)
18073 #define MASK_MSA_I8(op) (MASK_MSA_MINOR(op) | (op & (0x03 << 24)))
18074 uint8_t i8 = (ctx->opcode >> 16) & 0xff;
18075 uint8_t ws = (ctx->opcode >> 11) & 0x1f;
18076 uint8_t wd = (ctx->opcode >> 6) & 0x1f;
18078 TCGv_i32 twd = tcg_const_i32(wd);
18079 TCGv_i32 tws = tcg_const_i32(ws);
18080 TCGv_i32 ti8 = tcg_const_i32(i8);
18082 switch (MASK_MSA_I8(ctx->opcode)) {
18083 case OPC_ANDI_B:
18084 gen_helper_msa_andi_b(cpu_env, twd, tws, ti8);
18085 break;
18086 case OPC_ORI_B:
18087 gen_helper_msa_ori_b(cpu_env, twd, tws, ti8);
18088 break;
18089 case OPC_NORI_B:
18090 gen_helper_msa_nori_b(cpu_env, twd, tws, ti8);
18091 break;
18092 case OPC_XORI_B:
18093 gen_helper_msa_xori_b(cpu_env, twd, tws, ti8);
18094 break;
18095 case OPC_BMNZI_B:
18096 gen_helper_msa_bmnzi_b(cpu_env, twd, tws, ti8);
18097 break;
18098 case OPC_BMZI_B:
18099 gen_helper_msa_bmzi_b(cpu_env, twd, tws, ti8);
18100 break;
18101 case OPC_BSELI_B:
18102 gen_helper_msa_bseli_b(cpu_env, twd, tws, ti8);
18103 break;
18104 case OPC_SHF_B:
18105 case OPC_SHF_H:
18106 case OPC_SHF_W:
18108 uint8_t df = (ctx->opcode >> 24) & 0x3;
18109 if (df == DF_DOUBLE) {
18110 generate_exception_end(ctx, EXCP_RI);
18111 } else {
18112 TCGv_i32 tdf = tcg_const_i32(df);
18113 gen_helper_msa_shf_df(cpu_env, tdf, twd, tws, ti8);
18114 tcg_temp_free_i32(tdf);
18117 break;
18118 default:
18119 MIPS_INVAL("MSA instruction");
18120 generate_exception_end(ctx, EXCP_RI);
18121 break;
18124 tcg_temp_free_i32(twd);
18125 tcg_temp_free_i32(tws);
18126 tcg_temp_free_i32(ti8);
18129 static void gen_msa_i5(CPUMIPSState *env, DisasContext *ctx)
18131 #define MASK_MSA_I5(op) (MASK_MSA_MINOR(op) | (op & (0x7 << 23)))
18132 uint8_t df = (ctx->opcode >> 21) & 0x3;
18133 int8_t s5 = (int8_t) sextract32(ctx->opcode, 16, 5);
18134 uint8_t u5 = (ctx->opcode >> 16) & 0x1f;
18135 uint8_t ws = (ctx->opcode >> 11) & 0x1f;
18136 uint8_t wd = (ctx->opcode >> 6) & 0x1f;
18138 TCGv_i32 tdf = tcg_const_i32(df);
18139 TCGv_i32 twd = tcg_const_i32(wd);
18140 TCGv_i32 tws = tcg_const_i32(ws);
18141 TCGv_i32 timm = tcg_temp_new_i32();
18142 tcg_gen_movi_i32(timm, u5);
18144 switch (MASK_MSA_I5(ctx->opcode)) {
18145 case OPC_ADDVI_df:
18146 gen_helper_msa_addvi_df(cpu_env, tdf, twd, tws, timm);
18147 break;
18148 case OPC_SUBVI_df:
18149 gen_helper_msa_subvi_df(cpu_env, tdf, twd, tws, timm);
18150 break;
18151 case OPC_MAXI_S_df:
18152 tcg_gen_movi_i32(timm, s5);
18153 gen_helper_msa_maxi_s_df(cpu_env, tdf, twd, tws, timm);
18154 break;
18155 case OPC_MAXI_U_df:
18156 gen_helper_msa_maxi_u_df(cpu_env, tdf, twd, tws, timm);
18157 break;
18158 case OPC_MINI_S_df:
18159 tcg_gen_movi_i32(timm, s5);
18160 gen_helper_msa_mini_s_df(cpu_env, tdf, twd, tws, timm);
18161 break;
18162 case OPC_MINI_U_df:
18163 gen_helper_msa_mini_u_df(cpu_env, tdf, twd, tws, timm);
18164 break;
18165 case OPC_CEQI_df:
18166 tcg_gen_movi_i32(timm, s5);
18167 gen_helper_msa_ceqi_df(cpu_env, tdf, twd, tws, timm);
18168 break;
18169 case OPC_CLTI_S_df:
18170 tcg_gen_movi_i32(timm, s5);
18171 gen_helper_msa_clti_s_df(cpu_env, tdf, twd, tws, timm);
18172 break;
18173 case OPC_CLTI_U_df:
18174 gen_helper_msa_clti_u_df(cpu_env, tdf, twd, tws, timm);
18175 break;
18176 case OPC_CLEI_S_df:
18177 tcg_gen_movi_i32(timm, s5);
18178 gen_helper_msa_clei_s_df(cpu_env, tdf, twd, tws, timm);
18179 break;
18180 case OPC_CLEI_U_df:
18181 gen_helper_msa_clei_u_df(cpu_env, tdf, twd, tws, timm);
18182 break;
18183 case OPC_LDI_df:
18185 int32_t s10 = sextract32(ctx->opcode, 11, 10);
18186 tcg_gen_movi_i32(timm, s10);
18187 gen_helper_msa_ldi_df(cpu_env, tdf, twd, timm);
18189 break;
18190 default:
18191 MIPS_INVAL("MSA instruction");
18192 generate_exception_end(ctx, EXCP_RI);
18193 break;
18196 tcg_temp_free_i32(tdf);
18197 tcg_temp_free_i32(twd);
18198 tcg_temp_free_i32(tws);
18199 tcg_temp_free_i32(timm);
18202 static void gen_msa_bit(CPUMIPSState *env, DisasContext *ctx)
18204 #define MASK_MSA_BIT(op) (MASK_MSA_MINOR(op) | (op & (0x7 << 23)))
18205 uint8_t dfm = (ctx->opcode >> 16) & 0x7f;
18206 uint32_t df = 0, m = 0;
18207 uint8_t ws = (ctx->opcode >> 11) & 0x1f;
18208 uint8_t wd = (ctx->opcode >> 6) & 0x1f;
18210 TCGv_i32 tdf;
18211 TCGv_i32 tm;
18212 TCGv_i32 twd;
18213 TCGv_i32 tws;
18215 if ((dfm & 0x40) == 0x00) {
18216 m = dfm & 0x3f;
18217 df = DF_DOUBLE;
18218 } else if ((dfm & 0x60) == 0x40) {
18219 m = dfm & 0x1f;
18220 df = DF_WORD;
18221 } else if ((dfm & 0x70) == 0x60) {
18222 m = dfm & 0x0f;
18223 df = DF_HALF;
18224 } else if ((dfm & 0x78) == 0x70) {
18225 m = dfm & 0x7;
18226 df = DF_BYTE;
18227 } else {
18228 generate_exception_end(ctx, EXCP_RI);
18229 return;
18232 tdf = tcg_const_i32(df);
18233 tm = tcg_const_i32(m);
18234 twd = tcg_const_i32(wd);
18235 tws = tcg_const_i32(ws);
18237 switch (MASK_MSA_BIT(ctx->opcode)) {
18238 case OPC_SLLI_df:
18239 gen_helper_msa_slli_df(cpu_env, tdf, twd, tws, tm);
18240 break;
18241 case OPC_SRAI_df:
18242 gen_helper_msa_srai_df(cpu_env, tdf, twd, tws, tm);
18243 break;
18244 case OPC_SRLI_df:
18245 gen_helper_msa_srli_df(cpu_env, tdf, twd, tws, tm);
18246 break;
18247 case OPC_BCLRI_df:
18248 gen_helper_msa_bclri_df(cpu_env, tdf, twd, tws, tm);
18249 break;
18250 case OPC_BSETI_df:
18251 gen_helper_msa_bseti_df(cpu_env, tdf, twd, tws, tm);
18252 break;
18253 case OPC_BNEGI_df:
18254 gen_helper_msa_bnegi_df(cpu_env, tdf, twd, tws, tm);
18255 break;
18256 case OPC_BINSLI_df:
18257 gen_helper_msa_binsli_df(cpu_env, tdf, twd, tws, tm);
18258 break;
18259 case OPC_BINSRI_df:
18260 gen_helper_msa_binsri_df(cpu_env, tdf, twd, tws, tm);
18261 break;
18262 case OPC_SAT_S_df:
18263 gen_helper_msa_sat_s_df(cpu_env, tdf, twd, tws, tm);
18264 break;
18265 case OPC_SAT_U_df:
18266 gen_helper_msa_sat_u_df(cpu_env, tdf, twd, tws, tm);
18267 break;
18268 case OPC_SRARI_df:
18269 gen_helper_msa_srari_df(cpu_env, tdf, twd, tws, tm);
18270 break;
18271 case OPC_SRLRI_df:
18272 gen_helper_msa_srlri_df(cpu_env, tdf, twd, tws, tm);
18273 break;
18274 default:
18275 MIPS_INVAL("MSA instruction");
18276 generate_exception_end(ctx, EXCP_RI);
18277 break;
18280 tcg_temp_free_i32(tdf);
18281 tcg_temp_free_i32(tm);
18282 tcg_temp_free_i32(twd);
18283 tcg_temp_free_i32(tws);
18286 static void gen_msa_3r(CPUMIPSState *env, DisasContext *ctx)
18288 #define MASK_MSA_3R(op) (MASK_MSA_MINOR(op) | (op & (0x7 << 23)))
18289 uint8_t df = (ctx->opcode >> 21) & 0x3;
18290 uint8_t wt = (ctx->opcode >> 16) & 0x1f;
18291 uint8_t ws = (ctx->opcode >> 11) & 0x1f;
18292 uint8_t wd = (ctx->opcode >> 6) & 0x1f;
18294 TCGv_i32 tdf = tcg_const_i32(df);
18295 TCGv_i32 twd = tcg_const_i32(wd);
18296 TCGv_i32 tws = tcg_const_i32(ws);
18297 TCGv_i32 twt = tcg_const_i32(wt);
18299 switch (MASK_MSA_3R(ctx->opcode)) {
18300 case OPC_SLL_df:
18301 gen_helper_msa_sll_df(cpu_env, tdf, twd, tws, twt);
18302 break;
18303 case OPC_ADDV_df:
18304 gen_helper_msa_addv_df(cpu_env, tdf, twd, tws, twt);
18305 break;
18306 case OPC_CEQ_df:
18307 gen_helper_msa_ceq_df(cpu_env, tdf, twd, tws, twt);
18308 break;
18309 case OPC_ADD_A_df:
18310 gen_helper_msa_add_a_df(cpu_env, tdf, twd, tws, twt);
18311 break;
18312 case OPC_SUBS_S_df:
18313 gen_helper_msa_subs_s_df(cpu_env, tdf, twd, tws, twt);
18314 break;
18315 case OPC_MULV_df:
18316 gen_helper_msa_mulv_df(cpu_env, tdf, twd, tws, twt);
18317 break;
18318 case OPC_SLD_df:
18319 gen_helper_msa_sld_df(cpu_env, tdf, twd, tws, twt);
18320 break;
18321 case OPC_VSHF_df:
18322 gen_helper_msa_vshf_df(cpu_env, tdf, twd, tws, twt);
18323 break;
18324 case OPC_SRA_df:
18325 gen_helper_msa_sra_df(cpu_env, tdf, twd, tws, twt);
18326 break;
18327 case OPC_SUBV_df:
18328 gen_helper_msa_subv_df(cpu_env, tdf, twd, tws, twt);
18329 break;
18330 case OPC_ADDS_A_df:
18331 gen_helper_msa_adds_a_df(cpu_env, tdf, twd, tws, twt);
18332 break;
18333 case OPC_SUBS_U_df:
18334 gen_helper_msa_subs_u_df(cpu_env, tdf, twd, tws, twt);
18335 break;
18336 case OPC_MADDV_df:
18337 gen_helper_msa_maddv_df(cpu_env, tdf, twd, tws, twt);
18338 break;
18339 case OPC_SPLAT_df:
18340 gen_helper_msa_splat_df(cpu_env, tdf, twd, tws, twt);
18341 break;
18342 case OPC_SRAR_df:
18343 gen_helper_msa_srar_df(cpu_env, tdf, twd, tws, twt);
18344 break;
18345 case OPC_SRL_df:
18346 gen_helper_msa_srl_df(cpu_env, tdf, twd, tws, twt);
18347 break;
18348 case OPC_MAX_S_df:
18349 gen_helper_msa_max_s_df(cpu_env, tdf, twd, tws, twt);
18350 break;
18351 case OPC_CLT_S_df:
18352 gen_helper_msa_clt_s_df(cpu_env, tdf, twd, tws, twt);
18353 break;
18354 case OPC_ADDS_S_df:
18355 gen_helper_msa_adds_s_df(cpu_env, tdf, twd, tws, twt);
18356 break;
18357 case OPC_SUBSUS_U_df:
18358 gen_helper_msa_subsus_u_df(cpu_env, tdf, twd, tws, twt);
18359 break;
18360 case OPC_MSUBV_df:
18361 gen_helper_msa_msubv_df(cpu_env, tdf, twd, tws, twt);
18362 break;
18363 case OPC_PCKEV_df:
18364 gen_helper_msa_pckev_df(cpu_env, tdf, twd, tws, twt);
18365 break;
18366 case OPC_SRLR_df:
18367 gen_helper_msa_srlr_df(cpu_env, tdf, twd, tws, twt);
18368 break;
18369 case OPC_BCLR_df:
18370 gen_helper_msa_bclr_df(cpu_env, tdf, twd, tws, twt);
18371 break;
18372 case OPC_MAX_U_df:
18373 gen_helper_msa_max_u_df(cpu_env, tdf, twd, tws, twt);
18374 break;
18375 case OPC_CLT_U_df:
18376 gen_helper_msa_clt_u_df(cpu_env, tdf, twd, tws, twt);
18377 break;
18378 case OPC_ADDS_U_df:
18379 gen_helper_msa_adds_u_df(cpu_env, tdf, twd, tws, twt);
18380 break;
18381 case OPC_SUBSUU_S_df:
18382 gen_helper_msa_subsuu_s_df(cpu_env, tdf, twd, tws, twt);
18383 break;
18384 case OPC_PCKOD_df:
18385 gen_helper_msa_pckod_df(cpu_env, tdf, twd, tws, twt);
18386 break;
18387 case OPC_BSET_df:
18388 gen_helper_msa_bset_df(cpu_env, tdf, twd, tws, twt);
18389 break;
18390 case OPC_MIN_S_df:
18391 gen_helper_msa_min_s_df(cpu_env, tdf, twd, tws, twt);
18392 break;
18393 case OPC_CLE_S_df:
18394 gen_helper_msa_cle_s_df(cpu_env, tdf, twd, tws, twt);
18395 break;
18396 case OPC_AVE_S_df:
18397 gen_helper_msa_ave_s_df(cpu_env, tdf, twd, tws, twt);
18398 break;
18399 case OPC_ASUB_S_df:
18400 gen_helper_msa_asub_s_df(cpu_env, tdf, twd, tws, twt);
18401 break;
18402 case OPC_DIV_S_df:
18403 gen_helper_msa_div_s_df(cpu_env, tdf, twd, tws, twt);
18404 break;
18405 case OPC_ILVL_df:
18406 gen_helper_msa_ilvl_df(cpu_env, tdf, twd, tws, twt);
18407 break;
18408 case OPC_BNEG_df:
18409 gen_helper_msa_bneg_df(cpu_env, tdf, twd, tws, twt);
18410 break;
18411 case OPC_MIN_U_df:
18412 gen_helper_msa_min_u_df(cpu_env, tdf, twd, tws, twt);
18413 break;
18414 case OPC_CLE_U_df:
18415 gen_helper_msa_cle_u_df(cpu_env, tdf, twd, tws, twt);
18416 break;
18417 case OPC_AVE_U_df:
18418 gen_helper_msa_ave_u_df(cpu_env, tdf, twd, tws, twt);
18419 break;
18420 case OPC_ASUB_U_df:
18421 gen_helper_msa_asub_u_df(cpu_env, tdf, twd, tws, twt);
18422 break;
18423 case OPC_DIV_U_df:
18424 gen_helper_msa_div_u_df(cpu_env, tdf, twd, tws, twt);
18425 break;
18426 case OPC_ILVR_df:
18427 gen_helper_msa_ilvr_df(cpu_env, tdf, twd, tws, twt);
18428 break;
18429 case OPC_BINSL_df:
18430 gen_helper_msa_binsl_df(cpu_env, tdf, twd, tws, twt);
18431 break;
18432 case OPC_MAX_A_df:
18433 gen_helper_msa_max_a_df(cpu_env, tdf, twd, tws, twt);
18434 break;
18435 case OPC_AVER_S_df:
18436 gen_helper_msa_aver_s_df(cpu_env, tdf, twd, tws, twt);
18437 break;
18438 case OPC_MOD_S_df:
18439 gen_helper_msa_mod_s_df(cpu_env, tdf, twd, tws, twt);
18440 break;
18441 case OPC_ILVEV_df:
18442 gen_helper_msa_ilvev_df(cpu_env, tdf, twd, tws, twt);
18443 break;
18444 case OPC_BINSR_df:
18445 gen_helper_msa_binsr_df(cpu_env, tdf, twd, tws, twt);
18446 break;
18447 case OPC_MIN_A_df:
18448 gen_helper_msa_min_a_df(cpu_env, tdf, twd, tws, twt);
18449 break;
18450 case OPC_AVER_U_df:
18451 gen_helper_msa_aver_u_df(cpu_env, tdf, twd, tws, twt);
18452 break;
18453 case OPC_MOD_U_df:
18454 gen_helper_msa_mod_u_df(cpu_env, tdf, twd, tws, twt);
18455 break;
18456 case OPC_ILVOD_df:
18457 gen_helper_msa_ilvod_df(cpu_env, tdf, twd, tws, twt);
18458 break;
18460 case OPC_DOTP_S_df:
18461 case OPC_DOTP_U_df:
18462 case OPC_DPADD_S_df:
18463 case OPC_DPADD_U_df:
18464 case OPC_DPSUB_S_df:
18465 case OPC_HADD_S_df:
18466 case OPC_DPSUB_U_df:
18467 case OPC_HADD_U_df:
18468 case OPC_HSUB_S_df:
18469 case OPC_HSUB_U_df:
18470 if (df == DF_BYTE) {
18471 generate_exception_end(ctx, EXCP_RI);
18472 break;
18474 switch (MASK_MSA_3R(ctx->opcode)) {
18475 case OPC_DOTP_S_df:
18476 gen_helper_msa_dotp_s_df(cpu_env, tdf, twd, tws, twt);
18477 break;
18478 case OPC_DOTP_U_df:
18479 gen_helper_msa_dotp_u_df(cpu_env, tdf, twd, tws, twt);
18480 break;
18481 case OPC_DPADD_S_df:
18482 gen_helper_msa_dpadd_s_df(cpu_env, tdf, twd, tws, twt);
18483 break;
18484 case OPC_DPADD_U_df:
18485 gen_helper_msa_dpadd_u_df(cpu_env, tdf, twd, tws, twt);
18486 break;
18487 case OPC_DPSUB_S_df:
18488 gen_helper_msa_dpsub_s_df(cpu_env, tdf, twd, tws, twt);
18489 break;
18490 case OPC_HADD_S_df:
18491 gen_helper_msa_hadd_s_df(cpu_env, tdf, twd, tws, twt);
18492 break;
18493 case OPC_DPSUB_U_df:
18494 gen_helper_msa_dpsub_u_df(cpu_env, tdf, twd, tws, twt);
18495 break;
18496 case OPC_HADD_U_df:
18497 gen_helper_msa_hadd_u_df(cpu_env, tdf, twd, tws, twt);
18498 break;
18499 case OPC_HSUB_S_df:
18500 gen_helper_msa_hsub_s_df(cpu_env, tdf, twd, tws, twt);
18501 break;
18502 case OPC_HSUB_U_df:
18503 gen_helper_msa_hsub_u_df(cpu_env, tdf, twd, tws, twt);
18504 break;
18506 break;
18507 default:
18508 MIPS_INVAL("MSA instruction");
18509 generate_exception_end(ctx, EXCP_RI);
18510 break;
18512 tcg_temp_free_i32(twd);
18513 tcg_temp_free_i32(tws);
18514 tcg_temp_free_i32(twt);
18515 tcg_temp_free_i32(tdf);
18518 static void gen_msa_elm_3e(CPUMIPSState *env, DisasContext *ctx)
18520 #define MASK_MSA_ELM_DF3E(op) (MASK_MSA_MINOR(op) | (op & (0x3FF << 16)))
18521 uint8_t source = (ctx->opcode >> 11) & 0x1f;
18522 uint8_t dest = (ctx->opcode >> 6) & 0x1f;
18523 TCGv telm = tcg_temp_new();
18524 TCGv_i32 tsr = tcg_const_i32(source);
18525 TCGv_i32 tdt = tcg_const_i32(dest);
18527 switch (MASK_MSA_ELM_DF3E(ctx->opcode)) {
18528 case OPC_CTCMSA:
18529 gen_load_gpr(telm, source);
18530 gen_helper_msa_ctcmsa(cpu_env, telm, tdt);
18531 break;
18532 case OPC_CFCMSA:
18533 gen_helper_msa_cfcmsa(telm, cpu_env, tsr);
18534 gen_store_gpr(telm, dest);
18535 break;
18536 case OPC_MOVE_V:
18537 gen_helper_msa_move_v(cpu_env, tdt, tsr);
18538 break;
18539 default:
18540 MIPS_INVAL("MSA instruction");
18541 generate_exception_end(ctx, EXCP_RI);
18542 break;
18545 tcg_temp_free(telm);
18546 tcg_temp_free_i32(tdt);
18547 tcg_temp_free_i32(tsr);
18550 static void gen_msa_elm_df(CPUMIPSState *env, DisasContext *ctx, uint32_t df,
18551 uint32_t n)
18553 #define MASK_MSA_ELM(op) (MASK_MSA_MINOR(op) | (op & (0xf << 22)))
18554 uint8_t ws = (ctx->opcode >> 11) & 0x1f;
18555 uint8_t wd = (ctx->opcode >> 6) & 0x1f;
18557 TCGv_i32 tws = tcg_const_i32(ws);
18558 TCGv_i32 twd = tcg_const_i32(wd);
18559 TCGv_i32 tn = tcg_const_i32(n);
18560 TCGv_i32 tdf = tcg_const_i32(df);
18562 switch (MASK_MSA_ELM(ctx->opcode)) {
18563 case OPC_SLDI_df:
18564 gen_helper_msa_sldi_df(cpu_env, tdf, twd, tws, tn);
18565 break;
18566 case OPC_SPLATI_df:
18567 gen_helper_msa_splati_df(cpu_env, tdf, twd, tws, tn);
18568 break;
18569 case OPC_INSVE_df:
18570 gen_helper_msa_insve_df(cpu_env, tdf, twd, tws, tn);
18571 break;
18572 case OPC_COPY_S_df:
18573 case OPC_COPY_U_df:
18574 case OPC_INSERT_df:
18575 #if !defined(TARGET_MIPS64)
18576 /* Double format valid only for MIPS64 */
18577 if (df == DF_DOUBLE) {
18578 generate_exception_end(ctx, EXCP_RI);
18579 break;
18581 #endif
18582 switch (MASK_MSA_ELM(ctx->opcode)) {
18583 case OPC_COPY_S_df:
18584 gen_helper_msa_copy_s_df(cpu_env, tdf, twd, tws, tn);
18585 break;
18586 case OPC_COPY_U_df:
18587 gen_helper_msa_copy_u_df(cpu_env, tdf, twd, tws, tn);
18588 break;
18589 case OPC_INSERT_df:
18590 gen_helper_msa_insert_df(cpu_env, tdf, twd, tws, tn);
18591 break;
18593 break;
18594 default:
18595 MIPS_INVAL("MSA instruction");
18596 generate_exception_end(ctx, EXCP_RI);
18598 tcg_temp_free_i32(twd);
18599 tcg_temp_free_i32(tws);
18600 tcg_temp_free_i32(tn);
18601 tcg_temp_free_i32(tdf);
18604 static void gen_msa_elm(CPUMIPSState *env, DisasContext *ctx)
18606 uint8_t dfn = (ctx->opcode >> 16) & 0x3f;
18607 uint32_t df = 0, n = 0;
18609 if ((dfn & 0x30) == 0x00) {
18610 n = dfn & 0x0f;
18611 df = DF_BYTE;
18612 } else if ((dfn & 0x38) == 0x20) {
18613 n = dfn & 0x07;
18614 df = DF_HALF;
18615 } else if ((dfn & 0x3c) == 0x30) {
18616 n = dfn & 0x03;
18617 df = DF_WORD;
18618 } else if ((dfn & 0x3e) == 0x38) {
18619 n = dfn & 0x01;
18620 df = DF_DOUBLE;
18621 } else if (dfn == 0x3E) {
18622 /* CTCMSA, CFCMSA, MOVE.V */
18623 gen_msa_elm_3e(env, ctx);
18624 return;
18625 } else {
18626 generate_exception_end(ctx, EXCP_RI);
18627 return;
18630 gen_msa_elm_df(env, ctx, df, n);
18633 static void gen_msa_3rf(CPUMIPSState *env, DisasContext *ctx)
18635 #define MASK_MSA_3RF(op) (MASK_MSA_MINOR(op) | (op & (0xf << 22)))
18636 uint8_t df = (ctx->opcode >> 21) & 0x1;
18637 uint8_t wt = (ctx->opcode >> 16) & 0x1f;
18638 uint8_t ws = (ctx->opcode >> 11) & 0x1f;
18639 uint8_t wd = (ctx->opcode >> 6) & 0x1f;
18641 TCGv_i32 twd = tcg_const_i32(wd);
18642 TCGv_i32 tws = tcg_const_i32(ws);
18643 TCGv_i32 twt = tcg_const_i32(wt);
18644 TCGv_i32 tdf = tcg_temp_new_i32();
18646 /* adjust df value for floating-point instruction */
18647 tcg_gen_movi_i32(tdf, df + 2);
18649 switch (MASK_MSA_3RF(ctx->opcode)) {
18650 case OPC_FCAF_df:
18651 gen_helper_msa_fcaf_df(cpu_env, tdf, twd, tws, twt);
18652 break;
18653 case OPC_FADD_df:
18654 gen_helper_msa_fadd_df(cpu_env, tdf, twd, tws, twt);
18655 break;
18656 case OPC_FCUN_df:
18657 gen_helper_msa_fcun_df(cpu_env, tdf, twd, tws, twt);
18658 break;
18659 case OPC_FSUB_df:
18660 gen_helper_msa_fsub_df(cpu_env, tdf, twd, tws, twt);
18661 break;
18662 case OPC_FCOR_df:
18663 gen_helper_msa_fcor_df(cpu_env, tdf, twd, tws, twt);
18664 break;
18665 case OPC_FCEQ_df:
18666 gen_helper_msa_fceq_df(cpu_env, tdf, twd, tws, twt);
18667 break;
18668 case OPC_FMUL_df:
18669 gen_helper_msa_fmul_df(cpu_env, tdf, twd, tws, twt);
18670 break;
18671 case OPC_FCUNE_df:
18672 gen_helper_msa_fcune_df(cpu_env, tdf, twd, tws, twt);
18673 break;
18674 case OPC_FCUEQ_df:
18675 gen_helper_msa_fcueq_df(cpu_env, tdf, twd, tws, twt);
18676 break;
18677 case OPC_FDIV_df:
18678 gen_helper_msa_fdiv_df(cpu_env, tdf, twd, tws, twt);
18679 break;
18680 case OPC_FCNE_df:
18681 gen_helper_msa_fcne_df(cpu_env, tdf, twd, tws, twt);
18682 break;
18683 case OPC_FCLT_df:
18684 gen_helper_msa_fclt_df(cpu_env, tdf, twd, tws, twt);
18685 break;
18686 case OPC_FMADD_df:
18687 gen_helper_msa_fmadd_df(cpu_env, tdf, twd, tws, twt);
18688 break;
18689 case OPC_MUL_Q_df:
18690 tcg_gen_movi_i32(tdf, df + 1);
18691 gen_helper_msa_mul_q_df(cpu_env, tdf, twd, tws, twt);
18692 break;
18693 case OPC_FCULT_df:
18694 gen_helper_msa_fcult_df(cpu_env, tdf, twd, tws, twt);
18695 break;
18696 case OPC_FMSUB_df:
18697 gen_helper_msa_fmsub_df(cpu_env, tdf, twd, tws, twt);
18698 break;
18699 case OPC_MADD_Q_df:
18700 tcg_gen_movi_i32(tdf, df + 1);
18701 gen_helper_msa_madd_q_df(cpu_env, tdf, twd, tws, twt);
18702 break;
18703 case OPC_FCLE_df:
18704 gen_helper_msa_fcle_df(cpu_env, tdf, twd, tws, twt);
18705 break;
18706 case OPC_MSUB_Q_df:
18707 tcg_gen_movi_i32(tdf, df + 1);
18708 gen_helper_msa_msub_q_df(cpu_env, tdf, twd, tws, twt);
18709 break;
18710 case OPC_FCULE_df:
18711 gen_helper_msa_fcule_df(cpu_env, tdf, twd, tws, twt);
18712 break;
18713 case OPC_FEXP2_df:
18714 gen_helper_msa_fexp2_df(cpu_env, tdf, twd, tws, twt);
18715 break;
18716 case OPC_FSAF_df:
18717 gen_helper_msa_fsaf_df(cpu_env, tdf, twd, tws, twt);
18718 break;
18719 case OPC_FEXDO_df:
18720 gen_helper_msa_fexdo_df(cpu_env, tdf, twd, tws, twt);
18721 break;
18722 case OPC_FSUN_df:
18723 gen_helper_msa_fsun_df(cpu_env, tdf, twd, tws, twt);
18724 break;
18725 case OPC_FSOR_df:
18726 gen_helper_msa_fsor_df(cpu_env, tdf, twd, tws, twt);
18727 break;
18728 case OPC_FSEQ_df:
18729 gen_helper_msa_fseq_df(cpu_env, tdf, twd, tws, twt);
18730 break;
18731 case OPC_FTQ_df:
18732 gen_helper_msa_ftq_df(cpu_env, tdf, twd, tws, twt);
18733 break;
18734 case OPC_FSUNE_df:
18735 gen_helper_msa_fsune_df(cpu_env, tdf, twd, tws, twt);
18736 break;
18737 case OPC_FSUEQ_df:
18738 gen_helper_msa_fsueq_df(cpu_env, tdf, twd, tws, twt);
18739 break;
18740 case OPC_FSNE_df:
18741 gen_helper_msa_fsne_df(cpu_env, tdf, twd, tws, twt);
18742 break;
18743 case OPC_FSLT_df:
18744 gen_helper_msa_fslt_df(cpu_env, tdf, twd, tws, twt);
18745 break;
18746 case OPC_FMIN_df:
18747 gen_helper_msa_fmin_df(cpu_env, tdf, twd, tws, twt);
18748 break;
18749 case OPC_MULR_Q_df:
18750 tcg_gen_movi_i32(tdf, df + 1);
18751 gen_helper_msa_mulr_q_df(cpu_env, tdf, twd, tws, twt);
18752 break;
18753 case OPC_FSULT_df:
18754 gen_helper_msa_fsult_df(cpu_env, tdf, twd, tws, twt);
18755 break;
18756 case OPC_FMIN_A_df:
18757 gen_helper_msa_fmin_a_df(cpu_env, tdf, twd, tws, twt);
18758 break;
18759 case OPC_MADDR_Q_df:
18760 tcg_gen_movi_i32(tdf, df + 1);
18761 gen_helper_msa_maddr_q_df(cpu_env, tdf, twd, tws, twt);
18762 break;
18763 case OPC_FSLE_df:
18764 gen_helper_msa_fsle_df(cpu_env, tdf, twd, tws, twt);
18765 break;
18766 case OPC_FMAX_df:
18767 gen_helper_msa_fmax_df(cpu_env, tdf, twd, tws, twt);
18768 break;
18769 case OPC_MSUBR_Q_df:
18770 tcg_gen_movi_i32(tdf, df + 1);
18771 gen_helper_msa_msubr_q_df(cpu_env, tdf, twd, tws, twt);
18772 break;
18773 case OPC_FSULE_df:
18774 gen_helper_msa_fsule_df(cpu_env, tdf, twd, tws, twt);
18775 break;
18776 case OPC_FMAX_A_df:
18777 gen_helper_msa_fmax_a_df(cpu_env, tdf, twd, tws, twt);
18778 break;
18779 default:
18780 MIPS_INVAL("MSA instruction");
18781 generate_exception_end(ctx, EXCP_RI);
18782 break;
18785 tcg_temp_free_i32(twd);
18786 tcg_temp_free_i32(tws);
18787 tcg_temp_free_i32(twt);
18788 tcg_temp_free_i32(tdf);
18791 static void gen_msa_2r(CPUMIPSState *env, DisasContext *ctx)
18793 #define MASK_MSA_2R(op) (MASK_MSA_MINOR(op) | (op & (0x1f << 21)) | \
18794 (op & (0x7 << 18)))
18795 uint8_t wt = (ctx->opcode >> 16) & 0x1f;
18796 uint8_t ws = (ctx->opcode >> 11) & 0x1f;
18797 uint8_t wd = (ctx->opcode >> 6) & 0x1f;
18798 uint8_t df = (ctx->opcode >> 16) & 0x3;
18799 TCGv_i32 twd = tcg_const_i32(wd);
18800 TCGv_i32 tws = tcg_const_i32(ws);
18801 TCGv_i32 twt = tcg_const_i32(wt);
18802 TCGv_i32 tdf = tcg_const_i32(df);
18804 switch (MASK_MSA_2R(ctx->opcode)) {
18805 case OPC_FILL_df:
18806 #if !defined(TARGET_MIPS64)
18807 /* Double format valid only for MIPS64 */
18808 if (df == DF_DOUBLE) {
18809 generate_exception_end(ctx, EXCP_RI);
18810 break;
18812 #endif
18813 gen_helper_msa_fill_df(cpu_env, tdf, twd, tws); /* trs */
18814 break;
18815 case OPC_PCNT_df:
18816 gen_helper_msa_pcnt_df(cpu_env, tdf, twd, tws);
18817 break;
18818 case OPC_NLOC_df:
18819 gen_helper_msa_nloc_df(cpu_env, tdf, twd, tws);
18820 break;
18821 case OPC_NLZC_df:
18822 gen_helper_msa_nlzc_df(cpu_env, tdf, twd, tws);
18823 break;
18824 default:
18825 MIPS_INVAL("MSA instruction");
18826 generate_exception_end(ctx, EXCP_RI);
18827 break;
18830 tcg_temp_free_i32(twd);
18831 tcg_temp_free_i32(tws);
18832 tcg_temp_free_i32(twt);
18833 tcg_temp_free_i32(tdf);
18836 static void gen_msa_2rf(CPUMIPSState *env, DisasContext *ctx)
18838 #define MASK_MSA_2RF(op) (MASK_MSA_MINOR(op) | (op & (0x1f << 21)) | \
18839 (op & (0xf << 17)))
18840 uint8_t wt = (ctx->opcode >> 16) & 0x1f;
18841 uint8_t ws = (ctx->opcode >> 11) & 0x1f;
18842 uint8_t wd = (ctx->opcode >> 6) & 0x1f;
18843 uint8_t df = (ctx->opcode >> 16) & 0x1;
18844 TCGv_i32 twd = tcg_const_i32(wd);
18845 TCGv_i32 tws = tcg_const_i32(ws);
18846 TCGv_i32 twt = tcg_const_i32(wt);
18847 /* adjust df value for floating-point instruction */
18848 TCGv_i32 tdf = tcg_const_i32(df + 2);
18850 switch (MASK_MSA_2RF(ctx->opcode)) {
18851 case OPC_FCLASS_df:
18852 gen_helper_msa_fclass_df(cpu_env, tdf, twd, tws);
18853 break;
18854 case OPC_FTRUNC_S_df:
18855 gen_helper_msa_ftrunc_s_df(cpu_env, tdf, twd, tws);
18856 break;
18857 case OPC_FTRUNC_U_df:
18858 gen_helper_msa_ftrunc_u_df(cpu_env, tdf, twd, tws);
18859 break;
18860 case OPC_FSQRT_df:
18861 gen_helper_msa_fsqrt_df(cpu_env, tdf, twd, tws);
18862 break;
18863 case OPC_FRSQRT_df:
18864 gen_helper_msa_frsqrt_df(cpu_env, tdf, twd, tws);
18865 break;
18866 case OPC_FRCP_df:
18867 gen_helper_msa_frcp_df(cpu_env, tdf, twd, tws);
18868 break;
18869 case OPC_FRINT_df:
18870 gen_helper_msa_frint_df(cpu_env, tdf, twd, tws);
18871 break;
18872 case OPC_FLOG2_df:
18873 gen_helper_msa_flog2_df(cpu_env, tdf, twd, tws);
18874 break;
18875 case OPC_FEXUPL_df:
18876 gen_helper_msa_fexupl_df(cpu_env, tdf, twd, tws);
18877 break;
18878 case OPC_FEXUPR_df:
18879 gen_helper_msa_fexupr_df(cpu_env, tdf, twd, tws);
18880 break;
18881 case OPC_FFQL_df:
18882 gen_helper_msa_ffql_df(cpu_env, tdf, twd, tws);
18883 break;
18884 case OPC_FFQR_df:
18885 gen_helper_msa_ffqr_df(cpu_env, tdf, twd, tws);
18886 break;
18887 case OPC_FTINT_S_df:
18888 gen_helper_msa_ftint_s_df(cpu_env, tdf, twd, tws);
18889 break;
18890 case OPC_FTINT_U_df:
18891 gen_helper_msa_ftint_u_df(cpu_env, tdf, twd, tws);
18892 break;
18893 case OPC_FFINT_S_df:
18894 gen_helper_msa_ffint_s_df(cpu_env, tdf, twd, tws);
18895 break;
18896 case OPC_FFINT_U_df:
18897 gen_helper_msa_ffint_u_df(cpu_env, tdf, twd, tws);
18898 break;
18901 tcg_temp_free_i32(twd);
18902 tcg_temp_free_i32(tws);
18903 tcg_temp_free_i32(twt);
18904 tcg_temp_free_i32(tdf);
18907 static void gen_msa_vec_v(CPUMIPSState *env, DisasContext *ctx)
18909 #define MASK_MSA_VEC(op) (MASK_MSA_MINOR(op) | (op & (0x1f << 21)))
18910 uint8_t wt = (ctx->opcode >> 16) & 0x1f;
18911 uint8_t ws = (ctx->opcode >> 11) & 0x1f;
18912 uint8_t wd = (ctx->opcode >> 6) & 0x1f;
18913 TCGv_i32 twd = tcg_const_i32(wd);
18914 TCGv_i32 tws = tcg_const_i32(ws);
18915 TCGv_i32 twt = tcg_const_i32(wt);
18917 switch (MASK_MSA_VEC(ctx->opcode)) {
18918 case OPC_AND_V:
18919 gen_helper_msa_and_v(cpu_env, twd, tws, twt);
18920 break;
18921 case OPC_OR_V:
18922 gen_helper_msa_or_v(cpu_env, twd, tws, twt);
18923 break;
18924 case OPC_NOR_V:
18925 gen_helper_msa_nor_v(cpu_env, twd, tws, twt);
18926 break;
18927 case OPC_XOR_V:
18928 gen_helper_msa_xor_v(cpu_env, twd, tws, twt);
18929 break;
18930 case OPC_BMNZ_V:
18931 gen_helper_msa_bmnz_v(cpu_env, twd, tws, twt);
18932 break;
18933 case OPC_BMZ_V:
18934 gen_helper_msa_bmz_v(cpu_env, twd, tws, twt);
18935 break;
18936 case OPC_BSEL_V:
18937 gen_helper_msa_bsel_v(cpu_env, twd, tws, twt);
18938 break;
18939 default:
18940 MIPS_INVAL("MSA instruction");
18941 generate_exception_end(ctx, EXCP_RI);
18942 break;
18945 tcg_temp_free_i32(twd);
18946 tcg_temp_free_i32(tws);
18947 tcg_temp_free_i32(twt);
18950 static void gen_msa_vec(CPUMIPSState *env, DisasContext *ctx)
18952 switch (MASK_MSA_VEC(ctx->opcode)) {
18953 case OPC_AND_V:
18954 case OPC_OR_V:
18955 case OPC_NOR_V:
18956 case OPC_XOR_V:
18957 case OPC_BMNZ_V:
18958 case OPC_BMZ_V:
18959 case OPC_BSEL_V:
18960 gen_msa_vec_v(env, ctx);
18961 break;
18962 case OPC_MSA_2R:
18963 gen_msa_2r(env, ctx);
18964 break;
18965 case OPC_MSA_2RF:
18966 gen_msa_2rf(env, ctx);
18967 break;
18968 default:
18969 MIPS_INVAL("MSA instruction");
18970 generate_exception_end(ctx, EXCP_RI);
18971 break;
18975 static void gen_msa(CPUMIPSState *env, DisasContext *ctx)
18977 uint32_t opcode = ctx->opcode;
18978 check_insn(ctx, ASE_MSA);
18979 check_msa_access(ctx);
18981 switch (MASK_MSA_MINOR(opcode)) {
18982 case OPC_MSA_I8_00:
18983 case OPC_MSA_I8_01:
18984 case OPC_MSA_I8_02:
18985 gen_msa_i8(env, ctx);
18986 break;
18987 case OPC_MSA_I5_06:
18988 case OPC_MSA_I5_07:
18989 gen_msa_i5(env, ctx);
18990 break;
18991 case OPC_MSA_BIT_09:
18992 case OPC_MSA_BIT_0A:
18993 gen_msa_bit(env, ctx);
18994 break;
18995 case OPC_MSA_3R_0D:
18996 case OPC_MSA_3R_0E:
18997 case OPC_MSA_3R_0F:
18998 case OPC_MSA_3R_10:
18999 case OPC_MSA_3R_11:
19000 case OPC_MSA_3R_12:
19001 case OPC_MSA_3R_13:
19002 case OPC_MSA_3R_14:
19003 case OPC_MSA_3R_15:
19004 gen_msa_3r(env, ctx);
19005 break;
19006 case OPC_MSA_ELM:
19007 gen_msa_elm(env, ctx);
19008 break;
19009 case OPC_MSA_3RF_1A:
19010 case OPC_MSA_3RF_1B:
19011 case OPC_MSA_3RF_1C:
19012 gen_msa_3rf(env, ctx);
19013 break;
19014 case OPC_MSA_VEC:
19015 gen_msa_vec(env, ctx);
19016 break;
19017 case OPC_LD_B:
19018 case OPC_LD_H:
19019 case OPC_LD_W:
19020 case OPC_LD_D:
19021 case OPC_ST_B:
19022 case OPC_ST_H:
19023 case OPC_ST_W:
19024 case OPC_ST_D:
19026 int32_t s10 = sextract32(ctx->opcode, 16, 10);
19027 uint8_t rs = (ctx->opcode >> 11) & 0x1f;
19028 uint8_t wd = (ctx->opcode >> 6) & 0x1f;
19029 uint8_t df = (ctx->opcode >> 0) & 0x3;
19031 TCGv_i32 twd = tcg_const_i32(wd);
19032 TCGv taddr = tcg_temp_new();
19033 gen_base_offset_addr(ctx, taddr, rs, s10 << df);
19035 switch (MASK_MSA_MINOR(opcode)) {
19036 case OPC_LD_B:
19037 gen_helper_msa_ld_b(cpu_env, twd, taddr);
19038 break;
19039 case OPC_LD_H:
19040 gen_helper_msa_ld_h(cpu_env, twd, taddr);
19041 break;
19042 case OPC_LD_W:
19043 gen_helper_msa_ld_w(cpu_env, twd, taddr);
19044 break;
19045 case OPC_LD_D:
19046 gen_helper_msa_ld_d(cpu_env, twd, taddr);
19047 break;
19048 case OPC_ST_B:
19049 gen_helper_msa_st_b(cpu_env, twd, taddr);
19050 break;
19051 case OPC_ST_H:
19052 gen_helper_msa_st_h(cpu_env, twd, taddr);
19053 break;
19054 case OPC_ST_W:
19055 gen_helper_msa_st_w(cpu_env, twd, taddr);
19056 break;
19057 case OPC_ST_D:
19058 gen_helper_msa_st_d(cpu_env, twd, taddr);
19059 break;
19062 tcg_temp_free_i32(twd);
19063 tcg_temp_free(taddr);
19065 break;
19066 default:
19067 MIPS_INVAL("MSA instruction");
19068 generate_exception_end(ctx, EXCP_RI);
19069 break;
19074 static void decode_opc(CPUMIPSState *env, DisasContext *ctx)
19076 int32_t offset;
19077 int rs, rt, rd, sa;
19078 uint32_t op, op1;
19079 int16_t imm;
19081 /* make sure instructions are on a word boundary */
19082 if (ctx->pc & 0x3) {
19083 env->CP0_BadVAddr = ctx->pc;
19084 generate_exception_err(ctx, EXCP_AdEL, EXCP_INST_NOTAVAIL);
19085 return;
19088 /* Handle blikely not taken case */
19089 if ((ctx->hflags & MIPS_HFLAG_BMASK_BASE) == MIPS_HFLAG_BL) {
19090 TCGLabel *l1 = gen_new_label();
19092 tcg_gen_brcondi_tl(TCG_COND_NE, bcond, 0, l1);
19093 tcg_gen_movi_i32(hflags, ctx->hflags & ~MIPS_HFLAG_BMASK);
19094 gen_goto_tb(ctx, 1, ctx->pc + 4);
19095 gen_set_label(l1);
19098 op = MASK_OP_MAJOR(ctx->opcode);
19099 rs = (ctx->opcode >> 21) & 0x1f;
19100 rt = (ctx->opcode >> 16) & 0x1f;
19101 rd = (ctx->opcode >> 11) & 0x1f;
19102 sa = (ctx->opcode >> 6) & 0x1f;
19103 imm = (int16_t)ctx->opcode;
19104 switch (op) {
19105 case OPC_SPECIAL:
19106 decode_opc_special(env, ctx);
19107 break;
19108 case OPC_SPECIAL2:
19109 decode_opc_special2_legacy(env, ctx);
19110 break;
19111 case OPC_SPECIAL3:
19112 decode_opc_special3(env, ctx);
19113 break;
19114 case OPC_REGIMM:
19115 op1 = MASK_REGIMM(ctx->opcode);
19116 switch (op1) {
19117 case OPC_BLTZL: /* REGIMM branches */
19118 case OPC_BGEZL:
19119 case OPC_BLTZALL:
19120 case OPC_BGEZALL:
19121 check_insn(ctx, ISA_MIPS2);
19122 check_insn_opc_removed(ctx, ISA_MIPS32R6);
19123 /* Fallthrough */
19124 case OPC_BLTZ:
19125 case OPC_BGEZ:
19126 gen_compute_branch(ctx, op1, 4, rs, -1, imm << 2, 4);
19127 break;
19128 case OPC_BLTZAL:
19129 case OPC_BGEZAL:
19130 if (ctx->insn_flags & ISA_MIPS32R6) {
19131 if (rs == 0) {
19132 /* OPC_NAL, OPC_BAL */
19133 gen_compute_branch(ctx, op1, 4, 0, -1, imm << 2, 4);
19134 } else {
19135 generate_exception_end(ctx, EXCP_RI);
19137 } else {
19138 gen_compute_branch(ctx, op1, 4, rs, -1, imm << 2, 4);
19140 break;
19141 case OPC_TGEI ... OPC_TEQI: /* REGIMM traps */
19142 case OPC_TNEI:
19143 check_insn(ctx, ISA_MIPS2);
19144 check_insn_opc_removed(ctx, ISA_MIPS32R6);
19145 gen_trap(ctx, op1, rs, -1, imm);
19146 break;
19147 case OPC_SIGRIE:
19148 check_insn(ctx, ISA_MIPS32R6);
19149 generate_exception_end(ctx, EXCP_RI);
19150 break;
19151 case OPC_SYNCI:
19152 check_insn(ctx, ISA_MIPS32R2);
19153 /* Break the TB to be able to sync copied instructions
19154 immediately */
19155 ctx->bstate = BS_STOP;
19156 break;
19157 case OPC_BPOSGE32: /* MIPS DSP branch */
19158 #if defined(TARGET_MIPS64)
19159 case OPC_BPOSGE64:
19160 #endif
19161 check_dsp(ctx);
19162 gen_compute_branch(ctx, op1, 4, -1, -2, (int32_t)imm << 2, 4);
19163 break;
19164 #if defined(TARGET_MIPS64)
19165 case OPC_DAHI:
19166 check_insn(ctx, ISA_MIPS32R6);
19167 check_mips_64(ctx);
19168 if (rs != 0) {
19169 tcg_gen_addi_tl(cpu_gpr[rs], cpu_gpr[rs], (int64_t)imm << 32);
19171 break;
19172 case OPC_DATI:
19173 check_insn(ctx, ISA_MIPS32R6);
19174 check_mips_64(ctx);
19175 if (rs != 0) {
19176 tcg_gen_addi_tl(cpu_gpr[rs], cpu_gpr[rs], (int64_t)imm << 48);
19178 break;
19179 #endif
19180 default: /* Invalid */
19181 MIPS_INVAL("regimm");
19182 generate_exception_end(ctx, EXCP_RI);
19183 break;
19185 break;
19186 case OPC_CP0:
19187 check_cp0_enabled(ctx);
19188 op1 = MASK_CP0(ctx->opcode);
19189 switch (op1) {
19190 case OPC_MFC0:
19191 case OPC_MTC0:
19192 case OPC_MFTR:
19193 case OPC_MTTR:
19194 case OPC_MFHC0:
19195 case OPC_MTHC0:
19196 #if defined(TARGET_MIPS64)
19197 case OPC_DMFC0:
19198 case OPC_DMTC0:
19199 #endif
19200 #ifndef CONFIG_USER_ONLY
19201 gen_cp0(env, ctx, op1, rt, rd);
19202 #endif /* !CONFIG_USER_ONLY */
19203 break;
19204 case OPC_C0_FIRST ... OPC_C0_LAST:
19205 #ifndef CONFIG_USER_ONLY
19206 gen_cp0(env, ctx, MASK_C0(ctx->opcode), rt, rd);
19207 #endif /* !CONFIG_USER_ONLY */
19208 break;
19209 case OPC_MFMC0:
19210 #ifndef CONFIG_USER_ONLY
19212 uint32_t op2;
19213 TCGv t0 = tcg_temp_new();
19215 op2 = MASK_MFMC0(ctx->opcode);
19216 switch (op2) {
19217 case OPC_DMT:
19218 check_insn(ctx, ASE_MT);
19219 gen_helper_dmt(t0);
19220 gen_store_gpr(t0, rt);
19221 break;
19222 case OPC_EMT:
19223 check_insn(ctx, ASE_MT);
19224 gen_helper_emt(t0);
19225 gen_store_gpr(t0, rt);
19226 break;
19227 case OPC_DVPE:
19228 check_insn(ctx, ASE_MT);
19229 gen_helper_dvpe(t0, cpu_env);
19230 gen_store_gpr(t0, rt);
19231 break;
19232 case OPC_EVPE:
19233 check_insn(ctx, ASE_MT);
19234 gen_helper_evpe(t0, cpu_env);
19235 gen_store_gpr(t0, rt);
19236 break;
19237 case OPC_DVP:
19238 check_insn(ctx, ISA_MIPS32R6);
19239 if (ctx->vp) {
19240 gen_helper_dvp(t0, cpu_env);
19241 gen_store_gpr(t0, rt);
19243 break;
19244 case OPC_EVP:
19245 check_insn(ctx, ISA_MIPS32R6);
19246 if (ctx->vp) {
19247 gen_helper_evp(t0, cpu_env);
19248 gen_store_gpr(t0, rt);
19250 break;
19251 case OPC_DI:
19252 check_insn(ctx, ISA_MIPS32R2);
19253 save_cpu_state(ctx, 1);
19254 gen_helper_di(t0, cpu_env);
19255 gen_store_gpr(t0, rt);
19256 /* Stop translation as we may have switched
19257 the execution mode. */
19258 ctx->bstate = BS_STOP;
19259 break;
19260 case OPC_EI:
19261 check_insn(ctx, ISA_MIPS32R2);
19262 save_cpu_state(ctx, 1);
19263 gen_helper_ei(t0, cpu_env);
19264 gen_store_gpr(t0, rt);
19265 /* Stop translation as we may have switched
19266 the execution mode. */
19267 ctx->bstate = BS_STOP;
19268 break;
19269 default: /* Invalid */
19270 MIPS_INVAL("mfmc0");
19271 generate_exception_end(ctx, EXCP_RI);
19272 break;
19274 tcg_temp_free(t0);
19276 #endif /* !CONFIG_USER_ONLY */
19277 break;
19278 case OPC_RDPGPR:
19279 check_insn(ctx, ISA_MIPS32R2);
19280 gen_load_srsgpr(rt, rd);
19281 break;
19282 case OPC_WRPGPR:
19283 check_insn(ctx, ISA_MIPS32R2);
19284 gen_store_srsgpr(rt, rd);
19285 break;
19286 default:
19287 MIPS_INVAL("cp0");
19288 generate_exception_end(ctx, EXCP_RI);
19289 break;
19291 break;
19292 case OPC_BOVC: /* OPC_BEQZALC, OPC_BEQC, OPC_ADDI */
19293 if (ctx->insn_flags & ISA_MIPS32R6) {
19294 /* OPC_BOVC, OPC_BEQZALC, OPC_BEQC */
19295 gen_compute_compact_branch(ctx, op, rs, rt, imm << 2);
19296 } else {
19297 /* OPC_ADDI */
19298 /* Arithmetic with immediate opcode */
19299 gen_arith_imm(ctx, op, rt, rs, imm);
19301 break;
19302 case OPC_ADDIU:
19303 gen_arith_imm(ctx, op, rt, rs, imm);
19304 break;
19305 case OPC_SLTI: /* Set on less than with immediate opcode */
19306 case OPC_SLTIU:
19307 gen_slt_imm(ctx, op, rt, rs, imm);
19308 break;
19309 case OPC_ANDI: /* Arithmetic with immediate opcode */
19310 case OPC_LUI: /* OPC_AUI */
19311 case OPC_ORI:
19312 case OPC_XORI:
19313 gen_logic_imm(ctx, op, rt, rs, imm);
19314 break;
19315 case OPC_J ... OPC_JAL: /* Jump */
19316 offset = (int32_t)(ctx->opcode & 0x3FFFFFF) << 2;
19317 gen_compute_branch(ctx, op, 4, rs, rt, offset, 4);
19318 break;
19319 /* Branch */
19320 case OPC_BLEZC: /* OPC_BGEZC, OPC_BGEC, OPC_BLEZL */
19321 if (ctx->insn_flags & ISA_MIPS32R6) {
19322 if (rt == 0) {
19323 generate_exception_end(ctx, EXCP_RI);
19324 break;
19326 /* OPC_BLEZC, OPC_BGEZC, OPC_BGEC */
19327 gen_compute_compact_branch(ctx, op, rs, rt, imm << 2);
19328 } else {
19329 /* OPC_BLEZL */
19330 gen_compute_branch(ctx, op, 4, rs, rt, imm << 2, 4);
19332 break;
19333 case OPC_BGTZC: /* OPC_BLTZC, OPC_BLTC, OPC_BGTZL */
19334 if (ctx->insn_flags & ISA_MIPS32R6) {
19335 if (rt == 0) {
19336 generate_exception_end(ctx, EXCP_RI);
19337 break;
19339 /* OPC_BGTZC, OPC_BLTZC, OPC_BLTC */
19340 gen_compute_compact_branch(ctx, op, rs, rt, imm << 2);
19341 } else {
19342 /* OPC_BGTZL */
19343 gen_compute_branch(ctx, op, 4, rs, rt, imm << 2, 4);
19345 break;
19346 case OPC_BLEZALC: /* OPC_BGEZALC, OPC_BGEUC, OPC_BLEZ */
19347 if (rt == 0) {
19348 /* OPC_BLEZ */
19349 gen_compute_branch(ctx, op, 4, rs, rt, imm << 2, 4);
19350 } else {
19351 check_insn(ctx, ISA_MIPS32R6);
19352 /* OPC_BLEZALC, OPC_BGEZALC, OPC_BGEUC */
19353 gen_compute_compact_branch(ctx, op, rs, rt, imm << 2);
19355 break;
19356 case OPC_BGTZALC: /* OPC_BLTZALC, OPC_BLTUC, OPC_BGTZ */
19357 if (rt == 0) {
19358 /* OPC_BGTZ */
19359 gen_compute_branch(ctx, op, 4, rs, rt, imm << 2, 4);
19360 } else {
19361 check_insn(ctx, ISA_MIPS32R6);
19362 /* OPC_BGTZALC, OPC_BLTZALC, OPC_BLTUC */
19363 gen_compute_compact_branch(ctx, op, rs, rt, imm << 2);
19365 break;
19366 case OPC_BEQL:
19367 case OPC_BNEL:
19368 check_insn(ctx, ISA_MIPS2);
19369 check_insn_opc_removed(ctx, ISA_MIPS32R6);
19370 /* Fallthrough */
19371 case OPC_BEQ:
19372 case OPC_BNE:
19373 gen_compute_branch(ctx, op, 4, rs, rt, imm << 2, 4);
19374 break;
19375 case OPC_LL: /* Load and stores */
19376 check_insn(ctx, ISA_MIPS2);
19377 /* Fallthrough */
19378 case OPC_LWL:
19379 case OPC_LWR:
19380 check_insn_opc_removed(ctx, ISA_MIPS32R6);
19381 /* Fallthrough */
19382 case OPC_LB ... OPC_LH:
19383 case OPC_LW ... OPC_LHU:
19384 gen_ld(ctx, op, rt, rs, imm);
19385 break;
19386 case OPC_SWL:
19387 case OPC_SWR:
19388 check_insn_opc_removed(ctx, ISA_MIPS32R6);
19389 /* fall through */
19390 case OPC_SB ... OPC_SH:
19391 case OPC_SW:
19392 gen_st(ctx, op, rt, rs, imm);
19393 break;
19394 case OPC_SC:
19395 check_insn(ctx, ISA_MIPS2);
19396 check_insn_opc_removed(ctx, ISA_MIPS32R6);
19397 gen_st_cond(ctx, op, rt, rs, imm);
19398 break;
19399 case OPC_CACHE:
19400 check_insn_opc_removed(ctx, ISA_MIPS32R6);
19401 check_cp0_enabled(ctx);
19402 check_insn(ctx, ISA_MIPS3 | ISA_MIPS32);
19403 if (ctx->hflags & MIPS_HFLAG_ITC_CACHE) {
19404 gen_cache_operation(ctx, rt, rs, imm);
19406 /* Treat as NOP. */
19407 break;
19408 case OPC_PREF:
19409 check_insn_opc_removed(ctx, ISA_MIPS32R6);
19410 check_insn(ctx, ISA_MIPS4 | ISA_MIPS32);
19411 /* Treat as NOP. */
19412 break;
19414 /* Floating point (COP1). */
19415 case OPC_LWC1:
19416 case OPC_LDC1:
19417 case OPC_SWC1:
19418 case OPC_SDC1:
19419 gen_cop1_ldst(ctx, op, rt, rs, imm);
19420 break;
19422 case OPC_CP1:
19423 op1 = MASK_CP1(ctx->opcode);
19425 switch (op1) {
19426 case OPC_MFHC1:
19427 case OPC_MTHC1:
19428 check_cp1_enabled(ctx);
19429 check_insn(ctx, ISA_MIPS32R2);
19430 case OPC_MFC1:
19431 case OPC_CFC1:
19432 case OPC_MTC1:
19433 case OPC_CTC1:
19434 check_cp1_enabled(ctx);
19435 gen_cp1(ctx, op1, rt, rd);
19436 break;
19437 #if defined(TARGET_MIPS64)
19438 case OPC_DMFC1:
19439 case OPC_DMTC1:
19440 check_cp1_enabled(ctx);
19441 check_insn(ctx, ISA_MIPS3);
19442 check_mips_64(ctx);
19443 gen_cp1(ctx, op1, rt, rd);
19444 break;
19445 #endif
19446 case OPC_BC1EQZ: /* OPC_BC1ANY2 */
19447 check_cp1_enabled(ctx);
19448 if (ctx->insn_flags & ISA_MIPS32R6) {
19449 /* OPC_BC1EQZ */
19450 gen_compute_branch1_r6(ctx, MASK_CP1(ctx->opcode),
19451 rt, imm << 2, 4);
19452 } else {
19453 /* OPC_BC1ANY2 */
19454 check_cop1x(ctx);
19455 check_insn(ctx, ASE_MIPS3D);
19456 gen_compute_branch1(ctx, MASK_BC1(ctx->opcode),
19457 (rt >> 2) & 0x7, imm << 2);
19459 break;
19460 case OPC_BC1NEZ:
19461 check_cp1_enabled(ctx);
19462 check_insn(ctx, ISA_MIPS32R6);
19463 gen_compute_branch1_r6(ctx, MASK_CP1(ctx->opcode),
19464 rt, imm << 2, 4);
19465 break;
19466 case OPC_BC1ANY4:
19467 check_cp1_enabled(ctx);
19468 check_insn_opc_removed(ctx, ISA_MIPS32R6);
19469 check_cop1x(ctx);
19470 check_insn(ctx, ASE_MIPS3D);
19471 /* fall through */
19472 case OPC_BC1:
19473 check_cp1_enabled(ctx);
19474 check_insn_opc_removed(ctx, ISA_MIPS32R6);
19475 gen_compute_branch1(ctx, MASK_BC1(ctx->opcode),
19476 (rt >> 2) & 0x7, imm << 2);
19477 break;
19478 case OPC_PS_FMT:
19479 check_ps(ctx);
19480 /* fall through */
19481 case OPC_S_FMT:
19482 case OPC_D_FMT:
19483 check_cp1_enabled(ctx);
19484 gen_farith(ctx, ctx->opcode & FOP(0x3f, 0x1f), rt, rd, sa,
19485 (imm >> 8) & 0x7);
19486 break;
19487 case OPC_W_FMT:
19488 case OPC_L_FMT:
19490 int r6_op = ctx->opcode & FOP(0x3f, 0x1f);
19491 check_cp1_enabled(ctx);
19492 if (ctx->insn_flags & ISA_MIPS32R6) {
19493 switch (r6_op) {
19494 case R6_OPC_CMP_AF_S:
19495 case R6_OPC_CMP_UN_S:
19496 case R6_OPC_CMP_EQ_S:
19497 case R6_OPC_CMP_UEQ_S:
19498 case R6_OPC_CMP_LT_S:
19499 case R6_OPC_CMP_ULT_S:
19500 case R6_OPC_CMP_LE_S:
19501 case R6_OPC_CMP_ULE_S:
19502 case R6_OPC_CMP_SAF_S:
19503 case R6_OPC_CMP_SUN_S:
19504 case R6_OPC_CMP_SEQ_S:
19505 case R6_OPC_CMP_SEUQ_S:
19506 case R6_OPC_CMP_SLT_S:
19507 case R6_OPC_CMP_SULT_S:
19508 case R6_OPC_CMP_SLE_S:
19509 case R6_OPC_CMP_SULE_S:
19510 case R6_OPC_CMP_OR_S:
19511 case R6_OPC_CMP_UNE_S:
19512 case R6_OPC_CMP_NE_S:
19513 case R6_OPC_CMP_SOR_S:
19514 case R6_OPC_CMP_SUNE_S:
19515 case R6_OPC_CMP_SNE_S:
19516 gen_r6_cmp_s(ctx, ctx->opcode & 0x1f, rt, rd, sa);
19517 break;
19518 case R6_OPC_CMP_AF_D:
19519 case R6_OPC_CMP_UN_D:
19520 case R6_OPC_CMP_EQ_D:
19521 case R6_OPC_CMP_UEQ_D:
19522 case R6_OPC_CMP_LT_D:
19523 case R6_OPC_CMP_ULT_D:
19524 case R6_OPC_CMP_LE_D:
19525 case R6_OPC_CMP_ULE_D:
19526 case R6_OPC_CMP_SAF_D:
19527 case R6_OPC_CMP_SUN_D:
19528 case R6_OPC_CMP_SEQ_D:
19529 case R6_OPC_CMP_SEUQ_D:
19530 case R6_OPC_CMP_SLT_D:
19531 case R6_OPC_CMP_SULT_D:
19532 case R6_OPC_CMP_SLE_D:
19533 case R6_OPC_CMP_SULE_D:
19534 case R6_OPC_CMP_OR_D:
19535 case R6_OPC_CMP_UNE_D:
19536 case R6_OPC_CMP_NE_D:
19537 case R6_OPC_CMP_SOR_D:
19538 case R6_OPC_CMP_SUNE_D:
19539 case R6_OPC_CMP_SNE_D:
19540 gen_r6_cmp_d(ctx, ctx->opcode & 0x1f, rt, rd, sa);
19541 break;
19542 default:
19543 gen_farith(ctx, ctx->opcode & FOP(0x3f, 0x1f),
19544 rt, rd, sa, (imm >> 8) & 0x7);
19546 break;
19548 } else {
19549 gen_farith(ctx, ctx->opcode & FOP(0x3f, 0x1f), rt, rd, sa,
19550 (imm >> 8) & 0x7);
19552 break;
19554 case OPC_BZ_V:
19555 case OPC_BNZ_V:
19556 case OPC_BZ_B:
19557 case OPC_BZ_H:
19558 case OPC_BZ_W:
19559 case OPC_BZ_D:
19560 case OPC_BNZ_B:
19561 case OPC_BNZ_H:
19562 case OPC_BNZ_W:
19563 case OPC_BNZ_D:
19564 check_insn(ctx, ASE_MSA);
19565 gen_msa_branch(env, ctx, op1);
19566 break;
19567 default:
19568 MIPS_INVAL("cp1");
19569 generate_exception_end(ctx, EXCP_RI);
19570 break;
19572 break;
19574 /* Compact branches [R6] and COP2 [non-R6] */
19575 case OPC_BC: /* OPC_LWC2 */
19576 case OPC_BALC: /* OPC_SWC2 */
19577 if (ctx->insn_flags & ISA_MIPS32R6) {
19578 /* OPC_BC, OPC_BALC */
19579 gen_compute_compact_branch(ctx, op, 0, 0,
19580 sextract32(ctx->opcode << 2, 0, 28));
19581 } else {
19582 /* OPC_LWC2, OPC_SWC2 */
19583 /* COP2: Not implemented. */
19584 generate_exception_err(ctx, EXCP_CpU, 2);
19586 break;
19587 case OPC_BEQZC: /* OPC_JIC, OPC_LDC2 */
19588 case OPC_BNEZC: /* OPC_JIALC, OPC_SDC2 */
19589 if (ctx->insn_flags & ISA_MIPS32R6) {
19590 if (rs != 0) {
19591 /* OPC_BEQZC, OPC_BNEZC */
19592 gen_compute_compact_branch(ctx, op, rs, 0,
19593 sextract32(ctx->opcode << 2, 0, 23));
19594 } else {
19595 /* OPC_JIC, OPC_JIALC */
19596 gen_compute_compact_branch(ctx, op, 0, rt, imm);
19598 } else {
19599 /* OPC_LWC2, OPC_SWC2 */
19600 /* COP2: Not implemented. */
19601 generate_exception_err(ctx, EXCP_CpU, 2);
19603 break;
19604 case OPC_CP2:
19605 check_insn(ctx, INSN_LOONGSON2F);
19606 /* Note that these instructions use different fields. */
19607 gen_loongson_multimedia(ctx, sa, rd, rt);
19608 break;
19610 case OPC_CP3:
19611 check_insn_opc_removed(ctx, ISA_MIPS32R6);
19612 if (ctx->CP0_Config1 & (1 << CP0C1_FP)) {
19613 check_cp1_enabled(ctx);
19614 op1 = MASK_CP3(ctx->opcode);
19615 switch (op1) {
19616 case OPC_LUXC1:
19617 case OPC_SUXC1:
19618 check_insn(ctx, ISA_MIPS5 | ISA_MIPS32R2);
19619 /* Fallthrough */
19620 case OPC_LWXC1:
19621 case OPC_LDXC1:
19622 case OPC_SWXC1:
19623 case OPC_SDXC1:
19624 check_insn(ctx, ISA_MIPS4 | ISA_MIPS32R2);
19625 gen_flt3_ldst(ctx, op1, sa, rd, rs, rt);
19626 break;
19627 case OPC_PREFX:
19628 check_insn(ctx, ISA_MIPS4 | ISA_MIPS32R2);
19629 /* Treat as NOP. */
19630 break;
19631 case OPC_ALNV_PS:
19632 check_insn(ctx, ISA_MIPS5 | ISA_MIPS32R2);
19633 /* Fallthrough */
19634 case OPC_MADD_S:
19635 case OPC_MADD_D:
19636 case OPC_MADD_PS:
19637 case OPC_MSUB_S:
19638 case OPC_MSUB_D:
19639 case OPC_MSUB_PS:
19640 case OPC_NMADD_S:
19641 case OPC_NMADD_D:
19642 case OPC_NMADD_PS:
19643 case OPC_NMSUB_S:
19644 case OPC_NMSUB_D:
19645 case OPC_NMSUB_PS:
19646 check_insn(ctx, ISA_MIPS4 | ISA_MIPS32R2);
19647 gen_flt3_arith(ctx, op1, sa, rs, rd, rt);
19648 break;
19649 default:
19650 MIPS_INVAL("cp3");
19651 generate_exception_end(ctx, EXCP_RI);
19652 break;
19654 } else {
19655 generate_exception_err(ctx, EXCP_CpU, 1);
19657 break;
19659 #if defined(TARGET_MIPS64)
19660 /* MIPS64 opcodes */
19661 case OPC_LDL ... OPC_LDR:
19662 case OPC_LLD:
19663 check_insn_opc_removed(ctx, ISA_MIPS32R6);
19664 /* fall through */
19665 case OPC_LWU:
19666 case OPC_LD:
19667 check_insn(ctx, ISA_MIPS3);
19668 check_mips_64(ctx);
19669 gen_ld(ctx, op, rt, rs, imm);
19670 break;
19671 case OPC_SDL ... OPC_SDR:
19672 check_insn_opc_removed(ctx, ISA_MIPS32R6);
19673 /* fall through */
19674 case OPC_SD:
19675 check_insn(ctx, ISA_MIPS3);
19676 check_mips_64(ctx);
19677 gen_st(ctx, op, rt, rs, imm);
19678 break;
19679 case OPC_SCD:
19680 check_insn_opc_removed(ctx, ISA_MIPS32R6);
19681 check_insn(ctx, ISA_MIPS3);
19682 check_mips_64(ctx);
19683 gen_st_cond(ctx, op, rt, rs, imm);
19684 break;
19685 case OPC_BNVC: /* OPC_BNEZALC, OPC_BNEC, OPC_DADDI */
19686 if (ctx->insn_flags & ISA_MIPS32R6) {
19687 /* OPC_BNVC, OPC_BNEZALC, OPC_BNEC */
19688 gen_compute_compact_branch(ctx, op, rs, rt, imm << 2);
19689 } else {
19690 /* OPC_DADDI */
19691 check_insn(ctx, ISA_MIPS3);
19692 check_mips_64(ctx);
19693 gen_arith_imm(ctx, op, rt, rs, imm);
19695 break;
19696 case OPC_DADDIU:
19697 check_insn(ctx, ISA_MIPS3);
19698 check_mips_64(ctx);
19699 gen_arith_imm(ctx, op, rt, rs, imm);
19700 break;
19701 #else
19702 case OPC_BNVC: /* OPC_BNEZALC, OPC_BNEC */
19703 if (ctx->insn_flags & ISA_MIPS32R6) {
19704 gen_compute_compact_branch(ctx, op, rs, rt, imm << 2);
19705 } else {
19706 MIPS_INVAL("major opcode");
19707 generate_exception_end(ctx, EXCP_RI);
19709 break;
19710 #endif
19711 case OPC_DAUI: /* OPC_JALX */
19712 if (ctx->insn_flags & ISA_MIPS32R6) {
19713 #if defined(TARGET_MIPS64)
19714 /* OPC_DAUI */
19715 check_mips_64(ctx);
19716 if (rs == 0) {
19717 generate_exception(ctx, EXCP_RI);
19718 } else if (rt != 0) {
19719 TCGv t0 = tcg_temp_new();
19720 gen_load_gpr(t0, rs);
19721 tcg_gen_addi_tl(cpu_gpr[rt], t0, imm << 16);
19722 tcg_temp_free(t0);
19724 #else
19725 generate_exception_end(ctx, EXCP_RI);
19726 MIPS_INVAL("major opcode");
19727 #endif
19728 } else {
19729 /* OPC_JALX */
19730 check_insn(ctx, ASE_MIPS16 | ASE_MICROMIPS);
19731 offset = (int32_t)(ctx->opcode & 0x3FFFFFF) << 2;
19732 gen_compute_branch(ctx, op, 4, rs, rt, offset, 4);
19734 break;
19735 case OPC_MSA: /* OPC_MDMX */
19736 /* MDMX: Not implemented. */
19737 gen_msa(env, ctx);
19738 break;
19739 case OPC_PCREL:
19740 check_insn(ctx, ISA_MIPS32R6);
19741 gen_pcrel(ctx, ctx->opcode, ctx->pc, rs);
19742 break;
19743 default: /* Invalid */
19744 MIPS_INVAL("major opcode");
19745 generate_exception_end(ctx, EXCP_RI);
19746 break;
19750 void gen_intermediate_code(CPUMIPSState *env, struct TranslationBlock *tb)
19752 MIPSCPU *cpu = mips_env_get_cpu(env);
19753 CPUState *cs = CPU(cpu);
19754 DisasContext ctx;
19755 target_ulong pc_start;
19756 target_ulong next_page_start;
19757 int num_insns;
19758 int max_insns;
19759 int insn_bytes;
19760 int is_slot;
19762 pc_start = tb->pc;
19763 next_page_start = (pc_start & TARGET_PAGE_MASK) + TARGET_PAGE_SIZE;
19764 ctx.pc = pc_start;
19765 ctx.saved_pc = -1;
19766 ctx.singlestep_enabled = cs->singlestep_enabled;
19767 ctx.insn_flags = env->insn_flags;
19768 ctx.CP0_Config1 = env->CP0_Config1;
19769 ctx.tb = tb;
19770 ctx.bstate = BS_NONE;
19771 ctx.btarget = 0;
19772 ctx.kscrexist = (env->CP0_Config4 >> CP0C4_KScrExist) & 0xff;
19773 ctx.rxi = (env->CP0_Config3 >> CP0C3_RXI) & 1;
19774 ctx.ie = (env->CP0_Config4 >> CP0C4_IE) & 3;
19775 ctx.bi = (env->CP0_Config3 >> CP0C3_BI) & 1;
19776 ctx.bp = (env->CP0_Config3 >> CP0C3_BP) & 1;
19777 ctx.PAMask = env->PAMask;
19778 ctx.mvh = (env->CP0_Config5 >> CP0C5_MVH) & 1;
19779 ctx.CP0_LLAddr_shift = env->CP0_LLAddr_shift;
19780 ctx.cmgcr = (env->CP0_Config3 >> CP0C3_CMGCR) & 1;
19781 /* Restore delay slot state from the tb context. */
19782 ctx.hflags = (uint32_t)tb->flags; /* FIXME: maybe use 64 bits here? */
19783 ctx.ulri = (env->CP0_Config3 >> CP0C3_ULRI) & 1;
19784 ctx.ps = ((env->active_fpu.fcr0 >> FCR0_PS) & 1) ||
19785 (env->insn_flags & (INSN_LOONGSON2E | INSN_LOONGSON2F));
19786 ctx.vp = (env->CP0_Config5 >> CP0C5_VP) & 1;
19787 ctx.mrp = (env->CP0_Config5 >> CP0C5_MRP) & 1;
19788 restore_cpu_state(env, &ctx);
19789 #ifdef CONFIG_USER_ONLY
19790 ctx.mem_idx = MIPS_HFLAG_UM;
19791 #else
19792 ctx.mem_idx = ctx.hflags & MIPS_HFLAG_KSU;
19793 #endif
19794 ctx.default_tcg_memop_mask = (ctx.insn_flags & ISA_MIPS32R6) ?
19795 MO_UNALN : MO_ALIGN;
19796 num_insns = 0;
19797 max_insns = tb->cflags & CF_COUNT_MASK;
19798 if (max_insns == 0) {
19799 max_insns = CF_COUNT_MASK;
19801 if (max_insns > TCG_MAX_INSNS) {
19802 max_insns = TCG_MAX_INSNS;
19805 LOG_DISAS("\ntb %p idx %d hflags %04x\n", tb, ctx.mem_idx, ctx.hflags);
19806 gen_tb_start(tb);
19807 while (ctx.bstate == BS_NONE) {
19808 tcg_gen_insn_start(ctx.pc, ctx.hflags & MIPS_HFLAG_BMASK, ctx.btarget);
19809 num_insns++;
19811 if (unlikely(cpu_breakpoint_test(cs, ctx.pc, BP_ANY))) {
19812 save_cpu_state(&ctx, 1);
19813 ctx.bstate = BS_BRANCH;
19814 gen_helper_raise_exception_debug(cpu_env);
19815 /* The address covered by the breakpoint must be included in
19816 [tb->pc, tb->pc + tb->size) in order to for it to be
19817 properly cleared -- thus we increment the PC here so that
19818 the logic setting tb->size below does the right thing. */
19819 ctx.pc += 4;
19820 goto done_generating;
19823 if (num_insns == max_insns && (tb->cflags & CF_LAST_IO)) {
19824 gen_io_start();
19827 is_slot = ctx.hflags & MIPS_HFLAG_BMASK;
19828 if (!(ctx.hflags & MIPS_HFLAG_M16)) {
19829 ctx.opcode = cpu_ldl_code(env, ctx.pc);
19830 insn_bytes = 4;
19831 decode_opc(env, &ctx);
19832 } else if (ctx.insn_flags & ASE_MICROMIPS) {
19833 ctx.opcode = cpu_lduw_code(env, ctx.pc);
19834 insn_bytes = decode_micromips_opc(env, &ctx);
19835 } else if (ctx.insn_flags & ASE_MIPS16) {
19836 ctx.opcode = cpu_lduw_code(env, ctx.pc);
19837 insn_bytes = decode_mips16_opc(env, &ctx);
19838 } else {
19839 generate_exception_end(&ctx, EXCP_RI);
19840 break;
19843 if (ctx.hflags & MIPS_HFLAG_BMASK) {
19844 if (!(ctx.hflags & (MIPS_HFLAG_BDS16 | MIPS_HFLAG_BDS32 |
19845 MIPS_HFLAG_FBNSLOT))) {
19846 /* force to generate branch as there is neither delay nor
19847 forbidden slot */
19848 is_slot = 1;
19850 if ((ctx.hflags & MIPS_HFLAG_M16) &&
19851 (ctx.hflags & MIPS_HFLAG_FBNSLOT)) {
19852 /* Force to generate branch as microMIPS R6 doesn't restrict
19853 branches in the forbidden slot. */
19854 is_slot = 1;
19857 if (is_slot) {
19858 gen_branch(&ctx, insn_bytes);
19860 ctx.pc += insn_bytes;
19862 /* Execute a branch and its delay slot as a single instruction.
19863 This is what GDB expects and is consistent with what the
19864 hardware does (e.g. if a delay slot instruction faults, the
19865 reported PC is the PC of the branch). */
19866 if (cs->singlestep_enabled && (ctx.hflags & MIPS_HFLAG_BMASK) == 0) {
19867 break;
19870 if (ctx.pc >= next_page_start) {
19871 break;
19874 if (tcg_op_buf_full()) {
19875 break;
19878 if (num_insns >= max_insns)
19879 break;
19881 if (singlestep)
19882 break;
19884 if (tb->cflags & CF_LAST_IO) {
19885 gen_io_end();
19887 if (cs->singlestep_enabled && ctx.bstate != BS_BRANCH) {
19888 save_cpu_state(&ctx, ctx.bstate != BS_EXCP);
19889 gen_helper_raise_exception_debug(cpu_env);
19890 } else {
19891 switch (ctx.bstate) {
19892 case BS_STOP:
19893 gen_goto_tb(&ctx, 0, ctx.pc);
19894 break;
19895 case BS_NONE:
19896 save_cpu_state(&ctx, 0);
19897 gen_goto_tb(&ctx, 0, ctx.pc);
19898 break;
19899 case BS_EXCP:
19900 tcg_gen_exit_tb(0);
19901 break;
19902 case BS_BRANCH:
19903 default:
19904 break;
19907 done_generating:
19908 gen_tb_end(tb, num_insns);
19910 tb->size = ctx.pc - pc_start;
19911 tb->icount = num_insns;
19913 #ifdef DEBUG_DISAS
19914 LOG_DISAS("\n");
19915 if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM)) {
19916 qemu_log("IN: %s\n", lookup_symbol(pc_start));
19917 log_target_disas(cs, pc_start, ctx.pc - pc_start, 0);
19918 qemu_log("\n");
19920 #endif
19923 static void fpu_dump_state(CPUMIPSState *env, FILE *f, fprintf_function fpu_fprintf,
19924 int flags)
19926 int i;
19927 int is_fpu64 = !!(env->hflags & MIPS_HFLAG_F64);
19929 #define printfpr(fp) \
19930 do { \
19931 if (is_fpu64) \
19932 fpu_fprintf(f, "w:%08x d:%016" PRIx64 \
19933 " fd:%13g fs:%13g psu: %13g\n", \
19934 (fp)->w[FP_ENDIAN_IDX], (fp)->d, \
19935 (double)(fp)->fd, \
19936 (double)(fp)->fs[FP_ENDIAN_IDX], \
19937 (double)(fp)->fs[!FP_ENDIAN_IDX]); \
19938 else { \
19939 fpr_t tmp; \
19940 tmp.w[FP_ENDIAN_IDX] = (fp)->w[FP_ENDIAN_IDX]; \
19941 tmp.w[!FP_ENDIAN_IDX] = ((fp) + 1)->w[FP_ENDIAN_IDX]; \
19942 fpu_fprintf(f, "w:%08x d:%016" PRIx64 \
19943 " fd:%13g fs:%13g psu:%13g\n", \
19944 tmp.w[FP_ENDIAN_IDX], tmp.d, \
19945 (double)tmp.fd, \
19946 (double)tmp.fs[FP_ENDIAN_IDX], \
19947 (double)tmp.fs[!FP_ENDIAN_IDX]); \
19949 } while(0)
19952 fpu_fprintf(f, "CP1 FCR0 0x%08x FCR31 0x%08x SR.FR %d fp_status 0x%02x\n",
19953 env->active_fpu.fcr0, env->active_fpu.fcr31, is_fpu64,
19954 get_float_exception_flags(&env->active_fpu.fp_status));
19955 for (i = 0; i < 32; (is_fpu64) ? i++ : (i += 2)) {
19956 fpu_fprintf(f, "%3s: ", fregnames[i]);
19957 printfpr(&env->active_fpu.fpr[i]);
19960 #undef printfpr
19963 void mips_cpu_dump_state(CPUState *cs, FILE *f, fprintf_function cpu_fprintf,
19964 int flags)
19966 MIPSCPU *cpu = MIPS_CPU(cs);
19967 CPUMIPSState *env = &cpu->env;
19968 int i;
19970 cpu_fprintf(f, "pc=0x" TARGET_FMT_lx " HI=0x" TARGET_FMT_lx
19971 " LO=0x" TARGET_FMT_lx " ds %04x "
19972 TARGET_FMT_lx " " TARGET_FMT_ld "\n",
19973 env->active_tc.PC, env->active_tc.HI[0], env->active_tc.LO[0],
19974 env->hflags, env->btarget, env->bcond);
19975 for (i = 0; i < 32; i++) {
19976 if ((i & 3) == 0)
19977 cpu_fprintf(f, "GPR%02d:", i);
19978 cpu_fprintf(f, " %s " TARGET_FMT_lx, regnames[i], env->active_tc.gpr[i]);
19979 if ((i & 3) == 3)
19980 cpu_fprintf(f, "\n");
19983 cpu_fprintf(f, "CP0 Status 0x%08x Cause 0x%08x EPC 0x" TARGET_FMT_lx "\n",
19984 env->CP0_Status, env->CP0_Cause, env->CP0_EPC);
19985 cpu_fprintf(f, " Config0 0x%08x Config1 0x%08x LLAddr 0x%016"
19986 PRIx64 "\n",
19987 env->CP0_Config0, env->CP0_Config1, env->lladdr);
19988 cpu_fprintf(f, " Config2 0x%08x Config3 0x%08x\n",
19989 env->CP0_Config2, env->CP0_Config3);
19990 cpu_fprintf(f, " Config4 0x%08x Config5 0x%08x\n",
19991 env->CP0_Config4, env->CP0_Config5);
19992 if (env->hflags & MIPS_HFLAG_FPU)
19993 fpu_dump_state(env, f, cpu_fprintf, flags);
19996 void mips_tcg_init(void)
19998 int i;
19999 static int inited;
20001 /* Initialize various static tables. */
20002 if (inited)
20003 return;
20005 cpu_env = tcg_global_reg_new_ptr(TCG_AREG0, "env");
20007 TCGV_UNUSED(cpu_gpr[0]);
20008 for (i = 1; i < 32; i++)
20009 cpu_gpr[i] = tcg_global_mem_new(cpu_env,
20010 offsetof(CPUMIPSState, active_tc.gpr[i]),
20011 regnames[i]);
20013 for (i = 0; i < 32; i++) {
20014 int off = offsetof(CPUMIPSState, active_fpu.fpr[i].wr.d[0]);
20015 msa_wr_d[i * 2] =
20016 tcg_global_mem_new_i64(cpu_env, off, msaregnames[i * 2]);
20017 /* The scalar floating-point unit (FPU) registers are mapped on
20018 * the MSA vector registers. */
20019 fpu_f64[i] = msa_wr_d[i * 2];
20020 off = offsetof(CPUMIPSState, active_fpu.fpr[i].wr.d[1]);
20021 msa_wr_d[i * 2 + 1] =
20022 tcg_global_mem_new_i64(cpu_env, off, msaregnames[i * 2 + 1]);
20025 cpu_PC = tcg_global_mem_new(cpu_env,
20026 offsetof(CPUMIPSState, active_tc.PC), "PC");
20027 for (i = 0; i < MIPS_DSP_ACC; i++) {
20028 cpu_HI[i] = tcg_global_mem_new(cpu_env,
20029 offsetof(CPUMIPSState, active_tc.HI[i]),
20030 regnames_HI[i]);
20031 cpu_LO[i] = tcg_global_mem_new(cpu_env,
20032 offsetof(CPUMIPSState, active_tc.LO[i]),
20033 regnames_LO[i]);
20035 cpu_dspctrl = tcg_global_mem_new(cpu_env,
20036 offsetof(CPUMIPSState, active_tc.DSPControl),
20037 "DSPControl");
20038 bcond = tcg_global_mem_new(cpu_env,
20039 offsetof(CPUMIPSState, bcond), "bcond");
20040 btarget = tcg_global_mem_new(cpu_env,
20041 offsetof(CPUMIPSState, btarget), "btarget");
20042 hflags = tcg_global_mem_new_i32(cpu_env,
20043 offsetof(CPUMIPSState, hflags), "hflags");
20045 fpu_fcr0 = tcg_global_mem_new_i32(cpu_env,
20046 offsetof(CPUMIPSState, active_fpu.fcr0),
20047 "fcr0");
20048 fpu_fcr31 = tcg_global_mem_new_i32(cpu_env,
20049 offsetof(CPUMIPSState, active_fpu.fcr31),
20050 "fcr31");
20052 inited = 1;
20055 #include "translate_init.c"
20057 MIPSCPU *cpu_mips_init(const char *cpu_model)
20059 MIPSCPU *cpu;
20060 CPUMIPSState *env;
20061 const mips_def_t *def;
20063 def = cpu_mips_find_by_name(cpu_model);
20064 if (!def)
20065 return NULL;
20066 cpu = MIPS_CPU(object_new(TYPE_MIPS_CPU));
20067 env = &cpu->env;
20068 env->cpu_model = def;
20070 #ifndef CONFIG_USER_ONLY
20071 mmu_init(env, def);
20072 #endif
20073 fpu_init(env, def);
20074 mvp_init(env, def);
20076 object_property_set_bool(OBJECT(cpu), true, "realized", NULL);
20078 return cpu;
20081 bool cpu_supports_cps_smp(const char *cpu_model)
20083 const mips_def_t *def = cpu_mips_find_by_name(cpu_model);
20084 if (!def) {
20085 return false;
20088 return (def->CP0_Config3 & (1 << CP0C3_CMGCR)) != 0;
20091 void cpu_state_reset(CPUMIPSState *env)
20093 MIPSCPU *cpu = mips_env_get_cpu(env);
20094 CPUState *cs = CPU(cpu);
20096 /* Reset registers to their default values */
20097 env->CP0_PRid = env->cpu_model->CP0_PRid;
20098 env->CP0_Config0 = env->cpu_model->CP0_Config0;
20099 #ifdef TARGET_WORDS_BIGENDIAN
20100 env->CP0_Config0 |= (1 << CP0C0_BE);
20101 #endif
20102 env->CP0_Config1 = env->cpu_model->CP0_Config1;
20103 env->CP0_Config2 = env->cpu_model->CP0_Config2;
20104 env->CP0_Config3 = env->cpu_model->CP0_Config3;
20105 env->CP0_Config4 = env->cpu_model->CP0_Config4;
20106 env->CP0_Config4_rw_bitmask = env->cpu_model->CP0_Config4_rw_bitmask;
20107 env->CP0_Config5 = env->cpu_model->CP0_Config5;
20108 env->CP0_Config5_rw_bitmask = env->cpu_model->CP0_Config5_rw_bitmask;
20109 env->CP0_Config6 = env->cpu_model->CP0_Config6;
20110 env->CP0_Config7 = env->cpu_model->CP0_Config7;
20111 env->CP0_LLAddr_rw_bitmask = env->cpu_model->CP0_LLAddr_rw_bitmask
20112 << env->cpu_model->CP0_LLAddr_shift;
20113 env->CP0_LLAddr_shift = env->cpu_model->CP0_LLAddr_shift;
20114 env->SYNCI_Step = env->cpu_model->SYNCI_Step;
20115 env->CCRes = env->cpu_model->CCRes;
20116 env->CP0_Status_rw_bitmask = env->cpu_model->CP0_Status_rw_bitmask;
20117 env->CP0_TCStatus_rw_bitmask = env->cpu_model->CP0_TCStatus_rw_bitmask;
20118 env->CP0_SRSCtl = env->cpu_model->CP0_SRSCtl;
20119 env->current_tc = 0;
20120 env->SEGBITS = env->cpu_model->SEGBITS;
20121 env->SEGMask = (target_ulong)((1ULL << env->cpu_model->SEGBITS) - 1);
20122 #if defined(TARGET_MIPS64)
20123 if (env->cpu_model->insn_flags & ISA_MIPS3) {
20124 env->SEGMask |= 3ULL << 62;
20126 #endif
20127 env->PABITS = env->cpu_model->PABITS;
20128 env->CP0_SRSConf0_rw_bitmask = env->cpu_model->CP0_SRSConf0_rw_bitmask;
20129 env->CP0_SRSConf0 = env->cpu_model->CP0_SRSConf0;
20130 env->CP0_SRSConf1_rw_bitmask = env->cpu_model->CP0_SRSConf1_rw_bitmask;
20131 env->CP0_SRSConf1 = env->cpu_model->CP0_SRSConf1;
20132 env->CP0_SRSConf2_rw_bitmask = env->cpu_model->CP0_SRSConf2_rw_bitmask;
20133 env->CP0_SRSConf2 = env->cpu_model->CP0_SRSConf2;
20134 env->CP0_SRSConf3_rw_bitmask = env->cpu_model->CP0_SRSConf3_rw_bitmask;
20135 env->CP0_SRSConf3 = env->cpu_model->CP0_SRSConf3;
20136 env->CP0_SRSConf4_rw_bitmask = env->cpu_model->CP0_SRSConf4_rw_bitmask;
20137 env->CP0_SRSConf4 = env->cpu_model->CP0_SRSConf4;
20138 env->CP0_PageGrain_rw_bitmask = env->cpu_model->CP0_PageGrain_rw_bitmask;
20139 env->CP0_PageGrain = env->cpu_model->CP0_PageGrain;
20140 env->active_fpu.fcr0 = env->cpu_model->CP1_fcr0;
20141 env->active_fpu.fcr31 = env->cpu_model->CP1_fcr31;
20142 env->msair = env->cpu_model->MSAIR;
20143 env->insn_flags = env->cpu_model->insn_flags;
20145 #if defined(CONFIG_USER_ONLY)
20146 env->CP0_Status = (MIPS_HFLAG_UM << CP0St_KSU);
20147 # ifdef TARGET_MIPS64
20148 /* Enable 64-bit register mode. */
20149 env->CP0_Status |= (1 << CP0St_PX);
20150 # endif
20151 # ifdef TARGET_ABI_MIPSN64
20152 /* Enable 64-bit address mode. */
20153 env->CP0_Status |= (1 << CP0St_UX);
20154 # endif
20155 /* Enable access to the CPUNum, SYNCI_Step, CC, and CCRes RDHWR
20156 hardware registers. */
20157 env->CP0_HWREna |= 0x0000000F;
20158 if (env->CP0_Config1 & (1 << CP0C1_FP)) {
20159 env->CP0_Status |= (1 << CP0St_CU1);
20161 if (env->CP0_Config3 & (1 << CP0C3_DSPP)) {
20162 env->CP0_Status |= (1 << CP0St_MX);
20164 # if defined(TARGET_MIPS64)
20165 /* For MIPS64, init FR bit to 1 if FPU unit is there and bit is writable. */
20166 if ((env->CP0_Config1 & (1 << CP0C1_FP)) &&
20167 (env->CP0_Status_rw_bitmask & (1 << CP0St_FR))) {
20168 env->CP0_Status |= (1 << CP0St_FR);
20170 # endif
20171 #else
20172 if (env->hflags & MIPS_HFLAG_BMASK) {
20173 /* If the exception was raised from a delay slot,
20174 come back to the jump. */
20175 env->CP0_ErrorEPC = (env->active_tc.PC
20176 - (env->hflags & MIPS_HFLAG_B16 ? 2 : 4));
20177 } else {
20178 env->CP0_ErrorEPC = env->active_tc.PC;
20180 env->active_tc.PC = (int32_t)0xBFC00000;
20181 env->CP0_Random = env->tlb->nb_tlb - 1;
20182 env->tlb->tlb_in_use = env->tlb->nb_tlb;
20183 env->CP0_Wired = 0;
20184 env->CP0_GlobalNumber = (cs->cpu_index & 0xFF) << CP0GN_VPId;
20185 env->CP0_EBase = (cs->cpu_index & 0x3FF);
20186 if (kvm_enabled()) {
20187 env->CP0_EBase |= 0x40000000;
20188 } else {
20189 env->CP0_EBase |= 0x80000000;
20191 if (env->CP0_Config3 & (1 << CP0C3_CMGCR)) {
20192 env->CP0_CMGCRBase = 0x1fbf8000 >> 4;
20194 env->CP0_Status = (1 << CP0St_BEV) | (1 << CP0St_ERL);
20195 /* vectored interrupts not implemented, timer on int 7,
20196 no performance counters. */
20197 env->CP0_IntCtl = 0xe0000000;
20199 int i;
20201 for (i = 0; i < 7; i++) {
20202 env->CP0_WatchLo[i] = 0;
20203 env->CP0_WatchHi[i] = 0x80000000;
20205 env->CP0_WatchLo[7] = 0;
20206 env->CP0_WatchHi[7] = 0;
20208 /* Count register increments in debug mode, EJTAG version 1 */
20209 env->CP0_Debug = (1 << CP0DB_CNT) | (0x1 << CP0DB_VER);
20211 cpu_mips_store_count(env, 1);
20213 if (env->CP0_Config3 & (1 << CP0C3_MT)) {
20214 int i;
20216 /* Only TC0 on VPE 0 starts as active. */
20217 for (i = 0; i < ARRAY_SIZE(env->tcs); i++) {
20218 env->tcs[i].CP0_TCBind = cs->cpu_index << CP0TCBd_CurVPE;
20219 env->tcs[i].CP0_TCHalt = 1;
20221 env->active_tc.CP0_TCHalt = 1;
20222 cs->halted = 1;
20224 if (cs->cpu_index == 0) {
20225 /* VPE0 starts up enabled. */
20226 env->mvp->CP0_MVPControl |= (1 << CP0MVPCo_EVP);
20227 env->CP0_VPEConf0 |= (1 << CP0VPEC0_MVP) | (1 << CP0VPEC0_VPA);
20229 /* TC0 starts up unhalted. */
20230 cs->halted = 0;
20231 env->active_tc.CP0_TCHalt = 0;
20232 env->tcs[0].CP0_TCHalt = 0;
20233 /* With thread 0 active. */
20234 env->active_tc.CP0_TCStatus = (1 << CP0TCSt_A);
20235 env->tcs[0].CP0_TCStatus = (1 << CP0TCSt_A);
20238 #endif
20239 if ((env->insn_flags & ISA_MIPS32R6) &&
20240 (env->active_fpu.fcr0 & (1 << FCR0_F64))) {
20241 /* Status.FR = 0 mode in 64-bit FPU not allowed in R6 */
20242 env->CP0_Status |= (1 << CP0St_FR);
20245 /* MSA */
20246 if (env->CP0_Config3 & (1 << CP0C3_MSAP)) {
20247 msa_reset(env);
20250 compute_hflags(env);
20251 restore_rounding_mode(env);
20252 restore_flush_mode(env);
20253 restore_pamask(env);
20254 cs->exception_index = EXCP_NONE;
20256 if (semihosting_get_argc()) {
20257 /* UHI interface can be used to obtain argc and argv */
20258 env->active_tc.gpr[4] = -1;
20262 void restore_state_to_opc(CPUMIPSState *env, TranslationBlock *tb,
20263 target_ulong *data)
20265 env->active_tc.PC = data[0];
20266 env->hflags &= ~MIPS_HFLAG_BMASK;
20267 env->hflags |= data[1];
20268 switch (env->hflags & MIPS_HFLAG_BMASK_BASE) {
20269 case MIPS_HFLAG_BR:
20270 break;
20271 case MIPS_HFLAG_BC:
20272 case MIPS_HFLAG_BL:
20273 case MIPS_HFLAG_B:
20274 env->btarget = data[2];
20275 break;