target-ppc: POWER8 supports the MSR_LE bit
[qemu/kevin.git] / target-mips / translate.c
blob05f82d2f9bbb482cd3b004c176abed9ed9c5696c
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(DisasContext *ctx, TCGv_i32 t, int reg)
1221 if (ctx->hflags & MIPS_HFLAG_F64) {
1222 TCGv_i64 t64 = tcg_temp_new_i64();
1223 tcg_gen_shri_i64(t64, fpu_f64[reg], 32);
1224 tcg_gen_trunc_i64_i32(t, t64);
1225 tcg_temp_free_i64(t64);
1226 } else {
1227 gen_load_fpr32(t, reg | 1);
1231 static void gen_store_fpr32h(DisasContext *ctx, TCGv_i32 t, int reg)
1233 if (ctx->hflags & MIPS_HFLAG_F64) {
1234 TCGv_i64 t64 = tcg_temp_new_i64();
1235 tcg_gen_extu_i32_i64(t64, t);
1236 tcg_gen_deposit_i64(fpu_f64[reg], fpu_f64[reg], t64, 32, 32);
1237 tcg_temp_free_i64(t64);
1238 } else {
1239 gen_store_fpr32(t, reg | 1);
1243 static void gen_load_fpr64(DisasContext *ctx, TCGv_i64 t, int reg)
1245 if (ctx->hflags & MIPS_HFLAG_F64) {
1246 tcg_gen_mov_i64(t, fpu_f64[reg]);
1247 } else {
1248 tcg_gen_concat32_i64(t, fpu_f64[reg & ~1], fpu_f64[reg | 1]);
1252 static void gen_store_fpr64(DisasContext *ctx, TCGv_i64 t, int reg)
1254 if (ctx->hflags & MIPS_HFLAG_F64) {
1255 tcg_gen_mov_i64(fpu_f64[reg], t);
1256 } else {
1257 TCGv_i64 t0;
1258 tcg_gen_deposit_i64(fpu_f64[reg & ~1], fpu_f64[reg & ~1], t, 0, 32);
1259 t0 = tcg_temp_new_i64();
1260 tcg_gen_shri_i64(t0, t, 32);
1261 tcg_gen_deposit_i64(fpu_f64[reg | 1], fpu_f64[reg | 1], t0, 0, 32);
1262 tcg_temp_free_i64(t0);
1266 static inline int get_fp_bit (int cc)
1268 if (cc)
1269 return 24 + cc;
1270 else
1271 return 23;
1274 /* Tests */
1275 static inline void gen_save_pc(target_ulong pc)
1277 tcg_gen_movi_tl(cpu_PC, pc);
1280 static inline void save_cpu_state (DisasContext *ctx, int do_save_pc)
1282 LOG_DISAS("hflags %08x saved %08x\n", ctx->hflags, ctx->saved_hflags);
1283 if (do_save_pc && ctx->pc != ctx->saved_pc) {
1284 gen_save_pc(ctx->pc);
1285 ctx->saved_pc = ctx->pc;
1287 if (ctx->hflags != ctx->saved_hflags) {
1288 tcg_gen_movi_i32(hflags, ctx->hflags);
1289 ctx->saved_hflags = ctx->hflags;
1290 switch (ctx->hflags & MIPS_HFLAG_BMASK_BASE) {
1291 case MIPS_HFLAG_BR:
1292 break;
1293 case MIPS_HFLAG_BC:
1294 case MIPS_HFLAG_BL:
1295 case MIPS_HFLAG_B:
1296 tcg_gen_movi_tl(btarget, ctx->btarget);
1297 break;
1302 static inline void restore_cpu_state (CPUMIPSState *env, DisasContext *ctx)
1304 ctx->saved_hflags = ctx->hflags;
1305 switch (ctx->hflags & MIPS_HFLAG_BMASK_BASE) {
1306 case MIPS_HFLAG_BR:
1307 break;
1308 case MIPS_HFLAG_BC:
1309 case MIPS_HFLAG_BL:
1310 case MIPS_HFLAG_B:
1311 ctx->btarget = env->btarget;
1312 break;
1316 static inline void
1317 generate_exception_err (DisasContext *ctx, int excp, int err)
1319 TCGv_i32 texcp = tcg_const_i32(excp);
1320 TCGv_i32 terr = tcg_const_i32(err);
1321 save_cpu_state(ctx, 1);
1322 gen_helper_raise_exception_err(cpu_env, texcp, terr);
1323 tcg_temp_free_i32(terr);
1324 tcg_temp_free_i32(texcp);
1327 static inline void
1328 generate_exception (DisasContext *ctx, int excp)
1330 save_cpu_state(ctx, 1);
1331 gen_helper_0e0i(raise_exception, excp);
1334 /* Addresses computation */
1335 static inline void gen_op_addr_add (DisasContext *ctx, TCGv ret, TCGv arg0, TCGv arg1)
1337 tcg_gen_add_tl(ret, arg0, arg1);
1339 #if defined(TARGET_MIPS64)
1340 /* For compatibility with 32-bit code, data reference in user mode
1341 with Status_UX = 0 should be casted to 32-bit and sign extended.
1342 See the MIPS64 PRA manual, section 4.10. */
1343 if (((ctx->hflags & MIPS_HFLAG_KSU) == MIPS_HFLAG_UM) &&
1344 !(ctx->hflags & MIPS_HFLAG_UX)) {
1345 tcg_gen_ext32s_i64(ret, ret);
1347 #endif
1350 static inline void check_cp0_enabled(DisasContext *ctx)
1352 if (unlikely(!(ctx->hflags & MIPS_HFLAG_CP0)))
1353 generate_exception_err(ctx, EXCP_CpU, 0);
1356 static inline void check_cp1_enabled(DisasContext *ctx)
1358 if (unlikely(!(ctx->hflags & MIPS_HFLAG_FPU)))
1359 generate_exception_err(ctx, EXCP_CpU, 1);
1362 /* Verify that the processor is running with COP1X instructions enabled.
1363 This is associated with the nabla symbol in the MIPS32 and MIPS64
1364 opcode tables. */
1366 static inline void check_cop1x(DisasContext *ctx)
1368 if (unlikely(!(ctx->hflags & MIPS_HFLAG_COP1X)))
1369 generate_exception(ctx, EXCP_RI);
1372 /* Verify that the processor is running with 64-bit floating-point
1373 operations enabled. */
1375 static inline void check_cp1_64bitmode(DisasContext *ctx)
1377 if (unlikely(~ctx->hflags & (MIPS_HFLAG_F64 | MIPS_HFLAG_COP1X)))
1378 generate_exception(ctx, EXCP_RI);
1382 * Verify if floating point register is valid; an operation is not defined
1383 * if bit 0 of any register specification is set and the FR bit in the
1384 * Status register equals zero, since the register numbers specify an
1385 * even-odd pair of adjacent coprocessor general registers. When the FR bit
1386 * in the Status register equals one, both even and odd register numbers
1387 * are valid. This limitation exists only for 64 bit wide (d,l,ps) registers.
1389 * Multiple 64 bit wide registers can be checked by calling
1390 * gen_op_cp1_registers(freg1 | freg2 | ... | fregN);
1392 static inline void check_cp1_registers(DisasContext *ctx, int regs)
1394 if (unlikely(!(ctx->hflags & MIPS_HFLAG_F64) && (regs & 1)))
1395 generate_exception(ctx, EXCP_RI);
1398 /* Verify that the processor is running with DSP instructions enabled.
1399 This is enabled by CP0 Status register MX(24) bit.
1402 static inline void check_dsp(DisasContext *ctx)
1404 if (unlikely(!(ctx->hflags & MIPS_HFLAG_DSP))) {
1405 if (ctx->insn_flags & ASE_DSP) {
1406 generate_exception(ctx, EXCP_DSPDIS);
1407 } else {
1408 generate_exception(ctx, EXCP_RI);
1413 static inline void check_dspr2(DisasContext *ctx)
1415 if (unlikely(!(ctx->hflags & MIPS_HFLAG_DSPR2))) {
1416 if (ctx->insn_flags & ASE_DSP) {
1417 generate_exception(ctx, EXCP_DSPDIS);
1418 } else {
1419 generate_exception(ctx, EXCP_RI);
1424 /* This code generates a "reserved instruction" exception if the
1425 CPU does not support the instruction set corresponding to flags. */
1426 static inline void check_insn(DisasContext *ctx, int flags)
1428 if (unlikely(!(ctx->insn_flags & flags))) {
1429 generate_exception(ctx, EXCP_RI);
1433 /* This code generates a "reserved instruction" exception if 64-bit
1434 instructions are not enabled. */
1435 static inline void check_mips_64(DisasContext *ctx)
1437 if (unlikely(!(ctx->hflags & MIPS_HFLAG_64)))
1438 generate_exception(ctx, EXCP_RI);
1441 /* Define small wrappers for gen_load_fpr* so that we have a uniform
1442 calling interface for 32 and 64-bit FPRs. No sense in changing
1443 all callers for gen_load_fpr32 when we need the CTX parameter for
1444 this one use. */
1445 #define gen_ldcmp_fpr32(ctx, x, y) gen_load_fpr32(x, y)
1446 #define gen_ldcmp_fpr64(ctx, x, y) gen_load_fpr64(ctx, x, y)
1447 #define FOP_CONDS(type, abs, fmt, ifmt, bits) \
1448 static inline void gen_cmp ## type ## _ ## fmt(DisasContext *ctx, int n, \
1449 int ft, int fs, int cc) \
1451 TCGv_i##bits fp0 = tcg_temp_new_i##bits (); \
1452 TCGv_i##bits fp1 = tcg_temp_new_i##bits (); \
1453 switch (ifmt) { \
1454 case FMT_PS: \
1455 check_cp1_64bitmode(ctx); \
1456 break; \
1457 case FMT_D: \
1458 if (abs) { \
1459 check_cop1x(ctx); \
1461 check_cp1_registers(ctx, fs | ft); \
1462 break; \
1463 case FMT_S: \
1464 if (abs) { \
1465 check_cop1x(ctx); \
1467 break; \
1469 gen_ldcmp_fpr##bits (ctx, fp0, fs); \
1470 gen_ldcmp_fpr##bits (ctx, fp1, ft); \
1471 switch (n) { \
1472 case 0: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _f, fp0, fp1, cc); break;\
1473 case 1: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _un, fp0, fp1, cc); break;\
1474 case 2: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _eq, fp0, fp1, cc); break;\
1475 case 3: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ueq, fp0, fp1, cc); break;\
1476 case 4: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _olt, fp0, fp1, cc); break;\
1477 case 5: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ult, fp0, fp1, cc); break;\
1478 case 6: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ole, fp0, fp1, cc); break;\
1479 case 7: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ule, fp0, fp1, cc); break;\
1480 case 8: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _sf, fp0, fp1, cc); break;\
1481 case 9: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ngle, fp0, fp1, cc); break;\
1482 case 10: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _seq, fp0, fp1, cc); break;\
1483 case 11: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ngl, fp0, fp1, cc); break;\
1484 case 12: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _lt, fp0, fp1, cc); break;\
1485 case 13: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _nge, fp0, fp1, cc); break;\
1486 case 14: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _le, fp0, fp1, cc); break;\
1487 case 15: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ngt, fp0, fp1, cc); break;\
1488 default: abort(); \
1490 tcg_temp_free_i##bits (fp0); \
1491 tcg_temp_free_i##bits (fp1); \
1494 FOP_CONDS(, 0, d, FMT_D, 64)
1495 FOP_CONDS(abs, 1, d, FMT_D, 64)
1496 FOP_CONDS(, 0, s, FMT_S, 32)
1497 FOP_CONDS(abs, 1, s, FMT_S, 32)
1498 FOP_CONDS(, 0, ps, FMT_PS, 64)
1499 FOP_CONDS(abs, 1, ps, FMT_PS, 64)
1500 #undef FOP_CONDS
1501 #undef gen_ldcmp_fpr32
1502 #undef gen_ldcmp_fpr64
1504 /* load/store instructions. */
1505 #ifdef CONFIG_USER_ONLY
1506 #define OP_LD_ATOMIC(insn,fname) \
1507 static inline void op_ld_##insn(TCGv ret, TCGv arg1, DisasContext *ctx) \
1509 TCGv t0 = tcg_temp_new(); \
1510 tcg_gen_mov_tl(t0, arg1); \
1511 tcg_gen_qemu_##fname(ret, arg1, ctx->mem_idx); \
1512 tcg_gen_st_tl(t0, cpu_env, offsetof(CPUMIPSState, lladdr)); \
1513 tcg_gen_st_tl(ret, cpu_env, offsetof(CPUMIPSState, llval)); \
1514 tcg_temp_free(t0); \
1516 #else
1517 #define OP_LD_ATOMIC(insn,fname) \
1518 static inline void op_ld_##insn(TCGv ret, TCGv arg1, DisasContext *ctx) \
1520 gen_helper_1e1i(insn, ret, arg1, ctx->mem_idx); \
1522 #endif
1523 OP_LD_ATOMIC(ll,ld32s);
1524 #if defined(TARGET_MIPS64)
1525 OP_LD_ATOMIC(lld,ld64);
1526 #endif
1527 #undef OP_LD_ATOMIC
1529 #ifdef CONFIG_USER_ONLY
1530 #define OP_ST_ATOMIC(insn,fname,ldname,almask) \
1531 static inline void op_st_##insn(TCGv arg1, TCGv arg2, int rt, DisasContext *ctx) \
1533 TCGv t0 = tcg_temp_new(); \
1534 int l1 = gen_new_label(); \
1535 int l2 = gen_new_label(); \
1537 tcg_gen_andi_tl(t0, arg2, almask); \
1538 tcg_gen_brcondi_tl(TCG_COND_EQ, t0, 0, l1); \
1539 tcg_gen_st_tl(arg2, cpu_env, offsetof(CPUMIPSState, CP0_BadVAddr)); \
1540 generate_exception(ctx, EXCP_AdES); \
1541 gen_set_label(l1); \
1542 tcg_gen_ld_tl(t0, cpu_env, offsetof(CPUMIPSState, lladdr)); \
1543 tcg_gen_brcond_tl(TCG_COND_NE, arg2, t0, l2); \
1544 tcg_gen_movi_tl(t0, rt | ((almask << 3) & 0x20)); \
1545 tcg_gen_st_tl(t0, cpu_env, offsetof(CPUMIPSState, llreg)); \
1546 tcg_gen_st_tl(arg1, cpu_env, offsetof(CPUMIPSState, llnewval)); \
1547 gen_helper_0e0i(raise_exception, EXCP_SC); \
1548 gen_set_label(l2); \
1549 tcg_gen_movi_tl(t0, 0); \
1550 gen_store_gpr(t0, rt); \
1551 tcg_temp_free(t0); \
1553 #else
1554 #define OP_ST_ATOMIC(insn,fname,ldname,almask) \
1555 static inline void op_st_##insn(TCGv arg1, TCGv arg2, int rt, DisasContext *ctx) \
1557 TCGv t0 = tcg_temp_new(); \
1558 gen_helper_1e2i(insn, t0, arg1, arg2, ctx->mem_idx); \
1559 gen_store_gpr(t0, rt); \
1560 tcg_temp_free(t0); \
1562 #endif
1563 OP_ST_ATOMIC(sc,st32,ld32s,0x3);
1564 #if defined(TARGET_MIPS64)
1565 OP_ST_ATOMIC(scd,st64,ld64,0x7);
1566 #endif
1567 #undef OP_ST_ATOMIC
1569 static void gen_base_offset_addr (DisasContext *ctx, TCGv addr,
1570 int base, int16_t offset)
1572 if (base == 0) {
1573 tcg_gen_movi_tl(addr, offset);
1574 } else if (offset == 0) {
1575 gen_load_gpr(addr, base);
1576 } else {
1577 tcg_gen_movi_tl(addr, offset);
1578 gen_op_addr_add(ctx, addr, cpu_gpr[base], addr);
1582 static target_ulong pc_relative_pc (DisasContext *ctx)
1584 target_ulong pc = ctx->pc;
1586 if (ctx->hflags & MIPS_HFLAG_BMASK) {
1587 int branch_bytes = ctx->hflags & MIPS_HFLAG_BDS16 ? 2 : 4;
1589 pc -= branch_bytes;
1592 pc &= ~(target_ulong)3;
1593 return pc;
1596 /* Load */
1597 static void gen_ld(DisasContext *ctx, uint32_t opc,
1598 int rt, int base, int16_t offset)
1600 const char *opn = "ld";
1601 TCGv t0, t1, t2;
1603 if (rt == 0 && ctx->insn_flags & (INSN_LOONGSON2E | INSN_LOONGSON2F)) {
1604 /* Loongson CPU uses a load to zero register for prefetch.
1605 We emulate it as a NOP. On other CPU we must perform the
1606 actual memory access. */
1607 MIPS_DEBUG("NOP");
1608 return;
1611 t0 = tcg_temp_new();
1612 gen_base_offset_addr(ctx, t0, base, offset);
1614 switch (opc) {
1615 #if defined(TARGET_MIPS64)
1616 case OPC_LWU:
1617 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TEUL);
1618 gen_store_gpr(t0, rt);
1619 opn = "lwu";
1620 break;
1621 case OPC_LD:
1622 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TEQ);
1623 gen_store_gpr(t0, rt);
1624 opn = "ld";
1625 break;
1626 case OPC_LLD:
1627 save_cpu_state(ctx, 1);
1628 op_ld_lld(t0, t0, ctx);
1629 gen_store_gpr(t0, rt);
1630 opn = "lld";
1631 break;
1632 case OPC_LDL:
1633 t1 = tcg_temp_new();
1634 tcg_gen_andi_tl(t1, t0, 7);
1635 #ifndef TARGET_WORDS_BIGENDIAN
1636 tcg_gen_xori_tl(t1, t1, 7);
1637 #endif
1638 tcg_gen_shli_tl(t1, t1, 3);
1639 tcg_gen_andi_tl(t0, t0, ~7);
1640 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TEQ);
1641 tcg_gen_shl_tl(t0, t0, t1);
1642 tcg_gen_xori_tl(t1, t1, 63);
1643 t2 = tcg_const_tl(0x7fffffffffffffffull);
1644 tcg_gen_shr_tl(t2, t2, t1);
1645 gen_load_gpr(t1, rt);
1646 tcg_gen_and_tl(t1, t1, t2);
1647 tcg_temp_free(t2);
1648 tcg_gen_or_tl(t0, t0, t1);
1649 tcg_temp_free(t1);
1650 gen_store_gpr(t0, rt);
1651 opn = "ldl";
1652 break;
1653 case OPC_LDR:
1654 t1 = tcg_temp_new();
1655 tcg_gen_andi_tl(t1, t0, 7);
1656 #ifdef TARGET_WORDS_BIGENDIAN
1657 tcg_gen_xori_tl(t1, t1, 7);
1658 #endif
1659 tcg_gen_shli_tl(t1, t1, 3);
1660 tcg_gen_andi_tl(t0, t0, ~7);
1661 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TEQ);
1662 tcg_gen_shr_tl(t0, t0, t1);
1663 tcg_gen_xori_tl(t1, t1, 63);
1664 t2 = tcg_const_tl(0xfffffffffffffffeull);
1665 tcg_gen_shl_tl(t2, t2, t1);
1666 gen_load_gpr(t1, rt);
1667 tcg_gen_and_tl(t1, t1, t2);
1668 tcg_temp_free(t2);
1669 tcg_gen_or_tl(t0, t0, t1);
1670 tcg_temp_free(t1);
1671 gen_store_gpr(t0, rt);
1672 opn = "ldr";
1673 break;
1674 case OPC_LDPC:
1675 t1 = tcg_const_tl(pc_relative_pc(ctx));
1676 gen_op_addr_add(ctx, t0, t0, t1);
1677 tcg_temp_free(t1);
1678 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TEQ);
1679 gen_store_gpr(t0, rt);
1680 opn = "ldpc";
1681 break;
1682 #endif
1683 case OPC_LWPC:
1684 t1 = tcg_const_tl(pc_relative_pc(ctx));
1685 gen_op_addr_add(ctx, t0, t0, t1);
1686 tcg_temp_free(t1);
1687 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TESL);
1688 gen_store_gpr(t0, rt);
1689 opn = "lwpc";
1690 break;
1691 case OPC_LW:
1692 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TESL);
1693 gen_store_gpr(t0, rt);
1694 opn = "lw";
1695 break;
1696 case OPC_LH:
1697 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TESW);
1698 gen_store_gpr(t0, rt);
1699 opn = "lh";
1700 break;
1701 case OPC_LHU:
1702 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TEUW);
1703 gen_store_gpr(t0, rt);
1704 opn = "lhu";
1705 break;
1706 case OPC_LB:
1707 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_SB);
1708 gen_store_gpr(t0, rt);
1709 opn = "lb";
1710 break;
1711 case OPC_LBU:
1712 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_UB);
1713 gen_store_gpr(t0, rt);
1714 opn = "lbu";
1715 break;
1716 case OPC_LWL:
1717 t1 = tcg_temp_new();
1718 tcg_gen_andi_tl(t1, t0, 3);
1719 #ifndef TARGET_WORDS_BIGENDIAN
1720 tcg_gen_xori_tl(t1, t1, 3);
1721 #endif
1722 tcg_gen_shli_tl(t1, t1, 3);
1723 tcg_gen_andi_tl(t0, t0, ~3);
1724 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TEUL);
1725 tcg_gen_shl_tl(t0, t0, t1);
1726 tcg_gen_xori_tl(t1, t1, 31);
1727 t2 = tcg_const_tl(0x7fffffffull);
1728 tcg_gen_shr_tl(t2, t2, t1);
1729 gen_load_gpr(t1, rt);
1730 tcg_gen_and_tl(t1, t1, t2);
1731 tcg_temp_free(t2);
1732 tcg_gen_or_tl(t0, t0, t1);
1733 tcg_temp_free(t1);
1734 tcg_gen_ext32s_tl(t0, t0);
1735 gen_store_gpr(t0, rt);
1736 opn = "lwl";
1737 break;
1738 case OPC_LWR:
1739 t1 = tcg_temp_new();
1740 tcg_gen_andi_tl(t1, t0, 3);
1741 #ifdef TARGET_WORDS_BIGENDIAN
1742 tcg_gen_xori_tl(t1, t1, 3);
1743 #endif
1744 tcg_gen_shli_tl(t1, t1, 3);
1745 tcg_gen_andi_tl(t0, t0, ~3);
1746 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TEUL);
1747 tcg_gen_shr_tl(t0, t0, t1);
1748 tcg_gen_xori_tl(t1, t1, 31);
1749 t2 = tcg_const_tl(0xfffffffeull);
1750 tcg_gen_shl_tl(t2, t2, t1);
1751 gen_load_gpr(t1, rt);
1752 tcg_gen_and_tl(t1, t1, t2);
1753 tcg_temp_free(t2);
1754 tcg_gen_or_tl(t0, t0, t1);
1755 tcg_temp_free(t1);
1756 tcg_gen_ext32s_tl(t0, t0);
1757 gen_store_gpr(t0, rt);
1758 opn = "lwr";
1759 break;
1760 case OPC_LL:
1761 save_cpu_state(ctx, 1);
1762 op_ld_ll(t0, t0, ctx);
1763 gen_store_gpr(t0, rt);
1764 opn = "ll";
1765 break;
1767 (void)opn; /* avoid a compiler warning */
1768 MIPS_DEBUG("%s %s, %d(%s)", opn, regnames[rt], offset, regnames[base]);
1769 tcg_temp_free(t0);
1772 /* Store */
1773 static void gen_st (DisasContext *ctx, uint32_t opc, int rt,
1774 int base, int16_t offset)
1776 const char *opn = "st";
1777 TCGv t0 = tcg_temp_new();
1778 TCGv t1 = tcg_temp_new();
1780 gen_base_offset_addr(ctx, t0, base, offset);
1781 gen_load_gpr(t1, rt);
1782 switch (opc) {
1783 #if defined(TARGET_MIPS64)
1784 case OPC_SD:
1785 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEQ);
1786 opn = "sd";
1787 break;
1788 case OPC_SDL:
1789 save_cpu_state(ctx, 1);
1790 gen_helper_0e2i(sdl, t1, t0, ctx->mem_idx);
1791 opn = "sdl";
1792 break;
1793 case OPC_SDR:
1794 save_cpu_state(ctx, 1);
1795 gen_helper_0e2i(sdr, t1, t0, ctx->mem_idx);
1796 opn = "sdr";
1797 break;
1798 #endif
1799 case OPC_SW:
1800 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL);
1801 opn = "sw";
1802 break;
1803 case OPC_SH:
1804 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUW);
1805 opn = "sh";
1806 break;
1807 case OPC_SB:
1808 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_8);
1809 opn = "sb";
1810 break;
1811 case OPC_SWL:
1812 save_cpu_state(ctx, 1);
1813 gen_helper_0e2i(swl, t1, t0, ctx->mem_idx);
1814 opn = "swl";
1815 break;
1816 case OPC_SWR:
1817 save_cpu_state(ctx, 1);
1818 gen_helper_0e2i(swr, t1, t0, ctx->mem_idx);
1819 opn = "swr";
1820 break;
1822 (void)opn; /* avoid a compiler warning */
1823 MIPS_DEBUG("%s %s, %d(%s)", opn, regnames[rt], offset, regnames[base]);
1824 tcg_temp_free(t0);
1825 tcg_temp_free(t1);
1829 /* Store conditional */
1830 static void gen_st_cond (DisasContext *ctx, uint32_t opc, int rt,
1831 int base, int16_t offset)
1833 const char *opn = "st_cond";
1834 TCGv t0, t1;
1836 #ifdef CONFIG_USER_ONLY
1837 t0 = tcg_temp_local_new();
1838 t1 = tcg_temp_local_new();
1839 #else
1840 t0 = tcg_temp_new();
1841 t1 = tcg_temp_new();
1842 #endif
1843 gen_base_offset_addr(ctx, t0, base, offset);
1844 gen_load_gpr(t1, rt);
1845 switch (opc) {
1846 #if defined(TARGET_MIPS64)
1847 case OPC_SCD:
1848 save_cpu_state(ctx, 1);
1849 op_st_scd(t1, t0, rt, ctx);
1850 opn = "scd";
1851 break;
1852 #endif
1853 case OPC_SC:
1854 save_cpu_state(ctx, 1);
1855 op_st_sc(t1, t0, rt, ctx);
1856 opn = "sc";
1857 break;
1859 (void)opn; /* avoid a compiler warning */
1860 MIPS_DEBUG("%s %s, %d(%s)", opn, regnames[rt], offset, regnames[base]);
1861 tcg_temp_free(t1);
1862 tcg_temp_free(t0);
1865 /* Load and store */
1866 static void gen_flt_ldst (DisasContext *ctx, uint32_t opc, int ft,
1867 int base, int16_t offset)
1869 const char *opn = "flt_ldst";
1870 TCGv t0 = tcg_temp_new();
1872 gen_base_offset_addr(ctx, t0, base, offset);
1873 /* Don't do NOP if destination is zero: we must perform the actual
1874 memory access. */
1875 switch (opc) {
1876 case OPC_LWC1:
1878 TCGv_i32 fp0 = tcg_temp_new_i32();
1879 tcg_gen_qemu_ld_i32(fp0, t0, ctx->mem_idx, MO_TESL);
1880 gen_store_fpr32(fp0, ft);
1881 tcg_temp_free_i32(fp0);
1883 opn = "lwc1";
1884 break;
1885 case OPC_SWC1:
1887 TCGv_i32 fp0 = tcg_temp_new_i32();
1888 gen_load_fpr32(fp0, ft);
1889 tcg_gen_qemu_st_i32(fp0, t0, ctx->mem_idx, MO_TEUL);
1890 tcg_temp_free_i32(fp0);
1892 opn = "swc1";
1893 break;
1894 case OPC_LDC1:
1896 TCGv_i64 fp0 = tcg_temp_new_i64();
1897 tcg_gen_qemu_ld_i64(fp0, t0, ctx->mem_idx, MO_TEQ);
1898 gen_store_fpr64(ctx, fp0, ft);
1899 tcg_temp_free_i64(fp0);
1901 opn = "ldc1";
1902 break;
1903 case OPC_SDC1:
1905 TCGv_i64 fp0 = tcg_temp_new_i64();
1906 gen_load_fpr64(ctx, fp0, ft);
1907 tcg_gen_qemu_st_i64(fp0, t0, ctx->mem_idx, MO_TEQ);
1908 tcg_temp_free_i64(fp0);
1910 opn = "sdc1";
1911 break;
1912 default:
1913 MIPS_INVAL(opn);
1914 generate_exception(ctx, EXCP_RI);
1915 goto out;
1917 (void)opn; /* avoid a compiler warning */
1918 MIPS_DEBUG("%s %s, %d(%s)", opn, fregnames[ft], offset, regnames[base]);
1919 out:
1920 tcg_temp_free(t0);
1923 static void gen_cop1_ldst(CPUMIPSState *env, DisasContext *ctx,
1924 uint32_t op, int rt, int rs, int16_t imm)
1926 if (env->CP0_Config1 & (1 << CP0C1_FP)) {
1927 check_cp1_enabled(ctx);
1928 gen_flt_ldst(ctx, op, rt, rs, imm);
1929 } else {
1930 generate_exception_err(ctx, EXCP_CpU, 1);
1934 /* Arithmetic with immediate operand */
1935 static void gen_arith_imm(DisasContext *ctx, uint32_t opc,
1936 int rt, int rs, int16_t imm)
1938 target_ulong uimm = (target_long)imm; /* Sign extend to 32/64 bits */
1939 const char *opn = "imm arith";
1941 if (rt == 0 && opc != OPC_ADDI && opc != OPC_DADDI) {
1942 /* If no destination, treat it as a NOP.
1943 For addi, we must generate the overflow exception when needed. */
1944 MIPS_DEBUG("NOP");
1945 return;
1947 switch (opc) {
1948 case OPC_ADDI:
1950 TCGv t0 = tcg_temp_local_new();
1951 TCGv t1 = tcg_temp_new();
1952 TCGv t2 = tcg_temp_new();
1953 int l1 = gen_new_label();
1955 gen_load_gpr(t1, rs);
1956 tcg_gen_addi_tl(t0, t1, uimm);
1957 tcg_gen_ext32s_tl(t0, t0);
1959 tcg_gen_xori_tl(t1, t1, ~uimm);
1960 tcg_gen_xori_tl(t2, t0, uimm);
1961 tcg_gen_and_tl(t1, t1, t2);
1962 tcg_temp_free(t2);
1963 tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
1964 tcg_temp_free(t1);
1965 /* operands of same sign, result different sign */
1966 generate_exception(ctx, EXCP_OVERFLOW);
1967 gen_set_label(l1);
1968 tcg_gen_ext32s_tl(t0, t0);
1969 gen_store_gpr(t0, rt);
1970 tcg_temp_free(t0);
1972 opn = "addi";
1973 break;
1974 case OPC_ADDIU:
1975 if (rs != 0) {
1976 tcg_gen_addi_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
1977 tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]);
1978 } else {
1979 tcg_gen_movi_tl(cpu_gpr[rt], uimm);
1981 opn = "addiu";
1982 break;
1983 #if defined(TARGET_MIPS64)
1984 case OPC_DADDI:
1986 TCGv t0 = tcg_temp_local_new();
1987 TCGv t1 = tcg_temp_new();
1988 TCGv t2 = tcg_temp_new();
1989 int l1 = gen_new_label();
1991 gen_load_gpr(t1, rs);
1992 tcg_gen_addi_tl(t0, t1, uimm);
1994 tcg_gen_xori_tl(t1, t1, ~uimm);
1995 tcg_gen_xori_tl(t2, t0, uimm);
1996 tcg_gen_and_tl(t1, t1, t2);
1997 tcg_temp_free(t2);
1998 tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
1999 tcg_temp_free(t1);
2000 /* operands of same sign, result different sign */
2001 generate_exception(ctx, EXCP_OVERFLOW);
2002 gen_set_label(l1);
2003 gen_store_gpr(t0, rt);
2004 tcg_temp_free(t0);
2006 opn = "daddi";
2007 break;
2008 case OPC_DADDIU:
2009 if (rs != 0) {
2010 tcg_gen_addi_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
2011 } else {
2012 tcg_gen_movi_tl(cpu_gpr[rt], uimm);
2014 opn = "daddiu";
2015 break;
2016 #endif
2018 (void)opn; /* avoid a compiler warning */
2019 MIPS_DEBUG("%s %s, %s, " TARGET_FMT_lx, opn, regnames[rt], regnames[rs], uimm);
2022 /* Logic with immediate operand */
2023 static void gen_logic_imm(DisasContext *ctx, uint32_t opc,
2024 int rt, int rs, int16_t imm)
2026 target_ulong uimm;
2028 if (rt == 0) {
2029 /* If no destination, treat it as a NOP. */
2030 MIPS_DEBUG("NOP");
2031 return;
2033 uimm = (uint16_t)imm;
2034 switch (opc) {
2035 case OPC_ANDI:
2036 if (likely(rs != 0))
2037 tcg_gen_andi_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
2038 else
2039 tcg_gen_movi_tl(cpu_gpr[rt], 0);
2040 MIPS_DEBUG("andi %s, %s, " TARGET_FMT_lx, regnames[rt],
2041 regnames[rs], uimm);
2042 break;
2043 case OPC_ORI:
2044 if (rs != 0)
2045 tcg_gen_ori_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
2046 else
2047 tcg_gen_movi_tl(cpu_gpr[rt], uimm);
2048 MIPS_DEBUG("ori %s, %s, " TARGET_FMT_lx, regnames[rt],
2049 regnames[rs], uimm);
2050 break;
2051 case OPC_XORI:
2052 if (likely(rs != 0))
2053 tcg_gen_xori_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
2054 else
2055 tcg_gen_movi_tl(cpu_gpr[rt], uimm);
2056 MIPS_DEBUG("xori %s, %s, " TARGET_FMT_lx, regnames[rt],
2057 regnames[rs], uimm);
2058 break;
2059 case OPC_LUI:
2060 tcg_gen_movi_tl(cpu_gpr[rt], imm << 16);
2061 MIPS_DEBUG("lui %s, " TARGET_FMT_lx, regnames[rt], uimm);
2062 break;
2064 default:
2065 MIPS_DEBUG("Unknown logical immediate opcode %08x", opc);
2066 break;
2070 /* Set on less than with immediate operand */
2071 static void gen_slt_imm(DisasContext *ctx, uint32_t opc,
2072 int rt, int rs, int16_t imm)
2074 target_ulong uimm = (target_long)imm; /* Sign extend to 32/64 bits */
2075 const char *opn = "imm arith";
2076 TCGv t0;
2078 if (rt == 0) {
2079 /* If no destination, treat it as a NOP. */
2080 MIPS_DEBUG("NOP");
2081 return;
2083 t0 = tcg_temp_new();
2084 gen_load_gpr(t0, rs);
2085 switch (opc) {
2086 case OPC_SLTI:
2087 tcg_gen_setcondi_tl(TCG_COND_LT, cpu_gpr[rt], t0, uimm);
2088 opn = "slti";
2089 break;
2090 case OPC_SLTIU:
2091 tcg_gen_setcondi_tl(TCG_COND_LTU, cpu_gpr[rt], t0, uimm);
2092 opn = "sltiu";
2093 break;
2095 (void)opn; /* avoid a compiler warning */
2096 MIPS_DEBUG("%s %s, %s, " TARGET_FMT_lx, opn, regnames[rt], regnames[rs], uimm);
2097 tcg_temp_free(t0);
2100 /* Shifts with immediate operand */
2101 static void gen_shift_imm(DisasContext *ctx, uint32_t opc,
2102 int rt, int rs, int16_t imm)
2104 target_ulong uimm = ((uint16_t)imm) & 0x1f;
2105 const char *opn = "imm shift";
2106 TCGv t0;
2108 if (rt == 0) {
2109 /* If no destination, treat it as a NOP. */
2110 MIPS_DEBUG("NOP");
2111 return;
2114 t0 = tcg_temp_new();
2115 gen_load_gpr(t0, rs);
2116 switch (opc) {
2117 case OPC_SLL:
2118 tcg_gen_shli_tl(t0, t0, uimm);
2119 tcg_gen_ext32s_tl(cpu_gpr[rt], t0);
2120 opn = "sll";
2121 break;
2122 case OPC_SRA:
2123 tcg_gen_sari_tl(cpu_gpr[rt], t0, uimm);
2124 opn = "sra";
2125 break;
2126 case OPC_SRL:
2127 if (uimm != 0) {
2128 tcg_gen_ext32u_tl(t0, t0);
2129 tcg_gen_shri_tl(cpu_gpr[rt], t0, uimm);
2130 } else {
2131 tcg_gen_ext32s_tl(cpu_gpr[rt], t0);
2133 opn = "srl";
2134 break;
2135 case OPC_ROTR:
2136 if (uimm != 0) {
2137 TCGv_i32 t1 = tcg_temp_new_i32();
2139 tcg_gen_trunc_tl_i32(t1, t0);
2140 tcg_gen_rotri_i32(t1, t1, uimm);
2141 tcg_gen_ext_i32_tl(cpu_gpr[rt], t1);
2142 tcg_temp_free_i32(t1);
2143 } else {
2144 tcg_gen_ext32s_tl(cpu_gpr[rt], t0);
2146 opn = "rotr";
2147 break;
2148 #if defined(TARGET_MIPS64)
2149 case OPC_DSLL:
2150 tcg_gen_shli_tl(cpu_gpr[rt], t0, uimm);
2151 opn = "dsll";
2152 break;
2153 case OPC_DSRA:
2154 tcg_gen_sari_tl(cpu_gpr[rt], t0, uimm);
2155 opn = "dsra";
2156 break;
2157 case OPC_DSRL:
2158 tcg_gen_shri_tl(cpu_gpr[rt], t0, uimm);
2159 opn = "dsrl";
2160 break;
2161 case OPC_DROTR:
2162 if (uimm != 0) {
2163 tcg_gen_rotri_tl(cpu_gpr[rt], t0, uimm);
2164 } else {
2165 tcg_gen_mov_tl(cpu_gpr[rt], t0);
2167 opn = "drotr";
2168 break;
2169 case OPC_DSLL32:
2170 tcg_gen_shli_tl(cpu_gpr[rt], t0, uimm + 32);
2171 opn = "dsll32";
2172 break;
2173 case OPC_DSRA32:
2174 tcg_gen_sari_tl(cpu_gpr[rt], t0, uimm + 32);
2175 opn = "dsra32";
2176 break;
2177 case OPC_DSRL32:
2178 tcg_gen_shri_tl(cpu_gpr[rt], t0, uimm + 32);
2179 opn = "dsrl32";
2180 break;
2181 case OPC_DROTR32:
2182 tcg_gen_rotri_tl(cpu_gpr[rt], t0, uimm + 32);
2183 opn = "drotr32";
2184 break;
2185 #endif
2187 (void)opn; /* avoid a compiler warning */
2188 MIPS_DEBUG("%s %s, %s, " TARGET_FMT_lx, opn, regnames[rt], regnames[rs], uimm);
2189 tcg_temp_free(t0);
2192 /* Arithmetic */
2193 static void gen_arith(DisasContext *ctx, uint32_t opc,
2194 int rd, int rs, int rt)
2196 const char *opn = "arith";
2198 if (rd == 0 && opc != OPC_ADD && opc != OPC_SUB
2199 && opc != OPC_DADD && opc != OPC_DSUB) {
2200 /* If no destination, treat it as a NOP.
2201 For add & sub, we must generate the overflow exception when needed. */
2202 MIPS_DEBUG("NOP");
2203 return;
2206 switch (opc) {
2207 case OPC_ADD:
2209 TCGv t0 = tcg_temp_local_new();
2210 TCGv t1 = tcg_temp_new();
2211 TCGv t2 = tcg_temp_new();
2212 int l1 = gen_new_label();
2214 gen_load_gpr(t1, rs);
2215 gen_load_gpr(t2, rt);
2216 tcg_gen_add_tl(t0, t1, t2);
2217 tcg_gen_ext32s_tl(t0, t0);
2218 tcg_gen_xor_tl(t1, t1, t2);
2219 tcg_gen_xor_tl(t2, t0, t2);
2220 tcg_gen_andc_tl(t1, t2, t1);
2221 tcg_temp_free(t2);
2222 tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
2223 tcg_temp_free(t1);
2224 /* operands of same sign, result different sign */
2225 generate_exception(ctx, EXCP_OVERFLOW);
2226 gen_set_label(l1);
2227 gen_store_gpr(t0, rd);
2228 tcg_temp_free(t0);
2230 opn = "add";
2231 break;
2232 case OPC_ADDU:
2233 if (rs != 0 && rt != 0) {
2234 tcg_gen_add_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2235 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
2236 } else if (rs == 0 && rt != 0) {
2237 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rt]);
2238 } else if (rs != 0 && rt == 0) {
2239 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
2240 } else {
2241 tcg_gen_movi_tl(cpu_gpr[rd], 0);
2243 opn = "addu";
2244 break;
2245 case OPC_SUB:
2247 TCGv t0 = tcg_temp_local_new();
2248 TCGv t1 = tcg_temp_new();
2249 TCGv t2 = tcg_temp_new();
2250 int l1 = gen_new_label();
2252 gen_load_gpr(t1, rs);
2253 gen_load_gpr(t2, rt);
2254 tcg_gen_sub_tl(t0, t1, t2);
2255 tcg_gen_ext32s_tl(t0, t0);
2256 tcg_gen_xor_tl(t2, t1, t2);
2257 tcg_gen_xor_tl(t1, t0, t1);
2258 tcg_gen_and_tl(t1, t1, t2);
2259 tcg_temp_free(t2);
2260 tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
2261 tcg_temp_free(t1);
2262 /* operands of different sign, first operand and result different sign */
2263 generate_exception(ctx, EXCP_OVERFLOW);
2264 gen_set_label(l1);
2265 gen_store_gpr(t0, rd);
2266 tcg_temp_free(t0);
2268 opn = "sub";
2269 break;
2270 case OPC_SUBU:
2271 if (rs != 0 && rt != 0) {
2272 tcg_gen_sub_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2273 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
2274 } else if (rs == 0 && rt != 0) {
2275 tcg_gen_neg_tl(cpu_gpr[rd], cpu_gpr[rt]);
2276 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
2277 } else if (rs != 0 && rt == 0) {
2278 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
2279 } else {
2280 tcg_gen_movi_tl(cpu_gpr[rd], 0);
2282 opn = "subu";
2283 break;
2284 #if defined(TARGET_MIPS64)
2285 case OPC_DADD:
2287 TCGv t0 = tcg_temp_local_new();
2288 TCGv t1 = tcg_temp_new();
2289 TCGv t2 = tcg_temp_new();
2290 int l1 = gen_new_label();
2292 gen_load_gpr(t1, rs);
2293 gen_load_gpr(t2, rt);
2294 tcg_gen_add_tl(t0, t1, t2);
2295 tcg_gen_xor_tl(t1, t1, t2);
2296 tcg_gen_xor_tl(t2, t0, t2);
2297 tcg_gen_andc_tl(t1, t2, t1);
2298 tcg_temp_free(t2);
2299 tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
2300 tcg_temp_free(t1);
2301 /* operands of same sign, result different sign */
2302 generate_exception(ctx, EXCP_OVERFLOW);
2303 gen_set_label(l1);
2304 gen_store_gpr(t0, rd);
2305 tcg_temp_free(t0);
2307 opn = "dadd";
2308 break;
2309 case OPC_DADDU:
2310 if (rs != 0 && rt != 0) {
2311 tcg_gen_add_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2312 } else if (rs == 0 && rt != 0) {
2313 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rt]);
2314 } else if (rs != 0 && rt == 0) {
2315 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
2316 } else {
2317 tcg_gen_movi_tl(cpu_gpr[rd], 0);
2319 opn = "daddu";
2320 break;
2321 case OPC_DSUB:
2323 TCGv t0 = tcg_temp_local_new();
2324 TCGv t1 = tcg_temp_new();
2325 TCGv t2 = tcg_temp_new();
2326 int l1 = gen_new_label();
2328 gen_load_gpr(t1, rs);
2329 gen_load_gpr(t2, rt);
2330 tcg_gen_sub_tl(t0, t1, t2);
2331 tcg_gen_xor_tl(t2, t1, t2);
2332 tcg_gen_xor_tl(t1, t0, t1);
2333 tcg_gen_and_tl(t1, t1, t2);
2334 tcg_temp_free(t2);
2335 tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
2336 tcg_temp_free(t1);
2337 /* operands of different sign, first operand and result different sign */
2338 generate_exception(ctx, EXCP_OVERFLOW);
2339 gen_set_label(l1);
2340 gen_store_gpr(t0, rd);
2341 tcg_temp_free(t0);
2343 opn = "dsub";
2344 break;
2345 case OPC_DSUBU:
2346 if (rs != 0 && rt != 0) {
2347 tcg_gen_sub_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2348 } else if (rs == 0 && rt != 0) {
2349 tcg_gen_neg_tl(cpu_gpr[rd], cpu_gpr[rt]);
2350 } else if (rs != 0 && rt == 0) {
2351 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
2352 } else {
2353 tcg_gen_movi_tl(cpu_gpr[rd], 0);
2355 opn = "dsubu";
2356 break;
2357 #endif
2358 case OPC_MUL:
2359 if (likely(rs != 0 && rt != 0)) {
2360 tcg_gen_mul_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2361 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
2362 } else {
2363 tcg_gen_movi_tl(cpu_gpr[rd], 0);
2365 opn = "mul";
2366 break;
2368 (void)opn; /* avoid a compiler warning */
2369 MIPS_DEBUG("%s %s, %s, %s", opn, regnames[rd], regnames[rs], regnames[rt]);
2372 /* Conditional move */
2373 static void gen_cond_move(DisasContext *ctx, uint32_t opc,
2374 int rd, int rs, int rt)
2376 const char *opn = "cond move";
2377 TCGv t0, t1, t2;
2379 if (rd == 0) {
2380 /* If no destination, treat it as a NOP. */
2381 MIPS_DEBUG("NOP");
2382 return;
2385 t0 = tcg_temp_new();
2386 gen_load_gpr(t0, rt);
2387 t1 = tcg_const_tl(0);
2388 t2 = tcg_temp_new();
2389 gen_load_gpr(t2, rs);
2390 switch (opc) {
2391 case OPC_MOVN:
2392 tcg_gen_movcond_tl(TCG_COND_NE, cpu_gpr[rd], t0, t1, t2, cpu_gpr[rd]);
2393 opn = "movn";
2394 break;
2395 case OPC_MOVZ:
2396 tcg_gen_movcond_tl(TCG_COND_EQ, cpu_gpr[rd], t0, t1, t2, cpu_gpr[rd]);
2397 opn = "movz";
2398 break;
2400 tcg_temp_free(t2);
2401 tcg_temp_free(t1);
2402 tcg_temp_free(t0);
2404 (void)opn; /* avoid a compiler warning */
2405 MIPS_DEBUG("%s %s, %s, %s", opn, regnames[rd], regnames[rs], regnames[rt]);
2408 /* Logic */
2409 static void gen_logic(DisasContext *ctx, uint32_t opc,
2410 int rd, int rs, int rt)
2412 const char *opn = "logic";
2414 if (rd == 0) {
2415 /* If no destination, treat it as a NOP. */
2416 MIPS_DEBUG("NOP");
2417 return;
2420 switch (opc) {
2421 case OPC_AND:
2422 if (likely(rs != 0 && rt != 0)) {
2423 tcg_gen_and_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2424 } else {
2425 tcg_gen_movi_tl(cpu_gpr[rd], 0);
2427 opn = "and";
2428 break;
2429 case OPC_NOR:
2430 if (rs != 0 && rt != 0) {
2431 tcg_gen_nor_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2432 } else if (rs == 0 && rt != 0) {
2433 tcg_gen_not_tl(cpu_gpr[rd], cpu_gpr[rt]);
2434 } else if (rs != 0 && rt == 0) {
2435 tcg_gen_not_tl(cpu_gpr[rd], cpu_gpr[rs]);
2436 } else {
2437 tcg_gen_movi_tl(cpu_gpr[rd], ~((target_ulong)0));
2439 opn = "nor";
2440 break;
2441 case OPC_OR:
2442 if (likely(rs != 0 && rt != 0)) {
2443 tcg_gen_or_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2444 } else if (rs == 0 && rt != 0) {
2445 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rt]);
2446 } else if (rs != 0 && rt == 0) {
2447 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
2448 } else {
2449 tcg_gen_movi_tl(cpu_gpr[rd], 0);
2451 opn = "or";
2452 break;
2453 case OPC_XOR:
2454 if (likely(rs != 0 && rt != 0)) {
2455 tcg_gen_xor_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2456 } else if (rs == 0 && rt != 0) {
2457 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rt]);
2458 } else if (rs != 0 && rt == 0) {
2459 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
2460 } else {
2461 tcg_gen_movi_tl(cpu_gpr[rd], 0);
2463 opn = "xor";
2464 break;
2466 (void)opn; /* avoid a compiler warning */
2467 MIPS_DEBUG("%s %s, %s, %s", opn, regnames[rd], regnames[rs], regnames[rt]);
2470 /* Set on lower than */
2471 static void gen_slt(DisasContext *ctx, uint32_t opc,
2472 int rd, int rs, int rt)
2474 const char *opn = "slt";
2475 TCGv t0, t1;
2477 if (rd == 0) {
2478 /* If no destination, treat it as a NOP. */
2479 MIPS_DEBUG("NOP");
2480 return;
2483 t0 = tcg_temp_new();
2484 t1 = tcg_temp_new();
2485 gen_load_gpr(t0, rs);
2486 gen_load_gpr(t1, rt);
2487 switch (opc) {
2488 case OPC_SLT:
2489 tcg_gen_setcond_tl(TCG_COND_LT, cpu_gpr[rd], t0, t1);
2490 opn = "slt";
2491 break;
2492 case OPC_SLTU:
2493 tcg_gen_setcond_tl(TCG_COND_LTU, cpu_gpr[rd], t0, t1);
2494 opn = "sltu";
2495 break;
2497 (void)opn; /* avoid a compiler warning */
2498 MIPS_DEBUG("%s %s, %s, %s", opn, regnames[rd], regnames[rs], regnames[rt]);
2499 tcg_temp_free(t0);
2500 tcg_temp_free(t1);
2503 /* Shifts */
2504 static void gen_shift(DisasContext *ctx, uint32_t opc,
2505 int rd, int rs, int rt)
2507 const char *opn = "shifts";
2508 TCGv t0, t1;
2510 if (rd == 0) {
2511 /* If no destination, treat it as a NOP.
2512 For add & sub, we must generate the overflow exception when needed. */
2513 MIPS_DEBUG("NOP");
2514 return;
2517 t0 = tcg_temp_new();
2518 t1 = tcg_temp_new();
2519 gen_load_gpr(t0, rs);
2520 gen_load_gpr(t1, rt);
2521 switch (opc) {
2522 case OPC_SLLV:
2523 tcg_gen_andi_tl(t0, t0, 0x1f);
2524 tcg_gen_shl_tl(t0, t1, t0);
2525 tcg_gen_ext32s_tl(cpu_gpr[rd], t0);
2526 opn = "sllv";
2527 break;
2528 case OPC_SRAV:
2529 tcg_gen_andi_tl(t0, t0, 0x1f);
2530 tcg_gen_sar_tl(cpu_gpr[rd], t1, t0);
2531 opn = "srav";
2532 break;
2533 case OPC_SRLV:
2534 tcg_gen_ext32u_tl(t1, t1);
2535 tcg_gen_andi_tl(t0, t0, 0x1f);
2536 tcg_gen_shr_tl(t0, t1, t0);
2537 tcg_gen_ext32s_tl(cpu_gpr[rd], t0);
2538 opn = "srlv";
2539 break;
2540 case OPC_ROTRV:
2542 TCGv_i32 t2 = tcg_temp_new_i32();
2543 TCGv_i32 t3 = tcg_temp_new_i32();
2545 tcg_gen_trunc_tl_i32(t2, t0);
2546 tcg_gen_trunc_tl_i32(t3, t1);
2547 tcg_gen_andi_i32(t2, t2, 0x1f);
2548 tcg_gen_rotr_i32(t2, t3, t2);
2549 tcg_gen_ext_i32_tl(cpu_gpr[rd], t2);
2550 tcg_temp_free_i32(t2);
2551 tcg_temp_free_i32(t3);
2552 opn = "rotrv";
2554 break;
2555 #if defined(TARGET_MIPS64)
2556 case OPC_DSLLV:
2557 tcg_gen_andi_tl(t0, t0, 0x3f);
2558 tcg_gen_shl_tl(cpu_gpr[rd], t1, t0);
2559 opn = "dsllv";
2560 break;
2561 case OPC_DSRAV:
2562 tcg_gen_andi_tl(t0, t0, 0x3f);
2563 tcg_gen_sar_tl(cpu_gpr[rd], t1, t0);
2564 opn = "dsrav";
2565 break;
2566 case OPC_DSRLV:
2567 tcg_gen_andi_tl(t0, t0, 0x3f);
2568 tcg_gen_shr_tl(cpu_gpr[rd], t1, t0);
2569 opn = "dsrlv";
2570 break;
2571 case OPC_DROTRV:
2572 tcg_gen_andi_tl(t0, t0, 0x3f);
2573 tcg_gen_rotr_tl(cpu_gpr[rd], t1, t0);
2574 opn = "drotrv";
2575 break;
2576 #endif
2578 (void)opn; /* avoid a compiler warning */
2579 MIPS_DEBUG("%s %s, %s, %s", opn, regnames[rd], regnames[rs], regnames[rt]);
2580 tcg_temp_free(t0);
2581 tcg_temp_free(t1);
2584 /* Arithmetic on HI/LO registers */
2585 static void gen_HILO(DisasContext *ctx, uint32_t opc, int acc, int reg)
2587 const char *opn = "hilo";
2589 if (reg == 0 && (opc == OPC_MFHI || opc == OPC_MFLO)) {
2590 /* Treat as NOP. */
2591 MIPS_DEBUG("NOP");
2592 return;
2595 if (acc != 0) {
2596 check_dsp(ctx);
2599 switch (opc) {
2600 case OPC_MFHI:
2601 #if defined(TARGET_MIPS64)
2602 if (acc != 0) {
2603 tcg_gen_ext32s_tl(cpu_gpr[reg], cpu_HI[acc]);
2604 } else
2605 #endif
2607 tcg_gen_mov_tl(cpu_gpr[reg], cpu_HI[acc]);
2609 opn = "mfhi";
2610 break;
2611 case OPC_MFLO:
2612 #if defined(TARGET_MIPS64)
2613 if (acc != 0) {
2614 tcg_gen_ext32s_tl(cpu_gpr[reg], cpu_LO[acc]);
2615 } else
2616 #endif
2618 tcg_gen_mov_tl(cpu_gpr[reg], cpu_LO[acc]);
2620 opn = "mflo";
2621 break;
2622 case OPC_MTHI:
2623 if (reg != 0) {
2624 #if defined(TARGET_MIPS64)
2625 if (acc != 0) {
2626 tcg_gen_ext32s_tl(cpu_HI[acc], cpu_gpr[reg]);
2627 } else
2628 #endif
2630 tcg_gen_mov_tl(cpu_HI[acc], cpu_gpr[reg]);
2632 } else {
2633 tcg_gen_movi_tl(cpu_HI[acc], 0);
2635 opn = "mthi";
2636 break;
2637 case OPC_MTLO:
2638 if (reg != 0) {
2639 #if defined(TARGET_MIPS64)
2640 if (acc != 0) {
2641 tcg_gen_ext32s_tl(cpu_LO[acc], cpu_gpr[reg]);
2642 } else
2643 #endif
2645 tcg_gen_mov_tl(cpu_LO[acc], cpu_gpr[reg]);
2647 } else {
2648 tcg_gen_movi_tl(cpu_LO[acc], 0);
2650 opn = "mtlo";
2651 break;
2653 (void)opn; /* avoid a compiler warning */
2654 MIPS_DEBUG("%s %s", opn, regnames[reg]);
2657 static void gen_muldiv(DisasContext *ctx, uint32_t opc,
2658 int acc, int rs, int rt)
2660 const char *opn = "mul/div";
2661 TCGv t0, t1;
2663 t0 = tcg_temp_new();
2664 t1 = tcg_temp_new();
2666 gen_load_gpr(t0, rs);
2667 gen_load_gpr(t1, rt);
2669 if (acc != 0) {
2670 check_dsp(ctx);
2673 switch (opc) {
2674 case OPC_DIV:
2676 TCGv t2 = tcg_temp_new();
2677 TCGv t3 = tcg_temp_new();
2678 tcg_gen_ext32s_tl(t0, t0);
2679 tcg_gen_ext32s_tl(t1, t1);
2680 tcg_gen_setcondi_tl(TCG_COND_EQ, t2, t0, INT_MIN);
2681 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, -1);
2682 tcg_gen_and_tl(t2, t2, t3);
2683 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, 0);
2684 tcg_gen_or_tl(t2, t2, t3);
2685 tcg_gen_movi_tl(t3, 0);
2686 tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, t3, t2, t1);
2687 tcg_gen_div_tl(cpu_LO[acc], t0, t1);
2688 tcg_gen_rem_tl(cpu_HI[acc], t0, t1);
2689 tcg_gen_ext32s_tl(cpu_LO[acc], cpu_LO[acc]);
2690 tcg_gen_ext32s_tl(cpu_HI[acc], cpu_HI[acc]);
2691 tcg_temp_free(t3);
2692 tcg_temp_free(t2);
2694 opn = "div";
2695 break;
2696 case OPC_DIVU:
2698 TCGv t2 = tcg_const_tl(0);
2699 TCGv t3 = tcg_const_tl(1);
2700 tcg_gen_ext32u_tl(t0, t0);
2701 tcg_gen_ext32u_tl(t1, t1);
2702 tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1, t2, t3, t1);
2703 tcg_gen_divu_tl(cpu_LO[acc], t0, t1);
2704 tcg_gen_remu_tl(cpu_HI[acc], t0, t1);
2705 tcg_gen_ext32s_tl(cpu_LO[acc], cpu_LO[acc]);
2706 tcg_gen_ext32s_tl(cpu_HI[acc], cpu_HI[acc]);
2707 tcg_temp_free(t3);
2708 tcg_temp_free(t2);
2710 opn = "divu";
2711 break;
2712 case OPC_MULT:
2714 TCGv_i32 t2 = tcg_temp_new_i32();
2715 TCGv_i32 t3 = tcg_temp_new_i32();
2716 tcg_gen_trunc_tl_i32(t2, t0);
2717 tcg_gen_trunc_tl_i32(t3, t1);
2718 tcg_gen_muls2_i32(t2, t3, t2, t3);
2719 tcg_gen_ext_i32_tl(cpu_LO[acc], t2);
2720 tcg_gen_ext_i32_tl(cpu_HI[acc], t3);
2721 tcg_temp_free_i32(t2);
2722 tcg_temp_free_i32(t3);
2724 opn = "mult";
2725 break;
2726 case OPC_MULTU:
2728 TCGv_i32 t2 = tcg_temp_new_i32();
2729 TCGv_i32 t3 = tcg_temp_new_i32();
2730 tcg_gen_trunc_tl_i32(t2, t0);
2731 tcg_gen_trunc_tl_i32(t3, t1);
2732 tcg_gen_mulu2_i32(t2, t3, t2, t3);
2733 tcg_gen_ext_i32_tl(cpu_LO[acc], t2);
2734 tcg_gen_ext_i32_tl(cpu_HI[acc], t3);
2735 tcg_temp_free_i32(t2);
2736 tcg_temp_free_i32(t3);
2738 opn = "multu";
2739 break;
2740 #if defined(TARGET_MIPS64)
2741 case OPC_DDIV:
2743 TCGv t2 = tcg_temp_new();
2744 TCGv t3 = tcg_temp_new();
2745 tcg_gen_setcondi_tl(TCG_COND_EQ, t2, t0, -1LL << 63);
2746 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, -1LL);
2747 tcg_gen_and_tl(t2, t2, t3);
2748 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, 0);
2749 tcg_gen_or_tl(t2, t2, t3);
2750 tcg_gen_movi_tl(t3, 0);
2751 tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, t3, t2, t1);
2752 tcg_gen_div_tl(cpu_LO[acc], t0, t1);
2753 tcg_gen_rem_tl(cpu_HI[acc], t0, t1);
2754 tcg_temp_free(t3);
2755 tcg_temp_free(t2);
2757 opn = "ddiv";
2758 break;
2759 case OPC_DDIVU:
2761 TCGv t2 = tcg_const_tl(0);
2762 TCGv t3 = tcg_const_tl(1);
2763 tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1, t2, t3, t1);
2764 tcg_gen_divu_i64(cpu_LO[acc], t0, t1);
2765 tcg_gen_remu_i64(cpu_HI[acc], t0, t1);
2766 tcg_temp_free(t3);
2767 tcg_temp_free(t2);
2769 opn = "ddivu";
2770 break;
2771 case OPC_DMULT:
2772 tcg_gen_muls2_i64(cpu_LO[acc], cpu_HI[acc], t0, t1);
2773 opn = "dmult";
2774 break;
2775 case OPC_DMULTU:
2776 tcg_gen_mulu2_i64(cpu_LO[acc], cpu_HI[acc], t0, t1);
2777 opn = "dmultu";
2778 break;
2779 #endif
2780 case OPC_MADD:
2782 TCGv_i64 t2 = tcg_temp_new_i64();
2783 TCGv_i64 t3 = tcg_temp_new_i64();
2785 tcg_gen_ext_tl_i64(t2, t0);
2786 tcg_gen_ext_tl_i64(t3, t1);
2787 tcg_gen_mul_i64(t2, t2, t3);
2788 tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]);
2789 tcg_gen_add_i64(t2, t2, t3);
2790 tcg_temp_free_i64(t3);
2791 tcg_gen_trunc_i64_tl(t0, t2);
2792 tcg_gen_shri_i64(t2, t2, 32);
2793 tcg_gen_trunc_i64_tl(t1, t2);
2794 tcg_temp_free_i64(t2);
2795 tcg_gen_ext32s_tl(cpu_LO[acc], t0);
2796 tcg_gen_ext32s_tl(cpu_HI[acc], t1);
2798 opn = "madd";
2799 break;
2800 case OPC_MADDU:
2802 TCGv_i64 t2 = tcg_temp_new_i64();
2803 TCGv_i64 t3 = tcg_temp_new_i64();
2805 tcg_gen_ext32u_tl(t0, t0);
2806 tcg_gen_ext32u_tl(t1, t1);
2807 tcg_gen_extu_tl_i64(t2, t0);
2808 tcg_gen_extu_tl_i64(t3, t1);
2809 tcg_gen_mul_i64(t2, t2, t3);
2810 tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]);
2811 tcg_gen_add_i64(t2, t2, t3);
2812 tcg_temp_free_i64(t3);
2813 tcg_gen_trunc_i64_tl(t0, t2);
2814 tcg_gen_shri_i64(t2, t2, 32);
2815 tcg_gen_trunc_i64_tl(t1, t2);
2816 tcg_temp_free_i64(t2);
2817 tcg_gen_ext32s_tl(cpu_LO[acc], t0);
2818 tcg_gen_ext32s_tl(cpu_HI[acc], t1);
2820 opn = "maddu";
2821 break;
2822 case OPC_MSUB:
2824 TCGv_i64 t2 = tcg_temp_new_i64();
2825 TCGv_i64 t3 = tcg_temp_new_i64();
2827 tcg_gen_ext_tl_i64(t2, t0);
2828 tcg_gen_ext_tl_i64(t3, t1);
2829 tcg_gen_mul_i64(t2, t2, t3);
2830 tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]);
2831 tcg_gen_sub_i64(t2, t3, t2);
2832 tcg_temp_free_i64(t3);
2833 tcg_gen_trunc_i64_tl(t0, t2);
2834 tcg_gen_shri_i64(t2, t2, 32);
2835 tcg_gen_trunc_i64_tl(t1, t2);
2836 tcg_temp_free_i64(t2);
2837 tcg_gen_ext32s_tl(cpu_LO[acc], t0);
2838 tcg_gen_ext32s_tl(cpu_HI[acc], t1);
2840 opn = "msub";
2841 break;
2842 case OPC_MSUBU:
2844 TCGv_i64 t2 = tcg_temp_new_i64();
2845 TCGv_i64 t3 = tcg_temp_new_i64();
2847 tcg_gen_ext32u_tl(t0, t0);
2848 tcg_gen_ext32u_tl(t1, t1);
2849 tcg_gen_extu_tl_i64(t2, t0);
2850 tcg_gen_extu_tl_i64(t3, t1);
2851 tcg_gen_mul_i64(t2, t2, t3);
2852 tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]);
2853 tcg_gen_sub_i64(t2, t3, t2);
2854 tcg_temp_free_i64(t3);
2855 tcg_gen_trunc_i64_tl(t0, t2);
2856 tcg_gen_shri_i64(t2, t2, 32);
2857 tcg_gen_trunc_i64_tl(t1, t2);
2858 tcg_temp_free_i64(t2);
2859 tcg_gen_ext32s_tl(cpu_LO[acc], t0);
2860 tcg_gen_ext32s_tl(cpu_HI[acc], t1);
2862 opn = "msubu";
2863 break;
2864 default:
2865 MIPS_INVAL(opn);
2866 generate_exception(ctx, EXCP_RI);
2867 goto out;
2869 (void)opn; /* avoid a compiler warning */
2870 MIPS_DEBUG("%s %s %s", opn, regnames[rs], regnames[rt]);
2871 out:
2872 tcg_temp_free(t0);
2873 tcg_temp_free(t1);
2876 static void gen_mul_vr54xx (DisasContext *ctx, uint32_t opc,
2877 int rd, int rs, int rt)
2879 const char *opn = "mul vr54xx";
2880 TCGv t0 = tcg_temp_new();
2881 TCGv t1 = tcg_temp_new();
2883 gen_load_gpr(t0, rs);
2884 gen_load_gpr(t1, rt);
2886 switch (opc) {
2887 case OPC_VR54XX_MULS:
2888 gen_helper_muls(t0, cpu_env, t0, t1);
2889 opn = "muls";
2890 break;
2891 case OPC_VR54XX_MULSU:
2892 gen_helper_mulsu(t0, cpu_env, t0, t1);
2893 opn = "mulsu";
2894 break;
2895 case OPC_VR54XX_MACC:
2896 gen_helper_macc(t0, cpu_env, t0, t1);
2897 opn = "macc";
2898 break;
2899 case OPC_VR54XX_MACCU:
2900 gen_helper_maccu(t0, cpu_env, t0, t1);
2901 opn = "maccu";
2902 break;
2903 case OPC_VR54XX_MSAC:
2904 gen_helper_msac(t0, cpu_env, t0, t1);
2905 opn = "msac";
2906 break;
2907 case OPC_VR54XX_MSACU:
2908 gen_helper_msacu(t0, cpu_env, t0, t1);
2909 opn = "msacu";
2910 break;
2911 case OPC_VR54XX_MULHI:
2912 gen_helper_mulhi(t0, cpu_env, t0, t1);
2913 opn = "mulhi";
2914 break;
2915 case OPC_VR54XX_MULHIU:
2916 gen_helper_mulhiu(t0, cpu_env, t0, t1);
2917 opn = "mulhiu";
2918 break;
2919 case OPC_VR54XX_MULSHI:
2920 gen_helper_mulshi(t0, cpu_env, t0, t1);
2921 opn = "mulshi";
2922 break;
2923 case OPC_VR54XX_MULSHIU:
2924 gen_helper_mulshiu(t0, cpu_env, t0, t1);
2925 opn = "mulshiu";
2926 break;
2927 case OPC_VR54XX_MACCHI:
2928 gen_helper_macchi(t0, cpu_env, t0, t1);
2929 opn = "macchi";
2930 break;
2931 case OPC_VR54XX_MACCHIU:
2932 gen_helper_macchiu(t0, cpu_env, t0, t1);
2933 opn = "macchiu";
2934 break;
2935 case OPC_VR54XX_MSACHI:
2936 gen_helper_msachi(t0, cpu_env, t0, t1);
2937 opn = "msachi";
2938 break;
2939 case OPC_VR54XX_MSACHIU:
2940 gen_helper_msachiu(t0, cpu_env, t0, t1);
2941 opn = "msachiu";
2942 break;
2943 default:
2944 MIPS_INVAL("mul vr54xx");
2945 generate_exception(ctx, EXCP_RI);
2946 goto out;
2948 gen_store_gpr(t0, rd);
2949 (void)opn; /* avoid a compiler warning */
2950 MIPS_DEBUG("%s %s, %s, %s", opn, regnames[rd], regnames[rs], regnames[rt]);
2952 out:
2953 tcg_temp_free(t0);
2954 tcg_temp_free(t1);
2957 static void gen_cl (DisasContext *ctx, uint32_t opc,
2958 int rd, int rs)
2960 const char *opn = "CLx";
2961 TCGv t0;
2963 if (rd == 0) {
2964 /* Treat as NOP. */
2965 MIPS_DEBUG("NOP");
2966 return;
2968 t0 = tcg_temp_new();
2969 gen_load_gpr(t0, rs);
2970 switch (opc) {
2971 case OPC_CLO:
2972 gen_helper_clo(cpu_gpr[rd], t0);
2973 opn = "clo";
2974 break;
2975 case OPC_CLZ:
2976 gen_helper_clz(cpu_gpr[rd], t0);
2977 opn = "clz";
2978 break;
2979 #if defined(TARGET_MIPS64)
2980 case OPC_DCLO:
2981 gen_helper_dclo(cpu_gpr[rd], t0);
2982 opn = "dclo";
2983 break;
2984 case OPC_DCLZ:
2985 gen_helper_dclz(cpu_gpr[rd], t0);
2986 opn = "dclz";
2987 break;
2988 #endif
2990 (void)opn; /* avoid a compiler warning */
2991 MIPS_DEBUG("%s %s, %s", opn, regnames[rd], regnames[rs]);
2992 tcg_temp_free(t0);
2995 /* Godson integer instructions */
2996 static void gen_loongson_integer(DisasContext *ctx, uint32_t opc,
2997 int rd, int rs, int rt)
2999 const char *opn = "loongson";
3000 TCGv t0, t1;
3002 if (rd == 0) {
3003 /* Treat as NOP. */
3004 MIPS_DEBUG("NOP");
3005 return;
3008 switch (opc) {
3009 case OPC_MULT_G_2E:
3010 case OPC_MULT_G_2F:
3011 case OPC_MULTU_G_2E:
3012 case OPC_MULTU_G_2F:
3013 #if defined(TARGET_MIPS64)
3014 case OPC_DMULT_G_2E:
3015 case OPC_DMULT_G_2F:
3016 case OPC_DMULTU_G_2E:
3017 case OPC_DMULTU_G_2F:
3018 #endif
3019 t0 = tcg_temp_new();
3020 t1 = tcg_temp_new();
3021 break;
3022 default:
3023 t0 = tcg_temp_local_new();
3024 t1 = tcg_temp_local_new();
3025 break;
3028 gen_load_gpr(t0, rs);
3029 gen_load_gpr(t1, rt);
3031 switch (opc) {
3032 case OPC_MULT_G_2E:
3033 case OPC_MULT_G_2F:
3034 tcg_gen_mul_tl(cpu_gpr[rd], t0, t1);
3035 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3036 opn = "mult.g";
3037 break;
3038 case OPC_MULTU_G_2E:
3039 case OPC_MULTU_G_2F:
3040 tcg_gen_ext32u_tl(t0, t0);
3041 tcg_gen_ext32u_tl(t1, t1);
3042 tcg_gen_mul_tl(cpu_gpr[rd], t0, t1);
3043 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3044 opn = "multu.g";
3045 break;
3046 case OPC_DIV_G_2E:
3047 case OPC_DIV_G_2F:
3049 int l1 = gen_new_label();
3050 int l2 = gen_new_label();
3051 int l3 = gen_new_label();
3052 tcg_gen_ext32s_tl(t0, t0);
3053 tcg_gen_ext32s_tl(t1, t1);
3054 tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
3055 tcg_gen_movi_tl(cpu_gpr[rd], 0);
3056 tcg_gen_br(l3);
3057 gen_set_label(l1);
3058 tcg_gen_brcondi_tl(TCG_COND_NE, t0, INT_MIN, l2);
3059 tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1, l2);
3060 tcg_gen_mov_tl(cpu_gpr[rd], t0);
3061 tcg_gen_br(l3);
3062 gen_set_label(l2);
3063 tcg_gen_div_tl(cpu_gpr[rd], t0, t1);
3064 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3065 gen_set_label(l3);
3067 opn = "div.g";
3068 break;
3069 case OPC_DIVU_G_2E:
3070 case OPC_DIVU_G_2F:
3072 int l1 = gen_new_label();
3073 int l2 = gen_new_label();
3074 tcg_gen_ext32u_tl(t0, t0);
3075 tcg_gen_ext32u_tl(t1, t1);
3076 tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
3077 tcg_gen_movi_tl(cpu_gpr[rd], 0);
3078 tcg_gen_br(l2);
3079 gen_set_label(l1);
3080 tcg_gen_divu_tl(cpu_gpr[rd], t0, t1);
3081 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3082 gen_set_label(l2);
3084 opn = "divu.g";
3085 break;
3086 case OPC_MOD_G_2E:
3087 case OPC_MOD_G_2F:
3089 int l1 = gen_new_label();
3090 int l2 = gen_new_label();
3091 int l3 = gen_new_label();
3092 tcg_gen_ext32u_tl(t0, t0);
3093 tcg_gen_ext32u_tl(t1, t1);
3094 tcg_gen_brcondi_tl(TCG_COND_EQ, t1, 0, l1);
3095 tcg_gen_brcondi_tl(TCG_COND_NE, t0, INT_MIN, l2);
3096 tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1, l2);
3097 gen_set_label(l1);
3098 tcg_gen_movi_tl(cpu_gpr[rd], 0);
3099 tcg_gen_br(l3);
3100 gen_set_label(l2);
3101 tcg_gen_rem_tl(cpu_gpr[rd], t0, t1);
3102 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3103 gen_set_label(l3);
3105 opn = "mod.g";
3106 break;
3107 case OPC_MODU_G_2E:
3108 case OPC_MODU_G_2F:
3110 int l1 = gen_new_label();
3111 int l2 = gen_new_label();
3112 tcg_gen_ext32u_tl(t0, t0);
3113 tcg_gen_ext32u_tl(t1, t1);
3114 tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
3115 tcg_gen_movi_tl(cpu_gpr[rd], 0);
3116 tcg_gen_br(l2);
3117 gen_set_label(l1);
3118 tcg_gen_remu_tl(cpu_gpr[rd], t0, t1);
3119 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3120 gen_set_label(l2);
3122 opn = "modu.g";
3123 break;
3124 #if defined(TARGET_MIPS64)
3125 case OPC_DMULT_G_2E:
3126 case OPC_DMULT_G_2F:
3127 tcg_gen_mul_tl(cpu_gpr[rd], t0, t1);
3128 opn = "dmult.g";
3129 break;
3130 case OPC_DMULTU_G_2E:
3131 case OPC_DMULTU_G_2F:
3132 tcg_gen_mul_tl(cpu_gpr[rd], t0, t1);
3133 opn = "dmultu.g";
3134 break;
3135 case OPC_DDIV_G_2E:
3136 case OPC_DDIV_G_2F:
3138 int l1 = gen_new_label();
3139 int l2 = gen_new_label();
3140 int l3 = gen_new_label();
3141 tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
3142 tcg_gen_movi_tl(cpu_gpr[rd], 0);
3143 tcg_gen_br(l3);
3144 gen_set_label(l1);
3145 tcg_gen_brcondi_tl(TCG_COND_NE, t0, -1LL << 63, l2);
3146 tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1LL, l2);
3147 tcg_gen_mov_tl(cpu_gpr[rd], t0);
3148 tcg_gen_br(l3);
3149 gen_set_label(l2);
3150 tcg_gen_div_tl(cpu_gpr[rd], t0, t1);
3151 gen_set_label(l3);
3153 opn = "ddiv.g";
3154 break;
3155 case OPC_DDIVU_G_2E:
3156 case OPC_DDIVU_G_2F:
3158 int l1 = gen_new_label();
3159 int l2 = gen_new_label();
3160 tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
3161 tcg_gen_movi_tl(cpu_gpr[rd], 0);
3162 tcg_gen_br(l2);
3163 gen_set_label(l1);
3164 tcg_gen_divu_tl(cpu_gpr[rd], t0, t1);
3165 gen_set_label(l2);
3167 opn = "ddivu.g";
3168 break;
3169 case OPC_DMOD_G_2E:
3170 case OPC_DMOD_G_2F:
3172 int l1 = gen_new_label();
3173 int l2 = gen_new_label();
3174 int l3 = gen_new_label();
3175 tcg_gen_brcondi_tl(TCG_COND_EQ, t1, 0, l1);
3176 tcg_gen_brcondi_tl(TCG_COND_NE, t0, -1LL << 63, l2);
3177 tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1LL, l2);
3178 gen_set_label(l1);
3179 tcg_gen_movi_tl(cpu_gpr[rd], 0);
3180 tcg_gen_br(l3);
3181 gen_set_label(l2);
3182 tcg_gen_rem_tl(cpu_gpr[rd], t0, t1);
3183 gen_set_label(l3);
3185 opn = "dmod.g";
3186 break;
3187 case OPC_DMODU_G_2E:
3188 case OPC_DMODU_G_2F:
3190 int l1 = gen_new_label();
3191 int l2 = gen_new_label();
3192 tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
3193 tcg_gen_movi_tl(cpu_gpr[rd], 0);
3194 tcg_gen_br(l2);
3195 gen_set_label(l1);
3196 tcg_gen_remu_tl(cpu_gpr[rd], t0, t1);
3197 gen_set_label(l2);
3199 opn = "dmodu.g";
3200 break;
3201 #endif
3204 (void)opn; /* avoid a compiler warning */
3205 MIPS_DEBUG("%s %s, %s", opn, regnames[rd], regnames[rs]);
3206 tcg_temp_free(t0);
3207 tcg_temp_free(t1);
3210 /* Loongson multimedia instructions */
3211 static void gen_loongson_multimedia(DisasContext *ctx, int rd, int rs, int rt)
3213 const char *opn = "loongson_cp2";
3214 uint32_t opc, shift_max;
3215 TCGv_i64 t0, t1;
3217 opc = MASK_LMI(ctx->opcode);
3218 switch (opc) {
3219 case OPC_ADD_CP2:
3220 case OPC_SUB_CP2:
3221 case OPC_DADD_CP2:
3222 case OPC_DSUB_CP2:
3223 t0 = tcg_temp_local_new_i64();
3224 t1 = tcg_temp_local_new_i64();
3225 break;
3226 default:
3227 t0 = tcg_temp_new_i64();
3228 t1 = tcg_temp_new_i64();
3229 break;
3232 gen_load_fpr64(ctx, t0, rs);
3233 gen_load_fpr64(ctx, t1, rt);
3235 #define LMI_HELPER(UP, LO) \
3236 case OPC_##UP: gen_helper_##LO(t0, t0, t1); opn = #LO; break
3237 #define LMI_HELPER_1(UP, LO) \
3238 case OPC_##UP: gen_helper_##LO(t0, t0); opn = #LO; break
3239 #define LMI_DIRECT(UP, LO, OP) \
3240 case OPC_##UP: tcg_gen_##OP##_i64(t0, t0, t1); opn = #LO; break
3242 switch (opc) {
3243 LMI_HELPER(PADDSH, paddsh);
3244 LMI_HELPER(PADDUSH, paddush);
3245 LMI_HELPER(PADDH, paddh);
3246 LMI_HELPER(PADDW, paddw);
3247 LMI_HELPER(PADDSB, paddsb);
3248 LMI_HELPER(PADDUSB, paddusb);
3249 LMI_HELPER(PADDB, paddb);
3251 LMI_HELPER(PSUBSH, psubsh);
3252 LMI_HELPER(PSUBUSH, psubush);
3253 LMI_HELPER(PSUBH, psubh);
3254 LMI_HELPER(PSUBW, psubw);
3255 LMI_HELPER(PSUBSB, psubsb);
3256 LMI_HELPER(PSUBUSB, psubusb);
3257 LMI_HELPER(PSUBB, psubb);
3259 LMI_HELPER(PSHUFH, pshufh);
3260 LMI_HELPER(PACKSSWH, packsswh);
3261 LMI_HELPER(PACKSSHB, packsshb);
3262 LMI_HELPER(PACKUSHB, packushb);
3264 LMI_HELPER(PUNPCKLHW, punpcklhw);
3265 LMI_HELPER(PUNPCKHHW, punpckhhw);
3266 LMI_HELPER(PUNPCKLBH, punpcklbh);
3267 LMI_HELPER(PUNPCKHBH, punpckhbh);
3268 LMI_HELPER(PUNPCKLWD, punpcklwd);
3269 LMI_HELPER(PUNPCKHWD, punpckhwd);
3271 LMI_HELPER(PAVGH, pavgh);
3272 LMI_HELPER(PAVGB, pavgb);
3273 LMI_HELPER(PMAXSH, pmaxsh);
3274 LMI_HELPER(PMINSH, pminsh);
3275 LMI_HELPER(PMAXUB, pmaxub);
3276 LMI_HELPER(PMINUB, pminub);
3278 LMI_HELPER(PCMPEQW, pcmpeqw);
3279 LMI_HELPER(PCMPGTW, pcmpgtw);
3280 LMI_HELPER(PCMPEQH, pcmpeqh);
3281 LMI_HELPER(PCMPGTH, pcmpgth);
3282 LMI_HELPER(PCMPEQB, pcmpeqb);
3283 LMI_HELPER(PCMPGTB, pcmpgtb);
3285 LMI_HELPER(PSLLW, psllw);
3286 LMI_HELPER(PSLLH, psllh);
3287 LMI_HELPER(PSRLW, psrlw);
3288 LMI_HELPER(PSRLH, psrlh);
3289 LMI_HELPER(PSRAW, psraw);
3290 LMI_HELPER(PSRAH, psrah);
3292 LMI_HELPER(PMULLH, pmullh);
3293 LMI_HELPER(PMULHH, pmulhh);
3294 LMI_HELPER(PMULHUH, pmulhuh);
3295 LMI_HELPER(PMADDHW, pmaddhw);
3297 LMI_HELPER(PASUBUB, pasubub);
3298 LMI_HELPER_1(BIADD, biadd);
3299 LMI_HELPER_1(PMOVMSKB, pmovmskb);
3301 LMI_DIRECT(PADDD, paddd, add);
3302 LMI_DIRECT(PSUBD, psubd, sub);
3303 LMI_DIRECT(XOR_CP2, xor, xor);
3304 LMI_DIRECT(NOR_CP2, nor, nor);
3305 LMI_DIRECT(AND_CP2, and, and);
3306 LMI_DIRECT(PANDN, pandn, andc);
3307 LMI_DIRECT(OR, or, or);
3309 case OPC_PINSRH_0:
3310 tcg_gen_deposit_i64(t0, t0, t1, 0, 16);
3311 opn = "pinsrh_0";
3312 break;
3313 case OPC_PINSRH_1:
3314 tcg_gen_deposit_i64(t0, t0, t1, 16, 16);
3315 opn = "pinsrh_1";
3316 break;
3317 case OPC_PINSRH_2:
3318 tcg_gen_deposit_i64(t0, t0, t1, 32, 16);
3319 opn = "pinsrh_2";
3320 break;
3321 case OPC_PINSRH_3:
3322 tcg_gen_deposit_i64(t0, t0, t1, 48, 16);
3323 opn = "pinsrh_3";
3324 break;
3326 case OPC_PEXTRH:
3327 tcg_gen_andi_i64(t1, t1, 3);
3328 tcg_gen_shli_i64(t1, t1, 4);
3329 tcg_gen_shr_i64(t0, t0, t1);
3330 tcg_gen_ext16u_i64(t0, t0);
3331 opn = "pextrh";
3332 break;
3334 case OPC_ADDU_CP2:
3335 tcg_gen_add_i64(t0, t0, t1);
3336 tcg_gen_ext32s_i64(t0, t0);
3337 opn = "addu";
3338 break;
3339 case OPC_SUBU_CP2:
3340 tcg_gen_sub_i64(t0, t0, t1);
3341 tcg_gen_ext32s_i64(t0, t0);
3342 opn = "addu";
3343 break;
3345 case OPC_SLL_CP2:
3346 opn = "sll";
3347 shift_max = 32;
3348 goto do_shift;
3349 case OPC_SRL_CP2:
3350 opn = "srl";
3351 shift_max = 32;
3352 goto do_shift;
3353 case OPC_SRA_CP2:
3354 opn = "sra";
3355 shift_max = 32;
3356 goto do_shift;
3357 case OPC_DSLL_CP2:
3358 opn = "dsll";
3359 shift_max = 64;
3360 goto do_shift;
3361 case OPC_DSRL_CP2:
3362 opn = "dsrl";
3363 shift_max = 64;
3364 goto do_shift;
3365 case OPC_DSRA_CP2:
3366 opn = "dsra";
3367 shift_max = 64;
3368 goto do_shift;
3369 do_shift:
3370 /* Make sure shift count isn't TCG undefined behaviour. */
3371 tcg_gen_andi_i64(t1, t1, shift_max - 1);
3373 switch (opc) {
3374 case OPC_SLL_CP2:
3375 case OPC_DSLL_CP2:
3376 tcg_gen_shl_i64(t0, t0, t1);
3377 break;
3378 case OPC_SRA_CP2:
3379 case OPC_DSRA_CP2:
3380 /* Since SRA is UndefinedResult without sign-extended inputs,
3381 we can treat SRA and DSRA the same. */
3382 tcg_gen_sar_i64(t0, t0, t1);
3383 break;
3384 case OPC_SRL_CP2:
3385 /* We want to shift in zeros for SRL; zero-extend first. */
3386 tcg_gen_ext32u_i64(t0, t0);
3387 /* FALLTHRU */
3388 case OPC_DSRL_CP2:
3389 tcg_gen_shr_i64(t0, t0, t1);
3390 break;
3393 if (shift_max == 32) {
3394 tcg_gen_ext32s_i64(t0, t0);
3397 /* Shifts larger than MAX produce zero. */
3398 tcg_gen_setcondi_i64(TCG_COND_LTU, t1, t1, shift_max);
3399 tcg_gen_neg_i64(t1, t1);
3400 tcg_gen_and_i64(t0, t0, t1);
3401 break;
3403 case OPC_ADD_CP2:
3404 case OPC_DADD_CP2:
3406 TCGv_i64 t2 = tcg_temp_new_i64();
3407 int lab = gen_new_label();
3409 tcg_gen_mov_i64(t2, t0);
3410 tcg_gen_add_i64(t0, t1, t2);
3411 if (opc == OPC_ADD_CP2) {
3412 tcg_gen_ext32s_i64(t0, t0);
3414 tcg_gen_xor_i64(t1, t1, t2);
3415 tcg_gen_xor_i64(t2, t2, t0);
3416 tcg_gen_andc_i64(t1, t2, t1);
3417 tcg_temp_free_i64(t2);
3418 tcg_gen_brcondi_i64(TCG_COND_GE, t1, 0, lab);
3419 generate_exception(ctx, EXCP_OVERFLOW);
3420 gen_set_label(lab);
3422 opn = (opc == OPC_ADD_CP2 ? "add" : "dadd");
3423 break;
3426 case OPC_SUB_CP2:
3427 case OPC_DSUB_CP2:
3429 TCGv_i64 t2 = tcg_temp_new_i64();
3430 int lab = gen_new_label();
3432 tcg_gen_mov_i64(t2, t0);
3433 tcg_gen_sub_i64(t0, t1, t2);
3434 if (opc == OPC_SUB_CP2) {
3435 tcg_gen_ext32s_i64(t0, t0);
3437 tcg_gen_xor_i64(t1, t1, t2);
3438 tcg_gen_xor_i64(t2, t2, t0);
3439 tcg_gen_and_i64(t1, t1, t2);
3440 tcg_temp_free_i64(t2);
3441 tcg_gen_brcondi_i64(TCG_COND_GE, t1, 0, lab);
3442 generate_exception(ctx, EXCP_OVERFLOW);
3443 gen_set_label(lab);
3445 opn = (opc == OPC_SUB_CP2 ? "sub" : "dsub");
3446 break;
3449 case OPC_PMULUW:
3450 tcg_gen_ext32u_i64(t0, t0);
3451 tcg_gen_ext32u_i64(t1, t1);
3452 tcg_gen_mul_i64(t0, t0, t1);
3453 opn = "pmuluw";
3454 break;
3456 case OPC_SEQU_CP2:
3457 case OPC_SEQ_CP2:
3458 case OPC_SLTU_CP2:
3459 case OPC_SLT_CP2:
3460 case OPC_SLEU_CP2:
3461 case OPC_SLE_CP2:
3462 /* ??? Document is unclear: Set FCC[CC]. Does that mean the
3463 FD field is the CC field? */
3464 default:
3465 MIPS_INVAL(opn);
3466 generate_exception(ctx, EXCP_RI);
3467 return;
3470 #undef LMI_HELPER
3471 #undef LMI_DIRECT
3473 gen_store_fpr64(ctx, t0, rd);
3475 (void)opn; /* avoid a compiler warning */
3476 MIPS_DEBUG("%s %s, %s, %s", opn,
3477 fregnames[rd], fregnames[rs], fregnames[rt]);
3478 tcg_temp_free_i64(t0);
3479 tcg_temp_free_i64(t1);
3482 /* Traps */
3483 static void gen_trap (DisasContext *ctx, uint32_t opc,
3484 int rs, int rt, int16_t imm)
3486 int cond;
3487 TCGv t0 = tcg_temp_new();
3488 TCGv t1 = tcg_temp_new();
3490 cond = 0;
3491 /* Load needed operands */
3492 switch (opc) {
3493 case OPC_TEQ:
3494 case OPC_TGE:
3495 case OPC_TGEU:
3496 case OPC_TLT:
3497 case OPC_TLTU:
3498 case OPC_TNE:
3499 /* Compare two registers */
3500 if (rs != rt) {
3501 gen_load_gpr(t0, rs);
3502 gen_load_gpr(t1, rt);
3503 cond = 1;
3505 break;
3506 case OPC_TEQI:
3507 case OPC_TGEI:
3508 case OPC_TGEIU:
3509 case OPC_TLTI:
3510 case OPC_TLTIU:
3511 case OPC_TNEI:
3512 /* Compare register to immediate */
3513 if (rs != 0 || imm != 0) {
3514 gen_load_gpr(t0, rs);
3515 tcg_gen_movi_tl(t1, (int32_t)imm);
3516 cond = 1;
3518 break;
3520 if (cond == 0) {
3521 switch (opc) {
3522 case OPC_TEQ: /* rs == rs */
3523 case OPC_TEQI: /* r0 == 0 */
3524 case OPC_TGE: /* rs >= rs */
3525 case OPC_TGEI: /* r0 >= 0 */
3526 case OPC_TGEU: /* rs >= rs unsigned */
3527 case OPC_TGEIU: /* r0 >= 0 unsigned */
3528 /* Always trap */
3529 generate_exception(ctx, EXCP_TRAP);
3530 break;
3531 case OPC_TLT: /* rs < rs */
3532 case OPC_TLTI: /* r0 < 0 */
3533 case OPC_TLTU: /* rs < rs unsigned */
3534 case OPC_TLTIU: /* r0 < 0 unsigned */
3535 case OPC_TNE: /* rs != rs */
3536 case OPC_TNEI: /* r0 != 0 */
3537 /* Never trap: treat as NOP. */
3538 break;
3540 } else {
3541 int l1 = gen_new_label();
3543 switch (opc) {
3544 case OPC_TEQ:
3545 case OPC_TEQI:
3546 tcg_gen_brcond_tl(TCG_COND_NE, t0, t1, l1);
3547 break;
3548 case OPC_TGE:
3549 case OPC_TGEI:
3550 tcg_gen_brcond_tl(TCG_COND_LT, t0, t1, l1);
3551 break;
3552 case OPC_TGEU:
3553 case OPC_TGEIU:
3554 tcg_gen_brcond_tl(TCG_COND_LTU, t0, t1, l1);
3555 break;
3556 case OPC_TLT:
3557 case OPC_TLTI:
3558 tcg_gen_brcond_tl(TCG_COND_GE, t0, t1, l1);
3559 break;
3560 case OPC_TLTU:
3561 case OPC_TLTIU:
3562 tcg_gen_brcond_tl(TCG_COND_GEU, t0, t1, l1);
3563 break;
3564 case OPC_TNE:
3565 case OPC_TNEI:
3566 tcg_gen_brcond_tl(TCG_COND_EQ, t0, t1, l1);
3567 break;
3569 generate_exception(ctx, EXCP_TRAP);
3570 gen_set_label(l1);
3572 tcg_temp_free(t0);
3573 tcg_temp_free(t1);
3576 static inline void gen_goto_tb(DisasContext *ctx, int n, target_ulong dest)
3578 TranslationBlock *tb;
3579 tb = ctx->tb;
3580 if ((tb->pc & TARGET_PAGE_MASK) == (dest & TARGET_PAGE_MASK) &&
3581 likely(!ctx->singlestep_enabled)) {
3582 tcg_gen_goto_tb(n);
3583 gen_save_pc(dest);
3584 tcg_gen_exit_tb((uintptr_t)tb + n);
3585 } else {
3586 gen_save_pc(dest);
3587 if (ctx->singlestep_enabled) {
3588 save_cpu_state(ctx, 0);
3589 gen_helper_0e0i(raise_exception, EXCP_DEBUG);
3591 tcg_gen_exit_tb(0);
3595 /* Branches (before delay slot) */
3596 static void gen_compute_branch (DisasContext *ctx, uint32_t opc,
3597 int insn_bytes,
3598 int rs, int rt, int32_t offset)
3600 target_ulong btgt = -1;
3601 int blink = 0;
3602 int bcond_compute = 0;
3603 TCGv t0 = tcg_temp_new();
3604 TCGv t1 = tcg_temp_new();
3606 if (ctx->hflags & MIPS_HFLAG_BMASK) {
3607 #ifdef MIPS_DEBUG_DISAS
3608 LOG_DISAS("Branch in delay slot at PC 0x" TARGET_FMT_lx "\n", ctx->pc);
3609 #endif
3610 generate_exception(ctx, EXCP_RI);
3611 goto out;
3614 /* Load needed operands */
3615 switch (opc) {
3616 case OPC_BEQ:
3617 case OPC_BEQL:
3618 case OPC_BNE:
3619 case OPC_BNEL:
3620 /* Compare two registers */
3621 if (rs != rt) {
3622 gen_load_gpr(t0, rs);
3623 gen_load_gpr(t1, rt);
3624 bcond_compute = 1;
3626 btgt = ctx->pc + insn_bytes + offset;
3627 break;
3628 case OPC_BGEZ:
3629 case OPC_BGEZAL:
3630 case OPC_BGEZALS:
3631 case OPC_BGEZALL:
3632 case OPC_BGEZL:
3633 case OPC_BGTZ:
3634 case OPC_BGTZL:
3635 case OPC_BLEZ:
3636 case OPC_BLEZL:
3637 case OPC_BLTZ:
3638 case OPC_BLTZAL:
3639 case OPC_BLTZALS:
3640 case OPC_BLTZALL:
3641 case OPC_BLTZL:
3642 /* Compare to zero */
3643 if (rs != 0) {
3644 gen_load_gpr(t0, rs);
3645 bcond_compute = 1;
3647 btgt = ctx->pc + insn_bytes + offset;
3648 break;
3649 case OPC_BPOSGE32:
3650 #if defined(TARGET_MIPS64)
3651 case OPC_BPOSGE64:
3652 tcg_gen_andi_tl(t0, cpu_dspctrl, 0x7F);
3653 #else
3654 tcg_gen_andi_tl(t0, cpu_dspctrl, 0x3F);
3655 #endif
3656 bcond_compute = 1;
3657 btgt = ctx->pc + insn_bytes + offset;
3658 break;
3659 case OPC_J:
3660 case OPC_JAL:
3661 case OPC_JALX:
3662 case OPC_JALS:
3663 case OPC_JALXS:
3664 /* Jump to immediate */
3665 btgt = ((ctx->pc + insn_bytes) & (int32_t)0xF0000000) | (uint32_t)offset;
3666 break;
3667 case OPC_JR:
3668 case OPC_JALR:
3669 case OPC_JALRC:
3670 case OPC_JALRS:
3671 /* Jump to register */
3672 if (offset != 0 && offset != 16) {
3673 /* Hint = 0 is JR/JALR, hint 16 is JR.HB/JALR.HB, the
3674 others are reserved. */
3675 MIPS_INVAL("jump hint");
3676 generate_exception(ctx, EXCP_RI);
3677 goto out;
3679 gen_load_gpr(btarget, rs);
3680 break;
3681 default:
3682 MIPS_INVAL("branch/jump");
3683 generate_exception(ctx, EXCP_RI);
3684 goto out;
3686 if (bcond_compute == 0) {
3687 /* No condition to be computed */
3688 switch (opc) {
3689 case OPC_BEQ: /* rx == rx */
3690 case OPC_BEQL: /* rx == rx likely */
3691 case OPC_BGEZ: /* 0 >= 0 */
3692 case OPC_BGEZL: /* 0 >= 0 likely */
3693 case OPC_BLEZ: /* 0 <= 0 */
3694 case OPC_BLEZL: /* 0 <= 0 likely */
3695 /* Always take */
3696 ctx->hflags |= MIPS_HFLAG_B;
3697 MIPS_DEBUG("balways");
3698 break;
3699 case OPC_BGEZALS:
3700 case OPC_BGEZAL: /* 0 >= 0 */
3701 case OPC_BGEZALL: /* 0 >= 0 likely */
3702 ctx->hflags |= (opc == OPC_BGEZALS
3703 ? MIPS_HFLAG_BDS16
3704 : MIPS_HFLAG_BDS32);
3705 /* Always take and link */
3706 blink = 31;
3707 ctx->hflags |= MIPS_HFLAG_B;
3708 MIPS_DEBUG("balways and link");
3709 break;
3710 case OPC_BNE: /* rx != rx */
3711 case OPC_BGTZ: /* 0 > 0 */
3712 case OPC_BLTZ: /* 0 < 0 */
3713 /* Treat as NOP. */
3714 MIPS_DEBUG("bnever (NOP)");
3715 goto out;
3716 case OPC_BLTZALS:
3717 case OPC_BLTZAL: /* 0 < 0 */
3718 ctx->hflags |= (opc == OPC_BLTZALS
3719 ? MIPS_HFLAG_BDS16
3720 : MIPS_HFLAG_BDS32);
3721 /* Handle as an unconditional branch to get correct delay
3722 slot checking. */
3723 blink = 31;
3724 btgt = ctx->pc + (opc == OPC_BLTZALS ? 6 : 8);
3725 ctx->hflags |= MIPS_HFLAG_B;
3726 MIPS_DEBUG("bnever and link");
3727 break;
3728 case OPC_BLTZALL: /* 0 < 0 likely */
3729 tcg_gen_movi_tl(cpu_gpr[31], ctx->pc + 8);
3730 /* Skip the instruction in the delay slot */
3731 MIPS_DEBUG("bnever, link and skip");
3732 ctx->pc += 4;
3733 goto out;
3734 case OPC_BNEL: /* rx != rx likely */
3735 case OPC_BGTZL: /* 0 > 0 likely */
3736 case OPC_BLTZL: /* 0 < 0 likely */
3737 /* Skip the instruction in the delay slot */
3738 MIPS_DEBUG("bnever and skip");
3739 ctx->pc += 4;
3740 goto out;
3741 case OPC_J:
3742 ctx->hflags |= MIPS_HFLAG_B;
3743 MIPS_DEBUG("j " TARGET_FMT_lx, btgt);
3744 break;
3745 case OPC_JALXS:
3746 case OPC_JALX:
3747 ctx->hflags |= MIPS_HFLAG_BX;
3748 /* Fallthrough */
3749 case OPC_JALS:
3750 case OPC_JAL:
3751 blink = 31;
3752 ctx->hflags |= MIPS_HFLAG_B;
3753 ctx->hflags |= ((opc == OPC_JALS || opc == OPC_JALXS)
3754 ? MIPS_HFLAG_BDS16
3755 : MIPS_HFLAG_BDS32);
3756 MIPS_DEBUG("jal " TARGET_FMT_lx, btgt);
3757 break;
3758 case OPC_JR:
3759 ctx->hflags |= MIPS_HFLAG_BR;
3760 if (insn_bytes == 4)
3761 ctx->hflags |= MIPS_HFLAG_BDS32;
3762 MIPS_DEBUG("jr %s", regnames[rs]);
3763 break;
3764 case OPC_JALRS:
3765 case OPC_JALR:
3766 case OPC_JALRC:
3767 blink = rt;
3768 ctx->hflags |= MIPS_HFLAG_BR;
3769 ctx->hflags |= (opc == OPC_JALRS
3770 ? MIPS_HFLAG_BDS16
3771 : MIPS_HFLAG_BDS32);
3772 MIPS_DEBUG("jalr %s, %s", regnames[rt], regnames[rs]);
3773 break;
3774 default:
3775 MIPS_INVAL("branch/jump");
3776 generate_exception(ctx, EXCP_RI);
3777 goto out;
3779 } else {
3780 switch (opc) {
3781 case OPC_BEQ:
3782 tcg_gen_setcond_tl(TCG_COND_EQ, bcond, t0, t1);
3783 MIPS_DEBUG("beq %s, %s, " TARGET_FMT_lx,
3784 regnames[rs], regnames[rt], btgt);
3785 goto not_likely;
3786 case OPC_BEQL:
3787 tcg_gen_setcond_tl(TCG_COND_EQ, bcond, t0, t1);
3788 MIPS_DEBUG("beql %s, %s, " TARGET_FMT_lx,
3789 regnames[rs], regnames[rt], btgt);
3790 goto likely;
3791 case OPC_BNE:
3792 tcg_gen_setcond_tl(TCG_COND_NE, bcond, t0, t1);
3793 MIPS_DEBUG("bne %s, %s, " TARGET_FMT_lx,
3794 regnames[rs], regnames[rt], btgt);
3795 goto not_likely;
3796 case OPC_BNEL:
3797 tcg_gen_setcond_tl(TCG_COND_NE, bcond, t0, t1);
3798 MIPS_DEBUG("bnel %s, %s, " TARGET_FMT_lx,
3799 regnames[rs], regnames[rt], btgt);
3800 goto likely;
3801 case OPC_BGEZ:
3802 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 0);
3803 MIPS_DEBUG("bgez %s, " TARGET_FMT_lx, regnames[rs], btgt);
3804 goto not_likely;
3805 case OPC_BGEZL:
3806 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 0);
3807 MIPS_DEBUG("bgezl %s, " TARGET_FMT_lx, regnames[rs], btgt);
3808 goto likely;
3809 case OPC_BGEZALS:
3810 case OPC_BGEZAL:
3811 ctx->hflags |= (opc == OPC_BGEZALS
3812 ? MIPS_HFLAG_BDS16
3813 : MIPS_HFLAG_BDS32);
3814 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 0);
3815 MIPS_DEBUG("bgezal %s, " TARGET_FMT_lx, regnames[rs], btgt);
3816 blink = 31;
3817 goto not_likely;
3818 case OPC_BGEZALL:
3819 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 0);
3820 blink = 31;
3821 MIPS_DEBUG("bgezall %s, " TARGET_FMT_lx, regnames[rs], btgt);
3822 goto likely;
3823 case OPC_BGTZ:
3824 tcg_gen_setcondi_tl(TCG_COND_GT, bcond, t0, 0);
3825 MIPS_DEBUG("bgtz %s, " TARGET_FMT_lx, regnames[rs], btgt);
3826 goto not_likely;
3827 case OPC_BGTZL:
3828 tcg_gen_setcondi_tl(TCG_COND_GT, bcond, t0, 0);
3829 MIPS_DEBUG("bgtzl %s, " TARGET_FMT_lx, regnames[rs], btgt);
3830 goto likely;
3831 case OPC_BLEZ:
3832 tcg_gen_setcondi_tl(TCG_COND_LE, bcond, t0, 0);
3833 MIPS_DEBUG("blez %s, " TARGET_FMT_lx, regnames[rs], btgt);
3834 goto not_likely;
3835 case OPC_BLEZL:
3836 tcg_gen_setcondi_tl(TCG_COND_LE, bcond, t0, 0);
3837 MIPS_DEBUG("blezl %s, " TARGET_FMT_lx, regnames[rs], btgt);
3838 goto likely;
3839 case OPC_BLTZ:
3840 tcg_gen_setcondi_tl(TCG_COND_LT, bcond, t0, 0);
3841 MIPS_DEBUG("bltz %s, " TARGET_FMT_lx, regnames[rs], btgt);
3842 goto not_likely;
3843 case OPC_BLTZL:
3844 tcg_gen_setcondi_tl(TCG_COND_LT, bcond, t0, 0);
3845 MIPS_DEBUG("bltzl %s, " TARGET_FMT_lx, regnames[rs], btgt);
3846 goto likely;
3847 case OPC_BPOSGE32:
3848 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 32);
3849 MIPS_DEBUG("bposge32 " TARGET_FMT_lx, btgt);
3850 goto not_likely;
3851 #if defined(TARGET_MIPS64)
3852 case OPC_BPOSGE64:
3853 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 64);
3854 MIPS_DEBUG("bposge64 " TARGET_FMT_lx, btgt);
3855 goto not_likely;
3856 #endif
3857 case OPC_BLTZALS:
3858 case OPC_BLTZAL:
3859 ctx->hflags |= (opc == OPC_BLTZALS
3860 ? MIPS_HFLAG_BDS16
3861 : MIPS_HFLAG_BDS32);
3862 tcg_gen_setcondi_tl(TCG_COND_LT, bcond, t0, 0);
3863 blink = 31;
3864 MIPS_DEBUG("bltzal %s, " TARGET_FMT_lx, regnames[rs], btgt);
3865 not_likely:
3866 ctx->hflags |= MIPS_HFLAG_BC;
3867 break;
3868 case OPC_BLTZALL:
3869 tcg_gen_setcondi_tl(TCG_COND_LT, bcond, t0, 0);
3870 blink = 31;
3871 MIPS_DEBUG("bltzall %s, " TARGET_FMT_lx, regnames[rs], btgt);
3872 likely:
3873 ctx->hflags |= MIPS_HFLAG_BL;
3874 break;
3875 default:
3876 MIPS_INVAL("conditional branch/jump");
3877 generate_exception(ctx, EXCP_RI);
3878 goto out;
3881 MIPS_DEBUG("enter ds: link %d cond %02x target " TARGET_FMT_lx,
3882 blink, ctx->hflags, btgt);
3884 ctx->btarget = btgt;
3885 if (blink > 0) {
3886 int post_delay = insn_bytes;
3887 int lowbit = !!(ctx->hflags & MIPS_HFLAG_M16);
3889 if (opc != OPC_JALRC)
3890 post_delay += ((ctx->hflags & MIPS_HFLAG_BDS16) ? 2 : 4);
3892 tcg_gen_movi_tl(cpu_gpr[blink], ctx->pc + post_delay + lowbit);
3895 out:
3896 if (insn_bytes == 2)
3897 ctx->hflags |= MIPS_HFLAG_B16;
3898 tcg_temp_free(t0);
3899 tcg_temp_free(t1);
3902 /* special3 bitfield operations */
3903 static void gen_bitops (DisasContext *ctx, uint32_t opc, int rt,
3904 int rs, int lsb, int msb)
3906 TCGv t0 = tcg_temp_new();
3907 TCGv t1 = tcg_temp_new();
3909 gen_load_gpr(t1, rs);
3910 switch (opc) {
3911 case OPC_EXT:
3912 if (lsb + msb > 31)
3913 goto fail;
3914 tcg_gen_shri_tl(t0, t1, lsb);
3915 if (msb != 31) {
3916 tcg_gen_andi_tl(t0, t0, (1 << (msb + 1)) - 1);
3917 } else {
3918 tcg_gen_ext32s_tl(t0, t0);
3920 break;
3921 #if defined(TARGET_MIPS64)
3922 case OPC_DEXTM:
3923 tcg_gen_shri_tl(t0, t1, lsb);
3924 if (msb != 31) {
3925 tcg_gen_andi_tl(t0, t0, (1ULL << (msb + 1 + 32)) - 1);
3927 break;
3928 case OPC_DEXTU:
3929 tcg_gen_shri_tl(t0, t1, lsb + 32);
3930 tcg_gen_andi_tl(t0, t0, (1ULL << (msb + 1)) - 1);
3931 break;
3932 case OPC_DEXT:
3933 tcg_gen_shri_tl(t0, t1, lsb);
3934 tcg_gen_andi_tl(t0, t0, (1ULL << (msb + 1)) - 1);
3935 break;
3936 #endif
3937 case OPC_INS:
3938 if (lsb > msb)
3939 goto fail;
3940 gen_load_gpr(t0, rt);
3941 tcg_gen_deposit_tl(t0, t0, t1, lsb, msb - lsb + 1);
3942 tcg_gen_ext32s_tl(t0, t0);
3943 break;
3944 #if defined(TARGET_MIPS64)
3945 case OPC_DINSM:
3946 gen_load_gpr(t0, rt);
3947 tcg_gen_deposit_tl(t0, t0, t1, lsb, msb + 32 - lsb + 1);
3948 break;
3949 case OPC_DINSU:
3950 gen_load_gpr(t0, rt);
3951 tcg_gen_deposit_tl(t0, t0, t1, lsb + 32, msb - lsb + 1);
3952 break;
3953 case OPC_DINS:
3954 gen_load_gpr(t0, rt);
3955 tcg_gen_deposit_tl(t0, t0, t1, lsb, msb - lsb + 1);
3956 break;
3957 #endif
3958 default:
3959 fail:
3960 MIPS_INVAL("bitops");
3961 generate_exception(ctx, EXCP_RI);
3962 tcg_temp_free(t0);
3963 tcg_temp_free(t1);
3964 return;
3966 gen_store_gpr(t0, rt);
3967 tcg_temp_free(t0);
3968 tcg_temp_free(t1);
3971 static void gen_bshfl (DisasContext *ctx, uint32_t op2, int rt, int rd)
3973 TCGv t0;
3975 if (rd == 0) {
3976 /* If no destination, treat it as a NOP. */
3977 MIPS_DEBUG("NOP");
3978 return;
3981 t0 = tcg_temp_new();
3982 gen_load_gpr(t0, rt);
3983 switch (op2) {
3984 case OPC_WSBH:
3986 TCGv t1 = tcg_temp_new();
3988 tcg_gen_shri_tl(t1, t0, 8);
3989 tcg_gen_andi_tl(t1, t1, 0x00FF00FF);
3990 tcg_gen_shli_tl(t0, t0, 8);
3991 tcg_gen_andi_tl(t0, t0, ~0x00FF00FF);
3992 tcg_gen_or_tl(t0, t0, t1);
3993 tcg_temp_free(t1);
3994 tcg_gen_ext32s_tl(cpu_gpr[rd], t0);
3996 break;
3997 case OPC_SEB:
3998 tcg_gen_ext8s_tl(cpu_gpr[rd], t0);
3999 break;
4000 case OPC_SEH:
4001 tcg_gen_ext16s_tl(cpu_gpr[rd], t0);
4002 break;
4003 #if defined(TARGET_MIPS64)
4004 case OPC_DSBH:
4006 TCGv t1 = tcg_temp_new();
4008 tcg_gen_shri_tl(t1, t0, 8);
4009 tcg_gen_andi_tl(t1, t1, 0x00FF00FF00FF00FFULL);
4010 tcg_gen_shli_tl(t0, t0, 8);
4011 tcg_gen_andi_tl(t0, t0, ~0x00FF00FF00FF00FFULL);
4012 tcg_gen_or_tl(cpu_gpr[rd], t0, t1);
4013 tcg_temp_free(t1);
4015 break;
4016 case OPC_DSHD:
4018 TCGv t1 = tcg_temp_new();
4020 tcg_gen_shri_tl(t1, t0, 16);
4021 tcg_gen_andi_tl(t1, t1, 0x0000FFFF0000FFFFULL);
4022 tcg_gen_shli_tl(t0, t0, 16);
4023 tcg_gen_andi_tl(t0, t0, ~0x0000FFFF0000FFFFULL);
4024 tcg_gen_or_tl(t0, t0, t1);
4025 tcg_gen_shri_tl(t1, t0, 32);
4026 tcg_gen_shli_tl(t0, t0, 32);
4027 tcg_gen_or_tl(cpu_gpr[rd], t0, t1);
4028 tcg_temp_free(t1);
4030 break;
4031 #endif
4032 default:
4033 MIPS_INVAL("bsfhl");
4034 generate_exception(ctx, EXCP_RI);
4035 tcg_temp_free(t0);
4036 return;
4038 tcg_temp_free(t0);
4041 #ifndef CONFIG_USER_ONLY
4042 /* CP0 (MMU and control) */
4043 static inline void gen_mfc0_load32 (TCGv arg, target_ulong off)
4045 TCGv_i32 t0 = tcg_temp_new_i32();
4047 tcg_gen_ld_i32(t0, cpu_env, off);
4048 tcg_gen_ext_i32_tl(arg, t0);
4049 tcg_temp_free_i32(t0);
4052 static inline void gen_mfc0_load64 (TCGv arg, target_ulong off)
4054 tcg_gen_ld_tl(arg, cpu_env, off);
4055 tcg_gen_ext32s_tl(arg, arg);
4058 static inline void gen_mtc0_store32 (TCGv arg, target_ulong off)
4060 TCGv_i32 t0 = tcg_temp_new_i32();
4062 tcg_gen_trunc_tl_i32(t0, arg);
4063 tcg_gen_st_i32(t0, cpu_env, off);
4064 tcg_temp_free_i32(t0);
4067 static inline void gen_mtc0_store64 (TCGv arg, target_ulong off)
4069 tcg_gen_ext32s_tl(arg, arg);
4070 tcg_gen_st_tl(arg, cpu_env, off);
4073 static void gen_mfc0(DisasContext *ctx, TCGv arg, int reg, int sel)
4075 const char *rn = "invalid";
4077 if (sel != 0)
4078 check_insn(ctx, ISA_MIPS32);
4080 switch (reg) {
4081 case 0:
4082 switch (sel) {
4083 case 0:
4084 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Index));
4085 rn = "Index";
4086 break;
4087 case 1:
4088 check_insn(ctx, ASE_MT);
4089 gen_helper_mfc0_mvpcontrol(arg, cpu_env);
4090 rn = "MVPControl";
4091 break;
4092 case 2:
4093 check_insn(ctx, ASE_MT);
4094 gen_helper_mfc0_mvpconf0(arg, cpu_env);
4095 rn = "MVPConf0";
4096 break;
4097 case 3:
4098 check_insn(ctx, ASE_MT);
4099 gen_helper_mfc0_mvpconf1(arg, cpu_env);
4100 rn = "MVPConf1";
4101 break;
4102 default:
4103 goto die;
4105 break;
4106 case 1:
4107 switch (sel) {
4108 case 0:
4109 gen_helper_mfc0_random(arg, cpu_env);
4110 rn = "Random";
4111 break;
4112 case 1:
4113 check_insn(ctx, ASE_MT);
4114 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEControl));
4115 rn = "VPEControl";
4116 break;
4117 case 2:
4118 check_insn(ctx, ASE_MT);
4119 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEConf0));
4120 rn = "VPEConf0";
4121 break;
4122 case 3:
4123 check_insn(ctx, ASE_MT);
4124 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEConf1));
4125 rn = "VPEConf1";
4126 break;
4127 case 4:
4128 check_insn(ctx, ASE_MT);
4129 gen_mfc0_load64(arg, offsetof(CPUMIPSState, CP0_YQMask));
4130 rn = "YQMask";
4131 break;
4132 case 5:
4133 check_insn(ctx, ASE_MT);
4134 gen_mfc0_load64(arg, offsetof(CPUMIPSState, CP0_VPESchedule));
4135 rn = "VPESchedule";
4136 break;
4137 case 6:
4138 check_insn(ctx, ASE_MT);
4139 gen_mfc0_load64(arg, offsetof(CPUMIPSState, CP0_VPEScheFBack));
4140 rn = "VPEScheFBack";
4141 break;
4142 case 7:
4143 check_insn(ctx, ASE_MT);
4144 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEOpt));
4145 rn = "VPEOpt";
4146 break;
4147 default:
4148 goto die;
4150 break;
4151 case 2:
4152 switch (sel) {
4153 case 0:
4154 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EntryLo0));
4155 tcg_gen_ext32s_tl(arg, arg);
4156 rn = "EntryLo0";
4157 break;
4158 case 1:
4159 check_insn(ctx, ASE_MT);
4160 gen_helper_mfc0_tcstatus(arg, cpu_env);
4161 rn = "TCStatus";
4162 break;
4163 case 2:
4164 check_insn(ctx, ASE_MT);
4165 gen_helper_mfc0_tcbind(arg, cpu_env);
4166 rn = "TCBind";
4167 break;
4168 case 3:
4169 check_insn(ctx, ASE_MT);
4170 gen_helper_mfc0_tcrestart(arg, cpu_env);
4171 rn = "TCRestart";
4172 break;
4173 case 4:
4174 check_insn(ctx, ASE_MT);
4175 gen_helper_mfc0_tchalt(arg, cpu_env);
4176 rn = "TCHalt";
4177 break;
4178 case 5:
4179 check_insn(ctx, ASE_MT);
4180 gen_helper_mfc0_tccontext(arg, cpu_env);
4181 rn = "TCContext";
4182 break;
4183 case 6:
4184 check_insn(ctx, ASE_MT);
4185 gen_helper_mfc0_tcschedule(arg, cpu_env);
4186 rn = "TCSchedule";
4187 break;
4188 case 7:
4189 check_insn(ctx, ASE_MT);
4190 gen_helper_mfc0_tcschefback(arg, cpu_env);
4191 rn = "TCScheFBack";
4192 break;
4193 default:
4194 goto die;
4196 break;
4197 case 3:
4198 switch (sel) {
4199 case 0:
4200 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EntryLo1));
4201 tcg_gen_ext32s_tl(arg, arg);
4202 rn = "EntryLo1";
4203 break;
4204 default:
4205 goto die;
4207 break;
4208 case 4:
4209 switch (sel) {
4210 case 0:
4211 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_Context));
4212 tcg_gen_ext32s_tl(arg, arg);
4213 rn = "Context";
4214 break;
4215 case 1:
4216 // gen_helper_mfc0_contextconfig(arg); /* SmartMIPS ASE */
4217 rn = "ContextConfig";
4218 // break;
4219 default:
4220 goto die;
4222 break;
4223 case 5:
4224 switch (sel) {
4225 case 0:
4226 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PageMask));
4227 rn = "PageMask";
4228 break;
4229 case 1:
4230 check_insn(ctx, ISA_MIPS32R2);
4231 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PageGrain));
4232 rn = "PageGrain";
4233 break;
4234 default:
4235 goto die;
4237 break;
4238 case 6:
4239 switch (sel) {
4240 case 0:
4241 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Wired));
4242 rn = "Wired";
4243 break;
4244 case 1:
4245 check_insn(ctx, ISA_MIPS32R2);
4246 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf0));
4247 rn = "SRSConf0";
4248 break;
4249 case 2:
4250 check_insn(ctx, ISA_MIPS32R2);
4251 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf1));
4252 rn = "SRSConf1";
4253 break;
4254 case 3:
4255 check_insn(ctx, ISA_MIPS32R2);
4256 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf2));
4257 rn = "SRSConf2";
4258 break;
4259 case 4:
4260 check_insn(ctx, ISA_MIPS32R2);
4261 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf3));
4262 rn = "SRSConf3";
4263 break;
4264 case 5:
4265 check_insn(ctx, ISA_MIPS32R2);
4266 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf4));
4267 rn = "SRSConf4";
4268 break;
4269 default:
4270 goto die;
4272 break;
4273 case 7:
4274 switch (sel) {
4275 case 0:
4276 check_insn(ctx, ISA_MIPS32R2);
4277 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_HWREna));
4278 rn = "HWREna";
4279 break;
4280 default:
4281 goto die;
4283 break;
4284 case 8:
4285 switch (sel) {
4286 case 0:
4287 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_BadVAddr));
4288 tcg_gen_ext32s_tl(arg, arg);
4289 rn = "BadVAddr";
4290 break;
4291 default:
4292 goto die;
4294 break;
4295 case 9:
4296 switch (sel) {
4297 case 0:
4298 /* Mark as an IO operation because we read the time. */
4299 if (use_icount)
4300 gen_io_start();
4301 gen_helper_mfc0_count(arg, cpu_env);
4302 if (use_icount) {
4303 gen_io_end();
4305 /* Break the TB to be able to take timer interrupts immediately
4306 after reading count. */
4307 ctx->bstate = BS_STOP;
4308 rn = "Count";
4309 break;
4310 /* 6,7 are implementation dependent */
4311 default:
4312 goto die;
4314 break;
4315 case 10:
4316 switch (sel) {
4317 case 0:
4318 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EntryHi));
4319 tcg_gen_ext32s_tl(arg, arg);
4320 rn = "EntryHi";
4321 break;
4322 default:
4323 goto die;
4325 break;
4326 case 11:
4327 switch (sel) {
4328 case 0:
4329 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Compare));
4330 rn = "Compare";
4331 break;
4332 /* 6,7 are implementation dependent */
4333 default:
4334 goto die;
4336 break;
4337 case 12:
4338 switch (sel) {
4339 case 0:
4340 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Status));
4341 rn = "Status";
4342 break;
4343 case 1:
4344 check_insn(ctx, ISA_MIPS32R2);
4345 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_IntCtl));
4346 rn = "IntCtl";
4347 break;
4348 case 2:
4349 check_insn(ctx, ISA_MIPS32R2);
4350 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSCtl));
4351 rn = "SRSCtl";
4352 break;
4353 case 3:
4354 check_insn(ctx, ISA_MIPS32R2);
4355 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSMap));
4356 rn = "SRSMap";
4357 break;
4358 default:
4359 goto die;
4361 break;
4362 case 13:
4363 switch (sel) {
4364 case 0:
4365 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Cause));
4366 rn = "Cause";
4367 break;
4368 default:
4369 goto die;
4371 break;
4372 case 14:
4373 switch (sel) {
4374 case 0:
4375 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EPC));
4376 tcg_gen_ext32s_tl(arg, arg);
4377 rn = "EPC";
4378 break;
4379 default:
4380 goto die;
4382 break;
4383 case 15:
4384 switch (sel) {
4385 case 0:
4386 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PRid));
4387 rn = "PRid";
4388 break;
4389 case 1:
4390 check_insn(ctx, ISA_MIPS32R2);
4391 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_EBase));
4392 rn = "EBase";
4393 break;
4394 default:
4395 goto die;
4397 break;
4398 case 16:
4399 switch (sel) {
4400 case 0:
4401 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config0));
4402 rn = "Config";
4403 break;
4404 case 1:
4405 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config1));
4406 rn = "Config1";
4407 break;
4408 case 2:
4409 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config2));
4410 rn = "Config2";
4411 break;
4412 case 3:
4413 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config3));
4414 rn = "Config3";
4415 break;
4416 case 4:
4417 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config4));
4418 rn = "Config4";
4419 break;
4420 case 5:
4421 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config5));
4422 rn = "Config5";
4423 break;
4424 /* 6,7 are implementation dependent */
4425 case 6:
4426 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config6));
4427 rn = "Config6";
4428 break;
4429 case 7:
4430 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config7));
4431 rn = "Config7";
4432 break;
4433 default:
4434 goto die;
4436 break;
4437 case 17:
4438 switch (sel) {
4439 case 0:
4440 gen_helper_mfc0_lladdr(arg, cpu_env);
4441 rn = "LLAddr";
4442 break;
4443 default:
4444 goto die;
4446 break;
4447 case 18:
4448 switch (sel) {
4449 case 0 ... 7:
4450 gen_helper_1e0i(mfc0_watchlo, arg, sel);
4451 rn = "WatchLo";
4452 break;
4453 default:
4454 goto die;
4456 break;
4457 case 19:
4458 switch (sel) {
4459 case 0 ...7:
4460 gen_helper_1e0i(mfc0_watchhi, arg, sel);
4461 rn = "WatchHi";
4462 break;
4463 default:
4464 goto die;
4466 break;
4467 case 20:
4468 switch (sel) {
4469 case 0:
4470 #if defined(TARGET_MIPS64)
4471 check_insn(ctx, ISA_MIPS3);
4472 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_XContext));
4473 tcg_gen_ext32s_tl(arg, arg);
4474 rn = "XContext";
4475 break;
4476 #endif
4477 default:
4478 goto die;
4480 break;
4481 case 21:
4482 /* Officially reserved, but sel 0 is used for R1x000 framemask */
4483 switch (sel) {
4484 case 0:
4485 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Framemask));
4486 rn = "Framemask";
4487 break;
4488 default:
4489 goto die;
4491 break;
4492 case 22:
4493 tcg_gen_movi_tl(arg, 0); /* unimplemented */
4494 rn = "'Diagnostic"; /* implementation dependent */
4495 break;
4496 case 23:
4497 switch (sel) {
4498 case 0:
4499 gen_helper_mfc0_debug(arg, cpu_env); /* EJTAG support */
4500 rn = "Debug";
4501 break;
4502 case 1:
4503 // gen_helper_mfc0_tracecontrol(arg); /* PDtrace support */
4504 rn = "TraceControl";
4505 // break;
4506 case 2:
4507 // gen_helper_mfc0_tracecontrol2(arg); /* PDtrace support */
4508 rn = "TraceControl2";
4509 // break;
4510 case 3:
4511 // gen_helper_mfc0_usertracedata(arg); /* PDtrace support */
4512 rn = "UserTraceData";
4513 // break;
4514 case 4:
4515 // gen_helper_mfc0_tracebpc(arg); /* PDtrace support */
4516 rn = "TraceBPC";
4517 // break;
4518 default:
4519 goto die;
4521 break;
4522 case 24:
4523 switch (sel) {
4524 case 0:
4525 /* EJTAG support */
4526 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_DEPC));
4527 tcg_gen_ext32s_tl(arg, arg);
4528 rn = "DEPC";
4529 break;
4530 default:
4531 goto die;
4533 break;
4534 case 25:
4535 switch (sel) {
4536 case 0:
4537 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Performance0));
4538 rn = "Performance0";
4539 break;
4540 case 1:
4541 // gen_helper_mfc0_performance1(arg);
4542 rn = "Performance1";
4543 // break;
4544 case 2:
4545 // gen_helper_mfc0_performance2(arg);
4546 rn = "Performance2";
4547 // break;
4548 case 3:
4549 // gen_helper_mfc0_performance3(arg);
4550 rn = "Performance3";
4551 // break;
4552 case 4:
4553 // gen_helper_mfc0_performance4(arg);
4554 rn = "Performance4";
4555 // break;
4556 case 5:
4557 // gen_helper_mfc0_performance5(arg);
4558 rn = "Performance5";
4559 // break;
4560 case 6:
4561 // gen_helper_mfc0_performance6(arg);
4562 rn = "Performance6";
4563 // break;
4564 case 7:
4565 // gen_helper_mfc0_performance7(arg);
4566 rn = "Performance7";
4567 // break;
4568 default:
4569 goto die;
4571 break;
4572 case 26:
4573 tcg_gen_movi_tl(arg, 0); /* unimplemented */
4574 rn = "ECC";
4575 break;
4576 case 27:
4577 switch (sel) {
4578 case 0 ... 3:
4579 tcg_gen_movi_tl(arg, 0); /* unimplemented */
4580 rn = "CacheErr";
4581 break;
4582 default:
4583 goto die;
4585 break;
4586 case 28:
4587 switch (sel) {
4588 case 0:
4589 case 2:
4590 case 4:
4591 case 6:
4592 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_TagLo));
4593 rn = "TagLo";
4594 break;
4595 case 1:
4596 case 3:
4597 case 5:
4598 case 7:
4599 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DataLo));
4600 rn = "DataLo";
4601 break;
4602 default:
4603 goto die;
4605 break;
4606 case 29:
4607 switch (sel) {
4608 case 0:
4609 case 2:
4610 case 4:
4611 case 6:
4612 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_TagHi));
4613 rn = "TagHi";
4614 break;
4615 case 1:
4616 case 3:
4617 case 5:
4618 case 7:
4619 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DataHi));
4620 rn = "DataHi";
4621 break;
4622 default:
4623 goto die;
4625 break;
4626 case 30:
4627 switch (sel) {
4628 case 0:
4629 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_ErrorEPC));
4630 tcg_gen_ext32s_tl(arg, arg);
4631 rn = "ErrorEPC";
4632 break;
4633 default:
4634 goto die;
4636 break;
4637 case 31:
4638 switch (sel) {
4639 case 0:
4640 /* EJTAG support */
4641 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DESAVE));
4642 rn = "DESAVE";
4643 break;
4644 default:
4645 goto die;
4647 break;
4648 default:
4649 goto die;
4651 (void)rn; /* avoid a compiler warning */
4652 LOG_DISAS("mfc0 %s (reg %d sel %d)\n", rn, reg, sel);
4653 return;
4655 die:
4656 LOG_DISAS("mfc0 %s (reg %d sel %d)\n", rn, reg, sel);
4657 generate_exception(ctx, EXCP_RI);
4660 static void gen_mtc0(DisasContext *ctx, TCGv arg, int reg, int sel)
4662 const char *rn = "invalid";
4664 if (sel != 0)
4665 check_insn(ctx, ISA_MIPS32);
4667 if (use_icount)
4668 gen_io_start();
4670 switch (reg) {
4671 case 0:
4672 switch (sel) {
4673 case 0:
4674 gen_helper_mtc0_index(cpu_env, arg);
4675 rn = "Index";
4676 break;
4677 case 1:
4678 check_insn(ctx, ASE_MT);
4679 gen_helper_mtc0_mvpcontrol(cpu_env, arg);
4680 rn = "MVPControl";
4681 break;
4682 case 2:
4683 check_insn(ctx, ASE_MT);
4684 /* ignored */
4685 rn = "MVPConf0";
4686 break;
4687 case 3:
4688 check_insn(ctx, ASE_MT);
4689 /* ignored */
4690 rn = "MVPConf1";
4691 break;
4692 default:
4693 goto die;
4695 break;
4696 case 1:
4697 switch (sel) {
4698 case 0:
4699 /* ignored */
4700 rn = "Random";
4701 break;
4702 case 1:
4703 check_insn(ctx, ASE_MT);
4704 gen_helper_mtc0_vpecontrol(cpu_env, arg);
4705 rn = "VPEControl";
4706 break;
4707 case 2:
4708 check_insn(ctx, ASE_MT);
4709 gen_helper_mtc0_vpeconf0(cpu_env, arg);
4710 rn = "VPEConf0";
4711 break;
4712 case 3:
4713 check_insn(ctx, ASE_MT);
4714 gen_helper_mtc0_vpeconf1(cpu_env, arg);
4715 rn = "VPEConf1";
4716 break;
4717 case 4:
4718 check_insn(ctx, ASE_MT);
4719 gen_helper_mtc0_yqmask(cpu_env, arg);
4720 rn = "YQMask";
4721 break;
4722 case 5:
4723 check_insn(ctx, ASE_MT);
4724 gen_mtc0_store64(arg, offsetof(CPUMIPSState, CP0_VPESchedule));
4725 rn = "VPESchedule";
4726 break;
4727 case 6:
4728 check_insn(ctx, ASE_MT);
4729 gen_mtc0_store64(arg, offsetof(CPUMIPSState, CP0_VPEScheFBack));
4730 rn = "VPEScheFBack";
4731 break;
4732 case 7:
4733 check_insn(ctx, ASE_MT);
4734 gen_helper_mtc0_vpeopt(cpu_env, arg);
4735 rn = "VPEOpt";
4736 break;
4737 default:
4738 goto die;
4740 break;
4741 case 2:
4742 switch (sel) {
4743 case 0:
4744 gen_helper_mtc0_entrylo0(cpu_env, arg);
4745 rn = "EntryLo0";
4746 break;
4747 case 1:
4748 check_insn(ctx, ASE_MT);
4749 gen_helper_mtc0_tcstatus(cpu_env, arg);
4750 rn = "TCStatus";
4751 break;
4752 case 2:
4753 check_insn(ctx, ASE_MT);
4754 gen_helper_mtc0_tcbind(cpu_env, arg);
4755 rn = "TCBind";
4756 break;
4757 case 3:
4758 check_insn(ctx, ASE_MT);
4759 gen_helper_mtc0_tcrestart(cpu_env, arg);
4760 rn = "TCRestart";
4761 break;
4762 case 4:
4763 check_insn(ctx, ASE_MT);
4764 gen_helper_mtc0_tchalt(cpu_env, arg);
4765 rn = "TCHalt";
4766 break;
4767 case 5:
4768 check_insn(ctx, ASE_MT);
4769 gen_helper_mtc0_tccontext(cpu_env, arg);
4770 rn = "TCContext";
4771 break;
4772 case 6:
4773 check_insn(ctx, ASE_MT);
4774 gen_helper_mtc0_tcschedule(cpu_env, arg);
4775 rn = "TCSchedule";
4776 break;
4777 case 7:
4778 check_insn(ctx, ASE_MT);
4779 gen_helper_mtc0_tcschefback(cpu_env, arg);
4780 rn = "TCScheFBack";
4781 break;
4782 default:
4783 goto die;
4785 break;
4786 case 3:
4787 switch (sel) {
4788 case 0:
4789 gen_helper_mtc0_entrylo1(cpu_env, arg);
4790 rn = "EntryLo1";
4791 break;
4792 default:
4793 goto die;
4795 break;
4796 case 4:
4797 switch (sel) {
4798 case 0:
4799 gen_helper_mtc0_context(cpu_env, arg);
4800 rn = "Context";
4801 break;
4802 case 1:
4803 // gen_helper_mtc0_contextconfig(cpu_env, arg); /* SmartMIPS ASE */
4804 rn = "ContextConfig";
4805 // break;
4806 default:
4807 goto die;
4809 break;
4810 case 5:
4811 switch (sel) {
4812 case 0:
4813 gen_helper_mtc0_pagemask(cpu_env, arg);
4814 rn = "PageMask";
4815 break;
4816 case 1:
4817 check_insn(ctx, ISA_MIPS32R2);
4818 gen_helper_mtc0_pagegrain(cpu_env, arg);
4819 rn = "PageGrain";
4820 break;
4821 default:
4822 goto die;
4824 break;
4825 case 6:
4826 switch (sel) {
4827 case 0:
4828 gen_helper_mtc0_wired(cpu_env, arg);
4829 rn = "Wired";
4830 break;
4831 case 1:
4832 check_insn(ctx, ISA_MIPS32R2);
4833 gen_helper_mtc0_srsconf0(cpu_env, arg);
4834 rn = "SRSConf0";
4835 break;
4836 case 2:
4837 check_insn(ctx, ISA_MIPS32R2);
4838 gen_helper_mtc0_srsconf1(cpu_env, arg);
4839 rn = "SRSConf1";
4840 break;
4841 case 3:
4842 check_insn(ctx, ISA_MIPS32R2);
4843 gen_helper_mtc0_srsconf2(cpu_env, arg);
4844 rn = "SRSConf2";
4845 break;
4846 case 4:
4847 check_insn(ctx, ISA_MIPS32R2);
4848 gen_helper_mtc0_srsconf3(cpu_env, arg);
4849 rn = "SRSConf3";
4850 break;
4851 case 5:
4852 check_insn(ctx, ISA_MIPS32R2);
4853 gen_helper_mtc0_srsconf4(cpu_env, arg);
4854 rn = "SRSConf4";
4855 break;
4856 default:
4857 goto die;
4859 break;
4860 case 7:
4861 switch (sel) {
4862 case 0:
4863 check_insn(ctx, ISA_MIPS32R2);
4864 gen_helper_mtc0_hwrena(cpu_env, arg);
4865 rn = "HWREna";
4866 break;
4867 default:
4868 goto die;
4870 break;
4871 case 8:
4872 /* ignored */
4873 rn = "BadVAddr";
4874 break;
4875 case 9:
4876 switch (sel) {
4877 case 0:
4878 gen_helper_mtc0_count(cpu_env, arg);
4879 rn = "Count";
4880 break;
4881 /* 6,7 are implementation dependent */
4882 default:
4883 goto die;
4885 break;
4886 case 10:
4887 switch (sel) {
4888 case 0:
4889 gen_helper_mtc0_entryhi(cpu_env, arg);
4890 rn = "EntryHi";
4891 break;
4892 default:
4893 goto die;
4895 break;
4896 case 11:
4897 switch (sel) {
4898 case 0:
4899 gen_helper_mtc0_compare(cpu_env, arg);
4900 rn = "Compare";
4901 break;
4902 /* 6,7 are implementation dependent */
4903 default:
4904 goto die;
4906 break;
4907 case 12:
4908 switch (sel) {
4909 case 0:
4910 save_cpu_state(ctx, 1);
4911 gen_helper_mtc0_status(cpu_env, arg);
4912 /* BS_STOP isn't good enough here, hflags may have changed. */
4913 gen_save_pc(ctx->pc + 4);
4914 ctx->bstate = BS_EXCP;
4915 rn = "Status";
4916 break;
4917 case 1:
4918 check_insn(ctx, ISA_MIPS32R2);
4919 gen_helper_mtc0_intctl(cpu_env, arg);
4920 /* Stop translation as we may have switched the execution mode */
4921 ctx->bstate = BS_STOP;
4922 rn = "IntCtl";
4923 break;
4924 case 2:
4925 check_insn(ctx, ISA_MIPS32R2);
4926 gen_helper_mtc0_srsctl(cpu_env, arg);
4927 /* Stop translation as we may have switched the execution mode */
4928 ctx->bstate = BS_STOP;
4929 rn = "SRSCtl";
4930 break;
4931 case 3:
4932 check_insn(ctx, ISA_MIPS32R2);
4933 gen_mtc0_store32(arg, offsetof(CPUMIPSState, CP0_SRSMap));
4934 /* Stop translation as we may have switched the execution mode */
4935 ctx->bstate = BS_STOP;
4936 rn = "SRSMap";
4937 break;
4938 default:
4939 goto die;
4941 break;
4942 case 13:
4943 switch (sel) {
4944 case 0:
4945 save_cpu_state(ctx, 1);
4946 gen_helper_mtc0_cause(cpu_env, arg);
4947 rn = "Cause";
4948 break;
4949 default:
4950 goto die;
4952 break;
4953 case 14:
4954 switch (sel) {
4955 case 0:
4956 gen_mtc0_store64(arg, offsetof(CPUMIPSState, CP0_EPC));
4957 rn = "EPC";
4958 break;
4959 default:
4960 goto die;
4962 break;
4963 case 15:
4964 switch (sel) {
4965 case 0:
4966 /* ignored */
4967 rn = "PRid";
4968 break;
4969 case 1:
4970 check_insn(ctx, ISA_MIPS32R2);
4971 gen_helper_mtc0_ebase(cpu_env, arg);
4972 rn = "EBase";
4973 break;
4974 default:
4975 goto die;
4977 break;
4978 case 16:
4979 switch (sel) {
4980 case 0:
4981 gen_helper_mtc0_config0(cpu_env, arg);
4982 rn = "Config";
4983 /* Stop translation as we may have switched the execution mode */
4984 ctx->bstate = BS_STOP;
4985 break;
4986 case 1:
4987 /* ignored, read only */
4988 rn = "Config1";
4989 break;
4990 case 2:
4991 gen_helper_mtc0_config2(cpu_env, arg);
4992 rn = "Config2";
4993 /* Stop translation as we may have switched the execution mode */
4994 ctx->bstate = BS_STOP;
4995 break;
4996 case 3:
4997 /* ignored, read only */
4998 rn = "Config3";
4999 break;
5000 case 4:
5001 gen_helper_mtc0_config4(cpu_env, arg);
5002 rn = "Config4";
5003 ctx->bstate = BS_STOP;
5004 break;
5005 case 5:
5006 gen_helper_mtc0_config5(cpu_env, arg);
5007 rn = "Config5";
5008 /* Stop translation as we may have switched the execution mode */
5009 ctx->bstate = BS_STOP;
5010 break;
5011 /* 6,7 are implementation dependent */
5012 case 6:
5013 /* ignored */
5014 rn = "Config6";
5015 break;
5016 case 7:
5017 /* ignored */
5018 rn = "Config7";
5019 break;
5020 default:
5021 rn = "Invalid config selector";
5022 goto die;
5024 break;
5025 case 17:
5026 switch (sel) {
5027 case 0:
5028 gen_helper_mtc0_lladdr(cpu_env, arg);
5029 rn = "LLAddr";
5030 break;
5031 default:
5032 goto die;
5034 break;
5035 case 18:
5036 switch (sel) {
5037 case 0 ... 7:
5038 gen_helper_0e1i(mtc0_watchlo, arg, sel);
5039 rn = "WatchLo";
5040 break;
5041 default:
5042 goto die;
5044 break;
5045 case 19:
5046 switch (sel) {
5047 case 0 ... 7:
5048 gen_helper_0e1i(mtc0_watchhi, arg, sel);
5049 rn = "WatchHi";
5050 break;
5051 default:
5052 goto die;
5054 break;
5055 case 20:
5056 switch (sel) {
5057 case 0:
5058 #if defined(TARGET_MIPS64)
5059 check_insn(ctx, ISA_MIPS3);
5060 gen_helper_mtc0_xcontext(cpu_env, arg);
5061 rn = "XContext";
5062 break;
5063 #endif
5064 default:
5065 goto die;
5067 break;
5068 case 21:
5069 /* Officially reserved, but sel 0 is used for R1x000 framemask */
5070 switch (sel) {
5071 case 0:
5072 gen_helper_mtc0_framemask(cpu_env, arg);
5073 rn = "Framemask";
5074 break;
5075 default:
5076 goto die;
5078 break;
5079 case 22:
5080 /* ignored */
5081 rn = "Diagnostic"; /* implementation dependent */
5082 break;
5083 case 23:
5084 switch (sel) {
5085 case 0:
5086 gen_helper_mtc0_debug(cpu_env, arg); /* EJTAG support */
5087 /* BS_STOP isn't good enough here, hflags may have changed. */
5088 gen_save_pc(ctx->pc + 4);
5089 ctx->bstate = BS_EXCP;
5090 rn = "Debug";
5091 break;
5092 case 1:
5093 // gen_helper_mtc0_tracecontrol(cpu_env, arg); /* PDtrace support */
5094 rn = "TraceControl";
5095 /* Stop translation as we may have switched the execution mode */
5096 ctx->bstate = BS_STOP;
5097 // break;
5098 case 2:
5099 // gen_helper_mtc0_tracecontrol2(cpu_env, arg); /* PDtrace support */
5100 rn = "TraceControl2";
5101 /* Stop translation as we may have switched the execution mode */
5102 ctx->bstate = BS_STOP;
5103 // break;
5104 case 3:
5105 /* Stop translation as we may have switched the execution mode */
5106 ctx->bstate = BS_STOP;
5107 // gen_helper_mtc0_usertracedata(cpu_env, arg); /* PDtrace support */
5108 rn = "UserTraceData";
5109 /* Stop translation as we may have switched the execution mode */
5110 ctx->bstate = BS_STOP;
5111 // break;
5112 case 4:
5113 // gen_helper_mtc0_tracebpc(cpu_env, arg); /* PDtrace support */
5114 /* Stop translation as we may have switched the execution mode */
5115 ctx->bstate = BS_STOP;
5116 rn = "TraceBPC";
5117 // break;
5118 default:
5119 goto die;
5121 break;
5122 case 24:
5123 switch (sel) {
5124 case 0:
5125 /* EJTAG support */
5126 gen_mtc0_store64(arg, offsetof(CPUMIPSState, CP0_DEPC));
5127 rn = "DEPC";
5128 break;
5129 default:
5130 goto die;
5132 break;
5133 case 25:
5134 switch (sel) {
5135 case 0:
5136 gen_helper_mtc0_performance0(cpu_env, arg);
5137 rn = "Performance0";
5138 break;
5139 case 1:
5140 // gen_helper_mtc0_performance1(arg);
5141 rn = "Performance1";
5142 // break;
5143 case 2:
5144 // gen_helper_mtc0_performance2(arg);
5145 rn = "Performance2";
5146 // break;
5147 case 3:
5148 // gen_helper_mtc0_performance3(arg);
5149 rn = "Performance3";
5150 // break;
5151 case 4:
5152 // gen_helper_mtc0_performance4(arg);
5153 rn = "Performance4";
5154 // break;
5155 case 5:
5156 // gen_helper_mtc0_performance5(arg);
5157 rn = "Performance5";
5158 // break;
5159 case 6:
5160 // gen_helper_mtc0_performance6(arg);
5161 rn = "Performance6";
5162 // break;
5163 case 7:
5164 // gen_helper_mtc0_performance7(arg);
5165 rn = "Performance7";
5166 // break;
5167 default:
5168 goto die;
5170 break;
5171 case 26:
5172 /* ignored */
5173 rn = "ECC";
5174 break;
5175 case 27:
5176 switch (sel) {
5177 case 0 ... 3:
5178 /* ignored */
5179 rn = "CacheErr";
5180 break;
5181 default:
5182 goto die;
5184 break;
5185 case 28:
5186 switch (sel) {
5187 case 0:
5188 case 2:
5189 case 4:
5190 case 6:
5191 gen_helper_mtc0_taglo(cpu_env, arg);
5192 rn = "TagLo";
5193 break;
5194 case 1:
5195 case 3:
5196 case 5:
5197 case 7:
5198 gen_helper_mtc0_datalo(cpu_env, arg);
5199 rn = "DataLo";
5200 break;
5201 default:
5202 goto die;
5204 break;
5205 case 29:
5206 switch (sel) {
5207 case 0:
5208 case 2:
5209 case 4:
5210 case 6:
5211 gen_helper_mtc0_taghi(cpu_env, arg);
5212 rn = "TagHi";
5213 break;
5214 case 1:
5215 case 3:
5216 case 5:
5217 case 7:
5218 gen_helper_mtc0_datahi(cpu_env, arg);
5219 rn = "DataHi";
5220 break;
5221 default:
5222 rn = "invalid sel";
5223 goto die;
5225 break;
5226 case 30:
5227 switch (sel) {
5228 case 0:
5229 gen_mtc0_store64(arg, offsetof(CPUMIPSState, CP0_ErrorEPC));
5230 rn = "ErrorEPC";
5231 break;
5232 default:
5233 goto die;
5235 break;
5236 case 31:
5237 switch (sel) {
5238 case 0:
5239 /* EJTAG support */
5240 gen_mtc0_store32(arg, offsetof(CPUMIPSState, CP0_DESAVE));
5241 rn = "DESAVE";
5242 break;
5243 default:
5244 goto die;
5246 /* Stop translation as we may have switched the execution mode */
5247 ctx->bstate = BS_STOP;
5248 break;
5249 default:
5250 goto die;
5252 (void)rn; /* avoid a compiler warning */
5253 LOG_DISAS("mtc0 %s (reg %d sel %d)\n", rn, reg, sel);
5254 /* For simplicity assume that all writes can cause interrupts. */
5255 if (use_icount) {
5256 gen_io_end();
5257 ctx->bstate = BS_STOP;
5259 return;
5261 die:
5262 LOG_DISAS("mtc0 %s (reg %d sel %d)\n", rn, reg, sel);
5263 generate_exception(ctx, EXCP_RI);
5266 #if defined(TARGET_MIPS64)
5267 static void gen_dmfc0(DisasContext *ctx, TCGv arg, int reg, int sel)
5269 const char *rn = "invalid";
5271 if (sel != 0)
5272 check_insn(ctx, ISA_MIPS64);
5274 switch (reg) {
5275 case 0:
5276 switch (sel) {
5277 case 0:
5278 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Index));
5279 rn = "Index";
5280 break;
5281 case 1:
5282 check_insn(ctx, ASE_MT);
5283 gen_helper_mfc0_mvpcontrol(arg, cpu_env);
5284 rn = "MVPControl";
5285 break;
5286 case 2:
5287 check_insn(ctx, ASE_MT);
5288 gen_helper_mfc0_mvpconf0(arg, cpu_env);
5289 rn = "MVPConf0";
5290 break;
5291 case 3:
5292 check_insn(ctx, ASE_MT);
5293 gen_helper_mfc0_mvpconf1(arg, cpu_env);
5294 rn = "MVPConf1";
5295 break;
5296 default:
5297 goto die;
5299 break;
5300 case 1:
5301 switch (sel) {
5302 case 0:
5303 gen_helper_mfc0_random(arg, cpu_env);
5304 rn = "Random";
5305 break;
5306 case 1:
5307 check_insn(ctx, ASE_MT);
5308 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEControl));
5309 rn = "VPEControl";
5310 break;
5311 case 2:
5312 check_insn(ctx, ASE_MT);
5313 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEConf0));
5314 rn = "VPEConf0";
5315 break;
5316 case 3:
5317 check_insn(ctx, ASE_MT);
5318 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEConf1));
5319 rn = "VPEConf1";
5320 break;
5321 case 4:
5322 check_insn(ctx, ASE_MT);
5323 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_YQMask));
5324 rn = "YQMask";
5325 break;
5326 case 5:
5327 check_insn(ctx, ASE_MT);
5328 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_VPESchedule));
5329 rn = "VPESchedule";
5330 break;
5331 case 6:
5332 check_insn(ctx, ASE_MT);
5333 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_VPEScheFBack));
5334 rn = "VPEScheFBack";
5335 break;
5336 case 7:
5337 check_insn(ctx, ASE_MT);
5338 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEOpt));
5339 rn = "VPEOpt";
5340 break;
5341 default:
5342 goto die;
5344 break;
5345 case 2:
5346 switch (sel) {
5347 case 0:
5348 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EntryLo0));
5349 rn = "EntryLo0";
5350 break;
5351 case 1:
5352 check_insn(ctx, ASE_MT);
5353 gen_helper_mfc0_tcstatus(arg, cpu_env);
5354 rn = "TCStatus";
5355 break;
5356 case 2:
5357 check_insn(ctx, ASE_MT);
5358 gen_helper_mfc0_tcbind(arg, cpu_env);
5359 rn = "TCBind";
5360 break;
5361 case 3:
5362 check_insn(ctx, ASE_MT);
5363 gen_helper_dmfc0_tcrestart(arg, cpu_env);
5364 rn = "TCRestart";
5365 break;
5366 case 4:
5367 check_insn(ctx, ASE_MT);
5368 gen_helper_dmfc0_tchalt(arg, cpu_env);
5369 rn = "TCHalt";
5370 break;
5371 case 5:
5372 check_insn(ctx, ASE_MT);
5373 gen_helper_dmfc0_tccontext(arg, cpu_env);
5374 rn = "TCContext";
5375 break;
5376 case 6:
5377 check_insn(ctx, ASE_MT);
5378 gen_helper_dmfc0_tcschedule(arg, cpu_env);
5379 rn = "TCSchedule";
5380 break;
5381 case 7:
5382 check_insn(ctx, ASE_MT);
5383 gen_helper_dmfc0_tcschefback(arg, cpu_env);
5384 rn = "TCScheFBack";
5385 break;
5386 default:
5387 goto die;
5389 break;
5390 case 3:
5391 switch (sel) {
5392 case 0:
5393 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EntryLo1));
5394 rn = "EntryLo1";
5395 break;
5396 default:
5397 goto die;
5399 break;
5400 case 4:
5401 switch (sel) {
5402 case 0:
5403 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_Context));
5404 rn = "Context";
5405 break;
5406 case 1:
5407 // gen_helper_dmfc0_contextconfig(arg); /* SmartMIPS ASE */
5408 rn = "ContextConfig";
5409 // break;
5410 default:
5411 goto die;
5413 break;
5414 case 5:
5415 switch (sel) {
5416 case 0:
5417 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PageMask));
5418 rn = "PageMask";
5419 break;
5420 case 1:
5421 check_insn(ctx, ISA_MIPS32R2);
5422 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PageGrain));
5423 rn = "PageGrain";
5424 break;
5425 default:
5426 goto die;
5428 break;
5429 case 6:
5430 switch (sel) {
5431 case 0:
5432 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Wired));
5433 rn = "Wired";
5434 break;
5435 case 1:
5436 check_insn(ctx, ISA_MIPS32R2);
5437 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf0));
5438 rn = "SRSConf0";
5439 break;
5440 case 2:
5441 check_insn(ctx, ISA_MIPS32R2);
5442 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf1));
5443 rn = "SRSConf1";
5444 break;
5445 case 3:
5446 check_insn(ctx, ISA_MIPS32R2);
5447 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf2));
5448 rn = "SRSConf2";
5449 break;
5450 case 4:
5451 check_insn(ctx, ISA_MIPS32R2);
5452 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf3));
5453 rn = "SRSConf3";
5454 break;
5455 case 5:
5456 check_insn(ctx, ISA_MIPS32R2);
5457 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf4));
5458 rn = "SRSConf4";
5459 break;
5460 default:
5461 goto die;
5463 break;
5464 case 7:
5465 switch (sel) {
5466 case 0:
5467 check_insn(ctx, ISA_MIPS32R2);
5468 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_HWREna));
5469 rn = "HWREna";
5470 break;
5471 default:
5472 goto die;
5474 break;
5475 case 8:
5476 switch (sel) {
5477 case 0:
5478 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_BadVAddr));
5479 rn = "BadVAddr";
5480 break;
5481 default:
5482 goto die;
5484 break;
5485 case 9:
5486 switch (sel) {
5487 case 0:
5488 /* Mark as an IO operation because we read the time. */
5489 if (use_icount)
5490 gen_io_start();
5491 gen_helper_mfc0_count(arg, cpu_env);
5492 if (use_icount) {
5493 gen_io_end();
5495 /* Break the TB to be able to take timer interrupts immediately
5496 after reading count. */
5497 ctx->bstate = BS_STOP;
5498 rn = "Count";
5499 break;
5500 /* 6,7 are implementation dependent */
5501 default:
5502 goto die;
5504 break;
5505 case 10:
5506 switch (sel) {
5507 case 0:
5508 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EntryHi));
5509 rn = "EntryHi";
5510 break;
5511 default:
5512 goto die;
5514 break;
5515 case 11:
5516 switch (sel) {
5517 case 0:
5518 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Compare));
5519 rn = "Compare";
5520 break;
5521 /* 6,7 are implementation dependent */
5522 default:
5523 goto die;
5525 break;
5526 case 12:
5527 switch (sel) {
5528 case 0:
5529 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Status));
5530 rn = "Status";
5531 break;
5532 case 1:
5533 check_insn(ctx, ISA_MIPS32R2);
5534 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_IntCtl));
5535 rn = "IntCtl";
5536 break;
5537 case 2:
5538 check_insn(ctx, ISA_MIPS32R2);
5539 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSCtl));
5540 rn = "SRSCtl";
5541 break;
5542 case 3:
5543 check_insn(ctx, ISA_MIPS32R2);
5544 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSMap));
5545 rn = "SRSMap";
5546 break;
5547 default:
5548 goto die;
5550 break;
5551 case 13:
5552 switch (sel) {
5553 case 0:
5554 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Cause));
5555 rn = "Cause";
5556 break;
5557 default:
5558 goto die;
5560 break;
5561 case 14:
5562 switch (sel) {
5563 case 0:
5564 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EPC));
5565 rn = "EPC";
5566 break;
5567 default:
5568 goto die;
5570 break;
5571 case 15:
5572 switch (sel) {
5573 case 0:
5574 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PRid));
5575 rn = "PRid";
5576 break;
5577 case 1:
5578 check_insn(ctx, ISA_MIPS32R2);
5579 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_EBase));
5580 rn = "EBase";
5581 break;
5582 default:
5583 goto die;
5585 break;
5586 case 16:
5587 switch (sel) {
5588 case 0:
5589 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config0));
5590 rn = "Config";
5591 break;
5592 case 1:
5593 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config1));
5594 rn = "Config1";
5595 break;
5596 case 2:
5597 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config2));
5598 rn = "Config2";
5599 break;
5600 case 3:
5601 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config3));
5602 rn = "Config3";
5603 break;
5604 /* 6,7 are implementation dependent */
5605 case 6:
5606 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config6));
5607 rn = "Config6";
5608 break;
5609 case 7:
5610 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config7));
5611 rn = "Config7";
5612 break;
5613 default:
5614 goto die;
5616 break;
5617 case 17:
5618 switch (sel) {
5619 case 0:
5620 gen_helper_dmfc0_lladdr(arg, cpu_env);
5621 rn = "LLAddr";
5622 break;
5623 default:
5624 goto die;
5626 break;
5627 case 18:
5628 switch (sel) {
5629 case 0 ... 7:
5630 gen_helper_1e0i(dmfc0_watchlo, arg, sel);
5631 rn = "WatchLo";
5632 break;
5633 default:
5634 goto die;
5636 break;
5637 case 19:
5638 switch (sel) {
5639 case 0 ... 7:
5640 gen_helper_1e0i(mfc0_watchhi, arg, sel);
5641 rn = "WatchHi";
5642 break;
5643 default:
5644 goto die;
5646 break;
5647 case 20:
5648 switch (sel) {
5649 case 0:
5650 check_insn(ctx, ISA_MIPS3);
5651 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_XContext));
5652 rn = "XContext";
5653 break;
5654 default:
5655 goto die;
5657 break;
5658 case 21:
5659 /* Officially reserved, but sel 0 is used for R1x000 framemask */
5660 switch (sel) {
5661 case 0:
5662 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Framemask));
5663 rn = "Framemask";
5664 break;
5665 default:
5666 goto die;
5668 break;
5669 case 22:
5670 tcg_gen_movi_tl(arg, 0); /* unimplemented */
5671 rn = "'Diagnostic"; /* implementation dependent */
5672 break;
5673 case 23:
5674 switch (sel) {
5675 case 0:
5676 gen_helper_mfc0_debug(arg, cpu_env); /* EJTAG support */
5677 rn = "Debug";
5678 break;
5679 case 1:
5680 // gen_helper_dmfc0_tracecontrol(arg, cpu_env); /* PDtrace support */
5681 rn = "TraceControl";
5682 // break;
5683 case 2:
5684 // gen_helper_dmfc0_tracecontrol2(arg, cpu_env); /* PDtrace support */
5685 rn = "TraceControl2";
5686 // break;
5687 case 3:
5688 // gen_helper_dmfc0_usertracedata(arg, cpu_env); /* PDtrace support */
5689 rn = "UserTraceData";
5690 // break;
5691 case 4:
5692 // gen_helper_dmfc0_tracebpc(arg, cpu_env); /* PDtrace support */
5693 rn = "TraceBPC";
5694 // break;
5695 default:
5696 goto die;
5698 break;
5699 case 24:
5700 switch (sel) {
5701 case 0:
5702 /* EJTAG support */
5703 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_DEPC));
5704 rn = "DEPC";
5705 break;
5706 default:
5707 goto die;
5709 break;
5710 case 25:
5711 switch (sel) {
5712 case 0:
5713 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Performance0));
5714 rn = "Performance0";
5715 break;
5716 case 1:
5717 // gen_helper_dmfc0_performance1(arg);
5718 rn = "Performance1";
5719 // break;
5720 case 2:
5721 // gen_helper_dmfc0_performance2(arg);
5722 rn = "Performance2";
5723 // break;
5724 case 3:
5725 // gen_helper_dmfc0_performance3(arg);
5726 rn = "Performance3";
5727 // break;
5728 case 4:
5729 // gen_helper_dmfc0_performance4(arg);
5730 rn = "Performance4";
5731 // break;
5732 case 5:
5733 // gen_helper_dmfc0_performance5(arg);
5734 rn = "Performance5";
5735 // break;
5736 case 6:
5737 // gen_helper_dmfc0_performance6(arg);
5738 rn = "Performance6";
5739 // break;
5740 case 7:
5741 // gen_helper_dmfc0_performance7(arg);
5742 rn = "Performance7";
5743 // break;
5744 default:
5745 goto die;
5747 break;
5748 case 26:
5749 tcg_gen_movi_tl(arg, 0); /* unimplemented */
5750 rn = "ECC";
5751 break;
5752 case 27:
5753 switch (sel) {
5754 /* ignored */
5755 case 0 ... 3:
5756 tcg_gen_movi_tl(arg, 0); /* unimplemented */
5757 rn = "CacheErr";
5758 break;
5759 default:
5760 goto die;
5762 break;
5763 case 28:
5764 switch (sel) {
5765 case 0:
5766 case 2:
5767 case 4:
5768 case 6:
5769 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_TagLo));
5770 rn = "TagLo";
5771 break;
5772 case 1:
5773 case 3:
5774 case 5:
5775 case 7:
5776 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DataLo));
5777 rn = "DataLo";
5778 break;
5779 default:
5780 goto die;
5782 break;
5783 case 29:
5784 switch (sel) {
5785 case 0:
5786 case 2:
5787 case 4:
5788 case 6:
5789 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_TagHi));
5790 rn = "TagHi";
5791 break;
5792 case 1:
5793 case 3:
5794 case 5:
5795 case 7:
5796 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DataHi));
5797 rn = "DataHi";
5798 break;
5799 default:
5800 goto die;
5802 break;
5803 case 30:
5804 switch (sel) {
5805 case 0:
5806 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_ErrorEPC));
5807 rn = "ErrorEPC";
5808 break;
5809 default:
5810 goto die;
5812 break;
5813 case 31:
5814 switch (sel) {
5815 case 0:
5816 /* EJTAG support */
5817 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DESAVE));
5818 rn = "DESAVE";
5819 break;
5820 default:
5821 goto die;
5823 break;
5824 default:
5825 goto die;
5827 (void)rn; /* avoid a compiler warning */
5828 LOG_DISAS("dmfc0 %s (reg %d sel %d)\n", rn, reg, sel);
5829 return;
5831 die:
5832 LOG_DISAS("dmfc0 %s (reg %d sel %d)\n", rn, reg, sel);
5833 generate_exception(ctx, EXCP_RI);
5836 static void gen_dmtc0(DisasContext *ctx, TCGv arg, int reg, int sel)
5838 const char *rn = "invalid";
5840 if (sel != 0)
5841 check_insn(ctx, ISA_MIPS64);
5843 if (use_icount)
5844 gen_io_start();
5846 switch (reg) {
5847 case 0:
5848 switch (sel) {
5849 case 0:
5850 gen_helper_mtc0_index(cpu_env, arg);
5851 rn = "Index";
5852 break;
5853 case 1:
5854 check_insn(ctx, ASE_MT);
5855 gen_helper_mtc0_mvpcontrol(cpu_env, arg);
5856 rn = "MVPControl";
5857 break;
5858 case 2:
5859 check_insn(ctx, ASE_MT);
5860 /* ignored */
5861 rn = "MVPConf0";
5862 break;
5863 case 3:
5864 check_insn(ctx, ASE_MT);
5865 /* ignored */
5866 rn = "MVPConf1";
5867 break;
5868 default:
5869 goto die;
5871 break;
5872 case 1:
5873 switch (sel) {
5874 case 0:
5875 /* ignored */
5876 rn = "Random";
5877 break;
5878 case 1:
5879 check_insn(ctx, ASE_MT);
5880 gen_helper_mtc0_vpecontrol(cpu_env, arg);
5881 rn = "VPEControl";
5882 break;
5883 case 2:
5884 check_insn(ctx, ASE_MT);
5885 gen_helper_mtc0_vpeconf0(cpu_env, arg);
5886 rn = "VPEConf0";
5887 break;
5888 case 3:
5889 check_insn(ctx, ASE_MT);
5890 gen_helper_mtc0_vpeconf1(cpu_env, arg);
5891 rn = "VPEConf1";
5892 break;
5893 case 4:
5894 check_insn(ctx, ASE_MT);
5895 gen_helper_mtc0_yqmask(cpu_env, arg);
5896 rn = "YQMask";
5897 break;
5898 case 5:
5899 check_insn(ctx, ASE_MT);
5900 tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_VPESchedule));
5901 rn = "VPESchedule";
5902 break;
5903 case 6:
5904 check_insn(ctx, ASE_MT);
5905 tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_VPEScheFBack));
5906 rn = "VPEScheFBack";
5907 break;
5908 case 7:
5909 check_insn(ctx, ASE_MT);
5910 gen_helper_mtc0_vpeopt(cpu_env, arg);
5911 rn = "VPEOpt";
5912 break;
5913 default:
5914 goto die;
5916 break;
5917 case 2:
5918 switch (sel) {
5919 case 0:
5920 gen_helper_mtc0_entrylo0(cpu_env, arg);
5921 rn = "EntryLo0";
5922 break;
5923 case 1:
5924 check_insn(ctx, ASE_MT);
5925 gen_helper_mtc0_tcstatus(cpu_env, arg);
5926 rn = "TCStatus";
5927 break;
5928 case 2:
5929 check_insn(ctx, ASE_MT);
5930 gen_helper_mtc0_tcbind(cpu_env, arg);
5931 rn = "TCBind";
5932 break;
5933 case 3:
5934 check_insn(ctx, ASE_MT);
5935 gen_helper_mtc0_tcrestart(cpu_env, arg);
5936 rn = "TCRestart";
5937 break;
5938 case 4:
5939 check_insn(ctx, ASE_MT);
5940 gen_helper_mtc0_tchalt(cpu_env, arg);
5941 rn = "TCHalt";
5942 break;
5943 case 5:
5944 check_insn(ctx, ASE_MT);
5945 gen_helper_mtc0_tccontext(cpu_env, arg);
5946 rn = "TCContext";
5947 break;
5948 case 6:
5949 check_insn(ctx, ASE_MT);
5950 gen_helper_mtc0_tcschedule(cpu_env, arg);
5951 rn = "TCSchedule";
5952 break;
5953 case 7:
5954 check_insn(ctx, ASE_MT);
5955 gen_helper_mtc0_tcschefback(cpu_env, arg);
5956 rn = "TCScheFBack";
5957 break;
5958 default:
5959 goto die;
5961 break;
5962 case 3:
5963 switch (sel) {
5964 case 0:
5965 gen_helper_mtc0_entrylo1(cpu_env, arg);
5966 rn = "EntryLo1";
5967 break;
5968 default:
5969 goto die;
5971 break;
5972 case 4:
5973 switch (sel) {
5974 case 0:
5975 gen_helper_mtc0_context(cpu_env, arg);
5976 rn = "Context";
5977 break;
5978 case 1:
5979 // gen_helper_mtc0_contextconfig(cpu_env, arg); /* SmartMIPS ASE */
5980 rn = "ContextConfig";
5981 // break;
5982 default:
5983 goto die;
5985 break;
5986 case 5:
5987 switch (sel) {
5988 case 0:
5989 gen_helper_mtc0_pagemask(cpu_env, arg);
5990 rn = "PageMask";
5991 break;
5992 case 1:
5993 check_insn(ctx, ISA_MIPS32R2);
5994 gen_helper_mtc0_pagegrain(cpu_env, arg);
5995 rn = "PageGrain";
5996 break;
5997 default:
5998 goto die;
6000 break;
6001 case 6:
6002 switch (sel) {
6003 case 0:
6004 gen_helper_mtc0_wired(cpu_env, arg);
6005 rn = "Wired";
6006 break;
6007 case 1:
6008 check_insn(ctx, ISA_MIPS32R2);
6009 gen_helper_mtc0_srsconf0(cpu_env, arg);
6010 rn = "SRSConf0";
6011 break;
6012 case 2:
6013 check_insn(ctx, ISA_MIPS32R2);
6014 gen_helper_mtc0_srsconf1(cpu_env, arg);
6015 rn = "SRSConf1";
6016 break;
6017 case 3:
6018 check_insn(ctx, ISA_MIPS32R2);
6019 gen_helper_mtc0_srsconf2(cpu_env, arg);
6020 rn = "SRSConf2";
6021 break;
6022 case 4:
6023 check_insn(ctx, ISA_MIPS32R2);
6024 gen_helper_mtc0_srsconf3(cpu_env, arg);
6025 rn = "SRSConf3";
6026 break;
6027 case 5:
6028 check_insn(ctx, ISA_MIPS32R2);
6029 gen_helper_mtc0_srsconf4(cpu_env, arg);
6030 rn = "SRSConf4";
6031 break;
6032 default:
6033 goto die;
6035 break;
6036 case 7:
6037 switch (sel) {
6038 case 0:
6039 check_insn(ctx, ISA_MIPS32R2);
6040 gen_helper_mtc0_hwrena(cpu_env, arg);
6041 rn = "HWREna";
6042 break;
6043 default:
6044 goto die;
6046 break;
6047 case 8:
6048 /* ignored */
6049 rn = "BadVAddr";
6050 break;
6051 case 9:
6052 switch (sel) {
6053 case 0:
6054 gen_helper_mtc0_count(cpu_env, arg);
6055 rn = "Count";
6056 break;
6057 /* 6,7 are implementation dependent */
6058 default:
6059 goto die;
6061 /* Stop translation as we may have switched the execution mode */
6062 ctx->bstate = BS_STOP;
6063 break;
6064 case 10:
6065 switch (sel) {
6066 case 0:
6067 gen_helper_mtc0_entryhi(cpu_env, arg);
6068 rn = "EntryHi";
6069 break;
6070 default:
6071 goto die;
6073 break;
6074 case 11:
6075 switch (sel) {
6076 case 0:
6077 gen_helper_mtc0_compare(cpu_env, arg);
6078 rn = "Compare";
6079 break;
6080 /* 6,7 are implementation dependent */
6081 default:
6082 goto die;
6084 /* Stop translation as we may have switched the execution mode */
6085 ctx->bstate = BS_STOP;
6086 break;
6087 case 12:
6088 switch (sel) {
6089 case 0:
6090 save_cpu_state(ctx, 1);
6091 gen_helper_mtc0_status(cpu_env, arg);
6092 /* BS_STOP isn't good enough here, hflags may have changed. */
6093 gen_save_pc(ctx->pc + 4);
6094 ctx->bstate = BS_EXCP;
6095 rn = "Status";
6096 break;
6097 case 1:
6098 check_insn(ctx, ISA_MIPS32R2);
6099 gen_helper_mtc0_intctl(cpu_env, arg);
6100 /* Stop translation as we may have switched the execution mode */
6101 ctx->bstate = BS_STOP;
6102 rn = "IntCtl";
6103 break;
6104 case 2:
6105 check_insn(ctx, ISA_MIPS32R2);
6106 gen_helper_mtc0_srsctl(cpu_env, arg);
6107 /* Stop translation as we may have switched the execution mode */
6108 ctx->bstate = BS_STOP;
6109 rn = "SRSCtl";
6110 break;
6111 case 3:
6112 check_insn(ctx, ISA_MIPS32R2);
6113 gen_mtc0_store32(arg, offsetof(CPUMIPSState, CP0_SRSMap));
6114 /* Stop translation as we may have switched the execution mode */
6115 ctx->bstate = BS_STOP;
6116 rn = "SRSMap";
6117 break;
6118 default:
6119 goto die;
6121 break;
6122 case 13:
6123 switch (sel) {
6124 case 0:
6125 save_cpu_state(ctx, 1);
6126 /* Mark as an IO operation because we may trigger a software
6127 interrupt. */
6128 if (use_icount) {
6129 gen_io_start();
6131 gen_helper_mtc0_cause(cpu_env, arg);
6132 if (use_icount) {
6133 gen_io_end();
6135 /* Stop translation as we may have triggered an intetrupt */
6136 ctx->bstate = BS_STOP;
6137 rn = "Cause";
6138 break;
6139 default:
6140 goto die;
6142 break;
6143 case 14:
6144 switch (sel) {
6145 case 0:
6146 tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EPC));
6147 rn = "EPC";
6148 break;
6149 default:
6150 goto die;
6152 break;
6153 case 15:
6154 switch (sel) {
6155 case 0:
6156 /* ignored */
6157 rn = "PRid";
6158 break;
6159 case 1:
6160 check_insn(ctx, ISA_MIPS32R2);
6161 gen_helper_mtc0_ebase(cpu_env, arg);
6162 rn = "EBase";
6163 break;
6164 default:
6165 goto die;
6167 break;
6168 case 16:
6169 switch (sel) {
6170 case 0:
6171 gen_helper_mtc0_config0(cpu_env, arg);
6172 rn = "Config";
6173 /* Stop translation as we may have switched the execution mode */
6174 ctx->bstate = BS_STOP;
6175 break;
6176 case 1:
6177 /* ignored, read only */
6178 rn = "Config1";
6179 break;
6180 case 2:
6181 gen_helper_mtc0_config2(cpu_env, arg);
6182 rn = "Config2";
6183 /* Stop translation as we may have switched the execution mode */
6184 ctx->bstate = BS_STOP;
6185 break;
6186 case 3:
6187 /* ignored */
6188 rn = "Config3";
6189 break;
6190 /* 6,7 are implementation dependent */
6191 default:
6192 rn = "Invalid config selector";
6193 goto die;
6195 break;
6196 case 17:
6197 switch (sel) {
6198 case 0:
6199 gen_helper_mtc0_lladdr(cpu_env, arg);
6200 rn = "LLAddr";
6201 break;
6202 default:
6203 goto die;
6205 break;
6206 case 18:
6207 switch (sel) {
6208 case 0 ... 7:
6209 gen_helper_0e1i(mtc0_watchlo, arg, sel);
6210 rn = "WatchLo";
6211 break;
6212 default:
6213 goto die;
6215 break;
6216 case 19:
6217 switch (sel) {
6218 case 0 ... 7:
6219 gen_helper_0e1i(mtc0_watchhi, arg, sel);
6220 rn = "WatchHi";
6221 break;
6222 default:
6223 goto die;
6225 break;
6226 case 20:
6227 switch (sel) {
6228 case 0:
6229 check_insn(ctx, ISA_MIPS3);
6230 gen_helper_mtc0_xcontext(cpu_env, arg);
6231 rn = "XContext";
6232 break;
6233 default:
6234 goto die;
6236 break;
6237 case 21:
6238 /* Officially reserved, but sel 0 is used for R1x000 framemask */
6239 switch (sel) {
6240 case 0:
6241 gen_helper_mtc0_framemask(cpu_env, arg);
6242 rn = "Framemask";
6243 break;
6244 default:
6245 goto die;
6247 break;
6248 case 22:
6249 /* ignored */
6250 rn = "Diagnostic"; /* implementation dependent */
6251 break;
6252 case 23:
6253 switch (sel) {
6254 case 0:
6255 gen_helper_mtc0_debug(cpu_env, arg); /* EJTAG support */
6256 /* BS_STOP isn't good enough here, hflags may have changed. */
6257 gen_save_pc(ctx->pc + 4);
6258 ctx->bstate = BS_EXCP;
6259 rn = "Debug";
6260 break;
6261 case 1:
6262 // gen_helper_mtc0_tracecontrol(cpu_env, arg); /* PDtrace support */
6263 /* Stop translation as we may have switched the execution mode */
6264 ctx->bstate = BS_STOP;
6265 rn = "TraceControl";
6266 // break;
6267 case 2:
6268 // gen_helper_mtc0_tracecontrol2(cpu_env, arg); /* PDtrace support */
6269 /* Stop translation as we may have switched the execution mode */
6270 ctx->bstate = BS_STOP;
6271 rn = "TraceControl2";
6272 // break;
6273 case 3:
6274 // gen_helper_mtc0_usertracedata(cpu_env, arg); /* PDtrace support */
6275 /* Stop translation as we may have switched the execution mode */
6276 ctx->bstate = BS_STOP;
6277 rn = "UserTraceData";
6278 // break;
6279 case 4:
6280 // gen_helper_mtc0_tracebpc(cpu_env, arg); /* PDtrace support */
6281 /* Stop translation as we may have switched the execution mode */
6282 ctx->bstate = BS_STOP;
6283 rn = "TraceBPC";
6284 // break;
6285 default:
6286 goto die;
6288 break;
6289 case 24:
6290 switch (sel) {
6291 case 0:
6292 /* EJTAG support */
6293 tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_DEPC));
6294 rn = "DEPC";
6295 break;
6296 default:
6297 goto die;
6299 break;
6300 case 25:
6301 switch (sel) {
6302 case 0:
6303 gen_helper_mtc0_performance0(cpu_env, arg);
6304 rn = "Performance0";
6305 break;
6306 case 1:
6307 // gen_helper_mtc0_performance1(cpu_env, arg);
6308 rn = "Performance1";
6309 // break;
6310 case 2:
6311 // gen_helper_mtc0_performance2(cpu_env, arg);
6312 rn = "Performance2";
6313 // break;
6314 case 3:
6315 // gen_helper_mtc0_performance3(cpu_env, arg);
6316 rn = "Performance3";
6317 // break;
6318 case 4:
6319 // gen_helper_mtc0_performance4(cpu_env, arg);
6320 rn = "Performance4";
6321 // break;
6322 case 5:
6323 // gen_helper_mtc0_performance5(cpu_env, arg);
6324 rn = "Performance5";
6325 // break;
6326 case 6:
6327 // gen_helper_mtc0_performance6(cpu_env, arg);
6328 rn = "Performance6";
6329 // break;
6330 case 7:
6331 // gen_helper_mtc0_performance7(cpu_env, arg);
6332 rn = "Performance7";
6333 // break;
6334 default:
6335 goto die;
6337 break;
6338 case 26:
6339 /* ignored */
6340 rn = "ECC";
6341 break;
6342 case 27:
6343 switch (sel) {
6344 case 0 ... 3:
6345 /* ignored */
6346 rn = "CacheErr";
6347 break;
6348 default:
6349 goto die;
6351 break;
6352 case 28:
6353 switch (sel) {
6354 case 0:
6355 case 2:
6356 case 4:
6357 case 6:
6358 gen_helper_mtc0_taglo(cpu_env, arg);
6359 rn = "TagLo";
6360 break;
6361 case 1:
6362 case 3:
6363 case 5:
6364 case 7:
6365 gen_helper_mtc0_datalo(cpu_env, arg);
6366 rn = "DataLo";
6367 break;
6368 default:
6369 goto die;
6371 break;
6372 case 29:
6373 switch (sel) {
6374 case 0:
6375 case 2:
6376 case 4:
6377 case 6:
6378 gen_helper_mtc0_taghi(cpu_env, arg);
6379 rn = "TagHi";
6380 break;
6381 case 1:
6382 case 3:
6383 case 5:
6384 case 7:
6385 gen_helper_mtc0_datahi(cpu_env, arg);
6386 rn = "DataHi";
6387 break;
6388 default:
6389 rn = "invalid sel";
6390 goto die;
6392 break;
6393 case 30:
6394 switch (sel) {
6395 case 0:
6396 tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_ErrorEPC));
6397 rn = "ErrorEPC";
6398 break;
6399 default:
6400 goto die;
6402 break;
6403 case 31:
6404 switch (sel) {
6405 case 0:
6406 /* EJTAG support */
6407 gen_mtc0_store32(arg, offsetof(CPUMIPSState, CP0_DESAVE));
6408 rn = "DESAVE";
6409 break;
6410 default:
6411 goto die;
6413 /* Stop translation as we may have switched the execution mode */
6414 ctx->bstate = BS_STOP;
6415 break;
6416 default:
6417 goto die;
6419 (void)rn; /* avoid a compiler warning */
6420 LOG_DISAS("dmtc0 %s (reg %d sel %d)\n", rn, reg, sel);
6421 /* For simplicity assume that all writes can cause interrupts. */
6422 if (use_icount) {
6423 gen_io_end();
6424 ctx->bstate = BS_STOP;
6426 return;
6428 die:
6429 LOG_DISAS("dmtc0 %s (reg %d sel %d)\n", rn, reg, sel);
6430 generate_exception(ctx, EXCP_RI);
6432 #endif /* TARGET_MIPS64 */
6434 static void gen_mftr(CPUMIPSState *env, DisasContext *ctx, int rt, int rd,
6435 int u, int sel, int h)
6437 int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
6438 TCGv t0 = tcg_temp_local_new();
6440 if ((env->CP0_VPEConf0 & (1 << CP0VPEC0_MVP)) == 0 &&
6441 ((env->tcs[other_tc].CP0_TCBind & (0xf << CP0TCBd_CurVPE)) !=
6442 (env->active_tc.CP0_TCBind & (0xf << CP0TCBd_CurVPE))))
6443 tcg_gen_movi_tl(t0, -1);
6444 else if ((env->CP0_VPEControl & (0xff << CP0VPECo_TargTC)) >
6445 (env->mvp->CP0_MVPConf0 & (0xff << CP0MVPC0_PTC)))
6446 tcg_gen_movi_tl(t0, -1);
6447 else if (u == 0) {
6448 switch (rt) {
6449 case 1:
6450 switch (sel) {
6451 case 1:
6452 gen_helper_mftc0_vpecontrol(t0, cpu_env);
6453 break;
6454 case 2:
6455 gen_helper_mftc0_vpeconf0(t0, cpu_env);
6456 break;
6457 default:
6458 goto die;
6459 break;
6461 break;
6462 case 2:
6463 switch (sel) {
6464 case 1:
6465 gen_helper_mftc0_tcstatus(t0, cpu_env);
6466 break;
6467 case 2:
6468 gen_helper_mftc0_tcbind(t0, cpu_env);
6469 break;
6470 case 3:
6471 gen_helper_mftc0_tcrestart(t0, cpu_env);
6472 break;
6473 case 4:
6474 gen_helper_mftc0_tchalt(t0, cpu_env);
6475 break;
6476 case 5:
6477 gen_helper_mftc0_tccontext(t0, cpu_env);
6478 break;
6479 case 6:
6480 gen_helper_mftc0_tcschedule(t0, cpu_env);
6481 break;
6482 case 7:
6483 gen_helper_mftc0_tcschefback(t0, cpu_env);
6484 break;
6485 default:
6486 gen_mfc0(ctx, t0, rt, sel);
6487 break;
6489 break;
6490 case 10:
6491 switch (sel) {
6492 case 0:
6493 gen_helper_mftc0_entryhi(t0, cpu_env);
6494 break;
6495 default:
6496 gen_mfc0(ctx, t0, rt, sel);
6497 break;
6499 case 12:
6500 switch (sel) {
6501 case 0:
6502 gen_helper_mftc0_status(t0, cpu_env);
6503 break;
6504 default:
6505 gen_mfc0(ctx, t0, rt, sel);
6506 break;
6508 case 13:
6509 switch (sel) {
6510 case 0:
6511 gen_helper_mftc0_cause(t0, cpu_env);
6512 break;
6513 default:
6514 goto die;
6515 break;
6517 break;
6518 case 14:
6519 switch (sel) {
6520 case 0:
6521 gen_helper_mftc0_epc(t0, cpu_env);
6522 break;
6523 default:
6524 goto die;
6525 break;
6527 break;
6528 case 15:
6529 switch (sel) {
6530 case 1:
6531 gen_helper_mftc0_ebase(t0, cpu_env);
6532 break;
6533 default:
6534 goto die;
6535 break;
6537 break;
6538 case 16:
6539 switch (sel) {
6540 case 0 ... 7:
6541 gen_helper_mftc0_configx(t0, cpu_env, tcg_const_tl(sel));
6542 break;
6543 default:
6544 goto die;
6545 break;
6547 break;
6548 case 23:
6549 switch (sel) {
6550 case 0:
6551 gen_helper_mftc0_debug(t0, cpu_env);
6552 break;
6553 default:
6554 gen_mfc0(ctx, t0, rt, sel);
6555 break;
6557 break;
6558 default:
6559 gen_mfc0(ctx, t0, rt, sel);
6561 } else switch (sel) {
6562 /* GPR registers. */
6563 case 0:
6564 gen_helper_1e0i(mftgpr, t0, rt);
6565 break;
6566 /* Auxiliary CPU registers */
6567 case 1:
6568 switch (rt) {
6569 case 0:
6570 gen_helper_1e0i(mftlo, t0, 0);
6571 break;
6572 case 1:
6573 gen_helper_1e0i(mfthi, t0, 0);
6574 break;
6575 case 2:
6576 gen_helper_1e0i(mftacx, t0, 0);
6577 break;
6578 case 4:
6579 gen_helper_1e0i(mftlo, t0, 1);
6580 break;
6581 case 5:
6582 gen_helper_1e0i(mfthi, t0, 1);
6583 break;
6584 case 6:
6585 gen_helper_1e0i(mftacx, t0, 1);
6586 break;
6587 case 8:
6588 gen_helper_1e0i(mftlo, t0, 2);
6589 break;
6590 case 9:
6591 gen_helper_1e0i(mfthi, t0, 2);
6592 break;
6593 case 10:
6594 gen_helper_1e0i(mftacx, t0, 2);
6595 break;
6596 case 12:
6597 gen_helper_1e0i(mftlo, t0, 3);
6598 break;
6599 case 13:
6600 gen_helper_1e0i(mfthi, t0, 3);
6601 break;
6602 case 14:
6603 gen_helper_1e0i(mftacx, t0, 3);
6604 break;
6605 case 16:
6606 gen_helper_mftdsp(t0, cpu_env);
6607 break;
6608 default:
6609 goto die;
6611 break;
6612 /* Floating point (COP1). */
6613 case 2:
6614 /* XXX: For now we support only a single FPU context. */
6615 if (h == 0) {
6616 TCGv_i32 fp0 = tcg_temp_new_i32();
6618 gen_load_fpr32(fp0, rt);
6619 tcg_gen_ext_i32_tl(t0, fp0);
6620 tcg_temp_free_i32(fp0);
6621 } else {
6622 TCGv_i32 fp0 = tcg_temp_new_i32();
6624 gen_load_fpr32h(ctx, fp0, rt);
6625 tcg_gen_ext_i32_tl(t0, fp0);
6626 tcg_temp_free_i32(fp0);
6628 break;
6629 case 3:
6630 /* XXX: For now we support only a single FPU context. */
6631 gen_helper_1e0i(cfc1, t0, rt);
6632 break;
6633 /* COP2: Not implemented. */
6634 case 4:
6635 case 5:
6636 /* fall through */
6637 default:
6638 goto die;
6640 LOG_DISAS("mftr (reg %d u %d sel %d h %d)\n", rt, u, sel, h);
6641 gen_store_gpr(t0, rd);
6642 tcg_temp_free(t0);
6643 return;
6645 die:
6646 tcg_temp_free(t0);
6647 LOG_DISAS("mftr (reg %d u %d sel %d h %d)\n", rt, u, sel, h);
6648 generate_exception(ctx, EXCP_RI);
6651 static void gen_mttr(CPUMIPSState *env, DisasContext *ctx, int rd, int rt,
6652 int u, int sel, int h)
6654 int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
6655 TCGv t0 = tcg_temp_local_new();
6657 gen_load_gpr(t0, rt);
6658 if ((env->CP0_VPEConf0 & (1 << CP0VPEC0_MVP)) == 0 &&
6659 ((env->tcs[other_tc].CP0_TCBind & (0xf << CP0TCBd_CurVPE)) !=
6660 (env->active_tc.CP0_TCBind & (0xf << CP0TCBd_CurVPE))))
6661 /* NOP */ ;
6662 else if ((env->CP0_VPEControl & (0xff << CP0VPECo_TargTC)) >
6663 (env->mvp->CP0_MVPConf0 & (0xff << CP0MVPC0_PTC)))
6664 /* NOP */ ;
6665 else if (u == 0) {
6666 switch (rd) {
6667 case 1:
6668 switch (sel) {
6669 case 1:
6670 gen_helper_mttc0_vpecontrol(cpu_env, t0);
6671 break;
6672 case 2:
6673 gen_helper_mttc0_vpeconf0(cpu_env, t0);
6674 break;
6675 default:
6676 goto die;
6677 break;
6679 break;
6680 case 2:
6681 switch (sel) {
6682 case 1:
6683 gen_helper_mttc0_tcstatus(cpu_env, t0);
6684 break;
6685 case 2:
6686 gen_helper_mttc0_tcbind(cpu_env, t0);
6687 break;
6688 case 3:
6689 gen_helper_mttc0_tcrestart(cpu_env, t0);
6690 break;
6691 case 4:
6692 gen_helper_mttc0_tchalt(cpu_env, t0);
6693 break;
6694 case 5:
6695 gen_helper_mttc0_tccontext(cpu_env, t0);
6696 break;
6697 case 6:
6698 gen_helper_mttc0_tcschedule(cpu_env, t0);
6699 break;
6700 case 7:
6701 gen_helper_mttc0_tcschefback(cpu_env, t0);
6702 break;
6703 default:
6704 gen_mtc0(ctx, t0, rd, sel);
6705 break;
6707 break;
6708 case 10:
6709 switch (sel) {
6710 case 0:
6711 gen_helper_mttc0_entryhi(cpu_env, t0);
6712 break;
6713 default:
6714 gen_mtc0(ctx, t0, rd, sel);
6715 break;
6717 case 12:
6718 switch (sel) {
6719 case 0:
6720 gen_helper_mttc0_status(cpu_env, t0);
6721 break;
6722 default:
6723 gen_mtc0(ctx, t0, rd, sel);
6724 break;
6726 case 13:
6727 switch (sel) {
6728 case 0:
6729 gen_helper_mttc0_cause(cpu_env, t0);
6730 break;
6731 default:
6732 goto die;
6733 break;
6735 break;
6736 case 15:
6737 switch (sel) {
6738 case 1:
6739 gen_helper_mttc0_ebase(cpu_env, t0);
6740 break;
6741 default:
6742 goto die;
6743 break;
6745 break;
6746 case 23:
6747 switch (sel) {
6748 case 0:
6749 gen_helper_mttc0_debug(cpu_env, t0);
6750 break;
6751 default:
6752 gen_mtc0(ctx, t0, rd, sel);
6753 break;
6755 break;
6756 default:
6757 gen_mtc0(ctx, t0, rd, sel);
6759 } else switch (sel) {
6760 /* GPR registers. */
6761 case 0:
6762 gen_helper_0e1i(mttgpr, t0, rd);
6763 break;
6764 /* Auxiliary CPU registers */
6765 case 1:
6766 switch (rd) {
6767 case 0:
6768 gen_helper_0e1i(mttlo, t0, 0);
6769 break;
6770 case 1:
6771 gen_helper_0e1i(mtthi, t0, 0);
6772 break;
6773 case 2:
6774 gen_helper_0e1i(mttacx, t0, 0);
6775 break;
6776 case 4:
6777 gen_helper_0e1i(mttlo, t0, 1);
6778 break;
6779 case 5:
6780 gen_helper_0e1i(mtthi, t0, 1);
6781 break;
6782 case 6:
6783 gen_helper_0e1i(mttacx, t0, 1);
6784 break;
6785 case 8:
6786 gen_helper_0e1i(mttlo, t0, 2);
6787 break;
6788 case 9:
6789 gen_helper_0e1i(mtthi, t0, 2);
6790 break;
6791 case 10:
6792 gen_helper_0e1i(mttacx, t0, 2);
6793 break;
6794 case 12:
6795 gen_helper_0e1i(mttlo, t0, 3);
6796 break;
6797 case 13:
6798 gen_helper_0e1i(mtthi, t0, 3);
6799 break;
6800 case 14:
6801 gen_helper_0e1i(mttacx, t0, 3);
6802 break;
6803 case 16:
6804 gen_helper_mttdsp(cpu_env, t0);
6805 break;
6806 default:
6807 goto die;
6809 break;
6810 /* Floating point (COP1). */
6811 case 2:
6812 /* XXX: For now we support only a single FPU context. */
6813 if (h == 0) {
6814 TCGv_i32 fp0 = tcg_temp_new_i32();
6816 tcg_gen_trunc_tl_i32(fp0, t0);
6817 gen_store_fpr32(fp0, rd);
6818 tcg_temp_free_i32(fp0);
6819 } else {
6820 TCGv_i32 fp0 = tcg_temp_new_i32();
6822 tcg_gen_trunc_tl_i32(fp0, t0);
6823 gen_store_fpr32h(ctx, fp0, rd);
6824 tcg_temp_free_i32(fp0);
6826 break;
6827 case 3:
6828 /* XXX: For now we support only a single FPU context. */
6830 TCGv_i32 fs_tmp = tcg_const_i32(rd);
6832 gen_helper_0e2i(ctc1, t0, fs_tmp, rt);
6833 tcg_temp_free_i32(fs_tmp);
6835 break;
6836 /* COP2: Not implemented. */
6837 case 4:
6838 case 5:
6839 /* fall through */
6840 default:
6841 goto die;
6843 LOG_DISAS("mttr (reg %d u %d sel %d h %d)\n", rd, u, sel, h);
6844 tcg_temp_free(t0);
6845 return;
6847 die:
6848 tcg_temp_free(t0);
6849 LOG_DISAS("mttr (reg %d u %d sel %d h %d)\n", rd, u, sel, h);
6850 generate_exception(ctx, EXCP_RI);
6853 static void gen_cp0 (CPUMIPSState *env, DisasContext *ctx, uint32_t opc, int rt, int rd)
6855 const char *opn = "ldst";
6857 check_cp0_enabled(ctx);
6858 switch (opc) {
6859 case OPC_MFC0:
6860 if (rt == 0) {
6861 /* Treat as NOP. */
6862 return;
6864 gen_mfc0(ctx, cpu_gpr[rt], rd, ctx->opcode & 0x7);
6865 opn = "mfc0";
6866 break;
6867 case OPC_MTC0:
6869 TCGv t0 = tcg_temp_new();
6871 gen_load_gpr(t0, rt);
6872 gen_mtc0(ctx, t0, rd, ctx->opcode & 0x7);
6873 tcg_temp_free(t0);
6875 opn = "mtc0";
6876 break;
6877 #if defined(TARGET_MIPS64)
6878 case OPC_DMFC0:
6879 check_insn(ctx, ISA_MIPS3);
6880 if (rt == 0) {
6881 /* Treat as NOP. */
6882 return;
6884 gen_dmfc0(ctx, cpu_gpr[rt], rd, ctx->opcode & 0x7);
6885 opn = "dmfc0";
6886 break;
6887 case OPC_DMTC0:
6888 check_insn(ctx, ISA_MIPS3);
6890 TCGv t0 = tcg_temp_new();
6892 gen_load_gpr(t0, rt);
6893 gen_dmtc0(ctx, t0, rd, ctx->opcode & 0x7);
6894 tcg_temp_free(t0);
6896 opn = "dmtc0";
6897 break;
6898 #endif
6899 case OPC_MFTR:
6900 check_insn(ctx, ASE_MT);
6901 if (rd == 0) {
6902 /* Treat as NOP. */
6903 return;
6905 gen_mftr(env, ctx, rt, rd, (ctx->opcode >> 5) & 1,
6906 ctx->opcode & 0x7, (ctx->opcode >> 4) & 1);
6907 opn = "mftr";
6908 break;
6909 case OPC_MTTR:
6910 check_insn(ctx, ASE_MT);
6911 gen_mttr(env, ctx, rd, rt, (ctx->opcode >> 5) & 1,
6912 ctx->opcode & 0x7, (ctx->opcode >> 4) & 1);
6913 opn = "mttr";
6914 break;
6915 case OPC_TLBWI:
6916 opn = "tlbwi";
6917 if (!env->tlb->helper_tlbwi)
6918 goto die;
6919 gen_helper_tlbwi(cpu_env);
6920 break;
6921 case OPC_TLBWR:
6922 opn = "tlbwr";
6923 if (!env->tlb->helper_tlbwr)
6924 goto die;
6925 gen_helper_tlbwr(cpu_env);
6926 break;
6927 case OPC_TLBP:
6928 opn = "tlbp";
6929 if (!env->tlb->helper_tlbp)
6930 goto die;
6931 gen_helper_tlbp(cpu_env);
6932 break;
6933 case OPC_TLBR:
6934 opn = "tlbr";
6935 if (!env->tlb->helper_tlbr)
6936 goto die;
6937 gen_helper_tlbr(cpu_env);
6938 break;
6939 case OPC_ERET:
6940 opn = "eret";
6941 check_insn(ctx, ISA_MIPS2);
6942 gen_helper_eret(cpu_env);
6943 ctx->bstate = BS_EXCP;
6944 break;
6945 case OPC_DERET:
6946 opn = "deret";
6947 check_insn(ctx, ISA_MIPS32);
6948 if (!(ctx->hflags & MIPS_HFLAG_DM)) {
6949 MIPS_INVAL(opn);
6950 generate_exception(ctx, EXCP_RI);
6951 } else {
6952 gen_helper_deret(cpu_env);
6953 ctx->bstate = BS_EXCP;
6955 break;
6956 case OPC_WAIT:
6957 opn = "wait";
6958 check_insn(ctx, ISA_MIPS3 | ISA_MIPS32);
6959 /* If we get an exception, we want to restart at next instruction */
6960 ctx->pc += 4;
6961 save_cpu_state(ctx, 1);
6962 ctx->pc -= 4;
6963 gen_helper_wait(cpu_env);
6964 ctx->bstate = BS_EXCP;
6965 break;
6966 default:
6967 die:
6968 MIPS_INVAL(opn);
6969 generate_exception(ctx, EXCP_RI);
6970 return;
6972 (void)opn; /* avoid a compiler warning */
6973 MIPS_DEBUG("%s %s %d", opn, regnames[rt], rd);
6975 #endif /* !CONFIG_USER_ONLY */
6977 /* CP1 Branches (before delay slot) */
6978 static void gen_compute_branch1(DisasContext *ctx, uint32_t op,
6979 int32_t cc, int32_t offset)
6981 target_ulong btarget;
6982 const char *opn = "cp1 cond branch";
6983 TCGv_i32 t0 = tcg_temp_new_i32();
6985 if (cc != 0)
6986 check_insn(ctx, ISA_MIPS4 | ISA_MIPS32);
6988 btarget = ctx->pc + 4 + offset;
6990 switch (op) {
6991 case OPC_BC1F:
6992 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
6993 tcg_gen_not_i32(t0, t0);
6994 tcg_gen_andi_i32(t0, t0, 1);
6995 tcg_gen_extu_i32_tl(bcond, t0);
6996 opn = "bc1f";
6997 goto not_likely;
6998 case OPC_BC1FL:
6999 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
7000 tcg_gen_not_i32(t0, t0);
7001 tcg_gen_andi_i32(t0, t0, 1);
7002 tcg_gen_extu_i32_tl(bcond, t0);
7003 opn = "bc1fl";
7004 goto likely;
7005 case OPC_BC1T:
7006 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
7007 tcg_gen_andi_i32(t0, t0, 1);
7008 tcg_gen_extu_i32_tl(bcond, t0);
7009 opn = "bc1t";
7010 goto not_likely;
7011 case OPC_BC1TL:
7012 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
7013 tcg_gen_andi_i32(t0, t0, 1);
7014 tcg_gen_extu_i32_tl(bcond, t0);
7015 opn = "bc1tl";
7016 likely:
7017 ctx->hflags |= MIPS_HFLAG_BL;
7018 break;
7019 case OPC_BC1FANY2:
7021 TCGv_i32 t1 = tcg_temp_new_i32();
7022 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
7023 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+1));
7024 tcg_gen_nand_i32(t0, t0, t1);
7025 tcg_temp_free_i32(t1);
7026 tcg_gen_andi_i32(t0, t0, 1);
7027 tcg_gen_extu_i32_tl(bcond, t0);
7029 opn = "bc1any2f";
7030 goto not_likely;
7031 case OPC_BC1TANY2:
7033 TCGv_i32 t1 = tcg_temp_new_i32();
7034 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
7035 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+1));
7036 tcg_gen_or_i32(t0, t0, t1);
7037 tcg_temp_free_i32(t1);
7038 tcg_gen_andi_i32(t0, t0, 1);
7039 tcg_gen_extu_i32_tl(bcond, t0);
7041 opn = "bc1any2t";
7042 goto not_likely;
7043 case OPC_BC1FANY4:
7045 TCGv_i32 t1 = tcg_temp_new_i32();
7046 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
7047 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+1));
7048 tcg_gen_and_i32(t0, t0, t1);
7049 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+2));
7050 tcg_gen_and_i32(t0, t0, t1);
7051 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+3));
7052 tcg_gen_nand_i32(t0, t0, t1);
7053 tcg_temp_free_i32(t1);
7054 tcg_gen_andi_i32(t0, t0, 1);
7055 tcg_gen_extu_i32_tl(bcond, t0);
7057 opn = "bc1any4f";
7058 goto not_likely;
7059 case OPC_BC1TANY4:
7061 TCGv_i32 t1 = tcg_temp_new_i32();
7062 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
7063 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+1));
7064 tcg_gen_or_i32(t0, t0, t1);
7065 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+2));
7066 tcg_gen_or_i32(t0, t0, t1);
7067 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+3));
7068 tcg_gen_or_i32(t0, t0, t1);
7069 tcg_temp_free_i32(t1);
7070 tcg_gen_andi_i32(t0, t0, 1);
7071 tcg_gen_extu_i32_tl(bcond, t0);
7073 opn = "bc1any4t";
7074 not_likely:
7075 ctx->hflags |= MIPS_HFLAG_BC;
7076 break;
7077 default:
7078 MIPS_INVAL(opn);
7079 generate_exception (ctx, EXCP_RI);
7080 goto out;
7082 (void)opn; /* avoid a compiler warning */
7083 MIPS_DEBUG("%s: cond %02x target " TARGET_FMT_lx, opn,
7084 ctx->hflags, btarget);
7085 ctx->btarget = btarget;
7087 out:
7088 tcg_temp_free_i32(t0);
7091 /* Coprocessor 1 (FPU) */
7093 #define FOP(func, fmt) (((fmt) << 21) | (func))
7095 enum fopcode {
7096 OPC_ADD_S = FOP(0, FMT_S),
7097 OPC_SUB_S = FOP(1, FMT_S),
7098 OPC_MUL_S = FOP(2, FMT_S),
7099 OPC_DIV_S = FOP(3, FMT_S),
7100 OPC_SQRT_S = FOP(4, FMT_S),
7101 OPC_ABS_S = FOP(5, FMT_S),
7102 OPC_MOV_S = FOP(6, FMT_S),
7103 OPC_NEG_S = FOP(7, FMT_S),
7104 OPC_ROUND_L_S = FOP(8, FMT_S),
7105 OPC_TRUNC_L_S = FOP(9, FMT_S),
7106 OPC_CEIL_L_S = FOP(10, FMT_S),
7107 OPC_FLOOR_L_S = FOP(11, FMT_S),
7108 OPC_ROUND_W_S = FOP(12, FMT_S),
7109 OPC_TRUNC_W_S = FOP(13, FMT_S),
7110 OPC_CEIL_W_S = FOP(14, FMT_S),
7111 OPC_FLOOR_W_S = FOP(15, FMT_S),
7112 OPC_MOVCF_S = FOP(17, FMT_S),
7113 OPC_MOVZ_S = FOP(18, FMT_S),
7114 OPC_MOVN_S = FOP(19, FMT_S),
7115 OPC_RECIP_S = FOP(21, FMT_S),
7116 OPC_RSQRT_S = FOP(22, FMT_S),
7117 OPC_RECIP2_S = FOP(28, FMT_S),
7118 OPC_RECIP1_S = FOP(29, FMT_S),
7119 OPC_RSQRT1_S = FOP(30, FMT_S),
7120 OPC_RSQRT2_S = FOP(31, FMT_S),
7121 OPC_CVT_D_S = FOP(33, FMT_S),
7122 OPC_CVT_W_S = FOP(36, FMT_S),
7123 OPC_CVT_L_S = FOP(37, FMT_S),
7124 OPC_CVT_PS_S = FOP(38, FMT_S),
7125 OPC_CMP_F_S = FOP (48, FMT_S),
7126 OPC_CMP_UN_S = FOP (49, FMT_S),
7127 OPC_CMP_EQ_S = FOP (50, FMT_S),
7128 OPC_CMP_UEQ_S = FOP (51, FMT_S),
7129 OPC_CMP_OLT_S = FOP (52, FMT_S),
7130 OPC_CMP_ULT_S = FOP (53, FMT_S),
7131 OPC_CMP_OLE_S = FOP (54, FMT_S),
7132 OPC_CMP_ULE_S = FOP (55, FMT_S),
7133 OPC_CMP_SF_S = FOP (56, FMT_S),
7134 OPC_CMP_NGLE_S = FOP (57, FMT_S),
7135 OPC_CMP_SEQ_S = FOP (58, FMT_S),
7136 OPC_CMP_NGL_S = FOP (59, FMT_S),
7137 OPC_CMP_LT_S = FOP (60, FMT_S),
7138 OPC_CMP_NGE_S = FOP (61, FMT_S),
7139 OPC_CMP_LE_S = FOP (62, FMT_S),
7140 OPC_CMP_NGT_S = FOP (63, FMT_S),
7142 OPC_ADD_D = FOP(0, FMT_D),
7143 OPC_SUB_D = FOP(1, FMT_D),
7144 OPC_MUL_D = FOP(2, FMT_D),
7145 OPC_DIV_D = FOP(3, FMT_D),
7146 OPC_SQRT_D = FOP(4, FMT_D),
7147 OPC_ABS_D = FOP(5, FMT_D),
7148 OPC_MOV_D = FOP(6, FMT_D),
7149 OPC_NEG_D = FOP(7, FMT_D),
7150 OPC_ROUND_L_D = FOP(8, FMT_D),
7151 OPC_TRUNC_L_D = FOP(9, FMT_D),
7152 OPC_CEIL_L_D = FOP(10, FMT_D),
7153 OPC_FLOOR_L_D = FOP(11, FMT_D),
7154 OPC_ROUND_W_D = FOP(12, FMT_D),
7155 OPC_TRUNC_W_D = FOP(13, FMT_D),
7156 OPC_CEIL_W_D = FOP(14, FMT_D),
7157 OPC_FLOOR_W_D = FOP(15, FMT_D),
7158 OPC_MOVCF_D = FOP(17, FMT_D),
7159 OPC_MOVZ_D = FOP(18, FMT_D),
7160 OPC_MOVN_D = FOP(19, FMT_D),
7161 OPC_RECIP_D = FOP(21, FMT_D),
7162 OPC_RSQRT_D = FOP(22, FMT_D),
7163 OPC_RECIP2_D = FOP(28, FMT_D),
7164 OPC_RECIP1_D = FOP(29, FMT_D),
7165 OPC_RSQRT1_D = FOP(30, FMT_D),
7166 OPC_RSQRT2_D = FOP(31, FMT_D),
7167 OPC_CVT_S_D = FOP(32, FMT_D),
7168 OPC_CVT_W_D = FOP(36, FMT_D),
7169 OPC_CVT_L_D = FOP(37, FMT_D),
7170 OPC_CMP_F_D = FOP (48, FMT_D),
7171 OPC_CMP_UN_D = FOP (49, FMT_D),
7172 OPC_CMP_EQ_D = FOP (50, FMT_D),
7173 OPC_CMP_UEQ_D = FOP (51, FMT_D),
7174 OPC_CMP_OLT_D = FOP (52, FMT_D),
7175 OPC_CMP_ULT_D = FOP (53, FMT_D),
7176 OPC_CMP_OLE_D = FOP (54, FMT_D),
7177 OPC_CMP_ULE_D = FOP (55, FMT_D),
7178 OPC_CMP_SF_D = FOP (56, FMT_D),
7179 OPC_CMP_NGLE_D = FOP (57, FMT_D),
7180 OPC_CMP_SEQ_D = FOP (58, FMT_D),
7181 OPC_CMP_NGL_D = FOP (59, FMT_D),
7182 OPC_CMP_LT_D = FOP (60, FMT_D),
7183 OPC_CMP_NGE_D = FOP (61, FMT_D),
7184 OPC_CMP_LE_D = FOP (62, FMT_D),
7185 OPC_CMP_NGT_D = FOP (63, FMT_D),
7187 OPC_CVT_S_W = FOP(32, FMT_W),
7188 OPC_CVT_D_W = FOP(33, FMT_W),
7189 OPC_CVT_S_L = FOP(32, FMT_L),
7190 OPC_CVT_D_L = FOP(33, FMT_L),
7191 OPC_CVT_PS_PW = FOP(38, FMT_W),
7193 OPC_ADD_PS = FOP(0, FMT_PS),
7194 OPC_SUB_PS = FOP(1, FMT_PS),
7195 OPC_MUL_PS = FOP(2, FMT_PS),
7196 OPC_DIV_PS = FOP(3, FMT_PS),
7197 OPC_ABS_PS = FOP(5, FMT_PS),
7198 OPC_MOV_PS = FOP(6, FMT_PS),
7199 OPC_NEG_PS = FOP(7, FMT_PS),
7200 OPC_MOVCF_PS = FOP(17, FMT_PS),
7201 OPC_MOVZ_PS = FOP(18, FMT_PS),
7202 OPC_MOVN_PS = FOP(19, FMT_PS),
7203 OPC_ADDR_PS = FOP(24, FMT_PS),
7204 OPC_MULR_PS = FOP(26, FMT_PS),
7205 OPC_RECIP2_PS = FOP(28, FMT_PS),
7206 OPC_RECIP1_PS = FOP(29, FMT_PS),
7207 OPC_RSQRT1_PS = FOP(30, FMT_PS),
7208 OPC_RSQRT2_PS = FOP(31, FMT_PS),
7210 OPC_CVT_S_PU = FOP(32, FMT_PS),
7211 OPC_CVT_PW_PS = FOP(36, FMT_PS),
7212 OPC_CVT_S_PL = FOP(40, FMT_PS),
7213 OPC_PLL_PS = FOP(44, FMT_PS),
7214 OPC_PLU_PS = FOP(45, FMT_PS),
7215 OPC_PUL_PS = FOP(46, FMT_PS),
7216 OPC_PUU_PS = FOP(47, FMT_PS),
7217 OPC_CMP_F_PS = FOP (48, FMT_PS),
7218 OPC_CMP_UN_PS = FOP (49, FMT_PS),
7219 OPC_CMP_EQ_PS = FOP (50, FMT_PS),
7220 OPC_CMP_UEQ_PS = FOP (51, FMT_PS),
7221 OPC_CMP_OLT_PS = FOP (52, FMT_PS),
7222 OPC_CMP_ULT_PS = FOP (53, FMT_PS),
7223 OPC_CMP_OLE_PS = FOP (54, FMT_PS),
7224 OPC_CMP_ULE_PS = FOP (55, FMT_PS),
7225 OPC_CMP_SF_PS = FOP (56, FMT_PS),
7226 OPC_CMP_NGLE_PS = FOP (57, FMT_PS),
7227 OPC_CMP_SEQ_PS = FOP (58, FMT_PS),
7228 OPC_CMP_NGL_PS = FOP (59, FMT_PS),
7229 OPC_CMP_LT_PS = FOP (60, FMT_PS),
7230 OPC_CMP_NGE_PS = FOP (61, FMT_PS),
7231 OPC_CMP_LE_PS = FOP (62, FMT_PS),
7232 OPC_CMP_NGT_PS = FOP (63, FMT_PS),
7235 static void gen_cp1 (DisasContext *ctx, uint32_t opc, int rt, int fs)
7237 const char *opn = "cp1 move";
7238 TCGv t0 = tcg_temp_new();
7240 switch (opc) {
7241 case OPC_MFC1:
7243 TCGv_i32 fp0 = tcg_temp_new_i32();
7245 gen_load_fpr32(fp0, fs);
7246 tcg_gen_ext_i32_tl(t0, fp0);
7247 tcg_temp_free_i32(fp0);
7249 gen_store_gpr(t0, rt);
7250 opn = "mfc1";
7251 break;
7252 case OPC_MTC1:
7253 gen_load_gpr(t0, rt);
7255 TCGv_i32 fp0 = tcg_temp_new_i32();
7257 tcg_gen_trunc_tl_i32(fp0, t0);
7258 gen_store_fpr32(fp0, fs);
7259 tcg_temp_free_i32(fp0);
7261 opn = "mtc1";
7262 break;
7263 case OPC_CFC1:
7264 gen_helper_1e0i(cfc1, t0, fs);
7265 gen_store_gpr(t0, rt);
7266 opn = "cfc1";
7267 break;
7268 case OPC_CTC1:
7269 gen_load_gpr(t0, rt);
7271 TCGv_i32 fs_tmp = tcg_const_i32(fs);
7273 gen_helper_0e2i(ctc1, t0, fs_tmp, rt);
7274 tcg_temp_free_i32(fs_tmp);
7276 opn = "ctc1";
7277 break;
7278 #if defined(TARGET_MIPS64)
7279 case OPC_DMFC1:
7280 gen_load_fpr64(ctx, t0, fs);
7281 gen_store_gpr(t0, rt);
7282 opn = "dmfc1";
7283 break;
7284 case OPC_DMTC1:
7285 gen_load_gpr(t0, rt);
7286 gen_store_fpr64(ctx, t0, fs);
7287 opn = "dmtc1";
7288 break;
7289 #endif
7290 case OPC_MFHC1:
7292 TCGv_i32 fp0 = tcg_temp_new_i32();
7294 gen_load_fpr32h(ctx, fp0, fs);
7295 tcg_gen_ext_i32_tl(t0, fp0);
7296 tcg_temp_free_i32(fp0);
7298 gen_store_gpr(t0, rt);
7299 opn = "mfhc1";
7300 break;
7301 case OPC_MTHC1:
7302 gen_load_gpr(t0, rt);
7304 TCGv_i32 fp0 = tcg_temp_new_i32();
7306 tcg_gen_trunc_tl_i32(fp0, t0);
7307 gen_store_fpr32h(ctx, fp0, fs);
7308 tcg_temp_free_i32(fp0);
7310 opn = "mthc1";
7311 break;
7312 default:
7313 MIPS_INVAL(opn);
7314 generate_exception (ctx, EXCP_RI);
7315 goto out;
7317 (void)opn; /* avoid a compiler warning */
7318 MIPS_DEBUG("%s %s %s", opn, regnames[rt], fregnames[fs]);
7320 out:
7321 tcg_temp_free(t0);
7324 static void gen_movci (DisasContext *ctx, int rd, int rs, int cc, int tf)
7326 int l1;
7327 TCGCond cond;
7328 TCGv_i32 t0;
7330 if (rd == 0) {
7331 /* Treat as NOP. */
7332 return;
7335 if (tf)
7336 cond = TCG_COND_EQ;
7337 else
7338 cond = TCG_COND_NE;
7340 l1 = gen_new_label();
7341 t0 = tcg_temp_new_i32();
7342 tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc));
7343 tcg_gen_brcondi_i32(cond, t0, 0, l1);
7344 tcg_temp_free_i32(t0);
7345 if (rs == 0) {
7346 tcg_gen_movi_tl(cpu_gpr[rd], 0);
7347 } else {
7348 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
7350 gen_set_label(l1);
7353 static inline void gen_movcf_s (int fs, int fd, int cc, int tf)
7355 int cond;
7356 TCGv_i32 t0 = tcg_temp_new_i32();
7357 int l1 = gen_new_label();
7359 if (tf)
7360 cond = TCG_COND_EQ;
7361 else
7362 cond = TCG_COND_NE;
7364 tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc));
7365 tcg_gen_brcondi_i32(cond, t0, 0, l1);
7366 gen_load_fpr32(t0, fs);
7367 gen_store_fpr32(t0, fd);
7368 gen_set_label(l1);
7369 tcg_temp_free_i32(t0);
7372 static inline void gen_movcf_d (DisasContext *ctx, int fs, int fd, int cc, int tf)
7374 int cond;
7375 TCGv_i32 t0 = tcg_temp_new_i32();
7376 TCGv_i64 fp0;
7377 int l1 = gen_new_label();
7379 if (tf)
7380 cond = TCG_COND_EQ;
7381 else
7382 cond = TCG_COND_NE;
7384 tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc));
7385 tcg_gen_brcondi_i32(cond, t0, 0, l1);
7386 tcg_temp_free_i32(t0);
7387 fp0 = tcg_temp_new_i64();
7388 gen_load_fpr64(ctx, fp0, fs);
7389 gen_store_fpr64(ctx, fp0, fd);
7390 tcg_temp_free_i64(fp0);
7391 gen_set_label(l1);
7394 static inline void gen_movcf_ps(DisasContext *ctx, int fs, int fd,
7395 int cc, int tf)
7397 int cond;
7398 TCGv_i32 t0 = tcg_temp_new_i32();
7399 int l1 = gen_new_label();
7400 int l2 = gen_new_label();
7402 if (tf)
7403 cond = TCG_COND_EQ;
7404 else
7405 cond = TCG_COND_NE;
7407 tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc));
7408 tcg_gen_brcondi_i32(cond, t0, 0, l1);
7409 gen_load_fpr32(t0, fs);
7410 gen_store_fpr32(t0, fd);
7411 gen_set_label(l1);
7413 tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc+1));
7414 tcg_gen_brcondi_i32(cond, t0, 0, l2);
7415 gen_load_fpr32h(ctx, t0, fs);
7416 gen_store_fpr32h(ctx, t0, fd);
7417 tcg_temp_free_i32(t0);
7418 gen_set_label(l2);
7422 static void gen_farith (DisasContext *ctx, enum fopcode op1,
7423 int ft, int fs, int fd, int cc)
7425 const char *opn = "farith";
7426 const char *condnames[] = {
7427 "c.f",
7428 "c.un",
7429 "c.eq",
7430 "c.ueq",
7431 "c.olt",
7432 "c.ult",
7433 "c.ole",
7434 "c.ule",
7435 "c.sf",
7436 "c.ngle",
7437 "c.seq",
7438 "c.ngl",
7439 "c.lt",
7440 "c.nge",
7441 "c.le",
7442 "c.ngt",
7444 const char *condnames_abs[] = {
7445 "cabs.f",
7446 "cabs.un",
7447 "cabs.eq",
7448 "cabs.ueq",
7449 "cabs.olt",
7450 "cabs.ult",
7451 "cabs.ole",
7452 "cabs.ule",
7453 "cabs.sf",
7454 "cabs.ngle",
7455 "cabs.seq",
7456 "cabs.ngl",
7457 "cabs.lt",
7458 "cabs.nge",
7459 "cabs.le",
7460 "cabs.ngt",
7462 enum { BINOP, CMPOP, OTHEROP } optype = OTHEROP;
7463 uint32_t func = ctx->opcode & 0x3f;
7465 switch (op1) {
7466 case OPC_ADD_S:
7468 TCGv_i32 fp0 = tcg_temp_new_i32();
7469 TCGv_i32 fp1 = tcg_temp_new_i32();
7471 gen_load_fpr32(fp0, fs);
7472 gen_load_fpr32(fp1, ft);
7473 gen_helper_float_add_s(fp0, cpu_env, fp0, fp1);
7474 tcg_temp_free_i32(fp1);
7475 gen_store_fpr32(fp0, fd);
7476 tcg_temp_free_i32(fp0);
7478 opn = "add.s";
7479 optype = BINOP;
7480 break;
7481 case OPC_SUB_S:
7483 TCGv_i32 fp0 = tcg_temp_new_i32();
7484 TCGv_i32 fp1 = tcg_temp_new_i32();
7486 gen_load_fpr32(fp0, fs);
7487 gen_load_fpr32(fp1, ft);
7488 gen_helper_float_sub_s(fp0, cpu_env, fp0, fp1);
7489 tcg_temp_free_i32(fp1);
7490 gen_store_fpr32(fp0, fd);
7491 tcg_temp_free_i32(fp0);
7493 opn = "sub.s";
7494 optype = BINOP;
7495 break;
7496 case OPC_MUL_S:
7498 TCGv_i32 fp0 = tcg_temp_new_i32();
7499 TCGv_i32 fp1 = tcg_temp_new_i32();
7501 gen_load_fpr32(fp0, fs);
7502 gen_load_fpr32(fp1, ft);
7503 gen_helper_float_mul_s(fp0, cpu_env, fp0, fp1);
7504 tcg_temp_free_i32(fp1);
7505 gen_store_fpr32(fp0, fd);
7506 tcg_temp_free_i32(fp0);
7508 opn = "mul.s";
7509 optype = BINOP;
7510 break;
7511 case OPC_DIV_S:
7513 TCGv_i32 fp0 = tcg_temp_new_i32();
7514 TCGv_i32 fp1 = tcg_temp_new_i32();
7516 gen_load_fpr32(fp0, fs);
7517 gen_load_fpr32(fp1, ft);
7518 gen_helper_float_div_s(fp0, cpu_env, fp0, fp1);
7519 tcg_temp_free_i32(fp1);
7520 gen_store_fpr32(fp0, fd);
7521 tcg_temp_free_i32(fp0);
7523 opn = "div.s";
7524 optype = BINOP;
7525 break;
7526 case OPC_SQRT_S:
7528 TCGv_i32 fp0 = tcg_temp_new_i32();
7530 gen_load_fpr32(fp0, fs);
7531 gen_helper_float_sqrt_s(fp0, cpu_env, fp0);
7532 gen_store_fpr32(fp0, fd);
7533 tcg_temp_free_i32(fp0);
7535 opn = "sqrt.s";
7536 break;
7537 case OPC_ABS_S:
7539 TCGv_i32 fp0 = tcg_temp_new_i32();
7541 gen_load_fpr32(fp0, fs);
7542 gen_helper_float_abs_s(fp0, fp0);
7543 gen_store_fpr32(fp0, fd);
7544 tcg_temp_free_i32(fp0);
7546 opn = "abs.s";
7547 break;
7548 case OPC_MOV_S:
7550 TCGv_i32 fp0 = tcg_temp_new_i32();
7552 gen_load_fpr32(fp0, fs);
7553 gen_store_fpr32(fp0, fd);
7554 tcg_temp_free_i32(fp0);
7556 opn = "mov.s";
7557 break;
7558 case OPC_NEG_S:
7560 TCGv_i32 fp0 = tcg_temp_new_i32();
7562 gen_load_fpr32(fp0, fs);
7563 gen_helper_float_chs_s(fp0, fp0);
7564 gen_store_fpr32(fp0, fd);
7565 tcg_temp_free_i32(fp0);
7567 opn = "neg.s";
7568 break;
7569 case OPC_ROUND_L_S:
7570 check_cp1_64bitmode(ctx);
7572 TCGv_i32 fp32 = tcg_temp_new_i32();
7573 TCGv_i64 fp64 = tcg_temp_new_i64();
7575 gen_load_fpr32(fp32, fs);
7576 gen_helper_float_roundl_s(fp64, cpu_env, fp32);
7577 tcg_temp_free_i32(fp32);
7578 gen_store_fpr64(ctx, fp64, fd);
7579 tcg_temp_free_i64(fp64);
7581 opn = "round.l.s";
7582 break;
7583 case OPC_TRUNC_L_S:
7584 check_cp1_64bitmode(ctx);
7586 TCGv_i32 fp32 = tcg_temp_new_i32();
7587 TCGv_i64 fp64 = tcg_temp_new_i64();
7589 gen_load_fpr32(fp32, fs);
7590 gen_helper_float_truncl_s(fp64, cpu_env, fp32);
7591 tcg_temp_free_i32(fp32);
7592 gen_store_fpr64(ctx, fp64, fd);
7593 tcg_temp_free_i64(fp64);
7595 opn = "trunc.l.s";
7596 break;
7597 case OPC_CEIL_L_S:
7598 check_cp1_64bitmode(ctx);
7600 TCGv_i32 fp32 = tcg_temp_new_i32();
7601 TCGv_i64 fp64 = tcg_temp_new_i64();
7603 gen_load_fpr32(fp32, fs);
7604 gen_helper_float_ceill_s(fp64, cpu_env, fp32);
7605 tcg_temp_free_i32(fp32);
7606 gen_store_fpr64(ctx, fp64, fd);
7607 tcg_temp_free_i64(fp64);
7609 opn = "ceil.l.s";
7610 break;
7611 case OPC_FLOOR_L_S:
7612 check_cp1_64bitmode(ctx);
7614 TCGv_i32 fp32 = tcg_temp_new_i32();
7615 TCGv_i64 fp64 = tcg_temp_new_i64();
7617 gen_load_fpr32(fp32, fs);
7618 gen_helper_float_floorl_s(fp64, cpu_env, fp32);
7619 tcg_temp_free_i32(fp32);
7620 gen_store_fpr64(ctx, fp64, fd);
7621 tcg_temp_free_i64(fp64);
7623 opn = "floor.l.s";
7624 break;
7625 case OPC_ROUND_W_S:
7627 TCGv_i32 fp0 = tcg_temp_new_i32();
7629 gen_load_fpr32(fp0, fs);
7630 gen_helper_float_roundw_s(fp0, cpu_env, fp0);
7631 gen_store_fpr32(fp0, fd);
7632 tcg_temp_free_i32(fp0);
7634 opn = "round.w.s";
7635 break;
7636 case OPC_TRUNC_W_S:
7638 TCGv_i32 fp0 = tcg_temp_new_i32();
7640 gen_load_fpr32(fp0, fs);
7641 gen_helper_float_truncw_s(fp0, cpu_env, fp0);
7642 gen_store_fpr32(fp0, fd);
7643 tcg_temp_free_i32(fp0);
7645 opn = "trunc.w.s";
7646 break;
7647 case OPC_CEIL_W_S:
7649 TCGv_i32 fp0 = tcg_temp_new_i32();
7651 gen_load_fpr32(fp0, fs);
7652 gen_helper_float_ceilw_s(fp0, cpu_env, fp0);
7653 gen_store_fpr32(fp0, fd);
7654 tcg_temp_free_i32(fp0);
7656 opn = "ceil.w.s";
7657 break;
7658 case OPC_FLOOR_W_S:
7660 TCGv_i32 fp0 = tcg_temp_new_i32();
7662 gen_load_fpr32(fp0, fs);
7663 gen_helper_float_floorw_s(fp0, cpu_env, fp0);
7664 gen_store_fpr32(fp0, fd);
7665 tcg_temp_free_i32(fp0);
7667 opn = "floor.w.s";
7668 break;
7669 case OPC_MOVCF_S:
7670 gen_movcf_s(fs, fd, (ft >> 2) & 0x7, ft & 0x1);
7671 opn = "movcf.s";
7672 break;
7673 case OPC_MOVZ_S:
7675 int l1 = gen_new_label();
7676 TCGv_i32 fp0;
7678 if (ft != 0) {
7679 tcg_gen_brcondi_tl(TCG_COND_NE, cpu_gpr[ft], 0, l1);
7681 fp0 = tcg_temp_new_i32();
7682 gen_load_fpr32(fp0, fs);
7683 gen_store_fpr32(fp0, fd);
7684 tcg_temp_free_i32(fp0);
7685 gen_set_label(l1);
7687 opn = "movz.s";
7688 break;
7689 case OPC_MOVN_S:
7691 int l1 = gen_new_label();
7692 TCGv_i32 fp0;
7694 if (ft != 0) {
7695 tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_gpr[ft], 0, l1);
7696 fp0 = tcg_temp_new_i32();
7697 gen_load_fpr32(fp0, fs);
7698 gen_store_fpr32(fp0, fd);
7699 tcg_temp_free_i32(fp0);
7700 gen_set_label(l1);
7703 opn = "movn.s";
7704 break;
7705 case OPC_RECIP_S:
7706 check_cop1x(ctx);
7708 TCGv_i32 fp0 = tcg_temp_new_i32();
7710 gen_load_fpr32(fp0, fs);
7711 gen_helper_float_recip_s(fp0, cpu_env, fp0);
7712 gen_store_fpr32(fp0, fd);
7713 tcg_temp_free_i32(fp0);
7715 opn = "recip.s";
7716 break;
7717 case OPC_RSQRT_S:
7718 check_cop1x(ctx);
7720 TCGv_i32 fp0 = tcg_temp_new_i32();
7722 gen_load_fpr32(fp0, fs);
7723 gen_helper_float_rsqrt_s(fp0, cpu_env, fp0);
7724 gen_store_fpr32(fp0, fd);
7725 tcg_temp_free_i32(fp0);
7727 opn = "rsqrt.s";
7728 break;
7729 case OPC_RECIP2_S:
7730 check_cp1_64bitmode(ctx);
7732 TCGv_i32 fp0 = tcg_temp_new_i32();
7733 TCGv_i32 fp1 = tcg_temp_new_i32();
7735 gen_load_fpr32(fp0, fs);
7736 gen_load_fpr32(fp1, ft);
7737 gen_helper_float_recip2_s(fp0, cpu_env, fp0, fp1);
7738 tcg_temp_free_i32(fp1);
7739 gen_store_fpr32(fp0, fd);
7740 tcg_temp_free_i32(fp0);
7742 opn = "recip2.s";
7743 break;
7744 case OPC_RECIP1_S:
7745 check_cp1_64bitmode(ctx);
7747 TCGv_i32 fp0 = tcg_temp_new_i32();
7749 gen_load_fpr32(fp0, fs);
7750 gen_helper_float_recip1_s(fp0, cpu_env, fp0);
7751 gen_store_fpr32(fp0, fd);
7752 tcg_temp_free_i32(fp0);
7754 opn = "recip1.s";
7755 break;
7756 case OPC_RSQRT1_S:
7757 check_cp1_64bitmode(ctx);
7759 TCGv_i32 fp0 = tcg_temp_new_i32();
7761 gen_load_fpr32(fp0, fs);
7762 gen_helper_float_rsqrt1_s(fp0, cpu_env, fp0);
7763 gen_store_fpr32(fp0, fd);
7764 tcg_temp_free_i32(fp0);
7766 opn = "rsqrt1.s";
7767 break;
7768 case OPC_RSQRT2_S:
7769 check_cp1_64bitmode(ctx);
7771 TCGv_i32 fp0 = tcg_temp_new_i32();
7772 TCGv_i32 fp1 = tcg_temp_new_i32();
7774 gen_load_fpr32(fp0, fs);
7775 gen_load_fpr32(fp1, ft);
7776 gen_helper_float_rsqrt2_s(fp0, cpu_env, fp0, fp1);
7777 tcg_temp_free_i32(fp1);
7778 gen_store_fpr32(fp0, fd);
7779 tcg_temp_free_i32(fp0);
7781 opn = "rsqrt2.s";
7782 break;
7783 case OPC_CVT_D_S:
7784 check_cp1_registers(ctx, fd);
7786 TCGv_i32 fp32 = tcg_temp_new_i32();
7787 TCGv_i64 fp64 = tcg_temp_new_i64();
7789 gen_load_fpr32(fp32, fs);
7790 gen_helper_float_cvtd_s(fp64, cpu_env, fp32);
7791 tcg_temp_free_i32(fp32);
7792 gen_store_fpr64(ctx, fp64, fd);
7793 tcg_temp_free_i64(fp64);
7795 opn = "cvt.d.s";
7796 break;
7797 case OPC_CVT_W_S:
7799 TCGv_i32 fp0 = tcg_temp_new_i32();
7801 gen_load_fpr32(fp0, fs);
7802 gen_helper_float_cvtw_s(fp0, cpu_env, fp0);
7803 gen_store_fpr32(fp0, fd);
7804 tcg_temp_free_i32(fp0);
7806 opn = "cvt.w.s";
7807 break;
7808 case OPC_CVT_L_S:
7809 check_cp1_64bitmode(ctx);
7811 TCGv_i32 fp32 = tcg_temp_new_i32();
7812 TCGv_i64 fp64 = tcg_temp_new_i64();
7814 gen_load_fpr32(fp32, fs);
7815 gen_helper_float_cvtl_s(fp64, cpu_env, fp32);
7816 tcg_temp_free_i32(fp32);
7817 gen_store_fpr64(ctx, fp64, fd);
7818 tcg_temp_free_i64(fp64);
7820 opn = "cvt.l.s";
7821 break;
7822 case OPC_CVT_PS_S:
7823 check_cp1_64bitmode(ctx);
7825 TCGv_i64 fp64 = tcg_temp_new_i64();
7826 TCGv_i32 fp32_0 = tcg_temp_new_i32();
7827 TCGv_i32 fp32_1 = tcg_temp_new_i32();
7829 gen_load_fpr32(fp32_0, fs);
7830 gen_load_fpr32(fp32_1, ft);
7831 tcg_gen_concat_i32_i64(fp64, fp32_1, fp32_0);
7832 tcg_temp_free_i32(fp32_1);
7833 tcg_temp_free_i32(fp32_0);
7834 gen_store_fpr64(ctx, fp64, fd);
7835 tcg_temp_free_i64(fp64);
7837 opn = "cvt.ps.s";
7838 break;
7839 case OPC_CMP_F_S:
7840 case OPC_CMP_UN_S:
7841 case OPC_CMP_EQ_S:
7842 case OPC_CMP_UEQ_S:
7843 case OPC_CMP_OLT_S:
7844 case OPC_CMP_ULT_S:
7845 case OPC_CMP_OLE_S:
7846 case OPC_CMP_ULE_S:
7847 case OPC_CMP_SF_S:
7848 case OPC_CMP_NGLE_S:
7849 case OPC_CMP_SEQ_S:
7850 case OPC_CMP_NGL_S:
7851 case OPC_CMP_LT_S:
7852 case OPC_CMP_NGE_S:
7853 case OPC_CMP_LE_S:
7854 case OPC_CMP_NGT_S:
7855 if (ctx->opcode & (1 << 6)) {
7856 gen_cmpabs_s(ctx, func-48, ft, fs, cc);
7857 opn = condnames_abs[func-48];
7858 } else {
7859 gen_cmp_s(ctx, func-48, ft, fs, cc);
7860 opn = condnames[func-48];
7862 break;
7863 case OPC_ADD_D:
7864 check_cp1_registers(ctx, fs | ft | fd);
7866 TCGv_i64 fp0 = tcg_temp_new_i64();
7867 TCGv_i64 fp1 = tcg_temp_new_i64();
7869 gen_load_fpr64(ctx, fp0, fs);
7870 gen_load_fpr64(ctx, fp1, ft);
7871 gen_helper_float_add_d(fp0, cpu_env, fp0, fp1);
7872 tcg_temp_free_i64(fp1);
7873 gen_store_fpr64(ctx, fp0, fd);
7874 tcg_temp_free_i64(fp0);
7876 opn = "add.d";
7877 optype = BINOP;
7878 break;
7879 case OPC_SUB_D:
7880 check_cp1_registers(ctx, fs | ft | fd);
7882 TCGv_i64 fp0 = tcg_temp_new_i64();
7883 TCGv_i64 fp1 = tcg_temp_new_i64();
7885 gen_load_fpr64(ctx, fp0, fs);
7886 gen_load_fpr64(ctx, fp1, ft);
7887 gen_helper_float_sub_d(fp0, cpu_env, fp0, fp1);
7888 tcg_temp_free_i64(fp1);
7889 gen_store_fpr64(ctx, fp0, fd);
7890 tcg_temp_free_i64(fp0);
7892 opn = "sub.d";
7893 optype = BINOP;
7894 break;
7895 case OPC_MUL_D:
7896 check_cp1_registers(ctx, fs | ft | fd);
7898 TCGv_i64 fp0 = tcg_temp_new_i64();
7899 TCGv_i64 fp1 = tcg_temp_new_i64();
7901 gen_load_fpr64(ctx, fp0, fs);
7902 gen_load_fpr64(ctx, fp1, ft);
7903 gen_helper_float_mul_d(fp0, cpu_env, fp0, fp1);
7904 tcg_temp_free_i64(fp1);
7905 gen_store_fpr64(ctx, fp0, fd);
7906 tcg_temp_free_i64(fp0);
7908 opn = "mul.d";
7909 optype = BINOP;
7910 break;
7911 case OPC_DIV_D:
7912 check_cp1_registers(ctx, fs | ft | fd);
7914 TCGv_i64 fp0 = tcg_temp_new_i64();
7915 TCGv_i64 fp1 = tcg_temp_new_i64();
7917 gen_load_fpr64(ctx, fp0, fs);
7918 gen_load_fpr64(ctx, fp1, ft);
7919 gen_helper_float_div_d(fp0, cpu_env, fp0, fp1);
7920 tcg_temp_free_i64(fp1);
7921 gen_store_fpr64(ctx, fp0, fd);
7922 tcg_temp_free_i64(fp0);
7924 opn = "div.d";
7925 optype = BINOP;
7926 break;
7927 case OPC_SQRT_D:
7928 check_cp1_registers(ctx, fs | fd);
7930 TCGv_i64 fp0 = tcg_temp_new_i64();
7932 gen_load_fpr64(ctx, fp0, fs);
7933 gen_helper_float_sqrt_d(fp0, cpu_env, fp0);
7934 gen_store_fpr64(ctx, fp0, fd);
7935 tcg_temp_free_i64(fp0);
7937 opn = "sqrt.d";
7938 break;
7939 case OPC_ABS_D:
7940 check_cp1_registers(ctx, fs | fd);
7942 TCGv_i64 fp0 = tcg_temp_new_i64();
7944 gen_load_fpr64(ctx, fp0, fs);
7945 gen_helper_float_abs_d(fp0, fp0);
7946 gen_store_fpr64(ctx, fp0, fd);
7947 tcg_temp_free_i64(fp0);
7949 opn = "abs.d";
7950 break;
7951 case OPC_MOV_D:
7952 check_cp1_registers(ctx, fs | fd);
7954 TCGv_i64 fp0 = tcg_temp_new_i64();
7956 gen_load_fpr64(ctx, fp0, fs);
7957 gen_store_fpr64(ctx, fp0, fd);
7958 tcg_temp_free_i64(fp0);
7960 opn = "mov.d";
7961 break;
7962 case OPC_NEG_D:
7963 check_cp1_registers(ctx, fs | fd);
7965 TCGv_i64 fp0 = tcg_temp_new_i64();
7967 gen_load_fpr64(ctx, fp0, fs);
7968 gen_helper_float_chs_d(fp0, fp0);
7969 gen_store_fpr64(ctx, fp0, fd);
7970 tcg_temp_free_i64(fp0);
7972 opn = "neg.d";
7973 break;
7974 case OPC_ROUND_L_D:
7975 check_cp1_64bitmode(ctx);
7977 TCGv_i64 fp0 = tcg_temp_new_i64();
7979 gen_load_fpr64(ctx, fp0, fs);
7980 gen_helper_float_roundl_d(fp0, cpu_env, fp0);
7981 gen_store_fpr64(ctx, fp0, fd);
7982 tcg_temp_free_i64(fp0);
7984 opn = "round.l.d";
7985 break;
7986 case OPC_TRUNC_L_D:
7987 check_cp1_64bitmode(ctx);
7989 TCGv_i64 fp0 = tcg_temp_new_i64();
7991 gen_load_fpr64(ctx, fp0, fs);
7992 gen_helper_float_truncl_d(fp0, cpu_env, fp0);
7993 gen_store_fpr64(ctx, fp0, fd);
7994 tcg_temp_free_i64(fp0);
7996 opn = "trunc.l.d";
7997 break;
7998 case OPC_CEIL_L_D:
7999 check_cp1_64bitmode(ctx);
8001 TCGv_i64 fp0 = tcg_temp_new_i64();
8003 gen_load_fpr64(ctx, fp0, fs);
8004 gen_helper_float_ceill_d(fp0, cpu_env, fp0);
8005 gen_store_fpr64(ctx, fp0, fd);
8006 tcg_temp_free_i64(fp0);
8008 opn = "ceil.l.d";
8009 break;
8010 case OPC_FLOOR_L_D:
8011 check_cp1_64bitmode(ctx);
8013 TCGv_i64 fp0 = tcg_temp_new_i64();
8015 gen_load_fpr64(ctx, fp0, fs);
8016 gen_helper_float_floorl_d(fp0, cpu_env, fp0);
8017 gen_store_fpr64(ctx, fp0, fd);
8018 tcg_temp_free_i64(fp0);
8020 opn = "floor.l.d";
8021 break;
8022 case OPC_ROUND_W_D:
8023 check_cp1_registers(ctx, fs);
8025 TCGv_i32 fp32 = tcg_temp_new_i32();
8026 TCGv_i64 fp64 = tcg_temp_new_i64();
8028 gen_load_fpr64(ctx, fp64, fs);
8029 gen_helper_float_roundw_d(fp32, cpu_env, fp64);
8030 tcg_temp_free_i64(fp64);
8031 gen_store_fpr32(fp32, fd);
8032 tcg_temp_free_i32(fp32);
8034 opn = "round.w.d";
8035 break;
8036 case OPC_TRUNC_W_D:
8037 check_cp1_registers(ctx, fs);
8039 TCGv_i32 fp32 = tcg_temp_new_i32();
8040 TCGv_i64 fp64 = tcg_temp_new_i64();
8042 gen_load_fpr64(ctx, fp64, fs);
8043 gen_helper_float_truncw_d(fp32, cpu_env, fp64);
8044 tcg_temp_free_i64(fp64);
8045 gen_store_fpr32(fp32, fd);
8046 tcg_temp_free_i32(fp32);
8048 opn = "trunc.w.d";
8049 break;
8050 case OPC_CEIL_W_D:
8051 check_cp1_registers(ctx, fs);
8053 TCGv_i32 fp32 = tcg_temp_new_i32();
8054 TCGv_i64 fp64 = tcg_temp_new_i64();
8056 gen_load_fpr64(ctx, fp64, fs);
8057 gen_helper_float_ceilw_d(fp32, cpu_env, fp64);
8058 tcg_temp_free_i64(fp64);
8059 gen_store_fpr32(fp32, fd);
8060 tcg_temp_free_i32(fp32);
8062 opn = "ceil.w.d";
8063 break;
8064 case OPC_FLOOR_W_D:
8065 check_cp1_registers(ctx, fs);
8067 TCGv_i32 fp32 = tcg_temp_new_i32();
8068 TCGv_i64 fp64 = tcg_temp_new_i64();
8070 gen_load_fpr64(ctx, fp64, fs);
8071 gen_helper_float_floorw_d(fp32, cpu_env, fp64);
8072 tcg_temp_free_i64(fp64);
8073 gen_store_fpr32(fp32, fd);
8074 tcg_temp_free_i32(fp32);
8076 opn = "floor.w.d";
8077 break;
8078 case OPC_MOVCF_D:
8079 gen_movcf_d(ctx, fs, fd, (ft >> 2) & 0x7, ft & 0x1);
8080 opn = "movcf.d";
8081 break;
8082 case OPC_MOVZ_D:
8084 int l1 = gen_new_label();
8085 TCGv_i64 fp0;
8087 if (ft != 0) {
8088 tcg_gen_brcondi_tl(TCG_COND_NE, cpu_gpr[ft], 0, l1);
8090 fp0 = tcg_temp_new_i64();
8091 gen_load_fpr64(ctx, fp0, fs);
8092 gen_store_fpr64(ctx, fp0, fd);
8093 tcg_temp_free_i64(fp0);
8094 gen_set_label(l1);
8096 opn = "movz.d";
8097 break;
8098 case OPC_MOVN_D:
8100 int l1 = gen_new_label();
8101 TCGv_i64 fp0;
8103 if (ft != 0) {
8104 tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_gpr[ft], 0, l1);
8105 fp0 = tcg_temp_new_i64();
8106 gen_load_fpr64(ctx, fp0, fs);
8107 gen_store_fpr64(ctx, fp0, fd);
8108 tcg_temp_free_i64(fp0);
8109 gen_set_label(l1);
8112 opn = "movn.d";
8113 break;
8114 case OPC_RECIP_D:
8115 check_cp1_64bitmode(ctx);
8117 TCGv_i64 fp0 = tcg_temp_new_i64();
8119 gen_load_fpr64(ctx, fp0, fs);
8120 gen_helper_float_recip_d(fp0, cpu_env, fp0);
8121 gen_store_fpr64(ctx, fp0, fd);
8122 tcg_temp_free_i64(fp0);
8124 opn = "recip.d";
8125 break;
8126 case OPC_RSQRT_D:
8127 check_cp1_64bitmode(ctx);
8129 TCGv_i64 fp0 = tcg_temp_new_i64();
8131 gen_load_fpr64(ctx, fp0, fs);
8132 gen_helper_float_rsqrt_d(fp0, cpu_env, fp0);
8133 gen_store_fpr64(ctx, fp0, fd);
8134 tcg_temp_free_i64(fp0);
8136 opn = "rsqrt.d";
8137 break;
8138 case OPC_RECIP2_D:
8139 check_cp1_64bitmode(ctx);
8141 TCGv_i64 fp0 = tcg_temp_new_i64();
8142 TCGv_i64 fp1 = tcg_temp_new_i64();
8144 gen_load_fpr64(ctx, fp0, fs);
8145 gen_load_fpr64(ctx, fp1, ft);
8146 gen_helper_float_recip2_d(fp0, cpu_env, fp0, fp1);
8147 tcg_temp_free_i64(fp1);
8148 gen_store_fpr64(ctx, fp0, fd);
8149 tcg_temp_free_i64(fp0);
8151 opn = "recip2.d";
8152 break;
8153 case OPC_RECIP1_D:
8154 check_cp1_64bitmode(ctx);
8156 TCGv_i64 fp0 = tcg_temp_new_i64();
8158 gen_load_fpr64(ctx, fp0, fs);
8159 gen_helper_float_recip1_d(fp0, cpu_env, fp0);
8160 gen_store_fpr64(ctx, fp0, fd);
8161 tcg_temp_free_i64(fp0);
8163 opn = "recip1.d";
8164 break;
8165 case OPC_RSQRT1_D:
8166 check_cp1_64bitmode(ctx);
8168 TCGv_i64 fp0 = tcg_temp_new_i64();
8170 gen_load_fpr64(ctx, fp0, fs);
8171 gen_helper_float_rsqrt1_d(fp0, cpu_env, fp0);
8172 gen_store_fpr64(ctx, fp0, fd);
8173 tcg_temp_free_i64(fp0);
8175 opn = "rsqrt1.d";
8176 break;
8177 case OPC_RSQRT2_D:
8178 check_cp1_64bitmode(ctx);
8180 TCGv_i64 fp0 = tcg_temp_new_i64();
8181 TCGv_i64 fp1 = tcg_temp_new_i64();
8183 gen_load_fpr64(ctx, fp0, fs);
8184 gen_load_fpr64(ctx, fp1, ft);
8185 gen_helper_float_rsqrt2_d(fp0, cpu_env, fp0, fp1);
8186 tcg_temp_free_i64(fp1);
8187 gen_store_fpr64(ctx, fp0, fd);
8188 tcg_temp_free_i64(fp0);
8190 opn = "rsqrt2.d";
8191 break;
8192 case OPC_CMP_F_D:
8193 case OPC_CMP_UN_D:
8194 case OPC_CMP_EQ_D:
8195 case OPC_CMP_UEQ_D:
8196 case OPC_CMP_OLT_D:
8197 case OPC_CMP_ULT_D:
8198 case OPC_CMP_OLE_D:
8199 case OPC_CMP_ULE_D:
8200 case OPC_CMP_SF_D:
8201 case OPC_CMP_NGLE_D:
8202 case OPC_CMP_SEQ_D:
8203 case OPC_CMP_NGL_D:
8204 case OPC_CMP_LT_D:
8205 case OPC_CMP_NGE_D:
8206 case OPC_CMP_LE_D:
8207 case OPC_CMP_NGT_D:
8208 if (ctx->opcode & (1 << 6)) {
8209 gen_cmpabs_d(ctx, func-48, ft, fs, cc);
8210 opn = condnames_abs[func-48];
8211 } else {
8212 gen_cmp_d(ctx, func-48, ft, fs, cc);
8213 opn = condnames[func-48];
8215 break;
8216 case OPC_CVT_S_D:
8217 check_cp1_registers(ctx, fs);
8219 TCGv_i32 fp32 = tcg_temp_new_i32();
8220 TCGv_i64 fp64 = tcg_temp_new_i64();
8222 gen_load_fpr64(ctx, fp64, fs);
8223 gen_helper_float_cvts_d(fp32, cpu_env, fp64);
8224 tcg_temp_free_i64(fp64);
8225 gen_store_fpr32(fp32, fd);
8226 tcg_temp_free_i32(fp32);
8228 opn = "cvt.s.d";
8229 break;
8230 case OPC_CVT_W_D:
8231 check_cp1_registers(ctx, fs);
8233 TCGv_i32 fp32 = tcg_temp_new_i32();
8234 TCGv_i64 fp64 = tcg_temp_new_i64();
8236 gen_load_fpr64(ctx, fp64, fs);
8237 gen_helper_float_cvtw_d(fp32, cpu_env, fp64);
8238 tcg_temp_free_i64(fp64);
8239 gen_store_fpr32(fp32, fd);
8240 tcg_temp_free_i32(fp32);
8242 opn = "cvt.w.d";
8243 break;
8244 case OPC_CVT_L_D:
8245 check_cp1_64bitmode(ctx);
8247 TCGv_i64 fp0 = tcg_temp_new_i64();
8249 gen_load_fpr64(ctx, fp0, fs);
8250 gen_helper_float_cvtl_d(fp0, cpu_env, fp0);
8251 gen_store_fpr64(ctx, fp0, fd);
8252 tcg_temp_free_i64(fp0);
8254 opn = "cvt.l.d";
8255 break;
8256 case OPC_CVT_S_W:
8258 TCGv_i32 fp0 = tcg_temp_new_i32();
8260 gen_load_fpr32(fp0, fs);
8261 gen_helper_float_cvts_w(fp0, cpu_env, fp0);
8262 gen_store_fpr32(fp0, fd);
8263 tcg_temp_free_i32(fp0);
8265 opn = "cvt.s.w";
8266 break;
8267 case OPC_CVT_D_W:
8268 check_cp1_registers(ctx, fd);
8270 TCGv_i32 fp32 = tcg_temp_new_i32();
8271 TCGv_i64 fp64 = tcg_temp_new_i64();
8273 gen_load_fpr32(fp32, fs);
8274 gen_helper_float_cvtd_w(fp64, cpu_env, fp32);
8275 tcg_temp_free_i32(fp32);
8276 gen_store_fpr64(ctx, fp64, fd);
8277 tcg_temp_free_i64(fp64);
8279 opn = "cvt.d.w";
8280 break;
8281 case OPC_CVT_S_L:
8282 check_cp1_64bitmode(ctx);
8284 TCGv_i32 fp32 = tcg_temp_new_i32();
8285 TCGv_i64 fp64 = tcg_temp_new_i64();
8287 gen_load_fpr64(ctx, fp64, fs);
8288 gen_helper_float_cvts_l(fp32, cpu_env, fp64);
8289 tcg_temp_free_i64(fp64);
8290 gen_store_fpr32(fp32, fd);
8291 tcg_temp_free_i32(fp32);
8293 opn = "cvt.s.l";
8294 break;
8295 case OPC_CVT_D_L:
8296 check_cp1_64bitmode(ctx);
8298 TCGv_i64 fp0 = tcg_temp_new_i64();
8300 gen_load_fpr64(ctx, fp0, fs);
8301 gen_helper_float_cvtd_l(fp0, cpu_env, fp0);
8302 gen_store_fpr64(ctx, fp0, fd);
8303 tcg_temp_free_i64(fp0);
8305 opn = "cvt.d.l";
8306 break;
8307 case OPC_CVT_PS_PW:
8308 check_cp1_64bitmode(ctx);
8310 TCGv_i64 fp0 = tcg_temp_new_i64();
8312 gen_load_fpr64(ctx, fp0, fs);
8313 gen_helper_float_cvtps_pw(fp0, cpu_env, fp0);
8314 gen_store_fpr64(ctx, fp0, fd);
8315 tcg_temp_free_i64(fp0);
8317 opn = "cvt.ps.pw";
8318 break;
8319 case OPC_ADD_PS:
8320 check_cp1_64bitmode(ctx);
8322 TCGv_i64 fp0 = tcg_temp_new_i64();
8323 TCGv_i64 fp1 = tcg_temp_new_i64();
8325 gen_load_fpr64(ctx, fp0, fs);
8326 gen_load_fpr64(ctx, fp1, ft);
8327 gen_helper_float_add_ps(fp0, cpu_env, fp0, fp1);
8328 tcg_temp_free_i64(fp1);
8329 gen_store_fpr64(ctx, fp0, fd);
8330 tcg_temp_free_i64(fp0);
8332 opn = "add.ps";
8333 break;
8334 case OPC_SUB_PS:
8335 check_cp1_64bitmode(ctx);
8337 TCGv_i64 fp0 = tcg_temp_new_i64();
8338 TCGv_i64 fp1 = tcg_temp_new_i64();
8340 gen_load_fpr64(ctx, fp0, fs);
8341 gen_load_fpr64(ctx, fp1, ft);
8342 gen_helper_float_sub_ps(fp0, cpu_env, fp0, fp1);
8343 tcg_temp_free_i64(fp1);
8344 gen_store_fpr64(ctx, fp0, fd);
8345 tcg_temp_free_i64(fp0);
8347 opn = "sub.ps";
8348 break;
8349 case OPC_MUL_PS:
8350 check_cp1_64bitmode(ctx);
8352 TCGv_i64 fp0 = tcg_temp_new_i64();
8353 TCGv_i64 fp1 = tcg_temp_new_i64();
8355 gen_load_fpr64(ctx, fp0, fs);
8356 gen_load_fpr64(ctx, fp1, ft);
8357 gen_helper_float_mul_ps(fp0, cpu_env, fp0, fp1);
8358 tcg_temp_free_i64(fp1);
8359 gen_store_fpr64(ctx, fp0, fd);
8360 tcg_temp_free_i64(fp0);
8362 opn = "mul.ps";
8363 break;
8364 case OPC_ABS_PS:
8365 check_cp1_64bitmode(ctx);
8367 TCGv_i64 fp0 = tcg_temp_new_i64();
8369 gen_load_fpr64(ctx, fp0, fs);
8370 gen_helper_float_abs_ps(fp0, fp0);
8371 gen_store_fpr64(ctx, fp0, fd);
8372 tcg_temp_free_i64(fp0);
8374 opn = "abs.ps";
8375 break;
8376 case OPC_MOV_PS:
8377 check_cp1_64bitmode(ctx);
8379 TCGv_i64 fp0 = tcg_temp_new_i64();
8381 gen_load_fpr64(ctx, fp0, fs);
8382 gen_store_fpr64(ctx, fp0, fd);
8383 tcg_temp_free_i64(fp0);
8385 opn = "mov.ps";
8386 break;
8387 case OPC_NEG_PS:
8388 check_cp1_64bitmode(ctx);
8390 TCGv_i64 fp0 = tcg_temp_new_i64();
8392 gen_load_fpr64(ctx, fp0, fs);
8393 gen_helper_float_chs_ps(fp0, fp0);
8394 gen_store_fpr64(ctx, fp0, fd);
8395 tcg_temp_free_i64(fp0);
8397 opn = "neg.ps";
8398 break;
8399 case OPC_MOVCF_PS:
8400 check_cp1_64bitmode(ctx);
8401 gen_movcf_ps(ctx, fs, fd, (ft >> 2) & 0x7, ft & 0x1);
8402 opn = "movcf.ps";
8403 break;
8404 case OPC_MOVZ_PS:
8405 check_cp1_64bitmode(ctx);
8407 int l1 = gen_new_label();
8408 TCGv_i64 fp0;
8410 if (ft != 0)
8411 tcg_gen_brcondi_tl(TCG_COND_NE, cpu_gpr[ft], 0, l1);
8412 fp0 = tcg_temp_new_i64();
8413 gen_load_fpr64(ctx, fp0, fs);
8414 gen_store_fpr64(ctx, fp0, fd);
8415 tcg_temp_free_i64(fp0);
8416 gen_set_label(l1);
8418 opn = "movz.ps";
8419 break;
8420 case OPC_MOVN_PS:
8421 check_cp1_64bitmode(ctx);
8423 int l1 = gen_new_label();
8424 TCGv_i64 fp0;
8426 if (ft != 0) {
8427 tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_gpr[ft], 0, l1);
8428 fp0 = tcg_temp_new_i64();
8429 gen_load_fpr64(ctx, fp0, fs);
8430 gen_store_fpr64(ctx, fp0, fd);
8431 tcg_temp_free_i64(fp0);
8432 gen_set_label(l1);
8435 opn = "movn.ps";
8436 break;
8437 case OPC_ADDR_PS:
8438 check_cp1_64bitmode(ctx);
8440 TCGv_i64 fp0 = tcg_temp_new_i64();
8441 TCGv_i64 fp1 = tcg_temp_new_i64();
8443 gen_load_fpr64(ctx, fp0, ft);
8444 gen_load_fpr64(ctx, fp1, fs);
8445 gen_helper_float_addr_ps(fp0, cpu_env, fp0, fp1);
8446 tcg_temp_free_i64(fp1);
8447 gen_store_fpr64(ctx, fp0, fd);
8448 tcg_temp_free_i64(fp0);
8450 opn = "addr.ps";
8451 break;
8452 case OPC_MULR_PS:
8453 check_cp1_64bitmode(ctx);
8455 TCGv_i64 fp0 = tcg_temp_new_i64();
8456 TCGv_i64 fp1 = tcg_temp_new_i64();
8458 gen_load_fpr64(ctx, fp0, ft);
8459 gen_load_fpr64(ctx, fp1, fs);
8460 gen_helper_float_mulr_ps(fp0, cpu_env, fp0, fp1);
8461 tcg_temp_free_i64(fp1);
8462 gen_store_fpr64(ctx, fp0, fd);
8463 tcg_temp_free_i64(fp0);
8465 opn = "mulr.ps";
8466 break;
8467 case OPC_RECIP2_PS:
8468 check_cp1_64bitmode(ctx);
8470 TCGv_i64 fp0 = tcg_temp_new_i64();
8471 TCGv_i64 fp1 = tcg_temp_new_i64();
8473 gen_load_fpr64(ctx, fp0, fs);
8474 gen_load_fpr64(ctx, fp1, ft);
8475 gen_helper_float_recip2_ps(fp0, cpu_env, fp0, fp1);
8476 tcg_temp_free_i64(fp1);
8477 gen_store_fpr64(ctx, fp0, fd);
8478 tcg_temp_free_i64(fp0);
8480 opn = "recip2.ps";
8481 break;
8482 case OPC_RECIP1_PS:
8483 check_cp1_64bitmode(ctx);
8485 TCGv_i64 fp0 = tcg_temp_new_i64();
8487 gen_load_fpr64(ctx, fp0, fs);
8488 gen_helper_float_recip1_ps(fp0, cpu_env, fp0);
8489 gen_store_fpr64(ctx, fp0, fd);
8490 tcg_temp_free_i64(fp0);
8492 opn = "recip1.ps";
8493 break;
8494 case OPC_RSQRT1_PS:
8495 check_cp1_64bitmode(ctx);
8497 TCGv_i64 fp0 = tcg_temp_new_i64();
8499 gen_load_fpr64(ctx, fp0, fs);
8500 gen_helper_float_rsqrt1_ps(fp0, cpu_env, fp0);
8501 gen_store_fpr64(ctx, fp0, fd);
8502 tcg_temp_free_i64(fp0);
8504 opn = "rsqrt1.ps";
8505 break;
8506 case OPC_RSQRT2_PS:
8507 check_cp1_64bitmode(ctx);
8509 TCGv_i64 fp0 = tcg_temp_new_i64();
8510 TCGv_i64 fp1 = tcg_temp_new_i64();
8512 gen_load_fpr64(ctx, fp0, fs);
8513 gen_load_fpr64(ctx, fp1, ft);
8514 gen_helper_float_rsqrt2_ps(fp0, cpu_env, fp0, fp1);
8515 tcg_temp_free_i64(fp1);
8516 gen_store_fpr64(ctx, fp0, fd);
8517 tcg_temp_free_i64(fp0);
8519 opn = "rsqrt2.ps";
8520 break;
8521 case OPC_CVT_S_PU:
8522 check_cp1_64bitmode(ctx);
8524 TCGv_i32 fp0 = tcg_temp_new_i32();
8526 gen_load_fpr32h(ctx, fp0, fs);
8527 gen_helper_float_cvts_pu(fp0, cpu_env, fp0);
8528 gen_store_fpr32(fp0, fd);
8529 tcg_temp_free_i32(fp0);
8531 opn = "cvt.s.pu";
8532 break;
8533 case OPC_CVT_PW_PS:
8534 check_cp1_64bitmode(ctx);
8536 TCGv_i64 fp0 = tcg_temp_new_i64();
8538 gen_load_fpr64(ctx, fp0, fs);
8539 gen_helper_float_cvtpw_ps(fp0, cpu_env, fp0);
8540 gen_store_fpr64(ctx, fp0, fd);
8541 tcg_temp_free_i64(fp0);
8543 opn = "cvt.pw.ps";
8544 break;
8545 case OPC_CVT_S_PL:
8546 check_cp1_64bitmode(ctx);
8548 TCGv_i32 fp0 = tcg_temp_new_i32();
8550 gen_load_fpr32(fp0, fs);
8551 gen_helper_float_cvts_pl(fp0, cpu_env, fp0);
8552 gen_store_fpr32(fp0, fd);
8553 tcg_temp_free_i32(fp0);
8555 opn = "cvt.s.pl";
8556 break;
8557 case OPC_PLL_PS:
8558 check_cp1_64bitmode(ctx);
8560 TCGv_i32 fp0 = tcg_temp_new_i32();
8561 TCGv_i32 fp1 = tcg_temp_new_i32();
8563 gen_load_fpr32(fp0, fs);
8564 gen_load_fpr32(fp1, ft);
8565 gen_store_fpr32h(ctx, fp0, fd);
8566 gen_store_fpr32(fp1, fd);
8567 tcg_temp_free_i32(fp0);
8568 tcg_temp_free_i32(fp1);
8570 opn = "pll.ps";
8571 break;
8572 case OPC_PLU_PS:
8573 check_cp1_64bitmode(ctx);
8575 TCGv_i32 fp0 = tcg_temp_new_i32();
8576 TCGv_i32 fp1 = tcg_temp_new_i32();
8578 gen_load_fpr32(fp0, fs);
8579 gen_load_fpr32h(ctx, fp1, ft);
8580 gen_store_fpr32(fp1, fd);
8581 gen_store_fpr32h(ctx, fp0, fd);
8582 tcg_temp_free_i32(fp0);
8583 tcg_temp_free_i32(fp1);
8585 opn = "plu.ps";
8586 break;
8587 case OPC_PUL_PS:
8588 check_cp1_64bitmode(ctx);
8590 TCGv_i32 fp0 = tcg_temp_new_i32();
8591 TCGv_i32 fp1 = tcg_temp_new_i32();
8593 gen_load_fpr32h(ctx, fp0, fs);
8594 gen_load_fpr32(fp1, ft);
8595 gen_store_fpr32(fp1, fd);
8596 gen_store_fpr32h(ctx, fp0, fd);
8597 tcg_temp_free_i32(fp0);
8598 tcg_temp_free_i32(fp1);
8600 opn = "pul.ps";
8601 break;
8602 case OPC_PUU_PS:
8603 check_cp1_64bitmode(ctx);
8605 TCGv_i32 fp0 = tcg_temp_new_i32();
8606 TCGv_i32 fp1 = tcg_temp_new_i32();
8608 gen_load_fpr32h(ctx, fp0, fs);
8609 gen_load_fpr32h(ctx, fp1, ft);
8610 gen_store_fpr32(fp1, fd);
8611 gen_store_fpr32h(ctx, fp0, fd);
8612 tcg_temp_free_i32(fp0);
8613 tcg_temp_free_i32(fp1);
8615 opn = "puu.ps";
8616 break;
8617 case OPC_CMP_F_PS:
8618 case OPC_CMP_UN_PS:
8619 case OPC_CMP_EQ_PS:
8620 case OPC_CMP_UEQ_PS:
8621 case OPC_CMP_OLT_PS:
8622 case OPC_CMP_ULT_PS:
8623 case OPC_CMP_OLE_PS:
8624 case OPC_CMP_ULE_PS:
8625 case OPC_CMP_SF_PS:
8626 case OPC_CMP_NGLE_PS:
8627 case OPC_CMP_SEQ_PS:
8628 case OPC_CMP_NGL_PS:
8629 case OPC_CMP_LT_PS:
8630 case OPC_CMP_NGE_PS:
8631 case OPC_CMP_LE_PS:
8632 case OPC_CMP_NGT_PS:
8633 if (ctx->opcode & (1 << 6)) {
8634 gen_cmpabs_ps(ctx, func-48, ft, fs, cc);
8635 opn = condnames_abs[func-48];
8636 } else {
8637 gen_cmp_ps(ctx, func-48, ft, fs, cc);
8638 opn = condnames[func-48];
8640 break;
8641 default:
8642 MIPS_INVAL(opn);
8643 generate_exception (ctx, EXCP_RI);
8644 return;
8646 (void)opn; /* avoid a compiler warning */
8647 switch (optype) {
8648 case BINOP:
8649 MIPS_DEBUG("%s %s, %s, %s", opn, fregnames[fd], fregnames[fs], fregnames[ft]);
8650 break;
8651 case CMPOP:
8652 MIPS_DEBUG("%s %s,%s", opn, fregnames[fs], fregnames[ft]);
8653 break;
8654 default:
8655 MIPS_DEBUG("%s %s,%s", opn, fregnames[fd], fregnames[fs]);
8656 break;
8660 /* Coprocessor 3 (FPU) */
8661 static void gen_flt3_ldst (DisasContext *ctx, uint32_t opc,
8662 int fd, int fs, int base, int index)
8664 const char *opn = "extended float load/store";
8665 int store = 0;
8666 TCGv t0 = tcg_temp_new();
8668 if (base == 0) {
8669 gen_load_gpr(t0, index);
8670 } else if (index == 0) {
8671 gen_load_gpr(t0, base);
8672 } else {
8673 gen_op_addr_add(ctx, t0, cpu_gpr[base], cpu_gpr[index]);
8675 /* Don't do NOP if destination is zero: we must perform the actual
8676 memory access. */
8677 switch (opc) {
8678 case OPC_LWXC1:
8679 check_cop1x(ctx);
8681 TCGv_i32 fp0 = tcg_temp_new_i32();
8683 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TESL);
8684 tcg_gen_trunc_tl_i32(fp0, t0);
8685 gen_store_fpr32(fp0, fd);
8686 tcg_temp_free_i32(fp0);
8688 opn = "lwxc1";
8689 break;
8690 case OPC_LDXC1:
8691 check_cop1x(ctx);
8692 check_cp1_registers(ctx, fd);
8694 TCGv_i64 fp0 = tcg_temp_new_i64();
8695 tcg_gen_qemu_ld_i64(fp0, t0, ctx->mem_idx, MO_TEQ);
8696 gen_store_fpr64(ctx, fp0, fd);
8697 tcg_temp_free_i64(fp0);
8699 opn = "ldxc1";
8700 break;
8701 case OPC_LUXC1:
8702 check_cp1_64bitmode(ctx);
8703 tcg_gen_andi_tl(t0, t0, ~0x7);
8705 TCGv_i64 fp0 = tcg_temp_new_i64();
8707 tcg_gen_qemu_ld_i64(fp0, t0, ctx->mem_idx, MO_TEQ);
8708 gen_store_fpr64(ctx, fp0, fd);
8709 tcg_temp_free_i64(fp0);
8711 opn = "luxc1";
8712 break;
8713 case OPC_SWXC1:
8714 check_cop1x(ctx);
8716 TCGv_i32 fp0 = tcg_temp_new_i32();
8717 gen_load_fpr32(fp0, fs);
8718 tcg_gen_qemu_st_i32(fp0, t0, ctx->mem_idx, MO_TEUL);
8719 tcg_temp_free_i32(fp0);
8721 opn = "swxc1";
8722 store = 1;
8723 break;
8724 case OPC_SDXC1:
8725 check_cop1x(ctx);
8726 check_cp1_registers(ctx, fs);
8728 TCGv_i64 fp0 = tcg_temp_new_i64();
8729 gen_load_fpr64(ctx, fp0, fs);
8730 tcg_gen_qemu_st_i64(fp0, t0, ctx->mem_idx, MO_TEQ);
8731 tcg_temp_free_i64(fp0);
8733 opn = "sdxc1";
8734 store = 1;
8735 break;
8736 case OPC_SUXC1:
8737 check_cp1_64bitmode(ctx);
8738 tcg_gen_andi_tl(t0, t0, ~0x7);
8740 TCGv_i64 fp0 = tcg_temp_new_i64();
8741 gen_load_fpr64(ctx, fp0, fs);
8742 tcg_gen_qemu_st_i64(fp0, t0, ctx->mem_idx, MO_TEQ);
8743 tcg_temp_free_i64(fp0);
8745 opn = "suxc1";
8746 store = 1;
8747 break;
8749 tcg_temp_free(t0);
8750 (void)opn; (void)store; /* avoid compiler warnings */
8751 MIPS_DEBUG("%s %s, %s(%s)", opn, fregnames[store ? fs : fd],
8752 regnames[index], regnames[base]);
8755 static void gen_flt3_arith (DisasContext *ctx, uint32_t opc,
8756 int fd, int fr, int fs, int ft)
8758 const char *opn = "flt3_arith";
8760 switch (opc) {
8761 case OPC_ALNV_PS:
8762 check_cp1_64bitmode(ctx);
8764 TCGv t0 = tcg_temp_local_new();
8765 TCGv_i32 fp = tcg_temp_new_i32();
8766 TCGv_i32 fph = tcg_temp_new_i32();
8767 int l1 = gen_new_label();
8768 int l2 = gen_new_label();
8770 gen_load_gpr(t0, fr);
8771 tcg_gen_andi_tl(t0, t0, 0x7);
8773 tcg_gen_brcondi_tl(TCG_COND_NE, t0, 0, l1);
8774 gen_load_fpr32(fp, fs);
8775 gen_load_fpr32h(ctx, fph, fs);
8776 gen_store_fpr32(fp, fd);
8777 gen_store_fpr32h(ctx, fph, fd);
8778 tcg_gen_br(l2);
8779 gen_set_label(l1);
8780 tcg_gen_brcondi_tl(TCG_COND_NE, t0, 4, l2);
8781 tcg_temp_free(t0);
8782 #ifdef TARGET_WORDS_BIGENDIAN
8783 gen_load_fpr32(fp, fs);
8784 gen_load_fpr32h(ctx, fph, ft);
8785 gen_store_fpr32h(ctx, fp, fd);
8786 gen_store_fpr32(fph, fd);
8787 #else
8788 gen_load_fpr32h(ctx, fph, fs);
8789 gen_load_fpr32(fp, ft);
8790 gen_store_fpr32(fph, fd);
8791 gen_store_fpr32h(ctx, fp, fd);
8792 #endif
8793 gen_set_label(l2);
8794 tcg_temp_free_i32(fp);
8795 tcg_temp_free_i32(fph);
8797 opn = "alnv.ps";
8798 break;
8799 case OPC_MADD_S:
8800 check_cop1x(ctx);
8802 TCGv_i32 fp0 = tcg_temp_new_i32();
8803 TCGv_i32 fp1 = tcg_temp_new_i32();
8804 TCGv_i32 fp2 = tcg_temp_new_i32();
8806 gen_load_fpr32(fp0, fs);
8807 gen_load_fpr32(fp1, ft);
8808 gen_load_fpr32(fp2, fr);
8809 gen_helper_float_madd_s(fp2, cpu_env, fp0, fp1, fp2);
8810 tcg_temp_free_i32(fp0);
8811 tcg_temp_free_i32(fp1);
8812 gen_store_fpr32(fp2, fd);
8813 tcg_temp_free_i32(fp2);
8815 opn = "madd.s";
8816 break;
8817 case OPC_MADD_D:
8818 check_cop1x(ctx);
8819 check_cp1_registers(ctx, fd | fs | ft | fr);
8821 TCGv_i64 fp0 = tcg_temp_new_i64();
8822 TCGv_i64 fp1 = tcg_temp_new_i64();
8823 TCGv_i64 fp2 = tcg_temp_new_i64();
8825 gen_load_fpr64(ctx, fp0, fs);
8826 gen_load_fpr64(ctx, fp1, ft);
8827 gen_load_fpr64(ctx, fp2, fr);
8828 gen_helper_float_madd_d(fp2, cpu_env, fp0, fp1, fp2);
8829 tcg_temp_free_i64(fp0);
8830 tcg_temp_free_i64(fp1);
8831 gen_store_fpr64(ctx, fp2, fd);
8832 tcg_temp_free_i64(fp2);
8834 opn = "madd.d";
8835 break;
8836 case OPC_MADD_PS:
8837 check_cp1_64bitmode(ctx);
8839 TCGv_i64 fp0 = tcg_temp_new_i64();
8840 TCGv_i64 fp1 = tcg_temp_new_i64();
8841 TCGv_i64 fp2 = tcg_temp_new_i64();
8843 gen_load_fpr64(ctx, fp0, fs);
8844 gen_load_fpr64(ctx, fp1, ft);
8845 gen_load_fpr64(ctx, fp2, fr);
8846 gen_helper_float_madd_ps(fp2, cpu_env, fp0, fp1, fp2);
8847 tcg_temp_free_i64(fp0);
8848 tcg_temp_free_i64(fp1);
8849 gen_store_fpr64(ctx, fp2, fd);
8850 tcg_temp_free_i64(fp2);
8852 opn = "madd.ps";
8853 break;
8854 case OPC_MSUB_S:
8855 check_cop1x(ctx);
8857 TCGv_i32 fp0 = tcg_temp_new_i32();
8858 TCGv_i32 fp1 = tcg_temp_new_i32();
8859 TCGv_i32 fp2 = tcg_temp_new_i32();
8861 gen_load_fpr32(fp0, fs);
8862 gen_load_fpr32(fp1, ft);
8863 gen_load_fpr32(fp2, fr);
8864 gen_helper_float_msub_s(fp2, cpu_env, fp0, fp1, fp2);
8865 tcg_temp_free_i32(fp0);
8866 tcg_temp_free_i32(fp1);
8867 gen_store_fpr32(fp2, fd);
8868 tcg_temp_free_i32(fp2);
8870 opn = "msub.s";
8871 break;
8872 case OPC_MSUB_D:
8873 check_cop1x(ctx);
8874 check_cp1_registers(ctx, fd | fs | ft | fr);
8876 TCGv_i64 fp0 = tcg_temp_new_i64();
8877 TCGv_i64 fp1 = tcg_temp_new_i64();
8878 TCGv_i64 fp2 = tcg_temp_new_i64();
8880 gen_load_fpr64(ctx, fp0, fs);
8881 gen_load_fpr64(ctx, fp1, ft);
8882 gen_load_fpr64(ctx, fp2, fr);
8883 gen_helper_float_msub_d(fp2, cpu_env, fp0, fp1, fp2);
8884 tcg_temp_free_i64(fp0);
8885 tcg_temp_free_i64(fp1);
8886 gen_store_fpr64(ctx, fp2, fd);
8887 tcg_temp_free_i64(fp2);
8889 opn = "msub.d";
8890 break;
8891 case OPC_MSUB_PS:
8892 check_cp1_64bitmode(ctx);
8894 TCGv_i64 fp0 = tcg_temp_new_i64();
8895 TCGv_i64 fp1 = tcg_temp_new_i64();
8896 TCGv_i64 fp2 = tcg_temp_new_i64();
8898 gen_load_fpr64(ctx, fp0, fs);
8899 gen_load_fpr64(ctx, fp1, ft);
8900 gen_load_fpr64(ctx, fp2, fr);
8901 gen_helper_float_msub_ps(fp2, cpu_env, fp0, fp1, fp2);
8902 tcg_temp_free_i64(fp0);
8903 tcg_temp_free_i64(fp1);
8904 gen_store_fpr64(ctx, fp2, fd);
8905 tcg_temp_free_i64(fp2);
8907 opn = "msub.ps";
8908 break;
8909 case OPC_NMADD_S:
8910 check_cop1x(ctx);
8912 TCGv_i32 fp0 = tcg_temp_new_i32();
8913 TCGv_i32 fp1 = tcg_temp_new_i32();
8914 TCGv_i32 fp2 = tcg_temp_new_i32();
8916 gen_load_fpr32(fp0, fs);
8917 gen_load_fpr32(fp1, ft);
8918 gen_load_fpr32(fp2, fr);
8919 gen_helper_float_nmadd_s(fp2, cpu_env, fp0, fp1, fp2);
8920 tcg_temp_free_i32(fp0);
8921 tcg_temp_free_i32(fp1);
8922 gen_store_fpr32(fp2, fd);
8923 tcg_temp_free_i32(fp2);
8925 opn = "nmadd.s";
8926 break;
8927 case OPC_NMADD_D:
8928 check_cop1x(ctx);
8929 check_cp1_registers(ctx, fd | fs | ft | fr);
8931 TCGv_i64 fp0 = tcg_temp_new_i64();
8932 TCGv_i64 fp1 = tcg_temp_new_i64();
8933 TCGv_i64 fp2 = tcg_temp_new_i64();
8935 gen_load_fpr64(ctx, fp0, fs);
8936 gen_load_fpr64(ctx, fp1, ft);
8937 gen_load_fpr64(ctx, fp2, fr);
8938 gen_helper_float_nmadd_d(fp2, cpu_env, fp0, fp1, fp2);
8939 tcg_temp_free_i64(fp0);
8940 tcg_temp_free_i64(fp1);
8941 gen_store_fpr64(ctx, fp2, fd);
8942 tcg_temp_free_i64(fp2);
8944 opn = "nmadd.d";
8945 break;
8946 case OPC_NMADD_PS:
8947 check_cp1_64bitmode(ctx);
8949 TCGv_i64 fp0 = tcg_temp_new_i64();
8950 TCGv_i64 fp1 = tcg_temp_new_i64();
8951 TCGv_i64 fp2 = tcg_temp_new_i64();
8953 gen_load_fpr64(ctx, fp0, fs);
8954 gen_load_fpr64(ctx, fp1, ft);
8955 gen_load_fpr64(ctx, fp2, fr);
8956 gen_helper_float_nmadd_ps(fp2, cpu_env, fp0, fp1, fp2);
8957 tcg_temp_free_i64(fp0);
8958 tcg_temp_free_i64(fp1);
8959 gen_store_fpr64(ctx, fp2, fd);
8960 tcg_temp_free_i64(fp2);
8962 opn = "nmadd.ps";
8963 break;
8964 case OPC_NMSUB_S:
8965 check_cop1x(ctx);
8967 TCGv_i32 fp0 = tcg_temp_new_i32();
8968 TCGv_i32 fp1 = tcg_temp_new_i32();
8969 TCGv_i32 fp2 = tcg_temp_new_i32();
8971 gen_load_fpr32(fp0, fs);
8972 gen_load_fpr32(fp1, ft);
8973 gen_load_fpr32(fp2, fr);
8974 gen_helper_float_nmsub_s(fp2, cpu_env, fp0, fp1, fp2);
8975 tcg_temp_free_i32(fp0);
8976 tcg_temp_free_i32(fp1);
8977 gen_store_fpr32(fp2, fd);
8978 tcg_temp_free_i32(fp2);
8980 opn = "nmsub.s";
8981 break;
8982 case OPC_NMSUB_D:
8983 check_cop1x(ctx);
8984 check_cp1_registers(ctx, fd | fs | ft | fr);
8986 TCGv_i64 fp0 = tcg_temp_new_i64();
8987 TCGv_i64 fp1 = tcg_temp_new_i64();
8988 TCGv_i64 fp2 = tcg_temp_new_i64();
8990 gen_load_fpr64(ctx, fp0, fs);
8991 gen_load_fpr64(ctx, fp1, ft);
8992 gen_load_fpr64(ctx, fp2, fr);
8993 gen_helper_float_nmsub_d(fp2, cpu_env, fp0, fp1, fp2);
8994 tcg_temp_free_i64(fp0);
8995 tcg_temp_free_i64(fp1);
8996 gen_store_fpr64(ctx, fp2, fd);
8997 tcg_temp_free_i64(fp2);
8999 opn = "nmsub.d";
9000 break;
9001 case OPC_NMSUB_PS:
9002 check_cp1_64bitmode(ctx);
9004 TCGv_i64 fp0 = tcg_temp_new_i64();
9005 TCGv_i64 fp1 = tcg_temp_new_i64();
9006 TCGv_i64 fp2 = tcg_temp_new_i64();
9008 gen_load_fpr64(ctx, fp0, fs);
9009 gen_load_fpr64(ctx, fp1, ft);
9010 gen_load_fpr64(ctx, fp2, fr);
9011 gen_helper_float_nmsub_ps(fp2, cpu_env, fp0, fp1, fp2);
9012 tcg_temp_free_i64(fp0);
9013 tcg_temp_free_i64(fp1);
9014 gen_store_fpr64(ctx, fp2, fd);
9015 tcg_temp_free_i64(fp2);
9017 opn = "nmsub.ps";
9018 break;
9019 default:
9020 MIPS_INVAL(opn);
9021 generate_exception (ctx, EXCP_RI);
9022 return;
9024 (void)opn; /* avoid a compiler warning */
9025 MIPS_DEBUG("%s %s, %s, %s, %s", opn, fregnames[fd], fregnames[fr],
9026 fregnames[fs], fregnames[ft]);
9029 static void gen_rdhwr(DisasContext *ctx, int rt, int rd)
9031 TCGv t0;
9033 #if !defined(CONFIG_USER_ONLY)
9034 /* The Linux kernel will emulate rdhwr if it's not supported natively.
9035 Therefore only check the ISA in system mode. */
9036 check_insn(ctx, ISA_MIPS32R2);
9037 #endif
9038 t0 = tcg_temp_new();
9040 switch (rd) {
9041 case 0:
9042 save_cpu_state(ctx, 1);
9043 gen_helper_rdhwr_cpunum(t0, cpu_env);
9044 gen_store_gpr(t0, rt);
9045 break;
9046 case 1:
9047 save_cpu_state(ctx, 1);
9048 gen_helper_rdhwr_synci_step(t0, cpu_env);
9049 gen_store_gpr(t0, rt);
9050 break;
9051 case 2:
9052 save_cpu_state(ctx, 1);
9053 gen_helper_rdhwr_cc(t0, cpu_env);
9054 gen_store_gpr(t0, rt);
9055 break;
9056 case 3:
9057 save_cpu_state(ctx, 1);
9058 gen_helper_rdhwr_ccres(t0, cpu_env);
9059 gen_store_gpr(t0, rt);
9060 break;
9061 case 29:
9062 #if defined(CONFIG_USER_ONLY)
9063 tcg_gen_ld_tl(t0, cpu_env, offsetof(CPUMIPSState, tls_value));
9064 gen_store_gpr(t0, rt);
9065 break;
9066 #else
9067 /* XXX: Some CPUs implement this in hardware.
9068 Not supported yet. */
9069 #endif
9070 default: /* Invalid */
9071 MIPS_INVAL("rdhwr");
9072 generate_exception(ctx, EXCP_RI);
9073 break;
9075 tcg_temp_free(t0);
9078 static void handle_delay_slot(DisasContext *ctx, int insn_bytes)
9080 if (ctx->hflags & MIPS_HFLAG_BMASK) {
9081 int proc_hflags = ctx->hflags & MIPS_HFLAG_BMASK;
9082 /* Branches completion */
9083 ctx->hflags &= ~MIPS_HFLAG_BMASK;
9084 ctx->bstate = BS_BRANCH;
9085 save_cpu_state(ctx, 0);
9086 /* FIXME: Need to clear can_do_io. */
9087 switch (proc_hflags & MIPS_HFLAG_BMASK_BASE) {
9088 case MIPS_HFLAG_B:
9089 /* unconditional branch */
9090 MIPS_DEBUG("unconditional branch");
9091 if (proc_hflags & MIPS_HFLAG_BX) {
9092 tcg_gen_xori_i32(hflags, hflags, MIPS_HFLAG_M16);
9094 gen_goto_tb(ctx, 0, ctx->btarget);
9095 break;
9096 case MIPS_HFLAG_BL:
9097 /* blikely taken case */
9098 MIPS_DEBUG("blikely branch taken");
9099 gen_goto_tb(ctx, 0, ctx->btarget);
9100 break;
9101 case MIPS_HFLAG_BC:
9102 /* Conditional branch */
9103 MIPS_DEBUG("conditional branch");
9105 int l1 = gen_new_label();
9107 tcg_gen_brcondi_tl(TCG_COND_NE, bcond, 0, l1);
9108 gen_goto_tb(ctx, 1, ctx->pc + insn_bytes);
9109 gen_set_label(l1);
9110 gen_goto_tb(ctx, 0, ctx->btarget);
9112 break;
9113 case MIPS_HFLAG_BR:
9114 /* unconditional branch to register */
9115 MIPS_DEBUG("branch to register");
9116 if (ctx->insn_flags & (ASE_MIPS16 | ASE_MICROMIPS)) {
9117 TCGv t0 = tcg_temp_new();
9118 TCGv_i32 t1 = tcg_temp_new_i32();
9120 tcg_gen_andi_tl(t0, btarget, 0x1);
9121 tcg_gen_trunc_tl_i32(t1, t0);
9122 tcg_temp_free(t0);
9123 tcg_gen_andi_i32(hflags, hflags, ~(uint32_t)MIPS_HFLAG_M16);
9124 tcg_gen_shli_i32(t1, t1, MIPS_HFLAG_M16_SHIFT);
9125 tcg_gen_or_i32(hflags, hflags, t1);
9126 tcg_temp_free_i32(t1);
9128 tcg_gen_andi_tl(cpu_PC, btarget, ~(target_ulong)0x1);
9129 } else {
9130 tcg_gen_mov_tl(cpu_PC, btarget);
9132 if (ctx->singlestep_enabled) {
9133 save_cpu_state(ctx, 0);
9134 gen_helper_0e0i(raise_exception, EXCP_DEBUG);
9136 tcg_gen_exit_tb(0);
9137 break;
9138 default:
9139 MIPS_DEBUG("unknown branch");
9140 break;
9145 /* ISA extensions (ASEs) */
9146 /* MIPS16 extension to MIPS32 */
9148 /* MIPS16 major opcodes */
9149 enum {
9150 M16_OPC_ADDIUSP = 0x00,
9151 M16_OPC_ADDIUPC = 0x01,
9152 M16_OPC_B = 0x02,
9153 M16_OPC_JAL = 0x03,
9154 M16_OPC_BEQZ = 0x04,
9155 M16_OPC_BNEQZ = 0x05,
9156 M16_OPC_SHIFT = 0x06,
9157 M16_OPC_LD = 0x07,
9158 M16_OPC_RRIA = 0x08,
9159 M16_OPC_ADDIU8 = 0x09,
9160 M16_OPC_SLTI = 0x0a,
9161 M16_OPC_SLTIU = 0x0b,
9162 M16_OPC_I8 = 0x0c,
9163 M16_OPC_LI = 0x0d,
9164 M16_OPC_CMPI = 0x0e,
9165 M16_OPC_SD = 0x0f,
9166 M16_OPC_LB = 0x10,
9167 M16_OPC_LH = 0x11,
9168 M16_OPC_LWSP = 0x12,
9169 M16_OPC_LW = 0x13,
9170 M16_OPC_LBU = 0x14,
9171 M16_OPC_LHU = 0x15,
9172 M16_OPC_LWPC = 0x16,
9173 M16_OPC_LWU = 0x17,
9174 M16_OPC_SB = 0x18,
9175 M16_OPC_SH = 0x19,
9176 M16_OPC_SWSP = 0x1a,
9177 M16_OPC_SW = 0x1b,
9178 M16_OPC_RRR = 0x1c,
9179 M16_OPC_RR = 0x1d,
9180 M16_OPC_EXTEND = 0x1e,
9181 M16_OPC_I64 = 0x1f
9184 /* I8 funct field */
9185 enum {
9186 I8_BTEQZ = 0x0,
9187 I8_BTNEZ = 0x1,
9188 I8_SWRASP = 0x2,
9189 I8_ADJSP = 0x3,
9190 I8_SVRS = 0x4,
9191 I8_MOV32R = 0x5,
9192 I8_MOVR32 = 0x7
9195 /* RRR f field */
9196 enum {
9197 RRR_DADDU = 0x0,
9198 RRR_ADDU = 0x1,
9199 RRR_DSUBU = 0x2,
9200 RRR_SUBU = 0x3
9203 /* RR funct field */
9204 enum {
9205 RR_JR = 0x00,
9206 RR_SDBBP = 0x01,
9207 RR_SLT = 0x02,
9208 RR_SLTU = 0x03,
9209 RR_SLLV = 0x04,
9210 RR_BREAK = 0x05,
9211 RR_SRLV = 0x06,
9212 RR_SRAV = 0x07,
9213 RR_DSRL = 0x08,
9214 RR_CMP = 0x0a,
9215 RR_NEG = 0x0b,
9216 RR_AND = 0x0c,
9217 RR_OR = 0x0d,
9218 RR_XOR = 0x0e,
9219 RR_NOT = 0x0f,
9220 RR_MFHI = 0x10,
9221 RR_CNVT = 0x11,
9222 RR_MFLO = 0x12,
9223 RR_DSRA = 0x13,
9224 RR_DSLLV = 0x14,
9225 RR_DSRLV = 0x16,
9226 RR_DSRAV = 0x17,
9227 RR_MULT = 0x18,
9228 RR_MULTU = 0x19,
9229 RR_DIV = 0x1a,
9230 RR_DIVU = 0x1b,
9231 RR_DMULT = 0x1c,
9232 RR_DMULTU = 0x1d,
9233 RR_DDIV = 0x1e,
9234 RR_DDIVU = 0x1f
9237 /* I64 funct field */
9238 enum {
9239 I64_LDSP = 0x0,
9240 I64_SDSP = 0x1,
9241 I64_SDRASP = 0x2,
9242 I64_DADJSP = 0x3,
9243 I64_LDPC = 0x4,
9244 I64_DADDIU5 = 0x5,
9245 I64_DADDIUPC = 0x6,
9246 I64_DADDIUSP = 0x7
9249 /* RR ry field for CNVT */
9250 enum {
9251 RR_RY_CNVT_ZEB = 0x0,
9252 RR_RY_CNVT_ZEH = 0x1,
9253 RR_RY_CNVT_ZEW = 0x2,
9254 RR_RY_CNVT_SEB = 0x4,
9255 RR_RY_CNVT_SEH = 0x5,
9256 RR_RY_CNVT_SEW = 0x6,
9259 static int xlat (int r)
9261 static int map[] = { 16, 17, 2, 3, 4, 5, 6, 7 };
9263 return map[r];
9266 static void gen_mips16_save (DisasContext *ctx,
9267 int xsregs, int aregs,
9268 int do_ra, int do_s0, int do_s1,
9269 int framesize)
9271 TCGv t0 = tcg_temp_new();
9272 TCGv t1 = tcg_temp_new();
9273 int args, astatic;
9275 switch (aregs) {
9276 case 0:
9277 case 1:
9278 case 2:
9279 case 3:
9280 case 11:
9281 args = 0;
9282 break;
9283 case 4:
9284 case 5:
9285 case 6:
9286 case 7:
9287 args = 1;
9288 break;
9289 case 8:
9290 case 9:
9291 case 10:
9292 args = 2;
9293 break;
9294 case 12:
9295 case 13:
9296 args = 3;
9297 break;
9298 case 14:
9299 args = 4;
9300 break;
9301 default:
9302 generate_exception(ctx, EXCP_RI);
9303 return;
9306 switch (args) {
9307 case 4:
9308 gen_base_offset_addr(ctx, t0, 29, 12);
9309 gen_load_gpr(t1, 7);
9310 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL);
9311 /* Fall through */
9312 case 3:
9313 gen_base_offset_addr(ctx, t0, 29, 8);
9314 gen_load_gpr(t1, 6);
9315 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL);
9316 /* Fall through */
9317 case 2:
9318 gen_base_offset_addr(ctx, t0, 29, 4);
9319 gen_load_gpr(t1, 5);
9320 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL);
9321 /* Fall through */
9322 case 1:
9323 gen_base_offset_addr(ctx, t0, 29, 0);
9324 gen_load_gpr(t1, 4);
9325 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL);
9328 gen_load_gpr(t0, 29);
9330 #define DECR_AND_STORE(reg) do { \
9331 tcg_gen_subi_tl(t0, t0, 4); \
9332 gen_load_gpr(t1, reg); \
9333 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL); \
9334 } while (0)
9336 if (do_ra) {
9337 DECR_AND_STORE(31);
9340 switch (xsregs) {
9341 case 7:
9342 DECR_AND_STORE(30);
9343 /* Fall through */
9344 case 6:
9345 DECR_AND_STORE(23);
9346 /* Fall through */
9347 case 5:
9348 DECR_AND_STORE(22);
9349 /* Fall through */
9350 case 4:
9351 DECR_AND_STORE(21);
9352 /* Fall through */
9353 case 3:
9354 DECR_AND_STORE(20);
9355 /* Fall through */
9356 case 2:
9357 DECR_AND_STORE(19);
9358 /* Fall through */
9359 case 1:
9360 DECR_AND_STORE(18);
9363 if (do_s1) {
9364 DECR_AND_STORE(17);
9366 if (do_s0) {
9367 DECR_AND_STORE(16);
9370 switch (aregs) {
9371 case 0:
9372 case 4:
9373 case 8:
9374 case 12:
9375 case 14:
9376 astatic = 0;
9377 break;
9378 case 1:
9379 case 5:
9380 case 9:
9381 case 13:
9382 astatic = 1;
9383 break;
9384 case 2:
9385 case 6:
9386 case 10:
9387 astatic = 2;
9388 break;
9389 case 3:
9390 case 7:
9391 astatic = 3;
9392 break;
9393 case 11:
9394 astatic = 4;
9395 break;
9396 default:
9397 generate_exception(ctx, EXCP_RI);
9398 return;
9401 if (astatic > 0) {
9402 DECR_AND_STORE(7);
9403 if (astatic > 1) {
9404 DECR_AND_STORE(6);
9405 if (astatic > 2) {
9406 DECR_AND_STORE(5);
9407 if (astatic > 3) {
9408 DECR_AND_STORE(4);
9413 #undef DECR_AND_STORE
9415 tcg_gen_subi_tl(cpu_gpr[29], cpu_gpr[29], framesize);
9416 tcg_temp_free(t0);
9417 tcg_temp_free(t1);
9420 static void gen_mips16_restore (DisasContext *ctx,
9421 int xsregs, int aregs,
9422 int do_ra, int do_s0, int do_s1,
9423 int framesize)
9425 int astatic;
9426 TCGv t0 = tcg_temp_new();
9427 TCGv t1 = tcg_temp_new();
9429 tcg_gen_addi_tl(t0, cpu_gpr[29], framesize);
9431 #define DECR_AND_LOAD(reg) do { \
9432 tcg_gen_subi_tl(t0, t0, 4); \
9433 tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_TESL); \
9434 gen_store_gpr(t1, reg); \
9435 } while (0)
9437 if (do_ra) {
9438 DECR_AND_LOAD(31);
9441 switch (xsregs) {
9442 case 7:
9443 DECR_AND_LOAD(30);
9444 /* Fall through */
9445 case 6:
9446 DECR_AND_LOAD(23);
9447 /* Fall through */
9448 case 5:
9449 DECR_AND_LOAD(22);
9450 /* Fall through */
9451 case 4:
9452 DECR_AND_LOAD(21);
9453 /* Fall through */
9454 case 3:
9455 DECR_AND_LOAD(20);
9456 /* Fall through */
9457 case 2:
9458 DECR_AND_LOAD(19);
9459 /* Fall through */
9460 case 1:
9461 DECR_AND_LOAD(18);
9464 if (do_s1) {
9465 DECR_AND_LOAD(17);
9467 if (do_s0) {
9468 DECR_AND_LOAD(16);
9471 switch (aregs) {
9472 case 0:
9473 case 4:
9474 case 8:
9475 case 12:
9476 case 14:
9477 astatic = 0;
9478 break;
9479 case 1:
9480 case 5:
9481 case 9:
9482 case 13:
9483 astatic = 1;
9484 break;
9485 case 2:
9486 case 6:
9487 case 10:
9488 astatic = 2;
9489 break;
9490 case 3:
9491 case 7:
9492 astatic = 3;
9493 break;
9494 case 11:
9495 astatic = 4;
9496 break;
9497 default:
9498 generate_exception(ctx, EXCP_RI);
9499 return;
9502 if (astatic > 0) {
9503 DECR_AND_LOAD(7);
9504 if (astatic > 1) {
9505 DECR_AND_LOAD(6);
9506 if (astatic > 2) {
9507 DECR_AND_LOAD(5);
9508 if (astatic > 3) {
9509 DECR_AND_LOAD(4);
9514 #undef DECR_AND_LOAD
9516 tcg_gen_addi_tl(cpu_gpr[29], cpu_gpr[29], framesize);
9517 tcg_temp_free(t0);
9518 tcg_temp_free(t1);
9521 static void gen_addiupc (DisasContext *ctx, int rx, int imm,
9522 int is_64_bit, int extended)
9524 TCGv t0;
9526 if (extended && (ctx->hflags & MIPS_HFLAG_BMASK)) {
9527 generate_exception(ctx, EXCP_RI);
9528 return;
9531 t0 = tcg_temp_new();
9533 tcg_gen_movi_tl(t0, pc_relative_pc(ctx));
9534 tcg_gen_addi_tl(cpu_gpr[rx], t0, imm);
9535 if (!is_64_bit) {
9536 tcg_gen_ext32s_tl(cpu_gpr[rx], cpu_gpr[rx]);
9539 tcg_temp_free(t0);
9542 #if defined(TARGET_MIPS64)
9543 static void decode_i64_mips16 (DisasContext *ctx,
9544 int ry, int funct, int16_t offset,
9545 int extended)
9547 switch (funct) {
9548 case I64_LDSP:
9549 check_mips_64(ctx);
9550 offset = extended ? offset : offset << 3;
9551 gen_ld(ctx, OPC_LD, ry, 29, offset);
9552 break;
9553 case I64_SDSP:
9554 check_mips_64(ctx);
9555 offset = extended ? offset : offset << 3;
9556 gen_st(ctx, OPC_SD, ry, 29, offset);
9557 break;
9558 case I64_SDRASP:
9559 check_mips_64(ctx);
9560 offset = extended ? offset : (ctx->opcode & 0xff) << 3;
9561 gen_st(ctx, OPC_SD, 31, 29, offset);
9562 break;
9563 case I64_DADJSP:
9564 check_mips_64(ctx);
9565 offset = extended ? offset : ((int8_t)ctx->opcode) << 3;
9566 gen_arith_imm(ctx, OPC_DADDIU, 29, 29, offset);
9567 break;
9568 case I64_LDPC:
9569 if (extended && (ctx->hflags & MIPS_HFLAG_BMASK)) {
9570 generate_exception(ctx, EXCP_RI);
9571 } else {
9572 offset = extended ? offset : offset << 3;
9573 gen_ld(ctx, OPC_LDPC, ry, 0, offset);
9575 break;
9576 case I64_DADDIU5:
9577 check_mips_64(ctx);
9578 offset = extended ? offset : ((int8_t)(offset << 3)) >> 3;
9579 gen_arith_imm(ctx, OPC_DADDIU, ry, ry, offset);
9580 break;
9581 case I64_DADDIUPC:
9582 check_mips_64(ctx);
9583 offset = extended ? offset : offset << 2;
9584 gen_addiupc(ctx, ry, offset, 1, extended);
9585 break;
9586 case I64_DADDIUSP:
9587 check_mips_64(ctx);
9588 offset = extended ? offset : offset << 2;
9589 gen_arith_imm(ctx, OPC_DADDIU, ry, 29, offset);
9590 break;
9593 #endif
9595 static int decode_extended_mips16_opc (CPUMIPSState *env, DisasContext *ctx)
9597 int extend = cpu_lduw_code(env, ctx->pc + 2);
9598 int op, rx, ry, funct, sa;
9599 int16_t imm, offset;
9601 ctx->opcode = (ctx->opcode << 16) | extend;
9602 op = (ctx->opcode >> 11) & 0x1f;
9603 sa = (ctx->opcode >> 22) & 0x1f;
9604 funct = (ctx->opcode >> 8) & 0x7;
9605 rx = xlat((ctx->opcode >> 8) & 0x7);
9606 ry = xlat((ctx->opcode >> 5) & 0x7);
9607 offset = imm = (int16_t) (((ctx->opcode >> 16) & 0x1f) << 11
9608 | ((ctx->opcode >> 21) & 0x3f) << 5
9609 | (ctx->opcode & 0x1f));
9611 /* The extended opcodes cleverly reuse the opcodes from their 16-bit
9612 counterparts. */
9613 switch (op) {
9614 case M16_OPC_ADDIUSP:
9615 gen_arith_imm(ctx, OPC_ADDIU, rx, 29, imm);
9616 break;
9617 case M16_OPC_ADDIUPC:
9618 gen_addiupc(ctx, rx, imm, 0, 1);
9619 break;
9620 case M16_OPC_B:
9621 gen_compute_branch(ctx, OPC_BEQ, 4, 0, 0, offset << 1);
9622 /* No delay slot, so just process as a normal instruction */
9623 break;
9624 case M16_OPC_BEQZ:
9625 gen_compute_branch(ctx, OPC_BEQ, 4, rx, 0, offset << 1);
9626 /* No delay slot, so just process as a normal instruction */
9627 break;
9628 case M16_OPC_BNEQZ:
9629 gen_compute_branch(ctx, OPC_BNE, 4, rx, 0, offset << 1);
9630 /* No delay slot, so just process as a normal instruction */
9631 break;
9632 case M16_OPC_SHIFT:
9633 switch (ctx->opcode & 0x3) {
9634 case 0x0:
9635 gen_shift_imm(ctx, OPC_SLL, rx, ry, sa);
9636 break;
9637 case 0x1:
9638 #if defined(TARGET_MIPS64)
9639 check_mips_64(ctx);
9640 gen_shift_imm(ctx, OPC_DSLL, rx, ry, sa);
9641 #else
9642 generate_exception(ctx, EXCP_RI);
9643 #endif
9644 break;
9645 case 0x2:
9646 gen_shift_imm(ctx, OPC_SRL, rx, ry, sa);
9647 break;
9648 case 0x3:
9649 gen_shift_imm(ctx, OPC_SRA, rx, ry, sa);
9650 break;
9652 break;
9653 #if defined(TARGET_MIPS64)
9654 case M16_OPC_LD:
9655 check_mips_64(ctx);
9656 gen_ld(ctx, OPC_LD, ry, rx, offset);
9657 break;
9658 #endif
9659 case M16_OPC_RRIA:
9660 imm = ctx->opcode & 0xf;
9661 imm = imm | ((ctx->opcode >> 20) & 0x7f) << 4;
9662 imm = imm | ((ctx->opcode >> 16) & 0xf) << 11;
9663 imm = (int16_t) (imm << 1) >> 1;
9664 if ((ctx->opcode >> 4) & 0x1) {
9665 #if defined(TARGET_MIPS64)
9666 check_mips_64(ctx);
9667 gen_arith_imm(ctx, OPC_DADDIU, ry, rx, imm);
9668 #else
9669 generate_exception(ctx, EXCP_RI);
9670 #endif
9671 } else {
9672 gen_arith_imm(ctx, OPC_ADDIU, ry, rx, imm);
9674 break;
9675 case M16_OPC_ADDIU8:
9676 gen_arith_imm(ctx, OPC_ADDIU, rx, rx, imm);
9677 break;
9678 case M16_OPC_SLTI:
9679 gen_slt_imm(ctx, OPC_SLTI, 24, rx, imm);
9680 break;
9681 case M16_OPC_SLTIU:
9682 gen_slt_imm(ctx, OPC_SLTIU, 24, rx, imm);
9683 break;
9684 case M16_OPC_I8:
9685 switch (funct) {
9686 case I8_BTEQZ:
9687 gen_compute_branch(ctx, OPC_BEQ, 4, 24, 0, offset << 1);
9688 break;
9689 case I8_BTNEZ:
9690 gen_compute_branch(ctx, OPC_BNE, 4, 24, 0, offset << 1);
9691 break;
9692 case I8_SWRASP:
9693 gen_st(ctx, OPC_SW, 31, 29, imm);
9694 break;
9695 case I8_ADJSP:
9696 gen_arith_imm(ctx, OPC_ADDIU, 29, 29, imm);
9697 break;
9698 case I8_SVRS:
9700 int xsregs = (ctx->opcode >> 24) & 0x7;
9701 int aregs = (ctx->opcode >> 16) & 0xf;
9702 int do_ra = (ctx->opcode >> 6) & 0x1;
9703 int do_s0 = (ctx->opcode >> 5) & 0x1;
9704 int do_s1 = (ctx->opcode >> 4) & 0x1;
9705 int framesize = (((ctx->opcode >> 20) & 0xf) << 4
9706 | (ctx->opcode & 0xf)) << 3;
9708 if (ctx->opcode & (1 << 7)) {
9709 gen_mips16_save(ctx, xsregs, aregs,
9710 do_ra, do_s0, do_s1,
9711 framesize);
9712 } else {
9713 gen_mips16_restore(ctx, xsregs, aregs,
9714 do_ra, do_s0, do_s1,
9715 framesize);
9718 break;
9719 default:
9720 generate_exception(ctx, EXCP_RI);
9721 break;
9723 break;
9724 case M16_OPC_LI:
9725 tcg_gen_movi_tl(cpu_gpr[rx], (uint16_t) imm);
9726 break;
9727 case M16_OPC_CMPI:
9728 tcg_gen_xori_tl(cpu_gpr[24], cpu_gpr[rx], (uint16_t) imm);
9729 break;
9730 #if defined(TARGET_MIPS64)
9731 case M16_OPC_SD:
9732 gen_st(ctx, OPC_SD, ry, rx, offset);
9733 break;
9734 #endif
9735 case M16_OPC_LB:
9736 gen_ld(ctx, OPC_LB, ry, rx, offset);
9737 break;
9738 case M16_OPC_LH:
9739 gen_ld(ctx, OPC_LH, ry, rx, offset);
9740 break;
9741 case M16_OPC_LWSP:
9742 gen_ld(ctx, OPC_LW, rx, 29, offset);
9743 break;
9744 case M16_OPC_LW:
9745 gen_ld(ctx, OPC_LW, ry, rx, offset);
9746 break;
9747 case M16_OPC_LBU:
9748 gen_ld(ctx, OPC_LBU, ry, rx, offset);
9749 break;
9750 case M16_OPC_LHU:
9751 gen_ld(ctx, OPC_LHU, ry, rx, offset);
9752 break;
9753 case M16_OPC_LWPC:
9754 gen_ld(ctx, OPC_LWPC, rx, 0, offset);
9755 break;
9756 #if defined(TARGET_MIPS64)
9757 case M16_OPC_LWU:
9758 gen_ld(ctx, OPC_LWU, ry, rx, offset);
9759 break;
9760 #endif
9761 case M16_OPC_SB:
9762 gen_st(ctx, OPC_SB, ry, rx, offset);
9763 break;
9764 case M16_OPC_SH:
9765 gen_st(ctx, OPC_SH, ry, rx, offset);
9766 break;
9767 case M16_OPC_SWSP:
9768 gen_st(ctx, OPC_SW, rx, 29, offset);
9769 break;
9770 case M16_OPC_SW:
9771 gen_st(ctx, OPC_SW, ry, rx, offset);
9772 break;
9773 #if defined(TARGET_MIPS64)
9774 case M16_OPC_I64:
9775 decode_i64_mips16(ctx, ry, funct, offset, 1);
9776 break;
9777 #endif
9778 default:
9779 generate_exception(ctx, EXCP_RI);
9780 break;
9783 return 4;
9786 static int decode_mips16_opc (CPUMIPSState *env, DisasContext *ctx)
9788 int rx, ry;
9789 int sa;
9790 int op, cnvt_op, op1, offset;
9791 int funct;
9792 int n_bytes;
9794 op = (ctx->opcode >> 11) & 0x1f;
9795 sa = (ctx->opcode >> 2) & 0x7;
9796 sa = sa == 0 ? 8 : sa;
9797 rx = xlat((ctx->opcode >> 8) & 0x7);
9798 cnvt_op = (ctx->opcode >> 5) & 0x7;
9799 ry = xlat((ctx->opcode >> 5) & 0x7);
9800 op1 = offset = ctx->opcode & 0x1f;
9802 n_bytes = 2;
9804 switch (op) {
9805 case M16_OPC_ADDIUSP:
9807 int16_t imm = ((uint8_t) ctx->opcode) << 2;
9809 gen_arith_imm(ctx, OPC_ADDIU, rx, 29, imm);
9811 break;
9812 case M16_OPC_ADDIUPC:
9813 gen_addiupc(ctx, rx, ((uint8_t) ctx->opcode) << 2, 0, 0);
9814 break;
9815 case M16_OPC_B:
9816 offset = (ctx->opcode & 0x7ff) << 1;
9817 offset = (int16_t)(offset << 4) >> 4;
9818 gen_compute_branch(ctx, OPC_BEQ, 2, 0, 0, offset);
9819 /* No delay slot, so just process as a normal instruction */
9820 break;
9821 case M16_OPC_JAL:
9822 offset = cpu_lduw_code(env, ctx->pc + 2);
9823 offset = (((ctx->opcode & 0x1f) << 21)
9824 | ((ctx->opcode >> 5) & 0x1f) << 16
9825 | offset) << 2;
9826 op = ((ctx->opcode >> 10) & 0x1) ? OPC_JALXS : OPC_JALS;
9827 gen_compute_branch(ctx, op, 4, rx, ry, offset);
9828 n_bytes = 4;
9829 break;
9830 case M16_OPC_BEQZ:
9831 gen_compute_branch(ctx, OPC_BEQ, 2, rx, 0, ((int8_t)ctx->opcode) << 1);
9832 /* No delay slot, so just process as a normal instruction */
9833 break;
9834 case M16_OPC_BNEQZ:
9835 gen_compute_branch(ctx, OPC_BNE, 2, rx, 0, ((int8_t)ctx->opcode) << 1);
9836 /* No delay slot, so just process as a normal instruction */
9837 break;
9838 case M16_OPC_SHIFT:
9839 switch (ctx->opcode & 0x3) {
9840 case 0x0:
9841 gen_shift_imm(ctx, OPC_SLL, rx, ry, sa);
9842 break;
9843 case 0x1:
9844 #if defined(TARGET_MIPS64)
9845 check_mips_64(ctx);
9846 gen_shift_imm(ctx, OPC_DSLL, rx, ry, sa);
9847 #else
9848 generate_exception(ctx, EXCP_RI);
9849 #endif
9850 break;
9851 case 0x2:
9852 gen_shift_imm(ctx, OPC_SRL, rx, ry, sa);
9853 break;
9854 case 0x3:
9855 gen_shift_imm(ctx, OPC_SRA, rx, ry, sa);
9856 break;
9858 break;
9859 #if defined(TARGET_MIPS64)
9860 case M16_OPC_LD:
9861 check_mips_64(ctx);
9862 gen_ld(ctx, OPC_LD, ry, rx, offset << 3);
9863 break;
9864 #endif
9865 case M16_OPC_RRIA:
9867 int16_t imm = (int8_t)((ctx->opcode & 0xf) << 4) >> 4;
9869 if ((ctx->opcode >> 4) & 1) {
9870 #if defined(TARGET_MIPS64)
9871 check_mips_64(ctx);
9872 gen_arith_imm(ctx, OPC_DADDIU, ry, rx, imm);
9873 #else
9874 generate_exception(ctx, EXCP_RI);
9875 #endif
9876 } else {
9877 gen_arith_imm(ctx, OPC_ADDIU, ry, rx, imm);
9880 break;
9881 case M16_OPC_ADDIU8:
9883 int16_t imm = (int8_t) ctx->opcode;
9885 gen_arith_imm(ctx, OPC_ADDIU, rx, rx, imm);
9887 break;
9888 case M16_OPC_SLTI:
9890 int16_t imm = (uint8_t) ctx->opcode;
9891 gen_slt_imm(ctx, OPC_SLTI, 24, rx, imm);
9893 break;
9894 case M16_OPC_SLTIU:
9896 int16_t imm = (uint8_t) ctx->opcode;
9897 gen_slt_imm(ctx, OPC_SLTIU, 24, rx, imm);
9899 break;
9900 case M16_OPC_I8:
9902 int reg32;
9904 funct = (ctx->opcode >> 8) & 0x7;
9905 switch (funct) {
9906 case I8_BTEQZ:
9907 gen_compute_branch(ctx, OPC_BEQ, 2, 24, 0,
9908 ((int8_t)ctx->opcode) << 1);
9909 break;
9910 case I8_BTNEZ:
9911 gen_compute_branch(ctx, OPC_BNE, 2, 24, 0,
9912 ((int8_t)ctx->opcode) << 1);
9913 break;
9914 case I8_SWRASP:
9915 gen_st(ctx, OPC_SW, 31, 29, (ctx->opcode & 0xff) << 2);
9916 break;
9917 case I8_ADJSP:
9918 gen_arith_imm(ctx, OPC_ADDIU, 29, 29,
9919 ((int8_t)ctx->opcode) << 3);
9920 break;
9921 case I8_SVRS:
9923 int do_ra = ctx->opcode & (1 << 6);
9924 int do_s0 = ctx->opcode & (1 << 5);
9925 int do_s1 = ctx->opcode & (1 << 4);
9926 int framesize = ctx->opcode & 0xf;
9928 if (framesize == 0) {
9929 framesize = 128;
9930 } else {
9931 framesize = framesize << 3;
9934 if (ctx->opcode & (1 << 7)) {
9935 gen_mips16_save(ctx, 0, 0,
9936 do_ra, do_s0, do_s1, framesize);
9937 } else {
9938 gen_mips16_restore(ctx, 0, 0,
9939 do_ra, do_s0, do_s1, framesize);
9942 break;
9943 case I8_MOV32R:
9945 int rz = xlat(ctx->opcode & 0x7);
9947 reg32 = (((ctx->opcode >> 3) & 0x3) << 3) |
9948 ((ctx->opcode >> 5) & 0x7);
9949 gen_arith(ctx, OPC_ADDU, reg32, rz, 0);
9951 break;
9952 case I8_MOVR32:
9953 reg32 = ctx->opcode & 0x1f;
9954 gen_arith(ctx, OPC_ADDU, ry, reg32, 0);
9955 break;
9956 default:
9957 generate_exception(ctx, EXCP_RI);
9958 break;
9961 break;
9962 case M16_OPC_LI:
9964 int16_t imm = (uint8_t) ctx->opcode;
9966 gen_arith_imm(ctx, OPC_ADDIU, rx, 0, imm);
9968 break;
9969 case M16_OPC_CMPI:
9971 int16_t imm = (uint8_t) ctx->opcode;
9972 gen_logic_imm(ctx, OPC_XORI, 24, rx, imm);
9974 break;
9975 #if defined(TARGET_MIPS64)
9976 case M16_OPC_SD:
9977 check_mips_64(ctx);
9978 gen_st(ctx, OPC_SD, ry, rx, offset << 3);
9979 break;
9980 #endif
9981 case M16_OPC_LB:
9982 gen_ld(ctx, OPC_LB, ry, rx, offset);
9983 break;
9984 case M16_OPC_LH:
9985 gen_ld(ctx, OPC_LH, ry, rx, offset << 1);
9986 break;
9987 case M16_OPC_LWSP:
9988 gen_ld(ctx, OPC_LW, rx, 29, ((uint8_t)ctx->opcode) << 2);
9989 break;
9990 case M16_OPC_LW:
9991 gen_ld(ctx, OPC_LW, ry, rx, offset << 2);
9992 break;
9993 case M16_OPC_LBU:
9994 gen_ld(ctx, OPC_LBU, ry, rx, offset);
9995 break;
9996 case M16_OPC_LHU:
9997 gen_ld(ctx, OPC_LHU, ry, rx, offset << 1);
9998 break;
9999 case M16_OPC_LWPC:
10000 gen_ld(ctx, OPC_LWPC, rx, 0, ((uint8_t)ctx->opcode) << 2);
10001 break;
10002 #if defined (TARGET_MIPS64)
10003 case M16_OPC_LWU:
10004 check_mips_64(ctx);
10005 gen_ld(ctx, OPC_LWU, ry, rx, offset << 2);
10006 break;
10007 #endif
10008 case M16_OPC_SB:
10009 gen_st(ctx, OPC_SB, ry, rx, offset);
10010 break;
10011 case M16_OPC_SH:
10012 gen_st(ctx, OPC_SH, ry, rx, offset << 1);
10013 break;
10014 case M16_OPC_SWSP:
10015 gen_st(ctx, OPC_SW, rx, 29, ((uint8_t)ctx->opcode) << 2);
10016 break;
10017 case M16_OPC_SW:
10018 gen_st(ctx, OPC_SW, ry, rx, offset << 2);
10019 break;
10020 case M16_OPC_RRR:
10022 int rz = xlat((ctx->opcode >> 2) & 0x7);
10023 int mips32_op;
10025 switch (ctx->opcode & 0x3) {
10026 case RRR_ADDU:
10027 mips32_op = OPC_ADDU;
10028 break;
10029 case RRR_SUBU:
10030 mips32_op = OPC_SUBU;
10031 break;
10032 #if defined(TARGET_MIPS64)
10033 case RRR_DADDU:
10034 mips32_op = OPC_DADDU;
10035 check_mips_64(ctx);
10036 break;
10037 case RRR_DSUBU:
10038 mips32_op = OPC_DSUBU;
10039 check_mips_64(ctx);
10040 break;
10041 #endif
10042 default:
10043 generate_exception(ctx, EXCP_RI);
10044 goto done;
10047 gen_arith(ctx, mips32_op, rz, rx, ry);
10048 done:
10051 break;
10052 case M16_OPC_RR:
10053 switch (op1) {
10054 case RR_JR:
10056 int nd = (ctx->opcode >> 7) & 0x1;
10057 int link = (ctx->opcode >> 6) & 0x1;
10058 int ra = (ctx->opcode >> 5) & 0x1;
10060 if (link) {
10061 op = nd ? OPC_JALRC : OPC_JALRS;
10062 } else {
10063 op = OPC_JR;
10066 gen_compute_branch(ctx, op, 2, ra ? 31 : rx, 31, 0);
10068 break;
10069 case RR_SDBBP:
10070 /* XXX: not clear which exception should be raised
10071 * when in debug mode...
10073 check_insn(ctx, ISA_MIPS32);
10074 if (!(ctx->hflags & MIPS_HFLAG_DM)) {
10075 generate_exception(ctx, EXCP_DBp);
10076 } else {
10077 generate_exception(ctx, EXCP_DBp);
10079 break;
10080 case RR_SLT:
10081 gen_slt(ctx, OPC_SLT, 24, rx, ry);
10082 break;
10083 case RR_SLTU:
10084 gen_slt(ctx, OPC_SLTU, 24, rx, ry);
10085 break;
10086 case RR_BREAK:
10087 generate_exception(ctx, EXCP_BREAK);
10088 break;
10089 case RR_SLLV:
10090 gen_shift(ctx, OPC_SLLV, ry, rx, ry);
10091 break;
10092 case RR_SRLV:
10093 gen_shift(ctx, OPC_SRLV, ry, rx, ry);
10094 break;
10095 case RR_SRAV:
10096 gen_shift(ctx, OPC_SRAV, ry, rx, ry);
10097 break;
10098 #if defined (TARGET_MIPS64)
10099 case RR_DSRL:
10100 check_mips_64(ctx);
10101 gen_shift_imm(ctx, OPC_DSRL, ry, ry, sa);
10102 break;
10103 #endif
10104 case RR_CMP:
10105 gen_logic(ctx, OPC_XOR, 24, rx, ry);
10106 break;
10107 case RR_NEG:
10108 gen_arith(ctx, OPC_SUBU, rx, 0, ry);
10109 break;
10110 case RR_AND:
10111 gen_logic(ctx, OPC_AND, rx, rx, ry);
10112 break;
10113 case RR_OR:
10114 gen_logic(ctx, OPC_OR, rx, rx, ry);
10115 break;
10116 case RR_XOR:
10117 gen_logic(ctx, OPC_XOR, rx, rx, ry);
10118 break;
10119 case RR_NOT:
10120 gen_logic(ctx, OPC_NOR, rx, ry, 0);
10121 break;
10122 case RR_MFHI:
10123 gen_HILO(ctx, OPC_MFHI, 0, rx);
10124 break;
10125 case RR_CNVT:
10126 switch (cnvt_op) {
10127 case RR_RY_CNVT_ZEB:
10128 tcg_gen_ext8u_tl(cpu_gpr[rx], cpu_gpr[rx]);
10129 break;
10130 case RR_RY_CNVT_ZEH:
10131 tcg_gen_ext16u_tl(cpu_gpr[rx], cpu_gpr[rx]);
10132 break;
10133 case RR_RY_CNVT_SEB:
10134 tcg_gen_ext8s_tl(cpu_gpr[rx], cpu_gpr[rx]);
10135 break;
10136 case RR_RY_CNVT_SEH:
10137 tcg_gen_ext16s_tl(cpu_gpr[rx], cpu_gpr[rx]);
10138 break;
10139 #if defined (TARGET_MIPS64)
10140 case RR_RY_CNVT_ZEW:
10141 check_mips_64(ctx);
10142 tcg_gen_ext32u_tl(cpu_gpr[rx], cpu_gpr[rx]);
10143 break;
10144 case RR_RY_CNVT_SEW:
10145 check_mips_64(ctx);
10146 tcg_gen_ext32s_tl(cpu_gpr[rx], cpu_gpr[rx]);
10147 break;
10148 #endif
10149 default:
10150 generate_exception(ctx, EXCP_RI);
10151 break;
10153 break;
10154 case RR_MFLO:
10155 gen_HILO(ctx, OPC_MFLO, 0, rx);
10156 break;
10157 #if defined (TARGET_MIPS64)
10158 case RR_DSRA:
10159 check_mips_64(ctx);
10160 gen_shift_imm(ctx, OPC_DSRA, ry, ry, sa);
10161 break;
10162 case RR_DSLLV:
10163 check_mips_64(ctx);
10164 gen_shift(ctx, OPC_DSLLV, ry, rx, ry);
10165 break;
10166 case RR_DSRLV:
10167 check_mips_64(ctx);
10168 gen_shift(ctx, OPC_DSRLV, ry, rx, ry);
10169 break;
10170 case RR_DSRAV:
10171 check_mips_64(ctx);
10172 gen_shift(ctx, OPC_DSRAV, ry, rx, ry);
10173 break;
10174 #endif
10175 case RR_MULT:
10176 gen_muldiv(ctx, OPC_MULT, 0, rx, ry);
10177 break;
10178 case RR_MULTU:
10179 gen_muldiv(ctx, OPC_MULTU, 0, rx, ry);
10180 break;
10181 case RR_DIV:
10182 gen_muldiv(ctx, OPC_DIV, 0, rx, ry);
10183 break;
10184 case RR_DIVU:
10185 gen_muldiv(ctx, OPC_DIVU, 0, rx, ry);
10186 break;
10187 #if defined (TARGET_MIPS64)
10188 case RR_DMULT:
10189 check_mips_64(ctx);
10190 gen_muldiv(ctx, OPC_DMULT, 0, rx, ry);
10191 break;
10192 case RR_DMULTU:
10193 check_mips_64(ctx);
10194 gen_muldiv(ctx, OPC_DMULTU, 0, rx, ry);
10195 break;
10196 case RR_DDIV:
10197 check_mips_64(ctx);
10198 gen_muldiv(ctx, OPC_DDIV, 0, rx, ry);
10199 break;
10200 case RR_DDIVU:
10201 check_mips_64(ctx);
10202 gen_muldiv(ctx, OPC_DDIVU, 0, rx, ry);
10203 break;
10204 #endif
10205 default:
10206 generate_exception(ctx, EXCP_RI);
10207 break;
10209 break;
10210 case M16_OPC_EXTEND:
10211 decode_extended_mips16_opc(env, ctx);
10212 n_bytes = 4;
10213 break;
10214 #if defined(TARGET_MIPS64)
10215 case M16_OPC_I64:
10216 funct = (ctx->opcode >> 8) & 0x7;
10217 decode_i64_mips16(ctx, ry, funct, offset, 0);
10218 break;
10219 #endif
10220 default:
10221 generate_exception(ctx, EXCP_RI);
10222 break;
10225 return n_bytes;
10228 /* microMIPS extension to MIPS32/MIPS64 */
10231 * microMIPS32/microMIPS64 major opcodes
10233 * 1. MIPS Architecture for Programmers Volume II-B:
10234 * The microMIPS32 Instruction Set (Revision 3.05)
10236 * Table 6.2 microMIPS32 Encoding of Major Opcode Field
10238 * 2. MIPS Architecture For Programmers Volume II-A:
10239 * The MIPS64 Instruction Set (Revision 3.51)
10242 enum {
10243 POOL32A = 0x00,
10244 POOL16A = 0x01,
10245 LBU16 = 0x02,
10246 MOVE16 = 0x03,
10247 ADDI32 = 0x04,
10248 LBU32 = 0x05,
10249 SB32 = 0x06,
10250 LB32 = 0x07,
10252 POOL32B = 0x08,
10253 POOL16B = 0x09,
10254 LHU16 = 0x0a,
10255 ANDI16 = 0x0b,
10256 ADDIU32 = 0x0c,
10257 LHU32 = 0x0d,
10258 SH32 = 0x0e,
10259 LH32 = 0x0f,
10261 POOL32I = 0x10,
10262 POOL16C = 0x11,
10263 LWSP16 = 0x12,
10264 POOL16D = 0x13,
10265 ORI32 = 0x14,
10266 POOL32F = 0x15,
10267 POOL32S = 0x16, /* MIPS64 */
10268 DADDIU32 = 0x17, /* MIPS64 */
10270 /* 0x1f is reserved */
10271 POOL32C = 0x18,
10272 LWGP16 = 0x19,
10273 LW16 = 0x1a,
10274 POOL16E = 0x1b,
10275 XORI32 = 0x1c,
10276 JALS32 = 0x1d,
10277 ADDIUPC = 0x1e,
10279 /* 0x20 is reserved */
10280 RES_20 = 0x20,
10281 POOL16F = 0x21,
10282 SB16 = 0x22,
10283 BEQZ16 = 0x23,
10284 SLTI32 = 0x24,
10285 BEQ32 = 0x25,
10286 SWC132 = 0x26,
10287 LWC132 = 0x27,
10289 /* 0x28 and 0x29 are reserved */
10290 RES_28 = 0x28,
10291 RES_29 = 0x29,
10292 SH16 = 0x2a,
10293 BNEZ16 = 0x2b,
10294 SLTIU32 = 0x2c,
10295 BNE32 = 0x2d,
10296 SDC132 = 0x2e,
10297 LDC132 = 0x2f,
10299 /* 0x30 and 0x31 are reserved */
10300 RES_30 = 0x30,
10301 RES_31 = 0x31,
10302 SWSP16 = 0x32,
10303 B16 = 0x33,
10304 ANDI32 = 0x34,
10305 J32 = 0x35,
10306 SD32 = 0x36, /* MIPS64 */
10307 LD32 = 0x37, /* MIPS64 */
10309 /* 0x38 and 0x39 are reserved */
10310 RES_38 = 0x38,
10311 RES_39 = 0x39,
10312 SW16 = 0x3a,
10313 LI16 = 0x3b,
10314 JALX32 = 0x3c,
10315 JAL32 = 0x3d,
10316 SW32 = 0x3e,
10317 LW32 = 0x3f
10320 /* POOL32A encoding of minor opcode field */
10322 enum {
10323 /* These opcodes are distinguished only by bits 9..6; those bits are
10324 * what are recorded below. */
10325 SLL32 = 0x0,
10326 SRL32 = 0x1,
10327 SRA = 0x2,
10328 ROTR = 0x3,
10330 SLLV = 0x0,
10331 SRLV = 0x1,
10332 SRAV = 0x2,
10333 ROTRV = 0x3,
10334 ADD = 0x4,
10335 ADDU32 = 0x5,
10336 SUB = 0x6,
10337 SUBU32 = 0x7,
10338 MUL = 0x8,
10339 AND = 0x9,
10340 OR32 = 0xa,
10341 NOR = 0xb,
10342 XOR32 = 0xc,
10343 SLT = 0xd,
10344 SLTU = 0xe,
10346 MOVN = 0x0,
10347 MOVZ = 0x1,
10348 LWXS = 0x4,
10350 /* The following can be distinguished by their lower 6 bits. */
10351 INS = 0x0c,
10352 EXT = 0x2c,
10353 POOL32AXF = 0x3c
10356 /* POOL32AXF encoding of minor opcode field extension */
10359 * 1. MIPS Architecture for Programmers Volume II-B:
10360 * The microMIPS32 Instruction Set (Revision 3.05)
10362 * Table 6.5 POOL32Axf Encoding of Minor Opcode Extension Field
10364 * 2. MIPS Architecture for Programmers VolumeIV-e:
10365 * The MIPS DSP Application-Specific Extension
10366 * to the microMIPS32 Architecture (Revision 2.34)
10368 * Table 5.5 POOL32Axf Encoding of Minor Opcode Extension Field
10371 enum {
10372 /* bits 11..6 */
10373 TEQ = 0x00,
10374 TGE = 0x08,
10375 TGEU = 0x10,
10376 TLT = 0x20,
10377 TLTU = 0x28,
10378 TNE = 0x30,
10380 MFC0 = 0x03,
10381 MTC0 = 0x0b,
10383 /* begin of microMIPS32 DSP */
10385 /* bits 13..12 for 0x01 */
10386 MFHI_ACC = 0x0,
10387 MFLO_ACC = 0x1,
10388 MTHI_ACC = 0x2,
10389 MTLO_ACC = 0x3,
10391 /* bits 13..12 for 0x2a */
10392 MADD_ACC = 0x0,
10393 MADDU_ACC = 0x1,
10394 MSUB_ACC = 0x2,
10395 MSUBU_ACC = 0x3,
10397 /* bits 13..12 for 0x32 */
10398 MULT_ACC = 0x0,
10399 MULTU_ACC = 0x1,
10401 /* end of microMIPS32 DSP */
10403 /* bits 15..12 for 0x2c */
10404 SEB = 0x2,
10405 SEH = 0x3,
10406 CLO = 0x4,
10407 CLZ = 0x5,
10408 RDHWR = 0x6,
10409 WSBH = 0x7,
10410 MULT = 0x8,
10411 MULTU = 0x9,
10412 DIV = 0xa,
10413 DIVU = 0xb,
10414 MADD = 0xc,
10415 MADDU = 0xd,
10416 MSUB = 0xe,
10417 MSUBU = 0xf,
10419 /* bits 15..12 for 0x34 */
10420 MFC2 = 0x4,
10421 MTC2 = 0x5,
10422 MFHC2 = 0x8,
10423 MTHC2 = 0x9,
10424 CFC2 = 0xc,
10425 CTC2 = 0xd,
10427 /* bits 15..12 for 0x3c */
10428 JALR = 0x0,
10429 JR = 0x0, /* alias */
10430 JALR_HB = 0x1,
10431 JALRS = 0x4,
10432 JALRS_HB = 0x5,
10434 /* bits 15..12 for 0x05 */
10435 RDPGPR = 0xe,
10436 WRPGPR = 0xf,
10438 /* bits 15..12 for 0x0d */
10439 TLBP = 0x0,
10440 TLBR = 0x1,
10441 TLBWI = 0x2,
10442 TLBWR = 0x3,
10443 WAIT = 0x9,
10444 IRET = 0xd,
10445 DERET = 0xe,
10446 ERET = 0xf,
10448 /* bits 15..12 for 0x15 */
10449 DMT = 0x0,
10450 DVPE = 0x1,
10451 EMT = 0x2,
10452 EVPE = 0x3,
10454 /* bits 15..12 for 0x1d */
10455 DI = 0x4,
10456 EI = 0x5,
10458 /* bits 15..12 for 0x2d */
10459 SYNC = 0x6,
10460 SYSCALL = 0x8,
10461 SDBBP = 0xd,
10463 /* bits 15..12 for 0x35 */
10464 MFHI32 = 0x0,
10465 MFLO32 = 0x1,
10466 MTHI32 = 0x2,
10467 MTLO32 = 0x3,
10470 /* POOL32B encoding of minor opcode field (bits 15..12) */
10472 enum {
10473 LWC2 = 0x0,
10474 LWP = 0x1,
10475 LDP = 0x4,
10476 LWM32 = 0x5,
10477 CACHE = 0x6,
10478 LDM = 0x7,
10479 SWC2 = 0x8,
10480 SWP = 0x9,
10481 SDP = 0xc,
10482 SWM32 = 0xd,
10483 SDM = 0xf
10486 /* POOL32C encoding of minor opcode field (bits 15..12) */
10488 enum {
10489 LWL = 0x0,
10490 SWL = 0x8,
10491 LWR = 0x1,
10492 SWR = 0x9,
10493 PREF = 0x2,
10494 /* 0xa is reserved */
10495 LL = 0x3,
10496 SC = 0xb,
10497 LDL = 0x4,
10498 SDL = 0xc,
10499 LDR = 0x5,
10500 SDR = 0xd,
10501 /* 0x6 is reserved */
10502 LWU = 0xe,
10503 LLD = 0x7,
10504 SCD = 0xf
10507 /* POOL32F encoding of minor opcode field (bits 5..0) */
10509 enum {
10510 /* These are the bit 7..6 values */
10511 ADD_FMT = 0x0,
10512 MOVN_FMT = 0x0,
10514 SUB_FMT = 0x1,
10515 MOVZ_FMT = 0x1,
10517 MUL_FMT = 0x2,
10519 DIV_FMT = 0x3,
10521 /* These are the bit 8..6 values */
10522 RSQRT2_FMT = 0x0,
10523 MOVF_FMT = 0x0,
10525 LWXC1 = 0x1,
10526 MOVT_FMT = 0x1,
10528 PLL_PS = 0x2,
10529 SWXC1 = 0x2,
10531 PLU_PS = 0x3,
10532 LDXC1 = 0x3,
10534 PUL_PS = 0x4,
10535 SDXC1 = 0x4,
10536 RECIP2_FMT = 0x4,
10538 PUU_PS = 0x5,
10539 LUXC1 = 0x5,
10541 CVT_PS_S = 0x6,
10542 SUXC1 = 0x6,
10543 ADDR_PS = 0x6,
10544 PREFX = 0x6,
10546 MULR_PS = 0x7,
10548 MADD_S = 0x01,
10549 MADD_D = 0x09,
10550 MADD_PS = 0x11,
10551 ALNV_PS = 0x19,
10552 MSUB_S = 0x21,
10553 MSUB_D = 0x29,
10554 MSUB_PS = 0x31,
10556 NMADD_S = 0x02,
10557 NMADD_D = 0x0a,
10558 NMADD_PS = 0x12,
10559 NMSUB_S = 0x22,
10560 NMSUB_D = 0x2a,
10561 NMSUB_PS = 0x32,
10563 POOL32FXF = 0x3b,
10565 CABS_COND_FMT = 0x1c, /* MIPS3D */
10566 C_COND_FMT = 0x3c
10569 /* POOL32Fxf encoding of minor opcode extension field */
10571 enum {
10572 CVT_L = 0x04,
10573 RSQRT_FMT = 0x08,
10574 FLOOR_L = 0x0c,
10575 CVT_PW_PS = 0x1c,
10576 CVT_W = 0x24,
10577 SQRT_FMT = 0x28,
10578 FLOOR_W = 0x2c,
10579 CVT_PS_PW = 0x3c,
10580 CFC1 = 0x40,
10581 RECIP_FMT = 0x48,
10582 CEIL_L = 0x4c,
10583 CTC1 = 0x60,
10584 CEIL_W = 0x6c,
10585 MFC1 = 0x80,
10586 CVT_S_PL = 0x84,
10587 TRUNC_L = 0x8c,
10588 MTC1 = 0xa0,
10589 CVT_S_PU = 0xa4,
10590 TRUNC_W = 0xac,
10591 MFHC1 = 0xc0,
10592 ROUND_L = 0xcc,
10593 MTHC1 = 0xe0,
10594 ROUND_W = 0xec,
10596 MOV_FMT = 0x01,
10597 MOVF = 0x05,
10598 ABS_FMT = 0x0d,
10599 RSQRT1_FMT = 0x1d,
10600 MOVT = 0x25,
10601 NEG_FMT = 0x2d,
10602 CVT_D = 0x4d,
10603 RECIP1_FMT = 0x5d,
10604 CVT_S = 0x6d
10607 /* POOL32I encoding of minor opcode field (bits 25..21) */
10609 enum {
10610 BLTZ = 0x00,
10611 BLTZAL = 0x01,
10612 BGEZ = 0x02,
10613 BGEZAL = 0x03,
10614 BLEZ = 0x04,
10615 BNEZC = 0x05,
10616 BGTZ = 0x06,
10617 BEQZC = 0x07,
10618 TLTI = 0x08,
10619 TGEI = 0x09,
10620 TLTIU = 0x0a,
10621 TGEIU = 0x0b,
10622 TNEI = 0x0c,
10623 LUI = 0x0d,
10624 TEQI = 0x0e,
10625 SYNCI = 0x10,
10626 BLTZALS = 0x11,
10627 BGEZALS = 0x13,
10628 BC2F = 0x14,
10629 BC2T = 0x15,
10630 BPOSGE64 = 0x1a,
10631 BPOSGE32 = 0x1b,
10632 /* These overlap and are distinguished by bit16 of the instruction */
10633 BC1F = 0x1c,
10634 BC1T = 0x1d,
10635 BC1ANY2F = 0x1c,
10636 BC1ANY2T = 0x1d,
10637 BC1ANY4F = 0x1e,
10638 BC1ANY4T = 0x1f
10641 /* POOL16A encoding of minor opcode field */
10643 enum {
10644 ADDU16 = 0x0,
10645 SUBU16 = 0x1
10648 /* POOL16B encoding of minor opcode field */
10650 enum {
10651 SLL16 = 0x0,
10652 SRL16 = 0x1
10655 /* POOL16C encoding of minor opcode field */
10657 enum {
10658 NOT16 = 0x00,
10659 XOR16 = 0x04,
10660 AND16 = 0x08,
10661 OR16 = 0x0c,
10662 LWM16 = 0x10,
10663 SWM16 = 0x14,
10664 JR16 = 0x18,
10665 JRC16 = 0x1a,
10666 JALR16 = 0x1c,
10667 JALR16S = 0x1e,
10668 MFHI16 = 0x20,
10669 MFLO16 = 0x24,
10670 BREAK16 = 0x28,
10671 SDBBP16 = 0x2c,
10672 JRADDIUSP = 0x30
10675 /* POOL16D encoding of minor opcode field */
10677 enum {
10678 ADDIUS5 = 0x0,
10679 ADDIUSP = 0x1
10682 /* POOL16E encoding of minor opcode field */
10684 enum {
10685 ADDIUR2 = 0x0,
10686 ADDIUR1SP = 0x1
10689 static int mmreg (int r)
10691 static const int map[] = { 16, 17, 2, 3, 4, 5, 6, 7 };
10693 return map[r];
10696 /* Used for 16-bit store instructions. */
10697 static int mmreg2 (int r)
10699 static const int map[] = { 0, 17, 2, 3, 4, 5, 6, 7 };
10701 return map[r];
10704 #define uMIPS_RD(op) ((op >> 7) & 0x7)
10705 #define uMIPS_RS(op) ((op >> 4) & 0x7)
10706 #define uMIPS_RS2(op) uMIPS_RS(op)
10707 #define uMIPS_RS1(op) ((op >> 1) & 0x7)
10708 #define uMIPS_RD5(op) ((op >> 5) & 0x1f)
10709 #define uMIPS_RS5(op) (op & 0x1f)
10711 /* Signed immediate */
10712 #define SIMM(op, start, width) \
10713 ((int32_t)(((op >> start) & ((~0U) >> (32-width))) \
10714 << (32-width)) \
10715 >> (32-width))
10716 /* Zero-extended immediate */
10717 #define ZIMM(op, start, width) ((op >> start) & ((~0U) >> (32-width)))
10719 static void gen_addiur1sp(DisasContext *ctx)
10721 int rd = mmreg(uMIPS_RD(ctx->opcode));
10723 gen_arith_imm(ctx, OPC_ADDIU, rd, 29, ((ctx->opcode >> 1) & 0x3f) << 2);
10726 static void gen_addiur2(DisasContext *ctx)
10728 static const int decoded_imm[] = { 1, 4, 8, 12, 16, 20, 24, -1 };
10729 int rd = mmreg(uMIPS_RD(ctx->opcode));
10730 int rs = mmreg(uMIPS_RS(ctx->opcode));
10732 gen_arith_imm(ctx, OPC_ADDIU, rd, rs, decoded_imm[ZIMM(ctx->opcode, 1, 3)]);
10735 static void gen_addiusp(DisasContext *ctx)
10737 int encoded = ZIMM(ctx->opcode, 1, 9);
10738 int decoded;
10740 if (encoded <= 1) {
10741 decoded = 256 + encoded;
10742 } else if (encoded <= 255) {
10743 decoded = encoded;
10744 } else if (encoded <= 509) {
10745 decoded = encoded - 512;
10746 } else {
10747 decoded = encoded - 768;
10750 gen_arith_imm(ctx, OPC_ADDIU, 29, 29, decoded << 2);
10753 static void gen_addius5(DisasContext *ctx)
10755 int imm = SIMM(ctx->opcode, 1, 4);
10756 int rd = (ctx->opcode >> 5) & 0x1f;
10758 gen_arith_imm(ctx, OPC_ADDIU, rd, rd, imm);
10761 static void gen_andi16(DisasContext *ctx)
10763 static const int decoded_imm[] = { 128, 1, 2, 3, 4, 7, 8, 15, 16,
10764 31, 32, 63, 64, 255, 32768, 65535 };
10765 int rd = mmreg(uMIPS_RD(ctx->opcode));
10766 int rs = mmreg(uMIPS_RS(ctx->opcode));
10767 int encoded = ZIMM(ctx->opcode, 0, 4);
10769 gen_logic_imm(ctx, OPC_ANDI, rd, rs, decoded_imm[encoded]);
10772 static void gen_ldst_multiple (DisasContext *ctx, uint32_t opc, int reglist,
10773 int base, int16_t offset)
10775 const char *opn = "ldst_multiple";
10776 TCGv t0, t1;
10777 TCGv_i32 t2;
10779 if (ctx->hflags & MIPS_HFLAG_BMASK) {
10780 generate_exception(ctx, EXCP_RI);
10781 return;
10784 t0 = tcg_temp_new();
10786 gen_base_offset_addr(ctx, t0, base, offset);
10788 t1 = tcg_const_tl(reglist);
10789 t2 = tcg_const_i32(ctx->mem_idx);
10791 save_cpu_state(ctx, 1);
10792 switch (opc) {
10793 case LWM32:
10794 gen_helper_lwm(cpu_env, t0, t1, t2);
10795 opn = "lwm";
10796 break;
10797 case SWM32:
10798 gen_helper_swm(cpu_env, t0, t1, t2);
10799 opn = "swm";
10800 break;
10801 #ifdef TARGET_MIPS64
10802 case LDM:
10803 gen_helper_ldm(cpu_env, t0, t1, t2);
10804 opn = "ldm";
10805 break;
10806 case SDM:
10807 gen_helper_sdm(cpu_env, t0, t1, t2);
10808 opn = "sdm";
10809 break;
10810 #endif
10812 (void)opn;
10813 MIPS_DEBUG("%s, %x, %d(%s)", opn, reglist, offset, regnames[base]);
10814 tcg_temp_free(t0);
10815 tcg_temp_free(t1);
10816 tcg_temp_free_i32(t2);
10820 static void gen_pool16c_insn(DisasContext *ctx)
10822 int rd = mmreg((ctx->opcode >> 3) & 0x7);
10823 int rs = mmreg(ctx->opcode & 0x7);
10824 int opc;
10826 switch (((ctx->opcode) >> 4) & 0x3f) {
10827 case NOT16 + 0:
10828 case NOT16 + 1:
10829 case NOT16 + 2:
10830 case NOT16 + 3:
10831 gen_logic(ctx, OPC_NOR, rd, rs, 0);
10832 break;
10833 case XOR16 + 0:
10834 case XOR16 + 1:
10835 case XOR16 + 2:
10836 case XOR16 + 3:
10837 gen_logic(ctx, OPC_XOR, rd, rd, rs);
10838 break;
10839 case AND16 + 0:
10840 case AND16 + 1:
10841 case AND16 + 2:
10842 case AND16 + 3:
10843 gen_logic(ctx, OPC_AND, rd, rd, rs);
10844 break;
10845 case OR16 + 0:
10846 case OR16 + 1:
10847 case OR16 + 2:
10848 case OR16 + 3:
10849 gen_logic(ctx, OPC_OR, rd, rd, rs);
10850 break;
10851 case LWM16 + 0:
10852 case LWM16 + 1:
10853 case LWM16 + 2:
10854 case LWM16 + 3:
10856 static const int lwm_convert[] = { 0x11, 0x12, 0x13, 0x14 };
10857 int offset = ZIMM(ctx->opcode, 0, 4);
10859 gen_ldst_multiple(ctx, LWM32, lwm_convert[(ctx->opcode >> 4) & 0x3],
10860 29, offset << 2);
10862 break;
10863 case SWM16 + 0:
10864 case SWM16 + 1:
10865 case SWM16 + 2:
10866 case SWM16 + 3:
10868 static const int swm_convert[] = { 0x11, 0x12, 0x13, 0x14 };
10869 int offset = ZIMM(ctx->opcode, 0, 4);
10871 gen_ldst_multiple(ctx, SWM32, swm_convert[(ctx->opcode >> 4) & 0x3],
10872 29, offset << 2);
10874 break;
10875 case JR16 + 0:
10876 case JR16 + 1:
10878 int reg = ctx->opcode & 0x1f;
10880 gen_compute_branch(ctx, OPC_JR, 2, reg, 0, 0);
10882 break;
10883 case JRC16 + 0:
10884 case JRC16 + 1:
10886 int reg = ctx->opcode & 0x1f;
10888 gen_compute_branch(ctx, OPC_JR, 2, reg, 0, 0);
10889 /* Let normal delay slot handling in our caller take us
10890 to the branch target. */
10892 break;
10893 case JALR16 + 0:
10894 case JALR16 + 1:
10895 opc = OPC_JALR;
10896 goto do_jalr;
10897 case JALR16S + 0:
10898 case JALR16S + 1:
10899 opc = OPC_JALRS;
10900 do_jalr:
10902 int reg = ctx->opcode & 0x1f;
10904 gen_compute_branch(ctx, opc, 2, reg, 31, 0);
10906 break;
10907 case MFHI16 + 0:
10908 case MFHI16 + 1:
10909 gen_HILO(ctx, OPC_MFHI, 0, uMIPS_RS5(ctx->opcode));
10910 break;
10911 case MFLO16 + 0:
10912 case MFLO16 + 1:
10913 gen_HILO(ctx, OPC_MFLO, 0, uMIPS_RS5(ctx->opcode));
10914 break;
10915 case BREAK16:
10916 generate_exception(ctx, EXCP_BREAK);
10917 break;
10918 case SDBBP16:
10919 /* XXX: not clear which exception should be raised
10920 * when in debug mode...
10922 check_insn(ctx, ISA_MIPS32);
10923 if (!(ctx->hflags & MIPS_HFLAG_DM)) {
10924 generate_exception(ctx, EXCP_DBp);
10925 } else {
10926 generate_exception(ctx, EXCP_DBp);
10928 break;
10929 case JRADDIUSP + 0:
10930 case JRADDIUSP + 1:
10932 int imm = ZIMM(ctx->opcode, 0, 5);
10934 gen_compute_branch(ctx, OPC_JR, 2, 31, 0, 0);
10935 gen_arith_imm(ctx, OPC_ADDIU, 29, 29, imm << 2);
10936 /* Let normal delay slot handling in our caller take us
10937 to the branch target. */
10939 break;
10940 default:
10941 generate_exception(ctx, EXCP_RI);
10942 break;
10946 static void gen_ldxs (DisasContext *ctx, int base, int index, int rd)
10948 TCGv t0 = tcg_temp_new();
10949 TCGv t1 = tcg_temp_new();
10951 gen_load_gpr(t0, base);
10953 if (index != 0) {
10954 gen_load_gpr(t1, index);
10955 tcg_gen_shli_tl(t1, t1, 2);
10956 gen_op_addr_add(ctx, t0, t1, t0);
10959 tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_TESL);
10960 gen_store_gpr(t1, rd);
10962 tcg_temp_free(t0);
10963 tcg_temp_free(t1);
10966 static void gen_ldst_pair (DisasContext *ctx, uint32_t opc, int rd,
10967 int base, int16_t offset)
10969 const char *opn = "ldst_pair";
10970 TCGv t0, t1;
10972 if (ctx->hflags & MIPS_HFLAG_BMASK || rd == 31) {
10973 generate_exception(ctx, EXCP_RI);
10974 return;
10977 t0 = tcg_temp_new();
10978 t1 = tcg_temp_new();
10980 gen_base_offset_addr(ctx, t0, base, offset);
10982 switch (opc) {
10983 case LWP:
10984 if (rd == base) {
10985 generate_exception(ctx, EXCP_RI);
10986 return;
10988 tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_TESL);
10989 gen_store_gpr(t1, rd);
10990 tcg_gen_movi_tl(t1, 4);
10991 gen_op_addr_add(ctx, t0, t0, t1);
10992 tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_TESL);
10993 gen_store_gpr(t1, rd+1);
10994 opn = "lwp";
10995 break;
10996 case SWP:
10997 gen_load_gpr(t1, rd);
10998 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL);
10999 tcg_gen_movi_tl(t1, 4);
11000 gen_op_addr_add(ctx, t0, t0, t1);
11001 gen_load_gpr(t1, rd+1);
11002 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL);
11003 opn = "swp";
11004 break;
11005 #ifdef TARGET_MIPS64
11006 case LDP:
11007 if (rd == base) {
11008 generate_exception(ctx, EXCP_RI);
11009 return;
11011 tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_TEQ);
11012 gen_store_gpr(t1, rd);
11013 tcg_gen_movi_tl(t1, 8);
11014 gen_op_addr_add(ctx, t0, t0, t1);
11015 tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_TEQ);
11016 gen_store_gpr(t1, rd+1);
11017 opn = "ldp";
11018 break;
11019 case SDP:
11020 gen_load_gpr(t1, rd);
11021 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEQ);
11022 tcg_gen_movi_tl(t1, 8);
11023 gen_op_addr_add(ctx, t0, t0, t1);
11024 gen_load_gpr(t1, rd+1);
11025 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEQ);
11026 opn = "sdp";
11027 break;
11028 #endif
11030 (void)opn; /* avoid a compiler warning */
11031 MIPS_DEBUG("%s, %s, %d(%s)", opn, regnames[rd], offset, regnames[base]);
11032 tcg_temp_free(t0);
11033 tcg_temp_free(t1);
11036 static void gen_pool32axf (CPUMIPSState *env, DisasContext *ctx, int rt, int rs)
11038 int extension = (ctx->opcode >> 6) & 0x3f;
11039 int minor = (ctx->opcode >> 12) & 0xf;
11040 uint32_t mips32_op;
11042 switch (extension) {
11043 case TEQ:
11044 mips32_op = OPC_TEQ;
11045 goto do_trap;
11046 case TGE:
11047 mips32_op = OPC_TGE;
11048 goto do_trap;
11049 case TGEU:
11050 mips32_op = OPC_TGEU;
11051 goto do_trap;
11052 case TLT:
11053 mips32_op = OPC_TLT;
11054 goto do_trap;
11055 case TLTU:
11056 mips32_op = OPC_TLTU;
11057 goto do_trap;
11058 case TNE:
11059 mips32_op = OPC_TNE;
11060 do_trap:
11061 gen_trap(ctx, mips32_op, rs, rt, -1);
11062 break;
11063 #ifndef CONFIG_USER_ONLY
11064 case MFC0:
11065 case MFC0 + 32:
11066 check_cp0_enabled(ctx);
11067 if (rt == 0) {
11068 /* Treat as NOP. */
11069 break;
11071 gen_mfc0(ctx, cpu_gpr[rt], rs, (ctx->opcode >> 11) & 0x7);
11072 break;
11073 case MTC0:
11074 case MTC0 + 32:
11075 check_cp0_enabled(ctx);
11077 TCGv t0 = tcg_temp_new();
11079 gen_load_gpr(t0, rt);
11080 gen_mtc0(ctx, t0, rs, (ctx->opcode >> 11) & 0x7);
11081 tcg_temp_free(t0);
11083 break;
11084 #endif
11085 case 0x2a:
11086 switch (minor & 3) {
11087 case MADD_ACC:
11088 gen_muldiv(ctx, OPC_MADD, (ctx->opcode >> 14) & 3, rs, rt);
11089 break;
11090 case MADDU_ACC:
11091 gen_muldiv(ctx, OPC_MADDU, (ctx->opcode >> 14) & 3, rs, rt);
11092 break;
11093 case MSUB_ACC:
11094 gen_muldiv(ctx, OPC_MSUB, (ctx->opcode >> 14) & 3, rs, rt);
11095 break;
11096 case MSUBU_ACC:
11097 gen_muldiv(ctx, OPC_MSUBU, (ctx->opcode >> 14) & 3, rs, rt);
11098 break;
11099 default:
11100 goto pool32axf_invalid;
11102 break;
11103 case 0x32:
11104 switch (minor & 3) {
11105 case MULT_ACC:
11106 gen_muldiv(ctx, OPC_MULT, (ctx->opcode >> 14) & 3, rs, rt);
11107 break;
11108 case MULTU_ACC:
11109 gen_muldiv(ctx, OPC_MULTU, (ctx->opcode >> 14) & 3, rs, rt);
11110 break;
11111 default:
11112 goto pool32axf_invalid;
11114 break;
11115 case 0x2c:
11116 switch (minor) {
11117 case SEB:
11118 gen_bshfl(ctx, OPC_SEB, rs, rt);
11119 break;
11120 case SEH:
11121 gen_bshfl(ctx, OPC_SEH, rs, rt);
11122 break;
11123 case CLO:
11124 mips32_op = OPC_CLO;
11125 goto do_cl;
11126 case CLZ:
11127 mips32_op = OPC_CLZ;
11128 do_cl:
11129 check_insn(ctx, ISA_MIPS32);
11130 gen_cl(ctx, mips32_op, rt, rs);
11131 break;
11132 case RDHWR:
11133 gen_rdhwr(ctx, rt, rs);
11134 break;
11135 case WSBH:
11136 gen_bshfl(ctx, OPC_WSBH, rs, rt);
11137 break;
11138 case MULT:
11139 mips32_op = OPC_MULT;
11140 goto do_mul;
11141 case MULTU:
11142 mips32_op = OPC_MULTU;
11143 goto do_mul;
11144 case DIV:
11145 mips32_op = OPC_DIV;
11146 goto do_div;
11147 case DIVU:
11148 mips32_op = OPC_DIVU;
11149 goto do_div;
11150 do_div:
11151 check_insn(ctx, ISA_MIPS32);
11152 gen_muldiv(ctx, mips32_op, 0, rs, rt);
11153 break;
11154 case MADD:
11155 mips32_op = OPC_MADD;
11156 goto do_mul;
11157 case MADDU:
11158 mips32_op = OPC_MADDU;
11159 goto do_mul;
11160 case MSUB:
11161 mips32_op = OPC_MSUB;
11162 goto do_mul;
11163 case MSUBU:
11164 mips32_op = OPC_MSUBU;
11165 do_mul:
11166 check_insn(ctx, ISA_MIPS32);
11167 gen_muldiv(ctx, mips32_op, 0, rs, rt);
11168 break;
11169 default:
11170 goto pool32axf_invalid;
11172 break;
11173 case 0x34:
11174 switch (minor) {
11175 case MFC2:
11176 case MTC2:
11177 case MFHC2:
11178 case MTHC2:
11179 case CFC2:
11180 case CTC2:
11181 generate_exception_err(ctx, EXCP_CpU, 2);
11182 break;
11183 default:
11184 goto pool32axf_invalid;
11186 break;
11187 case 0x3c:
11188 switch (minor) {
11189 case JALR:
11190 case JALR_HB:
11191 gen_compute_branch (ctx, OPC_JALR, 4, rs, rt, 0);
11192 break;
11193 case JALRS:
11194 case JALRS_HB:
11195 gen_compute_branch (ctx, OPC_JALRS, 4, rs, rt, 0);
11196 break;
11197 default:
11198 goto pool32axf_invalid;
11200 break;
11201 case 0x05:
11202 switch (minor) {
11203 case RDPGPR:
11204 check_cp0_enabled(ctx);
11205 check_insn(ctx, ISA_MIPS32R2);
11206 gen_load_srsgpr(rt, rs);
11207 break;
11208 case WRPGPR:
11209 check_cp0_enabled(ctx);
11210 check_insn(ctx, ISA_MIPS32R2);
11211 gen_store_srsgpr(rt, rs);
11212 break;
11213 default:
11214 goto pool32axf_invalid;
11216 break;
11217 #ifndef CONFIG_USER_ONLY
11218 case 0x0d:
11219 switch (minor) {
11220 case TLBP:
11221 mips32_op = OPC_TLBP;
11222 goto do_cp0;
11223 case TLBR:
11224 mips32_op = OPC_TLBR;
11225 goto do_cp0;
11226 case TLBWI:
11227 mips32_op = OPC_TLBWI;
11228 goto do_cp0;
11229 case TLBWR:
11230 mips32_op = OPC_TLBWR;
11231 goto do_cp0;
11232 case WAIT:
11233 mips32_op = OPC_WAIT;
11234 goto do_cp0;
11235 case DERET:
11236 mips32_op = OPC_DERET;
11237 goto do_cp0;
11238 case ERET:
11239 mips32_op = OPC_ERET;
11240 do_cp0:
11241 gen_cp0(env, ctx, mips32_op, rt, rs);
11242 break;
11243 default:
11244 goto pool32axf_invalid;
11246 break;
11247 case 0x1d:
11248 switch (minor) {
11249 case DI:
11250 check_cp0_enabled(ctx);
11252 TCGv t0 = tcg_temp_new();
11254 save_cpu_state(ctx, 1);
11255 gen_helper_di(t0, cpu_env);
11256 gen_store_gpr(t0, rs);
11257 /* Stop translation as we may have switched the execution mode */
11258 ctx->bstate = BS_STOP;
11259 tcg_temp_free(t0);
11261 break;
11262 case EI:
11263 check_cp0_enabled(ctx);
11265 TCGv t0 = tcg_temp_new();
11267 save_cpu_state(ctx, 1);
11268 gen_helper_ei(t0, cpu_env);
11269 gen_store_gpr(t0, rs);
11270 /* Stop translation as we may have switched the execution mode */
11271 ctx->bstate = BS_STOP;
11272 tcg_temp_free(t0);
11274 break;
11275 default:
11276 goto pool32axf_invalid;
11278 break;
11279 #endif
11280 case 0x2d:
11281 switch (minor) {
11282 case SYNC:
11283 /* NOP */
11284 break;
11285 case SYSCALL:
11286 generate_exception(ctx, EXCP_SYSCALL);
11287 ctx->bstate = BS_STOP;
11288 break;
11289 case SDBBP:
11290 check_insn(ctx, ISA_MIPS32);
11291 if (!(ctx->hflags & MIPS_HFLAG_DM)) {
11292 generate_exception(ctx, EXCP_DBp);
11293 } else {
11294 generate_exception(ctx, EXCP_DBp);
11296 break;
11297 default:
11298 goto pool32axf_invalid;
11300 break;
11301 case 0x01:
11302 switch (minor & 3) {
11303 case MFHI_ACC:
11304 gen_HILO(ctx, OPC_MFHI, minor >> 2, rs);
11305 break;
11306 case MFLO_ACC:
11307 gen_HILO(ctx, OPC_MFLO, minor >> 2, rs);
11308 break;
11309 case MTHI_ACC:
11310 gen_HILO(ctx, OPC_MTHI, minor >> 2, rs);
11311 break;
11312 case MTLO_ACC:
11313 gen_HILO(ctx, OPC_MTLO, minor >> 2, rs);
11314 break;
11315 default:
11316 goto pool32axf_invalid;
11318 break;
11319 case 0x35:
11320 switch (minor) {
11321 case MFHI32:
11322 gen_HILO(ctx, OPC_MFHI, 0, rs);
11323 break;
11324 case MFLO32:
11325 gen_HILO(ctx, OPC_MFLO, 0, rs);
11326 break;
11327 case MTHI32:
11328 gen_HILO(ctx, OPC_MTHI, 0, rs);
11329 break;
11330 case MTLO32:
11331 gen_HILO(ctx, OPC_MTLO, 0, rs);
11332 break;
11333 default:
11334 goto pool32axf_invalid;
11336 break;
11337 default:
11338 pool32axf_invalid:
11339 MIPS_INVAL("pool32axf");
11340 generate_exception(ctx, EXCP_RI);
11341 break;
11345 /* Values for microMIPS fmt field. Variable-width, depending on which
11346 formats the instruction supports. */
11348 enum {
11349 FMT_SD_S = 0,
11350 FMT_SD_D = 1,
11352 FMT_SDPS_S = 0,
11353 FMT_SDPS_D = 1,
11354 FMT_SDPS_PS = 2,
11356 FMT_SWL_S = 0,
11357 FMT_SWL_W = 1,
11358 FMT_SWL_L = 2,
11360 FMT_DWL_D = 0,
11361 FMT_DWL_W = 1,
11362 FMT_DWL_L = 2
11365 static void gen_pool32fxf(DisasContext *ctx, int rt, int rs)
11367 int extension = (ctx->opcode >> 6) & 0x3ff;
11368 uint32_t mips32_op;
11370 #define FLOAT_1BIT_FMT(opc, fmt) (fmt << 8) | opc
11371 #define FLOAT_2BIT_FMT(opc, fmt) (fmt << 7) | opc
11372 #define COND_FLOAT_MOV(opc, cond) (cond << 7) | opc
11374 switch (extension) {
11375 case FLOAT_1BIT_FMT(CFC1, 0):
11376 mips32_op = OPC_CFC1;
11377 goto do_cp1;
11378 case FLOAT_1BIT_FMT(CTC1, 0):
11379 mips32_op = OPC_CTC1;
11380 goto do_cp1;
11381 case FLOAT_1BIT_FMT(MFC1, 0):
11382 mips32_op = OPC_MFC1;
11383 goto do_cp1;
11384 case FLOAT_1BIT_FMT(MTC1, 0):
11385 mips32_op = OPC_MTC1;
11386 goto do_cp1;
11387 case FLOAT_1BIT_FMT(MFHC1, 0):
11388 mips32_op = OPC_MFHC1;
11389 goto do_cp1;
11390 case FLOAT_1BIT_FMT(MTHC1, 0):
11391 mips32_op = OPC_MTHC1;
11392 do_cp1:
11393 gen_cp1(ctx, mips32_op, rt, rs);
11394 break;
11396 /* Reciprocal square root */
11397 case FLOAT_1BIT_FMT(RSQRT_FMT, FMT_SD_S):
11398 mips32_op = OPC_RSQRT_S;
11399 goto do_unaryfp;
11400 case FLOAT_1BIT_FMT(RSQRT_FMT, FMT_SD_D):
11401 mips32_op = OPC_RSQRT_D;
11402 goto do_unaryfp;
11404 /* Square root */
11405 case FLOAT_1BIT_FMT(SQRT_FMT, FMT_SD_S):
11406 mips32_op = OPC_SQRT_S;
11407 goto do_unaryfp;
11408 case FLOAT_1BIT_FMT(SQRT_FMT, FMT_SD_D):
11409 mips32_op = OPC_SQRT_D;
11410 goto do_unaryfp;
11412 /* Reciprocal */
11413 case FLOAT_1BIT_FMT(RECIP_FMT, FMT_SD_S):
11414 mips32_op = OPC_RECIP_S;
11415 goto do_unaryfp;
11416 case FLOAT_1BIT_FMT(RECIP_FMT, FMT_SD_D):
11417 mips32_op = OPC_RECIP_D;
11418 goto do_unaryfp;
11420 /* Floor */
11421 case FLOAT_1BIT_FMT(FLOOR_L, FMT_SD_S):
11422 mips32_op = OPC_FLOOR_L_S;
11423 goto do_unaryfp;
11424 case FLOAT_1BIT_FMT(FLOOR_L, FMT_SD_D):
11425 mips32_op = OPC_FLOOR_L_D;
11426 goto do_unaryfp;
11427 case FLOAT_1BIT_FMT(FLOOR_W, FMT_SD_S):
11428 mips32_op = OPC_FLOOR_W_S;
11429 goto do_unaryfp;
11430 case FLOAT_1BIT_FMT(FLOOR_W, FMT_SD_D):
11431 mips32_op = OPC_FLOOR_W_D;
11432 goto do_unaryfp;
11434 /* Ceiling */
11435 case FLOAT_1BIT_FMT(CEIL_L, FMT_SD_S):
11436 mips32_op = OPC_CEIL_L_S;
11437 goto do_unaryfp;
11438 case FLOAT_1BIT_FMT(CEIL_L, FMT_SD_D):
11439 mips32_op = OPC_CEIL_L_D;
11440 goto do_unaryfp;
11441 case FLOAT_1BIT_FMT(CEIL_W, FMT_SD_S):
11442 mips32_op = OPC_CEIL_W_S;
11443 goto do_unaryfp;
11444 case FLOAT_1BIT_FMT(CEIL_W, FMT_SD_D):
11445 mips32_op = OPC_CEIL_W_D;
11446 goto do_unaryfp;
11448 /* Truncation */
11449 case FLOAT_1BIT_FMT(TRUNC_L, FMT_SD_S):
11450 mips32_op = OPC_TRUNC_L_S;
11451 goto do_unaryfp;
11452 case FLOAT_1BIT_FMT(TRUNC_L, FMT_SD_D):
11453 mips32_op = OPC_TRUNC_L_D;
11454 goto do_unaryfp;
11455 case FLOAT_1BIT_FMT(TRUNC_W, FMT_SD_S):
11456 mips32_op = OPC_TRUNC_W_S;
11457 goto do_unaryfp;
11458 case FLOAT_1BIT_FMT(TRUNC_W, FMT_SD_D):
11459 mips32_op = OPC_TRUNC_W_D;
11460 goto do_unaryfp;
11462 /* Round */
11463 case FLOAT_1BIT_FMT(ROUND_L, FMT_SD_S):
11464 mips32_op = OPC_ROUND_L_S;
11465 goto do_unaryfp;
11466 case FLOAT_1BIT_FMT(ROUND_L, FMT_SD_D):
11467 mips32_op = OPC_ROUND_L_D;
11468 goto do_unaryfp;
11469 case FLOAT_1BIT_FMT(ROUND_W, FMT_SD_S):
11470 mips32_op = OPC_ROUND_W_S;
11471 goto do_unaryfp;
11472 case FLOAT_1BIT_FMT(ROUND_W, FMT_SD_D):
11473 mips32_op = OPC_ROUND_W_D;
11474 goto do_unaryfp;
11476 /* Integer to floating-point conversion */
11477 case FLOAT_1BIT_FMT(CVT_L, FMT_SD_S):
11478 mips32_op = OPC_CVT_L_S;
11479 goto do_unaryfp;
11480 case FLOAT_1BIT_FMT(CVT_L, FMT_SD_D):
11481 mips32_op = OPC_CVT_L_D;
11482 goto do_unaryfp;
11483 case FLOAT_1BIT_FMT(CVT_W, FMT_SD_S):
11484 mips32_op = OPC_CVT_W_S;
11485 goto do_unaryfp;
11486 case FLOAT_1BIT_FMT(CVT_W, FMT_SD_D):
11487 mips32_op = OPC_CVT_W_D;
11488 goto do_unaryfp;
11490 /* Paired-foo conversions */
11491 case FLOAT_1BIT_FMT(CVT_S_PL, 0):
11492 mips32_op = OPC_CVT_S_PL;
11493 goto do_unaryfp;
11494 case FLOAT_1BIT_FMT(CVT_S_PU, 0):
11495 mips32_op = OPC_CVT_S_PU;
11496 goto do_unaryfp;
11497 case FLOAT_1BIT_FMT(CVT_PW_PS, 0):
11498 mips32_op = OPC_CVT_PW_PS;
11499 goto do_unaryfp;
11500 case FLOAT_1BIT_FMT(CVT_PS_PW, 0):
11501 mips32_op = OPC_CVT_PS_PW;
11502 goto do_unaryfp;
11504 /* Floating-point moves */
11505 case FLOAT_2BIT_FMT(MOV_FMT, FMT_SDPS_S):
11506 mips32_op = OPC_MOV_S;
11507 goto do_unaryfp;
11508 case FLOAT_2BIT_FMT(MOV_FMT, FMT_SDPS_D):
11509 mips32_op = OPC_MOV_D;
11510 goto do_unaryfp;
11511 case FLOAT_2BIT_FMT(MOV_FMT, FMT_SDPS_PS):
11512 mips32_op = OPC_MOV_PS;
11513 goto do_unaryfp;
11515 /* Absolute value */
11516 case FLOAT_2BIT_FMT(ABS_FMT, FMT_SDPS_S):
11517 mips32_op = OPC_ABS_S;
11518 goto do_unaryfp;
11519 case FLOAT_2BIT_FMT(ABS_FMT, FMT_SDPS_D):
11520 mips32_op = OPC_ABS_D;
11521 goto do_unaryfp;
11522 case FLOAT_2BIT_FMT(ABS_FMT, FMT_SDPS_PS):
11523 mips32_op = OPC_ABS_PS;
11524 goto do_unaryfp;
11526 /* Negation */
11527 case FLOAT_2BIT_FMT(NEG_FMT, FMT_SDPS_S):
11528 mips32_op = OPC_NEG_S;
11529 goto do_unaryfp;
11530 case FLOAT_2BIT_FMT(NEG_FMT, FMT_SDPS_D):
11531 mips32_op = OPC_NEG_D;
11532 goto do_unaryfp;
11533 case FLOAT_2BIT_FMT(NEG_FMT, FMT_SDPS_PS):
11534 mips32_op = OPC_NEG_PS;
11535 goto do_unaryfp;
11537 /* Reciprocal square root step */
11538 case FLOAT_2BIT_FMT(RSQRT1_FMT, FMT_SDPS_S):
11539 mips32_op = OPC_RSQRT1_S;
11540 goto do_unaryfp;
11541 case FLOAT_2BIT_FMT(RSQRT1_FMT, FMT_SDPS_D):
11542 mips32_op = OPC_RSQRT1_D;
11543 goto do_unaryfp;
11544 case FLOAT_2BIT_FMT(RSQRT1_FMT, FMT_SDPS_PS):
11545 mips32_op = OPC_RSQRT1_PS;
11546 goto do_unaryfp;
11548 /* Reciprocal step */
11549 case FLOAT_2BIT_FMT(RECIP1_FMT, FMT_SDPS_S):
11550 mips32_op = OPC_RECIP1_S;
11551 goto do_unaryfp;
11552 case FLOAT_2BIT_FMT(RECIP1_FMT, FMT_SDPS_D):
11553 mips32_op = OPC_RECIP1_S;
11554 goto do_unaryfp;
11555 case FLOAT_2BIT_FMT(RECIP1_FMT, FMT_SDPS_PS):
11556 mips32_op = OPC_RECIP1_PS;
11557 goto do_unaryfp;
11559 /* Conversions from double */
11560 case FLOAT_2BIT_FMT(CVT_D, FMT_SWL_S):
11561 mips32_op = OPC_CVT_D_S;
11562 goto do_unaryfp;
11563 case FLOAT_2BIT_FMT(CVT_D, FMT_SWL_W):
11564 mips32_op = OPC_CVT_D_W;
11565 goto do_unaryfp;
11566 case FLOAT_2BIT_FMT(CVT_D, FMT_SWL_L):
11567 mips32_op = OPC_CVT_D_L;
11568 goto do_unaryfp;
11570 /* Conversions from single */
11571 case FLOAT_2BIT_FMT(CVT_S, FMT_DWL_D):
11572 mips32_op = OPC_CVT_S_D;
11573 goto do_unaryfp;
11574 case FLOAT_2BIT_FMT(CVT_S, FMT_DWL_W):
11575 mips32_op = OPC_CVT_S_W;
11576 goto do_unaryfp;
11577 case FLOAT_2BIT_FMT(CVT_S, FMT_DWL_L):
11578 mips32_op = OPC_CVT_S_L;
11579 do_unaryfp:
11580 gen_farith(ctx, mips32_op, -1, rs, rt, 0);
11581 break;
11583 /* Conditional moves on floating-point codes */
11584 case COND_FLOAT_MOV(MOVT, 0):
11585 case COND_FLOAT_MOV(MOVT, 1):
11586 case COND_FLOAT_MOV(MOVT, 2):
11587 case COND_FLOAT_MOV(MOVT, 3):
11588 case COND_FLOAT_MOV(MOVT, 4):
11589 case COND_FLOAT_MOV(MOVT, 5):
11590 case COND_FLOAT_MOV(MOVT, 6):
11591 case COND_FLOAT_MOV(MOVT, 7):
11592 gen_movci(ctx, rt, rs, (ctx->opcode >> 13) & 0x7, 1);
11593 break;
11594 case COND_FLOAT_MOV(MOVF, 0):
11595 case COND_FLOAT_MOV(MOVF, 1):
11596 case COND_FLOAT_MOV(MOVF, 2):
11597 case COND_FLOAT_MOV(MOVF, 3):
11598 case COND_FLOAT_MOV(MOVF, 4):
11599 case COND_FLOAT_MOV(MOVF, 5):
11600 case COND_FLOAT_MOV(MOVF, 6):
11601 case COND_FLOAT_MOV(MOVF, 7):
11602 gen_movci(ctx, rt, rs, (ctx->opcode >> 13) & 0x7, 0);
11603 break;
11604 default:
11605 MIPS_INVAL("pool32fxf");
11606 generate_exception(ctx, EXCP_RI);
11607 break;
11611 static void decode_micromips32_opc (CPUMIPSState *env, DisasContext *ctx,
11612 uint16_t insn_hw1)
11614 int32_t offset;
11615 uint16_t insn;
11616 int rt, rs, rd, rr;
11617 int16_t imm;
11618 uint32_t op, minor, mips32_op;
11619 uint32_t cond, fmt, cc;
11621 insn = cpu_lduw_code(env, ctx->pc + 2);
11622 ctx->opcode = (ctx->opcode << 16) | insn;
11624 rt = (ctx->opcode >> 21) & 0x1f;
11625 rs = (ctx->opcode >> 16) & 0x1f;
11626 rd = (ctx->opcode >> 11) & 0x1f;
11627 rr = (ctx->opcode >> 6) & 0x1f;
11628 imm = (int16_t) ctx->opcode;
11630 op = (ctx->opcode >> 26) & 0x3f;
11631 switch (op) {
11632 case POOL32A:
11633 minor = ctx->opcode & 0x3f;
11634 switch (minor) {
11635 case 0x00:
11636 minor = (ctx->opcode >> 6) & 0xf;
11637 switch (minor) {
11638 case SLL32:
11639 mips32_op = OPC_SLL;
11640 goto do_shifti;
11641 case SRA:
11642 mips32_op = OPC_SRA;
11643 goto do_shifti;
11644 case SRL32:
11645 mips32_op = OPC_SRL;
11646 goto do_shifti;
11647 case ROTR:
11648 mips32_op = OPC_ROTR;
11649 do_shifti:
11650 gen_shift_imm(ctx, mips32_op, rt, rs, rd);
11651 break;
11652 default:
11653 goto pool32a_invalid;
11655 break;
11656 case 0x10:
11657 minor = (ctx->opcode >> 6) & 0xf;
11658 switch (minor) {
11659 /* Arithmetic */
11660 case ADD:
11661 mips32_op = OPC_ADD;
11662 goto do_arith;
11663 case ADDU32:
11664 mips32_op = OPC_ADDU;
11665 goto do_arith;
11666 case SUB:
11667 mips32_op = OPC_SUB;
11668 goto do_arith;
11669 case SUBU32:
11670 mips32_op = OPC_SUBU;
11671 goto do_arith;
11672 case MUL:
11673 mips32_op = OPC_MUL;
11674 do_arith:
11675 gen_arith(ctx, mips32_op, rd, rs, rt);
11676 break;
11677 /* Shifts */
11678 case SLLV:
11679 mips32_op = OPC_SLLV;
11680 goto do_shift;
11681 case SRLV:
11682 mips32_op = OPC_SRLV;
11683 goto do_shift;
11684 case SRAV:
11685 mips32_op = OPC_SRAV;
11686 goto do_shift;
11687 case ROTRV:
11688 mips32_op = OPC_ROTRV;
11689 do_shift:
11690 gen_shift(ctx, mips32_op, rd, rs, rt);
11691 break;
11692 /* Logical operations */
11693 case AND:
11694 mips32_op = OPC_AND;
11695 goto do_logic;
11696 case OR32:
11697 mips32_op = OPC_OR;
11698 goto do_logic;
11699 case NOR:
11700 mips32_op = OPC_NOR;
11701 goto do_logic;
11702 case XOR32:
11703 mips32_op = OPC_XOR;
11704 do_logic:
11705 gen_logic(ctx, mips32_op, rd, rs, rt);
11706 break;
11707 /* Set less than */
11708 case SLT:
11709 mips32_op = OPC_SLT;
11710 goto do_slt;
11711 case SLTU:
11712 mips32_op = OPC_SLTU;
11713 do_slt:
11714 gen_slt(ctx, mips32_op, rd, rs, rt);
11715 break;
11716 default:
11717 goto pool32a_invalid;
11719 break;
11720 case 0x18:
11721 minor = (ctx->opcode >> 6) & 0xf;
11722 switch (minor) {
11723 /* Conditional moves */
11724 case MOVN:
11725 mips32_op = OPC_MOVN;
11726 goto do_cmov;
11727 case MOVZ:
11728 mips32_op = OPC_MOVZ;
11729 do_cmov:
11730 gen_cond_move(ctx, mips32_op, rd, rs, rt);
11731 break;
11732 case LWXS:
11733 gen_ldxs(ctx, rs, rt, rd);
11734 break;
11735 default:
11736 goto pool32a_invalid;
11738 break;
11739 case INS:
11740 gen_bitops(ctx, OPC_INS, rt, rs, rr, rd);
11741 return;
11742 case EXT:
11743 gen_bitops(ctx, OPC_EXT, rt, rs, rr, rd);
11744 return;
11745 case POOL32AXF:
11746 gen_pool32axf(env, ctx, rt, rs);
11747 break;
11748 case 0x07:
11749 generate_exception(ctx, EXCP_BREAK);
11750 break;
11751 default:
11752 pool32a_invalid:
11753 MIPS_INVAL("pool32a");
11754 generate_exception(ctx, EXCP_RI);
11755 break;
11757 break;
11758 case POOL32B:
11759 minor = (ctx->opcode >> 12) & 0xf;
11760 switch (minor) {
11761 case CACHE:
11762 check_cp0_enabled(ctx);
11763 /* Treat as no-op. */
11764 break;
11765 case LWC2:
11766 case SWC2:
11767 /* COP2: Not implemented. */
11768 generate_exception_err(ctx, EXCP_CpU, 2);
11769 break;
11770 case LWP:
11771 case SWP:
11772 #ifdef TARGET_MIPS64
11773 case LDP:
11774 case SDP:
11775 #endif
11776 gen_ldst_pair(ctx, minor, rt, rs, SIMM(ctx->opcode, 0, 12));
11777 break;
11778 case LWM32:
11779 case SWM32:
11780 #ifdef TARGET_MIPS64
11781 case LDM:
11782 case SDM:
11783 #endif
11784 gen_ldst_multiple(ctx, minor, rt, rs, SIMM(ctx->opcode, 0, 12));
11785 break;
11786 default:
11787 MIPS_INVAL("pool32b");
11788 generate_exception(ctx, EXCP_RI);
11789 break;
11791 break;
11792 case POOL32F:
11793 if (env->CP0_Config1 & (1 << CP0C1_FP)) {
11794 minor = ctx->opcode & 0x3f;
11795 check_cp1_enabled(ctx);
11796 switch (minor) {
11797 case ALNV_PS:
11798 mips32_op = OPC_ALNV_PS;
11799 goto do_madd;
11800 case MADD_S:
11801 mips32_op = OPC_MADD_S;
11802 goto do_madd;
11803 case MADD_D:
11804 mips32_op = OPC_MADD_D;
11805 goto do_madd;
11806 case MADD_PS:
11807 mips32_op = OPC_MADD_PS;
11808 goto do_madd;
11809 case MSUB_S:
11810 mips32_op = OPC_MSUB_S;
11811 goto do_madd;
11812 case MSUB_D:
11813 mips32_op = OPC_MSUB_D;
11814 goto do_madd;
11815 case MSUB_PS:
11816 mips32_op = OPC_MSUB_PS;
11817 goto do_madd;
11818 case NMADD_S:
11819 mips32_op = OPC_NMADD_S;
11820 goto do_madd;
11821 case NMADD_D:
11822 mips32_op = OPC_NMADD_D;
11823 goto do_madd;
11824 case NMADD_PS:
11825 mips32_op = OPC_NMADD_PS;
11826 goto do_madd;
11827 case NMSUB_S:
11828 mips32_op = OPC_NMSUB_S;
11829 goto do_madd;
11830 case NMSUB_D:
11831 mips32_op = OPC_NMSUB_D;
11832 goto do_madd;
11833 case NMSUB_PS:
11834 mips32_op = OPC_NMSUB_PS;
11835 do_madd:
11836 gen_flt3_arith(ctx, mips32_op, rd, rr, rs, rt);
11837 break;
11838 case CABS_COND_FMT:
11839 cond = (ctx->opcode >> 6) & 0xf;
11840 cc = (ctx->opcode >> 13) & 0x7;
11841 fmt = (ctx->opcode >> 10) & 0x3;
11842 switch (fmt) {
11843 case 0x0:
11844 gen_cmpabs_s(ctx, cond, rt, rs, cc);
11845 break;
11846 case 0x1:
11847 gen_cmpabs_d(ctx, cond, rt, rs, cc);
11848 break;
11849 case 0x2:
11850 gen_cmpabs_ps(ctx, cond, rt, rs, cc);
11851 break;
11852 default:
11853 goto pool32f_invalid;
11855 break;
11856 case C_COND_FMT:
11857 cond = (ctx->opcode >> 6) & 0xf;
11858 cc = (ctx->opcode >> 13) & 0x7;
11859 fmt = (ctx->opcode >> 10) & 0x3;
11860 switch (fmt) {
11861 case 0x0:
11862 gen_cmp_s(ctx, cond, rt, rs, cc);
11863 break;
11864 case 0x1:
11865 gen_cmp_d(ctx, cond, rt, rs, cc);
11866 break;
11867 case 0x2:
11868 gen_cmp_ps(ctx, cond, rt, rs, cc);
11869 break;
11870 default:
11871 goto pool32f_invalid;
11873 break;
11874 case POOL32FXF:
11875 gen_pool32fxf(ctx, rt, rs);
11876 break;
11877 case 0x00:
11878 /* PLL foo */
11879 switch ((ctx->opcode >> 6) & 0x7) {
11880 case PLL_PS:
11881 mips32_op = OPC_PLL_PS;
11882 goto do_ps;
11883 case PLU_PS:
11884 mips32_op = OPC_PLU_PS;
11885 goto do_ps;
11886 case PUL_PS:
11887 mips32_op = OPC_PUL_PS;
11888 goto do_ps;
11889 case PUU_PS:
11890 mips32_op = OPC_PUU_PS;
11891 goto do_ps;
11892 case CVT_PS_S:
11893 mips32_op = OPC_CVT_PS_S;
11894 do_ps:
11895 gen_farith(ctx, mips32_op, rt, rs, rd, 0);
11896 break;
11897 default:
11898 goto pool32f_invalid;
11900 break;
11901 case 0x08:
11902 /* [LS][WDU]XC1 */
11903 switch ((ctx->opcode >> 6) & 0x7) {
11904 case LWXC1:
11905 mips32_op = OPC_LWXC1;
11906 goto do_ldst_cp1;
11907 case SWXC1:
11908 mips32_op = OPC_SWXC1;
11909 goto do_ldst_cp1;
11910 case LDXC1:
11911 mips32_op = OPC_LDXC1;
11912 goto do_ldst_cp1;
11913 case SDXC1:
11914 mips32_op = OPC_SDXC1;
11915 goto do_ldst_cp1;
11916 case LUXC1:
11917 mips32_op = OPC_LUXC1;
11918 goto do_ldst_cp1;
11919 case SUXC1:
11920 mips32_op = OPC_SUXC1;
11921 do_ldst_cp1:
11922 gen_flt3_ldst(ctx, mips32_op, rd, rd, rt, rs);
11923 break;
11924 default:
11925 goto pool32f_invalid;
11927 break;
11928 case 0x18:
11929 /* 3D insns */
11930 fmt = (ctx->opcode >> 9) & 0x3;
11931 switch ((ctx->opcode >> 6) & 0x7) {
11932 case RSQRT2_FMT:
11933 switch (fmt) {
11934 case FMT_SDPS_S:
11935 mips32_op = OPC_RSQRT2_S;
11936 goto do_3d;
11937 case FMT_SDPS_D:
11938 mips32_op = OPC_RSQRT2_D;
11939 goto do_3d;
11940 case FMT_SDPS_PS:
11941 mips32_op = OPC_RSQRT2_PS;
11942 goto do_3d;
11943 default:
11944 goto pool32f_invalid;
11946 break;
11947 case RECIP2_FMT:
11948 switch (fmt) {
11949 case FMT_SDPS_S:
11950 mips32_op = OPC_RECIP2_S;
11951 goto do_3d;
11952 case FMT_SDPS_D:
11953 mips32_op = OPC_RECIP2_D;
11954 goto do_3d;
11955 case FMT_SDPS_PS:
11956 mips32_op = OPC_RECIP2_PS;
11957 goto do_3d;
11958 default:
11959 goto pool32f_invalid;
11961 break;
11962 case ADDR_PS:
11963 mips32_op = OPC_ADDR_PS;
11964 goto do_3d;
11965 case MULR_PS:
11966 mips32_op = OPC_MULR_PS;
11967 do_3d:
11968 gen_farith(ctx, mips32_op, rt, rs, rd, 0);
11969 break;
11970 default:
11971 goto pool32f_invalid;
11973 break;
11974 case 0x20:
11975 /* MOV[FT].fmt and PREFX */
11976 cc = (ctx->opcode >> 13) & 0x7;
11977 fmt = (ctx->opcode >> 9) & 0x3;
11978 switch ((ctx->opcode >> 6) & 0x7) {
11979 case MOVF_FMT:
11980 switch (fmt) {
11981 case FMT_SDPS_S:
11982 gen_movcf_s(rs, rt, cc, 0);
11983 break;
11984 case FMT_SDPS_D:
11985 gen_movcf_d(ctx, rs, rt, cc, 0);
11986 break;
11987 case FMT_SDPS_PS:
11988 gen_movcf_ps(ctx, rs, rt, cc, 0);
11989 break;
11990 default:
11991 goto pool32f_invalid;
11993 break;
11994 case MOVT_FMT:
11995 switch (fmt) {
11996 case FMT_SDPS_S:
11997 gen_movcf_s(rs, rt, cc, 1);
11998 break;
11999 case FMT_SDPS_D:
12000 gen_movcf_d(ctx, rs, rt, cc, 1);
12001 break;
12002 case FMT_SDPS_PS:
12003 gen_movcf_ps(ctx, rs, rt, cc, 1);
12004 break;
12005 default:
12006 goto pool32f_invalid;
12008 break;
12009 case PREFX:
12010 break;
12011 default:
12012 goto pool32f_invalid;
12014 break;
12015 #define FINSN_3ARG_SDPS(prfx) \
12016 switch ((ctx->opcode >> 8) & 0x3) { \
12017 case FMT_SDPS_S: \
12018 mips32_op = OPC_##prfx##_S; \
12019 goto do_fpop; \
12020 case FMT_SDPS_D: \
12021 mips32_op = OPC_##prfx##_D; \
12022 goto do_fpop; \
12023 case FMT_SDPS_PS: \
12024 mips32_op = OPC_##prfx##_PS; \
12025 goto do_fpop; \
12026 default: \
12027 goto pool32f_invalid; \
12029 case 0x30:
12030 /* regular FP ops */
12031 switch ((ctx->opcode >> 6) & 0x3) {
12032 case ADD_FMT:
12033 FINSN_3ARG_SDPS(ADD);
12034 break;
12035 case SUB_FMT:
12036 FINSN_3ARG_SDPS(SUB);
12037 break;
12038 case MUL_FMT:
12039 FINSN_3ARG_SDPS(MUL);
12040 break;
12041 case DIV_FMT:
12042 fmt = (ctx->opcode >> 8) & 0x3;
12043 if (fmt == 1) {
12044 mips32_op = OPC_DIV_D;
12045 } else if (fmt == 0) {
12046 mips32_op = OPC_DIV_S;
12047 } else {
12048 goto pool32f_invalid;
12050 goto do_fpop;
12051 default:
12052 goto pool32f_invalid;
12054 break;
12055 case 0x38:
12056 /* cmovs */
12057 switch ((ctx->opcode >> 6) & 0x3) {
12058 case MOVN_FMT:
12059 FINSN_3ARG_SDPS(MOVN);
12060 break;
12061 case MOVZ_FMT:
12062 FINSN_3ARG_SDPS(MOVZ);
12063 break;
12064 default:
12065 goto pool32f_invalid;
12067 break;
12068 do_fpop:
12069 gen_farith(ctx, mips32_op, rt, rs, rd, 0);
12070 break;
12071 default:
12072 pool32f_invalid:
12073 MIPS_INVAL("pool32f");
12074 generate_exception(ctx, EXCP_RI);
12075 break;
12077 } else {
12078 generate_exception_err(ctx, EXCP_CpU, 1);
12080 break;
12081 case POOL32I:
12082 minor = (ctx->opcode >> 21) & 0x1f;
12083 switch (minor) {
12084 case BLTZ:
12085 mips32_op = OPC_BLTZ;
12086 goto do_branch;
12087 case BLTZAL:
12088 mips32_op = OPC_BLTZAL;
12089 goto do_branch;
12090 case BLTZALS:
12091 mips32_op = OPC_BLTZALS;
12092 goto do_branch;
12093 case BGEZ:
12094 mips32_op = OPC_BGEZ;
12095 goto do_branch;
12096 case BGEZAL:
12097 mips32_op = OPC_BGEZAL;
12098 goto do_branch;
12099 case BGEZALS:
12100 mips32_op = OPC_BGEZALS;
12101 goto do_branch;
12102 case BLEZ:
12103 mips32_op = OPC_BLEZ;
12104 goto do_branch;
12105 case BGTZ:
12106 mips32_op = OPC_BGTZ;
12107 do_branch:
12108 gen_compute_branch(ctx, mips32_op, 4, rs, -1, imm << 1);
12109 break;
12111 /* Traps */
12112 case TLTI:
12113 mips32_op = OPC_TLTI;
12114 goto do_trapi;
12115 case TGEI:
12116 mips32_op = OPC_TGEI;
12117 goto do_trapi;
12118 case TLTIU:
12119 mips32_op = OPC_TLTIU;
12120 goto do_trapi;
12121 case TGEIU:
12122 mips32_op = OPC_TGEIU;
12123 goto do_trapi;
12124 case TNEI:
12125 mips32_op = OPC_TNEI;
12126 goto do_trapi;
12127 case TEQI:
12128 mips32_op = OPC_TEQI;
12129 do_trapi:
12130 gen_trap(ctx, mips32_op, rs, -1, imm);
12131 break;
12133 case BNEZC:
12134 case BEQZC:
12135 gen_compute_branch(ctx, minor == BNEZC ? OPC_BNE : OPC_BEQ,
12136 4, rs, 0, imm << 1);
12137 /* Compact branches don't have a delay slot, so just let
12138 the normal delay slot handling take us to the branch
12139 target. */
12140 break;
12141 case LUI:
12142 gen_logic_imm(ctx, OPC_LUI, rs, -1, imm);
12143 break;
12144 case SYNCI:
12145 break;
12146 case BC2F:
12147 case BC2T:
12148 /* COP2: Not implemented. */
12149 generate_exception_err(ctx, EXCP_CpU, 2);
12150 break;
12151 case BC1F:
12152 mips32_op = (ctx->opcode & (1 << 16)) ? OPC_BC1FANY2 : OPC_BC1F;
12153 goto do_cp1branch;
12154 case BC1T:
12155 mips32_op = (ctx->opcode & (1 << 16)) ? OPC_BC1TANY2 : OPC_BC1T;
12156 goto do_cp1branch;
12157 case BC1ANY4F:
12158 mips32_op = OPC_BC1FANY4;
12159 goto do_cp1mips3d;
12160 case BC1ANY4T:
12161 mips32_op = OPC_BC1TANY4;
12162 do_cp1mips3d:
12163 check_cop1x(ctx);
12164 check_insn(ctx, ASE_MIPS3D);
12165 /* Fall through */
12166 do_cp1branch:
12167 gen_compute_branch1(ctx, mips32_op,
12168 (ctx->opcode >> 18) & 0x7, imm << 1);
12169 break;
12170 case BPOSGE64:
12171 case BPOSGE32:
12172 /* MIPS DSP: not implemented */
12173 /* Fall through */
12174 default:
12175 MIPS_INVAL("pool32i");
12176 generate_exception(ctx, EXCP_RI);
12177 break;
12179 break;
12180 case POOL32C:
12181 minor = (ctx->opcode >> 12) & 0xf;
12182 switch (minor) {
12183 case LWL:
12184 mips32_op = OPC_LWL;
12185 goto do_ld_lr;
12186 case SWL:
12187 mips32_op = OPC_SWL;
12188 goto do_st_lr;
12189 case LWR:
12190 mips32_op = OPC_LWR;
12191 goto do_ld_lr;
12192 case SWR:
12193 mips32_op = OPC_SWR;
12194 goto do_st_lr;
12195 #if defined(TARGET_MIPS64)
12196 case LDL:
12197 mips32_op = OPC_LDL;
12198 goto do_ld_lr;
12199 case SDL:
12200 mips32_op = OPC_SDL;
12201 goto do_st_lr;
12202 case LDR:
12203 mips32_op = OPC_LDR;
12204 goto do_ld_lr;
12205 case SDR:
12206 mips32_op = OPC_SDR;
12207 goto do_st_lr;
12208 case LWU:
12209 mips32_op = OPC_LWU;
12210 goto do_ld_lr;
12211 case LLD:
12212 mips32_op = OPC_LLD;
12213 goto do_ld_lr;
12214 #endif
12215 case LL:
12216 mips32_op = OPC_LL;
12217 goto do_ld_lr;
12218 do_ld_lr:
12219 gen_ld(ctx, mips32_op, rt, rs, SIMM(ctx->opcode, 0, 12));
12220 break;
12221 do_st_lr:
12222 gen_st(ctx, mips32_op, rt, rs, SIMM(ctx->opcode, 0, 12));
12223 break;
12224 case SC:
12225 gen_st_cond(ctx, OPC_SC, rt, rs, SIMM(ctx->opcode, 0, 12));
12226 break;
12227 #if defined(TARGET_MIPS64)
12228 case SCD:
12229 gen_st_cond(ctx, OPC_SCD, rt, rs, SIMM(ctx->opcode, 0, 12));
12230 break;
12231 #endif
12232 case PREF:
12233 /* Treat as no-op */
12234 break;
12235 default:
12236 MIPS_INVAL("pool32c");
12237 generate_exception(ctx, EXCP_RI);
12238 break;
12240 break;
12241 case ADDI32:
12242 mips32_op = OPC_ADDI;
12243 goto do_addi;
12244 case ADDIU32:
12245 mips32_op = OPC_ADDIU;
12246 do_addi:
12247 gen_arith_imm(ctx, mips32_op, rt, rs, imm);
12248 break;
12250 /* Logical operations */
12251 case ORI32:
12252 mips32_op = OPC_ORI;
12253 goto do_logici;
12254 case XORI32:
12255 mips32_op = OPC_XORI;
12256 goto do_logici;
12257 case ANDI32:
12258 mips32_op = OPC_ANDI;
12259 do_logici:
12260 gen_logic_imm(ctx, mips32_op, rt, rs, imm);
12261 break;
12263 /* Set less than immediate */
12264 case SLTI32:
12265 mips32_op = OPC_SLTI;
12266 goto do_slti;
12267 case SLTIU32:
12268 mips32_op = OPC_SLTIU;
12269 do_slti:
12270 gen_slt_imm(ctx, mips32_op, rt, rs, imm);
12271 break;
12272 case JALX32:
12273 offset = (int32_t)(ctx->opcode & 0x3FFFFFF) << 2;
12274 gen_compute_branch(ctx, OPC_JALX, 4, rt, rs, offset);
12275 break;
12276 case JALS32:
12277 offset = (int32_t)(ctx->opcode & 0x3FFFFFF) << 1;
12278 gen_compute_branch(ctx, OPC_JALS, 4, rt, rs, offset);
12279 break;
12280 case BEQ32:
12281 gen_compute_branch(ctx, OPC_BEQ, 4, rt, rs, imm << 1);
12282 break;
12283 case BNE32:
12284 gen_compute_branch(ctx, OPC_BNE, 4, rt, rs, imm << 1);
12285 break;
12286 case J32:
12287 gen_compute_branch(ctx, OPC_J, 4, rt, rs,
12288 (int32_t)(ctx->opcode & 0x3FFFFFF) << 1);
12289 break;
12290 case JAL32:
12291 gen_compute_branch(ctx, OPC_JAL, 4, rt, rs,
12292 (int32_t)(ctx->opcode & 0x3FFFFFF) << 1);
12293 break;
12294 /* Floating point (COP1) */
12295 case LWC132:
12296 mips32_op = OPC_LWC1;
12297 goto do_cop1;
12298 case LDC132:
12299 mips32_op = OPC_LDC1;
12300 goto do_cop1;
12301 case SWC132:
12302 mips32_op = OPC_SWC1;
12303 goto do_cop1;
12304 case SDC132:
12305 mips32_op = OPC_SDC1;
12306 do_cop1:
12307 gen_cop1_ldst(env, ctx, mips32_op, rt, rs, imm);
12308 break;
12309 case ADDIUPC:
12311 int reg = mmreg(ZIMM(ctx->opcode, 23, 3));
12312 int offset = SIMM(ctx->opcode, 0, 23) << 2;
12314 gen_addiupc(ctx, reg, offset, 0, 0);
12316 break;
12317 /* Loads and stores */
12318 case LB32:
12319 mips32_op = OPC_LB;
12320 goto do_ld;
12321 case LBU32:
12322 mips32_op = OPC_LBU;
12323 goto do_ld;
12324 case LH32:
12325 mips32_op = OPC_LH;
12326 goto do_ld;
12327 case LHU32:
12328 mips32_op = OPC_LHU;
12329 goto do_ld;
12330 case LW32:
12331 mips32_op = OPC_LW;
12332 goto do_ld;
12333 #ifdef TARGET_MIPS64
12334 case LD32:
12335 mips32_op = OPC_LD;
12336 goto do_ld;
12337 case SD32:
12338 mips32_op = OPC_SD;
12339 goto do_st;
12340 #endif
12341 case SB32:
12342 mips32_op = OPC_SB;
12343 goto do_st;
12344 case SH32:
12345 mips32_op = OPC_SH;
12346 goto do_st;
12347 case SW32:
12348 mips32_op = OPC_SW;
12349 goto do_st;
12350 do_ld:
12351 gen_ld(ctx, mips32_op, rt, rs, imm);
12352 break;
12353 do_st:
12354 gen_st(ctx, mips32_op, rt, rs, imm);
12355 break;
12356 default:
12357 generate_exception(ctx, EXCP_RI);
12358 break;
12362 static int decode_micromips_opc (CPUMIPSState *env, DisasContext *ctx)
12364 uint32_t op;
12366 /* make sure instructions are on a halfword boundary */
12367 if (ctx->pc & 0x1) {
12368 env->CP0_BadVAddr = ctx->pc;
12369 generate_exception(ctx, EXCP_AdEL);
12370 ctx->bstate = BS_STOP;
12371 return 2;
12374 op = (ctx->opcode >> 10) & 0x3f;
12375 /* Enforce properly-sized instructions in a delay slot */
12376 if (ctx->hflags & MIPS_HFLAG_BMASK) {
12377 int bits = ctx->hflags & MIPS_HFLAG_BMASK_EXT;
12379 switch (op) {
12380 case POOL32A:
12381 case POOL32B:
12382 case POOL32I:
12383 case POOL32C:
12384 case ADDI32:
12385 case ADDIU32:
12386 case ORI32:
12387 case XORI32:
12388 case SLTI32:
12389 case SLTIU32:
12390 case ANDI32:
12391 case JALX32:
12392 case LBU32:
12393 case LHU32:
12394 case POOL32F:
12395 case JALS32:
12396 case BEQ32:
12397 case BNE32:
12398 case J32:
12399 case JAL32:
12400 case SB32:
12401 case SH32:
12402 case POOL32S:
12403 case ADDIUPC:
12404 case SWC132:
12405 case SDC132:
12406 case SD32:
12407 case SW32:
12408 case LB32:
12409 case LH32:
12410 case DADDIU32:
12411 case LWC132:
12412 case LDC132:
12413 case LD32:
12414 case LW32:
12415 if (bits & MIPS_HFLAG_BDS16) {
12416 generate_exception(ctx, EXCP_RI);
12417 /* Just stop translation; the user is confused. */
12418 ctx->bstate = BS_STOP;
12419 return 2;
12421 break;
12422 case POOL16A:
12423 case POOL16B:
12424 case POOL16C:
12425 case LWGP16:
12426 case POOL16F:
12427 case LBU16:
12428 case LHU16:
12429 case LWSP16:
12430 case LW16:
12431 case SB16:
12432 case SH16:
12433 case SWSP16:
12434 case SW16:
12435 case MOVE16:
12436 case ANDI16:
12437 case POOL16D:
12438 case POOL16E:
12439 case BEQZ16:
12440 case BNEZ16:
12441 case B16:
12442 case LI16:
12443 if (bits & MIPS_HFLAG_BDS32) {
12444 generate_exception(ctx, EXCP_RI);
12445 /* Just stop translation; the user is confused. */
12446 ctx->bstate = BS_STOP;
12447 return 2;
12449 break;
12450 default:
12451 break;
12454 switch (op) {
12455 case POOL16A:
12457 int rd = mmreg(uMIPS_RD(ctx->opcode));
12458 int rs1 = mmreg(uMIPS_RS1(ctx->opcode));
12459 int rs2 = mmreg(uMIPS_RS2(ctx->opcode));
12460 uint32_t opc = 0;
12462 switch (ctx->opcode & 0x1) {
12463 case ADDU16:
12464 opc = OPC_ADDU;
12465 break;
12466 case SUBU16:
12467 opc = OPC_SUBU;
12468 break;
12471 gen_arith(ctx, opc, rd, rs1, rs2);
12473 break;
12474 case POOL16B:
12476 int rd = mmreg(uMIPS_RD(ctx->opcode));
12477 int rs = mmreg(uMIPS_RS(ctx->opcode));
12478 int amount = (ctx->opcode >> 1) & 0x7;
12479 uint32_t opc = 0;
12480 amount = amount == 0 ? 8 : amount;
12482 switch (ctx->opcode & 0x1) {
12483 case SLL16:
12484 opc = OPC_SLL;
12485 break;
12486 case SRL16:
12487 opc = OPC_SRL;
12488 break;
12491 gen_shift_imm(ctx, opc, rd, rs, amount);
12493 break;
12494 case POOL16C:
12495 gen_pool16c_insn(ctx);
12496 break;
12497 case LWGP16:
12499 int rd = mmreg(uMIPS_RD(ctx->opcode));
12500 int rb = 28; /* GP */
12501 int16_t offset = SIMM(ctx->opcode, 0, 7) << 2;
12503 gen_ld(ctx, OPC_LW, rd, rb, offset);
12505 break;
12506 case POOL16F:
12507 if (ctx->opcode & 1) {
12508 generate_exception(ctx, EXCP_RI);
12509 } else {
12510 /* MOVEP */
12511 int enc_dest = uMIPS_RD(ctx->opcode);
12512 int enc_rt = uMIPS_RS2(ctx->opcode);
12513 int enc_rs = uMIPS_RS1(ctx->opcode);
12514 int rd, rs, re, rt;
12515 static const int rd_enc[] = { 5, 5, 6, 4, 4, 4, 4, 4 };
12516 static const int re_enc[] = { 6, 7, 7, 21, 22, 5, 6, 7 };
12517 static const int rs_rt_enc[] = { 0, 17, 2, 3, 16, 18, 19, 20 };
12519 rd = rd_enc[enc_dest];
12520 re = re_enc[enc_dest];
12521 rs = rs_rt_enc[enc_rs];
12522 rt = rs_rt_enc[enc_rt];
12524 gen_arith_imm(ctx, OPC_ADDIU, rd, rs, 0);
12525 gen_arith_imm(ctx, OPC_ADDIU, re, rt, 0);
12527 break;
12528 case LBU16:
12530 int rd = mmreg(uMIPS_RD(ctx->opcode));
12531 int rb = mmreg(uMIPS_RS(ctx->opcode));
12532 int16_t offset = ZIMM(ctx->opcode, 0, 4);
12533 offset = (offset == 0xf ? -1 : offset);
12535 gen_ld(ctx, OPC_LBU, rd, rb, offset);
12537 break;
12538 case LHU16:
12540 int rd = mmreg(uMIPS_RD(ctx->opcode));
12541 int rb = mmreg(uMIPS_RS(ctx->opcode));
12542 int16_t offset = ZIMM(ctx->opcode, 0, 4) << 1;
12544 gen_ld(ctx, OPC_LHU, rd, rb, offset);
12546 break;
12547 case LWSP16:
12549 int rd = (ctx->opcode >> 5) & 0x1f;
12550 int rb = 29; /* SP */
12551 int16_t offset = ZIMM(ctx->opcode, 0, 5) << 2;
12553 gen_ld(ctx, OPC_LW, rd, rb, offset);
12555 break;
12556 case LW16:
12558 int rd = mmreg(uMIPS_RD(ctx->opcode));
12559 int rb = mmreg(uMIPS_RS(ctx->opcode));
12560 int16_t offset = ZIMM(ctx->opcode, 0, 4) << 2;
12562 gen_ld(ctx, OPC_LW, rd, rb, offset);
12564 break;
12565 case SB16:
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);
12571 gen_st(ctx, OPC_SB, rd, rb, offset);
12573 break;
12574 case SH16:
12576 int rd = mmreg2(uMIPS_RD(ctx->opcode));
12577 int rb = mmreg(uMIPS_RS(ctx->opcode));
12578 int16_t offset = ZIMM(ctx->opcode, 0, 4) << 1;
12580 gen_st(ctx, OPC_SH, rd, rb, offset);
12582 break;
12583 case SWSP16:
12585 int rd = (ctx->opcode >> 5) & 0x1f;
12586 int rb = 29; /* SP */
12587 int16_t offset = ZIMM(ctx->opcode, 0, 5) << 2;
12589 gen_st(ctx, OPC_SW, rd, rb, offset);
12591 break;
12592 case SW16:
12594 int rd = mmreg2(uMIPS_RD(ctx->opcode));
12595 int rb = mmreg(uMIPS_RS(ctx->opcode));
12596 int16_t offset = ZIMM(ctx->opcode, 0, 4) << 2;
12598 gen_st(ctx, OPC_SW, rd, rb, offset);
12600 break;
12601 case MOVE16:
12603 int rd = uMIPS_RD5(ctx->opcode);
12604 int rs = uMIPS_RS5(ctx->opcode);
12606 gen_arith_imm(ctx, OPC_ADDIU, rd, rs, 0);
12608 break;
12609 case ANDI16:
12610 gen_andi16(ctx);
12611 break;
12612 case POOL16D:
12613 switch (ctx->opcode & 0x1) {
12614 case ADDIUS5:
12615 gen_addius5(ctx);
12616 break;
12617 case ADDIUSP:
12618 gen_addiusp(ctx);
12619 break;
12621 break;
12622 case POOL16E:
12623 switch (ctx->opcode & 0x1) {
12624 case ADDIUR2:
12625 gen_addiur2(ctx);
12626 break;
12627 case ADDIUR1SP:
12628 gen_addiur1sp(ctx);
12629 break;
12631 break;
12632 case B16:
12633 gen_compute_branch(ctx, OPC_BEQ, 2, 0, 0,
12634 SIMM(ctx->opcode, 0, 10) << 1);
12635 break;
12636 case BNEZ16:
12637 case BEQZ16:
12638 gen_compute_branch(ctx, op == BNEZ16 ? OPC_BNE : OPC_BEQ, 2,
12639 mmreg(uMIPS_RD(ctx->opcode)),
12640 0, SIMM(ctx->opcode, 0, 7) << 1);
12641 break;
12642 case LI16:
12644 int reg = mmreg(uMIPS_RD(ctx->opcode));
12645 int imm = ZIMM(ctx->opcode, 0, 7);
12647 imm = (imm == 0x7f ? -1 : imm);
12648 tcg_gen_movi_tl(cpu_gpr[reg], imm);
12650 break;
12651 case RES_20:
12652 case RES_28:
12653 case RES_29:
12654 case RES_30:
12655 case RES_31:
12656 case RES_38:
12657 case RES_39:
12658 generate_exception(ctx, EXCP_RI);
12659 break;
12660 default:
12661 decode_micromips32_opc (env, ctx, op);
12662 return 4;
12665 return 2;
12668 /* SmartMIPS extension to MIPS32 */
12670 #if defined(TARGET_MIPS64)
12672 /* MDMX extension to MIPS64 */
12674 #endif
12676 /* MIPSDSP functions. */
12677 static void gen_mipsdsp_ld(DisasContext *ctx, uint32_t opc,
12678 int rd, int base, int offset)
12680 const char *opn = "ldx";
12681 TCGv t0;
12683 check_dsp(ctx);
12684 t0 = tcg_temp_new();
12686 if (base == 0) {
12687 gen_load_gpr(t0, offset);
12688 } else if (offset == 0) {
12689 gen_load_gpr(t0, base);
12690 } else {
12691 gen_op_addr_add(ctx, t0, cpu_gpr[base], cpu_gpr[offset]);
12694 switch (opc) {
12695 case OPC_LBUX:
12696 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_UB);
12697 gen_store_gpr(t0, rd);
12698 opn = "lbux";
12699 break;
12700 case OPC_LHX:
12701 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TESW);
12702 gen_store_gpr(t0, rd);
12703 opn = "lhx";
12704 break;
12705 case OPC_LWX:
12706 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TESL);
12707 gen_store_gpr(t0, rd);
12708 opn = "lwx";
12709 break;
12710 #if defined(TARGET_MIPS64)
12711 case OPC_LDX:
12712 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TEQ);
12713 gen_store_gpr(t0, rd);
12714 opn = "ldx";
12715 break;
12716 #endif
12718 (void)opn; /* avoid a compiler warning */
12719 MIPS_DEBUG("%s %s, %s(%s)", opn,
12720 regnames[rd], regnames[offset], regnames[base]);
12721 tcg_temp_free(t0);
12724 static void gen_mipsdsp_arith(DisasContext *ctx, uint32_t op1, uint32_t op2,
12725 int ret, int v1, int v2)
12727 const char *opn = "mipsdsp arith";
12728 TCGv v1_t;
12729 TCGv v2_t;
12731 if (ret == 0) {
12732 /* Treat as NOP. */
12733 MIPS_DEBUG("NOP");
12734 return;
12737 v1_t = tcg_temp_new();
12738 v2_t = tcg_temp_new();
12740 gen_load_gpr(v1_t, v1);
12741 gen_load_gpr(v2_t, v2);
12743 switch (op1) {
12744 /* OPC_MULT_G_2E is equal OPC_ADDUH_QB_DSP */
12745 case OPC_MULT_G_2E:
12746 check_dspr2(ctx);
12747 switch (op2) {
12748 case OPC_ADDUH_QB:
12749 gen_helper_adduh_qb(cpu_gpr[ret], v1_t, v2_t);
12750 break;
12751 case OPC_ADDUH_R_QB:
12752 gen_helper_adduh_r_qb(cpu_gpr[ret], v1_t, v2_t);
12753 break;
12754 case OPC_ADDQH_PH:
12755 gen_helper_addqh_ph(cpu_gpr[ret], v1_t, v2_t);
12756 break;
12757 case OPC_ADDQH_R_PH:
12758 gen_helper_addqh_r_ph(cpu_gpr[ret], v1_t, v2_t);
12759 break;
12760 case OPC_ADDQH_W:
12761 gen_helper_addqh_w(cpu_gpr[ret], v1_t, v2_t);
12762 break;
12763 case OPC_ADDQH_R_W:
12764 gen_helper_addqh_r_w(cpu_gpr[ret], v1_t, v2_t);
12765 break;
12766 case OPC_SUBUH_QB:
12767 gen_helper_subuh_qb(cpu_gpr[ret], v1_t, v2_t);
12768 break;
12769 case OPC_SUBUH_R_QB:
12770 gen_helper_subuh_r_qb(cpu_gpr[ret], v1_t, v2_t);
12771 break;
12772 case OPC_SUBQH_PH:
12773 gen_helper_subqh_ph(cpu_gpr[ret], v1_t, v2_t);
12774 break;
12775 case OPC_SUBQH_R_PH:
12776 gen_helper_subqh_r_ph(cpu_gpr[ret], v1_t, v2_t);
12777 break;
12778 case OPC_SUBQH_W:
12779 gen_helper_subqh_w(cpu_gpr[ret], v1_t, v2_t);
12780 break;
12781 case OPC_SUBQH_R_W:
12782 gen_helper_subqh_r_w(cpu_gpr[ret], v1_t, v2_t);
12783 break;
12785 break;
12786 case OPC_ABSQ_S_PH_DSP:
12787 switch (op2) {
12788 case OPC_ABSQ_S_QB:
12789 check_dspr2(ctx);
12790 gen_helper_absq_s_qb(cpu_gpr[ret], v2_t, cpu_env);
12791 break;
12792 case OPC_ABSQ_S_PH:
12793 check_dsp(ctx);
12794 gen_helper_absq_s_ph(cpu_gpr[ret], v2_t, cpu_env);
12795 break;
12796 case OPC_ABSQ_S_W:
12797 check_dsp(ctx);
12798 gen_helper_absq_s_w(cpu_gpr[ret], v2_t, cpu_env);
12799 break;
12800 case OPC_PRECEQ_W_PHL:
12801 check_dsp(ctx);
12802 tcg_gen_andi_tl(cpu_gpr[ret], v2_t, 0xFFFF0000);
12803 tcg_gen_ext32s_tl(cpu_gpr[ret], cpu_gpr[ret]);
12804 break;
12805 case OPC_PRECEQ_W_PHR:
12806 check_dsp(ctx);
12807 tcg_gen_andi_tl(cpu_gpr[ret], v2_t, 0x0000FFFF);
12808 tcg_gen_shli_tl(cpu_gpr[ret], cpu_gpr[ret], 16);
12809 tcg_gen_ext32s_tl(cpu_gpr[ret], cpu_gpr[ret]);
12810 break;
12811 case OPC_PRECEQU_PH_QBL:
12812 check_dsp(ctx);
12813 gen_helper_precequ_ph_qbl(cpu_gpr[ret], v2_t);
12814 break;
12815 case OPC_PRECEQU_PH_QBR:
12816 check_dsp(ctx);
12817 gen_helper_precequ_ph_qbr(cpu_gpr[ret], v2_t);
12818 break;
12819 case OPC_PRECEQU_PH_QBLA:
12820 check_dsp(ctx);
12821 gen_helper_precequ_ph_qbla(cpu_gpr[ret], v2_t);
12822 break;
12823 case OPC_PRECEQU_PH_QBRA:
12824 check_dsp(ctx);
12825 gen_helper_precequ_ph_qbra(cpu_gpr[ret], v2_t);
12826 break;
12827 case OPC_PRECEU_PH_QBL:
12828 check_dsp(ctx);
12829 gen_helper_preceu_ph_qbl(cpu_gpr[ret], v2_t);
12830 break;
12831 case OPC_PRECEU_PH_QBR:
12832 check_dsp(ctx);
12833 gen_helper_preceu_ph_qbr(cpu_gpr[ret], v2_t);
12834 break;
12835 case OPC_PRECEU_PH_QBLA:
12836 check_dsp(ctx);
12837 gen_helper_preceu_ph_qbla(cpu_gpr[ret], v2_t);
12838 break;
12839 case OPC_PRECEU_PH_QBRA:
12840 check_dsp(ctx);
12841 gen_helper_preceu_ph_qbra(cpu_gpr[ret], v2_t);
12842 break;
12844 break;
12845 case OPC_ADDU_QB_DSP:
12846 switch (op2) {
12847 case OPC_ADDQ_PH:
12848 check_dsp(ctx);
12849 gen_helper_addq_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12850 break;
12851 case OPC_ADDQ_S_PH:
12852 check_dsp(ctx);
12853 gen_helper_addq_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12854 break;
12855 case OPC_ADDQ_S_W:
12856 check_dsp(ctx);
12857 gen_helper_addq_s_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12858 break;
12859 case OPC_ADDU_QB:
12860 check_dsp(ctx);
12861 gen_helper_addu_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12862 break;
12863 case OPC_ADDU_S_QB:
12864 check_dsp(ctx);
12865 gen_helper_addu_s_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12866 break;
12867 case OPC_ADDU_PH:
12868 check_dspr2(ctx);
12869 gen_helper_addu_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12870 break;
12871 case OPC_ADDU_S_PH:
12872 check_dspr2(ctx);
12873 gen_helper_addu_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12874 break;
12875 case OPC_SUBQ_PH:
12876 check_dsp(ctx);
12877 gen_helper_subq_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12878 break;
12879 case OPC_SUBQ_S_PH:
12880 check_dsp(ctx);
12881 gen_helper_subq_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12882 break;
12883 case OPC_SUBQ_S_W:
12884 check_dsp(ctx);
12885 gen_helper_subq_s_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12886 break;
12887 case OPC_SUBU_QB:
12888 check_dsp(ctx);
12889 gen_helper_subu_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12890 break;
12891 case OPC_SUBU_S_QB:
12892 check_dsp(ctx);
12893 gen_helper_subu_s_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12894 break;
12895 case OPC_SUBU_PH:
12896 check_dspr2(ctx);
12897 gen_helper_subu_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12898 break;
12899 case OPC_SUBU_S_PH:
12900 check_dspr2(ctx);
12901 gen_helper_subu_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12902 break;
12903 case OPC_ADDSC:
12904 check_dsp(ctx);
12905 gen_helper_addsc(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12906 break;
12907 case OPC_ADDWC:
12908 check_dsp(ctx);
12909 gen_helper_addwc(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12910 break;
12911 case OPC_MODSUB:
12912 check_dsp(ctx);
12913 gen_helper_modsub(cpu_gpr[ret], v1_t, v2_t);
12914 break;
12915 case OPC_RADDU_W_QB:
12916 check_dsp(ctx);
12917 gen_helper_raddu_w_qb(cpu_gpr[ret], v1_t);
12918 break;
12920 break;
12921 case OPC_CMPU_EQ_QB_DSP:
12922 switch (op2) {
12923 case OPC_PRECR_QB_PH:
12924 check_dspr2(ctx);
12925 gen_helper_precr_qb_ph(cpu_gpr[ret], v1_t, v2_t);
12926 break;
12927 case OPC_PRECRQ_QB_PH:
12928 check_dsp(ctx);
12929 gen_helper_precrq_qb_ph(cpu_gpr[ret], v1_t, v2_t);
12930 break;
12931 case OPC_PRECR_SRA_PH_W:
12932 check_dspr2(ctx);
12934 TCGv_i32 sa_t = tcg_const_i32(v2);
12935 gen_helper_precr_sra_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_PRECR_SRA_R_PH_W:
12941 check_dspr2(ctx);
12943 TCGv_i32 sa_t = tcg_const_i32(v2);
12944 gen_helper_precr_sra_r_ph_w(cpu_gpr[ret], sa_t, v1_t,
12945 cpu_gpr[ret]);
12946 tcg_temp_free_i32(sa_t);
12947 break;
12949 case OPC_PRECRQ_PH_W:
12950 check_dsp(ctx);
12951 gen_helper_precrq_ph_w(cpu_gpr[ret], v1_t, v2_t);
12952 break;
12953 case OPC_PRECRQ_RS_PH_W:
12954 check_dsp(ctx);
12955 gen_helper_precrq_rs_ph_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12956 break;
12957 case OPC_PRECRQU_S_QB_PH:
12958 check_dsp(ctx);
12959 gen_helper_precrqu_s_qb_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12960 break;
12962 break;
12963 #ifdef TARGET_MIPS64
12964 case OPC_ABSQ_S_QH_DSP:
12965 switch (op2) {
12966 case OPC_PRECEQ_L_PWL:
12967 check_dsp(ctx);
12968 tcg_gen_andi_tl(cpu_gpr[ret], v2_t, 0xFFFFFFFF00000000ull);
12969 break;
12970 case OPC_PRECEQ_L_PWR:
12971 check_dsp(ctx);
12972 tcg_gen_shli_tl(cpu_gpr[ret], v2_t, 32);
12973 break;
12974 case OPC_PRECEQ_PW_QHL:
12975 check_dsp(ctx);
12976 gen_helper_preceq_pw_qhl(cpu_gpr[ret], v2_t);
12977 break;
12978 case OPC_PRECEQ_PW_QHR:
12979 check_dsp(ctx);
12980 gen_helper_preceq_pw_qhr(cpu_gpr[ret], v2_t);
12981 break;
12982 case OPC_PRECEQ_PW_QHLA:
12983 check_dsp(ctx);
12984 gen_helper_preceq_pw_qhla(cpu_gpr[ret], v2_t);
12985 break;
12986 case OPC_PRECEQ_PW_QHRA:
12987 check_dsp(ctx);
12988 gen_helper_preceq_pw_qhra(cpu_gpr[ret], v2_t);
12989 break;
12990 case OPC_PRECEQU_QH_OBL:
12991 check_dsp(ctx);
12992 gen_helper_precequ_qh_obl(cpu_gpr[ret], v2_t);
12993 break;
12994 case OPC_PRECEQU_QH_OBR:
12995 check_dsp(ctx);
12996 gen_helper_precequ_qh_obr(cpu_gpr[ret], v2_t);
12997 break;
12998 case OPC_PRECEQU_QH_OBLA:
12999 check_dsp(ctx);
13000 gen_helper_precequ_qh_obla(cpu_gpr[ret], v2_t);
13001 break;
13002 case OPC_PRECEQU_QH_OBRA:
13003 check_dsp(ctx);
13004 gen_helper_precequ_qh_obra(cpu_gpr[ret], v2_t);
13005 break;
13006 case OPC_PRECEU_QH_OBL:
13007 check_dsp(ctx);
13008 gen_helper_preceu_qh_obl(cpu_gpr[ret], v2_t);
13009 break;
13010 case OPC_PRECEU_QH_OBR:
13011 check_dsp(ctx);
13012 gen_helper_preceu_qh_obr(cpu_gpr[ret], v2_t);
13013 break;
13014 case OPC_PRECEU_QH_OBLA:
13015 check_dsp(ctx);
13016 gen_helper_preceu_qh_obla(cpu_gpr[ret], v2_t);
13017 break;
13018 case OPC_PRECEU_QH_OBRA:
13019 check_dsp(ctx);
13020 gen_helper_preceu_qh_obra(cpu_gpr[ret], v2_t);
13021 break;
13022 case OPC_ABSQ_S_OB:
13023 check_dspr2(ctx);
13024 gen_helper_absq_s_ob(cpu_gpr[ret], v2_t, cpu_env);
13025 break;
13026 case OPC_ABSQ_S_PW:
13027 check_dsp(ctx);
13028 gen_helper_absq_s_pw(cpu_gpr[ret], v2_t, cpu_env);
13029 break;
13030 case OPC_ABSQ_S_QH:
13031 check_dsp(ctx);
13032 gen_helper_absq_s_qh(cpu_gpr[ret], v2_t, cpu_env);
13033 break;
13035 break;
13036 case OPC_ADDU_OB_DSP:
13037 switch (op2) {
13038 case OPC_RADDU_L_OB:
13039 check_dsp(ctx);
13040 gen_helper_raddu_l_ob(cpu_gpr[ret], v1_t);
13041 break;
13042 case OPC_SUBQ_PW:
13043 check_dsp(ctx);
13044 gen_helper_subq_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13045 break;
13046 case OPC_SUBQ_S_PW:
13047 check_dsp(ctx);
13048 gen_helper_subq_s_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13049 break;
13050 case OPC_SUBQ_QH:
13051 check_dsp(ctx);
13052 gen_helper_subq_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13053 break;
13054 case OPC_SUBQ_S_QH:
13055 check_dsp(ctx);
13056 gen_helper_subq_s_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13057 break;
13058 case OPC_SUBU_OB:
13059 check_dsp(ctx);
13060 gen_helper_subu_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13061 break;
13062 case OPC_SUBU_S_OB:
13063 check_dsp(ctx);
13064 gen_helper_subu_s_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13065 break;
13066 case OPC_SUBU_QH:
13067 check_dspr2(ctx);
13068 gen_helper_subu_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13069 break;
13070 case OPC_SUBU_S_QH:
13071 check_dspr2(ctx);
13072 gen_helper_subu_s_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13073 break;
13074 case OPC_SUBUH_OB:
13075 check_dspr2(ctx);
13076 gen_helper_subuh_ob(cpu_gpr[ret], v1_t, v2_t);
13077 break;
13078 case OPC_SUBUH_R_OB:
13079 check_dspr2(ctx);
13080 gen_helper_subuh_r_ob(cpu_gpr[ret], v1_t, v2_t);
13081 break;
13082 case OPC_ADDQ_PW:
13083 check_dsp(ctx);
13084 gen_helper_addq_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13085 break;
13086 case OPC_ADDQ_S_PW:
13087 check_dsp(ctx);
13088 gen_helper_addq_s_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13089 break;
13090 case OPC_ADDQ_QH:
13091 check_dsp(ctx);
13092 gen_helper_addq_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13093 break;
13094 case OPC_ADDQ_S_QH:
13095 check_dsp(ctx);
13096 gen_helper_addq_s_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13097 break;
13098 case OPC_ADDU_OB:
13099 check_dsp(ctx);
13100 gen_helper_addu_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13101 break;
13102 case OPC_ADDU_S_OB:
13103 check_dsp(ctx);
13104 gen_helper_addu_s_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13105 break;
13106 case OPC_ADDU_QH:
13107 check_dspr2(ctx);
13108 gen_helper_addu_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13109 break;
13110 case OPC_ADDU_S_QH:
13111 check_dspr2(ctx);
13112 gen_helper_addu_s_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13113 break;
13114 case OPC_ADDUH_OB:
13115 check_dspr2(ctx);
13116 gen_helper_adduh_ob(cpu_gpr[ret], v1_t, v2_t);
13117 break;
13118 case OPC_ADDUH_R_OB:
13119 check_dspr2(ctx);
13120 gen_helper_adduh_r_ob(cpu_gpr[ret], v1_t, v2_t);
13121 break;
13123 break;
13124 case OPC_CMPU_EQ_OB_DSP:
13125 switch (op2) {
13126 case OPC_PRECR_OB_QH:
13127 check_dspr2(ctx);
13128 gen_helper_precr_ob_qh(cpu_gpr[ret], v1_t, v2_t);
13129 break;
13130 case OPC_PRECR_SRA_QH_PW:
13131 check_dspr2(ctx);
13133 TCGv_i32 ret_t = tcg_const_i32(ret);
13134 gen_helper_precr_sra_qh_pw(v2_t, v1_t, v2_t, ret_t);
13135 tcg_temp_free_i32(ret_t);
13136 break;
13138 case OPC_PRECR_SRA_R_QH_PW:
13139 check_dspr2(ctx);
13141 TCGv_i32 sa_v = tcg_const_i32(ret);
13142 gen_helper_precr_sra_r_qh_pw(v2_t, v1_t, v2_t, sa_v);
13143 tcg_temp_free_i32(sa_v);
13144 break;
13146 case OPC_PRECRQ_OB_QH:
13147 check_dsp(ctx);
13148 gen_helper_precrq_ob_qh(cpu_gpr[ret], v1_t, v2_t);
13149 break;
13150 case OPC_PRECRQ_PW_L:
13151 check_dsp(ctx);
13152 gen_helper_precrq_pw_l(cpu_gpr[ret], v1_t, v2_t);
13153 break;
13154 case OPC_PRECRQ_QH_PW:
13155 check_dsp(ctx);
13156 gen_helper_precrq_qh_pw(cpu_gpr[ret], v1_t, v2_t);
13157 break;
13158 case OPC_PRECRQ_RS_QH_PW:
13159 check_dsp(ctx);
13160 gen_helper_precrq_rs_qh_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13161 break;
13162 case OPC_PRECRQU_S_OB_QH:
13163 check_dsp(ctx);
13164 gen_helper_precrqu_s_ob_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13165 break;
13167 break;
13168 #endif
13171 tcg_temp_free(v1_t);
13172 tcg_temp_free(v2_t);
13174 (void)opn; /* avoid a compiler warning */
13175 MIPS_DEBUG("%s", opn);
13178 static void gen_mipsdsp_shift(DisasContext *ctx, uint32_t opc,
13179 int ret, int v1, int v2)
13181 uint32_t op2;
13182 const char *opn = "mipsdsp shift";
13183 TCGv t0;
13184 TCGv v1_t;
13185 TCGv v2_t;
13187 if (ret == 0) {
13188 /* Treat as NOP. */
13189 MIPS_DEBUG("NOP");
13190 return;
13193 t0 = tcg_temp_new();
13194 v1_t = tcg_temp_new();
13195 v2_t = tcg_temp_new();
13197 tcg_gen_movi_tl(t0, v1);
13198 gen_load_gpr(v1_t, v1);
13199 gen_load_gpr(v2_t, v2);
13201 switch (opc) {
13202 case OPC_SHLL_QB_DSP:
13204 op2 = MASK_SHLL_QB(ctx->opcode);
13205 switch (op2) {
13206 case OPC_SHLL_QB:
13207 check_dsp(ctx);
13208 gen_helper_shll_qb(cpu_gpr[ret], t0, v2_t, cpu_env);
13209 break;
13210 case OPC_SHLLV_QB:
13211 check_dsp(ctx);
13212 gen_helper_shll_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13213 break;
13214 case OPC_SHLL_PH:
13215 check_dsp(ctx);
13216 gen_helper_shll_ph(cpu_gpr[ret], t0, v2_t, cpu_env);
13217 break;
13218 case OPC_SHLLV_PH:
13219 check_dsp(ctx);
13220 gen_helper_shll_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13221 break;
13222 case OPC_SHLL_S_PH:
13223 check_dsp(ctx);
13224 gen_helper_shll_s_ph(cpu_gpr[ret], t0, v2_t, cpu_env);
13225 break;
13226 case OPC_SHLLV_S_PH:
13227 check_dsp(ctx);
13228 gen_helper_shll_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13229 break;
13230 case OPC_SHLL_S_W:
13231 check_dsp(ctx);
13232 gen_helper_shll_s_w(cpu_gpr[ret], t0, v2_t, cpu_env);
13233 break;
13234 case OPC_SHLLV_S_W:
13235 check_dsp(ctx);
13236 gen_helper_shll_s_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13237 break;
13238 case OPC_SHRL_QB:
13239 check_dsp(ctx);
13240 gen_helper_shrl_qb(cpu_gpr[ret], t0, v2_t);
13241 break;
13242 case OPC_SHRLV_QB:
13243 check_dsp(ctx);
13244 gen_helper_shrl_qb(cpu_gpr[ret], v1_t, v2_t);
13245 break;
13246 case OPC_SHRL_PH:
13247 check_dspr2(ctx);
13248 gen_helper_shrl_ph(cpu_gpr[ret], t0, v2_t);
13249 break;
13250 case OPC_SHRLV_PH:
13251 check_dspr2(ctx);
13252 gen_helper_shrl_ph(cpu_gpr[ret], v1_t, v2_t);
13253 break;
13254 case OPC_SHRA_QB:
13255 check_dspr2(ctx);
13256 gen_helper_shra_qb(cpu_gpr[ret], t0, v2_t);
13257 break;
13258 case OPC_SHRA_R_QB:
13259 check_dspr2(ctx);
13260 gen_helper_shra_r_qb(cpu_gpr[ret], t0, v2_t);
13261 break;
13262 case OPC_SHRAV_QB:
13263 check_dspr2(ctx);
13264 gen_helper_shra_qb(cpu_gpr[ret], v1_t, v2_t);
13265 break;
13266 case OPC_SHRAV_R_QB:
13267 check_dspr2(ctx);
13268 gen_helper_shra_r_qb(cpu_gpr[ret], v1_t, v2_t);
13269 break;
13270 case OPC_SHRA_PH:
13271 check_dsp(ctx);
13272 gen_helper_shra_ph(cpu_gpr[ret], t0, v2_t);
13273 break;
13274 case OPC_SHRA_R_PH:
13275 check_dsp(ctx);
13276 gen_helper_shra_r_ph(cpu_gpr[ret], t0, v2_t);
13277 break;
13278 case OPC_SHRAV_PH:
13279 check_dsp(ctx);
13280 gen_helper_shra_ph(cpu_gpr[ret], v1_t, v2_t);
13281 break;
13282 case OPC_SHRAV_R_PH:
13283 check_dsp(ctx);
13284 gen_helper_shra_r_ph(cpu_gpr[ret], v1_t, v2_t);
13285 break;
13286 case OPC_SHRA_R_W:
13287 check_dsp(ctx);
13288 gen_helper_shra_r_w(cpu_gpr[ret], t0, v2_t);
13289 break;
13290 case OPC_SHRAV_R_W:
13291 check_dsp(ctx);
13292 gen_helper_shra_r_w(cpu_gpr[ret], v1_t, v2_t);
13293 break;
13294 default: /* Invalid */
13295 MIPS_INVAL("MASK SHLL.QB");
13296 generate_exception(ctx, EXCP_RI);
13297 break;
13299 break;
13301 #ifdef TARGET_MIPS64
13302 case OPC_SHLL_OB_DSP:
13303 op2 = MASK_SHLL_OB(ctx->opcode);
13304 switch (op2) {
13305 case OPC_SHLL_PW:
13306 check_dsp(ctx);
13307 gen_helper_shll_pw(cpu_gpr[ret], v2_t, t0, cpu_env);
13308 break;
13309 case OPC_SHLLV_PW:
13310 check_dsp(ctx);
13311 gen_helper_shll_pw(cpu_gpr[ret], v2_t, v1_t, cpu_env);
13312 break;
13313 case OPC_SHLL_S_PW:
13314 check_dsp(ctx);
13315 gen_helper_shll_s_pw(cpu_gpr[ret], v2_t, t0, cpu_env);
13316 break;
13317 case OPC_SHLLV_S_PW:
13318 check_dsp(ctx);
13319 gen_helper_shll_s_pw(cpu_gpr[ret], v2_t, v1_t, cpu_env);
13320 break;
13321 case OPC_SHLL_OB:
13322 check_dsp(ctx);
13323 gen_helper_shll_ob(cpu_gpr[ret], v2_t, t0, cpu_env);
13324 break;
13325 case OPC_SHLLV_OB:
13326 check_dsp(ctx);
13327 gen_helper_shll_ob(cpu_gpr[ret], v2_t, v1_t, cpu_env);
13328 break;
13329 case OPC_SHLL_QH:
13330 check_dsp(ctx);
13331 gen_helper_shll_qh(cpu_gpr[ret], v2_t, t0, cpu_env);
13332 break;
13333 case OPC_SHLLV_QH:
13334 check_dsp(ctx);
13335 gen_helper_shll_qh(cpu_gpr[ret], v2_t, v1_t, cpu_env);
13336 break;
13337 case OPC_SHLL_S_QH:
13338 check_dsp(ctx);
13339 gen_helper_shll_s_qh(cpu_gpr[ret], v2_t, t0, cpu_env);
13340 break;
13341 case OPC_SHLLV_S_QH:
13342 check_dsp(ctx);
13343 gen_helper_shll_s_qh(cpu_gpr[ret], v2_t, v1_t, cpu_env);
13344 break;
13345 case OPC_SHRA_OB:
13346 check_dspr2(ctx);
13347 gen_helper_shra_ob(cpu_gpr[ret], v2_t, t0);
13348 break;
13349 case OPC_SHRAV_OB:
13350 check_dspr2(ctx);
13351 gen_helper_shra_ob(cpu_gpr[ret], v2_t, v1_t);
13352 break;
13353 case OPC_SHRA_R_OB:
13354 check_dspr2(ctx);
13355 gen_helper_shra_r_ob(cpu_gpr[ret], v2_t, t0);
13356 break;
13357 case OPC_SHRAV_R_OB:
13358 check_dspr2(ctx);
13359 gen_helper_shra_r_ob(cpu_gpr[ret], v2_t, v1_t);
13360 break;
13361 case OPC_SHRA_PW:
13362 check_dsp(ctx);
13363 gen_helper_shra_pw(cpu_gpr[ret], v2_t, t0);
13364 break;
13365 case OPC_SHRAV_PW:
13366 check_dsp(ctx);
13367 gen_helper_shra_pw(cpu_gpr[ret], v2_t, v1_t);
13368 break;
13369 case OPC_SHRA_R_PW:
13370 check_dsp(ctx);
13371 gen_helper_shra_r_pw(cpu_gpr[ret], v2_t, t0);
13372 break;
13373 case OPC_SHRAV_R_PW:
13374 check_dsp(ctx);
13375 gen_helper_shra_r_pw(cpu_gpr[ret], v2_t, v1_t);
13376 break;
13377 case OPC_SHRA_QH:
13378 check_dsp(ctx);
13379 gen_helper_shra_qh(cpu_gpr[ret], v2_t, t0);
13380 break;
13381 case OPC_SHRAV_QH:
13382 check_dsp(ctx);
13383 gen_helper_shra_qh(cpu_gpr[ret], v2_t, v1_t);
13384 break;
13385 case OPC_SHRA_R_QH:
13386 check_dsp(ctx);
13387 gen_helper_shra_r_qh(cpu_gpr[ret], v2_t, t0);
13388 break;
13389 case OPC_SHRAV_R_QH:
13390 check_dsp(ctx);
13391 gen_helper_shra_r_qh(cpu_gpr[ret], v2_t, v1_t);
13392 break;
13393 case OPC_SHRL_OB:
13394 check_dsp(ctx);
13395 gen_helper_shrl_ob(cpu_gpr[ret], v2_t, t0);
13396 break;
13397 case OPC_SHRLV_OB:
13398 check_dsp(ctx);
13399 gen_helper_shrl_ob(cpu_gpr[ret], v2_t, v1_t);
13400 break;
13401 case OPC_SHRL_QH:
13402 check_dspr2(ctx);
13403 gen_helper_shrl_qh(cpu_gpr[ret], v2_t, t0);
13404 break;
13405 case OPC_SHRLV_QH:
13406 check_dspr2(ctx);
13407 gen_helper_shrl_qh(cpu_gpr[ret], v2_t, v1_t);
13408 break;
13409 default: /* Invalid */
13410 MIPS_INVAL("MASK SHLL.OB");
13411 generate_exception(ctx, EXCP_RI);
13412 break;
13414 break;
13415 #endif
13418 tcg_temp_free(t0);
13419 tcg_temp_free(v1_t);
13420 tcg_temp_free(v2_t);
13421 (void)opn; /* avoid a compiler warning */
13422 MIPS_DEBUG("%s", opn);
13425 static void gen_mipsdsp_multiply(DisasContext *ctx, uint32_t op1, uint32_t op2,
13426 int ret, int v1, int v2, int check_ret)
13428 const char *opn = "mipsdsp multiply";
13429 TCGv_i32 t0;
13430 TCGv v1_t;
13431 TCGv v2_t;
13433 if ((ret == 0) && (check_ret == 1)) {
13434 /* Treat as NOP. */
13435 MIPS_DEBUG("NOP");
13436 return;
13439 t0 = tcg_temp_new_i32();
13440 v1_t = tcg_temp_new();
13441 v2_t = tcg_temp_new();
13443 tcg_gen_movi_i32(t0, ret);
13444 gen_load_gpr(v1_t, v1);
13445 gen_load_gpr(v2_t, v2);
13447 switch (op1) {
13448 /* OPC_MULT_G_2E, OPC_ADDUH_QB_DSP, OPC_MUL_PH_DSP have
13449 * the same mask and op1. */
13450 case OPC_MULT_G_2E:
13451 check_dspr2(ctx);
13452 switch (op2) {
13453 case OPC_MUL_PH:
13454 gen_helper_mul_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13455 break;
13456 case OPC_MUL_S_PH:
13457 gen_helper_mul_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13458 break;
13459 case OPC_MULQ_S_W:
13460 gen_helper_mulq_s_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13461 break;
13462 case OPC_MULQ_RS_W:
13463 gen_helper_mulq_rs_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13464 break;
13466 break;
13467 case OPC_DPA_W_PH_DSP:
13468 switch (op2) {
13469 case OPC_DPAU_H_QBL:
13470 check_dsp(ctx);
13471 gen_helper_dpau_h_qbl(t0, v1_t, v2_t, cpu_env);
13472 break;
13473 case OPC_DPAU_H_QBR:
13474 check_dsp(ctx);
13475 gen_helper_dpau_h_qbr(t0, v1_t, v2_t, cpu_env);
13476 break;
13477 case OPC_DPSU_H_QBL:
13478 check_dsp(ctx);
13479 gen_helper_dpsu_h_qbl(t0, v1_t, v2_t, cpu_env);
13480 break;
13481 case OPC_DPSU_H_QBR:
13482 check_dsp(ctx);
13483 gen_helper_dpsu_h_qbr(t0, v1_t, v2_t, cpu_env);
13484 break;
13485 case OPC_DPA_W_PH:
13486 check_dspr2(ctx);
13487 gen_helper_dpa_w_ph(t0, v1_t, v2_t, cpu_env);
13488 break;
13489 case OPC_DPAX_W_PH:
13490 check_dspr2(ctx);
13491 gen_helper_dpax_w_ph(t0, v1_t, v2_t, cpu_env);
13492 break;
13493 case OPC_DPAQ_S_W_PH:
13494 check_dsp(ctx);
13495 gen_helper_dpaq_s_w_ph(t0, v1_t, v2_t, cpu_env);
13496 break;
13497 case OPC_DPAQX_S_W_PH:
13498 check_dspr2(ctx);
13499 gen_helper_dpaqx_s_w_ph(t0, v1_t, v2_t, cpu_env);
13500 break;
13501 case OPC_DPAQX_SA_W_PH:
13502 check_dspr2(ctx);
13503 gen_helper_dpaqx_sa_w_ph(t0, v1_t, v2_t, cpu_env);
13504 break;
13505 case OPC_DPS_W_PH:
13506 check_dspr2(ctx);
13507 gen_helper_dps_w_ph(t0, v1_t, v2_t, cpu_env);
13508 break;
13509 case OPC_DPSX_W_PH:
13510 check_dspr2(ctx);
13511 gen_helper_dpsx_w_ph(t0, v1_t, v2_t, cpu_env);
13512 break;
13513 case OPC_DPSQ_S_W_PH:
13514 check_dsp(ctx);
13515 gen_helper_dpsq_s_w_ph(t0, v1_t, v2_t, cpu_env);
13516 break;
13517 case OPC_DPSQX_S_W_PH:
13518 check_dspr2(ctx);
13519 gen_helper_dpsqx_s_w_ph(t0, v1_t, v2_t, cpu_env);
13520 break;
13521 case OPC_DPSQX_SA_W_PH:
13522 check_dspr2(ctx);
13523 gen_helper_dpsqx_sa_w_ph(t0, v1_t, v2_t, cpu_env);
13524 break;
13525 case OPC_MULSAQ_S_W_PH:
13526 check_dsp(ctx);
13527 gen_helper_mulsaq_s_w_ph(t0, v1_t, v2_t, cpu_env);
13528 break;
13529 case OPC_DPAQ_SA_L_W:
13530 check_dsp(ctx);
13531 gen_helper_dpaq_sa_l_w(t0, v1_t, v2_t, cpu_env);
13532 break;
13533 case OPC_DPSQ_SA_L_W:
13534 check_dsp(ctx);
13535 gen_helper_dpsq_sa_l_w(t0, v1_t, v2_t, cpu_env);
13536 break;
13537 case OPC_MAQ_S_W_PHL:
13538 check_dsp(ctx);
13539 gen_helper_maq_s_w_phl(t0, v1_t, v2_t, cpu_env);
13540 break;
13541 case OPC_MAQ_S_W_PHR:
13542 check_dsp(ctx);
13543 gen_helper_maq_s_w_phr(t0, v1_t, v2_t, cpu_env);
13544 break;
13545 case OPC_MAQ_SA_W_PHL:
13546 check_dsp(ctx);
13547 gen_helper_maq_sa_w_phl(t0, v1_t, v2_t, cpu_env);
13548 break;
13549 case OPC_MAQ_SA_W_PHR:
13550 check_dsp(ctx);
13551 gen_helper_maq_sa_w_phr(t0, v1_t, v2_t, cpu_env);
13552 break;
13553 case OPC_MULSA_W_PH:
13554 check_dspr2(ctx);
13555 gen_helper_mulsa_w_ph(t0, v1_t, v2_t, cpu_env);
13556 break;
13558 break;
13559 #ifdef TARGET_MIPS64
13560 case OPC_DPAQ_W_QH_DSP:
13562 int ac = ret & 0x03;
13563 tcg_gen_movi_i32(t0, ac);
13565 switch (op2) {
13566 case OPC_DMADD:
13567 check_dsp(ctx);
13568 gen_helper_dmadd(v1_t, v2_t, t0, cpu_env);
13569 break;
13570 case OPC_DMADDU:
13571 check_dsp(ctx);
13572 gen_helper_dmaddu(v1_t, v2_t, t0, cpu_env);
13573 break;
13574 case OPC_DMSUB:
13575 check_dsp(ctx);
13576 gen_helper_dmsub(v1_t, v2_t, t0, cpu_env);
13577 break;
13578 case OPC_DMSUBU:
13579 check_dsp(ctx);
13580 gen_helper_dmsubu(v1_t, v2_t, t0, cpu_env);
13581 break;
13582 case OPC_DPA_W_QH:
13583 check_dspr2(ctx);
13584 gen_helper_dpa_w_qh(v1_t, v2_t, t0, cpu_env);
13585 break;
13586 case OPC_DPAQ_S_W_QH:
13587 check_dsp(ctx);
13588 gen_helper_dpaq_s_w_qh(v1_t, v2_t, t0, cpu_env);
13589 break;
13590 case OPC_DPAQ_SA_L_PW:
13591 check_dsp(ctx);
13592 gen_helper_dpaq_sa_l_pw(v1_t, v2_t, t0, cpu_env);
13593 break;
13594 case OPC_DPAU_H_OBL:
13595 check_dsp(ctx);
13596 gen_helper_dpau_h_obl(v1_t, v2_t, t0, cpu_env);
13597 break;
13598 case OPC_DPAU_H_OBR:
13599 check_dsp(ctx);
13600 gen_helper_dpau_h_obr(v1_t, v2_t, t0, cpu_env);
13601 break;
13602 case OPC_DPS_W_QH:
13603 check_dspr2(ctx);
13604 gen_helper_dps_w_qh(v1_t, v2_t, t0, cpu_env);
13605 break;
13606 case OPC_DPSQ_S_W_QH:
13607 check_dsp(ctx);
13608 gen_helper_dpsq_s_w_qh(v1_t, v2_t, t0, cpu_env);
13609 break;
13610 case OPC_DPSQ_SA_L_PW:
13611 check_dsp(ctx);
13612 gen_helper_dpsq_sa_l_pw(v1_t, v2_t, t0, cpu_env);
13613 break;
13614 case OPC_DPSU_H_OBL:
13615 check_dsp(ctx);
13616 gen_helper_dpsu_h_obl(v1_t, v2_t, t0, cpu_env);
13617 break;
13618 case OPC_DPSU_H_OBR:
13619 check_dsp(ctx);
13620 gen_helper_dpsu_h_obr(v1_t, v2_t, t0, cpu_env);
13621 break;
13622 case OPC_MAQ_S_L_PWL:
13623 check_dsp(ctx);
13624 gen_helper_maq_s_l_pwl(v1_t, v2_t, t0, cpu_env);
13625 break;
13626 case OPC_MAQ_S_L_PWR:
13627 check_dsp(ctx);
13628 gen_helper_maq_s_l_pwr(v1_t, v2_t, t0, cpu_env);
13629 break;
13630 case OPC_MAQ_S_W_QHLL:
13631 check_dsp(ctx);
13632 gen_helper_maq_s_w_qhll(v1_t, v2_t, t0, cpu_env);
13633 break;
13634 case OPC_MAQ_SA_W_QHLL:
13635 check_dsp(ctx);
13636 gen_helper_maq_sa_w_qhll(v1_t, v2_t, t0, cpu_env);
13637 break;
13638 case OPC_MAQ_S_W_QHLR:
13639 check_dsp(ctx);
13640 gen_helper_maq_s_w_qhlr(v1_t, v2_t, t0, cpu_env);
13641 break;
13642 case OPC_MAQ_SA_W_QHLR:
13643 check_dsp(ctx);
13644 gen_helper_maq_sa_w_qhlr(v1_t, v2_t, t0, cpu_env);
13645 break;
13646 case OPC_MAQ_S_W_QHRL:
13647 check_dsp(ctx);
13648 gen_helper_maq_s_w_qhrl(v1_t, v2_t, t0, cpu_env);
13649 break;
13650 case OPC_MAQ_SA_W_QHRL:
13651 check_dsp(ctx);
13652 gen_helper_maq_sa_w_qhrl(v1_t, v2_t, t0, cpu_env);
13653 break;
13654 case OPC_MAQ_S_W_QHRR:
13655 check_dsp(ctx);
13656 gen_helper_maq_s_w_qhrr(v1_t, v2_t, t0, cpu_env);
13657 break;
13658 case OPC_MAQ_SA_W_QHRR:
13659 check_dsp(ctx);
13660 gen_helper_maq_sa_w_qhrr(v1_t, v2_t, t0, cpu_env);
13661 break;
13662 case OPC_MULSAQ_S_L_PW:
13663 check_dsp(ctx);
13664 gen_helper_mulsaq_s_l_pw(v1_t, v2_t, t0, cpu_env);
13665 break;
13666 case OPC_MULSAQ_S_W_QH:
13667 check_dsp(ctx);
13668 gen_helper_mulsaq_s_w_qh(v1_t, v2_t, t0, cpu_env);
13669 break;
13672 break;
13673 #endif
13674 case OPC_ADDU_QB_DSP:
13675 switch (op2) {
13676 case OPC_MULEU_S_PH_QBL:
13677 check_dsp(ctx);
13678 gen_helper_muleu_s_ph_qbl(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13679 break;
13680 case OPC_MULEU_S_PH_QBR:
13681 check_dsp(ctx);
13682 gen_helper_muleu_s_ph_qbr(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13683 break;
13684 case OPC_MULQ_RS_PH:
13685 check_dsp(ctx);
13686 gen_helper_mulq_rs_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13687 break;
13688 case OPC_MULEQ_S_W_PHL:
13689 check_dsp(ctx);
13690 gen_helper_muleq_s_w_phl(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13691 break;
13692 case OPC_MULEQ_S_W_PHR:
13693 check_dsp(ctx);
13694 gen_helper_muleq_s_w_phr(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13695 break;
13696 case OPC_MULQ_S_PH:
13697 check_dspr2(ctx);
13698 gen_helper_mulq_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13699 break;
13701 break;
13702 #ifdef TARGET_MIPS64
13703 case OPC_ADDU_OB_DSP:
13704 switch (op2) {
13705 case OPC_MULEQ_S_PW_QHL:
13706 check_dsp(ctx);
13707 gen_helper_muleq_s_pw_qhl(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13708 break;
13709 case OPC_MULEQ_S_PW_QHR:
13710 check_dsp(ctx);
13711 gen_helper_muleq_s_pw_qhr(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13712 break;
13713 case OPC_MULEU_S_QH_OBL:
13714 check_dsp(ctx);
13715 gen_helper_muleu_s_qh_obl(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13716 break;
13717 case OPC_MULEU_S_QH_OBR:
13718 check_dsp(ctx);
13719 gen_helper_muleu_s_qh_obr(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13720 break;
13721 case OPC_MULQ_RS_QH:
13722 check_dsp(ctx);
13723 gen_helper_mulq_rs_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13724 break;
13726 break;
13727 #endif
13730 tcg_temp_free_i32(t0);
13731 tcg_temp_free(v1_t);
13732 tcg_temp_free(v2_t);
13734 (void)opn; /* avoid a compiler warning */
13735 MIPS_DEBUG("%s", opn);
13739 static void gen_mipsdsp_bitinsn(DisasContext *ctx, uint32_t op1, uint32_t op2,
13740 int ret, int val)
13742 const char *opn = "mipsdsp Bit/ Manipulation";
13743 int16_t imm;
13744 TCGv t0;
13745 TCGv val_t;
13747 if (ret == 0) {
13748 /* Treat as NOP. */
13749 MIPS_DEBUG("NOP");
13750 return;
13753 t0 = tcg_temp_new();
13754 val_t = tcg_temp_new();
13755 gen_load_gpr(val_t, val);
13757 switch (op1) {
13758 case OPC_ABSQ_S_PH_DSP:
13759 switch (op2) {
13760 case OPC_BITREV:
13761 check_dsp(ctx);
13762 gen_helper_bitrev(cpu_gpr[ret], val_t);
13763 break;
13764 case OPC_REPL_QB:
13765 check_dsp(ctx);
13767 target_long result;
13768 imm = (ctx->opcode >> 16) & 0xFF;
13769 result = (uint32_t)imm << 24 |
13770 (uint32_t)imm << 16 |
13771 (uint32_t)imm << 8 |
13772 (uint32_t)imm;
13773 result = (int32_t)result;
13774 tcg_gen_movi_tl(cpu_gpr[ret], result);
13776 break;
13777 case OPC_REPLV_QB:
13778 check_dsp(ctx);
13779 tcg_gen_ext8u_tl(cpu_gpr[ret], val_t);
13780 tcg_gen_shli_tl(t0, cpu_gpr[ret], 8);
13781 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
13782 tcg_gen_shli_tl(t0, cpu_gpr[ret], 16);
13783 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
13784 tcg_gen_ext32s_tl(cpu_gpr[ret], cpu_gpr[ret]);
13785 break;
13786 case OPC_REPL_PH:
13787 check_dsp(ctx);
13789 imm = (ctx->opcode >> 16) & 0x03FF;
13790 imm = (int16_t)(imm << 6) >> 6;
13791 tcg_gen_movi_tl(cpu_gpr[ret], \
13792 (target_long)((int32_t)imm << 16 | \
13793 (uint16_t)imm));
13795 break;
13796 case OPC_REPLV_PH:
13797 check_dsp(ctx);
13798 tcg_gen_ext16u_tl(cpu_gpr[ret], val_t);
13799 tcg_gen_shli_tl(t0, cpu_gpr[ret], 16);
13800 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
13801 tcg_gen_ext32s_tl(cpu_gpr[ret], cpu_gpr[ret]);
13802 break;
13804 break;
13805 #ifdef TARGET_MIPS64
13806 case OPC_ABSQ_S_QH_DSP:
13807 switch (op2) {
13808 case OPC_REPL_OB:
13809 check_dsp(ctx);
13811 target_long temp;
13813 imm = (ctx->opcode >> 16) & 0xFF;
13814 temp = ((uint64_t)imm << 8) | (uint64_t)imm;
13815 temp = (temp << 16) | temp;
13816 temp = (temp << 32) | temp;
13817 tcg_gen_movi_tl(cpu_gpr[ret], temp);
13818 break;
13820 case OPC_REPL_PW:
13821 check_dsp(ctx);
13823 target_long temp;
13825 imm = (ctx->opcode >> 16) & 0x03FF;
13826 imm = (int16_t)(imm << 6) >> 6;
13827 temp = ((target_long)imm << 32) \
13828 | ((target_long)imm & 0xFFFFFFFF);
13829 tcg_gen_movi_tl(cpu_gpr[ret], temp);
13830 break;
13832 case OPC_REPL_QH:
13833 check_dsp(ctx);
13835 target_long temp;
13837 imm = (ctx->opcode >> 16) & 0x03FF;
13838 imm = (int16_t)(imm << 6) >> 6;
13840 temp = ((uint64_t)(uint16_t)imm << 48) |
13841 ((uint64_t)(uint16_t)imm << 32) |
13842 ((uint64_t)(uint16_t)imm << 16) |
13843 (uint64_t)(uint16_t)imm;
13844 tcg_gen_movi_tl(cpu_gpr[ret], temp);
13845 break;
13847 case OPC_REPLV_OB:
13848 check_dsp(ctx);
13849 tcg_gen_ext8u_tl(cpu_gpr[ret], val_t);
13850 tcg_gen_shli_tl(t0, cpu_gpr[ret], 8);
13851 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
13852 tcg_gen_shli_tl(t0, cpu_gpr[ret], 16);
13853 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
13854 tcg_gen_shli_tl(t0, cpu_gpr[ret], 32);
13855 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
13856 break;
13857 case OPC_REPLV_PW:
13858 check_dsp(ctx);
13859 tcg_gen_ext32u_i64(cpu_gpr[ret], val_t);
13860 tcg_gen_shli_tl(t0, cpu_gpr[ret], 32);
13861 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
13862 break;
13863 case OPC_REPLV_QH:
13864 check_dsp(ctx);
13865 tcg_gen_ext16u_tl(cpu_gpr[ret], val_t);
13866 tcg_gen_shli_tl(t0, cpu_gpr[ret], 16);
13867 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
13868 tcg_gen_shli_tl(t0, cpu_gpr[ret], 32);
13869 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
13870 break;
13872 break;
13873 #endif
13875 tcg_temp_free(t0);
13876 tcg_temp_free(val_t);
13878 (void)opn; /* avoid a compiler warning */
13879 MIPS_DEBUG("%s", opn);
13882 static void gen_mipsdsp_add_cmp_pick(DisasContext *ctx,
13883 uint32_t op1, uint32_t op2,
13884 int ret, int v1, int v2, int check_ret)
13886 const char *opn = "mipsdsp add compare pick";
13887 TCGv t1;
13888 TCGv v1_t;
13889 TCGv v2_t;
13891 if ((ret == 0) && (check_ret == 1)) {
13892 /* Treat as NOP. */
13893 MIPS_DEBUG("NOP");
13894 return;
13897 t1 = tcg_temp_new();
13898 v1_t = tcg_temp_new();
13899 v2_t = tcg_temp_new();
13901 gen_load_gpr(v1_t, v1);
13902 gen_load_gpr(v2_t, v2);
13904 switch (op1) {
13905 case OPC_CMPU_EQ_QB_DSP:
13906 switch (op2) {
13907 case OPC_CMPU_EQ_QB:
13908 check_dsp(ctx);
13909 gen_helper_cmpu_eq_qb(v1_t, v2_t, cpu_env);
13910 break;
13911 case OPC_CMPU_LT_QB:
13912 check_dsp(ctx);
13913 gen_helper_cmpu_lt_qb(v1_t, v2_t, cpu_env);
13914 break;
13915 case OPC_CMPU_LE_QB:
13916 check_dsp(ctx);
13917 gen_helper_cmpu_le_qb(v1_t, v2_t, cpu_env);
13918 break;
13919 case OPC_CMPGU_EQ_QB:
13920 check_dsp(ctx);
13921 gen_helper_cmpgu_eq_qb(cpu_gpr[ret], v1_t, v2_t);
13922 break;
13923 case OPC_CMPGU_LT_QB:
13924 check_dsp(ctx);
13925 gen_helper_cmpgu_lt_qb(cpu_gpr[ret], v1_t, v2_t);
13926 break;
13927 case OPC_CMPGU_LE_QB:
13928 check_dsp(ctx);
13929 gen_helper_cmpgu_le_qb(cpu_gpr[ret], v1_t, v2_t);
13930 break;
13931 case OPC_CMPGDU_EQ_QB:
13932 check_dspr2(ctx);
13933 gen_helper_cmpgu_eq_qb(t1, v1_t, v2_t);
13934 tcg_gen_mov_tl(cpu_gpr[ret], t1);
13935 tcg_gen_andi_tl(cpu_dspctrl, cpu_dspctrl, 0xF0FFFFFF);
13936 tcg_gen_shli_tl(t1, t1, 24);
13937 tcg_gen_or_tl(cpu_dspctrl, cpu_dspctrl, t1);
13938 break;
13939 case OPC_CMPGDU_LT_QB:
13940 check_dspr2(ctx);
13941 gen_helper_cmpgu_lt_qb(t1, v1_t, v2_t);
13942 tcg_gen_mov_tl(cpu_gpr[ret], t1);
13943 tcg_gen_andi_tl(cpu_dspctrl, cpu_dspctrl, 0xF0FFFFFF);
13944 tcg_gen_shli_tl(t1, t1, 24);
13945 tcg_gen_or_tl(cpu_dspctrl, cpu_dspctrl, t1);
13946 break;
13947 case OPC_CMPGDU_LE_QB:
13948 check_dspr2(ctx);
13949 gen_helper_cmpgu_le_qb(t1, v1_t, v2_t);
13950 tcg_gen_mov_tl(cpu_gpr[ret], t1);
13951 tcg_gen_andi_tl(cpu_dspctrl, cpu_dspctrl, 0xF0FFFFFF);
13952 tcg_gen_shli_tl(t1, t1, 24);
13953 tcg_gen_or_tl(cpu_dspctrl, cpu_dspctrl, t1);
13954 break;
13955 case OPC_CMP_EQ_PH:
13956 check_dsp(ctx);
13957 gen_helper_cmp_eq_ph(v1_t, v2_t, cpu_env);
13958 break;
13959 case OPC_CMP_LT_PH:
13960 check_dsp(ctx);
13961 gen_helper_cmp_lt_ph(v1_t, v2_t, cpu_env);
13962 break;
13963 case OPC_CMP_LE_PH:
13964 check_dsp(ctx);
13965 gen_helper_cmp_le_ph(v1_t, v2_t, cpu_env);
13966 break;
13967 case OPC_PICK_QB:
13968 check_dsp(ctx);
13969 gen_helper_pick_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13970 break;
13971 case OPC_PICK_PH:
13972 check_dsp(ctx);
13973 gen_helper_pick_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13974 break;
13975 case OPC_PACKRL_PH:
13976 check_dsp(ctx);
13977 gen_helper_packrl_ph(cpu_gpr[ret], v1_t, v2_t);
13978 break;
13980 break;
13981 #ifdef TARGET_MIPS64
13982 case OPC_CMPU_EQ_OB_DSP:
13983 switch (op2) {
13984 case OPC_CMP_EQ_PW:
13985 check_dsp(ctx);
13986 gen_helper_cmp_eq_pw(v1_t, v2_t, cpu_env);
13987 break;
13988 case OPC_CMP_LT_PW:
13989 check_dsp(ctx);
13990 gen_helper_cmp_lt_pw(v1_t, v2_t, cpu_env);
13991 break;
13992 case OPC_CMP_LE_PW:
13993 check_dsp(ctx);
13994 gen_helper_cmp_le_pw(v1_t, v2_t, cpu_env);
13995 break;
13996 case OPC_CMP_EQ_QH:
13997 check_dsp(ctx);
13998 gen_helper_cmp_eq_qh(v1_t, v2_t, cpu_env);
13999 break;
14000 case OPC_CMP_LT_QH:
14001 check_dsp(ctx);
14002 gen_helper_cmp_lt_qh(v1_t, v2_t, cpu_env);
14003 break;
14004 case OPC_CMP_LE_QH:
14005 check_dsp(ctx);
14006 gen_helper_cmp_le_qh(v1_t, v2_t, cpu_env);
14007 break;
14008 case OPC_CMPGDU_EQ_OB:
14009 check_dspr2(ctx);
14010 gen_helper_cmpgdu_eq_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
14011 break;
14012 case OPC_CMPGDU_LT_OB:
14013 check_dspr2(ctx);
14014 gen_helper_cmpgdu_lt_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
14015 break;
14016 case OPC_CMPGDU_LE_OB:
14017 check_dspr2(ctx);
14018 gen_helper_cmpgdu_le_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
14019 break;
14020 case OPC_CMPGU_EQ_OB:
14021 check_dsp(ctx);
14022 gen_helper_cmpgu_eq_ob(cpu_gpr[ret], v1_t, v2_t);
14023 break;
14024 case OPC_CMPGU_LT_OB:
14025 check_dsp(ctx);
14026 gen_helper_cmpgu_lt_ob(cpu_gpr[ret], v1_t, v2_t);
14027 break;
14028 case OPC_CMPGU_LE_OB:
14029 check_dsp(ctx);
14030 gen_helper_cmpgu_le_ob(cpu_gpr[ret], v1_t, v2_t);
14031 break;
14032 case OPC_CMPU_EQ_OB:
14033 check_dsp(ctx);
14034 gen_helper_cmpu_eq_ob(v1_t, v2_t, cpu_env);
14035 break;
14036 case OPC_CMPU_LT_OB:
14037 check_dsp(ctx);
14038 gen_helper_cmpu_lt_ob(v1_t, v2_t, cpu_env);
14039 break;
14040 case OPC_CMPU_LE_OB:
14041 check_dsp(ctx);
14042 gen_helper_cmpu_le_ob(v1_t, v2_t, cpu_env);
14043 break;
14044 case OPC_PACKRL_PW:
14045 check_dsp(ctx);
14046 gen_helper_packrl_pw(cpu_gpr[ret], v1_t, v2_t);
14047 break;
14048 case OPC_PICK_OB:
14049 check_dsp(ctx);
14050 gen_helper_pick_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
14051 break;
14052 case OPC_PICK_PW:
14053 check_dsp(ctx);
14054 gen_helper_pick_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
14055 break;
14056 case OPC_PICK_QH:
14057 check_dsp(ctx);
14058 gen_helper_pick_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
14059 break;
14061 break;
14062 #endif
14065 tcg_temp_free(t1);
14066 tcg_temp_free(v1_t);
14067 tcg_temp_free(v2_t);
14069 (void)opn; /* avoid a compiler warning */
14070 MIPS_DEBUG("%s", opn);
14073 static void gen_mipsdsp_append(CPUMIPSState *env, DisasContext *ctx,
14074 uint32_t op1, int rt, int rs, int sa)
14076 const char *opn = "mipsdsp append/dappend";
14077 TCGv t0;
14079 check_dspr2(ctx);
14081 if (rt == 0) {
14082 /* Treat as NOP. */
14083 MIPS_DEBUG("NOP");
14084 return;
14087 t0 = tcg_temp_new();
14088 gen_load_gpr(t0, rs);
14090 switch (op1) {
14091 case OPC_APPEND_DSP:
14092 switch (MASK_APPEND(ctx->opcode)) {
14093 case OPC_APPEND:
14094 if (sa != 0) {
14095 tcg_gen_deposit_tl(cpu_gpr[rt], t0, cpu_gpr[rt], sa, 32 - sa);
14097 tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]);
14098 break;
14099 case OPC_PREPEND:
14100 if (sa != 0) {
14101 tcg_gen_ext32u_tl(cpu_gpr[rt], cpu_gpr[rt]);
14102 tcg_gen_shri_tl(cpu_gpr[rt], cpu_gpr[rt], sa);
14103 tcg_gen_shli_tl(t0, t0, 32 - sa);
14104 tcg_gen_or_tl(cpu_gpr[rt], cpu_gpr[rt], t0);
14106 tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]);
14107 break;
14108 case OPC_BALIGN:
14109 sa &= 3;
14110 if (sa != 0 && sa != 2) {
14111 tcg_gen_shli_tl(cpu_gpr[rt], cpu_gpr[rt], 8 * sa);
14112 tcg_gen_ext32u_tl(t0, t0);
14113 tcg_gen_shri_tl(t0, t0, 8 * (4 - sa));
14114 tcg_gen_or_tl(cpu_gpr[rt], cpu_gpr[rt], t0);
14116 tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]);
14117 break;
14118 default: /* Invalid */
14119 MIPS_INVAL("MASK APPEND");
14120 generate_exception(ctx, EXCP_RI);
14121 break;
14123 break;
14124 #ifdef TARGET_MIPS64
14125 case OPC_DAPPEND_DSP:
14126 switch (MASK_DAPPEND(ctx->opcode)) {
14127 case OPC_DAPPEND:
14128 if (sa != 0) {
14129 tcg_gen_deposit_tl(cpu_gpr[rt], t0, cpu_gpr[rt], sa, 64 - sa);
14131 break;
14132 case OPC_PREPENDD:
14133 tcg_gen_shri_tl(cpu_gpr[rt], cpu_gpr[rt], 0x20 | sa);
14134 tcg_gen_shli_tl(t0, t0, 64 - (0x20 | sa));
14135 tcg_gen_or_tl(cpu_gpr[rt], t0, t0);
14136 break;
14137 case OPC_PREPENDW:
14138 if (sa != 0) {
14139 tcg_gen_shri_tl(cpu_gpr[rt], cpu_gpr[rt], sa);
14140 tcg_gen_shli_tl(t0, t0, 64 - sa);
14141 tcg_gen_or_tl(cpu_gpr[rt], cpu_gpr[rt], t0);
14143 break;
14144 case OPC_DBALIGN:
14145 sa &= 7;
14146 if (sa != 0 && sa != 2 && sa != 4) {
14147 tcg_gen_shli_tl(cpu_gpr[rt], cpu_gpr[rt], 8 * sa);
14148 tcg_gen_shri_tl(t0, t0, 8 * (8 - sa));
14149 tcg_gen_or_tl(cpu_gpr[rt], cpu_gpr[rt], t0);
14151 break;
14152 default: /* Invalid */
14153 MIPS_INVAL("MASK DAPPEND");
14154 generate_exception(ctx, EXCP_RI);
14155 break;
14157 break;
14158 #endif
14160 tcg_temp_free(t0);
14161 (void)opn; /* avoid a compiler warning */
14162 MIPS_DEBUG("%s", opn);
14165 static void gen_mipsdsp_accinsn(DisasContext *ctx, uint32_t op1, uint32_t op2,
14166 int ret, int v1, int v2, int check_ret)
14169 const char *opn = "mipsdsp accumulator";
14170 TCGv t0;
14171 TCGv t1;
14172 TCGv v1_t;
14173 TCGv v2_t;
14174 int16_t imm;
14176 if ((ret == 0) && (check_ret == 1)) {
14177 /* Treat as NOP. */
14178 MIPS_DEBUG("NOP");
14179 return;
14182 t0 = tcg_temp_new();
14183 t1 = tcg_temp_new();
14184 v1_t = tcg_temp_new();
14185 v2_t = tcg_temp_new();
14187 gen_load_gpr(v1_t, v1);
14188 gen_load_gpr(v2_t, v2);
14190 switch (op1) {
14191 case OPC_EXTR_W_DSP:
14192 check_dsp(ctx);
14193 switch (op2) {
14194 case OPC_EXTR_W:
14195 tcg_gen_movi_tl(t0, v2);
14196 tcg_gen_movi_tl(t1, v1);
14197 gen_helper_extr_w(cpu_gpr[ret], t0, t1, cpu_env);
14198 break;
14199 case OPC_EXTR_R_W:
14200 tcg_gen_movi_tl(t0, v2);
14201 tcg_gen_movi_tl(t1, v1);
14202 gen_helper_extr_r_w(cpu_gpr[ret], t0, t1, cpu_env);
14203 break;
14204 case OPC_EXTR_RS_W:
14205 tcg_gen_movi_tl(t0, v2);
14206 tcg_gen_movi_tl(t1, v1);
14207 gen_helper_extr_rs_w(cpu_gpr[ret], t0, t1, cpu_env);
14208 break;
14209 case OPC_EXTR_S_H:
14210 tcg_gen_movi_tl(t0, v2);
14211 tcg_gen_movi_tl(t1, v1);
14212 gen_helper_extr_s_h(cpu_gpr[ret], t0, t1, cpu_env);
14213 break;
14214 case OPC_EXTRV_S_H:
14215 tcg_gen_movi_tl(t0, v2);
14216 gen_helper_extr_s_h(cpu_gpr[ret], t0, v1_t, cpu_env);
14217 break;
14218 case OPC_EXTRV_W:
14219 tcg_gen_movi_tl(t0, v2);
14220 gen_helper_extr_w(cpu_gpr[ret], t0, v1_t, cpu_env);
14221 break;
14222 case OPC_EXTRV_R_W:
14223 tcg_gen_movi_tl(t0, v2);
14224 gen_helper_extr_r_w(cpu_gpr[ret], t0, v1_t, cpu_env);
14225 break;
14226 case OPC_EXTRV_RS_W:
14227 tcg_gen_movi_tl(t0, v2);
14228 gen_helper_extr_rs_w(cpu_gpr[ret], t0, v1_t, cpu_env);
14229 break;
14230 case OPC_EXTP:
14231 tcg_gen_movi_tl(t0, v2);
14232 tcg_gen_movi_tl(t1, v1);
14233 gen_helper_extp(cpu_gpr[ret], t0, t1, cpu_env);
14234 break;
14235 case OPC_EXTPV:
14236 tcg_gen_movi_tl(t0, v2);
14237 gen_helper_extp(cpu_gpr[ret], t0, v1_t, cpu_env);
14238 break;
14239 case OPC_EXTPDP:
14240 tcg_gen_movi_tl(t0, v2);
14241 tcg_gen_movi_tl(t1, v1);
14242 gen_helper_extpdp(cpu_gpr[ret], t0, t1, cpu_env);
14243 break;
14244 case OPC_EXTPDPV:
14245 tcg_gen_movi_tl(t0, v2);
14246 gen_helper_extpdp(cpu_gpr[ret], t0, v1_t, cpu_env);
14247 break;
14248 case OPC_SHILO:
14249 imm = (ctx->opcode >> 20) & 0x3F;
14250 tcg_gen_movi_tl(t0, ret);
14251 tcg_gen_movi_tl(t1, imm);
14252 gen_helper_shilo(t0, t1, cpu_env);
14253 break;
14254 case OPC_SHILOV:
14255 tcg_gen_movi_tl(t0, ret);
14256 gen_helper_shilo(t0, v1_t, cpu_env);
14257 break;
14258 case OPC_MTHLIP:
14259 tcg_gen_movi_tl(t0, ret);
14260 gen_helper_mthlip(t0, v1_t, cpu_env);
14261 break;
14262 case OPC_WRDSP:
14263 imm = (ctx->opcode >> 11) & 0x3FF;
14264 tcg_gen_movi_tl(t0, imm);
14265 gen_helper_wrdsp(v1_t, t0, cpu_env);
14266 break;
14267 case OPC_RDDSP:
14268 imm = (ctx->opcode >> 16) & 0x03FF;
14269 tcg_gen_movi_tl(t0, imm);
14270 gen_helper_rddsp(cpu_gpr[ret], t0, cpu_env);
14271 break;
14273 break;
14274 #ifdef TARGET_MIPS64
14275 case OPC_DEXTR_W_DSP:
14276 check_dsp(ctx);
14277 switch (op2) {
14278 case OPC_DMTHLIP:
14279 tcg_gen_movi_tl(t0, ret);
14280 gen_helper_dmthlip(v1_t, t0, cpu_env);
14281 break;
14282 case OPC_DSHILO:
14284 int shift = (ctx->opcode >> 19) & 0x7F;
14285 int ac = (ctx->opcode >> 11) & 0x03;
14286 tcg_gen_movi_tl(t0, shift);
14287 tcg_gen_movi_tl(t1, ac);
14288 gen_helper_dshilo(t0, t1, cpu_env);
14289 break;
14291 case OPC_DSHILOV:
14293 int ac = (ctx->opcode >> 11) & 0x03;
14294 tcg_gen_movi_tl(t0, ac);
14295 gen_helper_dshilo(v1_t, t0, cpu_env);
14296 break;
14298 case OPC_DEXTP:
14299 tcg_gen_movi_tl(t0, v2);
14300 tcg_gen_movi_tl(t1, v1);
14302 gen_helper_dextp(cpu_gpr[ret], t0, t1, cpu_env);
14303 break;
14304 case OPC_DEXTPV:
14305 tcg_gen_movi_tl(t0, v2);
14306 gen_helper_dextp(cpu_gpr[ret], t0, v1_t, cpu_env);
14307 break;
14308 case OPC_DEXTPDP:
14309 tcg_gen_movi_tl(t0, v2);
14310 tcg_gen_movi_tl(t1, v1);
14311 gen_helper_dextpdp(cpu_gpr[ret], t0, t1, cpu_env);
14312 break;
14313 case OPC_DEXTPDPV:
14314 tcg_gen_movi_tl(t0, v2);
14315 gen_helper_dextpdp(cpu_gpr[ret], t0, v1_t, cpu_env);
14316 break;
14317 case OPC_DEXTR_L:
14318 tcg_gen_movi_tl(t0, v2);
14319 tcg_gen_movi_tl(t1, v1);
14320 gen_helper_dextr_l(cpu_gpr[ret], t0, t1, cpu_env);
14321 break;
14322 case OPC_DEXTR_R_L:
14323 tcg_gen_movi_tl(t0, v2);
14324 tcg_gen_movi_tl(t1, v1);
14325 gen_helper_dextr_r_l(cpu_gpr[ret], t0, t1, cpu_env);
14326 break;
14327 case OPC_DEXTR_RS_L:
14328 tcg_gen_movi_tl(t0, v2);
14329 tcg_gen_movi_tl(t1, v1);
14330 gen_helper_dextr_rs_l(cpu_gpr[ret], t0, t1, cpu_env);
14331 break;
14332 case OPC_DEXTR_W:
14333 tcg_gen_movi_tl(t0, v2);
14334 tcg_gen_movi_tl(t1, v1);
14335 gen_helper_dextr_w(cpu_gpr[ret], t0, t1, cpu_env);
14336 break;
14337 case OPC_DEXTR_R_W:
14338 tcg_gen_movi_tl(t0, v2);
14339 tcg_gen_movi_tl(t1, v1);
14340 gen_helper_dextr_r_w(cpu_gpr[ret], t0, t1, cpu_env);
14341 break;
14342 case OPC_DEXTR_RS_W:
14343 tcg_gen_movi_tl(t0, v2);
14344 tcg_gen_movi_tl(t1, v1);
14345 gen_helper_dextr_rs_w(cpu_gpr[ret], t0, t1, cpu_env);
14346 break;
14347 case OPC_DEXTR_S_H:
14348 tcg_gen_movi_tl(t0, v2);
14349 tcg_gen_movi_tl(t1, v1);
14350 gen_helper_dextr_s_h(cpu_gpr[ret], t0, t1, cpu_env);
14351 break;
14352 case OPC_DEXTRV_S_H:
14353 tcg_gen_movi_tl(t0, v2);
14354 tcg_gen_movi_tl(t1, v1);
14355 gen_helper_dextr_s_h(cpu_gpr[ret], t0, t1, cpu_env);
14356 break;
14357 case OPC_DEXTRV_L:
14358 tcg_gen_movi_tl(t0, v2);
14359 gen_helper_dextr_l(cpu_gpr[ret], t0, v1_t, cpu_env);
14360 break;
14361 case OPC_DEXTRV_R_L:
14362 tcg_gen_movi_tl(t0, v2);
14363 gen_helper_dextr_r_l(cpu_gpr[ret], t0, v1_t, cpu_env);
14364 break;
14365 case OPC_DEXTRV_RS_L:
14366 tcg_gen_movi_tl(t0, v2);
14367 gen_helper_dextr_rs_l(cpu_gpr[ret], t0, v1_t, cpu_env);
14368 break;
14369 case OPC_DEXTRV_W:
14370 tcg_gen_movi_tl(t0, v2);
14371 gen_helper_dextr_w(cpu_gpr[ret], t0, v1_t, cpu_env);
14372 break;
14373 case OPC_DEXTRV_R_W:
14374 tcg_gen_movi_tl(t0, v2);
14375 gen_helper_dextr_r_w(cpu_gpr[ret], t0, v1_t, cpu_env);
14376 break;
14377 case OPC_DEXTRV_RS_W:
14378 tcg_gen_movi_tl(t0, v2);
14379 gen_helper_dextr_rs_w(cpu_gpr[ret], t0, v1_t, cpu_env);
14380 break;
14382 break;
14383 #endif
14386 tcg_temp_free(t0);
14387 tcg_temp_free(t1);
14388 tcg_temp_free(v1_t);
14389 tcg_temp_free(v2_t);
14391 (void)opn; /* avoid a compiler warning */
14392 MIPS_DEBUG("%s", opn);
14395 /* End MIPSDSP functions. */
14397 static void decode_opc (CPUMIPSState *env, DisasContext *ctx)
14399 int32_t offset;
14400 int rs, rt, rd, sa;
14401 uint32_t op, op1, op2;
14402 int16_t imm;
14404 /* make sure instructions are on a word boundary */
14405 if (ctx->pc & 0x3) {
14406 env->CP0_BadVAddr = ctx->pc;
14407 generate_exception(ctx, EXCP_AdEL);
14408 return;
14411 /* Handle blikely not taken case */
14412 if ((ctx->hflags & MIPS_HFLAG_BMASK_BASE) == MIPS_HFLAG_BL) {
14413 int l1 = gen_new_label();
14415 MIPS_DEBUG("blikely condition (" TARGET_FMT_lx ")", ctx->pc + 4);
14416 tcg_gen_brcondi_tl(TCG_COND_NE, bcond, 0, l1);
14417 tcg_gen_movi_i32(hflags, ctx->hflags & ~MIPS_HFLAG_BMASK);
14418 gen_goto_tb(ctx, 1, ctx->pc + 4);
14419 gen_set_label(l1);
14422 if (unlikely(qemu_loglevel_mask(CPU_LOG_TB_OP | CPU_LOG_TB_OP_OPT))) {
14423 tcg_gen_debug_insn_start(ctx->pc);
14426 op = MASK_OP_MAJOR(ctx->opcode);
14427 rs = (ctx->opcode >> 21) & 0x1f;
14428 rt = (ctx->opcode >> 16) & 0x1f;
14429 rd = (ctx->opcode >> 11) & 0x1f;
14430 sa = (ctx->opcode >> 6) & 0x1f;
14431 imm = (int16_t)ctx->opcode;
14432 switch (op) {
14433 case OPC_SPECIAL:
14434 op1 = MASK_SPECIAL(ctx->opcode);
14435 switch (op1) {
14436 case OPC_SLL: /* Shift with immediate */
14437 case OPC_SRA:
14438 gen_shift_imm(ctx, op1, rd, rt, sa);
14439 break;
14440 case OPC_SRL:
14441 switch ((ctx->opcode >> 21) & 0x1f) {
14442 case 1:
14443 /* rotr is decoded as srl on non-R2 CPUs */
14444 if (ctx->insn_flags & ISA_MIPS32R2) {
14445 op1 = OPC_ROTR;
14447 /* Fallthrough */
14448 case 0:
14449 gen_shift_imm(ctx, op1, rd, rt, sa);
14450 break;
14451 default:
14452 generate_exception(ctx, EXCP_RI);
14453 break;
14455 break;
14456 case OPC_MOVN: /* Conditional move */
14457 case OPC_MOVZ:
14458 check_insn(ctx, ISA_MIPS4 | ISA_MIPS32 |
14459 INSN_LOONGSON2E | INSN_LOONGSON2F);
14460 gen_cond_move(ctx, op1, rd, rs, rt);
14461 break;
14462 case OPC_ADD ... OPC_SUBU:
14463 gen_arith(ctx, op1, rd, rs, rt);
14464 break;
14465 case OPC_SLLV: /* Shifts */
14466 case OPC_SRAV:
14467 gen_shift(ctx, op1, rd, rs, rt);
14468 break;
14469 case OPC_SRLV:
14470 switch ((ctx->opcode >> 6) & 0x1f) {
14471 case 1:
14472 /* rotrv is decoded as srlv on non-R2 CPUs */
14473 if (ctx->insn_flags & ISA_MIPS32R2) {
14474 op1 = OPC_ROTRV;
14476 /* Fallthrough */
14477 case 0:
14478 gen_shift(ctx, op1, rd, rs, rt);
14479 break;
14480 default:
14481 generate_exception(ctx, EXCP_RI);
14482 break;
14484 break;
14485 case OPC_SLT: /* Set on less than */
14486 case OPC_SLTU:
14487 gen_slt(ctx, op1, rd, rs, rt);
14488 break;
14489 case OPC_AND: /* Logic*/
14490 case OPC_OR:
14491 case OPC_NOR:
14492 case OPC_XOR:
14493 gen_logic(ctx, op1, rd, rs, rt);
14494 break;
14495 case OPC_MULT:
14496 case OPC_MULTU:
14497 if (sa) {
14498 check_insn(ctx, INSN_VR54XX);
14499 op1 = MASK_MUL_VR54XX(ctx->opcode);
14500 gen_mul_vr54xx(ctx, op1, rd, rs, rt);
14501 } else {
14502 gen_muldiv(ctx, op1, rd & 3, rs, rt);
14504 break;
14505 case OPC_DIV:
14506 case OPC_DIVU:
14507 gen_muldiv(ctx, op1, 0, rs, rt);
14508 break;
14509 case OPC_JR ... OPC_JALR:
14510 gen_compute_branch(ctx, op1, 4, rs, rd, sa);
14511 break;
14512 case OPC_TGE ... OPC_TEQ: /* Traps */
14513 case OPC_TNE:
14514 gen_trap(ctx, op1, rs, rt, -1);
14515 break;
14516 case OPC_MFHI: /* Move from HI/LO */
14517 case OPC_MFLO:
14518 gen_HILO(ctx, op1, rs & 3, rd);
14519 break;
14520 case OPC_MTHI:
14521 case OPC_MTLO: /* Move to HI/LO */
14522 gen_HILO(ctx, op1, rd & 3, rs);
14523 break;
14524 case OPC_PMON: /* Pmon entry point, also R4010 selsl */
14525 #ifdef MIPS_STRICT_STANDARD
14526 MIPS_INVAL("PMON / selsl");
14527 generate_exception(ctx, EXCP_RI);
14528 #else
14529 gen_helper_0e0i(pmon, sa);
14530 #endif
14531 break;
14532 case OPC_SYSCALL:
14533 generate_exception(ctx, EXCP_SYSCALL);
14534 ctx->bstate = BS_STOP;
14535 break;
14536 case OPC_BREAK:
14537 generate_exception(ctx, EXCP_BREAK);
14538 break;
14539 case OPC_SPIM:
14540 #ifdef MIPS_STRICT_STANDARD
14541 MIPS_INVAL("SPIM");
14542 generate_exception(ctx, EXCP_RI);
14543 #else
14544 /* Implemented as RI exception for now. */
14545 MIPS_INVAL("spim (unofficial)");
14546 generate_exception(ctx, EXCP_RI);
14547 #endif
14548 break;
14549 case OPC_SYNC:
14550 /* Treat as NOP. */
14551 break;
14553 case OPC_MOVCI:
14554 check_insn(ctx, ISA_MIPS4 | ISA_MIPS32);
14555 if (env->CP0_Config1 & (1 << CP0C1_FP)) {
14556 check_cp1_enabled(ctx);
14557 gen_movci(ctx, rd, rs, (ctx->opcode >> 18) & 0x7,
14558 (ctx->opcode >> 16) & 1);
14559 } else {
14560 generate_exception_err(ctx, EXCP_CpU, 1);
14562 break;
14564 #if defined(TARGET_MIPS64)
14565 /* MIPS64 specific opcodes */
14566 case OPC_DSLL:
14567 case OPC_DSRA:
14568 case OPC_DSLL32:
14569 case OPC_DSRA32:
14570 check_insn(ctx, ISA_MIPS3);
14571 check_mips_64(ctx);
14572 gen_shift_imm(ctx, op1, rd, rt, sa);
14573 break;
14574 case OPC_DSRL:
14575 switch ((ctx->opcode >> 21) & 0x1f) {
14576 case 1:
14577 /* drotr is decoded as dsrl on non-R2 CPUs */
14578 if (ctx->insn_flags & ISA_MIPS32R2) {
14579 op1 = OPC_DROTR;
14581 /* Fallthrough */
14582 case 0:
14583 check_insn(ctx, ISA_MIPS3);
14584 check_mips_64(ctx);
14585 gen_shift_imm(ctx, op1, rd, rt, sa);
14586 break;
14587 default:
14588 generate_exception(ctx, EXCP_RI);
14589 break;
14591 break;
14592 case OPC_DSRL32:
14593 switch ((ctx->opcode >> 21) & 0x1f) {
14594 case 1:
14595 /* drotr32 is decoded as dsrl32 on non-R2 CPUs */
14596 if (ctx->insn_flags & ISA_MIPS32R2) {
14597 op1 = OPC_DROTR32;
14599 /* Fallthrough */
14600 case 0:
14601 check_insn(ctx, ISA_MIPS3);
14602 check_mips_64(ctx);
14603 gen_shift_imm(ctx, op1, rd, rt, sa);
14604 break;
14605 default:
14606 generate_exception(ctx, EXCP_RI);
14607 break;
14609 break;
14610 case OPC_DADD ... OPC_DSUBU:
14611 check_insn(ctx, ISA_MIPS3);
14612 check_mips_64(ctx);
14613 gen_arith(ctx, op1, rd, rs, rt);
14614 break;
14615 case OPC_DSLLV:
14616 case OPC_DSRAV:
14617 check_insn(ctx, ISA_MIPS3);
14618 check_mips_64(ctx);
14619 gen_shift(ctx, op1, rd, rs, rt);
14620 break;
14621 case OPC_DSRLV:
14622 switch ((ctx->opcode >> 6) & 0x1f) {
14623 case 1:
14624 /* drotrv is decoded as dsrlv on non-R2 CPUs */
14625 if (ctx->insn_flags & ISA_MIPS32R2) {
14626 op1 = OPC_DROTRV;
14628 /* Fallthrough */
14629 case 0:
14630 check_insn(ctx, ISA_MIPS3);
14631 check_mips_64(ctx);
14632 gen_shift(ctx, op1, rd, rs, rt);
14633 break;
14634 default:
14635 generate_exception(ctx, EXCP_RI);
14636 break;
14638 break;
14639 case OPC_DMULT ... OPC_DDIVU:
14640 check_insn(ctx, ISA_MIPS3);
14641 check_mips_64(ctx);
14642 gen_muldiv(ctx, op1, 0, rs, rt);
14643 break;
14644 #endif
14645 default: /* Invalid */
14646 MIPS_INVAL("special");
14647 generate_exception(ctx, EXCP_RI);
14648 break;
14650 break;
14651 case OPC_SPECIAL2:
14652 op1 = MASK_SPECIAL2(ctx->opcode);
14653 switch (op1) {
14654 case OPC_MADD ... OPC_MADDU: /* Multiply and add/sub */
14655 case OPC_MSUB ... OPC_MSUBU:
14656 check_insn(ctx, ISA_MIPS32);
14657 gen_muldiv(ctx, op1, rd & 3, rs, rt);
14658 break;
14659 case OPC_MUL:
14660 gen_arith(ctx, op1, rd, rs, rt);
14661 break;
14662 case OPC_CLO:
14663 case OPC_CLZ:
14664 check_insn(ctx, ISA_MIPS32);
14665 gen_cl(ctx, op1, rd, rs);
14666 break;
14667 case OPC_SDBBP:
14668 /* XXX: not clear which exception should be raised
14669 * when in debug mode...
14671 check_insn(ctx, ISA_MIPS32);
14672 if (!(ctx->hflags & MIPS_HFLAG_DM)) {
14673 generate_exception(ctx, EXCP_DBp);
14674 } else {
14675 generate_exception(ctx, EXCP_DBp);
14677 /* Treat as NOP. */
14678 break;
14679 case OPC_DIV_G_2F:
14680 case OPC_DIVU_G_2F:
14681 case OPC_MULT_G_2F:
14682 case OPC_MULTU_G_2F:
14683 case OPC_MOD_G_2F:
14684 case OPC_MODU_G_2F:
14685 check_insn(ctx, INSN_LOONGSON2F);
14686 gen_loongson_integer(ctx, op1, rd, rs, rt);
14687 break;
14688 #if defined(TARGET_MIPS64)
14689 case OPC_DCLO:
14690 case OPC_DCLZ:
14691 check_insn(ctx, ISA_MIPS64);
14692 check_mips_64(ctx);
14693 gen_cl(ctx, op1, rd, rs);
14694 break;
14695 case OPC_DMULT_G_2F:
14696 case OPC_DMULTU_G_2F:
14697 case OPC_DDIV_G_2F:
14698 case OPC_DDIVU_G_2F:
14699 case OPC_DMOD_G_2F:
14700 case OPC_DMODU_G_2F:
14701 check_insn(ctx, INSN_LOONGSON2F);
14702 gen_loongson_integer(ctx, op1, rd, rs, rt);
14703 break;
14704 #endif
14705 default: /* Invalid */
14706 MIPS_INVAL("special2");
14707 generate_exception(ctx, EXCP_RI);
14708 break;
14710 break;
14711 case OPC_SPECIAL3:
14712 op1 = MASK_SPECIAL3(ctx->opcode);
14713 switch (op1) {
14714 case OPC_EXT:
14715 case OPC_INS:
14716 check_insn(ctx, ISA_MIPS32R2);
14717 gen_bitops(ctx, op1, rt, rs, sa, rd);
14718 break;
14719 case OPC_BSHFL:
14720 check_insn(ctx, ISA_MIPS32R2);
14721 op2 = MASK_BSHFL(ctx->opcode);
14722 gen_bshfl(ctx, op2, rt, rd);
14723 break;
14724 case OPC_RDHWR:
14725 gen_rdhwr(ctx, rt, rd);
14726 break;
14727 case OPC_FORK:
14728 check_insn(ctx, ASE_MT);
14730 TCGv t0 = tcg_temp_new();
14731 TCGv t1 = tcg_temp_new();
14733 gen_load_gpr(t0, rt);
14734 gen_load_gpr(t1, rs);
14735 gen_helper_fork(t0, t1);
14736 tcg_temp_free(t0);
14737 tcg_temp_free(t1);
14739 break;
14740 case OPC_YIELD:
14741 check_insn(ctx, ASE_MT);
14743 TCGv t0 = tcg_temp_new();
14745 save_cpu_state(ctx, 1);
14746 gen_load_gpr(t0, rs);
14747 gen_helper_yield(t0, cpu_env, t0);
14748 gen_store_gpr(t0, rd);
14749 tcg_temp_free(t0);
14751 break;
14752 case OPC_DIV_G_2E ... OPC_DIVU_G_2E:
14753 case OPC_MOD_G_2E ... OPC_MODU_G_2E:
14754 case OPC_MULT_G_2E ... OPC_MULTU_G_2E:
14755 /* OPC_MULT_G_2E, OPC_ADDUH_QB_DSP, OPC_MUL_PH_DSP have
14756 * the same mask and op1. */
14757 if ((ctx->insn_flags & ASE_DSPR2) && (op1 == OPC_MULT_G_2E)) {
14758 op2 = MASK_ADDUH_QB(ctx->opcode);
14759 switch (op2) {
14760 case OPC_ADDUH_QB:
14761 case OPC_ADDUH_R_QB:
14762 case OPC_ADDQH_PH:
14763 case OPC_ADDQH_R_PH:
14764 case OPC_ADDQH_W:
14765 case OPC_ADDQH_R_W:
14766 case OPC_SUBUH_QB:
14767 case OPC_SUBUH_R_QB:
14768 case OPC_SUBQH_PH:
14769 case OPC_SUBQH_R_PH:
14770 case OPC_SUBQH_W:
14771 case OPC_SUBQH_R_W:
14772 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
14773 break;
14774 case OPC_MUL_PH:
14775 case OPC_MUL_S_PH:
14776 case OPC_MULQ_S_W:
14777 case OPC_MULQ_RS_W:
14778 gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 1);
14779 break;
14780 default:
14781 MIPS_INVAL("MASK ADDUH.QB");
14782 generate_exception(ctx, EXCP_RI);
14783 break;
14785 } else if (ctx->insn_flags & INSN_LOONGSON2E) {
14786 gen_loongson_integer(ctx, op1, rd, rs, rt);
14787 } else {
14788 generate_exception(ctx, EXCP_RI);
14790 break;
14791 case OPC_LX_DSP:
14792 op2 = MASK_LX(ctx->opcode);
14793 switch (op2) {
14794 #if defined(TARGET_MIPS64)
14795 case OPC_LDX:
14796 #endif
14797 case OPC_LBUX:
14798 case OPC_LHX:
14799 case OPC_LWX:
14800 gen_mipsdsp_ld(ctx, op2, rd, rs, rt);
14801 break;
14802 default: /* Invalid */
14803 MIPS_INVAL("MASK LX");
14804 generate_exception(ctx, EXCP_RI);
14805 break;
14807 break;
14808 case OPC_ABSQ_S_PH_DSP:
14809 op2 = MASK_ABSQ_S_PH(ctx->opcode);
14810 switch (op2) {
14811 case OPC_ABSQ_S_QB:
14812 case OPC_ABSQ_S_PH:
14813 case OPC_ABSQ_S_W:
14814 case OPC_PRECEQ_W_PHL:
14815 case OPC_PRECEQ_W_PHR:
14816 case OPC_PRECEQU_PH_QBL:
14817 case OPC_PRECEQU_PH_QBR:
14818 case OPC_PRECEQU_PH_QBLA:
14819 case OPC_PRECEQU_PH_QBRA:
14820 case OPC_PRECEU_PH_QBL:
14821 case OPC_PRECEU_PH_QBR:
14822 case OPC_PRECEU_PH_QBLA:
14823 case OPC_PRECEU_PH_QBRA:
14824 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
14825 break;
14826 case OPC_BITREV:
14827 case OPC_REPL_QB:
14828 case OPC_REPLV_QB:
14829 case OPC_REPL_PH:
14830 case OPC_REPLV_PH:
14831 gen_mipsdsp_bitinsn(ctx, op1, op2, rd, rt);
14832 break;
14833 default:
14834 MIPS_INVAL("MASK ABSQ_S.PH");
14835 generate_exception(ctx, EXCP_RI);
14836 break;
14838 break;
14839 case OPC_ADDU_QB_DSP:
14840 op2 = MASK_ADDU_QB(ctx->opcode);
14841 switch (op2) {
14842 case OPC_ADDQ_PH:
14843 case OPC_ADDQ_S_PH:
14844 case OPC_ADDQ_S_W:
14845 case OPC_ADDU_QB:
14846 case OPC_ADDU_S_QB:
14847 case OPC_ADDU_PH:
14848 case OPC_ADDU_S_PH:
14849 case OPC_SUBQ_PH:
14850 case OPC_SUBQ_S_PH:
14851 case OPC_SUBQ_S_W:
14852 case OPC_SUBU_QB:
14853 case OPC_SUBU_S_QB:
14854 case OPC_SUBU_PH:
14855 case OPC_SUBU_S_PH:
14856 case OPC_ADDSC:
14857 case OPC_ADDWC:
14858 case OPC_MODSUB:
14859 case OPC_RADDU_W_QB:
14860 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
14861 break;
14862 case OPC_MULEU_S_PH_QBL:
14863 case OPC_MULEU_S_PH_QBR:
14864 case OPC_MULQ_RS_PH:
14865 case OPC_MULEQ_S_W_PHL:
14866 case OPC_MULEQ_S_W_PHR:
14867 case OPC_MULQ_S_PH:
14868 gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 1);
14869 break;
14870 default: /* Invalid */
14871 MIPS_INVAL("MASK ADDU.QB");
14872 generate_exception(ctx, EXCP_RI);
14873 break;
14876 break;
14877 case OPC_CMPU_EQ_QB_DSP:
14878 op2 = MASK_CMPU_EQ_QB(ctx->opcode);
14879 switch (op2) {
14880 case OPC_PRECR_SRA_PH_W:
14881 case OPC_PRECR_SRA_R_PH_W:
14882 gen_mipsdsp_arith(ctx, op1, op2, rt, rs, rd);
14883 break;
14884 case OPC_PRECR_QB_PH:
14885 case OPC_PRECRQ_QB_PH:
14886 case OPC_PRECRQ_PH_W:
14887 case OPC_PRECRQ_RS_PH_W:
14888 case OPC_PRECRQU_S_QB_PH:
14889 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
14890 break;
14891 case OPC_CMPU_EQ_QB:
14892 case OPC_CMPU_LT_QB:
14893 case OPC_CMPU_LE_QB:
14894 case OPC_CMP_EQ_PH:
14895 case OPC_CMP_LT_PH:
14896 case OPC_CMP_LE_PH:
14897 gen_mipsdsp_add_cmp_pick(ctx, op1, op2, rd, rs, rt, 0);
14898 break;
14899 case OPC_CMPGU_EQ_QB:
14900 case OPC_CMPGU_LT_QB:
14901 case OPC_CMPGU_LE_QB:
14902 case OPC_CMPGDU_EQ_QB:
14903 case OPC_CMPGDU_LT_QB:
14904 case OPC_CMPGDU_LE_QB:
14905 case OPC_PICK_QB:
14906 case OPC_PICK_PH:
14907 case OPC_PACKRL_PH:
14908 gen_mipsdsp_add_cmp_pick(ctx, op1, op2, rd, rs, rt, 1);
14909 break;
14910 default: /* Invalid */
14911 MIPS_INVAL("MASK CMPU.EQ.QB");
14912 generate_exception(ctx, EXCP_RI);
14913 break;
14915 break;
14916 case OPC_SHLL_QB_DSP:
14917 gen_mipsdsp_shift(ctx, op1, rd, rs, rt);
14918 break;
14919 case OPC_DPA_W_PH_DSP:
14920 op2 = MASK_DPA_W_PH(ctx->opcode);
14921 switch (op2) {
14922 case OPC_DPAU_H_QBL:
14923 case OPC_DPAU_H_QBR:
14924 case OPC_DPSU_H_QBL:
14925 case OPC_DPSU_H_QBR:
14926 case OPC_DPA_W_PH:
14927 case OPC_DPAX_W_PH:
14928 case OPC_DPAQ_S_W_PH:
14929 case OPC_DPAQX_S_W_PH:
14930 case OPC_DPAQX_SA_W_PH:
14931 case OPC_DPS_W_PH:
14932 case OPC_DPSX_W_PH:
14933 case OPC_DPSQ_S_W_PH:
14934 case OPC_DPSQX_S_W_PH:
14935 case OPC_DPSQX_SA_W_PH:
14936 case OPC_MULSAQ_S_W_PH:
14937 case OPC_DPAQ_SA_L_W:
14938 case OPC_DPSQ_SA_L_W:
14939 case OPC_MAQ_S_W_PHL:
14940 case OPC_MAQ_S_W_PHR:
14941 case OPC_MAQ_SA_W_PHL:
14942 case OPC_MAQ_SA_W_PHR:
14943 case OPC_MULSA_W_PH:
14944 gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 0);
14945 break;
14946 default: /* Invalid */
14947 MIPS_INVAL("MASK DPAW.PH");
14948 generate_exception(ctx, EXCP_RI);
14949 break;
14951 break;
14952 case OPC_INSV_DSP:
14953 op2 = MASK_INSV(ctx->opcode);
14954 switch (op2) {
14955 case OPC_INSV:
14956 check_dsp(ctx);
14958 TCGv t0, t1;
14960 if (rt == 0) {
14961 MIPS_DEBUG("NOP");
14962 break;
14965 t0 = tcg_temp_new();
14966 t1 = tcg_temp_new();
14968 gen_load_gpr(t0, rt);
14969 gen_load_gpr(t1, rs);
14971 gen_helper_insv(cpu_gpr[rt], cpu_env, t1, t0);
14973 tcg_temp_free(t0);
14974 tcg_temp_free(t1);
14975 break;
14977 default: /* Invalid */
14978 MIPS_INVAL("MASK INSV");
14979 generate_exception(ctx, EXCP_RI);
14980 break;
14982 break;
14983 case OPC_APPEND_DSP:
14984 gen_mipsdsp_append(env, ctx, op1, rt, rs, rd);
14985 break;
14986 case OPC_EXTR_W_DSP:
14987 op2 = MASK_EXTR_W(ctx->opcode);
14988 switch (op2) {
14989 case OPC_EXTR_W:
14990 case OPC_EXTR_R_W:
14991 case OPC_EXTR_RS_W:
14992 case OPC_EXTR_S_H:
14993 case OPC_EXTRV_S_H:
14994 case OPC_EXTRV_W:
14995 case OPC_EXTRV_R_W:
14996 case OPC_EXTRV_RS_W:
14997 case OPC_EXTP:
14998 case OPC_EXTPV:
14999 case OPC_EXTPDP:
15000 case OPC_EXTPDPV:
15001 gen_mipsdsp_accinsn(ctx, op1, op2, rt, rs, rd, 1);
15002 break;
15003 case OPC_RDDSP:
15004 gen_mipsdsp_accinsn(ctx, op1, op2, rd, rs, rt, 1);
15005 break;
15006 case OPC_SHILO:
15007 case OPC_SHILOV:
15008 case OPC_MTHLIP:
15009 case OPC_WRDSP:
15010 gen_mipsdsp_accinsn(ctx, op1, op2, rd, rs, rt, 0);
15011 break;
15012 default: /* Invalid */
15013 MIPS_INVAL("MASK EXTR.W");
15014 generate_exception(ctx, EXCP_RI);
15015 break;
15017 break;
15018 #if defined(TARGET_MIPS64)
15019 case OPC_DEXTM ... OPC_DEXT:
15020 case OPC_DINSM ... OPC_DINS:
15021 check_insn(ctx, ISA_MIPS64R2);
15022 check_mips_64(ctx);
15023 gen_bitops(ctx, op1, rt, rs, sa, rd);
15024 break;
15025 case OPC_DBSHFL:
15026 check_insn(ctx, ISA_MIPS64R2);
15027 check_mips_64(ctx);
15028 op2 = MASK_DBSHFL(ctx->opcode);
15029 gen_bshfl(ctx, op2, rt, rd);
15030 break;
15031 case OPC_DDIV_G_2E ... OPC_DDIVU_G_2E:
15032 case OPC_DMULT_G_2E ... OPC_DMULTU_G_2E:
15033 case OPC_DMOD_G_2E ... OPC_DMODU_G_2E:
15034 check_insn(ctx, INSN_LOONGSON2E);
15035 gen_loongson_integer(ctx, op1, rd, rs, rt);
15036 break;
15037 case OPC_ABSQ_S_QH_DSP:
15038 op2 = MASK_ABSQ_S_QH(ctx->opcode);
15039 switch (op2) {
15040 case OPC_PRECEQ_L_PWL:
15041 case OPC_PRECEQ_L_PWR:
15042 case OPC_PRECEQ_PW_QHL:
15043 case OPC_PRECEQ_PW_QHR:
15044 case OPC_PRECEQ_PW_QHLA:
15045 case OPC_PRECEQ_PW_QHRA:
15046 case OPC_PRECEQU_QH_OBL:
15047 case OPC_PRECEQU_QH_OBR:
15048 case OPC_PRECEQU_QH_OBLA:
15049 case OPC_PRECEQU_QH_OBRA:
15050 case OPC_PRECEU_QH_OBL:
15051 case OPC_PRECEU_QH_OBR:
15052 case OPC_PRECEU_QH_OBLA:
15053 case OPC_PRECEU_QH_OBRA:
15054 case OPC_ABSQ_S_OB:
15055 case OPC_ABSQ_S_PW:
15056 case OPC_ABSQ_S_QH:
15057 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
15058 break;
15059 case OPC_REPL_OB:
15060 case OPC_REPL_PW:
15061 case OPC_REPL_QH:
15062 case OPC_REPLV_OB:
15063 case OPC_REPLV_PW:
15064 case OPC_REPLV_QH:
15065 gen_mipsdsp_bitinsn(ctx, op1, op2, rd, rt);
15066 break;
15067 default: /* Invalid */
15068 MIPS_INVAL("MASK ABSQ_S.QH");
15069 generate_exception(ctx, EXCP_RI);
15070 break;
15072 break;
15073 case OPC_ADDU_OB_DSP:
15074 op2 = MASK_ADDU_OB(ctx->opcode);
15075 switch (op2) {
15076 case OPC_RADDU_L_OB:
15077 case OPC_SUBQ_PW:
15078 case OPC_SUBQ_S_PW:
15079 case OPC_SUBQ_QH:
15080 case OPC_SUBQ_S_QH:
15081 case OPC_SUBU_OB:
15082 case OPC_SUBU_S_OB:
15083 case OPC_SUBU_QH:
15084 case OPC_SUBU_S_QH:
15085 case OPC_SUBUH_OB:
15086 case OPC_SUBUH_R_OB:
15087 case OPC_ADDQ_PW:
15088 case OPC_ADDQ_S_PW:
15089 case OPC_ADDQ_QH:
15090 case OPC_ADDQ_S_QH:
15091 case OPC_ADDU_OB:
15092 case OPC_ADDU_S_OB:
15093 case OPC_ADDU_QH:
15094 case OPC_ADDU_S_QH:
15095 case OPC_ADDUH_OB:
15096 case OPC_ADDUH_R_OB:
15097 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
15098 break;
15099 case OPC_MULEQ_S_PW_QHL:
15100 case OPC_MULEQ_S_PW_QHR:
15101 case OPC_MULEU_S_QH_OBL:
15102 case OPC_MULEU_S_QH_OBR:
15103 case OPC_MULQ_RS_QH:
15104 gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 1);
15105 break;
15106 default: /* Invalid */
15107 MIPS_INVAL("MASK ADDU.OB");
15108 generate_exception(ctx, EXCP_RI);
15109 break;
15111 break;
15112 case OPC_CMPU_EQ_OB_DSP:
15113 op2 = MASK_CMPU_EQ_OB(ctx->opcode);
15114 switch (op2) {
15115 case OPC_PRECR_SRA_QH_PW:
15116 case OPC_PRECR_SRA_R_QH_PW:
15117 /* Return value is rt. */
15118 gen_mipsdsp_arith(ctx, op1, op2, rt, rs, rd);
15119 break;
15120 case OPC_PRECR_OB_QH:
15121 case OPC_PRECRQ_OB_QH:
15122 case OPC_PRECRQ_PW_L:
15123 case OPC_PRECRQ_QH_PW:
15124 case OPC_PRECRQ_RS_QH_PW:
15125 case OPC_PRECRQU_S_OB_QH:
15126 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
15127 break;
15128 case OPC_CMPU_EQ_OB:
15129 case OPC_CMPU_LT_OB:
15130 case OPC_CMPU_LE_OB:
15131 case OPC_CMP_EQ_QH:
15132 case OPC_CMP_LT_QH:
15133 case OPC_CMP_LE_QH:
15134 case OPC_CMP_EQ_PW:
15135 case OPC_CMP_LT_PW:
15136 case OPC_CMP_LE_PW:
15137 gen_mipsdsp_add_cmp_pick(ctx, op1, op2, rd, rs, rt, 0);
15138 break;
15139 case OPC_CMPGDU_EQ_OB:
15140 case OPC_CMPGDU_LT_OB:
15141 case OPC_CMPGDU_LE_OB:
15142 case OPC_CMPGU_EQ_OB:
15143 case OPC_CMPGU_LT_OB:
15144 case OPC_CMPGU_LE_OB:
15145 case OPC_PACKRL_PW:
15146 case OPC_PICK_OB:
15147 case OPC_PICK_PW:
15148 case OPC_PICK_QH:
15149 gen_mipsdsp_add_cmp_pick(ctx, op1, op2, rd, rs, rt, 1);
15150 break;
15151 default: /* Invalid */
15152 MIPS_INVAL("MASK CMPU_EQ.OB");
15153 generate_exception(ctx, EXCP_RI);
15154 break;
15156 break;
15157 case OPC_DAPPEND_DSP:
15158 gen_mipsdsp_append(env, ctx, op1, rt, rs, rd);
15159 break;
15160 case OPC_DEXTR_W_DSP:
15161 op2 = MASK_DEXTR_W(ctx->opcode);
15162 switch (op2) {
15163 case OPC_DEXTP:
15164 case OPC_DEXTPDP:
15165 case OPC_DEXTPDPV:
15166 case OPC_DEXTPV:
15167 case OPC_DEXTR_L:
15168 case OPC_DEXTR_R_L:
15169 case OPC_DEXTR_RS_L:
15170 case OPC_DEXTR_W:
15171 case OPC_DEXTR_R_W:
15172 case OPC_DEXTR_RS_W:
15173 case OPC_DEXTR_S_H:
15174 case OPC_DEXTRV_L:
15175 case OPC_DEXTRV_R_L:
15176 case OPC_DEXTRV_RS_L:
15177 case OPC_DEXTRV_S_H:
15178 case OPC_DEXTRV_W:
15179 case OPC_DEXTRV_R_W:
15180 case OPC_DEXTRV_RS_W:
15181 gen_mipsdsp_accinsn(ctx, op1, op2, rt, rs, rd, 1);
15182 break;
15183 case OPC_DMTHLIP:
15184 case OPC_DSHILO:
15185 case OPC_DSHILOV:
15186 gen_mipsdsp_accinsn(ctx, op1, op2, rd, rs, rt, 0);
15187 break;
15188 default: /* Invalid */
15189 MIPS_INVAL("MASK EXTR.W");
15190 generate_exception(ctx, EXCP_RI);
15191 break;
15193 break;
15194 case OPC_DPAQ_W_QH_DSP:
15195 op2 = MASK_DPAQ_W_QH(ctx->opcode);
15196 switch (op2) {
15197 case OPC_DPAU_H_OBL:
15198 case OPC_DPAU_H_OBR:
15199 case OPC_DPSU_H_OBL:
15200 case OPC_DPSU_H_OBR:
15201 case OPC_DPA_W_QH:
15202 case OPC_DPAQ_S_W_QH:
15203 case OPC_DPS_W_QH:
15204 case OPC_DPSQ_S_W_QH:
15205 case OPC_MULSAQ_S_W_QH:
15206 case OPC_DPAQ_SA_L_PW:
15207 case OPC_DPSQ_SA_L_PW:
15208 case OPC_MULSAQ_S_L_PW:
15209 gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 0);
15210 break;
15211 case OPC_MAQ_S_W_QHLL:
15212 case OPC_MAQ_S_W_QHLR:
15213 case OPC_MAQ_S_W_QHRL:
15214 case OPC_MAQ_S_W_QHRR:
15215 case OPC_MAQ_SA_W_QHLL:
15216 case OPC_MAQ_SA_W_QHLR:
15217 case OPC_MAQ_SA_W_QHRL:
15218 case OPC_MAQ_SA_W_QHRR:
15219 case OPC_MAQ_S_L_PWL:
15220 case OPC_MAQ_S_L_PWR:
15221 case OPC_DMADD:
15222 case OPC_DMADDU:
15223 case OPC_DMSUB:
15224 case OPC_DMSUBU:
15225 gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 0);
15226 break;
15227 default: /* Invalid */
15228 MIPS_INVAL("MASK DPAQ.W.QH");
15229 generate_exception(ctx, EXCP_RI);
15230 break;
15232 break;
15233 case OPC_DINSV_DSP:
15234 op2 = MASK_INSV(ctx->opcode);
15235 switch (op2) {
15236 case OPC_DINSV:
15238 TCGv t0, t1;
15240 if (rt == 0) {
15241 MIPS_DEBUG("NOP");
15242 break;
15244 check_dsp(ctx);
15246 t0 = tcg_temp_new();
15247 t1 = tcg_temp_new();
15249 gen_load_gpr(t0, rt);
15250 gen_load_gpr(t1, rs);
15252 gen_helper_dinsv(cpu_gpr[rt], cpu_env, t1, t0);
15253 break;
15255 default: /* Invalid */
15256 MIPS_INVAL("MASK DINSV");
15257 generate_exception(ctx, EXCP_RI);
15258 break;
15260 break;
15261 case OPC_SHLL_OB_DSP:
15262 gen_mipsdsp_shift(ctx, op1, rd, rs, rt);
15263 break;
15264 #endif
15265 default: /* Invalid */
15266 MIPS_INVAL("special3");
15267 generate_exception(ctx, EXCP_RI);
15268 break;
15270 break;
15271 case OPC_REGIMM:
15272 op1 = MASK_REGIMM(ctx->opcode);
15273 switch (op1) {
15274 case OPC_BLTZ ... OPC_BGEZL: /* REGIMM branches */
15275 case OPC_BLTZAL ... OPC_BGEZALL:
15276 gen_compute_branch(ctx, op1, 4, rs, -1, imm << 2);
15277 break;
15278 case OPC_TGEI ... OPC_TEQI: /* REGIMM traps */
15279 case OPC_TNEI:
15280 gen_trap(ctx, op1, rs, -1, imm);
15281 break;
15282 case OPC_SYNCI:
15283 check_insn(ctx, ISA_MIPS32R2);
15284 /* Treat as NOP. */
15285 break;
15286 case OPC_BPOSGE32: /* MIPS DSP branch */
15287 #if defined(TARGET_MIPS64)
15288 case OPC_BPOSGE64:
15289 #endif
15290 check_dsp(ctx);
15291 gen_compute_branch(ctx, op1, 4, -1, -2, (int32_t)imm << 2);
15292 break;
15293 default: /* Invalid */
15294 MIPS_INVAL("regimm");
15295 generate_exception(ctx, EXCP_RI);
15296 break;
15298 break;
15299 case OPC_CP0:
15300 check_cp0_enabled(ctx);
15301 op1 = MASK_CP0(ctx->opcode);
15302 switch (op1) {
15303 case OPC_MFC0:
15304 case OPC_MTC0:
15305 case OPC_MFTR:
15306 case OPC_MTTR:
15307 #if defined(TARGET_MIPS64)
15308 case OPC_DMFC0:
15309 case OPC_DMTC0:
15310 #endif
15311 #ifndef CONFIG_USER_ONLY
15312 gen_cp0(env, ctx, op1, rt, rd);
15313 #endif /* !CONFIG_USER_ONLY */
15314 break;
15315 case OPC_C0_FIRST ... OPC_C0_LAST:
15316 #ifndef CONFIG_USER_ONLY
15317 gen_cp0(env, ctx, MASK_C0(ctx->opcode), rt, rd);
15318 #endif /* !CONFIG_USER_ONLY */
15319 break;
15320 case OPC_MFMC0:
15321 #ifndef CONFIG_USER_ONLY
15323 TCGv t0 = tcg_temp_new();
15325 op2 = MASK_MFMC0(ctx->opcode);
15326 switch (op2) {
15327 case OPC_DMT:
15328 check_insn(ctx, ASE_MT);
15329 gen_helper_dmt(t0);
15330 gen_store_gpr(t0, rt);
15331 break;
15332 case OPC_EMT:
15333 check_insn(ctx, ASE_MT);
15334 gen_helper_emt(t0);
15335 gen_store_gpr(t0, rt);
15336 break;
15337 case OPC_DVPE:
15338 check_insn(ctx, ASE_MT);
15339 gen_helper_dvpe(t0, cpu_env);
15340 gen_store_gpr(t0, rt);
15341 break;
15342 case OPC_EVPE:
15343 check_insn(ctx, ASE_MT);
15344 gen_helper_evpe(t0, cpu_env);
15345 gen_store_gpr(t0, rt);
15346 break;
15347 case OPC_DI:
15348 check_insn(ctx, ISA_MIPS32R2);
15349 save_cpu_state(ctx, 1);
15350 gen_helper_di(t0, cpu_env);
15351 gen_store_gpr(t0, rt);
15352 /* Stop translation as we may have switched the execution mode */
15353 ctx->bstate = BS_STOP;
15354 break;
15355 case OPC_EI:
15356 check_insn(ctx, ISA_MIPS32R2);
15357 save_cpu_state(ctx, 1);
15358 gen_helper_ei(t0, cpu_env);
15359 gen_store_gpr(t0, rt);
15360 /* Stop translation as we may have switched the execution mode */
15361 ctx->bstate = BS_STOP;
15362 break;
15363 default: /* Invalid */
15364 MIPS_INVAL("mfmc0");
15365 generate_exception(ctx, EXCP_RI);
15366 break;
15368 tcg_temp_free(t0);
15370 #endif /* !CONFIG_USER_ONLY */
15371 break;
15372 case OPC_RDPGPR:
15373 check_insn(ctx, ISA_MIPS32R2);
15374 gen_load_srsgpr(rt, rd);
15375 break;
15376 case OPC_WRPGPR:
15377 check_insn(ctx, ISA_MIPS32R2);
15378 gen_store_srsgpr(rt, rd);
15379 break;
15380 default:
15381 MIPS_INVAL("cp0");
15382 generate_exception(ctx, EXCP_RI);
15383 break;
15385 break;
15386 case OPC_ADDI: /* Arithmetic with immediate opcode */
15387 case OPC_ADDIU:
15388 gen_arith_imm(ctx, op, rt, rs, imm);
15389 break;
15390 case OPC_SLTI: /* Set on less than with immediate opcode */
15391 case OPC_SLTIU:
15392 gen_slt_imm(ctx, op, rt, rs, imm);
15393 break;
15394 case OPC_ANDI: /* Arithmetic with immediate opcode */
15395 case OPC_LUI:
15396 case OPC_ORI:
15397 case OPC_XORI:
15398 gen_logic_imm(ctx, op, rt, rs, imm);
15399 break;
15400 case OPC_J ... OPC_JAL: /* Jump */
15401 offset = (int32_t)(ctx->opcode & 0x3FFFFFF) << 2;
15402 gen_compute_branch(ctx, op, 4, rs, rt, offset);
15403 break;
15404 case OPC_BEQ ... OPC_BGTZ: /* Branch */
15405 case OPC_BEQL ... OPC_BGTZL:
15406 gen_compute_branch(ctx, op, 4, rs, rt, imm << 2);
15407 break;
15408 case OPC_LB ... OPC_LWR: /* Load and stores */
15409 case OPC_LL:
15410 gen_ld(ctx, op, rt, rs, imm);
15411 break;
15412 case OPC_SB ... OPC_SW:
15413 case OPC_SWR:
15414 gen_st(ctx, op, rt, rs, imm);
15415 break;
15416 case OPC_SC:
15417 gen_st_cond(ctx, op, rt, rs, imm);
15418 break;
15419 case OPC_CACHE:
15420 check_cp0_enabled(ctx);
15421 check_insn(ctx, ISA_MIPS3 | ISA_MIPS32);
15422 /* Treat as NOP. */
15423 break;
15424 case OPC_PREF:
15425 check_insn(ctx, ISA_MIPS4 | ISA_MIPS32);
15426 /* Treat as NOP. */
15427 break;
15429 /* Floating point (COP1). */
15430 case OPC_LWC1:
15431 case OPC_LDC1:
15432 case OPC_SWC1:
15433 case OPC_SDC1:
15434 gen_cop1_ldst(env, ctx, op, rt, rs, imm);
15435 break;
15437 case OPC_CP1:
15438 if (env->CP0_Config1 & (1 << CP0C1_FP)) {
15439 check_cp1_enabled(ctx);
15440 op1 = MASK_CP1(ctx->opcode);
15441 switch (op1) {
15442 case OPC_MFHC1:
15443 case OPC_MTHC1:
15444 check_insn(ctx, ISA_MIPS32R2);
15445 case OPC_MFC1:
15446 case OPC_CFC1:
15447 case OPC_MTC1:
15448 case OPC_CTC1:
15449 gen_cp1(ctx, op1, rt, rd);
15450 break;
15451 #if defined(TARGET_MIPS64)
15452 case OPC_DMFC1:
15453 case OPC_DMTC1:
15454 check_insn(ctx, ISA_MIPS3);
15455 gen_cp1(ctx, op1, rt, rd);
15456 break;
15457 #endif
15458 case OPC_BC1ANY2:
15459 case OPC_BC1ANY4:
15460 check_cop1x(ctx);
15461 check_insn(ctx, ASE_MIPS3D);
15462 /* fall through */
15463 case OPC_BC1:
15464 gen_compute_branch1(ctx, MASK_BC1(ctx->opcode),
15465 (rt >> 2) & 0x7, imm << 2);
15466 break;
15467 case OPC_S_FMT:
15468 case OPC_D_FMT:
15469 case OPC_W_FMT:
15470 case OPC_L_FMT:
15471 case OPC_PS_FMT:
15472 gen_farith(ctx, ctx->opcode & FOP(0x3f, 0x1f), rt, rd, sa,
15473 (imm >> 8) & 0x7);
15474 break;
15475 default:
15476 MIPS_INVAL("cp1");
15477 generate_exception (ctx, EXCP_RI);
15478 break;
15480 } else {
15481 generate_exception_err(ctx, EXCP_CpU, 1);
15483 break;
15485 /* COP2. */
15486 case OPC_LWC2:
15487 case OPC_LDC2:
15488 case OPC_SWC2:
15489 case OPC_SDC2:
15490 /* COP2: Not implemented. */
15491 generate_exception_err(ctx, EXCP_CpU, 2);
15492 break;
15493 case OPC_CP2:
15494 check_insn(ctx, INSN_LOONGSON2F);
15495 /* Note that these instructions use different fields. */
15496 gen_loongson_multimedia(ctx, sa, rd, rt);
15497 break;
15499 case OPC_CP3:
15500 if (env->CP0_Config1 & (1 << CP0C1_FP)) {
15501 check_cp1_enabled(ctx);
15502 op1 = MASK_CP3(ctx->opcode);
15503 switch (op1) {
15504 case OPC_LWXC1:
15505 case OPC_LDXC1:
15506 case OPC_LUXC1:
15507 case OPC_SWXC1:
15508 case OPC_SDXC1:
15509 case OPC_SUXC1:
15510 gen_flt3_ldst(ctx, op1, sa, rd, rs, rt);
15511 break;
15512 case OPC_PREFX:
15513 /* Treat as NOP. */
15514 break;
15515 case OPC_ALNV_PS:
15516 case OPC_MADD_S:
15517 case OPC_MADD_D:
15518 case OPC_MADD_PS:
15519 case OPC_MSUB_S:
15520 case OPC_MSUB_D:
15521 case OPC_MSUB_PS:
15522 case OPC_NMADD_S:
15523 case OPC_NMADD_D:
15524 case OPC_NMADD_PS:
15525 case OPC_NMSUB_S:
15526 case OPC_NMSUB_D:
15527 case OPC_NMSUB_PS:
15528 gen_flt3_arith(ctx, op1, sa, rs, rd, rt);
15529 break;
15530 default:
15531 MIPS_INVAL("cp3");
15532 generate_exception (ctx, EXCP_RI);
15533 break;
15535 } else {
15536 generate_exception_err(ctx, EXCP_CpU, 1);
15538 break;
15540 #if defined(TARGET_MIPS64)
15541 /* MIPS64 opcodes */
15542 case OPC_LWU:
15543 case OPC_LDL ... OPC_LDR:
15544 case OPC_LLD:
15545 case OPC_LD:
15546 check_insn(ctx, ISA_MIPS3);
15547 check_mips_64(ctx);
15548 gen_ld(ctx, op, rt, rs, imm);
15549 break;
15550 case OPC_SDL ... OPC_SDR:
15551 case OPC_SD:
15552 check_insn(ctx, ISA_MIPS3);
15553 check_mips_64(ctx);
15554 gen_st(ctx, op, rt, rs, imm);
15555 break;
15556 case OPC_SCD:
15557 check_insn(ctx, ISA_MIPS3);
15558 check_mips_64(ctx);
15559 gen_st_cond(ctx, op, rt, rs, imm);
15560 break;
15561 case OPC_DADDI:
15562 case OPC_DADDIU:
15563 check_insn(ctx, ISA_MIPS3);
15564 check_mips_64(ctx);
15565 gen_arith_imm(ctx, op, rt, rs, imm);
15566 break;
15567 #endif
15568 case OPC_JALX:
15569 check_insn(ctx, ASE_MIPS16 | ASE_MICROMIPS);
15570 offset = (int32_t)(ctx->opcode & 0x3FFFFFF) << 2;
15571 gen_compute_branch(ctx, op, 4, rs, rt, offset);
15572 break;
15573 case OPC_MDMX:
15574 check_insn(ctx, ASE_MDMX);
15575 /* MDMX: Not implemented. */
15576 default: /* Invalid */
15577 MIPS_INVAL("major opcode");
15578 generate_exception(ctx, EXCP_RI);
15579 break;
15583 static inline void
15584 gen_intermediate_code_internal(MIPSCPU *cpu, TranslationBlock *tb,
15585 bool search_pc)
15587 CPUState *cs = CPU(cpu);
15588 CPUMIPSState *env = &cpu->env;
15589 DisasContext ctx;
15590 target_ulong pc_start;
15591 uint16_t *gen_opc_end;
15592 CPUBreakpoint *bp;
15593 int j, lj = -1;
15594 int num_insns;
15595 int max_insns;
15596 int insn_bytes;
15597 int is_delay;
15599 if (search_pc)
15600 qemu_log("search pc %d\n", search_pc);
15602 pc_start = tb->pc;
15603 gen_opc_end = tcg_ctx.gen_opc_buf + OPC_MAX_SIZE;
15604 ctx.pc = pc_start;
15605 ctx.saved_pc = -1;
15606 ctx.singlestep_enabled = cs->singlestep_enabled;
15607 ctx.insn_flags = env->insn_flags;
15608 ctx.tb = tb;
15609 ctx.bstate = BS_NONE;
15610 /* Restore delay slot state from the tb context. */
15611 ctx.hflags = (uint32_t)tb->flags; /* FIXME: maybe use 64 bits here? */
15612 restore_cpu_state(env, &ctx);
15613 #ifdef CONFIG_USER_ONLY
15614 ctx.mem_idx = MIPS_HFLAG_UM;
15615 #else
15616 ctx.mem_idx = ctx.hflags & MIPS_HFLAG_KSU;
15617 #endif
15618 num_insns = 0;
15619 max_insns = tb->cflags & CF_COUNT_MASK;
15620 if (max_insns == 0)
15621 max_insns = CF_COUNT_MASK;
15622 LOG_DISAS("\ntb %p idx %d hflags %04x\n", tb, ctx.mem_idx, ctx.hflags);
15623 gen_tb_start();
15624 while (ctx.bstate == BS_NONE) {
15625 if (unlikely(!QTAILQ_EMPTY(&cs->breakpoints))) {
15626 QTAILQ_FOREACH(bp, &cs->breakpoints, entry) {
15627 if (bp->pc == ctx.pc) {
15628 save_cpu_state(&ctx, 1);
15629 ctx.bstate = BS_BRANCH;
15630 gen_helper_0e0i(raise_exception, EXCP_DEBUG);
15631 /* Include the breakpoint location or the tb won't
15632 * be flushed when it must be. */
15633 ctx.pc += 4;
15634 goto done_generating;
15639 if (search_pc) {
15640 j = tcg_ctx.gen_opc_ptr - tcg_ctx.gen_opc_buf;
15641 if (lj < j) {
15642 lj++;
15643 while (lj < j)
15644 tcg_ctx.gen_opc_instr_start[lj++] = 0;
15646 tcg_ctx.gen_opc_pc[lj] = ctx.pc;
15647 gen_opc_hflags[lj] = ctx.hflags & MIPS_HFLAG_BMASK;
15648 gen_opc_btarget[lj] = ctx.btarget;
15649 tcg_ctx.gen_opc_instr_start[lj] = 1;
15650 tcg_ctx.gen_opc_icount[lj] = num_insns;
15652 if (num_insns + 1 == max_insns && (tb->cflags & CF_LAST_IO))
15653 gen_io_start();
15655 is_delay = ctx.hflags & MIPS_HFLAG_BMASK;
15656 if (!(ctx.hflags & MIPS_HFLAG_M16)) {
15657 ctx.opcode = cpu_ldl_code(env, ctx.pc);
15658 insn_bytes = 4;
15659 decode_opc(env, &ctx);
15660 } else if (ctx.insn_flags & ASE_MICROMIPS) {
15661 ctx.opcode = cpu_lduw_code(env, ctx.pc);
15662 insn_bytes = decode_micromips_opc(env, &ctx);
15663 } else if (ctx.insn_flags & ASE_MIPS16) {
15664 ctx.opcode = cpu_lduw_code(env, ctx.pc);
15665 insn_bytes = decode_mips16_opc(env, &ctx);
15666 } else {
15667 generate_exception(&ctx, EXCP_RI);
15668 ctx.bstate = BS_STOP;
15669 break;
15671 if (is_delay) {
15672 handle_delay_slot(&ctx, insn_bytes);
15674 ctx.pc += insn_bytes;
15676 num_insns++;
15678 /* Execute a branch and its delay slot as a single instruction.
15679 This is what GDB expects and is consistent with what the
15680 hardware does (e.g. if a delay slot instruction faults, the
15681 reported PC is the PC of the branch). */
15682 if (cs->singlestep_enabled && (ctx.hflags & MIPS_HFLAG_BMASK) == 0) {
15683 break;
15686 if ((ctx.pc & (TARGET_PAGE_SIZE - 1)) == 0)
15687 break;
15689 if (tcg_ctx.gen_opc_ptr >= gen_opc_end) {
15690 break;
15693 if (num_insns >= max_insns)
15694 break;
15696 if (singlestep)
15697 break;
15699 if (tb->cflags & CF_LAST_IO) {
15700 gen_io_end();
15702 if (cs->singlestep_enabled && ctx.bstate != BS_BRANCH) {
15703 save_cpu_state(&ctx, ctx.bstate == BS_NONE);
15704 gen_helper_0e0i(raise_exception, EXCP_DEBUG);
15705 } else {
15706 switch (ctx.bstate) {
15707 case BS_STOP:
15708 gen_goto_tb(&ctx, 0, ctx.pc);
15709 break;
15710 case BS_NONE:
15711 save_cpu_state(&ctx, 0);
15712 gen_goto_tb(&ctx, 0, ctx.pc);
15713 break;
15714 case BS_EXCP:
15715 tcg_gen_exit_tb(0);
15716 break;
15717 case BS_BRANCH:
15718 default:
15719 break;
15722 done_generating:
15723 gen_tb_end(tb, num_insns);
15724 *tcg_ctx.gen_opc_ptr = INDEX_op_end;
15725 if (search_pc) {
15726 j = tcg_ctx.gen_opc_ptr - tcg_ctx.gen_opc_buf;
15727 lj++;
15728 while (lj <= j)
15729 tcg_ctx.gen_opc_instr_start[lj++] = 0;
15730 } else {
15731 tb->size = ctx.pc - pc_start;
15732 tb->icount = num_insns;
15734 #ifdef DEBUG_DISAS
15735 LOG_DISAS("\n");
15736 if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM)) {
15737 qemu_log("IN: %s\n", lookup_symbol(pc_start));
15738 log_target_disas(env, pc_start, ctx.pc - pc_start, 0);
15739 qemu_log("\n");
15741 #endif
15744 void gen_intermediate_code (CPUMIPSState *env, struct TranslationBlock *tb)
15746 gen_intermediate_code_internal(mips_env_get_cpu(env), tb, false);
15749 void gen_intermediate_code_pc (CPUMIPSState *env, struct TranslationBlock *tb)
15751 gen_intermediate_code_internal(mips_env_get_cpu(env), tb, true);
15754 static void fpu_dump_state(CPUMIPSState *env, FILE *f, fprintf_function fpu_fprintf,
15755 int flags)
15757 int i;
15758 int is_fpu64 = !!(env->hflags & MIPS_HFLAG_F64);
15760 #define printfpr(fp) \
15761 do { \
15762 if (is_fpu64) \
15763 fpu_fprintf(f, "w:%08x d:%016" PRIx64 \
15764 " fd:%13g fs:%13g psu: %13g\n", \
15765 (fp)->w[FP_ENDIAN_IDX], (fp)->d, \
15766 (double)(fp)->fd, \
15767 (double)(fp)->fs[FP_ENDIAN_IDX], \
15768 (double)(fp)->fs[!FP_ENDIAN_IDX]); \
15769 else { \
15770 fpr_t tmp; \
15771 tmp.w[FP_ENDIAN_IDX] = (fp)->w[FP_ENDIAN_IDX]; \
15772 tmp.w[!FP_ENDIAN_IDX] = ((fp) + 1)->w[FP_ENDIAN_IDX]; \
15773 fpu_fprintf(f, "w:%08x d:%016" PRIx64 \
15774 " fd:%13g fs:%13g psu:%13g\n", \
15775 tmp.w[FP_ENDIAN_IDX], tmp.d, \
15776 (double)tmp.fd, \
15777 (double)tmp.fs[FP_ENDIAN_IDX], \
15778 (double)tmp.fs[!FP_ENDIAN_IDX]); \
15780 } while(0)
15783 fpu_fprintf(f, "CP1 FCR0 0x%08x FCR31 0x%08x SR.FR %d fp_status 0x%02x\n",
15784 env->active_fpu.fcr0, env->active_fpu.fcr31, is_fpu64,
15785 get_float_exception_flags(&env->active_fpu.fp_status));
15786 for (i = 0; i < 32; (is_fpu64) ? i++ : (i += 2)) {
15787 fpu_fprintf(f, "%3s: ", fregnames[i]);
15788 printfpr(&env->active_fpu.fpr[i]);
15791 #undef printfpr
15794 #if defined(TARGET_MIPS64) && defined(MIPS_DEBUG_SIGN_EXTENSIONS)
15795 /* Debug help: The architecture requires 32bit code to maintain proper
15796 sign-extended values on 64bit machines. */
15798 #define SIGN_EXT_P(val) ((((val) & ~0x7fffffff) == 0) || (((val) & ~0x7fffffff) == ~0x7fffffff))
15800 static void
15801 cpu_mips_check_sign_extensions (CPUMIPSState *env, FILE *f,
15802 fprintf_function cpu_fprintf,
15803 int flags)
15805 int i;
15807 if (!SIGN_EXT_P(env->active_tc.PC))
15808 cpu_fprintf(f, "BROKEN: pc=0x" TARGET_FMT_lx "\n", env->active_tc.PC);
15809 if (!SIGN_EXT_P(env->active_tc.HI[0]))
15810 cpu_fprintf(f, "BROKEN: HI=0x" TARGET_FMT_lx "\n", env->active_tc.HI[0]);
15811 if (!SIGN_EXT_P(env->active_tc.LO[0]))
15812 cpu_fprintf(f, "BROKEN: LO=0x" TARGET_FMT_lx "\n", env->active_tc.LO[0]);
15813 if (!SIGN_EXT_P(env->btarget))
15814 cpu_fprintf(f, "BROKEN: btarget=0x" TARGET_FMT_lx "\n", env->btarget);
15816 for (i = 0; i < 32; i++) {
15817 if (!SIGN_EXT_P(env->active_tc.gpr[i]))
15818 cpu_fprintf(f, "BROKEN: %s=0x" TARGET_FMT_lx "\n", regnames[i], env->active_tc.gpr[i]);
15821 if (!SIGN_EXT_P(env->CP0_EPC))
15822 cpu_fprintf(f, "BROKEN: EPC=0x" TARGET_FMT_lx "\n", env->CP0_EPC);
15823 if (!SIGN_EXT_P(env->lladdr))
15824 cpu_fprintf(f, "BROKEN: LLAddr=0x" TARGET_FMT_lx "\n", env->lladdr);
15826 #endif
15828 void mips_cpu_dump_state(CPUState *cs, FILE *f, fprintf_function cpu_fprintf,
15829 int flags)
15831 MIPSCPU *cpu = MIPS_CPU(cs);
15832 CPUMIPSState *env = &cpu->env;
15833 int i;
15835 cpu_fprintf(f, "pc=0x" TARGET_FMT_lx " HI=0x" TARGET_FMT_lx
15836 " LO=0x" TARGET_FMT_lx " ds %04x "
15837 TARGET_FMT_lx " " TARGET_FMT_ld "\n",
15838 env->active_tc.PC, env->active_tc.HI[0], env->active_tc.LO[0],
15839 env->hflags, env->btarget, env->bcond);
15840 for (i = 0; i < 32; i++) {
15841 if ((i & 3) == 0)
15842 cpu_fprintf(f, "GPR%02d:", i);
15843 cpu_fprintf(f, " %s " TARGET_FMT_lx, regnames[i], env->active_tc.gpr[i]);
15844 if ((i & 3) == 3)
15845 cpu_fprintf(f, "\n");
15848 cpu_fprintf(f, "CP0 Status 0x%08x Cause 0x%08x EPC 0x" TARGET_FMT_lx "\n",
15849 env->CP0_Status, env->CP0_Cause, env->CP0_EPC);
15850 cpu_fprintf(f, " Config0 0x%08x Config1 0x%08x LLAddr 0x" TARGET_FMT_lx "\n",
15851 env->CP0_Config0, env->CP0_Config1, env->lladdr);
15852 if (env->hflags & MIPS_HFLAG_FPU)
15853 fpu_dump_state(env, f, cpu_fprintf, flags);
15854 #if defined(TARGET_MIPS64) && defined(MIPS_DEBUG_SIGN_EXTENSIONS)
15855 cpu_mips_check_sign_extensions(env, f, cpu_fprintf, flags);
15856 #endif
15859 void mips_tcg_init(void)
15861 int i;
15862 static int inited;
15864 /* Initialize various static tables. */
15865 if (inited)
15866 return;
15868 cpu_env = tcg_global_reg_new_ptr(TCG_AREG0, "env");
15869 TCGV_UNUSED(cpu_gpr[0]);
15870 for (i = 1; i < 32; i++)
15871 cpu_gpr[i] = tcg_global_mem_new(TCG_AREG0,
15872 offsetof(CPUMIPSState, active_tc.gpr[i]),
15873 regnames[i]);
15875 for (i = 0; i < 32; i++) {
15876 int off = offsetof(CPUMIPSState, active_fpu.fpr[i]);
15877 fpu_f64[i] = tcg_global_mem_new_i64(TCG_AREG0, off, fregnames[i]);
15880 cpu_PC = tcg_global_mem_new(TCG_AREG0,
15881 offsetof(CPUMIPSState, active_tc.PC), "PC");
15882 for (i = 0; i < MIPS_DSP_ACC; i++) {
15883 cpu_HI[i] = tcg_global_mem_new(TCG_AREG0,
15884 offsetof(CPUMIPSState, active_tc.HI[i]),
15885 regnames_HI[i]);
15886 cpu_LO[i] = tcg_global_mem_new(TCG_AREG0,
15887 offsetof(CPUMIPSState, active_tc.LO[i]),
15888 regnames_LO[i]);
15889 cpu_ACX[i] = tcg_global_mem_new(TCG_AREG0,
15890 offsetof(CPUMIPSState, active_tc.ACX[i]),
15891 regnames_ACX[i]);
15893 cpu_dspctrl = tcg_global_mem_new(TCG_AREG0,
15894 offsetof(CPUMIPSState, active_tc.DSPControl),
15895 "DSPControl");
15896 bcond = tcg_global_mem_new(TCG_AREG0,
15897 offsetof(CPUMIPSState, bcond), "bcond");
15898 btarget = tcg_global_mem_new(TCG_AREG0,
15899 offsetof(CPUMIPSState, btarget), "btarget");
15900 hflags = tcg_global_mem_new_i32(TCG_AREG0,
15901 offsetof(CPUMIPSState, hflags), "hflags");
15903 fpu_fcr0 = tcg_global_mem_new_i32(TCG_AREG0,
15904 offsetof(CPUMIPSState, active_fpu.fcr0),
15905 "fcr0");
15906 fpu_fcr31 = tcg_global_mem_new_i32(TCG_AREG0,
15907 offsetof(CPUMIPSState, active_fpu.fcr31),
15908 "fcr31");
15910 inited = 1;
15913 #include "translate_init.c"
15915 MIPSCPU *cpu_mips_init(const char *cpu_model)
15917 MIPSCPU *cpu;
15918 CPUMIPSState *env;
15919 const mips_def_t *def;
15921 def = cpu_mips_find_by_name(cpu_model);
15922 if (!def)
15923 return NULL;
15924 cpu = MIPS_CPU(object_new(TYPE_MIPS_CPU));
15925 env = &cpu->env;
15926 env->cpu_model = def;
15928 #ifndef CONFIG_USER_ONLY
15929 mmu_init(env, def);
15930 #endif
15931 fpu_init(env, def);
15932 mvp_init(env, def);
15934 object_property_set_bool(OBJECT(cpu), true, "realized", NULL);
15936 return cpu;
15939 void cpu_state_reset(CPUMIPSState *env)
15941 MIPSCPU *cpu = mips_env_get_cpu(env);
15942 CPUState *cs = CPU(cpu);
15944 /* Reset registers to their default values */
15945 env->CP0_PRid = env->cpu_model->CP0_PRid;
15946 env->CP0_Config0 = env->cpu_model->CP0_Config0;
15947 #ifdef TARGET_WORDS_BIGENDIAN
15948 env->CP0_Config0 |= (1 << CP0C0_BE);
15949 #endif
15950 env->CP0_Config1 = env->cpu_model->CP0_Config1;
15951 env->CP0_Config2 = env->cpu_model->CP0_Config2;
15952 env->CP0_Config3 = env->cpu_model->CP0_Config3;
15953 env->CP0_Config4 = env->cpu_model->CP0_Config4;
15954 env->CP0_Config4_rw_bitmask = env->cpu_model->CP0_Config4_rw_bitmask;
15955 env->CP0_Config5 = env->cpu_model->CP0_Config5;
15956 env->CP0_Config5_rw_bitmask = env->cpu_model->CP0_Config5_rw_bitmask;
15957 env->CP0_Config6 = env->cpu_model->CP0_Config6;
15958 env->CP0_Config7 = env->cpu_model->CP0_Config7;
15959 env->CP0_LLAddr_rw_bitmask = env->cpu_model->CP0_LLAddr_rw_bitmask
15960 << env->cpu_model->CP0_LLAddr_shift;
15961 env->CP0_LLAddr_shift = env->cpu_model->CP0_LLAddr_shift;
15962 env->SYNCI_Step = env->cpu_model->SYNCI_Step;
15963 env->CCRes = env->cpu_model->CCRes;
15964 env->CP0_Status_rw_bitmask = env->cpu_model->CP0_Status_rw_bitmask;
15965 env->CP0_TCStatus_rw_bitmask = env->cpu_model->CP0_TCStatus_rw_bitmask;
15966 env->CP0_SRSCtl = env->cpu_model->CP0_SRSCtl;
15967 env->current_tc = 0;
15968 env->SEGBITS = env->cpu_model->SEGBITS;
15969 env->SEGMask = (target_ulong)((1ULL << env->cpu_model->SEGBITS) - 1);
15970 #if defined(TARGET_MIPS64)
15971 if (env->cpu_model->insn_flags & ISA_MIPS3) {
15972 env->SEGMask |= 3ULL << 62;
15974 #endif
15975 env->PABITS = env->cpu_model->PABITS;
15976 env->PAMask = (target_ulong)((1ULL << env->cpu_model->PABITS) - 1);
15977 env->CP0_SRSConf0_rw_bitmask = env->cpu_model->CP0_SRSConf0_rw_bitmask;
15978 env->CP0_SRSConf0 = env->cpu_model->CP0_SRSConf0;
15979 env->CP0_SRSConf1_rw_bitmask = env->cpu_model->CP0_SRSConf1_rw_bitmask;
15980 env->CP0_SRSConf1 = env->cpu_model->CP0_SRSConf1;
15981 env->CP0_SRSConf2_rw_bitmask = env->cpu_model->CP0_SRSConf2_rw_bitmask;
15982 env->CP0_SRSConf2 = env->cpu_model->CP0_SRSConf2;
15983 env->CP0_SRSConf3_rw_bitmask = env->cpu_model->CP0_SRSConf3_rw_bitmask;
15984 env->CP0_SRSConf3 = env->cpu_model->CP0_SRSConf3;
15985 env->CP0_SRSConf4_rw_bitmask = env->cpu_model->CP0_SRSConf4_rw_bitmask;
15986 env->CP0_SRSConf4 = env->cpu_model->CP0_SRSConf4;
15987 env->active_fpu.fcr0 = env->cpu_model->CP1_fcr0;
15988 env->insn_flags = env->cpu_model->insn_flags;
15990 #if defined(CONFIG_USER_ONLY)
15991 env->CP0_Status = (MIPS_HFLAG_UM << CP0St_KSU);
15992 # ifdef TARGET_MIPS64
15993 /* Enable 64-bit register mode. */
15994 env->CP0_Status |= (1 << CP0St_PX);
15995 # endif
15996 # ifdef TARGET_ABI_MIPSN64
15997 /* Enable 64-bit address mode. */
15998 env->CP0_Status |= (1 << CP0St_UX);
15999 # endif
16000 /* Enable access to the CPUNum, SYNCI_Step, CC, and CCRes RDHWR
16001 hardware registers. */
16002 env->CP0_HWREna |= 0x0000000F;
16003 if (env->CP0_Config1 & (1 << CP0C1_FP)) {
16004 env->CP0_Status |= (1 << CP0St_CU1);
16006 if (env->CP0_Config3 & (1 << CP0C3_DSPP)) {
16007 env->CP0_Status |= (1 << CP0St_MX);
16009 # if defined(TARGET_MIPS64)
16010 /* For MIPS64, init FR bit to 1 if FPU unit is there and bit is writable. */
16011 if ((env->CP0_Config1 & (1 << CP0C1_FP)) &&
16012 (env->CP0_Status_rw_bitmask & (1 << CP0St_FR))) {
16013 env->CP0_Status |= (1 << CP0St_FR);
16015 # endif
16016 #else
16017 if (env->hflags & MIPS_HFLAG_BMASK) {
16018 /* If the exception was raised from a delay slot,
16019 come back to the jump. */
16020 env->CP0_ErrorEPC = env->active_tc.PC - 4;
16021 } else {
16022 env->CP0_ErrorEPC = env->active_tc.PC;
16024 env->active_tc.PC = (int32_t)0xBFC00000;
16025 env->CP0_Random = env->tlb->nb_tlb - 1;
16026 env->tlb->tlb_in_use = env->tlb->nb_tlb;
16027 env->CP0_Wired = 0;
16028 env->CP0_EBase = 0x80000000 | (cs->cpu_index & 0x3FF);
16029 env->CP0_Status = (1 << CP0St_BEV) | (1 << CP0St_ERL);
16030 /* vectored interrupts not implemented, timer on int 7,
16031 no performance counters. */
16032 env->CP0_IntCtl = 0xe0000000;
16034 int i;
16036 for (i = 0; i < 7; i++) {
16037 env->CP0_WatchLo[i] = 0;
16038 env->CP0_WatchHi[i] = 0x80000000;
16040 env->CP0_WatchLo[7] = 0;
16041 env->CP0_WatchHi[7] = 0;
16043 /* Count register increments in debug mode, EJTAG version 1 */
16044 env->CP0_Debug = (1 << CP0DB_CNT) | (0x1 << CP0DB_VER);
16046 if (env->CP0_Config3 & (1 << CP0C3_MT)) {
16047 int i;
16049 /* Only TC0 on VPE 0 starts as active. */
16050 for (i = 0; i < ARRAY_SIZE(env->tcs); i++) {
16051 env->tcs[i].CP0_TCBind = cs->cpu_index << CP0TCBd_CurVPE;
16052 env->tcs[i].CP0_TCHalt = 1;
16054 env->active_tc.CP0_TCHalt = 1;
16055 cs->halted = 1;
16057 if (cs->cpu_index == 0) {
16058 /* VPE0 starts up enabled. */
16059 env->mvp->CP0_MVPControl |= (1 << CP0MVPCo_EVP);
16060 env->CP0_VPEConf0 |= (1 << CP0VPEC0_MVP) | (1 << CP0VPEC0_VPA);
16062 /* TC0 starts up unhalted. */
16063 cs->halted = 0;
16064 env->active_tc.CP0_TCHalt = 0;
16065 env->tcs[0].CP0_TCHalt = 0;
16066 /* With thread 0 active. */
16067 env->active_tc.CP0_TCStatus = (1 << CP0TCSt_A);
16068 env->tcs[0].CP0_TCStatus = (1 << CP0TCSt_A);
16071 #endif
16072 compute_hflags(env);
16073 cs->exception_index = EXCP_NONE;
16076 void restore_state_to_opc(CPUMIPSState *env, TranslationBlock *tb, int pc_pos)
16078 env->active_tc.PC = tcg_ctx.gen_opc_pc[pc_pos];
16079 env->hflags &= ~MIPS_HFLAG_BMASK;
16080 env->hflags |= gen_opc_hflags[pc_pos];
16081 switch (env->hflags & MIPS_HFLAG_BMASK_BASE) {
16082 case MIPS_HFLAG_BR:
16083 break;
16084 case MIPS_HFLAG_BC:
16085 case MIPS_HFLAG_BL:
16086 case MIPS_HFLAG_B:
16087 env->btarget = gen_opc_btarget[pc_pos];
16088 break;