scripts/qemu-binfmt-conf.sh: Add AArch64 registration
[qemu/ar7.git] / target-mips / translate.c
blob71dccaea55e73c7ed65f13af7f363d54a265537f
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 "cpu.h"
25 #include "disas/disas.h"
26 #include "tcg-op.h"
28 #include "helper.h"
29 #define GEN_HELPER 1
30 #include "helper.h"
32 #define MIPS_DEBUG_DISAS 0
33 //#define MIPS_DEBUG_SIGN_EXTENSIONS
35 /* MIPS major opcodes */
36 #define MASK_OP_MAJOR(op) (op & (0x3F << 26))
38 enum {
39 /* indirect opcode tables */
40 OPC_SPECIAL = (0x00 << 26),
41 OPC_REGIMM = (0x01 << 26),
42 OPC_CP0 = (0x10 << 26),
43 OPC_CP1 = (0x11 << 26),
44 OPC_CP2 = (0x12 << 26),
45 OPC_CP3 = (0x13 << 26),
46 OPC_SPECIAL2 = (0x1C << 26),
47 OPC_SPECIAL3 = (0x1F << 26),
48 /* arithmetic with immediate */
49 OPC_ADDI = (0x08 << 26),
50 OPC_ADDIU = (0x09 << 26),
51 OPC_SLTI = (0x0A << 26),
52 OPC_SLTIU = (0x0B << 26),
53 /* logic with immediate */
54 OPC_ANDI = (0x0C << 26),
55 OPC_ORI = (0x0D << 26),
56 OPC_XORI = (0x0E << 26),
57 OPC_LUI = (0x0F << 26),
58 /* arithmetic with immediate */
59 OPC_DADDI = (0x18 << 26),
60 OPC_DADDIU = (0x19 << 26),
61 /* Jump and branches */
62 OPC_J = (0x02 << 26),
63 OPC_JAL = (0x03 << 26),
64 OPC_JALS = OPC_JAL | 0x5,
65 OPC_BEQ = (0x04 << 26), /* Unconditional if rs = rt = 0 (B) */
66 OPC_BEQL = (0x14 << 26),
67 OPC_BNE = (0x05 << 26),
68 OPC_BNEL = (0x15 << 26),
69 OPC_BLEZ = (0x06 << 26),
70 OPC_BLEZL = (0x16 << 26),
71 OPC_BGTZ = (0x07 << 26),
72 OPC_BGTZL = (0x17 << 26),
73 OPC_JALX = (0x1D << 26), /* MIPS 16 only */
74 OPC_JALXS = OPC_JALX | 0x5,
75 /* Load and stores */
76 OPC_LDL = (0x1A << 26),
77 OPC_LDR = (0x1B << 26),
78 OPC_LB = (0x20 << 26),
79 OPC_LH = (0x21 << 26),
80 OPC_LWL = (0x22 << 26),
81 OPC_LW = (0x23 << 26),
82 OPC_LWPC = OPC_LW | 0x5,
83 OPC_LBU = (0x24 << 26),
84 OPC_LHU = (0x25 << 26),
85 OPC_LWR = (0x26 << 26),
86 OPC_LWU = (0x27 << 26),
87 OPC_SB = (0x28 << 26),
88 OPC_SH = (0x29 << 26),
89 OPC_SWL = (0x2A << 26),
90 OPC_SW = (0x2B << 26),
91 OPC_SDL = (0x2C << 26),
92 OPC_SDR = (0x2D << 26),
93 OPC_SWR = (0x2E << 26),
94 OPC_LL = (0x30 << 26),
95 OPC_LLD = (0x34 << 26),
96 OPC_LD = (0x37 << 26),
97 OPC_LDPC = OPC_LD | 0x5,
98 OPC_SC = (0x38 << 26),
99 OPC_SCD = (0x3C << 26),
100 OPC_SD = (0x3F << 26),
101 /* Floating point load/store */
102 OPC_LWC1 = (0x31 << 26),
103 OPC_LWC2 = (0x32 << 26),
104 OPC_LDC1 = (0x35 << 26),
105 OPC_LDC2 = (0x36 << 26),
106 OPC_SWC1 = (0x39 << 26),
107 OPC_SWC2 = (0x3A << 26),
108 OPC_SDC1 = (0x3D << 26),
109 OPC_SDC2 = (0x3E << 26),
110 /* MDMX ASE specific */
111 OPC_MDMX = (0x1E << 26),
112 /* Cache and prefetch */
113 OPC_CACHE = (0x2F << 26),
114 OPC_PREF = (0x33 << 26),
115 /* Reserved major opcode */
116 OPC_MAJOR3B_RESERVED = (0x3B << 26),
119 /* MIPS special opcodes */
120 #define MASK_SPECIAL(op) MASK_OP_MAJOR(op) | (op & 0x3F)
122 enum {
123 /* Shifts */
124 OPC_SLL = 0x00 | OPC_SPECIAL,
125 /* NOP is SLL r0, r0, 0 */
126 /* SSNOP is SLL r0, r0, 1 */
127 /* EHB is SLL r0, r0, 3 */
128 OPC_SRL = 0x02 | OPC_SPECIAL, /* also ROTR */
129 OPC_ROTR = OPC_SRL | (1 << 21),
130 OPC_SRA = 0x03 | OPC_SPECIAL,
131 OPC_SLLV = 0x04 | OPC_SPECIAL,
132 OPC_SRLV = 0x06 | OPC_SPECIAL, /* also ROTRV */
133 OPC_ROTRV = OPC_SRLV | (1 << 6),
134 OPC_SRAV = 0x07 | OPC_SPECIAL,
135 OPC_DSLLV = 0x14 | OPC_SPECIAL,
136 OPC_DSRLV = 0x16 | OPC_SPECIAL, /* also DROTRV */
137 OPC_DROTRV = OPC_DSRLV | (1 << 6),
138 OPC_DSRAV = 0x17 | OPC_SPECIAL,
139 OPC_DSLL = 0x38 | OPC_SPECIAL,
140 OPC_DSRL = 0x3A | OPC_SPECIAL, /* also DROTR */
141 OPC_DROTR = OPC_DSRL | (1 << 21),
142 OPC_DSRA = 0x3B | OPC_SPECIAL,
143 OPC_DSLL32 = 0x3C | OPC_SPECIAL,
144 OPC_DSRL32 = 0x3E | OPC_SPECIAL, /* also DROTR32 */
145 OPC_DROTR32 = OPC_DSRL32 | (1 << 21),
146 OPC_DSRA32 = 0x3F | OPC_SPECIAL,
147 /* Multiplication / division */
148 OPC_MULT = 0x18 | OPC_SPECIAL,
149 OPC_MULTU = 0x19 | OPC_SPECIAL,
150 OPC_DIV = 0x1A | OPC_SPECIAL,
151 OPC_DIVU = 0x1B | OPC_SPECIAL,
152 OPC_DMULT = 0x1C | OPC_SPECIAL,
153 OPC_DMULTU = 0x1D | OPC_SPECIAL,
154 OPC_DDIV = 0x1E | OPC_SPECIAL,
155 OPC_DDIVU = 0x1F | OPC_SPECIAL,
156 /* 2 registers arithmetic / logic */
157 OPC_ADD = 0x20 | OPC_SPECIAL,
158 OPC_ADDU = 0x21 | OPC_SPECIAL,
159 OPC_SUB = 0x22 | OPC_SPECIAL,
160 OPC_SUBU = 0x23 | OPC_SPECIAL,
161 OPC_AND = 0x24 | OPC_SPECIAL,
162 OPC_OR = 0x25 | OPC_SPECIAL,
163 OPC_XOR = 0x26 | OPC_SPECIAL,
164 OPC_NOR = 0x27 | OPC_SPECIAL,
165 OPC_SLT = 0x2A | OPC_SPECIAL,
166 OPC_SLTU = 0x2B | OPC_SPECIAL,
167 OPC_DADD = 0x2C | OPC_SPECIAL,
168 OPC_DADDU = 0x2D | OPC_SPECIAL,
169 OPC_DSUB = 0x2E | OPC_SPECIAL,
170 OPC_DSUBU = 0x2F | OPC_SPECIAL,
171 /* Jumps */
172 OPC_JR = 0x08 | OPC_SPECIAL, /* Also JR.HB */
173 OPC_JALR = 0x09 | OPC_SPECIAL, /* Also JALR.HB */
174 OPC_JALRC = OPC_JALR | (0x5 << 6),
175 OPC_JALRS = 0x10 | OPC_SPECIAL | (0x5 << 6),
176 /* Traps */
177 OPC_TGE = 0x30 | OPC_SPECIAL,
178 OPC_TGEU = 0x31 | OPC_SPECIAL,
179 OPC_TLT = 0x32 | OPC_SPECIAL,
180 OPC_TLTU = 0x33 | OPC_SPECIAL,
181 OPC_TEQ = 0x34 | OPC_SPECIAL,
182 OPC_TNE = 0x36 | OPC_SPECIAL,
183 /* HI / LO registers load & stores */
184 OPC_MFHI = 0x10 | OPC_SPECIAL,
185 OPC_MTHI = 0x11 | OPC_SPECIAL,
186 OPC_MFLO = 0x12 | OPC_SPECIAL,
187 OPC_MTLO = 0x13 | OPC_SPECIAL,
188 /* Conditional moves */
189 OPC_MOVZ = 0x0A | OPC_SPECIAL,
190 OPC_MOVN = 0x0B | OPC_SPECIAL,
192 OPC_MOVCI = 0x01 | OPC_SPECIAL,
194 /* Special */
195 OPC_PMON = 0x05 | OPC_SPECIAL, /* unofficial */
196 OPC_SYSCALL = 0x0C | OPC_SPECIAL,
197 OPC_BREAK = 0x0D | OPC_SPECIAL,
198 OPC_SPIM = 0x0E | OPC_SPECIAL, /* unofficial */
199 OPC_SYNC = 0x0F | OPC_SPECIAL,
201 OPC_SPECIAL15_RESERVED = 0x15 | OPC_SPECIAL,
202 OPC_SPECIAL28_RESERVED = 0x28 | OPC_SPECIAL,
203 OPC_SPECIAL29_RESERVED = 0x29 | OPC_SPECIAL,
204 OPC_SPECIAL35_RESERVED = 0x35 | OPC_SPECIAL,
205 OPC_SPECIAL37_RESERVED = 0x37 | OPC_SPECIAL,
206 OPC_SPECIAL39_RESERVED = 0x39 | OPC_SPECIAL,
207 OPC_SPECIAL3D_RESERVED = 0x3D | OPC_SPECIAL,
210 /* Multiplication variants of the vr54xx. */
211 #define MASK_MUL_VR54XX(op) MASK_SPECIAL(op) | (op & (0x1F << 6))
213 enum {
214 OPC_VR54XX_MULS = (0x03 << 6) | OPC_MULT,
215 OPC_VR54XX_MULSU = (0x03 << 6) | OPC_MULTU,
216 OPC_VR54XX_MACC = (0x05 << 6) | OPC_MULT,
217 OPC_VR54XX_MACCU = (0x05 << 6) | OPC_MULTU,
218 OPC_VR54XX_MSAC = (0x07 << 6) | OPC_MULT,
219 OPC_VR54XX_MSACU = (0x07 << 6) | OPC_MULTU,
220 OPC_VR54XX_MULHI = (0x09 << 6) | OPC_MULT,
221 OPC_VR54XX_MULHIU = (0x09 << 6) | OPC_MULTU,
222 OPC_VR54XX_MULSHI = (0x0B << 6) | OPC_MULT,
223 OPC_VR54XX_MULSHIU = (0x0B << 6) | OPC_MULTU,
224 OPC_VR54XX_MACCHI = (0x0D << 6) | OPC_MULT,
225 OPC_VR54XX_MACCHIU = (0x0D << 6) | OPC_MULTU,
226 OPC_VR54XX_MSACHI = (0x0F << 6) | OPC_MULT,
227 OPC_VR54XX_MSACHIU = (0x0F << 6) | OPC_MULTU,
230 /* REGIMM (rt field) opcodes */
231 #define MASK_REGIMM(op) MASK_OP_MAJOR(op) | (op & (0x1F << 16))
233 enum {
234 OPC_BLTZ = (0x00 << 16) | OPC_REGIMM,
235 OPC_BLTZL = (0x02 << 16) | OPC_REGIMM,
236 OPC_BGEZ = (0x01 << 16) | OPC_REGIMM,
237 OPC_BGEZL = (0x03 << 16) | OPC_REGIMM,
238 OPC_BLTZAL = (0x10 << 16) | OPC_REGIMM,
239 OPC_BLTZALS = OPC_BLTZAL | 0x5, /* microMIPS */
240 OPC_BLTZALL = (0x12 << 16) | OPC_REGIMM,
241 OPC_BGEZAL = (0x11 << 16) | OPC_REGIMM,
242 OPC_BGEZALS = OPC_BGEZAL | 0x5, /* microMIPS */
243 OPC_BGEZALL = (0x13 << 16) | OPC_REGIMM,
244 OPC_TGEI = (0x08 << 16) | OPC_REGIMM,
245 OPC_TGEIU = (0x09 << 16) | OPC_REGIMM,
246 OPC_TLTI = (0x0A << 16) | OPC_REGIMM,
247 OPC_TLTIU = (0x0B << 16) | OPC_REGIMM,
248 OPC_TEQI = (0x0C << 16) | OPC_REGIMM,
249 OPC_TNEI = (0x0E << 16) | OPC_REGIMM,
250 OPC_SYNCI = (0x1F << 16) | OPC_REGIMM,
253 /* Special2 opcodes */
254 #define MASK_SPECIAL2(op) MASK_OP_MAJOR(op) | (op & 0x3F)
256 enum {
257 /* Multiply & xxx operations */
258 OPC_MADD = 0x00 | OPC_SPECIAL2,
259 OPC_MADDU = 0x01 | OPC_SPECIAL2,
260 OPC_MUL = 0x02 | OPC_SPECIAL2,
261 OPC_MSUB = 0x04 | OPC_SPECIAL2,
262 OPC_MSUBU = 0x05 | OPC_SPECIAL2,
263 /* Loongson 2F */
264 OPC_MULT_G_2F = 0x10 | OPC_SPECIAL2,
265 OPC_DMULT_G_2F = 0x11 | OPC_SPECIAL2,
266 OPC_MULTU_G_2F = 0x12 | OPC_SPECIAL2,
267 OPC_DMULTU_G_2F = 0x13 | OPC_SPECIAL2,
268 OPC_DIV_G_2F = 0x14 | OPC_SPECIAL2,
269 OPC_DDIV_G_2F = 0x15 | OPC_SPECIAL2,
270 OPC_DIVU_G_2F = 0x16 | OPC_SPECIAL2,
271 OPC_DDIVU_G_2F = 0x17 | OPC_SPECIAL2,
272 OPC_MOD_G_2F = 0x1c | OPC_SPECIAL2,
273 OPC_DMOD_G_2F = 0x1d | OPC_SPECIAL2,
274 OPC_MODU_G_2F = 0x1e | OPC_SPECIAL2,
275 OPC_DMODU_G_2F = 0x1f | OPC_SPECIAL2,
276 /* Misc */
277 OPC_CLZ = 0x20 | OPC_SPECIAL2,
278 OPC_CLO = 0x21 | OPC_SPECIAL2,
279 OPC_DCLZ = 0x24 | OPC_SPECIAL2,
280 OPC_DCLO = 0x25 | OPC_SPECIAL2,
281 /* Special */
282 OPC_SDBBP = 0x3F | OPC_SPECIAL2,
285 /* Special3 opcodes */
286 #define MASK_SPECIAL3(op) MASK_OP_MAJOR(op) | (op & 0x3F)
288 enum {
289 OPC_EXT = 0x00 | OPC_SPECIAL3,
290 OPC_DEXTM = 0x01 | OPC_SPECIAL3,
291 OPC_DEXTU = 0x02 | OPC_SPECIAL3,
292 OPC_DEXT = 0x03 | OPC_SPECIAL3,
293 OPC_INS = 0x04 | OPC_SPECIAL3,
294 OPC_DINSM = 0x05 | OPC_SPECIAL3,
295 OPC_DINSU = 0x06 | OPC_SPECIAL3,
296 OPC_DINS = 0x07 | OPC_SPECIAL3,
297 OPC_FORK = 0x08 | OPC_SPECIAL3,
298 OPC_YIELD = 0x09 | OPC_SPECIAL3,
299 OPC_BSHFL = 0x20 | OPC_SPECIAL3,
300 OPC_DBSHFL = 0x24 | OPC_SPECIAL3,
301 OPC_RDHWR = 0x3B | OPC_SPECIAL3,
303 /* Loongson 2E */
304 OPC_MULT_G_2E = 0x18 | OPC_SPECIAL3,
305 OPC_MULTU_G_2E = 0x19 | OPC_SPECIAL3,
306 OPC_DIV_G_2E = 0x1A | OPC_SPECIAL3,
307 OPC_DIVU_G_2E = 0x1B | OPC_SPECIAL3,
308 OPC_DMULT_G_2E = 0x1C | OPC_SPECIAL3,
309 OPC_DMULTU_G_2E = 0x1D | OPC_SPECIAL3,
310 OPC_DDIV_G_2E = 0x1E | OPC_SPECIAL3,
311 OPC_DDIVU_G_2E = 0x1F | OPC_SPECIAL3,
312 OPC_MOD_G_2E = 0x22 | OPC_SPECIAL3,
313 OPC_MODU_G_2E = 0x23 | OPC_SPECIAL3,
314 OPC_DMOD_G_2E = 0x26 | OPC_SPECIAL3,
315 OPC_DMODU_G_2E = 0x27 | OPC_SPECIAL3,
317 /* MIPS DSP Load */
318 OPC_LX_DSP = 0x0A | OPC_SPECIAL3,
319 /* MIPS DSP Arithmetic */
320 OPC_ADDU_QB_DSP = 0x10 | OPC_SPECIAL3,
321 OPC_ADDU_OB_DSP = 0x14 | OPC_SPECIAL3,
322 OPC_ABSQ_S_PH_DSP = 0x12 | OPC_SPECIAL3,
323 OPC_ABSQ_S_QH_DSP = 0x16 | OPC_SPECIAL3,
324 /* OPC_ADDUH_QB_DSP is same as OPC_MULT_G_2E. */
325 /* OPC_ADDUH_QB_DSP = 0x18 | OPC_SPECIAL3, */
326 OPC_CMPU_EQ_QB_DSP = 0x11 | OPC_SPECIAL3,
327 OPC_CMPU_EQ_OB_DSP = 0x15 | OPC_SPECIAL3,
328 /* MIPS DSP GPR-Based Shift Sub-class */
329 OPC_SHLL_QB_DSP = 0x13 | OPC_SPECIAL3,
330 OPC_SHLL_OB_DSP = 0x17 | OPC_SPECIAL3,
331 /* MIPS DSP Multiply Sub-class insns */
332 /* OPC_MUL_PH_DSP is same as OPC_ADDUH_QB_DSP. */
333 /* OPC_MUL_PH_DSP = 0x18 | OPC_SPECIAL3, */
334 OPC_DPA_W_PH_DSP = 0x30 | OPC_SPECIAL3,
335 OPC_DPAQ_W_QH_DSP = 0x34 | OPC_SPECIAL3,
336 /* DSP Bit/Manipulation Sub-class */
337 OPC_INSV_DSP = 0x0C | OPC_SPECIAL3,
338 OPC_DINSV_DSP = 0x0D | OPC_SPECIAL3,
339 /* MIPS DSP Append Sub-class */
340 OPC_APPEND_DSP = 0x31 | OPC_SPECIAL3,
341 OPC_DAPPEND_DSP = 0x35 | OPC_SPECIAL3,
342 /* MIPS DSP Accumulator and DSPControl Access Sub-class */
343 OPC_EXTR_W_DSP = 0x38 | OPC_SPECIAL3,
344 OPC_DEXTR_W_DSP = 0x3C | OPC_SPECIAL3,
347 /* BSHFL opcodes */
348 #define MASK_BSHFL(op) MASK_SPECIAL3(op) | (op & (0x1F << 6))
350 enum {
351 OPC_WSBH = (0x02 << 6) | OPC_BSHFL,
352 OPC_SEB = (0x10 << 6) | OPC_BSHFL,
353 OPC_SEH = (0x18 << 6) | OPC_BSHFL,
356 /* DBSHFL opcodes */
357 #define MASK_DBSHFL(op) MASK_SPECIAL3(op) | (op & (0x1F << 6))
359 enum {
360 OPC_DSBH = (0x02 << 6) | OPC_DBSHFL,
361 OPC_DSHD = (0x05 << 6) | OPC_DBSHFL,
364 /* MIPS DSP REGIMM opcodes */
365 enum {
366 OPC_BPOSGE32 = (0x1C << 16) | OPC_REGIMM,
367 OPC_BPOSGE64 = (0x1D << 16) | OPC_REGIMM,
370 #define MASK_LX(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
371 /* MIPS DSP Load */
372 enum {
373 OPC_LBUX = (0x06 << 6) | OPC_LX_DSP,
374 OPC_LHX = (0x04 << 6) | OPC_LX_DSP,
375 OPC_LWX = (0x00 << 6) | OPC_LX_DSP,
376 OPC_LDX = (0x08 << 6) | OPC_LX_DSP,
379 #define MASK_ADDU_QB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
380 enum {
381 /* MIPS DSP Arithmetic Sub-class */
382 OPC_ADDQ_PH = (0x0A << 6) | OPC_ADDU_QB_DSP,
383 OPC_ADDQ_S_PH = (0x0E << 6) | OPC_ADDU_QB_DSP,
384 OPC_ADDQ_S_W = (0x16 << 6) | OPC_ADDU_QB_DSP,
385 OPC_ADDU_QB = (0x00 << 6) | OPC_ADDU_QB_DSP,
386 OPC_ADDU_S_QB = (0x04 << 6) | OPC_ADDU_QB_DSP,
387 OPC_ADDU_PH = (0x08 << 6) | OPC_ADDU_QB_DSP,
388 OPC_ADDU_S_PH = (0x0C << 6) | OPC_ADDU_QB_DSP,
389 OPC_SUBQ_PH = (0x0B << 6) | OPC_ADDU_QB_DSP,
390 OPC_SUBQ_S_PH = (0x0F << 6) | OPC_ADDU_QB_DSP,
391 OPC_SUBQ_S_W = (0x17 << 6) | OPC_ADDU_QB_DSP,
392 OPC_SUBU_QB = (0x01 << 6) | OPC_ADDU_QB_DSP,
393 OPC_SUBU_S_QB = (0x05 << 6) | OPC_ADDU_QB_DSP,
394 OPC_SUBU_PH = (0x09 << 6) | OPC_ADDU_QB_DSP,
395 OPC_SUBU_S_PH = (0x0D << 6) | OPC_ADDU_QB_DSP,
396 OPC_ADDSC = (0x10 << 6) | OPC_ADDU_QB_DSP,
397 OPC_ADDWC = (0x11 << 6) | OPC_ADDU_QB_DSP,
398 OPC_MODSUB = (0x12 << 6) | OPC_ADDU_QB_DSP,
399 OPC_RADDU_W_QB = (0x14 << 6) | OPC_ADDU_QB_DSP,
400 /* MIPS DSP Multiply Sub-class insns */
401 OPC_MULEU_S_PH_QBL = (0x06 << 6) | OPC_ADDU_QB_DSP,
402 OPC_MULEU_S_PH_QBR = (0x07 << 6) | OPC_ADDU_QB_DSP,
403 OPC_MULQ_RS_PH = (0x1F << 6) | OPC_ADDU_QB_DSP,
404 OPC_MULEQ_S_W_PHL = (0x1C << 6) | OPC_ADDU_QB_DSP,
405 OPC_MULEQ_S_W_PHR = (0x1D << 6) | OPC_ADDU_QB_DSP,
406 OPC_MULQ_S_PH = (0x1E << 6) | OPC_ADDU_QB_DSP,
409 #define OPC_ADDUH_QB_DSP OPC_MULT_G_2E
410 #define MASK_ADDUH_QB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
411 enum {
412 /* MIPS DSP Arithmetic Sub-class */
413 OPC_ADDUH_QB = (0x00 << 6) | OPC_ADDUH_QB_DSP,
414 OPC_ADDUH_R_QB = (0x02 << 6) | OPC_ADDUH_QB_DSP,
415 OPC_ADDQH_PH = (0x08 << 6) | OPC_ADDUH_QB_DSP,
416 OPC_ADDQH_R_PH = (0x0A << 6) | OPC_ADDUH_QB_DSP,
417 OPC_ADDQH_W = (0x10 << 6) | OPC_ADDUH_QB_DSP,
418 OPC_ADDQH_R_W = (0x12 << 6) | OPC_ADDUH_QB_DSP,
419 OPC_SUBUH_QB = (0x01 << 6) | OPC_ADDUH_QB_DSP,
420 OPC_SUBUH_R_QB = (0x03 << 6) | OPC_ADDUH_QB_DSP,
421 OPC_SUBQH_PH = (0x09 << 6) | OPC_ADDUH_QB_DSP,
422 OPC_SUBQH_R_PH = (0x0B << 6) | OPC_ADDUH_QB_DSP,
423 OPC_SUBQH_W = (0x11 << 6) | OPC_ADDUH_QB_DSP,
424 OPC_SUBQH_R_W = (0x13 << 6) | OPC_ADDUH_QB_DSP,
425 /* MIPS DSP Multiply Sub-class insns */
426 OPC_MUL_PH = (0x0C << 6) | OPC_ADDUH_QB_DSP,
427 OPC_MUL_S_PH = (0x0E << 6) | OPC_ADDUH_QB_DSP,
428 OPC_MULQ_S_W = (0x16 << 6) | OPC_ADDUH_QB_DSP,
429 OPC_MULQ_RS_W = (0x17 << 6) | OPC_ADDUH_QB_DSP,
432 #define MASK_ABSQ_S_PH(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
433 enum {
434 /* MIPS DSP Arithmetic Sub-class */
435 OPC_ABSQ_S_QB = (0x01 << 6) | OPC_ABSQ_S_PH_DSP,
436 OPC_ABSQ_S_PH = (0x09 << 6) | OPC_ABSQ_S_PH_DSP,
437 OPC_ABSQ_S_W = (0x11 << 6) | OPC_ABSQ_S_PH_DSP,
438 OPC_PRECEQ_W_PHL = (0x0C << 6) | OPC_ABSQ_S_PH_DSP,
439 OPC_PRECEQ_W_PHR = (0x0D << 6) | OPC_ABSQ_S_PH_DSP,
440 OPC_PRECEQU_PH_QBL = (0x04 << 6) | OPC_ABSQ_S_PH_DSP,
441 OPC_PRECEQU_PH_QBR = (0x05 << 6) | OPC_ABSQ_S_PH_DSP,
442 OPC_PRECEQU_PH_QBLA = (0x06 << 6) | OPC_ABSQ_S_PH_DSP,
443 OPC_PRECEQU_PH_QBRA = (0x07 << 6) | OPC_ABSQ_S_PH_DSP,
444 OPC_PRECEU_PH_QBL = (0x1C << 6) | OPC_ABSQ_S_PH_DSP,
445 OPC_PRECEU_PH_QBR = (0x1D << 6) | OPC_ABSQ_S_PH_DSP,
446 OPC_PRECEU_PH_QBLA = (0x1E << 6) | OPC_ABSQ_S_PH_DSP,
447 OPC_PRECEU_PH_QBRA = (0x1F << 6) | OPC_ABSQ_S_PH_DSP,
448 /* DSP Bit/Manipulation Sub-class */
449 OPC_BITREV = (0x1B << 6) | OPC_ABSQ_S_PH_DSP,
450 OPC_REPL_QB = (0x02 << 6) | OPC_ABSQ_S_PH_DSP,
451 OPC_REPLV_QB = (0x03 << 6) | OPC_ABSQ_S_PH_DSP,
452 OPC_REPL_PH = (0x0A << 6) | OPC_ABSQ_S_PH_DSP,
453 OPC_REPLV_PH = (0x0B << 6) | OPC_ABSQ_S_PH_DSP,
456 #define MASK_CMPU_EQ_QB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
457 enum {
458 /* MIPS DSP Arithmetic Sub-class */
459 OPC_PRECR_QB_PH = (0x0D << 6) | OPC_CMPU_EQ_QB_DSP,
460 OPC_PRECRQ_QB_PH = (0x0C << 6) | OPC_CMPU_EQ_QB_DSP,
461 OPC_PRECR_SRA_PH_W = (0x1E << 6) | OPC_CMPU_EQ_QB_DSP,
462 OPC_PRECR_SRA_R_PH_W = (0x1F << 6) | OPC_CMPU_EQ_QB_DSP,
463 OPC_PRECRQ_PH_W = (0x14 << 6) | OPC_CMPU_EQ_QB_DSP,
464 OPC_PRECRQ_RS_PH_W = (0x15 << 6) | OPC_CMPU_EQ_QB_DSP,
465 OPC_PRECRQU_S_QB_PH = (0x0F << 6) | OPC_CMPU_EQ_QB_DSP,
466 /* DSP Compare-Pick Sub-class */
467 OPC_CMPU_EQ_QB = (0x00 << 6) | OPC_CMPU_EQ_QB_DSP,
468 OPC_CMPU_LT_QB = (0x01 << 6) | OPC_CMPU_EQ_QB_DSP,
469 OPC_CMPU_LE_QB = (0x02 << 6) | OPC_CMPU_EQ_QB_DSP,
470 OPC_CMPGU_EQ_QB = (0x04 << 6) | OPC_CMPU_EQ_QB_DSP,
471 OPC_CMPGU_LT_QB = (0x05 << 6) | OPC_CMPU_EQ_QB_DSP,
472 OPC_CMPGU_LE_QB = (0x06 << 6) | OPC_CMPU_EQ_QB_DSP,
473 OPC_CMPGDU_EQ_QB = (0x18 << 6) | OPC_CMPU_EQ_QB_DSP,
474 OPC_CMPGDU_LT_QB = (0x19 << 6) | OPC_CMPU_EQ_QB_DSP,
475 OPC_CMPGDU_LE_QB = (0x1A << 6) | OPC_CMPU_EQ_QB_DSP,
476 OPC_CMP_EQ_PH = (0x08 << 6) | OPC_CMPU_EQ_QB_DSP,
477 OPC_CMP_LT_PH = (0x09 << 6) | OPC_CMPU_EQ_QB_DSP,
478 OPC_CMP_LE_PH = (0x0A << 6) | OPC_CMPU_EQ_QB_DSP,
479 OPC_PICK_QB = (0x03 << 6) | OPC_CMPU_EQ_QB_DSP,
480 OPC_PICK_PH = (0x0B << 6) | OPC_CMPU_EQ_QB_DSP,
481 OPC_PACKRL_PH = (0x0E << 6) | OPC_CMPU_EQ_QB_DSP,
484 #define MASK_SHLL_QB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
485 enum {
486 /* MIPS DSP GPR-Based Shift Sub-class */
487 OPC_SHLL_QB = (0x00 << 6) | OPC_SHLL_QB_DSP,
488 OPC_SHLLV_QB = (0x02 << 6) | OPC_SHLL_QB_DSP,
489 OPC_SHLL_PH = (0x08 << 6) | OPC_SHLL_QB_DSP,
490 OPC_SHLLV_PH = (0x0A << 6) | OPC_SHLL_QB_DSP,
491 OPC_SHLL_S_PH = (0x0C << 6) | OPC_SHLL_QB_DSP,
492 OPC_SHLLV_S_PH = (0x0E << 6) | OPC_SHLL_QB_DSP,
493 OPC_SHLL_S_W = (0x14 << 6) | OPC_SHLL_QB_DSP,
494 OPC_SHLLV_S_W = (0x16 << 6) | OPC_SHLL_QB_DSP,
495 OPC_SHRL_QB = (0x01 << 6) | OPC_SHLL_QB_DSP,
496 OPC_SHRLV_QB = (0x03 << 6) | OPC_SHLL_QB_DSP,
497 OPC_SHRL_PH = (0x19 << 6) | OPC_SHLL_QB_DSP,
498 OPC_SHRLV_PH = (0x1B << 6) | OPC_SHLL_QB_DSP,
499 OPC_SHRA_QB = (0x04 << 6) | OPC_SHLL_QB_DSP,
500 OPC_SHRA_R_QB = (0x05 << 6) | OPC_SHLL_QB_DSP,
501 OPC_SHRAV_QB = (0x06 << 6) | OPC_SHLL_QB_DSP,
502 OPC_SHRAV_R_QB = (0x07 << 6) | OPC_SHLL_QB_DSP,
503 OPC_SHRA_PH = (0x09 << 6) | OPC_SHLL_QB_DSP,
504 OPC_SHRAV_PH = (0x0B << 6) | OPC_SHLL_QB_DSP,
505 OPC_SHRA_R_PH = (0x0D << 6) | OPC_SHLL_QB_DSP,
506 OPC_SHRAV_R_PH = (0x0F << 6) | OPC_SHLL_QB_DSP,
507 OPC_SHRA_R_W = (0x15 << 6) | OPC_SHLL_QB_DSP,
508 OPC_SHRAV_R_W = (0x17 << 6) | OPC_SHLL_QB_DSP,
511 #define MASK_DPA_W_PH(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
512 enum {
513 /* MIPS DSP Multiply Sub-class insns */
514 OPC_DPAU_H_QBL = (0x03 << 6) | OPC_DPA_W_PH_DSP,
515 OPC_DPAU_H_QBR = (0x07 << 6) | OPC_DPA_W_PH_DSP,
516 OPC_DPSU_H_QBL = (0x0B << 6) | OPC_DPA_W_PH_DSP,
517 OPC_DPSU_H_QBR = (0x0F << 6) | OPC_DPA_W_PH_DSP,
518 OPC_DPA_W_PH = (0x00 << 6) | OPC_DPA_W_PH_DSP,
519 OPC_DPAX_W_PH = (0x08 << 6) | OPC_DPA_W_PH_DSP,
520 OPC_DPAQ_S_W_PH = (0x04 << 6) | OPC_DPA_W_PH_DSP,
521 OPC_DPAQX_S_W_PH = (0x18 << 6) | OPC_DPA_W_PH_DSP,
522 OPC_DPAQX_SA_W_PH = (0x1A << 6) | OPC_DPA_W_PH_DSP,
523 OPC_DPS_W_PH = (0x01 << 6) | OPC_DPA_W_PH_DSP,
524 OPC_DPSX_W_PH = (0x09 << 6) | OPC_DPA_W_PH_DSP,
525 OPC_DPSQ_S_W_PH = (0x05 << 6) | OPC_DPA_W_PH_DSP,
526 OPC_DPSQX_S_W_PH = (0x19 << 6) | OPC_DPA_W_PH_DSP,
527 OPC_DPSQX_SA_W_PH = (0x1B << 6) | OPC_DPA_W_PH_DSP,
528 OPC_MULSAQ_S_W_PH = (0x06 << 6) | OPC_DPA_W_PH_DSP,
529 OPC_DPAQ_SA_L_W = (0x0C << 6) | OPC_DPA_W_PH_DSP,
530 OPC_DPSQ_SA_L_W = (0x0D << 6) | OPC_DPA_W_PH_DSP,
531 OPC_MAQ_S_W_PHL = (0x14 << 6) | OPC_DPA_W_PH_DSP,
532 OPC_MAQ_S_W_PHR = (0x16 << 6) | OPC_DPA_W_PH_DSP,
533 OPC_MAQ_SA_W_PHL = (0x10 << 6) | OPC_DPA_W_PH_DSP,
534 OPC_MAQ_SA_W_PHR = (0x12 << 6) | OPC_DPA_W_PH_DSP,
535 OPC_MULSA_W_PH = (0x02 << 6) | OPC_DPA_W_PH_DSP,
538 #define MASK_INSV(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
539 enum {
540 /* DSP Bit/Manipulation Sub-class */
541 OPC_INSV = (0x00 << 6) | OPC_INSV_DSP,
544 #define MASK_APPEND(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
545 enum {
546 /* MIPS DSP Append Sub-class */
547 OPC_APPEND = (0x00 << 6) | OPC_APPEND_DSP,
548 OPC_PREPEND = (0x01 << 6) | OPC_APPEND_DSP,
549 OPC_BALIGN = (0x10 << 6) | OPC_APPEND_DSP,
552 #define MASK_EXTR_W(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
553 enum {
554 /* MIPS DSP Accumulator and DSPControl Access Sub-class */
555 OPC_EXTR_W = (0x00 << 6) | OPC_EXTR_W_DSP,
556 OPC_EXTR_R_W = (0x04 << 6) | OPC_EXTR_W_DSP,
557 OPC_EXTR_RS_W = (0x06 << 6) | OPC_EXTR_W_DSP,
558 OPC_EXTR_S_H = (0x0E << 6) | OPC_EXTR_W_DSP,
559 OPC_EXTRV_S_H = (0x0F << 6) | OPC_EXTR_W_DSP,
560 OPC_EXTRV_W = (0x01 << 6) | OPC_EXTR_W_DSP,
561 OPC_EXTRV_R_W = (0x05 << 6) | OPC_EXTR_W_DSP,
562 OPC_EXTRV_RS_W = (0x07 << 6) | OPC_EXTR_W_DSP,
563 OPC_EXTP = (0x02 << 6) | OPC_EXTR_W_DSP,
564 OPC_EXTPV = (0x03 << 6) | OPC_EXTR_W_DSP,
565 OPC_EXTPDP = (0x0A << 6) | OPC_EXTR_W_DSP,
566 OPC_EXTPDPV = (0x0B << 6) | OPC_EXTR_W_DSP,
567 OPC_SHILO = (0x1A << 6) | OPC_EXTR_W_DSP,
568 OPC_SHILOV = (0x1B << 6) | OPC_EXTR_W_DSP,
569 OPC_MTHLIP = (0x1F << 6) | OPC_EXTR_W_DSP,
570 OPC_WRDSP = (0x13 << 6) | OPC_EXTR_W_DSP,
571 OPC_RDDSP = (0x12 << 6) | OPC_EXTR_W_DSP,
574 #define MASK_ABSQ_S_QH(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
575 enum {
576 /* MIPS DSP Arithmetic Sub-class */
577 OPC_PRECEQ_L_PWL = (0x14 << 6) | OPC_ABSQ_S_QH_DSP,
578 OPC_PRECEQ_L_PWR = (0x15 << 6) | OPC_ABSQ_S_QH_DSP,
579 OPC_PRECEQ_PW_QHL = (0x0C << 6) | OPC_ABSQ_S_QH_DSP,
580 OPC_PRECEQ_PW_QHR = (0x0D << 6) | OPC_ABSQ_S_QH_DSP,
581 OPC_PRECEQ_PW_QHLA = (0x0E << 6) | OPC_ABSQ_S_QH_DSP,
582 OPC_PRECEQ_PW_QHRA = (0x0F << 6) | OPC_ABSQ_S_QH_DSP,
583 OPC_PRECEQU_QH_OBL = (0x04 << 6) | OPC_ABSQ_S_QH_DSP,
584 OPC_PRECEQU_QH_OBR = (0x05 << 6) | OPC_ABSQ_S_QH_DSP,
585 OPC_PRECEQU_QH_OBLA = (0x06 << 6) | OPC_ABSQ_S_QH_DSP,
586 OPC_PRECEQU_QH_OBRA = (0x07 << 6) | OPC_ABSQ_S_QH_DSP,
587 OPC_PRECEU_QH_OBL = (0x1C << 6) | OPC_ABSQ_S_QH_DSP,
588 OPC_PRECEU_QH_OBR = (0x1D << 6) | OPC_ABSQ_S_QH_DSP,
589 OPC_PRECEU_QH_OBLA = (0x1E << 6) | OPC_ABSQ_S_QH_DSP,
590 OPC_PRECEU_QH_OBRA = (0x1F << 6) | OPC_ABSQ_S_QH_DSP,
591 OPC_ABSQ_S_OB = (0x01 << 6) | OPC_ABSQ_S_QH_DSP,
592 OPC_ABSQ_S_PW = (0x11 << 6) | OPC_ABSQ_S_QH_DSP,
593 OPC_ABSQ_S_QH = (0x09 << 6) | OPC_ABSQ_S_QH_DSP,
594 /* DSP Bit/Manipulation Sub-class */
595 OPC_REPL_OB = (0x02 << 6) | OPC_ABSQ_S_QH_DSP,
596 OPC_REPL_PW = (0x12 << 6) | OPC_ABSQ_S_QH_DSP,
597 OPC_REPL_QH = (0x0A << 6) | OPC_ABSQ_S_QH_DSP,
598 OPC_REPLV_OB = (0x03 << 6) | OPC_ABSQ_S_QH_DSP,
599 OPC_REPLV_PW = (0x13 << 6) | OPC_ABSQ_S_QH_DSP,
600 OPC_REPLV_QH = (0x0B << 6) | OPC_ABSQ_S_QH_DSP,
603 #define MASK_ADDU_OB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
604 enum {
605 /* MIPS DSP Multiply Sub-class insns */
606 OPC_MULEQ_S_PW_QHL = (0x1C << 6) | OPC_ADDU_OB_DSP,
607 OPC_MULEQ_S_PW_QHR = (0x1D << 6) | OPC_ADDU_OB_DSP,
608 OPC_MULEU_S_QH_OBL = (0x06 << 6) | OPC_ADDU_OB_DSP,
609 OPC_MULEU_S_QH_OBR = (0x07 << 6) | OPC_ADDU_OB_DSP,
610 OPC_MULQ_RS_QH = (0x1F << 6) | OPC_ADDU_OB_DSP,
611 /* MIPS DSP Arithmetic Sub-class */
612 OPC_RADDU_L_OB = (0x14 << 6) | OPC_ADDU_OB_DSP,
613 OPC_SUBQ_PW = (0x13 << 6) | OPC_ADDU_OB_DSP,
614 OPC_SUBQ_S_PW = (0x17 << 6) | OPC_ADDU_OB_DSP,
615 OPC_SUBQ_QH = (0x0B << 6) | OPC_ADDU_OB_DSP,
616 OPC_SUBQ_S_QH = (0x0F << 6) | OPC_ADDU_OB_DSP,
617 OPC_SUBU_OB = (0x01 << 6) | OPC_ADDU_OB_DSP,
618 OPC_SUBU_S_OB = (0x05 << 6) | OPC_ADDU_OB_DSP,
619 OPC_SUBU_QH = (0x09 << 6) | OPC_ADDU_OB_DSP,
620 OPC_SUBU_S_QH = (0x0D << 6) | OPC_ADDU_OB_DSP,
621 OPC_SUBUH_OB = (0x19 << 6) | OPC_ADDU_OB_DSP,
622 OPC_SUBUH_R_OB = (0x1B << 6) | OPC_ADDU_OB_DSP,
623 OPC_ADDQ_PW = (0x12 << 6) | OPC_ADDU_OB_DSP,
624 OPC_ADDQ_S_PW = (0x16 << 6) | OPC_ADDU_OB_DSP,
625 OPC_ADDQ_QH = (0x0A << 6) | OPC_ADDU_OB_DSP,
626 OPC_ADDQ_S_QH = (0x0E << 6) | OPC_ADDU_OB_DSP,
627 OPC_ADDU_OB = (0x00 << 6) | OPC_ADDU_OB_DSP,
628 OPC_ADDU_S_OB = (0x04 << 6) | OPC_ADDU_OB_DSP,
629 OPC_ADDU_QH = (0x08 << 6) | OPC_ADDU_OB_DSP,
630 OPC_ADDU_S_QH = (0x0C << 6) | OPC_ADDU_OB_DSP,
631 OPC_ADDUH_OB = (0x18 << 6) | OPC_ADDU_OB_DSP,
632 OPC_ADDUH_R_OB = (0x1A << 6) | OPC_ADDU_OB_DSP,
635 #define MASK_CMPU_EQ_OB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
636 enum {
637 /* DSP Compare-Pick Sub-class */
638 OPC_CMP_EQ_PW = (0x10 << 6) | OPC_CMPU_EQ_OB_DSP,
639 OPC_CMP_LT_PW = (0x11 << 6) | OPC_CMPU_EQ_OB_DSP,
640 OPC_CMP_LE_PW = (0x12 << 6) | OPC_CMPU_EQ_OB_DSP,
641 OPC_CMP_EQ_QH = (0x08 << 6) | OPC_CMPU_EQ_OB_DSP,
642 OPC_CMP_LT_QH = (0x09 << 6) | OPC_CMPU_EQ_OB_DSP,
643 OPC_CMP_LE_QH = (0x0A << 6) | OPC_CMPU_EQ_OB_DSP,
644 OPC_CMPGDU_EQ_OB = (0x18 << 6) | OPC_CMPU_EQ_OB_DSP,
645 OPC_CMPGDU_LT_OB = (0x19 << 6) | OPC_CMPU_EQ_OB_DSP,
646 OPC_CMPGDU_LE_OB = (0x1A << 6) | OPC_CMPU_EQ_OB_DSP,
647 OPC_CMPGU_EQ_OB = (0x04 << 6) | OPC_CMPU_EQ_OB_DSP,
648 OPC_CMPGU_LT_OB = (0x05 << 6) | OPC_CMPU_EQ_OB_DSP,
649 OPC_CMPGU_LE_OB = (0x06 << 6) | OPC_CMPU_EQ_OB_DSP,
650 OPC_CMPU_EQ_OB = (0x00 << 6) | OPC_CMPU_EQ_OB_DSP,
651 OPC_CMPU_LT_OB = (0x01 << 6) | OPC_CMPU_EQ_OB_DSP,
652 OPC_CMPU_LE_OB = (0x02 << 6) | OPC_CMPU_EQ_OB_DSP,
653 OPC_PACKRL_PW = (0x0E << 6) | OPC_CMPU_EQ_OB_DSP,
654 OPC_PICK_OB = (0x03 << 6) | OPC_CMPU_EQ_OB_DSP,
655 OPC_PICK_PW = (0x13 << 6) | OPC_CMPU_EQ_OB_DSP,
656 OPC_PICK_QH = (0x0B << 6) | OPC_CMPU_EQ_OB_DSP,
657 /* MIPS DSP Arithmetic Sub-class */
658 OPC_PRECR_OB_QH = (0x0D << 6) | OPC_CMPU_EQ_OB_DSP,
659 OPC_PRECR_SRA_QH_PW = (0x1E << 6) | OPC_CMPU_EQ_OB_DSP,
660 OPC_PRECR_SRA_R_QH_PW = (0x1F << 6) | OPC_CMPU_EQ_OB_DSP,
661 OPC_PRECRQ_OB_QH = (0x0C << 6) | OPC_CMPU_EQ_OB_DSP,
662 OPC_PRECRQ_PW_L = (0x1C << 6) | OPC_CMPU_EQ_OB_DSP,
663 OPC_PRECRQ_QH_PW = (0x14 << 6) | OPC_CMPU_EQ_OB_DSP,
664 OPC_PRECRQ_RS_QH_PW = (0x15 << 6) | OPC_CMPU_EQ_OB_DSP,
665 OPC_PRECRQU_S_OB_QH = (0x0F << 6) | OPC_CMPU_EQ_OB_DSP,
668 #define MASK_DAPPEND(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
669 enum {
670 /* DSP Append Sub-class */
671 OPC_DAPPEND = (0x00 << 6) | OPC_DAPPEND_DSP,
672 OPC_PREPENDD = (0x03 << 6) | OPC_DAPPEND_DSP,
673 OPC_PREPENDW = (0x01 << 6) | OPC_DAPPEND_DSP,
674 OPC_DBALIGN = (0x10 << 6) | OPC_DAPPEND_DSP,
677 #define MASK_DEXTR_W(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
678 enum {
679 /* MIPS DSP Accumulator and DSPControl Access Sub-class */
680 OPC_DMTHLIP = (0x1F << 6) | OPC_DEXTR_W_DSP,
681 OPC_DSHILO = (0x1A << 6) | OPC_DEXTR_W_DSP,
682 OPC_DEXTP = (0x02 << 6) | OPC_DEXTR_W_DSP,
683 OPC_DEXTPDP = (0x0A << 6) | OPC_DEXTR_W_DSP,
684 OPC_DEXTPDPV = (0x0B << 6) | OPC_DEXTR_W_DSP,
685 OPC_DEXTPV = (0x03 << 6) | OPC_DEXTR_W_DSP,
686 OPC_DEXTR_L = (0x10 << 6) | OPC_DEXTR_W_DSP,
687 OPC_DEXTR_R_L = (0x14 << 6) | OPC_DEXTR_W_DSP,
688 OPC_DEXTR_RS_L = (0x16 << 6) | OPC_DEXTR_W_DSP,
689 OPC_DEXTR_W = (0x00 << 6) | OPC_DEXTR_W_DSP,
690 OPC_DEXTR_R_W = (0x04 << 6) | OPC_DEXTR_W_DSP,
691 OPC_DEXTR_RS_W = (0x06 << 6) | OPC_DEXTR_W_DSP,
692 OPC_DEXTR_S_H = (0x0E << 6) | OPC_DEXTR_W_DSP,
693 OPC_DEXTRV_L = (0x11 << 6) | OPC_DEXTR_W_DSP,
694 OPC_DEXTRV_R_L = (0x15 << 6) | OPC_DEXTR_W_DSP,
695 OPC_DEXTRV_RS_L = (0x17 << 6) | OPC_DEXTR_W_DSP,
696 OPC_DEXTRV_S_H = (0x0F << 6) | OPC_DEXTR_W_DSP,
697 OPC_DEXTRV_W = (0x01 << 6) | OPC_DEXTR_W_DSP,
698 OPC_DEXTRV_R_W = (0x05 << 6) | OPC_DEXTR_W_DSP,
699 OPC_DEXTRV_RS_W = (0x07 << 6) | OPC_DEXTR_W_DSP,
700 OPC_DSHILOV = (0x1B << 6) | OPC_DEXTR_W_DSP,
703 #define MASK_DINSV(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
704 enum {
705 /* DSP Bit/Manipulation Sub-class */
706 OPC_DINSV = (0x00 << 6) | OPC_DINSV_DSP,
709 #define MASK_DPAQ_W_QH(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
710 enum {
711 /* MIPS DSP Multiply Sub-class insns */
712 OPC_DMADD = (0x19 << 6) | OPC_DPAQ_W_QH_DSP,
713 OPC_DMADDU = (0x1D << 6) | OPC_DPAQ_W_QH_DSP,
714 OPC_DMSUB = (0x1B << 6) | OPC_DPAQ_W_QH_DSP,
715 OPC_DMSUBU = (0x1F << 6) | OPC_DPAQ_W_QH_DSP,
716 OPC_DPA_W_QH = (0x00 << 6) | OPC_DPAQ_W_QH_DSP,
717 OPC_DPAQ_S_W_QH = (0x04 << 6) | OPC_DPAQ_W_QH_DSP,
718 OPC_DPAQ_SA_L_PW = (0x0C << 6) | OPC_DPAQ_W_QH_DSP,
719 OPC_DPAU_H_OBL = (0x03 << 6) | OPC_DPAQ_W_QH_DSP,
720 OPC_DPAU_H_OBR = (0x07 << 6) | OPC_DPAQ_W_QH_DSP,
721 OPC_DPS_W_QH = (0x01 << 6) | OPC_DPAQ_W_QH_DSP,
722 OPC_DPSQ_S_W_QH = (0x05 << 6) | OPC_DPAQ_W_QH_DSP,
723 OPC_DPSQ_SA_L_PW = (0x0D << 6) | OPC_DPAQ_W_QH_DSP,
724 OPC_DPSU_H_OBL = (0x0B << 6) | OPC_DPAQ_W_QH_DSP,
725 OPC_DPSU_H_OBR = (0x0F << 6) | OPC_DPAQ_W_QH_DSP,
726 OPC_MAQ_S_L_PWL = (0x1C << 6) | OPC_DPAQ_W_QH_DSP,
727 OPC_MAQ_S_L_PWR = (0x1E << 6) | OPC_DPAQ_W_QH_DSP,
728 OPC_MAQ_S_W_QHLL = (0x14 << 6) | OPC_DPAQ_W_QH_DSP,
729 OPC_MAQ_SA_W_QHLL = (0x10 << 6) | OPC_DPAQ_W_QH_DSP,
730 OPC_MAQ_S_W_QHLR = (0x15 << 6) | OPC_DPAQ_W_QH_DSP,
731 OPC_MAQ_SA_W_QHLR = (0x11 << 6) | OPC_DPAQ_W_QH_DSP,
732 OPC_MAQ_S_W_QHRL = (0x16 << 6) | OPC_DPAQ_W_QH_DSP,
733 OPC_MAQ_SA_W_QHRL = (0x12 << 6) | OPC_DPAQ_W_QH_DSP,
734 OPC_MAQ_S_W_QHRR = (0x17 << 6) | OPC_DPAQ_W_QH_DSP,
735 OPC_MAQ_SA_W_QHRR = (0x13 << 6) | OPC_DPAQ_W_QH_DSP,
736 OPC_MULSAQ_S_L_PW = (0x0E << 6) | OPC_DPAQ_W_QH_DSP,
737 OPC_MULSAQ_S_W_QH = (0x06 << 6) | OPC_DPAQ_W_QH_DSP,
740 #define MASK_SHLL_OB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
741 enum {
742 /* MIPS DSP GPR-Based Shift Sub-class */
743 OPC_SHLL_PW = (0x10 << 6) | OPC_SHLL_OB_DSP,
744 OPC_SHLL_S_PW = (0x14 << 6) | OPC_SHLL_OB_DSP,
745 OPC_SHLLV_OB = (0x02 << 6) | OPC_SHLL_OB_DSP,
746 OPC_SHLLV_PW = (0x12 << 6) | OPC_SHLL_OB_DSP,
747 OPC_SHLLV_S_PW = (0x16 << 6) | OPC_SHLL_OB_DSP,
748 OPC_SHLLV_QH = (0x0A << 6) | OPC_SHLL_OB_DSP,
749 OPC_SHLLV_S_QH = (0x0E << 6) | OPC_SHLL_OB_DSP,
750 OPC_SHRA_PW = (0x11 << 6) | OPC_SHLL_OB_DSP,
751 OPC_SHRA_R_PW = (0x15 << 6) | OPC_SHLL_OB_DSP,
752 OPC_SHRAV_OB = (0x06 << 6) | OPC_SHLL_OB_DSP,
753 OPC_SHRAV_R_OB = (0x07 << 6) | OPC_SHLL_OB_DSP,
754 OPC_SHRAV_PW = (0x13 << 6) | OPC_SHLL_OB_DSP,
755 OPC_SHRAV_R_PW = (0x17 << 6) | OPC_SHLL_OB_DSP,
756 OPC_SHRAV_QH = (0x0B << 6) | OPC_SHLL_OB_DSP,
757 OPC_SHRAV_R_QH = (0x0F << 6) | OPC_SHLL_OB_DSP,
758 OPC_SHRLV_OB = (0x03 << 6) | OPC_SHLL_OB_DSP,
759 OPC_SHRLV_QH = (0x1B << 6) | OPC_SHLL_OB_DSP,
760 OPC_SHLL_OB = (0x00 << 6) | OPC_SHLL_OB_DSP,
761 OPC_SHLL_QH = (0x08 << 6) | OPC_SHLL_OB_DSP,
762 OPC_SHLL_S_QH = (0x0C << 6) | OPC_SHLL_OB_DSP,
763 OPC_SHRA_OB = (0x04 << 6) | OPC_SHLL_OB_DSP,
764 OPC_SHRA_R_OB = (0x05 << 6) | OPC_SHLL_OB_DSP,
765 OPC_SHRA_QH = (0x09 << 6) | OPC_SHLL_OB_DSP,
766 OPC_SHRA_R_QH = (0x0D << 6) | OPC_SHLL_OB_DSP,
767 OPC_SHRL_OB = (0x01 << 6) | OPC_SHLL_OB_DSP,
768 OPC_SHRL_QH = (0x19 << 6) | OPC_SHLL_OB_DSP,
771 /* Coprocessor 0 (rs field) */
772 #define MASK_CP0(op) MASK_OP_MAJOR(op) | (op & (0x1F << 21))
774 enum {
775 OPC_MFC0 = (0x00 << 21) | OPC_CP0,
776 OPC_DMFC0 = (0x01 << 21) | OPC_CP0,
777 OPC_MTC0 = (0x04 << 21) | OPC_CP0,
778 OPC_DMTC0 = (0x05 << 21) | OPC_CP0,
779 OPC_MFTR = (0x08 << 21) | OPC_CP0,
780 OPC_RDPGPR = (0x0A << 21) | OPC_CP0,
781 OPC_MFMC0 = (0x0B << 21) | OPC_CP0,
782 OPC_MTTR = (0x0C << 21) | OPC_CP0,
783 OPC_WRPGPR = (0x0E << 21) | OPC_CP0,
784 OPC_C0 = (0x10 << 21) | OPC_CP0,
785 OPC_C0_FIRST = (0x10 << 21) | OPC_CP0,
786 OPC_C0_LAST = (0x1F << 21) | OPC_CP0,
789 /* MFMC0 opcodes */
790 #define MASK_MFMC0(op) MASK_CP0(op) | (op & 0xFFFF)
792 enum {
793 OPC_DMT = 0x01 | (0 << 5) | (0x0F << 6) | (0x01 << 11) | OPC_MFMC0,
794 OPC_EMT = 0x01 | (1 << 5) | (0x0F << 6) | (0x01 << 11) | OPC_MFMC0,
795 OPC_DVPE = 0x01 | (0 << 5) | OPC_MFMC0,
796 OPC_EVPE = 0x01 | (1 << 5) | OPC_MFMC0,
797 OPC_DI = (0 << 5) | (0x0C << 11) | OPC_MFMC0,
798 OPC_EI = (1 << 5) | (0x0C << 11) | OPC_MFMC0,
801 /* Coprocessor 0 (with rs == C0) */
802 #define MASK_C0(op) MASK_CP0(op) | (op & 0x3F)
804 enum {
805 OPC_TLBR = 0x01 | OPC_C0,
806 OPC_TLBWI = 0x02 | OPC_C0,
807 OPC_TLBWR = 0x06 | OPC_C0,
808 OPC_TLBP = 0x08 | OPC_C0,
809 OPC_RFE = 0x10 | OPC_C0,
810 OPC_ERET = 0x18 | OPC_C0,
811 OPC_DERET = 0x1F | OPC_C0,
812 OPC_WAIT = 0x20 | OPC_C0,
815 /* Coprocessor 1 (rs field) */
816 #define MASK_CP1(op) MASK_OP_MAJOR(op) | (op & (0x1F << 21))
818 /* Values for the fmt field in FP instructions */
819 enum {
820 /* 0 - 15 are reserved */
821 FMT_S = 16, /* single fp */
822 FMT_D = 17, /* double fp */
823 FMT_E = 18, /* extended fp */
824 FMT_Q = 19, /* quad fp */
825 FMT_W = 20, /* 32-bit fixed */
826 FMT_L = 21, /* 64-bit fixed */
827 FMT_PS = 22, /* paired single fp */
828 /* 23 - 31 are reserved */
831 enum {
832 OPC_MFC1 = (0x00 << 21) | OPC_CP1,
833 OPC_DMFC1 = (0x01 << 21) | OPC_CP1,
834 OPC_CFC1 = (0x02 << 21) | OPC_CP1,
835 OPC_MFHC1 = (0x03 << 21) | OPC_CP1,
836 OPC_MTC1 = (0x04 << 21) | OPC_CP1,
837 OPC_DMTC1 = (0x05 << 21) | OPC_CP1,
838 OPC_CTC1 = (0x06 << 21) | OPC_CP1,
839 OPC_MTHC1 = (0x07 << 21) | OPC_CP1,
840 OPC_BC1 = (0x08 << 21) | OPC_CP1, /* bc */
841 OPC_BC1ANY2 = (0x09 << 21) | OPC_CP1,
842 OPC_BC1ANY4 = (0x0A << 21) | OPC_CP1,
843 OPC_S_FMT = (FMT_S << 21) | OPC_CP1,
844 OPC_D_FMT = (FMT_D << 21) | OPC_CP1,
845 OPC_E_FMT = (FMT_E << 21) | OPC_CP1,
846 OPC_Q_FMT = (FMT_Q << 21) | OPC_CP1,
847 OPC_W_FMT = (FMT_W << 21) | OPC_CP1,
848 OPC_L_FMT = (FMT_L << 21) | OPC_CP1,
849 OPC_PS_FMT = (FMT_PS << 21) | OPC_CP1,
852 #define MASK_CP1_FUNC(op) MASK_CP1(op) | (op & 0x3F)
853 #define MASK_BC1(op) MASK_CP1(op) | (op & (0x3 << 16))
855 enum {
856 OPC_BC1F = (0x00 << 16) | OPC_BC1,
857 OPC_BC1T = (0x01 << 16) | OPC_BC1,
858 OPC_BC1FL = (0x02 << 16) | OPC_BC1,
859 OPC_BC1TL = (0x03 << 16) | OPC_BC1,
862 enum {
863 OPC_BC1FANY2 = (0x00 << 16) | OPC_BC1ANY2,
864 OPC_BC1TANY2 = (0x01 << 16) | OPC_BC1ANY2,
867 enum {
868 OPC_BC1FANY4 = (0x00 << 16) | OPC_BC1ANY4,
869 OPC_BC1TANY4 = (0x01 << 16) | OPC_BC1ANY4,
872 #define MASK_CP2(op) MASK_OP_MAJOR(op) | (op & (0x1F << 21))
874 enum {
875 OPC_MFC2 = (0x00 << 21) | OPC_CP2,
876 OPC_DMFC2 = (0x01 << 21) | OPC_CP2,
877 OPC_CFC2 = (0x02 << 21) | OPC_CP2,
878 OPC_MFHC2 = (0x03 << 21) | OPC_CP2,
879 OPC_MTC2 = (0x04 << 21) | OPC_CP2,
880 OPC_DMTC2 = (0x05 << 21) | OPC_CP2,
881 OPC_CTC2 = (0x06 << 21) | OPC_CP2,
882 OPC_MTHC2 = (0x07 << 21) | OPC_CP2,
883 OPC_BC2 = (0x08 << 21) | OPC_CP2,
886 #define MASK_LMI(op) (MASK_OP_MAJOR(op) | (op & (0x1F << 21)) | (op & 0x1F))
888 enum {
889 OPC_PADDSH = (24 << 21) | (0x00) | OPC_CP2,
890 OPC_PADDUSH = (25 << 21) | (0x00) | OPC_CP2,
891 OPC_PADDH = (26 << 21) | (0x00) | OPC_CP2,
892 OPC_PADDW = (27 << 21) | (0x00) | OPC_CP2,
893 OPC_PADDSB = (28 << 21) | (0x00) | OPC_CP2,
894 OPC_PADDUSB = (29 << 21) | (0x00) | OPC_CP2,
895 OPC_PADDB = (30 << 21) | (0x00) | OPC_CP2,
896 OPC_PADDD = (31 << 21) | (0x00) | OPC_CP2,
898 OPC_PSUBSH = (24 << 21) | (0x01) | OPC_CP2,
899 OPC_PSUBUSH = (25 << 21) | (0x01) | OPC_CP2,
900 OPC_PSUBH = (26 << 21) | (0x01) | OPC_CP2,
901 OPC_PSUBW = (27 << 21) | (0x01) | OPC_CP2,
902 OPC_PSUBSB = (28 << 21) | (0x01) | OPC_CP2,
903 OPC_PSUBUSB = (29 << 21) | (0x01) | OPC_CP2,
904 OPC_PSUBB = (30 << 21) | (0x01) | OPC_CP2,
905 OPC_PSUBD = (31 << 21) | (0x01) | OPC_CP2,
907 OPC_PSHUFH = (24 << 21) | (0x02) | OPC_CP2,
908 OPC_PACKSSWH = (25 << 21) | (0x02) | OPC_CP2,
909 OPC_PACKSSHB = (26 << 21) | (0x02) | OPC_CP2,
910 OPC_PACKUSHB = (27 << 21) | (0x02) | OPC_CP2,
911 OPC_XOR_CP2 = (28 << 21) | (0x02) | OPC_CP2,
912 OPC_NOR_CP2 = (29 << 21) | (0x02) | OPC_CP2,
913 OPC_AND_CP2 = (30 << 21) | (0x02) | OPC_CP2,
914 OPC_PANDN = (31 << 21) | (0x02) | OPC_CP2,
916 OPC_PUNPCKLHW = (24 << 21) | (0x03) | OPC_CP2,
917 OPC_PUNPCKHHW = (25 << 21) | (0x03) | OPC_CP2,
918 OPC_PUNPCKLBH = (26 << 21) | (0x03) | OPC_CP2,
919 OPC_PUNPCKHBH = (27 << 21) | (0x03) | OPC_CP2,
920 OPC_PINSRH_0 = (28 << 21) | (0x03) | OPC_CP2,
921 OPC_PINSRH_1 = (29 << 21) | (0x03) | OPC_CP2,
922 OPC_PINSRH_2 = (30 << 21) | (0x03) | OPC_CP2,
923 OPC_PINSRH_3 = (31 << 21) | (0x03) | OPC_CP2,
925 OPC_PAVGH = (24 << 21) | (0x08) | OPC_CP2,
926 OPC_PAVGB = (25 << 21) | (0x08) | OPC_CP2,
927 OPC_PMAXSH = (26 << 21) | (0x08) | OPC_CP2,
928 OPC_PMINSH = (27 << 21) | (0x08) | OPC_CP2,
929 OPC_PMAXUB = (28 << 21) | (0x08) | OPC_CP2,
930 OPC_PMINUB = (29 << 21) | (0x08) | OPC_CP2,
932 OPC_PCMPEQW = (24 << 21) | (0x09) | OPC_CP2,
933 OPC_PCMPGTW = (25 << 21) | (0x09) | OPC_CP2,
934 OPC_PCMPEQH = (26 << 21) | (0x09) | OPC_CP2,
935 OPC_PCMPGTH = (27 << 21) | (0x09) | OPC_CP2,
936 OPC_PCMPEQB = (28 << 21) | (0x09) | OPC_CP2,
937 OPC_PCMPGTB = (29 << 21) | (0x09) | OPC_CP2,
939 OPC_PSLLW = (24 << 21) | (0x0A) | OPC_CP2,
940 OPC_PSLLH = (25 << 21) | (0x0A) | OPC_CP2,
941 OPC_PMULLH = (26 << 21) | (0x0A) | OPC_CP2,
942 OPC_PMULHH = (27 << 21) | (0x0A) | OPC_CP2,
943 OPC_PMULUW = (28 << 21) | (0x0A) | OPC_CP2,
944 OPC_PMULHUH = (29 << 21) | (0x0A) | OPC_CP2,
946 OPC_PSRLW = (24 << 21) | (0x0B) | OPC_CP2,
947 OPC_PSRLH = (25 << 21) | (0x0B) | OPC_CP2,
948 OPC_PSRAW = (26 << 21) | (0x0B) | OPC_CP2,
949 OPC_PSRAH = (27 << 21) | (0x0B) | OPC_CP2,
950 OPC_PUNPCKLWD = (28 << 21) | (0x0B) | OPC_CP2,
951 OPC_PUNPCKHWD = (29 << 21) | (0x0B) | OPC_CP2,
953 OPC_ADDU_CP2 = (24 << 21) | (0x0C) | OPC_CP2,
954 OPC_OR_CP2 = (25 << 21) | (0x0C) | OPC_CP2,
955 OPC_ADD_CP2 = (26 << 21) | (0x0C) | OPC_CP2,
956 OPC_DADD_CP2 = (27 << 21) | (0x0C) | OPC_CP2,
957 OPC_SEQU_CP2 = (28 << 21) | (0x0C) | OPC_CP2,
958 OPC_SEQ_CP2 = (29 << 21) | (0x0C) | OPC_CP2,
960 OPC_SUBU_CP2 = (24 << 21) | (0x0D) | OPC_CP2,
961 OPC_PASUBUB = (25 << 21) | (0x0D) | OPC_CP2,
962 OPC_SUB_CP2 = (26 << 21) | (0x0D) | OPC_CP2,
963 OPC_DSUB_CP2 = (27 << 21) | (0x0D) | OPC_CP2,
964 OPC_SLTU_CP2 = (28 << 21) | (0x0D) | OPC_CP2,
965 OPC_SLT_CP2 = (29 << 21) | (0x0D) | OPC_CP2,
967 OPC_SLL_CP2 = (24 << 21) | (0x0E) | OPC_CP2,
968 OPC_DSLL_CP2 = (25 << 21) | (0x0E) | OPC_CP2,
969 OPC_PEXTRH = (26 << 21) | (0x0E) | OPC_CP2,
970 OPC_PMADDHW = (27 << 21) | (0x0E) | OPC_CP2,
971 OPC_SLEU_CP2 = (28 << 21) | (0x0E) | OPC_CP2,
972 OPC_SLE_CP2 = (29 << 21) | (0x0E) | OPC_CP2,
974 OPC_SRL_CP2 = (24 << 21) | (0x0F) | OPC_CP2,
975 OPC_DSRL_CP2 = (25 << 21) | (0x0F) | OPC_CP2,
976 OPC_SRA_CP2 = (26 << 21) | (0x0F) | OPC_CP2,
977 OPC_DSRA_CP2 = (27 << 21) | (0x0F) | OPC_CP2,
978 OPC_BIADD = (28 << 21) | (0x0F) | OPC_CP2,
979 OPC_PMOVMSKB = (29 << 21) | (0x0F) | OPC_CP2,
983 #define MASK_CP3(op) MASK_OP_MAJOR(op) | (op & 0x3F)
985 enum {
986 OPC_LWXC1 = 0x00 | OPC_CP3,
987 OPC_LDXC1 = 0x01 | OPC_CP3,
988 OPC_LUXC1 = 0x05 | OPC_CP3,
989 OPC_SWXC1 = 0x08 | OPC_CP3,
990 OPC_SDXC1 = 0x09 | OPC_CP3,
991 OPC_SUXC1 = 0x0D | OPC_CP3,
992 OPC_PREFX = 0x0F | OPC_CP3,
993 OPC_ALNV_PS = 0x1E | OPC_CP3,
994 OPC_MADD_S = 0x20 | OPC_CP3,
995 OPC_MADD_D = 0x21 | OPC_CP3,
996 OPC_MADD_PS = 0x26 | OPC_CP3,
997 OPC_MSUB_S = 0x28 | OPC_CP3,
998 OPC_MSUB_D = 0x29 | OPC_CP3,
999 OPC_MSUB_PS = 0x2E | OPC_CP3,
1000 OPC_NMADD_S = 0x30 | OPC_CP3,
1001 OPC_NMADD_D = 0x31 | OPC_CP3,
1002 OPC_NMADD_PS= 0x36 | OPC_CP3,
1003 OPC_NMSUB_S = 0x38 | OPC_CP3,
1004 OPC_NMSUB_D = 0x39 | OPC_CP3,
1005 OPC_NMSUB_PS= 0x3E | OPC_CP3,
1008 /* global register indices */
1009 static TCGv_ptr cpu_env;
1010 static TCGv cpu_gpr[32], cpu_PC;
1011 static TCGv cpu_HI[MIPS_DSP_ACC], cpu_LO[MIPS_DSP_ACC], cpu_ACX[MIPS_DSP_ACC];
1012 static TCGv cpu_dspctrl, btarget, bcond;
1013 static TCGv_i32 hflags;
1014 static TCGv_i32 fpu_fcr0, fpu_fcr31;
1015 static TCGv_i64 fpu_f64[32];
1017 static uint32_t gen_opc_hflags[OPC_BUF_SIZE];
1018 static target_ulong gen_opc_btarget[OPC_BUF_SIZE];
1020 #include "exec/gen-icount.h"
1022 #define gen_helper_0e0i(name, arg) do { \
1023 TCGv_i32 helper_tmp = tcg_const_i32(arg); \
1024 gen_helper_##name(cpu_env, helper_tmp); \
1025 tcg_temp_free_i32(helper_tmp); \
1026 } while(0)
1028 #define gen_helper_0e1i(name, arg1, arg2) do { \
1029 TCGv_i32 helper_tmp = tcg_const_i32(arg2); \
1030 gen_helper_##name(cpu_env, arg1, helper_tmp); \
1031 tcg_temp_free_i32(helper_tmp); \
1032 } while(0)
1034 #define gen_helper_1e0i(name, ret, arg1) do { \
1035 TCGv_i32 helper_tmp = tcg_const_i32(arg1); \
1036 gen_helper_##name(ret, cpu_env, helper_tmp); \
1037 tcg_temp_free_i32(helper_tmp); \
1038 } while(0)
1040 #define gen_helper_1e1i(name, ret, arg1, arg2) do { \
1041 TCGv_i32 helper_tmp = tcg_const_i32(arg2); \
1042 gen_helper_##name(ret, cpu_env, arg1, helper_tmp); \
1043 tcg_temp_free_i32(helper_tmp); \
1044 } while(0)
1046 #define gen_helper_0e2i(name, arg1, arg2, arg3) do { \
1047 TCGv_i32 helper_tmp = tcg_const_i32(arg3); \
1048 gen_helper_##name(cpu_env, arg1, arg2, helper_tmp); \
1049 tcg_temp_free_i32(helper_tmp); \
1050 } while(0)
1052 #define gen_helper_1e2i(name, ret, arg1, arg2, arg3) do { \
1053 TCGv_i32 helper_tmp = tcg_const_i32(arg3); \
1054 gen_helper_##name(ret, cpu_env, arg1, arg2, helper_tmp); \
1055 tcg_temp_free_i32(helper_tmp); \
1056 } while(0)
1058 #define gen_helper_0e3i(name, arg1, arg2, arg3, arg4) do { \
1059 TCGv_i32 helper_tmp = tcg_const_i32(arg4); \
1060 gen_helper_##name(cpu_env, arg1, arg2, arg3, helper_tmp); \
1061 tcg_temp_free_i32(helper_tmp); \
1062 } while(0)
1064 typedef struct DisasContext {
1065 struct TranslationBlock *tb;
1066 target_ulong pc, saved_pc;
1067 uint32_t opcode;
1068 int singlestep_enabled;
1069 int insn_flags;
1070 /* Routine used to access memory */
1071 int mem_idx;
1072 uint32_t hflags, saved_hflags;
1073 int bstate;
1074 target_ulong btarget;
1075 } DisasContext;
1077 enum {
1078 BS_NONE = 0, /* We go out of the TB without reaching a branch or an
1079 * exception condition */
1080 BS_STOP = 1, /* We want to stop translation for any reason */
1081 BS_BRANCH = 2, /* We reached a branch condition */
1082 BS_EXCP = 3, /* We reached an exception condition */
1085 static const char * const regnames[] = {
1086 "r0", "at", "v0", "v1", "a0", "a1", "a2", "a3",
1087 "t0", "t1", "t2", "t3", "t4", "t5", "t6", "t7",
1088 "s0", "s1", "s2", "s3", "s4", "s5", "s6", "s7",
1089 "t8", "t9", "k0", "k1", "gp", "sp", "s8", "ra",
1092 static const char * const regnames_HI[] = {
1093 "HI0", "HI1", "HI2", "HI3",
1096 static const char * const regnames_LO[] = {
1097 "LO0", "LO1", "LO2", "LO3",
1100 static const char * const regnames_ACX[] = {
1101 "ACX0", "ACX1", "ACX2", "ACX3",
1104 static const char * const fregnames[] = {
1105 "f0", "f1", "f2", "f3", "f4", "f5", "f6", "f7",
1106 "f8", "f9", "f10", "f11", "f12", "f13", "f14", "f15",
1107 "f16", "f17", "f18", "f19", "f20", "f21", "f22", "f23",
1108 "f24", "f25", "f26", "f27", "f28", "f29", "f30", "f31",
1111 #define MIPS_DEBUG(fmt, ...) \
1112 do { \
1113 if (MIPS_DEBUG_DISAS) { \
1114 qemu_log_mask(CPU_LOG_TB_IN_ASM, \
1115 TARGET_FMT_lx ": %08x " fmt "\n", \
1116 ctx->pc, ctx->opcode , ## __VA_ARGS__); \
1118 } while (0)
1120 #define LOG_DISAS(...) \
1121 do { \
1122 if (MIPS_DEBUG_DISAS) { \
1123 qemu_log_mask(CPU_LOG_TB_IN_ASM, ## __VA_ARGS__); \
1125 } while (0)
1127 #define MIPS_INVAL(op) \
1128 MIPS_DEBUG("Invalid %s %03x %03x %03x", op, ctx->opcode >> 26, \
1129 ctx->opcode & 0x3F, ((ctx->opcode >> 16) & 0x1F))
1131 /* General purpose registers moves. */
1132 static inline void gen_load_gpr (TCGv t, int reg)
1134 if (reg == 0)
1135 tcg_gen_movi_tl(t, 0);
1136 else
1137 tcg_gen_mov_tl(t, cpu_gpr[reg]);
1140 static inline void gen_store_gpr (TCGv t, int reg)
1142 if (reg != 0)
1143 tcg_gen_mov_tl(cpu_gpr[reg], t);
1146 /* Moves to/from ACX register. */
1147 static inline void gen_load_ACX (TCGv t, int reg)
1149 tcg_gen_mov_tl(t, cpu_ACX[reg]);
1152 static inline void gen_store_ACX (TCGv t, int reg)
1154 tcg_gen_mov_tl(cpu_ACX[reg], t);
1157 /* Moves to/from shadow registers. */
1158 static inline void gen_load_srsgpr (int from, int to)
1160 TCGv t0 = tcg_temp_new();
1162 if (from == 0)
1163 tcg_gen_movi_tl(t0, 0);
1164 else {
1165 TCGv_i32 t2 = tcg_temp_new_i32();
1166 TCGv_ptr addr = tcg_temp_new_ptr();
1168 tcg_gen_ld_i32(t2, cpu_env, offsetof(CPUMIPSState, CP0_SRSCtl));
1169 tcg_gen_shri_i32(t2, t2, CP0SRSCtl_PSS);
1170 tcg_gen_andi_i32(t2, t2, 0xf);
1171 tcg_gen_muli_i32(t2, t2, sizeof(target_ulong) * 32);
1172 tcg_gen_ext_i32_ptr(addr, t2);
1173 tcg_gen_add_ptr(addr, cpu_env, addr);
1175 tcg_gen_ld_tl(t0, addr, sizeof(target_ulong) * from);
1176 tcg_temp_free_ptr(addr);
1177 tcg_temp_free_i32(t2);
1179 gen_store_gpr(t0, to);
1180 tcg_temp_free(t0);
1183 static inline void gen_store_srsgpr (int from, int to)
1185 if (to != 0) {
1186 TCGv t0 = tcg_temp_new();
1187 TCGv_i32 t2 = tcg_temp_new_i32();
1188 TCGv_ptr addr = tcg_temp_new_ptr();
1190 gen_load_gpr(t0, from);
1191 tcg_gen_ld_i32(t2, cpu_env, offsetof(CPUMIPSState, CP0_SRSCtl));
1192 tcg_gen_shri_i32(t2, t2, CP0SRSCtl_PSS);
1193 tcg_gen_andi_i32(t2, t2, 0xf);
1194 tcg_gen_muli_i32(t2, t2, sizeof(target_ulong) * 32);
1195 tcg_gen_ext_i32_ptr(addr, t2);
1196 tcg_gen_add_ptr(addr, cpu_env, addr);
1198 tcg_gen_st_tl(t0, addr, sizeof(target_ulong) * to);
1199 tcg_temp_free_ptr(addr);
1200 tcg_temp_free_i32(t2);
1201 tcg_temp_free(t0);
1205 /* Floating point register moves. */
1206 static void gen_load_fpr32(TCGv_i32 t, int reg)
1208 tcg_gen_trunc_i64_i32(t, fpu_f64[reg]);
1211 static void gen_store_fpr32(TCGv_i32 t, int reg)
1213 TCGv_i64 t64 = tcg_temp_new_i64();
1214 tcg_gen_extu_i32_i64(t64, t);
1215 tcg_gen_deposit_i64(fpu_f64[reg], fpu_f64[reg], t64, 0, 32);
1216 tcg_temp_free_i64(t64);
1219 static void gen_load_fpr32h(TCGv_i32 t, int reg)
1221 TCGv_i64 t64 = tcg_temp_new_i64();
1222 tcg_gen_shri_i64(t64, fpu_f64[reg], 32);
1223 tcg_gen_trunc_i64_i32(t, t64);
1224 tcg_temp_free_i64(t64);
1227 static void gen_store_fpr32h(TCGv_i32 t, int reg)
1229 TCGv_i64 t64 = tcg_temp_new_i64();
1230 tcg_gen_extu_i32_i64(t64, t);
1231 tcg_gen_deposit_i64(fpu_f64[reg], fpu_f64[reg], t64, 32, 32);
1232 tcg_temp_free_i64(t64);
1235 static void gen_load_fpr64(DisasContext *ctx, TCGv_i64 t, int reg)
1237 if (ctx->hflags & MIPS_HFLAG_F64) {
1238 tcg_gen_mov_i64(t, fpu_f64[reg]);
1239 } else {
1240 tcg_gen_concat32_i64(t, fpu_f64[reg & ~1], fpu_f64[reg | 1]);
1244 static void gen_store_fpr64(DisasContext *ctx, TCGv_i64 t, int reg)
1246 if (ctx->hflags & MIPS_HFLAG_F64) {
1247 tcg_gen_mov_i64(fpu_f64[reg], t);
1248 } else {
1249 TCGv_i64 t0;
1250 tcg_gen_deposit_i64(fpu_f64[reg & ~1], fpu_f64[reg & ~1], t, 0, 32);
1251 t0 = tcg_temp_new_i64();
1252 tcg_gen_shri_i64(t0, t, 32);
1253 tcg_gen_deposit_i64(fpu_f64[reg | 1], fpu_f64[reg | 1], t0, 0, 32);
1254 tcg_temp_free_i64(t0);
1258 static inline int get_fp_bit (int cc)
1260 if (cc)
1261 return 24 + cc;
1262 else
1263 return 23;
1266 /* Tests */
1267 static inline void gen_save_pc(target_ulong pc)
1269 tcg_gen_movi_tl(cpu_PC, pc);
1272 static inline void save_cpu_state (DisasContext *ctx, int do_save_pc)
1274 LOG_DISAS("hflags %08x saved %08x\n", ctx->hflags, ctx->saved_hflags);
1275 if (do_save_pc && ctx->pc != ctx->saved_pc) {
1276 gen_save_pc(ctx->pc);
1277 ctx->saved_pc = ctx->pc;
1279 if (ctx->hflags != ctx->saved_hflags) {
1280 tcg_gen_movi_i32(hflags, ctx->hflags);
1281 ctx->saved_hflags = ctx->hflags;
1282 switch (ctx->hflags & MIPS_HFLAG_BMASK_BASE) {
1283 case MIPS_HFLAG_BR:
1284 break;
1285 case MIPS_HFLAG_BC:
1286 case MIPS_HFLAG_BL:
1287 case MIPS_HFLAG_B:
1288 tcg_gen_movi_tl(btarget, ctx->btarget);
1289 break;
1294 static inline void restore_cpu_state (CPUMIPSState *env, DisasContext *ctx)
1296 ctx->saved_hflags = ctx->hflags;
1297 switch (ctx->hflags & MIPS_HFLAG_BMASK_BASE) {
1298 case MIPS_HFLAG_BR:
1299 break;
1300 case MIPS_HFLAG_BC:
1301 case MIPS_HFLAG_BL:
1302 case MIPS_HFLAG_B:
1303 ctx->btarget = env->btarget;
1304 break;
1308 static inline void
1309 generate_exception_err (DisasContext *ctx, int excp, int err)
1311 TCGv_i32 texcp = tcg_const_i32(excp);
1312 TCGv_i32 terr = tcg_const_i32(err);
1313 save_cpu_state(ctx, 1);
1314 gen_helper_raise_exception_err(cpu_env, texcp, terr);
1315 tcg_temp_free_i32(terr);
1316 tcg_temp_free_i32(texcp);
1319 static inline void
1320 generate_exception (DisasContext *ctx, int excp)
1322 save_cpu_state(ctx, 1);
1323 gen_helper_0e0i(raise_exception, excp);
1326 /* Addresses computation */
1327 static inline void gen_op_addr_add (DisasContext *ctx, TCGv ret, TCGv arg0, TCGv arg1)
1329 tcg_gen_add_tl(ret, arg0, arg1);
1331 #if defined(TARGET_MIPS64)
1332 /* For compatibility with 32-bit code, data reference in user mode
1333 with Status_UX = 0 should be casted to 32-bit and sign extended.
1334 See the MIPS64 PRA manual, section 4.10. */
1335 if (((ctx->hflags & MIPS_HFLAG_KSU) == MIPS_HFLAG_UM) &&
1336 !(ctx->hflags & MIPS_HFLAG_UX)) {
1337 tcg_gen_ext32s_i64(ret, ret);
1339 #endif
1342 static inline void check_cp0_enabled(DisasContext *ctx)
1344 if (unlikely(!(ctx->hflags & MIPS_HFLAG_CP0)))
1345 generate_exception_err(ctx, EXCP_CpU, 0);
1348 static inline void check_cp1_enabled(DisasContext *ctx)
1350 if (unlikely(!(ctx->hflags & MIPS_HFLAG_FPU)))
1351 generate_exception_err(ctx, EXCP_CpU, 1);
1354 /* Verify that the processor is running with COP1X instructions enabled.
1355 This is associated with the nabla symbol in the MIPS32 and MIPS64
1356 opcode tables. */
1358 static inline void check_cop1x(DisasContext *ctx)
1360 if (unlikely(!(ctx->hflags & MIPS_HFLAG_COP1X)))
1361 generate_exception(ctx, EXCP_RI);
1364 /* Verify that the processor is running with 64-bit floating-point
1365 operations enabled. */
1367 static inline void check_cp1_64bitmode(DisasContext *ctx)
1369 if (unlikely(~ctx->hflags & (MIPS_HFLAG_F64 | MIPS_HFLAG_COP1X)))
1370 generate_exception(ctx, EXCP_RI);
1374 * Verify if floating point register is valid; an operation is not defined
1375 * if bit 0 of any register specification is set and the FR bit in the
1376 * Status register equals zero, since the register numbers specify an
1377 * even-odd pair of adjacent coprocessor general registers. When the FR bit
1378 * in the Status register equals one, both even and odd register numbers
1379 * are valid. This limitation exists only for 64 bit wide (d,l,ps) registers.
1381 * Multiple 64 bit wide registers can be checked by calling
1382 * gen_op_cp1_registers(freg1 | freg2 | ... | fregN);
1384 static inline void check_cp1_registers(DisasContext *ctx, int regs)
1386 if (unlikely(!(ctx->hflags & MIPS_HFLAG_F64) && (regs & 1)))
1387 generate_exception(ctx, EXCP_RI);
1390 /* Verify that the processor is running with DSP instructions enabled.
1391 This is enabled by CP0 Status register MX(24) bit.
1394 static inline void check_dsp(DisasContext *ctx)
1396 if (unlikely(!(ctx->hflags & MIPS_HFLAG_DSP))) {
1397 if (ctx->insn_flags & ASE_DSP) {
1398 generate_exception(ctx, EXCP_DSPDIS);
1399 } else {
1400 generate_exception(ctx, EXCP_RI);
1405 static inline void check_dspr2(DisasContext *ctx)
1407 if (unlikely(!(ctx->hflags & MIPS_HFLAG_DSPR2))) {
1408 if (ctx->insn_flags & ASE_DSP) {
1409 generate_exception(ctx, EXCP_DSPDIS);
1410 } else {
1411 generate_exception(ctx, EXCP_RI);
1416 /* This code generates a "reserved instruction" exception if the
1417 CPU does not support the instruction set corresponding to flags. */
1418 static inline void check_insn(DisasContext *ctx, int flags)
1420 if (unlikely(!(ctx->insn_flags & flags))) {
1421 generate_exception(ctx, EXCP_RI);
1425 /* This code generates a "reserved instruction" exception if 64-bit
1426 instructions are not enabled. */
1427 static inline void check_mips_64(DisasContext *ctx)
1429 if (unlikely(!(ctx->hflags & MIPS_HFLAG_64)))
1430 generate_exception(ctx, EXCP_RI);
1433 /* Define small wrappers for gen_load_fpr* so that we have a uniform
1434 calling interface for 32 and 64-bit FPRs. No sense in changing
1435 all callers for gen_load_fpr32 when we need the CTX parameter for
1436 this one use. */
1437 #define gen_ldcmp_fpr32(ctx, x, y) gen_load_fpr32(x, y)
1438 #define gen_ldcmp_fpr64(ctx, x, y) gen_load_fpr64(ctx, x, y)
1439 #define FOP_CONDS(type, abs, fmt, ifmt, bits) \
1440 static inline void gen_cmp ## type ## _ ## fmt(DisasContext *ctx, int n, \
1441 int ft, int fs, int cc) \
1443 TCGv_i##bits fp0 = tcg_temp_new_i##bits (); \
1444 TCGv_i##bits fp1 = tcg_temp_new_i##bits (); \
1445 switch (ifmt) { \
1446 case FMT_PS: \
1447 check_cp1_64bitmode(ctx); \
1448 break; \
1449 case FMT_D: \
1450 if (abs) { \
1451 check_cop1x(ctx); \
1453 check_cp1_registers(ctx, fs | ft); \
1454 break; \
1455 case FMT_S: \
1456 if (abs) { \
1457 check_cop1x(ctx); \
1459 break; \
1461 gen_ldcmp_fpr##bits (ctx, fp0, fs); \
1462 gen_ldcmp_fpr##bits (ctx, fp1, ft); \
1463 switch (n) { \
1464 case 0: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _f, fp0, fp1, cc); break;\
1465 case 1: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _un, fp0, fp1, cc); break;\
1466 case 2: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _eq, fp0, fp1, cc); break;\
1467 case 3: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ueq, fp0, fp1, cc); break;\
1468 case 4: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _olt, fp0, fp1, cc); break;\
1469 case 5: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ult, fp0, fp1, cc); break;\
1470 case 6: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ole, fp0, fp1, cc); break;\
1471 case 7: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ule, fp0, fp1, cc); break;\
1472 case 8: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _sf, fp0, fp1, cc); break;\
1473 case 9: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ngle, fp0, fp1, cc); break;\
1474 case 10: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _seq, fp0, fp1, cc); break;\
1475 case 11: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ngl, fp0, fp1, cc); break;\
1476 case 12: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _lt, fp0, fp1, cc); break;\
1477 case 13: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _nge, fp0, fp1, cc); break;\
1478 case 14: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _le, fp0, fp1, cc); break;\
1479 case 15: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ngt, fp0, fp1, cc); break;\
1480 default: abort(); \
1482 tcg_temp_free_i##bits (fp0); \
1483 tcg_temp_free_i##bits (fp1); \
1486 FOP_CONDS(, 0, d, FMT_D, 64)
1487 FOP_CONDS(abs, 1, d, FMT_D, 64)
1488 FOP_CONDS(, 0, s, FMT_S, 32)
1489 FOP_CONDS(abs, 1, s, FMT_S, 32)
1490 FOP_CONDS(, 0, ps, FMT_PS, 64)
1491 FOP_CONDS(abs, 1, ps, FMT_PS, 64)
1492 #undef FOP_CONDS
1493 #undef gen_ldcmp_fpr32
1494 #undef gen_ldcmp_fpr64
1496 /* load/store instructions. */
1497 #ifdef CONFIG_USER_ONLY
1498 #define OP_LD_ATOMIC(insn,fname) \
1499 static inline void op_ld_##insn(TCGv ret, TCGv arg1, DisasContext *ctx) \
1501 TCGv t0 = tcg_temp_new(); \
1502 tcg_gen_mov_tl(t0, arg1); \
1503 tcg_gen_qemu_##fname(ret, arg1, ctx->mem_idx); \
1504 tcg_gen_st_tl(t0, cpu_env, offsetof(CPUMIPSState, lladdr)); \
1505 tcg_gen_st_tl(ret, cpu_env, offsetof(CPUMIPSState, llval)); \
1506 tcg_temp_free(t0); \
1508 #else
1509 #define OP_LD_ATOMIC(insn,fname) \
1510 static inline void op_ld_##insn(TCGv ret, TCGv arg1, DisasContext *ctx) \
1512 gen_helper_1e1i(insn, ret, arg1, ctx->mem_idx); \
1514 #endif
1515 OP_LD_ATOMIC(ll,ld32s);
1516 #if defined(TARGET_MIPS64)
1517 OP_LD_ATOMIC(lld,ld64);
1518 #endif
1519 #undef OP_LD_ATOMIC
1521 #ifdef CONFIG_USER_ONLY
1522 #define OP_ST_ATOMIC(insn,fname,ldname,almask) \
1523 static inline void op_st_##insn(TCGv arg1, TCGv arg2, int rt, DisasContext *ctx) \
1525 TCGv t0 = tcg_temp_new(); \
1526 int l1 = gen_new_label(); \
1527 int l2 = gen_new_label(); \
1529 tcg_gen_andi_tl(t0, arg2, almask); \
1530 tcg_gen_brcondi_tl(TCG_COND_EQ, t0, 0, l1); \
1531 tcg_gen_st_tl(arg2, cpu_env, offsetof(CPUMIPSState, CP0_BadVAddr)); \
1532 generate_exception(ctx, EXCP_AdES); \
1533 gen_set_label(l1); \
1534 tcg_gen_ld_tl(t0, cpu_env, offsetof(CPUMIPSState, lladdr)); \
1535 tcg_gen_brcond_tl(TCG_COND_NE, arg2, t0, l2); \
1536 tcg_gen_movi_tl(t0, rt | ((almask << 3) & 0x20)); \
1537 tcg_gen_st_tl(t0, cpu_env, offsetof(CPUMIPSState, llreg)); \
1538 tcg_gen_st_tl(arg1, cpu_env, offsetof(CPUMIPSState, llnewval)); \
1539 gen_helper_0e0i(raise_exception, EXCP_SC); \
1540 gen_set_label(l2); \
1541 tcg_gen_movi_tl(t0, 0); \
1542 gen_store_gpr(t0, rt); \
1543 tcg_temp_free(t0); \
1545 #else
1546 #define OP_ST_ATOMIC(insn,fname,ldname,almask) \
1547 static inline void op_st_##insn(TCGv arg1, TCGv arg2, int rt, DisasContext *ctx) \
1549 TCGv t0 = tcg_temp_new(); \
1550 gen_helper_1e2i(insn, t0, arg1, arg2, ctx->mem_idx); \
1551 gen_store_gpr(t0, rt); \
1552 tcg_temp_free(t0); \
1554 #endif
1555 OP_ST_ATOMIC(sc,st32,ld32s,0x3);
1556 #if defined(TARGET_MIPS64)
1557 OP_ST_ATOMIC(scd,st64,ld64,0x7);
1558 #endif
1559 #undef OP_ST_ATOMIC
1561 static void gen_base_offset_addr (DisasContext *ctx, TCGv addr,
1562 int base, int16_t offset)
1564 if (base == 0) {
1565 tcg_gen_movi_tl(addr, offset);
1566 } else if (offset == 0) {
1567 gen_load_gpr(addr, base);
1568 } else {
1569 tcg_gen_movi_tl(addr, offset);
1570 gen_op_addr_add(ctx, addr, cpu_gpr[base], addr);
1574 static target_ulong pc_relative_pc (DisasContext *ctx)
1576 target_ulong pc = ctx->pc;
1578 if (ctx->hflags & MIPS_HFLAG_BMASK) {
1579 int branch_bytes = ctx->hflags & MIPS_HFLAG_BDS16 ? 2 : 4;
1581 pc -= branch_bytes;
1584 pc &= ~(target_ulong)3;
1585 return pc;
1588 /* Load */
1589 static void gen_ld(DisasContext *ctx, uint32_t opc,
1590 int rt, int base, int16_t offset)
1592 const char *opn = "ld";
1593 TCGv t0, t1, t2;
1595 if (rt == 0 && ctx->insn_flags & (INSN_LOONGSON2E | INSN_LOONGSON2F)) {
1596 /* Loongson CPU uses a load to zero register for prefetch.
1597 We emulate it as a NOP. On other CPU we must perform the
1598 actual memory access. */
1599 MIPS_DEBUG("NOP");
1600 return;
1603 t0 = tcg_temp_new();
1604 gen_base_offset_addr(ctx, t0, base, offset);
1606 switch (opc) {
1607 #if defined(TARGET_MIPS64)
1608 case OPC_LWU:
1609 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TEUL);
1610 gen_store_gpr(t0, rt);
1611 opn = "lwu";
1612 break;
1613 case OPC_LD:
1614 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TEQ);
1615 gen_store_gpr(t0, rt);
1616 opn = "ld";
1617 break;
1618 case OPC_LLD:
1619 save_cpu_state(ctx, 1);
1620 op_ld_lld(t0, t0, ctx);
1621 gen_store_gpr(t0, rt);
1622 opn = "lld";
1623 break;
1624 case OPC_LDL:
1625 t1 = tcg_temp_new();
1626 tcg_gen_andi_tl(t1, t0, 7);
1627 #ifndef TARGET_WORDS_BIGENDIAN
1628 tcg_gen_xori_tl(t1, t1, 7);
1629 #endif
1630 tcg_gen_shli_tl(t1, t1, 3);
1631 tcg_gen_andi_tl(t0, t0, ~7);
1632 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TEQ);
1633 tcg_gen_shl_tl(t0, t0, t1);
1634 tcg_gen_xori_tl(t1, t1, 63);
1635 t2 = tcg_const_tl(0x7fffffffffffffffull);
1636 tcg_gen_shr_tl(t2, t2, t1);
1637 gen_load_gpr(t1, rt);
1638 tcg_gen_and_tl(t1, t1, t2);
1639 tcg_temp_free(t2);
1640 tcg_gen_or_tl(t0, t0, t1);
1641 tcg_temp_free(t1);
1642 gen_store_gpr(t0, rt);
1643 opn = "ldl";
1644 break;
1645 case OPC_LDR:
1646 t1 = tcg_temp_new();
1647 tcg_gen_andi_tl(t1, t0, 7);
1648 #ifdef TARGET_WORDS_BIGENDIAN
1649 tcg_gen_xori_tl(t1, t1, 7);
1650 #endif
1651 tcg_gen_shli_tl(t1, t1, 3);
1652 tcg_gen_andi_tl(t0, t0, ~7);
1653 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TEQ);
1654 tcg_gen_shr_tl(t0, t0, t1);
1655 tcg_gen_xori_tl(t1, t1, 63);
1656 t2 = tcg_const_tl(0xfffffffffffffffeull);
1657 tcg_gen_shl_tl(t2, t2, t1);
1658 gen_load_gpr(t1, rt);
1659 tcg_gen_and_tl(t1, t1, t2);
1660 tcg_temp_free(t2);
1661 tcg_gen_or_tl(t0, t0, t1);
1662 tcg_temp_free(t1);
1663 gen_store_gpr(t0, rt);
1664 opn = "ldr";
1665 break;
1666 case OPC_LDPC:
1667 t1 = tcg_const_tl(pc_relative_pc(ctx));
1668 gen_op_addr_add(ctx, t0, t0, t1);
1669 tcg_temp_free(t1);
1670 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TEQ);
1671 gen_store_gpr(t0, rt);
1672 opn = "ldpc";
1673 break;
1674 #endif
1675 case OPC_LWPC:
1676 t1 = tcg_const_tl(pc_relative_pc(ctx));
1677 gen_op_addr_add(ctx, t0, t0, t1);
1678 tcg_temp_free(t1);
1679 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TESL);
1680 gen_store_gpr(t0, rt);
1681 opn = "lwpc";
1682 break;
1683 case OPC_LW:
1684 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TESL);
1685 gen_store_gpr(t0, rt);
1686 opn = "lw";
1687 break;
1688 case OPC_LH:
1689 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TESW);
1690 gen_store_gpr(t0, rt);
1691 opn = "lh";
1692 break;
1693 case OPC_LHU:
1694 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TEUW);
1695 gen_store_gpr(t0, rt);
1696 opn = "lhu";
1697 break;
1698 case OPC_LB:
1699 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_SB);
1700 gen_store_gpr(t0, rt);
1701 opn = "lb";
1702 break;
1703 case OPC_LBU:
1704 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_UB);
1705 gen_store_gpr(t0, rt);
1706 opn = "lbu";
1707 break;
1708 case OPC_LWL:
1709 t1 = tcg_temp_new();
1710 tcg_gen_andi_tl(t1, t0, 3);
1711 #ifndef TARGET_WORDS_BIGENDIAN
1712 tcg_gen_xori_tl(t1, t1, 3);
1713 #endif
1714 tcg_gen_shli_tl(t1, t1, 3);
1715 tcg_gen_andi_tl(t0, t0, ~3);
1716 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TEUL);
1717 tcg_gen_shl_tl(t0, t0, t1);
1718 tcg_gen_xori_tl(t1, t1, 31);
1719 t2 = tcg_const_tl(0x7fffffffull);
1720 tcg_gen_shr_tl(t2, t2, t1);
1721 gen_load_gpr(t1, rt);
1722 tcg_gen_and_tl(t1, t1, t2);
1723 tcg_temp_free(t2);
1724 tcg_gen_or_tl(t0, t0, t1);
1725 tcg_temp_free(t1);
1726 tcg_gen_ext32s_tl(t0, t0);
1727 gen_store_gpr(t0, rt);
1728 opn = "lwl";
1729 break;
1730 case OPC_LWR:
1731 t1 = tcg_temp_new();
1732 tcg_gen_andi_tl(t1, t0, 3);
1733 #ifdef TARGET_WORDS_BIGENDIAN
1734 tcg_gen_xori_tl(t1, t1, 3);
1735 #endif
1736 tcg_gen_shli_tl(t1, t1, 3);
1737 tcg_gen_andi_tl(t0, t0, ~3);
1738 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TEUL);
1739 tcg_gen_shr_tl(t0, t0, t1);
1740 tcg_gen_xori_tl(t1, t1, 31);
1741 t2 = tcg_const_tl(0xfffffffeull);
1742 tcg_gen_shl_tl(t2, t2, t1);
1743 gen_load_gpr(t1, rt);
1744 tcg_gen_and_tl(t1, t1, t2);
1745 tcg_temp_free(t2);
1746 tcg_gen_or_tl(t0, t0, t1);
1747 tcg_temp_free(t1);
1748 tcg_gen_ext32s_tl(t0, t0);
1749 gen_store_gpr(t0, rt);
1750 opn = "lwr";
1751 break;
1752 case OPC_LL:
1753 save_cpu_state(ctx, 1);
1754 op_ld_ll(t0, t0, ctx);
1755 gen_store_gpr(t0, rt);
1756 opn = "ll";
1757 break;
1759 (void)opn; /* avoid a compiler warning */
1760 MIPS_DEBUG("%s %s, %d(%s)", opn, regnames[rt], offset, regnames[base]);
1761 tcg_temp_free(t0);
1764 /* Store */
1765 static void gen_st (DisasContext *ctx, uint32_t opc, int rt,
1766 int base, int16_t offset)
1768 const char *opn = "st";
1769 TCGv t0 = tcg_temp_new();
1770 TCGv t1 = tcg_temp_new();
1772 gen_base_offset_addr(ctx, t0, base, offset);
1773 gen_load_gpr(t1, rt);
1774 switch (opc) {
1775 #if defined(TARGET_MIPS64)
1776 case OPC_SD:
1777 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEQ);
1778 opn = "sd";
1779 break;
1780 case OPC_SDL:
1781 save_cpu_state(ctx, 1);
1782 gen_helper_0e2i(sdl, t1, t0, ctx->mem_idx);
1783 opn = "sdl";
1784 break;
1785 case OPC_SDR:
1786 save_cpu_state(ctx, 1);
1787 gen_helper_0e2i(sdr, t1, t0, ctx->mem_idx);
1788 opn = "sdr";
1789 break;
1790 #endif
1791 case OPC_SW:
1792 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL);
1793 opn = "sw";
1794 break;
1795 case OPC_SH:
1796 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUW);
1797 opn = "sh";
1798 break;
1799 case OPC_SB:
1800 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_8);
1801 opn = "sb";
1802 break;
1803 case OPC_SWL:
1804 save_cpu_state(ctx, 1);
1805 gen_helper_0e2i(swl, t1, t0, ctx->mem_idx);
1806 opn = "swl";
1807 break;
1808 case OPC_SWR:
1809 save_cpu_state(ctx, 1);
1810 gen_helper_0e2i(swr, t1, t0, ctx->mem_idx);
1811 opn = "swr";
1812 break;
1814 (void)opn; /* avoid a compiler warning */
1815 MIPS_DEBUG("%s %s, %d(%s)", opn, regnames[rt], offset, regnames[base]);
1816 tcg_temp_free(t0);
1817 tcg_temp_free(t1);
1821 /* Store conditional */
1822 static void gen_st_cond (DisasContext *ctx, uint32_t opc, int rt,
1823 int base, int16_t offset)
1825 const char *opn = "st_cond";
1826 TCGv t0, t1;
1828 #ifdef CONFIG_USER_ONLY
1829 t0 = tcg_temp_local_new();
1830 t1 = tcg_temp_local_new();
1831 #else
1832 t0 = tcg_temp_new();
1833 t1 = tcg_temp_new();
1834 #endif
1835 gen_base_offset_addr(ctx, t0, base, offset);
1836 gen_load_gpr(t1, rt);
1837 switch (opc) {
1838 #if defined(TARGET_MIPS64)
1839 case OPC_SCD:
1840 save_cpu_state(ctx, 1);
1841 op_st_scd(t1, t0, rt, ctx);
1842 opn = "scd";
1843 break;
1844 #endif
1845 case OPC_SC:
1846 save_cpu_state(ctx, 1);
1847 op_st_sc(t1, t0, rt, ctx);
1848 opn = "sc";
1849 break;
1851 (void)opn; /* avoid a compiler warning */
1852 MIPS_DEBUG("%s %s, %d(%s)", opn, regnames[rt], offset, regnames[base]);
1853 tcg_temp_free(t1);
1854 tcg_temp_free(t0);
1857 /* Load and store */
1858 static void gen_flt_ldst (DisasContext *ctx, uint32_t opc, int ft,
1859 int base, int16_t offset)
1861 const char *opn = "flt_ldst";
1862 TCGv t0 = tcg_temp_new();
1864 gen_base_offset_addr(ctx, t0, base, offset);
1865 /* Don't do NOP if destination is zero: we must perform the actual
1866 memory access. */
1867 switch (opc) {
1868 case OPC_LWC1:
1870 TCGv_i32 fp0 = tcg_temp_new_i32();
1871 tcg_gen_qemu_ld_i32(fp0, t0, ctx->mem_idx, MO_TESL);
1872 gen_store_fpr32(fp0, ft);
1873 tcg_temp_free_i32(fp0);
1875 opn = "lwc1";
1876 break;
1877 case OPC_SWC1:
1879 TCGv_i32 fp0 = tcg_temp_new_i32();
1880 gen_load_fpr32(fp0, ft);
1881 tcg_gen_qemu_st_i32(fp0, t0, ctx->mem_idx, MO_TEUL);
1882 tcg_temp_free_i32(fp0);
1884 opn = "swc1";
1885 break;
1886 case OPC_LDC1:
1888 TCGv_i64 fp0 = tcg_temp_new_i64();
1889 tcg_gen_qemu_ld_i64(fp0, t0, ctx->mem_idx, MO_TEQ);
1890 gen_store_fpr64(ctx, fp0, ft);
1891 tcg_temp_free_i64(fp0);
1893 opn = "ldc1";
1894 break;
1895 case OPC_SDC1:
1897 TCGv_i64 fp0 = tcg_temp_new_i64();
1898 gen_load_fpr64(ctx, fp0, ft);
1899 tcg_gen_qemu_st_i64(fp0, t0, ctx->mem_idx, MO_TEQ);
1900 tcg_temp_free_i64(fp0);
1902 opn = "sdc1";
1903 break;
1904 default:
1905 MIPS_INVAL(opn);
1906 generate_exception(ctx, EXCP_RI);
1907 goto out;
1909 (void)opn; /* avoid a compiler warning */
1910 MIPS_DEBUG("%s %s, %d(%s)", opn, fregnames[ft], offset, regnames[base]);
1911 out:
1912 tcg_temp_free(t0);
1915 static void gen_cop1_ldst(CPUMIPSState *env, DisasContext *ctx,
1916 uint32_t op, int rt, int rs, int16_t imm)
1918 if (env->CP0_Config1 & (1 << CP0C1_FP)) {
1919 check_cp1_enabled(ctx);
1920 gen_flt_ldst(ctx, op, rt, rs, imm);
1921 } else {
1922 generate_exception_err(ctx, EXCP_CpU, 1);
1926 /* Arithmetic with immediate operand */
1927 static void gen_arith_imm(DisasContext *ctx, uint32_t opc,
1928 int rt, int rs, int16_t imm)
1930 target_ulong uimm = (target_long)imm; /* Sign extend to 32/64 bits */
1931 const char *opn = "imm arith";
1933 if (rt == 0 && opc != OPC_ADDI && opc != OPC_DADDI) {
1934 /* If no destination, treat it as a NOP.
1935 For addi, we must generate the overflow exception when needed. */
1936 MIPS_DEBUG("NOP");
1937 return;
1939 switch (opc) {
1940 case OPC_ADDI:
1942 TCGv t0 = tcg_temp_local_new();
1943 TCGv t1 = tcg_temp_new();
1944 TCGv t2 = tcg_temp_new();
1945 int l1 = gen_new_label();
1947 gen_load_gpr(t1, rs);
1948 tcg_gen_addi_tl(t0, t1, uimm);
1949 tcg_gen_ext32s_tl(t0, t0);
1951 tcg_gen_xori_tl(t1, t1, ~uimm);
1952 tcg_gen_xori_tl(t2, t0, uimm);
1953 tcg_gen_and_tl(t1, t1, t2);
1954 tcg_temp_free(t2);
1955 tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
1956 tcg_temp_free(t1);
1957 /* operands of same sign, result different sign */
1958 generate_exception(ctx, EXCP_OVERFLOW);
1959 gen_set_label(l1);
1960 tcg_gen_ext32s_tl(t0, t0);
1961 gen_store_gpr(t0, rt);
1962 tcg_temp_free(t0);
1964 opn = "addi";
1965 break;
1966 case OPC_ADDIU:
1967 if (rs != 0) {
1968 tcg_gen_addi_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
1969 tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]);
1970 } else {
1971 tcg_gen_movi_tl(cpu_gpr[rt], uimm);
1973 opn = "addiu";
1974 break;
1975 #if defined(TARGET_MIPS64)
1976 case OPC_DADDI:
1978 TCGv t0 = tcg_temp_local_new();
1979 TCGv t1 = tcg_temp_new();
1980 TCGv t2 = tcg_temp_new();
1981 int l1 = gen_new_label();
1983 gen_load_gpr(t1, rs);
1984 tcg_gen_addi_tl(t0, t1, uimm);
1986 tcg_gen_xori_tl(t1, t1, ~uimm);
1987 tcg_gen_xori_tl(t2, t0, uimm);
1988 tcg_gen_and_tl(t1, t1, t2);
1989 tcg_temp_free(t2);
1990 tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
1991 tcg_temp_free(t1);
1992 /* operands of same sign, result different sign */
1993 generate_exception(ctx, EXCP_OVERFLOW);
1994 gen_set_label(l1);
1995 gen_store_gpr(t0, rt);
1996 tcg_temp_free(t0);
1998 opn = "daddi";
1999 break;
2000 case OPC_DADDIU:
2001 if (rs != 0) {
2002 tcg_gen_addi_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
2003 } else {
2004 tcg_gen_movi_tl(cpu_gpr[rt], uimm);
2006 opn = "daddiu";
2007 break;
2008 #endif
2010 (void)opn; /* avoid a compiler warning */
2011 MIPS_DEBUG("%s %s, %s, " TARGET_FMT_lx, opn, regnames[rt], regnames[rs], uimm);
2014 /* Logic with immediate operand */
2015 static void gen_logic_imm(DisasContext *ctx, uint32_t opc,
2016 int rt, int rs, int16_t imm)
2018 target_ulong uimm;
2020 if (rt == 0) {
2021 /* If no destination, treat it as a NOP. */
2022 MIPS_DEBUG("NOP");
2023 return;
2025 uimm = (uint16_t)imm;
2026 switch (opc) {
2027 case OPC_ANDI:
2028 if (likely(rs != 0))
2029 tcg_gen_andi_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
2030 else
2031 tcg_gen_movi_tl(cpu_gpr[rt], 0);
2032 MIPS_DEBUG("andi %s, %s, " TARGET_FMT_lx, regnames[rt],
2033 regnames[rs], uimm);
2034 break;
2035 case OPC_ORI:
2036 if (rs != 0)
2037 tcg_gen_ori_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
2038 else
2039 tcg_gen_movi_tl(cpu_gpr[rt], uimm);
2040 MIPS_DEBUG("ori %s, %s, " TARGET_FMT_lx, regnames[rt],
2041 regnames[rs], uimm);
2042 break;
2043 case OPC_XORI:
2044 if (likely(rs != 0))
2045 tcg_gen_xori_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
2046 else
2047 tcg_gen_movi_tl(cpu_gpr[rt], uimm);
2048 MIPS_DEBUG("xori %s, %s, " TARGET_FMT_lx, regnames[rt],
2049 regnames[rs], uimm);
2050 break;
2051 case OPC_LUI:
2052 tcg_gen_movi_tl(cpu_gpr[rt], imm << 16);
2053 MIPS_DEBUG("lui %s, " TARGET_FMT_lx, regnames[rt], uimm);
2054 break;
2056 default:
2057 MIPS_DEBUG("Unknown logical immediate opcode %08x", opc);
2058 break;
2062 /* Set on less than with immediate operand */
2063 static void gen_slt_imm(DisasContext *ctx, uint32_t opc,
2064 int rt, int rs, int16_t imm)
2066 target_ulong uimm = (target_long)imm; /* Sign extend to 32/64 bits */
2067 const char *opn = "imm arith";
2068 TCGv t0;
2070 if (rt == 0) {
2071 /* If no destination, treat it as a NOP. */
2072 MIPS_DEBUG("NOP");
2073 return;
2075 t0 = tcg_temp_new();
2076 gen_load_gpr(t0, rs);
2077 switch (opc) {
2078 case OPC_SLTI:
2079 tcg_gen_setcondi_tl(TCG_COND_LT, cpu_gpr[rt], t0, uimm);
2080 opn = "slti";
2081 break;
2082 case OPC_SLTIU:
2083 tcg_gen_setcondi_tl(TCG_COND_LTU, cpu_gpr[rt], t0, uimm);
2084 opn = "sltiu";
2085 break;
2087 (void)opn; /* avoid a compiler warning */
2088 MIPS_DEBUG("%s %s, %s, " TARGET_FMT_lx, opn, regnames[rt], regnames[rs], uimm);
2089 tcg_temp_free(t0);
2092 /* Shifts with immediate operand */
2093 static void gen_shift_imm(DisasContext *ctx, uint32_t opc,
2094 int rt, int rs, int16_t imm)
2096 target_ulong uimm = ((uint16_t)imm) & 0x1f;
2097 const char *opn = "imm shift";
2098 TCGv t0;
2100 if (rt == 0) {
2101 /* If no destination, treat it as a NOP. */
2102 MIPS_DEBUG("NOP");
2103 return;
2106 t0 = tcg_temp_new();
2107 gen_load_gpr(t0, rs);
2108 switch (opc) {
2109 case OPC_SLL:
2110 tcg_gen_shli_tl(t0, t0, uimm);
2111 tcg_gen_ext32s_tl(cpu_gpr[rt], t0);
2112 opn = "sll";
2113 break;
2114 case OPC_SRA:
2115 tcg_gen_sari_tl(cpu_gpr[rt], t0, uimm);
2116 opn = "sra";
2117 break;
2118 case OPC_SRL:
2119 if (uimm != 0) {
2120 tcg_gen_ext32u_tl(t0, t0);
2121 tcg_gen_shri_tl(cpu_gpr[rt], t0, uimm);
2122 } else {
2123 tcg_gen_ext32s_tl(cpu_gpr[rt], t0);
2125 opn = "srl";
2126 break;
2127 case OPC_ROTR:
2128 if (uimm != 0) {
2129 TCGv_i32 t1 = tcg_temp_new_i32();
2131 tcg_gen_trunc_tl_i32(t1, t0);
2132 tcg_gen_rotri_i32(t1, t1, uimm);
2133 tcg_gen_ext_i32_tl(cpu_gpr[rt], t1);
2134 tcg_temp_free_i32(t1);
2135 } else {
2136 tcg_gen_ext32s_tl(cpu_gpr[rt], t0);
2138 opn = "rotr";
2139 break;
2140 #if defined(TARGET_MIPS64)
2141 case OPC_DSLL:
2142 tcg_gen_shli_tl(cpu_gpr[rt], t0, uimm);
2143 opn = "dsll";
2144 break;
2145 case OPC_DSRA:
2146 tcg_gen_sari_tl(cpu_gpr[rt], t0, uimm);
2147 opn = "dsra";
2148 break;
2149 case OPC_DSRL:
2150 tcg_gen_shri_tl(cpu_gpr[rt], t0, uimm);
2151 opn = "dsrl";
2152 break;
2153 case OPC_DROTR:
2154 if (uimm != 0) {
2155 tcg_gen_rotri_tl(cpu_gpr[rt], t0, uimm);
2156 } else {
2157 tcg_gen_mov_tl(cpu_gpr[rt], t0);
2159 opn = "drotr";
2160 break;
2161 case OPC_DSLL32:
2162 tcg_gen_shli_tl(cpu_gpr[rt], t0, uimm + 32);
2163 opn = "dsll32";
2164 break;
2165 case OPC_DSRA32:
2166 tcg_gen_sari_tl(cpu_gpr[rt], t0, uimm + 32);
2167 opn = "dsra32";
2168 break;
2169 case OPC_DSRL32:
2170 tcg_gen_shri_tl(cpu_gpr[rt], t0, uimm + 32);
2171 opn = "dsrl32";
2172 break;
2173 case OPC_DROTR32:
2174 tcg_gen_rotri_tl(cpu_gpr[rt], t0, uimm + 32);
2175 opn = "drotr32";
2176 break;
2177 #endif
2179 (void)opn; /* avoid a compiler warning */
2180 MIPS_DEBUG("%s %s, %s, " TARGET_FMT_lx, opn, regnames[rt], regnames[rs], uimm);
2181 tcg_temp_free(t0);
2184 /* Arithmetic */
2185 static void gen_arith(DisasContext *ctx, uint32_t opc,
2186 int rd, int rs, int rt)
2188 const char *opn = "arith";
2190 if (rd == 0 && opc != OPC_ADD && opc != OPC_SUB
2191 && opc != OPC_DADD && opc != OPC_DSUB) {
2192 /* If no destination, treat it as a NOP.
2193 For add & sub, we must generate the overflow exception when needed. */
2194 MIPS_DEBUG("NOP");
2195 return;
2198 switch (opc) {
2199 case OPC_ADD:
2201 TCGv t0 = tcg_temp_local_new();
2202 TCGv t1 = tcg_temp_new();
2203 TCGv t2 = tcg_temp_new();
2204 int l1 = gen_new_label();
2206 gen_load_gpr(t1, rs);
2207 gen_load_gpr(t2, rt);
2208 tcg_gen_add_tl(t0, t1, t2);
2209 tcg_gen_ext32s_tl(t0, t0);
2210 tcg_gen_xor_tl(t1, t1, t2);
2211 tcg_gen_xor_tl(t2, t0, t2);
2212 tcg_gen_andc_tl(t1, t2, t1);
2213 tcg_temp_free(t2);
2214 tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
2215 tcg_temp_free(t1);
2216 /* operands of same sign, result different sign */
2217 generate_exception(ctx, EXCP_OVERFLOW);
2218 gen_set_label(l1);
2219 gen_store_gpr(t0, rd);
2220 tcg_temp_free(t0);
2222 opn = "add";
2223 break;
2224 case OPC_ADDU:
2225 if (rs != 0 && rt != 0) {
2226 tcg_gen_add_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2227 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
2228 } else if (rs == 0 && rt != 0) {
2229 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rt]);
2230 } else if (rs != 0 && rt == 0) {
2231 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
2232 } else {
2233 tcg_gen_movi_tl(cpu_gpr[rd], 0);
2235 opn = "addu";
2236 break;
2237 case OPC_SUB:
2239 TCGv t0 = tcg_temp_local_new();
2240 TCGv t1 = tcg_temp_new();
2241 TCGv t2 = tcg_temp_new();
2242 int l1 = gen_new_label();
2244 gen_load_gpr(t1, rs);
2245 gen_load_gpr(t2, rt);
2246 tcg_gen_sub_tl(t0, t1, t2);
2247 tcg_gen_ext32s_tl(t0, t0);
2248 tcg_gen_xor_tl(t2, t1, t2);
2249 tcg_gen_xor_tl(t1, t0, t1);
2250 tcg_gen_and_tl(t1, t1, t2);
2251 tcg_temp_free(t2);
2252 tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
2253 tcg_temp_free(t1);
2254 /* operands of different sign, first operand and result different sign */
2255 generate_exception(ctx, EXCP_OVERFLOW);
2256 gen_set_label(l1);
2257 gen_store_gpr(t0, rd);
2258 tcg_temp_free(t0);
2260 opn = "sub";
2261 break;
2262 case OPC_SUBU:
2263 if (rs != 0 && rt != 0) {
2264 tcg_gen_sub_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2265 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
2266 } else if (rs == 0 && rt != 0) {
2267 tcg_gen_neg_tl(cpu_gpr[rd], cpu_gpr[rt]);
2268 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
2269 } else if (rs != 0 && rt == 0) {
2270 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
2271 } else {
2272 tcg_gen_movi_tl(cpu_gpr[rd], 0);
2274 opn = "subu";
2275 break;
2276 #if defined(TARGET_MIPS64)
2277 case OPC_DADD:
2279 TCGv t0 = tcg_temp_local_new();
2280 TCGv t1 = tcg_temp_new();
2281 TCGv t2 = tcg_temp_new();
2282 int l1 = gen_new_label();
2284 gen_load_gpr(t1, rs);
2285 gen_load_gpr(t2, rt);
2286 tcg_gen_add_tl(t0, t1, t2);
2287 tcg_gen_xor_tl(t1, t1, t2);
2288 tcg_gen_xor_tl(t2, t0, t2);
2289 tcg_gen_andc_tl(t1, t2, t1);
2290 tcg_temp_free(t2);
2291 tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
2292 tcg_temp_free(t1);
2293 /* operands of same sign, result different sign */
2294 generate_exception(ctx, EXCP_OVERFLOW);
2295 gen_set_label(l1);
2296 gen_store_gpr(t0, rd);
2297 tcg_temp_free(t0);
2299 opn = "dadd";
2300 break;
2301 case OPC_DADDU:
2302 if (rs != 0 && rt != 0) {
2303 tcg_gen_add_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2304 } else if (rs == 0 && rt != 0) {
2305 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rt]);
2306 } else if (rs != 0 && rt == 0) {
2307 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
2308 } else {
2309 tcg_gen_movi_tl(cpu_gpr[rd], 0);
2311 opn = "daddu";
2312 break;
2313 case OPC_DSUB:
2315 TCGv t0 = tcg_temp_local_new();
2316 TCGv t1 = tcg_temp_new();
2317 TCGv t2 = tcg_temp_new();
2318 int l1 = gen_new_label();
2320 gen_load_gpr(t1, rs);
2321 gen_load_gpr(t2, rt);
2322 tcg_gen_sub_tl(t0, t1, t2);
2323 tcg_gen_xor_tl(t2, t1, t2);
2324 tcg_gen_xor_tl(t1, t0, t1);
2325 tcg_gen_and_tl(t1, t1, t2);
2326 tcg_temp_free(t2);
2327 tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
2328 tcg_temp_free(t1);
2329 /* operands of different sign, first operand and result different sign */
2330 generate_exception(ctx, EXCP_OVERFLOW);
2331 gen_set_label(l1);
2332 gen_store_gpr(t0, rd);
2333 tcg_temp_free(t0);
2335 opn = "dsub";
2336 break;
2337 case OPC_DSUBU:
2338 if (rs != 0 && rt != 0) {
2339 tcg_gen_sub_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2340 } else if (rs == 0 && rt != 0) {
2341 tcg_gen_neg_tl(cpu_gpr[rd], cpu_gpr[rt]);
2342 } else if (rs != 0 && rt == 0) {
2343 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
2344 } else {
2345 tcg_gen_movi_tl(cpu_gpr[rd], 0);
2347 opn = "dsubu";
2348 break;
2349 #endif
2350 case OPC_MUL:
2351 if (likely(rs != 0 && rt != 0)) {
2352 tcg_gen_mul_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2353 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
2354 } else {
2355 tcg_gen_movi_tl(cpu_gpr[rd], 0);
2357 opn = "mul";
2358 break;
2360 (void)opn; /* avoid a compiler warning */
2361 MIPS_DEBUG("%s %s, %s, %s", opn, regnames[rd], regnames[rs], regnames[rt]);
2364 /* Conditional move */
2365 static void gen_cond_move(DisasContext *ctx, uint32_t opc,
2366 int rd, int rs, int rt)
2368 const char *opn = "cond move";
2369 TCGv t0, t1, t2;
2371 if (rd == 0) {
2372 /* If no destination, treat it as a NOP. */
2373 MIPS_DEBUG("NOP");
2374 return;
2377 t0 = tcg_temp_new();
2378 gen_load_gpr(t0, rt);
2379 t1 = tcg_const_tl(0);
2380 t2 = tcg_temp_new();
2381 gen_load_gpr(t2, rs);
2382 switch (opc) {
2383 case OPC_MOVN:
2384 tcg_gen_movcond_tl(TCG_COND_NE, cpu_gpr[rd], t0, t1, t2, cpu_gpr[rd]);
2385 opn = "movn";
2386 break;
2387 case OPC_MOVZ:
2388 tcg_gen_movcond_tl(TCG_COND_EQ, cpu_gpr[rd], t0, t1, t2, cpu_gpr[rd]);
2389 opn = "movz";
2390 break;
2392 tcg_temp_free(t2);
2393 tcg_temp_free(t1);
2394 tcg_temp_free(t0);
2396 (void)opn; /* avoid a compiler warning */
2397 MIPS_DEBUG("%s %s, %s, %s", opn, regnames[rd], regnames[rs], regnames[rt]);
2400 /* Logic */
2401 static void gen_logic(DisasContext *ctx, uint32_t opc,
2402 int rd, int rs, int rt)
2404 const char *opn = "logic";
2406 if (rd == 0) {
2407 /* If no destination, treat it as a NOP. */
2408 MIPS_DEBUG("NOP");
2409 return;
2412 switch (opc) {
2413 case OPC_AND:
2414 if (likely(rs != 0 && rt != 0)) {
2415 tcg_gen_and_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2416 } else {
2417 tcg_gen_movi_tl(cpu_gpr[rd], 0);
2419 opn = "and";
2420 break;
2421 case OPC_NOR:
2422 if (rs != 0 && rt != 0) {
2423 tcg_gen_nor_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2424 } else if (rs == 0 && rt != 0) {
2425 tcg_gen_not_tl(cpu_gpr[rd], cpu_gpr[rt]);
2426 } else if (rs != 0 && rt == 0) {
2427 tcg_gen_not_tl(cpu_gpr[rd], cpu_gpr[rs]);
2428 } else {
2429 tcg_gen_movi_tl(cpu_gpr[rd], ~((target_ulong)0));
2431 opn = "nor";
2432 break;
2433 case OPC_OR:
2434 if (likely(rs != 0 && rt != 0)) {
2435 tcg_gen_or_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2436 } else if (rs == 0 && rt != 0) {
2437 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rt]);
2438 } else if (rs != 0 && rt == 0) {
2439 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
2440 } else {
2441 tcg_gen_movi_tl(cpu_gpr[rd], 0);
2443 opn = "or";
2444 break;
2445 case OPC_XOR:
2446 if (likely(rs != 0 && rt != 0)) {
2447 tcg_gen_xor_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2448 } else if (rs == 0 && rt != 0) {
2449 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rt]);
2450 } else if (rs != 0 && rt == 0) {
2451 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
2452 } else {
2453 tcg_gen_movi_tl(cpu_gpr[rd], 0);
2455 opn = "xor";
2456 break;
2458 (void)opn; /* avoid a compiler warning */
2459 MIPS_DEBUG("%s %s, %s, %s", opn, regnames[rd], regnames[rs], regnames[rt]);
2462 /* Set on lower than */
2463 static void gen_slt(DisasContext *ctx, uint32_t opc,
2464 int rd, int rs, int rt)
2466 const char *opn = "slt";
2467 TCGv t0, t1;
2469 if (rd == 0) {
2470 /* If no destination, treat it as a NOP. */
2471 MIPS_DEBUG("NOP");
2472 return;
2475 t0 = tcg_temp_new();
2476 t1 = tcg_temp_new();
2477 gen_load_gpr(t0, rs);
2478 gen_load_gpr(t1, rt);
2479 switch (opc) {
2480 case OPC_SLT:
2481 tcg_gen_setcond_tl(TCG_COND_LT, cpu_gpr[rd], t0, t1);
2482 opn = "slt";
2483 break;
2484 case OPC_SLTU:
2485 tcg_gen_setcond_tl(TCG_COND_LTU, cpu_gpr[rd], t0, t1);
2486 opn = "sltu";
2487 break;
2489 (void)opn; /* avoid a compiler warning */
2490 MIPS_DEBUG("%s %s, %s, %s", opn, regnames[rd], regnames[rs], regnames[rt]);
2491 tcg_temp_free(t0);
2492 tcg_temp_free(t1);
2495 /* Shifts */
2496 static void gen_shift(DisasContext *ctx, uint32_t opc,
2497 int rd, int rs, int rt)
2499 const char *opn = "shifts";
2500 TCGv t0, t1;
2502 if (rd == 0) {
2503 /* If no destination, treat it as a NOP.
2504 For add & sub, we must generate the overflow exception when needed. */
2505 MIPS_DEBUG("NOP");
2506 return;
2509 t0 = tcg_temp_new();
2510 t1 = tcg_temp_new();
2511 gen_load_gpr(t0, rs);
2512 gen_load_gpr(t1, rt);
2513 switch (opc) {
2514 case OPC_SLLV:
2515 tcg_gen_andi_tl(t0, t0, 0x1f);
2516 tcg_gen_shl_tl(t0, t1, t0);
2517 tcg_gen_ext32s_tl(cpu_gpr[rd], t0);
2518 opn = "sllv";
2519 break;
2520 case OPC_SRAV:
2521 tcg_gen_andi_tl(t0, t0, 0x1f);
2522 tcg_gen_sar_tl(cpu_gpr[rd], t1, t0);
2523 opn = "srav";
2524 break;
2525 case OPC_SRLV:
2526 tcg_gen_ext32u_tl(t1, t1);
2527 tcg_gen_andi_tl(t0, t0, 0x1f);
2528 tcg_gen_shr_tl(t0, t1, t0);
2529 tcg_gen_ext32s_tl(cpu_gpr[rd], t0);
2530 opn = "srlv";
2531 break;
2532 case OPC_ROTRV:
2534 TCGv_i32 t2 = tcg_temp_new_i32();
2535 TCGv_i32 t3 = tcg_temp_new_i32();
2537 tcg_gen_trunc_tl_i32(t2, t0);
2538 tcg_gen_trunc_tl_i32(t3, t1);
2539 tcg_gen_andi_i32(t2, t2, 0x1f);
2540 tcg_gen_rotr_i32(t2, t3, t2);
2541 tcg_gen_ext_i32_tl(cpu_gpr[rd], t2);
2542 tcg_temp_free_i32(t2);
2543 tcg_temp_free_i32(t3);
2544 opn = "rotrv";
2546 break;
2547 #if defined(TARGET_MIPS64)
2548 case OPC_DSLLV:
2549 tcg_gen_andi_tl(t0, t0, 0x3f);
2550 tcg_gen_shl_tl(cpu_gpr[rd], t1, t0);
2551 opn = "dsllv";
2552 break;
2553 case OPC_DSRAV:
2554 tcg_gen_andi_tl(t0, t0, 0x3f);
2555 tcg_gen_sar_tl(cpu_gpr[rd], t1, t0);
2556 opn = "dsrav";
2557 break;
2558 case OPC_DSRLV:
2559 tcg_gen_andi_tl(t0, t0, 0x3f);
2560 tcg_gen_shr_tl(cpu_gpr[rd], t1, t0);
2561 opn = "dsrlv";
2562 break;
2563 case OPC_DROTRV:
2564 tcg_gen_andi_tl(t0, t0, 0x3f);
2565 tcg_gen_rotr_tl(cpu_gpr[rd], t1, t0);
2566 opn = "drotrv";
2567 break;
2568 #endif
2570 (void)opn; /* avoid a compiler warning */
2571 MIPS_DEBUG("%s %s, %s, %s", opn, regnames[rd], regnames[rs], regnames[rt]);
2572 tcg_temp_free(t0);
2573 tcg_temp_free(t1);
2576 /* Arithmetic on HI/LO registers */
2577 static void gen_HILO(DisasContext *ctx, uint32_t opc, int acc, int reg)
2579 const char *opn = "hilo";
2581 if (reg == 0 && (opc == OPC_MFHI || opc == OPC_MFLO)) {
2582 /* Treat as NOP. */
2583 MIPS_DEBUG("NOP");
2584 return;
2587 if (acc != 0) {
2588 check_dsp(ctx);
2591 switch (opc) {
2592 case OPC_MFHI:
2593 #if defined(TARGET_MIPS64)
2594 if (acc != 0) {
2595 tcg_gen_ext32s_tl(cpu_gpr[reg], cpu_HI[acc]);
2596 } else
2597 #endif
2599 tcg_gen_mov_tl(cpu_gpr[reg], cpu_HI[acc]);
2601 opn = "mfhi";
2602 break;
2603 case OPC_MFLO:
2604 #if defined(TARGET_MIPS64)
2605 if (acc != 0) {
2606 tcg_gen_ext32s_tl(cpu_gpr[reg], cpu_LO[acc]);
2607 } else
2608 #endif
2610 tcg_gen_mov_tl(cpu_gpr[reg], cpu_LO[acc]);
2612 opn = "mflo";
2613 break;
2614 case OPC_MTHI:
2615 if (reg != 0) {
2616 #if defined(TARGET_MIPS64)
2617 if (acc != 0) {
2618 tcg_gen_ext32s_tl(cpu_HI[acc], cpu_gpr[reg]);
2619 } else
2620 #endif
2622 tcg_gen_mov_tl(cpu_HI[acc], cpu_gpr[reg]);
2624 } else {
2625 tcg_gen_movi_tl(cpu_HI[acc], 0);
2627 opn = "mthi";
2628 break;
2629 case OPC_MTLO:
2630 if (reg != 0) {
2631 #if defined(TARGET_MIPS64)
2632 if (acc != 0) {
2633 tcg_gen_ext32s_tl(cpu_LO[acc], cpu_gpr[reg]);
2634 } else
2635 #endif
2637 tcg_gen_mov_tl(cpu_LO[acc], cpu_gpr[reg]);
2639 } else {
2640 tcg_gen_movi_tl(cpu_LO[acc], 0);
2642 opn = "mtlo";
2643 break;
2645 (void)opn; /* avoid a compiler warning */
2646 MIPS_DEBUG("%s %s", opn, regnames[reg]);
2649 static void gen_muldiv(DisasContext *ctx, uint32_t opc,
2650 int acc, int rs, int rt)
2652 const char *opn = "mul/div";
2653 TCGv t0, t1;
2655 t0 = tcg_temp_new();
2656 t1 = tcg_temp_new();
2658 gen_load_gpr(t0, rs);
2659 gen_load_gpr(t1, rt);
2661 if (acc != 0) {
2662 check_dsp(ctx);
2665 switch (opc) {
2666 case OPC_DIV:
2668 TCGv t2 = tcg_temp_new();
2669 TCGv t3 = tcg_temp_new();
2670 tcg_gen_ext32s_tl(t0, t0);
2671 tcg_gen_ext32s_tl(t1, t1);
2672 tcg_gen_setcondi_tl(TCG_COND_EQ, t2, t0, INT_MIN);
2673 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, -1);
2674 tcg_gen_and_tl(t2, t2, t3);
2675 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, 0);
2676 tcg_gen_or_tl(t2, t2, t3);
2677 tcg_gen_movi_tl(t3, 0);
2678 tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, t3, t2, t1);
2679 tcg_gen_div_tl(cpu_LO[acc], t0, t1);
2680 tcg_gen_rem_tl(cpu_HI[acc], t0, t1);
2681 tcg_gen_ext32s_tl(cpu_LO[acc], cpu_LO[acc]);
2682 tcg_gen_ext32s_tl(cpu_HI[acc], cpu_HI[acc]);
2683 tcg_temp_free(t3);
2684 tcg_temp_free(t2);
2686 opn = "div";
2687 break;
2688 case OPC_DIVU:
2690 TCGv t2 = tcg_const_tl(0);
2691 TCGv t3 = tcg_const_tl(1);
2692 tcg_gen_ext32u_tl(t0, t0);
2693 tcg_gen_ext32u_tl(t1, t1);
2694 tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1, t2, t3, t1);
2695 tcg_gen_divu_tl(cpu_LO[acc], t0, t1);
2696 tcg_gen_remu_tl(cpu_HI[acc], t0, t1);
2697 tcg_gen_ext32s_tl(cpu_LO[acc], cpu_LO[acc]);
2698 tcg_gen_ext32s_tl(cpu_HI[acc], cpu_HI[acc]);
2699 tcg_temp_free(t3);
2700 tcg_temp_free(t2);
2702 opn = "divu";
2703 break;
2704 case OPC_MULT:
2706 TCGv_i32 t2 = tcg_temp_new_i32();
2707 TCGv_i32 t3 = tcg_temp_new_i32();
2708 tcg_gen_trunc_tl_i32(t2, t0);
2709 tcg_gen_trunc_tl_i32(t3, t1);
2710 tcg_gen_muls2_i32(t2, t3, t2, t3);
2711 tcg_gen_ext_i32_tl(cpu_LO[acc], t2);
2712 tcg_gen_ext_i32_tl(cpu_HI[acc], t3);
2713 tcg_temp_free_i32(t2);
2714 tcg_temp_free_i32(t3);
2716 opn = "mult";
2717 break;
2718 case OPC_MULTU:
2720 TCGv_i32 t2 = tcg_temp_new_i32();
2721 TCGv_i32 t3 = tcg_temp_new_i32();
2722 tcg_gen_trunc_tl_i32(t2, t0);
2723 tcg_gen_trunc_tl_i32(t3, t1);
2724 tcg_gen_mulu2_i32(t2, t3, t2, t3);
2725 tcg_gen_ext_i32_tl(cpu_LO[acc], t2);
2726 tcg_gen_ext_i32_tl(cpu_HI[acc], t3);
2727 tcg_temp_free_i32(t2);
2728 tcg_temp_free_i32(t3);
2730 opn = "multu";
2731 break;
2732 #if defined(TARGET_MIPS64)
2733 case OPC_DDIV:
2735 TCGv t2 = tcg_temp_new();
2736 TCGv t3 = tcg_temp_new();
2737 tcg_gen_setcondi_tl(TCG_COND_EQ, t2, t0, -1LL << 63);
2738 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, -1LL);
2739 tcg_gen_and_tl(t2, t2, t3);
2740 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, 0);
2741 tcg_gen_or_tl(t2, t2, t3);
2742 tcg_gen_movi_tl(t3, 0);
2743 tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, t3, t2, t1);
2744 tcg_gen_div_tl(cpu_LO[acc], t0, t1);
2745 tcg_gen_rem_tl(cpu_HI[acc], t0, t1);
2746 tcg_temp_free(t3);
2747 tcg_temp_free(t2);
2749 opn = "ddiv";
2750 break;
2751 case OPC_DDIVU:
2753 TCGv t2 = tcg_const_tl(0);
2754 TCGv t3 = tcg_const_tl(1);
2755 tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1, t2, t3, t1);
2756 tcg_gen_divu_i64(cpu_LO[acc], t0, t1);
2757 tcg_gen_remu_i64(cpu_HI[acc], t0, t1);
2758 tcg_temp_free(t3);
2759 tcg_temp_free(t2);
2761 opn = "ddivu";
2762 break;
2763 case OPC_DMULT:
2764 tcg_gen_muls2_i64(cpu_LO[acc], cpu_HI[acc], t0, t1);
2765 opn = "dmult";
2766 break;
2767 case OPC_DMULTU:
2768 tcg_gen_mulu2_i64(cpu_LO[acc], cpu_HI[acc], t0, t1);
2769 opn = "dmultu";
2770 break;
2771 #endif
2772 case OPC_MADD:
2774 TCGv_i64 t2 = tcg_temp_new_i64();
2775 TCGv_i64 t3 = tcg_temp_new_i64();
2777 tcg_gen_ext_tl_i64(t2, t0);
2778 tcg_gen_ext_tl_i64(t3, t1);
2779 tcg_gen_mul_i64(t2, t2, t3);
2780 tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]);
2781 tcg_gen_add_i64(t2, t2, t3);
2782 tcg_temp_free_i64(t3);
2783 tcg_gen_trunc_i64_tl(t0, t2);
2784 tcg_gen_shri_i64(t2, t2, 32);
2785 tcg_gen_trunc_i64_tl(t1, t2);
2786 tcg_temp_free_i64(t2);
2787 tcg_gen_ext32s_tl(cpu_LO[acc], t0);
2788 tcg_gen_ext32s_tl(cpu_HI[acc], t1);
2790 opn = "madd";
2791 break;
2792 case OPC_MADDU:
2794 TCGv_i64 t2 = tcg_temp_new_i64();
2795 TCGv_i64 t3 = tcg_temp_new_i64();
2797 tcg_gen_ext32u_tl(t0, t0);
2798 tcg_gen_ext32u_tl(t1, t1);
2799 tcg_gen_extu_tl_i64(t2, t0);
2800 tcg_gen_extu_tl_i64(t3, t1);
2801 tcg_gen_mul_i64(t2, t2, t3);
2802 tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]);
2803 tcg_gen_add_i64(t2, t2, t3);
2804 tcg_temp_free_i64(t3);
2805 tcg_gen_trunc_i64_tl(t0, t2);
2806 tcg_gen_shri_i64(t2, t2, 32);
2807 tcg_gen_trunc_i64_tl(t1, t2);
2808 tcg_temp_free_i64(t2);
2809 tcg_gen_ext32s_tl(cpu_LO[acc], t0);
2810 tcg_gen_ext32s_tl(cpu_HI[acc], t1);
2812 opn = "maddu";
2813 break;
2814 case OPC_MSUB:
2816 TCGv_i64 t2 = tcg_temp_new_i64();
2817 TCGv_i64 t3 = tcg_temp_new_i64();
2819 tcg_gen_ext_tl_i64(t2, t0);
2820 tcg_gen_ext_tl_i64(t3, t1);
2821 tcg_gen_mul_i64(t2, t2, t3);
2822 tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]);
2823 tcg_gen_sub_i64(t2, t3, t2);
2824 tcg_temp_free_i64(t3);
2825 tcg_gen_trunc_i64_tl(t0, t2);
2826 tcg_gen_shri_i64(t2, t2, 32);
2827 tcg_gen_trunc_i64_tl(t1, t2);
2828 tcg_temp_free_i64(t2);
2829 tcg_gen_ext32s_tl(cpu_LO[acc], t0);
2830 tcg_gen_ext32s_tl(cpu_HI[acc], t1);
2832 opn = "msub";
2833 break;
2834 case OPC_MSUBU:
2836 TCGv_i64 t2 = tcg_temp_new_i64();
2837 TCGv_i64 t3 = tcg_temp_new_i64();
2839 tcg_gen_ext32u_tl(t0, t0);
2840 tcg_gen_ext32u_tl(t1, t1);
2841 tcg_gen_extu_tl_i64(t2, t0);
2842 tcg_gen_extu_tl_i64(t3, t1);
2843 tcg_gen_mul_i64(t2, t2, t3);
2844 tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]);
2845 tcg_gen_sub_i64(t2, t3, t2);
2846 tcg_temp_free_i64(t3);
2847 tcg_gen_trunc_i64_tl(t0, t2);
2848 tcg_gen_shri_i64(t2, t2, 32);
2849 tcg_gen_trunc_i64_tl(t1, t2);
2850 tcg_temp_free_i64(t2);
2851 tcg_gen_ext32s_tl(cpu_LO[acc], t0);
2852 tcg_gen_ext32s_tl(cpu_HI[acc], t1);
2854 opn = "msubu";
2855 break;
2856 default:
2857 MIPS_INVAL(opn);
2858 generate_exception(ctx, EXCP_RI);
2859 goto out;
2861 (void)opn; /* avoid a compiler warning */
2862 MIPS_DEBUG("%s %s %s", opn, regnames[rs], regnames[rt]);
2863 out:
2864 tcg_temp_free(t0);
2865 tcg_temp_free(t1);
2868 static void gen_mul_vr54xx (DisasContext *ctx, uint32_t opc,
2869 int rd, int rs, int rt)
2871 const char *opn = "mul vr54xx";
2872 TCGv t0 = tcg_temp_new();
2873 TCGv t1 = tcg_temp_new();
2875 gen_load_gpr(t0, rs);
2876 gen_load_gpr(t1, rt);
2878 switch (opc) {
2879 case OPC_VR54XX_MULS:
2880 gen_helper_muls(t0, cpu_env, t0, t1);
2881 opn = "muls";
2882 break;
2883 case OPC_VR54XX_MULSU:
2884 gen_helper_mulsu(t0, cpu_env, t0, t1);
2885 opn = "mulsu";
2886 break;
2887 case OPC_VR54XX_MACC:
2888 gen_helper_macc(t0, cpu_env, t0, t1);
2889 opn = "macc";
2890 break;
2891 case OPC_VR54XX_MACCU:
2892 gen_helper_maccu(t0, cpu_env, t0, t1);
2893 opn = "maccu";
2894 break;
2895 case OPC_VR54XX_MSAC:
2896 gen_helper_msac(t0, cpu_env, t0, t1);
2897 opn = "msac";
2898 break;
2899 case OPC_VR54XX_MSACU:
2900 gen_helper_msacu(t0, cpu_env, t0, t1);
2901 opn = "msacu";
2902 break;
2903 case OPC_VR54XX_MULHI:
2904 gen_helper_mulhi(t0, cpu_env, t0, t1);
2905 opn = "mulhi";
2906 break;
2907 case OPC_VR54XX_MULHIU:
2908 gen_helper_mulhiu(t0, cpu_env, t0, t1);
2909 opn = "mulhiu";
2910 break;
2911 case OPC_VR54XX_MULSHI:
2912 gen_helper_mulshi(t0, cpu_env, t0, t1);
2913 opn = "mulshi";
2914 break;
2915 case OPC_VR54XX_MULSHIU:
2916 gen_helper_mulshiu(t0, cpu_env, t0, t1);
2917 opn = "mulshiu";
2918 break;
2919 case OPC_VR54XX_MACCHI:
2920 gen_helper_macchi(t0, cpu_env, t0, t1);
2921 opn = "macchi";
2922 break;
2923 case OPC_VR54XX_MACCHIU:
2924 gen_helper_macchiu(t0, cpu_env, t0, t1);
2925 opn = "macchiu";
2926 break;
2927 case OPC_VR54XX_MSACHI:
2928 gen_helper_msachi(t0, cpu_env, t0, t1);
2929 opn = "msachi";
2930 break;
2931 case OPC_VR54XX_MSACHIU:
2932 gen_helper_msachiu(t0, cpu_env, t0, t1);
2933 opn = "msachiu";
2934 break;
2935 default:
2936 MIPS_INVAL("mul vr54xx");
2937 generate_exception(ctx, EXCP_RI);
2938 goto out;
2940 gen_store_gpr(t0, rd);
2941 (void)opn; /* avoid a compiler warning */
2942 MIPS_DEBUG("%s %s, %s, %s", opn, regnames[rd], regnames[rs], regnames[rt]);
2944 out:
2945 tcg_temp_free(t0);
2946 tcg_temp_free(t1);
2949 static void gen_cl (DisasContext *ctx, uint32_t opc,
2950 int rd, int rs)
2952 const char *opn = "CLx";
2953 TCGv t0;
2955 if (rd == 0) {
2956 /* Treat as NOP. */
2957 MIPS_DEBUG("NOP");
2958 return;
2960 t0 = tcg_temp_new();
2961 gen_load_gpr(t0, rs);
2962 switch (opc) {
2963 case OPC_CLO:
2964 gen_helper_clo(cpu_gpr[rd], t0);
2965 opn = "clo";
2966 break;
2967 case OPC_CLZ:
2968 gen_helper_clz(cpu_gpr[rd], t0);
2969 opn = "clz";
2970 break;
2971 #if defined(TARGET_MIPS64)
2972 case OPC_DCLO:
2973 gen_helper_dclo(cpu_gpr[rd], t0);
2974 opn = "dclo";
2975 break;
2976 case OPC_DCLZ:
2977 gen_helper_dclz(cpu_gpr[rd], t0);
2978 opn = "dclz";
2979 break;
2980 #endif
2982 (void)opn; /* avoid a compiler warning */
2983 MIPS_DEBUG("%s %s, %s", opn, regnames[rd], regnames[rs]);
2984 tcg_temp_free(t0);
2987 /* Godson integer instructions */
2988 static void gen_loongson_integer(DisasContext *ctx, uint32_t opc,
2989 int rd, int rs, int rt)
2991 const char *opn = "loongson";
2992 TCGv t0, t1;
2994 if (rd == 0) {
2995 /* Treat as NOP. */
2996 MIPS_DEBUG("NOP");
2997 return;
3000 switch (opc) {
3001 case OPC_MULT_G_2E:
3002 case OPC_MULT_G_2F:
3003 case OPC_MULTU_G_2E:
3004 case OPC_MULTU_G_2F:
3005 #if defined(TARGET_MIPS64)
3006 case OPC_DMULT_G_2E:
3007 case OPC_DMULT_G_2F:
3008 case OPC_DMULTU_G_2E:
3009 case OPC_DMULTU_G_2F:
3010 #endif
3011 t0 = tcg_temp_new();
3012 t1 = tcg_temp_new();
3013 break;
3014 default:
3015 t0 = tcg_temp_local_new();
3016 t1 = tcg_temp_local_new();
3017 break;
3020 gen_load_gpr(t0, rs);
3021 gen_load_gpr(t1, rt);
3023 switch (opc) {
3024 case OPC_MULT_G_2E:
3025 case OPC_MULT_G_2F:
3026 tcg_gen_mul_tl(cpu_gpr[rd], t0, t1);
3027 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3028 opn = "mult.g";
3029 break;
3030 case OPC_MULTU_G_2E:
3031 case OPC_MULTU_G_2F:
3032 tcg_gen_ext32u_tl(t0, t0);
3033 tcg_gen_ext32u_tl(t1, t1);
3034 tcg_gen_mul_tl(cpu_gpr[rd], t0, t1);
3035 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3036 opn = "multu.g";
3037 break;
3038 case OPC_DIV_G_2E:
3039 case OPC_DIV_G_2F:
3041 int l1 = gen_new_label();
3042 int l2 = gen_new_label();
3043 int l3 = gen_new_label();
3044 tcg_gen_ext32s_tl(t0, t0);
3045 tcg_gen_ext32s_tl(t1, t1);
3046 tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
3047 tcg_gen_movi_tl(cpu_gpr[rd], 0);
3048 tcg_gen_br(l3);
3049 gen_set_label(l1);
3050 tcg_gen_brcondi_tl(TCG_COND_NE, t0, INT_MIN, l2);
3051 tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1, l2);
3052 tcg_gen_mov_tl(cpu_gpr[rd], t0);
3053 tcg_gen_br(l3);
3054 gen_set_label(l2);
3055 tcg_gen_div_tl(cpu_gpr[rd], t0, t1);
3056 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3057 gen_set_label(l3);
3059 opn = "div.g";
3060 break;
3061 case OPC_DIVU_G_2E:
3062 case OPC_DIVU_G_2F:
3064 int l1 = gen_new_label();
3065 int l2 = gen_new_label();
3066 tcg_gen_ext32u_tl(t0, t0);
3067 tcg_gen_ext32u_tl(t1, t1);
3068 tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
3069 tcg_gen_movi_tl(cpu_gpr[rd], 0);
3070 tcg_gen_br(l2);
3071 gen_set_label(l1);
3072 tcg_gen_divu_tl(cpu_gpr[rd], t0, t1);
3073 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3074 gen_set_label(l2);
3076 opn = "divu.g";
3077 break;
3078 case OPC_MOD_G_2E:
3079 case OPC_MOD_G_2F:
3081 int l1 = gen_new_label();
3082 int l2 = gen_new_label();
3083 int l3 = gen_new_label();
3084 tcg_gen_ext32u_tl(t0, t0);
3085 tcg_gen_ext32u_tl(t1, t1);
3086 tcg_gen_brcondi_tl(TCG_COND_EQ, t1, 0, l1);
3087 tcg_gen_brcondi_tl(TCG_COND_NE, t0, INT_MIN, l2);
3088 tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1, l2);
3089 gen_set_label(l1);
3090 tcg_gen_movi_tl(cpu_gpr[rd], 0);
3091 tcg_gen_br(l3);
3092 gen_set_label(l2);
3093 tcg_gen_rem_tl(cpu_gpr[rd], t0, t1);
3094 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3095 gen_set_label(l3);
3097 opn = "mod.g";
3098 break;
3099 case OPC_MODU_G_2E:
3100 case OPC_MODU_G_2F:
3102 int l1 = gen_new_label();
3103 int l2 = gen_new_label();
3104 tcg_gen_ext32u_tl(t0, t0);
3105 tcg_gen_ext32u_tl(t1, t1);
3106 tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
3107 tcg_gen_movi_tl(cpu_gpr[rd], 0);
3108 tcg_gen_br(l2);
3109 gen_set_label(l1);
3110 tcg_gen_remu_tl(cpu_gpr[rd], t0, t1);
3111 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3112 gen_set_label(l2);
3114 opn = "modu.g";
3115 break;
3116 #if defined(TARGET_MIPS64)
3117 case OPC_DMULT_G_2E:
3118 case OPC_DMULT_G_2F:
3119 tcg_gen_mul_tl(cpu_gpr[rd], t0, t1);
3120 opn = "dmult.g";
3121 break;
3122 case OPC_DMULTU_G_2E:
3123 case OPC_DMULTU_G_2F:
3124 tcg_gen_mul_tl(cpu_gpr[rd], t0, t1);
3125 opn = "dmultu.g";
3126 break;
3127 case OPC_DDIV_G_2E:
3128 case OPC_DDIV_G_2F:
3130 int l1 = gen_new_label();
3131 int l2 = gen_new_label();
3132 int l3 = gen_new_label();
3133 tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
3134 tcg_gen_movi_tl(cpu_gpr[rd], 0);
3135 tcg_gen_br(l3);
3136 gen_set_label(l1);
3137 tcg_gen_brcondi_tl(TCG_COND_NE, t0, -1LL << 63, l2);
3138 tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1LL, l2);
3139 tcg_gen_mov_tl(cpu_gpr[rd], t0);
3140 tcg_gen_br(l3);
3141 gen_set_label(l2);
3142 tcg_gen_div_tl(cpu_gpr[rd], t0, t1);
3143 gen_set_label(l3);
3145 opn = "ddiv.g";
3146 break;
3147 case OPC_DDIVU_G_2E:
3148 case OPC_DDIVU_G_2F:
3150 int l1 = gen_new_label();
3151 int l2 = gen_new_label();
3152 tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
3153 tcg_gen_movi_tl(cpu_gpr[rd], 0);
3154 tcg_gen_br(l2);
3155 gen_set_label(l1);
3156 tcg_gen_divu_tl(cpu_gpr[rd], t0, t1);
3157 gen_set_label(l2);
3159 opn = "ddivu.g";
3160 break;
3161 case OPC_DMOD_G_2E:
3162 case OPC_DMOD_G_2F:
3164 int l1 = gen_new_label();
3165 int l2 = gen_new_label();
3166 int l3 = gen_new_label();
3167 tcg_gen_brcondi_tl(TCG_COND_EQ, t1, 0, l1);
3168 tcg_gen_brcondi_tl(TCG_COND_NE, t0, -1LL << 63, l2);
3169 tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1LL, l2);
3170 gen_set_label(l1);
3171 tcg_gen_movi_tl(cpu_gpr[rd], 0);
3172 tcg_gen_br(l3);
3173 gen_set_label(l2);
3174 tcg_gen_rem_tl(cpu_gpr[rd], t0, t1);
3175 gen_set_label(l3);
3177 opn = "dmod.g";
3178 break;
3179 case OPC_DMODU_G_2E:
3180 case OPC_DMODU_G_2F:
3182 int l1 = gen_new_label();
3183 int l2 = gen_new_label();
3184 tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
3185 tcg_gen_movi_tl(cpu_gpr[rd], 0);
3186 tcg_gen_br(l2);
3187 gen_set_label(l1);
3188 tcg_gen_remu_tl(cpu_gpr[rd], t0, t1);
3189 gen_set_label(l2);
3191 opn = "dmodu.g";
3192 break;
3193 #endif
3196 (void)opn; /* avoid a compiler warning */
3197 MIPS_DEBUG("%s %s, %s", opn, regnames[rd], regnames[rs]);
3198 tcg_temp_free(t0);
3199 tcg_temp_free(t1);
3202 /* Loongson multimedia instructions */
3203 static void gen_loongson_multimedia(DisasContext *ctx, int rd, int rs, int rt)
3205 const char *opn = "loongson_cp2";
3206 uint32_t opc, shift_max;
3207 TCGv_i64 t0, t1;
3209 opc = MASK_LMI(ctx->opcode);
3210 switch (opc) {
3211 case OPC_ADD_CP2:
3212 case OPC_SUB_CP2:
3213 case OPC_DADD_CP2:
3214 case OPC_DSUB_CP2:
3215 t0 = tcg_temp_local_new_i64();
3216 t1 = tcg_temp_local_new_i64();
3217 break;
3218 default:
3219 t0 = tcg_temp_new_i64();
3220 t1 = tcg_temp_new_i64();
3221 break;
3224 gen_load_fpr64(ctx, t0, rs);
3225 gen_load_fpr64(ctx, t1, rt);
3227 #define LMI_HELPER(UP, LO) \
3228 case OPC_##UP: gen_helper_##LO(t0, t0, t1); opn = #LO; break
3229 #define LMI_HELPER_1(UP, LO) \
3230 case OPC_##UP: gen_helper_##LO(t0, t0); opn = #LO; break
3231 #define LMI_DIRECT(UP, LO, OP) \
3232 case OPC_##UP: tcg_gen_##OP##_i64(t0, t0, t1); opn = #LO; break
3234 switch (opc) {
3235 LMI_HELPER(PADDSH, paddsh);
3236 LMI_HELPER(PADDUSH, paddush);
3237 LMI_HELPER(PADDH, paddh);
3238 LMI_HELPER(PADDW, paddw);
3239 LMI_HELPER(PADDSB, paddsb);
3240 LMI_HELPER(PADDUSB, paddusb);
3241 LMI_HELPER(PADDB, paddb);
3243 LMI_HELPER(PSUBSH, psubsh);
3244 LMI_HELPER(PSUBUSH, psubush);
3245 LMI_HELPER(PSUBH, psubh);
3246 LMI_HELPER(PSUBW, psubw);
3247 LMI_HELPER(PSUBSB, psubsb);
3248 LMI_HELPER(PSUBUSB, psubusb);
3249 LMI_HELPER(PSUBB, psubb);
3251 LMI_HELPER(PSHUFH, pshufh);
3252 LMI_HELPER(PACKSSWH, packsswh);
3253 LMI_HELPER(PACKSSHB, packsshb);
3254 LMI_HELPER(PACKUSHB, packushb);
3256 LMI_HELPER(PUNPCKLHW, punpcklhw);
3257 LMI_HELPER(PUNPCKHHW, punpckhhw);
3258 LMI_HELPER(PUNPCKLBH, punpcklbh);
3259 LMI_HELPER(PUNPCKHBH, punpckhbh);
3260 LMI_HELPER(PUNPCKLWD, punpcklwd);
3261 LMI_HELPER(PUNPCKHWD, punpckhwd);
3263 LMI_HELPER(PAVGH, pavgh);
3264 LMI_HELPER(PAVGB, pavgb);
3265 LMI_HELPER(PMAXSH, pmaxsh);
3266 LMI_HELPER(PMINSH, pminsh);
3267 LMI_HELPER(PMAXUB, pmaxub);
3268 LMI_HELPER(PMINUB, pminub);
3270 LMI_HELPER(PCMPEQW, pcmpeqw);
3271 LMI_HELPER(PCMPGTW, pcmpgtw);
3272 LMI_HELPER(PCMPEQH, pcmpeqh);
3273 LMI_HELPER(PCMPGTH, pcmpgth);
3274 LMI_HELPER(PCMPEQB, pcmpeqb);
3275 LMI_HELPER(PCMPGTB, pcmpgtb);
3277 LMI_HELPER(PSLLW, psllw);
3278 LMI_HELPER(PSLLH, psllh);
3279 LMI_HELPER(PSRLW, psrlw);
3280 LMI_HELPER(PSRLH, psrlh);
3281 LMI_HELPER(PSRAW, psraw);
3282 LMI_HELPER(PSRAH, psrah);
3284 LMI_HELPER(PMULLH, pmullh);
3285 LMI_HELPER(PMULHH, pmulhh);
3286 LMI_HELPER(PMULHUH, pmulhuh);
3287 LMI_HELPER(PMADDHW, pmaddhw);
3289 LMI_HELPER(PASUBUB, pasubub);
3290 LMI_HELPER_1(BIADD, biadd);
3291 LMI_HELPER_1(PMOVMSKB, pmovmskb);
3293 LMI_DIRECT(PADDD, paddd, add);
3294 LMI_DIRECT(PSUBD, psubd, sub);
3295 LMI_DIRECT(XOR_CP2, xor, xor);
3296 LMI_DIRECT(NOR_CP2, nor, nor);
3297 LMI_DIRECT(AND_CP2, and, and);
3298 LMI_DIRECT(PANDN, pandn, andc);
3299 LMI_DIRECT(OR, or, or);
3301 case OPC_PINSRH_0:
3302 tcg_gen_deposit_i64(t0, t0, t1, 0, 16);
3303 opn = "pinsrh_0";
3304 break;
3305 case OPC_PINSRH_1:
3306 tcg_gen_deposit_i64(t0, t0, t1, 16, 16);
3307 opn = "pinsrh_1";
3308 break;
3309 case OPC_PINSRH_2:
3310 tcg_gen_deposit_i64(t0, t0, t1, 32, 16);
3311 opn = "pinsrh_2";
3312 break;
3313 case OPC_PINSRH_3:
3314 tcg_gen_deposit_i64(t0, t0, t1, 48, 16);
3315 opn = "pinsrh_3";
3316 break;
3318 case OPC_PEXTRH:
3319 tcg_gen_andi_i64(t1, t1, 3);
3320 tcg_gen_shli_i64(t1, t1, 4);
3321 tcg_gen_shr_i64(t0, t0, t1);
3322 tcg_gen_ext16u_i64(t0, t0);
3323 opn = "pextrh";
3324 break;
3326 case OPC_ADDU_CP2:
3327 tcg_gen_add_i64(t0, t0, t1);
3328 tcg_gen_ext32s_i64(t0, t0);
3329 opn = "addu";
3330 break;
3331 case OPC_SUBU_CP2:
3332 tcg_gen_sub_i64(t0, t0, t1);
3333 tcg_gen_ext32s_i64(t0, t0);
3334 opn = "addu";
3335 break;
3337 case OPC_SLL_CP2:
3338 opn = "sll";
3339 shift_max = 32;
3340 goto do_shift;
3341 case OPC_SRL_CP2:
3342 opn = "srl";
3343 shift_max = 32;
3344 goto do_shift;
3345 case OPC_SRA_CP2:
3346 opn = "sra";
3347 shift_max = 32;
3348 goto do_shift;
3349 case OPC_DSLL_CP2:
3350 opn = "dsll";
3351 shift_max = 64;
3352 goto do_shift;
3353 case OPC_DSRL_CP2:
3354 opn = "dsrl";
3355 shift_max = 64;
3356 goto do_shift;
3357 case OPC_DSRA_CP2:
3358 opn = "dsra";
3359 shift_max = 64;
3360 goto do_shift;
3361 do_shift:
3362 /* Make sure shift count isn't TCG undefined behaviour. */
3363 tcg_gen_andi_i64(t1, t1, shift_max - 1);
3365 switch (opc) {
3366 case OPC_SLL_CP2:
3367 case OPC_DSLL_CP2:
3368 tcg_gen_shl_i64(t0, t0, t1);
3369 break;
3370 case OPC_SRA_CP2:
3371 case OPC_DSRA_CP2:
3372 /* Since SRA is UndefinedResult without sign-extended inputs,
3373 we can treat SRA and DSRA the same. */
3374 tcg_gen_sar_i64(t0, t0, t1);
3375 break;
3376 case OPC_SRL_CP2:
3377 /* We want to shift in zeros for SRL; zero-extend first. */
3378 tcg_gen_ext32u_i64(t0, t0);
3379 /* FALLTHRU */
3380 case OPC_DSRL_CP2:
3381 tcg_gen_shr_i64(t0, t0, t1);
3382 break;
3385 if (shift_max == 32) {
3386 tcg_gen_ext32s_i64(t0, t0);
3389 /* Shifts larger than MAX produce zero. */
3390 tcg_gen_setcondi_i64(TCG_COND_LTU, t1, t1, shift_max);
3391 tcg_gen_neg_i64(t1, t1);
3392 tcg_gen_and_i64(t0, t0, t1);
3393 break;
3395 case OPC_ADD_CP2:
3396 case OPC_DADD_CP2:
3398 TCGv_i64 t2 = tcg_temp_new_i64();
3399 int lab = gen_new_label();
3401 tcg_gen_mov_i64(t2, t0);
3402 tcg_gen_add_i64(t0, t1, t2);
3403 if (opc == OPC_ADD_CP2) {
3404 tcg_gen_ext32s_i64(t0, t0);
3406 tcg_gen_xor_i64(t1, t1, t2);
3407 tcg_gen_xor_i64(t2, t2, t0);
3408 tcg_gen_andc_i64(t1, t2, t1);
3409 tcg_temp_free_i64(t2);
3410 tcg_gen_brcondi_i64(TCG_COND_GE, t1, 0, lab);
3411 generate_exception(ctx, EXCP_OVERFLOW);
3412 gen_set_label(lab);
3414 opn = (opc == OPC_ADD_CP2 ? "add" : "dadd");
3415 break;
3418 case OPC_SUB_CP2:
3419 case OPC_DSUB_CP2:
3421 TCGv_i64 t2 = tcg_temp_new_i64();
3422 int lab = gen_new_label();
3424 tcg_gen_mov_i64(t2, t0);
3425 tcg_gen_sub_i64(t0, t1, t2);
3426 if (opc == OPC_SUB_CP2) {
3427 tcg_gen_ext32s_i64(t0, t0);
3429 tcg_gen_xor_i64(t1, t1, t2);
3430 tcg_gen_xor_i64(t2, t2, t0);
3431 tcg_gen_and_i64(t1, t1, t2);
3432 tcg_temp_free_i64(t2);
3433 tcg_gen_brcondi_i64(TCG_COND_GE, t1, 0, lab);
3434 generate_exception(ctx, EXCP_OVERFLOW);
3435 gen_set_label(lab);
3437 opn = (opc == OPC_SUB_CP2 ? "sub" : "dsub");
3438 break;
3441 case OPC_PMULUW:
3442 tcg_gen_ext32u_i64(t0, t0);
3443 tcg_gen_ext32u_i64(t1, t1);
3444 tcg_gen_mul_i64(t0, t0, t1);
3445 opn = "pmuluw";
3446 break;
3448 case OPC_SEQU_CP2:
3449 case OPC_SEQ_CP2:
3450 case OPC_SLTU_CP2:
3451 case OPC_SLT_CP2:
3452 case OPC_SLEU_CP2:
3453 case OPC_SLE_CP2:
3454 /* ??? Document is unclear: Set FCC[CC]. Does that mean the
3455 FD field is the CC field? */
3456 default:
3457 MIPS_INVAL(opn);
3458 generate_exception(ctx, EXCP_RI);
3459 return;
3462 #undef LMI_HELPER
3463 #undef LMI_DIRECT
3465 gen_store_fpr64(ctx, t0, rd);
3467 (void)opn; /* avoid a compiler warning */
3468 MIPS_DEBUG("%s %s, %s, %s", opn,
3469 fregnames[rd], fregnames[rs], fregnames[rt]);
3470 tcg_temp_free_i64(t0);
3471 tcg_temp_free_i64(t1);
3474 /* Traps */
3475 static void gen_trap (DisasContext *ctx, uint32_t opc,
3476 int rs, int rt, int16_t imm)
3478 int cond;
3479 TCGv t0 = tcg_temp_new();
3480 TCGv t1 = tcg_temp_new();
3482 cond = 0;
3483 /* Load needed operands */
3484 switch (opc) {
3485 case OPC_TEQ:
3486 case OPC_TGE:
3487 case OPC_TGEU:
3488 case OPC_TLT:
3489 case OPC_TLTU:
3490 case OPC_TNE:
3491 /* Compare two registers */
3492 if (rs != rt) {
3493 gen_load_gpr(t0, rs);
3494 gen_load_gpr(t1, rt);
3495 cond = 1;
3497 break;
3498 case OPC_TEQI:
3499 case OPC_TGEI:
3500 case OPC_TGEIU:
3501 case OPC_TLTI:
3502 case OPC_TLTIU:
3503 case OPC_TNEI:
3504 /* Compare register to immediate */
3505 if (rs != 0 || imm != 0) {
3506 gen_load_gpr(t0, rs);
3507 tcg_gen_movi_tl(t1, (int32_t)imm);
3508 cond = 1;
3510 break;
3512 if (cond == 0) {
3513 switch (opc) {
3514 case OPC_TEQ: /* rs == rs */
3515 case OPC_TEQI: /* r0 == 0 */
3516 case OPC_TGE: /* rs >= rs */
3517 case OPC_TGEI: /* r0 >= 0 */
3518 case OPC_TGEU: /* rs >= rs unsigned */
3519 case OPC_TGEIU: /* r0 >= 0 unsigned */
3520 /* Always trap */
3521 generate_exception(ctx, EXCP_TRAP);
3522 break;
3523 case OPC_TLT: /* rs < rs */
3524 case OPC_TLTI: /* r0 < 0 */
3525 case OPC_TLTU: /* rs < rs unsigned */
3526 case OPC_TLTIU: /* r0 < 0 unsigned */
3527 case OPC_TNE: /* rs != rs */
3528 case OPC_TNEI: /* r0 != 0 */
3529 /* Never trap: treat as NOP. */
3530 break;
3532 } else {
3533 int l1 = gen_new_label();
3535 switch (opc) {
3536 case OPC_TEQ:
3537 case OPC_TEQI:
3538 tcg_gen_brcond_tl(TCG_COND_NE, t0, t1, l1);
3539 break;
3540 case OPC_TGE:
3541 case OPC_TGEI:
3542 tcg_gen_brcond_tl(TCG_COND_LT, t0, t1, l1);
3543 break;
3544 case OPC_TGEU:
3545 case OPC_TGEIU:
3546 tcg_gen_brcond_tl(TCG_COND_LTU, t0, t1, l1);
3547 break;
3548 case OPC_TLT:
3549 case OPC_TLTI:
3550 tcg_gen_brcond_tl(TCG_COND_GE, t0, t1, l1);
3551 break;
3552 case OPC_TLTU:
3553 case OPC_TLTIU:
3554 tcg_gen_brcond_tl(TCG_COND_GEU, t0, t1, l1);
3555 break;
3556 case OPC_TNE:
3557 case OPC_TNEI:
3558 tcg_gen_brcond_tl(TCG_COND_EQ, t0, t1, l1);
3559 break;
3561 generate_exception(ctx, EXCP_TRAP);
3562 gen_set_label(l1);
3564 tcg_temp_free(t0);
3565 tcg_temp_free(t1);
3568 static inline void gen_goto_tb(DisasContext *ctx, int n, target_ulong dest)
3570 TranslationBlock *tb;
3571 tb = ctx->tb;
3572 if ((tb->pc & TARGET_PAGE_MASK) == (dest & TARGET_PAGE_MASK) &&
3573 likely(!ctx->singlestep_enabled)) {
3574 tcg_gen_goto_tb(n);
3575 gen_save_pc(dest);
3576 tcg_gen_exit_tb((uintptr_t)tb + n);
3577 } else {
3578 gen_save_pc(dest);
3579 if (ctx->singlestep_enabled) {
3580 save_cpu_state(ctx, 0);
3581 gen_helper_0e0i(raise_exception, EXCP_DEBUG);
3583 tcg_gen_exit_tb(0);
3587 /* Branches (before delay slot) */
3588 static void gen_compute_branch (DisasContext *ctx, uint32_t opc,
3589 int insn_bytes,
3590 int rs, int rt, int32_t offset)
3592 target_ulong btgt = -1;
3593 int blink = 0;
3594 int bcond_compute = 0;
3595 TCGv t0 = tcg_temp_new();
3596 TCGv t1 = tcg_temp_new();
3598 if (ctx->hflags & MIPS_HFLAG_BMASK) {
3599 #ifdef MIPS_DEBUG_DISAS
3600 LOG_DISAS("Branch in delay slot at PC 0x" TARGET_FMT_lx "\n", ctx->pc);
3601 #endif
3602 generate_exception(ctx, EXCP_RI);
3603 goto out;
3606 /* Load needed operands */
3607 switch (opc) {
3608 case OPC_BEQ:
3609 case OPC_BEQL:
3610 case OPC_BNE:
3611 case OPC_BNEL:
3612 /* Compare two registers */
3613 if (rs != rt) {
3614 gen_load_gpr(t0, rs);
3615 gen_load_gpr(t1, rt);
3616 bcond_compute = 1;
3618 btgt = ctx->pc + insn_bytes + offset;
3619 break;
3620 case OPC_BGEZ:
3621 case OPC_BGEZAL:
3622 case OPC_BGEZALS:
3623 case OPC_BGEZALL:
3624 case OPC_BGEZL:
3625 case OPC_BGTZ:
3626 case OPC_BGTZL:
3627 case OPC_BLEZ:
3628 case OPC_BLEZL:
3629 case OPC_BLTZ:
3630 case OPC_BLTZAL:
3631 case OPC_BLTZALS:
3632 case OPC_BLTZALL:
3633 case OPC_BLTZL:
3634 /* Compare to zero */
3635 if (rs != 0) {
3636 gen_load_gpr(t0, rs);
3637 bcond_compute = 1;
3639 btgt = ctx->pc + insn_bytes + offset;
3640 break;
3641 case OPC_BPOSGE32:
3642 #if defined(TARGET_MIPS64)
3643 case OPC_BPOSGE64:
3644 tcg_gen_andi_tl(t0, cpu_dspctrl, 0x7F);
3645 #else
3646 tcg_gen_andi_tl(t0, cpu_dspctrl, 0x3F);
3647 #endif
3648 bcond_compute = 1;
3649 btgt = ctx->pc + insn_bytes + offset;
3650 break;
3651 case OPC_J:
3652 case OPC_JAL:
3653 case OPC_JALX:
3654 case OPC_JALS:
3655 case OPC_JALXS:
3656 /* Jump to immediate */
3657 btgt = ((ctx->pc + insn_bytes) & (int32_t)0xF0000000) | (uint32_t)offset;
3658 break;
3659 case OPC_JR:
3660 case OPC_JALR:
3661 case OPC_JALRC:
3662 case OPC_JALRS:
3663 /* Jump to register */
3664 if (offset != 0 && offset != 16) {
3665 /* Hint = 0 is JR/JALR, hint 16 is JR.HB/JALR.HB, the
3666 others are reserved. */
3667 MIPS_INVAL("jump hint");
3668 generate_exception(ctx, EXCP_RI);
3669 goto out;
3671 gen_load_gpr(btarget, rs);
3672 break;
3673 default:
3674 MIPS_INVAL("branch/jump");
3675 generate_exception(ctx, EXCP_RI);
3676 goto out;
3678 if (bcond_compute == 0) {
3679 /* No condition to be computed */
3680 switch (opc) {
3681 case OPC_BEQ: /* rx == rx */
3682 case OPC_BEQL: /* rx == rx likely */
3683 case OPC_BGEZ: /* 0 >= 0 */
3684 case OPC_BGEZL: /* 0 >= 0 likely */
3685 case OPC_BLEZ: /* 0 <= 0 */
3686 case OPC_BLEZL: /* 0 <= 0 likely */
3687 /* Always take */
3688 ctx->hflags |= MIPS_HFLAG_B;
3689 MIPS_DEBUG("balways");
3690 break;
3691 case OPC_BGEZALS:
3692 case OPC_BGEZAL: /* 0 >= 0 */
3693 case OPC_BGEZALL: /* 0 >= 0 likely */
3694 ctx->hflags |= (opc == OPC_BGEZALS
3695 ? MIPS_HFLAG_BDS16
3696 : MIPS_HFLAG_BDS32);
3697 /* Always take and link */
3698 blink = 31;
3699 ctx->hflags |= MIPS_HFLAG_B;
3700 MIPS_DEBUG("balways and link");
3701 break;
3702 case OPC_BNE: /* rx != rx */
3703 case OPC_BGTZ: /* 0 > 0 */
3704 case OPC_BLTZ: /* 0 < 0 */
3705 /* Treat as NOP. */
3706 MIPS_DEBUG("bnever (NOP)");
3707 goto out;
3708 case OPC_BLTZALS:
3709 case OPC_BLTZAL: /* 0 < 0 */
3710 ctx->hflags |= (opc == OPC_BLTZALS
3711 ? MIPS_HFLAG_BDS16
3712 : MIPS_HFLAG_BDS32);
3713 /* Handle as an unconditional branch to get correct delay
3714 slot checking. */
3715 blink = 31;
3716 btgt = ctx->pc + (opc == OPC_BLTZALS ? 6 : 8);
3717 ctx->hflags |= MIPS_HFLAG_B;
3718 MIPS_DEBUG("bnever and link");
3719 break;
3720 case OPC_BLTZALL: /* 0 < 0 likely */
3721 tcg_gen_movi_tl(cpu_gpr[31], ctx->pc + 8);
3722 /* Skip the instruction in the delay slot */
3723 MIPS_DEBUG("bnever, link and skip");
3724 ctx->pc += 4;
3725 goto out;
3726 case OPC_BNEL: /* rx != rx likely */
3727 case OPC_BGTZL: /* 0 > 0 likely */
3728 case OPC_BLTZL: /* 0 < 0 likely */
3729 /* Skip the instruction in the delay slot */
3730 MIPS_DEBUG("bnever and skip");
3731 ctx->pc += 4;
3732 goto out;
3733 case OPC_J:
3734 ctx->hflags |= MIPS_HFLAG_B;
3735 MIPS_DEBUG("j " TARGET_FMT_lx, btgt);
3736 break;
3737 case OPC_JALXS:
3738 case OPC_JALX:
3739 ctx->hflags |= MIPS_HFLAG_BX;
3740 /* Fallthrough */
3741 case OPC_JALS:
3742 case OPC_JAL:
3743 blink = 31;
3744 ctx->hflags |= MIPS_HFLAG_B;
3745 ctx->hflags |= ((opc == OPC_JALS || opc == OPC_JALXS)
3746 ? MIPS_HFLAG_BDS16
3747 : MIPS_HFLAG_BDS32);
3748 MIPS_DEBUG("jal " TARGET_FMT_lx, btgt);
3749 break;
3750 case OPC_JR:
3751 ctx->hflags |= MIPS_HFLAG_BR;
3752 if (insn_bytes == 4)
3753 ctx->hflags |= MIPS_HFLAG_BDS32;
3754 MIPS_DEBUG("jr %s", regnames[rs]);
3755 break;
3756 case OPC_JALRS:
3757 case OPC_JALR:
3758 case OPC_JALRC:
3759 blink = rt;
3760 ctx->hflags |= MIPS_HFLAG_BR;
3761 ctx->hflags |= (opc == OPC_JALRS
3762 ? MIPS_HFLAG_BDS16
3763 : MIPS_HFLAG_BDS32);
3764 MIPS_DEBUG("jalr %s, %s", regnames[rt], regnames[rs]);
3765 break;
3766 default:
3767 MIPS_INVAL("branch/jump");
3768 generate_exception(ctx, EXCP_RI);
3769 goto out;
3771 } else {
3772 switch (opc) {
3773 case OPC_BEQ:
3774 tcg_gen_setcond_tl(TCG_COND_EQ, bcond, t0, t1);
3775 MIPS_DEBUG("beq %s, %s, " TARGET_FMT_lx,
3776 regnames[rs], regnames[rt], btgt);
3777 goto not_likely;
3778 case OPC_BEQL:
3779 tcg_gen_setcond_tl(TCG_COND_EQ, bcond, t0, t1);
3780 MIPS_DEBUG("beql %s, %s, " TARGET_FMT_lx,
3781 regnames[rs], regnames[rt], btgt);
3782 goto likely;
3783 case OPC_BNE:
3784 tcg_gen_setcond_tl(TCG_COND_NE, bcond, t0, t1);
3785 MIPS_DEBUG("bne %s, %s, " TARGET_FMT_lx,
3786 regnames[rs], regnames[rt], btgt);
3787 goto not_likely;
3788 case OPC_BNEL:
3789 tcg_gen_setcond_tl(TCG_COND_NE, bcond, t0, t1);
3790 MIPS_DEBUG("bnel %s, %s, " TARGET_FMT_lx,
3791 regnames[rs], regnames[rt], btgt);
3792 goto likely;
3793 case OPC_BGEZ:
3794 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 0);
3795 MIPS_DEBUG("bgez %s, " TARGET_FMT_lx, regnames[rs], btgt);
3796 goto not_likely;
3797 case OPC_BGEZL:
3798 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 0);
3799 MIPS_DEBUG("bgezl %s, " TARGET_FMT_lx, regnames[rs], btgt);
3800 goto likely;
3801 case OPC_BGEZALS:
3802 case OPC_BGEZAL:
3803 ctx->hflags |= (opc == OPC_BGEZALS
3804 ? MIPS_HFLAG_BDS16
3805 : MIPS_HFLAG_BDS32);
3806 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 0);
3807 MIPS_DEBUG("bgezal %s, " TARGET_FMT_lx, regnames[rs], btgt);
3808 blink = 31;
3809 goto not_likely;
3810 case OPC_BGEZALL:
3811 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 0);
3812 blink = 31;
3813 MIPS_DEBUG("bgezall %s, " TARGET_FMT_lx, regnames[rs], btgt);
3814 goto likely;
3815 case OPC_BGTZ:
3816 tcg_gen_setcondi_tl(TCG_COND_GT, bcond, t0, 0);
3817 MIPS_DEBUG("bgtz %s, " TARGET_FMT_lx, regnames[rs], btgt);
3818 goto not_likely;
3819 case OPC_BGTZL:
3820 tcg_gen_setcondi_tl(TCG_COND_GT, bcond, t0, 0);
3821 MIPS_DEBUG("bgtzl %s, " TARGET_FMT_lx, regnames[rs], btgt);
3822 goto likely;
3823 case OPC_BLEZ:
3824 tcg_gen_setcondi_tl(TCG_COND_LE, bcond, t0, 0);
3825 MIPS_DEBUG("blez %s, " TARGET_FMT_lx, regnames[rs], btgt);
3826 goto not_likely;
3827 case OPC_BLEZL:
3828 tcg_gen_setcondi_tl(TCG_COND_LE, bcond, t0, 0);
3829 MIPS_DEBUG("blezl %s, " TARGET_FMT_lx, regnames[rs], btgt);
3830 goto likely;
3831 case OPC_BLTZ:
3832 tcg_gen_setcondi_tl(TCG_COND_LT, bcond, t0, 0);
3833 MIPS_DEBUG("bltz %s, " TARGET_FMT_lx, regnames[rs], btgt);
3834 goto not_likely;
3835 case OPC_BLTZL:
3836 tcg_gen_setcondi_tl(TCG_COND_LT, bcond, t0, 0);
3837 MIPS_DEBUG("bltzl %s, " TARGET_FMT_lx, regnames[rs], btgt);
3838 goto likely;
3839 case OPC_BPOSGE32:
3840 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 32);
3841 MIPS_DEBUG("bposge32 " TARGET_FMT_lx, btgt);
3842 goto not_likely;
3843 #if defined(TARGET_MIPS64)
3844 case OPC_BPOSGE64:
3845 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 64);
3846 MIPS_DEBUG("bposge64 " TARGET_FMT_lx, btgt);
3847 goto not_likely;
3848 #endif
3849 case OPC_BLTZALS:
3850 case OPC_BLTZAL:
3851 ctx->hflags |= (opc == OPC_BLTZALS
3852 ? MIPS_HFLAG_BDS16
3853 : MIPS_HFLAG_BDS32);
3854 tcg_gen_setcondi_tl(TCG_COND_LT, bcond, t0, 0);
3855 blink = 31;
3856 MIPS_DEBUG("bltzal %s, " TARGET_FMT_lx, regnames[rs], btgt);
3857 not_likely:
3858 ctx->hflags |= MIPS_HFLAG_BC;
3859 break;
3860 case OPC_BLTZALL:
3861 tcg_gen_setcondi_tl(TCG_COND_LT, bcond, t0, 0);
3862 blink = 31;
3863 MIPS_DEBUG("bltzall %s, " TARGET_FMT_lx, regnames[rs], btgt);
3864 likely:
3865 ctx->hflags |= MIPS_HFLAG_BL;
3866 break;
3867 default:
3868 MIPS_INVAL("conditional branch/jump");
3869 generate_exception(ctx, EXCP_RI);
3870 goto out;
3873 MIPS_DEBUG("enter ds: link %d cond %02x target " TARGET_FMT_lx,
3874 blink, ctx->hflags, btgt);
3876 ctx->btarget = btgt;
3877 if (blink > 0) {
3878 int post_delay = insn_bytes;
3879 int lowbit = !!(ctx->hflags & MIPS_HFLAG_M16);
3881 if (opc != OPC_JALRC)
3882 post_delay += ((ctx->hflags & MIPS_HFLAG_BDS16) ? 2 : 4);
3884 tcg_gen_movi_tl(cpu_gpr[blink], ctx->pc + post_delay + lowbit);
3887 out:
3888 if (insn_bytes == 2)
3889 ctx->hflags |= MIPS_HFLAG_B16;
3890 tcg_temp_free(t0);
3891 tcg_temp_free(t1);
3894 /* special3 bitfield operations */
3895 static void gen_bitops (DisasContext *ctx, uint32_t opc, int rt,
3896 int rs, int lsb, int msb)
3898 TCGv t0 = tcg_temp_new();
3899 TCGv t1 = tcg_temp_new();
3901 gen_load_gpr(t1, rs);
3902 switch (opc) {
3903 case OPC_EXT:
3904 if (lsb + msb > 31)
3905 goto fail;
3906 tcg_gen_shri_tl(t0, t1, lsb);
3907 if (msb != 31) {
3908 tcg_gen_andi_tl(t0, t0, (1 << (msb + 1)) - 1);
3909 } else {
3910 tcg_gen_ext32s_tl(t0, t0);
3912 break;
3913 #if defined(TARGET_MIPS64)
3914 case OPC_DEXTM:
3915 tcg_gen_shri_tl(t0, t1, lsb);
3916 if (msb != 31) {
3917 tcg_gen_andi_tl(t0, t0, (1ULL << (msb + 1 + 32)) - 1);
3919 break;
3920 case OPC_DEXTU:
3921 tcg_gen_shri_tl(t0, t1, lsb + 32);
3922 tcg_gen_andi_tl(t0, t0, (1ULL << (msb + 1)) - 1);
3923 break;
3924 case OPC_DEXT:
3925 tcg_gen_shri_tl(t0, t1, lsb);
3926 tcg_gen_andi_tl(t0, t0, (1ULL << (msb + 1)) - 1);
3927 break;
3928 #endif
3929 case OPC_INS:
3930 if (lsb > msb)
3931 goto fail;
3932 gen_load_gpr(t0, rt);
3933 tcg_gen_deposit_tl(t0, t0, t1, lsb, msb - lsb + 1);
3934 tcg_gen_ext32s_tl(t0, t0);
3935 break;
3936 #if defined(TARGET_MIPS64)
3937 case OPC_DINSM:
3938 gen_load_gpr(t0, rt);
3939 tcg_gen_deposit_tl(t0, t0, t1, lsb, msb + 32 - lsb + 1);
3940 break;
3941 case OPC_DINSU:
3942 gen_load_gpr(t0, rt);
3943 tcg_gen_deposit_tl(t0, t0, t1, lsb + 32, msb - lsb + 1);
3944 break;
3945 case OPC_DINS:
3946 gen_load_gpr(t0, rt);
3947 tcg_gen_deposit_tl(t0, t0, t1, lsb, msb - lsb + 1);
3948 break;
3949 #endif
3950 default:
3951 fail:
3952 MIPS_INVAL("bitops");
3953 generate_exception(ctx, EXCP_RI);
3954 tcg_temp_free(t0);
3955 tcg_temp_free(t1);
3956 return;
3958 gen_store_gpr(t0, rt);
3959 tcg_temp_free(t0);
3960 tcg_temp_free(t1);
3963 static void gen_bshfl (DisasContext *ctx, uint32_t op2, int rt, int rd)
3965 TCGv t0;
3967 if (rd == 0) {
3968 /* If no destination, treat it as a NOP. */
3969 MIPS_DEBUG("NOP");
3970 return;
3973 t0 = tcg_temp_new();
3974 gen_load_gpr(t0, rt);
3975 switch (op2) {
3976 case OPC_WSBH:
3978 TCGv t1 = tcg_temp_new();
3980 tcg_gen_shri_tl(t1, t0, 8);
3981 tcg_gen_andi_tl(t1, t1, 0x00FF00FF);
3982 tcg_gen_shli_tl(t0, t0, 8);
3983 tcg_gen_andi_tl(t0, t0, ~0x00FF00FF);
3984 tcg_gen_or_tl(t0, t0, t1);
3985 tcg_temp_free(t1);
3986 tcg_gen_ext32s_tl(cpu_gpr[rd], t0);
3988 break;
3989 case OPC_SEB:
3990 tcg_gen_ext8s_tl(cpu_gpr[rd], t0);
3991 break;
3992 case OPC_SEH:
3993 tcg_gen_ext16s_tl(cpu_gpr[rd], t0);
3994 break;
3995 #if defined(TARGET_MIPS64)
3996 case OPC_DSBH:
3998 TCGv t1 = tcg_temp_new();
4000 tcg_gen_shri_tl(t1, t0, 8);
4001 tcg_gen_andi_tl(t1, t1, 0x00FF00FF00FF00FFULL);
4002 tcg_gen_shli_tl(t0, t0, 8);
4003 tcg_gen_andi_tl(t0, t0, ~0x00FF00FF00FF00FFULL);
4004 tcg_gen_or_tl(cpu_gpr[rd], t0, t1);
4005 tcg_temp_free(t1);
4007 break;
4008 case OPC_DSHD:
4010 TCGv t1 = tcg_temp_new();
4012 tcg_gen_shri_tl(t1, t0, 16);
4013 tcg_gen_andi_tl(t1, t1, 0x0000FFFF0000FFFFULL);
4014 tcg_gen_shli_tl(t0, t0, 16);
4015 tcg_gen_andi_tl(t0, t0, ~0x0000FFFF0000FFFFULL);
4016 tcg_gen_or_tl(t0, t0, t1);
4017 tcg_gen_shri_tl(t1, t0, 32);
4018 tcg_gen_shli_tl(t0, t0, 32);
4019 tcg_gen_or_tl(cpu_gpr[rd], t0, t1);
4020 tcg_temp_free(t1);
4022 break;
4023 #endif
4024 default:
4025 MIPS_INVAL("bsfhl");
4026 generate_exception(ctx, EXCP_RI);
4027 tcg_temp_free(t0);
4028 return;
4030 tcg_temp_free(t0);
4033 #ifndef CONFIG_USER_ONLY
4034 /* CP0 (MMU and control) */
4035 static inline void gen_mfc0_load32 (TCGv arg, target_ulong off)
4037 TCGv_i32 t0 = tcg_temp_new_i32();
4039 tcg_gen_ld_i32(t0, cpu_env, off);
4040 tcg_gen_ext_i32_tl(arg, t0);
4041 tcg_temp_free_i32(t0);
4044 static inline void gen_mfc0_load64 (TCGv arg, target_ulong off)
4046 tcg_gen_ld_tl(arg, cpu_env, off);
4047 tcg_gen_ext32s_tl(arg, arg);
4050 static inline void gen_mtc0_store32 (TCGv arg, target_ulong off)
4052 TCGv_i32 t0 = tcg_temp_new_i32();
4054 tcg_gen_trunc_tl_i32(t0, arg);
4055 tcg_gen_st_i32(t0, cpu_env, off);
4056 tcg_temp_free_i32(t0);
4059 static inline void gen_mtc0_store64 (TCGv arg, target_ulong off)
4061 tcg_gen_ext32s_tl(arg, arg);
4062 tcg_gen_st_tl(arg, cpu_env, off);
4065 static void gen_mfc0(DisasContext *ctx, TCGv arg, int reg, int sel)
4067 const char *rn = "invalid";
4069 if (sel != 0)
4070 check_insn(ctx, ISA_MIPS32);
4072 switch (reg) {
4073 case 0:
4074 switch (sel) {
4075 case 0:
4076 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Index));
4077 rn = "Index";
4078 break;
4079 case 1:
4080 check_insn(ctx, ASE_MT);
4081 gen_helper_mfc0_mvpcontrol(arg, cpu_env);
4082 rn = "MVPControl";
4083 break;
4084 case 2:
4085 check_insn(ctx, ASE_MT);
4086 gen_helper_mfc0_mvpconf0(arg, cpu_env);
4087 rn = "MVPConf0";
4088 break;
4089 case 3:
4090 check_insn(ctx, ASE_MT);
4091 gen_helper_mfc0_mvpconf1(arg, cpu_env);
4092 rn = "MVPConf1";
4093 break;
4094 default:
4095 goto die;
4097 break;
4098 case 1:
4099 switch (sel) {
4100 case 0:
4101 gen_helper_mfc0_random(arg, cpu_env);
4102 rn = "Random";
4103 break;
4104 case 1:
4105 check_insn(ctx, ASE_MT);
4106 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEControl));
4107 rn = "VPEControl";
4108 break;
4109 case 2:
4110 check_insn(ctx, ASE_MT);
4111 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEConf0));
4112 rn = "VPEConf0";
4113 break;
4114 case 3:
4115 check_insn(ctx, ASE_MT);
4116 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEConf1));
4117 rn = "VPEConf1";
4118 break;
4119 case 4:
4120 check_insn(ctx, ASE_MT);
4121 gen_mfc0_load64(arg, offsetof(CPUMIPSState, CP0_YQMask));
4122 rn = "YQMask";
4123 break;
4124 case 5:
4125 check_insn(ctx, ASE_MT);
4126 gen_mfc0_load64(arg, offsetof(CPUMIPSState, CP0_VPESchedule));
4127 rn = "VPESchedule";
4128 break;
4129 case 6:
4130 check_insn(ctx, ASE_MT);
4131 gen_mfc0_load64(arg, offsetof(CPUMIPSState, CP0_VPEScheFBack));
4132 rn = "VPEScheFBack";
4133 break;
4134 case 7:
4135 check_insn(ctx, ASE_MT);
4136 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEOpt));
4137 rn = "VPEOpt";
4138 break;
4139 default:
4140 goto die;
4142 break;
4143 case 2:
4144 switch (sel) {
4145 case 0:
4146 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EntryLo0));
4147 tcg_gen_ext32s_tl(arg, arg);
4148 rn = "EntryLo0";
4149 break;
4150 case 1:
4151 check_insn(ctx, ASE_MT);
4152 gen_helper_mfc0_tcstatus(arg, cpu_env);
4153 rn = "TCStatus";
4154 break;
4155 case 2:
4156 check_insn(ctx, ASE_MT);
4157 gen_helper_mfc0_tcbind(arg, cpu_env);
4158 rn = "TCBind";
4159 break;
4160 case 3:
4161 check_insn(ctx, ASE_MT);
4162 gen_helper_mfc0_tcrestart(arg, cpu_env);
4163 rn = "TCRestart";
4164 break;
4165 case 4:
4166 check_insn(ctx, ASE_MT);
4167 gen_helper_mfc0_tchalt(arg, cpu_env);
4168 rn = "TCHalt";
4169 break;
4170 case 5:
4171 check_insn(ctx, ASE_MT);
4172 gen_helper_mfc0_tccontext(arg, cpu_env);
4173 rn = "TCContext";
4174 break;
4175 case 6:
4176 check_insn(ctx, ASE_MT);
4177 gen_helper_mfc0_tcschedule(arg, cpu_env);
4178 rn = "TCSchedule";
4179 break;
4180 case 7:
4181 check_insn(ctx, ASE_MT);
4182 gen_helper_mfc0_tcschefback(arg, cpu_env);
4183 rn = "TCScheFBack";
4184 break;
4185 default:
4186 goto die;
4188 break;
4189 case 3:
4190 switch (sel) {
4191 case 0:
4192 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EntryLo1));
4193 tcg_gen_ext32s_tl(arg, arg);
4194 rn = "EntryLo1";
4195 break;
4196 default:
4197 goto die;
4199 break;
4200 case 4:
4201 switch (sel) {
4202 case 0:
4203 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_Context));
4204 tcg_gen_ext32s_tl(arg, arg);
4205 rn = "Context";
4206 break;
4207 case 1:
4208 // gen_helper_mfc0_contextconfig(arg); /* SmartMIPS ASE */
4209 rn = "ContextConfig";
4210 // break;
4211 default:
4212 goto die;
4214 break;
4215 case 5:
4216 switch (sel) {
4217 case 0:
4218 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PageMask));
4219 rn = "PageMask";
4220 break;
4221 case 1:
4222 check_insn(ctx, ISA_MIPS32R2);
4223 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PageGrain));
4224 rn = "PageGrain";
4225 break;
4226 default:
4227 goto die;
4229 break;
4230 case 6:
4231 switch (sel) {
4232 case 0:
4233 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Wired));
4234 rn = "Wired";
4235 break;
4236 case 1:
4237 check_insn(ctx, ISA_MIPS32R2);
4238 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf0));
4239 rn = "SRSConf0";
4240 break;
4241 case 2:
4242 check_insn(ctx, ISA_MIPS32R2);
4243 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf1));
4244 rn = "SRSConf1";
4245 break;
4246 case 3:
4247 check_insn(ctx, ISA_MIPS32R2);
4248 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf2));
4249 rn = "SRSConf2";
4250 break;
4251 case 4:
4252 check_insn(ctx, ISA_MIPS32R2);
4253 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf3));
4254 rn = "SRSConf3";
4255 break;
4256 case 5:
4257 check_insn(ctx, ISA_MIPS32R2);
4258 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf4));
4259 rn = "SRSConf4";
4260 break;
4261 default:
4262 goto die;
4264 break;
4265 case 7:
4266 switch (sel) {
4267 case 0:
4268 check_insn(ctx, ISA_MIPS32R2);
4269 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_HWREna));
4270 rn = "HWREna";
4271 break;
4272 default:
4273 goto die;
4275 break;
4276 case 8:
4277 switch (sel) {
4278 case 0:
4279 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_BadVAddr));
4280 tcg_gen_ext32s_tl(arg, arg);
4281 rn = "BadVAddr";
4282 break;
4283 default:
4284 goto die;
4286 break;
4287 case 9:
4288 switch (sel) {
4289 case 0:
4290 /* Mark as an IO operation because we read the time. */
4291 if (use_icount)
4292 gen_io_start();
4293 gen_helper_mfc0_count(arg, cpu_env);
4294 if (use_icount) {
4295 gen_io_end();
4297 /* Break the TB to be able to take timer interrupts immediately
4298 after reading count. */
4299 ctx->bstate = BS_STOP;
4300 rn = "Count";
4301 break;
4302 /* 6,7 are implementation dependent */
4303 default:
4304 goto die;
4306 break;
4307 case 10:
4308 switch (sel) {
4309 case 0:
4310 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EntryHi));
4311 tcg_gen_ext32s_tl(arg, arg);
4312 rn = "EntryHi";
4313 break;
4314 default:
4315 goto die;
4317 break;
4318 case 11:
4319 switch (sel) {
4320 case 0:
4321 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Compare));
4322 rn = "Compare";
4323 break;
4324 /* 6,7 are implementation dependent */
4325 default:
4326 goto die;
4328 break;
4329 case 12:
4330 switch (sel) {
4331 case 0:
4332 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Status));
4333 rn = "Status";
4334 break;
4335 case 1:
4336 check_insn(ctx, ISA_MIPS32R2);
4337 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_IntCtl));
4338 rn = "IntCtl";
4339 break;
4340 case 2:
4341 check_insn(ctx, ISA_MIPS32R2);
4342 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSCtl));
4343 rn = "SRSCtl";
4344 break;
4345 case 3:
4346 check_insn(ctx, ISA_MIPS32R2);
4347 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSMap));
4348 rn = "SRSMap";
4349 break;
4350 default:
4351 goto die;
4353 break;
4354 case 13:
4355 switch (sel) {
4356 case 0:
4357 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Cause));
4358 rn = "Cause";
4359 break;
4360 default:
4361 goto die;
4363 break;
4364 case 14:
4365 switch (sel) {
4366 case 0:
4367 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EPC));
4368 tcg_gen_ext32s_tl(arg, arg);
4369 rn = "EPC";
4370 break;
4371 default:
4372 goto die;
4374 break;
4375 case 15:
4376 switch (sel) {
4377 case 0:
4378 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PRid));
4379 rn = "PRid";
4380 break;
4381 case 1:
4382 check_insn(ctx, ISA_MIPS32R2);
4383 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_EBase));
4384 rn = "EBase";
4385 break;
4386 default:
4387 goto die;
4389 break;
4390 case 16:
4391 switch (sel) {
4392 case 0:
4393 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config0));
4394 rn = "Config";
4395 break;
4396 case 1:
4397 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config1));
4398 rn = "Config1";
4399 break;
4400 case 2:
4401 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config2));
4402 rn = "Config2";
4403 break;
4404 case 3:
4405 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config3));
4406 rn = "Config3";
4407 break;
4408 case 4:
4409 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config4));
4410 rn = "Config4";
4411 break;
4412 case 5:
4413 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config5));
4414 rn = "Config5";
4415 break;
4416 /* 6,7 are implementation dependent */
4417 case 6:
4418 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config6));
4419 rn = "Config6";
4420 break;
4421 case 7:
4422 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config7));
4423 rn = "Config7";
4424 break;
4425 default:
4426 goto die;
4428 break;
4429 case 17:
4430 switch (sel) {
4431 case 0:
4432 gen_helper_mfc0_lladdr(arg, cpu_env);
4433 rn = "LLAddr";
4434 break;
4435 default:
4436 goto die;
4438 break;
4439 case 18:
4440 switch (sel) {
4441 case 0 ... 7:
4442 gen_helper_1e0i(mfc0_watchlo, arg, sel);
4443 rn = "WatchLo";
4444 break;
4445 default:
4446 goto die;
4448 break;
4449 case 19:
4450 switch (sel) {
4451 case 0 ...7:
4452 gen_helper_1e0i(mfc0_watchhi, arg, sel);
4453 rn = "WatchHi";
4454 break;
4455 default:
4456 goto die;
4458 break;
4459 case 20:
4460 switch (sel) {
4461 case 0:
4462 #if defined(TARGET_MIPS64)
4463 check_insn(ctx, ISA_MIPS3);
4464 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_XContext));
4465 tcg_gen_ext32s_tl(arg, arg);
4466 rn = "XContext";
4467 break;
4468 #endif
4469 default:
4470 goto die;
4472 break;
4473 case 21:
4474 /* Officially reserved, but sel 0 is used for R1x000 framemask */
4475 switch (sel) {
4476 case 0:
4477 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Framemask));
4478 rn = "Framemask";
4479 break;
4480 default:
4481 goto die;
4483 break;
4484 case 22:
4485 tcg_gen_movi_tl(arg, 0); /* unimplemented */
4486 rn = "'Diagnostic"; /* implementation dependent */
4487 break;
4488 case 23:
4489 switch (sel) {
4490 case 0:
4491 gen_helper_mfc0_debug(arg, cpu_env); /* EJTAG support */
4492 rn = "Debug";
4493 break;
4494 case 1:
4495 // gen_helper_mfc0_tracecontrol(arg); /* PDtrace support */
4496 rn = "TraceControl";
4497 // break;
4498 case 2:
4499 // gen_helper_mfc0_tracecontrol2(arg); /* PDtrace support */
4500 rn = "TraceControl2";
4501 // break;
4502 case 3:
4503 // gen_helper_mfc0_usertracedata(arg); /* PDtrace support */
4504 rn = "UserTraceData";
4505 // break;
4506 case 4:
4507 // gen_helper_mfc0_tracebpc(arg); /* PDtrace support */
4508 rn = "TraceBPC";
4509 // break;
4510 default:
4511 goto die;
4513 break;
4514 case 24:
4515 switch (sel) {
4516 case 0:
4517 /* EJTAG support */
4518 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_DEPC));
4519 tcg_gen_ext32s_tl(arg, arg);
4520 rn = "DEPC";
4521 break;
4522 default:
4523 goto die;
4525 break;
4526 case 25:
4527 switch (sel) {
4528 case 0:
4529 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Performance0));
4530 rn = "Performance0";
4531 break;
4532 case 1:
4533 // gen_helper_mfc0_performance1(arg);
4534 rn = "Performance1";
4535 // break;
4536 case 2:
4537 // gen_helper_mfc0_performance2(arg);
4538 rn = "Performance2";
4539 // break;
4540 case 3:
4541 // gen_helper_mfc0_performance3(arg);
4542 rn = "Performance3";
4543 // break;
4544 case 4:
4545 // gen_helper_mfc0_performance4(arg);
4546 rn = "Performance4";
4547 // break;
4548 case 5:
4549 // gen_helper_mfc0_performance5(arg);
4550 rn = "Performance5";
4551 // break;
4552 case 6:
4553 // gen_helper_mfc0_performance6(arg);
4554 rn = "Performance6";
4555 // break;
4556 case 7:
4557 // gen_helper_mfc0_performance7(arg);
4558 rn = "Performance7";
4559 // break;
4560 default:
4561 goto die;
4563 break;
4564 case 26:
4565 tcg_gen_movi_tl(arg, 0); /* unimplemented */
4566 rn = "ECC";
4567 break;
4568 case 27:
4569 switch (sel) {
4570 case 0 ... 3:
4571 tcg_gen_movi_tl(arg, 0); /* unimplemented */
4572 rn = "CacheErr";
4573 break;
4574 default:
4575 goto die;
4577 break;
4578 case 28:
4579 switch (sel) {
4580 case 0:
4581 case 2:
4582 case 4:
4583 case 6:
4584 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_TagLo));
4585 rn = "TagLo";
4586 break;
4587 case 1:
4588 case 3:
4589 case 5:
4590 case 7:
4591 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DataLo));
4592 rn = "DataLo";
4593 break;
4594 default:
4595 goto die;
4597 break;
4598 case 29:
4599 switch (sel) {
4600 case 0:
4601 case 2:
4602 case 4:
4603 case 6:
4604 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_TagHi));
4605 rn = "TagHi";
4606 break;
4607 case 1:
4608 case 3:
4609 case 5:
4610 case 7:
4611 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DataHi));
4612 rn = "DataHi";
4613 break;
4614 default:
4615 goto die;
4617 break;
4618 case 30:
4619 switch (sel) {
4620 case 0:
4621 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_ErrorEPC));
4622 tcg_gen_ext32s_tl(arg, arg);
4623 rn = "ErrorEPC";
4624 break;
4625 default:
4626 goto die;
4628 break;
4629 case 31:
4630 switch (sel) {
4631 case 0:
4632 /* EJTAG support */
4633 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DESAVE));
4634 rn = "DESAVE";
4635 break;
4636 default:
4637 goto die;
4639 break;
4640 default:
4641 goto die;
4643 (void)rn; /* avoid a compiler warning */
4644 LOG_DISAS("mfc0 %s (reg %d sel %d)\n", rn, reg, sel);
4645 return;
4647 die:
4648 LOG_DISAS("mfc0 %s (reg %d sel %d)\n", rn, reg, sel);
4649 generate_exception(ctx, EXCP_RI);
4652 static void gen_mtc0(DisasContext *ctx, TCGv arg, int reg, int sel)
4654 const char *rn = "invalid";
4656 if (sel != 0)
4657 check_insn(ctx, ISA_MIPS32);
4659 if (use_icount)
4660 gen_io_start();
4662 switch (reg) {
4663 case 0:
4664 switch (sel) {
4665 case 0:
4666 gen_helper_mtc0_index(cpu_env, arg);
4667 rn = "Index";
4668 break;
4669 case 1:
4670 check_insn(ctx, ASE_MT);
4671 gen_helper_mtc0_mvpcontrol(cpu_env, arg);
4672 rn = "MVPControl";
4673 break;
4674 case 2:
4675 check_insn(ctx, ASE_MT);
4676 /* ignored */
4677 rn = "MVPConf0";
4678 break;
4679 case 3:
4680 check_insn(ctx, ASE_MT);
4681 /* ignored */
4682 rn = "MVPConf1";
4683 break;
4684 default:
4685 goto die;
4687 break;
4688 case 1:
4689 switch (sel) {
4690 case 0:
4691 /* ignored */
4692 rn = "Random";
4693 break;
4694 case 1:
4695 check_insn(ctx, ASE_MT);
4696 gen_helper_mtc0_vpecontrol(cpu_env, arg);
4697 rn = "VPEControl";
4698 break;
4699 case 2:
4700 check_insn(ctx, ASE_MT);
4701 gen_helper_mtc0_vpeconf0(cpu_env, arg);
4702 rn = "VPEConf0";
4703 break;
4704 case 3:
4705 check_insn(ctx, ASE_MT);
4706 gen_helper_mtc0_vpeconf1(cpu_env, arg);
4707 rn = "VPEConf1";
4708 break;
4709 case 4:
4710 check_insn(ctx, ASE_MT);
4711 gen_helper_mtc0_yqmask(cpu_env, arg);
4712 rn = "YQMask";
4713 break;
4714 case 5:
4715 check_insn(ctx, ASE_MT);
4716 gen_mtc0_store64(arg, offsetof(CPUMIPSState, CP0_VPESchedule));
4717 rn = "VPESchedule";
4718 break;
4719 case 6:
4720 check_insn(ctx, ASE_MT);
4721 gen_mtc0_store64(arg, offsetof(CPUMIPSState, CP0_VPEScheFBack));
4722 rn = "VPEScheFBack";
4723 break;
4724 case 7:
4725 check_insn(ctx, ASE_MT);
4726 gen_helper_mtc0_vpeopt(cpu_env, arg);
4727 rn = "VPEOpt";
4728 break;
4729 default:
4730 goto die;
4732 break;
4733 case 2:
4734 switch (sel) {
4735 case 0:
4736 gen_helper_mtc0_entrylo0(cpu_env, arg);
4737 rn = "EntryLo0";
4738 break;
4739 case 1:
4740 check_insn(ctx, ASE_MT);
4741 gen_helper_mtc0_tcstatus(cpu_env, arg);
4742 rn = "TCStatus";
4743 break;
4744 case 2:
4745 check_insn(ctx, ASE_MT);
4746 gen_helper_mtc0_tcbind(cpu_env, arg);
4747 rn = "TCBind";
4748 break;
4749 case 3:
4750 check_insn(ctx, ASE_MT);
4751 gen_helper_mtc0_tcrestart(cpu_env, arg);
4752 rn = "TCRestart";
4753 break;
4754 case 4:
4755 check_insn(ctx, ASE_MT);
4756 gen_helper_mtc0_tchalt(cpu_env, arg);
4757 rn = "TCHalt";
4758 break;
4759 case 5:
4760 check_insn(ctx, ASE_MT);
4761 gen_helper_mtc0_tccontext(cpu_env, arg);
4762 rn = "TCContext";
4763 break;
4764 case 6:
4765 check_insn(ctx, ASE_MT);
4766 gen_helper_mtc0_tcschedule(cpu_env, arg);
4767 rn = "TCSchedule";
4768 break;
4769 case 7:
4770 check_insn(ctx, ASE_MT);
4771 gen_helper_mtc0_tcschefback(cpu_env, arg);
4772 rn = "TCScheFBack";
4773 break;
4774 default:
4775 goto die;
4777 break;
4778 case 3:
4779 switch (sel) {
4780 case 0:
4781 gen_helper_mtc0_entrylo1(cpu_env, arg);
4782 rn = "EntryLo1";
4783 break;
4784 default:
4785 goto die;
4787 break;
4788 case 4:
4789 switch (sel) {
4790 case 0:
4791 gen_helper_mtc0_context(cpu_env, arg);
4792 rn = "Context";
4793 break;
4794 case 1:
4795 // gen_helper_mtc0_contextconfig(cpu_env, arg); /* SmartMIPS ASE */
4796 rn = "ContextConfig";
4797 // break;
4798 default:
4799 goto die;
4801 break;
4802 case 5:
4803 switch (sel) {
4804 case 0:
4805 gen_helper_mtc0_pagemask(cpu_env, arg);
4806 rn = "PageMask";
4807 break;
4808 case 1:
4809 check_insn(ctx, ISA_MIPS32R2);
4810 gen_helper_mtc0_pagegrain(cpu_env, arg);
4811 rn = "PageGrain";
4812 break;
4813 default:
4814 goto die;
4816 break;
4817 case 6:
4818 switch (sel) {
4819 case 0:
4820 gen_helper_mtc0_wired(cpu_env, arg);
4821 rn = "Wired";
4822 break;
4823 case 1:
4824 check_insn(ctx, ISA_MIPS32R2);
4825 gen_helper_mtc0_srsconf0(cpu_env, arg);
4826 rn = "SRSConf0";
4827 break;
4828 case 2:
4829 check_insn(ctx, ISA_MIPS32R2);
4830 gen_helper_mtc0_srsconf1(cpu_env, arg);
4831 rn = "SRSConf1";
4832 break;
4833 case 3:
4834 check_insn(ctx, ISA_MIPS32R2);
4835 gen_helper_mtc0_srsconf2(cpu_env, arg);
4836 rn = "SRSConf2";
4837 break;
4838 case 4:
4839 check_insn(ctx, ISA_MIPS32R2);
4840 gen_helper_mtc0_srsconf3(cpu_env, arg);
4841 rn = "SRSConf3";
4842 break;
4843 case 5:
4844 check_insn(ctx, ISA_MIPS32R2);
4845 gen_helper_mtc0_srsconf4(cpu_env, arg);
4846 rn = "SRSConf4";
4847 break;
4848 default:
4849 goto die;
4851 break;
4852 case 7:
4853 switch (sel) {
4854 case 0:
4855 check_insn(ctx, ISA_MIPS32R2);
4856 gen_helper_mtc0_hwrena(cpu_env, arg);
4857 rn = "HWREna";
4858 break;
4859 default:
4860 goto die;
4862 break;
4863 case 8:
4864 /* ignored */
4865 rn = "BadVAddr";
4866 break;
4867 case 9:
4868 switch (sel) {
4869 case 0:
4870 gen_helper_mtc0_count(cpu_env, arg);
4871 rn = "Count";
4872 break;
4873 /* 6,7 are implementation dependent */
4874 default:
4875 goto die;
4877 break;
4878 case 10:
4879 switch (sel) {
4880 case 0:
4881 gen_helper_mtc0_entryhi(cpu_env, arg);
4882 rn = "EntryHi";
4883 break;
4884 default:
4885 goto die;
4887 break;
4888 case 11:
4889 switch (sel) {
4890 case 0:
4891 gen_helper_mtc0_compare(cpu_env, arg);
4892 rn = "Compare";
4893 break;
4894 /* 6,7 are implementation dependent */
4895 default:
4896 goto die;
4898 break;
4899 case 12:
4900 switch (sel) {
4901 case 0:
4902 save_cpu_state(ctx, 1);
4903 gen_helper_mtc0_status(cpu_env, arg);
4904 /* BS_STOP isn't good enough here, hflags may have changed. */
4905 gen_save_pc(ctx->pc + 4);
4906 ctx->bstate = BS_EXCP;
4907 rn = "Status";
4908 break;
4909 case 1:
4910 check_insn(ctx, ISA_MIPS32R2);
4911 gen_helper_mtc0_intctl(cpu_env, arg);
4912 /* Stop translation as we may have switched the execution mode */
4913 ctx->bstate = BS_STOP;
4914 rn = "IntCtl";
4915 break;
4916 case 2:
4917 check_insn(ctx, ISA_MIPS32R2);
4918 gen_helper_mtc0_srsctl(cpu_env, arg);
4919 /* Stop translation as we may have switched the execution mode */
4920 ctx->bstate = BS_STOP;
4921 rn = "SRSCtl";
4922 break;
4923 case 3:
4924 check_insn(ctx, ISA_MIPS32R2);
4925 gen_mtc0_store32(arg, offsetof(CPUMIPSState, CP0_SRSMap));
4926 /* Stop translation as we may have switched the execution mode */
4927 ctx->bstate = BS_STOP;
4928 rn = "SRSMap";
4929 break;
4930 default:
4931 goto die;
4933 break;
4934 case 13:
4935 switch (sel) {
4936 case 0:
4937 save_cpu_state(ctx, 1);
4938 gen_helper_mtc0_cause(cpu_env, arg);
4939 rn = "Cause";
4940 break;
4941 default:
4942 goto die;
4944 break;
4945 case 14:
4946 switch (sel) {
4947 case 0:
4948 gen_mtc0_store64(arg, offsetof(CPUMIPSState, CP0_EPC));
4949 rn = "EPC";
4950 break;
4951 default:
4952 goto die;
4954 break;
4955 case 15:
4956 switch (sel) {
4957 case 0:
4958 /* ignored */
4959 rn = "PRid";
4960 break;
4961 case 1:
4962 check_insn(ctx, ISA_MIPS32R2);
4963 gen_helper_mtc0_ebase(cpu_env, arg);
4964 rn = "EBase";
4965 break;
4966 default:
4967 goto die;
4969 break;
4970 case 16:
4971 switch (sel) {
4972 case 0:
4973 gen_helper_mtc0_config0(cpu_env, arg);
4974 rn = "Config";
4975 /* Stop translation as we may have switched the execution mode */
4976 ctx->bstate = BS_STOP;
4977 break;
4978 case 1:
4979 /* ignored, read only */
4980 rn = "Config1";
4981 break;
4982 case 2:
4983 gen_helper_mtc0_config2(cpu_env, arg);
4984 rn = "Config2";
4985 /* Stop translation as we may have switched the execution mode */
4986 ctx->bstate = BS_STOP;
4987 break;
4988 case 3:
4989 /* ignored, read only */
4990 rn = "Config3";
4991 break;
4992 case 4:
4993 gen_helper_mtc0_config4(cpu_env, arg);
4994 rn = "Config4";
4995 ctx->bstate = BS_STOP;
4996 break;
4997 case 5:
4998 gen_helper_mtc0_config5(cpu_env, arg);
4999 rn = "Config5";
5000 /* Stop translation as we may have switched the execution mode */
5001 ctx->bstate = BS_STOP;
5002 break;
5003 /* 6,7 are implementation dependent */
5004 case 6:
5005 /* ignored */
5006 rn = "Config6";
5007 break;
5008 case 7:
5009 /* ignored */
5010 rn = "Config7";
5011 break;
5012 default:
5013 rn = "Invalid config selector";
5014 goto die;
5016 break;
5017 case 17:
5018 switch (sel) {
5019 case 0:
5020 gen_helper_mtc0_lladdr(cpu_env, arg);
5021 rn = "LLAddr";
5022 break;
5023 default:
5024 goto die;
5026 break;
5027 case 18:
5028 switch (sel) {
5029 case 0 ... 7:
5030 gen_helper_0e1i(mtc0_watchlo, arg, sel);
5031 rn = "WatchLo";
5032 break;
5033 default:
5034 goto die;
5036 break;
5037 case 19:
5038 switch (sel) {
5039 case 0 ... 7:
5040 gen_helper_0e1i(mtc0_watchhi, arg, sel);
5041 rn = "WatchHi";
5042 break;
5043 default:
5044 goto die;
5046 break;
5047 case 20:
5048 switch (sel) {
5049 case 0:
5050 #if defined(TARGET_MIPS64)
5051 check_insn(ctx, ISA_MIPS3);
5052 gen_helper_mtc0_xcontext(cpu_env, arg);
5053 rn = "XContext";
5054 break;
5055 #endif
5056 default:
5057 goto die;
5059 break;
5060 case 21:
5061 /* Officially reserved, but sel 0 is used for R1x000 framemask */
5062 switch (sel) {
5063 case 0:
5064 gen_helper_mtc0_framemask(cpu_env, arg);
5065 rn = "Framemask";
5066 break;
5067 default:
5068 goto die;
5070 break;
5071 case 22:
5072 /* ignored */
5073 rn = "Diagnostic"; /* implementation dependent */
5074 break;
5075 case 23:
5076 switch (sel) {
5077 case 0:
5078 gen_helper_mtc0_debug(cpu_env, arg); /* EJTAG support */
5079 /* BS_STOP isn't good enough here, hflags may have changed. */
5080 gen_save_pc(ctx->pc + 4);
5081 ctx->bstate = BS_EXCP;
5082 rn = "Debug";
5083 break;
5084 case 1:
5085 // gen_helper_mtc0_tracecontrol(cpu_env, arg); /* PDtrace support */
5086 rn = "TraceControl";
5087 /* Stop translation as we may have switched the execution mode */
5088 ctx->bstate = BS_STOP;
5089 // break;
5090 case 2:
5091 // gen_helper_mtc0_tracecontrol2(cpu_env, arg); /* PDtrace support */
5092 rn = "TraceControl2";
5093 /* Stop translation as we may have switched the execution mode */
5094 ctx->bstate = BS_STOP;
5095 // break;
5096 case 3:
5097 /* Stop translation as we may have switched the execution mode */
5098 ctx->bstate = BS_STOP;
5099 // gen_helper_mtc0_usertracedata(cpu_env, arg); /* PDtrace support */
5100 rn = "UserTraceData";
5101 /* Stop translation as we may have switched the execution mode */
5102 ctx->bstate = BS_STOP;
5103 // break;
5104 case 4:
5105 // gen_helper_mtc0_tracebpc(cpu_env, arg); /* PDtrace support */
5106 /* Stop translation as we may have switched the execution mode */
5107 ctx->bstate = BS_STOP;
5108 rn = "TraceBPC";
5109 // break;
5110 default:
5111 goto die;
5113 break;
5114 case 24:
5115 switch (sel) {
5116 case 0:
5117 /* EJTAG support */
5118 gen_mtc0_store64(arg, offsetof(CPUMIPSState, CP0_DEPC));
5119 rn = "DEPC";
5120 break;
5121 default:
5122 goto die;
5124 break;
5125 case 25:
5126 switch (sel) {
5127 case 0:
5128 gen_helper_mtc0_performance0(cpu_env, arg);
5129 rn = "Performance0";
5130 break;
5131 case 1:
5132 // gen_helper_mtc0_performance1(arg);
5133 rn = "Performance1";
5134 // break;
5135 case 2:
5136 // gen_helper_mtc0_performance2(arg);
5137 rn = "Performance2";
5138 // break;
5139 case 3:
5140 // gen_helper_mtc0_performance3(arg);
5141 rn = "Performance3";
5142 // break;
5143 case 4:
5144 // gen_helper_mtc0_performance4(arg);
5145 rn = "Performance4";
5146 // break;
5147 case 5:
5148 // gen_helper_mtc0_performance5(arg);
5149 rn = "Performance5";
5150 // break;
5151 case 6:
5152 // gen_helper_mtc0_performance6(arg);
5153 rn = "Performance6";
5154 // break;
5155 case 7:
5156 // gen_helper_mtc0_performance7(arg);
5157 rn = "Performance7";
5158 // break;
5159 default:
5160 goto die;
5162 break;
5163 case 26:
5164 /* ignored */
5165 rn = "ECC";
5166 break;
5167 case 27:
5168 switch (sel) {
5169 case 0 ... 3:
5170 /* ignored */
5171 rn = "CacheErr";
5172 break;
5173 default:
5174 goto die;
5176 break;
5177 case 28:
5178 switch (sel) {
5179 case 0:
5180 case 2:
5181 case 4:
5182 case 6:
5183 gen_helper_mtc0_taglo(cpu_env, arg);
5184 rn = "TagLo";
5185 break;
5186 case 1:
5187 case 3:
5188 case 5:
5189 case 7:
5190 gen_helper_mtc0_datalo(cpu_env, arg);
5191 rn = "DataLo";
5192 break;
5193 default:
5194 goto die;
5196 break;
5197 case 29:
5198 switch (sel) {
5199 case 0:
5200 case 2:
5201 case 4:
5202 case 6:
5203 gen_helper_mtc0_taghi(cpu_env, arg);
5204 rn = "TagHi";
5205 break;
5206 case 1:
5207 case 3:
5208 case 5:
5209 case 7:
5210 gen_helper_mtc0_datahi(cpu_env, arg);
5211 rn = "DataHi";
5212 break;
5213 default:
5214 rn = "invalid sel";
5215 goto die;
5217 break;
5218 case 30:
5219 switch (sel) {
5220 case 0:
5221 gen_mtc0_store64(arg, offsetof(CPUMIPSState, CP0_ErrorEPC));
5222 rn = "ErrorEPC";
5223 break;
5224 default:
5225 goto die;
5227 break;
5228 case 31:
5229 switch (sel) {
5230 case 0:
5231 /* EJTAG support */
5232 gen_mtc0_store32(arg, offsetof(CPUMIPSState, CP0_DESAVE));
5233 rn = "DESAVE";
5234 break;
5235 default:
5236 goto die;
5238 /* Stop translation as we may have switched the execution mode */
5239 ctx->bstate = BS_STOP;
5240 break;
5241 default:
5242 goto die;
5244 (void)rn; /* avoid a compiler warning */
5245 LOG_DISAS("mtc0 %s (reg %d sel %d)\n", rn, reg, sel);
5246 /* For simplicity assume that all writes can cause interrupts. */
5247 if (use_icount) {
5248 gen_io_end();
5249 ctx->bstate = BS_STOP;
5251 return;
5253 die:
5254 LOG_DISAS("mtc0 %s (reg %d sel %d)\n", rn, reg, sel);
5255 generate_exception(ctx, EXCP_RI);
5258 #if defined(TARGET_MIPS64)
5259 static void gen_dmfc0(DisasContext *ctx, TCGv arg, int reg, int sel)
5261 const char *rn = "invalid";
5263 if (sel != 0)
5264 check_insn(ctx, ISA_MIPS64);
5266 switch (reg) {
5267 case 0:
5268 switch (sel) {
5269 case 0:
5270 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Index));
5271 rn = "Index";
5272 break;
5273 case 1:
5274 check_insn(ctx, ASE_MT);
5275 gen_helper_mfc0_mvpcontrol(arg, cpu_env);
5276 rn = "MVPControl";
5277 break;
5278 case 2:
5279 check_insn(ctx, ASE_MT);
5280 gen_helper_mfc0_mvpconf0(arg, cpu_env);
5281 rn = "MVPConf0";
5282 break;
5283 case 3:
5284 check_insn(ctx, ASE_MT);
5285 gen_helper_mfc0_mvpconf1(arg, cpu_env);
5286 rn = "MVPConf1";
5287 break;
5288 default:
5289 goto die;
5291 break;
5292 case 1:
5293 switch (sel) {
5294 case 0:
5295 gen_helper_mfc0_random(arg, cpu_env);
5296 rn = "Random";
5297 break;
5298 case 1:
5299 check_insn(ctx, ASE_MT);
5300 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEControl));
5301 rn = "VPEControl";
5302 break;
5303 case 2:
5304 check_insn(ctx, ASE_MT);
5305 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEConf0));
5306 rn = "VPEConf0";
5307 break;
5308 case 3:
5309 check_insn(ctx, ASE_MT);
5310 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEConf1));
5311 rn = "VPEConf1";
5312 break;
5313 case 4:
5314 check_insn(ctx, ASE_MT);
5315 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_YQMask));
5316 rn = "YQMask";
5317 break;
5318 case 5:
5319 check_insn(ctx, ASE_MT);
5320 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_VPESchedule));
5321 rn = "VPESchedule";
5322 break;
5323 case 6:
5324 check_insn(ctx, ASE_MT);
5325 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_VPEScheFBack));
5326 rn = "VPEScheFBack";
5327 break;
5328 case 7:
5329 check_insn(ctx, ASE_MT);
5330 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEOpt));
5331 rn = "VPEOpt";
5332 break;
5333 default:
5334 goto die;
5336 break;
5337 case 2:
5338 switch (sel) {
5339 case 0:
5340 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EntryLo0));
5341 rn = "EntryLo0";
5342 break;
5343 case 1:
5344 check_insn(ctx, ASE_MT);
5345 gen_helper_mfc0_tcstatus(arg, cpu_env);
5346 rn = "TCStatus";
5347 break;
5348 case 2:
5349 check_insn(ctx, ASE_MT);
5350 gen_helper_mfc0_tcbind(arg, cpu_env);
5351 rn = "TCBind";
5352 break;
5353 case 3:
5354 check_insn(ctx, ASE_MT);
5355 gen_helper_dmfc0_tcrestart(arg, cpu_env);
5356 rn = "TCRestart";
5357 break;
5358 case 4:
5359 check_insn(ctx, ASE_MT);
5360 gen_helper_dmfc0_tchalt(arg, cpu_env);
5361 rn = "TCHalt";
5362 break;
5363 case 5:
5364 check_insn(ctx, ASE_MT);
5365 gen_helper_dmfc0_tccontext(arg, cpu_env);
5366 rn = "TCContext";
5367 break;
5368 case 6:
5369 check_insn(ctx, ASE_MT);
5370 gen_helper_dmfc0_tcschedule(arg, cpu_env);
5371 rn = "TCSchedule";
5372 break;
5373 case 7:
5374 check_insn(ctx, ASE_MT);
5375 gen_helper_dmfc0_tcschefback(arg, cpu_env);
5376 rn = "TCScheFBack";
5377 break;
5378 default:
5379 goto die;
5381 break;
5382 case 3:
5383 switch (sel) {
5384 case 0:
5385 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EntryLo1));
5386 rn = "EntryLo1";
5387 break;
5388 default:
5389 goto die;
5391 break;
5392 case 4:
5393 switch (sel) {
5394 case 0:
5395 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_Context));
5396 rn = "Context";
5397 break;
5398 case 1:
5399 // gen_helper_dmfc0_contextconfig(arg); /* SmartMIPS ASE */
5400 rn = "ContextConfig";
5401 // break;
5402 default:
5403 goto die;
5405 break;
5406 case 5:
5407 switch (sel) {
5408 case 0:
5409 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PageMask));
5410 rn = "PageMask";
5411 break;
5412 case 1:
5413 check_insn(ctx, ISA_MIPS32R2);
5414 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PageGrain));
5415 rn = "PageGrain";
5416 break;
5417 default:
5418 goto die;
5420 break;
5421 case 6:
5422 switch (sel) {
5423 case 0:
5424 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Wired));
5425 rn = "Wired";
5426 break;
5427 case 1:
5428 check_insn(ctx, ISA_MIPS32R2);
5429 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf0));
5430 rn = "SRSConf0";
5431 break;
5432 case 2:
5433 check_insn(ctx, ISA_MIPS32R2);
5434 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf1));
5435 rn = "SRSConf1";
5436 break;
5437 case 3:
5438 check_insn(ctx, ISA_MIPS32R2);
5439 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf2));
5440 rn = "SRSConf2";
5441 break;
5442 case 4:
5443 check_insn(ctx, ISA_MIPS32R2);
5444 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf3));
5445 rn = "SRSConf3";
5446 break;
5447 case 5:
5448 check_insn(ctx, ISA_MIPS32R2);
5449 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf4));
5450 rn = "SRSConf4";
5451 break;
5452 default:
5453 goto die;
5455 break;
5456 case 7:
5457 switch (sel) {
5458 case 0:
5459 check_insn(ctx, ISA_MIPS32R2);
5460 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_HWREna));
5461 rn = "HWREna";
5462 break;
5463 default:
5464 goto die;
5466 break;
5467 case 8:
5468 switch (sel) {
5469 case 0:
5470 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_BadVAddr));
5471 rn = "BadVAddr";
5472 break;
5473 default:
5474 goto die;
5476 break;
5477 case 9:
5478 switch (sel) {
5479 case 0:
5480 /* Mark as an IO operation because we read the time. */
5481 if (use_icount)
5482 gen_io_start();
5483 gen_helper_mfc0_count(arg, cpu_env);
5484 if (use_icount) {
5485 gen_io_end();
5487 /* Break the TB to be able to take timer interrupts immediately
5488 after reading count. */
5489 ctx->bstate = BS_STOP;
5490 rn = "Count";
5491 break;
5492 /* 6,7 are implementation dependent */
5493 default:
5494 goto die;
5496 break;
5497 case 10:
5498 switch (sel) {
5499 case 0:
5500 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EntryHi));
5501 rn = "EntryHi";
5502 break;
5503 default:
5504 goto die;
5506 break;
5507 case 11:
5508 switch (sel) {
5509 case 0:
5510 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Compare));
5511 rn = "Compare";
5512 break;
5513 /* 6,7 are implementation dependent */
5514 default:
5515 goto die;
5517 break;
5518 case 12:
5519 switch (sel) {
5520 case 0:
5521 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Status));
5522 rn = "Status";
5523 break;
5524 case 1:
5525 check_insn(ctx, ISA_MIPS32R2);
5526 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_IntCtl));
5527 rn = "IntCtl";
5528 break;
5529 case 2:
5530 check_insn(ctx, ISA_MIPS32R2);
5531 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSCtl));
5532 rn = "SRSCtl";
5533 break;
5534 case 3:
5535 check_insn(ctx, ISA_MIPS32R2);
5536 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSMap));
5537 rn = "SRSMap";
5538 break;
5539 default:
5540 goto die;
5542 break;
5543 case 13:
5544 switch (sel) {
5545 case 0:
5546 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Cause));
5547 rn = "Cause";
5548 break;
5549 default:
5550 goto die;
5552 break;
5553 case 14:
5554 switch (sel) {
5555 case 0:
5556 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EPC));
5557 rn = "EPC";
5558 break;
5559 default:
5560 goto die;
5562 break;
5563 case 15:
5564 switch (sel) {
5565 case 0:
5566 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PRid));
5567 rn = "PRid";
5568 break;
5569 case 1:
5570 check_insn(ctx, ISA_MIPS32R2);
5571 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_EBase));
5572 rn = "EBase";
5573 break;
5574 default:
5575 goto die;
5577 break;
5578 case 16:
5579 switch (sel) {
5580 case 0:
5581 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config0));
5582 rn = "Config";
5583 break;
5584 case 1:
5585 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config1));
5586 rn = "Config1";
5587 break;
5588 case 2:
5589 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config2));
5590 rn = "Config2";
5591 break;
5592 case 3:
5593 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config3));
5594 rn = "Config3";
5595 break;
5596 /* 6,7 are implementation dependent */
5597 case 6:
5598 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config6));
5599 rn = "Config6";
5600 break;
5601 case 7:
5602 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config7));
5603 rn = "Config7";
5604 break;
5605 default:
5606 goto die;
5608 break;
5609 case 17:
5610 switch (sel) {
5611 case 0:
5612 gen_helper_dmfc0_lladdr(arg, cpu_env);
5613 rn = "LLAddr";
5614 break;
5615 default:
5616 goto die;
5618 break;
5619 case 18:
5620 switch (sel) {
5621 case 0 ... 7:
5622 gen_helper_1e0i(dmfc0_watchlo, arg, sel);
5623 rn = "WatchLo";
5624 break;
5625 default:
5626 goto die;
5628 break;
5629 case 19:
5630 switch (sel) {
5631 case 0 ... 7:
5632 gen_helper_1e0i(mfc0_watchhi, arg, sel);
5633 rn = "WatchHi";
5634 break;
5635 default:
5636 goto die;
5638 break;
5639 case 20:
5640 switch (sel) {
5641 case 0:
5642 check_insn(ctx, ISA_MIPS3);
5643 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_XContext));
5644 rn = "XContext";
5645 break;
5646 default:
5647 goto die;
5649 break;
5650 case 21:
5651 /* Officially reserved, but sel 0 is used for R1x000 framemask */
5652 switch (sel) {
5653 case 0:
5654 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Framemask));
5655 rn = "Framemask";
5656 break;
5657 default:
5658 goto die;
5660 break;
5661 case 22:
5662 tcg_gen_movi_tl(arg, 0); /* unimplemented */
5663 rn = "'Diagnostic"; /* implementation dependent */
5664 break;
5665 case 23:
5666 switch (sel) {
5667 case 0:
5668 gen_helper_mfc0_debug(arg, cpu_env); /* EJTAG support */
5669 rn = "Debug";
5670 break;
5671 case 1:
5672 // gen_helper_dmfc0_tracecontrol(arg, cpu_env); /* PDtrace support */
5673 rn = "TraceControl";
5674 // break;
5675 case 2:
5676 // gen_helper_dmfc0_tracecontrol2(arg, cpu_env); /* PDtrace support */
5677 rn = "TraceControl2";
5678 // break;
5679 case 3:
5680 // gen_helper_dmfc0_usertracedata(arg, cpu_env); /* PDtrace support */
5681 rn = "UserTraceData";
5682 // break;
5683 case 4:
5684 // gen_helper_dmfc0_tracebpc(arg, cpu_env); /* PDtrace support */
5685 rn = "TraceBPC";
5686 // break;
5687 default:
5688 goto die;
5690 break;
5691 case 24:
5692 switch (sel) {
5693 case 0:
5694 /* EJTAG support */
5695 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_DEPC));
5696 rn = "DEPC";
5697 break;
5698 default:
5699 goto die;
5701 break;
5702 case 25:
5703 switch (sel) {
5704 case 0:
5705 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Performance0));
5706 rn = "Performance0";
5707 break;
5708 case 1:
5709 // gen_helper_dmfc0_performance1(arg);
5710 rn = "Performance1";
5711 // break;
5712 case 2:
5713 // gen_helper_dmfc0_performance2(arg);
5714 rn = "Performance2";
5715 // break;
5716 case 3:
5717 // gen_helper_dmfc0_performance3(arg);
5718 rn = "Performance3";
5719 // break;
5720 case 4:
5721 // gen_helper_dmfc0_performance4(arg);
5722 rn = "Performance4";
5723 // break;
5724 case 5:
5725 // gen_helper_dmfc0_performance5(arg);
5726 rn = "Performance5";
5727 // break;
5728 case 6:
5729 // gen_helper_dmfc0_performance6(arg);
5730 rn = "Performance6";
5731 // break;
5732 case 7:
5733 // gen_helper_dmfc0_performance7(arg);
5734 rn = "Performance7";
5735 // break;
5736 default:
5737 goto die;
5739 break;
5740 case 26:
5741 tcg_gen_movi_tl(arg, 0); /* unimplemented */
5742 rn = "ECC";
5743 break;
5744 case 27:
5745 switch (sel) {
5746 /* ignored */
5747 case 0 ... 3:
5748 tcg_gen_movi_tl(arg, 0); /* unimplemented */
5749 rn = "CacheErr";
5750 break;
5751 default:
5752 goto die;
5754 break;
5755 case 28:
5756 switch (sel) {
5757 case 0:
5758 case 2:
5759 case 4:
5760 case 6:
5761 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_TagLo));
5762 rn = "TagLo";
5763 break;
5764 case 1:
5765 case 3:
5766 case 5:
5767 case 7:
5768 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DataLo));
5769 rn = "DataLo";
5770 break;
5771 default:
5772 goto die;
5774 break;
5775 case 29:
5776 switch (sel) {
5777 case 0:
5778 case 2:
5779 case 4:
5780 case 6:
5781 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_TagHi));
5782 rn = "TagHi";
5783 break;
5784 case 1:
5785 case 3:
5786 case 5:
5787 case 7:
5788 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DataHi));
5789 rn = "DataHi";
5790 break;
5791 default:
5792 goto die;
5794 break;
5795 case 30:
5796 switch (sel) {
5797 case 0:
5798 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_ErrorEPC));
5799 rn = "ErrorEPC";
5800 break;
5801 default:
5802 goto die;
5804 break;
5805 case 31:
5806 switch (sel) {
5807 case 0:
5808 /* EJTAG support */
5809 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DESAVE));
5810 rn = "DESAVE";
5811 break;
5812 default:
5813 goto die;
5815 break;
5816 default:
5817 goto die;
5819 (void)rn; /* avoid a compiler warning */
5820 LOG_DISAS("dmfc0 %s (reg %d sel %d)\n", rn, reg, sel);
5821 return;
5823 die:
5824 LOG_DISAS("dmfc0 %s (reg %d sel %d)\n", rn, reg, sel);
5825 generate_exception(ctx, EXCP_RI);
5828 static void gen_dmtc0(DisasContext *ctx, TCGv arg, int reg, int sel)
5830 const char *rn = "invalid";
5832 if (sel != 0)
5833 check_insn(ctx, ISA_MIPS64);
5835 if (use_icount)
5836 gen_io_start();
5838 switch (reg) {
5839 case 0:
5840 switch (sel) {
5841 case 0:
5842 gen_helper_mtc0_index(cpu_env, arg);
5843 rn = "Index";
5844 break;
5845 case 1:
5846 check_insn(ctx, ASE_MT);
5847 gen_helper_mtc0_mvpcontrol(cpu_env, arg);
5848 rn = "MVPControl";
5849 break;
5850 case 2:
5851 check_insn(ctx, ASE_MT);
5852 /* ignored */
5853 rn = "MVPConf0";
5854 break;
5855 case 3:
5856 check_insn(ctx, ASE_MT);
5857 /* ignored */
5858 rn = "MVPConf1";
5859 break;
5860 default:
5861 goto die;
5863 break;
5864 case 1:
5865 switch (sel) {
5866 case 0:
5867 /* ignored */
5868 rn = "Random";
5869 break;
5870 case 1:
5871 check_insn(ctx, ASE_MT);
5872 gen_helper_mtc0_vpecontrol(cpu_env, arg);
5873 rn = "VPEControl";
5874 break;
5875 case 2:
5876 check_insn(ctx, ASE_MT);
5877 gen_helper_mtc0_vpeconf0(cpu_env, arg);
5878 rn = "VPEConf0";
5879 break;
5880 case 3:
5881 check_insn(ctx, ASE_MT);
5882 gen_helper_mtc0_vpeconf1(cpu_env, arg);
5883 rn = "VPEConf1";
5884 break;
5885 case 4:
5886 check_insn(ctx, ASE_MT);
5887 gen_helper_mtc0_yqmask(cpu_env, arg);
5888 rn = "YQMask";
5889 break;
5890 case 5:
5891 check_insn(ctx, ASE_MT);
5892 tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_VPESchedule));
5893 rn = "VPESchedule";
5894 break;
5895 case 6:
5896 check_insn(ctx, ASE_MT);
5897 tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_VPEScheFBack));
5898 rn = "VPEScheFBack";
5899 break;
5900 case 7:
5901 check_insn(ctx, ASE_MT);
5902 gen_helper_mtc0_vpeopt(cpu_env, arg);
5903 rn = "VPEOpt";
5904 break;
5905 default:
5906 goto die;
5908 break;
5909 case 2:
5910 switch (sel) {
5911 case 0:
5912 gen_helper_mtc0_entrylo0(cpu_env, arg);
5913 rn = "EntryLo0";
5914 break;
5915 case 1:
5916 check_insn(ctx, ASE_MT);
5917 gen_helper_mtc0_tcstatus(cpu_env, arg);
5918 rn = "TCStatus";
5919 break;
5920 case 2:
5921 check_insn(ctx, ASE_MT);
5922 gen_helper_mtc0_tcbind(cpu_env, arg);
5923 rn = "TCBind";
5924 break;
5925 case 3:
5926 check_insn(ctx, ASE_MT);
5927 gen_helper_mtc0_tcrestart(cpu_env, arg);
5928 rn = "TCRestart";
5929 break;
5930 case 4:
5931 check_insn(ctx, ASE_MT);
5932 gen_helper_mtc0_tchalt(cpu_env, arg);
5933 rn = "TCHalt";
5934 break;
5935 case 5:
5936 check_insn(ctx, ASE_MT);
5937 gen_helper_mtc0_tccontext(cpu_env, arg);
5938 rn = "TCContext";
5939 break;
5940 case 6:
5941 check_insn(ctx, ASE_MT);
5942 gen_helper_mtc0_tcschedule(cpu_env, arg);
5943 rn = "TCSchedule";
5944 break;
5945 case 7:
5946 check_insn(ctx, ASE_MT);
5947 gen_helper_mtc0_tcschefback(cpu_env, arg);
5948 rn = "TCScheFBack";
5949 break;
5950 default:
5951 goto die;
5953 break;
5954 case 3:
5955 switch (sel) {
5956 case 0:
5957 gen_helper_mtc0_entrylo1(cpu_env, arg);
5958 rn = "EntryLo1";
5959 break;
5960 default:
5961 goto die;
5963 break;
5964 case 4:
5965 switch (sel) {
5966 case 0:
5967 gen_helper_mtc0_context(cpu_env, arg);
5968 rn = "Context";
5969 break;
5970 case 1:
5971 // gen_helper_mtc0_contextconfig(cpu_env, arg); /* SmartMIPS ASE */
5972 rn = "ContextConfig";
5973 // break;
5974 default:
5975 goto die;
5977 break;
5978 case 5:
5979 switch (sel) {
5980 case 0:
5981 gen_helper_mtc0_pagemask(cpu_env, arg);
5982 rn = "PageMask";
5983 break;
5984 case 1:
5985 check_insn(ctx, ISA_MIPS32R2);
5986 gen_helper_mtc0_pagegrain(cpu_env, arg);
5987 rn = "PageGrain";
5988 break;
5989 default:
5990 goto die;
5992 break;
5993 case 6:
5994 switch (sel) {
5995 case 0:
5996 gen_helper_mtc0_wired(cpu_env, arg);
5997 rn = "Wired";
5998 break;
5999 case 1:
6000 check_insn(ctx, ISA_MIPS32R2);
6001 gen_helper_mtc0_srsconf0(cpu_env, arg);
6002 rn = "SRSConf0";
6003 break;
6004 case 2:
6005 check_insn(ctx, ISA_MIPS32R2);
6006 gen_helper_mtc0_srsconf1(cpu_env, arg);
6007 rn = "SRSConf1";
6008 break;
6009 case 3:
6010 check_insn(ctx, ISA_MIPS32R2);
6011 gen_helper_mtc0_srsconf2(cpu_env, arg);
6012 rn = "SRSConf2";
6013 break;
6014 case 4:
6015 check_insn(ctx, ISA_MIPS32R2);
6016 gen_helper_mtc0_srsconf3(cpu_env, arg);
6017 rn = "SRSConf3";
6018 break;
6019 case 5:
6020 check_insn(ctx, ISA_MIPS32R2);
6021 gen_helper_mtc0_srsconf4(cpu_env, arg);
6022 rn = "SRSConf4";
6023 break;
6024 default:
6025 goto die;
6027 break;
6028 case 7:
6029 switch (sel) {
6030 case 0:
6031 check_insn(ctx, ISA_MIPS32R2);
6032 gen_helper_mtc0_hwrena(cpu_env, arg);
6033 rn = "HWREna";
6034 break;
6035 default:
6036 goto die;
6038 break;
6039 case 8:
6040 /* ignored */
6041 rn = "BadVAddr";
6042 break;
6043 case 9:
6044 switch (sel) {
6045 case 0:
6046 gen_helper_mtc0_count(cpu_env, arg);
6047 rn = "Count";
6048 break;
6049 /* 6,7 are implementation dependent */
6050 default:
6051 goto die;
6053 /* Stop translation as we may have switched the execution mode */
6054 ctx->bstate = BS_STOP;
6055 break;
6056 case 10:
6057 switch (sel) {
6058 case 0:
6059 gen_helper_mtc0_entryhi(cpu_env, arg);
6060 rn = "EntryHi";
6061 break;
6062 default:
6063 goto die;
6065 break;
6066 case 11:
6067 switch (sel) {
6068 case 0:
6069 gen_helper_mtc0_compare(cpu_env, arg);
6070 rn = "Compare";
6071 break;
6072 /* 6,7 are implementation dependent */
6073 default:
6074 goto die;
6076 /* Stop translation as we may have switched the execution mode */
6077 ctx->bstate = BS_STOP;
6078 break;
6079 case 12:
6080 switch (sel) {
6081 case 0:
6082 save_cpu_state(ctx, 1);
6083 gen_helper_mtc0_status(cpu_env, arg);
6084 /* BS_STOP isn't good enough here, hflags may have changed. */
6085 gen_save_pc(ctx->pc + 4);
6086 ctx->bstate = BS_EXCP;
6087 rn = "Status";
6088 break;
6089 case 1:
6090 check_insn(ctx, ISA_MIPS32R2);
6091 gen_helper_mtc0_intctl(cpu_env, arg);
6092 /* Stop translation as we may have switched the execution mode */
6093 ctx->bstate = BS_STOP;
6094 rn = "IntCtl";
6095 break;
6096 case 2:
6097 check_insn(ctx, ISA_MIPS32R2);
6098 gen_helper_mtc0_srsctl(cpu_env, arg);
6099 /* Stop translation as we may have switched the execution mode */
6100 ctx->bstate = BS_STOP;
6101 rn = "SRSCtl";
6102 break;
6103 case 3:
6104 check_insn(ctx, ISA_MIPS32R2);
6105 gen_mtc0_store32(arg, offsetof(CPUMIPSState, CP0_SRSMap));
6106 /* Stop translation as we may have switched the execution mode */
6107 ctx->bstate = BS_STOP;
6108 rn = "SRSMap";
6109 break;
6110 default:
6111 goto die;
6113 break;
6114 case 13:
6115 switch (sel) {
6116 case 0:
6117 save_cpu_state(ctx, 1);
6118 /* Mark as an IO operation because we may trigger a software
6119 interrupt. */
6120 if (use_icount) {
6121 gen_io_start();
6123 gen_helper_mtc0_cause(cpu_env, arg);
6124 if (use_icount) {
6125 gen_io_end();
6127 /* Stop translation as we may have triggered an intetrupt */
6128 ctx->bstate = BS_STOP;
6129 rn = "Cause";
6130 break;
6131 default:
6132 goto die;
6134 break;
6135 case 14:
6136 switch (sel) {
6137 case 0:
6138 tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EPC));
6139 rn = "EPC";
6140 break;
6141 default:
6142 goto die;
6144 break;
6145 case 15:
6146 switch (sel) {
6147 case 0:
6148 /* ignored */
6149 rn = "PRid";
6150 break;
6151 case 1:
6152 check_insn(ctx, ISA_MIPS32R2);
6153 gen_helper_mtc0_ebase(cpu_env, arg);
6154 rn = "EBase";
6155 break;
6156 default:
6157 goto die;
6159 break;
6160 case 16:
6161 switch (sel) {
6162 case 0:
6163 gen_helper_mtc0_config0(cpu_env, arg);
6164 rn = "Config";
6165 /* Stop translation as we may have switched the execution mode */
6166 ctx->bstate = BS_STOP;
6167 break;
6168 case 1:
6169 /* ignored, read only */
6170 rn = "Config1";
6171 break;
6172 case 2:
6173 gen_helper_mtc0_config2(cpu_env, arg);
6174 rn = "Config2";
6175 /* Stop translation as we may have switched the execution mode */
6176 ctx->bstate = BS_STOP;
6177 break;
6178 case 3:
6179 /* ignored */
6180 rn = "Config3";
6181 break;
6182 /* 6,7 are implementation dependent */
6183 default:
6184 rn = "Invalid config selector";
6185 goto die;
6187 break;
6188 case 17:
6189 switch (sel) {
6190 case 0:
6191 gen_helper_mtc0_lladdr(cpu_env, arg);
6192 rn = "LLAddr";
6193 break;
6194 default:
6195 goto die;
6197 break;
6198 case 18:
6199 switch (sel) {
6200 case 0 ... 7:
6201 gen_helper_0e1i(mtc0_watchlo, arg, sel);
6202 rn = "WatchLo";
6203 break;
6204 default:
6205 goto die;
6207 break;
6208 case 19:
6209 switch (sel) {
6210 case 0 ... 7:
6211 gen_helper_0e1i(mtc0_watchhi, arg, sel);
6212 rn = "WatchHi";
6213 break;
6214 default:
6215 goto die;
6217 break;
6218 case 20:
6219 switch (sel) {
6220 case 0:
6221 check_insn(ctx, ISA_MIPS3);
6222 gen_helper_mtc0_xcontext(cpu_env, arg);
6223 rn = "XContext";
6224 break;
6225 default:
6226 goto die;
6228 break;
6229 case 21:
6230 /* Officially reserved, but sel 0 is used for R1x000 framemask */
6231 switch (sel) {
6232 case 0:
6233 gen_helper_mtc0_framemask(cpu_env, arg);
6234 rn = "Framemask";
6235 break;
6236 default:
6237 goto die;
6239 break;
6240 case 22:
6241 /* ignored */
6242 rn = "Diagnostic"; /* implementation dependent */
6243 break;
6244 case 23:
6245 switch (sel) {
6246 case 0:
6247 gen_helper_mtc0_debug(cpu_env, arg); /* EJTAG support */
6248 /* BS_STOP isn't good enough here, hflags may have changed. */
6249 gen_save_pc(ctx->pc + 4);
6250 ctx->bstate = BS_EXCP;
6251 rn = "Debug";
6252 break;
6253 case 1:
6254 // gen_helper_mtc0_tracecontrol(cpu_env, arg); /* PDtrace support */
6255 /* Stop translation as we may have switched the execution mode */
6256 ctx->bstate = BS_STOP;
6257 rn = "TraceControl";
6258 // break;
6259 case 2:
6260 // gen_helper_mtc0_tracecontrol2(cpu_env, arg); /* PDtrace support */
6261 /* Stop translation as we may have switched the execution mode */
6262 ctx->bstate = BS_STOP;
6263 rn = "TraceControl2";
6264 // break;
6265 case 3:
6266 // gen_helper_mtc0_usertracedata(cpu_env, arg); /* PDtrace support */
6267 /* Stop translation as we may have switched the execution mode */
6268 ctx->bstate = BS_STOP;
6269 rn = "UserTraceData";
6270 // break;
6271 case 4:
6272 // gen_helper_mtc0_tracebpc(cpu_env, arg); /* PDtrace support */
6273 /* Stop translation as we may have switched the execution mode */
6274 ctx->bstate = BS_STOP;
6275 rn = "TraceBPC";
6276 // break;
6277 default:
6278 goto die;
6280 break;
6281 case 24:
6282 switch (sel) {
6283 case 0:
6284 /* EJTAG support */
6285 tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_DEPC));
6286 rn = "DEPC";
6287 break;
6288 default:
6289 goto die;
6291 break;
6292 case 25:
6293 switch (sel) {
6294 case 0:
6295 gen_helper_mtc0_performance0(cpu_env, arg);
6296 rn = "Performance0";
6297 break;
6298 case 1:
6299 // gen_helper_mtc0_performance1(cpu_env, arg);
6300 rn = "Performance1";
6301 // break;
6302 case 2:
6303 // gen_helper_mtc0_performance2(cpu_env, arg);
6304 rn = "Performance2";
6305 // break;
6306 case 3:
6307 // gen_helper_mtc0_performance3(cpu_env, arg);
6308 rn = "Performance3";
6309 // break;
6310 case 4:
6311 // gen_helper_mtc0_performance4(cpu_env, arg);
6312 rn = "Performance4";
6313 // break;
6314 case 5:
6315 // gen_helper_mtc0_performance5(cpu_env, arg);
6316 rn = "Performance5";
6317 // break;
6318 case 6:
6319 // gen_helper_mtc0_performance6(cpu_env, arg);
6320 rn = "Performance6";
6321 // break;
6322 case 7:
6323 // gen_helper_mtc0_performance7(cpu_env, arg);
6324 rn = "Performance7";
6325 // break;
6326 default:
6327 goto die;
6329 break;
6330 case 26:
6331 /* ignored */
6332 rn = "ECC";
6333 break;
6334 case 27:
6335 switch (sel) {
6336 case 0 ... 3:
6337 /* ignored */
6338 rn = "CacheErr";
6339 break;
6340 default:
6341 goto die;
6343 break;
6344 case 28:
6345 switch (sel) {
6346 case 0:
6347 case 2:
6348 case 4:
6349 case 6:
6350 gen_helper_mtc0_taglo(cpu_env, arg);
6351 rn = "TagLo";
6352 break;
6353 case 1:
6354 case 3:
6355 case 5:
6356 case 7:
6357 gen_helper_mtc0_datalo(cpu_env, arg);
6358 rn = "DataLo";
6359 break;
6360 default:
6361 goto die;
6363 break;
6364 case 29:
6365 switch (sel) {
6366 case 0:
6367 case 2:
6368 case 4:
6369 case 6:
6370 gen_helper_mtc0_taghi(cpu_env, arg);
6371 rn = "TagHi";
6372 break;
6373 case 1:
6374 case 3:
6375 case 5:
6376 case 7:
6377 gen_helper_mtc0_datahi(cpu_env, arg);
6378 rn = "DataHi";
6379 break;
6380 default:
6381 rn = "invalid sel";
6382 goto die;
6384 break;
6385 case 30:
6386 switch (sel) {
6387 case 0:
6388 tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_ErrorEPC));
6389 rn = "ErrorEPC";
6390 break;
6391 default:
6392 goto die;
6394 break;
6395 case 31:
6396 switch (sel) {
6397 case 0:
6398 /* EJTAG support */
6399 gen_mtc0_store32(arg, offsetof(CPUMIPSState, CP0_DESAVE));
6400 rn = "DESAVE";
6401 break;
6402 default:
6403 goto die;
6405 /* Stop translation as we may have switched the execution mode */
6406 ctx->bstate = BS_STOP;
6407 break;
6408 default:
6409 goto die;
6411 (void)rn; /* avoid a compiler warning */
6412 LOG_DISAS("dmtc0 %s (reg %d sel %d)\n", rn, reg, sel);
6413 /* For simplicity assume that all writes can cause interrupts. */
6414 if (use_icount) {
6415 gen_io_end();
6416 ctx->bstate = BS_STOP;
6418 return;
6420 die:
6421 LOG_DISAS("dmtc0 %s (reg %d sel %d)\n", rn, reg, sel);
6422 generate_exception(ctx, EXCP_RI);
6424 #endif /* TARGET_MIPS64 */
6426 static void gen_mftr(CPUMIPSState *env, DisasContext *ctx, int rt, int rd,
6427 int u, int sel, int h)
6429 int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
6430 TCGv t0 = tcg_temp_local_new();
6432 if ((env->CP0_VPEConf0 & (1 << CP0VPEC0_MVP)) == 0 &&
6433 ((env->tcs[other_tc].CP0_TCBind & (0xf << CP0TCBd_CurVPE)) !=
6434 (env->active_tc.CP0_TCBind & (0xf << CP0TCBd_CurVPE))))
6435 tcg_gen_movi_tl(t0, -1);
6436 else if ((env->CP0_VPEControl & (0xff << CP0VPECo_TargTC)) >
6437 (env->mvp->CP0_MVPConf0 & (0xff << CP0MVPC0_PTC)))
6438 tcg_gen_movi_tl(t0, -1);
6439 else if (u == 0) {
6440 switch (rt) {
6441 case 1:
6442 switch (sel) {
6443 case 1:
6444 gen_helper_mftc0_vpecontrol(t0, cpu_env);
6445 break;
6446 case 2:
6447 gen_helper_mftc0_vpeconf0(t0, cpu_env);
6448 break;
6449 default:
6450 goto die;
6451 break;
6453 break;
6454 case 2:
6455 switch (sel) {
6456 case 1:
6457 gen_helper_mftc0_tcstatus(t0, cpu_env);
6458 break;
6459 case 2:
6460 gen_helper_mftc0_tcbind(t0, cpu_env);
6461 break;
6462 case 3:
6463 gen_helper_mftc0_tcrestart(t0, cpu_env);
6464 break;
6465 case 4:
6466 gen_helper_mftc0_tchalt(t0, cpu_env);
6467 break;
6468 case 5:
6469 gen_helper_mftc0_tccontext(t0, cpu_env);
6470 break;
6471 case 6:
6472 gen_helper_mftc0_tcschedule(t0, cpu_env);
6473 break;
6474 case 7:
6475 gen_helper_mftc0_tcschefback(t0, cpu_env);
6476 break;
6477 default:
6478 gen_mfc0(ctx, t0, rt, sel);
6479 break;
6481 break;
6482 case 10:
6483 switch (sel) {
6484 case 0:
6485 gen_helper_mftc0_entryhi(t0, cpu_env);
6486 break;
6487 default:
6488 gen_mfc0(ctx, t0, rt, sel);
6489 break;
6491 case 12:
6492 switch (sel) {
6493 case 0:
6494 gen_helper_mftc0_status(t0, cpu_env);
6495 break;
6496 default:
6497 gen_mfc0(ctx, t0, rt, sel);
6498 break;
6500 case 13:
6501 switch (sel) {
6502 case 0:
6503 gen_helper_mftc0_cause(t0, cpu_env);
6504 break;
6505 default:
6506 goto die;
6507 break;
6509 break;
6510 case 14:
6511 switch (sel) {
6512 case 0:
6513 gen_helper_mftc0_epc(t0, cpu_env);
6514 break;
6515 default:
6516 goto die;
6517 break;
6519 break;
6520 case 15:
6521 switch (sel) {
6522 case 1:
6523 gen_helper_mftc0_ebase(t0, cpu_env);
6524 break;
6525 default:
6526 goto die;
6527 break;
6529 break;
6530 case 16:
6531 switch (sel) {
6532 case 0 ... 7:
6533 gen_helper_mftc0_configx(t0, cpu_env, tcg_const_tl(sel));
6534 break;
6535 default:
6536 goto die;
6537 break;
6539 break;
6540 case 23:
6541 switch (sel) {
6542 case 0:
6543 gen_helper_mftc0_debug(t0, cpu_env);
6544 break;
6545 default:
6546 gen_mfc0(ctx, t0, rt, sel);
6547 break;
6549 break;
6550 default:
6551 gen_mfc0(ctx, t0, rt, sel);
6553 } else switch (sel) {
6554 /* GPR registers. */
6555 case 0:
6556 gen_helper_1e0i(mftgpr, t0, rt);
6557 break;
6558 /* Auxiliary CPU registers */
6559 case 1:
6560 switch (rt) {
6561 case 0:
6562 gen_helper_1e0i(mftlo, t0, 0);
6563 break;
6564 case 1:
6565 gen_helper_1e0i(mfthi, t0, 0);
6566 break;
6567 case 2:
6568 gen_helper_1e0i(mftacx, t0, 0);
6569 break;
6570 case 4:
6571 gen_helper_1e0i(mftlo, t0, 1);
6572 break;
6573 case 5:
6574 gen_helper_1e0i(mfthi, t0, 1);
6575 break;
6576 case 6:
6577 gen_helper_1e0i(mftacx, t0, 1);
6578 break;
6579 case 8:
6580 gen_helper_1e0i(mftlo, t0, 2);
6581 break;
6582 case 9:
6583 gen_helper_1e0i(mfthi, t0, 2);
6584 break;
6585 case 10:
6586 gen_helper_1e0i(mftacx, t0, 2);
6587 break;
6588 case 12:
6589 gen_helper_1e0i(mftlo, t0, 3);
6590 break;
6591 case 13:
6592 gen_helper_1e0i(mfthi, t0, 3);
6593 break;
6594 case 14:
6595 gen_helper_1e0i(mftacx, t0, 3);
6596 break;
6597 case 16:
6598 gen_helper_mftdsp(t0, cpu_env);
6599 break;
6600 default:
6601 goto die;
6603 break;
6604 /* Floating point (COP1). */
6605 case 2:
6606 /* XXX: For now we support only a single FPU context. */
6607 if (h == 0) {
6608 TCGv_i32 fp0 = tcg_temp_new_i32();
6610 gen_load_fpr32(fp0, rt);
6611 tcg_gen_ext_i32_tl(t0, fp0);
6612 tcg_temp_free_i32(fp0);
6613 } else {
6614 TCGv_i32 fp0 = tcg_temp_new_i32();
6616 gen_load_fpr32h(fp0, rt);
6617 tcg_gen_ext_i32_tl(t0, fp0);
6618 tcg_temp_free_i32(fp0);
6620 break;
6621 case 3:
6622 /* XXX: For now we support only a single FPU context. */
6623 gen_helper_1e0i(cfc1, t0, rt);
6624 break;
6625 /* COP2: Not implemented. */
6626 case 4:
6627 case 5:
6628 /* fall through */
6629 default:
6630 goto die;
6632 LOG_DISAS("mftr (reg %d u %d sel %d h %d)\n", rt, u, sel, h);
6633 gen_store_gpr(t0, rd);
6634 tcg_temp_free(t0);
6635 return;
6637 die:
6638 tcg_temp_free(t0);
6639 LOG_DISAS("mftr (reg %d u %d sel %d h %d)\n", rt, u, sel, h);
6640 generate_exception(ctx, EXCP_RI);
6643 static void gen_mttr(CPUMIPSState *env, DisasContext *ctx, int rd, int rt,
6644 int u, int sel, int h)
6646 int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
6647 TCGv t0 = tcg_temp_local_new();
6649 gen_load_gpr(t0, rt);
6650 if ((env->CP0_VPEConf0 & (1 << CP0VPEC0_MVP)) == 0 &&
6651 ((env->tcs[other_tc].CP0_TCBind & (0xf << CP0TCBd_CurVPE)) !=
6652 (env->active_tc.CP0_TCBind & (0xf << CP0TCBd_CurVPE))))
6653 /* NOP */ ;
6654 else if ((env->CP0_VPEControl & (0xff << CP0VPECo_TargTC)) >
6655 (env->mvp->CP0_MVPConf0 & (0xff << CP0MVPC0_PTC)))
6656 /* NOP */ ;
6657 else if (u == 0) {
6658 switch (rd) {
6659 case 1:
6660 switch (sel) {
6661 case 1:
6662 gen_helper_mttc0_vpecontrol(cpu_env, t0);
6663 break;
6664 case 2:
6665 gen_helper_mttc0_vpeconf0(cpu_env, t0);
6666 break;
6667 default:
6668 goto die;
6669 break;
6671 break;
6672 case 2:
6673 switch (sel) {
6674 case 1:
6675 gen_helper_mttc0_tcstatus(cpu_env, t0);
6676 break;
6677 case 2:
6678 gen_helper_mttc0_tcbind(cpu_env, t0);
6679 break;
6680 case 3:
6681 gen_helper_mttc0_tcrestart(cpu_env, t0);
6682 break;
6683 case 4:
6684 gen_helper_mttc0_tchalt(cpu_env, t0);
6685 break;
6686 case 5:
6687 gen_helper_mttc0_tccontext(cpu_env, t0);
6688 break;
6689 case 6:
6690 gen_helper_mttc0_tcschedule(cpu_env, t0);
6691 break;
6692 case 7:
6693 gen_helper_mttc0_tcschefback(cpu_env, t0);
6694 break;
6695 default:
6696 gen_mtc0(ctx, t0, rd, sel);
6697 break;
6699 break;
6700 case 10:
6701 switch (sel) {
6702 case 0:
6703 gen_helper_mttc0_entryhi(cpu_env, t0);
6704 break;
6705 default:
6706 gen_mtc0(ctx, t0, rd, sel);
6707 break;
6709 case 12:
6710 switch (sel) {
6711 case 0:
6712 gen_helper_mttc0_status(cpu_env, t0);
6713 break;
6714 default:
6715 gen_mtc0(ctx, t0, rd, sel);
6716 break;
6718 case 13:
6719 switch (sel) {
6720 case 0:
6721 gen_helper_mttc0_cause(cpu_env, t0);
6722 break;
6723 default:
6724 goto die;
6725 break;
6727 break;
6728 case 15:
6729 switch (sel) {
6730 case 1:
6731 gen_helper_mttc0_ebase(cpu_env, t0);
6732 break;
6733 default:
6734 goto die;
6735 break;
6737 break;
6738 case 23:
6739 switch (sel) {
6740 case 0:
6741 gen_helper_mttc0_debug(cpu_env, t0);
6742 break;
6743 default:
6744 gen_mtc0(ctx, t0, rd, sel);
6745 break;
6747 break;
6748 default:
6749 gen_mtc0(ctx, t0, rd, sel);
6751 } else switch (sel) {
6752 /* GPR registers. */
6753 case 0:
6754 gen_helper_0e1i(mttgpr, t0, rd);
6755 break;
6756 /* Auxiliary CPU registers */
6757 case 1:
6758 switch (rd) {
6759 case 0:
6760 gen_helper_0e1i(mttlo, t0, 0);
6761 break;
6762 case 1:
6763 gen_helper_0e1i(mtthi, t0, 0);
6764 break;
6765 case 2:
6766 gen_helper_0e1i(mttacx, t0, 0);
6767 break;
6768 case 4:
6769 gen_helper_0e1i(mttlo, t0, 1);
6770 break;
6771 case 5:
6772 gen_helper_0e1i(mtthi, t0, 1);
6773 break;
6774 case 6:
6775 gen_helper_0e1i(mttacx, t0, 1);
6776 break;
6777 case 8:
6778 gen_helper_0e1i(mttlo, t0, 2);
6779 break;
6780 case 9:
6781 gen_helper_0e1i(mtthi, t0, 2);
6782 break;
6783 case 10:
6784 gen_helper_0e1i(mttacx, t0, 2);
6785 break;
6786 case 12:
6787 gen_helper_0e1i(mttlo, t0, 3);
6788 break;
6789 case 13:
6790 gen_helper_0e1i(mtthi, t0, 3);
6791 break;
6792 case 14:
6793 gen_helper_0e1i(mttacx, t0, 3);
6794 break;
6795 case 16:
6796 gen_helper_mttdsp(cpu_env, t0);
6797 break;
6798 default:
6799 goto die;
6801 break;
6802 /* Floating point (COP1). */
6803 case 2:
6804 /* XXX: For now we support only a single FPU context. */
6805 if (h == 0) {
6806 TCGv_i32 fp0 = tcg_temp_new_i32();
6808 tcg_gen_trunc_tl_i32(fp0, t0);
6809 gen_store_fpr32(fp0, rd);
6810 tcg_temp_free_i32(fp0);
6811 } else {
6812 TCGv_i32 fp0 = tcg_temp_new_i32();
6814 tcg_gen_trunc_tl_i32(fp0, t0);
6815 gen_store_fpr32h(fp0, rd);
6816 tcg_temp_free_i32(fp0);
6818 break;
6819 case 3:
6820 /* XXX: For now we support only a single FPU context. */
6822 TCGv_i32 fs_tmp = tcg_const_i32(rd);
6824 gen_helper_0e2i(ctc1, t0, fs_tmp, rt);
6825 tcg_temp_free_i32(fs_tmp);
6827 break;
6828 /* COP2: Not implemented. */
6829 case 4:
6830 case 5:
6831 /* fall through */
6832 default:
6833 goto die;
6835 LOG_DISAS("mttr (reg %d u %d sel %d h %d)\n", rd, u, sel, h);
6836 tcg_temp_free(t0);
6837 return;
6839 die:
6840 tcg_temp_free(t0);
6841 LOG_DISAS("mttr (reg %d u %d sel %d h %d)\n", rd, u, sel, h);
6842 generate_exception(ctx, EXCP_RI);
6845 static void gen_cp0 (CPUMIPSState *env, DisasContext *ctx, uint32_t opc, int rt, int rd)
6847 const char *opn = "ldst";
6849 check_cp0_enabled(ctx);
6850 switch (opc) {
6851 case OPC_MFC0:
6852 if (rt == 0) {
6853 /* Treat as NOP. */
6854 return;
6856 gen_mfc0(ctx, cpu_gpr[rt], rd, ctx->opcode & 0x7);
6857 opn = "mfc0";
6858 break;
6859 case OPC_MTC0:
6861 TCGv t0 = tcg_temp_new();
6863 gen_load_gpr(t0, rt);
6864 gen_mtc0(ctx, t0, rd, ctx->opcode & 0x7);
6865 tcg_temp_free(t0);
6867 opn = "mtc0";
6868 break;
6869 #if defined(TARGET_MIPS64)
6870 case OPC_DMFC0:
6871 check_insn(ctx, ISA_MIPS3);
6872 if (rt == 0) {
6873 /* Treat as NOP. */
6874 return;
6876 gen_dmfc0(ctx, cpu_gpr[rt], rd, ctx->opcode & 0x7);
6877 opn = "dmfc0";
6878 break;
6879 case OPC_DMTC0:
6880 check_insn(ctx, ISA_MIPS3);
6882 TCGv t0 = tcg_temp_new();
6884 gen_load_gpr(t0, rt);
6885 gen_dmtc0(ctx, t0, rd, ctx->opcode & 0x7);
6886 tcg_temp_free(t0);
6888 opn = "dmtc0";
6889 break;
6890 #endif
6891 case OPC_MFTR:
6892 check_insn(ctx, ASE_MT);
6893 if (rd == 0) {
6894 /* Treat as NOP. */
6895 return;
6897 gen_mftr(env, ctx, rt, rd, (ctx->opcode >> 5) & 1,
6898 ctx->opcode & 0x7, (ctx->opcode >> 4) & 1);
6899 opn = "mftr";
6900 break;
6901 case OPC_MTTR:
6902 check_insn(ctx, ASE_MT);
6903 gen_mttr(env, ctx, rd, rt, (ctx->opcode >> 5) & 1,
6904 ctx->opcode & 0x7, (ctx->opcode >> 4) & 1);
6905 opn = "mttr";
6906 break;
6907 case OPC_TLBWI:
6908 opn = "tlbwi";
6909 if (!env->tlb->helper_tlbwi)
6910 goto die;
6911 gen_helper_tlbwi(cpu_env);
6912 break;
6913 case OPC_TLBWR:
6914 opn = "tlbwr";
6915 if (!env->tlb->helper_tlbwr)
6916 goto die;
6917 gen_helper_tlbwr(cpu_env);
6918 break;
6919 case OPC_TLBP:
6920 opn = "tlbp";
6921 if (!env->tlb->helper_tlbp)
6922 goto die;
6923 gen_helper_tlbp(cpu_env);
6924 break;
6925 case OPC_TLBR:
6926 opn = "tlbr";
6927 if (!env->tlb->helper_tlbr)
6928 goto die;
6929 gen_helper_tlbr(cpu_env);
6930 break;
6931 case OPC_ERET:
6932 opn = "eret";
6933 check_insn(ctx, ISA_MIPS2);
6934 gen_helper_eret(cpu_env);
6935 ctx->bstate = BS_EXCP;
6936 break;
6937 case OPC_DERET:
6938 opn = "deret";
6939 check_insn(ctx, ISA_MIPS32);
6940 if (!(ctx->hflags & MIPS_HFLAG_DM)) {
6941 MIPS_INVAL(opn);
6942 generate_exception(ctx, EXCP_RI);
6943 } else {
6944 gen_helper_deret(cpu_env);
6945 ctx->bstate = BS_EXCP;
6947 break;
6948 case OPC_WAIT:
6949 opn = "wait";
6950 check_insn(ctx, ISA_MIPS3 | ISA_MIPS32);
6951 /* If we get an exception, we want to restart at next instruction */
6952 ctx->pc += 4;
6953 save_cpu_state(ctx, 1);
6954 ctx->pc -= 4;
6955 gen_helper_wait(cpu_env);
6956 ctx->bstate = BS_EXCP;
6957 break;
6958 default:
6959 die:
6960 MIPS_INVAL(opn);
6961 generate_exception(ctx, EXCP_RI);
6962 return;
6964 (void)opn; /* avoid a compiler warning */
6965 MIPS_DEBUG("%s %s %d", opn, regnames[rt], rd);
6967 #endif /* !CONFIG_USER_ONLY */
6969 /* CP1 Branches (before delay slot) */
6970 static void gen_compute_branch1(DisasContext *ctx, uint32_t op,
6971 int32_t cc, int32_t offset)
6973 target_ulong btarget;
6974 const char *opn = "cp1 cond branch";
6975 TCGv_i32 t0 = tcg_temp_new_i32();
6977 if (cc != 0)
6978 check_insn(ctx, ISA_MIPS4 | ISA_MIPS32);
6980 btarget = ctx->pc + 4 + offset;
6982 switch (op) {
6983 case OPC_BC1F:
6984 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
6985 tcg_gen_not_i32(t0, t0);
6986 tcg_gen_andi_i32(t0, t0, 1);
6987 tcg_gen_extu_i32_tl(bcond, t0);
6988 opn = "bc1f";
6989 goto not_likely;
6990 case OPC_BC1FL:
6991 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
6992 tcg_gen_not_i32(t0, t0);
6993 tcg_gen_andi_i32(t0, t0, 1);
6994 tcg_gen_extu_i32_tl(bcond, t0);
6995 opn = "bc1fl";
6996 goto likely;
6997 case OPC_BC1T:
6998 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
6999 tcg_gen_andi_i32(t0, t0, 1);
7000 tcg_gen_extu_i32_tl(bcond, t0);
7001 opn = "bc1t";
7002 goto not_likely;
7003 case OPC_BC1TL:
7004 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
7005 tcg_gen_andi_i32(t0, t0, 1);
7006 tcg_gen_extu_i32_tl(bcond, t0);
7007 opn = "bc1tl";
7008 likely:
7009 ctx->hflags |= MIPS_HFLAG_BL;
7010 break;
7011 case OPC_BC1FANY2:
7013 TCGv_i32 t1 = tcg_temp_new_i32();
7014 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
7015 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+1));
7016 tcg_gen_nand_i32(t0, t0, t1);
7017 tcg_temp_free_i32(t1);
7018 tcg_gen_andi_i32(t0, t0, 1);
7019 tcg_gen_extu_i32_tl(bcond, t0);
7021 opn = "bc1any2f";
7022 goto not_likely;
7023 case OPC_BC1TANY2:
7025 TCGv_i32 t1 = tcg_temp_new_i32();
7026 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
7027 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+1));
7028 tcg_gen_or_i32(t0, t0, t1);
7029 tcg_temp_free_i32(t1);
7030 tcg_gen_andi_i32(t0, t0, 1);
7031 tcg_gen_extu_i32_tl(bcond, t0);
7033 opn = "bc1any2t";
7034 goto not_likely;
7035 case OPC_BC1FANY4:
7037 TCGv_i32 t1 = tcg_temp_new_i32();
7038 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
7039 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+1));
7040 tcg_gen_and_i32(t0, t0, t1);
7041 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+2));
7042 tcg_gen_and_i32(t0, t0, t1);
7043 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+3));
7044 tcg_gen_nand_i32(t0, t0, t1);
7045 tcg_temp_free_i32(t1);
7046 tcg_gen_andi_i32(t0, t0, 1);
7047 tcg_gen_extu_i32_tl(bcond, t0);
7049 opn = "bc1any4f";
7050 goto not_likely;
7051 case OPC_BC1TANY4:
7053 TCGv_i32 t1 = tcg_temp_new_i32();
7054 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
7055 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+1));
7056 tcg_gen_or_i32(t0, t0, t1);
7057 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+2));
7058 tcg_gen_or_i32(t0, t0, t1);
7059 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+3));
7060 tcg_gen_or_i32(t0, t0, t1);
7061 tcg_temp_free_i32(t1);
7062 tcg_gen_andi_i32(t0, t0, 1);
7063 tcg_gen_extu_i32_tl(bcond, t0);
7065 opn = "bc1any4t";
7066 not_likely:
7067 ctx->hflags |= MIPS_HFLAG_BC;
7068 break;
7069 default:
7070 MIPS_INVAL(opn);
7071 generate_exception (ctx, EXCP_RI);
7072 goto out;
7074 (void)opn; /* avoid a compiler warning */
7075 MIPS_DEBUG("%s: cond %02x target " TARGET_FMT_lx, opn,
7076 ctx->hflags, btarget);
7077 ctx->btarget = btarget;
7079 out:
7080 tcg_temp_free_i32(t0);
7083 /* Coprocessor 1 (FPU) */
7085 #define FOP(func, fmt) (((fmt) << 21) | (func))
7087 enum fopcode {
7088 OPC_ADD_S = FOP(0, FMT_S),
7089 OPC_SUB_S = FOP(1, FMT_S),
7090 OPC_MUL_S = FOP(2, FMT_S),
7091 OPC_DIV_S = FOP(3, FMT_S),
7092 OPC_SQRT_S = FOP(4, FMT_S),
7093 OPC_ABS_S = FOP(5, FMT_S),
7094 OPC_MOV_S = FOP(6, FMT_S),
7095 OPC_NEG_S = FOP(7, FMT_S),
7096 OPC_ROUND_L_S = FOP(8, FMT_S),
7097 OPC_TRUNC_L_S = FOP(9, FMT_S),
7098 OPC_CEIL_L_S = FOP(10, FMT_S),
7099 OPC_FLOOR_L_S = FOP(11, FMT_S),
7100 OPC_ROUND_W_S = FOP(12, FMT_S),
7101 OPC_TRUNC_W_S = FOP(13, FMT_S),
7102 OPC_CEIL_W_S = FOP(14, FMT_S),
7103 OPC_FLOOR_W_S = FOP(15, FMT_S),
7104 OPC_MOVCF_S = FOP(17, FMT_S),
7105 OPC_MOVZ_S = FOP(18, FMT_S),
7106 OPC_MOVN_S = FOP(19, FMT_S),
7107 OPC_RECIP_S = FOP(21, FMT_S),
7108 OPC_RSQRT_S = FOP(22, FMT_S),
7109 OPC_RECIP2_S = FOP(28, FMT_S),
7110 OPC_RECIP1_S = FOP(29, FMT_S),
7111 OPC_RSQRT1_S = FOP(30, FMT_S),
7112 OPC_RSQRT2_S = FOP(31, FMT_S),
7113 OPC_CVT_D_S = FOP(33, FMT_S),
7114 OPC_CVT_W_S = FOP(36, FMT_S),
7115 OPC_CVT_L_S = FOP(37, FMT_S),
7116 OPC_CVT_PS_S = FOP(38, FMT_S),
7117 OPC_CMP_F_S = FOP (48, FMT_S),
7118 OPC_CMP_UN_S = FOP (49, FMT_S),
7119 OPC_CMP_EQ_S = FOP (50, FMT_S),
7120 OPC_CMP_UEQ_S = FOP (51, FMT_S),
7121 OPC_CMP_OLT_S = FOP (52, FMT_S),
7122 OPC_CMP_ULT_S = FOP (53, FMT_S),
7123 OPC_CMP_OLE_S = FOP (54, FMT_S),
7124 OPC_CMP_ULE_S = FOP (55, FMT_S),
7125 OPC_CMP_SF_S = FOP (56, FMT_S),
7126 OPC_CMP_NGLE_S = FOP (57, FMT_S),
7127 OPC_CMP_SEQ_S = FOP (58, FMT_S),
7128 OPC_CMP_NGL_S = FOP (59, FMT_S),
7129 OPC_CMP_LT_S = FOP (60, FMT_S),
7130 OPC_CMP_NGE_S = FOP (61, FMT_S),
7131 OPC_CMP_LE_S = FOP (62, FMT_S),
7132 OPC_CMP_NGT_S = FOP (63, FMT_S),
7134 OPC_ADD_D = FOP(0, FMT_D),
7135 OPC_SUB_D = FOP(1, FMT_D),
7136 OPC_MUL_D = FOP(2, FMT_D),
7137 OPC_DIV_D = FOP(3, FMT_D),
7138 OPC_SQRT_D = FOP(4, FMT_D),
7139 OPC_ABS_D = FOP(5, FMT_D),
7140 OPC_MOV_D = FOP(6, FMT_D),
7141 OPC_NEG_D = FOP(7, FMT_D),
7142 OPC_ROUND_L_D = FOP(8, FMT_D),
7143 OPC_TRUNC_L_D = FOP(9, FMT_D),
7144 OPC_CEIL_L_D = FOP(10, FMT_D),
7145 OPC_FLOOR_L_D = FOP(11, FMT_D),
7146 OPC_ROUND_W_D = FOP(12, FMT_D),
7147 OPC_TRUNC_W_D = FOP(13, FMT_D),
7148 OPC_CEIL_W_D = FOP(14, FMT_D),
7149 OPC_FLOOR_W_D = FOP(15, FMT_D),
7150 OPC_MOVCF_D = FOP(17, FMT_D),
7151 OPC_MOVZ_D = FOP(18, FMT_D),
7152 OPC_MOVN_D = FOP(19, FMT_D),
7153 OPC_RECIP_D = FOP(21, FMT_D),
7154 OPC_RSQRT_D = FOP(22, FMT_D),
7155 OPC_RECIP2_D = FOP(28, FMT_D),
7156 OPC_RECIP1_D = FOP(29, FMT_D),
7157 OPC_RSQRT1_D = FOP(30, FMT_D),
7158 OPC_RSQRT2_D = FOP(31, FMT_D),
7159 OPC_CVT_S_D = FOP(32, FMT_D),
7160 OPC_CVT_W_D = FOP(36, FMT_D),
7161 OPC_CVT_L_D = FOP(37, FMT_D),
7162 OPC_CMP_F_D = FOP (48, FMT_D),
7163 OPC_CMP_UN_D = FOP (49, FMT_D),
7164 OPC_CMP_EQ_D = FOP (50, FMT_D),
7165 OPC_CMP_UEQ_D = FOP (51, FMT_D),
7166 OPC_CMP_OLT_D = FOP (52, FMT_D),
7167 OPC_CMP_ULT_D = FOP (53, FMT_D),
7168 OPC_CMP_OLE_D = FOP (54, FMT_D),
7169 OPC_CMP_ULE_D = FOP (55, FMT_D),
7170 OPC_CMP_SF_D = FOP (56, FMT_D),
7171 OPC_CMP_NGLE_D = FOP (57, FMT_D),
7172 OPC_CMP_SEQ_D = FOP (58, FMT_D),
7173 OPC_CMP_NGL_D = FOP (59, FMT_D),
7174 OPC_CMP_LT_D = FOP (60, FMT_D),
7175 OPC_CMP_NGE_D = FOP (61, FMT_D),
7176 OPC_CMP_LE_D = FOP (62, FMT_D),
7177 OPC_CMP_NGT_D = FOP (63, FMT_D),
7179 OPC_CVT_S_W = FOP(32, FMT_W),
7180 OPC_CVT_D_W = FOP(33, FMT_W),
7181 OPC_CVT_S_L = FOP(32, FMT_L),
7182 OPC_CVT_D_L = FOP(33, FMT_L),
7183 OPC_CVT_PS_PW = FOP(38, FMT_W),
7185 OPC_ADD_PS = FOP(0, FMT_PS),
7186 OPC_SUB_PS = FOP(1, FMT_PS),
7187 OPC_MUL_PS = FOP(2, FMT_PS),
7188 OPC_DIV_PS = FOP(3, FMT_PS),
7189 OPC_ABS_PS = FOP(5, FMT_PS),
7190 OPC_MOV_PS = FOP(6, FMT_PS),
7191 OPC_NEG_PS = FOP(7, FMT_PS),
7192 OPC_MOVCF_PS = FOP(17, FMT_PS),
7193 OPC_MOVZ_PS = FOP(18, FMT_PS),
7194 OPC_MOVN_PS = FOP(19, FMT_PS),
7195 OPC_ADDR_PS = FOP(24, FMT_PS),
7196 OPC_MULR_PS = FOP(26, FMT_PS),
7197 OPC_RECIP2_PS = FOP(28, FMT_PS),
7198 OPC_RECIP1_PS = FOP(29, FMT_PS),
7199 OPC_RSQRT1_PS = FOP(30, FMT_PS),
7200 OPC_RSQRT2_PS = FOP(31, FMT_PS),
7202 OPC_CVT_S_PU = FOP(32, FMT_PS),
7203 OPC_CVT_PW_PS = FOP(36, FMT_PS),
7204 OPC_CVT_S_PL = FOP(40, FMT_PS),
7205 OPC_PLL_PS = FOP(44, FMT_PS),
7206 OPC_PLU_PS = FOP(45, FMT_PS),
7207 OPC_PUL_PS = FOP(46, FMT_PS),
7208 OPC_PUU_PS = FOP(47, FMT_PS),
7209 OPC_CMP_F_PS = FOP (48, FMT_PS),
7210 OPC_CMP_UN_PS = FOP (49, FMT_PS),
7211 OPC_CMP_EQ_PS = FOP (50, FMT_PS),
7212 OPC_CMP_UEQ_PS = FOP (51, FMT_PS),
7213 OPC_CMP_OLT_PS = FOP (52, FMT_PS),
7214 OPC_CMP_ULT_PS = FOP (53, FMT_PS),
7215 OPC_CMP_OLE_PS = FOP (54, FMT_PS),
7216 OPC_CMP_ULE_PS = FOP (55, FMT_PS),
7217 OPC_CMP_SF_PS = FOP (56, FMT_PS),
7218 OPC_CMP_NGLE_PS = FOP (57, FMT_PS),
7219 OPC_CMP_SEQ_PS = FOP (58, FMT_PS),
7220 OPC_CMP_NGL_PS = FOP (59, FMT_PS),
7221 OPC_CMP_LT_PS = FOP (60, FMT_PS),
7222 OPC_CMP_NGE_PS = FOP (61, FMT_PS),
7223 OPC_CMP_LE_PS = FOP (62, FMT_PS),
7224 OPC_CMP_NGT_PS = FOP (63, FMT_PS),
7227 static void gen_cp1 (DisasContext *ctx, uint32_t opc, int rt, int fs)
7229 const char *opn = "cp1 move";
7230 TCGv t0 = tcg_temp_new();
7232 switch (opc) {
7233 case OPC_MFC1:
7235 TCGv_i32 fp0 = tcg_temp_new_i32();
7237 gen_load_fpr32(fp0, fs);
7238 tcg_gen_ext_i32_tl(t0, fp0);
7239 tcg_temp_free_i32(fp0);
7241 gen_store_gpr(t0, rt);
7242 opn = "mfc1";
7243 break;
7244 case OPC_MTC1:
7245 gen_load_gpr(t0, rt);
7247 TCGv_i32 fp0 = tcg_temp_new_i32();
7249 tcg_gen_trunc_tl_i32(fp0, t0);
7250 gen_store_fpr32(fp0, fs);
7251 tcg_temp_free_i32(fp0);
7253 opn = "mtc1";
7254 break;
7255 case OPC_CFC1:
7256 gen_helper_1e0i(cfc1, t0, fs);
7257 gen_store_gpr(t0, rt);
7258 opn = "cfc1";
7259 break;
7260 case OPC_CTC1:
7261 gen_load_gpr(t0, rt);
7263 TCGv_i32 fs_tmp = tcg_const_i32(fs);
7265 gen_helper_0e2i(ctc1, t0, fs_tmp, rt);
7266 tcg_temp_free_i32(fs_tmp);
7268 opn = "ctc1";
7269 break;
7270 #if defined(TARGET_MIPS64)
7271 case OPC_DMFC1:
7272 gen_load_fpr64(ctx, t0, fs);
7273 gen_store_gpr(t0, rt);
7274 opn = "dmfc1";
7275 break;
7276 case OPC_DMTC1:
7277 gen_load_gpr(t0, rt);
7278 gen_store_fpr64(ctx, t0, fs);
7279 opn = "dmtc1";
7280 break;
7281 #endif
7282 case OPC_MFHC1:
7284 TCGv_i32 fp0 = tcg_temp_new_i32();
7286 gen_load_fpr32h(fp0, fs);
7287 tcg_gen_ext_i32_tl(t0, fp0);
7288 tcg_temp_free_i32(fp0);
7290 gen_store_gpr(t0, rt);
7291 opn = "mfhc1";
7292 break;
7293 case OPC_MTHC1:
7294 gen_load_gpr(t0, rt);
7296 TCGv_i32 fp0 = tcg_temp_new_i32();
7298 tcg_gen_trunc_tl_i32(fp0, t0);
7299 gen_store_fpr32h(fp0, fs);
7300 tcg_temp_free_i32(fp0);
7302 opn = "mthc1";
7303 break;
7304 default:
7305 MIPS_INVAL(opn);
7306 generate_exception (ctx, EXCP_RI);
7307 goto out;
7309 (void)opn; /* avoid a compiler warning */
7310 MIPS_DEBUG("%s %s %s", opn, regnames[rt], fregnames[fs]);
7312 out:
7313 tcg_temp_free(t0);
7316 static void gen_movci (DisasContext *ctx, int rd, int rs, int cc, int tf)
7318 int l1;
7319 TCGCond cond;
7320 TCGv_i32 t0;
7322 if (rd == 0) {
7323 /* Treat as NOP. */
7324 return;
7327 if (tf)
7328 cond = TCG_COND_EQ;
7329 else
7330 cond = TCG_COND_NE;
7332 l1 = gen_new_label();
7333 t0 = tcg_temp_new_i32();
7334 tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc));
7335 tcg_gen_brcondi_i32(cond, t0, 0, l1);
7336 tcg_temp_free_i32(t0);
7337 if (rs == 0) {
7338 tcg_gen_movi_tl(cpu_gpr[rd], 0);
7339 } else {
7340 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
7342 gen_set_label(l1);
7345 static inline void gen_movcf_s (int fs, int fd, int cc, int tf)
7347 int cond;
7348 TCGv_i32 t0 = tcg_temp_new_i32();
7349 int l1 = gen_new_label();
7351 if (tf)
7352 cond = TCG_COND_EQ;
7353 else
7354 cond = TCG_COND_NE;
7356 tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc));
7357 tcg_gen_brcondi_i32(cond, t0, 0, l1);
7358 gen_load_fpr32(t0, fs);
7359 gen_store_fpr32(t0, fd);
7360 gen_set_label(l1);
7361 tcg_temp_free_i32(t0);
7364 static inline void gen_movcf_d (DisasContext *ctx, int fs, int fd, int cc, int tf)
7366 int cond;
7367 TCGv_i32 t0 = tcg_temp_new_i32();
7368 TCGv_i64 fp0;
7369 int l1 = gen_new_label();
7371 if (tf)
7372 cond = TCG_COND_EQ;
7373 else
7374 cond = TCG_COND_NE;
7376 tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc));
7377 tcg_gen_brcondi_i32(cond, t0, 0, l1);
7378 tcg_temp_free_i32(t0);
7379 fp0 = tcg_temp_new_i64();
7380 gen_load_fpr64(ctx, fp0, fs);
7381 gen_store_fpr64(ctx, fp0, fd);
7382 tcg_temp_free_i64(fp0);
7383 gen_set_label(l1);
7386 static inline void gen_movcf_ps (int fs, int fd, int cc, int tf)
7388 int cond;
7389 TCGv_i32 t0 = tcg_temp_new_i32();
7390 int l1 = gen_new_label();
7391 int l2 = gen_new_label();
7393 if (tf)
7394 cond = TCG_COND_EQ;
7395 else
7396 cond = TCG_COND_NE;
7398 tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc));
7399 tcg_gen_brcondi_i32(cond, t0, 0, l1);
7400 gen_load_fpr32(t0, fs);
7401 gen_store_fpr32(t0, fd);
7402 gen_set_label(l1);
7404 tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc+1));
7405 tcg_gen_brcondi_i32(cond, t0, 0, l2);
7406 gen_load_fpr32h(t0, fs);
7407 gen_store_fpr32h(t0, fd);
7408 tcg_temp_free_i32(t0);
7409 gen_set_label(l2);
7413 static void gen_farith (DisasContext *ctx, enum fopcode op1,
7414 int ft, int fs, int fd, int cc)
7416 const char *opn = "farith";
7417 const char *condnames[] = {
7418 "c.f",
7419 "c.un",
7420 "c.eq",
7421 "c.ueq",
7422 "c.olt",
7423 "c.ult",
7424 "c.ole",
7425 "c.ule",
7426 "c.sf",
7427 "c.ngle",
7428 "c.seq",
7429 "c.ngl",
7430 "c.lt",
7431 "c.nge",
7432 "c.le",
7433 "c.ngt",
7435 const char *condnames_abs[] = {
7436 "cabs.f",
7437 "cabs.un",
7438 "cabs.eq",
7439 "cabs.ueq",
7440 "cabs.olt",
7441 "cabs.ult",
7442 "cabs.ole",
7443 "cabs.ule",
7444 "cabs.sf",
7445 "cabs.ngle",
7446 "cabs.seq",
7447 "cabs.ngl",
7448 "cabs.lt",
7449 "cabs.nge",
7450 "cabs.le",
7451 "cabs.ngt",
7453 enum { BINOP, CMPOP, OTHEROP } optype = OTHEROP;
7454 uint32_t func = ctx->opcode & 0x3f;
7456 switch (op1) {
7457 case OPC_ADD_S:
7459 TCGv_i32 fp0 = tcg_temp_new_i32();
7460 TCGv_i32 fp1 = tcg_temp_new_i32();
7462 gen_load_fpr32(fp0, fs);
7463 gen_load_fpr32(fp1, ft);
7464 gen_helper_float_add_s(fp0, cpu_env, fp0, fp1);
7465 tcg_temp_free_i32(fp1);
7466 gen_store_fpr32(fp0, fd);
7467 tcg_temp_free_i32(fp0);
7469 opn = "add.s";
7470 optype = BINOP;
7471 break;
7472 case OPC_SUB_S:
7474 TCGv_i32 fp0 = tcg_temp_new_i32();
7475 TCGv_i32 fp1 = tcg_temp_new_i32();
7477 gen_load_fpr32(fp0, fs);
7478 gen_load_fpr32(fp1, ft);
7479 gen_helper_float_sub_s(fp0, cpu_env, fp0, fp1);
7480 tcg_temp_free_i32(fp1);
7481 gen_store_fpr32(fp0, fd);
7482 tcg_temp_free_i32(fp0);
7484 opn = "sub.s";
7485 optype = BINOP;
7486 break;
7487 case OPC_MUL_S:
7489 TCGv_i32 fp0 = tcg_temp_new_i32();
7490 TCGv_i32 fp1 = tcg_temp_new_i32();
7492 gen_load_fpr32(fp0, fs);
7493 gen_load_fpr32(fp1, ft);
7494 gen_helper_float_mul_s(fp0, cpu_env, fp0, fp1);
7495 tcg_temp_free_i32(fp1);
7496 gen_store_fpr32(fp0, fd);
7497 tcg_temp_free_i32(fp0);
7499 opn = "mul.s";
7500 optype = BINOP;
7501 break;
7502 case OPC_DIV_S:
7504 TCGv_i32 fp0 = tcg_temp_new_i32();
7505 TCGv_i32 fp1 = tcg_temp_new_i32();
7507 gen_load_fpr32(fp0, fs);
7508 gen_load_fpr32(fp1, ft);
7509 gen_helper_float_div_s(fp0, cpu_env, fp0, fp1);
7510 tcg_temp_free_i32(fp1);
7511 gen_store_fpr32(fp0, fd);
7512 tcg_temp_free_i32(fp0);
7514 opn = "div.s";
7515 optype = BINOP;
7516 break;
7517 case OPC_SQRT_S:
7519 TCGv_i32 fp0 = tcg_temp_new_i32();
7521 gen_load_fpr32(fp0, fs);
7522 gen_helper_float_sqrt_s(fp0, cpu_env, fp0);
7523 gen_store_fpr32(fp0, fd);
7524 tcg_temp_free_i32(fp0);
7526 opn = "sqrt.s";
7527 break;
7528 case OPC_ABS_S:
7530 TCGv_i32 fp0 = tcg_temp_new_i32();
7532 gen_load_fpr32(fp0, fs);
7533 gen_helper_float_abs_s(fp0, fp0);
7534 gen_store_fpr32(fp0, fd);
7535 tcg_temp_free_i32(fp0);
7537 opn = "abs.s";
7538 break;
7539 case OPC_MOV_S:
7541 TCGv_i32 fp0 = tcg_temp_new_i32();
7543 gen_load_fpr32(fp0, fs);
7544 gen_store_fpr32(fp0, fd);
7545 tcg_temp_free_i32(fp0);
7547 opn = "mov.s";
7548 break;
7549 case OPC_NEG_S:
7551 TCGv_i32 fp0 = tcg_temp_new_i32();
7553 gen_load_fpr32(fp0, fs);
7554 gen_helper_float_chs_s(fp0, fp0);
7555 gen_store_fpr32(fp0, fd);
7556 tcg_temp_free_i32(fp0);
7558 opn = "neg.s";
7559 break;
7560 case OPC_ROUND_L_S:
7561 check_cp1_64bitmode(ctx);
7563 TCGv_i32 fp32 = tcg_temp_new_i32();
7564 TCGv_i64 fp64 = tcg_temp_new_i64();
7566 gen_load_fpr32(fp32, fs);
7567 gen_helper_float_roundl_s(fp64, cpu_env, fp32);
7568 tcg_temp_free_i32(fp32);
7569 gen_store_fpr64(ctx, fp64, fd);
7570 tcg_temp_free_i64(fp64);
7572 opn = "round.l.s";
7573 break;
7574 case OPC_TRUNC_L_S:
7575 check_cp1_64bitmode(ctx);
7577 TCGv_i32 fp32 = tcg_temp_new_i32();
7578 TCGv_i64 fp64 = tcg_temp_new_i64();
7580 gen_load_fpr32(fp32, fs);
7581 gen_helper_float_truncl_s(fp64, cpu_env, fp32);
7582 tcg_temp_free_i32(fp32);
7583 gen_store_fpr64(ctx, fp64, fd);
7584 tcg_temp_free_i64(fp64);
7586 opn = "trunc.l.s";
7587 break;
7588 case OPC_CEIL_L_S:
7589 check_cp1_64bitmode(ctx);
7591 TCGv_i32 fp32 = tcg_temp_new_i32();
7592 TCGv_i64 fp64 = tcg_temp_new_i64();
7594 gen_load_fpr32(fp32, fs);
7595 gen_helper_float_ceill_s(fp64, cpu_env, fp32);
7596 tcg_temp_free_i32(fp32);
7597 gen_store_fpr64(ctx, fp64, fd);
7598 tcg_temp_free_i64(fp64);
7600 opn = "ceil.l.s";
7601 break;
7602 case OPC_FLOOR_L_S:
7603 check_cp1_64bitmode(ctx);
7605 TCGv_i32 fp32 = tcg_temp_new_i32();
7606 TCGv_i64 fp64 = tcg_temp_new_i64();
7608 gen_load_fpr32(fp32, fs);
7609 gen_helper_float_floorl_s(fp64, cpu_env, fp32);
7610 tcg_temp_free_i32(fp32);
7611 gen_store_fpr64(ctx, fp64, fd);
7612 tcg_temp_free_i64(fp64);
7614 opn = "floor.l.s";
7615 break;
7616 case OPC_ROUND_W_S:
7618 TCGv_i32 fp0 = tcg_temp_new_i32();
7620 gen_load_fpr32(fp0, fs);
7621 gen_helper_float_roundw_s(fp0, cpu_env, fp0);
7622 gen_store_fpr32(fp0, fd);
7623 tcg_temp_free_i32(fp0);
7625 opn = "round.w.s";
7626 break;
7627 case OPC_TRUNC_W_S:
7629 TCGv_i32 fp0 = tcg_temp_new_i32();
7631 gen_load_fpr32(fp0, fs);
7632 gen_helper_float_truncw_s(fp0, cpu_env, fp0);
7633 gen_store_fpr32(fp0, fd);
7634 tcg_temp_free_i32(fp0);
7636 opn = "trunc.w.s";
7637 break;
7638 case OPC_CEIL_W_S:
7640 TCGv_i32 fp0 = tcg_temp_new_i32();
7642 gen_load_fpr32(fp0, fs);
7643 gen_helper_float_ceilw_s(fp0, cpu_env, fp0);
7644 gen_store_fpr32(fp0, fd);
7645 tcg_temp_free_i32(fp0);
7647 opn = "ceil.w.s";
7648 break;
7649 case OPC_FLOOR_W_S:
7651 TCGv_i32 fp0 = tcg_temp_new_i32();
7653 gen_load_fpr32(fp0, fs);
7654 gen_helper_float_floorw_s(fp0, cpu_env, fp0);
7655 gen_store_fpr32(fp0, fd);
7656 tcg_temp_free_i32(fp0);
7658 opn = "floor.w.s";
7659 break;
7660 case OPC_MOVCF_S:
7661 gen_movcf_s(fs, fd, (ft >> 2) & 0x7, ft & 0x1);
7662 opn = "movcf.s";
7663 break;
7664 case OPC_MOVZ_S:
7666 int l1 = gen_new_label();
7667 TCGv_i32 fp0;
7669 if (ft != 0) {
7670 tcg_gen_brcondi_tl(TCG_COND_NE, cpu_gpr[ft], 0, l1);
7672 fp0 = tcg_temp_new_i32();
7673 gen_load_fpr32(fp0, fs);
7674 gen_store_fpr32(fp0, fd);
7675 tcg_temp_free_i32(fp0);
7676 gen_set_label(l1);
7678 opn = "movz.s";
7679 break;
7680 case OPC_MOVN_S:
7682 int l1 = gen_new_label();
7683 TCGv_i32 fp0;
7685 if (ft != 0) {
7686 tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_gpr[ft], 0, l1);
7687 fp0 = tcg_temp_new_i32();
7688 gen_load_fpr32(fp0, fs);
7689 gen_store_fpr32(fp0, fd);
7690 tcg_temp_free_i32(fp0);
7691 gen_set_label(l1);
7694 opn = "movn.s";
7695 break;
7696 case OPC_RECIP_S:
7697 check_cop1x(ctx);
7699 TCGv_i32 fp0 = tcg_temp_new_i32();
7701 gen_load_fpr32(fp0, fs);
7702 gen_helper_float_recip_s(fp0, cpu_env, fp0);
7703 gen_store_fpr32(fp0, fd);
7704 tcg_temp_free_i32(fp0);
7706 opn = "recip.s";
7707 break;
7708 case OPC_RSQRT_S:
7709 check_cop1x(ctx);
7711 TCGv_i32 fp0 = tcg_temp_new_i32();
7713 gen_load_fpr32(fp0, fs);
7714 gen_helper_float_rsqrt_s(fp0, cpu_env, fp0);
7715 gen_store_fpr32(fp0, fd);
7716 tcg_temp_free_i32(fp0);
7718 opn = "rsqrt.s";
7719 break;
7720 case OPC_RECIP2_S:
7721 check_cp1_64bitmode(ctx);
7723 TCGv_i32 fp0 = tcg_temp_new_i32();
7724 TCGv_i32 fp1 = tcg_temp_new_i32();
7726 gen_load_fpr32(fp0, fs);
7727 gen_load_fpr32(fp1, ft);
7728 gen_helper_float_recip2_s(fp0, cpu_env, fp0, fp1);
7729 tcg_temp_free_i32(fp1);
7730 gen_store_fpr32(fp0, fd);
7731 tcg_temp_free_i32(fp0);
7733 opn = "recip2.s";
7734 break;
7735 case OPC_RECIP1_S:
7736 check_cp1_64bitmode(ctx);
7738 TCGv_i32 fp0 = tcg_temp_new_i32();
7740 gen_load_fpr32(fp0, fs);
7741 gen_helper_float_recip1_s(fp0, cpu_env, fp0);
7742 gen_store_fpr32(fp0, fd);
7743 tcg_temp_free_i32(fp0);
7745 opn = "recip1.s";
7746 break;
7747 case OPC_RSQRT1_S:
7748 check_cp1_64bitmode(ctx);
7750 TCGv_i32 fp0 = tcg_temp_new_i32();
7752 gen_load_fpr32(fp0, fs);
7753 gen_helper_float_rsqrt1_s(fp0, cpu_env, fp0);
7754 gen_store_fpr32(fp0, fd);
7755 tcg_temp_free_i32(fp0);
7757 opn = "rsqrt1.s";
7758 break;
7759 case OPC_RSQRT2_S:
7760 check_cp1_64bitmode(ctx);
7762 TCGv_i32 fp0 = tcg_temp_new_i32();
7763 TCGv_i32 fp1 = tcg_temp_new_i32();
7765 gen_load_fpr32(fp0, fs);
7766 gen_load_fpr32(fp1, ft);
7767 gen_helper_float_rsqrt2_s(fp0, cpu_env, fp0, fp1);
7768 tcg_temp_free_i32(fp1);
7769 gen_store_fpr32(fp0, fd);
7770 tcg_temp_free_i32(fp0);
7772 opn = "rsqrt2.s";
7773 break;
7774 case OPC_CVT_D_S:
7775 check_cp1_registers(ctx, fd);
7777 TCGv_i32 fp32 = tcg_temp_new_i32();
7778 TCGv_i64 fp64 = tcg_temp_new_i64();
7780 gen_load_fpr32(fp32, fs);
7781 gen_helper_float_cvtd_s(fp64, cpu_env, fp32);
7782 tcg_temp_free_i32(fp32);
7783 gen_store_fpr64(ctx, fp64, fd);
7784 tcg_temp_free_i64(fp64);
7786 opn = "cvt.d.s";
7787 break;
7788 case OPC_CVT_W_S:
7790 TCGv_i32 fp0 = tcg_temp_new_i32();
7792 gen_load_fpr32(fp0, fs);
7793 gen_helper_float_cvtw_s(fp0, cpu_env, fp0);
7794 gen_store_fpr32(fp0, fd);
7795 tcg_temp_free_i32(fp0);
7797 opn = "cvt.w.s";
7798 break;
7799 case OPC_CVT_L_S:
7800 check_cp1_64bitmode(ctx);
7802 TCGv_i32 fp32 = tcg_temp_new_i32();
7803 TCGv_i64 fp64 = tcg_temp_new_i64();
7805 gen_load_fpr32(fp32, fs);
7806 gen_helper_float_cvtl_s(fp64, cpu_env, fp32);
7807 tcg_temp_free_i32(fp32);
7808 gen_store_fpr64(ctx, fp64, fd);
7809 tcg_temp_free_i64(fp64);
7811 opn = "cvt.l.s";
7812 break;
7813 case OPC_CVT_PS_S:
7814 check_cp1_64bitmode(ctx);
7816 TCGv_i64 fp64 = tcg_temp_new_i64();
7817 TCGv_i32 fp32_0 = tcg_temp_new_i32();
7818 TCGv_i32 fp32_1 = tcg_temp_new_i32();
7820 gen_load_fpr32(fp32_0, fs);
7821 gen_load_fpr32(fp32_1, ft);
7822 tcg_gen_concat_i32_i64(fp64, fp32_1, fp32_0);
7823 tcg_temp_free_i32(fp32_1);
7824 tcg_temp_free_i32(fp32_0);
7825 gen_store_fpr64(ctx, fp64, fd);
7826 tcg_temp_free_i64(fp64);
7828 opn = "cvt.ps.s";
7829 break;
7830 case OPC_CMP_F_S:
7831 case OPC_CMP_UN_S:
7832 case OPC_CMP_EQ_S:
7833 case OPC_CMP_UEQ_S:
7834 case OPC_CMP_OLT_S:
7835 case OPC_CMP_ULT_S:
7836 case OPC_CMP_OLE_S:
7837 case OPC_CMP_ULE_S:
7838 case OPC_CMP_SF_S:
7839 case OPC_CMP_NGLE_S:
7840 case OPC_CMP_SEQ_S:
7841 case OPC_CMP_NGL_S:
7842 case OPC_CMP_LT_S:
7843 case OPC_CMP_NGE_S:
7844 case OPC_CMP_LE_S:
7845 case OPC_CMP_NGT_S:
7846 if (ctx->opcode & (1 << 6)) {
7847 gen_cmpabs_s(ctx, func-48, ft, fs, cc);
7848 opn = condnames_abs[func-48];
7849 } else {
7850 gen_cmp_s(ctx, func-48, ft, fs, cc);
7851 opn = condnames[func-48];
7853 break;
7854 case OPC_ADD_D:
7855 check_cp1_registers(ctx, fs | ft | fd);
7857 TCGv_i64 fp0 = tcg_temp_new_i64();
7858 TCGv_i64 fp1 = tcg_temp_new_i64();
7860 gen_load_fpr64(ctx, fp0, fs);
7861 gen_load_fpr64(ctx, fp1, ft);
7862 gen_helper_float_add_d(fp0, cpu_env, fp0, fp1);
7863 tcg_temp_free_i64(fp1);
7864 gen_store_fpr64(ctx, fp0, fd);
7865 tcg_temp_free_i64(fp0);
7867 opn = "add.d";
7868 optype = BINOP;
7869 break;
7870 case OPC_SUB_D:
7871 check_cp1_registers(ctx, fs | ft | fd);
7873 TCGv_i64 fp0 = tcg_temp_new_i64();
7874 TCGv_i64 fp1 = tcg_temp_new_i64();
7876 gen_load_fpr64(ctx, fp0, fs);
7877 gen_load_fpr64(ctx, fp1, ft);
7878 gen_helper_float_sub_d(fp0, cpu_env, fp0, fp1);
7879 tcg_temp_free_i64(fp1);
7880 gen_store_fpr64(ctx, fp0, fd);
7881 tcg_temp_free_i64(fp0);
7883 opn = "sub.d";
7884 optype = BINOP;
7885 break;
7886 case OPC_MUL_D:
7887 check_cp1_registers(ctx, fs | ft | fd);
7889 TCGv_i64 fp0 = tcg_temp_new_i64();
7890 TCGv_i64 fp1 = tcg_temp_new_i64();
7892 gen_load_fpr64(ctx, fp0, fs);
7893 gen_load_fpr64(ctx, fp1, ft);
7894 gen_helper_float_mul_d(fp0, cpu_env, fp0, fp1);
7895 tcg_temp_free_i64(fp1);
7896 gen_store_fpr64(ctx, fp0, fd);
7897 tcg_temp_free_i64(fp0);
7899 opn = "mul.d";
7900 optype = BINOP;
7901 break;
7902 case OPC_DIV_D:
7903 check_cp1_registers(ctx, fs | ft | fd);
7905 TCGv_i64 fp0 = tcg_temp_new_i64();
7906 TCGv_i64 fp1 = tcg_temp_new_i64();
7908 gen_load_fpr64(ctx, fp0, fs);
7909 gen_load_fpr64(ctx, fp1, ft);
7910 gen_helper_float_div_d(fp0, cpu_env, fp0, fp1);
7911 tcg_temp_free_i64(fp1);
7912 gen_store_fpr64(ctx, fp0, fd);
7913 tcg_temp_free_i64(fp0);
7915 opn = "div.d";
7916 optype = BINOP;
7917 break;
7918 case OPC_SQRT_D:
7919 check_cp1_registers(ctx, fs | fd);
7921 TCGv_i64 fp0 = tcg_temp_new_i64();
7923 gen_load_fpr64(ctx, fp0, fs);
7924 gen_helper_float_sqrt_d(fp0, cpu_env, fp0);
7925 gen_store_fpr64(ctx, fp0, fd);
7926 tcg_temp_free_i64(fp0);
7928 opn = "sqrt.d";
7929 break;
7930 case OPC_ABS_D:
7931 check_cp1_registers(ctx, fs | fd);
7933 TCGv_i64 fp0 = tcg_temp_new_i64();
7935 gen_load_fpr64(ctx, fp0, fs);
7936 gen_helper_float_abs_d(fp0, fp0);
7937 gen_store_fpr64(ctx, fp0, fd);
7938 tcg_temp_free_i64(fp0);
7940 opn = "abs.d";
7941 break;
7942 case OPC_MOV_D:
7943 check_cp1_registers(ctx, fs | fd);
7945 TCGv_i64 fp0 = tcg_temp_new_i64();
7947 gen_load_fpr64(ctx, fp0, fs);
7948 gen_store_fpr64(ctx, fp0, fd);
7949 tcg_temp_free_i64(fp0);
7951 opn = "mov.d";
7952 break;
7953 case OPC_NEG_D:
7954 check_cp1_registers(ctx, fs | fd);
7956 TCGv_i64 fp0 = tcg_temp_new_i64();
7958 gen_load_fpr64(ctx, fp0, fs);
7959 gen_helper_float_chs_d(fp0, fp0);
7960 gen_store_fpr64(ctx, fp0, fd);
7961 tcg_temp_free_i64(fp0);
7963 opn = "neg.d";
7964 break;
7965 case OPC_ROUND_L_D:
7966 check_cp1_64bitmode(ctx);
7968 TCGv_i64 fp0 = tcg_temp_new_i64();
7970 gen_load_fpr64(ctx, fp0, fs);
7971 gen_helper_float_roundl_d(fp0, cpu_env, fp0);
7972 gen_store_fpr64(ctx, fp0, fd);
7973 tcg_temp_free_i64(fp0);
7975 opn = "round.l.d";
7976 break;
7977 case OPC_TRUNC_L_D:
7978 check_cp1_64bitmode(ctx);
7980 TCGv_i64 fp0 = tcg_temp_new_i64();
7982 gen_load_fpr64(ctx, fp0, fs);
7983 gen_helper_float_truncl_d(fp0, cpu_env, fp0);
7984 gen_store_fpr64(ctx, fp0, fd);
7985 tcg_temp_free_i64(fp0);
7987 opn = "trunc.l.d";
7988 break;
7989 case OPC_CEIL_L_D:
7990 check_cp1_64bitmode(ctx);
7992 TCGv_i64 fp0 = tcg_temp_new_i64();
7994 gen_load_fpr64(ctx, fp0, fs);
7995 gen_helper_float_ceill_d(fp0, cpu_env, fp0);
7996 gen_store_fpr64(ctx, fp0, fd);
7997 tcg_temp_free_i64(fp0);
7999 opn = "ceil.l.d";
8000 break;
8001 case OPC_FLOOR_L_D:
8002 check_cp1_64bitmode(ctx);
8004 TCGv_i64 fp0 = tcg_temp_new_i64();
8006 gen_load_fpr64(ctx, fp0, fs);
8007 gen_helper_float_floorl_d(fp0, cpu_env, fp0);
8008 gen_store_fpr64(ctx, fp0, fd);
8009 tcg_temp_free_i64(fp0);
8011 opn = "floor.l.d";
8012 break;
8013 case OPC_ROUND_W_D:
8014 check_cp1_registers(ctx, fs);
8016 TCGv_i32 fp32 = tcg_temp_new_i32();
8017 TCGv_i64 fp64 = tcg_temp_new_i64();
8019 gen_load_fpr64(ctx, fp64, fs);
8020 gen_helper_float_roundw_d(fp32, cpu_env, fp64);
8021 tcg_temp_free_i64(fp64);
8022 gen_store_fpr32(fp32, fd);
8023 tcg_temp_free_i32(fp32);
8025 opn = "round.w.d";
8026 break;
8027 case OPC_TRUNC_W_D:
8028 check_cp1_registers(ctx, fs);
8030 TCGv_i32 fp32 = tcg_temp_new_i32();
8031 TCGv_i64 fp64 = tcg_temp_new_i64();
8033 gen_load_fpr64(ctx, fp64, fs);
8034 gen_helper_float_truncw_d(fp32, cpu_env, fp64);
8035 tcg_temp_free_i64(fp64);
8036 gen_store_fpr32(fp32, fd);
8037 tcg_temp_free_i32(fp32);
8039 opn = "trunc.w.d";
8040 break;
8041 case OPC_CEIL_W_D:
8042 check_cp1_registers(ctx, fs);
8044 TCGv_i32 fp32 = tcg_temp_new_i32();
8045 TCGv_i64 fp64 = tcg_temp_new_i64();
8047 gen_load_fpr64(ctx, fp64, fs);
8048 gen_helper_float_ceilw_d(fp32, cpu_env, fp64);
8049 tcg_temp_free_i64(fp64);
8050 gen_store_fpr32(fp32, fd);
8051 tcg_temp_free_i32(fp32);
8053 opn = "ceil.w.d";
8054 break;
8055 case OPC_FLOOR_W_D:
8056 check_cp1_registers(ctx, fs);
8058 TCGv_i32 fp32 = tcg_temp_new_i32();
8059 TCGv_i64 fp64 = tcg_temp_new_i64();
8061 gen_load_fpr64(ctx, fp64, fs);
8062 gen_helper_float_floorw_d(fp32, cpu_env, fp64);
8063 tcg_temp_free_i64(fp64);
8064 gen_store_fpr32(fp32, fd);
8065 tcg_temp_free_i32(fp32);
8067 opn = "floor.w.d";
8068 break;
8069 case OPC_MOVCF_D:
8070 gen_movcf_d(ctx, fs, fd, (ft >> 2) & 0x7, ft & 0x1);
8071 opn = "movcf.d";
8072 break;
8073 case OPC_MOVZ_D:
8075 int l1 = gen_new_label();
8076 TCGv_i64 fp0;
8078 if (ft != 0) {
8079 tcg_gen_brcondi_tl(TCG_COND_NE, cpu_gpr[ft], 0, l1);
8081 fp0 = tcg_temp_new_i64();
8082 gen_load_fpr64(ctx, fp0, fs);
8083 gen_store_fpr64(ctx, fp0, fd);
8084 tcg_temp_free_i64(fp0);
8085 gen_set_label(l1);
8087 opn = "movz.d";
8088 break;
8089 case OPC_MOVN_D:
8091 int l1 = gen_new_label();
8092 TCGv_i64 fp0;
8094 if (ft != 0) {
8095 tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_gpr[ft], 0, l1);
8096 fp0 = tcg_temp_new_i64();
8097 gen_load_fpr64(ctx, fp0, fs);
8098 gen_store_fpr64(ctx, fp0, fd);
8099 tcg_temp_free_i64(fp0);
8100 gen_set_label(l1);
8103 opn = "movn.d";
8104 break;
8105 case OPC_RECIP_D:
8106 check_cp1_64bitmode(ctx);
8108 TCGv_i64 fp0 = tcg_temp_new_i64();
8110 gen_load_fpr64(ctx, fp0, fs);
8111 gen_helper_float_recip_d(fp0, cpu_env, fp0);
8112 gen_store_fpr64(ctx, fp0, fd);
8113 tcg_temp_free_i64(fp0);
8115 opn = "recip.d";
8116 break;
8117 case OPC_RSQRT_D:
8118 check_cp1_64bitmode(ctx);
8120 TCGv_i64 fp0 = tcg_temp_new_i64();
8122 gen_load_fpr64(ctx, fp0, fs);
8123 gen_helper_float_rsqrt_d(fp0, cpu_env, fp0);
8124 gen_store_fpr64(ctx, fp0, fd);
8125 tcg_temp_free_i64(fp0);
8127 opn = "rsqrt.d";
8128 break;
8129 case OPC_RECIP2_D:
8130 check_cp1_64bitmode(ctx);
8132 TCGv_i64 fp0 = tcg_temp_new_i64();
8133 TCGv_i64 fp1 = tcg_temp_new_i64();
8135 gen_load_fpr64(ctx, fp0, fs);
8136 gen_load_fpr64(ctx, fp1, ft);
8137 gen_helper_float_recip2_d(fp0, cpu_env, fp0, fp1);
8138 tcg_temp_free_i64(fp1);
8139 gen_store_fpr64(ctx, fp0, fd);
8140 tcg_temp_free_i64(fp0);
8142 opn = "recip2.d";
8143 break;
8144 case OPC_RECIP1_D:
8145 check_cp1_64bitmode(ctx);
8147 TCGv_i64 fp0 = tcg_temp_new_i64();
8149 gen_load_fpr64(ctx, fp0, fs);
8150 gen_helper_float_recip1_d(fp0, cpu_env, fp0);
8151 gen_store_fpr64(ctx, fp0, fd);
8152 tcg_temp_free_i64(fp0);
8154 opn = "recip1.d";
8155 break;
8156 case OPC_RSQRT1_D:
8157 check_cp1_64bitmode(ctx);
8159 TCGv_i64 fp0 = tcg_temp_new_i64();
8161 gen_load_fpr64(ctx, fp0, fs);
8162 gen_helper_float_rsqrt1_d(fp0, cpu_env, fp0);
8163 gen_store_fpr64(ctx, fp0, fd);
8164 tcg_temp_free_i64(fp0);
8166 opn = "rsqrt1.d";
8167 break;
8168 case OPC_RSQRT2_D:
8169 check_cp1_64bitmode(ctx);
8171 TCGv_i64 fp0 = tcg_temp_new_i64();
8172 TCGv_i64 fp1 = tcg_temp_new_i64();
8174 gen_load_fpr64(ctx, fp0, fs);
8175 gen_load_fpr64(ctx, fp1, ft);
8176 gen_helper_float_rsqrt2_d(fp0, cpu_env, fp0, fp1);
8177 tcg_temp_free_i64(fp1);
8178 gen_store_fpr64(ctx, fp0, fd);
8179 tcg_temp_free_i64(fp0);
8181 opn = "rsqrt2.d";
8182 break;
8183 case OPC_CMP_F_D:
8184 case OPC_CMP_UN_D:
8185 case OPC_CMP_EQ_D:
8186 case OPC_CMP_UEQ_D:
8187 case OPC_CMP_OLT_D:
8188 case OPC_CMP_ULT_D:
8189 case OPC_CMP_OLE_D:
8190 case OPC_CMP_ULE_D:
8191 case OPC_CMP_SF_D:
8192 case OPC_CMP_NGLE_D:
8193 case OPC_CMP_SEQ_D:
8194 case OPC_CMP_NGL_D:
8195 case OPC_CMP_LT_D:
8196 case OPC_CMP_NGE_D:
8197 case OPC_CMP_LE_D:
8198 case OPC_CMP_NGT_D:
8199 if (ctx->opcode & (1 << 6)) {
8200 gen_cmpabs_d(ctx, func-48, ft, fs, cc);
8201 opn = condnames_abs[func-48];
8202 } else {
8203 gen_cmp_d(ctx, func-48, ft, fs, cc);
8204 opn = condnames[func-48];
8206 break;
8207 case OPC_CVT_S_D:
8208 check_cp1_registers(ctx, fs);
8210 TCGv_i32 fp32 = tcg_temp_new_i32();
8211 TCGv_i64 fp64 = tcg_temp_new_i64();
8213 gen_load_fpr64(ctx, fp64, fs);
8214 gen_helper_float_cvts_d(fp32, cpu_env, fp64);
8215 tcg_temp_free_i64(fp64);
8216 gen_store_fpr32(fp32, fd);
8217 tcg_temp_free_i32(fp32);
8219 opn = "cvt.s.d";
8220 break;
8221 case OPC_CVT_W_D:
8222 check_cp1_registers(ctx, fs);
8224 TCGv_i32 fp32 = tcg_temp_new_i32();
8225 TCGv_i64 fp64 = tcg_temp_new_i64();
8227 gen_load_fpr64(ctx, fp64, fs);
8228 gen_helper_float_cvtw_d(fp32, cpu_env, fp64);
8229 tcg_temp_free_i64(fp64);
8230 gen_store_fpr32(fp32, fd);
8231 tcg_temp_free_i32(fp32);
8233 opn = "cvt.w.d";
8234 break;
8235 case OPC_CVT_L_D:
8236 check_cp1_64bitmode(ctx);
8238 TCGv_i64 fp0 = tcg_temp_new_i64();
8240 gen_load_fpr64(ctx, fp0, fs);
8241 gen_helper_float_cvtl_d(fp0, cpu_env, fp0);
8242 gen_store_fpr64(ctx, fp0, fd);
8243 tcg_temp_free_i64(fp0);
8245 opn = "cvt.l.d";
8246 break;
8247 case OPC_CVT_S_W:
8249 TCGv_i32 fp0 = tcg_temp_new_i32();
8251 gen_load_fpr32(fp0, fs);
8252 gen_helper_float_cvts_w(fp0, cpu_env, fp0);
8253 gen_store_fpr32(fp0, fd);
8254 tcg_temp_free_i32(fp0);
8256 opn = "cvt.s.w";
8257 break;
8258 case OPC_CVT_D_W:
8259 check_cp1_registers(ctx, fd);
8261 TCGv_i32 fp32 = tcg_temp_new_i32();
8262 TCGv_i64 fp64 = tcg_temp_new_i64();
8264 gen_load_fpr32(fp32, fs);
8265 gen_helper_float_cvtd_w(fp64, cpu_env, fp32);
8266 tcg_temp_free_i32(fp32);
8267 gen_store_fpr64(ctx, fp64, fd);
8268 tcg_temp_free_i64(fp64);
8270 opn = "cvt.d.w";
8271 break;
8272 case OPC_CVT_S_L:
8273 check_cp1_64bitmode(ctx);
8275 TCGv_i32 fp32 = tcg_temp_new_i32();
8276 TCGv_i64 fp64 = tcg_temp_new_i64();
8278 gen_load_fpr64(ctx, fp64, fs);
8279 gen_helper_float_cvts_l(fp32, cpu_env, fp64);
8280 tcg_temp_free_i64(fp64);
8281 gen_store_fpr32(fp32, fd);
8282 tcg_temp_free_i32(fp32);
8284 opn = "cvt.s.l";
8285 break;
8286 case OPC_CVT_D_L:
8287 check_cp1_64bitmode(ctx);
8289 TCGv_i64 fp0 = tcg_temp_new_i64();
8291 gen_load_fpr64(ctx, fp0, fs);
8292 gen_helper_float_cvtd_l(fp0, cpu_env, fp0);
8293 gen_store_fpr64(ctx, fp0, fd);
8294 tcg_temp_free_i64(fp0);
8296 opn = "cvt.d.l";
8297 break;
8298 case OPC_CVT_PS_PW:
8299 check_cp1_64bitmode(ctx);
8301 TCGv_i64 fp0 = tcg_temp_new_i64();
8303 gen_load_fpr64(ctx, fp0, fs);
8304 gen_helper_float_cvtps_pw(fp0, cpu_env, fp0);
8305 gen_store_fpr64(ctx, fp0, fd);
8306 tcg_temp_free_i64(fp0);
8308 opn = "cvt.ps.pw";
8309 break;
8310 case OPC_ADD_PS:
8311 check_cp1_64bitmode(ctx);
8313 TCGv_i64 fp0 = tcg_temp_new_i64();
8314 TCGv_i64 fp1 = tcg_temp_new_i64();
8316 gen_load_fpr64(ctx, fp0, fs);
8317 gen_load_fpr64(ctx, fp1, ft);
8318 gen_helper_float_add_ps(fp0, cpu_env, fp0, fp1);
8319 tcg_temp_free_i64(fp1);
8320 gen_store_fpr64(ctx, fp0, fd);
8321 tcg_temp_free_i64(fp0);
8323 opn = "add.ps";
8324 break;
8325 case OPC_SUB_PS:
8326 check_cp1_64bitmode(ctx);
8328 TCGv_i64 fp0 = tcg_temp_new_i64();
8329 TCGv_i64 fp1 = tcg_temp_new_i64();
8331 gen_load_fpr64(ctx, fp0, fs);
8332 gen_load_fpr64(ctx, fp1, ft);
8333 gen_helper_float_sub_ps(fp0, cpu_env, fp0, fp1);
8334 tcg_temp_free_i64(fp1);
8335 gen_store_fpr64(ctx, fp0, fd);
8336 tcg_temp_free_i64(fp0);
8338 opn = "sub.ps";
8339 break;
8340 case OPC_MUL_PS:
8341 check_cp1_64bitmode(ctx);
8343 TCGv_i64 fp0 = tcg_temp_new_i64();
8344 TCGv_i64 fp1 = tcg_temp_new_i64();
8346 gen_load_fpr64(ctx, fp0, fs);
8347 gen_load_fpr64(ctx, fp1, ft);
8348 gen_helper_float_mul_ps(fp0, cpu_env, fp0, fp1);
8349 tcg_temp_free_i64(fp1);
8350 gen_store_fpr64(ctx, fp0, fd);
8351 tcg_temp_free_i64(fp0);
8353 opn = "mul.ps";
8354 break;
8355 case OPC_ABS_PS:
8356 check_cp1_64bitmode(ctx);
8358 TCGv_i64 fp0 = tcg_temp_new_i64();
8360 gen_load_fpr64(ctx, fp0, fs);
8361 gen_helper_float_abs_ps(fp0, fp0);
8362 gen_store_fpr64(ctx, fp0, fd);
8363 tcg_temp_free_i64(fp0);
8365 opn = "abs.ps";
8366 break;
8367 case OPC_MOV_PS:
8368 check_cp1_64bitmode(ctx);
8370 TCGv_i64 fp0 = tcg_temp_new_i64();
8372 gen_load_fpr64(ctx, fp0, fs);
8373 gen_store_fpr64(ctx, fp0, fd);
8374 tcg_temp_free_i64(fp0);
8376 opn = "mov.ps";
8377 break;
8378 case OPC_NEG_PS:
8379 check_cp1_64bitmode(ctx);
8381 TCGv_i64 fp0 = tcg_temp_new_i64();
8383 gen_load_fpr64(ctx, fp0, fs);
8384 gen_helper_float_chs_ps(fp0, fp0);
8385 gen_store_fpr64(ctx, fp0, fd);
8386 tcg_temp_free_i64(fp0);
8388 opn = "neg.ps";
8389 break;
8390 case OPC_MOVCF_PS:
8391 check_cp1_64bitmode(ctx);
8392 gen_movcf_ps(fs, fd, (ft >> 2) & 0x7, ft & 0x1);
8393 opn = "movcf.ps";
8394 break;
8395 case OPC_MOVZ_PS:
8396 check_cp1_64bitmode(ctx);
8398 int l1 = gen_new_label();
8399 TCGv_i64 fp0;
8401 if (ft != 0)
8402 tcg_gen_brcondi_tl(TCG_COND_NE, cpu_gpr[ft], 0, l1);
8403 fp0 = tcg_temp_new_i64();
8404 gen_load_fpr64(ctx, fp0, fs);
8405 gen_store_fpr64(ctx, fp0, fd);
8406 tcg_temp_free_i64(fp0);
8407 gen_set_label(l1);
8409 opn = "movz.ps";
8410 break;
8411 case OPC_MOVN_PS:
8412 check_cp1_64bitmode(ctx);
8414 int l1 = gen_new_label();
8415 TCGv_i64 fp0;
8417 if (ft != 0) {
8418 tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_gpr[ft], 0, l1);
8419 fp0 = tcg_temp_new_i64();
8420 gen_load_fpr64(ctx, fp0, fs);
8421 gen_store_fpr64(ctx, fp0, fd);
8422 tcg_temp_free_i64(fp0);
8423 gen_set_label(l1);
8426 opn = "movn.ps";
8427 break;
8428 case OPC_ADDR_PS:
8429 check_cp1_64bitmode(ctx);
8431 TCGv_i64 fp0 = tcg_temp_new_i64();
8432 TCGv_i64 fp1 = tcg_temp_new_i64();
8434 gen_load_fpr64(ctx, fp0, ft);
8435 gen_load_fpr64(ctx, fp1, fs);
8436 gen_helper_float_addr_ps(fp0, cpu_env, fp0, fp1);
8437 tcg_temp_free_i64(fp1);
8438 gen_store_fpr64(ctx, fp0, fd);
8439 tcg_temp_free_i64(fp0);
8441 opn = "addr.ps";
8442 break;
8443 case OPC_MULR_PS:
8444 check_cp1_64bitmode(ctx);
8446 TCGv_i64 fp0 = tcg_temp_new_i64();
8447 TCGv_i64 fp1 = tcg_temp_new_i64();
8449 gen_load_fpr64(ctx, fp0, ft);
8450 gen_load_fpr64(ctx, fp1, fs);
8451 gen_helper_float_mulr_ps(fp0, cpu_env, fp0, fp1);
8452 tcg_temp_free_i64(fp1);
8453 gen_store_fpr64(ctx, fp0, fd);
8454 tcg_temp_free_i64(fp0);
8456 opn = "mulr.ps";
8457 break;
8458 case OPC_RECIP2_PS:
8459 check_cp1_64bitmode(ctx);
8461 TCGv_i64 fp0 = tcg_temp_new_i64();
8462 TCGv_i64 fp1 = tcg_temp_new_i64();
8464 gen_load_fpr64(ctx, fp0, fs);
8465 gen_load_fpr64(ctx, fp1, ft);
8466 gen_helper_float_recip2_ps(fp0, cpu_env, fp0, fp1);
8467 tcg_temp_free_i64(fp1);
8468 gen_store_fpr64(ctx, fp0, fd);
8469 tcg_temp_free_i64(fp0);
8471 opn = "recip2.ps";
8472 break;
8473 case OPC_RECIP1_PS:
8474 check_cp1_64bitmode(ctx);
8476 TCGv_i64 fp0 = tcg_temp_new_i64();
8478 gen_load_fpr64(ctx, fp0, fs);
8479 gen_helper_float_recip1_ps(fp0, cpu_env, fp0);
8480 gen_store_fpr64(ctx, fp0, fd);
8481 tcg_temp_free_i64(fp0);
8483 opn = "recip1.ps";
8484 break;
8485 case OPC_RSQRT1_PS:
8486 check_cp1_64bitmode(ctx);
8488 TCGv_i64 fp0 = tcg_temp_new_i64();
8490 gen_load_fpr64(ctx, fp0, fs);
8491 gen_helper_float_rsqrt1_ps(fp0, cpu_env, fp0);
8492 gen_store_fpr64(ctx, fp0, fd);
8493 tcg_temp_free_i64(fp0);
8495 opn = "rsqrt1.ps";
8496 break;
8497 case OPC_RSQRT2_PS:
8498 check_cp1_64bitmode(ctx);
8500 TCGv_i64 fp0 = tcg_temp_new_i64();
8501 TCGv_i64 fp1 = tcg_temp_new_i64();
8503 gen_load_fpr64(ctx, fp0, fs);
8504 gen_load_fpr64(ctx, fp1, ft);
8505 gen_helper_float_rsqrt2_ps(fp0, cpu_env, fp0, fp1);
8506 tcg_temp_free_i64(fp1);
8507 gen_store_fpr64(ctx, fp0, fd);
8508 tcg_temp_free_i64(fp0);
8510 opn = "rsqrt2.ps";
8511 break;
8512 case OPC_CVT_S_PU:
8513 check_cp1_64bitmode(ctx);
8515 TCGv_i32 fp0 = tcg_temp_new_i32();
8517 gen_load_fpr32h(fp0, fs);
8518 gen_helper_float_cvts_pu(fp0, cpu_env, fp0);
8519 gen_store_fpr32(fp0, fd);
8520 tcg_temp_free_i32(fp0);
8522 opn = "cvt.s.pu";
8523 break;
8524 case OPC_CVT_PW_PS:
8525 check_cp1_64bitmode(ctx);
8527 TCGv_i64 fp0 = tcg_temp_new_i64();
8529 gen_load_fpr64(ctx, fp0, fs);
8530 gen_helper_float_cvtpw_ps(fp0, cpu_env, fp0);
8531 gen_store_fpr64(ctx, fp0, fd);
8532 tcg_temp_free_i64(fp0);
8534 opn = "cvt.pw.ps";
8535 break;
8536 case OPC_CVT_S_PL:
8537 check_cp1_64bitmode(ctx);
8539 TCGv_i32 fp0 = tcg_temp_new_i32();
8541 gen_load_fpr32(fp0, fs);
8542 gen_helper_float_cvts_pl(fp0, cpu_env, fp0);
8543 gen_store_fpr32(fp0, fd);
8544 tcg_temp_free_i32(fp0);
8546 opn = "cvt.s.pl";
8547 break;
8548 case OPC_PLL_PS:
8549 check_cp1_64bitmode(ctx);
8551 TCGv_i32 fp0 = tcg_temp_new_i32();
8552 TCGv_i32 fp1 = tcg_temp_new_i32();
8554 gen_load_fpr32(fp0, fs);
8555 gen_load_fpr32(fp1, ft);
8556 gen_store_fpr32h(fp0, fd);
8557 gen_store_fpr32(fp1, fd);
8558 tcg_temp_free_i32(fp0);
8559 tcg_temp_free_i32(fp1);
8561 opn = "pll.ps";
8562 break;
8563 case OPC_PLU_PS:
8564 check_cp1_64bitmode(ctx);
8566 TCGv_i32 fp0 = tcg_temp_new_i32();
8567 TCGv_i32 fp1 = tcg_temp_new_i32();
8569 gen_load_fpr32(fp0, fs);
8570 gen_load_fpr32h(fp1, ft);
8571 gen_store_fpr32(fp1, fd);
8572 gen_store_fpr32h(fp0, fd);
8573 tcg_temp_free_i32(fp0);
8574 tcg_temp_free_i32(fp1);
8576 opn = "plu.ps";
8577 break;
8578 case OPC_PUL_PS:
8579 check_cp1_64bitmode(ctx);
8581 TCGv_i32 fp0 = tcg_temp_new_i32();
8582 TCGv_i32 fp1 = tcg_temp_new_i32();
8584 gen_load_fpr32h(fp0, fs);
8585 gen_load_fpr32(fp1, ft);
8586 gen_store_fpr32(fp1, fd);
8587 gen_store_fpr32h(fp0, fd);
8588 tcg_temp_free_i32(fp0);
8589 tcg_temp_free_i32(fp1);
8591 opn = "pul.ps";
8592 break;
8593 case OPC_PUU_PS:
8594 check_cp1_64bitmode(ctx);
8596 TCGv_i32 fp0 = tcg_temp_new_i32();
8597 TCGv_i32 fp1 = tcg_temp_new_i32();
8599 gen_load_fpr32h(fp0, fs);
8600 gen_load_fpr32h(fp1, ft);
8601 gen_store_fpr32(fp1, fd);
8602 gen_store_fpr32h(fp0, fd);
8603 tcg_temp_free_i32(fp0);
8604 tcg_temp_free_i32(fp1);
8606 opn = "puu.ps";
8607 break;
8608 case OPC_CMP_F_PS:
8609 case OPC_CMP_UN_PS:
8610 case OPC_CMP_EQ_PS:
8611 case OPC_CMP_UEQ_PS:
8612 case OPC_CMP_OLT_PS:
8613 case OPC_CMP_ULT_PS:
8614 case OPC_CMP_OLE_PS:
8615 case OPC_CMP_ULE_PS:
8616 case OPC_CMP_SF_PS:
8617 case OPC_CMP_NGLE_PS:
8618 case OPC_CMP_SEQ_PS:
8619 case OPC_CMP_NGL_PS:
8620 case OPC_CMP_LT_PS:
8621 case OPC_CMP_NGE_PS:
8622 case OPC_CMP_LE_PS:
8623 case OPC_CMP_NGT_PS:
8624 if (ctx->opcode & (1 << 6)) {
8625 gen_cmpabs_ps(ctx, func-48, ft, fs, cc);
8626 opn = condnames_abs[func-48];
8627 } else {
8628 gen_cmp_ps(ctx, func-48, ft, fs, cc);
8629 opn = condnames[func-48];
8631 break;
8632 default:
8633 MIPS_INVAL(opn);
8634 generate_exception (ctx, EXCP_RI);
8635 return;
8637 (void)opn; /* avoid a compiler warning */
8638 switch (optype) {
8639 case BINOP:
8640 MIPS_DEBUG("%s %s, %s, %s", opn, fregnames[fd], fregnames[fs], fregnames[ft]);
8641 break;
8642 case CMPOP:
8643 MIPS_DEBUG("%s %s,%s", opn, fregnames[fs], fregnames[ft]);
8644 break;
8645 default:
8646 MIPS_DEBUG("%s %s,%s", opn, fregnames[fd], fregnames[fs]);
8647 break;
8651 /* Coprocessor 3 (FPU) */
8652 static void gen_flt3_ldst (DisasContext *ctx, uint32_t opc,
8653 int fd, int fs, int base, int index)
8655 const char *opn = "extended float load/store";
8656 int store = 0;
8657 TCGv t0 = tcg_temp_new();
8659 if (base == 0) {
8660 gen_load_gpr(t0, index);
8661 } else if (index == 0) {
8662 gen_load_gpr(t0, base);
8663 } else {
8664 gen_op_addr_add(ctx, t0, cpu_gpr[base], cpu_gpr[index]);
8666 /* Don't do NOP if destination is zero: we must perform the actual
8667 memory access. */
8668 switch (opc) {
8669 case OPC_LWXC1:
8670 check_cop1x(ctx);
8672 TCGv_i32 fp0 = tcg_temp_new_i32();
8674 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TESL);
8675 tcg_gen_trunc_tl_i32(fp0, t0);
8676 gen_store_fpr32(fp0, fd);
8677 tcg_temp_free_i32(fp0);
8679 opn = "lwxc1";
8680 break;
8681 case OPC_LDXC1:
8682 check_cop1x(ctx);
8683 check_cp1_registers(ctx, fd);
8685 TCGv_i64 fp0 = tcg_temp_new_i64();
8686 tcg_gen_qemu_ld_i64(fp0, t0, ctx->mem_idx, MO_TEQ);
8687 gen_store_fpr64(ctx, fp0, fd);
8688 tcg_temp_free_i64(fp0);
8690 opn = "ldxc1";
8691 break;
8692 case OPC_LUXC1:
8693 check_cp1_64bitmode(ctx);
8694 tcg_gen_andi_tl(t0, t0, ~0x7);
8696 TCGv_i64 fp0 = tcg_temp_new_i64();
8698 tcg_gen_qemu_ld_i64(fp0, t0, ctx->mem_idx, MO_TEQ);
8699 gen_store_fpr64(ctx, fp0, fd);
8700 tcg_temp_free_i64(fp0);
8702 opn = "luxc1";
8703 break;
8704 case OPC_SWXC1:
8705 check_cop1x(ctx);
8707 TCGv_i32 fp0 = tcg_temp_new_i32();
8708 gen_load_fpr32(fp0, fs);
8709 tcg_gen_qemu_st_i32(fp0, t0, ctx->mem_idx, MO_TEUL);
8710 tcg_temp_free_i32(fp0);
8712 opn = "swxc1";
8713 store = 1;
8714 break;
8715 case OPC_SDXC1:
8716 check_cop1x(ctx);
8717 check_cp1_registers(ctx, fs);
8719 TCGv_i64 fp0 = tcg_temp_new_i64();
8720 gen_load_fpr64(ctx, fp0, fs);
8721 tcg_gen_qemu_st_i64(fp0, t0, ctx->mem_idx, MO_TEQ);
8722 tcg_temp_free_i64(fp0);
8724 opn = "sdxc1";
8725 store = 1;
8726 break;
8727 case OPC_SUXC1:
8728 check_cp1_64bitmode(ctx);
8729 tcg_gen_andi_tl(t0, t0, ~0x7);
8731 TCGv_i64 fp0 = tcg_temp_new_i64();
8732 gen_load_fpr64(ctx, fp0, fs);
8733 tcg_gen_qemu_st_i64(fp0, t0, ctx->mem_idx, MO_TEQ);
8734 tcg_temp_free_i64(fp0);
8736 opn = "suxc1";
8737 store = 1;
8738 break;
8740 tcg_temp_free(t0);
8741 (void)opn; (void)store; /* avoid compiler warnings */
8742 MIPS_DEBUG("%s %s, %s(%s)", opn, fregnames[store ? fs : fd],
8743 regnames[index], regnames[base]);
8746 static void gen_flt3_arith (DisasContext *ctx, uint32_t opc,
8747 int fd, int fr, int fs, int ft)
8749 const char *opn = "flt3_arith";
8751 switch (opc) {
8752 case OPC_ALNV_PS:
8753 check_cp1_64bitmode(ctx);
8755 TCGv t0 = tcg_temp_local_new();
8756 TCGv_i32 fp = tcg_temp_new_i32();
8757 TCGv_i32 fph = tcg_temp_new_i32();
8758 int l1 = gen_new_label();
8759 int l2 = gen_new_label();
8761 gen_load_gpr(t0, fr);
8762 tcg_gen_andi_tl(t0, t0, 0x7);
8764 tcg_gen_brcondi_tl(TCG_COND_NE, t0, 0, l1);
8765 gen_load_fpr32(fp, fs);
8766 gen_load_fpr32h(fph, fs);
8767 gen_store_fpr32(fp, fd);
8768 gen_store_fpr32h(fph, fd);
8769 tcg_gen_br(l2);
8770 gen_set_label(l1);
8771 tcg_gen_brcondi_tl(TCG_COND_NE, t0, 4, l2);
8772 tcg_temp_free(t0);
8773 #ifdef TARGET_WORDS_BIGENDIAN
8774 gen_load_fpr32(fp, fs);
8775 gen_load_fpr32h(fph, ft);
8776 gen_store_fpr32h(fp, fd);
8777 gen_store_fpr32(fph, fd);
8778 #else
8779 gen_load_fpr32h(fph, fs);
8780 gen_load_fpr32(fp, ft);
8781 gen_store_fpr32(fph, fd);
8782 gen_store_fpr32h(fp, fd);
8783 #endif
8784 gen_set_label(l2);
8785 tcg_temp_free_i32(fp);
8786 tcg_temp_free_i32(fph);
8788 opn = "alnv.ps";
8789 break;
8790 case OPC_MADD_S:
8791 check_cop1x(ctx);
8793 TCGv_i32 fp0 = tcg_temp_new_i32();
8794 TCGv_i32 fp1 = tcg_temp_new_i32();
8795 TCGv_i32 fp2 = tcg_temp_new_i32();
8797 gen_load_fpr32(fp0, fs);
8798 gen_load_fpr32(fp1, ft);
8799 gen_load_fpr32(fp2, fr);
8800 gen_helper_float_madd_s(fp2, cpu_env, fp0, fp1, fp2);
8801 tcg_temp_free_i32(fp0);
8802 tcg_temp_free_i32(fp1);
8803 gen_store_fpr32(fp2, fd);
8804 tcg_temp_free_i32(fp2);
8806 opn = "madd.s";
8807 break;
8808 case OPC_MADD_D:
8809 check_cop1x(ctx);
8810 check_cp1_registers(ctx, fd | fs | ft | fr);
8812 TCGv_i64 fp0 = tcg_temp_new_i64();
8813 TCGv_i64 fp1 = tcg_temp_new_i64();
8814 TCGv_i64 fp2 = tcg_temp_new_i64();
8816 gen_load_fpr64(ctx, fp0, fs);
8817 gen_load_fpr64(ctx, fp1, ft);
8818 gen_load_fpr64(ctx, fp2, fr);
8819 gen_helper_float_madd_d(fp2, cpu_env, fp0, fp1, fp2);
8820 tcg_temp_free_i64(fp0);
8821 tcg_temp_free_i64(fp1);
8822 gen_store_fpr64(ctx, fp2, fd);
8823 tcg_temp_free_i64(fp2);
8825 opn = "madd.d";
8826 break;
8827 case OPC_MADD_PS:
8828 check_cp1_64bitmode(ctx);
8830 TCGv_i64 fp0 = tcg_temp_new_i64();
8831 TCGv_i64 fp1 = tcg_temp_new_i64();
8832 TCGv_i64 fp2 = tcg_temp_new_i64();
8834 gen_load_fpr64(ctx, fp0, fs);
8835 gen_load_fpr64(ctx, fp1, ft);
8836 gen_load_fpr64(ctx, fp2, fr);
8837 gen_helper_float_madd_ps(fp2, cpu_env, fp0, fp1, fp2);
8838 tcg_temp_free_i64(fp0);
8839 tcg_temp_free_i64(fp1);
8840 gen_store_fpr64(ctx, fp2, fd);
8841 tcg_temp_free_i64(fp2);
8843 opn = "madd.ps";
8844 break;
8845 case OPC_MSUB_S:
8846 check_cop1x(ctx);
8848 TCGv_i32 fp0 = tcg_temp_new_i32();
8849 TCGv_i32 fp1 = tcg_temp_new_i32();
8850 TCGv_i32 fp2 = tcg_temp_new_i32();
8852 gen_load_fpr32(fp0, fs);
8853 gen_load_fpr32(fp1, ft);
8854 gen_load_fpr32(fp2, fr);
8855 gen_helper_float_msub_s(fp2, cpu_env, fp0, fp1, fp2);
8856 tcg_temp_free_i32(fp0);
8857 tcg_temp_free_i32(fp1);
8858 gen_store_fpr32(fp2, fd);
8859 tcg_temp_free_i32(fp2);
8861 opn = "msub.s";
8862 break;
8863 case OPC_MSUB_D:
8864 check_cop1x(ctx);
8865 check_cp1_registers(ctx, fd | fs | ft | fr);
8867 TCGv_i64 fp0 = tcg_temp_new_i64();
8868 TCGv_i64 fp1 = tcg_temp_new_i64();
8869 TCGv_i64 fp2 = tcg_temp_new_i64();
8871 gen_load_fpr64(ctx, fp0, fs);
8872 gen_load_fpr64(ctx, fp1, ft);
8873 gen_load_fpr64(ctx, fp2, fr);
8874 gen_helper_float_msub_d(fp2, cpu_env, fp0, fp1, fp2);
8875 tcg_temp_free_i64(fp0);
8876 tcg_temp_free_i64(fp1);
8877 gen_store_fpr64(ctx, fp2, fd);
8878 tcg_temp_free_i64(fp2);
8880 opn = "msub.d";
8881 break;
8882 case OPC_MSUB_PS:
8883 check_cp1_64bitmode(ctx);
8885 TCGv_i64 fp0 = tcg_temp_new_i64();
8886 TCGv_i64 fp1 = tcg_temp_new_i64();
8887 TCGv_i64 fp2 = tcg_temp_new_i64();
8889 gen_load_fpr64(ctx, fp0, fs);
8890 gen_load_fpr64(ctx, fp1, ft);
8891 gen_load_fpr64(ctx, fp2, fr);
8892 gen_helper_float_msub_ps(fp2, cpu_env, fp0, fp1, fp2);
8893 tcg_temp_free_i64(fp0);
8894 tcg_temp_free_i64(fp1);
8895 gen_store_fpr64(ctx, fp2, fd);
8896 tcg_temp_free_i64(fp2);
8898 opn = "msub.ps";
8899 break;
8900 case OPC_NMADD_S:
8901 check_cop1x(ctx);
8903 TCGv_i32 fp0 = tcg_temp_new_i32();
8904 TCGv_i32 fp1 = tcg_temp_new_i32();
8905 TCGv_i32 fp2 = tcg_temp_new_i32();
8907 gen_load_fpr32(fp0, fs);
8908 gen_load_fpr32(fp1, ft);
8909 gen_load_fpr32(fp2, fr);
8910 gen_helper_float_nmadd_s(fp2, cpu_env, fp0, fp1, fp2);
8911 tcg_temp_free_i32(fp0);
8912 tcg_temp_free_i32(fp1);
8913 gen_store_fpr32(fp2, fd);
8914 tcg_temp_free_i32(fp2);
8916 opn = "nmadd.s";
8917 break;
8918 case OPC_NMADD_D:
8919 check_cop1x(ctx);
8920 check_cp1_registers(ctx, fd | fs | ft | fr);
8922 TCGv_i64 fp0 = tcg_temp_new_i64();
8923 TCGv_i64 fp1 = tcg_temp_new_i64();
8924 TCGv_i64 fp2 = tcg_temp_new_i64();
8926 gen_load_fpr64(ctx, fp0, fs);
8927 gen_load_fpr64(ctx, fp1, ft);
8928 gen_load_fpr64(ctx, fp2, fr);
8929 gen_helper_float_nmadd_d(fp2, cpu_env, fp0, fp1, fp2);
8930 tcg_temp_free_i64(fp0);
8931 tcg_temp_free_i64(fp1);
8932 gen_store_fpr64(ctx, fp2, fd);
8933 tcg_temp_free_i64(fp2);
8935 opn = "nmadd.d";
8936 break;
8937 case OPC_NMADD_PS:
8938 check_cp1_64bitmode(ctx);
8940 TCGv_i64 fp0 = tcg_temp_new_i64();
8941 TCGv_i64 fp1 = tcg_temp_new_i64();
8942 TCGv_i64 fp2 = tcg_temp_new_i64();
8944 gen_load_fpr64(ctx, fp0, fs);
8945 gen_load_fpr64(ctx, fp1, ft);
8946 gen_load_fpr64(ctx, fp2, fr);
8947 gen_helper_float_nmadd_ps(fp2, cpu_env, fp0, fp1, fp2);
8948 tcg_temp_free_i64(fp0);
8949 tcg_temp_free_i64(fp1);
8950 gen_store_fpr64(ctx, fp2, fd);
8951 tcg_temp_free_i64(fp2);
8953 opn = "nmadd.ps";
8954 break;
8955 case OPC_NMSUB_S:
8956 check_cop1x(ctx);
8958 TCGv_i32 fp0 = tcg_temp_new_i32();
8959 TCGv_i32 fp1 = tcg_temp_new_i32();
8960 TCGv_i32 fp2 = tcg_temp_new_i32();
8962 gen_load_fpr32(fp0, fs);
8963 gen_load_fpr32(fp1, ft);
8964 gen_load_fpr32(fp2, fr);
8965 gen_helper_float_nmsub_s(fp2, cpu_env, fp0, fp1, fp2);
8966 tcg_temp_free_i32(fp0);
8967 tcg_temp_free_i32(fp1);
8968 gen_store_fpr32(fp2, fd);
8969 tcg_temp_free_i32(fp2);
8971 opn = "nmsub.s";
8972 break;
8973 case OPC_NMSUB_D:
8974 check_cop1x(ctx);
8975 check_cp1_registers(ctx, fd | fs | ft | fr);
8977 TCGv_i64 fp0 = tcg_temp_new_i64();
8978 TCGv_i64 fp1 = tcg_temp_new_i64();
8979 TCGv_i64 fp2 = tcg_temp_new_i64();
8981 gen_load_fpr64(ctx, fp0, fs);
8982 gen_load_fpr64(ctx, fp1, ft);
8983 gen_load_fpr64(ctx, fp2, fr);
8984 gen_helper_float_nmsub_d(fp2, cpu_env, fp0, fp1, fp2);
8985 tcg_temp_free_i64(fp0);
8986 tcg_temp_free_i64(fp1);
8987 gen_store_fpr64(ctx, fp2, fd);
8988 tcg_temp_free_i64(fp2);
8990 opn = "nmsub.d";
8991 break;
8992 case OPC_NMSUB_PS:
8993 check_cp1_64bitmode(ctx);
8995 TCGv_i64 fp0 = tcg_temp_new_i64();
8996 TCGv_i64 fp1 = tcg_temp_new_i64();
8997 TCGv_i64 fp2 = tcg_temp_new_i64();
8999 gen_load_fpr64(ctx, fp0, fs);
9000 gen_load_fpr64(ctx, fp1, ft);
9001 gen_load_fpr64(ctx, fp2, fr);
9002 gen_helper_float_nmsub_ps(fp2, cpu_env, fp0, fp1, fp2);
9003 tcg_temp_free_i64(fp0);
9004 tcg_temp_free_i64(fp1);
9005 gen_store_fpr64(ctx, fp2, fd);
9006 tcg_temp_free_i64(fp2);
9008 opn = "nmsub.ps";
9009 break;
9010 default:
9011 MIPS_INVAL(opn);
9012 generate_exception (ctx, EXCP_RI);
9013 return;
9015 (void)opn; /* avoid a compiler warning */
9016 MIPS_DEBUG("%s %s, %s, %s, %s", opn, fregnames[fd], fregnames[fr],
9017 fregnames[fs], fregnames[ft]);
9020 static void gen_rdhwr(DisasContext *ctx, int rt, int rd)
9022 TCGv t0;
9024 #if !defined(CONFIG_USER_ONLY)
9025 /* The Linux kernel will emulate rdhwr if it's not supported natively.
9026 Therefore only check the ISA in system mode. */
9027 check_insn(ctx, ISA_MIPS32R2);
9028 #endif
9029 t0 = tcg_temp_new();
9031 switch (rd) {
9032 case 0:
9033 save_cpu_state(ctx, 1);
9034 gen_helper_rdhwr_cpunum(t0, cpu_env);
9035 gen_store_gpr(t0, rt);
9036 break;
9037 case 1:
9038 save_cpu_state(ctx, 1);
9039 gen_helper_rdhwr_synci_step(t0, cpu_env);
9040 gen_store_gpr(t0, rt);
9041 break;
9042 case 2:
9043 save_cpu_state(ctx, 1);
9044 gen_helper_rdhwr_cc(t0, cpu_env);
9045 gen_store_gpr(t0, rt);
9046 break;
9047 case 3:
9048 save_cpu_state(ctx, 1);
9049 gen_helper_rdhwr_ccres(t0, cpu_env);
9050 gen_store_gpr(t0, rt);
9051 break;
9052 case 29:
9053 #if defined(CONFIG_USER_ONLY)
9054 tcg_gen_ld_tl(t0, cpu_env, offsetof(CPUMIPSState, tls_value));
9055 gen_store_gpr(t0, rt);
9056 break;
9057 #else
9058 /* XXX: Some CPUs implement this in hardware.
9059 Not supported yet. */
9060 #endif
9061 default: /* Invalid */
9062 MIPS_INVAL("rdhwr");
9063 generate_exception(ctx, EXCP_RI);
9064 break;
9066 tcg_temp_free(t0);
9069 static void handle_delay_slot(DisasContext *ctx, int insn_bytes)
9071 if (ctx->hflags & MIPS_HFLAG_BMASK) {
9072 int proc_hflags = ctx->hflags & MIPS_HFLAG_BMASK;
9073 /* Branches completion */
9074 ctx->hflags &= ~MIPS_HFLAG_BMASK;
9075 ctx->bstate = BS_BRANCH;
9076 save_cpu_state(ctx, 0);
9077 /* FIXME: Need to clear can_do_io. */
9078 switch (proc_hflags & MIPS_HFLAG_BMASK_BASE) {
9079 case MIPS_HFLAG_B:
9080 /* unconditional branch */
9081 MIPS_DEBUG("unconditional branch");
9082 if (proc_hflags & MIPS_HFLAG_BX) {
9083 tcg_gen_xori_i32(hflags, hflags, MIPS_HFLAG_M16);
9085 gen_goto_tb(ctx, 0, ctx->btarget);
9086 break;
9087 case MIPS_HFLAG_BL:
9088 /* blikely taken case */
9089 MIPS_DEBUG("blikely branch taken");
9090 gen_goto_tb(ctx, 0, ctx->btarget);
9091 break;
9092 case MIPS_HFLAG_BC:
9093 /* Conditional branch */
9094 MIPS_DEBUG("conditional branch");
9096 int l1 = gen_new_label();
9098 tcg_gen_brcondi_tl(TCG_COND_NE, bcond, 0, l1);
9099 gen_goto_tb(ctx, 1, ctx->pc + insn_bytes);
9100 gen_set_label(l1);
9101 gen_goto_tb(ctx, 0, ctx->btarget);
9103 break;
9104 case MIPS_HFLAG_BR:
9105 /* unconditional branch to register */
9106 MIPS_DEBUG("branch to register");
9107 if (ctx->insn_flags & (ASE_MIPS16 | ASE_MICROMIPS)) {
9108 TCGv t0 = tcg_temp_new();
9109 TCGv_i32 t1 = tcg_temp_new_i32();
9111 tcg_gen_andi_tl(t0, btarget, 0x1);
9112 tcg_gen_trunc_tl_i32(t1, t0);
9113 tcg_temp_free(t0);
9114 tcg_gen_andi_i32(hflags, hflags, ~(uint32_t)MIPS_HFLAG_M16);
9115 tcg_gen_shli_i32(t1, t1, MIPS_HFLAG_M16_SHIFT);
9116 tcg_gen_or_i32(hflags, hflags, t1);
9117 tcg_temp_free_i32(t1);
9119 tcg_gen_andi_tl(cpu_PC, btarget, ~(target_ulong)0x1);
9120 } else {
9121 tcg_gen_mov_tl(cpu_PC, btarget);
9123 if (ctx->singlestep_enabled) {
9124 save_cpu_state(ctx, 0);
9125 gen_helper_0e0i(raise_exception, EXCP_DEBUG);
9127 tcg_gen_exit_tb(0);
9128 break;
9129 default:
9130 MIPS_DEBUG("unknown branch");
9131 break;
9136 /* ISA extensions (ASEs) */
9137 /* MIPS16 extension to MIPS32 */
9139 /* MIPS16 major opcodes */
9140 enum {
9141 M16_OPC_ADDIUSP = 0x00,
9142 M16_OPC_ADDIUPC = 0x01,
9143 M16_OPC_B = 0x02,
9144 M16_OPC_JAL = 0x03,
9145 M16_OPC_BEQZ = 0x04,
9146 M16_OPC_BNEQZ = 0x05,
9147 M16_OPC_SHIFT = 0x06,
9148 M16_OPC_LD = 0x07,
9149 M16_OPC_RRIA = 0x08,
9150 M16_OPC_ADDIU8 = 0x09,
9151 M16_OPC_SLTI = 0x0a,
9152 M16_OPC_SLTIU = 0x0b,
9153 M16_OPC_I8 = 0x0c,
9154 M16_OPC_LI = 0x0d,
9155 M16_OPC_CMPI = 0x0e,
9156 M16_OPC_SD = 0x0f,
9157 M16_OPC_LB = 0x10,
9158 M16_OPC_LH = 0x11,
9159 M16_OPC_LWSP = 0x12,
9160 M16_OPC_LW = 0x13,
9161 M16_OPC_LBU = 0x14,
9162 M16_OPC_LHU = 0x15,
9163 M16_OPC_LWPC = 0x16,
9164 M16_OPC_LWU = 0x17,
9165 M16_OPC_SB = 0x18,
9166 M16_OPC_SH = 0x19,
9167 M16_OPC_SWSP = 0x1a,
9168 M16_OPC_SW = 0x1b,
9169 M16_OPC_RRR = 0x1c,
9170 M16_OPC_RR = 0x1d,
9171 M16_OPC_EXTEND = 0x1e,
9172 M16_OPC_I64 = 0x1f
9175 /* I8 funct field */
9176 enum {
9177 I8_BTEQZ = 0x0,
9178 I8_BTNEZ = 0x1,
9179 I8_SWRASP = 0x2,
9180 I8_ADJSP = 0x3,
9181 I8_SVRS = 0x4,
9182 I8_MOV32R = 0x5,
9183 I8_MOVR32 = 0x7
9186 /* RRR f field */
9187 enum {
9188 RRR_DADDU = 0x0,
9189 RRR_ADDU = 0x1,
9190 RRR_DSUBU = 0x2,
9191 RRR_SUBU = 0x3
9194 /* RR funct field */
9195 enum {
9196 RR_JR = 0x00,
9197 RR_SDBBP = 0x01,
9198 RR_SLT = 0x02,
9199 RR_SLTU = 0x03,
9200 RR_SLLV = 0x04,
9201 RR_BREAK = 0x05,
9202 RR_SRLV = 0x06,
9203 RR_SRAV = 0x07,
9204 RR_DSRL = 0x08,
9205 RR_CMP = 0x0a,
9206 RR_NEG = 0x0b,
9207 RR_AND = 0x0c,
9208 RR_OR = 0x0d,
9209 RR_XOR = 0x0e,
9210 RR_NOT = 0x0f,
9211 RR_MFHI = 0x10,
9212 RR_CNVT = 0x11,
9213 RR_MFLO = 0x12,
9214 RR_DSRA = 0x13,
9215 RR_DSLLV = 0x14,
9216 RR_DSRLV = 0x16,
9217 RR_DSRAV = 0x17,
9218 RR_MULT = 0x18,
9219 RR_MULTU = 0x19,
9220 RR_DIV = 0x1a,
9221 RR_DIVU = 0x1b,
9222 RR_DMULT = 0x1c,
9223 RR_DMULTU = 0x1d,
9224 RR_DDIV = 0x1e,
9225 RR_DDIVU = 0x1f
9228 /* I64 funct field */
9229 enum {
9230 I64_LDSP = 0x0,
9231 I64_SDSP = 0x1,
9232 I64_SDRASP = 0x2,
9233 I64_DADJSP = 0x3,
9234 I64_LDPC = 0x4,
9235 I64_DADDIU5 = 0x5,
9236 I64_DADDIUPC = 0x6,
9237 I64_DADDIUSP = 0x7
9240 /* RR ry field for CNVT */
9241 enum {
9242 RR_RY_CNVT_ZEB = 0x0,
9243 RR_RY_CNVT_ZEH = 0x1,
9244 RR_RY_CNVT_ZEW = 0x2,
9245 RR_RY_CNVT_SEB = 0x4,
9246 RR_RY_CNVT_SEH = 0x5,
9247 RR_RY_CNVT_SEW = 0x6,
9250 static int xlat (int r)
9252 static int map[] = { 16, 17, 2, 3, 4, 5, 6, 7 };
9254 return map[r];
9257 static void gen_mips16_save (DisasContext *ctx,
9258 int xsregs, int aregs,
9259 int do_ra, int do_s0, int do_s1,
9260 int framesize)
9262 TCGv t0 = tcg_temp_new();
9263 TCGv t1 = tcg_temp_new();
9264 int args, astatic;
9266 switch (aregs) {
9267 case 0:
9268 case 1:
9269 case 2:
9270 case 3:
9271 case 11:
9272 args = 0;
9273 break;
9274 case 4:
9275 case 5:
9276 case 6:
9277 case 7:
9278 args = 1;
9279 break;
9280 case 8:
9281 case 9:
9282 case 10:
9283 args = 2;
9284 break;
9285 case 12:
9286 case 13:
9287 args = 3;
9288 break;
9289 case 14:
9290 args = 4;
9291 break;
9292 default:
9293 generate_exception(ctx, EXCP_RI);
9294 return;
9297 switch (args) {
9298 case 4:
9299 gen_base_offset_addr(ctx, t0, 29, 12);
9300 gen_load_gpr(t1, 7);
9301 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL);
9302 /* Fall through */
9303 case 3:
9304 gen_base_offset_addr(ctx, t0, 29, 8);
9305 gen_load_gpr(t1, 6);
9306 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL);
9307 /* Fall through */
9308 case 2:
9309 gen_base_offset_addr(ctx, t0, 29, 4);
9310 gen_load_gpr(t1, 5);
9311 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL);
9312 /* Fall through */
9313 case 1:
9314 gen_base_offset_addr(ctx, t0, 29, 0);
9315 gen_load_gpr(t1, 4);
9316 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL);
9319 gen_load_gpr(t0, 29);
9321 #define DECR_AND_STORE(reg) do { \
9322 tcg_gen_subi_tl(t0, t0, 4); \
9323 gen_load_gpr(t1, reg); \
9324 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL); \
9325 } while (0)
9327 if (do_ra) {
9328 DECR_AND_STORE(31);
9331 switch (xsregs) {
9332 case 7:
9333 DECR_AND_STORE(30);
9334 /* Fall through */
9335 case 6:
9336 DECR_AND_STORE(23);
9337 /* Fall through */
9338 case 5:
9339 DECR_AND_STORE(22);
9340 /* Fall through */
9341 case 4:
9342 DECR_AND_STORE(21);
9343 /* Fall through */
9344 case 3:
9345 DECR_AND_STORE(20);
9346 /* Fall through */
9347 case 2:
9348 DECR_AND_STORE(19);
9349 /* Fall through */
9350 case 1:
9351 DECR_AND_STORE(18);
9354 if (do_s1) {
9355 DECR_AND_STORE(17);
9357 if (do_s0) {
9358 DECR_AND_STORE(16);
9361 switch (aregs) {
9362 case 0:
9363 case 4:
9364 case 8:
9365 case 12:
9366 case 14:
9367 astatic = 0;
9368 break;
9369 case 1:
9370 case 5:
9371 case 9:
9372 case 13:
9373 astatic = 1;
9374 break;
9375 case 2:
9376 case 6:
9377 case 10:
9378 astatic = 2;
9379 break;
9380 case 3:
9381 case 7:
9382 astatic = 3;
9383 break;
9384 case 11:
9385 astatic = 4;
9386 break;
9387 default:
9388 generate_exception(ctx, EXCP_RI);
9389 return;
9392 if (astatic > 0) {
9393 DECR_AND_STORE(7);
9394 if (astatic > 1) {
9395 DECR_AND_STORE(6);
9396 if (astatic > 2) {
9397 DECR_AND_STORE(5);
9398 if (astatic > 3) {
9399 DECR_AND_STORE(4);
9404 #undef DECR_AND_STORE
9406 tcg_gen_subi_tl(cpu_gpr[29], cpu_gpr[29], framesize);
9407 tcg_temp_free(t0);
9408 tcg_temp_free(t1);
9411 static void gen_mips16_restore (DisasContext *ctx,
9412 int xsregs, int aregs,
9413 int do_ra, int do_s0, int do_s1,
9414 int framesize)
9416 int astatic;
9417 TCGv t0 = tcg_temp_new();
9418 TCGv t1 = tcg_temp_new();
9420 tcg_gen_addi_tl(t0, cpu_gpr[29], framesize);
9422 #define DECR_AND_LOAD(reg) do { \
9423 tcg_gen_subi_tl(t0, t0, 4); \
9424 tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_TESL); \
9425 gen_store_gpr(t1, reg); \
9426 } while (0)
9428 if (do_ra) {
9429 DECR_AND_LOAD(31);
9432 switch (xsregs) {
9433 case 7:
9434 DECR_AND_LOAD(30);
9435 /* Fall through */
9436 case 6:
9437 DECR_AND_LOAD(23);
9438 /* Fall through */
9439 case 5:
9440 DECR_AND_LOAD(22);
9441 /* Fall through */
9442 case 4:
9443 DECR_AND_LOAD(21);
9444 /* Fall through */
9445 case 3:
9446 DECR_AND_LOAD(20);
9447 /* Fall through */
9448 case 2:
9449 DECR_AND_LOAD(19);
9450 /* Fall through */
9451 case 1:
9452 DECR_AND_LOAD(18);
9455 if (do_s1) {
9456 DECR_AND_LOAD(17);
9458 if (do_s0) {
9459 DECR_AND_LOAD(16);
9462 switch (aregs) {
9463 case 0:
9464 case 4:
9465 case 8:
9466 case 12:
9467 case 14:
9468 astatic = 0;
9469 break;
9470 case 1:
9471 case 5:
9472 case 9:
9473 case 13:
9474 astatic = 1;
9475 break;
9476 case 2:
9477 case 6:
9478 case 10:
9479 astatic = 2;
9480 break;
9481 case 3:
9482 case 7:
9483 astatic = 3;
9484 break;
9485 case 11:
9486 astatic = 4;
9487 break;
9488 default:
9489 generate_exception(ctx, EXCP_RI);
9490 return;
9493 if (astatic > 0) {
9494 DECR_AND_LOAD(7);
9495 if (astatic > 1) {
9496 DECR_AND_LOAD(6);
9497 if (astatic > 2) {
9498 DECR_AND_LOAD(5);
9499 if (astatic > 3) {
9500 DECR_AND_LOAD(4);
9505 #undef DECR_AND_LOAD
9507 tcg_gen_addi_tl(cpu_gpr[29], cpu_gpr[29], framesize);
9508 tcg_temp_free(t0);
9509 tcg_temp_free(t1);
9512 static void gen_addiupc (DisasContext *ctx, int rx, int imm,
9513 int is_64_bit, int extended)
9515 TCGv t0;
9517 if (extended && (ctx->hflags & MIPS_HFLAG_BMASK)) {
9518 generate_exception(ctx, EXCP_RI);
9519 return;
9522 t0 = tcg_temp_new();
9524 tcg_gen_movi_tl(t0, pc_relative_pc(ctx));
9525 tcg_gen_addi_tl(cpu_gpr[rx], t0, imm);
9526 if (!is_64_bit) {
9527 tcg_gen_ext32s_tl(cpu_gpr[rx], cpu_gpr[rx]);
9530 tcg_temp_free(t0);
9533 #if defined(TARGET_MIPS64)
9534 static void decode_i64_mips16 (DisasContext *ctx,
9535 int ry, int funct, int16_t offset,
9536 int extended)
9538 switch (funct) {
9539 case I64_LDSP:
9540 check_mips_64(ctx);
9541 offset = extended ? offset : offset << 3;
9542 gen_ld(ctx, OPC_LD, ry, 29, offset);
9543 break;
9544 case I64_SDSP:
9545 check_mips_64(ctx);
9546 offset = extended ? offset : offset << 3;
9547 gen_st(ctx, OPC_SD, ry, 29, offset);
9548 break;
9549 case I64_SDRASP:
9550 check_mips_64(ctx);
9551 offset = extended ? offset : (ctx->opcode & 0xff) << 3;
9552 gen_st(ctx, OPC_SD, 31, 29, offset);
9553 break;
9554 case I64_DADJSP:
9555 check_mips_64(ctx);
9556 offset = extended ? offset : ((int8_t)ctx->opcode) << 3;
9557 gen_arith_imm(ctx, OPC_DADDIU, 29, 29, offset);
9558 break;
9559 case I64_LDPC:
9560 if (extended && (ctx->hflags & MIPS_HFLAG_BMASK)) {
9561 generate_exception(ctx, EXCP_RI);
9562 } else {
9563 offset = extended ? offset : offset << 3;
9564 gen_ld(ctx, OPC_LDPC, ry, 0, offset);
9566 break;
9567 case I64_DADDIU5:
9568 check_mips_64(ctx);
9569 offset = extended ? offset : ((int8_t)(offset << 3)) >> 3;
9570 gen_arith_imm(ctx, OPC_DADDIU, ry, ry, offset);
9571 break;
9572 case I64_DADDIUPC:
9573 check_mips_64(ctx);
9574 offset = extended ? offset : offset << 2;
9575 gen_addiupc(ctx, ry, offset, 1, extended);
9576 break;
9577 case I64_DADDIUSP:
9578 check_mips_64(ctx);
9579 offset = extended ? offset : offset << 2;
9580 gen_arith_imm(ctx, OPC_DADDIU, ry, 29, offset);
9581 break;
9584 #endif
9586 static int decode_extended_mips16_opc (CPUMIPSState *env, DisasContext *ctx)
9588 int extend = cpu_lduw_code(env, ctx->pc + 2);
9589 int op, rx, ry, funct, sa;
9590 int16_t imm, offset;
9592 ctx->opcode = (ctx->opcode << 16) | extend;
9593 op = (ctx->opcode >> 11) & 0x1f;
9594 sa = (ctx->opcode >> 22) & 0x1f;
9595 funct = (ctx->opcode >> 8) & 0x7;
9596 rx = xlat((ctx->opcode >> 8) & 0x7);
9597 ry = xlat((ctx->opcode >> 5) & 0x7);
9598 offset = imm = (int16_t) (((ctx->opcode >> 16) & 0x1f) << 11
9599 | ((ctx->opcode >> 21) & 0x3f) << 5
9600 | (ctx->opcode & 0x1f));
9602 /* The extended opcodes cleverly reuse the opcodes from their 16-bit
9603 counterparts. */
9604 switch (op) {
9605 case M16_OPC_ADDIUSP:
9606 gen_arith_imm(ctx, OPC_ADDIU, rx, 29, imm);
9607 break;
9608 case M16_OPC_ADDIUPC:
9609 gen_addiupc(ctx, rx, imm, 0, 1);
9610 break;
9611 case M16_OPC_B:
9612 gen_compute_branch(ctx, OPC_BEQ, 4, 0, 0, offset << 1);
9613 /* No delay slot, so just process as a normal instruction */
9614 break;
9615 case M16_OPC_BEQZ:
9616 gen_compute_branch(ctx, OPC_BEQ, 4, rx, 0, offset << 1);
9617 /* No delay slot, so just process as a normal instruction */
9618 break;
9619 case M16_OPC_BNEQZ:
9620 gen_compute_branch(ctx, OPC_BNE, 4, rx, 0, offset << 1);
9621 /* No delay slot, so just process as a normal instruction */
9622 break;
9623 case M16_OPC_SHIFT:
9624 switch (ctx->opcode & 0x3) {
9625 case 0x0:
9626 gen_shift_imm(ctx, OPC_SLL, rx, ry, sa);
9627 break;
9628 case 0x1:
9629 #if defined(TARGET_MIPS64)
9630 check_mips_64(ctx);
9631 gen_shift_imm(ctx, OPC_DSLL, rx, ry, sa);
9632 #else
9633 generate_exception(ctx, EXCP_RI);
9634 #endif
9635 break;
9636 case 0x2:
9637 gen_shift_imm(ctx, OPC_SRL, rx, ry, sa);
9638 break;
9639 case 0x3:
9640 gen_shift_imm(ctx, OPC_SRA, rx, ry, sa);
9641 break;
9643 break;
9644 #if defined(TARGET_MIPS64)
9645 case M16_OPC_LD:
9646 check_mips_64(ctx);
9647 gen_ld(ctx, OPC_LD, ry, rx, offset);
9648 break;
9649 #endif
9650 case M16_OPC_RRIA:
9651 imm = ctx->opcode & 0xf;
9652 imm = imm | ((ctx->opcode >> 20) & 0x7f) << 4;
9653 imm = imm | ((ctx->opcode >> 16) & 0xf) << 11;
9654 imm = (int16_t) (imm << 1) >> 1;
9655 if ((ctx->opcode >> 4) & 0x1) {
9656 #if defined(TARGET_MIPS64)
9657 check_mips_64(ctx);
9658 gen_arith_imm(ctx, OPC_DADDIU, ry, rx, imm);
9659 #else
9660 generate_exception(ctx, EXCP_RI);
9661 #endif
9662 } else {
9663 gen_arith_imm(ctx, OPC_ADDIU, ry, rx, imm);
9665 break;
9666 case M16_OPC_ADDIU8:
9667 gen_arith_imm(ctx, OPC_ADDIU, rx, rx, imm);
9668 break;
9669 case M16_OPC_SLTI:
9670 gen_slt_imm(ctx, OPC_SLTI, 24, rx, imm);
9671 break;
9672 case M16_OPC_SLTIU:
9673 gen_slt_imm(ctx, OPC_SLTIU, 24, rx, imm);
9674 break;
9675 case M16_OPC_I8:
9676 switch (funct) {
9677 case I8_BTEQZ:
9678 gen_compute_branch(ctx, OPC_BEQ, 4, 24, 0, offset << 1);
9679 break;
9680 case I8_BTNEZ:
9681 gen_compute_branch(ctx, OPC_BNE, 4, 24, 0, offset << 1);
9682 break;
9683 case I8_SWRASP:
9684 gen_st(ctx, OPC_SW, 31, 29, imm);
9685 break;
9686 case I8_ADJSP:
9687 gen_arith_imm(ctx, OPC_ADDIU, 29, 29, imm);
9688 break;
9689 case I8_SVRS:
9691 int xsregs = (ctx->opcode >> 24) & 0x7;
9692 int aregs = (ctx->opcode >> 16) & 0xf;
9693 int do_ra = (ctx->opcode >> 6) & 0x1;
9694 int do_s0 = (ctx->opcode >> 5) & 0x1;
9695 int do_s1 = (ctx->opcode >> 4) & 0x1;
9696 int framesize = (((ctx->opcode >> 20) & 0xf) << 4
9697 | (ctx->opcode & 0xf)) << 3;
9699 if (ctx->opcode & (1 << 7)) {
9700 gen_mips16_save(ctx, xsregs, aregs,
9701 do_ra, do_s0, do_s1,
9702 framesize);
9703 } else {
9704 gen_mips16_restore(ctx, xsregs, aregs,
9705 do_ra, do_s0, do_s1,
9706 framesize);
9709 break;
9710 default:
9711 generate_exception(ctx, EXCP_RI);
9712 break;
9714 break;
9715 case M16_OPC_LI:
9716 tcg_gen_movi_tl(cpu_gpr[rx], (uint16_t) imm);
9717 break;
9718 case M16_OPC_CMPI:
9719 tcg_gen_xori_tl(cpu_gpr[24], cpu_gpr[rx], (uint16_t) imm);
9720 break;
9721 #if defined(TARGET_MIPS64)
9722 case M16_OPC_SD:
9723 gen_st(ctx, OPC_SD, ry, rx, offset);
9724 break;
9725 #endif
9726 case M16_OPC_LB:
9727 gen_ld(ctx, OPC_LB, ry, rx, offset);
9728 break;
9729 case M16_OPC_LH:
9730 gen_ld(ctx, OPC_LH, ry, rx, offset);
9731 break;
9732 case M16_OPC_LWSP:
9733 gen_ld(ctx, OPC_LW, rx, 29, offset);
9734 break;
9735 case M16_OPC_LW:
9736 gen_ld(ctx, OPC_LW, ry, rx, offset);
9737 break;
9738 case M16_OPC_LBU:
9739 gen_ld(ctx, OPC_LBU, ry, rx, offset);
9740 break;
9741 case M16_OPC_LHU:
9742 gen_ld(ctx, OPC_LHU, ry, rx, offset);
9743 break;
9744 case M16_OPC_LWPC:
9745 gen_ld(ctx, OPC_LWPC, rx, 0, offset);
9746 break;
9747 #if defined(TARGET_MIPS64)
9748 case M16_OPC_LWU:
9749 gen_ld(ctx, OPC_LWU, ry, rx, offset);
9750 break;
9751 #endif
9752 case M16_OPC_SB:
9753 gen_st(ctx, OPC_SB, ry, rx, offset);
9754 break;
9755 case M16_OPC_SH:
9756 gen_st(ctx, OPC_SH, ry, rx, offset);
9757 break;
9758 case M16_OPC_SWSP:
9759 gen_st(ctx, OPC_SW, rx, 29, offset);
9760 break;
9761 case M16_OPC_SW:
9762 gen_st(ctx, OPC_SW, ry, rx, offset);
9763 break;
9764 #if defined(TARGET_MIPS64)
9765 case M16_OPC_I64:
9766 decode_i64_mips16(ctx, ry, funct, offset, 1);
9767 break;
9768 #endif
9769 default:
9770 generate_exception(ctx, EXCP_RI);
9771 break;
9774 return 4;
9777 static int decode_mips16_opc (CPUMIPSState *env, DisasContext *ctx)
9779 int rx, ry;
9780 int sa;
9781 int op, cnvt_op, op1, offset;
9782 int funct;
9783 int n_bytes;
9785 op = (ctx->opcode >> 11) & 0x1f;
9786 sa = (ctx->opcode >> 2) & 0x7;
9787 sa = sa == 0 ? 8 : sa;
9788 rx = xlat((ctx->opcode >> 8) & 0x7);
9789 cnvt_op = (ctx->opcode >> 5) & 0x7;
9790 ry = xlat((ctx->opcode >> 5) & 0x7);
9791 op1 = offset = ctx->opcode & 0x1f;
9793 n_bytes = 2;
9795 switch (op) {
9796 case M16_OPC_ADDIUSP:
9798 int16_t imm = ((uint8_t) ctx->opcode) << 2;
9800 gen_arith_imm(ctx, OPC_ADDIU, rx, 29, imm);
9802 break;
9803 case M16_OPC_ADDIUPC:
9804 gen_addiupc(ctx, rx, ((uint8_t) ctx->opcode) << 2, 0, 0);
9805 break;
9806 case M16_OPC_B:
9807 offset = (ctx->opcode & 0x7ff) << 1;
9808 offset = (int16_t)(offset << 4) >> 4;
9809 gen_compute_branch(ctx, OPC_BEQ, 2, 0, 0, offset);
9810 /* No delay slot, so just process as a normal instruction */
9811 break;
9812 case M16_OPC_JAL:
9813 offset = cpu_lduw_code(env, ctx->pc + 2);
9814 offset = (((ctx->opcode & 0x1f) << 21)
9815 | ((ctx->opcode >> 5) & 0x1f) << 16
9816 | offset) << 2;
9817 op = ((ctx->opcode >> 10) & 0x1) ? OPC_JALXS : OPC_JALS;
9818 gen_compute_branch(ctx, op, 4, rx, ry, offset);
9819 n_bytes = 4;
9820 break;
9821 case M16_OPC_BEQZ:
9822 gen_compute_branch(ctx, OPC_BEQ, 2, rx, 0, ((int8_t)ctx->opcode) << 1);
9823 /* No delay slot, so just process as a normal instruction */
9824 break;
9825 case M16_OPC_BNEQZ:
9826 gen_compute_branch(ctx, OPC_BNE, 2, rx, 0, ((int8_t)ctx->opcode) << 1);
9827 /* No delay slot, so just process as a normal instruction */
9828 break;
9829 case M16_OPC_SHIFT:
9830 switch (ctx->opcode & 0x3) {
9831 case 0x0:
9832 gen_shift_imm(ctx, OPC_SLL, rx, ry, sa);
9833 break;
9834 case 0x1:
9835 #if defined(TARGET_MIPS64)
9836 check_mips_64(ctx);
9837 gen_shift_imm(ctx, OPC_DSLL, rx, ry, sa);
9838 #else
9839 generate_exception(ctx, EXCP_RI);
9840 #endif
9841 break;
9842 case 0x2:
9843 gen_shift_imm(ctx, OPC_SRL, rx, ry, sa);
9844 break;
9845 case 0x3:
9846 gen_shift_imm(ctx, OPC_SRA, rx, ry, sa);
9847 break;
9849 break;
9850 #if defined(TARGET_MIPS64)
9851 case M16_OPC_LD:
9852 check_mips_64(ctx);
9853 gen_ld(ctx, OPC_LD, ry, rx, offset << 3);
9854 break;
9855 #endif
9856 case M16_OPC_RRIA:
9858 int16_t imm = (int8_t)((ctx->opcode & 0xf) << 4) >> 4;
9860 if ((ctx->opcode >> 4) & 1) {
9861 #if defined(TARGET_MIPS64)
9862 check_mips_64(ctx);
9863 gen_arith_imm(ctx, OPC_DADDIU, ry, rx, imm);
9864 #else
9865 generate_exception(ctx, EXCP_RI);
9866 #endif
9867 } else {
9868 gen_arith_imm(ctx, OPC_ADDIU, ry, rx, imm);
9871 break;
9872 case M16_OPC_ADDIU8:
9874 int16_t imm = (int8_t) ctx->opcode;
9876 gen_arith_imm(ctx, OPC_ADDIU, rx, rx, imm);
9878 break;
9879 case M16_OPC_SLTI:
9881 int16_t imm = (uint8_t) ctx->opcode;
9882 gen_slt_imm(ctx, OPC_SLTI, 24, rx, imm);
9884 break;
9885 case M16_OPC_SLTIU:
9887 int16_t imm = (uint8_t) ctx->opcode;
9888 gen_slt_imm(ctx, OPC_SLTIU, 24, rx, imm);
9890 break;
9891 case M16_OPC_I8:
9893 int reg32;
9895 funct = (ctx->opcode >> 8) & 0x7;
9896 switch (funct) {
9897 case I8_BTEQZ:
9898 gen_compute_branch(ctx, OPC_BEQ, 2, 24, 0,
9899 ((int8_t)ctx->opcode) << 1);
9900 break;
9901 case I8_BTNEZ:
9902 gen_compute_branch(ctx, OPC_BNE, 2, 24, 0,
9903 ((int8_t)ctx->opcode) << 1);
9904 break;
9905 case I8_SWRASP:
9906 gen_st(ctx, OPC_SW, 31, 29, (ctx->opcode & 0xff) << 2);
9907 break;
9908 case I8_ADJSP:
9909 gen_arith_imm(ctx, OPC_ADDIU, 29, 29,
9910 ((int8_t)ctx->opcode) << 3);
9911 break;
9912 case I8_SVRS:
9914 int do_ra = ctx->opcode & (1 << 6);
9915 int do_s0 = ctx->opcode & (1 << 5);
9916 int do_s1 = ctx->opcode & (1 << 4);
9917 int framesize = ctx->opcode & 0xf;
9919 if (framesize == 0) {
9920 framesize = 128;
9921 } else {
9922 framesize = framesize << 3;
9925 if (ctx->opcode & (1 << 7)) {
9926 gen_mips16_save(ctx, 0, 0,
9927 do_ra, do_s0, do_s1, framesize);
9928 } else {
9929 gen_mips16_restore(ctx, 0, 0,
9930 do_ra, do_s0, do_s1, framesize);
9933 break;
9934 case I8_MOV32R:
9936 int rz = xlat(ctx->opcode & 0x7);
9938 reg32 = (((ctx->opcode >> 3) & 0x3) << 3) |
9939 ((ctx->opcode >> 5) & 0x7);
9940 gen_arith(ctx, OPC_ADDU, reg32, rz, 0);
9942 break;
9943 case I8_MOVR32:
9944 reg32 = ctx->opcode & 0x1f;
9945 gen_arith(ctx, OPC_ADDU, ry, reg32, 0);
9946 break;
9947 default:
9948 generate_exception(ctx, EXCP_RI);
9949 break;
9952 break;
9953 case M16_OPC_LI:
9955 int16_t imm = (uint8_t) ctx->opcode;
9957 gen_arith_imm(ctx, OPC_ADDIU, rx, 0, imm);
9959 break;
9960 case M16_OPC_CMPI:
9962 int16_t imm = (uint8_t) ctx->opcode;
9963 gen_logic_imm(ctx, OPC_XORI, 24, rx, imm);
9965 break;
9966 #if defined(TARGET_MIPS64)
9967 case M16_OPC_SD:
9968 check_mips_64(ctx);
9969 gen_st(ctx, OPC_SD, ry, rx, offset << 3);
9970 break;
9971 #endif
9972 case M16_OPC_LB:
9973 gen_ld(ctx, OPC_LB, ry, rx, offset);
9974 break;
9975 case M16_OPC_LH:
9976 gen_ld(ctx, OPC_LH, ry, rx, offset << 1);
9977 break;
9978 case M16_OPC_LWSP:
9979 gen_ld(ctx, OPC_LW, rx, 29, ((uint8_t)ctx->opcode) << 2);
9980 break;
9981 case M16_OPC_LW:
9982 gen_ld(ctx, OPC_LW, ry, rx, offset << 2);
9983 break;
9984 case M16_OPC_LBU:
9985 gen_ld(ctx, OPC_LBU, ry, rx, offset);
9986 break;
9987 case M16_OPC_LHU:
9988 gen_ld(ctx, OPC_LHU, ry, rx, offset << 1);
9989 break;
9990 case M16_OPC_LWPC:
9991 gen_ld(ctx, OPC_LWPC, rx, 0, ((uint8_t)ctx->opcode) << 2);
9992 break;
9993 #if defined (TARGET_MIPS64)
9994 case M16_OPC_LWU:
9995 check_mips_64(ctx);
9996 gen_ld(ctx, OPC_LWU, ry, rx, offset << 2);
9997 break;
9998 #endif
9999 case M16_OPC_SB:
10000 gen_st(ctx, OPC_SB, ry, rx, offset);
10001 break;
10002 case M16_OPC_SH:
10003 gen_st(ctx, OPC_SH, ry, rx, offset << 1);
10004 break;
10005 case M16_OPC_SWSP:
10006 gen_st(ctx, OPC_SW, rx, 29, ((uint8_t)ctx->opcode) << 2);
10007 break;
10008 case M16_OPC_SW:
10009 gen_st(ctx, OPC_SW, ry, rx, offset << 2);
10010 break;
10011 case M16_OPC_RRR:
10013 int rz = xlat((ctx->opcode >> 2) & 0x7);
10014 int mips32_op;
10016 switch (ctx->opcode & 0x3) {
10017 case RRR_ADDU:
10018 mips32_op = OPC_ADDU;
10019 break;
10020 case RRR_SUBU:
10021 mips32_op = OPC_SUBU;
10022 break;
10023 #if defined(TARGET_MIPS64)
10024 case RRR_DADDU:
10025 mips32_op = OPC_DADDU;
10026 check_mips_64(ctx);
10027 break;
10028 case RRR_DSUBU:
10029 mips32_op = OPC_DSUBU;
10030 check_mips_64(ctx);
10031 break;
10032 #endif
10033 default:
10034 generate_exception(ctx, EXCP_RI);
10035 goto done;
10038 gen_arith(ctx, mips32_op, rz, rx, ry);
10039 done:
10042 break;
10043 case M16_OPC_RR:
10044 switch (op1) {
10045 case RR_JR:
10047 int nd = (ctx->opcode >> 7) & 0x1;
10048 int link = (ctx->opcode >> 6) & 0x1;
10049 int ra = (ctx->opcode >> 5) & 0x1;
10051 if (link) {
10052 op = nd ? OPC_JALRC : OPC_JALRS;
10053 } else {
10054 op = OPC_JR;
10057 gen_compute_branch(ctx, op, 2, ra ? 31 : rx, 31, 0);
10059 break;
10060 case RR_SDBBP:
10061 /* XXX: not clear which exception should be raised
10062 * when in debug mode...
10064 check_insn(ctx, ISA_MIPS32);
10065 if (!(ctx->hflags & MIPS_HFLAG_DM)) {
10066 generate_exception(ctx, EXCP_DBp);
10067 } else {
10068 generate_exception(ctx, EXCP_DBp);
10070 break;
10071 case RR_SLT:
10072 gen_slt(ctx, OPC_SLT, 24, rx, ry);
10073 break;
10074 case RR_SLTU:
10075 gen_slt(ctx, OPC_SLTU, 24, rx, ry);
10076 break;
10077 case RR_BREAK:
10078 generate_exception(ctx, EXCP_BREAK);
10079 break;
10080 case RR_SLLV:
10081 gen_shift(ctx, OPC_SLLV, ry, rx, ry);
10082 break;
10083 case RR_SRLV:
10084 gen_shift(ctx, OPC_SRLV, ry, rx, ry);
10085 break;
10086 case RR_SRAV:
10087 gen_shift(ctx, OPC_SRAV, ry, rx, ry);
10088 break;
10089 #if defined (TARGET_MIPS64)
10090 case RR_DSRL:
10091 check_mips_64(ctx);
10092 gen_shift_imm(ctx, OPC_DSRL, ry, ry, sa);
10093 break;
10094 #endif
10095 case RR_CMP:
10096 gen_logic(ctx, OPC_XOR, 24, rx, ry);
10097 break;
10098 case RR_NEG:
10099 gen_arith(ctx, OPC_SUBU, rx, 0, ry);
10100 break;
10101 case RR_AND:
10102 gen_logic(ctx, OPC_AND, rx, rx, ry);
10103 break;
10104 case RR_OR:
10105 gen_logic(ctx, OPC_OR, rx, rx, ry);
10106 break;
10107 case RR_XOR:
10108 gen_logic(ctx, OPC_XOR, rx, rx, ry);
10109 break;
10110 case RR_NOT:
10111 gen_logic(ctx, OPC_NOR, rx, ry, 0);
10112 break;
10113 case RR_MFHI:
10114 gen_HILO(ctx, OPC_MFHI, 0, rx);
10115 break;
10116 case RR_CNVT:
10117 switch (cnvt_op) {
10118 case RR_RY_CNVT_ZEB:
10119 tcg_gen_ext8u_tl(cpu_gpr[rx], cpu_gpr[rx]);
10120 break;
10121 case RR_RY_CNVT_ZEH:
10122 tcg_gen_ext16u_tl(cpu_gpr[rx], cpu_gpr[rx]);
10123 break;
10124 case RR_RY_CNVT_SEB:
10125 tcg_gen_ext8s_tl(cpu_gpr[rx], cpu_gpr[rx]);
10126 break;
10127 case RR_RY_CNVT_SEH:
10128 tcg_gen_ext16s_tl(cpu_gpr[rx], cpu_gpr[rx]);
10129 break;
10130 #if defined (TARGET_MIPS64)
10131 case RR_RY_CNVT_ZEW:
10132 check_mips_64(ctx);
10133 tcg_gen_ext32u_tl(cpu_gpr[rx], cpu_gpr[rx]);
10134 break;
10135 case RR_RY_CNVT_SEW:
10136 check_mips_64(ctx);
10137 tcg_gen_ext32s_tl(cpu_gpr[rx], cpu_gpr[rx]);
10138 break;
10139 #endif
10140 default:
10141 generate_exception(ctx, EXCP_RI);
10142 break;
10144 break;
10145 case RR_MFLO:
10146 gen_HILO(ctx, OPC_MFLO, 0, rx);
10147 break;
10148 #if defined (TARGET_MIPS64)
10149 case RR_DSRA:
10150 check_mips_64(ctx);
10151 gen_shift_imm(ctx, OPC_DSRA, ry, ry, sa);
10152 break;
10153 case RR_DSLLV:
10154 check_mips_64(ctx);
10155 gen_shift(ctx, OPC_DSLLV, ry, rx, ry);
10156 break;
10157 case RR_DSRLV:
10158 check_mips_64(ctx);
10159 gen_shift(ctx, OPC_DSRLV, ry, rx, ry);
10160 break;
10161 case RR_DSRAV:
10162 check_mips_64(ctx);
10163 gen_shift(ctx, OPC_DSRAV, ry, rx, ry);
10164 break;
10165 #endif
10166 case RR_MULT:
10167 gen_muldiv(ctx, OPC_MULT, 0, rx, ry);
10168 break;
10169 case RR_MULTU:
10170 gen_muldiv(ctx, OPC_MULTU, 0, rx, ry);
10171 break;
10172 case RR_DIV:
10173 gen_muldiv(ctx, OPC_DIV, 0, rx, ry);
10174 break;
10175 case RR_DIVU:
10176 gen_muldiv(ctx, OPC_DIVU, 0, rx, ry);
10177 break;
10178 #if defined (TARGET_MIPS64)
10179 case RR_DMULT:
10180 check_mips_64(ctx);
10181 gen_muldiv(ctx, OPC_DMULT, 0, rx, ry);
10182 break;
10183 case RR_DMULTU:
10184 check_mips_64(ctx);
10185 gen_muldiv(ctx, OPC_DMULTU, 0, rx, ry);
10186 break;
10187 case RR_DDIV:
10188 check_mips_64(ctx);
10189 gen_muldiv(ctx, OPC_DDIV, 0, rx, ry);
10190 break;
10191 case RR_DDIVU:
10192 check_mips_64(ctx);
10193 gen_muldiv(ctx, OPC_DDIVU, 0, rx, ry);
10194 break;
10195 #endif
10196 default:
10197 generate_exception(ctx, EXCP_RI);
10198 break;
10200 break;
10201 case M16_OPC_EXTEND:
10202 decode_extended_mips16_opc(env, ctx);
10203 n_bytes = 4;
10204 break;
10205 #if defined(TARGET_MIPS64)
10206 case M16_OPC_I64:
10207 funct = (ctx->opcode >> 8) & 0x7;
10208 decode_i64_mips16(ctx, ry, funct, offset, 0);
10209 break;
10210 #endif
10211 default:
10212 generate_exception(ctx, EXCP_RI);
10213 break;
10216 return n_bytes;
10219 /* microMIPS extension to MIPS32/MIPS64 */
10222 * microMIPS32/microMIPS64 major opcodes
10224 * 1. MIPS Architecture for Programmers Volume II-B:
10225 * The microMIPS32 Instruction Set (Revision 3.05)
10227 * Table 6.2 microMIPS32 Encoding of Major Opcode Field
10229 * 2. MIPS Architecture For Programmers Volume II-A:
10230 * The MIPS64 Instruction Set (Revision 3.51)
10233 enum {
10234 POOL32A = 0x00,
10235 POOL16A = 0x01,
10236 LBU16 = 0x02,
10237 MOVE16 = 0x03,
10238 ADDI32 = 0x04,
10239 LBU32 = 0x05,
10240 SB32 = 0x06,
10241 LB32 = 0x07,
10243 POOL32B = 0x08,
10244 POOL16B = 0x09,
10245 LHU16 = 0x0a,
10246 ANDI16 = 0x0b,
10247 ADDIU32 = 0x0c,
10248 LHU32 = 0x0d,
10249 SH32 = 0x0e,
10250 LH32 = 0x0f,
10252 POOL32I = 0x10,
10253 POOL16C = 0x11,
10254 LWSP16 = 0x12,
10255 POOL16D = 0x13,
10256 ORI32 = 0x14,
10257 POOL32F = 0x15,
10258 POOL32S = 0x16, /* MIPS64 */
10259 DADDIU32 = 0x17, /* MIPS64 */
10261 /* 0x1f is reserved */
10262 POOL32C = 0x18,
10263 LWGP16 = 0x19,
10264 LW16 = 0x1a,
10265 POOL16E = 0x1b,
10266 XORI32 = 0x1c,
10267 JALS32 = 0x1d,
10268 ADDIUPC = 0x1e,
10270 /* 0x20 is reserved */
10271 RES_20 = 0x20,
10272 POOL16F = 0x21,
10273 SB16 = 0x22,
10274 BEQZ16 = 0x23,
10275 SLTI32 = 0x24,
10276 BEQ32 = 0x25,
10277 SWC132 = 0x26,
10278 LWC132 = 0x27,
10280 /* 0x28 and 0x29 are reserved */
10281 RES_28 = 0x28,
10282 RES_29 = 0x29,
10283 SH16 = 0x2a,
10284 BNEZ16 = 0x2b,
10285 SLTIU32 = 0x2c,
10286 BNE32 = 0x2d,
10287 SDC132 = 0x2e,
10288 LDC132 = 0x2f,
10290 /* 0x30 and 0x31 are reserved */
10291 RES_30 = 0x30,
10292 RES_31 = 0x31,
10293 SWSP16 = 0x32,
10294 B16 = 0x33,
10295 ANDI32 = 0x34,
10296 J32 = 0x35,
10297 SD32 = 0x36, /* MIPS64 */
10298 LD32 = 0x37, /* MIPS64 */
10300 /* 0x38 and 0x39 are reserved */
10301 RES_38 = 0x38,
10302 RES_39 = 0x39,
10303 SW16 = 0x3a,
10304 LI16 = 0x3b,
10305 JALX32 = 0x3c,
10306 JAL32 = 0x3d,
10307 SW32 = 0x3e,
10308 LW32 = 0x3f
10311 /* POOL32A encoding of minor opcode field */
10313 enum {
10314 /* These opcodes are distinguished only by bits 9..6; those bits are
10315 * what are recorded below. */
10316 SLL32 = 0x0,
10317 SRL32 = 0x1,
10318 SRA = 0x2,
10319 ROTR = 0x3,
10321 SLLV = 0x0,
10322 SRLV = 0x1,
10323 SRAV = 0x2,
10324 ROTRV = 0x3,
10325 ADD = 0x4,
10326 ADDU32 = 0x5,
10327 SUB = 0x6,
10328 SUBU32 = 0x7,
10329 MUL = 0x8,
10330 AND = 0x9,
10331 OR32 = 0xa,
10332 NOR = 0xb,
10333 XOR32 = 0xc,
10334 SLT = 0xd,
10335 SLTU = 0xe,
10337 MOVN = 0x0,
10338 MOVZ = 0x1,
10339 LWXS = 0x4,
10341 /* The following can be distinguished by their lower 6 bits. */
10342 INS = 0x0c,
10343 EXT = 0x2c,
10344 POOL32AXF = 0x3c
10347 /* POOL32AXF encoding of minor opcode field extension */
10350 * 1. MIPS Architecture for Programmers Volume II-B:
10351 * The microMIPS32 Instruction Set (Revision 3.05)
10353 * Table 6.5 POOL32Axf Encoding of Minor Opcode Extension Field
10355 * 2. MIPS Architecture for Programmers VolumeIV-e:
10356 * The MIPS DSP Application-Specific Extension
10357 * to the microMIPS32 Architecture (Revision 2.34)
10359 * Table 5.5 POOL32Axf Encoding of Minor Opcode Extension Field
10362 enum {
10363 /* bits 11..6 */
10364 TEQ = 0x00,
10365 TGE = 0x08,
10366 TGEU = 0x10,
10367 TLT = 0x20,
10368 TLTU = 0x28,
10369 TNE = 0x30,
10371 MFC0 = 0x03,
10372 MTC0 = 0x0b,
10374 /* begin of microMIPS32 DSP */
10376 /* bits 13..12 for 0x01 */
10377 MFHI_ACC = 0x0,
10378 MFLO_ACC = 0x1,
10379 MTHI_ACC = 0x2,
10380 MTLO_ACC = 0x3,
10382 /* bits 13..12 for 0x2a */
10383 MADD_ACC = 0x0,
10384 MADDU_ACC = 0x1,
10385 MSUB_ACC = 0x2,
10386 MSUBU_ACC = 0x3,
10388 /* bits 13..12 for 0x32 */
10389 MULT_ACC = 0x0,
10390 MULTU_ACC = 0x1,
10392 /* end of microMIPS32 DSP */
10394 /* bits 15..12 for 0x2c */
10395 SEB = 0x2,
10396 SEH = 0x3,
10397 CLO = 0x4,
10398 CLZ = 0x5,
10399 RDHWR = 0x6,
10400 WSBH = 0x7,
10401 MULT = 0x8,
10402 MULTU = 0x9,
10403 DIV = 0xa,
10404 DIVU = 0xb,
10405 MADD = 0xc,
10406 MADDU = 0xd,
10407 MSUB = 0xe,
10408 MSUBU = 0xf,
10410 /* bits 15..12 for 0x34 */
10411 MFC2 = 0x4,
10412 MTC2 = 0x5,
10413 MFHC2 = 0x8,
10414 MTHC2 = 0x9,
10415 CFC2 = 0xc,
10416 CTC2 = 0xd,
10418 /* bits 15..12 for 0x3c */
10419 JALR = 0x0,
10420 JR = 0x0, /* alias */
10421 JALR_HB = 0x1,
10422 JALRS = 0x4,
10423 JALRS_HB = 0x5,
10425 /* bits 15..12 for 0x05 */
10426 RDPGPR = 0xe,
10427 WRPGPR = 0xf,
10429 /* bits 15..12 for 0x0d */
10430 TLBP = 0x0,
10431 TLBR = 0x1,
10432 TLBWI = 0x2,
10433 TLBWR = 0x3,
10434 WAIT = 0x9,
10435 IRET = 0xd,
10436 DERET = 0xe,
10437 ERET = 0xf,
10439 /* bits 15..12 for 0x15 */
10440 DMT = 0x0,
10441 DVPE = 0x1,
10442 EMT = 0x2,
10443 EVPE = 0x3,
10445 /* bits 15..12 for 0x1d */
10446 DI = 0x4,
10447 EI = 0x5,
10449 /* bits 15..12 for 0x2d */
10450 SYNC = 0x6,
10451 SYSCALL = 0x8,
10452 SDBBP = 0xd,
10454 /* bits 15..12 for 0x35 */
10455 MFHI32 = 0x0,
10456 MFLO32 = 0x1,
10457 MTHI32 = 0x2,
10458 MTLO32 = 0x3,
10461 /* POOL32B encoding of minor opcode field (bits 15..12) */
10463 enum {
10464 LWC2 = 0x0,
10465 LWP = 0x1,
10466 LDP = 0x4,
10467 LWM32 = 0x5,
10468 CACHE = 0x6,
10469 LDM = 0x7,
10470 SWC2 = 0x8,
10471 SWP = 0x9,
10472 SDP = 0xc,
10473 SWM32 = 0xd,
10474 SDM = 0xf
10477 /* POOL32C encoding of minor opcode field (bits 15..12) */
10479 enum {
10480 LWL = 0x0,
10481 SWL = 0x8,
10482 LWR = 0x1,
10483 SWR = 0x9,
10484 PREF = 0x2,
10485 /* 0xa is reserved */
10486 LL = 0x3,
10487 SC = 0xb,
10488 LDL = 0x4,
10489 SDL = 0xc,
10490 LDR = 0x5,
10491 SDR = 0xd,
10492 /* 0x6 is reserved */
10493 LWU = 0xe,
10494 LLD = 0x7,
10495 SCD = 0xf
10498 /* POOL32F encoding of minor opcode field (bits 5..0) */
10500 enum {
10501 /* These are the bit 7..6 values */
10502 ADD_FMT = 0x0,
10503 MOVN_FMT = 0x0,
10505 SUB_FMT = 0x1,
10506 MOVZ_FMT = 0x1,
10508 MUL_FMT = 0x2,
10510 DIV_FMT = 0x3,
10512 /* These are the bit 8..6 values */
10513 RSQRT2_FMT = 0x0,
10514 MOVF_FMT = 0x0,
10516 LWXC1 = 0x1,
10517 MOVT_FMT = 0x1,
10519 PLL_PS = 0x2,
10520 SWXC1 = 0x2,
10522 PLU_PS = 0x3,
10523 LDXC1 = 0x3,
10525 PUL_PS = 0x4,
10526 SDXC1 = 0x4,
10527 RECIP2_FMT = 0x4,
10529 PUU_PS = 0x5,
10530 LUXC1 = 0x5,
10532 CVT_PS_S = 0x6,
10533 SUXC1 = 0x6,
10534 ADDR_PS = 0x6,
10535 PREFX = 0x6,
10537 MULR_PS = 0x7,
10539 MADD_S = 0x01,
10540 MADD_D = 0x09,
10541 MADD_PS = 0x11,
10542 ALNV_PS = 0x19,
10543 MSUB_S = 0x21,
10544 MSUB_D = 0x29,
10545 MSUB_PS = 0x31,
10547 NMADD_S = 0x02,
10548 NMADD_D = 0x0a,
10549 NMADD_PS = 0x12,
10550 NMSUB_S = 0x22,
10551 NMSUB_D = 0x2a,
10552 NMSUB_PS = 0x32,
10554 POOL32FXF = 0x3b,
10556 CABS_COND_FMT = 0x1c, /* MIPS3D */
10557 C_COND_FMT = 0x3c
10560 /* POOL32Fxf encoding of minor opcode extension field */
10562 enum {
10563 CVT_L = 0x04,
10564 RSQRT_FMT = 0x08,
10565 FLOOR_L = 0x0c,
10566 CVT_PW_PS = 0x1c,
10567 CVT_W = 0x24,
10568 SQRT_FMT = 0x28,
10569 FLOOR_W = 0x2c,
10570 CVT_PS_PW = 0x3c,
10571 CFC1 = 0x40,
10572 RECIP_FMT = 0x48,
10573 CEIL_L = 0x4c,
10574 CTC1 = 0x60,
10575 CEIL_W = 0x6c,
10576 MFC1 = 0x80,
10577 CVT_S_PL = 0x84,
10578 TRUNC_L = 0x8c,
10579 MTC1 = 0xa0,
10580 CVT_S_PU = 0xa4,
10581 TRUNC_W = 0xac,
10582 MFHC1 = 0xc0,
10583 ROUND_L = 0xcc,
10584 MTHC1 = 0xe0,
10585 ROUND_W = 0xec,
10587 MOV_FMT = 0x01,
10588 MOVF = 0x05,
10589 ABS_FMT = 0x0d,
10590 RSQRT1_FMT = 0x1d,
10591 MOVT = 0x25,
10592 NEG_FMT = 0x2d,
10593 CVT_D = 0x4d,
10594 RECIP1_FMT = 0x5d,
10595 CVT_S = 0x6d
10598 /* POOL32I encoding of minor opcode field (bits 25..21) */
10600 enum {
10601 BLTZ = 0x00,
10602 BLTZAL = 0x01,
10603 BGEZ = 0x02,
10604 BGEZAL = 0x03,
10605 BLEZ = 0x04,
10606 BNEZC = 0x05,
10607 BGTZ = 0x06,
10608 BEQZC = 0x07,
10609 TLTI = 0x08,
10610 TGEI = 0x09,
10611 TLTIU = 0x0a,
10612 TGEIU = 0x0b,
10613 TNEI = 0x0c,
10614 LUI = 0x0d,
10615 TEQI = 0x0e,
10616 SYNCI = 0x10,
10617 BLTZALS = 0x11,
10618 BGEZALS = 0x13,
10619 BC2F = 0x14,
10620 BC2T = 0x15,
10621 BPOSGE64 = 0x1a,
10622 BPOSGE32 = 0x1b,
10623 /* These overlap and are distinguished by bit16 of the instruction */
10624 BC1F = 0x1c,
10625 BC1T = 0x1d,
10626 BC1ANY2F = 0x1c,
10627 BC1ANY2T = 0x1d,
10628 BC1ANY4F = 0x1e,
10629 BC1ANY4T = 0x1f
10632 /* POOL16A encoding of minor opcode field */
10634 enum {
10635 ADDU16 = 0x0,
10636 SUBU16 = 0x1
10639 /* POOL16B encoding of minor opcode field */
10641 enum {
10642 SLL16 = 0x0,
10643 SRL16 = 0x1
10646 /* POOL16C encoding of minor opcode field */
10648 enum {
10649 NOT16 = 0x00,
10650 XOR16 = 0x04,
10651 AND16 = 0x08,
10652 OR16 = 0x0c,
10653 LWM16 = 0x10,
10654 SWM16 = 0x14,
10655 JR16 = 0x18,
10656 JRC16 = 0x1a,
10657 JALR16 = 0x1c,
10658 JALR16S = 0x1e,
10659 MFHI16 = 0x20,
10660 MFLO16 = 0x24,
10661 BREAK16 = 0x28,
10662 SDBBP16 = 0x2c,
10663 JRADDIUSP = 0x30
10666 /* POOL16D encoding of minor opcode field */
10668 enum {
10669 ADDIUS5 = 0x0,
10670 ADDIUSP = 0x1
10673 /* POOL16E encoding of minor opcode field */
10675 enum {
10676 ADDIUR2 = 0x0,
10677 ADDIUR1SP = 0x1
10680 static int mmreg (int r)
10682 static const int map[] = { 16, 17, 2, 3, 4, 5, 6, 7 };
10684 return map[r];
10687 /* Used for 16-bit store instructions. */
10688 static int mmreg2 (int r)
10690 static const int map[] = { 0, 17, 2, 3, 4, 5, 6, 7 };
10692 return map[r];
10695 #define uMIPS_RD(op) ((op >> 7) & 0x7)
10696 #define uMIPS_RS(op) ((op >> 4) & 0x7)
10697 #define uMIPS_RS2(op) uMIPS_RS(op)
10698 #define uMIPS_RS1(op) ((op >> 1) & 0x7)
10699 #define uMIPS_RD5(op) ((op >> 5) & 0x1f)
10700 #define uMIPS_RS5(op) (op & 0x1f)
10702 /* Signed immediate */
10703 #define SIMM(op, start, width) \
10704 ((int32_t)(((op >> start) & ((~0U) >> (32-width))) \
10705 << (32-width)) \
10706 >> (32-width))
10707 /* Zero-extended immediate */
10708 #define ZIMM(op, start, width) ((op >> start) & ((~0U) >> (32-width)))
10710 static void gen_addiur1sp(DisasContext *ctx)
10712 int rd = mmreg(uMIPS_RD(ctx->opcode));
10714 gen_arith_imm(ctx, OPC_ADDIU, rd, 29, ((ctx->opcode >> 1) & 0x3f) << 2);
10717 static void gen_addiur2(DisasContext *ctx)
10719 static const int decoded_imm[] = { 1, 4, 8, 12, 16, 20, 24, -1 };
10720 int rd = mmreg(uMIPS_RD(ctx->opcode));
10721 int rs = mmreg(uMIPS_RS(ctx->opcode));
10723 gen_arith_imm(ctx, OPC_ADDIU, rd, rs, decoded_imm[ZIMM(ctx->opcode, 1, 3)]);
10726 static void gen_addiusp(DisasContext *ctx)
10728 int encoded = ZIMM(ctx->opcode, 1, 9);
10729 int decoded;
10731 if (encoded <= 1) {
10732 decoded = 256 + encoded;
10733 } else if (encoded <= 255) {
10734 decoded = encoded;
10735 } else if (encoded <= 509) {
10736 decoded = encoded - 512;
10737 } else {
10738 decoded = encoded - 768;
10741 gen_arith_imm(ctx, OPC_ADDIU, 29, 29, decoded << 2);
10744 static void gen_addius5(DisasContext *ctx)
10746 int imm = SIMM(ctx->opcode, 1, 4);
10747 int rd = (ctx->opcode >> 5) & 0x1f;
10749 gen_arith_imm(ctx, OPC_ADDIU, rd, rd, imm);
10752 static void gen_andi16(DisasContext *ctx)
10754 static const int decoded_imm[] = { 128, 1, 2, 3, 4, 7, 8, 15, 16,
10755 31, 32, 63, 64, 255, 32768, 65535 };
10756 int rd = mmreg(uMIPS_RD(ctx->opcode));
10757 int rs = mmreg(uMIPS_RS(ctx->opcode));
10758 int encoded = ZIMM(ctx->opcode, 0, 4);
10760 gen_logic_imm(ctx, OPC_ANDI, rd, rs, decoded_imm[encoded]);
10763 static void gen_ldst_multiple (DisasContext *ctx, uint32_t opc, int reglist,
10764 int base, int16_t offset)
10766 const char *opn = "ldst_multiple";
10767 TCGv t0, t1;
10768 TCGv_i32 t2;
10770 if (ctx->hflags & MIPS_HFLAG_BMASK) {
10771 generate_exception(ctx, EXCP_RI);
10772 return;
10775 t0 = tcg_temp_new();
10777 gen_base_offset_addr(ctx, t0, base, offset);
10779 t1 = tcg_const_tl(reglist);
10780 t2 = tcg_const_i32(ctx->mem_idx);
10782 save_cpu_state(ctx, 1);
10783 switch (opc) {
10784 case LWM32:
10785 gen_helper_lwm(cpu_env, t0, t1, t2);
10786 opn = "lwm";
10787 break;
10788 case SWM32:
10789 gen_helper_swm(cpu_env, t0, t1, t2);
10790 opn = "swm";
10791 break;
10792 #ifdef TARGET_MIPS64
10793 case LDM:
10794 gen_helper_ldm(cpu_env, t0, t1, t2);
10795 opn = "ldm";
10796 break;
10797 case SDM:
10798 gen_helper_sdm(cpu_env, t0, t1, t2);
10799 opn = "sdm";
10800 break;
10801 #endif
10803 (void)opn;
10804 MIPS_DEBUG("%s, %x, %d(%s)", opn, reglist, offset, regnames[base]);
10805 tcg_temp_free(t0);
10806 tcg_temp_free(t1);
10807 tcg_temp_free_i32(t2);
10811 static void gen_pool16c_insn(DisasContext *ctx)
10813 int rd = mmreg((ctx->opcode >> 3) & 0x7);
10814 int rs = mmreg(ctx->opcode & 0x7);
10815 int opc;
10817 switch (((ctx->opcode) >> 4) & 0x3f) {
10818 case NOT16 + 0:
10819 case NOT16 + 1:
10820 case NOT16 + 2:
10821 case NOT16 + 3:
10822 gen_logic(ctx, OPC_NOR, rd, rs, 0);
10823 break;
10824 case XOR16 + 0:
10825 case XOR16 + 1:
10826 case XOR16 + 2:
10827 case XOR16 + 3:
10828 gen_logic(ctx, OPC_XOR, rd, rd, rs);
10829 break;
10830 case AND16 + 0:
10831 case AND16 + 1:
10832 case AND16 + 2:
10833 case AND16 + 3:
10834 gen_logic(ctx, OPC_AND, rd, rd, rs);
10835 break;
10836 case OR16 + 0:
10837 case OR16 + 1:
10838 case OR16 + 2:
10839 case OR16 + 3:
10840 gen_logic(ctx, OPC_OR, rd, rd, rs);
10841 break;
10842 case LWM16 + 0:
10843 case LWM16 + 1:
10844 case LWM16 + 2:
10845 case LWM16 + 3:
10847 static const int lwm_convert[] = { 0x11, 0x12, 0x13, 0x14 };
10848 int offset = ZIMM(ctx->opcode, 0, 4);
10850 gen_ldst_multiple(ctx, LWM32, lwm_convert[(ctx->opcode >> 4) & 0x3],
10851 29, offset << 2);
10853 break;
10854 case SWM16 + 0:
10855 case SWM16 + 1:
10856 case SWM16 + 2:
10857 case SWM16 + 3:
10859 static const int swm_convert[] = { 0x11, 0x12, 0x13, 0x14 };
10860 int offset = ZIMM(ctx->opcode, 0, 4);
10862 gen_ldst_multiple(ctx, SWM32, swm_convert[(ctx->opcode >> 4) & 0x3],
10863 29, offset << 2);
10865 break;
10866 case JR16 + 0:
10867 case JR16 + 1:
10869 int reg = ctx->opcode & 0x1f;
10871 gen_compute_branch(ctx, OPC_JR, 2, reg, 0, 0);
10873 break;
10874 case JRC16 + 0:
10875 case JRC16 + 1:
10877 int reg = ctx->opcode & 0x1f;
10879 gen_compute_branch(ctx, OPC_JR, 2, reg, 0, 0);
10880 /* Let normal delay slot handling in our caller take us
10881 to the branch target. */
10883 break;
10884 case JALR16 + 0:
10885 case JALR16 + 1:
10886 opc = OPC_JALR;
10887 goto do_jalr;
10888 case JALR16S + 0:
10889 case JALR16S + 1:
10890 opc = OPC_JALRS;
10891 do_jalr:
10893 int reg = ctx->opcode & 0x1f;
10895 gen_compute_branch(ctx, opc, 2, reg, 31, 0);
10897 break;
10898 case MFHI16 + 0:
10899 case MFHI16 + 1:
10900 gen_HILO(ctx, OPC_MFHI, 0, uMIPS_RS5(ctx->opcode));
10901 break;
10902 case MFLO16 + 0:
10903 case MFLO16 + 1:
10904 gen_HILO(ctx, OPC_MFLO, 0, uMIPS_RS5(ctx->opcode));
10905 break;
10906 case BREAK16:
10907 generate_exception(ctx, EXCP_BREAK);
10908 break;
10909 case SDBBP16:
10910 /* XXX: not clear which exception should be raised
10911 * when in debug mode...
10913 check_insn(ctx, ISA_MIPS32);
10914 if (!(ctx->hflags & MIPS_HFLAG_DM)) {
10915 generate_exception(ctx, EXCP_DBp);
10916 } else {
10917 generate_exception(ctx, EXCP_DBp);
10919 break;
10920 case JRADDIUSP + 0:
10921 case JRADDIUSP + 1:
10923 int imm = ZIMM(ctx->opcode, 0, 5);
10925 gen_compute_branch(ctx, OPC_JR, 2, 31, 0, 0);
10926 gen_arith_imm(ctx, OPC_ADDIU, 29, 29, imm << 2);
10927 /* Let normal delay slot handling in our caller take us
10928 to the branch target. */
10930 break;
10931 default:
10932 generate_exception(ctx, EXCP_RI);
10933 break;
10937 static void gen_ldxs (DisasContext *ctx, int base, int index, int rd)
10939 TCGv t0 = tcg_temp_new();
10940 TCGv t1 = tcg_temp_new();
10942 gen_load_gpr(t0, base);
10944 if (index != 0) {
10945 gen_load_gpr(t1, index);
10946 tcg_gen_shli_tl(t1, t1, 2);
10947 gen_op_addr_add(ctx, t0, t1, t0);
10950 tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_TESL);
10951 gen_store_gpr(t1, rd);
10953 tcg_temp_free(t0);
10954 tcg_temp_free(t1);
10957 static void gen_ldst_pair (DisasContext *ctx, uint32_t opc, int rd,
10958 int base, int16_t offset)
10960 const char *opn = "ldst_pair";
10961 TCGv t0, t1;
10963 if (ctx->hflags & MIPS_HFLAG_BMASK || rd == 31) {
10964 generate_exception(ctx, EXCP_RI);
10965 return;
10968 t0 = tcg_temp_new();
10969 t1 = tcg_temp_new();
10971 gen_base_offset_addr(ctx, t0, base, offset);
10973 switch (opc) {
10974 case LWP:
10975 if (rd == base) {
10976 generate_exception(ctx, EXCP_RI);
10977 return;
10979 tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_TESL);
10980 gen_store_gpr(t1, rd);
10981 tcg_gen_movi_tl(t1, 4);
10982 gen_op_addr_add(ctx, t0, t0, t1);
10983 tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_TESL);
10984 gen_store_gpr(t1, rd+1);
10985 opn = "lwp";
10986 break;
10987 case SWP:
10988 gen_load_gpr(t1, rd);
10989 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL);
10990 tcg_gen_movi_tl(t1, 4);
10991 gen_op_addr_add(ctx, t0, t0, t1);
10992 gen_load_gpr(t1, rd+1);
10993 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL);
10994 opn = "swp";
10995 break;
10996 #ifdef TARGET_MIPS64
10997 case LDP:
10998 if (rd == base) {
10999 generate_exception(ctx, EXCP_RI);
11000 return;
11002 tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_TEQ);
11003 gen_store_gpr(t1, rd);
11004 tcg_gen_movi_tl(t1, 8);
11005 gen_op_addr_add(ctx, t0, t0, t1);
11006 tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_TEQ);
11007 gen_store_gpr(t1, rd+1);
11008 opn = "ldp";
11009 break;
11010 case SDP:
11011 gen_load_gpr(t1, rd);
11012 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEQ);
11013 tcg_gen_movi_tl(t1, 8);
11014 gen_op_addr_add(ctx, t0, t0, t1);
11015 gen_load_gpr(t1, rd+1);
11016 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEQ);
11017 opn = "sdp";
11018 break;
11019 #endif
11021 (void)opn; /* avoid a compiler warning */
11022 MIPS_DEBUG("%s, %s, %d(%s)", opn, regnames[rd], offset, regnames[base]);
11023 tcg_temp_free(t0);
11024 tcg_temp_free(t1);
11027 static void gen_pool32axf (CPUMIPSState *env, DisasContext *ctx, int rt, int rs)
11029 int extension = (ctx->opcode >> 6) & 0x3f;
11030 int minor = (ctx->opcode >> 12) & 0xf;
11031 uint32_t mips32_op;
11033 switch (extension) {
11034 case TEQ:
11035 mips32_op = OPC_TEQ;
11036 goto do_trap;
11037 case TGE:
11038 mips32_op = OPC_TGE;
11039 goto do_trap;
11040 case TGEU:
11041 mips32_op = OPC_TGEU;
11042 goto do_trap;
11043 case TLT:
11044 mips32_op = OPC_TLT;
11045 goto do_trap;
11046 case TLTU:
11047 mips32_op = OPC_TLTU;
11048 goto do_trap;
11049 case TNE:
11050 mips32_op = OPC_TNE;
11051 do_trap:
11052 gen_trap(ctx, mips32_op, rs, rt, -1);
11053 break;
11054 #ifndef CONFIG_USER_ONLY
11055 case MFC0:
11056 case MFC0 + 32:
11057 check_cp0_enabled(ctx);
11058 if (rt == 0) {
11059 /* Treat as NOP. */
11060 break;
11062 gen_mfc0(ctx, cpu_gpr[rt], rs, (ctx->opcode >> 11) & 0x7);
11063 break;
11064 case MTC0:
11065 case MTC0 + 32:
11066 check_cp0_enabled(ctx);
11068 TCGv t0 = tcg_temp_new();
11070 gen_load_gpr(t0, rt);
11071 gen_mtc0(ctx, t0, rs, (ctx->opcode >> 11) & 0x7);
11072 tcg_temp_free(t0);
11074 break;
11075 #endif
11076 case 0x2a:
11077 switch (minor & 3) {
11078 case MADD_ACC:
11079 gen_muldiv(ctx, OPC_MADD, (ctx->opcode >> 14) & 3, rs, rt);
11080 break;
11081 case MADDU_ACC:
11082 gen_muldiv(ctx, OPC_MADDU, (ctx->opcode >> 14) & 3, rs, rt);
11083 break;
11084 case MSUB_ACC:
11085 gen_muldiv(ctx, OPC_MSUB, (ctx->opcode >> 14) & 3, rs, rt);
11086 break;
11087 case MSUBU_ACC:
11088 gen_muldiv(ctx, OPC_MSUBU, (ctx->opcode >> 14) & 3, rs, rt);
11089 break;
11090 default:
11091 goto pool32axf_invalid;
11093 break;
11094 case 0x32:
11095 switch (minor & 3) {
11096 case MULT_ACC:
11097 gen_muldiv(ctx, OPC_MULT, (ctx->opcode >> 14) & 3, rs, rt);
11098 break;
11099 case MULTU_ACC:
11100 gen_muldiv(ctx, OPC_MULTU, (ctx->opcode >> 14) & 3, rs, rt);
11101 break;
11102 default:
11103 goto pool32axf_invalid;
11105 break;
11106 case 0x2c:
11107 switch (minor) {
11108 case SEB:
11109 gen_bshfl(ctx, OPC_SEB, rs, rt);
11110 break;
11111 case SEH:
11112 gen_bshfl(ctx, OPC_SEH, rs, rt);
11113 break;
11114 case CLO:
11115 mips32_op = OPC_CLO;
11116 goto do_cl;
11117 case CLZ:
11118 mips32_op = OPC_CLZ;
11119 do_cl:
11120 check_insn(ctx, ISA_MIPS32);
11121 gen_cl(ctx, mips32_op, rt, rs);
11122 break;
11123 case RDHWR:
11124 gen_rdhwr(ctx, rt, rs);
11125 break;
11126 case WSBH:
11127 gen_bshfl(ctx, OPC_WSBH, rs, rt);
11128 break;
11129 case MULT:
11130 mips32_op = OPC_MULT;
11131 goto do_mul;
11132 case MULTU:
11133 mips32_op = OPC_MULTU;
11134 goto do_mul;
11135 case DIV:
11136 mips32_op = OPC_DIV;
11137 goto do_div;
11138 case DIVU:
11139 mips32_op = OPC_DIVU;
11140 goto do_div;
11141 do_div:
11142 check_insn(ctx, ISA_MIPS32);
11143 gen_muldiv(ctx, mips32_op, 0, rs, rt);
11144 break;
11145 case MADD:
11146 mips32_op = OPC_MADD;
11147 goto do_mul;
11148 case MADDU:
11149 mips32_op = OPC_MADDU;
11150 goto do_mul;
11151 case MSUB:
11152 mips32_op = OPC_MSUB;
11153 goto do_mul;
11154 case MSUBU:
11155 mips32_op = OPC_MSUBU;
11156 do_mul:
11157 check_insn(ctx, ISA_MIPS32);
11158 gen_muldiv(ctx, mips32_op, 0, rs, rt);
11159 break;
11160 default:
11161 goto pool32axf_invalid;
11163 break;
11164 case 0x34:
11165 switch (minor) {
11166 case MFC2:
11167 case MTC2:
11168 case MFHC2:
11169 case MTHC2:
11170 case CFC2:
11171 case CTC2:
11172 generate_exception_err(ctx, EXCP_CpU, 2);
11173 break;
11174 default:
11175 goto pool32axf_invalid;
11177 break;
11178 case 0x3c:
11179 switch (minor) {
11180 case JALR:
11181 case JALR_HB:
11182 gen_compute_branch (ctx, OPC_JALR, 4, rs, rt, 0);
11183 break;
11184 case JALRS:
11185 case JALRS_HB:
11186 gen_compute_branch (ctx, OPC_JALRS, 4, rs, rt, 0);
11187 break;
11188 default:
11189 goto pool32axf_invalid;
11191 break;
11192 case 0x05:
11193 switch (minor) {
11194 case RDPGPR:
11195 check_cp0_enabled(ctx);
11196 check_insn(ctx, ISA_MIPS32R2);
11197 gen_load_srsgpr(rt, rs);
11198 break;
11199 case WRPGPR:
11200 check_cp0_enabled(ctx);
11201 check_insn(ctx, ISA_MIPS32R2);
11202 gen_store_srsgpr(rt, rs);
11203 break;
11204 default:
11205 goto pool32axf_invalid;
11207 break;
11208 #ifndef CONFIG_USER_ONLY
11209 case 0x0d:
11210 switch (minor) {
11211 case TLBP:
11212 mips32_op = OPC_TLBP;
11213 goto do_cp0;
11214 case TLBR:
11215 mips32_op = OPC_TLBR;
11216 goto do_cp0;
11217 case TLBWI:
11218 mips32_op = OPC_TLBWI;
11219 goto do_cp0;
11220 case TLBWR:
11221 mips32_op = OPC_TLBWR;
11222 goto do_cp0;
11223 case WAIT:
11224 mips32_op = OPC_WAIT;
11225 goto do_cp0;
11226 case DERET:
11227 mips32_op = OPC_DERET;
11228 goto do_cp0;
11229 case ERET:
11230 mips32_op = OPC_ERET;
11231 do_cp0:
11232 gen_cp0(env, ctx, mips32_op, rt, rs);
11233 break;
11234 default:
11235 goto pool32axf_invalid;
11237 break;
11238 case 0x1d:
11239 switch (minor) {
11240 case DI:
11241 check_cp0_enabled(ctx);
11243 TCGv t0 = tcg_temp_new();
11245 save_cpu_state(ctx, 1);
11246 gen_helper_di(t0, cpu_env);
11247 gen_store_gpr(t0, rs);
11248 /* Stop translation as we may have switched the execution mode */
11249 ctx->bstate = BS_STOP;
11250 tcg_temp_free(t0);
11252 break;
11253 case EI:
11254 check_cp0_enabled(ctx);
11256 TCGv t0 = tcg_temp_new();
11258 save_cpu_state(ctx, 1);
11259 gen_helper_ei(t0, cpu_env);
11260 gen_store_gpr(t0, rs);
11261 /* Stop translation as we may have switched the execution mode */
11262 ctx->bstate = BS_STOP;
11263 tcg_temp_free(t0);
11265 break;
11266 default:
11267 goto pool32axf_invalid;
11269 break;
11270 #endif
11271 case 0x2d:
11272 switch (minor) {
11273 case SYNC:
11274 /* NOP */
11275 break;
11276 case SYSCALL:
11277 generate_exception(ctx, EXCP_SYSCALL);
11278 ctx->bstate = BS_STOP;
11279 break;
11280 case SDBBP:
11281 check_insn(ctx, ISA_MIPS32);
11282 if (!(ctx->hflags & MIPS_HFLAG_DM)) {
11283 generate_exception(ctx, EXCP_DBp);
11284 } else {
11285 generate_exception(ctx, EXCP_DBp);
11287 break;
11288 default:
11289 goto pool32axf_invalid;
11291 break;
11292 case 0x01:
11293 switch (minor & 3) {
11294 case MFHI_ACC:
11295 gen_HILO(ctx, OPC_MFHI, minor >> 2, rs);
11296 break;
11297 case MFLO_ACC:
11298 gen_HILO(ctx, OPC_MFLO, minor >> 2, rs);
11299 break;
11300 case MTHI_ACC:
11301 gen_HILO(ctx, OPC_MTHI, minor >> 2, rs);
11302 break;
11303 case MTLO_ACC:
11304 gen_HILO(ctx, OPC_MTLO, minor >> 2, rs);
11305 break;
11306 default:
11307 goto pool32axf_invalid;
11309 break;
11310 case 0x35:
11311 switch (minor) {
11312 case MFHI32:
11313 gen_HILO(ctx, OPC_MFHI, 0, rs);
11314 break;
11315 case MFLO32:
11316 gen_HILO(ctx, OPC_MFLO, 0, rs);
11317 break;
11318 case MTHI32:
11319 gen_HILO(ctx, OPC_MTHI, 0, rs);
11320 break;
11321 case MTLO32:
11322 gen_HILO(ctx, OPC_MTLO, 0, rs);
11323 break;
11324 default:
11325 goto pool32axf_invalid;
11327 break;
11328 default:
11329 pool32axf_invalid:
11330 MIPS_INVAL("pool32axf");
11331 generate_exception(ctx, EXCP_RI);
11332 break;
11336 /* Values for microMIPS fmt field. Variable-width, depending on which
11337 formats the instruction supports. */
11339 enum {
11340 FMT_SD_S = 0,
11341 FMT_SD_D = 1,
11343 FMT_SDPS_S = 0,
11344 FMT_SDPS_D = 1,
11345 FMT_SDPS_PS = 2,
11347 FMT_SWL_S = 0,
11348 FMT_SWL_W = 1,
11349 FMT_SWL_L = 2,
11351 FMT_DWL_D = 0,
11352 FMT_DWL_W = 1,
11353 FMT_DWL_L = 2
11356 static void gen_pool32fxf(DisasContext *ctx, int rt, int rs)
11358 int extension = (ctx->opcode >> 6) & 0x3ff;
11359 uint32_t mips32_op;
11361 #define FLOAT_1BIT_FMT(opc, fmt) (fmt << 8) | opc
11362 #define FLOAT_2BIT_FMT(opc, fmt) (fmt << 7) | opc
11363 #define COND_FLOAT_MOV(opc, cond) (cond << 7) | opc
11365 switch (extension) {
11366 case FLOAT_1BIT_FMT(CFC1, 0):
11367 mips32_op = OPC_CFC1;
11368 goto do_cp1;
11369 case FLOAT_1BIT_FMT(CTC1, 0):
11370 mips32_op = OPC_CTC1;
11371 goto do_cp1;
11372 case FLOAT_1BIT_FMT(MFC1, 0):
11373 mips32_op = OPC_MFC1;
11374 goto do_cp1;
11375 case FLOAT_1BIT_FMT(MTC1, 0):
11376 mips32_op = OPC_MTC1;
11377 goto do_cp1;
11378 case FLOAT_1BIT_FMT(MFHC1, 0):
11379 mips32_op = OPC_MFHC1;
11380 goto do_cp1;
11381 case FLOAT_1BIT_FMT(MTHC1, 0):
11382 mips32_op = OPC_MTHC1;
11383 do_cp1:
11384 gen_cp1(ctx, mips32_op, rt, rs);
11385 break;
11387 /* Reciprocal square root */
11388 case FLOAT_1BIT_FMT(RSQRT_FMT, FMT_SD_S):
11389 mips32_op = OPC_RSQRT_S;
11390 goto do_unaryfp;
11391 case FLOAT_1BIT_FMT(RSQRT_FMT, FMT_SD_D):
11392 mips32_op = OPC_RSQRT_D;
11393 goto do_unaryfp;
11395 /* Square root */
11396 case FLOAT_1BIT_FMT(SQRT_FMT, FMT_SD_S):
11397 mips32_op = OPC_SQRT_S;
11398 goto do_unaryfp;
11399 case FLOAT_1BIT_FMT(SQRT_FMT, FMT_SD_D):
11400 mips32_op = OPC_SQRT_D;
11401 goto do_unaryfp;
11403 /* Reciprocal */
11404 case FLOAT_1BIT_FMT(RECIP_FMT, FMT_SD_S):
11405 mips32_op = OPC_RECIP_S;
11406 goto do_unaryfp;
11407 case FLOAT_1BIT_FMT(RECIP_FMT, FMT_SD_D):
11408 mips32_op = OPC_RECIP_D;
11409 goto do_unaryfp;
11411 /* Floor */
11412 case FLOAT_1BIT_FMT(FLOOR_L, FMT_SD_S):
11413 mips32_op = OPC_FLOOR_L_S;
11414 goto do_unaryfp;
11415 case FLOAT_1BIT_FMT(FLOOR_L, FMT_SD_D):
11416 mips32_op = OPC_FLOOR_L_D;
11417 goto do_unaryfp;
11418 case FLOAT_1BIT_FMT(FLOOR_W, FMT_SD_S):
11419 mips32_op = OPC_FLOOR_W_S;
11420 goto do_unaryfp;
11421 case FLOAT_1BIT_FMT(FLOOR_W, FMT_SD_D):
11422 mips32_op = OPC_FLOOR_W_D;
11423 goto do_unaryfp;
11425 /* Ceiling */
11426 case FLOAT_1BIT_FMT(CEIL_L, FMT_SD_S):
11427 mips32_op = OPC_CEIL_L_S;
11428 goto do_unaryfp;
11429 case FLOAT_1BIT_FMT(CEIL_L, FMT_SD_D):
11430 mips32_op = OPC_CEIL_L_D;
11431 goto do_unaryfp;
11432 case FLOAT_1BIT_FMT(CEIL_W, FMT_SD_S):
11433 mips32_op = OPC_CEIL_W_S;
11434 goto do_unaryfp;
11435 case FLOAT_1BIT_FMT(CEIL_W, FMT_SD_D):
11436 mips32_op = OPC_CEIL_W_D;
11437 goto do_unaryfp;
11439 /* Truncation */
11440 case FLOAT_1BIT_FMT(TRUNC_L, FMT_SD_S):
11441 mips32_op = OPC_TRUNC_L_S;
11442 goto do_unaryfp;
11443 case FLOAT_1BIT_FMT(TRUNC_L, FMT_SD_D):
11444 mips32_op = OPC_TRUNC_L_D;
11445 goto do_unaryfp;
11446 case FLOAT_1BIT_FMT(TRUNC_W, FMT_SD_S):
11447 mips32_op = OPC_TRUNC_W_S;
11448 goto do_unaryfp;
11449 case FLOAT_1BIT_FMT(TRUNC_W, FMT_SD_D):
11450 mips32_op = OPC_TRUNC_W_D;
11451 goto do_unaryfp;
11453 /* Round */
11454 case FLOAT_1BIT_FMT(ROUND_L, FMT_SD_S):
11455 mips32_op = OPC_ROUND_L_S;
11456 goto do_unaryfp;
11457 case FLOAT_1BIT_FMT(ROUND_L, FMT_SD_D):
11458 mips32_op = OPC_ROUND_L_D;
11459 goto do_unaryfp;
11460 case FLOAT_1BIT_FMT(ROUND_W, FMT_SD_S):
11461 mips32_op = OPC_ROUND_W_S;
11462 goto do_unaryfp;
11463 case FLOAT_1BIT_FMT(ROUND_W, FMT_SD_D):
11464 mips32_op = OPC_ROUND_W_D;
11465 goto do_unaryfp;
11467 /* Integer to floating-point conversion */
11468 case FLOAT_1BIT_FMT(CVT_L, FMT_SD_S):
11469 mips32_op = OPC_CVT_L_S;
11470 goto do_unaryfp;
11471 case FLOAT_1BIT_FMT(CVT_L, FMT_SD_D):
11472 mips32_op = OPC_CVT_L_D;
11473 goto do_unaryfp;
11474 case FLOAT_1BIT_FMT(CVT_W, FMT_SD_S):
11475 mips32_op = OPC_CVT_W_S;
11476 goto do_unaryfp;
11477 case FLOAT_1BIT_FMT(CVT_W, FMT_SD_D):
11478 mips32_op = OPC_CVT_W_D;
11479 goto do_unaryfp;
11481 /* Paired-foo conversions */
11482 case FLOAT_1BIT_FMT(CVT_S_PL, 0):
11483 mips32_op = OPC_CVT_S_PL;
11484 goto do_unaryfp;
11485 case FLOAT_1BIT_FMT(CVT_S_PU, 0):
11486 mips32_op = OPC_CVT_S_PU;
11487 goto do_unaryfp;
11488 case FLOAT_1BIT_FMT(CVT_PW_PS, 0):
11489 mips32_op = OPC_CVT_PW_PS;
11490 goto do_unaryfp;
11491 case FLOAT_1BIT_FMT(CVT_PS_PW, 0):
11492 mips32_op = OPC_CVT_PS_PW;
11493 goto do_unaryfp;
11495 /* Floating-point moves */
11496 case FLOAT_2BIT_FMT(MOV_FMT, FMT_SDPS_S):
11497 mips32_op = OPC_MOV_S;
11498 goto do_unaryfp;
11499 case FLOAT_2BIT_FMT(MOV_FMT, FMT_SDPS_D):
11500 mips32_op = OPC_MOV_D;
11501 goto do_unaryfp;
11502 case FLOAT_2BIT_FMT(MOV_FMT, FMT_SDPS_PS):
11503 mips32_op = OPC_MOV_PS;
11504 goto do_unaryfp;
11506 /* Absolute value */
11507 case FLOAT_2BIT_FMT(ABS_FMT, FMT_SDPS_S):
11508 mips32_op = OPC_ABS_S;
11509 goto do_unaryfp;
11510 case FLOAT_2BIT_FMT(ABS_FMT, FMT_SDPS_D):
11511 mips32_op = OPC_ABS_D;
11512 goto do_unaryfp;
11513 case FLOAT_2BIT_FMT(ABS_FMT, FMT_SDPS_PS):
11514 mips32_op = OPC_ABS_PS;
11515 goto do_unaryfp;
11517 /* Negation */
11518 case FLOAT_2BIT_FMT(NEG_FMT, FMT_SDPS_S):
11519 mips32_op = OPC_NEG_S;
11520 goto do_unaryfp;
11521 case FLOAT_2BIT_FMT(NEG_FMT, FMT_SDPS_D):
11522 mips32_op = OPC_NEG_D;
11523 goto do_unaryfp;
11524 case FLOAT_2BIT_FMT(NEG_FMT, FMT_SDPS_PS):
11525 mips32_op = OPC_NEG_PS;
11526 goto do_unaryfp;
11528 /* Reciprocal square root step */
11529 case FLOAT_2BIT_FMT(RSQRT1_FMT, FMT_SDPS_S):
11530 mips32_op = OPC_RSQRT1_S;
11531 goto do_unaryfp;
11532 case FLOAT_2BIT_FMT(RSQRT1_FMT, FMT_SDPS_D):
11533 mips32_op = OPC_RSQRT1_D;
11534 goto do_unaryfp;
11535 case FLOAT_2BIT_FMT(RSQRT1_FMT, FMT_SDPS_PS):
11536 mips32_op = OPC_RSQRT1_PS;
11537 goto do_unaryfp;
11539 /* Reciprocal step */
11540 case FLOAT_2BIT_FMT(RECIP1_FMT, FMT_SDPS_S):
11541 mips32_op = OPC_RECIP1_S;
11542 goto do_unaryfp;
11543 case FLOAT_2BIT_FMT(RECIP1_FMT, FMT_SDPS_D):
11544 mips32_op = OPC_RECIP1_S;
11545 goto do_unaryfp;
11546 case FLOAT_2BIT_FMT(RECIP1_FMT, FMT_SDPS_PS):
11547 mips32_op = OPC_RECIP1_PS;
11548 goto do_unaryfp;
11550 /* Conversions from double */
11551 case FLOAT_2BIT_FMT(CVT_D, FMT_SWL_S):
11552 mips32_op = OPC_CVT_D_S;
11553 goto do_unaryfp;
11554 case FLOAT_2BIT_FMT(CVT_D, FMT_SWL_W):
11555 mips32_op = OPC_CVT_D_W;
11556 goto do_unaryfp;
11557 case FLOAT_2BIT_FMT(CVT_D, FMT_SWL_L):
11558 mips32_op = OPC_CVT_D_L;
11559 goto do_unaryfp;
11561 /* Conversions from single */
11562 case FLOAT_2BIT_FMT(CVT_S, FMT_DWL_D):
11563 mips32_op = OPC_CVT_S_D;
11564 goto do_unaryfp;
11565 case FLOAT_2BIT_FMT(CVT_S, FMT_DWL_W):
11566 mips32_op = OPC_CVT_S_W;
11567 goto do_unaryfp;
11568 case FLOAT_2BIT_FMT(CVT_S, FMT_DWL_L):
11569 mips32_op = OPC_CVT_S_L;
11570 do_unaryfp:
11571 gen_farith(ctx, mips32_op, -1, rs, rt, 0);
11572 break;
11574 /* Conditional moves on floating-point codes */
11575 case COND_FLOAT_MOV(MOVT, 0):
11576 case COND_FLOAT_MOV(MOVT, 1):
11577 case COND_FLOAT_MOV(MOVT, 2):
11578 case COND_FLOAT_MOV(MOVT, 3):
11579 case COND_FLOAT_MOV(MOVT, 4):
11580 case COND_FLOAT_MOV(MOVT, 5):
11581 case COND_FLOAT_MOV(MOVT, 6):
11582 case COND_FLOAT_MOV(MOVT, 7):
11583 gen_movci(ctx, rt, rs, (ctx->opcode >> 13) & 0x7, 1);
11584 break;
11585 case COND_FLOAT_MOV(MOVF, 0):
11586 case COND_FLOAT_MOV(MOVF, 1):
11587 case COND_FLOAT_MOV(MOVF, 2):
11588 case COND_FLOAT_MOV(MOVF, 3):
11589 case COND_FLOAT_MOV(MOVF, 4):
11590 case COND_FLOAT_MOV(MOVF, 5):
11591 case COND_FLOAT_MOV(MOVF, 6):
11592 case COND_FLOAT_MOV(MOVF, 7):
11593 gen_movci(ctx, rt, rs, (ctx->opcode >> 13) & 0x7, 0);
11594 break;
11595 default:
11596 MIPS_INVAL("pool32fxf");
11597 generate_exception(ctx, EXCP_RI);
11598 break;
11602 static void decode_micromips32_opc (CPUMIPSState *env, DisasContext *ctx,
11603 uint16_t insn_hw1)
11605 int32_t offset;
11606 uint16_t insn;
11607 int rt, rs, rd, rr;
11608 int16_t imm;
11609 uint32_t op, minor, mips32_op;
11610 uint32_t cond, fmt, cc;
11612 insn = cpu_lduw_code(env, ctx->pc + 2);
11613 ctx->opcode = (ctx->opcode << 16) | insn;
11615 rt = (ctx->opcode >> 21) & 0x1f;
11616 rs = (ctx->opcode >> 16) & 0x1f;
11617 rd = (ctx->opcode >> 11) & 0x1f;
11618 rr = (ctx->opcode >> 6) & 0x1f;
11619 imm = (int16_t) ctx->opcode;
11621 op = (ctx->opcode >> 26) & 0x3f;
11622 switch (op) {
11623 case POOL32A:
11624 minor = ctx->opcode & 0x3f;
11625 switch (minor) {
11626 case 0x00:
11627 minor = (ctx->opcode >> 6) & 0xf;
11628 switch (minor) {
11629 case SLL32:
11630 mips32_op = OPC_SLL;
11631 goto do_shifti;
11632 case SRA:
11633 mips32_op = OPC_SRA;
11634 goto do_shifti;
11635 case SRL32:
11636 mips32_op = OPC_SRL;
11637 goto do_shifti;
11638 case ROTR:
11639 mips32_op = OPC_ROTR;
11640 do_shifti:
11641 gen_shift_imm(ctx, mips32_op, rt, rs, rd);
11642 break;
11643 default:
11644 goto pool32a_invalid;
11646 break;
11647 case 0x10:
11648 minor = (ctx->opcode >> 6) & 0xf;
11649 switch (minor) {
11650 /* Arithmetic */
11651 case ADD:
11652 mips32_op = OPC_ADD;
11653 goto do_arith;
11654 case ADDU32:
11655 mips32_op = OPC_ADDU;
11656 goto do_arith;
11657 case SUB:
11658 mips32_op = OPC_SUB;
11659 goto do_arith;
11660 case SUBU32:
11661 mips32_op = OPC_SUBU;
11662 goto do_arith;
11663 case MUL:
11664 mips32_op = OPC_MUL;
11665 do_arith:
11666 gen_arith(ctx, mips32_op, rd, rs, rt);
11667 break;
11668 /* Shifts */
11669 case SLLV:
11670 mips32_op = OPC_SLLV;
11671 goto do_shift;
11672 case SRLV:
11673 mips32_op = OPC_SRLV;
11674 goto do_shift;
11675 case SRAV:
11676 mips32_op = OPC_SRAV;
11677 goto do_shift;
11678 case ROTRV:
11679 mips32_op = OPC_ROTRV;
11680 do_shift:
11681 gen_shift(ctx, mips32_op, rd, rs, rt);
11682 break;
11683 /* Logical operations */
11684 case AND:
11685 mips32_op = OPC_AND;
11686 goto do_logic;
11687 case OR32:
11688 mips32_op = OPC_OR;
11689 goto do_logic;
11690 case NOR:
11691 mips32_op = OPC_NOR;
11692 goto do_logic;
11693 case XOR32:
11694 mips32_op = OPC_XOR;
11695 do_logic:
11696 gen_logic(ctx, mips32_op, rd, rs, rt);
11697 break;
11698 /* Set less than */
11699 case SLT:
11700 mips32_op = OPC_SLT;
11701 goto do_slt;
11702 case SLTU:
11703 mips32_op = OPC_SLTU;
11704 do_slt:
11705 gen_slt(ctx, mips32_op, rd, rs, rt);
11706 break;
11707 default:
11708 goto pool32a_invalid;
11710 break;
11711 case 0x18:
11712 minor = (ctx->opcode >> 6) & 0xf;
11713 switch (minor) {
11714 /* Conditional moves */
11715 case MOVN:
11716 mips32_op = OPC_MOVN;
11717 goto do_cmov;
11718 case MOVZ:
11719 mips32_op = OPC_MOVZ;
11720 do_cmov:
11721 gen_cond_move(ctx, mips32_op, rd, rs, rt);
11722 break;
11723 case LWXS:
11724 gen_ldxs(ctx, rs, rt, rd);
11725 break;
11726 default:
11727 goto pool32a_invalid;
11729 break;
11730 case INS:
11731 gen_bitops(ctx, OPC_INS, rt, rs, rr, rd);
11732 return;
11733 case EXT:
11734 gen_bitops(ctx, OPC_EXT, rt, rs, rr, rd);
11735 return;
11736 case POOL32AXF:
11737 gen_pool32axf(env, ctx, rt, rs);
11738 break;
11739 case 0x07:
11740 generate_exception(ctx, EXCP_BREAK);
11741 break;
11742 default:
11743 pool32a_invalid:
11744 MIPS_INVAL("pool32a");
11745 generate_exception(ctx, EXCP_RI);
11746 break;
11748 break;
11749 case POOL32B:
11750 minor = (ctx->opcode >> 12) & 0xf;
11751 switch (minor) {
11752 case CACHE:
11753 check_cp0_enabled(ctx);
11754 /* Treat as no-op. */
11755 break;
11756 case LWC2:
11757 case SWC2:
11758 /* COP2: Not implemented. */
11759 generate_exception_err(ctx, EXCP_CpU, 2);
11760 break;
11761 case LWP:
11762 case SWP:
11763 #ifdef TARGET_MIPS64
11764 case LDP:
11765 case SDP:
11766 #endif
11767 gen_ldst_pair(ctx, minor, rt, rs, SIMM(ctx->opcode, 0, 12));
11768 break;
11769 case LWM32:
11770 case SWM32:
11771 #ifdef TARGET_MIPS64
11772 case LDM:
11773 case SDM:
11774 #endif
11775 gen_ldst_multiple(ctx, minor, rt, rs, SIMM(ctx->opcode, 0, 12));
11776 break;
11777 default:
11778 MIPS_INVAL("pool32b");
11779 generate_exception(ctx, EXCP_RI);
11780 break;
11782 break;
11783 case POOL32F:
11784 if (env->CP0_Config1 & (1 << CP0C1_FP)) {
11785 minor = ctx->opcode & 0x3f;
11786 check_cp1_enabled(ctx);
11787 switch (minor) {
11788 case ALNV_PS:
11789 mips32_op = OPC_ALNV_PS;
11790 goto do_madd;
11791 case MADD_S:
11792 mips32_op = OPC_MADD_S;
11793 goto do_madd;
11794 case MADD_D:
11795 mips32_op = OPC_MADD_D;
11796 goto do_madd;
11797 case MADD_PS:
11798 mips32_op = OPC_MADD_PS;
11799 goto do_madd;
11800 case MSUB_S:
11801 mips32_op = OPC_MSUB_S;
11802 goto do_madd;
11803 case MSUB_D:
11804 mips32_op = OPC_MSUB_D;
11805 goto do_madd;
11806 case MSUB_PS:
11807 mips32_op = OPC_MSUB_PS;
11808 goto do_madd;
11809 case NMADD_S:
11810 mips32_op = OPC_NMADD_S;
11811 goto do_madd;
11812 case NMADD_D:
11813 mips32_op = OPC_NMADD_D;
11814 goto do_madd;
11815 case NMADD_PS:
11816 mips32_op = OPC_NMADD_PS;
11817 goto do_madd;
11818 case NMSUB_S:
11819 mips32_op = OPC_NMSUB_S;
11820 goto do_madd;
11821 case NMSUB_D:
11822 mips32_op = OPC_NMSUB_D;
11823 goto do_madd;
11824 case NMSUB_PS:
11825 mips32_op = OPC_NMSUB_PS;
11826 do_madd:
11827 gen_flt3_arith(ctx, mips32_op, rd, rr, rs, rt);
11828 break;
11829 case CABS_COND_FMT:
11830 cond = (ctx->opcode >> 6) & 0xf;
11831 cc = (ctx->opcode >> 13) & 0x7;
11832 fmt = (ctx->opcode >> 10) & 0x3;
11833 switch (fmt) {
11834 case 0x0:
11835 gen_cmpabs_s(ctx, cond, rt, rs, cc);
11836 break;
11837 case 0x1:
11838 gen_cmpabs_d(ctx, cond, rt, rs, cc);
11839 break;
11840 case 0x2:
11841 gen_cmpabs_ps(ctx, cond, rt, rs, cc);
11842 break;
11843 default:
11844 goto pool32f_invalid;
11846 break;
11847 case C_COND_FMT:
11848 cond = (ctx->opcode >> 6) & 0xf;
11849 cc = (ctx->opcode >> 13) & 0x7;
11850 fmt = (ctx->opcode >> 10) & 0x3;
11851 switch (fmt) {
11852 case 0x0:
11853 gen_cmp_s(ctx, cond, rt, rs, cc);
11854 break;
11855 case 0x1:
11856 gen_cmp_d(ctx, cond, rt, rs, cc);
11857 break;
11858 case 0x2:
11859 gen_cmp_ps(ctx, cond, rt, rs, cc);
11860 break;
11861 default:
11862 goto pool32f_invalid;
11864 break;
11865 case POOL32FXF:
11866 gen_pool32fxf(ctx, rt, rs);
11867 break;
11868 case 0x00:
11869 /* PLL foo */
11870 switch ((ctx->opcode >> 6) & 0x7) {
11871 case PLL_PS:
11872 mips32_op = OPC_PLL_PS;
11873 goto do_ps;
11874 case PLU_PS:
11875 mips32_op = OPC_PLU_PS;
11876 goto do_ps;
11877 case PUL_PS:
11878 mips32_op = OPC_PUL_PS;
11879 goto do_ps;
11880 case PUU_PS:
11881 mips32_op = OPC_PUU_PS;
11882 goto do_ps;
11883 case CVT_PS_S:
11884 mips32_op = OPC_CVT_PS_S;
11885 do_ps:
11886 gen_farith(ctx, mips32_op, rt, rs, rd, 0);
11887 break;
11888 default:
11889 goto pool32f_invalid;
11891 break;
11892 case 0x08:
11893 /* [LS][WDU]XC1 */
11894 switch ((ctx->opcode >> 6) & 0x7) {
11895 case LWXC1:
11896 mips32_op = OPC_LWXC1;
11897 goto do_ldst_cp1;
11898 case SWXC1:
11899 mips32_op = OPC_SWXC1;
11900 goto do_ldst_cp1;
11901 case LDXC1:
11902 mips32_op = OPC_LDXC1;
11903 goto do_ldst_cp1;
11904 case SDXC1:
11905 mips32_op = OPC_SDXC1;
11906 goto do_ldst_cp1;
11907 case LUXC1:
11908 mips32_op = OPC_LUXC1;
11909 goto do_ldst_cp1;
11910 case SUXC1:
11911 mips32_op = OPC_SUXC1;
11912 do_ldst_cp1:
11913 gen_flt3_ldst(ctx, mips32_op, rd, rd, rt, rs);
11914 break;
11915 default:
11916 goto pool32f_invalid;
11918 break;
11919 case 0x18:
11920 /* 3D insns */
11921 fmt = (ctx->opcode >> 9) & 0x3;
11922 switch ((ctx->opcode >> 6) & 0x7) {
11923 case RSQRT2_FMT:
11924 switch (fmt) {
11925 case FMT_SDPS_S:
11926 mips32_op = OPC_RSQRT2_S;
11927 goto do_3d;
11928 case FMT_SDPS_D:
11929 mips32_op = OPC_RSQRT2_D;
11930 goto do_3d;
11931 case FMT_SDPS_PS:
11932 mips32_op = OPC_RSQRT2_PS;
11933 goto do_3d;
11934 default:
11935 goto pool32f_invalid;
11937 break;
11938 case RECIP2_FMT:
11939 switch (fmt) {
11940 case FMT_SDPS_S:
11941 mips32_op = OPC_RECIP2_S;
11942 goto do_3d;
11943 case FMT_SDPS_D:
11944 mips32_op = OPC_RECIP2_D;
11945 goto do_3d;
11946 case FMT_SDPS_PS:
11947 mips32_op = OPC_RECIP2_PS;
11948 goto do_3d;
11949 default:
11950 goto pool32f_invalid;
11952 break;
11953 case ADDR_PS:
11954 mips32_op = OPC_ADDR_PS;
11955 goto do_3d;
11956 case MULR_PS:
11957 mips32_op = OPC_MULR_PS;
11958 do_3d:
11959 gen_farith(ctx, mips32_op, rt, rs, rd, 0);
11960 break;
11961 default:
11962 goto pool32f_invalid;
11964 break;
11965 case 0x20:
11966 /* MOV[FT].fmt and PREFX */
11967 cc = (ctx->opcode >> 13) & 0x7;
11968 fmt = (ctx->opcode >> 9) & 0x3;
11969 switch ((ctx->opcode >> 6) & 0x7) {
11970 case MOVF_FMT:
11971 switch (fmt) {
11972 case FMT_SDPS_S:
11973 gen_movcf_s(rs, rt, cc, 0);
11974 break;
11975 case FMT_SDPS_D:
11976 gen_movcf_d(ctx, rs, rt, cc, 0);
11977 break;
11978 case FMT_SDPS_PS:
11979 gen_movcf_ps(rs, rt, cc, 0);
11980 break;
11981 default:
11982 goto pool32f_invalid;
11984 break;
11985 case MOVT_FMT:
11986 switch (fmt) {
11987 case FMT_SDPS_S:
11988 gen_movcf_s(rs, rt, cc, 1);
11989 break;
11990 case FMT_SDPS_D:
11991 gen_movcf_d(ctx, rs, rt, cc, 1);
11992 break;
11993 case FMT_SDPS_PS:
11994 gen_movcf_ps(rs, rt, cc, 1);
11995 break;
11996 default:
11997 goto pool32f_invalid;
11999 break;
12000 case PREFX:
12001 break;
12002 default:
12003 goto pool32f_invalid;
12005 break;
12006 #define FINSN_3ARG_SDPS(prfx) \
12007 switch ((ctx->opcode >> 8) & 0x3) { \
12008 case FMT_SDPS_S: \
12009 mips32_op = OPC_##prfx##_S; \
12010 goto do_fpop; \
12011 case FMT_SDPS_D: \
12012 mips32_op = OPC_##prfx##_D; \
12013 goto do_fpop; \
12014 case FMT_SDPS_PS: \
12015 mips32_op = OPC_##prfx##_PS; \
12016 goto do_fpop; \
12017 default: \
12018 goto pool32f_invalid; \
12020 case 0x30:
12021 /* regular FP ops */
12022 switch ((ctx->opcode >> 6) & 0x3) {
12023 case ADD_FMT:
12024 FINSN_3ARG_SDPS(ADD);
12025 break;
12026 case SUB_FMT:
12027 FINSN_3ARG_SDPS(SUB);
12028 break;
12029 case MUL_FMT:
12030 FINSN_3ARG_SDPS(MUL);
12031 break;
12032 case DIV_FMT:
12033 fmt = (ctx->opcode >> 8) & 0x3;
12034 if (fmt == 1) {
12035 mips32_op = OPC_DIV_D;
12036 } else if (fmt == 0) {
12037 mips32_op = OPC_DIV_S;
12038 } else {
12039 goto pool32f_invalid;
12041 goto do_fpop;
12042 default:
12043 goto pool32f_invalid;
12045 break;
12046 case 0x38:
12047 /* cmovs */
12048 switch ((ctx->opcode >> 6) & 0x3) {
12049 case MOVN_FMT:
12050 FINSN_3ARG_SDPS(MOVN);
12051 break;
12052 case MOVZ_FMT:
12053 FINSN_3ARG_SDPS(MOVZ);
12054 break;
12055 default:
12056 goto pool32f_invalid;
12058 break;
12059 do_fpop:
12060 gen_farith(ctx, mips32_op, rt, rs, rd, 0);
12061 break;
12062 default:
12063 pool32f_invalid:
12064 MIPS_INVAL("pool32f");
12065 generate_exception(ctx, EXCP_RI);
12066 break;
12068 } else {
12069 generate_exception_err(ctx, EXCP_CpU, 1);
12071 break;
12072 case POOL32I:
12073 minor = (ctx->opcode >> 21) & 0x1f;
12074 switch (minor) {
12075 case BLTZ:
12076 mips32_op = OPC_BLTZ;
12077 goto do_branch;
12078 case BLTZAL:
12079 mips32_op = OPC_BLTZAL;
12080 goto do_branch;
12081 case BLTZALS:
12082 mips32_op = OPC_BLTZALS;
12083 goto do_branch;
12084 case BGEZ:
12085 mips32_op = OPC_BGEZ;
12086 goto do_branch;
12087 case BGEZAL:
12088 mips32_op = OPC_BGEZAL;
12089 goto do_branch;
12090 case BGEZALS:
12091 mips32_op = OPC_BGEZALS;
12092 goto do_branch;
12093 case BLEZ:
12094 mips32_op = OPC_BLEZ;
12095 goto do_branch;
12096 case BGTZ:
12097 mips32_op = OPC_BGTZ;
12098 do_branch:
12099 gen_compute_branch(ctx, mips32_op, 4, rs, -1, imm << 1);
12100 break;
12102 /* Traps */
12103 case TLTI:
12104 mips32_op = OPC_TLTI;
12105 goto do_trapi;
12106 case TGEI:
12107 mips32_op = OPC_TGEI;
12108 goto do_trapi;
12109 case TLTIU:
12110 mips32_op = OPC_TLTIU;
12111 goto do_trapi;
12112 case TGEIU:
12113 mips32_op = OPC_TGEIU;
12114 goto do_trapi;
12115 case TNEI:
12116 mips32_op = OPC_TNEI;
12117 goto do_trapi;
12118 case TEQI:
12119 mips32_op = OPC_TEQI;
12120 do_trapi:
12121 gen_trap(ctx, mips32_op, rs, -1, imm);
12122 break;
12124 case BNEZC:
12125 case BEQZC:
12126 gen_compute_branch(ctx, minor == BNEZC ? OPC_BNE : OPC_BEQ,
12127 4, rs, 0, imm << 1);
12128 /* Compact branches don't have a delay slot, so just let
12129 the normal delay slot handling take us to the branch
12130 target. */
12131 break;
12132 case LUI:
12133 gen_logic_imm(ctx, OPC_LUI, rs, -1, imm);
12134 break;
12135 case SYNCI:
12136 break;
12137 case BC2F:
12138 case BC2T:
12139 /* COP2: Not implemented. */
12140 generate_exception_err(ctx, EXCP_CpU, 2);
12141 break;
12142 case BC1F:
12143 mips32_op = (ctx->opcode & (1 << 16)) ? OPC_BC1FANY2 : OPC_BC1F;
12144 goto do_cp1branch;
12145 case BC1T:
12146 mips32_op = (ctx->opcode & (1 << 16)) ? OPC_BC1TANY2 : OPC_BC1T;
12147 goto do_cp1branch;
12148 case BC1ANY4F:
12149 mips32_op = OPC_BC1FANY4;
12150 goto do_cp1mips3d;
12151 case BC1ANY4T:
12152 mips32_op = OPC_BC1TANY4;
12153 do_cp1mips3d:
12154 check_cop1x(ctx);
12155 check_insn(ctx, ASE_MIPS3D);
12156 /* Fall through */
12157 do_cp1branch:
12158 gen_compute_branch1(ctx, mips32_op,
12159 (ctx->opcode >> 18) & 0x7, imm << 1);
12160 break;
12161 case BPOSGE64:
12162 case BPOSGE32:
12163 /* MIPS DSP: not implemented */
12164 /* Fall through */
12165 default:
12166 MIPS_INVAL("pool32i");
12167 generate_exception(ctx, EXCP_RI);
12168 break;
12170 break;
12171 case POOL32C:
12172 minor = (ctx->opcode >> 12) & 0xf;
12173 switch (minor) {
12174 case LWL:
12175 mips32_op = OPC_LWL;
12176 goto do_ld_lr;
12177 case SWL:
12178 mips32_op = OPC_SWL;
12179 goto do_st_lr;
12180 case LWR:
12181 mips32_op = OPC_LWR;
12182 goto do_ld_lr;
12183 case SWR:
12184 mips32_op = OPC_SWR;
12185 goto do_st_lr;
12186 #if defined(TARGET_MIPS64)
12187 case LDL:
12188 mips32_op = OPC_LDL;
12189 goto do_ld_lr;
12190 case SDL:
12191 mips32_op = OPC_SDL;
12192 goto do_st_lr;
12193 case LDR:
12194 mips32_op = OPC_LDR;
12195 goto do_ld_lr;
12196 case SDR:
12197 mips32_op = OPC_SDR;
12198 goto do_st_lr;
12199 case LWU:
12200 mips32_op = OPC_LWU;
12201 goto do_ld_lr;
12202 case LLD:
12203 mips32_op = OPC_LLD;
12204 goto do_ld_lr;
12205 #endif
12206 case LL:
12207 mips32_op = OPC_LL;
12208 goto do_ld_lr;
12209 do_ld_lr:
12210 gen_ld(ctx, mips32_op, rt, rs, SIMM(ctx->opcode, 0, 12));
12211 break;
12212 do_st_lr:
12213 gen_st(ctx, mips32_op, rt, rs, SIMM(ctx->opcode, 0, 12));
12214 break;
12215 case SC:
12216 gen_st_cond(ctx, OPC_SC, rt, rs, SIMM(ctx->opcode, 0, 12));
12217 break;
12218 #if defined(TARGET_MIPS64)
12219 case SCD:
12220 gen_st_cond(ctx, OPC_SCD, rt, rs, SIMM(ctx->opcode, 0, 12));
12221 break;
12222 #endif
12223 case PREF:
12224 /* Treat as no-op */
12225 break;
12226 default:
12227 MIPS_INVAL("pool32c");
12228 generate_exception(ctx, EXCP_RI);
12229 break;
12231 break;
12232 case ADDI32:
12233 mips32_op = OPC_ADDI;
12234 goto do_addi;
12235 case ADDIU32:
12236 mips32_op = OPC_ADDIU;
12237 do_addi:
12238 gen_arith_imm(ctx, mips32_op, rt, rs, imm);
12239 break;
12241 /* Logical operations */
12242 case ORI32:
12243 mips32_op = OPC_ORI;
12244 goto do_logici;
12245 case XORI32:
12246 mips32_op = OPC_XORI;
12247 goto do_logici;
12248 case ANDI32:
12249 mips32_op = OPC_ANDI;
12250 do_logici:
12251 gen_logic_imm(ctx, mips32_op, rt, rs, imm);
12252 break;
12254 /* Set less than immediate */
12255 case SLTI32:
12256 mips32_op = OPC_SLTI;
12257 goto do_slti;
12258 case SLTIU32:
12259 mips32_op = OPC_SLTIU;
12260 do_slti:
12261 gen_slt_imm(ctx, mips32_op, rt, rs, imm);
12262 break;
12263 case JALX32:
12264 offset = (int32_t)(ctx->opcode & 0x3FFFFFF) << 2;
12265 gen_compute_branch(ctx, OPC_JALX, 4, rt, rs, offset);
12266 break;
12267 case JALS32:
12268 offset = (int32_t)(ctx->opcode & 0x3FFFFFF) << 1;
12269 gen_compute_branch(ctx, OPC_JALS, 4, rt, rs, offset);
12270 break;
12271 case BEQ32:
12272 gen_compute_branch(ctx, OPC_BEQ, 4, rt, rs, imm << 1);
12273 break;
12274 case BNE32:
12275 gen_compute_branch(ctx, OPC_BNE, 4, rt, rs, imm << 1);
12276 break;
12277 case J32:
12278 gen_compute_branch(ctx, OPC_J, 4, rt, rs,
12279 (int32_t)(ctx->opcode & 0x3FFFFFF) << 1);
12280 break;
12281 case JAL32:
12282 gen_compute_branch(ctx, OPC_JAL, 4, rt, rs,
12283 (int32_t)(ctx->opcode & 0x3FFFFFF) << 1);
12284 break;
12285 /* Floating point (COP1) */
12286 case LWC132:
12287 mips32_op = OPC_LWC1;
12288 goto do_cop1;
12289 case LDC132:
12290 mips32_op = OPC_LDC1;
12291 goto do_cop1;
12292 case SWC132:
12293 mips32_op = OPC_SWC1;
12294 goto do_cop1;
12295 case SDC132:
12296 mips32_op = OPC_SDC1;
12297 do_cop1:
12298 gen_cop1_ldst(env, ctx, mips32_op, rt, rs, imm);
12299 break;
12300 case ADDIUPC:
12302 int reg = mmreg(ZIMM(ctx->opcode, 23, 3));
12303 int offset = SIMM(ctx->opcode, 0, 23) << 2;
12305 gen_addiupc(ctx, reg, offset, 0, 0);
12307 break;
12308 /* Loads and stores */
12309 case LB32:
12310 mips32_op = OPC_LB;
12311 goto do_ld;
12312 case LBU32:
12313 mips32_op = OPC_LBU;
12314 goto do_ld;
12315 case LH32:
12316 mips32_op = OPC_LH;
12317 goto do_ld;
12318 case LHU32:
12319 mips32_op = OPC_LHU;
12320 goto do_ld;
12321 case LW32:
12322 mips32_op = OPC_LW;
12323 goto do_ld;
12324 #ifdef TARGET_MIPS64
12325 case LD32:
12326 mips32_op = OPC_LD;
12327 goto do_ld;
12328 case SD32:
12329 mips32_op = OPC_SD;
12330 goto do_st;
12331 #endif
12332 case SB32:
12333 mips32_op = OPC_SB;
12334 goto do_st;
12335 case SH32:
12336 mips32_op = OPC_SH;
12337 goto do_st;
12338 case SW32:
12339 mips32_op = OPC_SW;
12340 goto do_st;
12341 do_ld:
12342 gen_ld(ctx, mips32_op, rt, rs, imm);
12343 break;
12344 do_st:
12345 gen_st(ctx, mips32_op, rt, rs, imm);
12346 break;
12347 default:
12348 generate_exception(ctx, EXCP_RI);
12349 break;
12353 static int decode_micromips_opc (CPUMIPSState *env, DisasContext *ctx)
12355 uint32_t op;
12357 /* make sure instructions are on a halfword boundary */
12358 if (ctx->pc & 0x1) {
12359 env->CP0_BadVAddr = ctx->pc;
12360 generate_exception(ctx, EXCP_AdEL);
12361 ctx->bstate = BS_STOP;
12362 return 2;
12365 op = (ctx->opcode >> 10) & 0x3f;
12366 /* Enforce properly-sized instructions in a delay slot */
12367 if (ctx->hflags & MIPS_HFLAG_BMASK) {
12368 int bits = ctx->hflags & MIPS_HFLAG_BMASK_EXT;
12370 switch (op) {
12371 case POOL32A:
12372 case POOL32B:
12373 case POOL32I:
12374 case POOL32C:
12375 case ADDI32:
12376 case ADDIU32:
12377 case ORI32:
12378 case XORI32:
12379 case SLTI32:
12380 case SLTIU32:
12381 case ANDI32:
12382 case JALX32:
12383 case LBU32:
12384 case LHU32:
12385 case POOL32F:
12386 case JALS32:
12387 case BEQ32:
12388 case BNE32:
12389 case J32:
12390 case JAL32:
12391 case SB32:
12392 case SH32:
12393 case POOL32S:
12394 case ADDIUPC:
12395 case SWC132:
12396 case SDC132:
12397 case SD32:
12398 case SW32:
12399 case LB32:
12400 case LH32:
12401 case DADDIU32:
12402 case LWC132:
12403 case LDC132:
12404 case LD32:
12405 case LW32:
12406 if (bits & MIPS_HFLAG_BDS16) {
12407 generate_exception(ctx, EXCP_RI);
12408 /* Just stop translation; the user is confused. */
12409 ctx->bstate = BS_STOP;
12410 return 2;
12412 break;
12413 case POOL16A:
12414 case POOL16B:
12415 case POOL16C:
12416 case LWGP16:
12417 case POOL16F:
12418 case LBU16:
12419 case LHU16:
12420 case LWSP16:
12421 case LW16:
12422 case SB16:
12423 case SH16:
12424 case SWSP16:
12425 case SW16:
12426 case MOVE16:
12427 case ANDI16:
12428 case POOL16D:
12429 case POOL16E:
12430 case BEQZ16:
12431 case BNEZ16:
12432 case B16:
12433 case LI16:
12434 if (bits & MIPS_HFLAG_BDS32) {
12435 generate_exception(ctx, EXCP_RI);
12436 /* Just stop translation; the user is confused. */
12437 ctx->bstate = BS_STOP;
12438 return 2;
12440 break;
12441 default:
12442 break;
12445 switch (op) {
12446 case POOL16A:
12448 int rd = mmreg(uMIPS_RD(ctx->opcode));
12449 int rs1 = mmreg(uMIPS_RS1(ctx->opcode));
12450 int rs2 = mmreg(uMIPS_RS2(ctx->opcode));
12451 uint32_t opc = 0;
12453 switch (ctx->opcode & 0x1) {
12454 case ADDU16:
12455 opc = OPC_ADDU;
12456 break;
12457 case SUBU16:
12458 opc = OPC_SUBU;
12459 break;
12462 gen_arith(ctx, opc, rd, rs1, rs2);
12464 break;
12465 case POOL16B:
12467 int rd = mmreg(uMIPS_RD(ctx->opcode));
12468 int rs = mmreg(uMIPS_RS(ctx->opcode));
12469 int amount = (ctx->opcode >> 1) & 0x7;
12470 uint32_t opc = 0;
12471 amount = amount == 0 ? 8 : amount;
12473 switch (ctx->opcode & 0x1) {
12474 case SLL16:
12475 opc = OPC_SLL;
12476 break;
12477 case SRL16:
12478 opc = OPC_SRL;
12479 break;
12482 gen_shift_imm(ctx, opc, rd, rs, amount);
12484 break;
12485 case POOL16C:
12486 gen_pool16c_insn(ctx);
12487 break;
12488 case LWGP16:
12490 int rd = mmreg(uMIPS_RD(ctx->opcode));
12491 int rb = 28; /* GP */
12492 int16_t offset = SIMM(ctx->opcode, 0, 7) << 2;
12494 gen_ld(ctx, OPC_LW, rd, rb, offset);
12496 break;
12497 case POOL16F:
12498 if (ctx->opcode & 1) {
12499 generate_exception(ctx, EXCP_RI);
12500 } else {
12501 /* MOVEP */
12502 int enc_dest = uMIPS_RD(ctx->opcode);
12503 int enc_rt = uMIPS_RS2(ctx->opcode);
12504 int enc_rs = uMIPS_RS1(ctx->opcode);
12505 int rd, rs, re, rt;
12506 static const int rd_enc[] = { 5, 5, 6, 4, 4, 4, 4, 4 };
12507 static const int re_enc[] = { 6, 7, 7, 21, 22, 5, 6, 7 };
12508 static const int rs_rt_enc[] = { 0, 17, 2, 3, 16, 18, 19, 20 };
12510 rd = rd_enc[enc_dest];
12511 re = re_enc[enc_dest];
12512 rs = rs_rt_enc[enc_rs];
12513 rt = rs_rt_enc[enc_rt];
12515 gen_arith_imm(ctx, OPC_ADDIU, rd, rs, 0);
12516 gen_arith_imm(ctx, OPC_ADDIU, re, rt, 0);
12518 break;
12519 case LBU16:
12521 int rd = mmreg(uMIPS_RD(ctx->opcode));
12522 int rb = mmreg(uMIPS_RS(ctx->opcode));
12523 int16_t offset = ZIMM(ctx->opcode, 0, 4);
12524 offset = (offset == 0xf ? -1 : offset);
12526 gen_ld(ctx, OPC_LBU, rd, rb, offset);
12528 break;
12529 case LHU16:
12531 int rd = mmreg(uMIPS_RD(ctx->opcode));
12532 int rb = mmreg(uMIPS_RS(ctx->opcode));
12533 int16_t offset = ZIMM(ctx->opcode, 0, 4) << 1;
12535 gen_ld(ctx, OPC_LHU, rd, rb, offset);
12537 break;
12538 case LWSP16:
12540 int rd = (ctx->opcode >> 5) & 0x1f;
12541 int rb = 29; /* SP */
12542 int16_t offset = ZIMM(ctx->opcode, 0, 5) << 2;
12544 gen_ld(ctx, OPC_LW, rd, rb, offset);
12546 break;
12547 case LW16:
12549 int rd = mmreg(uMIPS_RD(ctx->opcode));
12550 int rb = mmreg(uMIPS_RS(ctx->opcode));
12551 int16_t offset = ZIMM(ctx->opcode, 0, 4) << 2;
12553 gen_ld(ctx, OPC_LW, rd, rb, offset);
12555 break;
12556 case SB16:
12558 int rd = mmreg2(uMIPS_RD(ctx->opcode));
12559 int rb = mmreg(uMIPS_RS(ctx->opcode));
12560 int16_t offset = ZIMM(ctx->opcode, 0, 4);
12562 gen_st(ctx, OPC_SB, rd, rb, offset);
12564 break;
12565 case SH16:
12567 int rd = mmreg2(uMIPS_RD(ctx->opcode));
12568 int rb = mmreg(uMIPS_RS(ctx->opcode));
12569 int16_t offset = ZIMM(ctx->opcode, 0, 4) << 1;
12571 gen_st(ctx, OPC_SH, rd, rb, offset);
12573 break;
12574 case SWSP16:
12576 int rd = (ctx->opcode >> 5) & 0x1f;
12577 int rb = 29; /* SP */
12578 int16_t offset = ZIMM(ctx->opcode, 0, 5) << 2;
12580 gen_st(ctx, OPC_SW, rd, rb, offset);
12582 break;
12583 case SW16:
12585 int rd = mmreg2(uMIPS_RD(ctx->opcode));
12586 int rb = mmreg(uMIPS_RS(ctx->opcode));
12587 int16_t offset = ZIMM(ctx->opcode, 0, 4) << 2;
12589 gen_st(ctx, OPC_SW, rd, rb, offset);
12591 break;
12592 case MOVE16:
12594 int rd = uMIPS_RD5(ctx->opcode);
12595 int rs = uMIPS_RS5(ctx->opcode);
12597 gen_arith_imm(ctx, OPC_ADDIU, rd, rs, 0);
12599 break;
12600 case ANDI16:
12601 gen_andi16(ctx);
12602 break;
12603 case POOL16D:
12604 switch (ctx->opcode & 0x1) {
12605 case ADDIUS5:
12606 gen_addius5(ctx);
12607 break;
12608 case ADDIUSP:
12609 gen_addiusp(ctx);
12610 break;
12612 break;
12613 case POOL16E:
12614 switch (ctx->opcode & 0x1) {
12615 case ADDIUR2:
12616 gen_addiur2(ctx);
12617 break;
12618 case ADDIUR1SP:
12619 gen_addiur1sp(ctx);
12620 break;
12622 break;
12623 case B16:
12624 gen_compute_branch(ctx, OPC_BEQ, 2, 0, 0,
12625 SIMM(ctx->opcode, 0, 10) << 1);
12626 break;
12627 case BNEZ16:
12628 case BEQZ16:
12629 gen_compute_branch(ctx, op == BNEZ16 ? OPC_BNE : OPC_BEQ, 2,
12630 mmreg(uMIPS_RD(ctx->opcode)),
12631 0, SIMM(ctx->opcode, 0, 7) << 1);
12632 break;
12633 case LI16:
12635 int reg = mmreg(uMIPS_RD(ctx->opcode));
12636 int imm = ZIMM(ctx->opcode, 0, 7);
12638 imm = (imm == 0x7f ? -1 : imm);
12639 tcg_gen_movi_tl(cpu_gpr[reg], imm);
12641 break;
12642 case RES_20:
12643 case RES_28:
12644 case RES_29:
12645 case RES_30:
12646 case RES_31:
12647 case RES_38:
12648 case RES_39:
12649 generate_exception(ctx, EXCP_RI);
12650 break;
12651 default:
12652 decode_micromips32_opc (env, ctx, op);
12653 return 4;
12656 return 2;
12659 /* SmartMIPS extension to MIPS32 */
12661 #if defined(TARGET_MIPS64)
12663 /* MDMX extension to MIPS64 */
12665 #endif
12667 /* MIPSDSP functions. */
12668 static void gen_mipsdsp_ld(DisasContext *ctx, uint32_t opc,
12669 int rd, int base, int offset)
12671 const char *opn = "ldx";
12672 TCGv t0;
12674 check_dsp(ctx);
12675 t0 = tcg_temp_new();
12677 if (base == 0) {
12678 gen_load_gpr(t0, offset);
12679 } else if (offset == 0) {
12680 gen_load_gpr(t0, base);
12681 } else {
12682 gen_op_addr_add(ctx, t0, cpu_gpr[base], cpu_gpr[offset]);
12685 switch (opc) {
12686 case OPC_LBUX:
12687 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_UB);
12688 gen_store_gpr(t0, rd);
12689 opn = "lbux";
12690 break;
12691 case OPC_LHX:
12692 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TESW);
12693 gen_store_gpr(t0, rd);
12694 opn = "lhx";
12695 break;
12696 case OPC_LWX:
12697 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TESL);
12698 gen_store_gpr(t0, rd);
12699 opn = "lwx";
12700 break;
12701 #if defined(TARGET_MIPS64)
12702 case OPC_LDX:
12703 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TEQ);
12704 gen_store_gpr(t0, rd);
12705 opn = "ldx";
12706 break;
12707 #endif
12709 (void)opn; /* avoid a compiler warning */
12710 MIPS_DEBUG("%s %s, %s(%s)", opn,
12711 regnames[rd], regnames[offset], regnames[base]);
12712 tcg_temp_free(t0);
12715 static void gen_mipsdsp_arith(DisasContext *ctx, uint32_t op1, uint32_t op2,
12716 int ret, int v1, int v2)
12718 const char *opn = "mipsdsp arith";
12719 TCGv v1_t;
12720 TCGv v2_t;
12722 if (ret == 0) {
12723 /* Treat as NOP. */
12724 MIPS_DEBUG("NOP");
12725 return;
12728 v1_t = tcg_temp_new();
12729 v2_t = tcg_temp_new();
12731 gen_load_gpr(v1_t, v1);
12732 gen_load_gpr(v2_t, v2);
12734 switch (op1) {
12735 /* OPC_MULT_G_2E is equal OPC_ADDUH_QB_DSP */
12736 case OPC_MULT_G_2E:
12737 check_dspr2(ctx);
12738 switch (op2) {
12739 case OPC_ADDUH_QB:
12740 gen_helper_adduh_qb(cpu_gpr[ret], v1_t, v2_t);
12741 break;
12742 case OPC_ADDUH_R_QB:
12743 gen_helper_adduh_r_qb(cpu_gpr[ret], v1_t, v2_t);
12744 break;
12745 case OPC_ADDQH_PH:
12746 gen_helper_addqh_ph(cpu_gpr[ret], v1_t, v2_t);
12747 break;
12748 case OPC_ADDQH_R_PH:
12749 gen_helper_addqh_r_ph(cpu_gpr[ret], v1_t, v2_t);
12750 break;
12751 case OPC_ADDQH_W:
12752 gen_helper_addqh_w(cpu_gpr[ret], v1_t, v2_t);
12753 break;
12754 case OPC_ADDQH_R_W:
12755 gen_helper_addqh_r_w(cpu_gpr[ret], v1_t, v2_t);
12756 break;
12757 case OPC_SUBUH_QB:
12758 gen_helper_subuh_qb(cpu_gpr[ret], v1_t, v2_t);
12759 break;
12760 case OPC_SUBUH_R_QB:
12761 gen_helper_subuh_r_qb(cpu_gpr[ret], v1_t, v2_t);
12762 break;
12763 case OPC_SUBQH_PH:
12764 gen_helper_subqh_ph(cpu_gpr[ret], v1_t, v2_t);
12765 break;
12766 case OPC_SUBQH_R_PH:
12767 gen_helper_subqh_r_ph(cpu_gpr[ret], v1_t, v2_t);
12768 break;
12769 case OPC_SUBQH_W:
12770 gen_helper_subqh_w(cpu_gpr[ret], v1_t, v2_t);
12771 break;
12772 case OPC_SUBQH_R_W:
12773 gen_helper_subqh_r_w(cpu_gpr[ret], v1_t, v2_t);
12774 break;
12776 break;
12777 case OPC_ABSQ_S_PH_DSP:
12778 switch (op2) {
12779 case OPC_ABSQ_S_QB:
12780 check_dspr2(ctx);
12781 gen_helper_absq_s_qb(cpu_gpr[ret], v2_t, cpu_env);
12782 break;
12783 case OPC_ABSQ_S_PH:
12784 check_dsp(ctx);
12785 gen_helper_absq_s_ph(cpu_gpr[ret], v2_t, cpu_env);
12786 break;
12787 case OPC_ABSQ_S_W:
12788 check_dsp(ctx);
12789 gen_helper_absq_s_w(cpu_gpr[ret], v2_t, cpu_env);
12790 break;
12791 case OPC_PRECEQ_W_PHL:
12792 check_dsp(ctx);
12793 tcg_gen_andi_tl(cpu_gpr[ret], v2_t, 0xFFFF0000);
12794 tcg_gen_ext32s_tl(cpu_gpr[ret], cpu_gpr[ret]);
12795 break;
12796 case OPC_PRECEQ_W_PHR:
12797 check_dsp(ctx);
12798 tcg_gen_andi_tl(cpu_gpr[ret], v2_t, 0x0000FFFF);
12799 tcg_gen_shli_tl(cpu_gpr[ret], cpu_gpr[ret], 16);
12800 tcg_gen_ext32s_tl(cpu_gpr[ret], cpu_gpr[ret]);
12801 break;
12802 case OPC_PRECEQU_PH_QBL:
12803 check_dsp(ctx);
12804 gen_helper_precequ_ph_qbl(cpu_gpr[ret], v2_t);
12805 break;
12806 case OPC_PRECEQU_PH_QBR:
12807 check_dsp(ctx);
12808 gen_helper_precequ_ph_qbr(cpu_gpr[ret], v2_t);
12809 break;
12810 case OPC_PRECEQU_PH_QBLA:
12811 check_dsp(ctx);
12812 gen_helper_precequ_ph_qbla(cpu_gpr[ret], v2_t);
12813 break;
12814 case OPC_PRECEQU_PH_QBRA:
12815 check_dsp(ctx);
12816 gen_helper_precequ_ph_qbra(cpu_gpr[ret], v2_t);
12817 break;
12818 case OPC_PRECEU_PH_QBL:
12819 check_dsp(ctx);
12820 gen_helper_preceu_ph_qbl(cpu_gpr[ret], v2_t);
12821 break;
12822 case OPC_PRECEU_PH_QBR:
12823 check_dsp(ctx);
12824 gen_helper_preceu_ph_qbr(cpu_gpr[ret], v2_t);
12825 break;
12826 case OPC_PRECEU_PH_QBLA:
12827 check_dsp(ctx);
12828 gen_helper_preceu_ph_qbla(cpu_gpr[ret], v2_t);
12829 break;
12830 case OPC_PRECEU_PH_QBRA:
12831 check_dsp(ctx);
12832 gen_helper_preceu_ph_qbra(cpu_gpr[ret], v2_t);
12833 break;
12835 break;
12836 case OPC_ADDU_QB_DSP:
12837 switch (op2) {
12838 case OPC_ADDQ_PH:
12839 check_dsp(ctx);
12840 gen_helper_addq_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12841 break;
12842 case OPC_ADDQ_S_PH:
12843 check_dsp(ctx);
12844 gen_helper_addq_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12845 break;
12846 case OPC_ADDQ_S_W:
12847 check_dsp(ctx);
12848 gen_helper_addq_s_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12849 break;
12850 case OPC_ADDU_QB:
12851 check_dsp(ctx);
12852 gen_helper_addu_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12853 break;
12854 case OPC_ADDU_S_QB:
12855 check_dsp(ctx);
12856 gen_helper_addu_s_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12857 break;
12858 case OPC_ADDU_PH:
12859 check_dspr2(ctx);
12860 gen_helper_addu_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12861 break;
12862 case OPC_ADDU_S_PH:
12863 check_dspr2(ctx);
12864 gen_helper_addu_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12865 break;
12866 case OPC_SUBQ_PH:
12867 check_dsp(ctx);
12868 gen_helper_subq_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12869 break;
12870 case OPC_SUBQ_S_PH:
12871 check_dsp(ctx);
12872 gen_helper_subq_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12873 break;
12874 case OPC_SUBQ_S_W:
12875 check_dsp(ctx);
12876 gen_helper_subq_s_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12877 break;
12878 case OPC_SUBU_QB:
12879 check_dsp(ctx);
12880 gen_helper_subu_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12881 break;
12882 case OPC_SUBU_S_QB:
12883 check_dsp(ctx);
12884 gen_helper_subu_s_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12885 break;
12886 case OPC_SUBU_PH:
12887 check_dspr2(ctx);
12888 gen_helper_subu_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12889 break;
12890 case OPC_SUBU_S_PH:
12891 check_dspr2(ctx);
12892 gen_helper_subu_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12893 break;
12894 case OPC_ADDSC:
12895 check_dsp(ctx);
12896 gen_helper_addsc(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12897 break;
12898 case OPC_ADDWC:
12899 check_dsp(ctx);
12900 gen_helper_addwc(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12901 break;
12902 case OPC_MODSUB:
12903 check_dsp(ctx);
12904 gen_helper_modsub(cpu_gpr[ret], v1_t, v2_t);
12905 break;
12906 case OPC_RADDU_W_QB:
12907 check_dsp(ctx);
12908 gen_helper_raddu_w_qb(cpu_gpr[ret], v1_t);
12909 break;
12911 break;
12912 case OPC_CMPU_EQ_QB_DSP:
12913 switch (op2) {
12914 case OPC_PRECR_QB_PH:
12915 check_dspr2(ctx);
12916 gen_helper_precr_qb_ph(cpu_gpr[ret], v1_t, v2_t);
12917 break;
12918 case OPC_PRECRQ_QB_PH:
12919 check_dsp(ctx);
12920 gen_helper_precrq_qb_ph(cpu_gpr[ret], v1_t, v2_t);
12921 break;
12922 case OPC_PRECR_SRA_PH_W:
12923 check_dspr2(ctx);
12925 TCGv_i32 sa_t = tcg_const_i32(v2);
12926 gen_helper_precr_sra_ph_w(cpu_gpr[ret], sa_t, v1_t,
12927 cpu_gpr[ret]);
12928 tcg_temp_free_i32(sa_t);
12929 break;
12931 case OPC_PRECR_SRA_R_PH_W:
12932 check_dspr2(ctx);
12934 TCGv_i32 sa_t = tcg_const_i32(v2);
12935 gen_helper_precr_sra_r_ph_w(cpu_gpr[ret], sa_t, v1_t,
12936 cpu_gpr[ret]);
12937 tcg_temp_free_i32(sa_t);
12938 break;
12940 case OPC_PRECRQ_PH_W:
12941 check_dsp(ctx);
12942 gen_helper_precrq_ph_w(cpu_gpr[ret], v1_t, v2_t);
12943 break;
12944 case OPC_PRECRQ_RS_PH_W:
12945 check_dsp(ctx);
12946 gen_helper_precrq_rs_ph_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12947 break;
12948 case OPC_PRECRQU_S_QB_PH:
12949 check_dsp(ctx);
12950 gen_helper_precrqu_s_qb_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12951 break;
12953 break;
12954 #ifdef TARGET_MIPS64
12955 case OPC_ABSQ_S_QH_DSP:
12956 switch (op2) {
12957 case OPC_PRECEQ_L_PWL:
12958 check_dsp(ctx);
12959 tcg_gen_andi_tl(cpu_gpr[ret], v2_t, 0xFFFFFFFF00000000ull);
12960 break;
12961 case OPC_PRECEQ_L_PWR:
12962 check_dsp(ctx);
12963 tcg_gen_shli_tl(cpu_gpr[ret], v2_t, 32);
12964 break;
12965 case OPC_PRECEQ_PW_QHL:
12966 check_dsp(ctx);
12967 gen_helper_preceq_pw_qhl(cpu_gpr[ret], v2_t);
12968 break;
12969 case OPC_PRECEQ_PW_QHR:
12970 check_dsp(ctx);
12971 gen_helper_preceq_pw_qhr(cpu_gpr[ret], v2_t);
12972 break;
12973 case OPC_PRECEQ_PW_QHLA:
12974 check_dsp(ctx);
12975 gen_helper_preceq_pw_qhla(cpu_gpr[ret], v2_t);
12976 break;
12977 case OPC_PRECEQ_PW_QHRA:
12978 check_dsp(ctx);
12979 gen_helper_preceq_pw_qhra(cpu_gpr[ret], v2_t);
12980 break;
12981 case OPC_PRECEQU_QH_OBL:
12982 check_dsp(ctx);
12983 gen_helper_precequ_qh_obl(cpu_gpr[ret], v2_t);
12984 break;
12985 case OPC_PRECEQU_QH_OBR:
12986 check_dsp(ctx);
12987 gen_helper_precequ_qh_obr(cpu_gpr[ret], v2_t);
12988 break;
12989 case OPC_PRECEQU_QH_OBLA:
12990 check_dsp(ctx);
12991 gen_helper_precequ_qh_obla(cpu_gpr[ret], v2_t);
12992 break;
12993 case OPC_PRECEQU_QH_OBRA:
12994 check_dsp(ctx);
12995 gen_helper_precequ_qh_obra(cpu_gpr[ret], v2_t);
12996 break;
12997 case OPC_PRECEU_QH_OBL:
12998 check_dsp(ctx);
12999 gen_helper_preceu_qh_obl(cpu_gpr[ret], v2_t);
13000 break;
13001 case OPC_PRECEU_QH_OBR:
13002 check_dsp(ctx);
13003 gen_helper_preceu_qh_obr(cpu_gpr[ret], v2_t);
13004 break;
13005 case OPC_PRECEU_QH_OBLA:
13006 check_dsp(ctx);
13007 gen_helper_preceu_qh_obla(cpu_gpr[ret], v2_t);
13008 break;
13009 case OPC_PRECEU_QH_OBRA:
13010 check_dsp(ctx);
13011 gen_helper_preceu_qh_obra(cpu_gpr[ret], v2_t);
13012 break;
13013 case OPC_ABSQ_S_OB:
13014 check_dspr2(ctx);
13015 gen_helper_absq_s_ob(cpu_gpr[ret], v2_t, cpu_env);
13016 break;
13017 case OPC_ABSQ_S_PW:
13018 check_dsp(ctx);
13019 gen_helper_absq_s_pw(cpu_gpr[ret], v2_t, cpu_env);
13020 break;
13021 case OPC_ABSQ_S_QH:
13022 check_dsp(ctx);
13023 gen_helper_absq_s_qh(cpu_gpr[ret], v2_t, cpu_env);
13024 break;
13026 break;
13027 case OPC_ADDU_OB_DSP:
13028 switch (op2) {
13029 case OPC_RADDU_L_OB:
13030 check_dsp(ctx);
13031 gen_helper_raddu_l_ob(cpu_gpr[ret], v1_t);
13032 break;
13033 case OPC_SUBQ_PW:
13034 check_dsp(ctx);
13035 gen_helper_subq_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13036 break;
13037 case OPC_SUBQ_S_PW:
13038 check_dsp(ctx);
13039 gen_helper_subq_s_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13040 break;
13041 case OPC_SUBQ_QH:
13042 check_dsp(ctx);
13043 gen_helper_subq_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13044 break;
13045 case OPC_SUBQ_S_QH:
13046 check_dsp(ctx);
13047 gen_helper_subq_s_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13048 break;
13049 case OPC_SUBU_OB:
13050 check_dsp(ctx);
13051 gen_helper_subu_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13052 break;
13053 case OPC_SUBU_S_OB:
13054 check_dsp(ctx);
13055 gen_helper_subu_s_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13056 break;
13057 case OPC_SUBU_QH:
13058 check_dspr2(ctx);
13059 gen_helper_subu_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13060 break;
13061 case OPC_SUBU_S_QH:
13062 check_dspr2(ctx);
13063 gen_helper_subu_s_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13064 break;
13065 case OPC_SUBUH_OB:
13066 check_dspr2(ctx);
13067 gen_helper_subuh_ob(cpu_gpr[ret], v1_t, v2_t);
13068 break;
13069 case OPC_SUBUH_R_OB:
13070 check_dspr2(ctx);
13071 gen_helper_subuh_r_ob(cpu_gpr[ret], v1_t, v2_t);
13072 break;
13073 case OPC_ADDQ_PW:
13074 check_dsp(ctx);
13075 gen_helper_addq_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13076 break;
13077 case OPC_ADDQ_S_PW:
13078 check_dsp(ctx);
13079 gen_helper_addq_s_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13080 break;
13081 case OPC_ADDQ_QH:
13082 check_dsp(ctx);
13083 gen_helper_addq_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13084 break;
13085 case OPC_ADDQ_S_QH:
13086 check_dsp(ctx);
13087 gen_helper_addq_s_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13088 break;
13089 case OPC_ADDU_OB:
13090 check_dsp(ctx);
13091 gen_helper_addu_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13092 break;
13093 case OPC_ADDU_S_OB:
13094 check_dsp(ctx);
13095 gen_helper_addu_s_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13096 break;
13097 case OPC_ADDU_QH:
13098 check_dspr2(ctx);
13099 gen_helper_addu_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13100 break;
13101 case OPC_ADDU_S_QH:
13102 check_dspr2(ctx);
13103 gen_helper_addu_s_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13104 break;
13105 case OPC_ADDUH_OB:
13106 check_dspr2(ctx);
13107 gen_helper_adduh_ob(cpu_gpr[ret], v1_t, v2_t);
13108 break;
13109 case OPC_ADDUH_R_OB:
13110 check_dspr2(ctx);
13111 gen_helper_adduh_r_ob(cpu_gpr[ret], v1_t, v2_t);
13112 break;
13114 break;
13115 case OPC_CMPU_EQ_OB_DSP:
13116 switch (op2) {
13117 case OPC_PRECR_OB_QH:
13118 check_dspr2(ctx);
13119 gen_helper_precr_ob_qh(cpu_gpr[ret], v1_t, v2_t);
13120 break;
13121 case OPC_PRECR_SRA_QH_PW:
13122 check_dspr2(ctx);
13124 TCGv_i32 ret_t = tcg_const_i32(ret);
13125 gen_helper_precr_sra_qh_pw(v2_t, v1_t, v2_t, ret_t);
13126 tcg_temp_free_i32(ret_t);
13127 break;
13129 case OPC_PRECR_SRA_R_QH_PW:
13130 check_dspr2(ctx);
13132 TCGv_i32 sa_v = tcg_const_i32(ret);
13133 gen_helper_precr_sra_r_qh_pw(v2_t, v1_t, v2_t, sa_v);
13134 tcg_temp_free_i32(sa_v);
13135 break;
13137 case OPC_PRECRQ_OB_QH:
13138 check_dsp(ctx);
13139 gen_helper_precrq_ob_qh(cpu_gpr[ret], v1_t, v2_t);
13140 break;
13141 case OPC_PRECRQ_PW_L:
13142 check_dsp(ctx);
13143 gen_helper_precrq_pw_l(cpu_gpr[ret], v1_t, v2_t);
13144 break;
13145 case OPC_PRECRQ_QH_PW:
13146 check_dsp(ctx);
13147 gen_helper_precrq_qh_pw(cpu_gpr[ret], v1_t, v2_t);
13148 break;
13149 case OPC_PRECRQ_RS_QH_PW:
13150 check_dsp(ctx);
13151 gen_helper_precrq_rs_qh_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13152 break;
13153 case OPC_PRECRQU_S_OB_QH:
13154 check_dsp(ctx);
13155 gen_helper_precrqu_s_ob_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13156 break;
13158 break;
13159 #endif
13162 tcg_temp_free(v1_t);
13163 tcg_temp_free(v2_t);
13165 (void)opn; /* avoid a compiler warning */
13166 MIPS_DEBUG("%s", opn);
13169 static void gen_mipsdsp_shift(DisasContext *ctx, uint32_t opc,
13170 int ret, int v1, int v2)
13172 uint32_t op2;
13173 const char *opn = "mipsdsp shift";
13174 TCGv t0;
13175 TCGv v1_t;
13176 TCGv v2_t;
13178 if (ret == 0) {
13179 /* Treat as NOP. */
13180 MIPS_DEBUG("NOP");
13181 return;
13184 t0 = tcg_temp_new();
13185 v1_t = tcg_temp_new();
13186 v2_t = tcg_temp_new();
13188 tcg_gen_movi_tl(t0, v1);
13189 gen_load_gpr(v1_t, v1);
13190 gen_load_gpr(v2_t, v2);
13192 switch (opc) {
13193 case OPC_SHLL_QB_DSP:
13195 op2 = MASK_SHLL_QB(ctx->opcode);
13196 switch (op2) {
13197 case OPC_SHLL_QB:
13198 check_dsp(ctx);
13199 gen_helper_shll_qb(cpu_gpr[ret], t0, v2_t, cpu_env);
13200 break;
13201 case OPC_SHLLV_QB:
13202 check_dsp(ctx);
13203 gen_helper_shll_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13204 break;
13205 case OPC_SHLL_PH:
13206 check_dsp(ctx);
13207 gen_helper_shll_ph(cpu_gpr[ret], t0, v2_t, cpu_env);
13208 break;
13209 case OPC_SHLLV_PH:
13210 check_dsp(ctx);
13211 gen_helper_shll_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13212 break;
13213 case OPC_SHLL_S_PH:
13214 check_dsp(ctx);
13215 gen_helper_shll_s_ph(cpu_gpr[ret], t0, v2_t, cpu_env);
13216 break;
13217 case OPC_SHLLV_S_PH:
13218 check_dsp(ctx);
13219 gen_helper_shll_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13220 break;
13221 case OPC_SHLL_S_W:
13222 check_dsp(ctx);
13223 gen_helper_shll_s_w(cpu_gpr[ret], t0, v2_t, cpu_env);
13224 break;
13225 case OPC_SHLLV_S_W:
13226 check_dsp(ctx);
13227 gen_helper_shll_s_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13228 break;
13229 case OPC_SHRL_QB:
13230 check_dsp(ctx);
13231 gen_helper_shrl_qb(cpu_gpr[ret], t0, v2_t);
13232 break;
13233 case OPC_SHRLV_QB:
13234 check_dsp(ctx);
13235 gen_helper_shrl_qb(cpu_gpr[ret], v1_t, v2_t);
13236 break;
13237 case OPC_SHRL_PH:
13238 check_dspr2(ctx);
13239 gen_helper_shrl_ph(cpu_gpr[ret], t0, v2_t);
13240 break;
13241 case OPC_SHRLV_PH:
13242 check_dspr2(ctx);
13243 gen_helper_shrl_ph(cpu_gpr[ret], v1_t, v2_t);
13244 break;
13245 case OPC_SHRA_QB:
13246 check_dspr2(ctx);
13247 gen_helper_shra_qb(cpu_gpr[ret], t0, v2_t);
13248 break;
13249 case OPC_SHRA_R_QB:
13250 check_dspr2(ctx);
13251 gen_helper_shra_r_qb(cpu_gpr[ret], t0, v2_t);
13252 break;
13253 case OPC_SHRAV_QB:
13254 check_dspr2(ctx);
13255 gen_helper_shra_qb(cpu_gpr[ret], v1_t, v2_t);
13256 break;
13257 case OPC_SHRAV_R_QB:
13258 check_dspr2(ctx);
13259 gen_helper_shra_r_qb(cpu_gpr[ret], v1_t, v2_t);
13260 break;
13261 case OPC_SHRA_PH:
13262 check_dsp(ctx);
13263 gen_helper_shra_ph(cpu_gpr[ret], t0, v2_t);
13264 break;
13265 case OPC_SHRA_R_PH:
13266 check_dsp(ctx);
13267 gen_helper_shra_r_ph(cpu_gpr[ret], t0, v2_t);
13268 break;
13269 case OPC_SHRAV_PH:
13270 check_dsp(ctx);
13271 gen_helper_shra_ph(cpu_gpr[ret], v1_t, v2_t);
13272 break;
13273 case OPC_SHRAV_R_PH:
13274 check_dsp(ctx);
13275 gen_helper_shra_r_ph(cpu_gpr[ret], v1_t, v2_t);
13276 break;
13277 case OPC_SHRA_R_W:
13278 check_dsp(ctx);
13279 gen_helper_shra_r_w(cpu_gpr[ret], t0, v2_t);
13280 break;
13281 case OPC_SHRAV_R_W:
13282 check_dsp(ctx);
13283 gen_helper_shra_r_w(cpu_gpr[ret], v1_t, v2_t);
13284 break;
13285 default: /* Invalid */
13286 MIPS_INVAL("MASK SHLL.QB");
13287 generate_exception(ctx, EXCP_RI);
13288 break;
13290 break;
13292 #ifdef TARGET_MIPS64
13293 case OPC_SHLL_OB_DSP:
13294 op2 = MASK_SHLL_OB(ctx->opcode);
13295 switch (op2) {
13296 case OPC_SHLL_PW:
13297 check_dsp(ctx);
13298 gen_helper_shll_pw(cpu_gpr[ret], v2_t, t0, cpu_env);
13299 break;
13300 case OPC_SHLLV_PW:
13301 check_dsp(ctx);
13302 gen_helper_shll_pw(cpu_gpr[ret], v2_t, v1_t, cpu_env);
13303 break;
13304 case OPC_SHLL_S_PW:
13305 check_dsp(ctx);
13306 gen_helper_shll_s_pw(cpu_gpr[ret], v2_t, t0, cpu_env);
13307 break;
13308 case OPC_SHLLV_S_PW:
13309 check_dsp(ctx);
13310 gen_helper_shll_s_pw(cpu_gpr[ret], v2_t, v1_t, cpu_env);
13311 break;
13312 case OPC_SHLL_OB:
13313 check_dsp(ctx);
13314 gen_helper_shll_ob(cpu_gpr[ret], v2_t, t0, cpu_env);
13315 break;
13316 case OPC_SHLLV_OB:
13317 check_dsp(ctx);
13318 gen_helper_shll_ob(cpu_gpr[ret], v2_t, v1_t, cpu_env);
13319 break;
13320 case OPC_SHLL_QH:
13321 check_dsp(ctx);
13322 gen_helper_shll_qh(cpu_gpr[ret], v2_t, t0, cpu_env);
13323 break;
13324 case OPC_SHLLV_QH:
13325 check_dsp(ctx);
13326 gen_helper_shll_qh(cpu_gpr[ret], v2_t, v1_t, cpu_env);
13327 break;
13328 case OPC_SHLL_S_QH:
13329 check_dsp(ctx);
13330 gen_helper_shll_s_qh(cpu_gpr[ret], v2_t, t0, cpu_env);
13331 break;
13332 case OPC_SHLLV_S_QH:
13333 check_dsp(ctx);
13334 gen_helper_shll_s_qh(cpu_gpr[ret], v2_t, v1_t, cpu_env);
13335 break;
13336 case OPC_SHRA_OB:
13337 check_dspr2(ctx);
13338 gen_helper_shra_ob(cpu_gpr[ret], v2_t, t0);
13339 break;
13340 case OPC_SHRAV_OB:
13341 check_dspr2(ctx);
13342 gen_helper_shra_ob(cpu_gpr[ret], v2_t, v1_t);
13343 break;
13344 case OPC_SHRA_R_OB:
13345 check_dspr2(ctx);
13346 gen_helper_shra_r_ob(cpu_gpr[ret], v2_t, t0);
13347 break;
13348 case OPC_SHRAV_R_OB:
13349 check_dspr2(ctx);
13350 gen_helper_shra_r_ob(cpu_gpr[ret], v2_t, v1_t);
13351 break;
13352 case OPC_SHRA_PW:
13353 check_dsp(ctx);
13354 gen_helper_shra_pw(cpu_gpr[ret], v2_t, t0);
13355 break;
13356 case OPC_SHRAV_PW:
13357 check_dsp(ctx);
13358 gen_helper_shra_pw(cpu_gpr[ret], v2_t, v1_t);
13359 break;
13360 case OPC_SHRA_R_PW:
13361 check_dsp(ctx);
13362 gen_helper_shra_r_pw(cpu_gpr[ret], v2_t, t0);
13363 break;
13364 case OPC_SHRAV_R_PW:
13365 check_dsp(ctx);
13366 gen_helper_shra_r_pw(cpu_gpr[ret], v2_t, v1_t);
13367 break;
13368 case OPC_SHRA_QH:
13369 check_dsp(ctx);
13370 gen_helper_shra_qh(cpu_gpr[ret], v2_t, t0);
13371 break;
13372 case OPC_SHRAV_QH:
13373 check_dsp(ctx);
13374 gen_helper_shra_qh(cpu_gpr[ret], v2_t, v1_t);
13375 break;
13376 case OPC_SHRA_R_QH:
13377 check_dsp(ctx);
13378 gen_helper_shra_r_qh(cpu_gpr[ret], v2_t, t0);
13379 break;
13380 case OPC_SHRAV_R_QH:
13381 check_dsp(ctx);
13382 gen_helper_shra_r_qh(cpu_gpr[ret], v2_t, v1_t);
13383 break;
13384 case OPC_SHRL_OB:
13385 check_dsp(ctx);
13386 gen_helper_shrl_ob(cpu_gpr[ret], v2_t, t0);
13387 break;
13388 case OPC_SHRLV_OB:
13389 check_dsp(ctx);
13390 gen_helper_shrl_ob(cpu_gpr[ret], v2_t, v1_t);
13391 break;
13392 case OPC_SHRL_QH:
13393 check_dspr2(ctx);
13394 gen_helper_shrl_qh(cpu_gpr[ret], v2_t, t0);
13395 break;
13396 case OPC_SHRLV_QH:
13397 check_dspr2(ctx);
13398 gen_helper_shrl_qh(cpu_gpr[ret], v2_t, v1_t);
13399 break;
13400 default: /* Invalid */
13401 MIPS_INVAL("MASK SHLL.OB");
13402 generate_exception(ctx, EXCP_RI);
13403 break;
13405 break;
13406 #endif
13409 tcg_temp_free(t0);
13410 tcg_temp_free(v1_t);
13411 tcg_temp_free(v2_t);
13412 (void)opn; /* avoid a compiler warning */
13413 MIPS_DEBUG("%s", opn);
13416 static void gen_mipsdsp_multiply(DisasContext *ctx, uint32_t op1, uint32_t op2,
13417 int ret, int v1, int v2, int check_ret)
13419 const char *opn = "mipsdsp multiply";
13420 TCGv_i32 t0;
13421 TCGv v1_t;
13422 TCGv v2_t;
13424 if ((ret == 0) && (check_ret == 1)) {
13425 /* Treat as NOP. */
13426 MIPS_DEBUG("NOP");
13427 return;
13430 t0 = tcg_temp_new_i32();
13431 v1_t = tcg_temp_new();
13432 v2_t = tcg_temp_new();
13434 tcg_gen_movi_i32(t0, ret);
13435 gen_load_gpr(v1_t, v1);
13436 gen_load_gpr(v2_t, v2);
13438 switch (op1) {
13439 /* OPC_MULT_G_2E, OPC_ADDUH_QB_DSP, OPC_MUL_PH_DSP have
13440 * the same mask and op1. */
13441 case OPC_MULT_G_2E:
13442 check_dspr2(ctx);
13443 switch (op2) {
13444 case OPC_MUL_PH:
13445 gen_helper_mul_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13446 break;
13447 case OPC_MUL_S_PH:
13448 gen_helper_mul_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13449 break;
13450 case OPC_MULQ_S_W:
13451 gen_helper_mulq_s_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13452 break;
13453 case OPC_MULQ_RS_W:
13454 gen_helper_mulq_rs_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13455 break;
13457 break;
13458 case OPC_DPA_W_PH_DSP:
13459 switch (op2) {
13460 case OPC_DPAU_H_QBL:
13461 check_dsp(ctx);
13462 gen_helper_dpau_h_qbl(t0, v1_t, v2_t, cpu_env);
13463 break;
13464 case OPC_DPAU_H_QBR:
13465 check_dsp(ctx);
13466 gen_helper_dpau_h_qbr(t0, v1_t, v2_t, cpu_env);
13467 break;
13468 case OPC_DPSU_H_QBL:
13469 check_dsp(ctx);
13470 gen_helper_dpsu_h_qbl(t0, v1_t, v2_t, cpu_env);
13471 break;
13472 case OPC_DPSU_H_QBR:
13473 check_dsp(ctx);
13474 gen_helper_dpsu_h_qbr(t0, v1_t, v2_t, cpu_env);
13475 break;
13476 case OPC_DPA_W_PH:
13477 check_dspr2(ctx);
13478 gen_helper_dpa_w_ph(t0, v1_t, v2_t, cpu_env);
13479 break;
13480 case OPC_DPAX_W_PH:
13481 check_dspr2(ctx);
13482 gen_helper_dpax_w_ph(t0, v1_t, v2_t, cpu_env);
13483 break;
13484 case OPC_DPAQ_S_W_PH:
13485 check_dsp(ctx);
13486 gen_helper_dpaq_s_w_ph(t0, v1_t, v2_t, cpu_env);
13487 break;
13488 case OPC_DPAQX_S_W_PH:
13489 check_dspr2(ctx);
13490 gen_helper_dpaqx_s_w_ph(t0, v1_t, v2_t, cpu_env);
13491 break;
13492 case OPC_DPAQX_SA_W_PH:
13493 check_dspr2(ctx);
13494 gen_helper_dpaqx_sa_w_ph(t0, v1_t, v2_t, cpu_env);
13495 break;
13496 case OPC_DPS_W_PH:
13497 check_dspr2(ctx);
13498 gen_helper_dps_w_ph(t0, v1_t, v2_t, cpu_env);
13499 break;
13500 case OPC_DPSX_W_PH:
13501 check_dspr2(ctx);
13502 gen_helper_dpsx_w_ph(t0, v1_t, v2_t, cpu_env);
13503 break;
13504 case OPC_DPSQ_S_W_PH:
13505 check_dsp(ctx);
13506 gen_helper_dpsq_s_w_ph(t0, v1_t, v2_t, cpu_env);
13507 break;
13508 case OPC_DPSQX_S_W_PH:
13509 check_dspr2(ctx);
13510 gen_helper_dpsqx_s_w_ph(t0, v1_t, v2_t, cpu_env);
13511 break;
13512 case OPC_DPSQX_SA_W_PH:
13513 check_dspr2(ctx);
13514 gen_helper_dpsqx_sa_w_ph(t0, v1_t, v2_t, cpu_env);
13515 break;
13516 case OPC_MULSAQ_S_W_PH:
13517 check_dsp(ctx);
13518 gen_helper_mulsaq_s_w_ph(t0, v1_t, v2_t, cpu_env);
13519 break;
13520 case OPC_DPAQ_SA_L_W:
13521 check_dsp(ctx);
13522 gen_helper_dpaq_sa_l_w(t0, v1_t, v2_t, cpu_env);
13523 break;
13524 case OPC_DPSQ_SA_L_W:
13525 check_dsp(ctx);
13526 gen_helper_dpsq_sa_l_w(t0, v1_t, v2_t, cpu_env);
13527 break;
13528 case OPC_MAQ_S_W_PHL:
13529 check_dsp(ctx);
13530 gen_helper_maq_s_w_phl(t0, v1_t, v2_t, cpu_env);
13531 break;
13532 case OPC_MAQ_S_W_PHR:
13533 check_dsp(ctx);
13534 gen_helper_maq_s_w_phr(t0, v1_t, v2_t, cpu_env);
13535 break;
13536 case OPC_MAQ_SA_W_PHL:
13537 check_dsp(ctx);
13538 gen_helper_maq_sa_w_phl(t0, v1_t, v2_t, cpu_env);
13539 break;
13540 case OPC_MAQ_SA_W_PHR:
13541 check_dsp(ctx);
13542 gen_helper_maq_sa_w_phr(t0, v1_t, v2_t, cpu_env);
13543 break;
13544 case OPC_MULSA_W_PH:
13545 check_dspr2(ctx);
13546 gen_helper_mulsa_w_ph(t0, v1_t, v2_t, cpu_env);
13547 break;
13549 break;
13550 #ifdef TARGET_MIPS64
13551 case OPC_DPAQ_W_QH_DSP:
13553 int ac = ret & 0x03;
13554 tcg_gen_movi_i32(t0, ac);
13556 switch (op2) {
13557 case OPC_DMADD:
13558 check_dsp(ctx);
13559 gen_helper_dmadd(v1_t, v2_t, t0, cpu_env);
13560 break;
13561 case OPC_DMADDU:
13562 check_dsp(ctx);
13563 gen_helper_dmaddu(v1_t, v2_t, t0, cpu_env);
13564 break;
13565 case OPC_DMSUB:
13566 check_dsp(ctx);
13567 gen_helper_dmsub(v1_t, v2_t, t0, cpu_env);
13568 break;
13569 case OPC_DMSUBU:
13570 check_dsp(ctx);
13571 gen_helper_dmsubu(v1_t, v2_t, t0, cpu_env);
13572 break;
13573 case OPC_DPA_W_QH:
13574 check_dspr2(ctx);
13575 gen_helper_dpa_w_qh(v1_t, v2_t, t0, cpu_env);
13576 break;
13577 case OPC_DPAQ_S_W_QH:
13578 check_dsp(ctx);
13579 gen_helper_dpaq_s_w_qh(v1_t, v2_t, t0, cpu_env);
13580 break;
13581 case OPC_DPAQ_SA_L_PW:
13582 check_dsp(ctx);
13583 gen_helper_dpaq_sa_l_pw(v1_t, v2_t, t0, cpu_env);
13584 break;
13585 case OPC_DPAU_H_OBL:
13586 check_dsp(ctx);
13587 gen_helper_dpau_h_obl(v1_t, v2_t, t0, cpu_env);
13588 break;
13589 case OPC_DPAU_H_OBR:
13590 check_dsp(ctx);
13591 gen_helper_dpau_h_obr(v1_t, v2_t, t0, cpu_env);
13592 break;
13593 case OPC_DPS_W_QH:
13594 check_dspr2(ctx);
13595 gen_helper_dps_w_qh(v1_t, v2_t, t0, cpu_env);
13596 break;
13597 case OPC_DPSQ_S_W_QH:
13598 check_dsp(ctx);
13599 gen_helper_dpsq_s_w_qh(v1_t, v2_t, t0, cpu_env);
13600 break;
13601 case OPC_DPSQ_SA_L_PW:
13602 check_dsp(ctx);
13603 gen_helper_dpsq_sa_l_pw(v1_t, v2_t, t0, cpu_env);
13604 break;
13605 case OPC_DPSU_H_OBL:
13606 check_dsp(ctx);
13607 gen_helper_dpsu_h_obl(v1_t, v2_t, t0, cpu_env);
13608 break;
13609 case OPC_DPSU_H_OBR:
13610 check_dsp(ctx);
13611 gen_helper_dpsu_h_obr(v1_t, v2_t, t0, cpu_env);
13612 break;
13613 case OPC_MAQ_S_L_PWL:
13614 check_dsp(ctx);
13615 gen_helper_maq_s_l_pwl(v1_t, v2_t, t0, cpu_env);
13616 break;
13617 case OPC_MAQ_S_L_PWR:
13618 check_dsp(ctx);
13619 gen_helper_maq_s_l_pwr(v1_t, v2_t, t0, cpu_env);
13620 break;
13621 case OPC_MAQ_S_W_QHLL:
13622 check_dsp(ctx);
13623 gen_helper_maq_s_w_qhll(v1_t, v2_t, t0, cpu_env);
13624 break;
13625 case OPC_MAQ_SA_W_QHLL:
13626 check_dsp(ctx);
13627 gen_helper_maq_sa_w_qhll(v1_t, v2_t, t0, cpu_env);
13628 break;
13629 case OPC_MAQ_S_W_QHLR:
13630 check_dsp(ctx);
13631 gen_helper_maq_s_w_qhlr(v1_t, v2_t, t0, cpu_env);
13632 break;
13633 case OPC_MAQ_SA_W_QHLR:
13634 check_dsp(ctx);
13635 gen_helper_maq_sa_w_qhlr(v1_t, v2_t, t0, cpu_env);
13636 break;
13637 case OPC_MAQ_S_W_QHRL:
13638 check_dsp(ctx);
13639 gen_helper_maq_s_w_qhrl(v1_t, v2_t, t0, cpu_env);
13640 break;
13641 case OPC_MAQ_SA_W_QHRL:
13642 check_dsp(ctx);
13643 gen_helper_maq_sa_w_qhrl(v1_t, v2_t, t0, cpu_env);
13644 break;
13645 case OPC_MAQ_S_W_QHRR:
13646 check_dsp(ctx);
13647 gen_helper_maq_s_w_qhrr(v1_t, v2_t, t0, cpu_env);
13648 break;
13649 case OPC_MAQ_SA_W_QHRR:
13650 check_dsp(ctx);
13651 gen_helper_maq_sa_w_qhrr(v1_t, v2_t, t0, cpu_env);
13652 break;
13653 case OPC_MULSAQ_S_L_PW:
13654 check_dsp(ctx);
13655 gen_helper_mulsaq_s_l_pw(v1_t, v2_t, t0, cpu_env);
13656 break;
13657 case OPC_MULSAQ_S_W_QH:
13658 check_dsp(ctx);
13659 gen_helper_mulsaq_s_w_qh(v1_t, v2_t, t0, cpu_env);
13660 break;
13663 break;
13664 #endif
13665 case OPC_ADDU_QB_DSP:
13666 switch (op2) {
13667 case OPC_MULEU_S_PH_QBL:
13668 check_dsp(ctx);
13669 gen_helper_muleu_s_ph_qbl(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13670 break;
13671 case OPC_MULEU_S_PH_QBR:
13672 check_dsp(ctx);
13673 gen_helper_muleu_s_ph_qbr(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13674 break;
13675 case OPC_MULQ_RS_PH:
13676 check_dsp(ctx);
13677 gen_helper_mulq_rs_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13678 break;
13679 case OPC_MULEQ_S_W_PHL:
13680 check_dsp(ctx);
13681 gen_helper_muleq_s_w_phl(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13682 break;
13683 case OPC_MULEQ_S_W_PHR:
13684 check_dsp(ctx);
13685 gen_helper_muleq_s_w_phr(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13686 break;
13687 case OPC_MULQ_S_PH:
13688 check_dspr2(ctx);
13689 gen_helper_mulq_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13690 break;
13692 break;
13693 #ifdef TARGET_MIPS64
13694 case OPC_ADDU_OB_DSP:
13695 switch (op2) {
13696 case OPC_MULEQ_S_PW_QHL:
13697 check_dsp(ctx);
13698 gen_helper_muleq_s_pw_qhl(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13699 break;
13700 case OPC_MULEQ_S_PW_QHR:
13701 check_dsp(ctx);
13702 gen_helper_muleq_s_pw_qhr(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13703 break;
13704 case OPC_MULEU_S_QH_OBL:
13705 check_dsp(ctx);
13706 gen_helper_muleu_s_qh_obl(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13707 break;
13708 case OPC_MULEU_S_QH_OBR:
13709 check_dsp(ctx);
13710 gen_helper_muleu_s_qh_obr(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13711 break;
13712 case OPC_MULQ_RS_QH:
13713 check_dsp(ctx);
13714 gen_helper_mulq_rs_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13715 break;
13717 break;
13718 #endif
13721 tcg_temp_free_i32(t0);
13722 tcg_temp_free(v1_t);
13723 tcg_temp_free(v2_t);
13725 (void)opn; /* avoid a compiler warning */
13726 MIPS_DEBUG("%s", opn);
13730 static void gen_mipsdsp_bitinsn(DisasContext *ctx, uint32_t op1, uint32_t op2,
13731 int ret, int val)
13733 const char *opn = "mipsdsp Bit/ Manipulation";
13734 int16_t imm;
13735 TCGv t0;
13736 TCGv val_t;
13738 if (ret == 0) {
13739 /* Treat as NOP. */
13740 MIPS_DEBUG("NOP");
13741 return;
13744 t0 = tcg_temp_new();
13745 val_t = tcg_temp_new();
13746 gen_load_gpr(val_t, val);
13748 switch (op1) {
13749 case OPC_ABSQ_S_PH_DSP:
13750 switch (op2) {
13751 case OPC_BITREV:
13752 check_dsp(ctx);
13753 gen_helper_bitrev(cpu_gpr[ret], val_t);
13754 break;
13755 case OPC_REPL_QB:
13756 check_dsp(ctx);
13758 target_long result;
13759 imm = (ctx->opcode >> 16) & 0xFF;
13760 result = (uint32_t)imm << 24 |
13761 (uint32_t)imm << 16 |
13762 (uint32_t)imm << 8 |
13763 (uint32_t)imm;
13764 result = (int32_t)result;
13765 tcg_gen_movi_tl(cpu_gpr[ret], result);
13767 break;
13768 case OPC_REPLV_QB:
13769 check_dsp(ctx);
13770 tcg_gen_ext8u_tl(cpu_gpr[ret], val_t);
13771 tcg_gen_shli_tl(t0, cpu_gpr[ret], 8);
13772 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
13773 tcg_gen_shli_tl(t0, cpu_gpr[ret], 16);
13774 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
13775 tcg_gen_ext32s_tl(cpu_gpr[ret], cpu_gpr[ret]);
13776 break;
13777 case OPC_REPL_PH:
13778 check_dsp(ctx);
13780 imm = (ctx->opcode >> 16) & 0x03FF;
13781 imm = (int16_t)(imm << 6) >> 6;
13782 tcg_gen_movi_tl(cpu_gpr[ret], \
13783 (target_long)((int32_t)imm << 16 | \
13784 (uint16_t)imm));
13786 break;
13787 case OPC_REPLV_PH:
13788 check_dsp(ctx);
13789 tcg_gen_ext16u_tl(cpu_gpr[ret], val_t);
13790 tcg_gen_shli_tl(t0, cpu_gpr[ret], 16);
13791 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
13792 tcg_gen_ext32s_tl(cpu_gpr[ret], cpu_gpr[ret]);
13793 break;
13795 break;
13796 #ifdef TARGET_MIPS64
13797 case OPC_ABSQ_S_QH_DSP:
13798 switch (op2) {
13799 case OPC_REPL_OB:
13800 check_dsp(ctx);
13802 target_long temp;
13804 imm = (ctx->opcode >> 16) & 0xFF;
13805 temp = ((uint64_t)imm << 8) | (uint64_t)imm;
13806 temp = (temp << 16) | temp;
13807 temp = (temp << 32) | temp;
13808 tcg_gen_movi_tl(cpu_gpr[ret], temp);
13809 break;
13811 case OPC_REPL_PW:
13812 check_dsp(ctx);
13814 target_long temp;
13816 imm = (ctx->opcode >> 16) & 0x03FF;
13817 imm = (int16_t)(imm << 6) >> 6;
13818 temp = ((target_long)imm << 32) \
13819 | ((target_long)imm & 0xFFFFFFFF);
13820 tcg_gen_movi_tl(cpu_gpr[ret], temp);
13821 break;
13823 case OPC_REPL_QH:
13824 check_dsp(ctx);
13826 target_long temp;
13828 imm = (ctx->opcode >> 16) & 0x03FF;
13829 imm = (int16_t)(imm << 6) >> 6;
13831 temp = ((uint64_t)(uint16_t)imm << 48) |
13832 ((uint64_t)(uint16_t)imm << 32) |
13833 ((uint64_t)(uint16_t)imm << 16) |
13834 (uint64_t)(uint16_t)imm;
13835 tcg_gen_movi_tl(cpu_gpr[ret], temp);
13836 break;
13838 case OPC_REPLV_OB:
13839 check_dsp(ctx);
13840 tcg_gen_ext8u_tl(cpu_gpr[ret], val_t);
13841 tcg_gen_shli_tl(t0, cpu_gpr[ret], 8);
13842 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
13843 tcg_gen_shli_tl(t0, cpu_gpr[ret], 16);
13844 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
13845 tcg_gen_shli_tl(t0, cpu_gpr[ret], 32);
13846 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
13847 break;
13848 case OPC_REPLV_PW:
13849 check_dsp(ctx);
13850 tcg_gen_ext32u_i64(cpu_gpr[ret], val_t);
13851 tcg_gen_shli_tl(t0, cpu_gpr[ret], 32);
13852 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
13853 break;
13854 case OPC_REPLV_QH:
13855 check_dsp(ctx);
13856 tcg_gen_ext16u_tl(cpu_gpr[ret], val_t);
13857 tcg_gen_shli_tl(t0, cpu_gpr[ret], 16);
13858 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
13859 tcg_gen_shli_tl(t0, cpu_gpr[ret], 32);
13860 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
13861 break;
13863 break;
13864 #endif
13866 tcg_temp_free(t0);
13867 tcg_temp_free(val_t);
13869 (void)opn; /* avoid a compiler warning */
13870 MIPS_DEBUG("%s", opn);
13873 static void gen_mipsdsp_add_cmp_pick(DisasContext *ctx,
13874 uint32_t op1, uint32_t op2,
13875 int ret, int v1, int v2, int check_ret)
13877 const char *opn = "mipsdsp add compare pick";
13878 TCGv t1;
13879 TCGv v1_t;
13880 TCGv v2_t;
13882 if ((ret == 0) && (check_ret == 1)) {
13883 /* Treat as NOP. */
13884 MIPS_DEBUG("NOP");
13885 return;
13888 t1 = tcg_temp_new();
13889 v1_t = tcg_temp_new();
13890 v2_t = tcg_temp_new();
13892 gen_load_gpr(v1_t, v1);
13893 gen_load_gpr(v2_t, v2);
13895 switch (op1) {
13896 case OPC_CMPU_EQ_QB_DSP:
13897 switch (op2) {
13898 case OPC_CMPU_EQ_QB:
13899 check_dsp(ctx);
13900 gen_helper_cmpu_eq_qb(v1_t, v2_t, cpu_env);
13901 break;
13902 case OPC_CMPU_LT_QB:
13903 check_dsp(ctx);
13904 gen_helper_cmpu_lt_qb(v1_t, v2_t, cpu_env);
13905 break;
13906 case OPC_CMPU_LE_QB:
13907 check_dsp(ctx);
13908 gen_helper_cmpu_le_qb(v1_t, v2_t, cpu_env);
13909 break;
13910 case OPC_CMPGU_EQ_QB:
13911 check_dsp(ctx);
13912 gen_helper_cmpgu_eq_qb(cpu_gpr[ret], v1_t, v2_t);
13913 break;
13914 case OPC_CMPGU_LT_QB:
13915 check_dsp(ctx);
13916 gen_helper_cmpgu_lt_qb(cpu_gpr[ret], v1_t, v2_t);
13917 break;
13918 case OPC_CMPGU_LE_QB:
13919 check_dsp(ctx);
13920 gen_helper_cmpgu_le_qb(cpu_gpr[ret], v1_t, v2_t);
13921 break;
13922 case OPC_CMPGDU_EQ_QB:
13923 check_dspr2(ctx);
13924 gen_helper_cmpgu_eq_qb(t1, v1_t, v2_t);
13925 tcg_gen_mov_tl(cpu_gpr[ret], t1);
13926 tcg_gen_andi_tl(cpu_dspctrl, cpu_dspctrl, 0xF0FFFFFF);
13927 tcg_gen_shli_tl(t1, t1, 24);
13928 tcg_gen_or_tl(cpu_dspctrl, cpu_dspctrl, t1);
13929 break;
13930 case OPC_CMPGDU_LT_QB:
13931 check_dspr2(ctx);
13932 gen_helper_cmpgu_lt_qb(t1, v1_t, v2_t);
13933 tcg_gen_mov_tl(cpu_gpr[ret], t1);
13934 tcg_gen_andi_tl(cpu_dspctrl, cpu_dspctrl, 0xF0FFFFFF);
13935 tcg_gen_shli_tl(t1, t1, 24);
13936 tcg_gen_or_tl(cpu_dspctrl, cpu_dspctrl, t1);
13937 break;
13938 case OPC_CMPGDU_LE_QB:
13939 check_dspr2(ctx);
13940 gen_helper_cmpgu_le_qb(t1, v1_t, v2_t);
13941 tcg_gen_mov_tl(cpu_gpr[ret], t1);
13942 tcg_gen_andi_tl(cpu_dspctrl, cpu_dspctrl, 0xF0FFFFFF);
13943 tcg_gen_shli_tl(t1, t1, 24);
13944 tcg_gen_or_tl(cpu_dspctrl, cpu_dspctrl, t1);
13945 break;
13946 case OPC_CMP_EQ_PH:
13947 check_dsp(ctx);
13948 gen_helper_cmp_eq_ph(v1_t, v2_t, cpu_env);
13949 break;
13950 case OPC_CMP_LT_PH:
13951 check_dsp(ctx);
13952 gen_helper_cmp_lt_ph(v1_t, v2_t, cpu_env);
13953 break;
13954 case OPC_CMP_LE_PH:
13955 check_dsp(ctx);
13956 gen_helper_cmp_le_ph(v1_t, v2_t, cpu_env);
13957 break;
13958 case OPC_PICK_QB:
13959 check_dsp(ctx);
13960 gen_helper_pick_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13961 break;
13962 case OPC_PICK_PH:
13963 check_dsp(ctx);
13964 gen_helper_pick_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13965 break;
13966 case OPC_PACKRL_PH:
13967 check_dsp(ctx);
13968 gen_helper_packrl_ph(cpu_gpr[ret], v1_t, v2_t);
13969 break;
13971 break;
13972 #ifdef TARGET_MIPS64
13973 case OPC_CMPU_EQ_OB_DSP:
13974 switch (op2) {
13975 case OPC_CMP_EQ_PW:
13976 check_dsp(ctx);
13977 gen_helper_cmp_eq_pw(v1_t, v2_t, cpu_env);
13978 break;
13979 case OPC_CMP_LT_PW:
13980 check_dsp(ctx);
13981 gen_helper_cmp_lt_pw(v1_t, v2_t, cpu_env);
13982 break;
13983 case OPC_CMP_LE_PW:
13984 check_dsp(ctx);
13985 gen_helper_cmp_le_pw(v1_t, v2_t, cpu_env);
13986 break;
13987 case OPC_CMP_EQ_QH:
13988 check_dsp(ctx);
13989 gen_helper_cmp_eq_qh(v1_t, v2_t, cpu_env);
13990 break;
13991 case OPC_CMP_LT_QH:
13992 check_dsp(ctx);
13993 gen_helper_cmp_lt_qh(v1_t, v2_t, cpu_env);
13994 break;
13995 case OPC_CMP_LE_QH:
13996 check_dsp(ctx);
13997 gen_helper_cmp_le_qh(v1_t, v2_t, cpu_env);
13998 break;
13999 case OPC_CMPGDU_EQ_OB:
14000 check_dspr2(ctx);
14001 gen_helper_cmpgdu_eq_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
14002 break;
14003 case OPC_CMPGDU_LT_OB:
14004 check_dspr2(ctx);
14005 gen_helper_cmpgdu_lt_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
14006 break;
14007 case OPC_CMPGDU_LE_OB:
14008 check_dspr2(ctx);
14009 gen_helper_cmpgdu_le_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
14010 break;
14011 case OPC_CMPGU_EQ_OB:
14012 check_dsp(ctx);
14013 gen_helper_cmpgu_eq_ob(cpu_gpr[ret], v1_t, v2_t);
14014 break;
14015 case OPC_CMPGU_LT_OB:
14016 check_dsp(ctx);
14017 gen_helper_cmpgu_lt_ob(cpu_gpr[ret], v1_t, v2_t);
14018 break;
14019 case OPC_CMPGU_LE_OB:
14020 check_dsp(ctx);
14021 gen_helper_cmpgu_le_ob(cpu_gpr[ret], v1_t, v2_t);
14022 break;
14023 case OPC_CMPU_EQ_OB:
14024 check_dsp(ctx);
14025 gen_helper_cmpu_eq_ob(v1_t, v2_t, cpu_env);
14026 break;
14027 case OPC_CMPU_LT_OB:
14028 check_dsp(ctx);
14029 gen_helper_cmpu_lt_ob(v1_t, v2_t, cpu_env);
14030 break;
14031 case OPC_CMPU_LE_OB:
14032 check_dsp(ctx);
14033 gen_helper_cmpu_le_ob(v1_t, v2_t, cpu_env);
14034 break;
14035 case OPC_PACKRL_PW:
14036 check_dsp(ctx);
14037 gen_helper_packrl_pw(cpu_gpr[ret], v1_t, v2_t);
14038 break;
14039 case OPC_PICK_OB:
14040 check_dsp(ctx);
14041 gen_helper_pick_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
14042 break;
14043 case OPC_PICK_PW:
14044 check_dsp(ctx);
14045 gen_helper_pick_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
14046 break;
14047 case OPC_PICK_QH:
14048 check_dsp(ctx);
14049 gen_helper_pick_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
14050 break;
14052 break;
14053 #endif
14056 tcg_temp_free(t1);
14057 tcg_temp_free(v1_t);
14058 tcg_temp_free(v2_t);
14060 (void)opn; /* avoid a compiler warning */
14061 MIPS_DEBUG("%s", opn);
14064 static void gen_mipsdsp_append(CPUMIPSState *env, DisasContext *ctx,
14065 uint32_t op1, int rt, int rs, int sa)
14067 const char *opn = "mipsdsp append/dappend";
14068 TCGv t0;
14070 check_dspr2(ctx);
14072 if (rt == 0) {
14073 /* Treat as NOP. */
14074 MIPS_DEBUG("NOP");
14075 return;
14078 t0 = tcg_temp_new();
14079 gen_load_gpr(t0, rs);
14081 switch (op1) {
14082 case OPC_APPEND_DSP:
14083 switch (MASK_APPEND(ctx->opcode)) {
14084 case OPC_APPEND:
14085 if (sa != 0) {
14086 tcg_gen_deposit_tl(cpu_gpr[rt], t0, cpu_gpr[rt], sa, 32 - sa);
14088 tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]);
14089 break;
14090 case OPC_PREPEND:
14091 if (sa != 0) {
14092 tcg_gen_ext32u_tl(cpu_gpr[rt], cpu_gpr[rt]);
14093 tcg_gen_shri_tl(cpu_gpr[rt], cpu_gpr[rt], sa);
14094 tcg_gen_shli_tl(t0, t0, 32 - sa);
14095 tcg_gen_or_tl(cpu_gpr[rt], cpu_gpr[rt], t0);
14097 tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]);
14098 break;
14099 case OPC_BALIGN:
14100 sa &= 3;
14101 if (sa != 0 && sa != 2) {
14102 tcg_gen_shli_tl(cpu_gpr[rt], cpu_gpr[rt], 8 * sa);
14103 tcg_gen_ext32u_tl(t0, t0);
14104 tcg_gen_shri_tl(t0, t0, 8 * (4 - sa));
14105 tcg_gen_or_tl(cpu_gpr[rt], cpu_gpr[rt], t0);
14107 tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]);
14108 break;
14109 default: /* Invalid */
14110 MIPS_INVAL("MASK APPEND");
14111 generate_exception(ctx, EXCP_RI);
14112 break;
14114 break;
14115 #ifdef TARGET_MIPS64
14116 case OPC_DAPPEND_DSP:
14117 switch (MASK_DAPPEND(ctx->opcode)) {
14118 case OPC_DAPPEND:
14119 if (sa != 0) {
14120 tcg_gen_deposit_tl(cpu_gpr[rt], t0, cpu_gpr[rt], sa, 64 - sa);
14122 break;
14123 case OPC_PREPENDD:
14124 tcg_gen_shri_tl(cpu_gpr[rt], cpu_gpr[rt], 0x20 | sa);
14125 tcg_gen_shli_tl(t0, t0, 64 - (0x20 | sa));
14126 tcg_gen_or_tl(cpu_gpr[rt], t0, t0);
14127 break;
14128 case OPC_PREPENDW:
14129 if (sa != 0) {
14130 tcg_gen_shri_tl(cpu_gpr[rt], cpu_gpr[rt], sa);
14131 tcg_gen_shli_tl(t0, t0, 64 - sa);
14132 tcg_gen_or_tl(cpu_gpr[rt], cpu_gpr[rt], t0);
14134 break;
14135 case OPC_DBALIGN:
14136 sa &= 7;
14137 if (sa != 0 && sa != 2 && sa != 4) {
14138 tcg_gen_shli_tl(cpu_gpr[rt], cpu_gpr[rt], 8 * sa);
14139 tcg_gen_shri_tl(t0, t0, 8 * (8 - sa));
14140 tcg_gen_or_tl(cpu_gpr[rt], cpu_gpr[rt], t0);
14142 break;
14143 default: /* Invalid */
14144 MIPS_INVAL("MASK DAPPEND");
14145 generate_exception(ctx, EXCP_RI);
14146 break;
14148 break;
14149 #endif
14151 tcg_temp_free(t0);
14152 (void)opn; /* avoid a compiler warning */
14153 MIPS_DEBUG("%s", opn);
14156 static void gen_mipsdsp_accinsn(DisasContext *ctx, uint32_t op1, uint32_t op2,
14157 int ret, int v1, int v2, int check_ret)
14160 const char *opn = "mipsdsp accumulator";
14161 TCGv t0;
14162 TCGv t1;
14163 TCGv v1_t;
14164 TCGv v2_t;
14165 int16_t imm;
14167 if ((ret == 0) && (check_ret == 1)) {
14168 /* Treat as NOP. */
14169 MIPS_DEBUG("NOP");
14170 return;
14173 t0 = tcg_temp_new();
14174 t1 = tcg_temp_new();
14175 v1_t = tcg_temp_new();
14176 v2_t = tcg_temp_new();
14178 gen_load_gpr(v1_t, v1);
14179 gen_load_gpr(v2_t, v2);
14181 switch (op1) {
14182 case OPC_EXTR_W_DSP:
14183 check_dsp(ctx);
14184 switch (op2) {
14185 case OPC_EXTR_W:
14186 tcg_gen_movi_tl(t0, v2);
14187 tcg_gen_movi_tl(t1, v1);
14188 gen_helper_extr_w(cpu_gpr[ret], t0, t1, cpu_env);
14189 break;
14190 case OPC_EXTR_R_W:
14191 tcg_gen_movi_tl(t0, v2);
14192 tcg_gen_movi_tl(t1, v1);
14193 gen_helper_extr_r_w(cpu_gpr[ret], t0, t1, cpu_env);
14194 break;
14195 case OPC_EXTR_RS_W:
14196 tcg_gen_movi_tl(t0, v2);
14197 tcg_gen_movi_tl(t1, v1);
14198 gen_helper_extr_rs_w(cpu_gpr[ret], t0, t1, cpu_env);
14199 break;
14200 case OPC_EXTR_S_H:
14201 tcg_gen_movi_tl(t0, v2);
14202 tcg_gen_movi_tl(t1, v1);
14203 gen_helper_extr_s_h(cpu_gpr[ret], t0, t1, cpu_env);
14204 break;
14205 case OPC_EXTRV_S_H:
14206 tcg_gen_movi_tl(t0, v2);
14207 gen_helper_extr_s_h(cpu_gpr[ret], t0, v1_t, cpu_env);
14208 break;
14209 case OPC_EXTRV_W:
14210 tcg_gen_movi_tl(t0, v2);
14211 gen_helper_extr_w(cpu_gpr[ret], t0, v1_t, cpu_env);
14212 break;
14213 case OPC_EXTRV_R_W:
14214 tcg_gen_movi_tl(t0, v2);
14215 gen_helper_extr_r_w(cpu_gpr[ret], t0, v1_t, cpu_env);
14216 break;
14217 case OPC_EXTRV_RS_W:
14218 tcg_gen_movi_tl(t0, v2);
14219 gen_helper_extr_rs_w(cpu_gpr[ret], t0, v1_t, cpu_env);
14220 break;
14221 case OPC_EXTP:
14222 tcg_gen_movi_tl(t0, v2);
14223 tcg_gen_movi_tl(t1, v1);
14224 gen_helper_extp(cpu_gpr[ret], t0, t1, cpu_env);
14225 break;
14226 case OPC_EXTPV:
14227 tcg_gen_movi_tl(t0, v2);
14228 gen_helper_extp(cpu_gpr[ret], t0, v1_t, cpu_env);
14229 break;
14230 case OPC_EXTPDP:
14231 tcg_gen_movi_tl(t0, v2);
14232 tcg_gen_movi_tl(t1, v1);
14233 gen_helper_extpdp(cpu_gpr[ret], t0, t1, cpu_env);
14234 break;
14235 case OPC_EXTPDPV:
14236 tcg_gen_movi_tl(t0, v2);
14237 gen_helper_extpdp(cpu_gpr[ret], t0, v1_t, cpu_env);
14238 break;
14239 case OPC_SHILO:
14240 imm = (ctx->opcode >> 20) & 0x3F;
14241 tcg_gen_movi_tl(t0, ret);
14242 tcg_gen_movi_tl(t1, imm);
14243 gen_helper_shilo(t0, t1, cpu_env);
14244 break;
14245 case OPC_SHILOV:
14246 tcg_gen_movi_tl(t0, ret);
14247 gen_helper_shilo(t0, v1_t, cpu_env);
14248 break;
14249 case OPC_MTHLIP:
14250 tcg_gen_movi_tl(t0, ret);
14251 gen_helper_mthlip(t0, v1_t, cpu_env);
14252 break;
14253 case OPC_WRDSP:
14254 imm = (ctx->opcode >> 11) & 0x3FF;
14255 tcg_gen_movi_tl(t0, imm);
14256 gen_helper_wrdsp(v1_t, t0, cpu_env);
14257 break;
14258 case OPC_RDDSP:
14259 imm = (ctx->opcode >> 16) & 0x03FF;
14260 tcg_gen_movi_tl(t0, imm);
14261 gen_helper_rddsp(cpu_gpr[ret], t0, cpu_env);
14262 break;
14264 break;
14265 #ifdef TARGET_MIPS64
14266 case OPC_DEXTR_W_DSP:
14267 check_dsp(ctx);
14268 switch (op2) {
14269 case OPC_DMTHLIP:
14270 tcg_gen_movi_tl(t0, ret);
14271 gen_helper_dmthlip(v1_t, t0, cpu_env);
14272 break;
14273 case OPC_DSHILO:
14275 int shift = (ctx->opcode >> 19) & 0x7F;
14276 int ac = (ctx->opcode >> 11) & 0x03;
14277 tcg_gen_movi_tl(t0, shift);
14278 tcg_gen_movi_tl(t1, ac);
14279 gen_helper_dshilo(t0, t1, cpu_env);
14280 break;
14282 case OPC_DSHILOV:
14284 int ac = (ctx->opcode >> 11) & 0x03;
14285 tcg_gen_movi_tl(t0, ac);
14286 gen_helper_dshilo(v1_t, t0, cpu_env);
14287 break;
14289 case OPC_DEXTP:
14290 tcg_gen_movi_tl(t0, v2);
14291 tcg_gen_movi_tl(t1, v1);
14293 gen_helper_dextp(cpu_gpr[ret], t0, t1, cpu_env);
14294 break;
14295 case OPC_DEXTPV:
14296 tcg_gen_movi_tl(t0, v2);
14297 gen_helper_dextp(cpu_gpr[ret], t0, v1_t, cpu_env);
14298 break;
14299 case OPC_DEXTPDP:
14300 tcg_gen_movi_tl(t0, v2);
14301 tcg_gen_movi_tl(t1, v1);
14302 gen_helper_dextpdp(cpu_gpr[ret], t0, t1, cpu_env);
14303 break;
14304 case OPC_DEXTPDPV:
14305 tcg_gen_movi_tl(t0, v2);
14306 gen_helper_dextpdp(cpu_gpr[ret], t0, v1_t, cpu_env);
14307 break;
14308 case OPC_DEXTR_L:
14309 tcg_gen_movi_tl(t0, v2);
14310 tcg_gen_movi_tl(t1, v1);
14311 gen_helper_dextr_l(cpu_gpr[ret], t0, t1, cpu_env);
14312 break;
14313 case OPC_DEXTR_R_L:
14314 tcg_gen_movi_tl(t0, v2);
14315 tcg_gen_movi_tl(t1, v1);
14316 gen_helper_dextr_r_l(cpu_gpr[ret], t0, t1, cpu_env);
14317 break;
14318 case OPC_DEXTR_RS_L:
14319 tcg_gen_movi_tl(t0, v2);
14320 tcg_gen_movi_tl(t1, v1);
14321 gen_helper_dextr_rs_l(cpu_gpr[ret], t0, t1, cpu_env);
14322 break;
14323 case OPC_DEXTR_W:
14324 tcg_gen_movi_tl(t0, v2);
14325 tcg_gen_movi_tl(t1, v1);
14326 gen_helper_dextr_w(cpu_gpr[ret], t0, t1, cpu_env);
14327 break;
14328 case OPC_DEXTR_R_W:
14329 tcg_gen_movi_tl(t0, v2);
14330 tcg_gen_movi_tl(t1, v1);
14331 gen_helper_dextr_r_w(cpu_gpr[ret], t0, t1, cpu_env);
14332 break;
14333 case OPC_DEXTR_RS_W:
14334 tcg_gen_movi_tl(t0, v2);
14335 tcg_gen_movi_tl(t1, v1);
14336 gen_helper_dextr_rs_w(cpu_gpr[ret], t0, t1, cpu_env);
14337 break;
14338 case OPC_DEXTR_S_H:
14339 tcg_gen_movi_tl(t0, v2);
14340 tcg_gen_movi_tl(t1, v1);
14341 gen_helper_dextr_s_h(cpu_gpr[ret], t0, t1, cpu_env);
14342 break;
14343 case OPC_DEXTRV_S_H:
14344 tcg_gen_movi_tl(t0, v2);
14345 tcg_gen_movi_tl(t1, v1);
14346 gen_helper_dextr_s_h(cpu_gpr[ret], t0, t1, cpu_env);
14347 break;
14348 case OPC_DEXTRV_L:
14349 tcg_gen_movi_tl(t0, v2);
14350 gen_helper_dextr_l(cpu_gpr[ret], t0, v1_t, cpu_env);
14351 break;
14352 case OPC_DEXTRV_R_L:
14353 tcg_gen_movi_tl(t0, v2);
14354 gen_helper_dextr_r_l(cpu_gpr[ret], t0, v1_t, cpu_env);
14355 break;
14356 case OPC_DEXTRV_RS_L:
14357 tcg_gen_movi_tl(t0, v2);
14358 gen_helper_dextr_rs_l(cpu_gpr[ret], t0, v1_t, cpu_env);
14359 break;
14360 case OPC_DEXTRV_W:
14361 tcg_gen_movi_tl(t0, v2);
14362 gen_helper_dextr_w(cpu_gpr[ret], t0, v1_t, cpu_env);
14363 break;
14364 case OPC_DEXTRV_R_W:
14365 tcg_gen_movi_tl(t0, v2);
14366 gen_helper_dextr_r_w(cpu_gpr[ret], t0, v1_t, cpu_env);
14367 break;
14368 case OPC_DEXTRV_RS_W:
14369 tcg_gen_movi_tl(t0, v2);
14370 gen_helper_dextr_rs_w(cpu_gpr[ret], t0, v1_t, cpu_env);
14371 break;
14373 break;
14374 #endif
14377 tcg_temp_free(t0);
14378 tcg_temp_free(t1);
14379 tcg_temp_free(v1_t);
14380 tcg_temp_free(v2_t);
14382 (void)opn; /* avoid a compiler warning */
14383 MIPS_DEBUG("%s", opn);
14386 /* End MIPSDSP functions. */
14388 static void decode_opc (CPUMIPSState *env, DisasContext *ctx)
14390 int32_t offset;
14391 int rs, rt, rd, sa;
14392 uint32_t op, op1, op2;
14393 int16_t imm;
14395 /* make sure instructions are on a word boundary */
14396 if (ctx->pc & 0x3) {
14397 env->CP0_BadVAddr = ctx->pc;
14398 generate_exception(ctx, EXCP_AdEL);
14399 return;
14402 /* Handle blikely not taken case */
14403 if ((ctx->hflags & MIPS_HFLAG_BMASK_BASE) == MIPS_HFLAG_BL) {
14404 int l1 = gen_new_label();
14406 MIPS_DEBUG("blikely condition (" TARGET_FMT_lx ")", ctx->pc + 4);
14407 tcg_gen_brcondi_tl(TCG_COND_NE, bcond, 0, l1);
14408 tcg_gen_movi_i32(hflags, ctx->hflags & ~MIPS_HFLAG_BMASK);
14409 gen_goto_tb(ctx, 1, ctx->pc + 4);
14410 gen_set_label(l1);
14413 if (unlikely(qemu_loglevel_mask(CPU_LOG_TB_OP | CPU_LOG_TB_OP_OPT))) {
14414 tcg_gen_debug_insn_start(ctx->pc);
14417 op = MASK_OP_MAJOR(ctx->opcode);
14418 rs = (ctx->opcode >> 21) & 0x1f;
14419 rt = (ctx->opcode >> 16) & 0x1f;
14420 rd = (ctx->opcode >> 11) & 0x1f;
14421 sa = (ctx->opcode >> 6) & 0x1f;
14422 imm = (int16_t)ctx->opcode;
14423 switch (op) {
14424 case OPC_SPECIAL:
14425 op1 = MASK_SPECIAL(ctx->opcode);
14426 switch (op1) {
14427 case OPC_SLL: /* Shift with immediate */
14428 case OPC_SRA:
14429 gen_shift_imm(ctx, op1, rd, rt, sa);
14430 break;
14431 case OPC_SRL:
14432 switch ((ctx->opcode >> 21) & 0x1f) {
14433 case 1:
14434 /* rotr is decoded as srl on non-R2 CPUs */
14435 if (ctx->insn_flags & ISA_MIPS32R2) {
14436 op1 = OPC_ROTR;
14438 /* Fallthrough */
14439 case 0:
14440 gen_shift_imm(ctx, op1, rd, rt, sa);
14441 break;
14442 default:
14443 generate_exception(ctx, EXCP_RI);
14444 break;
14446 break;
14447 case OPC_MOVN: /* Conditional move */
14448 case OPC_MOVZ:
14449 check_insn(ctx, ISA_MIPS4 | ISA_MIPS32 |
14450 INSN_LOONGSON2E | INSN_LOONGSON2F);
14451 gen_cond_move(ctx, op1, rd, rs, rt);
14452 break;
14453 case OPC_ADD ... OPC_SUBU:
14454 gen_arith(ctx, op1, rd, rs, rt);
14455 break;
14456 case OPC_SLLV: /* Shifts */
14457 case OPC_SRAV:
14458 gen_shift(ctx, op1, rd, rs, rt);
14459 break;
14460 case OPC_SRLV:
14461 switch ((ctx->opcode >> 6) & 0x1f) {
14462 case 1:
14463 /* rotrv is decoded as srlv on non-R2 CPUs */
14464 if (ctx->insn_flags & ISA_MIPS32R2) {
14465 op1 = OPC_ROTRV;
14467 /* Fallthrough */
14468 case 0:
14469 gen_shift(ctx, op1, rd, rs, rt);
14470 break;
14471 default:
14472 generate_exception(ctx, EXCP_RI);
14473 break;
14475 break;
14476 case OPC_SLT: /* Set on less than */
14477 case OPC_SLTU:
14478 gen_slt(ctx, op1, rd, rs, rt);
14479 break;
14480 case OPC_AND: /* Logic*/
14481 case OPC_OR:
14482 case OPC_NOR:
14483 case OPC_XOR:
14484 gen_logic(ctx, op1, rd, rs, rt);
14485 break;
14486 case OPC_MULT:
14487 case OPC_MULTU:
14488 if (sa) {
14489 check_insn(ctx, INSN_VR54XX);
14490 op1 = MASK_MUL_VR54XX(ctx->opcode);
14491 gen_mul_vr54xx(ctx, op1, rd, rs, rt);
14492 } else {
14493 gen_muldiv(ctx, op1, rd & 3, rs, rt);
14495 break;
14496 case OPC_DIV:
14497 case OPC_DIVU:
14498 gen_muldiv(ctx, op1, 0, rs, rt);
14499 break;
14500 case OPC_JR ... OPC_JALR:
14501 gen_compute_branch(ctx, op1, 4, rs, rd, sa);
14502 break;
14503 case OPC_TGE ... OPC_TEQ: /* Traps */
14504 case OPC_TNE:
14505 gen_trap(ctx, op1, rs, rt, -1);
14506 break;
14507 case OPC_MFHI: /* Move from HI/LO */
14508 case OPC_MFLO:
14509 gen_HILO(ctx, op1, rs & 3, rd);
14510 break;
14511 case OPC_MTHI:
14512 case OPC_MTLO: /* Move to HI/LO */
14513 gen_HILO(ctx, op1, rd & 3, rs);
14514 break;
14515 case OPC_PMON: /* Pmon entry point, also R4010 selsl */
14516 #ifdef MIPS_STRICT_STANDARD
14517 MIPS_INVAL("PMON / selsl");
14518 generate_exception(ctx, EXCP_RI);
14519 #else
14520 gen_helper_0e0i(pmon, sa);
14521 #endif
14522 break;
14523 case OPC_SYSCALL:
14524 generate_exception(ctx, EXCP_SYSCALL);
14525 ctx->bstate = BS_STOP;
14526 break;
14527 case OPC_BREAK:
14528 generate_exception(ctx, EXCP_BREAK);
14529 break;
14530 case OPC_SPIM:
14531 #ifdef MIPS_STRICT_STANDARD
14532 MIPS_INVAL("SPIM");
14533 generate_exception(ctx, EXCP_RI);
14534 #else
14535 /* Implemented as RI exception for now. */
14536 MIPS_INVAL("spim (unofficial)");
14537 generate_exception(ctx, EXCP_RI);
14538 #endif
14539 break;
14540 case OPC_SYNC:
14541 /* Treat as NOP. */
14542 break;
14544 case OPC_MOVCI:
14545 check_insn(ctx, ISA_MIPS4 | ISA_MIPS32);
14546 if (env->CP0_Config1 & (1 << CP0C1_FP)) {
14547 check_cp1_enabled(ctx);
14548 gen_movci(ctx, rd, rs, (ctx->opcode >> 18) & 0x7,
14549 (ctx->opcode >> 16) & 1);
14550 } else {
14551 generate_exception_err(ctx, EXCP_CpU, 1);
14553 break;
14555 #if defined(TARGET_MIPS64)
14556 /* MIPS64 specific opcodes */
14557 case OPC_DSLL:
14558 case OPC_DSRA:
14559 case OPC_DSLL32:
14560 case OPC_DSRA32:
14561 check_insn(ctx, ISA_MIPS3);
14562 check_mips_64(ctx);
14563 gen_shift_imm(ctx, op1, rd, rt, sa);
14564 break;
14565 case OPC_DSRL:
14566 switch ((ctx->opcode >> 21) & 0x1f) {
14567 case 1:
14568 /* drotr is decoded as dsrl on non-R2 CPUs */
14569 if (ctx->insn_flags & ISA_MIPS32R2) {
14570 op1 = OPC_DROTR;
14572 /* Fallthrough */
14573 case 0:
14574 check_insn(ctx, ISA_MIPS3);
14575 check_mips_64(ctx);
14576 gen_shift_imm(ctx, op1, rd, rt, sa);
14577 break;
14578 default:
14579 generate_exception(ctx, EXCP_RI);
14580 break;
14582 break;
14583 case OPC_DSRL32:
14584 switch ((ctx->opcode >> 21) & 0x1f) {
14585 case 1:
14586 /* drotr32 is decoded as dsrl32 on non-R2 CPUs */
14587 if (ctx->insn_flags & ISA_MIPS32R2) {
14588 op1 = OPC_DROTR32;
14590 /* Fallthrough */
14591 case 0:
14592 check_insn(ctx, ISA_MIPS3);
14593 check_mips_64(ctx);
14594 gen_shift_imm(ctx, op1, rd, rt, sa);
14595 break;
14596 default:
14597 generate_exception(ctx, EXCP_RI);
14598 break;
14600 break;
14601 case OPC_DADD ... OPC_DSUBU:
14602 check_insn(ctx, ISA_MIPS3);
14603 check_mips_64(ctx);
14604 gen_arith(ctx, op1, rd, rs, rt);
14605 break;
14606 case OPC_DSLLV:
14607 case OPC_DSRAV:
14608 check_insn(ctx, ISA_MIPS3);
14609 check_mips_64(ctx);
14610 gen_shift(ctx, op1, rd, rs, rt);
14611 break;
14612 case OPC_DSRLV:
14613 switch ((ctx->opcode >> 6) & 0x1f) {
14614 case 1:
14615 /* drotrv is decoded as dsrlv on non-R2 CPUs */
14616 if (ctx->insn_flags & ISA_MIPS32R2) {
14617 op1 = OPC_DROTRV;
14619 /* Fallthrough */
14620 case 0:
14621 check_insn(ctx, ISA_MIPS3);
14622 check_mips_64(ctx);
14623 gen_shift(ctx, op1, rd, rs, rt);
14624 break;
14625 default:
14626 generate_exception(ctx, EXCP_RI);
14627 break;
14629 break;
14630 case OPC_DMULT ... OPC_DDIVU:
14631 check_insn(ctx, ISA_MIPS3);
14632 check_mips_64(ctx);
14633 gen_muldiv(ctx, op1, 0, rs, rt);
14634 break;
14635 #endif
14636 default: /* Invalid */
14637 MIPS_INVAL("special");
14638 generate_exception(ctx, EXCP_RI);
14639 break;
14641 break;
14642 case OPC_SPECIAL2:
14643 op1 = MASK_SPECIAL2(ctx->opcode);
14644 switch (op1) {
14645 case OPC_MADD ... OPC_MADDU: /* Multiply and add/sub */
14646 case OPC_MSUB ... OPC_MSUBU:
14647 check_insn(ctx, ISA_MIPS32);
14648 gen_muldiv(ctx, op1, rd & 3, rs, rt);
14649 break;
14650 case OPC_MUL:
14651 gen_arith(ctx, op1, rd, rs, rt);
14652 break;
14653 case OPC_CLO:
14654 case OPC_CLZ:
14655 check_insn(ctx, ISA_MIPS32);
14656 gen_cl(ctx, op1, rd, rs);
14657 break;
14658 case OPC_SDBBP:
14659 /* XXX: not clear which exception should be raised
14660 * when in debug mode...
14662 check_insn(ctx, ISA_MIPS32);
14663 if (!(ctx->hflags & MIPS_HFLAG_DM)) {
14664 generate_exception(ctx, EXCP_DBp);
14665 } else {
14666 generate_exception(ctx, EXCP_DBp);
14668 /* Treat as NOP. */
14669 break;
14670 case OPC_DIV_G_2F:
14671 case OPC_DIVU_G_2F:
14672 case OPC_MULT_G_2F:
14673 case OPC_MULTU_G_2F:
14674 case OPC_MOD_G_2F:
14675 case OPC_MODU_G_2F:
14676 check_insn(ctx, INSN_LOONGSON2F);
14677 gen_loongson_integer(ctx, op1, rd, rs, rt);
14678 break;
14679 #if defined(TARGET_MIPS64)
14680 case OPC_DCLO:
14681 case OPC_DCLZ:
14682 check_insn(ctx, ISA_MIPS64);
14683 check_mips_64(ctx);
14684 gen_cl(ctx, op1, rd, rs);
14685 break;
14686 case OPC_DMULT_G_2F:
14687 case OPC_DMULTU_G_2F:
14688 case OPC_DDIV_G_2F:
14689 case OPC_DDIVU_G_2F:
14690 case OPC_DMOD_G_2F:
14691 case OPC_DMODU_G_2F:
14692 check_insn(ctx, INSN_LOONGSON2F);
14693 gen_loongson_integer(ctx, op1, rd, rs, rt);
14694 break;
14695 #endif
14696 default: /* Invalid */
14697 MIPS_INVAL("special2");
14698 generate_exception(ctx, EXCP_RI);
14699 break;
14701 break;
14702 case OPC_SPECIAL3:
14703 op1 = MASK_SPECIAL3(ctx->opcode);
14704 switch (op1) {
14705 case OPC_EXT:
14706 case OPC_INS:
14707 check_insn(ctx, ISA_MIPS32R2);
14708 gen_bitops(ctx, op1, rt, rs, sa, rd);
14709 break;
14710 case OPC_BSHFL:
14711 check_insn(ctx, ISA_MIPS32R2);
14712 op2 = MASK_BSHFL(ctx->opcode);
14713 gen_bshfl(ctx, op2, rt, rd);
14714 break;
14715 case OPC_RDHWR:
14716 gen_rdhwr(ctx, rt, rd);
14717 break;
14718 case OPC_FORK:
14719 check_insn(ctx, ASE_MT);
14721 TCGv t0 = tcg_temp_new();
14722 TCGv t1 = tcg_temp_new();
14724 gen_load_gpr(t0, rt);
14725 gen_load_gpr(t1, rs);
14726 gen_helper_fork(t0, t1);
14727 tcg_temp_free(t0);
14728 tcg_temp_free(t1);
14730 break;
14731 case OPC_YIELD:
14732 check_insn(ctx, ASE_MT);
14734 TCGv t0 = tcg_temp_new();
14736 save_cpu_state(ctx, 1);
14737 gen_load_gpr(t0, rs);
14738 gen_helper_yield(t0, cpu_env, t0);
14739 gen_store_gpr(t0, rd);
14740 tcg_temp_free(t0);
14742 break;
14743 case OPC_DIV_G_2E ... OPC_DIVU_G_2E:
14744 case OPC_MOD_G_2E ... OPC_MODU_G_2E:
14745 case OPC_MULT_G_2E ... OPC_MULTU_G_2E:
14746 /* OPC_MULT_G_2E, OPC_ADDUH_QB_DSP, OPC_MUL_PH_DSP have
14747 * the same mask and op1. */
14748 if ((ctx->insn_flags & ASE_DSPR2) && (op1 == OPC_MULT_G_2E)) {
14749 op2 = MASK_ADDUH_QB(ctx->opcode);
14750 switch (op2) {
14751 case OPC_ADDUH_QB:
14752 case OPC_ADDUH_R_QB:
14753 case OPC_ADDQH_PH:
14754 case OPC_ADDQH_R_PH:
14755 case OPC_ADDQH_W:
14756 case OPC_ADDQH_R_W:
14757 case OPC_SUBUH_QB:
14758 case OPC_SUBUH_R_QB:
14759 case OPC_SUBQH_PH:
14760 case OPC_SUBQH_R_PH:
14761 case OPC_SUBQH_W:
14762 case OPC_SUBQH_R_W:
14763 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
14764 break;
14765 case OPC_MUL_PH:
14766 case OPC_MUL_S_PH:
14767 case OPC_MULQ_S_W:
14768 case OPC_MULQ_RS_W:
14769 gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 1);
14770 break;
14771 default:
14772 MIPS_INVAL("MASK ADDUH.QB");
14773 generate_exception(ctx, EXCP_RI);
14774 break;
14776 } else if (ctx->insn_flags & INSN_LOONGSON2E) {
14777 gen_loongson_integer(ctx, op1, rd, rs, rt);
14778 } else {
14779 generate_exception(ctx, EXCP_RI);
14781 break;
14782 case OPC_LX_DSP:
14783 op2 = MASK_LX(ctx->opcode);
14784 switch (op2) {
14785 #if defined(TARGET_MIPS64)
14786 case OPC_LDX:
14787 #endif
14788 case OPC_LBUX:
14789 case OPC_LHX:
14790 case OPC_LWX:
14791 gen_mipsdsp_ld(ctx, op2, rd, rs, rt);
14792 break;
14793 default: /* Invalid */
14794 MIPS_INVAL("MASK LX");
14795 generate_exception(ctx, EXCP_RI);
14796 break;
14798 break;
14799 case OPC_ABSQ_S_PH_DSP:
14800 op2 = MASK_ABSQ_S_PH(ctx->opcode);
14801 switch (op2) {
14802 case OPC_ABSQ_S_QB:
14803 case OPC_ABSQ_S_PH:
14804 case OPC_ABSQ_S_W:
14805 case OPC_PRECEQ_W_PHL:
14806 case OPC_PRECEQ_W_PHR:
14807 case OPC_PRECEQU_PH_QBL:
14808 case OPC_PRECEQU_PH_QBR:
14809 case OPC_PRECEQU_PH_QBLA:
14810 case OPC_PRECEQU_PH_QBRA:
14811 case OPC_PRECEU_PH_QBL:
14812 case OPC_PRECEU_PH_QBR:
14813 case OPC_PRECEU_PH_QBLA:
14814 case OPC_PRECEU_PH_QBRA:
14815 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
14816 break;
14817 case OPC_BITREV:
14818 case OPC_REPL_QB:
14819 case OPC_REPLV_QB:
14820 case OPC_REPL_PH:
14821 case OPC_REPLV_PH:
14822 gen_mipsdsp_bitinsn(ctx, op1, op2, rd, rt);
14823 break;
14824 default:
14825 MIPS_INVAL("MASK ABSQ_S.PH");
14826 generate_exception(ctx, EXCP_RI);
14827 break;
14829 break;
14830 case OPC_ADDU_QB_DSP:
14831 op2 = MASK_ADDU_QB(ctx->opcode);
14832 switch (op2) {
14833 case OPC_ADDQ_PH:
14834 case OPC_ADDQ_S_PH:
14835 case OPC_ADDQ_S_W:
14836 case OPC_ADDU_QB:
14837 case OPC_ADDU_S_QB:
14838 case OPC_ADDU_PH:
14839 case OPC_ADDU_S_PH:
14840 case OPC_SUBQ_PH:
14841 case OPC_SUBQ_S_PH:
14842 case OPC_SUBQ_S_W:
14843 case OPC_SUBU_QB:
14844 case OPC_SUBU_S_QB:
14845 case OPC_SUBU_PH:
14846 case OPC_SUBU_S_PH:
14847 case OPC_ADDSC:
14848 case OPC_ADDWC:
14849 case OPC_MODSUB:
14850 case OPC_RADDU_W_QB:
14851 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
14852 break;
14853 case OPC_MULEU_S_PH_QBL:
14854 case OPC_MULEU_S_PH_QBR:
14855 case OPC_MULQ_RS_PH:
14856 case OPC_MULEQ_S_W_PHL:
14857 case OPC_MULEQ_S_W_PHR:
14858 case OPC_MULQ_S_PH:
14859 gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 1);
14860 break;
14861 default: /* Invalid */
14862 MIPS_INVAL("MASK ADDU.QB");
14863 generate_exception(ctx, EXCP_RI);
14864 break;
14867 break;
14868 case OPC_CMPU_EQ_QB_DSP:
14869 op2 = MASK_CMPU_EQ_QB(ctx->opcode);
14870 switch (op2) {
14871 case OPC_PRECR_SRA_PH_W:
14872 case OPC_PRECR_SRA_R_PH_W:
14873 gen_mipsdsp_arith(ctx, op1, op2, rt, rs, rd);
14874 break;
14875 case OPC_PRECR_QB_PH:
14876 case OPC_PRECRQ_QB_PH:
14877 case OPC_PRECRQ_PH_W:
14878 case OPC_PRECRQ_RS_PH_W:
14879 case OPC_PRECRQU_S_QB_PH:
14880 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
14881 break;
14882 case OPC_CMPU_EQ_QB:
14883 case OPC_CMPU_LT_QB:
14884 case OPC_CMPU_LE_QB:
14885 case OPC_CMP_EQ_PH:
14886 case OPC_CMP_LT_PH:
14887 case OPC_CMP_LE_PH:
14888 gen_mipsdsp_add_cmp_pick(ctx, op1, op2, rd, rs, rt, 0);
14889 break;
14890 case OPC_CMPGU_EQ_QB:
14891 case OPC_CMPGU_LT_QB:
14892 case OPC_CMPGU_LE_QB:
14893 case OPC_CMPGDU_EQ_QB:
14894 case OPC_CMPGDU_LT_QB:
14895 case OPC_CMPGDU_LE_QB:
14896 case OPC_PICK_QB:
14897 case OPC_PICK_PH:
14898 case OPC_PACKRL_PH:
14899 gen_mipsdsp_add_cmp_pick(ctx, op1, op2, rd, rs, rt, 1);
14900 break;
14901 default: /* Invalid */
14902 MIPS_INVAL("MASK CMPU.EQ.QB");
14903 generate_exception(ctx, EXCP_RI);
14904 break;
14906 break;
14907 case OPC_SHLL_QB_DSP:
14908 gen_mipsdsp_shift(ctx, op1, rd, rs, rt);
14909 break;
14910 case OPC_DPA_W_PH_DSP:
14911 op2 = MASK_DPA_W_PH(ctx->opcode);
14912 switch (op2) {
14913 case OPC_DPAU_H_QBL:
14914 case OPC_DPAU_H_QBR:
14915 case OPC_DPSU_H_QBL:
14916 case OPC_DPSU_H_QBR:
14917 case OPC_DPA_W_PH:
14918 case OPC_DPAX_W_PH:
14919 case OPC_DPAQ_S_W_PH:
14920 case OPC_DPAQX_S_W_PH:
14921 case OPC_DPAQX_SA_W_PH:
14922 case OPC_DPS_W_PH:
14923 case OPC_DPSX_W_PH:
14924 case OPC_DPSQ_S_W_PH:
14925 case OPC_DPSQX_S_W_PH:
14926 case OPC_DPSQX_SA_W_PH:
14927 case OPC_MULSAQ_S_W_PH:
14928 case OPC_DPAQ_SA_L_W:
14929 case OPC_DPSQ_SA_L_W:
14930 case OPC_MAQ_S_W_PHL:
14931 case OPC_MAQ_S_W_PHR:
14932 case OPC_MAQ_SA_W_PHL:
14933 case OPC_MAQ_SA_W_PHR:
14934 case OPC_MULSA_W_PH:
14935 gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 0);
14936 break;
14937 default: /* Invalid */
14938 MIPS_INVAL("MASK DPAW.PH");
14939 generate_exception(ctx, EXCP_RI);
14940 break;
14942 break;
14943 case OPC_INSV_DSP:
14944 op2 = MASK_INSV(ctx->opcode);
14945 switch (op2) {
14946 case OPC_INSV:
14947 check_dsp(ctx);
14949 TCGv t0, t1;
14951 if (rt == 0) {
14952 MIPS_DEBUG("NOP");
14953 break;
14956 t0 = tcg_temp_new();
14957 t1 = tcg_temp_new();
14959 gen_load_gpr(t0, rt);
14960 gen_load_gpr(t1, rs);
14962 gen_helper_insv(cpu_gpr[rt], cpu_env, t1, t0);
14964 tcg_temp_free(t0);
14965 tcg_temp_free(t1);
14966 break;
14968 default: /* Invalid */
14969 MIPS_INVAL("MASK INSV");
14970 generate_exception(ctx, EXCP_RI);
14971 break;
14973 break;
14974 case OPC_APPEND_DSP:
14975 gen_mipsdsp_append(env, ctx, op1, rt, rs, rd);
14976 break;
14977 case OPC_EXTR_W_DSP:
14978 op2 = MASK_EXTR_W(ctx->opcode);
14979 switch (op2) {
14980 case OPC_EXTR_W:
14981 case OPC_EXTR_R_W:
14982 case OPC_EXTR_RS_W:
14983 case OPC_EXTR_S_H:
14984 case OPC_EXTRV_S_H:
14985 case OPC_EXTRV_W:
14986 case OPC_EXTRV_R_W:
14987 case OPC_EXTRV_RS_W:
14988 case OPC_EXTP:
14989 case OPC_EXTPV:
14990 case OPC_EXTPDP:
14991 case OPC_EXTPDPV:
14992 gen_mipsdsp_accinsn(ctx, op1, op2, rt, rs, rd, 1);
14993 break;
14994 case OPC_RDDSP:
14995 gen_mipsdsp_accinsn(ctx, op1, op2, rd, rs, rt, 1);
14996 break;
14997 case OPC_SHILO:
14998 case OPC_SHILOV:
14999 case OPC_MTHLIP:
15000 case OPC_WRDSP:
15001 gen_mipsdsp_accinsn(ctx, op1, op2, rd, rs, rt, 0);
15002 break;
15003 default: /* Invalid */
15004 MIPS_INVAL("MASK EXTR.W");
15005 generate_exception(ctx, EXCP_RI);
15006 break;
15008 break;
15009 #if defined(TARGET_MIPS64)
15010 case OPC_DEXTM ... OPC_DEXT:
15011 case OPC_DINSM ... OPC_DINS:
15012 check_insn(ctx, ISA_MIPS64R2);
15013 check_mips_64(ctx);
15014 gen_bitops(ctx, op1, rt, rs, sa, rd);
15015 break;
15016 case OPC_DBSHFL:
15017 check_insn(ctx, ISA_MIPS64R2);
15018 check_mips_64(ctx);
15019 op2 = MASK_DBSHFL(ctx->opcode);
15020 gen_bshfl(ctx, op2, rt, rd);
15021 break;
15022 case OPC_DDIV_G_2E ... OPC_DDIVU_G_2E:
15023 case OPC_DMULT_G_2E ... OPC_DMULTU_G_2E:
15024 case OPC_DMOD_G_2E ... OPC_DMODU_G_2E:
15025 check_insn(ctx, INSN_LOONGSON2E);
15026 gen_loongson_integer(ctx, op1, rd, rs, rt);
15027 break;
15028 case OPC_ABSQ_S_QH_DSP:
15029 op2 = MASK_ABSQ_S_QH(ctx->opcode);
15030 switch (op2) {
15031 case OPC_PRECEQ_L_PWL:
15032 case OPC_PRECEQ_L_PWR:
15033 case OPC_PRECEQ_PW_QHL:
15034 case OPC_PRECEQ_PW_QHR:
15035 case OPC_PRECEQ_PW_QHLA:
15036 case OPC_PRECEQ_PW_QHRA:
15037 case OPC_PRECEQU_QH_OBL:
15038 case OPC_PRECEQU_QH_OBR:
15039 case OPC_PRECEQU_QH_OBLA:
15040 case OPC_PRECEQU_QH_OBRA:
15041 case OPC_PRECEU_QH_OBL:
15042 case OPC_PRECEU_QH_OBR:
15043 case OPC_PRECEU_QH_OBLA:
15044 case OPC_PRECEU_QH_OBRA:
15045 case OPC_ABSQ_S_OB:
15046 case OPC_ABSQ_S_PW:
15047 case OPC_ABSQ_S_QH:
15048 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
15049 break;
15050 case OPC_REPL_OB:
15051 case OPC_REPL_PW:
15052 case OPC_REPL_QH:
15053 case OPC_REPLV_OB:
15054 case OPC_REPLV_PW:
15055 case OPC_REPLV_QH:
15056 gen_mipsdsp_bitinsn(ctx, op1, op2, rd, rt);
15057 break;
15058 default: /* Invalid */
15059 MIPS_INVAL("MASK ABSQ_S.QH");
15060 generate_exception(ctx, EXCP_RI);
15061 break;
15063 break;
15064 case OPC_ADDU_OB_DSP:
15065 op2 = MASK_ADDU_OB(ctx->opcode);
15066 switch (op2) {
15067 case OPC_RADDU_L_OB:
15068 case OPC_SUBQ_PW:
15069 case OPC_SUBQ_S_PW:
15070 case OPC_SUBQ_QH:
15071 case OPC_SUBQ_S_QH:
15072 case OPC_SUBU_OB:
15073 case OPC_SUBU_S_OB:
15074 case OPC_SUBU_QH:
15075 case OPC_SUBU_S_QH:
15076 case OPC_SUBUH_OB:
15077 case OPC_SUBUH_R_OB:
15078 case OPC_ADDQ_PW:
15079 case OPC_ADDQ_S_PW:
15080 case OPC_ADDQ_QH:
15081 case OPC_ADDQ_S_QH:
15082 case OPC_ADDU_OB:
15083 case OPC_ADDU_S_OB:
15084 case OPC_ADDU_QH:
15085 case OPC_ADDU_S_QH:
15086 case OPC_ADDUH_OB:
15087 case OPC_ADDUH_R_OB:
15088 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
15089 break;
15090 case OPC_MULEQ_S_PW_QHL:
15091 case OPC_MULEQ_S_PW_QHR:
15092 case OPC_MULEU_S_QH_OBL:
15093 case OPC_MULEU_S_QH_OBR:
15094 case OPC_MULQ_RS_QH:
15095 gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 1);
15096 break;
15097 default: /* Invalid */
15098 MIPS_INVAL("MASK ADDU.OB");
15099 generate_exception(ctx, EXCP_RI);
15100 break;
15102 break;
15103 case OPC_CMPU_EQ_OB_DSP:
15104 op2 = MASK_CMPU_EQ_OB(ctx->opcode);
15105 switch (op2) {
15106 case OPC_PRECR_SRA_QH_PW:
15107 case OPC_PRECR_SRA_R_QH_PW:
15108 /* Return value is rt. */
15109 gen_mipsdsp_arith(ctx, op1, op2, rt, rs, rd);
15110 break;
15111 case OPC_PRECR_OB_QH:
15112 case OPC_PRECRQ_OB_QH:
15113 case OPC_PRECRQ_PW_L:
15114 case OPC_PRECRQ_QH_PW:
15115 case OPC_PRECRQ_RS_QH_PW:
15116 case OPC_PRECRQU_S_OB_QH:
15117 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
15118 break;
15119 case OPC_CMPU_EQ_OB:
15120 case OPC_CMPU_LT_OB:
15121 case OPC_CMPU_LE_OB:
15122 case OPC_CMP_EQ_QH:
15123 case OPC_CMP_LT_QH:
15124 case OPC_CMP_LE_QH:
15125 case OPC_CMP_EQ_PW:
15126 case OPC_CMP_LT_PW:
15127 case OPC_CMP_LE_PW:
15128 gen_mipsdsp_add_cmp_pick(ctx, op1, op2, rd, rs, rt, 0);
15129 break;
15130 case OPC_CMPGDU_EQ_OB:
15131 case OPC_CMPGDU_LT_OB:
15132 case OPC_CMPGDU_LE_OB:
15133 case OPC_CMPGU_EQ_OB:
15134 case OPC_CMPGU_LT_OB:
15135 case OPC_CMPGU_LE_OB:
15136 case OPC_PACKRL_PW:
15137 case OPC_PICK_OB:
15138 case OPC_PICK_PW:
15139 case OPC_PICK_QH:
15140 gen_mipsdsp_add_cmp_pick(ctx, op1, op2, rd, rs, rt, 1);
15141 break;
15142 default: /* Invalid */
15143 MIPS_INVAL("MASK CMPU_EQ.OB");
15144 generate_exception(ctx, EXCP_RI);
15145 break;
15147 break;
15148 case OPC_DAPPEND_DSP:
15149 gen_mipsdsp_append(env, ctx, op1, rt, rs, rd);
15150 break;
15151 case OPC_DEXTR_W_DSP:
15152 op2 = MASK_DEXTR_W(ctx->opcode);
15153 switch (op2) {
15154 case OPC_DEXTP:
15155 case OPC_DEXTPDP:
15156 case OPC_DEXTPDPV:
15157 case OPC_DEXTPV:
15158 case OPC_DEXTR_L:
15159 case OPC_DEXTR_R_L:
15160 case OPC_DEXTR_RS_L:
15161 case OPC_DEXTR_W:
15162 case OPC_DEXTR_R_W:
15163 case OPC_DEXTR_RS_W:
15164 case OPC_DEXTR_S_H:
15165 case OPC_DEXTRV_L:
15166 case OPC_DEXTRV_R_L:
15167 case OPC_DEXTRV_RS_L:
15168 case OPC_DEXTRV_S_H:
15169 case OPC_DEXTRV_W:
15170 case OPC_DEXTRV_R_W:
15171 case OPC_DEXTRV_RS_W:
15172 gen_mipsdsp_accinsn(ctx, op1, op2, rt, rs, rd, 1);
15173 break;
15174 case OPC_DMTHLIP:
15175 case OPC_DSHILO:
15176 case OPC_DSHILOV:
15177 gen_mipsdsp_accinsn(ctx, op1, op2, rd, rs, rt, 0);
15178 break;
15179 default: /* Invalid */
15180 MIPS_INVAL("MASK EXTR.W");
15181 generate_exception(ctx, EXCP_RI);
15182 break;
15184 break;
15185 case OPC_DPAQ_W_QH_DSP:
15186 op2 = MASK_DPAQ_W_QH(ctx->opcode);
15187 switch (op2) {
15188 case OPC_DPAU_H_OBL:
15189 case OPC_DPAU_H_OBR:
15190 case OPC_DPSU_H_OBL:
15191 case OPC_DPSU_H_OBR:
15192 case OPC_DPA_W_QH:
15193 case OPC_DPAQ_S_W_QH:
15194 case OPC_DPS_W_QH:
15195 case OPC_DPSQ_S_W_QH:
15196 case OPC_MULSAQ_S_W_QH:
15197 case OPC_DPAQ_SA_L_PW:
15198 case OPC_DPSQ_SA_L_PW:
15199 case OPC_MULSAQ_S_L_PW:
15200 gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 0);
15201 break;
15202 case OPC_MAQ_S_W_QHLL:
15203 case OPC_MAQ_S_W_QHLR:
15204 case OPC_MAQ_S_W_QHRL:
15205 case OPC_MAQ_S_W_QHRR:
15206 case OPC_MAQ_SA_W_QHLL:
15207 case OPC_MAQ_SA_W_QHLR:
15208 case OPC_MAQ_SA_W_QHRL:
15209 case OPC_MAQ_SA_W_QHRR:
15210 case OPC_MAQ_S_L_PWL:
15211 case OPC_MAQ_S_L_PWR:
15212 case OPC_DMADD:
15213 case OPC_DMADDU:
15214 case OPC_DMSUB:
15215 case OPC_DMSUBU:
15216 gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 0);
15217 break;
15218 default: /* Invalid */
15219 MIPS_INVAL("MASK DPAQ.W.QH");
15220 generate_exception(ctx, EXCP_RI);
15221 break;
15223 break;
15224 case OPC_DINSV_DSP:
15225 op2 = MASK_INSV(ctx->opcode);
15226 switch (op2) {
15227 case OPC_DINSV:
15229 TCGv t0, t1;
15231 if (rt == 0) {
15232 MIPS_DEBUG("NOP");
15233 break;
15235 check_dsp(ctx);
15237 t0 = tcg_temp_new();
15238 t1 = tcg_temp_new();
15240 gen_load_gpr(t0, rt);
15241 gen_load_gpr(t1, rs);
15243 gen_helper_dinsv(cpu_gpr[rt], cpu_env, t1, t0);
15244 break;
15246 default: /* Invalid */
15247 MIPS_INVAL("MASK DINSV");
15248 generate_exception(ctx, EXCP_RI);
15249 break;
15251 break;
15252 case OPC_SHLL_OB_DSP:
15253 gen_mipsdsp_shift(ctx, op1, rd, rs, rt);
15254 break;
15255 #endif
15256 default: /* Invalid */
15257 MIPS_INVAL("special3");
15258 generate_exception(ctx, EXCP_RI);
15259 break;
15261 break;
15262 case OPC_REGIMM:
15263 op1 = MASK_REGIMM(ctx->opcode);
15264 switch (op1) {
15265 case OPC_BLTZ ... OPC_BGEZL: /* REGIMM branches */
15266 case OPC_BLTZAL ... OPC_BGEZALL:
15267 gen_compute_branch(ctx, op1, 4, rs, -1, imm << 2);
15268 break;
15269 case OPC_TGEI ... OPC_TEQI: /* REGIMM traps */
15270 case OPC_TNEI:
15271 gen_trap(ctx, op1, rs, -1, imm);
15272 break;
15273 case OPC_SYNCI:
15274 check_insn(ctx, ISA_MIPS32R2);
15275 /* Treat as NOP. */
15276 break;
15277 case OPC_BPOSGE32: /* MIPS DSP branch */
15278 #if defined(TARGET_MIPS64)
15279 case OPC_BPOSGE64:
15280 #endif
15281 check_dsp(ctx);
15282 gen_compute_branch(ctx, op1, 4, -1, -2, (int32_t)imm << 2);
15283 break;
15284 default: /* Invalid */
15285 MIPS_INVAL("regimm");
15286 generate_exception(ctx, EXCP_RI);
15287 break;
15289 break;
15290 case OPC_CP0:
15291 check_cp0_enabled(ctx);
15292 op1 = MASK_CP0(ctx->opcode);
15293 switch (op1) {
15294 case OPC_MFC0:
15295 case OPC_MTC0:
15296 case OPC_MFTR:
15297 case OPC_MTTR:
15298 #if defined(TARGET_MIPS64)
15299 case OPC_DMFC0:
15300 case OPC_DMTC0:
15301 #endif
15302 #ifndef CONFIG_USER_ONLY
15303 gen_cp0(env, ctx, op1, rt, rd);
15304 #endif /* !CONFIG_USER_ONLY */
15305 break;
15306 case OPC_C0_FIRST ... OPC_C0_LAST:
15307 #ifndef CONFIG_USER_ONLY
15308 gen_cp0(env, ctx, MASK_C0(ctx->opcode), rt, rd);
15309 #endif /* !CONFIG_USER_ONLY */
15310 break;
15311 case OPC_MFMC0:
15312 #ifndef CONFIG_USER_ONLY
15314 TCGv t0 = tcg_temp_new();
15316 op2 = MASK_MFMC0(ctx->opcode);
15317 switch (op2) {
15318 case OPC_DMT:
15319 check_insn(ctx, ASE_MT);
15320 gen_helper_dmt(t0);
15321 gen_store_gpr(t0, rt);
15322 break;
15323 case OPC_EMT:
15324 check_insn(ctx, ASE_MT);
15325 gen_helper_emt(t0);
15326 gen_store_gpr(t0, rt);
15327 break;
15328 case OPC_DVPE:
15329 check_insn(ctx, ASE_MT);
15330 gen_helper_dvpe(t0, cpu_env);
15331 gen_store_gpr(t0, rt);
15332 break;
15333 case OPC_EVPE:
15334 check_insn(ctx, ASE_MT);
15335 gen_helper_evpe(t0, cpu_env);
15336 gen_store_gpr(t0, rt);
15337 break;
15338 case OPC_DI:
15339 check_insn(ctx, ISA_MIPS32R2);
15340 save_cpu_state(ctx, 1);
15341 gen_helper_di(t0, cpu_env);
15342 gen_store_gpr(t0, rt);
15343 /* Stop translation as we may have switched the execution mode */
15344 ctx->bstate = BS_STOP;
15345 break;
15346 case OPC_EI:
15347 check_insn(ctx, ISA_MIPS32R2);
15348 save_cpu_state(ctx, 1);
15349 gen_helper_ei(t0, cpu_env);
15350 gen_store_gpr(t0, rt);
15351 /* Stop translation as we may have switched the execution mode */
15352 ctx->bstate = BS_STOP;
15353 break;
15354 default: /* Invalid */
15355 MIPS_INVAL("mfmc0");
15356 generate_exception(ctx, EXCP_RI);
15357 break;
15359 tcg_temp_free(t0);
15361 #endif /* !CONFIG_USER_ONLY */
15362 break;
15363 case OPC_RDPGPR:
15364 check_insn(ctx, ISA_MIPS32R2);
15365 gen_load_srsgpr(rt, rd);
15366 break;
15367 case OPC_WRPGPR:
15368 check_insn(ctx, ISA_MIPS32R2);
15369 gen_store_srsgpr(rt, rd);
15370 break;
15371 default:
15372 MIPS_INVAL("cp0");
15373 generate_exception(ctx, EXCP_RI);
15374 break;
15376 break;
15377 case OPC_ADDI: /* Arithmetic with immediate opcode */
15378 case OPC_ADDIU:
15379 gen_arith_imm(ctx, op, rt, rs, imm);
15380 break;
15381 case OPC_SLTI: /* Set on less than with immediate opcode */
15382 case OPC_SLTIU:
15383 gen_slt_imm(ctx, op, rt, rs, imm);
15384 break;
15385 case OPC_ANDI: /* Arithmetic with immediate opcode */
15386 case OPC_LUI:
15387 case OPC_ORI:
15388 case OPC_XORI:
15389 gen_logic_imm(ctx, op, rt, rs, imm);
15390 break;
15391 case OPC_J ... OPC_JAL: /* Jump */
15392 offset = (int32_t)(ctx->opcode & 0x3FFFFFF) << 2;
15393 gen_compute_branch(ctx, op, 4, rs, rt, offset);
15394 break;
15395 case OPC_BEQ ... OPC_BGTZ: /* Branch */
15396 case OPC_BEQL ... OPC_BGTZL:
15397 gen_compute_branch(ctx, op, 4, rs, rt, imm << 2);
15398 break;
15399 case OPC_LB ... OPC_LWR: /* Load and stores */
15400 case OPC_LL:
15401 gen_ld(ctx, op, rt, rs, imm);
15402 break;
15403 case OPC_SB ... OPC_SW:
15404 case OPC_SWR:
15405 gen_st(ctx, op, rt, rs, imm);
15406 break;
15407 case OPC_SC:
15408 gen_st_cond(ctx, op, rt, rs, imm);
15409 break;
15410 case OPC_CACHE:
15411 check_cp0_enabled(ctx);
15412 check_insn(ctx, ISA_MIPS3 | ISA_MIPS32);
15413 /* Treat as NOP. */
15414 break;
15415 case OPC_PREF:
15416 check_insn(ctx, ISA_MIPS4 | ISA_MIPS32);
15417 /* Treat as NOP. */
15418 break;
15420 /* Floating point (COP1). */
15421 case OPC_LWC1:
15422 case OPC_LDC1:
15423 case OPC_SWC1:
15424 case OPC_SDC1:
15425 gen_cop1_ldst(env, ctx, op, rt, rs, imm);
15426 break;
15428 case OPC_CP1:
15429 if (env->CP0_Config1 & (1 << CP0C1_FP)) {
15430 check_cp1_enabled(ctx);
15431 op1 = MASK_CP1(ctx->opcode);
15432 switch (op1) {
15433 case OPC_MFHC1:
15434 case OPC_MTHC1:
15435 check_insn(ctx, ISA_MIPS32R2);
15436 case OPC_MFC1:
15437 case OPC_CFC1:
15438 case OPC_MTC1:
15439 case OPC_CTC1:
15440 gen_cp1(ctx, op1, rt, rd);
15441 break;
15442 #if defined(TARGET_MIPS64)
15443 case OPC_DMFC1:
15444 case OPC_DMTC1:
15445 check_insn(ctx, ISA_MIPS3);
15446 gen_cp1(ctx, op1, rt, rd);
15447 break;
15448 #endif
15449 case OPC_BC1ANY2:
15450 case OPC_BC1ANY4:
15451 check_cop1x(ctx);
15452 check_insn(ctx, ASE_MIPS3D);
15453 /* fall through */
15454 case OPC_BC1:
15455 gen_compute_branch1(ctx, MASK_BC1(ctx->opcode),
15456 (rt >> 2) & 0x7, imm << 2);
15457 break;
15458 case OPC_S_FMT:
15459 case OPC_D_FMT:
15460 case OPC_W_FMT:
15461 case OPC_L_FMT:
15462 case OPC_PS_FMT:
15463 gen_farith(ctx, ctx->opcode & FOP(0x3f, 0x1f), rt, rd, sa,
15464 (imm >> 8) & 0x7);
15465 break;
15466 default:
15467 MIPS_INVAL("cp1");
15468 generate_exception (ctx, EXCP_RI);
15469 break;
15471 } else {
15472 generate_exception_err(ctx, EXCP_CpU, 1);
15474 break;
15476 /* COP2. */
15477 case OPC_LWC2:
15478 case OPC_LDC2:
15479 case OPC_SWC2:
15480 case OPC_SDC2:
15481 /* COP2: Not implemented. */
15482 generate_exception_err(ctx, EXCP_CpU, 2);
15483 break;
15484 case OPC_CP2:
15485 check_insn(ctx, INSN_LOONGSON2F);
15486 /* Note that these instructions use different fields. */
15487 gen_loongson_multimedia(ctx, sa, rd, rt);
15488 break;
15490 case OPC_CP3:
15491 if (env->CP0_Config1 & (1 << CP0C1_FP)) {
15492 check_cp1_enabled(ctx);
15493 op1 = MASK_CP3(ctx->opcode);
15494 switch (op1) {
15495 case OPC_LWXC1:
15496 case OPC_LDXC1:
15497 case OPC_LUXC1:
15498 case OPC_SWXC1:
15499 case OPC_SDXC1:
15500 case OPC_SUXC1:
15501 gen_flt3_ldst(ctx, op1, sa, rd, rs, rt);
15502 break;
15503 case OPC_PREFX:
15504 /* Treat as NOP. */
15505 break;
15506 case OPC_ALNV_PS:
15507 case OPC_MADD_S:
15508 case OPC_MADD_D:
15509 case OPC_MADD_PS:
15510 case OPC_MSUB_S:
15511 case OPC_MSUB_D:
15512 case OPC_MSUB_PS:
15513 case OPC_NMADD_S:
15514 case OPC_NMADD_D:
15515 case OPC_NMADD_PS:
15516 case OPC_NMSUB_S:
15517 case OPC_NMSUB_D:
15518 case OPC_NMSUB_PS:
15519 gen_flt3_arith(ctx, op1, sa, rs, rd, rt);
15520 break;
15521 default:
15522 MIPS_INVAL("cp3");
15523 generate_exception (ctx, EXCP_RI);
15524 break;
15526 } else {
15527 generate_exception_err(ctx, EXCP_CpU, 1);
15529 break;
15531 #if defined(TARGET_MIPS64)
15532 /* MIPS64 opcodes */
15533 case OPC_LWU:
15534 case OPC_LDL ... OPC_LDR:
15535 case OPC_LLD:
15536 case OPC_LD:
15537 check_insn(ctx, ISA_MIPS3);
15538 check_mips_64(ctx);
15539 gen_ld(ctx, op, rt, rs, imm);
15540 break;
15541 case OPC_SDL ... OPC_SDR:
15542 case OPC_SD:
15543 check_insn(ctx, ISA_MIPS3);
15544 check_mips_64(ctx);
15545 gen_st(ctx, op, rt, rs, imm);
15546 break;
15547 case OPC_SCD:
15548 check_insn(ctx, ISA_MIPS3);
15549 check_mips_64(ctx);
15550 gen_st_cond(ctx, op, rt, rs, imm);
15551 break;
15552 case OPC_DADDI:
15553 case OPC_DADDIU:
15554 check_insn(ctx, ISA_MIPS3);
15555 check_mips_64(ctx);
15556 gen_arith_imm(ctx, op, rt, rs, imm);
15557 break;
15558 #endif
15559 case OPC_JALX:
15560 check_insn(ctx, ASE_MIPS16 | ASE_MICROMIPS);
15561 offset = (int32_t)(ctx->opcode & 0x3FFFFFF) << 2;
15562 gen_compute_branch(ctx, op, 4, rs, rt, offset);
15563 break;
15564 case OPC_MDMX:
15565 check_insn(ctx, ASE_MDMX);
15566 /* MDMX: Not implemented. */
15567 default: /* Invalid */
15568 MIPS_INVAL("major opcode");
15569 generate_exception(ctx, EXCP_RI);
15570 break;
15574 static inline void
15575 gen_intermediate_code_internal(MIPSCPU *cpu, TranslationBlock *tb,
15576 bool search_pc)
15578 CPUState *cs = CPU(cpu);
15579 CPUMIPSState *env = &cpu->env;
15580 DisasContext ctx;
15581 target_ulong pc_start;
15582 uint16_t *gen_opc_end;
15583 CPUBreakpoint *bp;
15584 int j, lj = -1;
15585 int num_insns;
15586 int max_insns;
15587 int insn_bytes;
15588 int is_delay;
15590 if (search_pc)
15591 qemu_log("search pc %d\n", search_pc);
15593 pc_start = tb->pc;
15594 gen_opc_end = tcg_ctx.gen_opc_buf + OPC_MAX_SIZE;
15595 ctx.pc = pc_start;
15596 ctx.saved_pc = -1;
15597 ctx.singlestep_enabled = cs->singlestep_enabled;
15598 ctx.insn_flags = env->insn_flags;
15599 ctx.tb = tb;
15600 ctx.bstate = BS_NONE;
15601 /* Restore delay slot state from the tb context. */
15602 ctx.hflags = (uint32_t)tb->flags; /* FIXME: maybe use 64 bits here? */
15603 restore_cpu_state(env, &ctx);
15604 #ifdef CONFIG_USER_ONLY
15605 ctx.mem_idx = MIPS_HFLAG_UM;
15606 #else
15607 ctx.mem_idx = ctx.hflags & MIPS_HFLAG_KSU;
15608 #endif
15609 num_insns = 0;
15610 max_insns = tb->cflags & CF_COUNT_MASK;
15611 if (max_insns == 0)
15612 max_insns = CF_COUNT_MASK;
15613 LOG_DISAS("\ntb %p idx %d hflags %04x\n", tb, ctx.mem_idx, ctx.hflags);
15614 gen_tb_start();
15615 while (ctx.bstate == BS_NONE) {
15616 if (unlikely(!QTAILQ_EMPTY(&cs->breakpoints))) {
15617 QTAILQ_FOREACH(bp, &cs->breakpoints, entry) {
15618 if (bp->pc == ctx.pc) {
15619 save_cpu_state(&ctx, 1);
15620 ctx.bstate = BS_BRANCH;
15621 gen_helper_0e0i(raise_exception, EXCP_DEBUG);
15622 /* Include the breakpoint location or the tb won't
15623 * be flushed when it must be. */
15624 ctx.pc += 4;
15625 goto done_generating;
15630 if (search_pc) {
15631 j = tcg_ctx.gen_opc_ptr - tcg_ctx.gen_opc_buf;
15632 if (lj < j) {
15633 lj++;
15634 while (lj < j)
15635 tcg_ctx.gen_opc_instr_start[lj++] = 0;
15637 tcg_ctx.gen_opc_pc[lj] = ctx.pc;
15638 gen_opc_hflags[lj] = ctx.hflags & MIPS_HFLAG_BMASK;
15639 gen_opc_btarget[lj] = ctx.btarget;
15640 tcg_ctx.gen_opc_instr_start[lj] = 1;
15641 tcg_ctx.gen_opc_icount[lj] = num_insns;
15643 if (num_insns + 1 == max_insns && (tb->cflags & CF_LAST_IO))
15644 gen_io_start();
15646 is_delay = ctx.hflags & MIPS_HFLAG_BMASK;
15647 if (!(ctx.hflags & MIPS_HFLAG_M16)) {
15648 ctx.opcode = cpu_ldl_code(env, ctx.pc);
15649 insn_bytes = 4;
15650 decode_opc(env, &ctx);
15651 } else if (ctx.insn_flags & ASE_MICROMIPS) {
15652 ctx.opcode = cpu_lduw_code(env, ctx.pc);
15653 insn_bytes = decode_micromips_opc(env, &ctx);
15654 } else if (ctx.insn_flags & ASE_MIPS16) {
15655 ctx.opcode = cpu_lduw_code(env, ctx.pc);
15656 insn_bytes = decode_mips16_opc(env, &ctx);
15657 } else {
15658 generate_exception(&ctx, EXCP_RI);
15659 ctx.bstate = BS_STOP;
15660 break;
15662 if (is_delay) {
15663 handle_delay_slot(&ctx, insn_bytes);
15665 ctx.pc += insn_bytes;
15667 num_insns++;
15669 /* Execute a branch and its delay slot as a single instruction.
15670 This is what GDB expects and is consistent with what the
15671 hardware does (e.g. if a delay slot instruction faults, the
15672 reported PC is the PC of the branch). */
15673 if (cs->singlestep_enabled && (ctx.hflags & MIPS_HFLAG_BMASK) == 0) {
15674 break;
15677 if ((ctx.pc & (TARGET_PAGE_SIZE - 1)) == 0)
15678 break;
15680 if (tcg_ctx.gen_opc_ptr >= gen_opc_end) {
15681 break;
15684 if (num_insns >= max_insns)
15685 break;
15687 if (singlestep)
15688 break;
15690 if (tb->cflags & CF_LAST_IO) {
15691 gen_io_end();
15693 if (cs->singlestep_enabled && ctx.bstate != BS_BRANCH) {
15694 save_cpu_state(&ctx, ctx.bstate == BS_NONE);
15695 gen_helper_0e0i(raise_exception, EXCP_DEBUG);
15696 } else {
15697 switch (ctx.bstate) {
15698 case BS_STOP:
15699 gen_goto_tb(&ctx, 0, ctx.pc);
15700 break;
15701 case BS_NONE:
15702 save_cpu_state(&ctx, 0);
15703 gen_goto_tb(&ctx, 0, ctx.pc);
15704 break;
15705 case BS_EXCP:
15706 tcg_gen_exit_tb(0);
15707 break;
15708 case BS_BRANCH:
15709 default:
15710 break;
15713 done_generating:
15714 gen_tb_end(tb, num_insns);
15715 *tcg_ctx.gen_opc_ptr = INDEX_op_end;
15716 if (search_pc) {
15717 j = tcg_ctx.gen_opc_ptr - tcg_ctx.gen_opc_buf;
15718 lj++;
15719 while (lj <= j)
15720 tcg_ctx.gen_opc_instr_start[lj++] = 0;
15721 } else {
15722 tb->size = ctx.pc - pc_start;
15723 tb->icount = num_insns;
15725 #ifdef DEBUG_DISAS
15726 LOG_DISAS("\n");
15727 if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM)) {
15728 qemu_log("IN: %s\n", lookup_symbol(pc_start));
15729 log_target_disas(env, pc_start, ctx.pc - pc_start, 0);
15730 qemu_log("\n");
15732 #endif
15735 void gen_intermediate_code (CPUMIPSState *env, struct TranslationBlock *tb)
15737 gen_intermediate_code_internal(mips_env_get_cpu(env), tb, false);
15740 void gen_intermediate_code_pc (CPUMIPSState *env, struct TranslationBlock *tb)
15742 gen_intermediate_code_internal(mips_env_get_cpu(env), tb, true);
15745 static void fpu_dump_state(CPUMIPSState *env, FILE *f, fprintf_function fpu_fprintf,
15746 int flags)
15748 int i;
15749 int is_fpu64 = !!(env->hflags & MIPS_HFLAG_F64);
15751 #define printfpr(fp) \
15752 do { \
15753 if (is_fpu64) \
15754 fpu_fprintf(f, "w:%08x d:%016" PRIx64 \
15755 " fd:%13g fs:%13g psu: %13g\n", \
15756 (fp)->w[FP_ENDIAN_IDX], (fp)->d, \
15757 (double)(fp)->fd, \
15758 (double)(fp)->fs[FP_ENDIAN_IDX], \
15759 (double)(fp)->fs[!FP_ENDIAN_IDX]); \
15760 else { \
15761 fpr_t tmp; \
15762 tmp.w[FP_ENDIAN_IDX] = (fp)->w[FP_ENDIAN_IDX]; \
15763 tmp.w[!FP_ENDIAN_IDX] = ((fp) + 1)->w[FP_ENDIAN_IDX]; \
15764 fpu_fprintf(f, "w:%08x d:%016" PRIx64 \
15765 " fd:%13g fs:%13g psu:%13g\n", \
15766 tmp.w[FP_ENDIAN_IDX], tmp.d, \
15767 (double)tmp.fd, \
15768 (double)tmp.fs[FP_ENDIAN_IDX], \
15769 (double)tmp.fs[!FP_ENDIAN_IDX]); \
15771 } while(0)
15774 fpu_fprintf(f, "CP1 FCR0 0x%08x FCR31 0x%08x SR.FR %d fp_status 0x%02x\n",
15775 env->active_fpu.fcr0, env->active_fpu.fcr31, is_fpu64,
15776 get_float_exception_flags(&env->active_fpu.fp_status));
15777 for (i = 0; i < 32; (is_fpu64) ? i++ : (i += 2)) {
15778 fpu_fprintf(f, "%3s: ", fregnames[i]);
15779 printfpr(&env->active_fpu.fpr[i]);
15782 #undef printfpr
15785 #if defined(TARGET_MIPS64) && defined(MIPS_DEBUG_SIGN_EXTENSIONS)
15786 /* Debug help: The architecture requires 32bit code to maintain proper
15787 sign-extended values on 64bit machines. */
15789 #define SIGN_EXT_P(val) ((((val) & ~0x7fffffff) == 0) || (((val) & ~0x7fffffff) == ~0x7fffffff))
15791 static void
15792 cpu_mips_check_sign_extensions (CPUMIPSState *env, FILE *f,
15793 fprintf_function cpu_fprintf,
15794 int flags)
15796 int i;
15798 if (!SIGN_EXT_P(env->active_tc.PC))
15799 cpu_fprintf(f, "BROKEN: pc=0x" TARGET_FMT_lx "\n", env->active_tc.PC);
15800 if (!SIGN_EXT_P(env->active_tc.HI[0]))
15801 cpu_fprintf(f, "BROKEN: HI=0x" TARGET_FMT_lx "\n", env->active_tc.HI[0]);
15802 if (!SIGN_EXT_P(env->active_tc.LO[0]))
15803 cpu_fprintf(f, "BROKEN: LO=0x" TARGET_FMT_lx "\n", env->active_tc.LO[0]);
15804 if (!SIGN_EXT_P(env->btarget))
15805 cpu_fprintf(f, "BROKEN: btarget=0x" TARGET_FMT_lx "\n", env->btarget);
15807 for (i = 0; i < 32; i++) {
15808 if (!SIGN_EXT_P(env->active_tc.gpr[i]))
15809 cpu_fprintf(f, "BROKEN: %s=0x" TARGET_FMT_lx "\n", regnames[i], env->active_tc.gpr[i]);
15812 if (!SIGN_EXT_P(env->CP0_EPC))
15813 cpu_fprintf(f, "BROKEN: EPC=0x" TARGET_FMT_lx "\n", env->CP0_EPC);
15814 if (!SIGN_EXT_P(env->lladdr))
15815 cpu_fprintf(f, "BROKEN: LLAddr=0x" TARGET_FMT_lx "\n", env->lladdr);
15817 #endif
15819 void mips_cpu_dump_state(CPUState *cs, FILE *f, fprintf_function cpu_fprintf,
15820 int flags)
15822 MIPSCPU *cpu = MIPS_CPU(cs);
15823 CPUMIPSState *env = &cpu->env;
15824 int i;
15826 cpu_fprintf(f, "pc=0x" TARGET_FMT_lx " HI=0x" TARGET_FMT_lx
15827 " LO=0x" TARGET_FMT_lx " ds %04x "
15828 TARGET_FMT_lx " " TARGET_FMT_ld "\n",
15829 env->active_tc.PC, env->active_tc.HI[0], env->active_tc.LO[0],
15830 env->hflags, env->btarget, env->bcond);
15831 for (i = 0; i < 32; i++) {
15832 if ((i & 3) == 0)
15833 cpu_fprintf(f, "GPR%02d:", i);
15834 cpu_fprintf(f, " %s " TARGET_FMT_lx, regnames[i], env->active_tc.gpr[i]);
15835 if ((i & 3) == 3)
15836 cpu_fprintf(f, "\n");
15839 cpu_fprintf(f, "CP0 Status 0x%08x Cause 0x%08x EPC 0x" TARGET_FMT_lx "\n",
15840 env->CP0_Status, env->CP0_Cause, env->CP0_EPC);
15841 cpu_fprintf(f, " Config0 0x%08x Config1 0x%08x LLAddr 0x" TARGET_FMT_lx "\n",
15842 env->CP0_Config0, env->CP0_Config1, env->lladdr);
15843 if (env->hflags & MIPS_HFLAG_FPU)
15844 fpu_dump_state(env, f, cpu_fprintf, flags);
15845 #if defined(TARGET_MIPS64) && defined(MIPS_DEBUG_SIGN_EXTENSIONS)
15846 cpu_mips_check_sign_extensions(env, f, cpu_fprintf, flags);
15847 #endif
15850 void mips_tcg_init(void)
15852 int i;
15853 static int inited;
15855 /* Initialize various static tables. */
15856 if (inited)
15857 return;
15859 cpu_env = tcg_global_reg_new_ptr(TCG_AREG0, "env");
15860 TCGV_UNUSED(cpu_gpr[0]);
15861 for (i = 1; i < 32; i++)
15862 cpu_gpr[i] = tcg_global_mem_new(TCG_AREG0,
15863 offsetof(CPUMIPSState, active_tc.gpr[i]),
15864 regnames[i]);
15866 for (i = 0; i < 32; i++) {
15867 int off = offsetof(CPUMIPSState, active_fpu.fpr[i]);
15868 fpu_f64[i] = tcg_global_mem_new_i64(TCG_AREG0, off, fregnames[i]);
15871 cpu_PC = tcg_global_mem_new(TCG_AREG0,
15872 offsetof(CPUMIPSState, active_tc.PC), "PC");
15873 for (i = 0; i < MIPS_DSP_ACC; i++) {
15874 cpu_HI[i] = tcg_global_mem_new(TCG_AREG0,
15875 offsetof(CPUMIPSState, active_tc.HI[i]),
15876 regnames_HI[i]);
15877 cpu_LO[i] = tcg_global_mem_new(TCG_AREG0,
15878 offsetof(CPUMIPSState, active_tc.LO[i]),
15879 regnames_LO[i]);
15880 cpu_ACX[i] = tcg_global_mem_new(TCG_AREG0,
15881 offsetof(CPUMIPSState, active_tc.ACX[i]),
15882 regnames_ACX[i]);
15884 cpu_dspctrl = tcg_global_mem_new(TCG_AREG0,
15885 offsetof(CPUMIPSState, active_tc.DSPControl),
15886 "DSPControl");
15887 bcond = tcg_global_mem_new(TCG_AREG0,
15888 offsetof(CPUMIPSState, bcond), "bcond");
15889 btarget = tcg_global_mem_new(TCG_AREG0,
15890 offsetof(CPUMIPSState, btarget), "btarget");
15891 hflags = tcg_global_mem_new_i32(TCG_AREG0,
15892 offsetof(CPUMIPSState, hflags), "hflags");
15894 fpu_fcr0 = tcg_global_mem_new_i32(TCG_AREG0,
15895 offsetof(CPUMIPSState, active_fpu.fcr0),
15896 "fcr0");
15897 fpu_fcr31 = tcg_global_mem_new_i32(TCG_AREG0,
15898 offsetof(CPUMIPSState, active_fpu.fcr31),
15899 "fcr31");
15901 inited = 1;
15904 #include "translate_init.c"
15906 MIPSCPU *cpu_mips_init(const char *cpu_model)
15908 MIPSCPU *cpu;
15909 CPUMIPSState *env;
15910 const mips_def_t *def;
15912 def = cpu_mips_find_by_name(cpu_model);
15913 if (!def)
15914 return NULL;
15915 cpu = MIPS_CPU(object_new(TYPE_MIPS_CPU));
15916 env = &cpu->env;
15917 env->cpu_model = def;
15919 #ifndef CONFIG_USER_ONLY
15920 mmu_init(env, def);
15921 #endif
15922 fpu_init(env, def);
15923 mvp_init(env, def);
15925 object_property_set_bool(OBJECT(cpu), true, "realized", NULL);
15927 return cpu;
15930 void cpu_state_reset(CPUMIPSState *env)
15932 MIPSCPU *cpu = mips_env_get_cpu(env);
15933 CPUState *cs = CPU(cpu);
15935 /* Reset registers to their default values */
15936 env->CP0_PRid = env->cpu_model->CP0_PRid;
15937 env->CP0_Config0 = env->cpu_model->CP0_Config0;
15938 #ifdef TARGET_WORDS_BIGENDIAN
15939 env->CP0_Config0 |= (1 << CP0C0_BE);
15940 #endif
15941 env->CP0_Config1 = env->cpu_model->CP0_Config1;
15942 env->CP0_Config2 = env->cpu_model->CP0_Config2;
15943 env->CP0_Config3 = env->cpu_model->CP0_Config3;
15944 env->CP0_Config4 = env->cpu_model->CP0_Config4;
15945 env->CP0_Config4_rw_bitmask = env->cpu_model->CP0_Config4_rw_bitmask;
15946 env->CP0_Config5 = env->cpu_model->CP0_Config5;
15947 env->CP0_Config5_rw_bitmask = env->cpu_model->CP0_Config5_rw_bitmask;
15948 env->CP0_Config6 = env->cpu_model->CP0_Config6;
15949 env->CP0_Config7 = env->cpu_model->CP0_Config7;
15950 env->CP0_LLAddr_rw_bitmask = env->cpu_model->CP0_LLAddr_rw_bitmask
15951 << env->cpu_model->CP0_LLAddr_shift;
15952 env->CP0_LLAddr_shift = env->cpu_model->CP0_LLAddr_shift;
15953 env->SYNCI_Step = env->cpu_model->SYNCI_Step;
15954 env->CCRes = env->cpu_model->CCRes;
15955 env->CP0_Status_rw_bitmask = env->cpu_model->CP0_Status_rw_bitmask;
15956 env->CP0_TCStatus_rw_bitmask = env->cpu_model->CP0_TCStatus_rw_bitmask;
15957 env->CP0_SRSCtl = env->cpu_model->CP0_SRSCtl;
15958 env->current_tc = 0;
15959 env->SEGBITS = env->cpu_model->SEGBITS;
15960 env->SEGMask = (target_ulong)((1ULL << env->cpu_model->SEGBITS) - 1);
15961 #if defined(TARGET_MIPS64)
15962 if (env->cpu_model->insn_flags & ISA_MIPS3) {
15963 env->SEGMask |= 3ULL << 62;
15965 #endif
15966 env->PABITS = env->cpu_model->PABITS;
15967 env->PAMask = (target_ulong)((1ULL << env->cpu_model->PABITS) - 1);
15968 env->CP0_SRSConf0_rw_bitmask = env->cpu_model->CP0_SRSConf0_rw_bitmask;
15969 env->CP0_SRSConf0 = env->cpu_model->CP0_SRSConf0;
15970 env->CP0_SRSConf1_rw_bitmask = env->cpu_model->CP0_SRSConf1_rw_bitmask;
15971 env->CP0_SRSConf1 = env->cpu_model->CP0_SRSConf1;
15972 env->CP0_SRSConf2_rw_bitmask = env->cpu_model->CP0_SRSConf2_rw_bitmask;
15973 env->CP0_SRSConf2 = env->cpu_model->CP0_SRSConf2;
15974 env->CP0_SRSConf3_rw_bitmask = env->cpu_model->CP0_SRSConf3_rw_bitmask;
15975 env->CP0_SRSConf3 = env->cpu_model->CP0_SRSConf3;
15976 env->CP0_SRSConf4_rw_bitmask = env->cpu_model->CP0_SRSConf4_rw_bitmask;
15977 env->CP0_SRSConf4 = env->cpu_model->CP0_SRSConf4;
15978 env->active_fpu.fcr0 = env->cpu_model->CP1_fcr0;
15979 env->insn_flags = env->cpu_model->insn_flags;
15981 #if defined(CONFIG_USER_ONLY)
15982 env->CP0_Status = (MIPS_HFLAG_UM << CP0St_KSU);
15983 # ifdef TARGET_MIPS64
15984 /* Enable 64-bit register mode. */
15985 env->CP0_Status |= (1 << CP0St_PX);
15986 # endif
15987 # ifdef TARGET_ABI_MIPSN64
15988 /* Enable 64-bit address mode. */
15989 env->CP0_Status |= (1 << CP0St_UX);
15990 # endif
15991 /* Enable access to the CPUNum, SYNCI_Step, CC, and CCRes RDHWR
15992 hardware registers. */
15993 env->CP0_HWREna |= 0x0000000F;
15994 if (env->CP0_Config1 & (1 << CP0C1_FP)) {
15995 env->CP0_Status |= (1 << CP0St_CU1);
15997 if (env->CP0_Config3 & (1 << CP0C3_DSPP)) {
15998 env->CP0_Status |= (1 << CP0St_MX);
16000 # if defined(TARGET_MIPS64)
16001 /* For MIPS64, init FR bit to 1 if FPU unit is there and bit is writable. */
16002 if ((env->CP0_Config1 & (1 << CP0C1_FP)) &&
16003 (env->CP0_Status_rw_bitmask & (1 << CP0St_FR))) {
16004 env->CP0_Status |= (1 << CP0St_FR);
16006 # endif
16007 #else
16008 if (env->hflags & MIPS_HFLAG_BMASK) {
16009 /* If the exception was raised from a delay slot,
16010 come back to the jump. */
16011 env->CP0_ErrorEPC = env->active_tc.PC - 4;
16012 } else {
16013 env->CP0_ErrorEPC = env->active_tc.PC;
16015 env->active_tc.PC = (int32_t)0xBFC00000;
16016 env->CP0_Random = env->tlb->nb_tlb - 1;
16017 env->tlb->tlb_in_use = env->tlb->nb_tlb;
16018 env->CP0_Wired = 0;
16019 env->CP0_EBase = 0x80000000 | (cs->cpu_index & 0x3FF);
16020 env->CP0_Status = (1 << CP0St_BEV) | (1 << CP0St_ERL);
16021 /* vectored interrupts not implemented, timer on int 7,
16022 no performance counters. */
16023 env->CP0_IntCtl = 0xe0000000;
16025 int i;
16027 for (i = 0; i < 7; i++) {
16028 env->CP0_WatchLo[i] = 0;
16029 env->CP0_WatchHi[i] = 0x80000000;
16031 env->CP0_WatchLo[7] = 0;
16032 env->CP0_WatchHi[7] = 0;
16034 /* Count register increments in debug mode, EJTAG version 1 */
16035 env->CP0_Debug = (1 << CP0DB_CNT) | (0x1 << CP0DB_VER);
16037 if (env->CP0_Config3 & (1 << CP0C3_MT)) {
16038 int i;
16040 /* Only TC0 on VPE 0 starts as active. */
16041 for (i = 0; i < ARRAY_SIZE(env->tcs); i++) {
16042 env->tcs[i].CP0_TCBind = cs->cpu_index << CP0TCBd_CurVPE;
16043 env->tcs[i].CP0_TCHalt = 1;
16045 env->active_tc.CP0_TCHalt = 1;
16046 cs->halted = 1;
16048 if (cs->cpu_index == 0) {
16049 /* VPE0 starts up enabled. */
16050 env->mvp->CP0_MVPControl |= (1 << CP0MVPCo_EVP);
16051 env->CP0_VPEConf0 |= (1 << CP0VPEC0_MVP) | (1 << CP0VPEC0_VPA);
16053 /* TC0 starts up unhalted. */
16054 cs->halted = 0;
16055 env->active_tc.CP0_TCHalt = 0;
16056 env->tcs[0].CP0_TCHalt = 0;
16057 /* With thread 0 active. */
16058 env->active_tc.CP0_TCStatus = (1 << CP0TCSt_A);
16059 env->tcs[0].CP0_TCStatus = (1 << CP0TCSt_A);
16062 #endif
16063 compute_hflags(env);
16064 cs->exception_index = EXCP_NONE;
16067 void restore_state_to_opc(CPUMIPSState *env, TranslationBlock *tb, int pc_pos)
16069 env->active_tc.PC = tcg_ctx.gen_opc_pc[pc_pos];
16070 env->hflags &= ~MIPS_HFLAG_BMASK;
16071 env->hflags |= gen_opc_hflags[pc_pos];
16072 switch (env->hflags & MIPS_HFLAG_BMASK_BASE) {
16073 case MIPS_HFLAG_BR:
16074 break;
16075 case MIPS_HFLAG_BC:
16076 case MIPS_HFLAG_BL:
16077 case MIPS_HFLAG_B:
16078 env->btarget = gen_opc_btarget[pc_pos];
16079 break;