configure: add CONFIG_IASL to config-host.h
[qemu.git] / target-mips / translate.c
blobef0a2c36b067bf83578fd19a2a028bea6fcb1872
1 /*
2 * MIPS32 emulation for qemu: main translation routines.
4 * Copyright (c) 2004-2005 Jocelyn Mayer
5 * Copyright (c) 2006 Marius Groeger (FPU operations)
6 * Copyright (c) 2006 Thiemo Seufer (MIPS32R2 support)
7 * Copyright (c) 2009 CodeSourcery (MIPS16 and microMIPS support)
8 * Copyright (c) 2012 Jia Liu & Dongxue Zhang (MIPS ASE DSP support)
10 * This library is free software; you can redistribute it and/or
11 * modify it under the terms of the GNU Lesser General Public
12 * License as published by the Free Software Foundation; either
13 * version 2 of the License, or (at your option) any later version.
15 * This library is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
18 * Lesser General Public License for more details.
20 * You should have received a copy of the GNU Lesser General Public
21 * License along with this library; if not, see <http://www.gnu.org/licenses/>.
24 #include "cpu.h"
25 #include "disas/disas.h"
26 #include "tcg-op.h"
28 #include "helper.h"
29 #define GEN_HELPER 1
30 #include "helper.h"
32 #define MIPS_DEBUG_DISAS 0
33 //#define MIPS_DEBUG_SIGN_EXTENSIONS
35 /* MIPS major opcodes */
36 #define MASK_OP_MAJOR(op) (op & (0x3F << 26))
38 enum {
39 /* indirect opcode tables */
40 OPC_SPECIAL = (0x00 << 26),
41 OPC_REGIMM = (0x01 << 26),
42 OPC_CP0 = (0x10 << 26),
43 OPC_CP1 = (0x11 << 26),
44 OPC_CP2 = (0x12 << 26),
45 OPC_CP3 = (0x13 << 26),
46 OPC_SPECIAL2 = (0x1C << 26),
47 OPC_SPECIAL3 = (0x1F << 26),
48 /* arithmetic with immediate */
49 OPC_ADDI = (0x08 << 26),
50 OPC_ADDIU = (0x09 << 26),
51 OPC_SLTI = (0x0A << 26),
52 OPC_SLTIU = (0x0B << 26),
53 /* logic with immediate */
54 OPC_ANDI = (0x0C << 26),
55 OPC_ORI = (0x0D << 26),
56 OPC_XORI = (0x0E << 26),
57 OPC_LUI = (0x0F << 26),
58 /* arithmetic with immediate */
59 OPC_DADDI = (0x18 << 26),
60 OPC_DADDIU = (0x19 << 26),
61 /* Jump and branches */
62 OPC_J = (0x02 << 26),
63 OPC_JAL = (0x03 << 26),
64 OPC_JALS = OPC_JAL | 0x5,
65 OPC_BEQ = (0x04 << 26), /* Unconditional if rs = rt = 0 (B) */
66 OPC_BEQL = (0x14 << 26),
67 OPC_BNE = (0x05 << 26),
68 OPC_BNEL = (0x15 << 26),
69 OPC_BLEZ = (0x06 << 26),
70 OPC_BLEZL = (0x16 << 26),
71 OPC_BGTZ = (0x07 << 26),
72 OPC_BGTZL = (0x17 << 26),
73 OPC_JALX = (0x1D << 26), /* MIPS 16 only */
74 OPC_JALXS = OPC_JALX | 0x5,
75 /* Load and stores */
76 OPC_LDL = (0x1A << 26),
77 OPC_LDR = (0x1B << 26),
78 OPC_LB = (0x20 << 26),
79 OPC_LH = (0x21 << 26),
80 OPC_LWL = (0x22 << 26),
81 OPC_LW = (0x23 << 26),
82 OPC_LWPC = OPC_LW | 0x5,
83 OPC_LBU = (0x24 << 26),
84 OPC_LHU = (0x25 << 26),
85 OPC_LWR = (0x26 << 26),
86 OPC_LWU = (0x27 << 26),
87 OPC_SB = (0x28 << 26),
88 OPC_SH = (0x29 << 26),
89 OPC_SWL = (0x2A << 26),
90 OPC_SW = (0x2B << 26),
91 OPC_SDL = (0x2C << 26),
92 OPC_SDR = (0x2D << 26),
93 OPC_SWR = (0x2E << 26),
94 OPC_LL = (0x30 << 26),
95 OPC_LLD = (0x34 << 26),
96 OPC_LD = (0x37 << 26),
97 OPC_LDPC = OPC_LD | 0x5,
98 OPC_SC = (0x38 << 26),
99 OPC_SCD = (0x3C << 26),
100 OPC_SD = (0x3F << 26),
101 /* Floating point load/store */
102 OPC_LWC1 = (0x31 << 26),
103 OPC_LWC2 = (0x32 << 26),
104 OPC_LDC1 = (0x35 << 26),
105 OPC_LDC2 = (0x36 << 26),
106 OPC_SWC1 = (0x39 << 26),
107 OPC_SWC2 = (0x3A << 26),
108 OPC_SDC1 = (0x3D << 26),
109 OPC_SDC2 = (0x3E << 26),
110 /* MDMX ASE specific */
111 OPC_MDMX = (0x1E << 26),
112 /* Cache and prefetch */
113 OPC_CACHE = (0x2F << 26),
114 OPC_PREF = (0x33 << 26),
115 /* Reserved major opcode */
116 OPC_MAJOR3B_RESERVED = (0x3B << 26),
119 /* MIPS special opcodes */
120 #define MASK_SPECIAL(op) MASK_OP_MAJOR(op) | (op & 0x3F)
122 enum {
123 /* Shifts */
124 OPC_SLL = 0x00 | OPC_SPECIAL,
125 /* NOP is SLL r0, r0, 0 */
126 /* SSNOP is SLL r0, r0, 1 */
127 /* EHB is SLL r0, r0, 3 */
128 OPC_SRL = 0x02 | OPC_SPECIAL, /* also ROTR */
129 OPC_ROTR = OPC_SRL | (1 << 21),
130 OPC_SRA = 0x03 | OPC_SPECIAL,
131 OPC_SLLV = 0x04 | OPC_SPECIAL,
132 OPC_SRLV = 0x06 | OPC_SPECIAL, /* also ROTRV */
133 OPC_ROTRV = OPC_SRLV | (1 << 6),
134 OPC_SRAV = 0x07 | OPC_SPECIAL,
135 OPC_DSLLV = 0x14 | OPC_SPECIAL,
136 OPC_DSRLV = 0x16 | OPC_SPECIAL, /* also DROTRV */
137 OPC_DROTRV = OPC_DSRLV | (1 << 6),
138 OPC_DSRAV = 0x17 | OPC_SPECIAL,
139 OPC_DSLL = 0x38 | OPC_SPECIAL,
140 OPC_DSRL = 0x3A | OPC_SPECIAL, /* also DROTR */
141 OPC_DROTR = OPC_DSRL | (1 << 21),
142 OPC_DSRA = 0x3B | OPC_SPECIAL,
143 OPC_DSLL32 = 0x3C | OPC_SPECIAL,
144 OPC_DSRL32 = 0x3E | OPC_SPECIAL, /* also DROTR32 */
145 OPC_DROTR32 = OPC_DSRL32 | (1 << 21),
146 OPC_DSRA32 = 0x3F | OPC_SPECIAL,
147 /* Multiplication / division */
148 OPC_MULT = 0x18 | OPC_SPECIAL,
149 OPC_MULTU = 0x19 | OPC_SPECIAL,
150 OPC_DIV = 0x1A | OPC_SPECIAL,
151 OPC_DIVU = 0x1B | OPC_SPECIAL,
152 OPC_DMULT = 0x1C | OPC_SPECIAL,
153 OPC_DMULTU = 0x1D | OPC_SPECIAL,
154 OPC_DDIV = 0x1E | OPC_SPECIAL,
155 OPC_DDIVU = 0x1F | OPC_SPECIAL,
156 /* 2 registers arithmetic / logic */
157 OPC_ADD = 0x20 | OPC_SPECIAL,
158 OPC_ADDU = 0x21 | OPC_SPECIAL,
159 OPC_SUB = 0x22 | OPC_SPECIAL,
160 OPC_SUBU = 0x23 | OPC_SPECIAL,
161 OPC_AND = 0x24 | OPC_SPECIAL,
162 OPC_OR = 0x25 | OPC_SPECIAL,
163 OPC_XOR = 0x26 | OPC_SPECIAL,
164 OPC_NOR = 0x27 | OPC_SPECIAL,
165 OPC_SLT = 0x2A | OPC_SPECIAL,
166 OPC_SLTU = 0x2B | OPC_SPECIAL,
167 OPC_DADD = 0x2C | OPC_SPECIAL,
168 OPC_DADDU = 0x2D | OPC_SPECIAL,
169 OPC_DSUB = 0x2E | OPC_SPECIAL,
170 OPC_DSUBU = 0x2F | OPC_SPECIAL,
171 /* Jumps */
172 OPC_JR = 0x08 | OPC_SPECIAL, /* Also JR.HB */
173 OPC_JALR = 0x09 | OPC_SPECIAL, /* Also JALR.HB */
174 OPC_JALRC = OPC_JALR | (0x5 << 6),
175 OPC_JALRS = 0x10 | OPC_SPECIAL | (0x5 << 6),
176 /* Traps */
177 OPC_TGE = 0x30 | OPC_SPECIAL,
178 OPC_TGEU = 0x31 | OPC_SPECIAL,
179 OPC_TLT = 0x32 | OPC_SPECIAL,
180 OPC_TLTU = 0x33 | OPC_SPECIAL,
181 OPC_TEQ = 0x34 | OPC_SPECIAL,
182 OPC_TNE = 0x36 | OPC_SPECIAL,
183 /* HI / LO registers load & stores */
184 OPC_MFHI = 0x10 | OPC_SPECIAL,
185 OPC_MTHI = 0x11 | OPC_SPECIAL,
186 OPC_MFLO = 0x12 | OPC_SPECIAL,
187 OPC_MTLO = 0x13 | OPC_SPECIAL,
188 /* Conditional moves */
189 OPC_MOVZ = 0x0A | OPC_SPECIAL,
190 OPC_MOVN = 0x0B | OPC_SPECIAL,
192 OPC_MOVCI = 0x01 | OPC_SPECIAL,
194 /* Special */
195 OPC_PMON = 0x05 | OPC_SPECIAL, /* unofficial */
196 OPC_SYSCALL = 0x0C | OPC_SPECIAL,
197 OPC_BREAK = 0x0D | OPC_SPECIAL,
198 OPC_SPIM = 0x0E | OPC_SPECIAL, /* unofficial */
199 OPC_SYNC = 0x0F | OPC_SPECIAL,
201 OPC_SPECIAL15_RESERVED = 0x15 | OPC_SPECIAL,
202 OPC_SPECIAL28_RESERVED = 0x28 | OPC_SPECIAL,
203 OPC_SPECIAL29_RESERVED = 0x29 | OPC_SPECIAL,
204 OPC_SPECIAL35_RESERVED = 0x35 | OPC_SPECIAL,
205 OPC_SPECIAL37_RESERVED = 0x37 | OPC_SPECIAL,
206 OPC_SPECIAL39_RESERVED = 0x39 | OPC_SPECIAL,
207 OPC_SPECIAL3D_RESERVED = 0x3D | OPC_SPECIAL,
210 /* Multiplication variants of the vr54xx. */
211 #define MASK_MUL_VR54XX(op) MASK_SPECIAL(op) | (op & (0x1F << 6))
213 enum {
214 OPC_VR54XX_MULS = (0x03 << 6) | OPC_MULT,
215 OPC_VR54XX_MULSU = (0x03 << 6) | OPC_MULTU,
216 OPC_VR54XX_MACC = (0x05 << 6) | OPC_MULT,
217 OPC_VR54XX_MACCU = (0x05 << 6) | OPC_MULTU,
218 OPC_VR54XX_MSAC = (0x07 << 6) | OPC_MULT,
219 OPC_VR54XX_MSACU = (0x07 << 6) | OPC_MULTU,
220 OPC_VR54XX_MULHI = (0x09 << 6) | OPC_MULT,
221 OPC_VR54XX_MULHIU = (0x09 << 6) | OPC_MULTU,
222 OPC_VR54XX_MULSHI = (0x0B << 6) | OPC_MULT,
223 OPC_VR54XX_MULSHIU = (0x0B << 6) | OPC_MULTU,
224 OPC_VR54XX_MACCHI = (0x0D << 6) | OPC_MULT,
225 OPC_VR54XX_MACCHIU = (0x0D << 6) | OPC_MULTU,
226 OPC_VR54XX_MSACHI = (0x0F << 6) | OPC_MULT,
227 OPC_VR54XX_MSACHIU = (0x0F << 6) | OPC_MULTU,
230 /* REGIMM (rt field) opcodes */
231 #define MASK_REGIMM(op) MASK_OP_MAJOR(op) | (op & (0x1F << 16))
233 enum {
234 OPC_BLTZ = (0x00 << 16) | OPC_REGIMM,
235 OPC_BLTZL = (0x02 << 16) | OPC_REGIMM,
236 OPC_BGEZ = (0x01 << 16) | OPC_REGIMM,
237 OPC_BGEZL = (0x03 << 16) | OPC_REGIMM,
238 OPC_BLTZAL = (0x10 << 16) | OPC_REGIMM,
239 OPC_BLTZALS = OPC_BLTZAL | 0x5, /* microMIPS */
240 OPC_BLTZALL = (0x12 << 16) | OPC_REGIMM,
241 OPC_BGEZAL = (0x11 << 16) | OPC_REGIMM,
242 OPC_BGEZALS = OPC_BGEZAL | 0x5, /* microMIPS */
243 OPC_BGEZALL = (0x13 << 16) | OPC_REGIMM,
244 OPC_TGEI = (0x08 << 16) | OPC_REGIMM,
245 OPC_TGEIU = (0x09 << 16) | OPC_REGIMM,
246 OPC_TLTI = (0x0A << 16) | OPC_REGIMM,
247 OPC_TLTIU = (0x0B << 16) | OPC_REGIMM,
248 OPC_TEQI = (0x0C << 16) | OPC_REGIMM,
249 OPC_TNEI = (0x0E << 16) | OPC_REGIMM,
250 OPC_SYNCI = (0x1F << 16) | OPC_REGIMM,
253 /* Special2 opcodes */
254 #define MASK_SPECIAL2(op) MASK_OP_MAJOR(op) | (op & 0x3F)
256 enum {
257 /* Multiply & xxx operations */
258 OPC_MADD = 0x00 | OPC_SPECIAL2,
259 OPC_MADDU = 0x01 | OPC_SPECIAL2,
260 OPC_MUL = 0x02 | OPC_SPECIAL2,
261 OPC_MSUB = 0x04 | OPC_SPECIAL2,
262 OPC_MSUBU = 0x05 | OPC_SPECIAL2,
263 /* Loongson 2F */
264 OPC_MULT_G_2F = 0x10 | OPC_SPECIAL2,
265 OPC_DMULT_G_2F = 0x11 | OPC_SPECIAL2,
266 OPC_MULTU_G_2F = 0x12 | OPC_SPECIAL2,
267 OPC_DMULTU_G_2F = 0x13 | OPC_SPECIAL2,
268 OPC_DIV_G_2F = 0x14 | OPC_SPECIAL2,
269 OPC_DDIV_G_2F = 0x15 | OPC_SPECIAL2,
270 OPC_DIVU_G_2F = 0x16 | OPC_SPECIAL2,
271 OPC_DDIVU_G_2F = 0x17 | OPC_SPECIAL2,
272 OPC_MOD_G_2F = 0x1c | OPC_SPECIAL2,
273 OPC_DMOD_G_2F = 0x1d | OPC_SPECIAL2,
274 OPC_MODU_G_2F = 0x1e | OPC_SPECIAL2,
275 OPC_DMODU_G_2F = 0x1f | OPC_SPECIAL2,
276 /* Misc */
277 OPC_CLZ = 0x20 | OPC_SPECIAL2,
278 OPC_CLO = 0x21 | OPC_SPECIAL2,
279 OPC_DCLZ = 0x24 | OPC_SPECIAL2,
280 OPC_DCLO = 0x25 | OPC_SPECIAL2,
281 /* Special */
282 OPC_SDBBP = 0x3F | OPC_SPECIAL2,
285 /* Special3 opcodes */
286 #define MASK_SPECIAL3(op) MASK_OP_MAJOR(op) | (op & 0x3F)
288 enum {
289 OPC_EXT = 0x00 | OPC_SPECIAL3,
290 OPC_DEXTM = 0x01 | OPC_SPECIAL3,
291 OPC_DEXTU = 0x02 | OPC_SPECIAL3,
292 OPC_DEXT = 0x03 | OPC_SPECIAL3,
293 OPC_INS = 0x04 | OPC_SPECIAL3,
294 OPC_DINSM = 0x05 | OPC_SPECIAL3,
295 OPC_DINSU = 0x06 | OPC_SPECIAL3,
296 OPC_DINS = 0x07 | OPC_SPECIAL3,
297 OPC_FORK = 0x08 | OPC_SPECIAL3,
298 OPC_YIELD = 0x09 | OPC_SPECIAL3,
299 OPC_BSHFL = 0x20 | OPC_SPECIAL3,
300 OPC_DBSHFL = 0x24 | OPC_SPECIAL3,
301 OPC_RDHWR = 0x3B | OPC_SPECIAL3,
303 /* Loongson 2E */
304 OPC_MULT_G_2E = 0x18 | OPC_SPECIAL3,
305 OPC_MULTU_G_2E = 0x19 | OPC_SPECIAL3,
306 OPC_DIV_G_2E = 0x1A | OPC_SPECIAL3,
307 OPC_DIVU_G_2E = 0x1B | OPC_SPECIAL3,
308 OPC_DMULT_G_2E = 0x1C | OPC_SPECIAL3,
309 OPC_DMULTU_G_2E = 0x1D | OPC_SPECIAL3,
310 OPC_DDIV_G_2E = 0x1E | OPC_SPECIAL3,
311 OPC_DDIVU_G_2E = 0x1F | OPC_SPECIAL3,
312 OPC_MOD_G_2E = 0x22 | OPC_SPECIAL3,
313 OPC_MODU_G_2E = 0x23 | OPC_SPECIAL3,
314 OPC_DMOD_G_2E = 0x26 | OPC_SPECIAL3,
315 OPC_DMODU_G_2E = 0x27 | OPC_SPECIAL3,
317 /* MIPS DSP Load */
318 OPC_LX_DSP = 0x0A | OPC_SPECIAL3,
319 /* MIPS DSP Arithmetic */
320 OPC_ADDU_QB_DSP = 0x10 | OPC_SPECIAL3,
321 OPC_ADDU_OB_DSP = 0x14 | OPC_SPECIAL3,
322 OPC_ABSQ_S_PH_DSP = 0x12 | OPC_SPECIAL3,
323 OPC_ABSQ_S_QH_DSP = 0x16 | OPC_SPECIAL3,
324 /* OPC_ADDUH_QB_DSP is same as OPC_MULT_G_2E. */
325 /* OPC_ADDUH_QB_DSP = 0x18 | OPC_SPECIAL3, */
326 OPC_CMPU_EQ_QB_DSP = 0x11 | OPC_SPECIAL3,
327 OPC_CMPU_EQ_OB_DSP = 0x15 | OPC_SPECIAL3,
328 /* MIPS DSP GPR-Based Shift Sub-class */
329 OPC_SHLL_QB_DSP = 0x13 | OPC_SPECIAL3,
330 OPC_SHLL_OB_DSP = 0x17 | OPC_SPECIAL3,
331 /* MIPS DSP Multiply Sub-class insns */
332 /* OPC_MUL_PH_DSP is same as OPC_ADDUH_QB_DSP. */
333 /* OPC_MUL_PH_DSP = 0x18 | OPC_SPECIAL3, */
334 OPC_DPA_W_PH_DSP = 0x30 | OPC_SPECIAL3,
335 OPC_DPAQ_W_QH_DSP = 0x34 | OPC_SPECIAL3,
336 /* DSP Bit/Manipulation Sub-class */
337 OPC_INSV_DSP = 0x0C | OPC_SPECIAL3,
338 OPC_DINSV_DSP = 0x0D | OPC_SPECIAL3,
339 /* MIPS DSP Append Sub-class */
340 OPC_APPEND_DSP = 0x31 | OPC_SPECIAL3,
341 OPC_DAPPEND_DSP = 0x35 | OPC_SPECIAL3,
342 /* MIPS DSP Accumulator and DSPControl Access Sub-class */
343 OPC_EXTR_W_DSP = 0x38 | OPC_SPECIAL3,
344 OPC_DEXTR_W_DSP = 0x3C | OPC_SPECIAL3,
347 /* BSHFL opcodes */
348 #define MASK_BSHFL(op) MASK_SPECIAL3(op) | (op & (0x1F << 6))
350 enum {
351 OPC_WSBH = (0x02 << 6) | OPC_BSHFL,
352 OPC_SEB = (0x10 << 6) | OPC_BSHFL,
353 OPC_SEH = (0x18 << 6) | OPC_BSHFL,
356 /* DBSHFL opcodes */
357 #define MASK_DBSHFL(op) MASK_SPECIAL3(op) | (op & (0x1F << 6))
359 enum {
360 OPC_DSBH = (0x02 << 6) | OPC_DBSHFL,
361 OPC_DSHD = (0x05 << 6) | OPC_DBSHFL,
364 /* MIPS DSP REGIMM opcodes */
365 enum {
366 OPC_BPOSGE32 = (0x1C << 16) | OPC_REGIMM,
367 OPC_BPOSGE64 = (0x1D << 16) | OPC_REGIMM,
370 #define MASK_LX(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
371 /* MIPS DSP Load */
372 enum {
373 OPC_LBUX = (0x06 << 6) | OPC_LX_DSP,
374 OPC_LHX = (0x04 << 6) | OPC_LX_DSP,
375 OPC_LWX = (0x00 << 6) | OPC_LX_DSP,
376 OPC_LDX = (0x08 << 6) | OPC_LX_DSP,
379 #define MASK_ADDU_QB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
380 enum {
381 /* MIPS DSP Arithmetic Sub-class */
382 OPC_ADDQ_PH = (0x0A << 6) | OPC_ADDU_QB_DSP,
383 OPC_ADDQ_S_PH = (0x0E << 6) | OPC_ADDU_QB_DSP,
384 OPC_ADDQ_S_W = (0x16 << 6) | OPC_ADDU_QB_DSP,
385 OPC_ADDU_QB = (0x00 << 6) | OPC_ADDU_QB_DSP,
386 OPC_ADDU_S_QB = (0x04 << 6) | OPC_ADDU_QB_DSP,
387 OPC_ADDU_PH = (0x08 << 6) | OPC_ADDU_QB_DSP,
388 OPC_ADDU_S_PH = (0x0C << 6) | OPC_ADDU_QB_DSP,
389 OPC_SUBQ_PH = (0x0B << 6) | OPC_ADDU_QB_DSP,
390 OPC_SUBQ_S_PH = (0x0F << 6) | OPC_ADDU_QB_DSP,
391 OPC_SUBQ_S_W = (0x17 << 6) | OPC_ADDU_QB_DSP,
392 OPC_SUBU_QB = (0x01 << 6) | OPC_ADDU_QB_DSP,
393 OPC_SUBU_S_QB = (0x05 << 6) | OPC_ADDU_QB_DSP,
394 OPC_SUBU_PH = (0x09 << 6) | OPC_ADDU_QB_DSP,
395 OPC_SUBU_S_PH = (0x0D << 6) | OPC_ADDU_QB_DSP,
396 OPC_ADDSC = (0x10 << 6) | OPC_ADDU_QB_DSP,
397 OPC_ADDWC = (0x11 << 6) | OPC_ADDU_QB_DSP,
398 OPC_MODSUB = (0x12 << 6) | OPC_ADDU_QB_DSP,
399 OPC_RADDU_W_QB = (0x14 << 6) | OPC_ADDU_QB_DSP,
400 /* MIPS DSP Multiply Sub-class insns */
401 OPC_MULEU_S_PH_QBL = (0x06 << 6) | OPC_ADDU_QB_DSP,
402 OPC_MULEU_S_PH_QBR = (0x07 << 6) | OPC_ADDU_QB_DSP,
403 OPC_MULQ_RS_PH = (0x1F << 6) | OPC_ADDU_QB_DSP,
404 OPC_MULEQ_S_W_PHL = (0x1C << 6) | OPC_ADDU_QB_DSP,
405 OPC_MULEQ_S_W_PHR = (0x1D << 6) | OPC_ADDU_QB_DSP,
406 OPC_MULQ_S_PH = (0x1E << 6) | OPC_ADDU_QB_DSP,
409 #define OPC_ADDUH_QB_DSP OPC_MULT_G_2E
410 #define MASK_ADDUH_QB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
411 enum {
412 /* MIPS DSP Arithmetic Sub-class */
413 OPC_ADDUH_QB = (0x00 << 6) | OPC_ADDUH_QB_DSP,
414 OPC_ADDUH_R_QB = (0x02 << 6) | OPC_ADDUH_QB_DSP,
415 OPC_ADDQH_PH = (0x08 << 6) | OPC_ADDUH_QB_DSP,
416 OPC_ADDQH_R_PH = (0x0A << 6) | OPC_ADDUH_QB_DSP,
417 OPC_ADDQH_W = (0x10 << 6) | OPC_ADDUH_QB_DSP,
418 OPC_ADDQH_R_W = (0x12 << 6) | OPC_ADDUH_QB_DSP,
419 OPC_SUBUH_QB = (0x01 << 6) | OPC_ADDUH_QB_DSP,
420 OPC_SUBUH_R_QB = (0x03 << 6) | OPC_ADDUH_QB_DSP,
421 OPC_SUBQH_PH = (0x09 << 6) | OPC_ADDUH_QB_DSP,
422 OPC_SUBQH_R_PH = (0x0B << 6) | OPC_ADDUH_QB_DSP,
423 OPC_SUBQH_W = (0x11 << 6) | OPC_ADDUH_QB_DSP,
424 OPC_SUBQH_R_W = (0x13 << 6) | OPC_ADDUH_QB_DSP,
425 /* MIPS DSP Multiply Sub-class insns */
426 OPC_MUL_PH = (0x0C << 6) | OPC_ADDUH_QB_DSP,
427 OPC_MUL_S_PH = (0x0E << 6) | OPC_ADDUH_QB_DSP,
428 OPC_MULQ_S_W = (0x16 << 6) | OPC_ADDUH_QB_DSP,
429 OPC_MULQ_RS_W = (0x17 << 6) | OPC_ADDUH_QB_DSP,
432 #define MASK_ABSQ_S_PH(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
433 enum {
434 /* MIPS DSP Arithmetic Sub-class */
435 OPC_ABSQ_S_QB = (0x01 << 6) | OPC_ABSQ_S_PH_DSP,
436 OPC_ABSQ_S_PH = (0x09 << 6) | OPC_ABSQ_S_PH_DSP,
437 OPC_ABSQ_S_W = (0x11 << 6) | OPC_ABSQ_S_PH_DSP,
438 OPC_PRECEQ_W_PHL = (0x0C << 6) | OPC_ABSQ_S_PH_DSP,
439 OPC_PRECEQ_W_PHR = (0x0D << 6) | OPC_ABSQ_S_PH_DSP,
440 OPC_PRECEQU_PH_QBL = (0x04 << 6) | OPC_ABSQ_S_PH_DSP,
441 OPC_PRECEQU_PH_QBR = (0x05 << 6) | OPC_ABSQ_S_PH_DSP,
442 OPC_PRECEQU_PH_QBLA = (0x06 << 6) | OPC_ABSQ_S_PH_DSP,
443 OPC_PRECEQU_PH_QBRA = (0x07 << 6) | OPC_ABSQ_S_PH_DSP,
444 OPC_PRECEU_PH_QBL = (0x1C << 6) | OPC_ABSQ_S_PH_DSP,
445 OPC_PRECEU_PH_QBR = (0x1D << 6) | OPC_ABSQ_S_PH_DSP,
446 OPC_PRECEU_PH_QBLA = (0x1E << 6) | OPC_ABSQ_S_PH_DSP,
447 OPC_PRECEU_PH_QBRA = (0x1F << 6) | OPC_ABSQ_S_PH_DSP,
448 /* DSP Bit/Manipulation Sub-class */
449 OPC_BITREV = (0x1B << 6) | OPC_ABSQ_S_PH_DSP,
450 OPC_REPL_QB = (0x02 << 6) | OPC_ABSQ_S_PH_DSP,
451 OPC_REPLV_QB = (0x03 << 6) | OPC_ABSQ_S_PH_DSP,
452 OPC_REPL_PH = (0x0A << 6) | OPC_ABSQ_S_PH_DSP,
453 OPC_REPLV_PH = (0x0B << 6) | OPC_ABSQ_S_PH_DSP,
456 #define MASK_CMPU_EQ_QB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
457 enum {
458 /* MIPS DSP Arithmetic Sub-class */
459 OPC_PRECR_QB_PH = (0x0D << 6) | OPC_CMPU_EQ_QB_DSP,
460 OPC_PRECRQ_QB_PH = (0x0C << 6) | OPC_CMPU_EQ_QB_DSP,
461 OPC_PRECR_SRA_PH_W = (0x1E << 6) | OPC_CMPU_EQ_QB_DSP,
462 OPC_PRECR_SRA_R_PH_W = (0x1F << 6) | OPC_CMPU_EQ_QB_DSP,
463 OPC_PRECRQ_PH_W = (0x14 << 6) | OPC_CMPU_EQ_QB_DSP,
464 OPC_PRECRQ_RS_PH_W = (0x15 << 6) | OPC_CMPU_EQ_QB_DSP,
465 OPC_PRECRQU_S_QB_PH = (0x0F << 6) | OPC_CMPU_EQ_QB_DSP,
466 /* DSP Compare-Pick Sub-class */
467 OPC_CMPU_EQ_QB = (0x00 << 6) | OPC_CMPU_EQ_QB_DSP,
468 OPC_CMPU_LT_QB = (0x01 << 6) | OPC_CMPU_EQ_QB_DSP,
469 OPC_CMPU_LE_QB = (0x02 << 6) | OPC_CMPU_EQ_QB_DSP,
470 OPC_CMPGU_EQ_QB = (0x04 << 6) | OPC_CMPU_EQ_QB_DSP,
471 OPC_CMPGU_LT_QB = (0x05 << 6) | OPC_CMPU_EQ_QB_DSP,
472 OPC_CMPGU_LE_QB = (0x06 << 6) | OPC_CMPU_EQ_QB_DSP,
473 OPC_CMPGDU_EQ_QB = (0x18 << 6) | OPC_CMPU_EQ_QB_DSP,
474 OPC_CMPGDU_LT_QB = (0x19 << 6) | OPC_CMPU_EQ_QB_DSP,
475 OPC_CMPGDU_LE_QB = (0x1A << 6) | OPC_CMPU_EQ_QB_DSP,
476 OPC_CMP_EQ_PH = (0x08 << 6) | OPC_CMPU_EQ_QB_DSP,
477 OPC_CMP_LT_PH = (0x09 << 6) | OPC_CMPU_EQ_QB_DSP,
478 OPC_CMP_LE_PH = (0x0A << 6) | OPC_CMPU_EQ_QB_DSP,
479 OPC_PICK_QB = (0x03 << 6) | OPC_CMPU_EQ_QB_DSP,
480 OPC_PICK_PH = (0x0B << 6) | OPC_CMPU_EQ_QB_DSP,
481 OPC_PACKRL_PH = (0x0E << 6) | OPC_CMPU_EQ_QB_DSP,
484 #define MASK_SHLL_QB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
485 enum {
486 /* MIPS DSP GPR-Based Shift Sub-class */
487 OPC_SHLL_QB = (0x00 << 6) | OPC_SHLL_QB_DSP,
488 OPC_SHLLV_QB = (0x02 << 6) | OPC_SHLL_QB_DSP,
489 OPC_SHLL_PH = (0x08 << 6) | OPC_SHLL_QB_DSP,
490 OPC_SHLLV_PH = (0x0A << 6) | OPC_SHLL_QB_DSP,
491 OPC_SHLL_S_PH = (0x0C << 6) | OPC_SHLL_QB_DSP,
492 OPC_SHLLV_S_PH = (0x0E << 6) | OPC_SHLL_QB_DSP,
493 OPC_SHLL_S_W = (0x14 << 6) | OPC_SHLL_QB_DSP,
494 OPC_SHLLV_S_W = (0x16 << 6) | OPC_SHLL_QB_DSP,
495 OPC_SHRL_QB = (0x01 << 6) | OPC_SHLL_QB_DSP,
496 OPC_SHRLV_QB = (0x03 << 6) | OPC_SHLL_QB_DSP,
497 OPC_SHRL_PH = (0x19 << 6) | OPC_SHLL_QB_DSP,
498 OPC_SHRLV_PH = (0x1B << 6) | OPC_SHLL_QB_DSP,
499 OPC_SHRA_QB = (0x04 << 6) | OPC_SHLL_QB_DSP,
500 OPC_SHRA_R_QB = (0x05 << 6) | OPC_SHLL_QB_DSP,
501 OPC_SHRAV_QB = (0x06 << 6) | OPC_SHLL_QB_DSP,
502 OPC_SHRAV_R_QB = (0x07 << 6) | OPC_SHLL_QB_DSP,
503 OPC_SHRA_PH = (0x09 << 6) | OPC_SHLL_QB_DSP,
504 OPC_SHRAV_PH = (0x0B << 6) | OPC_SHLL_QB_DSP,
505 OPC_SHRA_R_PH = (0x0D << 6) | OPC_SHLL_QB_DSP,
506 OPC_SHRAV_R_PH = (0x0F << 6) | OPC_SHLL_QB_DSP,
507 OPC_SHRA_R_W = (0x15 << 6) | OPC_SHLL_QB_DSP,
508 OPC_SHRAV_R_W = (0x17 << 6) | OPC_SHLL_QB_DSP,
511 #define MASK_DPA_W_PH(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
512 enum {
513 /* MIPS DSP Multiply Sub-class insns */
514 OPC_DPAU_H_QBL = (0x03 << 6) | OPC_DPA_W_PH_DSP,
515 OPC_DPAU_H_QBR = (0x07 << 6) | OPC_DPA_W_PH_DSP,
516 OPC_DPSU_H_QBL = (0x0B << 6) | OPC_DPA_W_PH_DSP,
517 OPC_DPSU_H_QBR = (0x0F << 6) | OPC_DPA_W_PH_DSP,
518 OPC_DPA_W_PH = (0x00 << 6) | OPC_DPA_W_PH_DSP,
519 OPC_DPAX_W_PH = (0x08 << 6) | OPC_DPA_W_PH_DSP,
520 OPC_DPAQ_S_W_PH = (0x04 << 6) | OPC_DPA_W_PH_DSP,
521 OPC_DPAQX_S_W_PH = (0x18 << 6) | OPC_DPA_W_PH_DSP,
522 OPC_DPAQX_SA_W_PH = (0x1A << 6) | OPC_DPA_W_PH_DSP,
523 OPC_DPS_W_PH = (0x01 << 6) | OPC_DPA_W_PH_DSP,
524 OPC_DPSX_W_PH = (0x09 << 6) | OPC_DPA_W_PH_DSP,
525 OPC_DPSQ_S_W_PH = (0x05 << 6) | OPC_DPA_W_PH_DSP,
526 OPC_DPSQX_S_W_PH = (0x19 << 6) | OPC_DPA_W_PH_DSP,
527 OPC_DPSQX_SA_W_PH = (0x1B << 6) | OPC_DPA_W_PH_DSP,
528 OPC_MULSAQ_S_W_PH = (0x06 << 6) | OPC_DPA_W_PH_DSP,
529 OPC_DPAQ_SA_L_W = (0x0C << 6) | OPC_DPA_W_PH_DSP,
530 OPC_DPSQ_SA_L_W = (0x0D << 6) | OPC_DPA_W_PH_DSP,
531 OPC_MAQ_S_W_PHL = (0x14 << 6) | OPC_DPA_W_PH_DSP,
532 OPC_MAQ_S_W_PHR = (0x16 << 6) | OPC_DPA_W_PH_DSP,
533 OPC_MAQ_SA_W_PHL = (0x10 << 6) | OPC_DPA_W_PH_DSP,
534 OPC_MAQ_SA_W_PHR = (0x12 << 6) | OPC_DPA_W_PH_DSP,
535 OPC_MULSA_W_PH = (0x02 << 6) | OPC_DPA_W_PH_DSP,
538 #define MASK_INSV(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
539 enum {
540 /* DSP Bit/Manipulation Sub-class */
541 OPC_INSV = (0x00 << 6) | OPC_INSV_DSP,
544 #define MASK_APPEND(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
545 enum {
546 /* MIPS DSP Append Sub-class */
547 OPC_APPEND = (0x00 << 6) | OPC_APPEND_DSP,
548 OPC_PREPEND = (0x01 << 6) | OPC_APPEND_DSP,
549 OPC_BALIGN = (0x10 << 6) | OPC_APPEND_DSP,
552 #define MASK_EXTR_W(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
553 enum {
554 /* MIPS DSP Accumulator and DSPControl Access Sub-class */
555 OPC_EXTR_W = (0x00 << 6) | OPC_EXTR_W_DSP,
556 OPC_EXTR_R_W = (0x04 << 6) | OPC_EXTR_W_DSP,
557 OPC_EXTR_RS_W = (0x06 << 6) | OPC_EXTR_W_DSP,
558 OPC_EXTR_S_H = (0x0E << 6) | OPC_EXTR_W_DSP,
559 OPC_EXTRV_S_H = (0x0F << 6) | OPC_EXTR_W_DSP,
560 OPC_EXTRV_W = (0x01 << 6) | OPC_EXTR_W_DSP,
561 OPC_EXTRV_R_W = (0x05 << 6) | OPC_EXTR_W_DSP,
562 OPC_EXTRV_RS_W = (0x07 << 6) | OPC_EXTR_W_DSP,
563 OPC_EXTP = (0x02 << 6) | OPC_EXTR_W_DSP,
564 OPC_EXTPV = (0x03 << 6) | OPC_EXTR_W_DSP,
565 OPC_EXTPDP = (0x0A << 6) | OPC_EXTR_W_DSP,
566 OPC_EXTPDPV = (0x0B << 6) | OPC_EXTR_W_DSP,
567 OPC_SHILO = (0x1A << 6) | OPC_EXTR_W_DSP,
568 OPC_SHILOV = (0x1B << 6) | OPC_EXTR_W_DSP,
569 OPC_MTHLIP = (0x1F << 6) | OPC_EXTR_W_DSP,
570 OPC_WRDSP = (0x13 << 6) | OPC_EXTR_W_DSP,
571 OPC_RDDSP = (0x12 << 6) | OPC_EXTR_W_DSP,
574 #define MASK_ABSQ_S_QH(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
575 enum {
576 /* MIPS DSP Arithmetic Sub-class */
577 OPC_PRECEQ_L_PWL = (0x14 << 6) | OPC_ABSQ_S_QH_DSP,
578 OPC_PRECEQ_L_PWR = (0x15 << 6) | OPC_ABSQ_S_QH_DSP,
579 OPC_PRECEQ_PW_QHL = (0x0C << 6) | OPC_ABSQ_S_QH_DSP,
580 OPC_PRECEQ_PW_QHR = (0x0D << 6) | OPC_ABSQ_S_QH_DSP,
581 OPC_PRECEQ_PW_QHLA = (0x0E << 6) | OPC_ABSQ_S_QH_DSP,
582 OPC_PRECEQ_PW_QHRA = (0x0F << 6) | OPC_ABSQ_S_QH_DSP,
583 OPC_PRECEQU_QH_OBL = (0x04 << 6) | OPC_ABSQ_S_QH_DSP,
584 OPC_PRECEQU_QH_OBR = (0x05 << 6) | OPC_ABSQ_S_QH_DSP,
585 OPC_PRECEQU_QH_OBLA = (0x06 << 6) | OPC_ABSQ_S_QH_DSP,
586 OPC_PRECEQU_QH_OBRA = (0x07 << 6) | OPC_ABSQ_S_QH_DSP,
587 OPC_PRECEU_QH_OBL = (0x1C << 6) | OPC_ABSQ_S_QH_DSP,
588 OPC_PRECEU_QH_OBR = (0x1D << 6) | OPC_ABSQ_S_QH_DSP,
589 OPC_PRECEU_QH_OBLA = (0x1E << 6) | OPC_ABSQ_S_QH_DSP,
590 OPC_PRECEU_QH_OBRA = (0x1F << 6) | OPC_ABSQ_S_QH_DSP,
591 OPC_ABSQ_S_OB = (0x01 << 6) | OPC_ABSQ_S_QH_DSP,
592 OPC_ABSQ_S_PW = (0x11 << 6) | OPC_ABSQ_S_QH_DSP,
593 OPC_ABSQ_S_QH = (0x09 << 6) | OPC_ABSQ_S_QH_DSP,
594 /* DSP Bit/Manipulation Sub-class */
595 OPC_REPL_OB = (0x02 << 6) | OPC_ABSQ_S_QH_DSP,
596 OPC_REPL_PW = (0x12 << 6) | OPC_ABSQ_S_QH_DSP,
597 OPC_REPL_QH = (0x0A << 6) | OPC_ABSQ_S_QH_DSP,
598 OPC_REPLV_OB = (0x03 << 6) | OPC_ABSQ_S_QH_DSP,
599 OPC_REPLV_PW = (0x13 << 6) | OPC_ABSQ_S_QH_DSP,
600 OPC_REPLV_QH = (0x0B << 6) | OPC_ABSQ_S_QH_DSP,
603 #define MASK_ADDU_OB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
604 enum {
605 /* MIPS DSP Multiply Sub-class insns */
606 OPC_MULEQ_S_PW_QHL = (0x1C << 6) | OPC_ADDU_OB_DSP,
607 OPC_MULEQ_S_PW_QHR = (0x1D << 6) | OPC_ADDU_OB_DSP,
608 OPC_MULEU_S_QH_OBL = (0x06 << 6) | OPC_ADDU_OB_DSP,
609 OPC_MULEU_S_QH_OBR = (0x07 << 6) | OPC_ADDU_OB_DSP,
610 OPC_MULQ_RS_QH = (0x1F << 6) | OPC_ADDU_OB_DSP,
611 /* MIPS DSP Arithmetic Sub-class */
612 OPC_RADDU_L_OB = (0x14 << 6) | OPC_ADDU_OB_DSP,
613 OPC_SUBQ_PW = (0x13 << 6) | OPC_ADDU_OB_DSP,
614 OPC_SUBQ_S_PW = (0x17 << 6) | OPC_ADDU_OB_DSP,
615 OPC_SUBQ_QH = (0x0B << 6) | OPC_ADDU_OB_DSP,
616 OPC_SUBQ_S_QH = (0x0F << 6) | OPC_ADDU_OB_DSP,
617 OPC_SUBU_OB = (0x01 << 6) | OPC_ADDU_OB_DSP,
618 OPC_SUBU_S_OB = (0x05 << 6) | OPC_ADDU_OB_DSP,
619 OPC_SUBU_QH = (0x09 << 6) | OPC_ADDU_OB_DSP,
620 OPC_SUBU_S_QH = (0x0D << 6) | OPC_ADDU_OB_DSP,
621 OPC_SUBUH_OB = (0x19 << 6) | OPC_ADDU_OB_DSP,
622 OPC_SUBUH_R_OB = (0x1B << 6) | OPC_ADDU_OB_DSP,
623 OPC_ADDQ_PW = (0x12 << 6) | OPC_ADDU_OB_DSP,
624 OPC_ADDQ_S_PW = (0x16 << 6) | OPC_ADDU_OB_DSP,
625 OPC_ADDQ_QH = (0x0A << 6) | OPC_ADDU_OB_DSP,
626 OPC_ADDQ_S_QH = (0x0E << 6) | OPC_ADDU_OB_DSP,
627 OPC_ADDU_OB = (0x00 << 6) | OPC_ADDU_OB_DSP,
628 OPC_ADDU_S_OB = (0x04 << 6) | OPC_ADDU_OB_DSP,
629 OPC_ADDU_QH = (0x08 << 6) | OPC_ADDU_OB_DSP,
630 OPC_ADDU_S_QH = (0x0C << 6) | OPC_ADDU_OB_DSP,
631 OPC_ADDUH_OB = (0x18 << 6) | OPC_ADDU_OB_DSP,
632 OPC_ADDUH_R_OB = (0x1A << 6) | OPC_ADDU_OB_DSP,
635 #define MASK_CMPU_EQ_OB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
636 enum {
637 /* DSP Compare-Pick Sub-class */
638 OPC_CMP_EQ_PW = (0x10 << 6) | OPC_CMPU_EQ_OB_DSP,
639 OPC_CMP_LT_PW = (0x11 << 6) | OPC_CMPU_EQ_OB_DSP,
640 OPC_CMP_LE_PW = (0x12 << 6) | OPC_CMPU_EQ_OB_DSP,
641 OPC_CMP_EQ_QH = (0x08 << 6) | OPC_CMPU_EQ_OB_DSP,
642 OPC_CMP_LT_QH = (0x09 << 6) | OPC_CMPU_EQ_OB_DSP,
643 OPC_CMP_LE_QH = (0x0A << 6) | OPC_CMPU_EQ_OB_DSP,
644 OPC_CMPGDU_EQ_OB = (0x18 << 6) | OPC_CMPU_EQ_OB_DSP,
645 OPC_CMPGDU_LT_OB = (0x19 << 6) | OPC_CMPU_EQ_OB_DSP,
646 OPC_CMPGDU_LE_OB = (0x1A << 6) | OPC_CMPU_EQ_OB_DSP,
647 OPC_CMPGU_EQ_OB = (0x04 << 6) | OPC_CMPU_EQ_OB_DSP,
648 OPC_CMPGU_LT_OB = (0x05 << 6) | OPC_CMPU_EQ_OB_DSP,
649 OPC_CMPGU_LE_OB = (0x06 << 6) | OPC_CMPU_EQ_OB_DSP,
650 OPC_CMPU_EQ_OB = (0x00 << 6) | OPC_CMPU_EQ_OB_DSP,
651 OPC_CMPU_LT_OB = (0x01 << 6) | OPC_CMPU_EQ_OB_DSP,
652 OPC_CMPU_LE_OB = (0x02 << 6) | OPC_CMPU_EQ_OB_DSP,
653 OPC_PACKRL_PW = (0x0E << 6) | OPC_CMPU_EQ_OB_DSP,
654 OPC_PICK_OB = (0x03 << 6) | OPC_CMPU_EQ_OB_DSP,
655 OPC_PICK_PW = (0x13 << 6) | OPC_CMPU_EQ_OB_DSP,
656 OPC_PICK_QH = (0x0B << 6) | OPC_CMPU_EQ_OB_DSP,
657 /* MIPS DSP Arithmetic Sub-class */
658 OPC_PRECR_OB_QH = (0x0D << 6) | OPC_CMPU_EQ_OB_DSP,
659 OPC_PRECR_SRA_QH_PW = (0x1E << 6) | OPC_CMPU_EQ_OB_DSP,
660 OPC_PRECR_SRA_R_QH_PW = (0x1F << 6) | OPC_CMPU_EQ_OB_DSP,
661 OPC_PRECRQ_OB_QH = (0x0C << 6) | OPC_CMPU_EQ_OB_DSP,
662 OPC_PRECRQ_PW_L = (0x1C << 6) | OPC_CMPU_EQ_OB_DSP,
663 OPC_PRECRQ_QH_PW = (0x14 << 6) | OPC_CMPU_EQ_OB_DSP,
664 OPC_PRECRQ_RS_QH_PW = (0x15 << 6) | OPC_CMPU_EQ_OB_DSP,
665 OPC_PRECRQU_S_OB_QH = (0x0F << 6) | OPC_CMPU_EQ_OB_DSP,
668 #define MASK_DAPPEND(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
669 enum {
670 /* DSP Append Sub-class */
671 OPC_DAPPEND = (0x00 << 6) | OPC_DAPPEND_DSP,
672 OPC_PREPENDD = (0x03 << 6) | OPC_DAPPEND_DSP,
673 OPC_PREPENDW = (0x01 << 6) | OPC_DAPPEND_DSP,
674 OPC_DBALIGN = (0x10 << 6) | OPC_DAPPEND_DSP,
677 #define MASK_DEXTR_W(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
678 enum {
679 /* MIPS DSP Accumulator and DSPControl Access Sub-class */
680 OPC_DMTHLIP = (0x1F << 6) | OPC_DEXTR_W_DSP,
681 OPC_DSHILO = (0x1A << 6) | OPC_DEXTR_W_DSP,
682 OPC_DEXTP = (0x02 << 6) | OPC_DEXTR_W_DSP,
683 OPC_DEXTPDP = (0x0A << 6) | OPC_DEXTR_W_DSP,
684 OPC_DEXTPDPV = (0x0B << 6) | OPC_DEXTR_W_DSP,
685 OPC_DEXTPV = (0x03 << 6) | OPC_DEXTR_W_DSP,
686 OPC_DEXTR_L = (0x10 << 6) | OPC_DEXTR_W_DSP,
687 OPC_DEXTR_R_L = (0x14 << 6) | OPC_DEXTR_W_DSP,
688 OPC_DEXTR_RS_L = (0x16 << 6) | OPC_DEXTR_W_DSP,
689 OPC_DEXTR_W = (0x00 << 6) | OPC_DEXTR_W_DSP,
690 OPC_DEXTR_R_W = (0x04 << 6) | OPC_DEXTR_W_DSP,
691 OPC_DEXTR_RS_W = (0x06 << 6) | OPC_DEXTR_W_DSP,
692 OPC_DEXTR_S_H = (0x0E << 6) | OPC_DEXTR_W_DSP,
693 OPC_DEXTRV_L = (0x11 << 6) | OPC_DEXTR_W_DSP,
694 OPC_DEXTRV_R_L = (0x15 << 6) | OPC_DEXTR_W_DSP,
695 OPC_DEXTRV_RS_L = (0x17 << 6) | OPC_DEXTR_W_DSP,
696 OPC_DEXTRV_S_H = (0x0F << 6) | OPC_DEXTR_W_DSP,
697 OPC_DEXTRV_W = (0x01 << 6) | OPC_DEXTR_W_DSP,
698 OPC_DEXTRV_R_W = (0x05 << 6) | OPC_DEXTR_W_DSP,
699 OPC_DEXTRV_RS_W = (0x07 << 6) | OPC_DEXTR_W_DSP,
700 OPC_DSHILOV = (0x1B << 6) | OPC_DEXTR_W_DSP,
703 #define MASK_DINSV(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
704 enum {
705 /* DSP Bit/Manipulation Sub-class */
706 OPC_DINSV = (0x00 << 6) | OPC_DINSV_DSP,
709 #define MASK_DPAQ_W_QH(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
710 enum {
711 /* MIPS DSP Multiply Sub-class insns */
712 OPC_DMADD = (0x19 << 6) | OPC_DPAQ_W_QH_DSP,
713 OPC_DMADDU = (0x1D << 6) | OPC_DPAQ_W_QH_DSP,
714 OPC_DMSUB = (0x1B << 6) | OPC_DPAQ_W_QH_DSP,
715 OPC_DMSUBU = (0x1F << 6) | OPC_DPAQ_W_QH_DSP,
716 OPC_DPA_W_QH = (0x00 << 6) | OPC_DPAQ_W_QH_DSP,
717 OPC_DPAQ_S_W_QH = (0x04 << 6) | OPC_DPAQ_W_QH_DSP,
718 OPC_DPAQ_SA_L_PW = (0x0C << 6) | OPC_DPAQ_W_QH_DSP,
719 OPC_DPAU_H_OBL = (0x03 << 6) | OPC_DPAQ_W_QH_DSP,
720 OPC_DPAU_H_OBR = (0x07 << 6) | OPC_DPAQ_W_QH_DSP,
721 OPC_DPS_W_QH = (0x01 << 6) | OPC_DPAQ_W_QH_DSP,
722 OPC_DPSQ_S_W_QH = (0x05 << 6) | OPC_DPAQ_W_QH_DSP,
723 OPC_DPSQ_SA_L_PW = (0x0D << 6) | OPC_DPAQ_W_QH_DSP,
724 OPC_DPSU_H_OBL = (0x0B << 6) | OPC_DPAQ_W_QH_DSP,
725 OPC_DPSU_H_OBR = (0x0F << 6) | OPC_DPAQ_W_QH_DSP,
726 OPC_MAQ_S_L_PWL = (0x1C << 6) | OPC_DPAQ_W_QH_DSP,
727 OPC_MAQ_S_L_PWR = (0x1E << 6) | OPC_DPAQ_W_QH_DSP,
728 OPC_MAQ_S_W_QHLL = (0x14 << 6) | OPC_DPAQ_W_QH_DSP,
729 OPC_MAQ_SA_W_QHLL = (0x10 << 6) | OPC_DPAQ_W_QH_DSP,
730 OPC_MAQ_S_W_QHLR = (0x15 << 6) | OPC_DPAQ_W_QH_DSP,
731 OPC_MAQ_SA_W_QHLR = (0x11 << 6) | OPC_DPAQ_W_QH_DSP,
732 OPC_MAQ_S_W_QHRL = (0x16 << 6) | OPC_DPAQ_W_QH_DSP,
733 OPC_MAQ_SA_W_QHRL = (0x12 << 6) | OPC_DPAQ_W_QH_DSP,
734 OPC_MAQ_S_W_QHRR = (0x17 << 6) | OPC_DPAQ_W_QH_DSP,
735 OPC_MAQ_SA_W_QHRR = (0x13 << 6) | OPC_DPAQ_W_QH_DSP,
736 OPC_MULSAQ_S_L_PW = (0x0E << 6) | OPC_DPAQ_W_QH_DSP,
737 OPC_MULSAQ_S_W_QH = (0x06 << 6) | OPC_DPAQ_W_QH_DSP,
740 #define MASK_SHLL_OB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
741 enum {
742 /* MIPS DSP GPR-Based Shift Sub-class */
743 OPC_SHLL_PW = (0x10 << 6) | OPC_SHLL_OB_DSP,
744 OPC_SHLL_S_PW = (0x14 << 6) | OPC_SHLL_OB_DSP,
745 OPC_SHLLV_OB = (0x02 << 6) | OPC_SHLL_OB_DSP,
746 OPC_SHLLV_PW = (0x12 << 6) | OPC_SHLL_OB_DSP,
747 OPC_SHLLV_S_PW = (0x16 << 6) | OPC_SHLL_OB_DSP,
748 OPC_SHLLV_QH = (0x0A << 6) | OPC_SHLL_OB_DSP,
749 OPC_SHLLV_S_QH = (0x0E << 6) | OPC_SHLL_OB_DSP,
750 OPC_SHRA_PW = (0x11 << 6) | OPC_SHLL_OB_DSP,
751 OPC_SHRA_R_PW = (0x15 << 6) | OPC_SHLL_OB_DSP,
752 OPC_SHRAV_OB = (0x06 << 6) | OPC_SHLL_OB_DSP,
753 OPC_SHRAV_R_OB = (0x07 << 6) | OPC_SHLL_OB_DSP,
754 OPC_SHRAV_PW = (0x13 << 6) | OPC_SHLL_OB_DSP,
755 OPC_SHRAV_R_PW = (0x17 << 6) | OPC_SHLL_OB_DSP,
756 OPC_SHRAV_QH = (0x0B << 6) | OPC_SHLL_OB_DSP,
757 OPC_SHRAV_R_QH = (0x0F << 6) | OPC_SHLL_OB_DSP,
758 OPC_SHRLV_OB = (0x03 << 6) | OPC_SHLL_OB_DSP,
759 OPC_SHRLV_QH = (0x1B << 6) | OPC_SHLL_OB_DSP,
760 OPC_SHLL_OB = (0x00 << 6) | OPC_SHLL_OB_DSP,
761 OPC_SHLL_QH = (0x08 << 6) | OPC_SHLL_OB_DSP,
762 OPC_SHLL_S_QH = (0x0C << 6) | OPC_SHLL_OB_DSP,
763 OPC_SHRA_OB = (0x04 << 6) | OPC_SHLL_OB_DSP,
764 OPC_SHRA_R_OB = (0x05 << 6) | OPC_SHLL_OB_DSP,
765 OPC_SHRA_QH = (0x09 << 6) | OPC_SHLL_OB_DSP,
766 OPC_SHRA_R_QH = (0x0D << 6) | OPC_SHLL_OB_DSP,
767 OPC_SHRL_OB = (0x01 << 6) | OPC_SHLL_OB_DSP,
768 OPC_SHRL_QH = (0x19 << 6) | OPC_SHLL_OB_DSP,
771 /* Coprocessor 0 (rs field) */
772 #define MASK_CP0(op) MASK_OP_MAJOR(op) | (op & (0x1F << 21))
774 enum {
775 OPC_MFC0 = (0x00 << 21) | OPC_CP0,
776 OPC_DMFC0 = (0x01 << 21) | OPC_CP0,
777 OPC_MTC0 = (0x04 << 21) | OPC_CP0,
778 OPC_DMTC0 = (0x05 << 21) | OPC_CP0,
779 OPC_MFTR = (0x08 << 21) | OPC_CP0,
780 OPC_RDPGPR = (0x0A << 21) | OPC_CP0,
781 OPC_MFMC0 = (0x0B << 21) | OPC_CP0,
782 OPC_MTTR = (0x0C << 21) | OPC_CP0,
783 OPC_WRPGPR = (0x0E << 21) | OPC_CP0,
784 OPC_C0 = (0x10 << 21) | OPC_CP0,
785 OPC_C0_FIRST = (0x10 << 21) | OPC_CP0,
786 OPC_C0_LAST = (0x1F << 21) | OPC_CP0,
789 /* MFMC0 opcodes */
790 #define MASK_MFMC0(op) MASK_CP0(op) | (op & 0xFFFF)
792 enum {
793 OPC_DMT = 0x01 | (0 << 5) | (0x0F << 6) | (0x01 << 11) | OPC_MFMC0,
794 OPC_EMT = 0x01 | (1 << 5) | (0x0F << 6) | (0x01 << 11) | OPC_MFMC0,
795 OPC_DVPE = 0x01 | (0 << 5) | OPC_MFMC0,
796 OPC_EVPE = 0x01 | (1 << 5) | OPC_MFMC0,
797 OPC_DI = (0 << 5) | (0x0C << 11) | OPC_MFMC0,
798 OPC_EI = (1 << 5) | (0x0C << 11) | OPC_MFMC0,
801 /* Coprocessor 0 (with rs == C0) */
802 #define MASK_C0(op) MASK_CP0(op) | (op & 0x3F)
804 enum {
805 OPC_TLBR = 0x01 | OPC_C0,
806 OPC_TLBWI = 0x02 | OPC_C0,
807 OPC_TLBWR = 0x06 | OPC_C0,
808 OPC_TLBP = 0x08 | OPC_C0,
809 OPC_RFE = 0x10 | OPC_C0,
810 OPC_ERET = 0x18 | OPC_C0,
811 OPC_DERET = 0x1F | OPC_C0,
812 OPC_WAIT = 0x20 | OPC_C0,
815 /* Coprocessor 1 (rs field) */
816 #define MASK_CP1(op) MASK_OP_MAJOR(op) | (op & (0x1F << 21))
818 /* Values for the fmt field in FP instructions */
819 enum {
820 /* 0 - 15 are reserved */
821 FMT_S = 16, /* single fp */
822 FMT_D = 17, /* double fp */
823 FMT_E = 18, /* extended fp */
824 FMT_Q = 19, /* quad fp */
825 FMT_W = 20, /* 32-bit fixed */
826 FMT_L = 21, /* 64-bit fixed */
827 FMT_PS = 22, /* paired single fp */
828 /* 23 - 31 are reserved */
831 enum {
832 OPC_MFC1 = (0x00 << 21) | OPC_CP1,
833 OPC_DMFC1 = (0x01 << 21) | OPC_CP1,
834 OPC_CFC1 = (0x02 << 21) | OPC_CP1,
835 OPC_MFHC1 = (0x03 << 21) | OPC_CP1,
836 OPC_MTC1 = (0x04 << 21) | OPC_CP1,
837 OPC_DMTC1 = (0x05 << 21) | OPC_CP1,
838 OPC_CTC1 = (0x06 << 21) | OPC_CP1,
839 OPC_MTHC1 = (0x07 << 21) | OPC_CP1,
840 OPC_BC1 = (0x08 << 21) | OPC_CP1, /* bc */
841 OPC_BC1ANY2 = (0x09 << 21) | OPC_CP1,
842 OPC_BC1ANY4 = (0x0A << 21) | OPC_CP1,
843 OPC_S_FMT = (FMT_S << 21) | OPC_CP1,
844 OPC_D_FMT = (FMT_D << 21) | OPC_CP1,
845 OPC_E_FMT = (FMT_E << 21) | OPC_CP1,
846 OPC_Q_FMT = (FMT_Q << 21) | OPC_CP1,
847 OPC_W_FMT = (FMT_W << 21) | OPC_CP1,
848 OPC_L_FMT = (FMT_L << 21) | OPC_CP1,
849 OPC_PS_FMT = (FMT_PS << 21) | OPC_CP1,
852 #define MASK_CP1_FUNC(op) MASK_CP1(op) | (op & 0x3F)
853 #define MASK_BC1(op) MASK_CP1(op) | (op & (0x3 << 16))
855 enum {
856 OPC_BC1F = (0x00 << 16) | OPC_BC1,
857 OPC_BC1T = (0x01 << 16) | OPC_BC1,
858 OPC_BC1FL = (0x02 << 16) | OPC_BC1,
859 OPC_BC1TL = (0x03 << 16) | OPC_BC1,
862 enum {
863 OPC_BC1FANY2 = (0x00 << 16) | OPC_BC1ANY2,
864 OPC_BC1TANY2 = (0x01 << 16) | OPC_BC1ANY2,
867 enum {
868 OPC_BC1FANY4 = (0x00 << 16) | OPC_BC1ANY4,
869 OPC_BC1TANY4 = (0x01 << 16) | OPC_BC1ANY4,
872 #define MASK_CP2(op) MASK_OP_MAJOR(op) | (op & (0x1F << 21))
874 enum {
875 OPC_MFC2 = (0x00 << 21) | OPC_CP2,
876 OPC_DMFC2 = (0x01 << 21) | OPC_CP2,
877 OPC_CFC2 = (0x02 << 21) | OPC_CP2,
878 OPC_MFHC2 = (0x03 << 21) | OPC_CP2,
879 OPC_MTC2 = (0x04 << 21) | OPC_CP2,
880 OPC_DMTC2 = (0x05 << 21) | OPC_CP2,
881 OPC_CTC2 = (0x06 << 21) | OPC_CP2,
882 OPC_MTHC2 = (0x07 << 21) | OPC_CP2,
883 OPC_BC2 = (0x08 << 21) | OPC_CP2,
886 #define MASK_LMI(op) (MASK_OP_MAJOR(op) | (op & (0x1F << 21)) | (op & 0x1F))
888 enum {
889 OPC_PADDSH = (24 << 21) | (0x00) | OPC_CP2,
890 OPC_PADDUSH = (25 << 21) | (0x00) | OPC_CP2,
891 OPC_PADDH = (26 << 21) | (0x00) | OPC_CP2,
892 OPC_PADDW = (27 << 21) | (0x00) | OPC_CP2,
893 OPC_PADDSB = (28 << 21) | (0x00) | OPC_CP2,
894 OPC_PADDUSB = (29 << 21) | (0x00) | OPC_CP2,
895 OPC_PADDB = (30 << 21) | (0x00) | OPC_CP2,
896 OPC_PADDD = (31 << 21) | (0x00) | OPC_CP2,
898 OPC_PSUBSH = (24 << 21) | (0x01) | OPC_CP2,
899 OPC_PSUBUSH = (25 << 21) | (0x01) | OPC_CP2,
900 OPC_PSUBH = (26 << 21) | (0x01) | OPC_CP2,
901 OPC_PSUBW = (27 << 21) | (0x01) | OPC_CP2,
902 OPC_PSUBSB = (28 << 21) | (0x01) | OPC_CP2,
903 OPC_PSUBUSB = (29 << 21) | (0x01) | OPC_CP2,
904 OPC_PSUBB = (30 << 21) | (0x01) | OPC_CP2,
905 OPC_PSUBD = (31 << 21) | (0x01) | OPC_CP2,
907 OPC_PSHUFH = (24 << 21) | (0x02) | OPC_CP2,
908 OPC_PACKSSWH = (25 << 21) | (0x02) | OPC_CP2,
909 OPC_PACKSSHB = (26 << 21) | (0x02) | OPC_CP2,
910 OPC_PACKUSHB = (27 << 21) | (0x02) | OPC_CP2,
911 OPC_XOR_CP2 = (28 << 21) | (0x02) | OPC_CP2,
912 OPC_NOR_CP2 = (29 << 21) | (0x02) | OPC_CP2,
913 OPC_AND_CP2 = (30 << 21) | (0x02) | OPC_CP2,
914 OPC_PANDN = (31 << 21) | (0x02) | OPC_CP2,
916 OPC_PUNPCKLHW = (24 << 21) | (0x03) | OPC_CP2,
917 OPC_PUNPCKHHW = (25 << 21) | (0x03) | OPC_CP2,
918 OPC_PUNPCKLBH = (26 << 21) | (0x03) | OPC_CP2,
919 OPC_PUNPCKHBH = (27 << 21) | (0x03) | OPC_CP2,
920 OPC_PINSRH_0 = (28 << 21) | (0x03) | OPC_CP2,
921 OPC_PINSRH_1 = (29 << 21) | (0x03) | OPC_CP2,
922 OPC_PINSRH_2 = (30 << 21) | (0x03) | OPC_CP2,
923 OPC_PINSRH_3 = (31 << 21) | (0x03) | OPC_CP2,
925 OPC_PAVGH = (24 << 21) | (0x08) | OPC_CP2,
926 OPC_PAVGB = (25 << 21) | (0x08) | OPC_CP2,
927 OPC_PMAXSH = (26 << 21) | (0x08) | OPC_CP2,
928 OPC_PMINSH = (27 << 21) | (0x08) | OPC_CP2,
929 OPC_PMAXUB = (28 << 21) | (0x08) | OPC_CP2,
930 OPC_PMINUB = (29 << 21) | (0x08) | OPC_CP2,
932 OPC_PCMPEQW = (24 << 21) | (0x09) | OPC_CP2,
933 OPC_PCMPGTW = (25 << 21) | (0x09) | OPC_CP2,
934 OPC_PCMPEQH = (26 << 21) | (0x09) | OPC_CP2,
935 OPC_PCMPGTH = (27 << 21) | (0x09) | OPC_CP2,
936 OPC_PCMPEQB = (28 << 21) | (0x09) | OPC_CP2,
937 OPC_PCMPGTB = (29 << 21) | (0x09) | OPC_CP2,
939 OPC_PSLLW = (24 << 21) | (0x0A) | OPC_CP2,
940 OPC_PSLLH = (25 << 21) | (0x0A) | OPC_CP2,
941 OPC_PMULLH = (26 << 21) | (0x0A) | OPC_CP2,
942 OPC_PMULHH = (27 << 21) | (0x0A) | OPC_CP2,
943 OPC_PMULUW = (28 << 21) | (0x0A) | OPC_CP2,
944 OPC_PMULHUH = (29 << 21) | (0x0A) | OPC_CP2,
946 OPC_PSRLW = (24 << 21) | (0x0B) | OPC_CP2,
947 OPC_PSRLH = (25 << 21) | (0x0B) | OPC_CP2,
948 OPC_PSRAW = (26 << 21) | (0x0B) | OPC_CP2,
949 OPC_PSRAH = (27 << 21) | (0x0B) | OPC_CP2,
950 OPC_PUNPCKLWD = (28 << 21) | (0x0B) | OPC_CP2,
951 OPC_PUNPCKHWD = (29 << 21) | (0x0B) | OPC_CP2,
953 OPC_ADDU_CP2 = (24 << 21) | (0x0C) | OPC_CP2,
954 OPC_OR_CP2 = (25 << 21) | (0x0C) | OPC_CP2,
955 OPC_ADD_CP2 = (26 << 21) | (0x0C) | OPC_CP2,
956 OPC_DADD_CP2 = (27 << 21) | (0x0C) | OPC_CP2,
957 OPC_SEQU_CP2 = (28 << 21) | (0x0C) | OPC_CP2,
958 OPC_SEQ_CP2 = (29 << 21) | (0x0C) | OPC_CP2,
960 OPC_SUBU_CP2 = (24 << 21) | (0x0D) | OPC_CP2,
961 OPC_PASUBUB = (25 << 21) | (0x0D) | OPC_CP2,
962 OPC_SUB_CP2 = (26 << 21) | (0x0D) | OPC_CP2,
963 OPC_DSUB_CP2 = (27 << 21) | (0x0D) | OPC_CP2,
964 OPC_SLTU_CP2 = (28 << 21) | (0x0D) | OPC_CP2,
965 OPC_SLT_CP2 = (29 << 21) | (0x0D) | OPC_CP2,
967 OPC_SLL_CP2 = (24 << 21) | (0x0E) | OPC_CP2,
968 OPC_DSLL_CP2 = (25 << 21) | (0x0E) | OPC_CP2,
969 OPC_PEXTRH = (26 << 21) | (0x0E) | OPC_CP2,
970 OPC_PMADDHW = (27 << 21) | (0x0E) | OPC_CP2,
971 OPC_SLEU_CP2 = (28 << 21) | (0x0E) | OPC_CP2,
972 OPC_SLE_CP2 = (29 << 21) | (0x0E) | OPC_CP2,
974 OPC_SRL_CP2 = (24 << 21) | (0x0F) | OPC_CP2,
975 OPC_DSRL_CP2 = (25 << 21) | (0x0F) | OPC_CP2,
976 OPC_SRA_CP2 = (26 << 21) | (0x0F) | OPC_CP2,
977 OPC_DSRA_CP2 = (27 << 21) | (0x0F) | OPC_CP2,
978 OPC_BIADD = (28 << 21) | (0x0F) | OPC_CP2,
979 OPC_PMOVMSKB = (29 << 21) | (0x0F) | OPC_CP2,
983 #define MASK_CP3(op) MASK_OP_MAJOR(op) | (op & 0x3F)
985 enum {
986 OPC_LWXC1 = 0x00 | OPC_CP3,
987 OPC_LDXC1 = 0x01 | OPC_CP3,
988 OPC_LUXC1 = 0x05 | OPC_CP3,
989 OPC_SWXC1 = 0x08 | OPC_CP3,
990 OPC_SDXC1 = 0x09 | OPC_CP3,
991 OPC_SUXC1 = 0x0D | OPC_CP3,
992 OPC_PREFX = 0x0F | OPC_CP3,
993 OPC_ALNV_PS = 0x1E | OPC_CP3,
994 OPC_MADD_S = 0x20 | OPC_CP3,
995 OPC_MADD_D = 0x21 | OPC_CP3,
996 OPC_MADD_PS = 0x26 | OPC_CP3,
997 OPC_MSUB_S = 0x28 | OPC_CP3,
998 OPC_MSUB_D = 0x29 | OPC_CP3,
999 OPC_MSUB_PS = 0x2E | OPC_CP3,
1000 OPC_NMADD_S = 0x30 | OPC_CP3,
1001 OPC_NMADD_D = 0x31 | OPC_CP3,
1002 OPC_NMADD_PS= 0x36 | OPC_CP3,
1003 OPC_NMSUB_S = 0x38 | OPC_CP3,
1004 OPC_NMSUB_D = 0x39 | OPC_CP3,
1005 OPC_NMSUB_PS= 0x3E | OPC_CP3,
1008 /* global register indices */
1009 static TCGv_ptr cpu_env;
1010 static TCGv cpu_gpr[32], cpu_PC;
1011 static TCGv cpu_HI[MIPS_DSP_ACC], cpu_LO[MIPS_DSP_ACC], cpu_ACX[MIPS_DSP_ACC];
1012 static TCGv cpu_dspctrl, btarget, bcond;
1013 static TCGv_i32 hflags;
1014 static TCGv_i32 fpu_fcr0, fpu_fcr31;
1015 static TCGv_i64 fpu_f64[32];
1017 static uint32_t gen_opc_hflags[OPC_BUF_SIZE];
1018 static target_ulong gen_opc_btarget[OPC_BUF_SIZE];
1020 #include "exec/gen-icount.h"
1022 #define gen_helper_0e0i(name, arg) do { \
1023 TCGv_i32 helper_tmp = tcg_const_i32(arg); \
1024 gen_helper_##name(cpu_env, helper_tmp); \
1025 tcg_temp_free_i32(helper_tmp); \
1026 } while(0)
1028 #define gen_helper_0e1i(name, arg1, arg2) do { \
1029 TCGv_i32 helper_tmp = tcg_const_i32(arg2); \
1030 gen_helper_##name(cpu_env, arg1, helper_tmp); \
1031 tcg_temp_free_i32(helper_tmp); \
1032 } while(0)
1034 #define gen_helper_1e0i(name, ret, arg1) do { \
1035 TCGv_i32 helper_tmp = tcg_const_i32(arg1); \
1036 gen_helper_##name(ret, cpu_env, helper_tmp); \
1037 tcg_temp_free_i32(helper_tmp); \
1038 } while(0)
1040 #define gen_helper_1e1i(name, ret, arg1, arg2) do { \
1041 TCGv_i32 helper_tmp = tcg_const_i32(arg2); \
1042 gen_helper_##name(ret, cpu_env, arg1, helper_tmp); \
1043 tcg_temp_free_i32(helper_tmp); \
1044 } while(0)
1046 #define gen_helper_0e2i(name, arg1, arg2, arg3) do { \
1047 TCGv_i32 helper_tmp = tcg_const_i32(arg3); \
1048 gen_helper_##name(cpu_env, arg1, arg2, helper_tmp); \
1049 tcg_temp_free_i32(helper_tmp); \
1050 } while(0)
1052 #define gen_helper_1e2i(name, ret, arg1, arg2, arg3) do { \
1053 TCGv_i32 helper_tmp = tcg_const_i32(arg3); \
1054 gen_helper_##name(ret, cpu_env, arg1, arg2, helper_tmp); \
1055 tcg_temp_free_i32(helper_tmp); \
1056 } while(0)
1058 #define gen_helper_0e3i(name, arg1, arg2, arg3, arg4) do { \
1059 TCGv_i32 helper_tmp = tcg_const_i32(arg4); \
1060 gen_helper_##name(cpu_env, arg1, arg2, arg3, helper_tmp); \
1061 tcg_temp_free_i32(helper_tmp); \
1062 } while(0)
1064 typedef struct DisasContext {
1065 struct TranslationBlock *tb;
1066 target_ulong pc, saved_pc;
1067 uint32_t opcode;
1068 int singlestep_enabled;
1069 int insn_flags;
1070 /* Routine used to access memory */
1071 int mem_idx;
1072 uint32_t hflags, saved_hflags;
1073 int bstate;
1074 target_ulong btarget;
1075 } DisasContext;
1077 enum {
1078 BS_NONE = 0, /* We go out of the TB without reaching a branch or an
1079 * exception condition */
1080 BS_STOP = 1, /* We want to stop translation for any reason */
1081 BS_BRANCH = 2, /* We reached a branch condition */
1082 BS_EXCP = 3, /* We reached an exception condition */
1085 static const char * const regnames[] = {
1086 "r0", "at", "v0", "v1", "a0", "a1", "a2", "a3",
1087 "t0", "t1", "t2", "t3", "t4", "t5", "t6", "t7",
1088 "s0", "s1", "s2", "s3", "s4", "s5", "s6", "s7",
1089 "t8", "t9", "k0", "k1", "gp", "sp", "s8", "ra",
1092 static const char * const regnames_HI[] = {
1093 "HI0", "HI1", "HI2", "HI3",
1096 static const char * const regnames_LO[] = {
1097 "LO0", "LO1", "LO2", "LO3",
1100 static const char * const regnames_ACX[] = {
1101 "ACX0", "ACX1", "ACX2", "ACX3",
1104 static const char * const fregnames[] = {
1105 "f0", "f1", "f2", "f3", "f4", "f5", "f6", "f7",
1106 "f8", "f9", "f10", "f11", "f12", "f13", "f14", "f15",
1107 "f16", "f17", "f18", "f19", "f20", "f21", "f22", "f23",
1108 "f24", "f25", "f26", "f27", "f28", "f29", "f30", "f31",
1111 #define MIPS_DEBUG(fmt, ...) \
1112 do { \
1113 if (MIPS_DEBUG_DISAS) { \
1114 qemu_log_mask(CPU_LOG_TB_IN_ASM, \
1115 TARGET_FMT_lx ": %08x " fmt "\n", \
1116 ctx->pc, ctx->opcode , ## __VA_ARGS__); \
1118 } while (0)
1120 #define LOG_DISAS(...) \
1121 do { \
1122 if (MIPS_DEBUG_DISAS) { \
1123 qemu_log_mask(CPU_LOG_TB_IN_ASM, ## __VA_ARGS__); \
1125 } while (0)
1127 #define MIPS_INVAL(op) \
1128 MIPS_DEBUG("Invalid %s %03x %03x %03x", op, ctx->opcode >> 26, \
1129 ctx->opcode & 0x3F, ((ctx->opcode >> 16) & 0x1F))
1131 /* General purpose registers moves. */
1132 static inline void gen_load_gpr (TCGv t, int reg)
1134 if (reg == 0)
1135 tcg_gen_movi_tl(t, 0);
1136 else
1137 tcg_gen_mov_tl(t, cpu_gpr[reg]);
1140 static inline void gen_store_gpr (TCGv t, int reg)
1142 if (reg != 0)
1143 tcg_gen_mov_tl(cpu_gpr[reg], t);
1146 /* Moves to/from ACX register. */
1147 static inline void gen_load_ACX (TCGv t, int reg)
1149 tcg_gen_mov_tl(t, cpu_ACX[reg]);
1152 static inline void gen_store_ACX (TCGv t, int reg)
1154 tcg_gen_mov_tl(cpu_ACX[reg], t);
1157 /* Moves to/from shadow registers. */
1158 static inline void gen_load_srsgpr (int from, int to)
1160 TCGv t0 = tcg_temp_new();
1162 if (from == 0)
1163 tcg_gen_movi_tl(t0, 0);
1164 else {
1165 TCGv_i32 t2 = tcg_temp_new_i32();
1166 TCGv_ptr addr = tcg_temp_new_ptr();
1168 tcg_gen_ld_i32(t2, cpu_env, offsetof(CPUMIPSState, CP0_SRSCtl));
1169 tcg_gen_shri_i32(t2, t2, CP0SRSCtl_PSS);
1170 tcg_gen_andi_i32(t2, t2, 0xf);
1171 tcg_gen_muli_i32(t2, t2, sizeof(target_ulong) * 32);
1172 tcg_gen_ext_i32_ptr(addr, t2);
1173 tcg_gen_add_ptr(addr, cpu_env, addr);
1175 tcg_gen_ld_tl(t0, addr, sizeof(target_ulong) * from);
1176 tcg_temp_free_ptr(addr);
1177 tcg_temp_free_i32(t2);
1179 gen_store_gpr(t0, to);
1180 tcg_temp_free(t0);
1183 static inline void gen_store_srsgpr (int from, int to)
1185 if (to != 0) {
1186 TCGv t0 = tcg_temp_new();
1187 TCGv_i32 t2 = tcg_temp_new_i32();
1188 TCGv_ptr addr = tcg_temp_new_ptr();
1190 gen_load_gpr(t0, from);
1191 tcg_gen_ld_i32(t2, cpu_env, offsetof(CPUMIPSState, CP0_SRSCtl));
1192 tcg_gen_shri_i32(t2, t2, CP0SRSCtl_PSS);
1193 tcg_gen_andi_i32(t2, t2, 0xf);
1194 tcg_gen_muli_i32(t2, t2, sizeof(target_ulong) * 32);
1195 tcg_gen_ext_i32_ptr(addr, t2);
1196 tcg_gen_add_ptr(addr, cpu_env, addr);
1198 tcg_gen_st_tl(t0, addr, sizeof(target_ulong) * to);
1199 tcg_temp_free_ptr(addr);
1200 tcg_temp_free_i32(t2);
1201 tcg_temp_free(t0);
1205 /* Floating point register moves. */
1206 static void gen_load_fpr32(TCGv_i32 t, int reg)
1208 tcg_gen_trunc_i64_i32(t, fpu_f64[reg]);
1211 static void gen_store_fpr32(TCGv_i32 t, int reg)
1213 TCGv_i64 t64 = tcg_temp_new_i64();
1214 tcg_gen_extu_i32_i64(t64, t);
1215 tcg_gen_deposit_i64(fpu_f64[reg], fpu_f64[reg], t64, 0, 32);
1216 tcg_temp_free_i64(t64);
1219 static void gen_load_fpr32h(TCGv_i32 t, int reg)
1221 TCGv_i64 t64 = tcg_temp_new_i64();
1222 tcg_gen_shri_i64(t64, fpu_f64[reg], 32);
1223 tcg_gen_trunc_i64_i32(t, t64);
1224 tcg_temp_free_i64(t64);
1227 static void gen_store_fpr32h(TCGv_i32 t, int reg)
1229 TCGv_i64 t64 = tcg_temp_new_i64();
1230 tcg_gen_extu_i32_i64(t64, t);
1231 tcg_gen_deposit_i64(fpu_f64[reg], fpu_f64[reg], t64, 32, 32);
1232 tcg_temp_free_i64(t64);
1235 static void gen_load_fpr64(DisasContext *ctx, TCGv_i64 t, int reg)
1237 if (ctx->hflags & MIPS_HFLAG_F64) {
1238 tcg_gen_mov_i64(t, fpu_f64[reg]);
1239 } else {
1240 tcg_gen_concat32_i64(t, fpu_f64[reg & ~1], fpu_f64[reg | 1]);
1244 static void gen_store_fpr64(DisasContext *ctx, TCGv_i64 t, int reg)
1246 if (ctx->hflags & MIPS_HFLAG_F64) {
1247 tcg_gen_mov_i64(fpu_f64[reg], t);
1248 } else {
1249 TCGv_i64 t0;
1250 tcg_gen_deposit_i64(fpu_f64[reg & ~1], fpu_f64[reg & ~1], t, 0, 32);
1251 t0 = tcg_temp_new_i64();
1252 tcg_gen_shri_i64(t0, t, 32);
1253 tcg_gen_deposit_i64(fpu_f64[reg | 1], fpu_f64[reg | 1], t0, 0, 32);
1254 tcg_temp_free_i64(t0);
1258 static inline int get_fp_bit (int cc)
1260 if (cc)
1261 return 24 + cc;
1262 else
1263 return 23;
1266 /* Tests */
1267 static inline void gen_save_pc(target_ulong pc)
1269 tcg_gen_movi_tl(cpu_PC, pc);
1272 static inline void save_cpu_state (DisasContext *ctx, int do_save_pc)
1274 LOG_DISAS("hflags %08x saved %08x\n", ctx->hflags, ctx->saved_hflags);
1275 if (do_save_pc && ctx->pc != ctx->saved_pc) {
1276 gen_save_pc(ctx->pc);
1277 ctx->saved_pc = ctx->pc;
1279 if (ctx->hflags != ctx->saved_hflags) {
1280 tcg_gen_movi_i32(hflags, ctx->hflags);
1281 ctx->saved_hflags = ctx->hflags;
1282 switch (ctx->hflags & MIPS_HFLAG_BMASK_BASE) {
1283 case MIPS_HFLAG_BR:
1284 break;
1285 case MIPS_HFLAG_BC:
1286 case MIPS_HFLAG_BL:
1287 case MIPS_HFLAG_B:
1288 tcg_gen_movi_tl(btarget, ctx->btarget);
1289 break;
1294 static inline void restore_cpu_state (CPUMIPSState *env, DisasContext *ctx)
1296 ctx->saved_hflags = ctx->hflags;
1297 switch (ctx->hflags & MIPS_HFLAG_BMASK_BASE) {
1298 case MIPS_HFLAG_BR:
1299 break;
1300 case MIPS_HFLAG_BC:
1301 case MIPS_HFLAG_BL:
1302 case MIPS_HFLAG_B:
1303 ctx->btarget = env->btarget;
1304 break;
1308 static inline void
1309 generate_exception_err (DisasContext *ctx, int excp, int err)
1311 TCGv_i32 texcp = tcg_const_i32(excp);
1312 TCGv_i32 terr = tcg_const_i32(err);
1313 save_cpu_state(ctx, 1);
1314 gen_helper_raise_exception_err(cpu_env, texcp, terr);
1315 tcg_temp_free_i32(terr);
1316 tcg_temp_free_i32(texcp);
1319 static inline void
1320 generate_exception (DisasContext *ctx, int excp)
1322 save_cpu_state(ctx, 1);
1323 gen_helper_0e0i(raise_exception, excp);
1326 /* Addresses computation */
1327 static inline void gen_op_addr_add (DisasContext *ctx, TCGv ret, TCGv arg0, TCGv arg1)
1329 tcg_gen_add_tl(ret, arg0, arg1);
1331 #if defined(TARGET_MIPS64)
1332 /* For compatibility with 32-bit code, data reference in user mode
1333 with Status_UX = 0 should be casted to 32-bit and sign extended.
1334 See the MIPS64 PRA manual, section 4.10. */
1335 if (((ctx->hflags & MIPS_HFLAG_KSU) == MIPS_HFLAG_UM) &&
1336 !(ctx->hflags & MIPS_HFLAG_UX)) {
1337 tcg_gen_ext32s_i64(ret, ret);
1339 #endif
1342 static inline void check_cp0_enabled(DisasContext *ctx)
1344 if (unlikely(!(ctx->hflags & MIPS_HFLAG_CP0)))
1345 generate_exception_err(ctx, EXCP_CpU, 0);
1348 static inline void check_cp1_enabled(DisasContext *ctx)
1350 if (unlikely(!(ctx->hflags & MIPS_HFLAG_FPU)))
1351 generate_exception_err(ctx, EXCP_CpU, 1);
1354 /* Verify that the processor is running with COP1X instructions enabled.
1355 This is associated with the nabla symbol in the MIPS32 and MIPS64
1356 opcode tables. */
1358 static inline void check_cop1x(DisasContext *ctx)
1360 if (unlikely(!(ctx->hflags & MIPS_HFLAG_COP1X)))
1361 generate_exception(ctx, EXCP_RI);
1364 /* Verify that the processor is running with 64-bit floating-point
1365 operations enabled. */
1367 static inline void check_cp1_64bitmode(DisasContext *ctx)
1369 if (unlikely(~ctx->hflags & (MIPS_HFLAG_F64 | MIPS_HFLAG_COP1X)))
1370 generate_exception(ctx, EXCP_RI);
1374 * Verify if floating point register is valid; an operation is not defined
1375 * if bit 0 of any register specification is set and the FR bit in the
1376 * Status register equals zero, since the register numbers specify an
1377 * even-odd pair of adjacent coprocessor general registers. When the FR bit
1378 * in the Status register equals one, both even and odd register numbers
1379 * are valid. This limitation exists only for 64 bit wide (d,l,ps) registers.
1381 * Multiple 64 bit wide registers can be checked by calling
1382 * gen_op_cp1_registers(freg1 | freg2 | ... | fregN);
1384 static inline void check_cp1_registers(DisasContext *ctx, int regs)
1386 if (unlikely(!(ctx->hflags & MIPS_HFLAG_F64) && (regs & 1)))
1387 generate_exception(ctx, EXCP_RI);
1390 /* Verify that the processor is running with DSP instructions enabled.
1391 This is enabled by CP0 Status register MX(24) bit.
1394 static inline void check_dsp(DisasContext *ctx)
1396 if (unlikely(!(ctx->hflags & MIPS_HFLAG_DSP))) {
1397 if (ctx->insn_flags & ASE_DSP) {
1398 generate_exception(ctx, EXCP_DSPDIS);
1399 } else {
1400 generate_exception(ctx, EXCP_RI);
1405 static inline void check_dspr2(DisasContext *ctx)
1407 if (unlikely(!(ctx->hflags & MIPS_HFLAG_DSPR2))) {
1408 if (ctx->insn_flags & ASE_DSP) {
1409 generate_exception(ctx, EXCP_DSPDIS);
1410 } else {
1411 generate_exception(ctx, EXCP_RI);
1416 /* This code generates a "reserved instruction" exception if the
1417 CPU does not support the instruction set corresponding to flags. */
1418 static inline void check_insn(DisasContext *ctx, int flags)
1420 if (unlikely(!(ctx->insn_flags & flags))) {
1421 generate_exception(ctx, EXCP_RI);
1425 /* This code generates a "reserved instruction" exception if 64-bit
1426 instructions are not enabled. */
1427 static inline void check_mips_64(DisasContext *ctx)
1429 if (unlikely(!(ctx->hflags & MIPS_HFLAG_64)))
1430 generate_exception(ctx, EXCP_RI);
1433 /* Define small wrappers for gen_load_fpr* so that we have a uniform
1434 calling interface for 32 and 64-bit FPRs. No sense in changing
1435 all callers for gen_load_fpr32 when we need the CTX parameter for
1436 this one use. */
1437 #define gen_ldcmp_fpr32(ctx, x, y) gen_load_fpr32(x, y)
1438 #define gen_ldcmp_fpr64(ctx, x, y) gen_load_fpr64(ctx, x, y)
1439 #define FOP_CONDS(type, abs, fmt, ifmt, bits) \
1440 static inline void gen_cmp ## type ## _ ## fmt(DisasContext *ctx, int n, \
1441 int ft, int fs, int cc) \
1443 TCGv_i##bits fp0 = tcg_temp_new_i##bits (); \
1444 TCGv_i##bits fp1 = tcg_temp_new_i##bits (); \
1445 switch (ifmt) { \
1446 case FMT_PS: \
1447 check_cp1_64bitmode(ctx); \
1448 break; \
1449 case FMT_D: \
1450 if (abs) { \
1451 check_cop1x(ctx); \
1453 check_cp1_registers(ctx, fs | ft); \
1454 break; \
1455 case FMT_S: \
1456 if (abs) { \
1457 check_cop1x(ctx); \
1459 break; \
1461 gen_ldcmp_fpr##bits (ctx, fp0, fs); \
1462 gen_ldcmp_fpr##bits (ctx, fp1, ft); \
1463 switch (n) { \
1464 case 0: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _f, fp0, fp1, cc); break;\
1465 case 1: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _un, fp0, fp1, cc); break;\
1466 case 2: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _eq, fp0, fp1, cc); break;\
1467 case 3: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ueq, fp0, fp1, cc); break;\
1468 case 4: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _olt, fp0, fp1, cc); break;\
1469 case 5: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ult, fp0, fp1, cc); break;\
1470 case 6: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ole, fp0, fp1, cc); break;\
1471 case 7: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ule, fp0, fp1, cc); break;\
1472 case 8: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _sf, fp0, fp1, cc); break;\
1473 case 9: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ngle, fp0, fp1, cc); break;\
1474 case 10: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _seq, fp0, fp1, cc); break;\
1475 case 11: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ngl, fp0, fp1, cc); break;\
1476 case 12: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _lt, fp0, fp1, cc); break;\
1477 case 13: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _nge, fp0, fp1, cc); break;\
1478 case 14: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _le, fp0, fp1, cc); break;\
1479 case 15: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ngt, fp0, fp1, cc); break;\
1480 default: abort(); \
1482 tcg_temp_free_i##bits (fp0); \
1483 tcg_temp_free_i##bits (fp1); \
1486 FOP_CONDS(, 0, d, FMT_D, 64)
1487 FOP_CONDS(abs, 1, d, FMT_D, 64)
1488 FOP_CONDS(, 0, s, FMT_S, 32)
1489 FOP_CONDS(abs, 1, s, FMT_S, 32)
1490 FOP_CONDS(, 0, ps, FMT_PS, 64)
1491 FOP_CONDS(abs, 1, ps, FMT_PS, 64)
1492 #undef FOP_CONDS
1493 #undef gen_ldcmp_fpr32
1494 #undef gen_ldcmp_fpr64
1496 /* load/store instructions. */
1497 #ifdef CONFIG_USER_ONLY
1498 #define OP_LD_ATOMIC(insn,fname) \
1499 static inline void op_ld_##insn(TCGv ret, TCGv arg1, DisasContext *ctx) \
1501 TCGv t0 = tcg_temp_new(); \
1502 tcg_gen_mov_tl(t0, arg1); \
1503 tcg_gen_qemu_##fname(ret, arg1, ctx->mem_idx); \
1504 tcg_gen_st_tl(t0, cpu_env, offsetof(CPUMIPSState, lladdr)); \
1505 tcg_gen_st_tl(ret, cpu_env, offsetof(CPUMIPSState, llval)); \
1506 tcg_temp_free(t0); \
1508 #else
1509 #define OP_LD_ATOMIC(insn,fname) \
1510 static inline void op_ld_##insn(TCGv ret, TCGv arg1, DisasContext *ctx) \
1512 gen_helper_1e1i(insn, ret, arg1, ctx->mem_idx); \
1514 #endif
1515 OP_LD_ATOMIC(ll,ld32s);
1516 #if defined(TARGET_MIPS64)
1517 OP_LD_ATOMIC(lld,ld64);
1518 #endif
1519 #undef OP_LD_ATOMIC
1521 #ifdef CONFIG_USER_ONLY
1522 #define OP_ST_ATOMIC(insn,fname,ldname,almask) \
1523 static inline void op_st_##insn(TCGv arg1, TCGv arg2, int rt, DisasContext *ctx) \
1525 TCGv t0 = tcg_temp_new(); \
1526 int l1 = gen_new_label(); \
1527 int l2 = gen_new_label(); \
1529 tcg_gen_andi_tl(t0, arg2, almask); \
1530 tcg_gen_brcondi_tl(TCG_COND_EQ, t0, 0, l1); \
1531 tcg_gen_st_tl(arg2, cpu_env, offsetof(CPUMIPSState, CP0_BadVAddr)); \
1532 generate_exception(ctx, EXCP_AdES); \
1533 gen_set_label(l1); \
1534 tcg_gen_ld_tl(t0, cpu_env, offsetof(CPUMIPSState, lladdr)); \
1535 tcg_gen_brcond_tl(TCG_COND_NE, arg2, t0, l2); \
1536 tcg_gen_movi_tl(t0, rt | ((almask << 3) & 0x20)); \
1537 tcg_gen_st_tl(t0, cpu_env, offsetof(CPUMIPSState, llreg)); \
1538 tcg_gen_st_tl(arg1, cpu_env, offsetof(CPUMIPSState, llnewval)); \
1539 gen_helper_0e0i(raise_exception, EXCP_SC); \
1540 gen_set_label(l2); \
1541 tcg_gen_movi_tl(t0, 0); \
1542 gen_store_gpr(t0, rt); \
1543 tcg_temp_free(t0); \
1545 #else
1546 #define OP_ST_ATOMIC(insn,fname,ldname,almask) \
1547 static inline void op_st_##insn(TCGv arg1, TCGv arg2, int rt, DisasContext *ctx) \
1549 TCGv t0 = tcg_temp_new(); \
1550 gen_helper_1e2i(insn, t0, arg1, arg2, ctx->mem_idx); \
1551 gen_store_gpr(t0, rt); \
1552 tcg_temp_free(t0); \
1554 #endif
1555 OP_ST_ATOMIC(sc,st32,ld32s,0x3);
1556 #if defined(TARGET_MIPS64)
1557 OP_ST_ATOMIC(scd,st64,ld64,0x7);
1558 #endif
1559 #undef OP_ST_ATOMIC
1561 static void gen_base_offset_addr (DisasContext *ctx, TCGv addr,
1562 int base, int16_t offset)
1564 if (base == 0) {
1565 tcg_gen_movi_tl(addr, offset);
1566 } else if (offset == 0) {
1567 gen_load_gpr(addr, base);
1568 } else {
1569 tcg_gen_movi_tl(addr, offset);
1570 gen_op_addr_add(ctx, addr, cpu_gpr[base], addr);
1574 static target_ulong pc_relative_pc (DisasContext *ctx)
1576 target_ulong pc = ctx->pc;
1578 if (ctx->hflags & MIPS_HFLAG_BMASK) {
1579 int branch_bytes = ctx->hflags & MIPS_HFLAG_BDS16 ? 2 : 4;
1581 pc -= branch_bytes;
1584 pc &= ~(target_ulong)3;
1585 return pc;
1588 /* Load */
1589 static void gen_ld(DisasContext *ctx, uint32_t opc,
1590 int rt, int base, int16_t offset)
1592 const char *opn = "ld";
1593 TCGv t0, t1, t2;
1595 if (rt == 0 && ctx->insn_flags & (INSN_LOONGSON2E | INSN_LOONGSON2F)) {
1596 /* Loongson CPU uses a load to zero register for prefetch.
1597 We emulate it as a NOP. On other CPU we must perform the
1598 actual memory access. */
1599 MIPS_DEBUG("NOP");
1600 return;
1603 t0 = tcg_temp_new();
1604 gen_base_offset_addr(ctx, t0, base, offset);
1606 switch (opc) {
1607 #if defined(TARGET_MIPS64)
1608 case OPC_LWU:
1609 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TEUL);
1610 gen_store_gpr(t0, rt);
1611 opn = "lwu";
1612 break;
1613 case OPC_LD:
1614 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TEQ);
1615 gen_store_gpr(t0, rt);
1616 opn = "ld";
1617 break;
1618 case OPC_LLD:
1619 save_cpu_state(ctx, 1);
1620 op_ld_lld(t0, t0, ctx);
1621 gen_store_gpr(t0, rt);
1622 opn = "lld";
1623 break;
1624 case OPC_LDL:
1625 t1 = tcg_temp_new();
1626 tcg_gen_andi_tl(t1, t0, 7);
1627 #ifndef TARGET_WORDS_BIGENDIAN
1628 tcg_gen_xori_tl(t1, t1, 7);
1629 #endif
1630 tcg_gen_shli_tl(t1, t1, 3);
1631 tcg_gen_andi_tl(t0, t0, ~7);
1632 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TEQ);
1633 tcg_gen_shl_tl(t0, t0, t1);
1634 tcg_gen_xori_tl(t1, t1, 63);
1635 t2 = tcg_const_tl(0x7fffffffffffffffull);
1636 tcg_gen_shr_tl(t2, t2, t1);
1637 gen_load_gpr(t1, rt);
1638 tcg_gen_and_tl(t1, t1, t2);
1639 tcg_temp_free(t2);
1640 tcg_gen_or_tl(t0, t0, t1);
1641 tcg_temp_free(t1);
1642 gen_store_gpr(t0, rt);
1643 opn = "ldl";
1644 break;
1645 case OPC_LDR:
1646 t1 = tcg_temp_new();
1647 tcg_gen_andi_tl(t1, t0, 7);
1648 #ifdef TARGET_WORDS_BIGENDIAN
1649 tcg_gen_xori_tl(t1, t1, 7);
1650 #endif
1651 tcg_gen_shli_tl(t1, t1, 3);
1652 tcg_gen_andi_tl(t0, t0, ~7);
1653 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TEQ);
1654 tcg_gen_shr_tl(t0, t0, t1);
1655 tcg_gen_xori_tl(t1, t1, 63);
1656 t2 = tcg_const_tl(0xfffffffffffffffeull);
1657 tcg_gen_shl_tl(t2, t2, t1);
1658 gen_load_gpr(t1, rt);
1659 tcg_gen_and_tl(t1, t1, t2);
1660 tcg_temp_free(t2);
1661 tcg_gen_or_tl(t0, t0, t1);
1662 tcg_temp_free(t1);
1663 gen_store_gpr(t0, rt);
1664 opn = "ldr";
1665 break;
1666 case OPC_LDPC:
1667 t1 = tcg_const_tl(pc_relative_pc(ctx));
1668 gen_op_addr_add(ctx, t0, t0, t1);
1669 tcg_temp_free(t1);
1670 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TEQ);
1671 gen_store_gpr(t0, rt);
1672 opn = "ldpc";
1673 break;
1674 #endif
1675 case OPC_LWPC:
1676 t1 = tcg_const_tl(pc_relative_pc(ctx));
1677 gen_op_addr_add(ctx, t0, t0, t1);
1678 tcg_temp_free(t1);
1679 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TESL);
1680 gen_store_gpr(t0, rt);
1681 opn = "lwpc";
1682 break;
1683 case OPC_LW:
1684 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TESL);
1685 gen_store_gpr(t0, rt);
1686 opn = "lw";
1687 break;
1688 case OPC_LH:
1689 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TESW);
1690 gen_store_gpr(t0, rt);
1691 opn = "lh";
1692 break;
1693 case OPC_LHU:
1694 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TEUW);
1695 gen_store_gpr(t0, rt);
1696 opn = "lhu";
1697 break;
1698 case OPC_LB:
1699 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_SB);
1700 gen_store_gpr(t0, rt);
1701 opn = "lb";
1702 break;
1703 case OPC_LBU:
1704 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_UB);
1705 gen_store_gpr(t0, rt);
1706 opn = "lbu";
1707 break;
1708 case OPC_LWL:
1709 t1 = tcg_temp_new();
1710 tcg_gen_andi_tl(t1, t0, 3);
1711 #ifndef TARGET_WORDS_BIGENDIAN
1712 tcg_gen_xori_tl(t1, t1, 3);
1713 #endif
1714 tcg_gen_shli_tl(t1, t1, 3);
1715 tcg_gen_andi_tl(t0, t0, ~3);
1716 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TEUL);
1717 tcg_gen_shl_tl(t0, t0, t1);
1718 tcg_gen_xori_tl(t1, t1, 31);
1719 t2 = tcg_const_tl(0x7fffffffull);
1720 tcg_gen_shr_tl(t2, t2, t1);
1721 gen_load_gpr(t1, rt);
1722 tcg_gen_and_tl(t1, t1, t2);
1723 tcg_temp_free(t2);
1724 tcg_gen_or_tl(t0, t0, t1);
1725 tcg_temp_free(t1);
1726 tcg_gen_ext32s_tl(t0, t0);
1727 gen_store_gpr(t0, rt);
1728 opn = "lwl";
1729 break;
1730 case OPC_LWR:
1731 t1 = tcg_temp_new();
1732 tcg_gen_andi_tl(t1, t0, 3);
1733 #ifdef TARGET_WORDS_BIGENDIAN
1734 tcg_gen_xori_tl(t1, t1, 3);
1735 #endif
1736 tcg_gen_shli_tl(t1, t1, 3);
1737 tcg_gen_andi_tl(t0, t0, ~3);
1738 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TEUL);
1739 tcg_gen_shr_tl(t0, t0, t1);
1740 tcg_gen_xori_tl(t1, t1, 31);
1741 t2 = tcg_const_tl(0xfffffffeull);
1742 tcg_gen_shl_tl(t2, t2, t1);
1743 gen_load_gpr(t1, rt);
1744 tcg_gen_and_tl(t1, t1, t2);
1745 tcg_temp_free(t2);
1746 tcg_gen_or_tl(t0, t0, t1);
1747 tcg_temp_free(t1);
1748 tcg_gen_ext32s_tl(t0, t0);
1749 gen_store_gpr(t0, rt);
1750 opn = "lwr";
1751 break;
1752 case OPC_LL:
1753 save_cpu_state(ctx, 1);
1754 op_ld_ll(t0, t0, ctx);
1755 gen_store_gpr(t0, rt);
1756 opn = "ll";
1757 break;
1759 (void)opn; /* avoid a compiler warning */
1760 MIPS_DEBUG("%s %s, %d(%s)", opn, regnames[rt], offset, regnames[base]);
1761 tcg_temp_free(t0);
1764 /* Store */
1765 static void gen_st (DisasContext *ctx, uint32_t opc, int rt,
1766 int base, int16_t offset)
1768 const char *opn = "st";
1769 TCGv t0 = tcg_temp_new();
1770 TCGv t1 = tcg_temp_new();
1772 gen_base_offset_addr(ctx, t0, base, offset);
1773 gen_load_gpr(t1, rt);
1774 switch (opc) {
1775 #if defined(TARGET_MIPS64)
1776 case OPC_SD:
1777 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEQ);
1778 opn = "sd";
1779 break;
1780 case OPC_SDL:
1781 save_cpu_state(ctx, 1);
1782 gen_helper_0e2i(sdl, t1, t0, ctx->mem_idx);
1783 opn = "sdl";
1784 break;
1785 case OPC_SDR:
1786 save_cpu_state(ctx, 1);
1787 gen_helper_0e2i(sdr, t1, t0, ctx->mem_idx);
1788 opn = "sdr";
1789 break;
1790 #endif
1791 case OPC_SW:
1792 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL);
1793 opn = "sw";
1794 break;
1795 case OPC_SH:
1796 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUW);
1797 opn = "sh";
1798 break;
1799 case OPC_SB:
1800 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_8);
1801 opn = "sb";
1802 break;
1803 case OPC_SWL:
1804 save_cpu_state(ctx, 1);
1805 gen_helper_0e2i(swl, t1, t0, ctx->mem_idx);
1806 opn = "swl";
1807 break;
1808 case OPC_SWR:
1809 save_cpu_state(ctx, 1);
1810 gen_helper_0e2i(swr, t1, t0, ctx->mem_idx);
1811 opn = "swr";
1812 break;
1814 (void)opn; /* avoid a compiler warning */
1815 MIPS_DEBUG("%s %s, %d(%s)", opn, regnames[rt], offset, regnames[base]);
1816 tcg_temp_free(t0);
1817 tcg_temp_free(t1);
1821 /* Store conditional */
1822 static void gen_st_cond (DisasContext *ctx, uint32_t opc, int rt,
1823 int base, int16_t offset)
1825 const char *opn = "st_cond";
1826 TCGv t0, t1;
1828 #ifdef CONFIG_USER_ONLY
1829 t0 = tcg_temp_local_new();
1830 t1 = tcg_temp_local_new();
1831 #else
1832 t0 = tcg_temp_new();
1833 t1 = tcg_temp_new();
1834 #endif
1835 gen_base_offset_addr(ctx, t0, base, offset);
1836 gen_load_gpr(t1, rt);
1837 switch (opc) {
1838 #if defined(TARGET_MIPS64)
1839 case OPC_SCD:
1840 save_cpu_state(ctx, 1);
1841 op_st_scd(t1, t0, rt, ctx);
1842 opn = "scd";
1843 break;
1844 #endif
1845 case OPC_SC:
1846 save_cpu_state(ctx, 1);
1847 op_st_sc(t1, t0, rt, ctx);
1848 opn = "sc";
1849 break;
1851 (void)opn; /* avoid a compiler warning */
1852 MIPS_DEBUG("%s %s, %d(%s)", opn, regnames[rt], offset, regnames[base]);
1853 tcg_temp_free(t1);
1854 tcg_temp_free(t0);
1857 /* Load and store */
1858 static void gen_flt_ldst (DisasContext *ctx, uint32_t opc, int ft,
1859 int base, int16_t offset)
1861 const char *opn = "flt_ldst";
1862 TCGv t0 = tcg_temp_new();
1864 gen_base_offset_addr(ctx, t0, base, offset);
1865 /* Don't do NOP if destination is zero: we must perform the actual
1866 memory access. */
1867 switch (opc) {
1868 case OPC_LWC1:
1870 TCGv_i32 fp0 = tcg_temp_new_i32();
1871 tcg_gen_qemu_ld_i32(fp0, t0, ctx->mem_idx, MO_TESL);
1872 gen_store_fpr32(fp0, ft);
1873 tcg_temp_free_i32(fp0);
1875 opn = "lwc1";
1876 break;
1877 case OPC_SWC1:
1879 TCGv_i32 fp0 = tcg_temp_new_i32();
1880 gen_load_fpr32(fp0, ft);
1881 tcg_gen_qemu_st_i32(fp0, t0, ctx->mem_idx, MO_TEUL);
1882 tcg_temp_free_i32(fp0);
1884 opn = "swc1";
1885 break;
1886 case OPC_LDC1:
1888 TCGv_i64 fp0 = tcg_temp_new_i64();
1889 tcg_gen_qemu_ld_i64(fp0, t0, ctx->mem_idx, MO_TEQ);
1890 gen_store_fpr64(ctx, fp0, ft);
1891 tcg_temp_free_i64(fp0);
1893 opn = "ldc1";
1894 break;
1895 case OPC_SDC1:
1897 TCGv_i64 fp0 = tcg_temp_new_i64();
1898 gen_load_fpr64(ctx, fp0, ft);
1899 tcg_gen_qemu_st_i64(fp0, t0, ctx->mem_idx, MO_TEQ);
1900 tcg_temp_free_i64(fp0);
1902 opn = "sdc1";
1903 break;
1904 default:
1905 MIPS_INVAL(opn);
1906 generate_exception(ctx, EXCP_RI);
1907 goto out;
1909 (void)opn; /* avoid a compiler warning */
1910 MIPS_DEBUG("%s %s, %d(%s)", opn, fregnames[ft], offset, regnames[base]);
1911 out:
1912 tcg_temp_free(t0);
1915 static void gen_cop1_ldst(CPUMIPSState *env, DisasContext *ctx,
1916 uint32_t op, int rt, int rs, int16_t imm)
1918 if (env->CP0_Config1 & (1 << CP0C1_FP)) {
1919 check_cp1_enabled(ctx);
1920 gen_flt_ldst(ctx, op, rt, rs, imm);
1921 } else {
1922 generate_exception_err(ctx, EXCP_CpU, 1);
1926 /* Arithmetic with immediate operand */
1927 static void gen_arith_imm(DisasContext *ctx, uint32_t opc,
1928 int rt, int rs, int16_t imm)
1930 target_ulong uimm = (target_long)imm; /* Sign extend to 32/64 bits */
1931 const char *opn = "imm arith";
1933 if (rt == 0 && opc != OPC_ADDI && opc != OPC_DADDI) {
1934 /* If no destination, treat it as a NOP.
1935 For addi, we must generate the overflow exception when needed. */
1936 MIPS_DEBUG("NOP");
1937 return;
1939 switch (opc) {
1940 case OPC_ADDI:
1942 TCGv t0 = tcg_temp_local_new();
1943 TCGv t1 = tcg_temp_new();
1944 TCGv t2 = tcg_temp_new();
1945 int l1 = gen_new_label();
1947 gen_load_gpr(t1, rs);
1948 tcg_gen_addi_tl(t0, t1, uimm);
1949 tcg_gen_ext32s_tl(t0, t0);
1951 tcg_gen_xori_tl(t1, t1, ~uimm);
1952 tcg_gen_xori_tl(t2, t0, uimm);
1953 tcg_gen_and_tl(t1, t1, t2);
1954 tcg_temp_free(t2);
1955 tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
1956 tcg_temp_free(t1);
1957 /* operands of same sign, result different sign */
1958 generate_exception(ctx, EXCP_OVERFLOW);
1959 gen_set_label(l1);
1960 tcg_gen_ext32s_tl(t0, t0);
1961 gen_store_gpr(t0, rt);
1962 tcg_temp_free(t0);
1964 opn = "addi";
1965 break;
1966 case OPC_ADDIU:
1967 if (rs != 0) {
1968 tcg_gen_addi_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
1969 tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]);
1970 } else {
1971 tcg_gen_movi_tl(cpu_gpr[rt], uimm);
1973 opn = "addiu";
1974 break;
1975 #if defined(TARGET_MIPS64)
1976 case OPC_DADDI:
1978 TCGv t0 = tcg_temp_local_new();
1979 TCGv t1 = tcg_temp_new();
1980 TCGv t2 = tcg_temp_new();
1981 int l1 = gen_new_label();
1983 gen_load_gpr(t1, rs);
1984 tcg_gen_addi_tl(t0, t1, uimm);
1986 tcg_gen_xori_tl(t1, t1, ~uimm);
1987 tcg_gen_xori_tl(t2, t0, uimm);
1988 tcg_gen_and_tl(t1, t1, t2);
1989 tcg_temp_free(t2);
1990 tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
1991 tcg_temp_free(t1);
1992 /* operands of same sign, result different sign */
1993 generate_exception(ctx, EXCP_OVERFLOW);
1994 gen_set_label(l1);
1995 gen_store_gpr(t0, rt);
1996 tcg_temp_free(t0);
1998 opn = "daddi";
1999 break;
2000 case OPC_DADDIU:
2001 if (rs != 0) {
2002 tcg_gen_addi_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
2003 } else {
2004 tcg_gen_movi_tl(cpu_gpr[rt], uimm);
2006 opn = "daddiu";
2007 break;
2008 #endif
2010 (void)opn; /* avoid a compiler warning */
2011 MIPS_DEBUG("%s %s, %s, " TARGET_FMT_lx, opn, regnames[rt], regnames[rs], uimm);
2014 /* Logic with immediate operand */
2015 static void gen_logic_imm(DisasContext *ctx, uint32_t opc,
2016 int rt, int rs, int16_t imm)
2018 target_ulong uimm;
2020 if (rt == 0) {
2021 /* If no destination, treat it as a NOP. */
2022 MIPS_DEBUG("NOP");
2023 return;
2025 uimm = (uint16_t)imm;
2026 switch (opc) {
2027 case OPC_ANDI:
2028 if (likely(rs != 0))
2029 tcg_gen_andi_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
2030 else
2031 tcg_gen_movi_tl(cpu_gpr[rt], 0);
2032 MIPS_DEBUG("andi %s, %s, " TARGET_FMT_lx, regnames[rt],
2033 regnames[rs], uimm);
2034 break;
2035 case OPC_ORI:
2036 if (rs != 0)
2037 tcg_gen_ori_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
2038 else
2039 tcg_gen_movi_tl(cpu_gpr[rt], uimm);
2040 MIPS_DEBUG("ori %s, %s, " TARGET_FMT_lx, regnames[rt],
2041 regnames[rs], uimm);
2042 break;
2043 case OPC_XORI:
2044 if (likely(rs != 0))
2045 tcg_gen_xori_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
2046 else
2047 tcg_gen_movi_tl(cpu_gpr[rt], uimm);
2048 MIPS_DEBUG("xori %s, %s, " TARGET_FMT_lx, regnames[rt],
2049 regnames[rs], uimm);
2050 break;
2051 case OPC_LUI:
2052 tcg_gen_movi_tl(cpu_gpr[rt], imm << 16);
2053 MIPS_DEBUG("lui %s, " TARGET_FMT_lx, regnames[rt], uimm);
2054 break;
2056 default:
2057 MIPS_DEBUG("Unknown logical immediate opcode %08x", opc);
2058 break;
2062 /* Set on less than with immediate operand */
2063 static void gen_slt_imm(DisasContext *ctx, uint32_t opc,
2064 int rt, int rs, int16_t imm)
2066 target_ulong uimm = (target_long)imm; /* Sign extend to 32/64 bits */
2067 const char *opn = "imm arith";
2068 TCGv t0;
2070 if (rt == 0) {
2071 /* If no destination, treat it as a NOP. */
2072 MIPS_DEBUG("NOP");
2073 return;
2075 t0 = tcg_temp_new();
2076 gen_load_gpr(t0, rs);
2077 switch (opc) {
2078 case OPC_SLTI:
2079 tcg_gen_setcondi_tl(TCG_COND_LT, cpu_gpr[rt], t0, uimm);
2080 opn = "slti";
2081 break;
2082 case OPC_SLTIU:
2083 tcg_gen_setcondi_tl(TCG_COND_LTU, cpu_gpr[rt], t0, uimm);
2084 opn = "sltiu";
2085 break;
2087 (void)opn; /* avoid a compiler warning */
2088 MIPS_DEBUG("%s %s, %s, " TARGET_FMT_lx, opn, regnames[rt], regnames[rs], uimm);
2089 tcg_temp_free(t0);
2092 /* Shifts with immediate operand */
2093 static void gen_shift_imm(DisasContext *ctx, uint32_t opc,
2094 int rt, int rs, int16_t imm)
2096 target_ulong uimm = ((uint16_t)imm) & 0x1f;
2097 const char *opn = "imm shift";
2098 TCGv t0;
2100 if (rt == 0) {
2101 /* If no destination, treat it as a NOP. */
2102 MIPS_DEBUG("NOP");
2103 return;
2106 t0 = tcg_temp_new();
2107 gen_load_gpr(t0, rs);
2108 switch (opc) {
2109 case OPC_SLL:
2110 tcg_gen_shli_tl(t0, t0, uimm);
2111 tcg_gen_ext32s_tl(cpu_gpr[rt], t0);
2112 opn = "sll";
2113 break;
2114 case OPC_SRA:
2115 tcg_gen_sari_tl(cpu_gpr[rt], t0, uimm);
2116 opn = "sra";
2117 break;
2118 case OPC_SRL:
2119 if (uimm != 0) {
2120 tcg_gen_ext32u_tl(t0, t0);
2121 tcg_gen_shri_tl(cpu_gpr[rt], t0, uimm);
2122 } else {
2123 tcg_gen_ext32s_tl(cpu_gpr[rt], t0);
2125 opn = "srl";
2126 break;
2127 case OPC_ROTR:
2128 if (uimm != 0) {
2129 TCGv_i32 t1 = tcg_temp_new_i32();
2131 tcg_gen_trunc_tl_i32(t1, t0);
2132 tcg_gen_rotri_i32(t1, t1, uimm);
2133 tcg_gen_ext_i32_tl(cpu_gpr[rt], t1);
2134 tcg_temp_free_i32(t1);
2135 } else {
2136 tcg_gen_ext32s_tl(cpu_gpr[rt], t0);
2138 opn = "rotr";
2139 break;
2140 #if defined(TARGET_MIPS64)
2141 case OPC_DSLL:
2142 tcg_gen_shli_tl(cpu_gpr[rt], t0, uimm);
2143 opn = "dsll";
2144 break;
2145 case OPC_DSRA:
2146 tcg_gen_sari_tl(cpu_gpr[rt], t0, uimm);
2147 opn = "dsra";
2148 break;
2149 case OPC_DSRL:
2150 tcg_gen_shri_tl(cpu_gpr[rt], t0, uimm);
2151 opn = "dsrl";
2152 break;
2153 case OPC_DROTR:
2154 if (uimm != 0) {
2155 tcg_gen_rotri_tl(cpu_gpr[rt], t0, uimm);
2156 } else {
2157 tcg_gen_mov_tl(cpu_gpr[rt], t0);
2159 opn = "drotr";
2160 break;
2161 case OPC_DSLL32:
2162 tcg_gen_shli_tl(cpu_gpr[rt], t0, uimm + 32);
2163 opn = "dsll32";
2164 break;
2165 case OPC_DSRA32:
2166 tcg_gen_sari_tl(cpu_gpr[rt], t0, uimm + 32);
2167 opn = "dsra32";
2168 break;
2169 case OPC_DSRL32:
2170 tcg_gen_shri_tl(cpu_gpr[rt], t0, uimm + 32);
2171 opn = "dsrl32";
2172 break;
2173 case OPC_DROTR32:
2174 tcg_gen_rotri_tl(cpu_gpr[rt], t0, uimm + 32);
2175 opn = "drotr32";
2176 break;
2177 #endif
2179 (void)opn; /* avoid a compiler warning */
2180 MIPS_DEBUG("%s %s, %s, " TARGET_FMT_lx, opn, regnames[rt], regnames[rs], uimm);
2181 tcg_temp_free(t0);
2184 /* Arithmetic */
2185 static void gen_arith(DisasContext *ctx, uint32_t opc,
2186 int rd, int rs, int rt)
2188 const char *opn = "arith";
2190 if (rd == 0 && opc != OPC_ADD && opc != OPC_SUB
2191 && opc != OPC_DADD && opc != OPC_DSUB) {
2192 /* If no destination, treat it as a NOP.
2193 For add & sub, we must generate the overflow exception when needed. */
2194 MIPS_DEBUG("NOP");
2195 return;
2198 switch (opc) {
2199 case OPC_ADD:
2201 TCGv t0 = tcg_temp_local_new();
2202 TCGv t1 = tcg_temp_new();
2203 TCGv t2 = tcg_temp_new();
2204 int l1 = gen_new_label();
2206 gen_load_gpr(t1, rs);
2207 gen_load_gpr(t2, rt);
2208 tcg_gen_add_tl(t0, t1, t2);
2209 tcg_gen_ext32s_tl(t0, t0);
2210 tcg_gen_xor_tl(t1, t1, t2);
2211 tcg_gen_xor_tl(t2, t0, t2);
2212 tcg_gen_andc_tl(t1, t2, t1);
2213 tcg_temp_free(t2);
2214 tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
2215 tcg_temp_free(t1);
2216 /* operands of same sign, result different sign */
2217 generate_exception(ctx, EXCP_OVERFLOW);
2218 gen_set_label(l1);
2219 gen_store_gpr(t0, rd);
2220 tcg_temp_free(t0);
2222 opn = "add";
2223 break;
2224 case OPC_ADDU:
2225 if (rs != 0 && rt != 0) {
2226 tcg_gen_add_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2227 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
2228 } else if (rs == 0 && rt != 0) {
2229 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rt]);
2230 } else if (rs != 0 && rt == 0) {
2231 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
2232 } else {
2233 tcg_gen_movi_tl(cpu_gpr[rd], 0);
2235 opn = "addu";
2236 break;
2237 case OPC_SUB:
2239 TCGv t0 = tcg_temp_local_new();
2240 TCGv t1 = tcg_temp_new();
2241 TCGv t2 = tcg_temp_new();
2242 int l1 = gen_new_label();
2244 gen_load_gpr(t1, rs);
2245 gen_load_gpr(t2, rt);
2246 tcg_gen_sub_tl(t0, t1, t2);
2247 tcg_gen_ext32s_tl(t0, t0);
2248 tcg_gen_xor_tl(t2, t1, t2);
2249 tcg_gen_xor_tl(t1, t0, t1);
2250 tcg_gen_and_tl(t1, t1, t2);
2251 tcg_temp_free(t2);
2252 tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
2253 tcg_temp_free(t1);
2254 /* operands of different sign, first operand and result different sign */
2255 generate_exception(ctx, EXCP_OVERFLOW);
2256 gen_set_label(l1);
2257 gen_store_gpr(t0, rd);
2258 tcg_temp_free(t0);
2260 opn = "sub";
2261 break;
2262 case OPC_SUBU:
2263 if (rs != 0 && rt != 0) {
2264 tcg_gen_sub_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2265 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
2266 } else if (rs == 0 && rt != 0) {
2267 tcg_gen_neg_tl(cpu_gpr[rd], cpu_gpr[rt]);
2268 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
2269 } else if (rs != 0 && rt == 0) {
2270 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
2271 } else {
2272 tcg_gen_movi_tl(cpu_gpr[rd], 0);
2274 opn = "subu";
2275 break;
2276 #if defined(TARGET_MIPS64)
2277 case OPC_DADD:
2279 TCGv t0 = tcg_temp_local_new();
2280 TCGv t1 = tcg_temp_new();
2281 TCGv t2 = tcg_temp_new();
2282 int l1 = gen_new_label();
2284 gen_load_gpr(t1, rs);
2285 gen_load_gpr(t2, rt);
2286 tcg_gen_add_tl(t0, t1, t2);
2287 tcg_gen_xor_tl(t1, t1, t2);
2288 tcg_gen_xor_tl(t2, t0, t2);
2289 tcg_gen_andc_tl(t1, t2, t1);
2290 tcg_temp_free(t2);
2291 tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
2292 tcg_temp_free(t1);
2293 /* operands of same sign, result different sign */
2294 generate_exception(ctx, EXCP_OVERFLOW);
2295 gen_set_label(l1);
2296 gen_store_gpr(t0, rd);
2297 tcg_temp_free(t0);
2299 opn = "dadd";
2300 break;
2301 case OPC_DADDU:
2302 if (rs != 0 && rt != 0) {
2303 tcg_gen_add_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2304 } else if (rs == 0 && rt != 0) {
2305 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rt]);
2306 } else if (rs != 0 && rt == 0) {
2307 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
2308 } else {
2309 tcg_gen_movi_tl(cpu_gpr[rd], 0);
2311 opn = "daddu";
2312 break;
2313 case OPC_DSUB:
2315 TCGv t0 = tcg_temp_local_new();
2316 TCGv t1 = tcg_temp_new();
2317 TCGv t2 = tcg_temp_new();
2318 int l1 = gen_new_label();
2320 gen_load_gpr(t1, rs);
2321 gen_load_gpr(t2, rt);
2322 tcg_gen_sub_tl(t0, t1, t2);
2323 tcg_gen_xor_tl(t2, t1, t2);
2324 tcg_gen_xor_tl(t1, t0, t1);
2325 tcg_gen_and_tl(t1, t1, t2);
2326 tcg_temp_free(t2);
2327 tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
2328 tcg_temp_free(t1);
2329 /* operands of different sign, first operand and result different sign */
2330 generate_exception(ctx, EXCP_OVERFLOW);
2331 gen_set_label(l1);
2332 gen_store_gpr(t0, rd);
2333 tcg_temp_free(t0);
2335 opn = "dsub";
2336 break;
2337 case OPC_DSUBU:
2338 if (rs != 0 && rt != 0) {
2339 tcg_gen_sub_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2340 } else if (rs == 0 && rt != 0) {
2341 tcg_gen_neg_tl(cpu_gpr[rd], cpu_gpr[rt]);
2342 } else if (rs != 0 && rt == 0) {
2343 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
2344 } else {
2345 tcg_gen_movi_tl(cpu_gpr[rd], 0);
2347 opn = "dsubu";
2348 break;
2349 #endif
2350 case OPC_MUL:
2351 if (likely(rs != 0 && rt != 0)) {
2352 tcg_gen_mul_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2353 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
2354 } else {
2355 tcg_gen_movi_tl(cpu_gpr[rd], 0);
2357 opn = "mul";
2358 break;
2360 (void)opn; /* avoid a compiler warning */
2361 MIPS_DEBUG("%s %s, %s, %s", opn, regnames[rd], regnames[rs], regnames[rt]);
2364 /* Conditional move */
2365 static void gen_cond_move(DisasContext *ctx, uint32_t opc,
2366 int rd, int rs, int rt)
2368 const char *opn = "cond move";
2369 TCGv t0, t1, t2;
2371 if (rd == 0) {
2372 /* If no destination, treat it as a NOP. */
2373 MIPS_DEBUG("NOP");
2374 return;
2377 t0 = tcg_temp_new();
2378 gen_load_gpr(t0, rt);
2379 t1 = tcg_const_tl(0);
2380 t2 = tcg_temp_new();
2381 gen_load_gpr(t2, rs);
2382 switch (opc) {
2383 case OPC_MOVN:
2384 tcg_gen_movcond_tl(TCG_COND_NE, cpu_gpr[rd], t0, t1, t2, cpu_gpr[rd]);
2385 opn = "movn";
2386 break;
2387 case OPC_MOVZ:
2388 tcg_gen_movcond_tl(TCG_COND_EQ, cpu_gpr[rd], t0, t1, t2, cpu_gpr[rd]);
2389 opn = "movz";
2390 break;
2392 tcg_temp_free(t2);
2393 tcg_temp_free(t1);
2394 tcg_temp_free(t0);
2396 (void)opn; /* avoid a compiler warning */
2397 MIPS_DEBUG("%s %s, %s, %s", opn, regnames[rd], regnames[rs], regnames[rt]);
2400 /* Logic */
2401 static void gen_logic(DisasContext *ctx, uint32_t opc,
2402 int rd, int rs, int rt)
2404 const char *opn = "logic";
2406 if (rd == 0) {
2407 /* If no destination, treat it as a NOP. */
2408 MIPS_DEBUG("NOP");
2409 return;
2412 switch (opc) {
2413 case OPC_AND:
2414 if (likely(rs != 0 && rt != 0)) {
2415 tcg_gen_and_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2416 } else {
2417 tcg_gen_movi_tl(cpu_gpr[rd], 0);
2419 opn = "and";
2420 break;
2421 case OPC_NOR:
2422 if (rs != 0 && rt != 0) {
2423 tcg_gen_nor_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2424 } else if (rs == 0 && rt != 0) {
2425 tcg_gen_not_tl(cpu_gpr[rd], cpu_gpr[rt]);
2426 } else if (rs != 0 && rt == 0) {
2427 tcg_gen_not_tl(cpu_gpr[rd], cpu_gpr[rs]);
2428 } else {
2429 tcg_gen_movi_tl(cpu_gpr[rd], ~((target_ulong)0));
2431 opn = "nor";
2432 break;
2433 case OPC_OR:
2434 if (likely(rs != 0 && rt != 0)) {
2435 tcg_gen_or_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2436 } else if (rs == 0 && rt != 0) {
2437 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rt]);
2438 } else if (rs != 0 && rt == 0) {
2439 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
2440 } else {
2441 tcg_gen_movi_tl(cpu_gpr[rd], 0);
2443 opn = "or";
2444 break;
2445 case OPC_XOR:
2446 if (likely(rs != 0 && rt != 0)) {
2447 tcg_gen_xor_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2448 } else if (rs == 0 && rt != 0) {
2449 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rt]);
2450 } else if (rs != 0 && rt == 0) {
2451 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
2452 } else {
2453 tcg_gen_movi_tl(cpu_gpr[rd], 0);
2455 opn = "xor";
2456 break;
2458 (void)opn; /* avoid a compiler warning */
2459 MIPS_DEBUG("%s %s, %s, %s", opn, regnames[rd], regnames[rs], regnames[rt]);
2462 /* Set on lower than */
2463 static void gen_slt(DisasContext *ctx, uint32_t opc,
2464 int rd, int rs, int rt)
2466 const char *opn = "slt";
2467 TCGv t0, t1;
2469 if (rd == 0) {
2470 /* If no destination, treat it as a NOP. */
2471 MIPS_DEBUG("NOP");
2472 return;
2475 t0 = tcg_temp_new();
2476 t1 = tcg_temp_new();
2477 gen_load_gpr(t0, rs);
2478 gen_load_gpr(t1, rt);
2479 switch (opc) {
2480 case OPC_SLT:
2481 tcg_gen_setcond_tl(TCG_COND_LT, cpu_gpr[rd], t0, t1);
2482 opn = "slt";
2483 break;
2484 case OPC_SLTU:
2485 tcg_gen_setcond_tl(TCG_COND_LTU, cpu_gpr[rd], t0, t1);
2486 opn = "sltu";
2487 break;
2489 (void)opn; /* avoid a compiler warning */
2490 MIPS_DEBUG("%s %s, %s, %s", opn, regnames[rd], regnames[rs], regnames[rt]);
2491 tcg_temp_free(t0);
2492 tcg_temp_free(t1);
2495 /* Shifts */
2496 static void gen_shift(DisasContext *ctx, uint32_t opc,
2497 int rd, int rs, int rt)
2499 const char *opn = "shifts";
2500 TCGv t0, t1;
2502 if (rd == 0) {
2503 /* If no destination, treat it as a NOP.
2504 For add & sub, we must generate the overflow exception when needed. */
2505 MIPS_DEBUG("NOP");
2506 return;
2509 t0 = tcg_temp_new();
2510 t1 = tcg_temp_new();
2511 gen_load_gpr(t0, rs);
2512 gen_load_gpr(t1, rt);
2513 switch (opc) {
2514 case OPC_SLLV:
2515 tcg_gen_andi_tl(t0, t0, 0x1f);
2516 tcg_gen_shl_tl(t0, t1, t0);
2517 tcg_gen_ext32s_tl(cpu_gpr[rd], t0);
2518 opn = "sllv";
2519 break;
2520 case OPC_SRAV:
2521 tcg_gen_andi_tl(t0, t0, 0x1f);
2522 tcg_gen_sar_tl(cpu_gpr[rd], t1, t0);
2523 opn = "srav";
2524 break;
2525 case OPC_SRLV:
2526 tcg_gen_ext32u_tl(t1, t1);
2527 tcg_gen_andi_tl(t0, t0, 0x1f);
2528 tcg_gen_shr_tl(t0, t1, t0);
2529 tcg_gen_ext32s_tl(cpu_gpr[rd], t0);
2530 opn = "srlv";
2531 break;
2532 case OPC_ROTRV:
2534 TCGv_i32 t2 = tcg_temp_new_i32();
2535 TCGv_i32 t3 = tcg_temp_new_i32();
2537 tcg_gen_trunc_tl_i32(t2, t0);
2538 tcg_gen_trunc_tl_i32(t3, t1);
2539 tcg_gen_andi_i32(t2, t2, 0x1f);
2540 tcg_gen_rotr_i32(t2, t3, t2);
2541 tcg_gen_ext_i32_tl(cpu_gpr[rd], t2);
2542 tcg_temp_free_i32(t2);
2543 tcg_temp_free_i32(t3);
2544 opn = "rotrv";
2546 break;
2547 #if defined(TARGET_MIPS64)
2548 case OPC_DSLLV:
2549 tcg_gen_andi_tl(t0, t0, 0x3f);
2550 tcg_gen_shl_tl(cpu_gpr[rd], t1, t0);
2551 opn = "dsllv";
2552 break;
2553 case OPC_DSRAV:
2554 tcg_gen_andi_tl(t0, t0, 0x3f);
2555 tcg_gen_sar_tl(cpu_gpr[rd], t1, t0);
2556 opn = "dsrav";
2557 break;
2558 case OPC_DSRLV:
2559 tcg_gen_andi_tl(t0, t0, 0x3f);
2560 tcg_gen_shr_tl(cpu_gpr[rd], t1, t0);
2561 opn = "dsrlv";
2562 break;
2563 case OPC_DROTRV:
2564 tcg_gen_andi_tl(t0, t0, 0x3f);
2565 tcg_gen_rotr_tl(cpu_gpr[rd], t1, t0);
2566 opn = "drotrv";
2567 break;
2568 #endif
2570 (void)opn; /* avoid a compiler warning */
2571 MIPS_DEBUG("%s %s, %s, %s", opn, regnames[rd], regnames[rs], regnames[rt]);
2572 tcg_temp_free(t0);
2573 tcg_temp_free(t1);
2576 /* Arithmetic on HI/LO registers */
2577 static void gen_HILO(DisasContext *ctx, uint32_t opc, int acc, int reg)
2579 const char *opn = "hilo";
2581 if (reg == 0 && (opc == OPC_MFHI || opc == OPC_MFLO)) {
2582 /* Treat as NOP. */
2583 MIPS_DEBUG("NOP");
2584 return;
2587 if (acc != 0) {
2588 check_dsp(ctx);
2591 switch (opc) {
2592 case OPC_MFHI:
2593 #if defined(TARGET_MIPS64)
2594 if (acc != 0) {
2595 tcg_gen_ext32s_tl(cpu_gpr[reg], cpu_HI[acc]);
2596 } else
2597 #endif
2599 tcg_gen_mov_tl(cpu_gpr[reg], cpu_HI[acc]);
2601 opn = "mfhi";
2602 break;
2603 case OPC_MFLO:
2604 #if defined(TARGET_MIPS64)
2605 if (acc != 0) {
2606 tcg_gen_ext32s_tl(cpu_gpr[reg], cpu_LO[acc]);
2607 } else
2608 #endif
2610 tcg_gen_mov_tl(cpu_gpr[reg], cpu_LO[acc]);
2612 opn = "mflo";
2613 break;
2614 case OPC_MTHI:
2615 if (reg != 0) {
2616 #if defined(TARGET_MIPS64)
2617 if (acc != 0) {
2618 tcg_gen_ext32s_tl(cpu_HI[acc], cpu_gpr[reg]);
2619 } else
2620 #endif
2622 tcg_gen_mov_tl(cpu_HI[acc], cpu_gpr[reg]);
2624 } else {
2625 tcg_gen_movi_tl(cpu_HI[acc], 0);
2627 opn = "mthi";
2628 break;
2629 case OPC_MTLO:
2630 if (reg != 0) {
2631 #if defined(TARGET_MIPS64)
2632 if (acc != 0) {
2633 tcg_gen_ext32s_tl(cpu_LO[acc], cpu_gpr[reg]);
2634 } else
2635 #endif
2637 tcg_gen_mov_tl(cpu_LO[acc], cpu_gpr[reg]);
2639 } else {
2640 tcg_gen_movi_tl(cpu_LO[acc], 0);
2642 opn = "mtlo";
2643 break;
2645 (void)opn; /* avoid a compiler warning */
2646 MIPS_DEBUG("%s %s", opn, regnames[reg]);
2649 static void gen_muldiv(DisasContext *ctx, uint32_t opc,
2650 int acc, int rs, int rt)
2652 const char *opn = "mul/div";
2653 TCGv t0, t1;
2655 t0 = tcg_temp_new();
2656 t1 = tcg_temp_new();
2658 gen_load_gpr(t0, rs);
2659 gen_load_gpr(t1, rt);
2661 if (acc != 0) {
2662 check_dsp(ctx);
2665 switch (opc) {
2666 case OPC_DIV:
2668 TCGv t2 = tcg_temp_new();
2669 TCGv t3 = tcg_temp_new();
2670 tcg_gen_ext32s_tl(t0, t0);
2671 tcg_gen_ext32s_tl(t1, t1);
2672 tcg_gen_setcondi_tl(TCG_COND_EQ, t2, t0, INT_MIN);
2673 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, -1);
2674 tcg_gen_and_tl(t2, t2, t3);
2675 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, 0);
2676 tcg_gen_or_tl(t2, t2, t3);
2677 tcg_gen_movi_tl(t3, 0);
2678 tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, t3, t2, t1);
2679 tcg_gen_div_tl(cpu_LO[acc], t0, t1);
2680 tcg_gen_rem_tl(cpu_HI[acc], t0, t1);
2681 tcg_gen_ext32s_tl(cpu_LO[acc], cpu_LO[acc]);
2682 tcg_gen_ext32s_tl(cpu_HI[acc], cpu_HI[acc]);
2683 tcg_temp_free(t3);
2684 tcg_temp_free(t2);
2686 opn = "div";
2687 break;
2688 case OPC_DIVU:
2690 TCGv t2 = tcg_const_tl(0);
2691 TCGv t3 = tcg_const_tl(1);
2692 tcg_gen_ext32u_tl(t0, t0);
2693 tcg_gen_ext32u_tl(t1, t1);
2694 tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1, t2, t3, t1);
2695 tcg_gen_divu_tl(cpu_LO[acc], t0, t1);
2696 tcg_gen_remu_tl(cpu_HI[acc], t0, t1);
2697 tcg_gen_ext32s_tl(cpu_LO[acc], cpu_LO[acc]);
2698 tcg_gen_ext32s_tl(cpu_HI[acc], cpu_HI[acc]);
2699 tcg_temp_free(t3);
2700 tcg_temp_free(t2);
2702 opn = "divu";
2703 break;
2704 case OPC_MULT:
2706 TCGv_i32 t2 = tcg_temp_new_i32();
2707 TCGv_i32 t3 = tcg_temp_new_i32();
2708 tcg_gen_trunc_tl_i32(t2, t0);
2709 tcg_gen_trunc_tl_i32(t3, t1);
2710 tcg_gen_muls2_i32(t2, t3, t2, t3);
2711 tcg_gen_ext_i32_tl(cpu_LO[acc], t2);
2712 tcg_gen_ext_i32_tl(cpu_HI[acc], t3);
2713 tcg_temp_free_i32(t2);
2714 tcg_temp_free_i32(t3);
2716 opn = "mult";
2717 break;
2718 case OPC_MULTU:
2720 TCGv_i32 t2 = tcg_temp_new_i32();
2721 TCGv_i32 t3 = tcg_temp_new_i32();
2722 tcg_gen_trunc_tl_i32(t2, t0);
2723 tcg_gen_trunc_tl_i32(t3, t1);
2724 tcg_gen_mulu2_i32(t2, t3, t2, t3);
2725 tcg_gen_ext_i32_tl(cpu_LO[acc], t2);
2726 tcg_gen_ext_i32_tl(cpu_HI[acc], t3);
2727 tcg_temp_free_i32(t2);
2728 tcg_temp_free_i32(t3);
2730 opn = "multu";
2731 break;
2732 #if defined(TARGET_MIPS64)
2733 case OPC_DDIV:
2735 TCGv t2 = tcg_temp_new();
2736 TCGv t3 = tcg_temp_new();
2737 tcg_gen_setcondi_tl(TCG_COND_EQ, t2, t0, -1LL << 63);
2738 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, -1LL);
2739 tcg_gen_and_tl(t2, t2, t3);
2740 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, 0);
2741 tcg_gen_or_tl(t2, t2, t3);
2742 tcg_gen_movi_tl(t3, 0);
2743 tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, t3, t2, t1);
2744 tcg_gen_div_tl(cpu_LO[acc], t0, t1);
2745 tcg_gen_rem_tl(cpu_HI[acc], t0, t1);
2746 tcg_temp_free(t3);
2747 tcg_temp_free(t2);
2749 opn = "ddiv";
2750 break;
2751 case OPC_DDIVU:
2753 TCGv t2 = tcg_const_tl(0);
2754 TCGv t3 = tcg_const_tl(1);
2755 tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1, t2, t3, t1);
2756 tcg_gen_divu_i64(cpu_LO[acc], t0, t1);
2757 tcg_gen_remu_i64(cpu_HI[acc], t0, t1);
2758 tcg_temp_free(t3);
2759 tcg_temp_free(t2);
2761 opn = "ddivu";
2762 break;
2763 case OPC_DMULT:
2764 tcg_gen_muls2_i64(cpu_LO[acc], cpu_HI[acc], t0, t1);
2765 opn = "dmult";
2766 break;
2767 case OPC_DMULTU:
2768 tcg_gen_mulu2_i64(cpu_LO[acc], cpu_HI[acc], t0, t1);
2769 opn = "dmultu";
2770 break;
2771 #endif
2772 case OPC_MADD:
2774 TCGv_i64 t2 = tcg_temp_new_i64();
2775 TCGv_i64 t3 = tcg_temp_new_i64();
2777 tcg_gen_ext_tl_i64(t2, t0);
2778 tcg_gen_ext_tl_i64(t3, t1);
2779 tcg_gen_mul_i64(t2, t2, t3);
2780 tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]);
2781 tcg_gen_add_i64(t2, t2, t3);
2782 tcg_temp_free_i64(t3);
2783 tcg_gen_trunc_i64_tl(t0, t2);
2784 tcg_gen_shri_i64(t2, t2, 32);
2785 tcg_gen_trunc_i64_tl(t1, t2);
2786 tcg_temp_free_i64(t2);
2787 tcg_gen_ext32s_tl(cpu_LO[acc], t0);
2788 tcg_gen_ext32s_tl(cpu_HI[acc], t1);
2790 opn = "madd";
2791 break;
2792 case OPC_MADDU:
2794 TCGv_i64 t2 = tcg_temp_new_i64();
2795 TCGv_i64 t3 = tcg_temp_new_i64();
2797 tcg_gen_ext32u_tl(t0, t0);
2798 tcg_gen_ext32u_tl(t1, t1);
2799 tcg_gen_extu_tl_i64(t2, t0);
2800 tcg_gen_extu_tl_i64(t3, t1);
2801 tcg_gen_mul_i64(t2, t2, t3);
2802 tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]);
2803 tcg_gen_add_i64(t2, t2, t3);
2804 tcg_temp_free_i64(t3);
2805 tcg_gen_trunc_i64_tl(t0, t2);
2806 tcg_gen_shri_i64(t2, t2, 32);
2807 tcg_gen_trunc_i64_tl(t1, t2);
2808 tcg_temp_free_i64(t2);
2809 tcg_gen_ext32s_tl(cpu_LO[acc], t0);
2810 tcg_gen_ext32s_tl(cpu_HI[acc], t1);
2812 opn = "maddu";
2813 break;
2814 case OPC_MSUB:
2816 TCGv_i64 t2 = tcg_temp_new_i64();
2817 TCGv_i64 t3 = tcg_temp_new_i64();
2819 tcg_gen_ext_tl_i64(t2, t0);
2820 tcg_gen_ext_tl_i64(t3, t1);
2821 tcg_gen_mul_i64(t2, t2, t3);
2822 tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]);
2823 tcg_gen_sub_i64(t2, t3, t2);
2824 tcg_temp_free_i64(t3);
2825 tcg_gen_trunc_i64_tl(t0, t2);
2826 tcg_gen_shri_i64(t2, t2, 32);
2827 tcg_gen_trunc_i64_tl(t1, t2);
2828 tcg_temp_free_i64(t2);
2829 tcg_gen_ext32s_tl(cpu_LO[acc], t0);
2830 tcg_gen_ext32s_tl(cpu_HI[acc], t1);
2832 opn = "msub";
2833 break;
2834 case OPC_MSUBU:
2836 TCGv_i64 t2 = tcg_temp_new_i64();
2837 TCGv_i64 t3 = tcg_temp_new_i64();
2839 tcg_gen_ext32u_tl(t0, t0);
2840 tcg_gen_ext32u_tl(t1, t1);
2841 tcg_gen_extu_tl_i64(t2, t0);
2842 tcg_gen_extu_tl_i64(t3, t1);
2843 tcg_gen_mul_i64(t2, t2, t3);
2844 tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]);
2845 tcg_gen_sub_i64(t2, t3, t2);
2846 tcg_temp_free_i64(t3);
2847 tcg_gen_trunc_i64_tl(t0, t2);
2848 tcg_gen_shri_i64(t2, t2, 32);
2849 tcg_gen_trunc_i64_tl(t1, t2);
2850 tcg_temp_free_i64(t2);
2851 tcg_gen_ext32s_tl(cpu_LO[acc], t0);
2852 tcg_gen_ext32s_tl(cpu_HI[acc], t1);
2854 opn = "msubu";
2855 break;
2856 default:
2857 MIPS_INVAL(opn);
2858 generate_exception(ctx, EXCP_RI);
2859 goto out;
2861 (void)opn; /* avoid a compiler warning */
2862 MIPS_DEBUG("%s %s %s", opn, regnames[rs], regnames[rt]);
2863 out:
2864 tcg_temp_free(t0);
2865 tcg_temp_free(t1);
2868 static void gen_mul_vr54xx (DisasContext *ctx, uint32_t opc,
2869 int rd, int rs, int rt)
2871 const char *opn = "mul vr54xx";
2872 TCGv t0 = tcg_temp_new();
2873 TCGv t1 = tcg_temp_new();
2875 gen_load_gpr(t0, rs);
2876 gen_load_gpr(t1, rt);
2878 switch (opc) {
2879 case OPC_VR54XX_MULS:
2880 gen_helper_muls(t0, cpu_env, t0, t1);
2881 opn = "muls";
2882 break;
2883 case OPC_VR54XX_MULSU:
2884 gen_helper_mulsu(t0, cpu_env, t0, t1);
2885 opn = "mulsu";
2886 break;
2887 case OPC_VR54XX_MACC:
2888 gen_helper_macc(t0, cpu_env, t0, t1);
2889 opn = "macc";
2890 break;
2891 case OPC_VR54XX_MACCU:
2892 gen_helper_maccu(t0, cpu_env, t0, t1);
2893 opn = "maccu";
2894 break;
2895 case OPC_VR54XX_MSAC:
2896 gen_helper_msac(t0, cpu_env, t0, t1);
2897 opn = "msac";
2898 break;
2899 case OPC_VR54XX_MSACU:
2900 gen_helper_msacu(t0, cpu_env, t0, t1);
2901 opn = "msacu";
2902 break;
2903 case OPC_VR54XX_MULHI:
2904 gen_helper_mulhi(t0, cpu_env, t0, t1);
2905 opn = "mulhi";
2906 break;
2907 case OPC_VR54XX_MULHIU:
2908 gen_helper_mulhiu(t0, cpu_env, t0, t1);
2909 opn = "mulhiu";
2910 break;
2911 case OPC_VR54XX_MULSHI:
2912 gen_helper_mulshi(t0, cpu_env, t0, t1);
2913 opn = "mulshi";
2914 break;
2915 case OPC_VR54XX_MULSHIU:
2916 gen_helper_mulshiu(t0, cpu_env, t0, t1);
2917 opn = "mulshiu";
2918 break;
2919 case OPC_VR54XX_MACCHI:
2920 gen_helper_macchi(t0, cpu_env, t0, t1);
2921 opn = "macchi";
2922 break;
2923 case OPC_VR54XX_MACCHIU:
2924 gen_helper_macchiu(t0, cpu_env, t0, t1);
2925 opn = "macchiu";
2926 break;
2927 case OPC_VR54XX_MSACHI:
2928 gen_helper_msachi(t0, cpu_env, t0, t1);
2929 opn = "msachi";
2930 break;
2931 case OPC_VR54XX_MSACHIU:
2932 gen_helper_msachiu(t0, cpu_env, t0, t1);
2933 opn = "msachiu";
2934 break;
2935 default:
2936 MIPS_INVAL("mul vr54xx");
2937 generate_exception(ctx, EXCP_RI);
2938 goto out;
2940 gen_store_gpr(t0, rd);
2941 (void)opn; /* avoid a compiler warning */
2942 MIPS_DEBUG("%s %s, %s, %s", opn, regnames[rd], regnames[rs], regnames[rt]);
2944 out:
2945 tcg_temp_free(t0);
2946 tcg_temp_free(t1);
2949 static void gen_cl (DisasContext *ctx, uint32_t opc,
2950 int rd, int rs)
2952 const char *opn = "CLx";
2953 TCGv t0;
2955 if (rd == 0) {
2956 /* Treat as NOP. */
2957 MIPS_DEBUG("NOP");
2958 return;
2960 t0 = tcg_temp_new();
2961 gen_load_gpr(t0, rs);
2962 switch (opc) {
2963 case OPC_CLO:
2964 gen_helper_clo(cpu_gpr[rd], t0);
2965 opn = "clo";
2966 break;
2967 case OPC_CLZ:
2968 gen_helper_clz(cpu_gpr[rd], t0);
2969 opn = "clz";
2970 break;
2971 #if defined(TARGET_MIPS64)
2972 case OPC_DCLO:
2973 gen_helper_dclo(cpu_gpr[rd], t0);
2974 opn = "dclo";
2975 break;
2976 case OPC_DCLZ:
2977 gen_helper_dclz(cpu_gpr[rd], t0);
2978 opn = "dclz";
2979 break;
2980 #endif
2982 (void)opn; /* avoid a compiler warning */
2983 MIPS_DEBUG("%s %s, %s", opn, regnames[rd], regnames[rs]);
2984 tcg_temp_free(t0);
2987 /* Godson integer instructions */
2988 static void gen_loongson_integer(DisasContext *ctx, uint32_t opc,
2989 int rd, int rs, int rt)
2991 const char *opn = "loongson";
2992 TCGv t0, t1;
2994 if (rd == 0) {
2995 /* Treat as NOP. */
2996 MIPS_DEBUG("NOP");
2997 return;
3000 switch (opc) {
3001 case OPC_MULT_G_2E:
3002 case OPC_MULT_G_2F:
3003 case OPC_MULTU_G_2E:
3004 case OPC_MULTU_G_2F:
3005 #if defined(TARGET_MIPS64)
3006 case OPC_DMULT_G_2E:
3007 case OPC_DMULT_G_2F:
3008 case OPC_DMULTU_G_2E:
3009 case OPC_DMULTU_G_2F:
3010 #endif
3011 t0 = tcg_temp_new();
3012 t1 = tcg_temp_new();
3013 break;
3014 default:
3015 t0 = tcg_temp_local_new();
3016 t1 = tcg_temp_local_new();
3017 break;
3020 gen_load_gpr(t0, rs);
3021 gen_load_gpr(t1, rt);
3023 switch (opc) {
3024 case OPC_MULT_G_2E:
3025 case OPC_MULT_G_2F:
3026 tcg_gen_mul_tl(cpu_gpr[rd], t0, t1);
3027 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3028 opn = "mult.g";
3029 break;
3030 case OPC_MULTU_G_2E:
3031 case OPC_MULTU_G_2F:
3032 tcg_gen_ext32u_tl(t0, t0);
3033 tcg_gen_ext32u_tl(t1, t1);
3034 tcg_gen_mul_tl(cpu_gpr[rd], t0, t1);
3035 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3036 opn = "multu.g";
3037 break;
3038 case OPC_DIV_G_2E:
3039 case OPC_DIV_G_2F:
3041 int l1 = gen_new_label();
3042 int l2 = gen_new_label();
3043 int l3 = gen_new_label();
3044 tcg_gen_ext32s_tl(t0, t0);
3045 tcg_gen_ext32s_tl(t1, t1);
3046 tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
3047 tcg_gen_movi_tl(cpu_gpr[rd], 0);
3048 tcg_gen_br(l3);
3049 gen_set_label(l1);
3050 tcg_gen_brcondi_tl(TCG_COND_NE, t0, INT_MIN, l2);
3051 tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1, l2);
3052 tcg_gen_mov_tl(cpu_gpr[rd], t0);
3053 tcg_gen_br(l3);
3054 gen_set_label(l2);
3055 tcg_gen_div_tl(cpu_gpr[rd], t0, t1);
3056 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3057 gen_set_label(l3);
3059 opn = "div.g";
3060 break;
3061 case OPC_DIVU_G_2E:
3062 case OPC_DIVU_G_2F:
3064 int l1 = gen_new_label();
3065 int l2 = gen_new_label();
3066 tcg_gen_ext32u_tl(t0, t0);
3067 tcg_gen_ext32u_tl(t1, t1);
3068 tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
3069 tcg_gen_movi_tl(cpu_gpr[rd], 0);
3070 tcg_gen_br(l2);
3071 gen_set_label(l1);
3072 tcg_gen_divu_tl(cpu_gpr[rd], t0, t1);
3073 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3074 gen_set_label(l2);
3076 opn = "divu.g";
3077 break;
3078 case OPC_MOD_G_2E:
3079 case OPC_MOD_G_2F:
3081 int l1 = gen_new_label();
3082 int l2 = gen_new_label();
3083 int l3 = gen_new_label();
3084 tcg_gen_ext32u_tl(t0, t0);
3085 tcg_gen_ext32u_tl(t1, t1);
3086 tcg_gen_brcondi_tl(TCG_COND_EQ, t1, 0, l1);
3087 tcg_gen_brcondi_tl(TCG_COND_NE, t0, INT_MIN, l2);
3088 tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1, l2);
3089 gen_set_label(l1);
3090 tcg_gen_movi_tl(cpu_gpr[rd], 0);
3091 tcg_gen_br(l3);
3092 gen_set_label(l2);
3093 tcg_gen_rem_tl(cpu_gpr[rd], t0, t1);
3094 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3095 gen_set_label(l3);
3097 opn = "mod.g";
3098 break;
3099 case OPC_MODU_G_2E:
3100 case OPC_MODU_G_2F:
3102 int l1 = gen_new_label();
3103 int l2 = gen_new_label();
3104 tcg_gen_ext32u_tl(t0, t0);
3105 tcg_gen_ext32u_tl(t1, t1);
3106 tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
3107 tcg_gen_movi_tl(cpu_gpr[rd], 0);
3108 tcg_gen_br(l2);
3109 gen_set_label(l1);
3110 tcg_gen_remu_tl(cpu_gpr[rd], t0, t1);
3111 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3112 gen_set_label(l2);
3114 opn = "modu.g";
3115 break;
3116 #if defined(TARGET_MIPS64)
3117 case OPC_DMULT_G_2E:
3118 case OPC_DMULT_G_2F:
3119 tcg_gen_mul_tl(cpu_gpr[rd], t0, t1);
3120 opn = "dmult.g";
3121 break;
3122 case OPC_DMULTU_G_2E:
3123 case OPC_DMULTU_G_2F:
3124 tcg_gen_mul_tl(cpu_gpr[rd], t0, t1);
3125 opn = "dmultu.g";
3126 break;
3127 case OPC_DDIV_G_2E:
3128 case OPC_DDIV_G_2F:
3130 int l1 = gen_new_label();
3131 int l2 = gen_new_label();
3132 int l3 = gen_new_label();
3133 tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
3134 tcg_gen_movi_tl(cpu_gpr[rd], 0);
3135 tcg_gen_br(l3);
3136 gen_set_label(l1);
3137 tcg_gen_brcondi_tl(TCG_COND_NE, t0, -1LL << 63, l2);
3138 tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1LL, l2);
3139 tcg_gen_mov_tl(cpu_gpr[rd], t0);
3140 tcg_gen_br(l3);
3141 gen_set_label(l2);
3142 tcg_gen_div_tl(cpu_gpr[rd], t0, t1);
3143 gen_set_label(l3);
3145 opn = "ddiv.g";
3146 break;
3147 case OPC_DDIVU_G_2E:
3148 case OPC_DDIVU_G_2F:
3150 int l1 = gen_new_label();
3151 int l2 = gen_new_label();
3152 tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
3153 tcg_gen_movi_tl(cpu_gpr[rd], 0);
3154 tcg_gen_br(l2);
3155 gen_set_label(l1);
3156 tcg_gen_divu_tl(cpu_gpr[rd], t0, t1);
3157 gen_set_label(l2);
3159 opn = "ddivu.g";
3160 break;
3161 case OPC_DMOD_G_2E:
3162 case OPC_DMOD_G_2F:
3164 int l1 = gen_new_label();
3165 int l2 = gen_new_label();
3166 int l3 = gen_new_label();
3167 tcg_gen_brcondi_tl(TCG_COND_EQ, t1, 0, l1);
3168 tcg_gen_brcondi_tl(TCG_COND_NE, t0, -1LL << 63, l2);
3169 tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1LL, l2);
3170 gen_set_label(l1);
3171 tcg_gen_movi_tl(cpu_gpr[rd], 0);
3172 tcg_gen_br(l3);
3173 gen_set_label(l2);
3174 tcg_gen_rem_tl(cpu_gpr[rd], t0, t1);
3175 gen_set_label(l3);
3177 opn = "dmod.g";
3178 break;
3179 case OPC_DMODU_G_2E:
3180 case OPC_DMODU_G_2F:
3182 int l1 = gen_new_label();
3183 int l2 = gen_new_label();
3184 tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
3185 tcg_gen_movi_tl(cpu_gpr[rd], 0);
3186 tcg_gen_br(l2);
3187 gen_set_label(l1);
3188 tcg_gen_remu_tl(cpu_gpr[rd], t0, t1);
3189 gen_set_label(l2);
3191 opn = "dmodu.g";
3192 break;
3193 #endif
3196 (void)opn; /* avoid a compiler warning */
3197 MIPS_DEBUG("%s %s, %s", opn, regnames[rd], regnames[rs]);
3198 tcg_temp_free(t0);
3199 tcg_temp_free(t1);
3202 /* Loongson multimedia instructions */
3203 static void gen_loongson_multimedia(DisasContext *ctx, int rd, int rs, int rt)
3205 const char *opn = "loongson_cp2";
3206 uint32_t opc, shift_max;
3207 TCGv_i64 t0, t1;
3209 opc = MASK_LMI(ctx->opcode);
3210 switch (opc) {
3211 case OPC_ADD_CP2:
3212 case OPC_SUB_CP2:
3213 case OPC_DADD_CP2:
3214 case OPC_DSUB_CP2:
3215 t0 = tcg_temp_local_new_i64();
3216 t1 = tcg_temp_local_new_i64();
3217 break;
3218 default:
3219 t0 = tcg_temp_new_i64();
3220 t1 = tcg_temp_new_i64();
3221 break;
3224 gen_load_fpr64(ctx, t0, rs);
3225 gen_load_fpr64(ctx, t1, rt);
3227 #define LMI_HELPER(UP, LO) \
3228 case OPC_##UP: gen_helper_##LO(t0, t0, t1); opn = #LO; break
3229 #define LMI_HELPER_1(UP, LO) \
3230 case OPC_##UP: gen_helper_##LO(t0, t0); opn = #LO; break
3231 #define LMI_DIRECT(UP, LO, OP) \
3232 case OPC_##UP: tcg_gen_##OP##_i64(t0, t0, t1); opn = #LO; break
3234 switch (opc) {
3235 LMI_HELPER(PADDSH, paddsh);
3236 LMI_HELPER(PADDUSH, paddush);
3237 LMI_HELPER(PADDH, paddh);
3238 LMI_HELPER(PADDW, paddw);
3239 LMI_HELPER(PADDSB, paddsb);
3240 LMI_HELPER(PADDUSB, paddusb);
3241 LMI_HELPER(PADDB, paddb);
3243 LMI_HELPER(PSUBSH, psubsh);
3244 LMI_HELPER(PSUBUSH, psubush);
3245 LMI_HELPER(PSUBH, psubh);
3246 LMI_HELPER(PSUBW, psubw);
3247 LMI_HELPER(PSUBSB, psubsb);
3248 LMI_HELPER(PSUBUSB, psubusb);
3249 LMI_HELPER(PSUBB, psubb);
3251 LMI_HELPER(PSHUFH, pshufh);
3252 LMI_HELPER(PACKSSWH, packsswh);
3253 LMI_HELPER(PACKSSHB, packsshb);
3254 LMI_HELPER(PACKUSHB, packushb);
3256 LMI_HELPER(PUNPCKLHW, punpcklhw);
3257 LMI_HELPER(PUNPCKHHW, punpckhhw);
3258 LMI_HELPER(PUNPCKLBH, punpcklbh);
3259 LMI_HELPER(PUNPCKHBH, punpckhbh);
3260 LMI_HELPER(PUNPCKLWD, punpcklwd);
3261 LMI_HELPER(PUNPCKHWD, punpckhwd);
3263 LMI_HELPER(PAVGH, pavgh);
3264 LMI_HELPER(PAVGB, pavgb);
3265 LMI_HELPER(PMAXSH, pmaxsh);
3266 LMI_HELPER(PMINSH, pminsh);
3267 LMI_HELPER(PMAXUB, pmaxub);
3268 LMI_HELPER(PMINUB, pminub);
3270 LMI_HELPER(PCMPEQW, pcmpeqw);
3271 LMI_HELPER(PCMPGTW, pcmpgtw);
3272 LMI_HELPER(PCMPEQH, pcmpeqh);
3273 LMI_HELPER(PCMPGTH, pcmpgth);
3274 LMI_HELPER(PCMPEQB, pcmpeqb);
3275 LMI_HELPER(PCMPGTB, pcmpgtb);
3277 LMI_HELPER(PSLLW, psllw);
3278 LMI_HELPER(PSLLH, psllh);
3279 LMI_HELPER(PSRLW, psrlw);
3280 LMI_HELPER(PSRLH, psrlh);
3281 LMI_HELPER(PSRAW, psraw);
3282 LMI_HELPER(PSRAH, psrah);
3284 LMI_HELPER(PMULLH, pmullh);
3285 LMI_HELPER(PMULHH, pmulhh);
3286 LMI_HELPER(PMULHUH, pmulhuh);
3287 LMI_HELPER(PMADDHW, pmaddhw);
3289 LMI_HELPER(PASUBUB, pasubub);
3290 LMI_HELPER_1(BIADD, biadd);
3291 LMI_HELPER_1(PMOVMSKB, pmovmskb);
3293 LMI_DIRECT(PADDD, paddd, add);
3294 LMI_DIRECT(PSUBD, psubd, sub);
3295 LMI_DIRECT(XOR_CP2, xor, xor);
3296 LMI_DIRECT(NOR_CP2, nor, nor);
3297 LMI_DIRECT(AND_CP2, and, and);
3298 LMI_DIRECT(PANDN, pandn, andc);
3299 LMI_DIRECT(OR, or, or);
3301 case OPC_PINSRH_0:
3302 tcg_gen_deposit_i64(t0, t0, t1, 0, 16);
3303 opn = "pinsrh_0";
3304 break;
3305 case OPC_PINSRH_1:
3306 tcg_gen_deposit_i64(t0, t0, t1, 16, 16);
3307 opn = "pinsrh_1";
3308 break;
3309 case OPC_PINSRH_2:
3310 tcg_gen_deposit_i64(t0, t0, t1, 32, 16);
3311 opn = "pinsrh_2";
3312 break;
3313 case OPC_PINSRH_3:
3314 tcg_gen_deposit_i64(t0, t0, t1, 48, 16);
3315 opn = "pinsrh_3";
3316 break;
3318 case OPC_PEXTRH:
3319 tcg_gen_andi_i64(t1, t1, 3);
3320 tcg_gen_shli_i64(t1, t1, 4);
3321 tcg_gen_shr_i64(t0, t0, t1);
3322 tcg_gen_ext16u_i64(t0, t0);
3323 opn = "pextrh";
3324 break;
3326 case OPC_ADDU_CP2:
3327 tcg_gen_add_i64(t0, t0, t1);
3328 tcg_gen_ext32s_i64(t0, t0);
3329 opn = "addu";
3330 break;
3331 case OPC_SUBU_CP2:
3332 tcg_gen_sub_i64(t0, t0, t1);
3333 tcg_gen_ext32s_i64(t0, t0);
3334 opn = "addu";
3335 break;
3337 case OPC_SLL_CP2:
3338 opn = "sll";
3339 shift_max = 32;
3340 goto do_shift;
3341 case OPC_SRL_CP2:
3342 opn = "srl";
3343 shift_max = 32;
3344 goto do_shift;
3345 case OPC_SRA_CP2:
3346 opn = "sra";
3347 shift_max = 32;
3348 goto do_shift;
3349 case OPC_DSLL_CP2:
3350 opn = "dsll";
3351 shift_max = 64;
3352 goto do_shift;
3353 case OPC_DSRL_CP2:
3354 opn = "dsrl";
3355 shift_max = 64;
3356 goto do_shift;
3357 case OPC_DSRA_CP2:
3358 opn = "dsra";
3359 shift_max = 64;
3360 goto do_shift;
3361 do_shift:
3362 /* Make sure shift count isn't TCG undefined behaviour. */
3363 tcg_gen_andi_i64(t1, t1, shift_max - 1);
3365 switch (opc) {
3366 case OPC_SLL_CP2:
3367 case OPC_DSLL_CP2:
3368 tcg_gen_shl_i64(t0, t0, t1);
3369 break;
3370 case OPC_SRA_CP2:
3371 case OPC_DSRA_CP2:
3372 /* Since SRA is UndefinedResult without sign-extended inputs,
3373 we can treat SRA and DSRA the same. */
3374 tcg_gen_sar_i64(t0, t0, t1);
3375 break;
3376 case OPC_SRL_CP2:
3377 /* We want to shift in zeros for SRL; zero-extend first. */
3378 tcg_gen_ext32u_i64(t0, t0);
3379 /* FALLTHRU */
3380 case OPC_DSRL_CP2:
3381 tcg_gen_shr_i64(t0, t0, t1);
3382 break;
3385 if (shift_max == 32) {
3386 tcg_gen_ext32s_i64(t0, t0);
3389 /* Shifts larger than MAX produce zero. */
3390 tcg_gen_setcondi_i64(TCG_COND_LTU, t1, t1, shift_max);
3391 tcg_gen_neg_i64(t1, t1);
3392 tcg_gen_and_i64(t0, t0, t1);
3393 break;
3395 case OPC_ADD_CP2:
3396 case OPC_DADD_CP2:
3398 TCGv_i64 t2 = tcg_temp_new_i64();
3399 int lab = gen_new_label();
3401 tcg_gen_mov_i64(t2, t0);
3402 tcg_gen_add_i64(t0, t1, t2);
3403 if (opc == OPC_ADD_CP2) {
3404 tcg_gen_ext32s_i64(t0, t0);
3406 tcg_gen_xor_i64(t1, t1, t2);
3407 tcg_gen_xor_i64(t2, t2, t0);
3408 tcg_gen_andc_i64(t1, t2, t1);
3409 tcg_temp_free_i64(t2);
3410 tcg_gen_brcondi_i64(TCG_COND_GE, t1, 0, lab);
3411 generate_exception(ctx, EXCP_OVERFLOW);
3412 gen_set_label(lab);
3414 opn = (opc == OPC_ADD_CP2 ? "add" : "dadd");
3415 break;
3418 case OPC_SUB_CP2:
3419 case OPC_DSUB_CP2:
3421 TCGv_i64 t2 = tcg_temp_new_i64();
3422 int lab = gen_new_label();
3424 tcg_gen_mov_i64(t2, t0);
3425 tcg_gen_sub_i64(t0, t1, t2);
3426 if (opc == OPC_SUB_CP2) {
3427 tcg_gen_ext32s_i64(t0, t0);
3429 tcg_gen_xor_i64(t1, t1, t2);
3430 tcg_gen_xor_i64(t2, t2, t0);
3431 tcg_gen_and_i64(t1, t1, t2);
3432 tcg_temp_free_i64(t2);
3433 tcg_gen_brcondi_i64(TCG_COND_GE, t1, 0, lab);
3434 generate_exception(ctx, EXCP_OVERFLOW);
3435 gen_set_label(lab);
3437 opn = (opc == OPC_SUB_CP2 ? "sub" : "dsub");
3438 break;
3441 case OPC_PMULUW:
3442 tcg_gen_ext32u_i64(t0, t0);
3443 tcg_gen_ext32u_i64(t1, t1);
3444 tcg_gen_mul_i64(t0, t0, t1);
3445 opn = "pmuluw";
3446 break;
3448 case OPC_SEQU_CP2:
3449 case OPC_SEQ_CP2:
3450 case OPC_SLTU_CP2:
3451 case OPC_SLT_CP2:
3452 case OPC_SLEU_CP2:
3453 case OPC_SLE_CP2:
3454 /* ??? Document is unclear: Set FCC[CC]. Does that mean the
3455 FD field is the CC field? */
3456 default:
3457 MIPS_INVAL(opn);
3458 generate_exception(ctx, EXCP_RI);
3459 return;
3462 #undef LMI_HELPER
3463 #undef LMI_DIRECT
3465 gen_store_fpr64(ctx, t0, rd);
3467 (void)opn; /* avoid a compiler warning */
3468 MIPS_DEBUG("%s %s, %s, %s", opn,
3469 fregnames[rd], fregnames[rs], fregnames[rt]);
3470 tcg_temp_free_i64(t0);
3471 tcg_temp_free_i64(t1);
3474 /* Traps */
3475 static void gen_trap (DisasContext *ctx, uint32_t opc,
3476 int rs, int rt, int16_t imm)
3478 int cond;
3479 TCGv t0 = tcg_temp_new();
3480 TCGv t1 = tcg_temp_new();
3482 cond = 0;
3483 /* Load needed operands */
3484 switch (opc) {
3485 case OPC_TEQ:
3486 case OPC_TGE:
3487 case OPC_TGEU:
3488 case OPC_TLT:
3489 case OPC_TLTU:
3490 case OPC_TNE:
3491 /* Compare two registers */
3492 if (rs != rt) {
3493 gen_load_gpr(t0, rs);
3494 gen_load_gpr(t1, rt);
3495 cond = 1;
3497 break;
3498 case OPC_TEQI:
3499 case OPC_TGEI:
3500 case OPC_TGEIU:
3501 case OPC_TLTI:
3502 case OPC_TLTIU:
3503 case OPC_TNEI:
3504 /* Compare register to immediate */
3505 if (rs != 0 || imm != 0) {
3506 gen_load_gpr(t0, rs);
3507 tcg_gen_movi_tl(t1, (int32_t)imm);
3508 cond = 1;
3510 break;
3512 if (cond == 0) {
3513 switch (opc) {
3514 case OPC_TEQ: /* rs == rs */
3515 case OPC_TEQI: /* r0 == 0 */
3516 case OPC_TGE: /* rs >= rs */
3517 case OPC_TGEI: /* r0 >= 0 */
3518 case OPC_TGEU: /* rs >= rs unsigned */
3519 case OPC_TGEIU: /* r0 >= 0 unsigned */
3520 /* Always trap */
3521 generate_exception(ctx, EXCP_TRAP);
3522 break;
3523 case OPC_TLT: /* rs < rs */
3524 case OPC_TLTI: /* r0 < 0 */
3525 case OPC_TLTU: /* rs < rs unsigned */
3526 case OPC_TLTIU: /* r0 < 0 unsigned */
3527 case OPC_TNE: /* rs != rs */
3528 case OPC_TNEI: /* r0 != 0 */
3529 /* Never trap: treat as NOP. */
3530 break;
3532 } else {
3533 int l1 = gen_new_label();
3535 switch (opc) {
3536 case OPC_TEQ:
3537 case OPC_TEQI:
3538 tcg_gen_brcond_tl(TCG_COND_NE, t0, t1, l1);
3539 break;
3540 case OPC_TGE:
3541 case OPC_TGEI:
3542 tcg_gen_brcond_tl(TCG_COND_LT, t0, t1, l1);
3543 break;
3544 case OPC_TGEU:
3545 case OPC_TGEIU:
3546 tcg_gen_brcond_tl(TCG_COND_LTU, t0, t1, l1);
3547 break;
3548 case OPC_TLT:
3549 case OPC_TLTI:
3550 tcg_gen_brcond_tl(TCG_COND_GE, t0, t1, l1);
3551 break;
3552 case OPC_TLTU:
3553 case OPC_TLTIU:
3554 tcg_gen_brcond_tl(TCG_COND_GEU, t0, t1, l1);
3555 break;
3556 case OPC_TNE:
3557 case OPC_TNEI:
3558 tcg_gen_brcond_tl(TCG_COND_EQ, t0, t1, l1);
3559 break;
3561 generate_exception(ctx, EXCP_TRAP);
3562 gen_set_label(l1);
3564 tcg_temp_free(t0);
3565 tcg_temp_free(t1);
3568 static inline void gen_goto_tb(DisasContext *ctx, int n, target_ulong dest)
3570 TranslationBlock *tb;
3571 tb = ctx->tb;
3572 if ((tb->pc & TARGET_PAGE_MASK) == (dest & TARGET_PAGE_MASK) &&
3573 likely(!ctx->singlestep_enabled)) {
3574 tcg_gen_goto_tb(n);
3575 gen_save_pc(dest);
3576 tcg_gen_exit_tb((uintptr_t)tb + n);
3577 } else {
3578 gen_save_pc(dest);
3579 if (ctx->singlestep_enabled) {
3580 save_cpu_state(ctx, 0);
3581 gen_helper_0e0i(raise_exception, EXCP_DEBUG);
3583 tcg_gen_exit_tb(0);
3587 /* Branches (before delay slot) */
3588 static void gen_compute_branch (DisasContext *ctx, uint32_t opc,
3589 int insn_bytes,
3590 int rs, int rt, int32_t offset)
3592 target_ulong btgt = -1;
3593 int blink = 0;
3594 int bcond_compute = 0;
3595 TCGv t0 = tcg_temp_new();
3596 TCGv t1 = tcg_temp_new();
3598 if (ctx->hflags & MIPS_HFLAG_BMASK) {
3599 #ifdef MIPS_DEBUG_DISAS
3600 LOG_DISAS("Branch in delay slot at PC 0x" TARGET_FMT_lx "\n", ctx->pc);
3601 #endif
3602 generate_exception(ctx, EXCP_RI);
3603 goto out;
3606 /* Load needed operands */
3607 switch (opc) {
3608 case OPC_BEQ:
3609 case OPC_BEQL:
3610 case OPC_BNE:
3611 case OPC_BNEL:
3612 /* Compare two registers */
3613 if (rs != rt) {
3614 gen_load_gpr(t0, rs);
3615 gen_load_gpr(t1, rt);
3616 bcond_compute = 1;
3618 btgt = ctx->pc + insn_bytes + offset;
3619 break;
3620 case OPC_BGEZ:
3621 case OPC_BGEZAL:
3622 case OPC_BGEZALS:
3623 case OPC_BGEZALL:
3624 case OPC_BGEZL:
3625 case OPC_BGTZ:
3626 case OPC_BGTZL:
3627 case OPC_BLEZ:
3628 case OPC_BLEZL:
3629 case OPC_BLTZ:
3630 case OPC_BLTZAL:
3631 case OPC_BLTZALS:
3632 case OPC_BLTZALL:
3633 case OPC_BLTZL:
3634 /* Compare to zero */
3635 if (rs != 0) {
3636 gen_load_gpr(t0, rs);
3637 bcond_compute = 1;
3639 btgt = ctx->pc + insn_bytes + offset;
3640 break;
3641 case OPC_BPOSGE32:
3642 #if defined(TARGET_MIPS64)
3643 case OPC_BPOSGE64:
3644 tcg_gen_andi_tl(t0, cpu_dspctrl, 0x7F);
3645 #else
3646 tcg_gen_andi_tl(t0, cpu_dspctrl, 0x3F);
3647 #endif
3648 bcond_compute = 1;
3649 btgt = ctx->pc + insn_bytes + offset;
3650 break;
3651 case OPC_J:
3652 case OPC_JAL:
3653 case OPC_JALX:
3654 case OPC_JALS:
3655 case OPC_JALXS:
3656 /* Jump to immediate */
3657 btgt = ((ctx->pc + insn_bytes) & (int32_t)0xF0000000) | (uint32_t)offset;
3658 break;
3659 case OPC_JR:
3660 case OPC_JALR:
3661 case OPC_JALRC:
3662 case OPC_JALRS:
3663 /* Jump to register */
3664 if (offset != 0 && offset != 16) {
3665 /* Hint = 0 is JR/JALR, hint 16 is JR.HB/JALR.HB, the
3666 others are reserved. */
3667 MIPS_INVAL("jump hint");
3668 generate_exception(ctx, EXCP_RI);
3669 goto out;
3671 gen_load_gpr(btarget, rs);
3672 break;
3673 default:
3674 MIPS_INVAL("branch/jump");
3675 generate_exception(ctx, EXCP_RI);
3676 goto out;
3678 if (bcond_compute == 0) {
3679 /* No condition to be computed */
3680 switch (opc) {
3681 case OPC_BEQ: /* rx == rx */
3682 case OPC_BEQL: /* rx == rx likely */
3683 case OPC_BGEZ: /* 0 >= 0 */
3684 case OPC_BGEZL: /* 0 >= 0 likely */
3685 case OPC_BLEZ: /* 0 <= 0 */
3686 case OPC_BLEZL: /* 0 <= 0 likely */
3687 /* Always take */
3688 ctx->hflags |= MIPS_HFLAG_B;
3689 MIPS_DEBUG("balways");
3690 break;
3691 case OPC_BGEZALS:
3692 case OPC_BGEZAL: /* 0 >= 0 */
3693 case OPC_BGEZALL: /* 0 >= 0 likely */
3694 ctx->hflags |= (opc == OPC_BGEZALS
3695 ? MIPS_HFLAG_BDS16
3696 : MIPS_HFLAG_BDS32);
3697 /* Always take and link */
3698 blink = 31;
3699 ctx->hflags |= MIPS_HFLAG_B;
3700 MIPS_DEBUG("balways and link");
3701 break;
3702 case OPC_BNE: /* rx != rx */
3703 case OPC_BGTZ: /* 0 > 0 */
3704 case OPC_BLTZ: /* 0 < 0 */
3705 /* Treat as NOP. */
3706 MIPS_DEBUG("bnever (NOP)");
3707 goto out;
3708 case OPC_BLTZALS:
3709 case OPC_BLTZAL: /* 0 < 0 */
3710 ctx->hflags |= (opc == OPC_BLTZALS
3711 ? MIPS_HFLAG_BDS16
3712 : MIPS_HFLAG_BDS32);
3713 /* Handle as an unconditional branch to get correct delay
3714 slot checking. */
3715 blink = 31;
3716 btgt = ctx->pc + (opc == OPC_BLTZALS ? 6 : 8);
3717 ctx->hflags |= MIPS_HFLAG_B;
3718 MIPS_DEBUG("bnever and link");
3719 break;
3720 case OPC_BLTZALL: /* 0 < 0 likely */
3721 tcg_gen_movi_tl(cpu_gpr[31], ctx->pc + 8);
3722 /* Skip the instruction in the delay slot */
3723 MIPS_DEBUG("bnever, link and skip");
3724 ctx->pc += 4;
3725 goto out;
3726 case OPC_BNEL: /* rx != rx likely */
3727 case OPC_BGTZL: /* 0 > 0 likely */
3728 case OPC_BLTZL: /* 0 < 0 likely */
3729 /* Skip the instruction in the delay slot */
3730 MIPS_DEBUG("bnever and skip");
3731 ctx->pc += 4;
3732 goto out;
3733 case OPC_J:
3734 ctx->hflags |= MIPS_HFLAG_B;
3735 MIPS_DEBUG("j " TARGET_FMT_lx, btgt);
3736 break;
3737 case OPC_JALXS:
3738 case OPC_JALX:
3739 ctx->hflags |= MIPS_HFLAG_BX;
3740 /* Fallthrough */
3741 case OPC_JALS:
3742 case OPC_JAL:
3743 blink = 31;
3744 ctx->hflags |= MIPS_HFLAG_B;
3745 ctx->hflags |= ((opc == OPC_JALS || opc == OPC_JALXS)
3746 ? MIPS_HFLAG_BDS16
3747 : MIPS_HFLAG_BDS32);
3748 MIPS_DEBUG("jal " TARGET_FMT_lx, btgt);
3749 break;
3750 case OPC_JR:
3751 ctx->hflags |= MIPS_HFLAG_BR;
3752 if (insn_bytes == 4)
3753 ctx->hflags |= MIPS_HFLAG_BDS32;
3754 MIPS_DEBUG("jr %s", regnames[rs]);
3755 break;
3756 case OPC_JALRS:
3757 case OPC_JALR:
3758 case OPC_JALRC:
3759 blink = rt;
3760 ctx->hflags |= MIPS_HFLAG_BR;
3761 ctx->hflags |= (opc == OPC_JALRS
3762 ? MIPS_HFLAG_BDS16
3763 : MIPS_HFLAG_BDS32);
3764 MIPS_DEBUG("jalr %s, %s", regnames[rt], regnames[rs]);
3765 break;
3766 default:
3767 MIPS_INVAL("branch/jump");
3768 generate_exception(ctx, EXCP_RI);
3769 goto out;
3771 } else {
3772 switch (opc) {
3773 case OPC_BEQ:
3774 tcg_gen_setcond_tl(TCG_COND_EQ, bcond, t0, t1);
3775 MIPS_DEBUG("beq %s, %s, " TARGET_FMT_lx,
3776 regnames[rs], regnames[rt], btgt);
3777 goto not_likely;
3778 case OPC_BEQL:
3779 tcg_gen_setcond_tl(TCG_COND_EQ, bcond, t0, t1);
3780 MIPS_DEBUG("beql %s, %s, " TARGET_FMT_lx,
3781 regnames[rs], regnames[rt], btgt);
3782 goto likely;
3783 case OPC_BNE:
3784 tcg_gen_setcond_tl(TCG_COND_NE, bcond, t0, t1);
3785 MIPS_DEBUG("bne %s, %s, " TARGET_FMT_lx,
3786 regnames[rs], regnames[rt], btgt);
3787 goto not_likely;
3788 case OPC_BNEL:
3789 tcg_gen_setcond_tl(TCG_COND_NE, bcond, t0, t1);
3790 MIPS_DEBUG("bnel %s, %s, " TARGET_FMT_lx,
3791 regnames[rs], regnames[rt], btgt);
3792 goto likely;
3793 case OPC_BGEZ:
3794 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 0);
3795 MIPS_DEBUG("bgez %s, " TARGET_FMT_lx, regnames[rs], btgt);
3796 goto not_likely;
3797 case OPC_BGEZL:
3798 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 0);
3799 MIPS_DEBUG("bgezl %s, " TARGET_FMT_lx, regnames[rs], btgt);
3800 goto likely;
3801 case OPC_BGEZALS:
3802 case OPC_BGEZAL:
3803 ctx->hflags |= (opc == OPC_BGEZALS
3804 ? MIPS_HFLAG_BDS16
3805 : MIPS_HFLAG_BDS32);
3806 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 0);
3807 MIPS_DEBUG("bgezal %s, " TARGET_FMT_lx, regnames[rs], btgt);
3808 blink = 31;
3809 goto not_likely;
3810 case OPC_BGEZALL:
3811 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 0);
3812 blink = 31;
3813 MIPS_DEBUG("bgezall %s, " TARGET_FMT_lx, regnames[rs], btgt);
3814 goto likely;
3815 case OPC_BGTZ:
3816 tcg_gen_setcondi_tl(TCG_COND_GT, bcond, t0, 0);
3817 MIPS_DEBUG("bgtz %s, " TARGET_FMT_lx, regnames[rs], btgt);
3818 goto not_likely;
3819 case OPC_BGTZL:
3820 tcg_gen_setcondi_tl(TCG_COND_GT, bcond, t0, 0);
3821 MIPS_DEBUG("bgtzl %s, " TARGET_FMT_lx, regnames[rs], btgt);
3822 goto likely;
3823 case OPC_BLEZ:
3824 tcg_gen_setcondi_tl(TCG_COND_LE, bcond, t0, 0);
3825 MIPS_DEBUG("blez %s, " TARGET_FMT_lx, regnames[rs], btgt);
3826 goto not_likely;
3827 case OPC_BLEZL:
3828 tcg_gen_setcondi_tl(TCG_COND_LE, bcond, t0, 0);
3829 MIPS_DEBUG("blezl %s, " TARGET_FMT_lx, regnames[rs], btgt);
3830 goto likely;
3831 case OPC_BLTZ:
3832 tcg_gen_setcondi_tl(TCG_COND_LT, bcond, t0, 0);
3833 MIPS_DEBUG("bltz %s, " TARGET_FMT_lx, regnames[rs], btgt);
3834 goto not_likely;
3835 case OPC_BLTZL:
3836 tcg_gen_setcondi_tl(TCG_COND_LT, bcond, t0, 0);
3837 MIPS_DEBUG("bltzl %s, " TARGET_FMT_lx, regnames[rs], btgt);
3838 goto likely;
3839 case OPC_BPOSGE32:
3840 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 32);
3841 MIPS_DEBUG("bposge32 " TARGET_FMT_lx, btgt);
3842 goto not_likely;
3843 #if defined(TARGET_MIPS64)
3844 case OPC_BPOSGE64:
3845 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 64);
3846 MIPS_DEBUG("bposge64 " TARGET_FMT_lx, btgt);
3847 goto not_likely;
3848 #endif
3849 case OPC_BLTZALS:
3850 case OPC_BLTZAL:
3851 ctx->hflags |= (opc == OPC_BLTZALS
3852 ? MIPS_HFLAG_BDS16
3853 : MIPS_HFLAG_BDS32);
3854 tcg_gen_setcondi_tl(TCG_COND_LT, bcond, t0, 0);
3855 blink = 31;
3856 MIPS_DEBUG("bltzal %s, " TARGET_FMT_lx, regnames[rs], btgt);
3857 not_likely:
3858 ctx->hflags |= MIPS_HFLAG_BC;
3859 break;
3860 case OPC_BLTZALL:
3861 tcg_gen_setcondi_tl(TCG_COND_LT, bcond, t0, 0);
3862 blink = 31;
3863 MIPS_DEBUG("bltzall %s, " TARGET_FMT_lx, regnames[rs], btgt);
3864 likely:
3865 ctx->hflags |= MIPS_HFLAG_BL;
3866 break;
3867 default:
3868 MIPS_INVAL("conditional branch/jump");
3869 generate_exception(ctx, EXCP_RI);
3870 goto out;
3873 MIPS_DEBUG("enter ds: link %d cond %02x target " TARGET_FMT_lx,
3874 blink, ctx->hflags, btgt);
3876 ctx->btarget = btgt;
3877 if (blink > 0) {
3878 int post_delay = insn_bytes;
3879 int lowbit = !!(ctx->hflags & MIPS_HFLAG_M16);
3881 if (opc != OPC_JALRC)
3882 post_delay += ((ctx->hflags & MIPS_HFLAG_BDS16) ? 2 : 4);
3884 tcg_gen_movi_tl(cpu_gpr[blink], ctx->pc + post_delay + lowbit);
3887 out:
3888 if (insn_bytes == 2)
3889 ctx->hflags |= MIPS_HFLAG_B16;
3890 tcg_temp_free(t0);
3891 tcg_temp_free(t1);
3894 /* special3 bitfield operations */
3895 static void gen_bitops (DisasContext *ctx, uint32_t opc, int rt,
3896 int rs, int lsb, int msb)
3898 TCGv t0 = tcg_temp_new();
3899 TCGv t1 = tcg_temp_new();
3901 gen_load_gpr(t1, rs);
3902 switch (opc) {
3903 case OPC_EXT:
3904 if (lsb + msb > 31)
3905 goto fail;
3906 tcg_gen_shri_tl(t0, t1, lsb);
3907 if (msb != 31) {
3908 tcg_gen_andi_tl(t0, t0, (1 << (msb + 1)) - 1);
3909 } else {
3910 tcg_gen_ext32s_tl(t0, t0);
3912 break;
3913 #if defined(TARGET_MIPS64)
3914 case OPC_DEXTM:
3915 tcg_gen_shri_tl(t0, t1, lsb);
3916 if (msb != 31) {
3917 tcg_gen_andi_tl(t0, t0, (1ULL << (msb + 1 + 32)) - 1);
3919 break;
3920 case OPC_DEXTU:
3921 tcg_gen_shri_tl(t0, t1, lsb + 32);
3922 tcg_gen_andi_tl(t0, t0, (1ULL << (msb + 1)) - 1);
3923 break;
3924 case OPC_DEXT:
3925 tcg_gen_shri_tl(t0, t1, lsb);
3926 tcg_gen_andi_tl(t0, t0, (1ULL << (msb + 1)) - 1);
3927 break;
3928 #endif
3929 case OPC_INS:
3930 if (lsb > msb)
3931 goto fail;
3932 gen_load_gpr(t0, rt);
3933 tcg_gen_deposit_tl(t0, t0, t1, lsb, msb - lsb + 1);
3934 tcg_gen_ext32s_tl(t0, t0);
3935 break;
3936 #if defined(TARGET_MIPS64)
3937 case OPC_DINSM:
3938 gen_load_gpr(t0, rt);
3939 tcg_gen_deposit_tl(t0, t0, t1, lsb, msb + 32 - lsb + 1);
3940 break;
3941 case OPC_DINSU:
3942 gen_load_gpr(t0, rt);
3943 tcg_gen_deposit_tl(t0, t0, t1, lsb + 32, msb - lsb + 1);
3944 break;
3945 case OPC_DINS:
3946 gen_load_gpr(t0, rt);
3947 tcg_gen_deposit_tl(t0, t0, t1, lsb, msb - lsb + 1);
3948 break;
3949 #endif
3950 default:
3951 fail:
3952 MIPS_INVAL("bitops");
3953 generate_exception(ctx, EXCP_RI);
3954 tcg_temp_free(t0);
3955 tcg_temp_free(t1);
3956 return;
3958 gen_store_gpr(t0, rt);
3959 tcg_temp_free(t0);
3960 tcg_temp_free(t1);
3963 static void gen_bshfl (DisasContext *ctx, uint32_t op2, int rt, int rd)
3965 TCGv t0;
3967 if (rd == 0) {
3968 /* If no destination, treat it as a NOP. */
3969 MIPS_DEBUG("NOP");
3970 return;
3973 t0 = tcg_temp_new();
3974 gen_load_gpr(t0, rt);
3975 switch (op2) {
3976 case OPC_WSBH:
3978 TCGv t1 = tcg_temp_new();
3980 tcg_gen_shri_tl(t1, t0, 8);
3981 tcg_gen_andi_tl(t1, t1, 0x00FF00FF);
3982 tcg_gen_shli_tl(t0, t0, 8);
3983 tcg_gen_andi_tl(t0, t0, ~0x00FF00FF);
3984 tcg_gen_or_tl(t0, t0, t1);
3985 tcg_temp_free(t1);
3986 tcg_gen_ext32s_tl(cpu_gpr[rd], t0);
3988 break;
3989 case OPC_SEB:
3990 tcg_gen_ext8s_tl(cpu_gpr[rd], t0);
3991 break;
3992 case OPC_SEH:
3993 tcg_gen_ext16s_tl(cpu_gpr[rd], t0);
3994 break;
3995 #if defined(TARGET_MIPS64)
3996 case OPC_DSBH:
3998 TCGv t1 = tcg_temp_new();
4000 tcg_gen_shri_tl(t1, t0, 8);
4001 tcg_gen_andi_tl(t1, t1, 0x00FF00FF00FF00FFULL);
4002 tcg_gen_shli_tl(t0, t0, 8);
4003 tcg_gen_andi_tl(t0, t0, ~0x00FF00FF00FF00FFULL);
4004 tcg_gen_or_tl(cpu_gpr[rd], t0, t1);
4005 tcg_temp_free(t1);
4007 break;
4008 case OPC_DSHD:
4010 TCGv t1 = tcg_temp_new();
4012 tcg_gen_shri_tl(t1, t0, 16);
4013 tcg_gen_andi_tl(t1, t1, 0x0000FFFF0000FFFFULL);
4014 tcg_gen_shli_tl(t0, t0, 16);
4015 tcg_gen_andi_tl(t0, t0, ~0x0000FFFF0000FFFFULL);
4016 tcg_gen_or_tl(t0, t0, t1);
4017 tcg_gen_shri_tl(t1, t0, 32);
4018 tcg_gen_shli_tl(t0, t0, 32);
4019 tcg_gen_or_tl(cpu_gpr[rd], t0, t1);
4020 tcg_temp_free(t1);
4022 break;
4023 #endif
4024 default:
4025 MIPS_INVAL("bsfhl");
4026 generate_exception(ctx, EXCP_RI);
4027 tcg_temp_free(t0);
4028 return;
4030 tcg_temp_free(t0);
4033 #ifndef CONFIG_USER_ONLY
4034 /* CP0 (MMU and control) */
4035 static inline void gen_mfc0_load32 (TCGv arg, target_ulong off)
4037 TCGv_i32 t0 = tcg_temp_new_i32();
4039 tcg_gen_ld_i32(t0, cpu_env, off);
4040 tcg_gen_ext_i32_tl(arg, t0);
4041 tcg_temp_free_i32(t0);
4044 static inline void gen_mfc0_load64 (TCGv arg, target_ulong off)
4046 tcg_gen_ld_tl(arg, cpu_env, off);
4047 tcg_gen_ext32s_tl(arg, arg);
4050 static inline void gen_mtc0_store32 (TCGv arg, target_ulong off)
4052 TCGv_i32 t0 = tcg_temp_new_i32();
4054 tcg_gen_trunc_tl_i32(t0, arg);
4055 tcg_gen_st_i32(t0, cpu_env, off);
4056 tcg_temp_free_i32(t0);
4059 static inline void gen_mtc0_store64 (TCGv arg, target_ulong off)
4061 tcg_gen_ext32s_tl(arg, arg);
4062 tcg_gen_st_tl(arg, cpu_env, off);
4065 static void gen_mfc0(DisasContext *ctx, TCGv arg, int reg, int sel)
4067 const char *rn = "invalid";
4069 if (sel != 0)
4070 check_insn(ctx, ISA_MIPS32);
4072 switch (reg) {
4073 case 0:
4074 switch (sel) {
4075 case 0:
4076 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Index));
4077 rn = "Index";
4078 break;
4079 case 1:
4080 check_insn(ctx, ASE_MT);
4081 gen_helper_mfc0_mvpcontrol(arg, cpu_env);
4082 rn = "MVPControl";
4083 break;
4084 case 2:
4085 check_insn(ctx, ASE_MT);
4086 gen_helper_mfc0_mvpconf0(arg, cpu_env);
4087 rn = "MVPConf0";
4088 break;
4089 case 3:
4090 check_insn(ctx, ASE_MT);
4091 gen_helper_mfc0_mvpconf1(arg, cpu_env);
4092 rn = "MVPConf1";
4093 break;
4094 default:
4095 goto die;
4097 break;
4098 case 1:
4099 switch (sel) {
4100 case 0:
4101 gen_helper_mfc0_random(arg, cpu_env);
4102 rn = "Random";
4103 break;
4104 case 1:
4105 check_insn(ctx, ASE_MT);
4106 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEControl));
4107 rn = "VPEControl";
4108 break;
4109 case 2:
4110 check_insn(ctx, ASE_MT);
4111 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEConf0));
4112 rn = "VPEConf0";
4113 break;
4114 case 3:
4115 check_insn(ctx, ASE_MT);
4116 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEConf1));
4117 rn = "VPEConf1";
4118 break;
4119 case 4:
4120 check_insn(ctx, ASE_MT);
4121 gen_mfc0_load64(arg, offsetof(CPUMIPSState, CP0_YQMask));
4122 rn = "YQMask";
4123 break;
4124 case 5:
4125 check_insn(ctx, ASE_MT);
4126 gen_mfc0_load64(arg, offsetof(CPUMIPSState, CP0_VPESchedule));
4127 rn = "VPESchedule";
4128 break;
4129 case 6:
4130 check_insn(ctx, ASE_MT);
4131 gen_mfc0_load64(arg, offsetof(CPUMIPSState, CP0_VPEScheFBack));
4132 rn = "VPEScheFBack";
4133 break;
4134 case 7:
4135 check_insn(ctx, ASE_MT);
4136 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEOpt));
4137 rn = "VPEOpt";
4138 break;
4139 default:
4140 goto die;
4142 break;
4143 case 2:
4144 switch (sel) {
4145 case 0:
4146 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EntryLo0));
4147 tcg_gen_ext32s_tl(arg, arg);
4148 rn = "EntryLo0";
4149 break;
4150 case 1:
4151 check_insn(ctx, ASE_MT);
4152 gen_helper_mfc0_tcstatus(arg, cpu_env);
4153 rn = "TCStatus";
4154 break;
4155 case 2:
4156 check_insn(ctx, ASE_MT);
4157 gen_helper_mfc0_tcbind(arg, cpu_env);
4158 rn = "TCBind";
4159 break;
4160 case 3:
4161 check_insn(ctx, ASE_MT);
4162 gen_helper_mfc0_tcrestart(arg, cpu_env);
4163 rn = "TCRestart";
4164 break;
4165 case 4:
4166 check_insn(ctx, ASE_MT);
4167 gen_helper_mfc0_tchalt(arg, cpu_env);
4168 rn = "TCHalt";
4169 break;
4170 case 5:
4171 check_insn(ctx, ASE_MT);
4172 gen_helper_mfc0_tccontext(arg, cpu_env);
4173 rn = "TCContext";
4174 break;
4175 case 6:
4176 check_insn(ctx, ASE_MT);
4177 gen_helper_mfc0_tcschedule(arg, cpu_env);
4178 rn = "TCSchedule";
4179 break;
4180 case 7:
4181 check_insn(ctx, ASE_MT);
4182 gen_helper_mfc0_tcschefback(arg, cpu_env);
4183 rn = "TCScheFBack";
4184 break;
4185 default:
4186 goto die;
4188 break;
4189 case 3:
4190 switch (sel) {
4191 case 0:
4192 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EntryLo1));
4193 tcg_gen_ext32s_tl(arg, arg);
4194 rn = "EntryLo1";
4195 break;
4196 default:
4197 goto die;
4199 break;
4200 case 4:
4201 switch (sel) {
4202 case 0:
4203 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_Context));
4204 tcg_gen_ext32s_tl(arg, arg);
4205 rn = "Context";
4206 break;
4207 case 1:
4208 // gen_helper_mfc0_contextconfig(arg); /* SmartMIPS ASE */
4209 rn = "ContextConfig";
4210 // break;
4211 default:
4212 goto die;
4214 break;
4215 case 5:
4216 switch (sel) {
4217 case 0:
4218 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PageMask));
4219 rn = "PageMask";
4220 break;
4221 case 1:
4222 check_insn(ctx, ISA_MIPS32R2);
4223 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PageGrain));
4224 rn = "PageGrain";
4225 break;
4226 default:
4227 goto die;
4229 break;
4230 case 6:
4231 switch (sel) {
4232 case 0:
4233 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Wired));
4234 rn = "Wired";
4235 break;
4236 case 1:
4237 check_insn(ctx, ISA_MIPS32R2);
4238 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf0));
4239 rn = "SRSConf0";
4240 break;
4241 case 2:
4242 check_insn(ctx, ISA_MIPS32R2);
4243 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf1));
4244 rn = "SRSConf1";
4245 break;
4246 case 3:
4247 check_insn(ctx, ISA_MIPS32R2);
4248 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf2));
4249 rn = "SRSConf2";
4250 break;
4251 case 4:
4252 check_insn(ctx, ISA_MIPS32R2);
4253 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf3));
4254 rn = "SRSConf3";
4255 break;
4256 case 5:
4257 check_insn(ctx, ISA_MIPS32R2);
4258 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf4));
4259 rn = "SRSConf4";
4260 break;
4261 default:
4262 goto die;
4264 break;
4265 case 7:
4266 switch (sel) {
4267 case 0:
4268 check_insn(ctx, ISA_MIPS32R2);
4269 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_HWREna));
4270 rn = "HWREna";
4271 break;
4272 default:
4273 goto die;
4275 break;
4276 case 8:
4277 switch (sel) {
4278 case 0:
4279 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_BadVAddr));
4280 tcg_gen_ext32s_tl(arg, arg);
4281 rn = "BadVAddr";
4282 break;
4283 default:
4284 goto die;
4286 break;
4287 case 9:
4288 switch (sel) {
4289 case 0:
4290 /* Mark as an IO operation because we read the time. */
4291 if (use_icount)
4292 gen_io_start();
4293 gen_helper_mfc0_count(arg, cpu_env);
4294 if (use_icount) {
4295 gen_io_end();
4297 /* Break the TB to be able to take timer interrupts immediately
4298 after reading count. */
4299 ctx->bstate = BS_STOP;
4300 rn = "Count";
4301 break;
4302 /* 6,7 are implementation dependent */
4303 default:
4304 goto die;
4306 break;
4307 case 10:
4308 switch (sel) {
4309 case 0:
4310 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EntryHi));
4311 tcg_gen_ext32s_tl(arg, arg);
4312 rn = "EntryHi";
4313 break;
4314 default:
4315 goto die;
4317 break;
4318 case 11:
4319 switch (sel) {
4320 case 0:
4321 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Compare));
4322 rn = "Compare";
4323 break;
4324 /* 6,7 are implementation dependent */
4325 default:
4326 goto die;
4328 break;
4329 case 12:
4330 switch (sel) {
4331 case 0:
4332 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Status));
4333 rn = "Status";
4334 break;
4335 case 1:
4336 check_insn(ctx, ISA_MIPS32R2);
4337 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_IntCtl));
4338 rn = "IntCtl";
4339 break;
4340 case 2:
4341 check_insn(ctx, ISA_MIPS32R2);
4342 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSCtl));
4343 rn = "SRSCtl";
4344 break;
4345 case 3:
4346 check_insn(ctx, ISA_MIPS32R2);
4347 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSMap));
4348 rn = "SRSMap";
4349 break;
4350 default:
4351 goto die;
4353 break;
4354 case 13:
4355 switch (sel) {
4356 case 0:
4357 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Cause));
4358 rn = "Cause";
4359 break;
4360 default:
4361 goto die;
4363 break;
4364 case 14:
4365 switch (sel) {
4366 case 0:
4367 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EPC));
4368 tcg_gen_ext32s_tl(arg, arg);
4369 rn = "EPC";
4370 break;
4371 default:
4372 goto die;
4374 break;
4375 case 15:
4376 switch (sel) {
4377 case 0:
4378 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PRid));
4379 rn = "PRid";
4380 break;
4381 case 1:
4382 check_insn(ctx, ISA_MIPS32R2);
4383 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_EBase));
4384 rn = "EBase";
4385 break;
4386 default:
4387 goto die;
4389 break;
4390 case 16:
4391 switch (sel) {
4392 case 0:
4393 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config0));
4394 rn = "Config";
4395 break;
4396 case 1:
4397 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config1));
4398 rn = "Config1";
4399 break;
4400 case 2:
4401 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config2));
4402 rn = "Config2";
4403 break;
4404 case 3:
4405 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config3));
4406 rn = "Config3";
4407 break;
4408 /* 4,5 are reserved */
4409 /* 6,7 are implementation dependent */
4410 case 6:
4411 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config6));
4412 rn = "Config6";
4413 break;
4414 case 7:
4415 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config7));
4416 rn = "Config7";
4417 break;
4418 default:
4419 goto die;
4421 break;
4422 case 17:
4423 switch (sel) {
4424 case 0:
4425 gen_helper_mfc0_lladdr(arg, cpu_env);
4426 rn = "LLAddr";
4427 break;
4428 default:
4429 goto die;
4431 break;
4432 case 18:
4433 switch (sel) {
4434 case 0 ... 7:
4435 gen_helper_1e0i(mfc0_watchlo, arg, sel);
4436 rn = "WatchLo";
4437 break;
4438 default:
4439 goto die;
4441 break;
4442 case 19:
4443 switch (sel) {
4444 case 0 ...7:
4445 gen_helper_1e0i(mfc0_watchhi, arg, sel);
4446 rn = "WatchHi";
4447 break;
4448 default:
4449 goto die;
4451 break;
4452 case 20:
4453 switch (sel) {
4454 case 0:
4455 #if defined(TARGET_MIPS64)
4456 check_insn(ctx, ISA_MIPS3);
4457 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_XContext));
4458 tcg_gen_ext32s_tl(arg, arg);
4459 rn = "XContext";
4460 break;
4461 #endif
4462 default:
4463 goto die;
4465 break;
4466 case 21:
4467 /* Officially reserved, but sel 0 is used for R1x000 framemask */
4468 switch (sel) {
4469 case 0:
4470 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Framemask));
4471 rn = "Framemask";
4472 break;
4473 default:
4474 goto die;
4476 break;
4477 case 22:
4478 tcg_gen_movi_tl(arg, 0); /* unimplemented */
4479 rn = "'Diagnostic"; /* implementation dependent */
4480 break;
4481 case 23:
4482 switch (sel) {
4483 case 0:
4484 gen_helper_mfc0_debug(arg, cpu_env); /* EJTAG support */
4485 rn = "Debug";
4486 break;
4487 case 1:
4488 // gen_helper_mfc0_tracecontrol(arg); /* PDtrace support */
4489 rn = "TraceControl";
4490 // break;
4491 case 2:
4492 // gen_helper_mfc0_tracecontrol2(arg); /* PDtrace support */
4493 rn = "TraceControl2";
4494 // break;
4495 case 3:
4496 // gen_helper_mfc0_usertracedata(arg); /* PDtrace support */
4497 rn = "UserTraceData";
4498 // break;
4499 case 4:
4500 // gen_helper_mfc0_tracebpc(arg); /* PDtrace support */
4501 rn = "TraceBPC";
4502 // break;
4503 default:
4504 goto die;
4506 break;
4507 case 24:
4508 switch (sel) {
4509 case 0:
4510 /* EJTAG support */
4511 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_DEPC));
4512 tcg_gen_ext32s_tl(arg, arg);
4513 rn = "DEPC";
4514 break;
4515 default:
4516 goto die;
4518 break;
4519 case 25:
4520 switch (sel) {
4521 case 0:
4522 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Performance0));
4523 rn = "Performance0";
4524 break;
4525 case 1:
4526 // gen_helper_mfc0_performance1(arg);
4527 rn = "Performance1";
4528 // break;
4529 case 2:
4530 // gen_helper_mfc0_performance2(arg);
4531 rn = "Performance2";
4532 // break;
4533 case 3:
4534 // gen_helper_mfc0_performance3(arg);
4535 rn = "Performance3";
4536 // break;
4537 case 4:
4538 // gen_helper_mfc0_performance4(arg);
4539 rn = "Performance4";
4540 // break;
4541 case 5:
4542 // gen_helper_mfc0_performance5(arg);
4543 rn = "Performance5";
4544 // break;
4545 case 6:
4546 // gen_helper_mfc0_performance6(arg);
4547 rn = "Performance6";
4548 // break;
4549 case 7:
4550 // gen_helper_mfc0_performance7(arg);
4551 rn = "Performance7";
4552 // break;
4553 default:
4554 goto die;
4556 break;
4557 case 26:
4558 tcg_gen_movi_tl(arg, 0); /* unimplemented */
4559 rn = "ECC";
4560 break;
4561 case 27:
4562 switch (sel) {
4563 case 0 ... 3:
4564 tcg_gen_movi_tl(arg, 0); /* unimplemented */
4565 rn = "CacheErr";
4566 break;
4567 default:
4568 goto die;
4570 break;
4571 case 28:
4572 switch (sel) {
4573 case 0:
4574 case 2:
4575 case 4:
4576 case 6:
4577 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_TagLo));
4578 rn = "TagLo";
4579 break;
4580 case 1:
4581 case 3:
4582 case 5:
4583 case 7:
4584 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DataLo));
4585 rn = "DataLo";
4586 break;
4587 default:
4588 goto die;
4590 break;
4591 case 29:
4592 switch (sel) {
4593 case 0:
4594 case 2:
4595 case 4:
4596 case 6:
4597 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_TagHi));
4598 rn = "TagHi";
4599 break;
4600 case 1:
4601 case 3:
4602 case 5:
4603 case 7:
4604 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DataHi));
4605 rn = "DataHi";
4606 break;
4607 default:
4608 goto die;
4610 break;
4611 case 30:
4612 switch (sel) {
4613 case 0:
4614 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_ErrorEPC));
4615 tcg_gen_ext32s_tl(arg, arg);
4616 rn = "ErrorEPC";
4617 break;
4618 default:
4619 goto die;
4621 break;
4622 case 31:
4623 switch (sel) {
4624 case 0:
4625 /* EJTAG support */
4626 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DESAVE));
4627 rn = "DESAVE";
4628 break;
4629 default:
4630 goto die;
4632 break;
4633 default:
4634 goto die;
4636 (void)rn; /* avoid a compiler warning */
4637 LOG_DISAS("mfc0 %s (reg %d sel %d)\n", rn, reg, sel);
4638 return;
4640 die:
4641 LOG_DISAS("mfc0 %s (reg %d sel %d)\n", rn, reg, sel);
4642 generate_exception(ctx, EXCP_RI);
4645 static void gen_mtc0(DisasContext *ctx, TCGv arg, int reg, int sel)
4647 const char *rn = "invalid";
4649 if (sel != 0)
4650 check_insn(ctx, ISA_MIPS32);
4652 if (use_icount)
4653 gen_io_start();
4655 switch (reg) {
4656 case 0:
4657 switch (sel) {
4658 case 0:
4659 gen_helper_mtc0_index(cpu_env, arg);
4660 rn = "Index";
4661 break;
4662 case 1:
4663 check_insn(ctx, ASE_MT);
4664 gen_helper_mtc0_mvpcontrol(cpu_env, arg);
4665 rn = "MVPControl";
4666 break;
4667 case 2:
4668 check_insn(ctx, ASE_MT);
4669 /* ignored */
4670 rn = "MVPConf0";
4671 break;
4672 case 3:
4673 check_insn(ctx, ASE_MT);
4674 /* ignored */
4675 rn = "MVPConf1";
4676 break;
4677 default:
4678 goto die;
4680 break;
4681 case 1:
4682 switch (sel) {
4683 case 0:
4684 /* ignored */
4685 rn = "Random";
4686 break;
4687 case 1:
4688 check_insn(ctx, ASE_MT);
4689 gen_helper_mtc0_vpecontrol(cpu_env, arg);
4690 rn = "VPEControl";
4691 break;
4692 case 2:
4693 check_insn(ctx, ASE_MT);
4694 gen_helper_mtc0_vpeconf0(cpu_env, arg);
4695 rn = "VPEConf0";
4696 break;
4697 case 3:
4698 check_insn(ctx, ASE_MT);
4699 gen_helper_mtc0_vpeconf1(cpu_env, arg);
4700 rn = "VPEConf1";
4701 break;
4702 case 4:
4703 check_insn(ctx, ASE_MT);
4704 gen_helper_mtc0_yqmask(cpu_env, arg);
4705 rn = "YQMask";
4706 break;
4707 case 5:
4708 check_insn(ctx, ASE_MT);
4709 gen_mtc0_store64(arg, offsetof(CPUMIPSState, CP0_VPESchedule));
4710 rn = "VPESchedule";
4711 break;
4712 case 6:
4713 check_insn(ctx, ASE_MT);
4714 gen_mtc0_store64(arg, offsetof(CPUMIPSState, CP0_VPEScheFBack));
4715 rn = "VPEScheFBack";
4716 break;
4717 case 7:
4718 check_insn(ctx, ASE_MT);
4719 gen_helper_mtc0_vpeopt(cpu_env, arg);
4720 rn = "VPEOpt";
4721 break;
4722 default:
4723 goto die;
4725 break;
4726 case 2:
4727 switch (sel) {
4728 case 0:
4729 gen_helper_mtc0_entrylo0(cpu_env, arg);
4730 rn = "EntryLo0";
4731 break;
4732 case 1:
4733 check_insn(ctx, ASE_MT);
4734 gen_helper_mtc0_tcstatus(cpu_env, arg);
4735 rn = "TCStatus";
4736 break;
4737 case 2:
4738 check_insn(ctx, ASE_MT);
4739 gen_helper_mtc0_tcbind(cpu_env, arg);
4740 rn = "TCBind";
4741 break;
4742 case 3:
4743 check_insn(ctx, ASE_MT);
4744 gen_helper_mtc0_tcrestart(cpu_env, arg);
4745 rn = "TCRestart";
4746 break;
4747 case 4:
4748 check_insn(ctx, ASE_MT);
4749 gen_helper_mtc0_tchalt(cpu_env, arg);
4750 rn = "TCHalt";
4751 break;
4752 case 5:
4753 check_insn(ctx, ASE_MT);
4754 gen_helper_mtc0_tccontext(cpu_env, arg);
4755 rn = "TCContext";
4756 break;
4757 case 6:
4758 check_insn(ctx, ASE_MT);
4759 gen_helper_mtc0_tcschedule(cpu_env, arg);
4760 rn = "TCSchedule";
4761 break;
4762 case 7:
4763 check_insn(ctx, ASE_MT);
4764 gen_helper_mtc0_tcschefback(cpu_env, arg);
4765 rn = "TCScheFBack";
4766 break;
4767 default:
4768 goto die;
4770 break;
4771 case 3:
4772 switch (sel) {
4773 case 0:
4774 gen_helper_mtc0_entrylo1(cpu_env, arg);
4775 rn = "EntryLo1";
4776 break;
4777 default:
4778 goto die;
4780 break;
4781 case 4:
4782 switch (sel) {
4783 case 0:
4784 gen_helper_mtc0_context(cpu_env, arg);
4785 rn = "Context";
4786 break;
4787 case 1:
4788 // gen_helper_mtc0_contextconfig(cpu_env, arg); /* SmartMIPS ASE */
4789 rn = "ContextConfig";
4790 // break;
4791 default:
4792 goto die;
4794 break;
4795 case 5:
4796 switch (sel) {
4797 case 0:
4798 gen_helper_mtc0_pagemask(cpu_env, arg);
4799 rn = "PageMask";
4800 break;
4801 case 1:
4802 check_insn(ctx, ISA_MIPS32R2);
4803 gen_helper_mtc0_pagegrain(cpu_env, arg);
4804 rn = "PageGrain";
4805 break;
4806 default:
4807 goto die;
4809 break;
4810 case 6:
4811 switch (sel) {
4812 case 0:
4813 gen_helper_mtc0_wired(cpu_env, arg);
4814 rn = "Wired";
4815 break;
4816 case 1:
4817 check_insn(ctx, ISA_MIPS32R2);
4818 gen_helper_mtc0_srsconf0(cpu_env, arg);
4819 rn = "SRSConf0";
4820 break;
4821 case 2:
4822 check_insn(ctx, ISA_MIPS32R2);
4823 gen_helper_mtc0_srsconf1(cpu_env, arg);
4824 rn = "SRSConf1";
4825 break;
4826 case 3:
4827 check_insn(ctx, ISA_MIPS32R2);
4828 gen_helper_mtc0_srsconf2(cpu_env, arg);
4829 rn = "SRSConf2";
4830 break;
4831 case 4:
4832 check_insn(ctx, ISA_MIPS32R2);
4833 gen_helper_mtc0_srsconf3(cpu_env, arg);
4834 rn = "SRSConf3";
4835 break;
4836 case 5:
4837 check_insn(ctx, ISA_MIPS32R2);
4838 gen_helper_mtc0_srsconf4(cpu_env, arg);
4839 rn = "SRSConf4";
4840 break;
4841 default:
4842 goto die;
4844 break;
4845 case 7:
4846 switch (sel) {
4847 case 0:
4848 check_insn(ctx, ISA_MIPS32R2);
4849 gen_helper_mtc0_hwrena(cpu_env, arg);
4850 rn = "HWREna";
4851 break;
4852 default:
4853 goto die;
4855 break;
4856 case 8:
4857 /* ignored */
4858 rn = "BadVAddr";
4859 break;
4860 case 9:
4861 switch (sel) {
4862 case 0:
4863 gen_helper_mtc0_count(cpu_env, arg);
4864 rn = "Count";
4865 break;
4866 /* 6,7 are implementation dependent */
4867 default:
4868 goto die;
4870 break;
4871 case 10:
4872 switch (sel) {
4873 case 0:
4874 gen_helper_mtc0_entryhi(cpu_env, arg);
4875 rn = "EntryHi";
4876 break;
4877 default:
4878 goto die;
4880 break;
4881 case 11:
4882 switch (sel) {
4883 case 0:
4884 gen_helper_mtc0_compare(cpu_env, arg);
4885 rn = "Compare";
4886 break;
4887 /* 6,7 are implementation dependent */
4888 default:
4889 goto die;
4891 break;
4892 case 12:
4893 switch (sel) {
4894 case 0:
4895 save_cpu_state(ctx, 1);
4896 gen_helper_mtc0_status(cpu_env, arg);
4897 /* BS_STOP isn't good enough here, hflags may have changed. */
4898 gen_save_pc(ctx->pc + 4);
4899 ctx->bstate = BS_EXCP;
4900 rn = "Status";
4901 break;
4902 case 1:
4903 check_insn(ctx, ISA_MIPS32R2);
4904 gen_helper_mtc0_intctl(cpu_env, arg);
4905 /* Stop translation as we may have switched the execution mode */
4906 ctx->bstate = BS_STOP;
4907 rn = "IntCtl";
4908 break;
4909 case 2:
4910 check_insn(ctx, ISA_MIPS32R2);
4911 gen_helper_mtc0_srsctl(cpu_env, arg);
4912 /* Stop translation as we may have switched the execution mode */
4913 ctx->bstate = BS_STOP;
4914 rn = "SRSCtl";
4915 break;
4916 case 3:
4917 check_insn(ctx, ISA_MIPS32R2);
4918 gen_mtc0_store32(arg, offsetof(CPUMIPSState, CP0_SRSMap));
4919 /* Stop translation as we may have switched the execution mode */
4920 ctx->bstate = BS_STOP;
4921 rn = "SRSMap";
4922 break;
4923 default:
4924 goto die;
4926 break;
4927 case 13:
4928 switch (sel) {
4929 case 0:
4930 save_cpu_state(ctx, 1);
4931 gen_helper_mtc0_cause(cpu_env, arg);
4932 rn = "Cause";
4933 break;
4934 default:
4935 goto die;
4937 break;
4938 case 14:
4939 switch (sel) {
4940 case 0:
4941 gen_mtc0_store64(arg, offsetof(CPUMIPSState, CP0_EPC));
4942 rn = "EPC";
4943 break;
4944 default:
4945 goto die;
4947 break;
4948 case 15:
4949 switch (sel) {
4950 case 0:
4951 /* ignored */
4952 rn = "PRid";
4953 break;
4954 case 1:
4955 check_insn(ctx, ISA_MIPS32R2);
4956 gen_helper_mtc0_ebase(cpu_env, arg);
4957 rn = "EBase";
4958 break;
4959 default:
4960 goto die;
4962 break;
4963 case 16:
4964 switch (sel) {
4965 case 0:
4966 gen_helper_mtc0_config0(cpu_env, arg);
4967 rn = "Config";
4968 /* Stop translation as we may have switched the execution mode */
4969 ctx->bstate = BS_STOP;
4970 break;
4971 case 1:
4972 /* ignored, read only */
4973 rn = "Config1";
4974 break;
4975 case 2:
4976 gen_helper_mtc0_config2(cpu_env, arg);
4977 rn = "Config2";
4978 /* Stop translation as we may have switched the execution mode */
4979 ctx->bstate = BS_STOP;
4980 break;
4981 case 3:
4982 /* ignored, read only */
4983 rn = "Config3";
4984 break;
4985 /* 4,5 are reserved */
4986 /* 6,7 are implementation dependent */
4987 case 6:
4988 /* ignored */
4989 rn = "Config6";
4990 break;
4991 case 7:
4992 /* ignored */
4993 rn = "Config7";
4994 break;
4995 default:
4996 rn = "Invalid config selector";
4997 goto die;
4999 break;
5000 case 17:
5001 switch (sel) {
5002 case 0:
5003 gen_helper_mtc0_lladdr(cpu_env, arg);
5004 rn = "LLAddr";
5005 break;
5006 default:
5007 goto die;
5009 break;
5010 case 18:
5011 switch (sel) {
5012 case 0 ... 7:
5013 gen_helper_0e1i(mtc0_watchlo, arg, sel);
5014 rn = "WatchLo";
5015 break;
5016 default:
5017 goto die;
5019 break;
5020 case 19:
5021 switch (sel) {
5022 case 0 ... 7:
5023 gen_helper_0e1i(mtc0_watchhi, arg, sel);
5024 rn = "WatchHi";
5025 break;
5026 default:
5027 goto die;
5029 break;
5030 case 20:
5031 switch (sel) {
5032 case 0:
5033 #if defined(TARGET_MIPS64)
5034 check_insn(ctx, ISA_MIPS3);
5035 gen_helper_mtc0_xcontext(cpu_env, arg);
5036 rn = "XContext";
5037 break;
5038 #endif
5039 default:
5040 goto die;
5042 break;
5043 case 21:
5044 /* Officially reserved, but sel 0 is used for R1x000 framemask */
5045 switch (sel) {
5046 case 0:
5047 gen_helper_mtc0_framemask(cpu_env, arg);
5048 rn = "Framemask";
5049 break;
5050 default:
5051 goto die;
5053 break;
5054 case 22:
5055 /* ignored */
5056 rn = "Diagnostic"; /* implementation dependent */
5057 break;
5058 case 23:
5059 switch (sel) {
5060 case 0:
5061 gen_helper_mtc0_debug(cpu_env, arg); /* EJTAG support */
5062 /* BS_STOP isn't good enough here, hflags may have changed. */
5063 gen_save_pc(ctx->pc + 4);
5064 ctx->bstate = BS_EXCP;
5065 rn = "Debug";
5066 break;
5067 case 1:
5068 // gen_helper_mtc0_tracecontrol(cpu_env, arg); /* PDtrace support */
5069 rn = "TraceControl";
5070 /* Stop translation as we may have switched the execution mode */
5071 ctx->bstate = BS_STOP;
5072 // break;
5073 case 2:
5074 // gen_helper_mtc0_tracecontrol2(cpu_env, arg); /* PDtrace support */
5075 rn = "TraceControl2";
5076 /* Stop translation as we may have switched the execution mode */
5077 ctx->bstate = BS_STOP;
5078 // break;
5079 case 3:
5080 /* Stop translation as we may have switched the execution mode */
5081 ctx->bstate = BS_STOP;
5082 // gen_helper_mtc0_usertracedata(cpu_env, arg); /* PDtrace support */
5083 rn = "UserTraceData";
5084 /* Stop translation as we may have switched the execution mode */
5085 ctx->bstate = BS_STOP;
5086 // break;
5087 case 4:
5088 // gen_helper_mtc0_tracebpc(cpu_env, arg); /* PDtrace support */
5089 /* Stop translation as we may have switched the execution mode */
5090 ctx->bstate = BS_STOP;
5091 rn = "TraceBPC";
5092 // break;
5093 default:
5094 goto die;
5096 break;
5097 case 24:
5098 switch (sel) {
5099 case 0:
5100 /* EJTAG support */
5101 gen_mtc0_store64(arg, offsetof(CPUMIPSState, CP0_DEPC));
5102 rn = "DEPC";
5103 break;
5104 default:
5105 goto die;
5107 break;
5108 case 25:
5109 switch (sel) {
5110 case 0:
5111 gen_helper_mtc0_performance0(cpu_env, arg);
5112 rn = "Performance0";
5113 break;
5114 case 1:
5115 // gen_helper_mtc0_performance1(arg);
5116 rn = "Performance1";
5117 // break;
5118 case 2:
5119 // gen_helper_mtc0_performance2(arg);
5120 rn = "Performance2";
5121 // break;
5122 case 3:
5123 // gen_helper_mtc0_performance3(arg);
5124 rn = "Performance3";
5125 // break;
5126 case 4:
5127 // gen_helper_mtc0_performance4(arg);
5128 rn = "Performance4";
5129 // break;
5130 case 5:
5131 // gen_helper_mtc0_performance5(arg);
5132 rn = "Performance5";
5133 // break;
5134 case 6:
5135 // gen_helper_mtc0_performance6(arg);
5136 rn = "Performance6";
5137 // break;
5138 case 7:
5139 // gen_helper_mtc0_performance7(arg);
5140 rn = "Performance7";
5141 // break;
5142 default:
5143 goto die;
5145 break;
5146 case 26:
5147 /* ignored */
5148 rn = "ECC";
5149 break;
5150 case 27:
5151 switch (sel) {
5152 case 0 ... 3:
5153 /* ignored */
5154 rn = "CacheErr";
5155 break;
5156 default:
5157 goto die;
5159 break;
5160 case 28:
5161 switch (sel) {
5162 case 0:
5163 case 2:
5164 case 4:
5165 case 6:
5166 gen_helper_mtc0_taglo(cpu_env, arg);
5167 rn = "TagLo";
5168 break;
5169 case 1:
5170 case 3:
5171 case 5:
5172 case 7:
5173 gen_helper_mtc0_datalo(cpu_env, arg);
5174 rn = "DataLo";
5175 break;
5176 default:
5177 goto die;
5179 break;
5180 case 29:
5181 switch (sel) {
5182 case 0:
5183 case 2:
5184 case 4:
5185 case 6:
5186 gen_helper_mtc0_taghi(cpu_env, arg);
5187 rn = "TagHi";
5188 break;
5189 case 1:
5190 case 3:
5191 case 5:
5192 case 7:
5193 gen_helper_mtc0_datahi(cpu_env, arg);
5194 rn = "DataHi";
5195 break;
5196 default:
5197 rn = "invalid sel";
5198 goto die;
5200 break;
5201 case 30:
5202 switch (sel) {
5203 case 0:
5204 gen_mtc0_store64(arg, offsetof(CPUMIPSState, CP0_ErrorEPC));
5205 rn = "ErrorEPC";
5206 break;
5207 default:
5208 goto die;
5210 break;
5211 case 31:
5212 switch (sel) {
5213 case 0:
5214 /* EJTAG support */
5215 gen_mtc0_store32(arg, offsetof(CPUMIPSState, CP0_DESAVE));
5216 rn = "DESAVE";
5217 break;
5218 default:
5219 goto die;
5221 /* Stop translation as we may have switched the execution mode */
5222 ctx->bstate = BS_STOP;
5223 break;
5224 default:
5225 goto die;
5227 (void)rn; /* avoid a compiler warning */
5228 LOG_DISAS("mtc0 %s (reg %d sel %d)\n", rn, reg, sel);
5229 /* For simplicity assume that all writes can cause interrupts. */
5230 if (use_icount) {
5231 gen_io_end();
5232 ctx->bstate = BS_STOP;
5234 return;
5236 die:
5237 LOG_DISAS("mtc0 %s (reg %d sel %d)\n", rn, reg, sel);
5238 generate_exception(ctx, EXCP_RI);
5241 #if defined(TARGET_MIPS64)
5242 static void gen_dmfc0(DisasContext *ctx, TCGv arg, int reg, int sel)
5244 const char *rn = "invalid";
5246 if (sel != 0)
5247 check_insn(ctx, ISA_MIPS64);
5249 switch (reg) {
5250 case 0:
5251 switch (sel) {
5252 case 0:
5253 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Index));
5254 rn = "Index";
5255 break;
5256 case 1:
5257 check_insn(ctx, ASE_MT);
5258 gen_helper_mfc0_mvpcontrol(arg, cpu_env);
5259 rn = "MVPControl";
5260 break;
5261 case 2:
5262 check_insn(ctx, ASE_MT);
5263 gen_helper_mfc0_mvpconf0(arg, cpu_env);
5264 rn = "MVPConf0";
5265 break;
5266 case 3:
5267 check_insn(ctx, ASE_MT);
5268 gen_helper_mfc0_mvpconf1(arg, cpu_env);
5269 rn = "MVPConf1";
5270 break;
5271 default:
5272 goto die;
5274 break;
5275 case 1:
5276 switch (sel) {
5277 case 0:
5278 gen_helper_mfc0_random(arg, cpu_env);
5279 rn = "Random";
5280 break;
5281 case 1:
5282 check_insn(ctx, ASE_MT);
5283 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEControl));
5284 rn = "VPEControl";
5285 break;
5286 case 2:
5287 check_insn(ctx, ASE_MT);
5288 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEConf0));
5289 rn = "VPEConf0";
5290 break;
5291 case 3:
5292 check_insn(ctx, ASE_MT);
5293 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEConf1));
5294 rn = "VPEConf1";
5295 break;
5296 case 4:
5297 check_insn(ctx, ASE_MT);
5298 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_YQMask));
5299 rn = "YQMask";
5300 break;
5301 case 5:
5302 check_insn(ctx, ASE_MT);
5303 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_VPESchedule));
5304 rn = "VPESchedule";
5305 break;
5306 case 6:
5307 check_insn(ctx, ASE_MT);
5308 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_VPEScheFBack));
5309 rn = "VPEScheFBack";
5310 break;
5311 case 7:
5312 check_insn(ctx, ASE_MT);
5313 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEOpt));
5314 rn = "VPEOpt";
5315 break;
5316 default:
5317 goto die;
5319 break;
5320 case 2:
5321 switch (sel) {
5322 case 0:
5323 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EntryLo0));
5324 rn = "EntryLo0";
5325 break;
5326 case 1:
5327 check_insn(ctx, ASE_MT);
5328 gen_helper_mfc0_tcstatus(arg, cpu_env);
5329 rn = "TCStatus";
5330 break;
5331 case 2:
5332 check_insn(ctx, ASE_MT);
5333 gen_helper_mfc0_tcbind(arg, cpu_env);
5334 rn = "TCBind";
5335 break;
5336 case 3:
5337 check_insn(ctx, ASE_MT);
5338 gen_helper_dmfc0_tcrestart(arg, cpu_env);
5339 rn = "TCRestart";
5340 break;
5341 case 4:
5342 check_insn(ctx, ASE_MT);
5343 gen_helper_dmfc0_tchalt(arg, cpu_env);
5344 rn = "TCHalt";
5345 break;
5346 case 5:
5347 check_insn(ctx, ASE_MT);
5348 gen_helper_dmfc0_tccontext(arg, cpu_env);
5349 rn = "TCContext";
5350 break;
5351 case 6:
5352 check_insn(ctx, ASE_MT);
5353 gen_helper_dmfc0_tcschedule(arg, cpu_env);
5354 rn = "TCSchedule";
5355 break;
5356 case 7:
5357 check_insn(ctx, ASE_MT);
5358 gen_helper_dmfc0_tcschefback(arg, cpu_env);
5359 rn = "TCScheFBack";
5360 break;
5361 default:
5362 goto die;
5364 break;
5365 case 3:
5366 switch (sel) {
5367 case 0:
5368 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EntryLo1));
5369 rn = "EntryLo1";
5370 break;
5371 default:
5372 goto die;
5374 break;
5375 case 4:
5376 switch (sel) {
5377 case 0:
5378 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_Context));
5379 rn = "Context";
5380 break;
5381 case 1:
5382 // gen_helper_dmfc0_contextconfig(arg); /* SmartMIPS ASE */
5383 rn = "ContextConfig";
5384 // break;
5385 default:
5386 goto die;
5388 break;
5389 case 5:
5390 switch (sel) {
5391 case 0:
5392 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PageMask));
5393 rn = "PageMask";
5394 break;
5395 case 1:
5396 check_insn(ctx, ISA_MIPS32R2);
5397 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PageGrain));
5398 rn = "PageGrain";
5399 break;
5400 default:
5401 goto die;
5403 break;
5404 case 6:
5405 switch (sel) {
5406 case 0:
5407 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Wired));
5408 rn = "Wired";
5409 break;
5410 case 1:
5411 check_insn(ctx, ISA_MIPS32R2);
5412 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf0));
5413 rn = "SRSConf0";
5414 break;
5415 case 2:
5416 check_insn(ctx, ISA_MIPS32R2);
5417 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf1));
5418 rn = "SRSConf1";
5419 break;
5420 case 3:
5421 check_insn(ctx, ISA_MIPS32R2);
5422 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf2));
5423 rn = "SRSConf2";
5424 break;
5425 case 4:
5426 check_insn(ctx, ISA_MIPS32R2);
5427 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf3));
5428 rn = "SRSConf3";
5429 break;
5430 case 5:
5431 check_insn(ctx, ISA_MIPS32R2);
5432 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf4));
5433 rn = "SRSConf4";
5434 break;
5435 default:
5436 goto die;
5438 break;
5439 case 7:
5440 switch (sel) {
5441 case 0:
5442 check_insn(ctx, ISA_MIPS32R2);
5443 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_HWREna));
5444 rn = "HWREna";
5445 break;
5446 default:
5447 goto die;
5449 break;
5450 case 8:
5451 switch (sel) {
5452 case 0:
5453 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_BadVAddr));
5454 rn = "BadVAddr";
5455 break;
5456 default:
5457 goto die;
5459 break;
5460 case 9:
5461 switch (sel) {
5462 case 0:
5463 /* Mark as an IO operation because we read the time. */
5464 if (use_icount)
5465 gen_io_start();
5466 gen_helper_mfc0_count(arg, cpu_env);
5467 if (use_icount) {
5468 gen_io_end();
5470 /* Break the TB to be able to take timer interrupts immediately
5471 after reading count. */
5472 ctx->bstate = BS_STOP;
5473 rn = "Count";
5474 break;
5475 /* 6,7 are implementation dependent */
5476 default:
5477 goto die;
5479 break;
5480 case 10:
5481 switch (sel) {
5482 case 0:
5483 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EntryHi));
5484 rn = "EntryHi";
5485 break;
5486 default:
5487 goto die;
5489 break;
5490 case 11:
5491 switch (sel) {
5492 case 0:
5493 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Compare));
5494 rn = "Compare";
5495 break;
5496 /* 6,7 are implementation dependent */
5497 default:
5498 goto die;
5500 break;
5501 case 12:
5502 switch (sel) {
5503 case 0:
5504 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Status));
5505 rn = "Status";
5506 break;
5507 case 1:
5508 check_insn(ctx, ISA_MIPS32R2);
5509 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_IntCtl));
5510 rn = "IntCtl";
5511 break;
5512 case 2:
5513 check_insn(ctx, ISA_MIPS32R2);
5514 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSCtl));
5515 rn = "SRSCtl";
5516 break;
5517 case 3:
5518 check_insn(ctx, ISA_MIPS32R2);
5519 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSMap));
5520 rn = "SRSMap";
5521 break;
5522 default:
5523 goto die;
5525 break;
5526 case 13:
5527 switch (sel) {
5528 case 0:
5529 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Cause));
5530 rn = "Cause";
5531 break;
5532 default:
5533 goto die;
5535 break;
5536 case 14:
5537 switch (sel) {
5538 case 0:
5539 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EPC));
5540 rn = "EPC";
5541 break;
5542 default:
5543 goto die;
5545 break;
5546 case 15:
5547 switch (sel) {
5548 case 0:
5549 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PRid));
5550 rn = "PRid";
5551 break;
5552 case 1:
5553 check_insn(ctx, ISA_MIPS32R2);
5554 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_EBase));
5555 rn = "EBase";
5556 break;
5557 default:
5558 goto die;
5560 break;
5561 case 16:
5562 switch (sel) {
5563 case 0:
5564 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config0));
5565 rn = "Config";
5566 break;
5567 case 1:
5568 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config1));
5569 rn = "Config1";
5570 break;
5571 case 2:
5572 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config2));
5573 rn = "Config2";
5574 break;
5575 case 3:
5576 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config3));
5577 rn = "Config3";
5578 break;
5579 /* 6,7 are implementation dependent */
5580 case 6:
5581 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config6));
5582 rn = "Config6";
5583 break;
5584 case 7:
5585 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config7));
5586 rn = "Config7";
5587 break;
5588 default:
5589 goto die;
5591 break;
5592 case 17:
5593 switch (sel) {
5594 case 0:
5595 gen_helper_dmfc0_lladdr(arg, cpu_env);
5596 rn = "LLAddr";
5597 break;
5598 default:
5599 goto die;
5601 break;
5602 case 18:
5603 switch (sel) {
5604 case 0 ... 7:
5605 gen_helper_1e0i(dmfc0_watchlo, arg, sel);
5606 rn = "WatchLo";
5607 break;
5608 default:
5609 goto die;
5611 break;
5612 case 19:
5613 switch (sel) {
5614 case 0 ... 7:
5615 gen_helper_1e0i(mfc0_watchhi, arg, sel);
5616 rn = "WatchHi";
5617 break;
5618 default:
5619 goto die;
5621 break;
5622 case 20:
5623 switch (sel) {
5624 case 0:
5625 check_insn(ctx, ISA_MIPS3);
5626 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_XContext));
5627 rn = "XContext";
5628 break;
5629 default:
5630 goto die;
5632 break;
5633 case 21:
5634 /* Officially reserved, but sel 0 is used for R1x000 framemask */
5635 switch (sel) {
5636 case 0:
5637 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Framemask));
5638 rn = "Framemask";
5639 break;
5640 default:
5641 goto die;
5643 break;
5644 case 22:
5645 tcg_gen_movi_tl(arg, 0); /* unimplemented */
5646 rn = "'Diagnostic"; /* implementation dependent */
5647 break;
5648 case 23:
5649 switch (sel) {
5650 case 0:
5651 gen_helper_mfc0_debug(arg, cpu_env); /* EJTAG support */
5652 rn = "Debug";
5653 break;
5654 case 1:
5655 // gen_helper_dmfc0_tracecontrol(arg, cpu_env); /* PDtrace support */
5656 rn = "TraceControl";
5657 // break;
5658 case 2:
5659 // gen_helper_dmfc0_tracecontrol2(arg, cpu_env); /* PDtrace support */
5660 rn = "TraceControl2";
5661 // break;
5662 case 3:
5663 // gen_helper_dmfc0_usertracedata(arg, cpu_env); /* PDtrace support */
5664 rn = "UserTraceData";
5665 // break;
5666 case 4:
5667 // gen_helper_dmfc0_tracebpc(arg, cpu_env); /* PDtrace support */
5668 rn = "TraceBPC";
5669 // break;
5670 default:
5671 goto die;
5673 break;
5674 case 24:
5675 switch (sel) {
5676 case 0:
5677 /* EJTAG support */
5678 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_DEPC));
5679 rn = "DEPC";
5680 break;
5681 default:
5682 goto die;
5684 break;
5685 case 25:
5686 switch (sel) {
5687 case 0:
5688 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Performance0));
5689 rn = "Performance0";
5690 break;
5691 case 1:
5692 // gen_helper_dmfc0_performance1(arg);
5693 rn = "Performance1";
5694 // break;
5695 case 2:
5696 // gen_helper_dmfc0_performance2(arg);
5697 rn = "Performance2";
5698 // break;
5699 case 3:
5700 // gen_helper_dmfc0_performance3(arg);
5701 rn = "Performance3";
5702 // break;
5703 case 4:
5704 // gen_helper_dmfc0_performance4(arg);
5705 rn = "Performance4";
5706 // break;
5707 case 5:
5708 // gen_helper_dmfc0_performance5(arg);
5709 rn = "Performance5";
5710 // break;
5711 case 6:
5712 // gen_helper_dmfc0_performance6(arg);
5713 rn = "Performance6";
5714 // break;
5715 case 7:
5716 // gen_helper_dmfc0_performance7(arg);
5717 rn = "Performance7";
5718 // break;
5719 default:
5720 goto die;
5722 break;
5723 case 26:
5724 tcg_gen_movi_tl(arg, 0); /* unimplemented */
5725 rn = "ECC";
5726 break;
5727 case 27:
5728 switch (sel) {
5729 /* ignored */
5730 case 0 ... 3:
5731 tcg_gen_movi_tl(arg, 0); /* unimplemented */
5732 rn = "CacheErr";
5733 break;
5734 default:
5735 goto die;
5737 break;
5738 case 28:
5739 switch (sel) {
5740 case 0:
5741 case 2:
5742 case 4:
5743 case 6:
5744 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_TagLo));
5745 rn = "TagLo";
5746 break;
5747 case 1:
5748 case 3:
5749 case 5:
5750 case 7:
5751 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DataLo));
5752 rn = "DataLo";
5753 break;
5754 default:
5755 goto die;
5757 break;
5758 case 29:
5759 switch (sel) {
5760 case 0:
5761 case 2:
5762 case 4:
5763 case 6:
5764 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_TagHi));
5765 rn = "TagHi";
5766 break;
5767 case 1:
5768 case 3:
5769 case 5:
5770 case 7:
5771 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DataHi));
5772 rn = "DataHi";
5773 break;
5774 default:
5775 goto die;
5777 break;
5778 case 30:
5779 switch (sel) {
5780 case 0:
5781 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_ErrorEPC));
5782 rn = "ErrorEPC";
5783 break;
5784 default:
5785 goto die;
5787 break;
5788 case 31:
5789 switch (sel) {
5790 case 0:
5791 /* EJTAG support */
5792 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DESAVE));
5793 rn = "DESAVE";
5794 break;
5795 default:
5796 goto die;
5798 break;
5799 default:
5800 goto die;
5802 (void)rn; /* avoid a compiler warning */
5803 LOG_DISAS("dmfc0 %s (reg %d sel %d)\n", rn, reg, sel);
5804 return;
5806 die:
5807 LOG_DISAS("dmfc0 %s (reg %d sel %d)\n", rn, reg, sel);
5808 generate_exception(ctx, EXCP_RI);
5811 static void gen_dmtc0(DisasContext *ctx, TCGv arg, int reg, int sel)
5813 const char *rn = "invalid";
5815 if (sel != 0)
5816 check_insn(ctx, ISA_MIPS64);
5818 if (use_icount)
5819 gen_io_start();
5821 switch (reg) {
5822 case 0:
5823 switch (sel) {
5824 case 0:
5825 gen_helper_mtc0_index(cpu_env, arg);
5826 rn = "Index";
5827 break;
5828 case 1:
5829 check_insn(ctx, ASE_MT);
5830 gen_helper_mtc0_mvpcontrol(cpu_env, arg);
5831 rn = "MVPControl";
5832 break;
5833 case 2:
5834 check_insn(ctx, ASE_MT);
5835 /* ignored */
5836 rn = "MVPConf0";
5837 break;
5838 case 3:
5839 check_insn(ctx, ASE_MT);
5840 /* ignored */
5841 rn = "MVPConf1";
5842 break;
5843 default:
5844 goto die;
5846 break;
5847 case 1:
5848 switch (sel) {
5849 case 0:
5850 /* ignored */
5851 rn = "Random";
5852 break;
5853 case 1:
5854 check_insn(ctx, ASE_MT);
5855 gen_helper_mtc0_vpecontrol(cpu_env, arg);
5856 rn = "VPEControl";
5857 break;
5858 case 2:
5859 check_insn(ctx, ASE_MT);
5860 gen_helper_mtc0_vpeconf0(cpu_env, arg);
5861 rn = "VPEConf0";
5862 break;
5863 case 3:
5864 check_insn(ctx, ASE_MT);
5865 gen_helper_mtc0_vpeconf1(cpu_env, arg);
5866 rn = "VPEConf1";
5867 break;
5868 case 4:
5869 check_insn(ctx, ASE_MT);
5870 gen_helper_mtc0_yqmask(cpu_env, arg);
5871 rn = "YQMask";
5872 break;
5873 case 5:
5874 check_insn(ctx, ASE_MT);
5875 tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_VPESchedule));
5876 rn = "VPESchedule";
5877 break;
5878 case 6:
5879 check_insn(ctx, ASE_MT);
5880 tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_VPEScheFBack));
5881 rn = "VPEScheFBack";
5882 break;
5883 case 7:
5884 check_insn(ctx, ASE_MT);
5885 gen_helper_mtc0_vpeopt(cpu_env, arg);
5886 rn = "VPEOpt";
5887 break;
5888 default:
5889 goto die;
5891 break;
5892 case 2:
5893 switch (sel) {
5894 case 0:
5895 gen_helper_mtc0_entrylo0(cpu_env, arg);
5896 rn = "EntryLo0";
5897 break;
5898 case 1:
5899 check_insn(ctx, ASE_MT);
5900 gen_helper_mtc0_tcstatus(cpu_env, arg);
5901 rn = "TCStatus";
5902 break;
5903 case 2:
5904 check_insn(ctx, ASE_MT);
5905 gen_helper_mtc0_tcbind(cpu_env, arg);
5906 rn = "TCBind";
5907 break;
5908 case 3:
5909 check_insn(ctx, ASE_MT);
5910 gen_helper_mtc0_tcrestart(cpu_env, arg);
5911 rn = "TCRestart";
5912 break;
5913 case 4:
5914 check_insn(ctx, ASE_MT);
5915 gen_helper_mtc0_tchalt(cpu_env, arg);
5916 rn = "TCHalt";
5917 break;
5918 case 5:
5919 check_insn(ctx, ASE_MT);
5920 gen_helper_mtc0_tccontext(cpu_env, arg);
5921 rn = "TCContext";
5922 break;
5923 case 6:
5924 check_insn(ctx, ASE_MT);
5925 gen_helper_mtc0_tcschedule(cpu_env, arg);
5926 rn = "TCSchedule";
5927 break;
5928 case 7:
5929 check_insn(ctx, ASE_MT);
5930 gen_helper_mtc0_tcschefback(cpu_env, arg);
5931 rn = "TCScheFBack";
5932 break;
5933 default:
5934 goto die;
5936 break;
5937 case 3:
5938 switch (sel) {
5939 case 0:
5940 gen_helper_mtc0_entrylo1(cpu_env, arg);
5941 rn = "EntryLo1";
5942 break;
5943 default:
5944 goto die;
5946 break;
5947 case 4:
5948 switch (sel) {
5949 case 0:
5950 gen_helper_mtc0_context(cpu_env, arg);
5951 rn = "Context";
5952 break;
5953 case 1:
5954 // gen_helper_mtc0_contextconfig(cpu_env, arg); /* SmartMIPS ASE */
5955 rn = "ContextConfig";
5956 // break;
5957 default:
5958 goto die;
5960 break;
5961 case 5:
5962 switch (sel) {
5963 case 0:
5964 gen_helper_mtc0_pagemask(cpu_env, arg);
5965 rn = "PageMask";
5966 break;
5967 case 1:
5968 check_insn(ctx, ISA_MIPS32R2);
5969 gen_helper_mtc0_pagegrain(cpu_env, arg);
5970 rn = "PageGrain";
5971 break;
5972 default:
5973 goto die;
5975 break;
5976 case 6:
5977 switch (sel) {
5978 case 0:
5979 gen_helper_mtc0_wired(cpu_env, arg);
5980 rn = "Wired";
5981 break;
5982 case 1:
5983 check_insn(ctx, ISA_MIPS32R2);
5984 gen_helper_mtc0_srsconf0(cpu_env, arg);
5985 rn = "SRSConf0";
5986 break;
5987 case 2:
5988 check_insn(ctx, ISA_MIPS32R2);
5989 gen_helper_mtc0_srsconf1(cpu_env, arg);
5990 rn = "SRSConf1";
5991 break;
5992 case 3:
5993 check_insn(ctx, ISA_MIPS32R2);
5994 gen_helper_mtc0_srsconf2(cpu_env, arg);
5995 rn = "SRSConf2";
5996 break;
5997 case 4:
5998 check_insn(ctx, ISA_MIPS32R2);
5999 gen_helper_mtc0_srsconf3(cpu_env, arg);
6000 rn = "SRSConf3";
6001 break;
6002 case 5:
6003 check_insn(ctx, ISA_MIPS32R2);
6004 gen_helper_mtc0_srsconf4(cpu_env, arg);
6005 rn = "SRSConf4";
6006 break;
6007 default:
6008 goto die;
6010 break;
6011 case 7:
6012 switch (sel) {
6013 case 0:
6014 check_insn(ctx, ISA_MIPS32R2);
6015 gen_helper_mtc0_hwrena(cpu_env, arg);
6016 rn = "HWREna";
6017 break;
6018 default:
6019 goto die;
6021 break;
6022 case 8:
6023 /* ignored */
6024 rn = "BadVAddr";
6025 break;
6026 case 9:
6027 switch (sel) {
6028 case 0:
6029 gen_helper_mtc0_count(cpu_env, arg);
6030 rn = "Count";
6031 break;
6032 /* 6,7 are implementation dependent */
6033 default:
6034 goto die;
6036 /* Stop translation as we may have switched the execution mode */
6037 ctx->bstate = BS_STOP;
6038 break;
6039 case 10:
6040 switch (sel) {
6041 case 0:
6042 gen_helper_mtc0_entryhi(cpu_env, arg);
6043 rn = "EntryHi";
6044 break;
6045 default:
6046 goto die;
6048 break;
6049 case 11:
6050 switch (sel) {
6051 case 0:
6052 gen_helper_mtc0_compare(cpu_env, arg);
6053 rn = "Compare";
6054 break;
6055 /* 6,7 are implementation dependent */
6056 default:
6057 goto die;
6059 /* Stop translation as we may have switched the execution mode */
6060 ctx->bstate = BS_STOP;
6061 break;
6062 case 12:
6063 switch (sel) {
6064 case 0:
6065 save_cpu_state(ctx, 1);
6066 gen_helper_mtc0_status(cpu_env, arg);
6067 /* BS_STOP isn't good enough here, hflags may have changed. */
6068 gen_save_pc(ctx->pc + 4);
6069 ctx->bstate = BS_EXCP;
6070 rn = "Status";
6071 break;
6072 case 1:
6073 check_insn(ctx, ISA_MIPS32R2);
6074 gen_helper_mtc0_intctl(cpu_env, arg);
6075 /* Stop translation as we may have switched the execution mode */
6076 ctx->bstate = BS_STOP;
6077 rn = "IntCtl";
6078 break;
6079 case 2:
6080 check_insn(ctx, ISA_MIPS32R2);
6081 gen_helper_mtc0_srsctl(cpu_env, arg);
6082 /* Stop translation as we may have switched the execution mode */
6083 ctx->bstate = BS_STOP;
6084 rn = "SRSCtl";
6085 break;
6086 case 3:
6087 check_insn(ctx, ISA_MIPS32R2);
6088 gen_mtc0_store32(arg, offsetof(CPUMIPSState, CP0_SRSMap));
6089 /* Stop translation as we may have switched the execution mode */
6090 ctx->bstate = BS_STOP;
6091 rn = "SRSMap";
6092 break;
6093 default:
6094 goto die;
6096 break;
6097 case 13:
6098 switch (sel) {
6099 case 0:
6100 save_cpu_state(ctx, 1);
6101 /* Mark as an IO operation because we may trigger a software
6102 interrupt. */
6103 if (use_icount) {
6104 gen_io_start();
6106 gen_helper_mtc0_cause(cpu_env, arg);
6107 if (use_icount) {
6108 gen_io_end();
6110 /* Stop translation as we may have triggered an intetrupt */
6111 ctx->bstate = BS_STOP;
6112 rn = "Cause";
6113 break;
6114 default:
6115 goto die;
6117 break;
6118 case 14:
6119 switch (sel) {
6120 case 0:
6121 tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EPC));
6122 rn = "EPC";
6123 break;
6124 default:
6125 goto die;
6127 break;
6128 case 15:
6129 switch (sel) {
6130 case 0:
6131 /* ignored */
6132 rn = "PRid";
6133 break;
6134 case 1:
6135 check_insn(ctx, ISA_MIPS32R2);
6136 gen_helper_mtc0_ebase(cpu_env, arg);
6137 rn = "EBase";
6138 break;
6139 default:
6140 goto die;
6142 break;
6143 case 16:
6144 switch (sel) {
6145 case 0:
6146 gen_helper_mtc0_config0(cpu_env, arg);
6147 rn = "Config";
6148 /* Stop translation as we may have switched the execution mode */
6149 ctx->bstate = BS_STOP;
6150 break;
6151 case 1:
6152 /* ignored, read only */
6153 rn = "Config1";
6154 break;
6155 case 2:
6156 gen_helper_mtc0_config2(cpu_env, arg);
6157 rn = "Config2";
6158 /* Stop translation as we may have switched the execution mode */
6159 ctx->bstate = BS_STOP;
6160 break;
6161 case 3:
6162 /* ignored */
6163 rn = "Config3";
6164 break;
6165 /* 6,7 are implementation dependent */
6166 default:
6167 rn = "Invalid config selector";
6168 goto die;
6170 break;
6171 case 17:
6172 switch (sel) {
6173 case 0:
6174 gen_helper_mtc0_lladdr(cpu_env, arg);
6175 rn = "LLAddr";
6176 break;
6177 default:
6178 goto die;
6180 break;
6181 case 18:
6182 switch (sel) {
6183 case 0 ... 7:
6184 gen_helper_0e1i(mtc0_watchlo, arg, sel);
6185 rn = "WatchLo";
6186 break;
6187 default:
6188 goto die;
6190 break;
6191 case 19:
6192 switch (sel) {
6193 case 0 ... 7:
6194 gen_helper_0e1i(mtc0_watchhi, arg, sel);
6195 rn = "WatchHi";
6196 break;
6197 default:
6198 goto die;
6200 break;
6201 case 20:
6202 switch (sel) {
6203 case 0:
6204 check_insn(ctx, ISA_MIPS3);
6205 gen_helper_mtc0_xcontext(cpu_env, arg);
6206 rn = "XContext";
6207 break;
6208 default:
6209 goto die;
6211 break;
6212 case 21:
6213 /* Officially reserved, but sel 0 is used for R1x000 framemask */
6214 switch (sel) {
6215 case 0:
6216 gen_helper_mtc0_framemask(cpu_env, arg);
6217 rn = "Framemask";
6218 break;
6219 default:
6220 goto die;
6222 break;
6223 case 22:
6224 /* ignored */
6225 rn = "Diagnostic"; /* implementation dependent */
6226 break;
6227 case 23:
6228 switch (sel) {
6229 case 0:
6230 gen_helper_mtc0_debug(cpu_env, arg); /* EJTAG support */
6231 /* BS_STOP isn't good enough here, hflags may have changed. */
6232 gen_save_pc(ctx->pc + 4);
6233 ctx->bstate = BS_EXCP;
6234 rn = "Debug";
6235 break;
6236 case 1:
6237 // gen_helper_mtc0_tracecontrol(cpu_env, arg); /* PDtrace support */
6238 /* Stop translation as we may have switched the execution mode */
6239 ctx->bstate = BS_STOP;
6240 rn = "TraceControl";
6241 // break;
6242 case 2:
6243 // gen_helper_mtc0_tracecontrol2(cpu_env, arg); /* PDtrace support */
6244 /* Stop translation as we may have switched the execution mode */
6245 ctx->bstate = BS_STOP;
6246 rn = "TraceControl2";
6247 // break;
6248 case 3:
6249 // gen_helper_mtc0_usertracedata(cpu_env, arg); /* PDtrace support */
6250 /* Stop translation as we may have switched the execution mode */
6251 ctx->bstate = BS_STOP;
6252 rn = "UserTraceData";
6253 // break;
6254 case 4:
6255 // gen_helper_mtc0_tracebpc(cpu_env, arg); /* PDtrace support */
6256 /* Stop translation as we may have switched the execution mode */
6257 ctx->bstate = BS_STOP;
6258 rn = "TraceBPC";
6259 // break;
6260 default:
6261 goto die;
6263 break;
6264 case 24:
6265 switch (sel) {
6266 case 0:
6267 /* EJTAG support */
6268 tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_DEPC));
6269 rn = "DEPC";
6270 break;
6271 default:
6272 goto die;
6274 break;
6275 case 25:
6276 switch (sel) {
6277 case 0:
6278 gen_helper_mtc0_performance0(cpu_env, arg);
6279 rn = "Performance0";
6280 break;
6281 case 1:
6282 // gen_helper_mtc0_performance1(cpu_env, arg);
6283 rn = "Performance1";
6284 // break;
6285 case 2:
6286 // gen_helper_mtc0_performance2(cpu_env, arg);
6287 rn = "Performance2";
6288 // break;
6289 case 3:
6290 // gen_helper_mtc0_performance3(cpu_env, arg);
6291 rn = "Performance3";
6292 // break;
6293 case 4:
6294 // gen_helper_mtc0_performance4(cpu_env, arg);
6295 rn = "Performance4";
6296 // break;
6297 case 5:
6298 // gen_helper_mtc0_performance5(cpu_env, arg);
6299 rn = "Performance5";
6300 // break;
6301 case 6:
6302 // gen_helper_mtc0_performance6(cpu_env, arg);
6303 rn = "Performance6";
6304 // break;
6305 case 7:
6306 // gen_helper_mtc0_performance7(cpu_env, arg);
6307 rn = "Performance7";
6308 // break;
6309 default:
6310 goto die;
6312 break;
6313 case 26:
6314 /* ignored */
6315 rn = "ECC";
6316 break;
6317 case 27:
6318 switch (sel) {
6319 case 0 ... 3:
6320 /* ignored */
6321 rn = "CacheErr";
6322 break;
6323 default:
6324 goto die;
6326 break;
6327 case 28:
6328 switch (sel) {
6329 case 0:
6330 case 2:
6331 case 4:
6332 case 6:
6333 gen_helper_mtc0_taglo(cpu_env, arg);
6334 rn = "TagLo";
6335 break;
6336 case 1:
6337 case 3:
6338 case 5:
6339 case 7:
6340 gen_helper_mtc0_datalo(cpu_env, arg);
6341 rn = "DataLo";
6342 break;
6343 default:
6344 goto die;
6346 break;
6347 case 29:
6348 switch (sel) {
6349 case 0:
6350 case 2:
6351 case 4:
6352 case 6:
6353 gen_helper_mtc0_taghi(cpu_env, arg);
6354 rn = "TagHi";
6355 break;
6356 case 1:
6357 case 3:
6358 case 5:
6359 case 7:
6360 gen_helper_mtc0_datahi(cpu_env, arg);
6361 rn = "DataHi";
6362 break;
6363 default:
6364 rn = "invalid sel";
6365 goto die;
6367 break;
6368 case 30:
6369 switch (sel) {
6370 case 0:
6371 tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_ErrorEPC));
6372 rn = "ErrorEPC";
6373 break;
6374 default:
6375 goto die;
6377 break;
6378 case 31:
6379 switch (sel) {
6380 case 0:
6381 /* EJTAG support */
6382 gen_mtc0_store32(arg, offsetof(CPUMIPSState, CP0_DESAVE));
6383 rn = "DESAVE";
6384 break;
6385 default:
6386 goto die;
6388 /* Stop translation as we may have switched the execution mode */
6389 ctx->bstate = BS_STOP;
6390 break;
6391 default:
6392 goto die;
6394 (void)rn; /* avoid a compiler warning */
6395 LOG_DISAS("dmtc0 %s (reg %d sel %d)\n", rn, reg, sel);
6396 /* For simplicity assume that all writes can cause interrupts. */
6397 if (use_icount) {
6398 gen_io_end();
6399 ctx->bstate = BS_STOP;
6401 return;
6403 die:
6404 LOG_DISAS("dmtc0 %s (reg %d sel %d)\n", rn, reg, sel);
6405 generate_exception(ctx, EXCP_RI);
6407 #endif /* TARGET_MIPS64 */
6409 static void gen_mftr(CPUMIPSState *env, DisasContext *ctx, int rt, int rd,
6410 int u, int sel, int h)
6412 int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
6413 TCGv t0 = tcg_temp_local_new();
6415 if ((env->CP0_VPEConf0 & (1 << CP0VPEC0_MVP)) == 0 &&
6416 ((env->tcs[other_tc].CP0_TCBind & (0xf << CP0TCBd_CurVPE)) !=
6417 (env->active_tc.CP0_TCBind & (0xf << CP0TCBd_CurVPE))))
6418 tcg_gen_movi_tl(t0, -1);
6419 else if ((env->CP0_VPEControl & (0xff << CP0VPECo_TargTC)) >
6420 (env->mvp->CP0_MVPConf0 & (0xff << CP0MVPC0_PTC)))
6421 tcg_gen_movi_tl(t0, -1);
6422 else if (u == 0) {
6423 switch (rt) {
6424 case 1:
6425 switch (sel) {
6426 case 1:
6427 gen_helper_mftc0_vpecontrol(t0, cpu_env);
6428 break;
6429 case 2:
6430 gen_helper_mftc0_vpeconf0(t0, cpu_env);
6431 break;
6432 default:
6433 goto die;
6434 break;
6436 break;
6437 case 2:
6438 switch (sel) {
6439 case 1:
6440 gen_helper_mftc0_tcstatus(t0, cpu_env);
6441 break;
6442 case 2:
6443 gen_helper_mftc0_tcbind(t0, cpu_env);
6444 break;
6445 case 3:
6446 gen_helper_mftc0_tcrestart(t0, cpu_env);
6447 break;
6448 case 4:
6449 gen_helper_mftc0_tchalt(t0, cpu_env);
6450 break;
6451 case 5:
6452 gen_helper_mftc0_tccontext(t0, cpu_env);
6453 break;
6454 case 6:
6455 gen_helper_mftc0_tcschedule(t0, cpu_env);
6456 break;
6457 case 7:
6458 gen_helper_mftc0_tcschefback(t0, cpu_env);
6459 break;
6460 default:
6461 gen_mfc0(ctx, t0, rt, sel);
6462 break;
6464 break;
6465 case 10:
6466 switch (sel) {
6467 case 0:
6468 gen_helper_mftc0_entryhi(t0, cpu_env);
6469 break;
6470 default:
6471 gen_mfc0(ctx, t0, rt, sel);
6472 break;
6474 case 12:
6475 switch (sel) {
6476 case 0:
6477 gen_helper_mftc0_status(t0, cpu_env);
6478 break;
6479 default:
6480 gen_mfc0(ctx, t0, rt, sel);
6481 break;
6483 case 13:
6484 switch (sel) {
6485 case 0:
6486 gen_helper_mftc0_cause(t0, cpu_env);
6487 break;
6488 default:
6489 goto die;
6490 break;
6492 break;
6493 case 14:
6494 switch (sel) {
6495 case 0:
6496 gen_helper_mftc0_epc(t0, cpu_env);
6497 break;
6498 default:
6499 goto die;
6500 break;
6502 break;
6503 case 15:
6504 switch (sel) {
6505 case 1:
6506 gen_helper_mftc0_ebase(t0, cpu_env);
6507 break;
6508 default:
6509 goto die;
6510 break;
6512 break;
6513 case 16:
6514 switch (sel) {
6515 case 0 ... 7:
6516 gen_helper_mftc0_configx(t0, cpu_env, tcg_const_tl(sel));
6517 break;
6518 default:
6519 goto die;
6520 break;
6522 break;
6523 case 23:
6524 switch (sel) {
6525 case 0:
6526 gen_helper_mftc0_debug(t0, cpu_env);
6527 break;
6528 default:
6529 gen_mfc0(ctx, t0, rt, sel);
6530 break;
6532 break;
6533 default:
6534 gen_mfc0(ctx, t0, rt, sel);
6536 } else switch (sel) {
6537 /* GPR registers. */
6538 case 0:
6539 gen_helper_1e0i(mftgpr, t0, rt);
6540 break;
6541 /* Auxiliary CPU registers */
6542 case 1:
6543 switch (rt) {
6544 case 0:
6545 gen_helper_1e0i(mftlo, t0, 0);
6546 break;
6547 case 1:
6548 gen_helper_1e0i(mfthi, t0, 0);
6549 break;
6550 case 2:
6551 gen_helper_1e0i(mftacx, t0, 0);
6552 break;
6553 case 4:
6554 gen_helper_1e0i(mftlo, t0, 1);
6555 break;
6556 case 5:
6557 gen_helper_1e0i(mfthi, t0, 1);
6558 break;
6559 case 6:
6560 gen_helper_1e0i(mftacx, t0, 1);
6561 break;
6562 case 8:
6563 gen_helper_1e0i(mftlo, t0, 2);
6564 break;
6565 case 9:
6566 gen_helper_1e0i(mfthi, t0, 2);
6567 break;
6568 case 10:
6569 gen_helper_1e0i(mftacx, t0, 2);
6570 break;
6571 case 12:
6572 gen_helper_1e0i(mftlo, t0, 3);
6573 break;
6574 case 13:
6575 gen_helper_1e0i(mfthi, t0, 3);
6576 break;
6577 case 14:
6578 gen_helper_1e0i(mftacx, t0, 3);
6579 break;
6580 case 16:
6581 gen_helper_mftdsp(t0, cpu_env);
6582 break;
6583 default:
6584 goto die;
6586 break;
6587 /* Floating point (COP1). */
6588 case 2:
6589 /* XXX: For now we support only a single FPU context. */
6590 if (h == 0) {
6591 TCGv_i32 fp0 = tcg_temp_new_i32();
6593 gen_load_fpr32(fp0, rt);
6594 tcg_gen_ext_i32_tl(t0, fp0);
6595 tcg_temp_free_i32(fp0);
6596 } else {
6597 TCGv_i32 fp0 = tcg_temp_new_i32();
6599 gen_load_fpr32h(fp0, rt);
6600 tcg_gen_ext_i32_tl(t0, fp0);
6601 tcg_temp_free_i32(fp0);
6603 break;
6604 case 3:
6605 /* XXX: For now we support only a single FPU context. */
6606 gen_helper_1e0i(cfc1, t0, rt);
6607 break;
6608 /* COP2: Not implemented. */
6609 case 4:
6610 case 5:
6611 /* fall through */
6612 default:
6613 goto die;
6615 LOG_DISAS("mftr (reg %d u %d sel %d h %d)\n", rt, u, sel, h);
6616 gen_store_gpr(t0, rd);
6617 tcg_temp_free(t0);
6618 return;
6620 die:
6621 tcg_temp_free(t0);
6622 LOG_DISAS("mftr (reg %d u %d sel %d h %d)\n", rt, u, sel, h);
6623 generate_exception(ctx, EXCP_RI);
6626 static void gen_mttr(CPUMIPSState *env, DisasContext *ctx, int rd, int rt,
6627 int u, int sel, int h)
6629 int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
6630 TCGv t0 = tcg_temp_local_new();
6632 gen_load_gpr(t0, rt);
6633 if ((env->CP0_VPEConf0 & (1 << CP0VPEC0_MVP)) == 0 &&
6634 ((env->tcs[other_tc].CP0_TCBind & (0xf << CP0TCBd_CurVPE)) !=
6635 (env->active_tc.CP0_TCBind & (0xf << CP0TCBd_CurVPE))))
6636 /* NOP */ ;
6637 else if ((env->CP0_VPEControl & (0xff << CP0VPECo_TargTC)) >
6638 (env->mvp->CP0_MVPConf0 & (0xff << CP0MVPC0_PTC)))
6639 /* NOP */ ;
6640 else if (u == 0) {
6641 switch (rd) {
6642 case 1:
6643 switch (sel) {
6644 case 1:
6645 gen_helper_mttc0_vpecontrol(cpu_env, t0);
6646 break;
6647 case 2:
6648 gen_helper_mttc0_vpeconf0(cpu_env, t0);
6649 break;
6650 default:
6651 goto die;
6652 break;
6654 break;
6655 case 2:
6656 switch (sel) {
6657 case 1:
6658 gen_helper_mttc0_tcstatus(cpu_env, t0);
6659 break;
6660 case 2:
6661 gen_helper_mttc0_tcbind(cpu_env, t0);
6662 break;
6663 case 3:
6664 gen_helper_mttc0_tcrestart(cpu_env, t0);
6665 break;
6666 case 4:
6667 gen_helper_mttc0_tchalt(cpu_env, t0);
6668 break;
6669 case 5:
6670 gen_helper_mttc0_tccontext(cpu_env, t0);
6671 break;
6672 case 6:
6673 gen_helper_mttc0_tcschedule(cpu_env, t0);
6674 break;
6675 case 7:
6676 gen_helper_mttc0_tcschefback(cpu_env, t0);
6677 break;
6678 default:
6679 gen_mtc0(ctx, t0, rd, sel);
6680 break;
6682 break;
6683 case 10:
6684 switch (sel) {
6685 case 0:
6686 gen_helper_mttc0_entryhi(cpu_env, t0);
6687 break;
6688 default:
6689 gen_mtc0(ctx, t0, rd, sel);
6690 break;
6692 case 12:
6693 switch (sel) {
6694 case 0:
6695 gen_helper_mttc0_status(cpu_env, t0);
6696 break;
6697 default:
6698 gen_mtc0(ctx, t0, rd, sel);
6699 break;
6701 case 13:
6702 switch (sel) {
6703 case 0:
6704 gen_helper_mttc0_cause(cpu_env, t0);
6705 break;
6706 default:
6707 goto die;
6708 break;
6710 break;
6711 case 15:
6712 switch (sel) {
6713 case 1:
6714 gen_helper_mttc0_ebase(cpu_env, t0);
6715 break;
6716 default:
6717 goto die;
6718 break;
6720 break;
6721 case 23:
6722 switch (sel) {
6723 case 0:
6724 gen_helper_mttc0_debug(cpu_env, t0);
6725 break;
6726 default:
6727 gen_mtc0(ctx, t0, rd, sel);
6728 break;
6730 break;
6731 default:
6732 gen_mtc0(ctx, t0, rd, sel);
6734 } else switch (sel) {
6735 /* GPR registers. */
6736 case 0:
6737 gen_helper_0e1i(mttgpr, t0, rd);
6738 break;
6739 /* Auxiliary CPU registers */
6740 case 1:
6741 switch (rd) {
6742 case 0:
6743 gen_helper_0e1i(mttlo, t0, 0);
6744 break;
6745 case 1:
6746 gen_helper_0e1i(mtthi, t0, 0);
6747 break;
6748 case 2:
6749 gen_helper_0e1i(mttacx, t0, 0);
6750 break;
6751 case 4:
6752 gen_helper_0e1i(mttlo, t0, 1);
6753 break;
6754 case 5:
6755 gen_helper_0e1i(mtthi, t0, 1);
6756 break;
6757 case 6:
6758 gen_helper_0e1i(mttacx, t0, 1);
6759 break;
6760 case 8:
6761 gen_helper_0e1i(mttlo, t0, 2);
6762 break;
6763 case 9:
6764 gen_helper_0e1i(mtthi, t0, 2);
6765 break;
6766 case 10:
6767 gen_helper_0e1i(mttacx, t0, 2);
6768 break;
6769 case 12:
6770 gen_helper_0e1i(mttlo, t0, 3);
6771 break;
6772 case 13:
6773 gen_helper_0e1i(mtthi, t0, 3);
6774 break;
6775 case 14:
6776 gen_helper_0e1i(mttacx, t0, 3);
6777 break;
6778 case 16:
6779 gen_helper_mttdsp(cpu_env, t0);
6780 break;
6781 default:
6782 goto die;
6784 break;
6785 /* Floating point (COP1). */
6786 case 2:
6787 /* XXX: For now we support only a single FPU context. */
6788 if (h == 0) {
6789 TCGv_i32 fp0 = tcg_temp_new_i32();
6791 tcg_gen_trunc_tl_i32(fp0, t0);
6792 gen_store_fpr32(fp0, rd);
6793 tcg_temp_free_i32(fp0);
6794 } else {
6795 TCGv_i32 fp0 = tcg_temp_new_i32();
6797 tcg_gen_trunc_tl_i32(fp0, t0);
6798 gen_store_fpr32h(fp0, rd);
6799 tcg_temp_free_i32(fp0);
6801 break;
6802 case 3:
6803 /* XXX: For now we support only a single FPU context. */
6804 gen_helper_0e1i(ctc1, t0, rd);
6805 break;
6806 /* COP2: Not implemented. */
6807 case 4:
6808 case 5:
6809 /* fall through */
6810 default:
6811 goto die;
6813 LOG_DISAS("mttr (reg %d u %d sel %d h %d)\n", rd, u, sel, h);
6814 tcg_temp_free(t0);
6815 return;
6817 die:
6818 tcg_temp_free(t0);
6819 LOG_DISAS("mttr (reg %d u %d sel %d h %d)\n", rd, u, sel, h);
6820 generate_exception(ctx, EXCP_RI);
6823 static void gen_cp0 (CPUMIPSState *env, DisasContext *ctx, uint32_t opc, int rt, int rd)
6825 const char *opn = "ldst";
6827 check_cp0_enabled(ctx);
6828 switch (opc) {
6829 case OPC_MFC0:
6830 if (rt == 0) {
6831 /* Treat as NOP. */
6832 return;
6834 gen_mfc0(ctx, cpu_gpr[rt], rd, ctx->opcode & 0x7);
6835 opn = "mfc0";
6836 break;
6837 case OPC_MTC0:
6839 TCGv t0 = tcg_temp_new();
6841 gen_load_gpr(t0, rt);
6842 gen_mtc0(ctx, t0, rd, ctx->opcode & 0x7);
6843 tcg_temp_free(t0);
6845 opn = "mtc0";
6846 break;
6847 #if defined(TARGET_MIPS64)
6848 case OPC_DMFC0:
6849 check_insn(ctx, ISA_MIPS3);
6850 if (rt == 0) {
6851 /* Treat as NOP. */
6852 return;
6854 gen_dmfc0(ctx, cpu_gpr[rt], rd, ctx->opcode & 0x7);
6855 opn = "dmfc0";
6856 break;
6857 case OPC_DMTC0:
6858 check_insn(ctx, ISA_MIPS3);
6860 TCGv t0 = tcg_temp_new();
6862 gen_load_gpr(t0, rt);
6863 gen_dmtc0(ctx, t0, rd, ctx->opcode & 0x7);
6864 tcg_temp_free(t0);
6866 opn = "dmtc0";
6867 break;
6868 #endif
6869 case OPC_MFTR:
6870 check_insn(ctx, ASE_MT);
6871 if (rd == 0) {
6872 /* Treat as NOP. */
6873 return;
6875 gen_mftr(env, ctx, rt, rd, (ctx->opcode >> 5) & 1,
6876 ctx->opcode & 0x7, (ctx->opcode >> 4) & 1);
6877 opn = "mftr";
6878 break;
6879 case OPC_MTTR:
6880 check_insn(ctx, ASE_MT);
6881 gen_mttr(env, ctx, rd, rt, (ctx->opcode >> 5) & 1,
6882 ctx->opcode & 0x7, (ctx->opcode >> 4) & 1);
6883 opn = "mttr";
6884 break;
6885 case OPC_TLBWI:
6886 opn = "tlbwi";
6887 if (!env->tlb->helper_tlbwi)
6888 goto die;
6889 gen_helper_tlbwi(cpu_env);
6890 break;
6891 case OPC_TLBWR:
6892 opn = "tlbwr";
6893 if (!env->tlb->helper_tlbwr)
6894 goto die;
6895 gen_helper_tlbwr(cpu_env);
6896 break;
6897 case OPC_TLBP:
6898 opn = "tlbp";
6899 if (!env->tlb->helper_tlbp)
6900 goto die;
6901 gen_helper_tlbp(cpu_env);
6902 break;
6903 case OPC_TLBR:
6904 opn = "tlbr";
6905 if (!env->tlb->helper_tlbr)
6906 goto die;
6907 gen_helper_tlbr(cpu_env);
6908 break;
6909 case OPC_ERET:
6910 opn = "eret";
6911 check_insn(ctx, ISA_MIPS2);
6912 gen_helper_eret(cpu_env);
6913 ctx->bstate = BS_EXCP;
6914 break;
6915 case OPC_DERET:
6916 opn = "deret";
6917 check_insn(ctx, ISA_MIPS32);
6918 if (!(ctx->hflags & MIPS_HFLAG_DM)) {
6919 MIPS_INVAL(opn);
6920 generate_exception(ctx, EXCP_RI);
6921 } else {
6922 gen_helper_deret(cpu_env);
6923 ctx->bstate = BS_EXCP;
6925 break;
6926 case OPC_WAIT:
6927 opn = "wait";
6928 check_insn(ctx, ISA_MIPS3 | ISA_MIPS32);
6929 /* If we get an exception, we want to restart at next instruction */
6930 ctx->pc += 4;
6931 save_cpu_state(ctx, 1);
6932 ctx->pc -= 4;
6933 gen_helper_wait(cpu_env);
6934 ctx->bstate = BS_EXCP;
6935 break;
6936 default:
6937 die:
6938 MIPS_INVAL(opn);
6939 generate_exception(ctx, EXCP_RI);
6940 return;
6942 (void)opn; /* avoid a compiler warning */
6943 MIPS_DEBUG("%s %s %d", opn, regnames[rt], rd);
6945 #endif /* !CONFIG_USER_ONLY */
6947 /* CP1 Branches (before delay slot) */
6948 static void gen_compute_branch1(DisasContext *ctx, uint32_t op,
6949 int32_t cc, int32_t offset)
6951 target_ulong btarget;
6952 const char *opn = "cp1 cond branch";
6953 TCGv_i32 t0 = tcg_temp_new_i32();
6955 if (cc != 0)
6956 check_insn(ctx, ISA_MIPS4 | ISA_MIPS32);
6958 btarget = ctx->pc + 4 + offset;
6960 switch (op) {
6961 case OPC_BC1F:
6962 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
6963 tcg_gen_not_i32(t0, t0);
6964 tcg_gen_andi_i32(t0, t0, 1);
6965 tcg_gen_extu_i32_tl(bcond, t0);
6966 opn = "bc1f";
6967 goto not_likely;
6968 case OPC_BC1FL:
6969 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
6970 tcg_gen_not_i32(t0, t0);
6971 tcg_gen_andi_i32(t0, t0, 1);
6972 tcg_gen_extu_i32_tl(bcond, t0);
6973 opn = "bc1fl";
6974 goto likely;
6975 case OPC_BC1T:
6976 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
6977 tcg_gen_andi_i32(t0, t0, 1);
6978 tcg_gen_extu_i32_tl(bcond, t0);
6979 opn = "bc1t";
6980 goto not_likely;
6981 case OPC_BC1TL:
6982 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
6983 tcg_gen_andi_i32(t0, t0, 1);
6984 tcg_gen_extu_i32_tl(bcond, t0);
6985 opn = "bc1tl";
6986 likely:
6987 ctx->hflags |= MIPS_HFLAG_BL;
6988 break;
6989 case OPC_BC1FANY2:
6991 TCGv_i32 t1 = tcg_temp_new_i32();
6992 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
6993 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+1));
6994 tcg_gen_nand_i32(t0, t0, t1);
6995 tcg_temp_free_i32(t1);
6996 tcg_gen_andi_i32(t0, t0, 1);
6997 tcg_gen_extu_i32_tl(bcond, t0);
6999 opn = "bc1any2f";
7000 goto not_likely;
7001 case OPC_BC1TANY2:
7003 TCGv_i32 t1 = tcg_temp_new_i32();
7004 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
7005 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+1));
7006 tcg_gen_or_i32(t0, t0, t1);
7007 tcg_temp_free_i32(t1);
7008 tcg_gen_andi_i32(t0, t0, 1);
7009 tcg_gen_extu_i32_tl(bcond, t0);
7011 opn = "bc1any2t";
7012 goto not_likely;
7013 case OPC_BC1FANY4:
7015 TCGv_i32 t1 = tcg_temp_new_i32();
7016 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
7017 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+1));
7018 tcg_gen_and_i32(t0, t0, t1);
7019 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+2));
7020 tcg_gen_and_i32(t0, t0, t1);
7021 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+3));
7022 tcg_gen_nand_i32(t0, t0, t1);
7023 tcg_temp_free_i32(t1);
7024 tcg_gen_andi_i32(t0, t0, 1);
7025 tcg_gen_extu_i32_tl(bcond, t0);
7027 opn = "bc1any4f";
7028 goto not_likely;
7029 case OPC_BC1TANY4:
7031 TCGv_i32 t1 = tcg_temp_new_i32();
7032 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
7033 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+1));
7034 tcg_gen_or_i32(t0, t0, t1);
7035 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+2));
7036 tcg_gen_or_i32(t0, t0, t1);
7037 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+3));
7038 tcg_gen_or_i32(t0, t0, t1);
7039 tcg_temp_free_i32(t1);
7040 tcg_gen_andi_i32(t0, t0, 1);
7041 tcg_gen_extu_i32_tl(bcond, t0);
7043 opn = "bc1any4t";
7044 not_likely:
7045 ctx->hflags |= MIPS_HFLAG_BC;
7046 break;
7047 default:
7048 MIPS_INVAL(opn);
7049 generate_exception (ctx, EXCP_RI);
7050 goto out;
7052 (void)opn; /* avoid a compiler warning */
7053 MIPS_DEBUG("%s: cond %02x target " TARGET_FMT_lx, opn,
7054 ctx->hflags, btarget);
7055 ctx->btarget = btarget;
7057 out:
7058 tcg_temp_free_i32(t0);
7061 /* Coprocessor 1 (FPU) */
7063 #define FOP(func, fmt) (((fmt) << 21) | (func))
7065 enum fopcode {
7066 OPC_ADD_S = FOP(0, FMT_S),
7067 OPC_SUB_S = FOP(1, FMT_S),
7068 OPC_MUL_S = FOP(2, FMT_S),
7069 OPC_DIV_S = FOP(3, FMT_S),
7070 OPC_SQRT_S = FOP(4, FMT_S),
7071 OPC_ABS_S = FOP(5, FMT_S),
7072 OPC_MOV_S = FOP(6, FMT_S),
7073 OPC_NEG_S = FOP(7, FMT_S),
7074 OPC_ROUND_L_S = FOP(8, FMT_S),
7075 OPC_TRUNC_L_S = FOP(9, FMT_S),
7076 OPC_CEIL_L_S = FOP(10, FMT_S),
7077 OPC_FLOOR_L_S = FOP(11, FMT_S),
7078 OPC_ROUND_W_S = FOP(12, FMT_S),
7079 OPC_TRUNC_W_S = FOP(13, FMT_S),
7080 OPC_CEIL_W_S = FOP(14, FMT_S),
7081 OPC_FLOOR_W_S = FOP(15, FMT_S),
7082 OPC_MOVCF_S = FOP(17, FMT_S),
7083 OPC_MOVZ_S = FOP(18, FMT_S),
7084 OPC_MOVN_S = FOP(19, FMT_S),
7085 OPC_RECIP_S = FOP(21, FMT_S),
7086 OPC_RSQRT_S = FOP(22, FMT_S),
7087 OPC_RECIP2_S = FOP(28, FMT_S),
7088 OPC_RECIP1_S = FOP(29, FMT_S),
7089 OPC_RSQRT1_S = FOP(30, FMT_S),
7090 OPC_RSQRT2_S = FOP(31, FMT_S),
7091 OPC_CVT_D_S = FOP(33, FMT_S),
7092 OPC_CVT_W_S = FOP(36, FMT_S),
7093 OPC_CVT_L_S = FOP(37, FMT_S),
7094 OPC_CVT_PS_S = FOP(38, FMT_S),
7095 OPC_CMP_F_S = FOP (48, FMT_S),
7096 OPC_CMP_UN_S = FOP (49, FMT_S),
7097 OPC_CMP_EQ_S = FOP (50, FMT_S),
7098 OPC_CMP_UEQ_S = FOP (51, FMT_S),
7099 OPC_CMP_OLT_S = FOP (52, FMT_S),
7100 OPC_CMP_ULT_S = FOP (53, FMT_S),
7101 OPC_CMP_OLE_S = FOP (54, FMT_S),
7102 OPC_CMP_ULE_S = FOP (55, FMT_S),
7103 OPC_CMP_SF_S = FOP (56, FMT_S),
7104 OPC_CMP_NGLE_S = FOP (57, FMT_S),
7105 OPC_CMP_SEQ_S = FOP (58, FMT_S),
7106 OPC_CMP_NGL_S = FOP (59, FMT_S),
7107 OPC_CMP_LT_S = FOP (60, FMT_S),
7108 OPC_CMP_NGE_S = FOP (61, FMT_S),
7109 OPC_CMP_LE_S = FOP (62, FMT_S),
7110 OPC_CMP_NGT_S = FOP (63, FMT_S),
7112 OPC_ADD_D = FOP(0, FMT_D),
7113 OPC_SUB_D = FOP(1, FMT_D),
7114 OPC_MUL_D = FOP(2, FMT_D),
7115 OPC_DIV_D = FOP(3, FMT_D),
7116 OPC_SQRT_D = FOP(4, FMT_D),
7117 OPC_ABS_D = FOP(5, FMT_D),
7118 OPC_MOV_D = FOP(6, FMT_D),
7119 OPC_NEG_D = FOP(7, FMT_D),
7120 OPC_ROUND_L_D = FOP(8, FMT_D),
7121 OPC_TRUNC_L_D = FOP(9, FMT_D),
7122 OPC_CEIL_L_D = FOP(10, FMT_D),
7123 OPC_FLOOR_L_D = FOP(11, FMT_D),
7124 OPC_ROUND_W_D = FOP(12, FMT_D),
7125 OPC_TRUNC_W_D = FOP(13, FMT_D),
7126 OPC_CEIL_W_D = FOP(14, FMT_D),
7127 OPC_FLOOR_W_D = FOP(15, FMT_D),
7128 OPC_MOVCF_D = FOP(17, FMT_D),
7129 OPC_MOVZ_D = FOP(18, FMT_D),
7130 OPC_MOVN_D = FOP(19, FMT_D),
7131 OPC_RECIP_D = FOP(21, FMT_D),
7132 OPC_RSQRT_D = FOP(22, FMT_D),
7133 OPC_RECIP2_D = FOP(28, FMT_D),
7134 OPC_RECIP1_D = FOP(29, FMT_D),
7135 OPC_RSQRT1_D = FOP(30, FMT_D),
7136 OPC_RSQRT2_D = FOP(31, FMT_D),
7137 OPC_CVT_S_D = FOP(32, FMT_D),
7138 OPC_CVT_W_D = FOP(36, FMT_D),
7139 OPC_CVT_L_D = FOP(37, FMT_D),
7140 OPC_CMP_F_D = FOP (48, FMT_D),
7141 OPC_CMP_UN_D = FOP (49, FMT_D),
7142 OPC_CMP_EQ_D = FOP (50, FMT_D),
7143 OPC_CMP_UEQ_D = FOP (51, FMT_D),
7144 OPC_CMP_OLT_D = FOP (52, FMT_D),
7145 OPC_CMP_ULT_D = FOP (53, FMT_D),
7146 OPC_CMP_OLE_D = FOP (54, FMT_D),
7147 OPC_CMP_ULE_D = FOP (55, FMT_D),
7148 OPC_CMP_SF_D = FOP (56, FMT_D),
7149 OPC_CMP_NGLE_D = FOP (57, FMT_D),
7150 OPC_CMP_SEQ_D = FOP (58, FMT_D),
7151 OPC_CMP_NGL_D = FOP (59, FMT_D),
7152 OPC_CMP_LT_D = FOP (60, FMT_D),
7153 OPC_CMP_NGE_D = FOP (61, FMT_D),
7154 OPC_CMP_LE_D = FOP (62, FMT_D),
7155 OPC_CMP_NGT_D = FOP (63, FMT_D),
7157 OPC_CVT_S_W = FOP(32, FMT_W),
7158 OPC_CVT_D_W = FOP(33, FMT_W),
7159 OPC_CVT_S_L = FOP(32, FMT_L),
7160 OPC_CVT_D_L = FOP(33, FMT_L),
7161 OPC_CVT_PS_PW = FOP(38, FMT_W),
7163 OPC_ADD_PS = FOP(0, FMT_PS),
7164 OPC_SUB_PS = FOP(1, FMT_PS),
7165 OPC_MUL_PS = FOP(2, FMT_PS),
7166 OPC_DIV_PS = FOP(3, FMT_PS),
7167 OPC_ABS_PS = FOP(5, FMT_PS),
7168 OPC_MOV_PS = FOP(6, FMT_PS),
7169 OPC_NEG_PS = FOP(7, FMT_PS),
7170 OPC_MOVCF_PS = FOP(17, FMT_PS),
7171 OPC_MOVZ_PS = FOP(18, FMT_PS),
7172 OPC_MOVN_PS = FOP(19, FMT_PS),
7173 OPC_ADDR_PS = FOP(24, FMT_PS),
7174 OPC_MULR_PS = FOP(26, FMT_PS),
7175 OPC_RECIP2_PS = FOP(28, FMT_PS),
7176 OPC_RECIP1_PS = FOP(29, FMT_PS),
7177 OPC_RSQRT1_PS = FOP(30, FMT_PS),
7178 OPC_RSQRT2_PS = FOP(31, FMT_PS),
7180 OPC_CVT_S_PU = FOP(32, FMT_PS),
7181 OPC_CVT_PW_PS = FOP(36, FMT_PS),
7182 OPC_CVT_S_PL = FOP(40, FMT_PS),
7183 OPC_PLL_PS = FOP(44, FMT_PS),
7184 OPC_PLU_PS = FOP(45, FMT_PS),
7185 OPC_PUL_PS = FOP(46, FMT_PS),
7186 OPC_PUU_PS = FOP(47, FMT_PS),
7187 OPC_CMP_F_PS = FOP (48, FMT_PS),
7188 OPC_CMP_UN_PS = FOP (49, FMT_PS),
7189 OPC_CMP_EQ_PS = FOP (50, FMT_PS),
7190 OPC_CMP_UEQ_PS = FOP (51, FMT_PS),
7191 OPC_CMP_OLT_PS = FOP (52, FMT_PS),
7192 OPC_CMP_ULT_PS = FOP (53, FMT_PS),
7193 OPC_CMP_OLE_PS = FOP (54, FMT_PS),
7194 OPC_CMP_ULE_PS = FOP (55, FMT_PS),
7195 OPC_CMP_SF_PS = FOP (56, FMT_PS),
7196 OPC_CMP_NGLE_PS = FOP (57, FMT_PS),
7197 OPC_CMP_SEQ_PS = FOP (58, FMT_PS),
7198 OPC_CMP_NGL_PS = FOP (59, FMT_PS),
7199 OPC_CMP_LT_PS = FOP (60, FMT_PS),
7200 OPC_CMP_NGE_PS = FOP (61, FMT_PS),
7201 OPC_CMP_LE_PS = FOP (62, FMT_PS),
7202 OPC_CMP_NGT_PS = FOP (63, FMT_PS),
7205 static void gen_cp1 (DisasContext *ctx, uint32_t opc, int rt, int fs)
7207 const char *opn = "cp1 move";
7208 TCGv t0 = tcg_temp_new();
7210 switch (opc) {
7211 case OPC_MFC1:
7213 TCGv_i32 fp0 = tcg_temp_new_i32();
7215 gen_load_fpr32(fp0, fs);
7216 tcg_gen_ext_i32_tl(t0, fp0);
7217 tcg_temp_free_i32(fp0);
7219 gen_store_gpr(t0, rt);
7220 opn = "mfc1";
7221 break;
7222 case OPC_MTC1:
7223 gen_load_gpr(t0, rt);
7225 TCGv_i32 fp0 = tcg_temp_new_i32();
7227 tcg_gen_trunc_tl_i32(fp0, t0);
7228 gen_store_fpr32(fp0, fs);
7229 tcg_temp_free_i32(fp0);
7231 opn = "mtc1";
7232 break;
7233 case OPC_CFC1:
7234 gen_helper_1e0i(cfc1, t0, fs);
7235 gen_store_gpr(t0, rt);
7236 opn = "cfc1";
7237 break;
7238 case OPC_CTC1:
7239 gen_load_gpr(t0, rt);
7240 gen_helper_0e1i(ctc1, t0, fs);
7241 opn = "ctc1";
7242 break;
7243 #if defined(TARGET_MIPS64)
7244 case OPC_DMFC1:
7245 gen_load_fpr64(ctx, t0, fs);
7246 gen_store_gpr(t0, rt);
7247 opn = "dmfc1";
7248 break;
7249 case OPC_DMTC1:
7250 gen_load_gpr(t0, rt);
7251 gen_store_fpr64(ctx, t0, fs);
7252 opn = "dmtc1";
7253 break;
7254 #endif
7255 case OPC_MFHC1:
7257 TCGv_i32 fp0 = tcg_temp_new_i32();
7259 gen_load_fpr32h(fp0, fs);
7260 tcg_gen_ext_i32_tl(t0, fp0);
7261 tcg_temp_free_i32(fp0);
7263 gen_store_gpr(t0, rt);
7264 opn = "mfhc1";
7265 break;
7266 case OPC_MTHC1:
7267 gen_load_gpr(t0, rt);
7269 TCGv_i32 fp0 = tcg_temp_new_i32();
7271 tcg_gen_trunc_tl_i32(fp0, t0);
7272 gen_store_fpr32h(fp0, fs);
7273 tcg_temp_free_i32(fp0);
7275 opn = "mthc1";
7276 break;
7277 default:
7278 MIPS_INVAL(opn);
7279 generate_exception (ctx, EXCP_RI);
7280 goto out;
7282 (void)opn; /* avoid a compiler warning */
7283 MIPS_DEBUG("%s %s %s", opn, regnames[rt], fregnames[fs]);
7285 out:
7286 tcg_temp_free(t0);
7289 static void gen_movci (DisasContext *ctx, int rd, int rs, int cc, int tf)
7291 int l1;
7292 TCGCond cond;
7293 TCGv_i32 t0;
7295 if (rd == 0) {
7296 /* Treat as NOP. */
7297 return;
7300 if (tf)
7301 cond = TCG_COND_EQ;
7302 else
7303 cond = TCG_COND_NE;
7305 l1 = gen_new_label();
7306 t0 = tcg_temp_new_i32();
7307 tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc));
7308 tcg_gen_brcondi_i32(cond, t0, 0, l1);
7309 tcg_temp_free_i32(t0);
7310 if (rs == 0) {
7311 tcg_gen_movi_tl(cpu_gpr[rd], 0);
7312 } else {
7313 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
7315 gen_set_label(l1);
7318 static inline void gen_movcf_s (int fs, int fd, int cc, int tf)
7320 int cond;
7321 TCGv_i32 t0 = tcg_temp_new_i32();
7322 int l1 = gen_new_label();
7324 if (tf)
7325 cond = TCG_COND_EQ;
7326 else
7327 cond = TCG_COND_NE;
7329 tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc));
7330 tcg_gen_brcondi_i32(cond, t0, 0, l1);
7331 gen_load_fpr32(t0, fs);
7332 gen_store_fpr32(t0, fd);
7333 gen_set_label(l1);
7334 tcg_temp_free_i32(t0);
7337 static inline void gen_movcf_d (DisasContext *ctx, int fs, int fd, int cc, int tf)
7339 int cond;
7340 TCGv_i32 t0 = tcg_temp_new_i32();
7341 TCGv_i64 fp0;
7342 int l1 = gen_new_label();
7344 if (tf)
7345 cond = TCG_COND_EQ;
7346 else
7347 cond = TCG_COND_NE;
7349 tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc));
7350 tcg_gen_brcondi_i32(cond, t0, 0, l1);
7351 tcg_temp_free_i32(t0);
7352 fp0 = tcg_temp_new_i64();
7353 gen_load_fpr64(ctx, fp0, fs);
7354 gen_store_fpr64(ctx, fp0, fd);
7355 tcg_temp_free_i64(fp0);
7356 gen_set_label(l1);
7359 static inline void gen_movcf_ps (int fs, int fd, int cc, int tf)
7361 int cond;
7362 TCGv_i32 t0 = tcg_temp_new_i32();
7363 int l1 = gen_new_label();
7364 int l2 = gen_new_label();
7366 if (tf)
7367 cond = TCG_COND_EQ;
7368 else
7369 cond = TCG_COND_NE;
7371 tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc));
7372 tcg_gen_brcondi_i32(cond, t0, 0, l1);
7373 gen_load_fpr32(t0, fs);
7374 gen_store_fpr32(t0, fd);
7375 gen_set_label(l1);
7377 tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc+1));
7378 tcg_gen_brcondi_i32(cond, t0, 0, l2);
7379 gen_load_fpr32h(t0, fs);
7380 gen_store_fpr32h(t0, fd);
7381 tcg_temp_free_i32(t0);
7382 gen_set_label(l2);
7386 static void gen_farith (DisasContext *ctx, enum fopcode op1,
7387 int ft, int fs, int fd, int cc)
7389 const char *opn = "farith";
7390 const char *condnames[] = {
7391 "c.f",
7392 "c.un",
7393 "c.eq",
7394 "c.ueq",
7395 "c.olt",
7396 "c.ult",
7397 "c.ole",
7398 "c.ule",
7399 "c.sf",
7400 "c.ngle",
7401 "c.seq",
7402 "c.ngl",
7403 "c.lt",
7404 "c.nge",
7405 "c.le",
7406 "c.ngt",
7408 const char *condnames_abs[] = {
7409 "cabs.f",
7410 "cabs.un",
7411 "cabs.eq",
7412 "cabs.ueq",
7413 "cabs.olt",
7414 "cabs.ult",
7415 "cabs.ole",
7416 "cabs.ule",
7417 "cabs.sf",
7418 "cabs.ngle",
7419 "cabs.seq",
7420 "cabs.ngl",
7421 "cabs.lt",
7422 "cabs.nge",
7423 "cabs.le",
7424 "cabs.ngt",
7426 enum { BINOP, CMPOP, OTHEROP } optype = OTHEROP;
7427 uint32_t func = ctx->opcode & 0x3f;
7429 switch (op1) {
7430 case OPC_ADD_S:
7432 TCGv_i32 fp0 = tcg_temp_new_i32();
7433 TCGv_i32 fp1 = tcg_temp_new_i32();
7435 gen_load_fpr32(fp0, fs);
7436 gen_load_fpr32(fp1, ft);
7437 gen_helper_float_add_s(fp0, cpu_env, fp0, fp1);
7438 tcg_temp_free_i32(fp1);
7439 gen_store_fpr32(fp0, fd);
7440 tcg_temp_free_i32(fp0);
7442 opn = "add.s";
7443 optype = BINOP;
7444 break;
7445 case OPC_SUB_S:
7447 TCGv_i32 fp0 = tcg_temp_new_i32();
7448 TCGv_i32 fp1 = tcg_temp_new_i32();
7450 gen_load_fpr32(fp0, fs);
7451 gen_load_fpr32(fp1, ft);
7452 gen_helper_float_sub_s(fp0, cpu_env, fp0, fp1);
7453 tcg_temp_free_i32(fp1);
7454 gen_store_fpr32(fp0, fd);
7455 tcg_temp_free_i32(fp0);
7457 opn = "sub.s";
7458 optype = BINOP;
7459 break;
7460 case OPC_MUL_S:
7462 TCGv_i32 fp0 = tcg_temp_new_i32();
7463 TCGv_i32 fp1 = tcg_temp_new_i32();
7465 gen_load_fpr32(fp0, fs);
7466 gen_load_fpr32(fp1, ft);
7467 gen_helper_float_mul_s(fp0, cpu_env, fp0, fp1);
7468 tcg_temp_free_i32(fp1);
7469 gen_store_fpr32(fp0, fd);
7470 tcg_temp_free_i32(fp0);
7472 opn = "mul.s";
7473 optype = BINOP;
7474 break;
7475 case OPC_DIV_S:
7477 TCGv_i32 fp0 = tcg_temp_new_i32();
7478 TCGv_i32 fp1 = tcg_temp_new_i32();
7480 gen_load_fpr32(fp0, fs);
7481 gen_load_fpr32(fp1, ft);
7482 gen_helper_float_div_s(fp0, cpu_env, fp0, fp1);
7483 tcg_temp_free_i32(fp1);
7484 gen_store_fpr32(fp0, fd);
7485 tcg_temp_free_i32(fp0);
7487 opn = "div.s";
7488 optype = BINOP;
7489 break;
7490 case OPC_SQRT_S:
7492 TCGv_i32 fp0 = tcg_temp_new_i32();
7494 gen_load_fpr32(fp0, fs);
7495 gen_helper_float_sqrt_s(fp0, cpu_env, fp0);
7496 gen_store_fpr32(fp0, fd);
7497 tcg_temp_free_i32(fp0);
7499 opn = "sqrt.s";
7500 break;
7501 case OPC_ABS_S:
7503 TCGv_i32 fp0 = tcg_temp_new_i32();
7505 gen_load_fpr32(fp0, fs);
7506 gen_helper_float_abs_s(fp0, fp0);
7507 gen_store_fpr32(fp0, fd);
7508 tcg_temp_free_i32(fp0);
7510 opn = "abs.s";
7511 break;
7512 case OPC_MOV_S:
7514 TCGv_i32 fp0 = tcg_temp_new_i32();
7516 gen_load_fpr32(fp0, fs);
7517 gen_store_fpr32(fp0, fd);
7518 tcg_temp_free_i32(fp0);
7520 opn = "mov.s";
7521 break;
7522 case OPC_NEG_S:
7524 TCGv_i32 fp0 = tcg_temp_new_i32();
7526 gen_load_fpr32(fp0, fs);
7527 gen_helper_float_chs_s(fp0, fp0);
7528 gen_store_fpr32(fp0, fd);
7529 tcg_temp_free_i32(fp0);
7531 opn = "neg.s";
7532 break;
7533 case OPC_ROUND_L_S:
7534 check_cp1_64bitmode(ctx);
7536 TCGv_i32 fp32 = tcg_temp_new_i32();
7537 TCGv_i64 fp64 = tcg_temp_new_i64();
7539 gen_load_fpr32(fp32, fs);
7540 gen_helper_float_roundl_s(fp64, cpu_env, fp32);
7541 tcg_temp_free_i32(fp32);
7542 gen_store_fpr64(ctx, fp64, fd);
7543 tcg_temp_free_i64(fp64);
7545 opn = "round.l.s";
7546 break;
7547 case OPC_TRUNC_L_S:
7548 check_cp1_64bitmode(ctx);
7550 TCGv_i32 fp32 = tcg_temp_new_i32();
7551 TCGv_i64 fp64 = tcg_temp_new_i64();
7553 gen_load_fpr32(fp32, fs);
7554 gen_helper_float_truncl_s(fp64, cpu_env, fp32);
7555 tcg_temp_free_i32(fp32);
7556 gen_store_fpr64(ctx, fp64, fd);
7557 tcg_temp_free_i64(fp64);
7559 opn = "trunc.l.s";
7560 break;
7561 case OPC_CEIL_L_S:
7562 check_cp1_64bitmode(ctx);
7564 TCGv_i32 fp32 = tcg_temp_new_i32();
7565 TCGv_i64 fp64 = tcg_temp_new_i64();
7567 gen_load_fpr32(fp32, fs);
7568 gen_helper_float_ceill_s(fp64, cpu_env, fp32);
7569 tcg_temp_free_i32(fp32);
7570 gen_store_fpr64(ctx, fp64, fd);
7571 tcg_temp_free_i64(fp64);
7573 opn = "ceil.l.s";
7574 break;
7575 case OPC_FLOOR_L_S:
7576 check_cp1_64bitmode(ctx);
7578 TCGv_i32 fp32 = tcg_temp_new_i32();
7579 TCGv_i64 fp64 = tcg_temp_new_i64();
7581 gen_load_fpr32(fp32, fs);
7582 gen_helper_float_floorl_s(fp64, cpu_env, fp32);
7583 tcg_temp_free_i32(fp32);
7584 gen_store_fpr64(ctx, fp64, fd);
7585 tcg_temp_free_i64(fp64);
7587 opn = "floor.l.s";
7588 break;
7589 case OPC_ROUND_W_S:
7591 TCGv_i32 fp0 = tcg_temp_new_i32();
7593 gen_load_fpr32(fp0, fs);
7594 gen_helper_float_roundw_s(fp0, cpu_env, fp0);
7595 gen_store_fpr32(fp0, fd);
7596 tcg_temp_free_i32(fp0);
7598 opn = "round.w.s";
7599 break;
7600 case OPC_TRUNC_W_S:
7602 TCGv_i32 fp0 = tcg_temp_new_i32();
7604 gen_load_fpr32(fp0, fs);
7605 gen_helper_float_truncw_s(fp0, cpu_env, fp0);
7606 gen_store_fpr32(fp0, fd);
7607 tcg_temp_free_i32(fp0);
7609 opn = "trunc.w.s";
7610 break;
7611 case OPC_CEIL_W_S:
7613 TCGv_i32 fp0 = tcg_temp_new_i32();
7615 gen_load_fpr32(fp0, fs);
7616 gen_helper_float_ceilw_s(fp0, cpu_env, fp0);
7617 gen_store_fpr32(fp0, fd);
7618 tcg_temp_free_i32(fp0);
7620 opn = "ceil.w.s";
7621 break;
7622 case OPC_FLOOR_W_S:
7624 TCGv_i32 fp0 = tcg_temp_new_i32();
7626 gen_load_fpr32(fp0, fs);
7627 gen_helper_float_floorw_s(fp0, cpu_env, fp0);
7628 gen_store_fpr32(fp0, fd);
7629 tcg_temp_free_i32(fp0);
7631 opn = "floor.w.s";
7632 break;
7633 case OPC_MOVCF_S:
7634 gen_movcf_s(fs, fd, (ft >> 2) & 0x7, ft & 0x1);
7635 opn = "movcf.s";
7636 break;
7637 case OPC_MOVZ_S:
7639 int l1 = gen_new_label();
7640 TCGv_i32 fp0;
7642 if (ft != 0) {
7643 tcg_gen_brcondi_tl(TCG_COND_NE, cpu_gpr[ft], 0, l1);
7645 fp0 = tcg_temp_new_i32();
7646 gen_load_fpr32(fp0, fs);
7647 gen_store_fpr32(fp0, fd);
7648 tcg_temp_free_i32(fp0);
7649 gen_set_label(l1);
7651 opn = "movz.s";
7652 break;
7653 case OPC_MOVN_S:
7655 int l1 = gen_new_label();
7656 TCGv_i32 fp0;
7658 if (ft != 0) {
7659 tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_gpr[ft], 0, l1);
7660 fp0 = tcg_temp_new_i32();
7661 gen_load_fpr32(fp0, fs);
7662 gen_store_fpr32(fp0, fd);
7663 tcg_temp_free_i32(fp0);
7664 gen_set_label(l1);
7667 opn = "movn.s";
7668 break;
7669 case OPC_RECIP_S:
7670 check_cop1x(ctx);
7672 TCGv_i32 fp0 = tcg_temp_new_i32();
7674 gen_load_fpr32(fp0, fs);
7675 gen_helper_float_recip_s(fp0, cpu_env, fp0);
7676 gen_store_fpr32(fp0, fd);
7677 tcg_temp_free_i32(fp0);
7679 opn = "recip.s";
7680 break;
7681 case OPC_RSQRT_S:
7682 check_cop1x(ctx);
7684 TCGv_i32 fp0 = tcg_temp_new_i32();
7686 gen_load_fpr32(fp0, fs);
7687 gen_helper_float_rsqrt_s(fp0, cpu_env, fp0);
7688 gen_store_fpr32(fp0, fd);
7689 tcg_temp_free_i32(fp0);
7691 opn = "rsqrt.s";
7692 break;
7693 case OPC_RECIP2_S:
7694 check_cp1_64bitmode(ctx);
7696 TCGv_i32 fp0 = tcg_temp_new_i32();
7697 TCGv_i32 fp1 = tcg_temp_new_i32();
7699 gen_load_fpr32(fp0, fs);
7700 gen_load_fpr32(fp1, ft);
7701 gen_helper_float_recip2_s(fp0, cpu_env, fp0, fp1);
7702 tcg_temp_free_i32(fp1);
7703 gen_store_fpr32(fp0, fd);
7704 tcg_temp_free_i32(fp0);
7706 opn = "recip2.s";
7707 break;
7708 case OPC_RECIP1_S:
7709 check_cp1_64bitmode(ctx);
7711 TCGv_i32 fp0 = tcg_temp_new_i32();
7713 gen_load_fpr32(fp0, fs);
7714 gen_helper_float_recip1_s(fp0, cpu_env, fp0);
7715 gen_store_fpr32(fp0, fd);
7716 tcg_temp_free_i32(fp0);
7718 opn = "recip1.s";
7719 break;
7720 case OPC_RSQRT1_S:
7721 check_cp1_64bitmode(ctx);
7723 TCGv_i32 fp0 = tcg_temp_new_i32();
7725 gen_load_fpr32(fp0, fs);
7726 gen_helper_float_rsqrt1_s(fp0, cpu_env, fp0);
7727 gen_store_fpr32(fp0, fd);
7728 tcg_temp_free_i32(fp0);
7730 opn = "rsqrt1.s";
7731 break;
7732 case OPC_RSQRT2_S:
7733 check_cp1_64bitmode(ctx);
7735 TCGv_i32 fp0 = tcg_temp_new_i32();
7736 TCGv_i32 fp1 = tcg_temp_new_i32();
7738 gen_load_fpr32(fp0, fs);
7739 gen_load_fpr32(fp1, ft);
7740 gen_helper_float_rsqrt2_s(fp0, cpu_env, fp0, fp1);
7741 tcg_temp_free_i32(fp1);
7742 gen_store_fpr32(fp0, fd);
7743 tcg_temp_free_i32(fp0);
7745 opn = "rsqrt2.s";
7746 break;
7747 case OPC_CVT_D_S:
7748 check_cp1_registers(ctx, fd);
7750 TCGv_i32 fp32 = tcg_temp_new_i32();
7751 TCGv_i64 fp64 = tcg_temp_new_i64();
7753 gen_load_fpr32(fp32, fs);
7754 gen_helper_float_cvtd_s(fp64, cpu_env, fp32);
7755 tcg_temp_free_i32(fp32);
7756 gen_store_fpr64(ctx, fp64, fd);
7757 tcg_temp_free_i64(fp64);
7759 opn = "cvt.d.s";
7760 break;
7761 case OPC_CVT_W_S:
7763 TCGv_i32 fp0 = tcg_temp_new_i32();
7765 gen_load_fpr32(fp0, fs);
7766 gen_helper_float_cvtw_s(fp0, cpu_env, fp0);
7767 gen_store_fpr32(fp0, fd);
7768 tcg_temp_free_i32(fp0);
7770 opn = "cvt.w.s";
7771 break;
7772 case OPC_CVT_L_S:
7773 check_cp1_64bitmode(ctx);
7775 TCGv_i32 fp32 = tcg_temp_new_i32();
7776 TCGv_i64 fp64 = tcg_temp_new_i64();
7778 gen_load_fpr32(fp32, fs);
7779 gen_helper_float_cvtl_s(fp64, cpu_env, fp32);
7780 tcg_temp_free_i32(fp32);
7781 gen_store_fpr64(ctx, fp64, fd);
7782 tcg_temp_free_i64(fp64);
7784 opn = "cvt.l.s";
7785 break;
7786 case OPC_CVT_PS_S:
7787 check_cp1_64bitmode(ctx);
7789 TCGv_i64 fp64 = tcg_temp_new_i64();
7790 TCGv_i32 fp32_0 = tcg_temp_new_i32();
7791 TCGv_i32 fp32_1 = tcg_temp_new_i32();
7793 gen_load_fpr32(fp32_0, fs);
7794 gen_load_fpr32(fp32_1, ft);
7795 tcg_gen_concat_i32_i64(fp64, fp32_1, fp32_0);
7796 tcg_temp_free_i32(fp32_1);
7797 tcg_temp_free_i32(fp32_0);
7798 gen_store_fpr64(ctx, fp64, fd);
7799 tcg_temp_free_i64(fp64);
7801 opn = "cvt.ps.s";
7802 break;
7803 case OPC_CMP_F_S:
7804 case OPC_CMP_UN_S:
7805 case OPC_CMP_EQ_S:
7806 case OPC_CMP_UEQ_S:
7807 case OPC_CMP_OLT_S:
7808 case OPC_CMP_ULT_S:
7809 case OPC_CMP_OLE_S:
7810 case OPC_CMP_ULE_S:
7811 case OPC_CMP_SF_S:
7812 case OPC_CMP_NGLE_S:
7813 case OPC_CMP_SEQ_S:
7814 case OPC_CMP_NGL_S:
7815 case OPC_CMP_LT_S:
7816 case OPC_CMP_NGE_S:
7817 case OPC_CMP_LE_S:
7818 case OPC_CMP_NGT_S:
7819 if (ctx->opcode & (1 << 6)) {
7820 gen_cmpabs_s(ctx, func-48, ft, fs, cc);
7821 opn = condnames_abs[func-48];
7822 } else {
7823 gen_cmp_s(ctx, func-48, ft, fs, cc);
7824 opn = condnames[func-48];
7826 break;
7827 case OPC_ADD_D:
7828 check_cp1_registers(ctx, fs | ft | fd);
7830 TCGv_i64 fp0 = tcg_temp_new_i64();
7831 TCGv_i64 fp1 = tcg_temp_new_i64();
7833 gen_load_fpr64(ctx, fp0, fs);
7834 gen_load_fpr64(ctx, fp1, ft);
7835 gen_helper_float_add_d(fp0, cpu_env, fp0, fp1);
7836 tcg_temp_free_i64(fp1);
7837 gen_store_fpr64(ctx, fp0, fd);
7838 tcg_temp_free_i64(fp0);
7840 opn = "add.d";
7841 optype = BINOP;
7842 break;
7843 case OPC_SUB_D:
7844 check_cp1_registers(ctx, fs | ft | fd);
7846 TCGv_i64 fp0 = tcg_temp_new_i64();
7847 TCGv_i64 fp1 = tcg_temp_new_i64();
7849 gen_load_fpr64(ctx, fp0, fs);
7850 gen_load_fpr64(ctx, fp1, ft);
7851 gen_helper_float_sub_d(fp0, cpu_env, fp0, fp1);
7852 tcg_temp_free_i64(fp1);
7853 gen_store_fpr64(ctx, fp0, fd);
7854 tcg_temp_free_i64(fp0);
7856 opn = "sub.d";
7857 optype = BINOP;
7858 break;
7859 case OPC_MUL_D:
7860 check_cp1_registers(ctx, fs | ft | fd);
7862 TCGv_i64 fp0 = tcg_temp_new_i64();
7863 TCGv_i64 fp1 = tcg_temp_new_i64();
7865 gen_load_fpr64(ctx, fp0, fs);
7866 gen_load_fpr64(ctx, fp1, ft);
7867 gen_helper_float_mul_d(fp0, cpu_env, fp0, fp1);
7868 tcg_temp_free_i64(fp1);
7869 gen_store_fpr64(ctx, fp0, fd);
7870 tcg_temp_free_i64(fp0);
7872 opn = "mul.d";
7873 optype = BINOP;
7874 break;
7875 case OPC_DIV_D:
7876 check_cp1_registers(ctx, fs | ft | fd);
7878 TCGv_i64 fp0 = tcg_temp_new_i64();
7879 TCGv_i64 fp1 = tcg_temp_new_i64();
7881 gen_load_fpr64(ctx, fp0, fs);
7882 gen_load_fpr64(ctx, fp1, ft);
7883 gen_helper_float_div_d(fp0, cpu_env, fp0, fp1);
7884 tcg_temp_free_i64(fp1);
7885 gen_store_fpr64(ctx, fp0, fd);
7886 tcg_temp_free_i64(fp0);
7888 opn = "div.d";
7889 optype = BINOP;
7890 break;
7891 case OPC_SQRT_D:
7892 check_cp1_registers(ctx, fs | fd);
7894 TCGv_i64 fp0 = tcg_temp_new_i64();
7896 gen_load_fpr64(ctx, fp0, fs);
7897 gen_helper_float_sqrt_d(fp0, cpu_env, fp0);
7898 gen_store_fpr64(ctx, fp0, fd);
7899 tcg_temp_free_i64(fp0);
7901 opn = "sqrt.d";
7902 break;
7903 case OPC_ABS_D:
7904 check_cp1_registers(ctx, fs | fd);
7906 TCGv_i64 fp0 = tcg_temp_new_i64();
7908 gen_load_fpr64(ctx, fp0, fs);
7909 gen_helper_float_abs_d(fp0, fp0);
7910 gen_store_fpr64(ctx, fp0, fd);
7911 tcg_temp_free_i64(fp0);
7913 opn = "abs.d";
7914 break;
7915 case OPC_MOV_D:
7916 check_cp1_registers(ctx, fs | fd);
7918 TCGv_i64 fp0 = tcg_temp_new_i64();
7920 gen_load_fpr64(ctx, fp0, fs);
7921 gen_store_fpr64(ctx, fp0, fd);
7922 tcg_temp_free_i64(fp0);
7924 opn = "mov.d";
7925 break;
7926 case OPC_NEG_D:
7927 check_cp1_registers(ctx, fs | fd);
7929 TCGv_i64 fp0 = tcg_temp_new_i64();
7931 gen_load_fpr64(ctx, fp0, fs);
7932 gen_helper_float_chs_d(fp0, fp0);
7933 gen_store_fpr64(ctx, fp0, fd);
7934 tcg_temp_free_i64(fp0);
7936 opn = "neg.d";
7937 break;
7938 case OPC_ROUND_L_D:
7939 check_cp1_64bitmode(ctx);
7941 TCGv_i64 fp0 = tcg_temp_new_i64();
7943 gen_load_fpr64(ctx, fp0, fs);
7944 gen_helper_float_roundl_d(fp0, cpu_env, fp0);
7945 gen_store_fpr64(ctx, fp0, fd);
7946 tcg_temp_free_i64(fp0);
7948 opn = "round.l.d";
7949 break;
7950 case OPC_TRUNC_L_D:
7951 check_cp1_64bitmode(ctx);
7953 TCGv_i64 fp0 = tcg_temp_new_i64();
7955 gen_load_fpr64(ctx, fp0, fs);
7956 gen_helper_float_truncl_d(fp0, cpu_env, fp0);
7957 gen_store_fpr64(ctx, fp0, fd);
7958 tcg_temp_free_i64(fp0);
7960 opn = "trunc.l.d";
7961 break;
7962 case OPC_CEIL_L_D:
7963 check_cp1_64bitmode(ctx);
7965 TCGv_i64 fp0 = tcg_temp_new_i64();
7967 gen_load_fpr64(ctx, fp0, fs);
7968 gen_helper_float_ceill_d(fp0, cpu_env, fp0);
7969 gen_store_fpr64(ctx, fp0, fd);
7970 tcg_temp_free_i64(fp0);
7972 opn = "ceil.l.d";
7973 break;
7974 case OPC_FLOOR_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_floorl_d(fp0, cpu_env, fp0);
7981 gen_store_fpr64(ctx, fp0, fd);
7982 tcg_temp_free_i64(fp0);
7984 opn = "floor.l.d";
7985 break;
7986 case OPC_ROUND_W_D:
7987 check_cp1_registers(ctx, fs);
7989 TCGv_i32 fp32 = tcg_temp_new_i32();
7990 TCGv_i64 fp64 = tcg_temp_new_i64();
7992 gen_load_fpr64(ctx, fp64, fs);
7993 gen_helper_float_roundw_d(fp32, cpu_env, fp64);
7994 tcg_temp_free_i64(fp64);
7995 gen_store_fpr32(fp32, fd);
7996 tcg_temp_free_i32(fp32);
7998 opn = "round.w.d";
7999 break;
8000 case OPC_TRUNC_W_D:
8001 check_cp1_registers(ctx, fs);
8003 TCGv_i32 fp32 = tcg_temp_new_i32();
8004 TCGv_i64 fp64 = tcg_temp_new_i64();
8006 gen_load_fpr64(ctx, fp64, fs);
8007 gen_helper_float_truncw_d(fp32, cpu_env, fp64);
8008 tcg_temp_free_i64(fp64);
8009 gen_store_fpr32(fp32, fd);
8010 tcg_temp_free_i32(fp32);
8012 opn = "trunc.w.d";
8013 break;
8014 case OPC_CEIL_W_D:
8015 check_cp1_registers(ctx, fs);
8017 TCGv_i32 fp32 = tcg_temp_new_i32();
8018 TCGv_i64 fp64 = tcg_temp_new_i64();
8020 gen_load_fpr64(ctx, fp64, fs);
8021 gen_helper_float_ceilw_d(fp32, cpu_env, fp64);
8022 tcg_temp_free_i64(fp64);
8023 gen_store_fpr32(fp32, fd);
8024 tcg_temp_free_i32(fp32);
8026 opn = "ceil.w.d";
8027 break;
8028 case OPC_FLOOR_W_D:
8029 check_cp1_registers(ctx, fs);
8031 TCGv_i32 fp32 = tcg_temp_new_i32();
8032 TCGv_i64 fp64 = tcg_temp_new_i64();
8034 gen_load_fpr64(ctx, fp64, fs);
8035 gen_helper_float_floorw_d(fp32, cpu_env, fp64);
8036 tcg_temp_free_i64(fp64);
8037 gen_store_fpr32(fp32, fd);
8038 tcg_temp_free_i32(fp32);
8040 opn = "floor.w.d";
8041 break;
8042 case OPC_MOVCF_D:
8043 gen_movcf_d(ctx, fs, fd, (ft >> 2) & 0x7, ft & 0x1);
8044 opn = "movcf.d";
8045 break;
8046 case OPC_MOVZ_D:
8048 int l1 = gen_new_label();
8049 TCGv_i64 fp0;
8051 if (ft != 0) {
8052 tcg_gen_brcondi_tl(TCG_COND_NE, cpu_gpr[ft], 0, l1);
8054 fp0 = tcg_temp_new_i64();
8055 gen_load_fpr64(ctx, fp0, fs);
8056 gen_store_fpr64(ctx, fp0, fd);
8057 tcg_temp_free_i64(fp0);
8058 gen_set_label(l1);
8060 opn = "movz.d";
8061 break;
8062 case OPC_MOVN_D:
8064 int l1 = gen_new_label();
8065 TCGv_i64 fp0;
8067 if (ft != 0) {
8068 tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_gpr[ft], 0, l1);
8069 fp0 = tcg_temp_new_i64();
8070 gen_load_fpr64(ctx, fp0, fs);
8071 gen_store_fpr64(ctx, fp0, fd);
8072 tcg_temp_free_i64(fp0);
8073 gen_set_label(l1);
8076 opn = "movn.d";
8077 break;
8078 case OPC_RECIP_D:
8079 check_cp1_64bitmode(ctx);
8081 TCGv_i64 fp0 = tcg_temp_new_i64();
8083 gen_load_fpr64(ctx, fp0, fs);
8084 gen_helper_float_recip_d(fp0, cpu_env, fp0);
8085 gen_store_fpr64(ctx, fp0, fd);
8086 tcg_temp_free_i64(fp0);
8088 opn = "recip.d";
8089 break;
8090 case OPC_RSQRT_D:
8091 check_cp1_64bitmode(ctx);
8093 TCGv_i64 fp0 = tcg_temp_new_i64();
8095 gen_load_fpr64(ctx, fp0, fs);
8096 gen_helper_float_rsqrt_d(fp0, cpu_env, fp0);
8097 gen_store_fpr64(ctx, fp0, fd);
8098 tcg_temp_free_i64(fp0);
8100 opn = "rsqrt.d";
8101 break;
8102 case OPC_RECIP2_D:
8103 check_cp1_64bitmode(ctx);
8105 TCGv_i64 fp0 = tcg_temp_new_i64();
8106 TCGv_i64 fp1 = tcg_temp_new_i64();
8108 gen_load_fpr64(ctx, fp0, fs);
8109 gen_load_fpr64(ctx, fp1, ft);
8110 gen_helper_float_recip2_d(fp0, cpu_env, fp0, fp1);
8111 tcg_temp_free_i64(fp1);
8112 gen_store_fpr64(ctx, fp0, fd);
8113 tcg_temp_free_i64(fp0);
8115 opn = "recip2.d";
8116 break;
8117 case OPC_RECIP1_D:
8118 check_cp1_64bitmode(ctx);
8120 TCGv_i64 fp0 = tcg_temp_new_i64();
8122 gen_load_fpr64(ctx, fp0, fs);
8123 gen_helper_float_recip1_d(fp0, cpu_env, fp0);
8124 gen_store_fpr64(ctx, fp0, fd);
8125 tcg_temp_free_i64(fp0);
8127 opn = "recip1.d";
8128 break;
8129 case OPC_RSQRT1_D:
8130 check_cp1_64bitmode(ctx);
8132 TCGv_i64 fp0 = tcg_temp_new_i64();
8134 gen_load_fpr64(ctx, fp0, fs);
8135 gen_helper_float_rsqrt1_d(fp0, cpu_env, fp0);
8136 gen_store_fpr64(ctx, fp0, fd);
8137 tcg_temp_free_i64(fp0);
8139 opn = "rsqrt1.d";
8140 break;
8141 case OPC_RSQRT2_D:
8142 check_cp1_64bitmode(ctx);
8144 TCGv_i64 fp0 = tcg_temp_new_i64();
8145 TCGv_i64 fp1 = tcg_temp_new_i64();
8147 gen_load_fpr64(ctx, fp0, fs);
8148 gen_load_fpr64(ctx, fp1, ft);
8149 gen_helper_float_rsqrt2_d(fp0, cpu_env, fp0, fp1);
8150 tcg_temp_free_i64(fp1);
8151 gen_store_fpr64(ctx, fp0, fd);
8152 tcg_temp_free_i64(fp0);
8154 opn = "rsqrt2.d";
8155 break;
8156 case OPC_CMP_F_D:
8157 case OPC_CMP_UN_D:
8158 case OPC_CMP_EQ_D:
8159 case OPC_CMP_UEQ_D:
8160 case OPC_CMP_OLT_D:
8161 case OPC_CMP_ULT_D:
8162 case OPC_CMP_OLE_D:
8163 case OPC_CMP_ULE_D:
8164 case OPC_CMP_SF_D:
8165 case OPC_CMP_NGLE_D:
8166 case OPC_CMP_SEQ_D:
8167 case OPC_CMP_NGL_D:
8168 case OPC_CMP_LT_D:
8169 case OPC_CMP_NGE_D:
8170 case OPC_CMP_LE_D:
8171 case OPC_CMP_NGT_D:
8172 if (ctx->opcode & (1 << 6)) {
8173 gen_cmpabs_d(ctx, func-48, ft, fs, cc);
8174 opn = condnames_abs[func-48];
8175 } else {
8176 gen_cmp_d(ctx, func-48, ft, fs, cc);
8177 opn = condnames[func-48];
8179 break;
8180 case OPC_CVT_S_D:
8181 check_cp1_registers(ctx, fs);
8183 TCGv_i32 fp32 = tcg_temp_new_i32();
8184 TCGv_i64 fp64 = tcg_temp_new_i64();
8186 gen_load_fpr64(ctx, fp64, fs);
8187 gen_helper_float_cvts_d(fp32, cpu_env, fp64);
8188 tcg_temp_free_i64(fp64);
8189 gen_store_fpr32(fp32, fd);
8190 tcg_temp_free_i32(fp32);
8192 opn = "cvt.s.d";
8193 break;
8194 case OPC_CVT_W_D:
8195 check_cp1_registers(ctx, fs);
8197 TCGv_i32 fp32 = tcg_temp_new_i32();
8198 TCGv_i64 fp64 = tcg_temp_new_i64();
8200 gen_load_fpr64(ctx, fp64, fs);
8201 gen_helper_float_cvtw_d(fp32, cpu_env, fp64);
8202 tcg_temp_free_i64(fp64);
8203 gen_store_fpr32(fp32, fd);
8204 tcg_temp_free_i32(fp32);
8206 opn = "cvt.w.d";
8207 break;
8208 case OPC_CVT_L_D:
8209 check_cp1_64bitmode(ctx);
8211 TCGv_i64 fp0 = tcg_temp_new_i64();
8213 gen_load_fpr64(ctx, fp0, fs);
8214 gen_helper_float_cvtl_d(fp0, cpu_env, fp0);
8215 gen_store_fpr64(ctx, fp0, fd);
8216 tcg_temp_free_i64(fp0);
8218 opn = "cvt.l.d";
8219 break;
8220 case OPC_CVT_S_W:
8222 TCGv_i32 fp0 = tcg_temp_new_i32();
8224 gen_load_fpr32(fp0, fs);
8225 gen_helper_float_cvts_w(fp0, cpu_env, fp0);
8226 gen_store_fpr32(fp0, fd);
8227 tcg_temp_free_i32(fp0);
8229 opn = "cvt.s.w";
8230 break;
8231 case OPC_CVT_D_W:
8232 check_cp1_registers(ctx, fd);
8234 TCGv_i32 fp32 = tcg_temp_new_i32();
8235 TCGv_i64 fp64 = tcg_temp_new_i64();
8237 gen_load_fpr32(fp32, fs);
8238 gen_helper_float_cvtd_w(fp64, cpu_env, fp32);
8239 tcg_temp_free_i32(fp32);
8240 gen_store_fpr64(ctx, fp64, fd);
8241 tcg_temp_free_i64(fp64);
8243 opn = "cvt.d.w";
8244 break;
8245 case OPC_CVT_S_L:
8246 check_cp1_64bitmode(ctx);
8248 TCGv_i32 fp32 = tcg_temp_new_i32();
8249 TCGv_i64 fp64 = tcg_temp_new_i64();
8251 gen_load_fpr64(ctx, fp64, fs);
8252 gen_helper_float_cvts_l(fp32, cpu_env, fp64);
8253 tcg_temp_free_i64(fp64);
8254 gen_store_fpr32(fp32, fd);
8255 tcg_temp_free_i32(fp32);
8257 opn = "cvt.s.l";
8258 break;
8259 case OPC_CVT_D_L:
8260 check_cp1_64bitmode(ctx);
8262 TCGv_i64 fp0 = tcg_temp_new_i64();
8264 gen_load_fpr64(ctx, fp0, fs);
8265 gen_helper_float_cvtd_l(fp0, cpu_env, fp0);
8266 gen_store_fpr64(ctx, fp0, fd);
8267 tcg_temp_free_i64(fp0);
8269 opn = "cvt.d.l";
8270 break;
8271 case OPC_CVT_PS_PW:
8272 check_cp1_64bitmode(ctx);
8274 TCGv_i64 fp0 = tcg_temp_new_i64();
8276 gen_load_fpr64(ctx, fp0, fs);
8277 gen_helper_float_cvtps_pw(fp0, cpu_env, fp0);
8278 gen_store_fpr64(ctx, fp0, fd);
8279 tcg_temp_free_i64(fp0);
8281 opn = "cvt.ps.pw";
8282 break;
8283 case OPC_ADD_PS:
8284 check_cp1_64bitmode(ctx);
8286 TCGv_i64 fp0 = tcg_temp_new_i64();
8287 TCGv_i64 fp1 = tcg_temp_new_i64();
8289 gen_load_fpr64(ctx, fp0, fs);
8290 gen_load_fpr64(ctx, fp1, ft);
8291 gen_helper_float_add_ps(fp0, cpu_env, fp0, fp1);
8292 tcg_temp_free_i64(fp1);
8293 gen_store_fpr64(ctx, fp0, fd);
8294 tcg_temp_free_i64(fp0);
8296 opn = "add.ps";
8297 break;
8298 case OPC_SUB_PS:
8299 check_cp1_64bitmode(ctx);
8301 TCGv_i64 fp0 = tcg_temp_new_i64();
8302 TCGv_i64 fp1 = tcg_temp_new_i64();
8304 gen_load_fpr64(ctx, fp0, fs);
8305 gen_load_fpr64(ctx, fp1, ft);
8306 gen_helper_float_sub_ps(fp0, cpu_env, fp0, fp1);
8307 tcg_temp_free_i64(fp1);
8308 gen_store_fpr64(ctx, fp0, fd);
8309 tcg_temp_free_i64(fp0);
8311 opn = "sub.ps";
8312 break;
8313 case OPC_MUL_PS:
8314 check_cp1_64bitmode(ctx);
8316 TCGv_i64 fp0 = tcg_temp_new_i64();
8317 TCGv_i64 fp1 = tcg_temp_new_i64();
8319 gen_load_fpr64(ctx, fp0, fs);
8320 gen_load_fpr64(ctx, fp1, ft);
8321 gen_helper_float_mul_ps(fp0, cpu_env, fp0, fp1);
8322 tcg_temp_free_i64(fp1);
8323 gen_store_fpr64(ctx, fp0, fd);
8324 tcg_temp_free_i64(fp0);
8326 opn = "mul.ps";
8327 break;
8328 case OPC_ABS_PS:
8329 check_cp1_64bitmode(ctx);
8331 TCGv_i64 fp0 = tcg_temp_new_i64();
8333 gen_load_fpr64(ctx, fp0, fs);
8334 gen_helper_float_abs_ps(fp0, fp0);
8335 gen_store_fpr64(ctx, fp0, fd);
8336 tcg_temp_free_i64(fp0);
8338 opn = "abs.ps";
8339 break;
8340 case OPC_MOV_PS:
8341 check_cp1_64bitmode(ctx);
8343 TCGv_i64 fp0 = tcg_temp_new_i64();
8345 gen_load_fpr64(ctx, fp0, fs);
8346 gen_store_fpr64(ctx, fp0, fd);
8347 tcg_temp_free_i64(fp0);
8349 opn = "mov.ps";
8350 break;
8351 case OPC_NEG_PS:
8352 check_cp1_64bitmode(ctx);
8354 TCGv_i64 fp0 = tcg_temp_new_i64();
8356 gen_load_fpr64(ctx, fp0, fs);
8357 gen_helper_float_chs_ps(fp0, fp0);
8358 gen_store_fpr64(ctx, fp0, fd);
8359 tcg_temp_free_i64(fp0);
8361 opn = "neg.ps";
8362 break;
8363 case OPC_MOVCF_PS:
8364 check_cp1_64bitmode(ctx);
8365 gen_movcf_ps(fs, fd, (ft >> 2) & 0x7, ft & 0x1);
8366 opn = "movcf.ps";
8367 break;
8368 case OPC_MOVZ_PS:
8369 check_cp1_64bitmode(ctx);
8371 int l1 = gen_new_label();
8372 TCGv_i64 fp0;
8374 if (ft != 0)
8375 tcg_gen_brcondi_tl(TCG_COND_NE, cpu_gpr[ft], 0, l1);
8376 fp0 = tcg_temp_new_i64();
8377 gen_load_fpr64(ctx, fp0, fs);
8378 gen_store_fpr64(ctx, fp0, fd);
8379 tcg_temp_free_i64(fp0);
8380 gen_set_label(l1);
8382 opn = "movz.ps";
8383 break;
8384 case OPC_MOVN_PS:
8385 check_cp1_64bitmode(ctx);
8387 int l1 = gen_new_label();
8388 TCGv_i64 fp0;
8390 if (ft != 0) {
8391 tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_gpr[ft], 0, l1);
8392 fp0 = tcg_temp_new_i64();
8393 gen_load_fpr64(ctx, fp0, fs);
8394 gen_store_fpr64(ctx, fp0, fd);
8395 tcg_temp_free_i64(fp0);
8396 gen_set_label(l1);
8399 opn = "movn.ps";
8400 break;
8401 case OPC_ADDR_PS:
8402 check_cp1_64bitmode(ctx);
8404 TCGv_i64 fp0 = tcg_temp_new_i64();
8405 TCGv_i64 fp1 = tcg_temp_new_i64();
8407 gen_load_fpr64(ctx, fp0, ft);
8408 gen_load_fpr64(ctx, fp1, fs);
8409 gen_helper_float_addr_ps(fp0, cpu_env, fp0, fp1);
8410 tcg_temp_free_i64(fp1);
8411 gen_store_fpr64(ctx, fp0, fd);
8412 tcg_temp_free_i64(fp0);
8414 opn = "addr.ps";
8415 break;
8416 case OPC_MULR_PS:
8417 check_cp1_64bitmode(ctx);
8419 TCGv_i64 fp0 = tcg_temp_new_i64();
8420 TCGv_i64 fp1 = tcg_temp_new_i64();
8422 gen_load_fpr64(ctx, fp0, ft);
8423 gen_load_fpr64(ctx, fp1, fs);
8424 gen_helper_float_mulr_ps(fp0, cpu_env, fp0, fp1);
8425 tcg_temp_free_i64(fp1);
8426 gen_store_fpr64(ctx, fp0, fd);
8427 tcg_temp_free_i64(fp0);
8429 opn = "mulr.ps";
8430 break;
8431 case OPC_RECIP2_PS:
8432 check_cp1_64bitmode(ctx);
8434 TCGv_i64 fp0 = tcg_temp_new_i64();
8435 TCGv_i64 fp1 = tcg_temp_new_i64();
8437 gen_load_fpr64(ctx, fp0, fs);
8438 gen_load_fpr64(ctx, fp1, ft);
8439 gen_helper_float_recip2_ps(fp0, cpu_env, fp0, fp1);
8440 tcg_temp_free_i64(fp1);
8441 gen_store_fpr64(ctx, fp0, fd);
8442 tcg_temp_free_i64(fp0);
8444 opn = "recip2.ps";
8445 break;
8446 case OPC_RECIP1_PS:
8447 check_cp1_64bitmode(ctx);
8449 TCGv_i64 fp0 = tcg_temp_new_i64();
8451 gen_load_fpr64(ctx, fp0, fs);
8452 gen_helper_float_recip1_ps(fp0, cpu_env, fp0);
8453 gen_store_fpr64(ctx, fp0, fd);
8454 tcg_temp_free_i64(fp0);
8456 opn = "recip1.ps";
8457 break;
8458 case OPC_RSQRT1_PS:
8459 check_cp1_64bitmode(ctx);
8461 TCGv_i64 fp0 = tcg_temp_new_i64();
8463 gen_load_fpr64(ctx, fp0, fs);
8464 gen_helper_float_rsqrt1_ps(fp0, cpu_env, fp0);
8465 gen_store_fpr64(ctx, fp0, fd);
8466 tcg_temp_free_i64(fp0);
8468 opn = "rsqrt1.ps";
8469 break;
8470 case OPC_RSQRT2_PS:
8471 check_cp1_64bitmode(ctx);
8473 TCGv_i64 fp0 = tcg_temp_new_i64();
8474 TCGv_i64 fp1 = tcg_temp_new_i64();
8476 gen_load_fpr64(ctx, fp0, fs);
8477 gen_load_fpr64(ctx, fp1, ft);
8478 gen_helper_float_rsqrt2_ps(fp0, cpu_env, fp0, fp1);
8479 tcg_temp_free_i64(fp1);
8480 gen_store_fpr64(ctx, fp0, fd);
8481 tcg_temp_free_i64(fp0);
8483 opn = "rsqrt2.ps";
8484 break;
8485 case OPC_CVT_S_PU:
8486 check_cp1_64bitmode(ctx);
8488 TCGv_i32 fp0 = tcg_temp_new_i32();
8490 gen_load_fpr32h(fp0, fs);
8491 gen_helper_float_cvts_pu(fp0, cpu_env, fp0);
8492 gen_store_fpr32(fp0, fd);
8493 tcg_temp_free_i32(fp0);
8495 opn = "cvt.s.pu";
8496 break;
8497 case OPC_CVT_PW_PS:
8498 check_cp1_64bitmode(ctx);
8500 TCGv_i64 fp0 = tcg_temp_new_i64();
8502 gen_load_fpr64(ctx, fp0, fs);
8503 gen_helper_float_cvtpw_ps(fp0, cpu_env, fp0);
8504 gen_store_fpr64(ctx, fp0, fd);
8505 tcg_temp_free_i64(fp0);
8507 opn = "cvt.pw.ps";
8508 break;
8509 case OPC_CVT_S_PL:
8510 check_cp1_64bitmode(ctx);
8512 TCGv_i32 fp0 = tcg_temp_new_i32();
8514 gen_load_fpr32(fp0, fs);
8515 gen_helper_float_cvts_pl(fp0, cpu_env, fp0);
8516 gen_store_fpr32(fp0, fd);
8517 tcg_temp_free_i32(fp0);
8519 opn = "cvt.s.pl";
8520 break;
8521 case OPC_PLL_PS:
8522 check_cp1_64bitmode(ctx);
8524 TCGv_i32 fp0 = tcg_temp_new_i32();
8525 TCGv_i32 fp1 = tcg_temp_new_i32();
8527 gen_load_fpr32(fp0, fs);
8528 gen_load_fpr32(fp1, ft);
8529 gen_store_fpr32h(fp0, fd);
8530 gen_store_fpr32(fp1, fd);
8531 tcg_temp_free_i32(fp0);
8532 tcg_temp_free_i32(fp1);
8534 opn = "pll.ps";
8535 break;
8536 case OPC_PLU_PS:
8537 check_cp1_64bitmode(ctx);
8539 TCGv_i32 fp0 = tcg_temp_new_i32();
8540 TCGv_i32 fp1 = tcg_temp_new_i32();
8542 gen_load_fpr32(fp0, fs);
8543 gen_load_fpr32h(fp1, ft);
8544 gen_store_fpr32(fp1, fd);
8545 gen_store_fpr32h(fp0, fd);
8546 tcg_temp_free_i32(fp0);
8547 tcg_temp_free_i32(fp1);
8549 opn = "plu.ps";
8550 break;
8551 case OPC_PUL_PS:
8552 check_cp1_64bitmode(ctx);
8554 TCGv_i32 fp0 = tcg_temp_new_i32();
8555 TCGv_i32 fp1 = tcg_temp_new_i32();
8557 gen_load_fpr32h(fp0, fs);
8558 gen_load_fpr32(fp1, ft);
8559 gen_store_fpr32(fp1, fd);
8560 gen_store_fpr32h(fp0, fd);
8561 tcg_temp_free_i32(fp0);
8562 tcg_temp_free_i32(fp1);
8564 opn = "pul.ps";
8565 break;
8566 case OPC_PUU_PS:
8567 check_cp1_64bitmode(ctx);
8569 TCGv_i32 fp0 = tcg_temp_new_i32();
8570 TCGv_i32 fp1 = tcg_temp_new_i32();
8572 gen_load_fpr32h(fp0, fs);
8573 gen_load_fpr32h(fp1, ft);
8574 gen_store_fpr32(fp1, fd);
8575 gen_store_fpr32h(fp0, fd);
8576 tcg_temp_free_i32(fp0);
8577 tcg_temp_free_i32(fp1);
8579 opn = "puu.ps";
8580 break;
8581 case OPC_CMP_F_PS:
8582 case OPC_CMP_UN_PS:
8583 case OPC_CMP_EQ_PS:
8584 case OPC_CMP_UEQ_PS:
8585 case OPC_CMP_OLT_PS:
8586 case OPC_CMP_ULT_PS:
8587 case OPC_CMP_OLE_PS:
8588 case OPC_CMP_ULE_PS:
8589 case OPC_CMP_SF_PS:
8590 case OPC_CMP_NGLE_PS:
8591 case OPC_CMP_SEQ_PS:
8592 case OPC_CMP_NGL_PS:
8593 case OPC_CMP_LT_PS:
8594 case OPC_CMP_NGE_PS:
8595 case OPC_CMP_LE_PS:
8596 case OPC_CMP_NGT_PS:
8597 if (ctx->opcode & (1 << 6)) {
8598 gen_cmpabs_ps(ctx, func-48, ft, fs, cc);
8599 opn = condnames_abs[func-48];
8600 } else {
8601 gen_cmp_ps(ctx, func-48, ft, fs, cc);
8602 opn = condnames[func-48];
8604 break;
8605 default:
8606 MIPS_INVAL(opn);
8607 generate_exception (ctx, EXCP_RI);
8608 return;
8610 (void)opn; /* avoid a compiler warning */
8611 switch (optype) {
8612 case BINOP:
8613 MIPS_DEBUG("%s %s, %s, %s", opn, fregnames[fd], fregnames[fs], fregnames[ft]);
8614 break;
8615 case CMPOP:
8616 MIPS_DEBUG("%s %s,%s", opn, fregnames[fs], fregnames[ft]);
8617 break;
8618 default:
8619 MIPS_DEBUG("%s %s,%s", opn, fregnames[fd], fregnames[fs]);
8620 break;
8624 /* Coprocessor 3 (FPU) */
8625 static void gen_flt3_ldst (DisasContext *ctx, uint32_t opc,
8626 int fd, int fs, int base, int index)
8628 const char *opn = "extended float load/store";
8629 int store = 0;
8630 TCGv t0 = tcg_temp_new();
8632 if (base == 0) {
8633 gen_load_gpr(t0, index);
8634 } else if (index == 0) {
8635 gen_load_gpr(t0, base);
8636 } else {
8637 gen_op_addr_add(ctx, t0, cpu_gpr[base], cpu_gpr[index]);
8639 /* Don't do NOP if destination is zero: we must perform the actual
8640 memory access. */
8641 switch (opc) {
8642 case OPC_LWXC1:
8643 check_cop1x(ctx);
8645 TCGv_i32 fp0 = tcg_temp_new_i32();
8647 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TESL);
8648 tcg_gen_trunc_tl_i32(fp0, t0);
8649 gen_store_fpr32(fp0, fd);
8650 tcg_temp_free_i32(fp0);
8652 opn = "lwxc1";
8653 break;
8654 case OPC_LDXC1:
8655 check_cop1x(ctx);
8656 check_cp1_registers(ctx, fd);
8658 TCGv_i64 fp0 = tcg_temp_new_i64();
8659 tcg_gen_qemu_ld_i64(fp0, t0, ctx->mem_idx, MO_TEQ);
8660 gen_store_fpr64(ctx, fp0, fd);
8661 tcg_temp_free_i64(fp0);
8663 opn = "ldxc1";
8664 break;
8665 case OPC_LUXC1:
8666 check_cp1_64bitmode(ctx);
8667 tcg_gen_andi_tl(t0, t0, ~0x7);
8669 TCGv_i64 fp0 = tcg_temp_new_i64();
8671 tcg_gen_qemu_ld_i64(fp0, t0, ctx->mem_idx, MO_TEQ);
8672 gen_store_fpr64(ctx, fp0, fd);
8673 tcg_temp_free_i64(fp0);
8675 opn = "luxc1";
8676 break;
8677 case OPC_SWXC1:
8678 check_cop1x(ctx);
8680 TCGv_i32 fp0 = tcg_temp_new_i32();
8681 gen_load_fpr32(fp0, fs);
8682 tcg_gen_qemu_st_i32(fp0, t0, ctx->mem_idx, MO_TEUL);
8683 tcg_temp_free_i32(fp0);
8685 opn = "swxc1";
8686 store = 1;
8687 break;
8688 case OPC_SDXC1:
8689 check_cop1x(ctx);
8690 check_cp1_registers(ctx, fs);
8692 TCGv_i64 fp0 = tcg_temp_new_i64();
8693 gen_load_fpr64(ctx, fp0, fs);
8694 tcg_gen_qemu_st_i64(fp0, t0, ctx->mem_idx, MO_TEQ);
8695 tcg_temp_free_i64(fp0);
8697 opn = "sdxc1";
8698 store = 1;
8699 break;
8700 case OPC_SUXC1:
8701 check_cp1_64bitmode(ctx);
8702 tcg_gen_andi_tl(t0, t0, ~0x7);
8704 TCGv_i64 fp0 = tcg_temp_new_i64();
8705 gen_load_fpr64(ctx, fp0, fs);
8706 tcg_gen_qemu_st_i64(fp0, t0, ctx->mem_idx, MO_TEQ);
8707 tcg_temp_free_i64(fp0);
8709 opn = "suxc1";
8710 store = 1;
8711 break;
8713 tcg_temp_free(t0);
8714 (void)opn; (void)store; /* avoid compiler warnings */
8715 MIPS_DEBUG("%s %s, %s(%s)", opn, fregnames[store ? fs : fd],
8716 regnames[index], regnames[base]);
8719 static void gen_flt3_arith (DisasContext *ctx, uint32_t opc,
8720 int fd, int fr, int fs, int ft)
8722 const char *opn = "flt3_arith";
8724 switch (opc) {
8725 case OPC_ALNV_PS:
8726 check_cp1_64bitmode(ctx);
8728 TCGv t0 = tcg_temp_local_new();
8729 TCGv_i32 fp = tcg_temp_new_i32();
8730 TCGv_i32 fph = tcg_temp_new_i32();
8731 int l1 = gen_new_label();
8732 int l2 = gen_new_label();
8734 gen_load_gpr(t0, fr);
8735 tcg_gen_andi_tl(t0, t0, 0x7);
8737 tcg_gen_brcondi_tl(TCG_COND_NE, t0, 0, l1);
8738 gen_load_fpr32(fp, fs);
8739 gen_load_fpr32h(fph, fs);
8740 gen_store_fpr32(fp, fd);
8741 gen_store_fpr32h(fph, fd);
8742 tcg_gen_br(l2);
8743 gen_set_label(l1);
8744 tcg_gen_brcondi_tl(TCG_COND_NE, t0, 4, l2);
8745 tcg_temp_free(t0);
8746 #ifdef TARGET_WORDS_BIGENDIAN
8747 gen_load_fpr32(fp, fs);
8748 gen_load_fpr32h(fph, ft);
8749 gen_store_fpr32h(fp, fd);
8750 gen_store_fpr32(fph, fd);
8751 #else
8752 gen_load_fpr32h(fph, fs);
8753 gen_load_fpr32(fp, ft);
8754 gen_store_fpr32(fph, fd);
8755 gen_store_fpr32h(fp, fd);
8756 #endif
8757 gen_set_label(l2);
8758 tcg_temp_free_i32(fp);
8759 tcg_temp_free_i32(fph);
8761 opn = "alnv.ps";
8762 break;
8763 case OPC_MADD_S:
8764 check_cop1x(ctx);
8766 TCGv_i32 fp0 = tcg_temp_new_i32();
8767 TCGv_i32 fp1 = tcg_temp_new_i32();
8768 TCGv_i32 fp2 = tcg_temp_new_i32();
8770 gen_load_fpr32(fp0, fs);
8771 gen_load_fpr32(fp1, ft);
8772 gen_load_fpr32(fp2, fr);
8773 gen_helper_float_madd_s(fp2, cpu_env, fp0, fp1, fp2);
8774 tcg_temp_free_i32(fp0);
8775 tcg_temp_free_i32(fp1);
8776 gen_store_fpr32(fp2, fd);
8777 tcg_temp_free_i32(fp2);
8779 opn = "madd.s";
8780 break;
8781 case OPC_MADD_D:
8782 check_cop1x(ctx);
8783 check_cp1_registers(ctx, fd | fs | ft | fr);
8785 TCGv_i64 fp0 = tcg_temp_new_i64();
8786 TCGv_i64 fp1 = tcg_temp_new_i64();
8787 TCGv_i64 fp2 = tcg_temp_new_i64();
8789 gen_load_fpr64(ctx, fp0, fs);
8790 gen_load_fpr64(ctx, fp1, ft);
8791 gen_load_fpr64(ctx, fp2, fr);
8792 gen_helper_float_madd_d(fp2, cpu_env, fp0, fp1, fp2);
8793 tcg_temp_free_i64(fp0);
8794 tcg_temp_free_i64(fp1);
8795 gen_store_fpr64(ctx, fp2, fd);
8796 tcg_temp_free_i64(fp2);
8798 opn = "madd.d";
8799 break;
8800 case OPC_MADD_PS:
8801 check_cp1_64bitmode(ctx);
8803 TCGv_i64 fp0 = tcg_temp_new_i64();
8804 TCGv_i64 fp1 = tcg_temp_new_i64();
8805 TCGv_i64 fp2 = tcg_temp_new_i64();
8807 gen_load_fpr64(ctx, fp0, fs);
8808 gen_load_fpr64(ctx, fp1, ft);
8809 gen_load_fpr64(ctx, fp2, fr);
8810 gen_helper_float_madd_ps(fp2, cpu_env, fp0, fp1, fp2);
8811 tcg_temp_free_i64(fp0);
8812 tcg_temp_free_i64(fp1);
8813 gen_store_fpr64(ctx, fp2, fd);
8814 tcg_temp_free_i64(fp2);
8816 opn = "madd.ps";
8817 break;
8818 case OPC_MSUB_S:
8819 check_cop1x(ctx);
8821 TCGv_i32 fp0 = tcg_temp_new_i32();
8822 TCGv_i32 fp1 = tcg_temp_new_i32();
8823 TCGv_i32 fp2 = tcg_temp_new_i32();
8825 gen_load_fpr32(fp0, fs);
8826 gen_load_fpr32(fp1, ft);
8827 gen_load_fpr32(fp2, fr);
8828 gen_helper_float_msub_s(fp2, cpu_env, fp0, fp1, fp2);
8829 tcg_temp_free_i32(fp0);
8830 tcg_temp_free_i32(fp1);
8831 gen_store_fpr32(fp2, fd);
8832 tcg_temp_free_i32(fp2);
8834 opn = "msub.s";
8835 break;
8836 case OPC_MSUB_D:
8837 check_cop1x(ctx);
8838 check_cp1_registers(ctx, fd | fs | ft | fr);
8840 TCGv_i64 fp0 = tcg_temp_new_i64();
8841 TCGv_i64 fp1 = tcg_temp_new_i64();
8842 TCGv_i64 fp2 = tcg_temp_new_i64();
8844 gen_load_fpr64(ctx, fp0, fs);
8845 gen_load_fpr64(ctx, fp1, ft);
8846 gen_load_fpr64(ctx, fp2, fr);
8847 gen_helper_float_msub_d(fp2, cpu_env, fp0, fp1, fp2);
8848 tcg_temp_free_i64(fp0);
8849 tcg_temp_free_i64(fp1);
8850 gen_store_fpr64(ctx, fp2, fd);
8851 tcg_temp_free_i64(fp2);
8853 opn = "msub.d";
8854 break;
8855 case OPC_MSUB_PS:
8856 check_cp1_64bitmode(ctx);
8858 TCGv_i64 fp0 = tcg_temp_new_i64();
8859 TCGv_i64 fp1 = tcg_temp_new_i64();
8860 TCGv_i64 fp2 = tcg_temp_new_i64();
8862 gen_load_fpr64(ctx, fp0, fs);
8863 gen_load_fpr64(ctx, fp1, ft);
8864 gen_load_fpr64(ctx, fp2, fr);
8865 gen_helper_float_msub_ps(fp2, cpu_env, fp0, fp1, fp2);
8866 tcg_temp_free_i64(fp0);
8867 tcg_temp_free_i64(fp1);
8868 gen_store_fpr64(ctx, fp2, fd);
8869 tcg_temp_free_i64(fp2);
8871 opn = "msub.ps";
8872 break;
8873 case OPC_NMADD_S:
8874 check_cop1x(ctx);
8876 TCGv_i32 fp0 = tcg_temp_new_i32();
8877 TCGv_i32 fp1 = tcg_temp_new_i32();
8878 TCGv_i32 fp2 = tcg_temp_new_i32();
8880 gen_load_fpr32(fp0, fs);
8881 gen_load_fpr32(fp1, ft);
8882 gen_load_fpr32(fp2, fr);
8883 gen_helper_float_nmadd_s(fp2, cpu_env, fp0, fp1, fp2);
8884 tcg_temp_free_i32(fp0);
8885 tcg_temp_free_i32(fp1);
8886 gen_store_fpr32(fp2, fd);
8887 tcg_temp_free_i32(fp2);
8889 opn = "nmadd.s";
8890 break;
8891 case OPC_NMADD_D:
8892 check_cop1x(ctx);
8893 check_cp1_registers(ctx, fd | fs | ft | fr);
8895 TCGv_i64 fp0 = tcg_temp_new_i64();
8896 TCGv_i64 fp1 = tcg_temp_new_i64();
8897 TCGv_i64 fp2 = tcg_temp_new_i64();
8899 gen_load_fpr64(ctx, fp0, fs);
8900 gen_load_fpr64(ctx, fp1, ft);
8901 gen_load_fpr64(ctx, fp2, fr);
8902 gen_helper_float_nmadd_d(fp2, cpu_env, fp0, fp1, fp2);
8903 tcg_temp_free_i64(fp0);
8904 tcg_temp_free_i64(fp1);
8905 gen_store_fpr64(ctx, fp2, fd);
8906 tcg_temp_free_i64(fp2);
8908 opn = "nmadd.d";
8909 break;
8910 case OPC_NMADD_PS:
8911 check_cp1_64bitmode(ctx);
8913 TCGv_i64 fp0 = tcg_temp_new_i64();
8914 TCGv_i64 fp1 = tcg_temp_new_i64();
8915 TCGv_i64 fp2 = tcg_temp_new_i64();
8917 gen_load_fpr64(ctx, fp0, fs);
8918 gen_load_fpr64(ctx, fp1, ft);
8919 gen_load_fpr64(ctx, fp2, fr);
8920 gen_helper_float_nmadd_ps(fp2, cpu_env, fp0, fp1, fp2);
8921 tcg_temp_free_i64(fp0);
8922 tcg_temp_free_i64(fp1);
8923 gen_store_fpr64(ctx, fp2, fd);
8924 tcg_temp_free_i64(fp2);
8926 opn = "nmadd.ps";
8927 break;
8928 case OPC_NMSUB_S:
8929 check_cop1x(ctx);
8931 TCGv_i32 fp0 = tcg_temp_new_i32();
8932 TCGv_i32 fp1 = tcg_temp_new_i32();
8933 TCGv_i32 fp2 = tcg_temp_new_i32();
8935 gen_load_fpr32(fp0, fs);
8936 gen_load_fpr32(fp1, ft);
8937 gen_load_fpr32(fp2, fr);
8938 gen_helper_float_nmsub_s(fp2, cpu_env, fp0, fp1, fp2);
8939 tcg_temp_free_i32(fp0);
8940 tcg_temp_free_i32(fp1);
8941 gen_store_fpr32(fp2, fd);
8942 tcg_temp_free_i32(fp2);
8944 opn = "nmsub.s";
8945 break;
8946 case OPC_NMSUB_D:
8947 check_cop1x(ctx);
8948 check_cp1_registers(ctx, fd | fs | ft | fr);
8950 TCGv_i64 fp0 = tcg_temp_new_i64();
8951 TCGv_i64 fp1 = tcg_temp_new_i64();
8952 TCGv_i64 fp2 = tcg_temp_new_i64();
8954 gen_load_fpr64(ctx, fp0, fs);
8955 gen_load_fpr64(ctx, fp1, ft);
8956 gen_load_fpr64(ctx, fp2, fr);
8957 gen_helper_float_nmsub_d(fp2, cpu_env, fp0, fp1, fp2);
8958 tcg_temp_free_i64(fp0);
8959 tcg_temp_free_i64(fp1);
8960 gen_store_fpr64(ctx, fp2, fd);
8961 tcg_temp_free_i64(fp2);
8963 opn = "nmsub.d";
8964 break;
8965 case OPC_NMSUB_PS:
8966 check_cp1_64bitmode(ctx);
8968 TCGv_i64 fp0 = tcg_temp_new_i64();
8969 TCGv_i64 fp1 = tcg_temp_new_i64();
8970 TCGv_i64 fp2 = tcg_temp_new_i64();
8972 gen_load_fpr64(ctx, fp0, fs);
8973 gen_load_fpr64(ctx, fp1, ft);
8974 gen_load_fpr64(ctx, fp2, fr);
8975 gen_helper_float_nmsub_ps(fp2, cpu_env, fp0, fp1, fp2);
8976 tcg_temp_free_i64(fp0);
8977 tcg_temp_free_i64(fp1);
8978 gen_store_fpr64(ctx, fp2, fd);
8979 tcg_temp_free_i64(fp2);
8981 opn = "nmsub.ps";
8982 break;
8983 default:
8984 MIPS_INVAL(opn);
8985 generate_exception (ctx, EXCP_RI);
8986 return;
8988 (void)opn; /* avoid a compiler warning */
8989 MIPS_DEBUG("%s %s, %s, %s, %s", opn, fregnames[fd], fregnames[fr],
8990 fregnames[fs], fregnames[ft]);
8993 static void gen_rdhwr(DisasContext *ctx, int rt, int rd)
8995 TCGv t0;
8997 #if !defined(CONFIG_USER_ONLY)
8998 /* The Linux kernel will emulate rdhwr if it's not supported natively.
8999 Therefore only check the ISA in system mode. */
9000 check_insn(ctx, ISA_MIPS32R2);
9001 #endif
9002 t0 = tcg_temp_new();
9004 switch (rd) {
9005 case 0:
9006 save_cpu_state(ctx, 1);
9007 gen_helper_rdhwr_cpunum(t0, cpu_env);
9008 gen_store_gpr(t0, rt);
9009 break;
9010 case 1:
9011 save_cpu_state(ctx, 1);
9012 gen_helper_rdhwr_synci_step(t0, cpu_env);
9013 gen_store_gpr(t0, rt);
9014 break;
9015 case 2:
9016 save_cpu_state(ctx, 1);
9017 gen_helper_rdhwr_cc(t0, cpu_env);
9018 gen_store_gpr(t0, rt);
9019 break;
9020 case 3:
9021 save_cpu_state(ctx, 1);
9022 gen_helper_rdhwr_ccres(t0, cpu_env);
9023 gen_store_gpr(t0, rt);
9024 break;
9025 case 29:
9026 #if defined(CONFIG_USER_ONLY)
9027 tcg_gen_ld_tl(t0, cpu_env, offsetof(CPUMIPSState, tls_value));
9028 gen_store_gpr(t0, rt);
9029 break;
9030 #else
9031 /* XXX: Some CPUs implement this in hardware.
9032 Not supported yet. */
9033 #endif
9034 default: /* Invalid */
9035 MIPS_INVAL("rdhwr");
9036 generate_exception(ctx, EXCP_RI);
9037 break;
9039 tcg_temp_free(t0);
9042 static void handle_delay_slot(DisasContext *ctx, int insn_bytes)
9044 if (ctx->hflags & MIPS_HFLAG_BMASK) {
9045 int proc_hflags = ctx->hflags & MIPS_HFLAG_BMASK;
9046 /* Branches completion */
9047 ctx->hflags &= ~MIPS_HFLAG_BMASK;
9048 ctx->bstate = BS_BRANCH;
9049 save_cpu_state(ctx, 0);
9050 /* FIXME: Need to clear can_do_io. */
9051 switch (proc_hflags & MIPS_HFLAG_BMASK_BASE) {
9052 case MIPS_HFLAG_B:
9053 /* unconditional branch */
9054 MIPS_DEBUG("unconditional branch");
9055 if (proc_hflags & MIPS_HFLAG_BX) {
9056 tcg_gen_xori_i32(hflags, hflags, MIPS_HFLAG_M16);
9058 gen_goto_tb(ctx, 0, ctx->btarget);
9059 break;
9060 case MIPS_HFLAG_BL:
9061 /* blikely taken case */
9062 MIPS_DEBUG("blikely branch taken");
9063 gen_goto_tb(ctx, 0, ctx->btarget);
9064 break;
9065 case MIPS_HFLAG_BC:
9066 /* Conditional branch */
9067 MIPS_DEBUG("conditional branch");
9069 int l1 = gen_new_label();
9071 tcg_gen_brcondi_tl(TCG_COND_NE, bcond, 0, l1);
9072 gen_goto_tb(ctx, 1, ctx->pc + insn_bytes);
9073 gen_set_label(l1);
9074 gen_goto_tb(ctx, 0, ctx->btarget);
9076 break;
9077 case MIPS_HFLAG_BR:
9078 /* unconditional branch to register */
9079 MIPS_DEBUG("branch to register");
9080 if (ctx->insn_flags & (ASE_MIPS16 | ASE_MICROMIPS)) {
9081 TCGv t0 = tcg_temp_new();
9082 TCGv_i32 t1 = tcg_temp_new_i32();
9084 tcg_gen_andi_tl(t0, btarget, 0x1);
9085 tcg_gen_trunc_tl_i32(t1, t0);
9086 tcg_temp_free(t0);
9087 tcg_gen_andi_i32(hflags, hflags, ~(uint32_t)MIPS_HFLAG_M16);
9088 tcg_gen_shli_i32(t1, t1, MIPS_HFLAG_M16_SHIFT);
9089 tcg_gen_or_i32(hflags, hflags, t1);
9090 tcg_temp_free_i32(t1);
9092 tcg_gen_andi_tl(cpu_PC, btarget, ~(target_ulong)0x1);
9093 } else {
9094 tcg_gen_mov_tl(cpu_PC, btarget);
9096 if (ctx->singlestep_enabled) {
9097 save_cpu_state(ctx, 0);
9098 gen_helper_0e0i(raise_exception, EXCP_DEBUG);
9100 tcg_gen_exit_tb(0);
9101 break;
9102 default:
9103 MIPS_DEBUG("unknown branch");
9104 break;
9109 /* ISA extensions (ASEs) */
9110 /* MIPS16 extension to MIPS32 */
9112 /* MIPS16 major opcodes */
9113 enum {
9114 M16_OPC_ADDIUSP = 0x00,
9115 M16_OPC_ADDIUPC = 0x01,
9116 M16_OPC_B = 0x02,
9117 M16_OPC_JAL = 0x03,
9118 M16_OPC_BEQZ = 0x04,
9119 M16_OPC_BNEQZ = 0x05,
9120 M16_OPC_SHIFT = 0x06,
9121 M16_OPC_LD = 0x07,
9122 M16_OPC_RRIA = 0x08,
9123 M16_OPC_ADDIU8 = 0x09,
9124 M16_OPC_SLTI = 0x0a,
9125 M16_OPC_SLTIU = 0x0b,
9126 M16_OPC_I8 = 0x0c,
9127 M16_OPC_LI = 0x0d,
9128 M16_OPC_CMPI = 0x0e,
9129 M16_OPC_SD = 0x0f,
9130 M16_OPC_LB = 0x10,
9131 M16_OPC_LH = 0x11,
9132 M16_OPC_LWSP = 0x12,
9133 M16_OPC_LW = 0x13,
9134 M16_OPC_LBU = 0x14,
9135 M16_OPC_LHU = 0x15,
9136 M16_OPC_LWPC = 0x16,
9137 M16_OPC_LWU = 0x17,
9138 M16_OPC_SB = 0x18,
9139 M16_OPC_SH = 0x19,
9140 M16_OPC_SWSP = 0x1a,
9141 M16_OPC_SW = 0x1b,
9142 M16_OPC_RRR = 0x1c,
9143 M16_OPC_RR = 0x1d,
9144 M16_OPC_EXTEND = 0x1e,
9145 M16_OPC_I64 = 0x1f
9148 /* I8 funct field */
9149 enum {
9150 I8_BTEQZ = 0x0,
9151 I8_BTNEZ = 0x1,
9152 I8_SWRASP = 0x2,
9153 I8_ADJSP = 0x3,
9154 I8_SVRS = 0x4,
9155 I8_MOV32R = 0x5,
9156 I8_MOVR32 = 0x7
9159 /* RRR f field */
9160 enum {
9161 RRR_DADDU = 0x0,
9162 RRR_ADDU = 0x1,
9163 RRR_DSUBU = 0x2,
9164 RRR_SUBU = 0x3
9167 /* RR funct field */
9168 enum {
9169 RR_JR = 0x00,
9170 RR_SDBBP = 0x01,
9171 RR_SLT = 0x02,
9172 RR_SLTU = 0x03,
9173 RR_SLLV = 0x04,
9174 RR_BREAK = 0x05,
9175 RR_SRLV = 0x06,
9176 RR_SRAV = 0x07,
9177 RR_DSRL = 0x08,
9178 RR_CMP = 0x0a,
9179 RR_NEG = 0x0b,
9180 RR_AND = 0x0c,
9181 RR_OR = 0x0d,
9182 RR_XOR = 0x0e,
9183 RR_NOT = 0x0f,
9184 RR_MFHI = 0x10,
9185 RR_CNVT = 0x11,
9186 RR_MFLO = 0x12,
9187 RR_DSRA = 0x13,
9188 RR_DSLLV = 0x14,
9189 RR_DSRLV = 0x16,
9190 RR_DSRAV = 0x17,
9191 RR_MULT = 0x18,
9192 RR_MULTU = 0x19,
9193 RR_DIV = 0x1a,
9194 RR_DIVU = 0x1b,
9195 RR_DMULT = 0x1c,
9196 RR_DMULTU = 0x1d,
9197 RR_DDIV = 0x1e,
9198 RR_DDIVU = 0x1f
9201 /* I64 funct field */
9202 enum {
9203 I64_LDSP = 0x0,
9204 I64_SDSP = 0x1,
9205 I64_SDRASP = 0x2,
9206 I64_DADJSP = 0x3,
9207 I64_LDPC = 0x4,
9208 I64_DADDIU5 = 0x5,
9209 I64_DADDIUPC = 0x6,
9210 I64_DADDIUSP = 0x7
9213 /* RR ry field for CNVT */
9214 enum {
9215 RR_RY_CNVT_ZEB = 0x0,
9216 RR_RY_CNVT_ZEH = 0x1,
9217 RR_RY_CNVT_ZEW = 0x2,
9218 RR_RY_CNVT_SEB = 0x4,
9219 RR_RY_CNVT_SEH = 0x5,
9220 RR_RY_CNVT_SEW = 0x6,
9223 static int xlat (int r)
9225 static int map[] = { 16, 17, 2, 3, 4, 5, 6, 7 };
9227 return map[r];
9230 static void gen_mips16_save (DisasContext *ctx,
9231 int xsregs, int aregs,
9232 int do_ra, int do_s0, int do_s1,
9233 int framesize)
9235 TCGv t0 = tcg_temp_new();
9236 TCGv t1 = tcg_temp_new();
9237 int args, astatic;
9239 switch (aregs) {
9240 case 0:
9241 case 1:
9242 case 2:
9243 case 3:
9244 case 11:
9245 args = 0;
9246 break;
9247 case 4:
9248 case 5:
9249 case 6:
9250 case 7:
9251 args = 1;
9252 break;
9253 case 8:
9254 case 9:
9255 case 10:
9256 args = 2;
9257 break;
9258 case 12:
9259 case 13:
9260 args = 3;
9261 break;
9262 case 14:
9263 args = 4;
9264 break;
9265 default:
9266 generate_exception(ctx, EXCP_RI);
9267 return;
9270 switch (args) {
9271 case 4:
9272 gen_base_offset_addr(ctx, t0, 29, 12);
9273 gen_load_gpr(t1, 7);
9274 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL);
9275 /* Fall through */
9276 case 3:
9277 gen_base_offset_addr(ctx, t0, 29, 8);
9278 gen_load_gpr(t1, 6);
9279 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL);
9280 /* Fall through */
9281 case 2:
9282 gen_base_offset_addr(ctx, t0, 29, 4);
9283 gen_load_gpr(t1, 5);
9284 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL);
9285 /* Fall through */
9286 case 1:
9287 gen_base_offset_addr(ctx, t0, 29, 0);
9288 gen_load_gpr(t1, 4);
9289 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL);
9292 gen_load_gpr(t0, 29);
9294 #define DECR_AND_STORE(reg) do { \
9295 tcg_gen_subi_tl(t0, t0, 4); \
9296 gen_load_gpr(t1, reg); \
9297 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL); \
9298 } while (0)
9300 if (do_ra) {
9301 DECR_AND_STORE(31);
9304 switch (xsregs) {
9305 case 7:
9306 DECR_AND_STORE(30);
9307 /* Fall through */
9308 case 6:
9309 DECR_AND_STORE(23);
9310 /* Fall through */
9311 case 5:
9312 DECR_AND_STORE(22);
9313 /* Fall through */
9314 case 4:
9315 DECR_AND_STORE(21);
9316 /* Fall through */
9317 case 3:
9318 DECR_AND_STORE(20);
9319 /* Fall through */
9320 case 2:
9321 DECR_AND_STORE(19);
9322 /* Fall through */
9323 case 1:
9324 DECR_AND_STORE(18);
9327 if (do_s1) {
9328 DECR_AND_STORE(17);
9330 if (do_s0) {
9331 DECR_AND_STORE(16);
9334 switch (aregs) {
9335 case 0:
9336 case 4:
9337 case 8:
9338 case 12:
9339 case 14:
9340 astatic = 0;
9341 break;
9342 case 1:
9343 case 5:
9344 case 9:
9345 case 13:
9346 astatic = 1;
9347 break;
9348 case 2:
9349 case 6:
9350 case 10:
9351 astatic = 2;
9352 break;
9353 case 3:
9354 case 7:
9355 astatic = 3;
9356 break;
9357 case 11:
9358 astatic = 4;
9359 break;
9360 default:
9361 generate_exception(ctx, EXCP_RI);
9362 return;
9365 if (astatic > 0) {
9366 DECR_AND_STORE(7);
9367 if (astatic > 1) {
9368 DECR_AND_STORE(6);
9369 if (astatic > 2) {
9370 DECR_AND_STORE(5);
9371 if (astatic > 3) {
9372 DECR_AND_STORE(4);
9377 #undef DECR_AND_STORE
9379 tcg_gen_subi_tl(cpu_gpr[29], cpu_gpr[29], framesize);
9380 tcg_temp_free(t0);
9381 tcg_temp_free(t1);
9384 static void gen_mips16_restore (DisasContext *ctx,
9385 int xsregs, int aregs,
9386 int do_ra, int do_s0, int do_s1,
9387 int framesize)
9389 int astatic;
9390 TCGv t0 = tcg_temp_new();
9391 TCGv t1 = tcg_temp_new();
9393 tcg_gen_addi_tl(t0, cpu_gpr[29], framesize);
9395 #define DECR_AND_LOAD(reg) do { \
9396 tcg_gen_subi_tl(t0, t0, 4); \
9397 tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_TESL); \
9398 gen_store_gpr(t1, reg); \
9399 } while (0)
9401 if (do_ra) {
9402 DECR_AND_LOAD(31);
9405 switch (xsregs) {
9406 case 7:
9407 DECR_AND_LOAD(30);
9408 /* Fall through */
9409 case 6:
9410 DECR_AND_LOAD(23);
9411 /* Fall through */
9412 case 5:
9413 DECR_AND_LOAD(22);
9414 /* Fall through */
9415 case 4:
9416 DECR_AND_LOAD(21);
9417 /* Fall through */
9418 case 3:
9419 DECR_AND_LOAD(20);
9420 /* Fall through */
9421 case 2:
9422 DECR_AND_LOAD(19);
9423 /* Fall through */
9424 case 1:
9425 DECR_AND_LOAD(18);
9428 if (do_s1) {
9429 DECR_AND_LOAD(17);
9431 if (do_s0) {
9432 DECR_AND_LOAD(16);
9435 switch (aregs) {
9436 case 0:
9437 case 4:
9438 case 8:
9439 case 12:
9440 case 14:
9441 astatic = 0;
9442 break;
9443 case 1:
9444 case 5:
9445 case 9:
9446 case 13:
9447 astatic = 1;
9448 break;
9449 case 2:
9450 case 6:
9451 case 10:
9452 astatic = 2;
9453 break;
9454 case 3:
9455 case 7:
9456 astatic = 3;
9457 break;
9458 case 11:
9459 astatic = 4;
9460 break;
9461 default:
9462 generate_exception(ctx, EXCP_RI);
9463 return;
9466 if (astatic > 0) {
9467 DECR_AND_LOAD(7);
9468 if (astatic > 1) {
9469 DECR_AND_LOAD(6);
9470 if (astatic > 2) {
9471 DECR_AND_LOAD(5);
9472 if (astatic > 3) {
9473 DECR_AND_LOAD(4);
9478 #undef DECR_AND_LOAD
9480 tcg_gen_addi_tl(cpu_gpr[29], cpu_gpr[29], framesize);
9481 tcg_temp_free(t0);
9482 tcg_temp_free(t1);
9485 static void gen_addiupc (DisasContext *ctx, int rx, int imm,
9486 int is_64_bit, int extended)
9488 TCGv t0;
9490 if (extended && (ctx->hflags & MIPS_HFLAG_BMASK)) {
9491 generate_exception(ctx, EXCP_RI);
9492 return;
9495 t0 = tcg_temp_new();
9497 tcg_gen_movi_tl(t0, pc_relative_pc(ctx));
9498 tcg_gen_addi_tl(cpu_gpr[rx], t0, imm);
9499 if (!is_64_bit) {
9500 tcg_gen_ext32s_tl(cpu_gpr[rx], cpu_gpr[rx]);
9503 tcg_temp_free(t0);
9506 #if defined(TARGET_MIPS64)
9507 static void decode_i64_mips16 (DisasContext *ctx,
9508 int ry, int funct, int16_t offset,
9509 int extended)
9511 switch (funct) {
9512 case I64_LDSP:
9513 check_mips_64(ctx);
9514 offset = extended ? offset : offset << 3;
9515 gen_ld(ctx, OPC_LD, ry, 29, offset);
9516 break;
9517 case I64_SDSP:
9518 check_mips_64(ctx);
9519 offset = extended ? offset : offset << 3;
9520 gen_st(ctx, OPC_SD, ry, 29, offset);
9521 break;
9522 case I64_SDRASP:
9523 check_mips_64(ctx);
9524 offset = extended ? offset : (ctx->opcode & 0xff) << 3;
9525 gen_st(ctx, OPC_SD, 31, 29, offset);
9526 break;
9527 case I64_DADJSP:
9528 check_mips_64(ctx);
9529 offset = extended ? offset : ((int8_t)ctx->opcode) << 3;
9530 gen_arith_imm(ctx, OPC_DADDIU, 29, 29, offset);
9531 break;
9532 case I64_LDPC:
9533 if (extended && (ctx->hflags & MIPS_HFLAG_BMASK)) {
9534 generate_exception(ctx, EXCP_RI);
9535 } else {
9536 offset = extended ? offset : offset << 3;
9537 gen_ld(ctx, OPC_LDPC, ry, 0, offset);
9539 break;
9540 case I64_DADDIU5:
9541 check_mips_64(ctx);
9542 offset = extended ? offset : ((int8_t)(offset << 3)) >> 3;
9543 gen_arith_imm(ctx, OPC_DADDIU, ry, ry, offset);
9544 break;
9545 case I64_DADDIUPC:
9546 check_mips_64(ctx);
9547 offset = extended ? offset : offset << 2;
9548 gen_addiupc(ctx, ry, offset, 1, extended);
9549 break;
9550 case I64_DADDIUSP:
9551 check_mips_64(ctx);
9552 offset = extended ? offset : offset << 2;
9553 gen_arith_imm(ctx, OPC_DADDIU, ry, 29, offset);
9554 break;
9557 #endif
9559 static int decode_extended_mips16_opc (CPUMIPSState *env, DisasContext *ctx)
9561 int extend = cpu_lduw_code(env, ctx->pc + 2);
9562 int op, rx, ry, funct, sa;
9563 int16_t imm, offset;
9565 ctx->opcode = (ctx->opcode << 16) | extend;
9566 op = (ctx->opcode >> 11) & 0x1f;
9567 sa = (ctx->opcode >> 22) & 0x1f;
9568 funct = (ctx->opcode >> 8) & 0x7;
9569 rx = xlat((ctx->opcode >> 8) & 0x7);
9570 ry = xlat((ctx->opcode >> 5) & 0x7);
9571 offset = imm = (int16_t) (((ctx->opcode >> 16) & 0x1f) << 11
9572 | ((ctx->opcode >> 21) & 0x3f) << 5
9573 | (ctx->opcode & 0x1f));
9575 /* The extended opcodes cleverly reuse the opcodes from their 16-bit
9576 counterparts. */
9577 switch (op) {
9578 case M16_OPC_ADDIUSP:
9579 gen_arith_imm(ctx, OPC_ADDIU, rx, 29, imm);
9580 break;
9581 case M16_OPC_ADDIUPC:
9582 gen_addiupc(ctx, rx, imm, 0, 1);
9583 break;
9584 case M16_OPC_B:
9585 gen_compute_branch(ctx, OPC_BEQ, 4, 0, 0, offset << 1);
9586 /* No delay slot, so just process as a normal instruction */
9587 break;
9588 case M16_OPC_BEQZ:
9589 gen_compute_branch(ctx, OPC_BEQ, 4, rx, 0, offset << 1);
9590 /* No delay slot, so just process as a normal instruction */
9591 break;
9592 case M16_OPC_BNEQZ:
9593 gen_compute_branch(ctx, OPC_BNE, 4, rx, 0, offset << 1);
9594 /* No delay slot, so just process as a normal instruction */
9595 break;
9596 case M16_OPC_SHIFT:
9597 switch (ctx->opcode & 0x3) {
9598 case 0x0:
9599 gen_shift_imm(ctx, OPC_SLL, rx, ry, sa);
9600 break;
9601 case 0x1:
9602 #if defined(TARGET_MIPS64)
9603 check_mips_64(ctx);
9604 gen_shift_imm(ctx, OPC_DSLL, rx, ry, sa);
9605 #else
9606 generate_exception(ctx, EXCP_RI);
9607 #endif
9608 break;
9609 case 0x2:
9610 gen_shift_imm(ctx, OPC_SRL, rx, ry, sa);
9611 break;
9612 case 0x3:
9613 gen_shift_imm(ctx, OPC_SRA, rx, ry, sa);
9614 break;
9616 break;
9617 #if defined(TARGET_MIPS64)
9618 case M16_OPC_LD:
9619 check_mips_64(ctx);
9620 gen_ld(ctx, OPC_LD, ry, rx, offset);
9621 break;
9622 #endif
9623 case M16_OPC_RRIA:
9624 imm = ctx->opcode & 0xf;
9625 imm = imm | ((ctx->opcode >> 20) & 0x7f) << 4;
9626 imm = imm | ((ctx->opcode >> 16) & 0xf) << 11;
9627 imm = (int16_t) (imm << 1) >> 1;
9628 if ((ctx->opcode >> 4) & 0x1) {
9629 #if defined(TARGET_MIPS64)
9630 check_mips_64(ctx);
9631 gen_arith_imm(ctx, OPC_DADDIU, ry, rx, imm);
9632 #else
9633 generate_exception(ctx, EXCP_RI);
9634 #endif
9635 } else {
9636 gen_arith_imm(ctx, OPC_ADDIU, ry, rx, imm);
9638 break;
9639 case M16_OPC_ADDIU8:
9640 gen_arith_imm(ctx, OPC_ADDIU, rx, rx, imm);
9641 break;
9642 case M16_OPC_SLTI:
9643 gen_slt_imm(ctx, OPC_SLTI, 24, rx, imm);
9644 break;
9645 case M16_OPC_SLTIU:
9646 gen_slt_imm(ctx, OPC_SLTIU, 24, rx, imm);
9647 break;
9648 case M16_OPC_I8:
9649 switch (funct) {
9650 case I8_BTEQZ:
9651 gen_compute_branch(ctx, OPC_BEQ, 4, 24, 0, offset << 1);
9652 break;
9653 case I8_BTNEZ:
9654 gen_compute_branch(ctx, OPC_BNE, 4, 24, 0, offset << 1);
9655 break;
9656 case I8_SWRASP:
9657 gen_st(ctx, OPC_SW, 31, 29, imm);
9658 break;
9659 case I8_ADJSP:
9660 gen_arith_imm(ctx, OPC_ADDIU, 29, 29, imm);
9661 break;
9662 case I8_SVRS:
9664 int xsregs = (ctx->opcode >> 24) & 0x7;
9665 int aregs = (ctx->opcode >> 16) & 0xf;
9666 int do_ra = (ctx->opcode >> 6) & 0x1;
9667 int do_s0 = (ctx->opcode >> 5) & 0x1;
9668 int do_s1 = (ctx->opcode >> 4) & 0x1;
9669 int framesize = (((ctx->opcode >> 20) & 0xf) << 4
9670 | (ctx->opcode & 0xf)) << 3;
9672 if (ctx->opcode & (1 << 7)) {
9673 gen_mips16_save(ctx, xsregs, aregs,
9674 do_ra, do_s0, do_s1,
9675 framesize);
9676 } else {
9677 gen_mips16_restore(ctx, xsregs, aregs,
9678 do_ra, do_s0, do_s1,
9679 framesize);
9682 break;
9683 default:
9684 generate_exception(ctx, EXCP_RI);
9685 break;
9687 break;
9688 case M16_OPC_LI:
9689 tcg_gen_movi_tl(cpu_gpr[rx], (uint16_t) imm);
9690 break;
9691 case M16_OPC_CMPI:
9692 tcg_gen_xori_tl(cpu_gpr[24], cpu_gpr[rx], (uint16_t) imm);
9693 break;
9694 #if defined(TARGET_MIPS64)
9695 case M16_OPC_SD:
9696 gen_st(ctx, OPC_SD, ry, rx, offset);
9697 break;
9698 #endif
9699 case M16_OPC_LB:
9700 gen_ld(ctx, OPC_LB, ry, rx, offset);
9701 break;
9702 case M16_OPC_LH:
9703 gen_ld(ctx, OPC_LH, ry, rx, offset);
9704 break;
9705 case M16_OPC_LWSP:
9706 gen_ld(ctx, OPC_LW, rx, 29, offset);
9707 break;
9708 case M16_OPC_LW:
9709 gen_ld(ctx, OPC_LW, ry, rx, offset);
9710 break;
9711 case M16_OPC_LBU:
9712 gen_ld(ctx, OPC_LBU, ry, rx, offset);
9713 break;
9714 case M16_OPC_LHU:
9715 gen_ld(ctx, OPC_LHU, ry, rx, offset);
9716 break;
9717 case M16_OPC_LWPC:
9718 gen_ld(ctx, OPC_LWPC, rx, 0, offset);
9719 break;
9720 #if defined(TARGET_MIPS64)
9721 case M16_OPC_LWU:
9722 gen_ld(ctx, OPC_LWU, ry, rx, offset);
9723 break;
9724 #endif
9725 case M16_OPC_SB:
9726 gen_st(ctx, OPC_SB, ry, rx, offset);
9727 break;
9728 case M16_OPC_SH:
9729 gen_st(ctx, OPC_SH, ry, rx, offset);
9730 break;
9731 case M16_OPC_SWSP:
9732 gen_st(ctx, OPC_SW, rx, 29, offset);
9733 break;
9734 case M16_OPC_SW:
9735 gen_st(ctx, OPC_SW, ry, rx, offset);
9736 break;
9737 #if defined(TARGET_MIPS64)
9738 case M16_OPC_I64:
9739 decode_i64_mips16(ctx, ry, funct, offset, 1);
9740 break;
9741 #endif
9742 default:
9743 generate_exception(ctx, EXCP_RI);
9744 break;
9747 return 4;
9750 static int decode_mips16_opc (CPUMIPSState *env, DisasContext *ctx)
9752 int rx, ry;
9753 int sa;
9754 int op, cnvt_op, op1, offset;
9755 int funct;
9756 int n_bytes;
9758 op = (ctx->opcode >> 11) & 0x1f;
9759 sa = (ctx->opcode >> 2) & 0x7;
9760 sa = sa == 0 ? 8 : sa;
9761 rx = xlat((ctx->opcode >> 8) & 0x7);
9762 cnvt_op = (ctx->opcode >> 5) & 0x7;
9763 ry = xlat((ctx->opcode >> 5) & 0x7);
9764 op1 = offset = ctx->opcode & 0x1f;
9766 n_bytes = 2;
9768 switch (op) {
9769 case M16_OPC_ADDIUSP:
9771 int16_t imm = ((uint8_t) ctx->opcode) << 2;
9773 gen_arith_imm(ctx, OPC_ADDIU, rx, 29, imm);
9775 break;
9776 case M16_OPC_ADDIUPC:
9777 gen_addiupc(ctx, rx, ((uint8_t) ctx->opcode) << 2, 0, 0);
9778 break;
9779 case M16_OPC_B:
9780 offset = (ctx->opcode & 0x7ff) << 1;
9781 offset = (int16_t)(offset << 4) >> 4;
9782 gen_compute_branch(ctx, OPC_BEQ, 2, 0, 0, offset);
9783 /* No delay slot, so just process as a normal instruction */
9784 break;
9785 case M16_OPC_JAL:
9786 offset = cpu_lduw_code(env, ctx->pc + 2);
9787 offset = (((ctx->opcode & 0x1f) << 21)
9788 | ((ctx->opcode >> 5) & 0x1f) << 16
9789 | offset) << 2;
9790 op = ((ctx->opcode >> 10) & 0x1) ? OPC_JALXS : OPC_JALS;
9791 gen_compute_branch(ctx, op, 4, rx, ry, offset);
9792 n_bytes = 4;
9793 break;
9794 case M16_OPC_BEQZ:
9795 gen_compute_branch(ctx, OPC_BEQ, 2, rx, 0, ((int8_t)ctx->opcode) << 1);
9796 /* No delay slot, so just process as a normal instruction */
9797 break;
9798 case M16_OPC_BNEQZ:
9799 gen_compute_branch(ctx, OPC_BNE, 2, rx, 0, ((int8_t)ctx->opcode) << 1);
9800 /* No delay slot, so just process as a normal instruction */
9801 break;
9802 case M16_OPC_SHIFT:
9803 switch (ctx->opcode & 0x3) {
9804 case 0x0:
9805 gen_shift_imm(ctx, OPC_SLL, rx, ry, sa);
9806 break;
9807 case 0x1:
9808 #if defined(TARGET_MIPS64)
9809 check_mips_64(ctx);
9810 gen_shift_imm(ctx, OPC_DSLL, rx, ry, sa);
9811 #else
9812 generate_exception(ctx, EXCP_RI);
9813 #endif
9814 break;
9815 case 0x2:
9816 gen_shift_imm(ctx, OPC_SRL, rx, ry, sa);
9817 break;
9818 case 0x3:
9819 gen_shift_imm(ctx, OPC_SRA, rx, ry, sa);
9820 break;
9822 break;
9823 #if defined(TARGET_MIPS64)
9824 case M16_OPC_LD:
9825 check_mips_64(ctx);
9826 gen_ld(ctx, OPC_LD, ry, rx, offset << 3);
9827 break;
9828 #endif
9829 case M16_OPC_RRIA:
9831 int16_t imm = (int8_t)((ctx->opcode & 0xf) << 4) >> 4;
9833 if ((ctx->opcode >> 4) & 1) {
9834 #if defined(TARGET_MIPS64)
9835 check_mips_64(ctx);
9836 gen_arith_imm(ctx, OPC_DADDIU, ry, rx, imm);
9837 #else
9838 generate_exception(ctx, EXCP_RI);
9839 #endif
9840 } else {
9841 gen_arith_imm(ctx, OPC_ADDIU, ry, rx, imm);
9844 break;
9845 case M16_OPC_ADDIU8:
9847 int16_t imm = (int8_t) ctx->opcode;
9849 gen_arith_imm(ctx, OPC_ADDIU, rx, rx, imm);
9851 break;
9852 case M16_OPC_SLTI:
9854 int16_t imm = (uint8_t) ctx->opcode;
9855 gen_slt_imm(ctx, OPC_SLTI, 24, rx, imm);
9857 break;
9858 case M16_OPC_SLTIU:
9860 int16_t imm = (uint8_t) ctx->opcode;
9861 gen_slt_imm(ctx, OPC_SLTIU, 24, rx, imm);
9863 break;
9864 case M16_OPC_I8:
9866 int reg32;
9868 funct = (ctx->opcode >> 8) & 0x7;
9869 switch (funct) {
9870 case I8_BTEQZ:
9871 gen_compute_branch(ctx, OPC_BEQ, 2, 24, 0,
9872 ((int8_t)ctx->opcode) << 1);
9873 break;
9874 case I8_BTNEZ:
9875 gen_compute_branch(ctx, OPC_BNE, 2, 24, 0,
9876 ((int8_t)ctx->opcode) << 1);
9877 break;
9878 case I8_SWRASP:
9879 gen_st(ctx, OPC_SW, 31, 29, (ctx->opcode & 0xff) << 2);
9880 break;
9881 case I8_ADJSP:
9882 gen_arith_imm(ctx, OPC_ADDIU, 29, 29,
9883 ((int8_t)ctx->opcode) << 3);
9884 break;
9885 case I8_SVRS:
9887 int do_ra = ctx->opcode & (1 << 6);
9888 int do_s0 = ctx->opcode & (1 << 5);
9889 int do_s1 = ctx->opcode & (1 << 4);
9890 int framesize = ctx->opcode & 0xf;
9892 if (framesize == 0) {
9893 framesize = 128;
9894 } else {
9895 framesize = framesize << 3;
9898 if (ctx->opcode & (1 << 7)) {
9899 gen_mips16_save(ctx, 0, 0,
9900 do_ra, do_s0, do_s1, framesize);
9901 } else {
9902 gen_mips16_restore(ctx, 0, 0,
9903 do_ra, do_s0, do_s1, framesize);
9906 break;
9907 case I8_MOV32R:
9909 int rz = xlat(ctx->opcode & 0x7);
9911 reg32 = (((ctx->opcode >> 3) & 0x3) << 3) |
9912 ((ctx->opcode >> 5) & 0x7);
9913 gen_arith(ctx, OPC_ADDU, reg32, rz, 0);
9915 break;
9916 case I8_MOVR32:
9917 reg32 = ctx->opcode & 0x1f;
9918 gen_arith(ctx, OPC_ADDU, ry, reg32, 0);
9919 break;
9920 default:
9921 generate_exception(ctx, EXCP_RI);
9922 break;
9925 break;
9926 case M16_OPC_LI:
9928 int16_t imm = (uint8_t) ctx->opcode;
9930 gen_arith_imm(ctx, OPC_ADDIU, rx, 0, imm);
9932 break;
9933 case M16_OPC_CMPI:
9935 int16_t imm = (uint8_t) ctx->opcode;
9936 gen_logic_imm(ctx, OPC_XORI, 24, rx, imm);
9938 break;
9939 #if defined(TARGET_MIPS64)
9940 case M16_OPC_SD:
9941 check_mips_64(ctx);
9942 gen_st(ctx, OPC_SD, ry, rx, offset << 3);
9943 break;
9944 #endif
9945 case M16_OPC_LB:
9946 gen_ld(ctx, OPC_LB, ry, rx, offset);
9947 break;
9948 case M16_OPC_LH:
9949 gen_ld(ctx, OPC_LH, ry, rx, offset << 1);
9950 break;
9951 case M16_OPC_LWSP:
9952 gen_ld(ctx, OPC_LW, rx, 29, ((uint8_t)ctx->opcode) << 2);
9953 break;
9954 case M16_OPC_LW:
9955 gen_ld(ctx, OPC_LW, ry, rx, offset << 2);
9956 break;
9957 case M16_OPC_LBU:
9958 gen_ld(ctx, OPC_LBU, ry, rx, offset);
9959 break;
9960 case M16_OPC_LHU:
9961 gen_ld(ctx, OPC_LHU, ry, rx, offset << 1);
9962 break;
9963 case M16_OPC_LWPC:
9964 gen_ld(ctx, OPC_LWPC, rx, 0, ((uint8_t)ctx->opcode) << 2);
9965 break;
9966 #if defined (TARGET_MIPS64)
9967 case M16_OPC_LWU:
9968 check_mips_64(ctx);
9969 gen_ld(ctx, OPC_LWU, ry, rx, offset << 2);
9970 break;
9971 #endif
9972 case M16_OPC_SB:
9973 gen_st(ctx, OPC_SB, ry, rx, offset);
9974 break;
9975 case M16_OPC_SH:
9976 gen_st(ctx, OPC_SH, ry, rx, offset << 1);
9977 break;
9978 case M16_OPC_SWSP:
9979 gen_st(ctx, OPC_SW, rx, 29, ((uint8_t)ctx->opcode) << 2);
9980 break;
9981 case M16_OPC_SW:
9982 gen_st(ctx, OPC_SW, ry, rx, offset << 2);
9983 break;
9984 case M16_OPC_RRR:
9986 int rz = xlat((ctx->opcode >> 2) & 0x7);
9987 int mips32_op;
9989 switch (ctx->opcode & 0x3) {
9990 case RRR_ADDU:
9991 mips32_op = OPC_ADDU;
9992 break;
9993 case RRR_SUBU:
9994 mips32_op = OPC_SUBU;
9995 break;
9996 #if defined(TARGET_MIPS64)
9997 case RRR_DADDU:
9998 mips32_op = OPC_DADDU;
9999 check_mips_64(ctx);
10000 break;
10001 case RRR_DSUBU:
10002 mips32_op = OPC_DSUBU;
10003 check_mips_64(ctx);
10004 break;
10005 #endif
10006 default:
10007 generate_exception(ctx, EXCP_RI);
10008 goto done;
10011 gen_arith(ctx, mips32_op, rz, rx, ry);
10012 done:
10015 break;
10016 case M16_OPC_RR:
10017 switch (op1) {
10018 case RR_JR:
10020 int nd = (ctx->opcode >> 7) & 0x1;
10021 int link = (ctx->opcode >> 6) & 0x1;
10022 int ra = (ctx->opcode >> 5) & 0x1;
10024 if (link) {
10025 op = nd ? OPC_JALRC : OPC_JALRS;
10026 } else {
10027 op = OPC_JR;
10030 gen_compute_branch(ctx, op, 2, ra ? 31 : rx, 31, 0);
10032 break;
10033 case RR_SDBBP:
10034 /* XXX: not clear which exception should be raised
10035 * when in debug mode...
10037 check_insn(ctx, ISA_MIPS32);
10038 if (!(ctx->hflags & MIPS_HFLAG_DM)) {
10039 generate_exception(ctx, EXCP_DBp);
10040 } else {
10041 generate_exception(ctx, EXCP_DBp);
10043 break;
10044 case RR_SLT:
10045 gen_slt(ctx, OPC_SLT, 24, rx, ry);
10046 break;
10047 case RR_SLTU:
10048 gen_slt(ctx, OPC_SLTU, 24, rx, ry);
10049 break;
10050 case RR_BREAK:
10051 generate_exception(ctx, EXCP_BREAK);
10052 break;
10053 case RR_SLLV:
10054 gen_shift(ctx, OPC_SLLV, ry, rx, ry);
10055 break;
10056 case RR_SRLV:
10057 gen_shift(ctx, OPC_SRLV, ry, rx, ry);
10058 break;
10059 case RR_SRAV:
10060 gen_shift(ctx, OPC_SRAV, ry, rx, ry);
10061 break;
10062 #if defined (TARGET_MIPS64)
10063 case RR_DSRL:
10064 check_mips_64(ctx);
10065 gen_shift_imm(ctx, OPC_DSRL, ry, ry, sa);
10066 break;
10067 #endif
10068 case RR_CMP:
10069 gen_logic(ctx, OPC_XOR, 24, rx, ry);
10070 break;
10071 case RR_NEG:
10072 gen_arith(ctx, OPC_SUBU, rx, 0, ry);
10073 break;
10074 case RR_AND:
10075 gen_logic(ctx, OPC_AND, rx, rx, ry);
10076 break;
10077 case RR_OR:
10078 gen_logic(ctx, OPC_OR, rx, rx, ry);
10079 break;
10080 case RR_XOR:
10081 gen_logic(ctx, OPC_XOR, rx, rx, ry);
10082 break;
10083 case RR_NOT:
10084 gen_logic(ctx, OPC_NOR, rx, ry, 0);
10085 break;
10086 case RR_MFHI:
10087 gen_HILO(ctx, OPC_MFHI, 0, rx);
10088 break;
10089 case RR_CNVT:
10090 switch (cnvt_op) {
10091 case RR_RY_CNVT_ZEB:
10092 tcg_gen_ext8u_tl(cpu_gpr[rx], cpu_gpr[rx]);
10093 break;
10094 case RR_RY_CNVT_ZEH:
10095 tcg_gen_ext16u_tl(cpu_gpr[rx], cpu_gpr[rx]);
10096 break;
10097 case RR_RY_CNVT_SEB:
10098 tcg_gen_ext8s_tl(cpu_gpr[rx], cpu_gpr[rx]);
10099 break;
10100 case RR_RY_CNVT_SEH:
10101 tcg_gen_ext16s_tl(cpu_gpr[rx], cpu_gpr[rx]);
10102 break;
10103 #if defined (TARGET_MIPS64)
10104 case RR_RY_CNVT_ZEW:
10105 check_mips_64(ctx);
10106 tcg_gen_ext32u_tl(cpu_gpr[rx], cpu_gpr[rx]);
10107 break;
10108 case RR_RY_CNVT_SEW:
10109 check_mips_64(ctx);
10110 tcg_gen_ext32s_tl(cpu_gpr[rx], cpu_gpr[rx]);
10111 break;
10112 #endif
10113 default:
10114 generate_exception(ctx, EXCP_RI);
10115 break;
10117 break;
10118 case RR_MFLO:
10119 gen_HILO(ctx, OPC_MFLO, 0, rx);
10120 break;
10121 #if defined (TARGET_MIPS64)
10122 case RR_DSRA:
10123 check_mips_64(ctx);
10124 gen_shift_imm(ctx, OPC_DSRA, ry, ry, sa);
10125 break;
10126 case RR_DSLLV:
10127 check_mips_64(ctx);
10128 gen_shift(ctx, OPC_DSLLV, ry, rx, ry);
10129 break;
10130 case RR_DSRLV:
10131 check_mips_64(ctx);
10132 gen_shift(ctx, OPC_DSRLV, ry, rx, ry);
10133 break;
10134 case RR_DSRAV:
10135 check_mips_64(ctx);
10136 gen_shift(ctx, OPC_DSRAV, ry, rx, ry);
10137 break;
10138 #endif
10139 case RR_MULT:
10140 gen_muldiv(ctx, OPC_MULT, 0, rx, ry);
10141 break;
10142 case RR_MULTU:
10143 gen_muldiv(ctx, OPC_MULTU, 0, rx, ry);
10144 break;
10145 case RR_DIV:
10146 gen_muldiv(ctx, OPC_DIV, 0, rx, ry);
10147 break;
10148 case RR_DIVU:
10149 gen_muldiv(ctx, OPC_DIVU, 0, rx, ry);
10150 break;
10151 #if defined (TARGET_MIPS64)
10152 case RR_DMULT:
10153 check_mips_64(ctx);
10154 gen_muldiv(ctx, OPC_DMULT, 0, rx, ry);
10155 break;
10156 case RR_DMULTU:
10157 check_mips_64(ctx);
10158 gen_muldiv(ctx, OPC_DMULTU, 0, rx, ry);
10159 break;
10160 case RR_DDIV:
10161 check_mips_64(ctx);
10162 gen_muldiv(ctx, OPC_DDIV, 0, rx, ry);
10163 break;
10164 case RR_DDIVU:
10165 check_mips_64(ctx);
10166 gen_muldiv(ctx, OPC_DDIVU, 0, rx, ry);
10167 break;
10168 #endif
10169 default:
10170 generate_exception(ctx, EXCP_RI);
10171 break;
10173 break;
10174 case M16_OPC_EXTEND:
10175 decode_extended_mips16_opc(env, ctx);
10176 n_bytes = 4;
10177 break;
10178 #if defined(TARGET_MIPS64)
10179 case M16_OPC_I64:
10180 funct = (ctx->opcode >> 8) & 0x7;
10181 decode_i64_mips16(ctx, ry, funct, offset, 0);
10182 break;
10183 #endif
10184 default:
10185 generate_exception(ctx, EXCP_RI);
10186 break;
10189 return n_bytes;
10192 /* microMIPS extension to MIPS32/MIPS64 */
10195 * microMIPS32/microMIPS64 major opcodes
10197 * 1. MIPS Architecture for Programmers Volume II-B:
10198 * The microMIPS32 Instruction Set (Revision 3.05)
10200 * Table 6.2 microMIPS32 Encoding of Major Opcode Field
10202 * 2. MIPS Architecture For Programmers Volume II-A:
10203 * The MIPS64 Instruction Set (Revision 3.51)
10206 enum {
10207 POOL32A = 0x00,
10208 POOL16A = 0x01,
10209 LBU16 = 0x02,
10210 MOVE16 = 0x03,
10211 ADDI32 = 0x04,
10212 LBU32 = 0x05,
10213 SB32 = 0x06,
10214 LB32 = 0x07,
10216 POOL32B = 0x08,
10217 POOL16B = 0x09,
10218 LHU16 = 0x0a,
10219 ANDI16 = 0x0b,
10220 ADDIU32 = 0x0c,
10221 LHU32 = 0x0d,
10222 SH32 = 0x0e,
10223 LH32 = 0x0f,
10225 POOL32I = 0x10,
10226 POOL16C = 0x11,
10227 LWSP16 = 0x12,
10228 POOL16D = 0x13,
10229 ORI32 = 0x14,
10230 POOL32F = 0x15,
10231 POOL32S = 0x16, /* MIPS64 */
10232 DADDIU32 = 0x17, /* MIPS64 */
10234 /* 0x1f is reserved */
10235 POOL32C = 0x18,
10236 LWGP16 = 0x19,
10237 LW16 = 0x1a,
10238 POOL16E = 0x1b,
10239 XORI32 = 0x1c,
10240 JALS32 = 0x1d,
10241 ADDIUPC = 0x1e,
10243 /* 0x20 is reserved */
10244 RES_20 = 0x20,
10245 POOL16F = 0x21,
10246 SB16 = 0x22,
10247 BEQZ16 = 0x23,
10248 SLTI32 = 0x24,
10249 BEQ32 = 0x25,
10250 SWC132 = 0x26,
10251 LWC132 = 0x27,
10253 /* 0x28 and 0x29 are reserved */
10254 RES_28 = 0x28,
10255 RES_29 = 0x29,
10256 SH16 = 0x2a,
10257 BNEZ16 = 0x2b,
10258 SLTIU32 = 0x2c,
10259 BNE32 = 0x2d,
10260 SDC132 = 0x2e,
10261 LDC132 = 0x2f,
10263 /* 0x30 and 0x31 are reserved */
10264 RES_30 = 0x30,
10265 RES_31 = 0x31,
10266 SWSP16 = 0x32,
10267 B16 = 0x33,
10268 ANDI32 = 0x34,
10269 J32 = 0x35,
10270 SD32 = 0x36, /* MIPS64 */
10271 LD32 = 0x37, /* MIPS64 */
10273 /* 0x38 and 0x39 are reserved */
10274 RES_38 = 0x38,
10275 RES_39 = 0x39,
10276 SW16 = 0x3a,
10277 LI16 = 0x3b,
10278 JALX32 = 0x3c,
10279 JAL32 = 0x3d,
10280 SW32 = 0x3e,
10281 LW32 = 0x3f
10284 /* POOL32A encoding of minor opcode field */
10286 enum {
10287 /* These opcodes are distinguished only by bits 9..6; those bits are
10288 * what are recorded below. */
10289 SLL32 = 0x0,
10290 SRL32 = 0x1,
10291 SRA = 0x2,
10292 ROTR = 0x3,
10294 SLLV = 0x0,
10295 SRLV = 0x1,
10296 SRAV = 0x2,
10297 ROTRV = 0x3,
10298 ADD = 0x4,
10299 ADDU32 = 0x5,
10300 SUB = 0x6,
10301 SUBU32 = 0x7,
10302 MUL = 0x8,
10303 AND = 0x9,
10304 OR32 = 0xa,
10305 NOR = 0xb,
10306 XOR32 = 0xc,
10307 SLT = 0xd,
10308 SLTU = 0xe,
10310 MOVN = 0x0,
10311 MOVZ = 0x1,
10312 LWXS = 0x4,
10314 /* The following can be distinguished by their lower 6 bits. */
10315 INS = 0x0c,
10316 EXT = 0x2c,
10317 POOL32AXF = 0x3c
10320 /* POOL32AXF encoding of minor opcode field extension */
10323 * 1. MIPS Architecture for Programmers Volume II-B:
10324 * The microMIPS32 Instruction Set (Revision 3.05)
10326 * Table 6.5 POOL32Axf Encoding of Minor Opcode Extension Field
10328 * 2. MIPS Architecture for Programmers VolumeIV-e:
10329 * The MIPS DSP Application-Specific Extension
10330 * to the microMIPS32 Architecture (Revision 2.34)
10332 * Table 5.5 POOL32Axf Encoding of Minor Opcode Extension Field
10335 enum {
10336 /* bits 11..6 */
10337 TEQ = 0x00,
10338 TGE = 0x08,
10339 TGEU = 0x10,
10340 TLT = 0x20,
10341 TLTU = 0x28,
10342 TNE = 0x30,
10344 MFC0 = 0x03,
10345 MTC0 = 0x0b,
10347 /* begin of microMIPS32 DSP */
10349 /* bits 13..12 for 0x01 */
10350 MFHI_ACC = 0x0,
10351 MFLO_ACC = 0x1,
10352 MTHI_ACC = 0x2,
10353 MTLO_ACC = 0x3,
10355 /* bits 13..12 for 0x2a */
10356 MADD_ACC = 0x0,
10357 MADDU_ACC = 0x1,
10358 MSUB_ACC = 0x2,
10359 MSUBU_ACC = 0x3,
10361 /* bits 13..12 for 0x32 */
10362 MULT_ACC = 0x0,
10363 MULTU_ACC = 0x1,
10365 /* end of microMIPS32 DSP */
10367 /* bits 15..12 for 0x2c */
10368 SEB = 0x2,
10369 SEH = 0x3,
10370 CLO = 0x4,
10371 CLZ = 0x5,
10372 RDHWR = 0x6,
10373 WSBH = 0x7,
10374 MULT = 0x8,
10375 MULTU = 0x9,
10376 DIV = 0xa,
10377 DIVU = 0xb,
10378 MADD = 0xc,
10379 MADDU = 0xd,
10380 MSUB = 0xe,
10381 MSUBU = 0xf,
10383 /* bits 15..12 for 0x34 */
10384 MFC2 = 0x4,
10385 MTC2 = 0x5,
10386 MFHC2 = 0x8,
10387 MTHC2 = 0x9,
10388 CFC2 = 0xc,
10389 CTC2 = 0xd,
10391 /* bits 15..12 for 0x3c */
10392 JALR = 0x0,
10393 JR = 0x0, /* alias */
10394 JALR_HB = 0x1,
10395 JALRS = 0x4,
10396 JALRS_HB = 0x5,
10398 /* bits 15..12 for 0x05 */
10399 RDPGPR = 0xe,
10400 WRPGPR = 0xf,
10402 /* bits 15..12 for 0x0d */
10403 TLBP = 0x0,
10404 TLBR = 0x1,
10405 TLBWI = 0x2,
10406 TLBWR = 0x3,
10407 WAIT = 0x9,
10408 IRET = 0xd,
10409 DERET = 0xe,
10410 ERET = 0xf,
10412 /* bits 15..12 for 0x15 */
10413 DMT = 0x0,
10414 DVPE = 0x1,
10415 EMT = 0x2,
10416 EVPE = 0x3,
10418 /* bits 15..12 for 0x1d */
10419 DI = 0x4,
10420 EI = 0x5,
10422 /* bits 15..12 for 0x2d */
10423 SYNC = 0x6,
10424 SYSCALL = 0x8,
10425 SDBBP = 0xd,
10427 /* bits 15..12 for 0x35 */
10428 MFHI32 = 0x0,
10429 MFLO32 = 0x1,
10430 MTHI32 = 0x2,
10431 MTLO32 = 0x3,
10434 /* POOL32B encoding of minor opcode field (bits 15..12) */
10436 enum {
10437 LWC2 = 0x0,
10438 LWP = 0x1,
10439 LDP = 0x4,
10440 LWM32 = 0x5,
10441 CACHE = 0x6,
10442 LDM = 0x7,
10443 SWC2 = 0x8,
10444 SWP = 0x9,
10445 SDP = 0xc,
10446 SWM32 = 0xd,
10447 SDM = 0xf
10450 /* POOL32C encoding of minor opcode field (bits 15..12) */
10452 enum {
10453 LWL = 0x0,
10454 SWL = 0x8,
10455 LWR = 0x1,
10456 SWR = 0x9,
10457 PREF = 0x2,
10458 /* 0xa is reserved */
10459 LL = 0x3,
10460 SC = 0xb,
10461 LDL = 0x4,
10462 SDL = 0xc,
10463 LDR = 0x5,
10464 SDR = 0xd,
10465 /* 0x6 is reserved */
10466 LWU = 0xe,
10467 LLD = 0x7,
10468 SCD = 0xf
10471 /* POOL32F encoding of minor opcode field (bits 5..0) */
10473 enum {
10474 /* These are the bit 7..6 values */
10475 ADD_FMT = 0x0,
10476 MOVN_FMT = 0x0,
10478 SUB_FMT = 0x1,
10479 MOVZ_FMT = 0x1,
10481 MUL_FMT = 0x2,
10483 DIV_FMT = 0x3,
10485 /* These are the bit 8..6 values */
10486 RSQRT2_FMT = 0x0,
10487 MOVF_FMT = 0x0,
10489 LWXC1 = 0x1,
10490 MOVT_FMT = 0x1,
10492 PLL_PS = 0x2,
10493 SWXC1 = 0x2,
10495 PLU_PS = 0x3,
10496 LDXC1 = 0x3,
10498 PUL_PS = 0x4,
10499 SDXC1 = 0x4,
10500 RECIP2_FMT = 0x4,
10502 PUU_PS = 0x5,
10503 LUXC1 = 0x5,
10505 CVT_PS_S = 0x6,
10506 SUXC1 = 0x6,
10507 ADDR_PS = 0x6,
10508 PREFX = 0x6,
10510 MULR_PS = 0x7,
10512 MADD_S = 0x01,
10513 MADD_D = 0x09,
10514 MADD_PS = 0x11,
10515 ALNV_PS = 0x19,
10516 MSUB_S = 0x21,
10517 MSUB_D = 0x29,
10518 MSUB_PS = 0x31,
10520 NMADD_S = 0x02,
10521 NMADD_D = 0x0a,
10522 NMADD_PS = 0x12,
10523 NMSUB_S = 0x22,
10524 NMSUB_D = 0x2a,
10525 NMSUB_PS = 0x32,
10527 POOL32FXF = 0x3b,
10529 CABS_COND_FMT = 0x1c, /* MIPS3D */
10530 C_COND_FMT = 0x3c
10533 /* POOL32Fxf encoding of minor opcode extension field */
10535 enum {
10536 CVT_L = 0x04,
10537 RSQRT_FMT = 0x08,
10538 FLOOR_L = 0x0c,
10539 CVT_PW_PS = 0x1c,
10540 CVT_W = 0x24,
10541 SQRT_FMT = 0x28,
10542 FLOOR_W = 0x2c,
10543 CVT_PS_PW = 0x3c,
10544 CFC1 = 0x40,
10545 RECIP_FMT = 0x48,
10546 CEIL_L = 0x4c,
10547 CTC1 = 0x60,
10548 CEIL_W = 0x6c,
10549 MFC1 = 0x80,
10550 CVT_S_PL = 0x84,
10551 TRUNC_L = 0x8c,
10552 MTC1 = 0xa0,
10553 CVT_S_PU = 0xa4,
10554 TRUNC_W = 0xac,
10555 MFHC1 = 0xc0,
10556 ROUND_L = 0xcc,
10557 MTHC1 = 0xe0,
10558 ROUND_W = 0xec,
10560 MOV_FMT = 0x01,
10561 MOVF = 0x05,
10562 ABS_FMT = 0x0d,
10563 RSQRT1_FMT = 0x1d,
10564 MOVT = 0x25,
10565 NEG_FMT = 0x2d,
10566 CVT_D = 0x4d,
10567 RECIP1_FMT = 0x5d,
10568 CVT_S = 0x6d
10571 /* POOL32I encoding of minor opcode field (bits 25..21) */
10573 enum {
10574 BLTZ = 0x00,
10575 BLTZAL = 0x01,
10576 BGEZ = 0x02,
10577 BGEZAL = 0x03,
10578 BLEZ = 0x04,
10579 BNEZC = 0x05,
10580 BGTZ = 0x06,
10581 BEQZC = 0x07,
10582 TLTI = 0x08,
10583 TGEI = 0x09,
10584 TLTIU = 0x0a,
10585 TGEIU = 0x0b,
10586 TNEI = 0x0c,
10587 LUI = 0x0d,
10588 TEQI = 0x0e,
10589 SYNCI = 0x10,
10590 BLTZALS = 0x11,
10591 BGEZALS = 0x13,
10592 BC2F = 0x14,
10593 BC2T = 0x15,
10594 BPOSGE64 = 0x1a,
10595 BPOSGE32 = 0x1b,
10596 /* These overlap and are distinguished by bit16 of the instruction */
10597 BC1F = 0x1c,
10598 BC1T = 0x1d,
10599 BC1ANY2F = 0x1c,
10600 BC1ANY2T = 0x1d,
10601 BC1ANY4F = 0x1e,
10602 BC1ANY4T = 0x1f
10605 /* POOL16A encoding of minor opcode field */
10607 enum {
10608 ADDU16 = 0x0,
10609 SUBU16 = 0x1
10612 /* POOL16B encoding of minor opcode field */
10614 enum {
10615 SLL16 = 0x0,
10616 SRL16 = 0x1
10619 /* POOL16C encoding of minor opcode field */
10621 enum {
10622 NOT16 = 0x00,
10623 XOR16 = 0x04,
10624 AND16 = 0x08,
10625 OR16 = 0x0c,
10626 LWM16 = 0x10,
10627 SWM16 = 0x14,
10628 JR16 = 0x18,
10629 JRC16 = 0x1a,
10630 JALR16 = 0x1c,
10631 JALR16S = 0x1e,
10632 MFHI16 = 0x20,
10633 MFLO16 = 0x24,
10634 BREAK16 = 0x28,
10635 SDBBP16 = 0x2c,
10636 JRADDIUSP = 0x30
10639 /* POOL16D encoding of minor opcode field */
10641 enum {
10642 ADDIUS5 = 0x0,
10643 ADDIUSP = 0x1
10646 /* POOL16E encoding of minor opcode field */
10648 enum {
10649 ADDIUR2 = 0x0,
10650 ADDIUR1SP = 0x1
10653 static int mmreg (int r)
10655 static const int map[] = { 16, 17, 2, 3, 4, 5, 6, 7 };
10657 return map[r];
10660 /* Used for 16-bit store instructions. */
10661 static int mmreg2 (int r)
10663 static const int map[] = { 0, 17, 2, 3, 4, 5, 6, 7 };
10665 return map[r];
10668 #define uMIPS_RD(op) ((op >> 7) & 0x7)
10669 #define uMIPS_RS(op) ((op >> 4) & 0x7)
10670 #define uMIPS_RS2(op) uMIPS_RS(op)
10671 #define uMIPS_RS1(op) ((op >> 1) & 0x7)
10672 #define uMIPS_RD5(op) ((op >> 5) & 0x1f)
10673 #define uMIPS_RS5(op) (op & 0x1f)
10675 /* Signed immediate */
10676 #define SIMM(op, start, width) \
10677 ((int32_t)(((op >> start) & ((~0U) >> (32-width))) \
10678 << (32-width)) \
10679 >> (32-width))
10680 /* Zero-extended immediate */
10681 #define ZIMM(op, start, width) ((op >> start) & ((~0U) >> (32-width)))
10683 static void gen_addiur1sp(DisasContext *ctx)
10685 int rd = mmreg(uMIPS_RD(ctx->opcode));
10687 gen_arith_imm(ctx, OPC_ADDIU, rd, 29, ((ctx->opcode >> 1) & 0x3f) << 2);
10690 static void gen_addiur2(DisasContext *ctx)
10692 static const int decoded_imm[] = { 1, 4, 8, 12, 16, 20, 24, -1 };
10693 int rd = mmreg(uMIPS_RD(ctx->opcode));
10694 int rs = mmreg(uMIPS_RS(ctx->opcode));
10696 gen_arith_imm(ctx, OPC_ADDIU, rd, rs, decoded_imm[ZIMM(ctx->opcode, 1, 3)]);
10699 static void gen_addiusp(DisasContext *ctx)
10701 int encoded = ZIMM(ctx->opcode, 1, 9);
10702 int decoded;
10704 if (encoded <= 1) {
10705 decoded = 256 + encoded;
10706 } else if (encoded <= 255) {
10707 decoded = encoded;
10708 } else if (encoded <= 509) {
10709 decoded = encoded - 512;
10710 } else {
10711 decoded = encoded - 768;
10714 gen_arith_imm(ctx, OPC_ADDIU, 29, 29, decoded << 2);
10717 static void gen_addius5(DisasContext *ctx)
10719 int imm = SIMM(ctx->opcode, 1, 4);
10720 int rd = (ctx->opcode >> 5) & 0x1f;
10722 gen_arith_imm(ctx, OPC_ADDIU, rd, rd, imm);
10725 static void gen_andi16(DisasContext *ctx)
10727 static const int decoded_imm[] = { 128, 1, 2, 3, 4, 7, 8, 15, 16,
10728 31, 32, 63, 64, 255, 32768, 65535 };
10729 int rd = mmreg(uMIPS_RD(ctx->opcode));
10730 int rs = mmreg(uMIPS_RS(ctx->opcode));
10731 int encoded = ZIMM(ctx->opcode, 0, 4);
10733 gen_logic_imm(ctx, OPC_ANDI, rd, rs, decoded_imm[encoded]);
10736 static void gen_ldst_multiple (DisasContext *ctx, uint32_t opc, int reglist,
10737 int base, int16_t offset)
10739 const char *opn = "ldst_multiple";
10740 TCGv t0, t1;
10741 TCGv_i32 t2;
10743 if (ctx->hflags & MIPS_HFLAG_BMASK) {
10744 generate_exception(ctx, EXCP_RI);
10745 return;
10748 t0 = tcg_temp_new();
10750 gen_base_offset_addr(ctx, t0, base, offset);
10752 t1 = tcg_const_tl(reglist);
10753 t2 = tcg_const_i32(ctx->mem_idx);
10755 save_cpu_state(ctx, 1);
10756 switch (opc) {
10757 case LWM32:
10758 gen_helper_lwm(cpu_env, t0, t1, t2);
10759 opn = "lwm";
10760 break;
10761 case SWM32:
10762 gen_helper_swm(cpu_env, t0, t1, t2);
10763 opn = "swm";
10764 break;
10765 #ifdef TARGET_MIPS64
10766 case LDM:
10767 gen_helper_ldm(cpu_env, t0, t1, t2);
10768 opn = "ldm";
10769 break;
10770 case SDM:
10771 gen_helper_sdm(cpu_env, t0, t1, t2);
10772 opn = "sdm";
10773 break;
10774 #endif
10776 (void)opn;
10777 MIPS_DEBUG("%s, %x, %d(%s)", opn, reglist, offset, regnames[base]);
10778 tcg_temp_free(t0);
10779 tcg_temp_free(t1);
10780 tcg_temp_free_i32(t2);
10784 static void gen_pool16c_insn(DisasContext *ctx)
10786 int rd = mmreg((ctx->opcode >> 3) & 0x7);
10787 int rs = mmreg(ctx->opcode & 0x7);
10788 int opc;
10790 switch (((ctx->opcode) >> 4) & 0x3f) {
10791 case NOT16 + 0:
10792 case NOT16 + 1:
10793 case NOT16 + 2:
10794 case NOT16 + 3:
10795 gen_logic(ctx, OPC_NOR, rd, rs, 0);
10796 break;
10797 case XOR16 + 0:
10798 case XOR16 + 1:
10799 case XOR16 + 2:
10800 case XOR16 + 3:
10801 gen_logic(ctx, OPC_XOR, rd, rd, rs);
10802 break;
10803 case AND16 + 0:
10804 case AND16 + 1:
10805 case AND16 + 2:
10806 case AND16 + 3:
10807 gen_logic(ctx, OPC_AND, rd, rd, rs);
10808 break;
10809 case OR16 + 0:
10810 case OR16 + 1:
10811 case OR16 + 2:
10812 case OR16 + 3:
10813 gen_logic(ctx, OPC_OR, rd, rd, rs);
10814 break;
10815 case LWM16 + 0:
10816 case LWM16 + 1:
10817 case LWM16 + 2:
10818 case LWM16 + 3:
10820 static const int lwm_convert[] = { 0x11, 0x12, 0x13, 0x14 };
10821 int offset = ZIMM(ctx->opcode, 0, 4);
10823 gen_ldst_multiple(ctx, LWM32, lwm_convert[(ctx->opcode >> 4) & 0x3],
10824 29, offset << 2);
10826 break;
10827 case SWM16 + 0:
10828 case SWM16 + 1:
10829 case SWM16 + 2:
10830 case SWM16 + 3:
10832 static const int swm_convert[] = { 0x11, 0x12, 0x13, 0x14 };
10833 int offset = ZIMM(ctx->opcode, 0, 4);
10835 gen_ldst_multiple(ctx, SWM32, swm_convert[(ctx->opcode >> 4) & 0x3],
10836 29, offset << 2);
10838 break;
10839 case JR16 + 0:
10840 case JR16 + 1:
10842 int reg = ctx->opcode & 0x1f;
10844 gen_compute_branch(ctx, OPC_JR, 2, reg, 0, 0);
10846 break;
10847 case JRC16 + 0:
10848 case JRC16 + 1:
10850 int reg = ctx->opcode & 0x1f;
10852 gen_compute_branch(ctx, OPC_JR, 2, reg, 0, 0);
10853 /* Let normal delay slot handling in our caller take us
10854 to the branch target. */
10856 break;
10857 case JALR16 + 0:
10858 case JALR16 + 1:
10859 opc = OPC_JALR;
10860 goto do_jalr;
10861 case JALR16S + 0:
10862 case JALR16S + 1:
10863 opc = OPC_JALRS;
10864 do_jalr:
10866 int reg = ctx->opcode & 0x1f;
10868 gen_compute_branch(ctx, opc, 2, reg, 31, 0);
10870 break;
10871 case MFHI16 + 0:
10872 case MFHI16 + 1:
10873 gen_HILO(ctx, OPC_MFHI, 0, uMIPS_RS5(ctx->opcode));
10874 break;
10875 case MFLO16 + 0:
10876 case MFLO16 + 1:
10877 gen_HILO(ctx, OPC_MFLO, 0, uMIPS_RS5(ctx->opcode));
10878 break;
10879 case BREAK16:
10880 generate_exception(ctx, EXCP_BREAK);
10881 break;
10882 case SDBBP16:
10883 /* XXX: not clear which exception should be raised
10884 * when in debug mode...
10886 check_insn(ctx, ISA_MIPS32);
10887 if (!(ctx->hflags & MIPS_HFLAG_DM)) {
10888 generate_exception(ctx, EXCP_DBp);
10889 } else {
10890 generate_exception(ctx, EXCP_DBp);
10892 break;
10893 case JRADDIUSP + 0:
10894 case JRADDIUSP + 1:
10896 int imm = ZIMM(ctx->opcode, 0, 5);
10898 gen_compute_branch(ctx, OPC_JR, 2, 31, 0, 0);
10899 gen_arith_imm(ctx, OPC_ADDIU, 29, 29, imm << 2);
10900 /* Let normal delay slot handling in our caller take us
10901 to the branch target. */
10903 break;
10904 default:
10905 generate_exception(ctx, EXCP_RI);
10906 break;
10910 static void gen_ldxs (DisasContext *ctx, int base, int index, int rd)
10912 TCGv t0 = tcg_temp_new();
10913 TCGv t1 = tcg_temp_new();
10915 gen_load_gpr(t0, base);
10917 if (index != 0) {
10918 gen_load_gpr(t1, index);
10919 tcg_gen_shli_tl(t1, t1, 2);
10920 gen_op_addr_add(ctx, t0, t1, t0);
10923 tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_TESL);
10924 gen_store_gpr(t1, rd);
10926 tcg_temp_free(t0);
10927 tcg_temp_free(t1);
10930 static void gen_ldst_pair (DisasContext *ctx, uint32_t opc, int rd,
10931 int base, int16_t offset)
10933 const char *opn = "ldst_pair";
10934 TCGv t0, t1;
10936 if (ctx->hflags & MIPS_HFLAG_BMASK || rd == 31) {
10937 generate_exception(ctx, EXCP_RI);
10938 return;
10941 t0 = tcg_temp_new();
10942 t1 = tcg_temp_new();
10944 gen_base_offset_addr(ctx, t0, base, offset);
10946 switch (opc) {
10947 case LWP:
10948 if (rd == base) {
10949 generate_exception(ctx, EXCP_RI);
10950 return;
10952 tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_TESL);
10953 gen_store_gpr(t1, rd);
10954 tcg_gen_movi_tl(t1, 4);
10955 gen_op_addr_add(ctx, t0, t0, t1);
10956 tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_TESL);
10957 gen_store_gpr(t1, rd+1);
10958 opn = "lwp";
10959 break;
10960 case SWP:
10961 gen_load_gpr(t1, rd);
10962 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL);
10963 tcg_gen_movi_tl(t1, 4);
10964 gen_op_addr_add(ctx, t0, t0, t1);
10965 gen_load_gpr(t1, rd+1);
10966 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL);
10967 opn = "swp";
10968 break;
10969 #ifdef TARGET_MIPS64
10970 case LDP:
10971 if (rd == base) {
10972 generate_exception(ctx, EXCP_RI);
10973 return;
10975 tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_TEQ);
10976 gen_store_gpr(t1, rd);
10977 tcg_gen_movi_tl(t1, 8);
10978 gen_op_addr_add(ctx, t0, t0, t1);
10979 tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_TEQ);
10980 gen_store_gpr(t1, rd+1);
10981 opn = "ldp";
10982 break;
10983 case SDP:
10984 gen_load_gpr(t1, rd);
10985 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEQ);
10986 tcg_gen_movi_tl(t1, 8);
10987 gen_op_addr_add(ctx, t0, t0, t1);
10988 gen_load_gpr(t1, rd+1);
10989 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEQ);
10990 opn = "sdp";
10991 break;
10992 #endif
10994 (void)opn; /* avoid a compiler warning */
10995 MIPS_DEBUG("%s, %s, %d(%s)", opn, regnames[rd], offset, regnames[base]);
10996 tcg_temp_free(t0);
10997 tcg_temp_free(t1);
11000 static void gen_pool32axf (CPUMIPSState *env, DisasContext *ctx, int rt, int rs)
11002 int extension = (ctx->opcode >> 6) & 0x3f;
11003 int minor = (ctx->opcode >> 12) & 0xf;
11004 uint32_t mips32_op;
11006 switch (extension) {
11007 case TEQ:
11008 mips32_op = OPC_TEQ;
11009 goto do_trap;
11010 case TGE:
11011 mips32_op = OPC_TGE;
11012 goto do_trap;
11013 case TGEU:
11014 mips32_op = OPC_TGEU;
11015 goto do_trap;
11016 case TLT:
11017 mips32_op = OPC_TLT;
11018 goto do_trap;
11019 case TLTU:
11020 mips32_op = OPC_TLTU;
11021 goto do_trap;
11022 case TNE:
11023 mips32_op = OPC_TNE;
11024 do_trap:
11025 gen_trap(ctx, mips32_op, rs, rt, -1);
11026 break;
11027 #ifndef CONFIG_USER_ONLY
11028 case MFC0:
11029 case MFC0 + 32:
11030 check_cp0_enabled(ctx);
11031 if (rt == 0) {
11032 /* Treat as NOP. */
11033 break;
11035 gen_mfc0(ctx, cpu_gpr[rt], rs, (ctx->opcode >> 11) & 0x7);
11036 break;
11037 case MTC0:
11038 case MTC0 + 32:
11039 check_cp0_enabled(ctx);
11041 TCGv t0 = tcg_temp_new();
11043 gen_load_gpr(t0, rt);
11044 gen_mtc0(ctx, t0, rs, (ctx->opcode >> 11) & 0x7);
11045 tcg_temp_free(t0);
11047 break;
11048 #endif
11049 case 0x2a:
11050 switch (minor & 3) {
11051 case MADD_ACC:
11052 gen_muldiv(ctx, OPC_MADD, (ctx->opcode >> 14) & 3, rs, rt);
11053 break;
11054 case MADDU_ACC:
11055 gen_muldiv(ctx, OPC_MADDU, (ctx->opcode >> 14) & 3, rs, rt);
11056 break;
11057 case MSUB_ACC:
11058 gen_muldiv(ctx, OPC_MSUB, (ctx->opcode >> 14) & 3, rs, rt);
11059 break;
11060 case MSUBU_ACC:
11061 gen_muldiv(ctx, OPC_MSUBU, (ctx->opcode >> 14) & 3, rs, rt);
11062 break;
11063 default:
11064 goto pool32axf_invalid;
11066 break;
11067 case 0x32:
11068 switch (minor & 3) {
11069 case MULT_ACC:
11070 gen_muldiv(ctx, OPC_MULT, (ctx->opcode >> 14) & 3, rs, rt);
11071 break;
11072 case MULTU_ACC:
11073 gen_muldiv(ctx, OPC_MULTU, (ctx->opcode >> 14) & 3, rs, rt);
11074 break;
11075 default:
11076 goto pool32axf_invalid;
11078 break;
11079 case 0x2c:
11080 switch (minor) {
11081 case SEB:
11082 gen_bshfl(ctx, OPC_SEB, rs, rt);
11083 break;
11084 case SEH:
11085 gen_bshfl(ctx, OPC_SEH, rs, rt);
11086 break;
11087 case CLO:
11088 mips32_op = OPC_CLO;
11089 goto do_cl;
11090 case CLZ:
11091 mips32_op = OPC_CLZ;
11092 do_cl:
11093 check_insn(ctx, ISA_MIPS32);
11094 gen_cl(ctx, mips32_op, rt, rs);
11095 break;
11096 case RDHWR:
11097 gen_rdhwr(ctx, rt, rs);
11098 break;
11099 case WSBH:
11100 gen_bshfl(ctx, OPC_WSBH, rs, rt);
11101 break;
11102 case MULT:
11103 mips32_op = OPC_MULT;
11104 goto do_mul;
11105 case MULTU:
11106 mips32_op = OPC_MULTU;
11107 goto do_mul;
11108 case DIV:
11109 mips32_op = OPC_DIV;
11110 goto do_div;
11111 case DIVU:
11112 mips32_op = OPC_DIVU;
11113 goto do_div;
11114 do_div:
11115 check_insn(ctx, ISA_MIPS32);
11116 gen_muldiv(ctx, mips32_op, 0, rs, rt);
11117 break;
11118 case MADD:
11119 mips32_op = OPC_MADD;
11120 goto do_mul;
11121 case MADDU:
11122 mips32_op = OPC_MADDU;
11123 goto do_mul;
11124 case MSUB:
11125 mips32_op = OPC_MSUB;
11126 goto do_mul;
11127 case MSUBU:
11128 mips32_op = OPC_MSUBU;
11129 do_mul:
11130 check_insn(ctx, ISA_MIPS32);
11131 gen_muldiv(ctx, mips32_op, 0, rs, rt);
11132 break;
11133 default:
11134 goto pool32axf_invalid;
11136 break;
11137 case 0x34:
11138 switch (minor) {
11139 case MFC2:
11140 case MTC2:
11141 case MFHC2:
11142 case MTHC2:
11143 case CFC2:
11144 case CTC2:
11145 generate_exception_err(ctx, EXCP_CpU, 2);
11146 break;
11147 default:
11148 goto pool32axf_invalid;
11150 break;
11151 case 0x3c:
11152 switch (minor) {
11153 case JALR:
11154 case JALR_HB:
11155 gen_compute_branch (ctx, OPC_JALR, 4, rs, rt, 0);
11156 break;
11157 case JALRS:
11158 case JALRS_HB:
11159 gen_compute_branch (ctx, OPC_JALRS, 4, rs, rt, 0);
11160 break;
11161 default:
11162 goto pool32axf_invalid;
11164 break;
11165 case 0x05:
11166 switch (minor) {
11167 case RDPGPR:
11168 check_cp0_enabled(ctx);
11169 check_insn(ctx, ISA_MIPS32R2);
11170 gen_load_srsgpr(rt, rs);
11171 break;
11172 case WRPGPR:
11173 check_cp0_enabled(ctx);
11174 check_insn(ctx, ISA_MIPS32R2);
11175 gen_store_srsgpr(rt, rs);
11176 break;
11177 default:
11178 goto pool32axf_invalid;
11180 break;
11181 #ifndef CONFIG_USER_ONLY
11182 case 0x0d:
11183 switch (minor) {
11184 case TLBP:
11185 mips32_op = OPC_TLBP;
11186 goto do_cp0;
11187 case TLBR:
11188 mips32_op = OPC_TLBR;
11189 goto do_cp0;
11190 case TLBWI:
11191 mips32_op = OPC_TLBWI;
11192 goto do_cp0;
11193 case TLBWR:
11194 mips32_op = OPC_TLBWR;
11195 goto do_cp0;
11196 case WAIT:
11197 mips32_op = OPC_WAIT;
11198 goto do_cp0;
11199 case DERET:
11200 mips32_op = OPC_DERET;
11201 goto do_cp0;
11202 case ERET:
11203 mips32_op = OPC_ERET;
11204 do_cp0:
11205 gen_cp0(env, ctx, mips32_op, rt, rs);
11206 break;
11207 default:
11208 goto pool32axf_invalid;
11210 break;
11211 case 0x1d:
11212 switch (minor) {
11213 case DI:
11214 check_cp0_enabled(ctx);
11216 TCGv t0 = tcg_temp_new();
11218 save_cpu_state(ctx, 1);
11219 gen_helper_di(t0, cpu_env);
11220 gen_store_gpr(t0, rs);
11221 /* Stop translation as we may have switched the execution mode */
11222 ctx->bstate = BS_STOP;
11223 tcg_temp_free(t0);
11225 break;
11226 case EI:
11227 check_cp0_enabled(ctx);
11229 TCGv t0 = tcg_temp_new();
11231 save_cpu_state(ctx, 1);
11232 gen_helper_ei(t0, cpu_env);
11233 gen_store_gpr(t0, rs);
11234 /* Stop translation as we may have switched the execution mode */
11235 ctx->bstate = BS_STOP;
11236 tcg_temp_free(t0);
11238 break;
11239 default:
11240 goto pool32axf_invalid;
11242 break;
11243 #endif
11244 case 0x2d:
11245 switch (minor) {
11246 case SYNC:
11247 /* NOP */
11248 break;
11249 case SYSCALL:
11250 generate_exception(ctx, EXCP_SYSCALL);
11251 ctx->bstate = BS_STOP;
11252 break;
11253 case SDBBP:
11254 check_insn(ctx, ISA_MIPS32);
11255 if (!(ctx->hflags & MIPS_HFLAG_DM)) {
11256 generate_exception(ctx, EXCP_DBp);
11257 } else {
11258 generate_exception(ctx, EXCP_DBp);
11260 break;
11261 default:
11262 goto pool32axf_invalid;
11264 break;
11265 case 0x01:
11266 switch (minor & 3) {
11267 case MFHI_ACC:
11268 gen_HILO(ctx, OPC_MFHI, minor >> 2, rs);
11269 break;
11270 case MFLO_ACC:
11271 gen_HILO(ctx, OPC_MFLO, minor >> 2, rs);
11272 break;
11273 case MTHI_ACC:
11274 gen_HILO(ctx, OPC_MTHI, minor >> 2, rs);
11275 break;
11276 case MTLO_ACC:
11277 gen_HILO(ctx, OPC_MTLO, minor >> 2, rs);
11278 break;
11279 default:
11280 goto pool32axf_invalid;
11282 break;
11283 case 0x35:
11284 switch (minor) {
11285 case MFHI32:
11286 gen_HILO(ctx, OPC_MFHI, 0, rs);
11287 break;
11288 case MFLO32:
11289 gen_HILO(ctx, OPC_MFLO, 0, rs);
11290 break;
11291 case MTHI32:
11292 gen_HILO(ctx, OPC_MTHI, 0, rs);
11293 break;
11294 case MTLO32:
11295 gen_HILO(ctx, OPC_MTLO, 0, rs);
11296 break;
11297 default:
11298 goto pool32axf_invalid;
11300 break;
11301 default:
11302 pool32axf_invalid:
11303 MIPS_INVAL("pool32axf");
11304 generate_exception(ctx, EXCP_RI);
11305 break;
11309 /* Values for microMIPS fmt field. Variable-width, depending on which
11310 formats the instruction supports. */
11312 enum {
11313 FMT_SD_S = 0,
11314 FMT_SD_D = 1,
11316 FMT_SDPS_S = 0,
11317 FMT_SDPS_D = 1,
11318 FMT_SDPS_PS = 2,
11320 FMT_SWL_S = 0,
11321 FMT_SWL_W = 1,
11322 FMT_SWL_L = 2,
11324 FMT_DWL_D = 0,
11325 FMT_DWL_W = 1,
11326 FMT_DWL_L = 2
11329 static void gen_pool32fxf(DisasContext *ctx, int rt, int rs)
11331 int extension = (ctx->opcode >> 6) & 0x3ff;
11332 uint32_t mips32_op;
11334 #define FLOAT_1BIT_FMT(opc, fmt) (fmt << 8) | opc
11335 #define FLOAT_2BIT_FMT(opc, fmt) (fmt << 7) | opc
11336 #define COND_FLOAT_MOV(opc, cond) (cond << 7) | opc
11338 switch (extension) {
11339 case FLOAT_1BIT_FMT(CFC1, 0):
11340 mips32_op = OPC_CFC1;
11341 goto do_cp1;
11342 case FLOAT_1BIT_FMT(CTC1, 0):
11343 mips32_op = OPC_CTC1;
11344 goto do_cp1;
11345 case FLOAT_1BIT_FMT(MFC1, 0):
11346 mips32_op = OPC_MFC1;
11347 goto do_cp1;
11348 case FLOAT_1BIT_FMT(MTC1, 0):
11349 mips32_op = OPC_MTC1;
11350 goto do_cp1;
11351 case FLOAT_1BIT_FMT(MFHC1, 0):
11352 mips32_op = OPC_MFHC1;
11353 goto do_cp1;
11354 case FLOAT_1BIT_FMT(MTHC1, 0):
11355 mips32_op = OPC_MTHC1;
11356 do_cp1:
11357 gen_cp1(ctx, mips32_op, rt, rs);
11358 break;
11360 /* Reciprocal square root */
11361 case FLOAT_1BIT_FMT(RSQRT_FMT, FMT_SD_S):
11362 mips32_op = OPC_RSQRT_S;
11363 goto do_unaryfp;
11364 case FLOAT_1BIT_FMT(RSQRT_FMT, FMT_SD_D):
11365 mips32_op = OPC_RSQRT_D;
11366 goto do_unaryfp;
11368 /* Square root */
11369 case FLOAT_1BIT_FMT(SQRT_FMT, FMT_SD_S):
11370 mips32_op = OPC_SQRT_S;
11371 goto do_unaryfp;
11372 case FLOAT_1BIT_FMT(SQRT_FMT, FMT_SD_D):
11373 mips32_op = OPC_SQRT_D;
11374 goto do_unaryfp;
11376 /* Reciprocal */
11377 case FLOAT_1BIT_FMT(RECIP_FMT, FMT_SD_S):
11378 mips32_op = OPC_RECIP_S;
11379 goto do_unaryfp;
11380 case FLOAT_1BIT_FMT(RECIP_FMT, FMT_SD_D):
11381 mips32_op = OPC_RECIP_D;
11382 goto do_unaryfp;
11384 /* Floor */
11385 case FLOAT_1BIT_FMT(FLOOR_L, FMT_SD_S):
11386 mips32_op = OPC_FLOOR_L_S;
11387 goto do_unaryfp;
11388 case FLOAT_1BIT_FMT(FLOOR_L, FMT_SD_D):
11389 mips32_op = OPC_FLOOR_L_D;
11390 goto do_unaryfp;
11391 case FLOAT_1BIT_FMT(FLOOR_W, FMT_SD_S):
11392 mips32_op = OPC_FLOOR_W_S;
11393 goto do_unaryfp;
11394 case FLOAT_1BIT_FMT(FLOOR_W, FMT_SD_D):
11395 mips32_op = OPC_FLOOR_W_D;
11396 goto do_unaryfp;
11398 /* Ceiling */
11399 case FLOAT_1BIT_FMT(CEIL_L, FMT_SD_S):
11400 mips32_op = OPC_CEIL_L_S;
11401 goto do_unaryfp;
11402 case FLOAT_1BIT_FMT(CEIL_L, FMT_SD_D):
11403 mips32_op = OPC_CEIL_L_D;
11404 goto do_unaryfp;
11405 case FLOAT_1BIT_FMT(CEIL_W, FMT_SD_S):
11406 mips32_op = OPC_CEIL_W_S;
11407 goto do_unaryfp;
11408 case FLOAT_1BIT_FMT(CEIL_W, FMT_SD_D):
11409 mips32_op = OPC_CEIL_W_D;
11410 goto do_unaryfp;
11412 /* Truncation */
11413 case FLOAT_1BIT_FMT(TRUNC_L, FMT_SD_S):
11414 mips32_op = OPC_TRUNC_L_S;
11415 goto do_unaryfp;
11416 case FLOAT_1BIT_FMT(TRUNC_L, FMT_SD_D):
11417 mips32_op = OPC_TRUNC_L_D;
11418 goto do_unaryfp;
11419 case FLOAT_1BIT_FMT(TRUNC_W, FMT_SD_S):
11420 mips32_op = OPC_TRUNC_W_S;
11421 goto do_unaryfp;
11422 case FLOAT_1BIT_FMT(TRUNC_W, FMT_SD_D):
11423 mips32_op = OPC_TRUNC_W_D;
11424 goto do_unaryfp;
11426 /* Round */
11427 case FLOAT_1BIT_FMT(ROUND_L, FMT_SD_S):
11428 mips32_op = OPC_ROUND_L_S;
11429 goto do_unaryfp;
11430 case FLOAT_1BIT_FMT(ROUND_L, FMT_SD_D):
11431 mips32_op = OPC_ROUND_L_D;
11432 goto do_unaryfp;
11433 case FLOAT_1BIT_FMT(ROUND_W, FMT_SD_S):
11434 mips32_op = OPC_ROUND_W_S;
11435 goto do_unaryfp;
11436 case FLOAT_1BIT_FMT(ROUND_W, FMT_SD_D):
11437 mips32_op = OPC_ROUND_W_D;
11438 goto do_unaryfp;
11440 /* Integer to floating-point conversion */
11441 case FLOAT_1BIT_FMT(CVT_L, FMT_SD_S):
11442 mips32_op = OPC_CVT_L_S;
11443 goto do_unaryfp;
11444 case FLOAT_1BIT_FMT(CVT_L, FMT_SD_D):
11445 mips32_op = OPC_CVT_L_D;
11446 goto do_unaryfp;
11447 case FLOAT_1BIT_FMT(CVT_W, FMT_SD_S):
11448 mips32_op = OPC_CVT_W_S;
11449 goto do_unaryfp;
11450 case FLOAT_1BIT_FMT(CVT_W, FMT_SD_D):
11451 mips32_op = OPC_CVT_W_D;
11452 goto do_unaryfp;
11454 /* Paired-foo conversions */
11455 case FLOAT_1BIT_FMT(CVT_S_PL, 0):
11456 mips32_op = OPC_CVT_S_PL;
11457 goto do_unaryfp;
11458 case FLOAT_1BIT_FMT(CVT_S_PU, 0):
11459 mips32_op = OPC_CVT_S_PU;
11460 goto do_unaryfp;
11461 case FLOAT_1BIT_FMT(CVT_PW_PS, 0):
11462 mips32_op = OPC_CVT_PW_PS;
11463 goto do_unaryfp;
11464 case FLOAT_1BIT_FMT(CVT_PS_PW, 0):
11465 mips32_op = OPC_CVT_PS_PW;
11466 goto do_unaryfp;
11468 /* Floating-point moves */
11469 case FLOAT_2BIT_FMT(MOV_FMT, FMT_SDPS_S):
11470 mips32_op = OPC_MOV_S;
11471 goto do_unaryfp;
11472 case FLOAT_2BIT_FMT(MOV_FMT, FMT_SDPS_D):
11473 mips32_op = OPC_MOV_D;
11474 goto do_unaryfp;
11475 case FLOAT_2BIT_FMT(MOV_FMT, FMT_SDPS_PS):
11476 mips32_op = OPC_MOV_PS;
11477 goto do_unaryfp;
11479 /* Absolute value */
11480 case FLOAT_2BIT_FMT(ABS_FMT, FMT_SDPS_S):
11481 mips32_op = OPC_ABS_S;
11482 goto do_unaryfp;
11483 case FLOAT_2BIT_FMT(ABS_FMT, FMT_SDPS_D):
11484 mips32_op = OPC_ABS_D;
11485 goto do_unaryfp;
11486 case FLOAT_2BIT_FMT(ABS_FMT, FMT_SDPS_PS):
11487 mips32_op = OPC_ABS_PS;
11488 goto do_unaryfp;
11490 /* Negation */
11491 case FLOAT_2BIT_FMT(NEG_FMT, FMT_SDPS_S):
11492 mips32_op = OPC_NEG_S;
11493 goto do_unaryfp;
11494 case FLOAT_2BIT_FMT(NEG_FMT, FMT_SDPS_D):
11495 mips32_op = OPC_NEG_D;
11496 goto do_unaryfp;
11497 case FLOAT_2BIT_FMT(NEG_FMT, FMT_SDPS_PS):
11498 mips32_op = OPC_NEG_PS;
11499 goto do_unaryfp;
11501 /* Reciprocal square root step */
11502 case FLOAT_2BIT_FMT(RSQRT1_FMT, FMT_SDPS_S):
11503 mips32_op = OPC_RSQRT1_S;
11504 goto do_unaryfp;
11505 case FLOAT_2BIT_FMT(RSQRT1_FMT, FMT_SDPS_D):
11506 mips32_op = OPC_RSQRT1_D;
11507 goto do_unaryfp;
11508 case FLOAT_2BIT_FMT(RSQRT1_FMT, FMT_SDPS_PS):
11509 mips32_op = OPC_RSQRT1_PS;
11510 goto do_unaryfp;
11512 /* Reciprocal step */
11513 case FLOAT_2BIT_FMT(RECIP1_FMT, FMT_SDPS_S):
11514 mips32_op = OPC_RECIP1_S;
11515 goto do_unaryfp;
11516 case FLOAT_2BIT_FMT(RECIP1_FMT, FMT_SDPS_D):
11517 mips32_op = OPC_RECIP1_S;
11518 goto do_unaryfp;
11519 case FLOAT_2BIT_FMT(RECIP1_FMT, FMT_SDPS_PS):
11520 mips32_op = OPC_RECIP1_PS;
11521 goto do_unaryfp;
11523 /* Conversions from double */
11524 case FLOAT_2BIT_FMT(CVT_D, FMT_SWL_S):
11525 mips32_op = OPC_CVT_D_S;
11526 goto do_unaryfp;
11527 case FLOAT_2BIT_FMT(CVT_D, FMT_SWL_W):
11528 mips32_op = OPC_CVT_D_W;
11529 goto do_unaryfp;
11530 case FLOAT_2BIT_FMT(CVT_D, FMT_SWL_L):
11531 mips32_op = OPC_CVT_D_L;
11532 goto do_unaryfp;
11534 /* Conversions from single */
11535 case FLOAT_2BIT_FMT(CVT_S, FMT_DWL_D):
11536 mips32_op = OPC_CVT_S_D;
11537 goto do_unaryfp;
11538 case FLOAT_2BIT_FMT(CVT_S, FMT_DWL_W):
11539 mips32_op = OPC_CVT_S_W;
11540 goto do_unaryfp;
11541 case FLOAT_2BIT_FMT(CVT_S, FMT_DWL_L):
11542 mips32_op = OPC_CVT_S_L;
11543 do_unaryfp:
11544 gen_farith(ctx, mips32_op, -1, rs, rt, 0);
11545 break;
11547 /* Conditional moves on floating-point codes */
11548 case COND_FLOAT_MOV(MOVT, 0):
11549 case COND_FLOAT_MOV(MOVT, 1):
11550 case COND_FLOAT_MOV(MOVT, 2):
11551 case COND_FLOAT_MOV(MOVT, 3):
11552 case COND_FLOAT_MOV(MOVT, 4):
11553 case COND_FLOAT_MOV(MOVT, 5):
11554 case COND_FLOAT_MOV(MOVT, 6):
11555 case COND_FLOAT_MOV(MOVT, 7):
11556 gen_movci(ctx, rt, rs, (ctx->opcode >> 13) & 0x7, 1);
11557 break;
11558 case COND_FLOAT_MOV(MOVF, 0):
11559 case COND_FLOAT_MOV(MOVF, 1):
11560 case COND_FLOAT_MOV(MOVF, 2):
11561 case COND_FLOAT_MOV(MOVF, 3):
11562 case COND_FLOAT_MOV(MOVF, 4):
11563 case COND_FLOAT_MOV(MOVF, 5):
11564 case COND_FLOAT_MOV(MOVF, 6):
11565 case COND_FLOAT_MOV(MOVF, 7):
11566 gen_movci(ctx, rt, rs, (ctx->opcode >> 13) & 0x7, 0);
11567 break;
11568 default:
11569 MIPS_INVAL("pool32fxf");
11570 generate_exception(ctx, EXCP_RI);
11571 break;
11575 static void decode_micromips32_opc (CPUMIPSState *env, DisasContext *ctx,
11576 uint16_t insn_hw1)
11578 int32_t offset;
11579 uint16_t insn;
11580 int rt, rs, rd, rr;
11581 int16_t imm;
11582 uint32_t op, minor, mips32_op;
11583 uint32_t cond, fmt, cc;
11585 insn = cpu_lduw_code(env, ctx->pc + 2);
11586 ctx->opcode = (ctx->opcode << 16) | insn;
11588 rt = (ctx->opcode >> 21) & 0x1f;
11589 rs = (ctx->opcode >> 16) & 0x1f;
11590 rd = (ctx->opcode >> 11) & 0x1f;
11591 rr = (ctx->opcode >> 6) & 0x1f;
11592 imm = (int16_t) ctx->opcode;
11594 op = (ctx->opcode >> 26) & 0x3f;
11595 switch (op) {
11596 case POOL32A:
11597 minor = ctx->opcode & 0x3f;
11598 switch (minor) {
11599 case 0x00:
11600 minor = (ctx->opcode >> 6) & 0xf;
11601 switch (minor) {
11602 case SLL32:
11603 mips32_op = OPC_SLL;
11604 goto do_shifti;
11605 case SRA:
11606 mips32_op = OPC_SRA;
11607 goto do_shifti;
11608 case SRL32:
11609 mips32_op = OPC_SRL;
11610 goto do_shifti;
11611 case ROTR:
11612 mips32_op = OPC_ROTR;
11613 do_shifti:
11614 gen_shift_imm(ctx, mips32_op, rt, rs, rd);
11615 break;
11616 default:
11617 goto pool32a_invalid;
11619 break;
11620 case 0x10:
11621 minor = (ctx->opcode >> 6) & 0xf;
11622 switch (minor) {
11623 /* Arithmetic */
11624 case ADD:
11625 mips32_op = OPC_ADD;
11626 goto do_arith;
11627 case ADDU32:
11628 mips32_op = OPC_ADDU;
11629 goto do_arith;
11630 case SUB:
11631 mips32_op = OPC_SUB;
11632 goto do_arith;
11633 case SUBU32:
11634 mips32_op = OPC_SUBU;
11635 goto do_arith;
11636 case MUL:
11637 mips32_op = OPC_MUL;
11638 do_arith:
11639 gen_arith(ctx, mips32_op, rd, rs, rt);
11640 break;
11641 /* Shifts */
11642 case SLLV:
11643 mips32_op = OPC_SLLV;
11644 goto do_shift;
11645 case SRLV:
11646 mips32_op = OPC_SRLV;
11647 goto do_shift;
11648 case SRAV:
11649 mips32_op = OPC_SRAV;
11650 goto do_shift;
11651 case ROTRV:
11652 mips32_op = OPC_ROTRV;
11653 do_shift:
11654 gen_shift(ctx, mips32_op, rd, rs, rt);
11655 break;
11656 /* Logical operations */
11657 case AND:
11658 mips32_op = OPC_AND;
11659 goto do_logic;
11660 case OR32:
11661 mips32_op = OPC_OR;
11662 goto do_logic;
11663 case NOR:
11664 mips32_op = OPC_NOR;
11665 goto do_logic;
11666 case XOR32:
11667 mips32_op = OPC_XOR;
11668 do_logic:
11669 gen_logic(ctx, mips32_op, rd, rs, rt);
11670 break;
11671 /* Set less than */
11672 case SLT:
11673 mips32_op = OPC_SLT;
11674 goto do_slt;
11675 case SLTU:
11676 mips32_op = OPC_SLTU;
11677 do_slt:
11678 gen_slt(ctx, mips32_op, rd, rs, rt);
11679 break;
11680 default:
11681 goto pool32a_invalid;
11683 break;
11684 case 0x18:
11685 minor = (ctx->opcode >> 6) & 0xf;
11686 switch (minor) {
11687 /* Conditional moves */
11688 case MOVN:
11689 mips32_op = OPC_MOVN;
11690 goto do_cmov;
11691 case MOVZ:
11692 mips32_op = OPC_MOVZ;
11693 do_cmov:
11694 gen_cond_move(ctx, mips32_op, rd, rs, rt);
11695 break;
11696 case LWXS:
11697 gen_ldxs(ctx, rs, rt, rd);
11698 break;
11699 default:
11700 goto pool32a_invalid;
11702 break;
11703 case INS:
11704 gen_bitops(ctx, OPC_INS, rt, rs, rr, rd);
11705 return;
11706 case EXT:
11707 gen_bitops(ctx, OPC_EXT, rt, rs, rr, rd);
11708 return;
11709 case POOL32AXF:
11710 gen_pool32axf(env, ctx, rt, rs);
11711 break;
11712 case 0x07:
11713 generate_exception(ctx, EXCP_BREAK);
11714 break;
11715 default:
11716 pool32a_invalid:
11717 MIPS_INVAL("pool32a");
11718 generate_exception(ctx, EXCP_RI);
11719 break;
11721 break;
11722 case POOL32B:
11723 minor = (ctx->opcode >> 12) & 0xf;
11724 switch (minor) {
11725 case CACHE:
11726 check_cp0_enabled(ctx);
11727 /* Treat as no-op. */
11728 break;
11729 case LWC2:
11730 case SWC2:
11731 /* COP2: Not implemented. */
11732 generate_exception_err(ctx, EXCP_CpU, 2);
11733 break;
11734 case LWP:
11735 case SWP:
11736 #ifdef TARGET_MIPS64
11737 case LDP:
11738 case SDP:
11739 #endif
11740 gen_ldst_pair(ctx, minor, rt, rs, SIMM(ctx->opcode, 0, 12));
11741 break;
11742 case LWM32:
11743 case SWM32:
11744 #ifdef TARGET_MIPS64
11745 case LDM:
11746 case SDM:
11747 #endif
11748 gen_ldst_multiple(ctx, minor, rt, rs, SIMM(ctx->opcode, 0, 12));
11749 break;
11750 default:
11751 MIPS_INVAL("pool32b");
11752 generate_exception(ctx, EXCP_RI);
11753 break;
11755 break;
11756 case POOL32F:
11757 if (env->CP0_Config1 & (1 << CP0C1_FP)) {
11758 minor = ctx->opcode & 0x3f;
11759 check_cp1_enabled(ctx);
11760 switch (minor) {
11761 case ALNV_PS:
11762 mips32_op = OPC_ALNV_PS;
11763 goto do_madd;
11764 case MADD_S:
11765 mips32_op = OPC_MADD_S;
11766 goto do_madd;
11767 case MADD_D:
11768 mips32_op = OPC_MADD_D;
11769 goto do_madd;
11770 case MADD_PS:
11771 mips32_op = OPC_MADD_PS;
11772 goto do_madd;
11773 case MSUB_S:
11774 mips32_op = OPC_MSUB_S;
11775 goto do_madd;
11776 case MSUB_D:
11777 mips32_op = OPC_MSUB_D;
11778 goto do_madd;
11779 case MSUB_PS:
11780 mips32_op = OPC_MSUB_PS;
11781 goto do_madd;
11782 case NMADD_S:
11783 mips32_op = OPC_NMADD_S;
11784 goto do_madd;
11785 case NMADD_D:
11786 mips32_op = OPC_NMADD_D;
11787 goto do_madd;
11788 case NMADD_PS:
11789 mips32_op = OPC_NMADD_PS;
11790 goto do_madd;
11791 case NMSUB_S:
11792 mips32_op = OPC_NMSUB_S;
11793 goto do_madd;
11794 case NMSUB_D:
11795 mips32_op = OPC_NMSUB_D;
11796 goto do_madd;
11797 case NMSUB_PS:
11798 mips32_op = OPC_NMSUB_PS;
11799 do_madd:
11800 gen_flt3_arith(ctx, mips32_op, rd, rr, rs, rt);
11801 break;
11802 case CABS_COND_FMT:
11803 cond = (ctx->opcode >> 6) & 0xf;
11804 cc = (ctx->opcode >> 13) & 0x7;
11805 fmt = (ctx->opcode >> 10) & 0x3;
11806 switch (fmt) {
11807 case 0x0:
11808 gen_cmpabs_s(ctx, cond, rt, rs, cc);
11809 break;
11810 case 0x1:
11811 gen_cmpabs_d(ctx, cond, rt, rs, cc);
11812 break;
11813 case 0x2:
11814 gen_cmpabs_ps(ctx, cond, rt, rs, cc);
11815 break;
11816 default:
11817 goto pool32f_invalid;
11819 break;
11820 case C_COND_FMT:
11821 cond = (ctx->opcode >> 6) & 0xf;
11822 cc = (ctx->opcode >> 13) & 0x7;
11823 fmt = (ctx->opcode >> 10) & 0x3;
11824 switch (fmt) {
11825 case 0x0:
11826 gen_cmp_s(ctx, cond, rt, rs, cc);
11827 break;
11828 case 0x1:
11829 gen_cmp_d(ctx, cond, rt, rs, cc);
11830 break;
11831 case 0x2:
11832 gen_cmp_ps(ctx, cond, rt, rs, cc);
11833 break;
11834 default:
11835 goto pool32f_invalid;
11837 break;
11838 case POOL32FXF:
11839 gen_pool32fxf(ctx, rt, rs);
11840 break;
11841 case 0x00:
11842 /* PLL foo */
11843 switch ((ctx->opcode >> 6) & 0x7) {
11844 case PLL_PS:
11845 mips32_op = OPC_PLL_PS;
11846 goto do_ps;
11847 case PLU_PS:
11848 mips32_op = OPC_PLU_PS;
11849 goto do_ps;
11850 case PUL_PS:
11851 mips32_op = OPC_PUL_PS;
11852 goto do_ps;
11853 case PUU_PS:
11854 mips32_op = OPC_PUU_PS;
11855 goto do_ps;
11856 case CVT_PS_S:
11857 mips32_op = OPC_CVT_PS_S;
11858 do_ps:
11859 gen_farith(ctx, mips32_op, rt, rs, rd, 0);
11860 break;
11861 default:
11862 goto pool32f_invalid;
11864 break;
11865 case 0x08:
11866 /* [LS][WDU]XC1 */
11867 switch ((ctx->opcode >> 6) & 0x7) {
11868 case LWXC1:
11869 mips32_op = OPC_LWXC1;
11870 goto do_ldst_cp1;
11871 case SWXC1:
11872 mips32_op = OPC_SWXC1;
11873 goto do_ldst_cp1;
11874 case LDXC1:
11875 mips32_op = OPC_LDXC1;
11876 goto do_ldst_cp1;
11877 case SDXC1:
11878 mips32_op = OPC_SDXC1;
11879 goto do_ldst_cp1;
11880 case LUXC1:
11881 mips32_op = OPC_LUXC1;
11882 goto do_ldst_cp1;
11883 case SUXC1:
11884 mips32_op = OPC_SUXC1;
11885 do_ldst_cp1:
11886 gen_flt3_ldst(ctx, mips32_op, rd, rd, rt, rs);
11887 break;
11888 default:
11889 goto pool32f_invalid;
11891 break;
11892 case 0x18:
11893 /* 3D insns */
11894 fmt = (ctx->opcode >> 9) & 0x3;
11895 switch ((ctx->opcode >> 6) & 0x7) {
11896 case RSQRT2_FMT:
11897 switch (fmt) {
11898 case FMT_SDPS_S:
11899 mips32_op = OPC_RSQRT2_S;
11900 goto do_3d;
11901 case FMT_SDPS_D:
11902 mips32_op = OPC_RSQRT2_D;
11903 goto do_3d;
11904 case FMT_SDPS_PS:
11905 mips32_op = OPC_RSQRT2_PS;
11906 goto do_3d;
11907 default:
11908 goto pool32f_invalid;
11910 break;
11911 case RECIP2_FMT:
11912 switch (fmt) {
11913 case FMT_SDPS_S:
11914 mips32_op = OPC_RECIP2_S;
11915 goto do_3d;
11916 case FMT_SDPS_D:
11917 mips32_op = OPC_RECIP2_D;
11918 goto do_3d;
11919 case FMT_SDPS_PS:
11920 mips32_op = OPC_RECIP2_PS;
11921 goto do_3d;
11922 default:
11923 goto pool32f_invalid;
11925 break;
11926 case ADDR_PS:
11927 mips32_op = OPC_ADDR_PS;
11928 goto do_3d;
11929 case MULR_PS:
11930 mips32_op = OPC_MULR_PS;
11931 do_3d:
11932 gen_farith(ctx, mips32_op, rt, rs, rd, 0);
11933 break;
11934 default:
11935 goto pool32f_invalid;
11937 break;
11938 case 0x20:
11939 /* MOV[FT].fmt and PREFX */
11940 cc = (ctx->opcode >> 13) & 0x7;
11941 fmt = (ctx->opcode >> 9) & 0x3;
11942 switch ((ctx->opcode >> 6) & 0x7) {
11943 case MOVF_FMT:
11944 switch (fmt) {
11945 case FMT_SDPS_S:
11946 gen_movcf_s(rs, rt, cc, 0);
11947 break;
11948 case FMT_SDPS_D:
11949 gen_movcf_d(ctx, rs, rt, cc, 0);
11950 break;
11951 case FMT_SDPS_PS:
11952 gen_movcf_ps(rs, rt, cc, 0);
11953 break;
11954 default:
11955 goto pool32f_invalid;
11957 break;
11958 case MOVT_FMT:
11959 switch (fmt) {
11960 case FMT_SDPS_S:
11961 gen_movcf_s(rs, rt, cc, 1);
11962 break;
11963 case FMT_SDPS_D:
11964 gen_movcf_d(ctx, rs, rt, cc, 1);
11965 break;
11966 case FMT_SDPS_PS:
11967 gen_movcf_ps(rs, rt, cc, 1);
11968 break;
11969 default:
11970 goto pool32f_invalid;
11972 break;
11973 case PREFX:
11974 break;
11975 default:
11976 goto pool32f_invalid;
11978 break;
11979 #define FINSN_3ARG_SDPS(prfx) \
11980 switch ((ctx->opcode >> 8) & 0x3) { \
11981 case FMT_SDPS_S: \
11982 mips32_op = OPC_##prfx##_S; \
11983 goto do_fpop; \
11984 case FMT_SDPS_D: \
11985 mips32_op = OPC_##prfx##_D; \
11986 goto do_fpop; \
11987 case FMT_SDPS_PS: \
11988 mips32_op = OPC_##prfx##_PS; \
11989 goto do_fpop; \
11990 default: \
11991 goto pool32f_invalid; \
11993 case 0x30:
11994 /* regular FP ops */
11995 switch ((ctx->opcode >> 6) & 0x3) {
11996 case ADD_FMT:
11997 FINSN_3ARG_SDPS(ADD);
11998 break;
11999 case SUB_FMT:
12000 FINSN_3ARG_SDPS(SUB);
12001 break;
12002 case MUL_FMT:
12003 FINSN_3ARG_SDPS(MUL);
12004 break;
12005 case DIV_FMT:
12006 fmt = (ctx->opcode >> 8) & 0x3;
12007 if (fmt == 1) {
12008 mips32_op = OPC_DIV_D;
12009 } else if (fmt == 0) {
12010 mips32_op = OPC_DIV_S;
12011 } else {
12012 goto pool32f_invalid;
12014 goto do_fpop;
12015 default:
12016 goto pool32f_invalid;
12018 break;
12019 case 0x38:
12020 /* cmovs */
12021 switch ((ctx->opcode >> 6) & 0x3) {
12022 case MOVN_FMT:
12023 FINSN_3ARG_SDPS(MOVN);
12024 break;
12025 case MOVZ_FMT:
12026 FINSN_3ARG_SDPS(MOVZ);
12027 break;
12028 default:
12029 goto pool32f_invalid;
12031 break;
12032 do_fpop:
12033 gen_farith(ctx, mips32_op, rt, rs, rd, 0);
12034 break;
12035 default:
12036 pool32f_invalid:
12037 MIPS_INVAL("pool32f");
12038 generate_exception(ctx, EXCP_RI);
12039 break;
12041 } else {
12042 generate_exception_err(ctx, EXCP_CpU, 1);
12044 break;
12045 case POOL32I:
12046 minor = (ctx->opcode >> 21) & 0x1f;
12047 switch (minor) {
12048 case BLTZ:
12049 mips32_op = OPC_BLTZ;
12050 goto do_branch;
12051 case BLTZAL:
12052 mips32_op = OPC_BLTZAL;
12053 goto do_branch;
12054 case BLTZALS:
12055 mips32_op = OPC_BLTZALS;
12056 goto do_branch;
12057 case BGEZ:
12058 mips32_op = OPC_BGEZ;
12059 goto do_branch;
12060 case BGEZAL:
12061 mips32_op = OPC_BGEZAL;
12062 goto do_branch;
12063 case BGEZALS:
12064 mips32_op = OPC_BGEZALS;
12065 goto do_branch;
12066 case BLEZ:
12067 mips32_op = OPC_BLEZ;
12068 goto do_branch;
12069 case BGTZ:
12070 mips32_op = OPC_BGTZ;
12071 do_branch:
12072 gen_compute_branch(ctx, mips32_op, 4, rs, -1, imm << 1);
12073 break;
12075 /* Traps */
12076 case TLTI:
12077 mips32_op = OPC_TLTI;
12078 goto do_trapi;
12079 case TGEI:
12080 mips32_op = OPC_TGEI;
12081 goto do_trapi;
12082 case TLTIU:
12083 mips32_op = OPC_TLTIU;
12084 goto do_trapi;
12085 case TGEIU:
12086 mips32_op = OPC_TGEIU;
12087 goto do_trapi;
12088 case TNEI:
12089 mips32_op = OPC_TNEI;
12090 goto do_trapi;
12091 case TEQI:
12092 mips32_op = OPC_TEQI;
12093 do_trapi:
12094 gen_trap(ctx, mips32_op, rs, -1, imm);
12095 break;
12097 case BNEZC:
12098 case BEQZC:
12099 gen_compute_branch(ctx, minor == BNEZC ? OPC_BNE : OPC_BEQ,
12100 4, rs, 0, imm << 1);
12101 /* Compact branches don't have a delay slot, so just let
12102 the normal delay slot handling take us to the branch
12103 target. */
12104 break;
12105 case LUI:
12106 gen_logic_imm(ctx, OPC_LUI, rs, -1, imm);
12107 break;
12108 case SYNCI:
12109 break;
12110 case BC2F:
12111 case BC2T:
12112 /* COP2: Not implemented. */
12113 generate_exception_err(ctx, EXCP_CpU, 2);
12114 break;
12115 case BC1F:
12116 mips32_op = (ctx->opcode & (1 << 16)) ? OPC_BC1FANY2 : OPC_BC1F;
12117 goto do_cp1branch;
12118 case BC1T:
12119 mips32_op = (ctx->opcode & (1 << 16)) ? OPC_BC1TANY2 : OPC_BC1T;
12120 goto do_cp1branch;
12121 case BC1ANY4F:
12122 mips32_op = OPC_BC1FANY4;
12123 goto do_cp1mips3d;
12124 case BC1ANY4T:
12125 mips32_op = OPC_BC1TANY4;
12126 do_cp1mips3d:
12127 check_cop1x(ctx);
12128 check_insn(ctx, ASE_MIPS3D);
12129 /* Fall through */
12130 do_cp1branch:
12131 gen_compute_branch1(ctx, mips32_op,
12132 (ctx->opcode >> 18) & 0x7, imm << 1);
12133 break;
12134 case BPOSGE64:
12135 case BPOSGE32:
12136 /* MIPS DSP: not implemented */
12137 /* Fall through */
12138 default:
12139 MIPS_INVAL("pool32i");
12140 generate_exception(ctx, EXCP_RI);
12141 break;
12143 break;
12144 case POOL32C:
12145 minor = (ctx->opcode >> 12) & 0xf;
12146 switch (minor) {
12147 case LWL:
12148 mips32_op = OPC_LWL;
12149 goto do_ld_lr;
12150 case SWL:
12151 mips32_op = OPC_SWL;
12152 goto do_st_lr;
12153 case LWR:
12154 mips32_op = OPC_LWR;
12155 goto do_ld_lr;
12156 case SWR:
12157 mips32_op = OPC_SWR;
12158 goto do_st_lr;
12159 #if defined(TARGET_MIPS64)
12160 case LDL:
12161 mips32_op = OPC_LDL;
12162 goto do_ld_lr;
12163 case SDL:
12164 mips32_op = OPC_SDL;
12165 goto do_st_lr;
12166 case LDR:
12167 mips32_op = OPC_LDR;
12168 goto do_ld_lr;
12169 case SDR:
12170 mips32_op = OPC_SDR;
12171 goto do_st_lr;
12172 case LWU:
12173 mips32_op = OPC_LWU;
12174 goto do_ld_lr;
12175 case LLD:
12176 mips32_op = OPC_LLD;
12177 goto do_ld_lr;
12178 #endif
12179 case LL:
12180 mips32_op = OPC_LL;
12181 goto do_ld_lr;
12182 do_ld_lr:
12183 gen_ld(ctx, mips32_op, rt, rs, SIMM(ctx->opcode, 0, 12));
12184 break;
12185 do_st_lr:
12186 gen_st(ctx, mips32_op, rt, rs, SIMM(ctx->opcode, 0, 12));
12187 break;
12188 case SC:
12189 gen_st_cond(ctx, OPC_SC, rt, rs, SIMM(ctx->opcode, 0, 12));
12190 break;
12191 #if defined(TARGET_MIPS64)
12192 case SCD:
12193 gen_st_cond(ctx, OPC_SCD, rt, rs, SIMM(ctx->opcode, 0, 12));
12194 break;
12195 #endif
12196 case PREF:
12197 /* Treat as no-op */
12198 break;
12199 default:
12200 MIPS_INVAL("pool32c");
12201 generate_exception(ctx, EXCP_RI);
12202 break;
12204 break;
12205 case ADDI32:
12206 mips32_op = OPC_ADDI;
12207 goto do_addi;
12208 case ADDIU32:
12209 mips32_op = OPC_ADDIU;
12210 do_addi:
12211 gen_arith_imm(ctx, mips32_op, rt, rs, imm);
12212 break;
12214 /* Logical operations */
12215 case ORI32:
12216 mips32_op = OPC_ORI;
12217 goto do_logici;
12218 case XORI32:
12219 mips32_op = OPC_XORI;
12220 goto do_logici;
12221 case ANDI32:
12222 mips32_op = OPC_ANDI;
12223 do_logici:
12224 gen_logic_imm(ctx, mips32_op, rt, rs, imm);
12225 break;
12227 /* Set less than immediate */
12228 case SLTI32:
12229 mips32_op = OPC_SLTI;
12230 goto do_slti;
12231 case SLTIU32:
12232 mips32_op = OPC_SLTIU;
12233 do_slti:
12234 gen_slt_imm(ctx, mips32_op, rt, rs, imm);
12235 break;
12236 case JALX32:
12237 offset = (int32_t)(ctx->opcode & 0x3FFFFFF) << 2;
12238 gen_compute_branch(ctx, OPC_JALX, 4, rt, rs, offset);
12239 break;
12240 case JALS32:
12241 offset = (int32_t)(ctx->opcode & 0x3FFFFFF) << 1;
12242 gen_compute_branch(ctx, OPC_JALS, 4, rt, rs, offset);
12243 break;
12244 case BEQ32:
12245 gen_compute_branch(ctx, OPC_BEQ, 4, rt, rs, imm << 1);
12246 break;
12247 case BNE32:
12248 gen_compute_branch(ctx, OPC_BNE, 4, rt, rs, imm << 1);
12249 break;
12250 case J32:
12251 gen_compute_branch(ctx, OPC_J, 4, rt, rs,
12252 (int32_t)(ctx->opcode & 0x3FFFFFF) << 1);
12253 break;
12254 case JAL32:
12255 gen_compute_branch(ctx, OPC_JAL, 4, rt, rs,
12256 (int32_t)(ctx->opcode & 0x3FFFFFF) << 1);
12257 break;
12258 /* Floating point (COP1) */
12259 case LWC132:
12260 mips32_op = OPC_LWC1;
12261 goto do_cop1;
12262 case LDC132:
12263 mips32_op = OPC_LDC1;
12264 goto do_cop1;
12265 case SWC132:
12266 mips32_op = OPC_SWC1;
12267 goto do_cop1;
12268 case SDC132:
12269 mips32_op = OPC_SDC1;
12270 do_cop1:
12271 gen_cop1_ldst(env, ctx, mips32_op, rt, rs, imm);
12272 break;
12273 case ADDIUPC:
12275 int reg = mmreg(ZIMM(ctx->opcode, 23, 3));
12276 int offset = SIMM(ctx->opcode, 0, 23) << 2;
12278 gen_addiupc(ctx, reg, offset, 0, 0);
12280 break;
12281 /* Loads and stores */
12282 case LB32:
12283 mips32_op = OPC_LB;
12284 goto do_ld;
12285 case LBU32:
12286 mips32_op = OPC_LBU;
12287 goto do_ld;
12288 case LH32:
12289 mips32_op = OPC_LH;
12290 goto do_ld;
12291 case LHU32:
12292 mips32_op = OPC_LHU;
12293 goto do_ld;
12294 case LW32:
12295 mips32_op = OPC_LW;
12296 goto do_ld;
12297 #ifdef TARGET_MIPS64
12298 case LD32:
12299 mips32_op = OPC_LD;
12300 goto do_ld;
12301 case SD32:
12302 mips32_op = OPC_SD;
12303 goto do_st;
12304 #endif
12305 case SB32:
12306 mips32_op = OPC_SB;
12307 goto do_st;
12308 case SH32:
12309 mips32_op = OPC_SH;
12310 goto do_st;
12311 case SW32:
12312 mips32_op = OPC_SW;
12313 goto do_st;
12314 do_ld:
12315 gen_ld(ctx, mips32_op, rt, rs, imm);
12316 break;
12317 do_st:
12318 gen_st(ctx, mips32_op, rt, rs, imm);
12319 break;
12320 default:
12321 generate_exception(ctx, EXCP_RI);
12322 break;
12326 static int decode_micromips_opc (CPUMIPSState *env, DisasContext *ctx)
12328 uint32_t op;
12330 /* make sure instructions are on a halfword boundary */
12331 if (ctx->pc & 0x1) {
12332 env->CP0_BadVAddr = ctx->pc;
12333 generate_exception(ctx, EXCP_AdEL);
12334 ctx->bstate = BS_STOP;
12335 return 2;
12338 op = (ctx->opcode >> 10) & 0x3f;
12339 /* Enforce properly-sized instructions in a delay slot */
12340 if (ctx->hflags & MIPS_HFLAG_BMASK) {
12341 int bits = ctx->hflags & MIPS_HFLAG_BMASK_EXT;
12343 switch (op) {
12344 case POOL32A:
12345 case POOL32B:
12346 case POOL32I:
12347 case POOL32C:
12348 case ADDI32:
12349 case ADDIU32:
12350 case ORI32:
12351 case XORI32:
12352 case SLTI32:
12353 case SLTIU32:
12354 case ANDI32:
12355 case JALX32:
12356 case LBU32:
12357 case LHU32:
12358 case POOL32F:
12359 case JALS32:
12360 case BEQ32:
12361 case BNE32:
12362 case J32:
12363 case JAL32:
12364 case SB32:
12365 case SH32:
12366 case POOL32S:
12367 case ADDIUPC:
12368 case SWC132:
12369 case SDC132:
12370 case SD32:
12371 case SW32:
12372 case LB32:
12373 case LH32:
12374 case DADDIU32:
12375 case LWC132:
12376 case LDC132:
12377 case LD32:
12378 case LW32:
12379 if (bits & MIPS_HFLAG_BDS16) {
12380 generate_exception(ctx, EXCP_RI);
12381 /* Just stop translation; the user is confused. */
12382 ctx->bstate = BS_STOP;
12383 return 2;
12385 break;
12386 case POOL16A:
12387 case POOL16B:
12388 case POOL16C:
12389 case LWGP16:
12390 case POOL16F:
12391 case LBU16:
12392 case LHU16:
12393 case LWSP16:
12394 case LW16:
12395 case SB16:
12396 case SH16:
12397 case SWSP16:
12398 case SW16:
12399 case MOVE16:
12400 case ANDI16:
12401 case POOL16D:
12402 case POOL16E:
12403 case BEQZ16:
12404 case BNEZ16:
12405 case B16:
12406 case LI16:
12407 if (bits & MIPS_HFLAG_BDS32) {
12408 generate_exception(ctx, EXCP_RI);
12409 /* Just stop translation; the user is confused. */
12410 ctx->bstate = BS_STOP;
12411 return 2;
12413 break;
12414 default:
12415 break;
12418 switch (op) {
12419 case POOL16A:
12421 int rd = mmreg(uMIPS_RD(ctx->opcode));
12422 int rs1 = mmreg(uMIPS_RS1(ctx->opcode));
12423 int rs2 = mmreg(uMIPS_RS2(ctx->opcode));
12424 uint32_t opc = 0;
12426 switch (ctx->opcode & 0x1) {
12427 case ADDU16:
12428 opc = OPC_ADDU;
12429 break;
12430 case SUBU16:
12431 opc = OPC_SUBU;
12432 break;
12435 gen_arith(ctx, opc, rd, rs1, rs2);
12437 break;
12438 case POOL16B:
12440 int rd = mmreg(uMIPS_RD(ctx->opcode));
12441 int rs = mmreg(uMIPS_RS(ctx->opcode));
12442 int amount = (ctx->opcode >> 1) & 0x7;
12443 uint32_t opc = 0;
12444 amount = amount == 0 ? 8 : amount;
12446 switch (ctx->opcode & 0x1) {
12447 case SLL16:
12448 opc = OPC_SLL;
12449 break;
12450 case SRL16:
12451 opc = OPC_SRL;
12452 break;
12455 gen_shift_imm(ctx, opc, rd, rs, amount);
12457 break;
12458 case POOL16C:
12459 gen_pool16c_insn(ctx);
12460 break;
12461 case LWGP16:
12463 int rd = mmreg(uMIPS_RD(ctx->opcode));
12464 int rb = 28; /* GP */
12465 int16_t offset = SIMM(ctx->opcode, 0, 7) << 2;
12467 gen_ld(ctx, OPC_LW, rd, rb, offset);
12469 break;
12470 case POOL16F:
12471 if (ctx->opcode & 1) {
12472 generate_exception(ctx, EXCP_RI);
12473 } else {
12474 /* MOVEP */
12475 int enc_dest = uMIPS_RD(ctx->opcode);
12476 int enc_rt = uMIPS_RS2(ctx->opcode);
12477 int enc_rs = uMIPS_RS1(ctx->opcode);
12478 int rd, rs, re, rt;
12479 static const int rd_enc[] = { 5, 5, 6, 4, 4, 4, 4, 4 };
12480 static const int re_enc[] = { 6, 7, 7, 21, 22, 5, 6, 7 };
12481 static const int rs_rt_enc[] = { 0, 17, 2, 3, 16, 18, 19, 20 };
12483 rd = rd_enc[enc_dest];
12484 re = re_enc[enc_dest];
12485 rs = rs_rt_enc[enc_rs];
12486 rt = rs_rt_enc[enc_rt];
12488 gen_arith_imm(ctx, OPC_ADDIU, rd, rs, 0);
12489 gen_arith_imm(ctx, OPC_ADDIU, re, rt, 0);
12491 break;
12492 case LBU16:
12494 int rd = mmreg(uMIPS_RD(ctx->opcode));
12495 int rb = mmreg(uMIPS_RS(ctx->opcode));
12496 int16_t offset = ZIMM(ctx->opcode, 0, 4);
12497 offset = (offset == 0xf ? -1 : offset);
12499 gen_ld(ctx, OPC_LBU, rd, rb, offset);
12501 break;
12502 case LHU16:
12504 int rd = mmreg(uMIPS_RD(ctx->opcode));
12505 int rb = mmreg(uMIPS_RS(ctx->opcode));
12506 int16_t offset = ZIMM(ctx->opcode, 0, 4) << 1;
12508 gen_ld(ctx, OPC_LHU, rd, rb, offset);
12510 break;
12511 case LWSP16:
12513 int rd = (ctx->opcode >> 5) & 0x1f;
12514 int rb = 29; /* SP */
12515 int16_t offset = ZIMM(ctx->opcode, 0, 5) << 2;
12517 gen_ld(ctx, OPC_LW, rd, rb, offset);
12519 break;
12520 case LW16:
12522 int rd = mmreg(uMIPS_RD(ctx->opcode));
12523 int rb = mmreg(uMIPS_RS(ctx->opcode));
12524 int16_t offset = ZIMM(ctx->opcode, 0, 4) << 2;
12526 gen_ld(ctx, OPC_LW, rd, rb, offset);
12528 break;
12529 case SB16:
12531 int rd = mmreg2(uMIPS_RD(ctx->opcode));
12532 int rb = mmreg(uMIPS_RS(ctx->opcode));
12533 int16_t offset = ZIMM(ctx->opcode, 0, 4);
12535 gen_st(ctx, OPC_SB, rd, rb, offset);
12537 break;
12538 case SH16:
12540 int rd = mmreg2(uMIPS_RD(ctx->opcode));
12541 int rb = mmreg(uMIPS_RS(ctx->opcode));
12542 int16_t offset = ZIMM(ctx->opcode, 0, 4) << 1;
12544 gen_st(ctx, OPC_SH, rd, rb, offset);
12546 break;
12547 case SWSP16:
12549 int rd = (ctx->opcode >> 5) & 0x1f;
12550 int rb = 29; /* SP */
12551 int16_t offset = ZIMM(ctx->opcode, 0, 5) << 2;
12553 gen_st(ctx, OPC_SW, rd, rb, offset);
12555 break;
12556 case SW16:
12558 int rd = mmreg2(uMIPS_RD(ctx->opcode));
12559 int rb = mmreg(uMIPS_RS(ctx->opcode));
12560 int16_t offset = ZIMM(ctx->opcode, 0, 4) << 2;
12562 gen_st(ctx, OPC_SW, rd, rb, offset);
12564 break;
12565 case MOVE16:
12567 int rd = uMIPS_RD5(ctx->opcode);
12568 int rs = uMIPS_RS5(ctx->opcode);
12570 gen_arith_imm(ctx, OPC_ADDIU, rd, rs, 0);
12572 break;
12573 case ANDI16:
12574 gen_andi16(ctx);
12575 break;
12576 case POOL16D:
12577 switch (ctx->opcode & 0x1) {
12578 case ADDIUS5:
12579 gen_addius5(ctx);
12580 break;
12581 case ADDIUSP:
12582 gen_addiusp(ctx);
12583 break;
12585 break;
12586 case POOL16E:
12587 switch (ctx->opcode & 0x1) {
12588 case ADDIUR2:
12589 gen_addiur2(ctx);
12590 break;
12591 case ADDIUR1SP:
12592 gen_addiur1sp(ctx);
12593 break;
12595 break;
12596 case B16:
12597 gen_compute_branch(ctx, OPC_BEQ, 2, 0, 0,
12598 SIMM(ctx->opcode, 0, 10) << 1);
12599 break;
12600 case BNEZ16:
12601 case BEQZ16:
12602 gen_compute_branch(ctx, op == BNEZ16 ? OPC_BNE : OPC_BEQ, 2,
12603 mmreg(uMIPS_RD(ctx->opcode)),
12604 0, SIMM(ctx->opcode, 0, 7) << 1);
12605 break;
12606 case LI16:
12608 int reg = mmreg(uMIPS_RD(ctx->opcode));
12609 int imm = ZIMM(ctx->opcode, 0, 7);
12611 imm = (imm == 0x7f ? -1 : imm);
12612 tcg_gen_movi_tl(cpu_gpr[reg], imm);
12614 break;
12615 case RES_20:
12616 case RES_28:
12617 case RES_29:
12618 case RES_30:
12619 case RES_31:
12620 case RES_38:
12621 case RES_39:
12622 generate_exception(ctx, EXCP_RI);
12623 break;
12624 default:
12625 decode_micromips32_opc (env, ctx, op);
12626 return 4;
12629 return 2;
12632 /* SmartMIPS extension to MIPS32 */
12634 #if defined(TARGET_MIPS64)
12636 /* MDMX extension to MIPS64 */
12638 #endif
12640 /* MIPSDSP functions. */
12641 static void gen_mipsdsp_ld(DisasContext *ctx, uint32_t opc,
12642 int rd, int base, int offset)
12644 const char *opn = "ldx";
12645 TCGv t0;
12647 check_dsp(ctx);
12648 t0 = tcg_temp_new();
12650 if (base == 0) {
12651 gen_load_gpr(t0, offset);
12652 } else if (offset == 0) {
12653 gen_load_gpr(t0, base);
12654 } else {
12655 gen_op_addr_add(ctx, t0, cpu_gpr[base], cpu_gpr[offset]);
12658 switch (opc) {
12659 case OPC_LBUX:
12660 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_UB);
12661 gen_store_gpr(t0, rd);
12662 opn = "lbux";
12663 break;
12664 case OPC_LHX:
12665 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TESW);
12666 gen_store_gpr(t0, rd);
12667 opn = "lhx";
12668 break;
12669 case OPC_LWX:
12670 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TESL);
12671 gen_store_gpr(t0, rd);
12672 opn = "lwx";
12673 break;
12674 #if defined(TARGET_MIPS64)
12675 case OPC_LDX:
12676 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TEQ);
12677 gen_store_gpr(t0, rd);
12678 opn = "ldx";
12679 break;
12680 #endif
12682 (void)opn; /* avoid a compiler warning */
12683 MIPS_DEBUG("%s %s, %s(%s)", opn,
12684 regnames[rd], regnames[offset], regnames[base]);
12685 tcg_temp_free(t0);
12688 static void gen_mipsdsp_arith(DisasContext *ctx, uint32_t op1, uint32_t op2,
12689 int ret, int v1, int v2)
12691 const char *opn = "mipsdsp arith";
12692 TCGv v1_t;
12693 TCGv v2_t;
12695 if (ret == 0) {
12696 /* Treat as NOP. */
12697 MIPS_DEBUG("NOP");
12698 return;
12701 v1_t = tcg_temp_new();
12702 v2_t = tcg_temp_new();
12704 gen_load_gpr(v1_t, v1);
12705 gen_load_gpr(v2_t, v2);
12707 switch (op1) {
12708 /* OPC_MULT_G_2E is equal OPC_ADDUH_QB_DSP */
12709 case OPC_MULT_G_2E:
12710 check_dspr2(ctx);
12711 switch (op2) {
12712 case OPC_ADDUH_QB:
12713 gen_helper_adduh_qb(cpu_gpr[ret], v1_t, v2_t);
12714 break;
12715 case OPC_ADDUH_R_QB:
12716 gen_helper_adduh_r_qb(cpu_gpr[ret], v1_t, v2_t);
12717 break;
12718 case OPC_ADDQH_PH:
12719 gen_helper_addqh_ph(cpu_gpr[ret], v1_t, v2_t);
12720 break;
12721 case OPC_ADDQH_R_PH:
12722 gen_helper_addqh_r_ph(cpu_gpr[ret], v1_t, v2_t);
12723 break;
12724 case OPC_ADDQH_W:
12725 gen_helper_addqh_w(cpu_gpr[ret], v1_t, v2_t);
12726 break;
12727 case OPC_ADDQH_R_W:
12728 gen_helper_addqh_r_w(cpu_gpr[ret], v1_t, v2_t);
12729 break;
12730 case OPC_SUBUH_QB:
12731 gen_helper_subuh_qb(cpu_gpr[ret], v1_t, v2_t);
12732 break;
12733 case OPC_SUBUH_R_QB:
12734 gen_helper_subuh_r_qb(cpu_gpr[ret], v1_t, v2_t);
12735 break;
12736 case OPC_SUBQH_PH:
12737 gen_helper_subqh_ph(cpu_gpr[ret], v1_t, v2_t);
12738 break;
12739 case OPC_SUBQH_R_PH:
12740 gen_helper_subqh_r_ph(cpu_gpr[ret], v1_t, v2_t);
12741 break;
12742 case OPC_SUBQH_W:
12743 gen_helper_subqh_w(cpu_gpr[ret], v1_t, v2_t);
12744 break;
12745 case OPC_SUBQH_R_W:
12746 gen_helper_subqh_r_w(cpu_gpr[ret], v1_t, v2_t);
12747 break;
12749 break;
12750 case OPC_ABSQ_S_PH_DSP:
12751 switch (op2) {
12752 case OPC_ABSQ_S_QB:
12753 check_dspr2(ctx);
12754 gen_helper_absq_s_qb(cpu_gpr[ret], v2_t, cpu_env);
12755 break;
12756 case OPC_ABSQ_S_PH:
12757 check_dsp(ctx);
12758 gen_helper_absq_s_ph(cpu_gpr[ret], v2_t, cpu_env);
12759 break;
12760 case OPC_ABSQ_S_W:
12761 check_dsp(ctx);
12762 gen_helper_absq_s_w(cpu_gpr[ret], v2_t, cpu_env);
12763 break;
12764 case OPC_PRECEQ_W_PHL:
12765 check_dsp(ctx);
12766 tcg_gen_andi_tl(cpu_gpr[ret], v2_t, 0xFFFF0000);
12767 tcg_gen_ext32s_tl(cpu_gpr[ret], cpu_gpr[ret]);
12768 break;
12769 case OPC_PRECEQ_W_PHR:
12770 check_dsp(ctx);
12771 tcg_gen_andi_tl(cpu_gpr[ret], v2_t, 0x0000FFFF);
12772 tcg_gen_shli_tl(cpu_gpr[ret], cpu_gpr[ret], 16);
12773 tcg_gen_ext32s_tl(cpu_gpr[ret], cpu_gpr[ret]);
12774 break;
12775 case OPC_PRECEQU_PH_QBL:
12776 check_dsp(ctx);
12777 gen_helper_precequ_ph_qbl(cpu_gpr[ret], v2_t);
12778 break;
12779 case OPC_PRECEQU_PH_QBR:
12780 check_dsp(ctx);
12781 gen_helper_precequ_ph_qbr(cpu_gpr[ret], v2_t);
12782 break;
12783 case OPC_PRECEQU_PH_QBLA:
12784 check_dsp(ctx);
12785 gen_helper_precequ_ph_qbla(cpu_gpr[ret], v2_t);
12786 break;
12787 case OPC_PRECEQU_PH_QBRA:
12788 check_dsp(ctx);
12789 gen_helper_precequ_ph_qbra(cpu_gpr[ret], v2_t);
12790 break;
12791 case OPC_PRECEU_PH_QBL:
12792 check_dsp(ctx);
12793 gen_helper_preceu_ph_qbl(cpu_gpr[ret], v2_t);
12794 break;
12795 case OPC_PRECEU_PH_QBR:
12796 check_dsp(ctx);
12797 gen_helper_preceu_ph_qbr(cpu_gpr[ret], v2_t);
12798 break;
12799 case OPC_PRECEU_PH_QBLA:
12800 check_dsp(ctx);
12801 gen_helper_preceu_ph_qbla(cpu_gpr[ret], v2_t);
12802 break;
12803 case OPC_PRECEU_PH_QBRA:
12804 check_dsp(ctx);
12805 gen_helper_preceu_ph_qbra(cpu_gpr[ret], v2_t);
12806 break;
12808 break;
12809 case OPC_ADDU_QB_DSP:
12810 switch (op2) {
12811 case OPC_ADDQ_PH:
12812 check_dsp(ctx);
12813 gen_helper_addq_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12814 break;
12815 case OPC_ADDQ_S_PH:
12816 check_dsp(ctx);
12817 gen_helper_addq_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12818 break;
12819 case OPC_ADDQ_S_W:
12820 check_dsp(ctx);
12821 gen_helper_addq_s_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12822 break;
12823 case OPC_ADDU_QB:
12824 check_dsp(ctx);
12825 gen_helper_addu_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12826 break;
12827 case OPC_ADDU_S_QB:
12828 check_dsp(ctx);
12829 gen_helper_addu_s_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12830 break;
12831 case OPC_ADDU_PH:
12832 check_dspr2(ctx);
12833 gen_helper_addu_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12834 break;
12835 case OPC_ADDU_S_PH:
12836 check_dspr2(ctx);
12837 gen_helper_addu_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12838 break;
12839 case OPC_SUBQ_PH:
12840 check_dsp(ctx);
12841 gen_helper_subq_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12842 break;
12843 case OPC_SUBQ_S_PH:
12844 check_dsp(ctx);
12845 gen_helper_subq_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12846 break;
12847 case OPC_SUBQ_S_W:
12848 check_dsp(ctx);
12849 gen_helper_subq_s_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12850 break;
12851 case OPC_SUBU_QB:
12852 check_dsp(ctx);
12853 gen_helper_subu_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12854 break;
12855 case OPC_SUBU_S_QB:
12856 check_dsp(ctx);
12857 gen_helper_subu_s_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12858 break;
12859 case OPC_SUBU_PH:
12860 check_dspr2(ctx);
12861 gen_helper_subu_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12862 break;
12863 case OPC_SUBU_S_PH:
12864 check_dspr2(ctx);
12865 gen_helper_subu_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12866 break;
12867 case OPC_ADDSC:
12868 check_dsp(ctx);
12869 gen_helper_addsc(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12870 break;
12871 case OPC_ADDWC:
12872 check_dsp(ctx);
12873 gen_helper_addwc(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12874 break;
12875 case OPC_MODSUB:
12876 check_dsp(ctx);
12877 gen_helper_modsub(cpu_gpr[ret], v1_t, v2_t);
12878 break;
12879 case OPC_RADDU_W_QB:
12880 check_dsp(ctx);
12881 gen_helper_raddu_w_qb(cpu_gpr[ret], v1_t);
12882 break;
12884 break;
12885 case OPC_CMPU_EQ_QB_DSP:
12886 switch (op2) {
12887 case OPC_PRECR_QB_PH:
12888 check_dspr2(ctx);
12889 gen_helper_precr_qb_ph(cpu_gpr[ret], v1_t, v2_t);
12890 break;
12891 case OPC_PRECRQ_QB_PH:
12892 check_dsp(ctx);
12893 gen_helper_precrq_qb_ph(cpu_gpr[ret], v1_t, v2_t);
12894 break;
12895 case OPC_PRECR_SRA_PH_W:
12896 check_dspr2(ctx);
12898 TCGv_i32 sa_t = tcg_const_i32(v2);
12899 gen_helper_precr_sra_ph_w(cpu_gpr[ret], sa_t, v1_t,
12900 cpu_gpr[ret]);
12901 tcg_temp_free_i32(sa_t);
12902 break;
12904 case OPC_PRECR_SRA_R_PH_W:
12905 check_dspr2(ctx);
12907 TCGv_i32 sa_t = tcg_const_i32(v2);
12908 gen_helper_precr_sra_r_ph_w(cpu_gpr[ret], sa_t, v1_t,
12909 cpu_gpr[ret]);
12910 tcg_temp_free_i32(sa_t);
12911 break;
12913 case OPC_PRECRQ_PH_W:
12914 check_dsp(ctx);
12915 gen_helper_precrq_ph_w(cpu_gpr[ret], v1_t, v2_t);
12916 break;
12917 case OPC_PRECRQ_RS_PH_W:
12918 check_dsp(ctx);
12919 gen_helper_precrq_rs_ph_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12920 break;
12921 case OPC_PRECRQU_S_QB_PH:
12922 check_dsp(ctx);
12923 gen_helper_precrqu_s_qb_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12924 break;
12926 break;
12927 #ifdef TARGET_MIPS64
12928 case OPC_ABSQ_S_QH_DSP:
12929 switch (op2) {
12930 case OPC_PRECEQ_L_PWL:
12931 check_dsp(ctx);
12932 tcg_gen_andi_tl(cpu_gpr[ret], v2_t, 0xFFFFFFFF00000000ull);
12933 break;
12934 case OPC_PRECEQ_L_PWR:
12935 check_dsp(ctx);
12936 tcg_gen_shli_tl(cpu_gpr[ret], v2_t, 32);
12937 break;
12938 case OPC_PRECEQ_PW_QHL:
12939 check_dsp(ctx);
12940 gen_helper_preceq_pw_qhl(cpu_gpr[ret], v2_t);
12941 break;
12942 case OPC_PRECEQ_PW_QHR:
12943 check_dsp(ctx);
12944 gen_helper_preceq_pw_qhr(cpu_gpr[ret], v2_t);
12945 break;
12946 case OPC_PRECEQ_PW_QHLA:
12947 check_dsp(ctx);
12948 gen_helper_preceq_pw_qhla(cpu_gpr[ret], v2_t);
12949 break;
12950 case OPC_PRECEQ_PW_QHRA:
12951 check_dsp(ctx);
12952 gen_helper_preceq_pw_qhra(cpu_gpr[ret], v2_t);
12953 break;
12954 case OPC_PRECEQU_QH_OBL:
12955 check_dsp(ctx);
12956 gen_helper_precequ_qh_obl(cpu_gpr[ret], v2_t);
12957 break;
12958 case OPC_PRECEQU_QH_OBR:
12959 check_dsp(ctx);
12960 gen_helper_precequ_qh_obr(cpu_gpr[ret], v2_t);
12961 break;
12962 case OPC_PRECEQU_QH_OBLA:
12963 check_dsp(ctx);
12964 gen_helper_precequ_qh_obla(cpu_gpr[ret], v2_t);
12965 break;
12966 case OPC_PRECEQU_QH_OBRA:
12967 check_dsp(ctx);
12968 gen_helper_precequ_qh_obra(cpu_gpr[ret], v2_t);
12969 break;
12970 case OPC_PRECEU_QH_OBL:
12971 check_dsp(ctx);
12972 gen_helper_preceu_qh_obl(cpu_gpr[ret], v2_t);
12973 break;
12974 case OPC_PRECEU_QH_OBR:
12975 check_dsp(ctx);
12976 gen_helper_preceu_qh_obr(cpu_gpr[ret], v2_t);
12977 break;
12978 case OPC_PRECEU_QH_OBLA:
12979 check_dsp(ctx);
12980 gen_helper_preceu_qh_obla(cpu_gpr[ret], v2_t);
12981 break;
12982 case OPC_PRECEU_QH_OBRA:
12983 check_dsp(ctx);
12984 gen_helper_preceu_qh_obra(cpu_gpr[ret], v2_t);
12985 break;
12986 case OPC_ABSQ_S_OB:
12987 check_dspr2(ctx);
12988 gen_helper_absq_s_ob(cpu_gpr[ret], v2_t, cpu_env);
12989 break;
12990 case OPC_ABSQ_S_PW:
12991 check_dsp(ctx);
12992 gen_helper_absq_s_pw(cpu_gpr[ret], v2_t, cpu_env);
12993 break;
12994 case OPC_ABSQ_S_QH:
12995 check_dsp(ctx);
12996 gen_helper_absq_s_qh(cpu_gpr[ret], v2_t, cpu_env);
12997 break;
12999 break;
13000 case OPC_ADDU_OB_DSP:
13001 switch (op2) {
13002 case OPC_RADDU_L_OB:
13003 check_dsp(ctx);
13004 gen_helper_raddu_l_ob(cpu_gpr[ret], v1_t);
13005 break;
13006 case OPC_SUBQ_PW:
13007 check_dsp(ctx);
13008 gen_helper_subq_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13009 break;
13010 case OPC_SUBQ_S_PW:
13011 check_dsp(ctx);
13012 gen_helper_subq_s_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13013 break;
13014 case OPC_SUBQ_QH:
13015 check_dsp(ctx);
13016 gen_helper_subq_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13017 break;
13018 case OPC_SUBQ_S_QH:
13019 check_dsp(ctx);
13020 gen_helper_subq_s_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13021 break;
13022 case OPC_SUBU_OB:
13023 check_dsp(ctx);
13024 gen_helper_subu_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13025 break;
13026 case OPC_SUBU_S_OB:
13027 check_dsp(ctx);
13028 gen_helper_subu_s_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13029 break;
13030 case OPC_SUBU_QH:
13031 check_dspr2(ctx);
13032 gen_helper_subu_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13033 break;
13034 case OPC_SUBU_S_QH:
13035 check_dspr2(ctx);
13036 gen_helper_subu_s_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13037 break;
13038 case OPC_SUBUH_OB:
13039 check_dspr2(ctx);
13040 gen_helper_subuh_ob(cpu_gpr[ret], v1_t, v2_t);
13041 break;
13042 case OPC_SUBUH_R_OB:
13043 check_dspr2(ctx);
13044 gen_helper_subuh_r_ob(cpu_gpr[ret], v1_t, v2_t);
13045 break;
13046 case OPC_ADDQ_PW:
13047 check_dsp(ctx);
13048 gen_helper_addq_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13049 break;
13050 case OPC_ADDQ_S_PW:
13051 check_dsp(ctx);
13052 gen_helper_addq_s_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13053 break;
13054 case OPC_ADDQ_QH:
13055 check_dsp(ctx);
13056 gen_helper_addq_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13057 break;
13058 case OPC_ADDQ_S_QH:
13059 check_dsp(ctx);
13060 gen_helper_addq_s_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13061 break;
13062 case OPC_ADDU_OB:
13063 check_dsp(ctx);
13064 gen_helper_addu_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13065 break;
13066 case OPC_ADDU_S_OB:
13067 check_dsp(ctx);
13068 gen_helper_addu_s_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13069 break;
13070 case OPC_ADDU_QH:
13071 check_dspr2(ctx);
13072 gen_helper_addu_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13073 break;
13074 case OPC_ADDU_S_QH:
13075 check_dspr2(ctx);
13076 gen_helper_addu_s_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13077 break;
13078 case OPC_ADDUH_OB:
13079 check_dspr2(ctx);
13080 gen_helper_adduh_ob(cpu_gpr[ret], v1_t, v2_t);
13081 break;
13082 case OPC_ADDUH_R_OB:
13083 check_dspr2(ctx);
13084 gen_helper_adduh_r_ob(cpu_gpr[ret], v1_t, v2_t);
13085 break;
13087 break;
13088 case OPC_CMPU_EQ_OB_DSP:
13089 switch (op2) {
13090 case OPC_PRECR_OB_QH:
13091 check_dspr2(ctx);
13092 gen_helper_precr_ob_qh(cpu_gpr[ret], v1_t, v2_t);
13093 break;
13094 case OPC_PRECR_SRA_QH_PW:
13095 check_dspr2(ctx);
13097 TCGv_i32 ret_t = tcg_const_i32(ret);
13098 gen_helper_precr_sra_qh_pw(v2_t, v1_t, v2_t, ret_t);
13099 tcg_temp_free_i32(ret_t);
13100 break;
13102 case OPC_PRECR_SRA_R_QH_PW:
13103 check_dspr2(ctx);
13105 TCGv_i32 sa_v = tcg_const_i32(ret);
13106 gen_helper_precr_sra_r_qh_pw(v2_t, v1_t, v2_t, sa_v);
13107 tcg_temp_free_i32(sa_v);
13108 break;
13110 case OPC_PRECRQ_OB_QH:
13111 check_dsp(ctx);
13112 gen_helper_precrq_ob_qh(cpu_gpr[ret], v1_t, v2_t);
13113 break;
13114 case OPC_PRECRQ_PW_L:
13115 check_dsp(ctx);
13116 gen_helper_precrq_pw_l(cpu_gpr[ret], v1_t, v2_t);
13117 break;
13118 case OPC_PRECRQ_QH_PW:
13119 check_dsp(ctx);
13120 gen_helper_precrq_qh_pw(cpu_gpr[ret], v1_t, v2_t);
13121 break;
13122 case OPC_PRECRQ_RS_QH_PW:
13123 check_dsp(ctx);
13124 gen_helper_precrq_rs_qh_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13125 break;
13126 case OPC_PRECRQU_S_OB_QH:
13127 check_dsp(ctx);
13128 gen_helper_precrqu_s_ob_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13129 break;
13131 break;
13132 #endif
13135 tcg_temp_free(v1_t);
13136 tcg_temp_free(v2_t);
13138 (void)opn; /* avoid a compiler warning */
13139 MIPS_DEBUG("%s", opn);
13142 static void gen_mipsdsp_shift(DisasContext *ctx, uint32_t opc,
13143 int ret, int v1, int v2)
13145 uint32_t op2;
13146 const char *opn = "mipsdsp shift";
13147 TCGv t0;
13148 TCGv v1_t;
13149 TCGv v2_t;
13151 if (ret == 0) {
13152 /* Treat as NOP. */
13153 MIPS_DEBUG("NOP");
13154 return;
13157 t0 = tcg_temp_new();
13158 v1_t = tcg_temp_new();
13159 v2_t = tcg_temp_new();
13161 tcg_gen_movi_tl(t0, v1);
13162 gen_load_gpr(v1_t, v1);
13163 gen_load_gpr(v2_t, v2);
13165 switch (opc) {
13166 case OPC_SHLL_QB_DSP:
13168 op2 = MASK_SHLL_QB(ctx->opcode);
13169 switch (op2) {
13170 case OPC_SHLL_QB:
13171 check_dsp(ctx);
13172 gen_helper_shll_qb(cpu_gpr[ret], t0, v2_t, cpu_env);
13173 break;
13174 case OPC_SHLLV_QB:
13175 check_dsp(ctx);
13176 gen_helper_shll_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13177 break;
13178 case OPC_SHLL_PH:
13179 check_dsp(ctx);
13180 gen_helper_shll_ph(cpu_gpr[ret], t0, v2_t, cpu_env);
13181 break;
13182 case OPC_SHLLV_PH:
13183 check_dsp(ctx);
13184 gen_helper_shll_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13185 break;
13186 case OPC_SHLL_S_PH:
13187 check_dsp(ctx);
13188 gen_helper_shll_s_ph(cpu_gpr[ret], t0, v2_t, cpu_env);
13189 break;
13190 case OPC_SHLLV_S_PH:
13191 check_dsp(ctx);
13192 gen_helper_shll_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13193 break;
13194 case OPC_SHLL_S_W:
13195 check_dsp(ctx);
13196 gen_helper_shll_s_w(cpu_gpr[ret], t0, v2_t, cpu_env);
13197 break;
13198 case OPC_SHLLV_S_W:
13199 check_dsp(ctx);
13200 gen_helper_shll_s_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13201 break;
13202 case OPC_SHRL_QB:
13203 check_dsp(ctx);
13204 gen_helper_shrl_qb(cpu_gpr[ret], t0, v2_t);
13205 break;
13206 case OPC_SHRLV_QB:
13207 check_dsp(ctx);
13208 gen_helper_shrl_qb(cpu_gpr[ret], v1_t, v2_t);
13209 break;
13210 case OPC_SHRL_PH:
13211 check_dspr2(ctx);
13212 gen_helper_shrl_ph(cpu_gpr[ret], t0, v2_t);
13213 break;
13214 case OPC_SHRLV_PH:
13215 check_dspr2(ctx);
13216 gen_helper_shrl_ph(cpu_gpr[ret], v1_t, v2_t);
13217 break;
13218 case OPC_SHRA_QB:
13219 check_dspr2(ctx);
13220 gen_helper_shra_qb(cpu_gpr[ret], t0, v2_t);
13221 break;
13222 case OPC_SHRA_R_QB:
13223 check_dspr2(ctx);
13224 gen_helper_shra_r_qb(cpu_gpr[ret], t0, v2_t);
13225 break;
13226 case OPC_SHRAV_QB:
13227 check_dspr2(ctx);
13228 gen_helper_shra_qb(cpu_gpr[ret], v1_t, v2_t);
13229 break;
13230 case OPC_SHRAV_R_QB:
13231 check_dspr2(ctx);
13232 gen_helper_shra_r_qb(cpu_gpr[ret], v1_t, v2_t);
13233 break;
13234 case OPC_SHRA_PH:
13235 check_dsp(ctx);
13236 gen_helper_shra_ph(cpu_gpr[ret], t0, v2_t);
13237 break;
13238 case OPC_SHRA_R_PH:
13239 check_dsp(ctx);
13240 gen_helper_shra_r_ph(cpu_gpr[ret], t0, v2_t);
13241 break;
13242 case OPC_SHRAV_PH:
13243 check_dsp(ctx);
13244 gen_helper_shra_ph(cpu_gpr[ret], v1_t, v2_t);
13245 break;
13246 case OPC_SHRAV_R_PH:
13247 check_dsp(ctx);
13248 gen_helper_shra_r_ph(cpu_gpr[ret], v1_t, v2_t);
13249 break;
13250 case OPC_SHRA_R_W:
13251 check_dsp(ctx);
13252 gen_helper_shra_r_w(cpu_gpr[ret], t0, v2_t);
13253 break;
13254 case OPC_SHRAV_R_W:
13255 check_dsp(ctx);
13256 gen_helper_shra_r_w(cpu_gpr[ret], v1_t, v2_t);
13257 break;
13258 default: /* Invalid */
13259 MIPS_INVAL("MASK SHLL.QB");
13260 generate_exception(ctx, EXCP_RI);
13261 break;
13263 break;
13265 #ifdef TARGET_MIPS64
13266 case OPC_SHLL_OB_DSP:
13267 op2 = MASK_SHLL_OB(ctx->opcode);
13268 switch (op2) {
13269 case OPC_SHLL_PW:
13270 check_dsp(ctx);
13271 gen_helper_shll_pw(cpu_gpr[ret], v2_t, t0, cpu_env);
13272 break;
13273 case OPC_SHLLV_PW:
13274 check_dsp(ctx);
13275 gen_helper_shll_pw(cpu_gpr[ret], v2_t, v1_t, cpu_env);
13276 break;
13277 case OPC_SHLL_S_PW:
13278 check_dsp(ctx);
13279 gen_helper_shll_s_pw(cpu_gpr[ret], v2_t, t0, cpu_env);
13280 break;
13281 case OPC_SHLLV_S_PW:
13282 check_dsp(ctx);
13283 gen_helper_shll_s_pw(cpu_gpr[ret], v2_t, v1_t, cpu_env);
13284 break;
13285 case OPC_SHLL_OB:
13286 check_dsp(ctx);
13287 gen_helper_shll_ob(cpu_gpr[ret], v2_t, t0, cpu_env);
13288 break;
13289 case OPC_SHLLV_OB:
13290 check_dsp(ctx);
13291 gen_helper_shll_ob(cpu_gpr[ret], v2_t, v1_t, cpu_env);
13292 break;
13293 case OPC_SHLL_QH:
13294 check_dsp(ctx);
13295 gen_helper_shll_qh(cpu_gpr[ret], v2_t, t0, cpu_env);
13296 break;
13297 case OPC_SHLLV_QH:
13298 check_dsp(ctx);
13299 gen_helper_shll_qh(cpu_gpr[ret], v2_t, v1_t, cpu_env);
13300 break;
13301 case OPC_SHLL_S_QH:
13302 check_dsp(ctx);
13303 gen_helper_shll_s_qh(cpu_gpr[ret], v2_t, t0, cpu_env);
13304 break;
13305 case OPC_SHLLV_S_QH:
13306 check_dsp(ctx);
13307 gen_helper_shll_s_qh(cpu_gpr[ret], v2_t, v1_t, cpu_env);
13308 break;
13309 case OPC_SHRA_OB:
13310 check_dspr2(ctx);
13311 gen_helper_shra_ob(cpu_gpr[ret], v2_t, t0);
13312 break;
13313 case OPC_SHRAV_OB:
13314 check_dspr2(ctx);
13315 gen_helper_shra_ob(cpu_gpr[ret], v2_t, v1_t);
13316 break;
13317 case OPC_SHRA_R_OB:
13318 check_dspr2(ctx);
13319 gen_helper_shra_r_ob(cpu_gpr[ret], v2_t, t0);
13320 break;
13321 case OPC_SHRAV_R_OB:
13322 check_dspr2(ctx);
13323 gen_helper_shra_r_ob(cpu_gpr[ret], v2_t, v1_t);
13324 break;
13325 case OPC_SHRA_PW:
13326 check_dsp(ctx);
13327 gen_helper_shra_pw(cpu_gpr[ret], v2_t, t0);
13328 break;
13329 case OPC_SHRAV_PW:
13330 check_dsp(ctx);
13331 gen_helper_shra_pw(cpu_gpr[ret], v2_t, v1_t);
13332 break;
13333 case OPC_SHRA_R_PW:
13334 check_dsp(ctx);
13335 gen_helper_shra_r_pw(cpu_gpr[ret], v2_t, t0);
13336 break;
13337 case OPC_SHRAV_R_PW:
13338 check_dsp(ctx);
13339 gen_helper_shra_r_pw(cpu_gpr[ret], v2_t, v1_t);
13340 break;
13341 case OPC_SHRA_QH:
13342 check_dsp(ctx);
13343 gen_helper_shra_qh(cpu_gpr[ret], v2_t, t0);
13344 break;
13345 case OPC_SHRAV_QH:
13346 check_dsp(ctx);
13347 gen_helper_shra_qh(cpu_gpr[ret], v2_t, v1_t);
13348 break;
13349 case OPC_SHRA_R_QH:
13350 check_dsp(ctx);
13351 gen_helper_shra_r_qh(cpu_gpr[ret], v2_t, t0);
13352 break;
13353 case OPC_SHRAV_R_QH:
13354 check_dsp(ctx);
13355 gen_helper_shra_r_qh(cpu_gpr[ret], v2_t, v1_t);
13356 break;
13357 case OPC_SHRL_OB:
13358 check_dsp(ctx);
13359 gen_helper_shrl_ob(cpu_gpr[ret], v2_t, t0);
13360 break;
13361 case OPC_SHRLV_OB:
13362 check_dsp(ctx);
13363 gen_helper_shrl_ob(cpu_gpr[ret], v2_t, v1_t);
13364 break;
13365 case OPC_SHRL_QH:
13366 check_dspr2(ctx);
13367 gen_helper_shrl_qh(cpu_gpr[ret], v2_t, t0);
13368 break;
13369 case OPC_SHRLV_QH:
13370 check_dspr2(ctx);
13371 gen_helper_shrl_qh(cpu_gpr[ret], v2_t, v1_t);
13372 break;
13373 default: /* Invalid */
13374 MIPS_INVAL("MASK SHLL.OB");
13375 generate_exception(ctx, EXCP_RI);
13376 break;
13378 break;
13379 #endif
13382 tcg_temp_free(t0);
13383 tcg_temp_free(v1_t);
13384 tcg_temp_free(v2_t);
13385 (void)opn; /* avoid a compiler warning */
13386 MIPS_DEBUG("%s", opn);
13389 static void gen_mipsdsp_multiply(DisasContext *ctx, uint32_t op1, uint32_t op2,
13390 int ret, int v1, int v2, int check_ret)
13392 const char *opn = "mipsdsp multiply";
13393 TCGv_i32 t0;
13394 TCGv v1_t;
13395 TCGv v2_t;
13397 if ((ret == 0) && (check_ret == 1)) {
13398 /* Treat as NOP. */
13399 MIPS_DEBUG("NOP");
13400 return;
13403 t0 = tcg_temp_new_i32();
13404 v1_t = tcg_temp_new();
13405 v2_t = tcg_temp_new();
13407 tcg_gen_movi_i32(t0, ret);
13408 gen_load_gpr(v1_t, v1);
13409 gen_load_gpr(v2_t, v2);
13411 switch (op1) {
13412 /* OPC_MULT_G_2E, OPC_ADDUH_QB_DSP, OPC_MUL_PH_DSP have
13413 * the same mask and op1. */
13414 case OPC_MULT_G_2E:
13415 check_dspr2(ctx);
13416 switch (op2) {
13417 case OPC_MUL_PH:
13418 gen_helper_mul_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13419 break;
13420 case OPC_MUL_S_PH:
13421 gen_helper_mul_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13422 break;
13423 case OPC_MULQ_S_W:
13424 gen_helper_mulq_s_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13425 break;
13426 case OPC_MULQ_RS_W:
13427 gen_helper_mulq_rs_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13428 break;
13430 break;
13431 case OPC_DPA_W_PH_DSP:
13432 switch (op2) {
13433 case OPC_DPAU_H_QBL:
13434 check_dsp(ctx);
13435 gen_helper_dpau_h_qbl(t0, v1_t, v2_t, cpu_env);
13436 break;
13437 case OPC_DPAU_H_QBR:
13438 check_dsp(ctx);
13439 gen_helper_dpau_h_qbr(t0, v1_t, v2_t, cpu_env);
13440 break;
13441 case OPC_DPSU_H_QBL:
13442 check_dsp(ctx);
13443 gen_helper_dpsu_h_qbl(t0, v1_t, v2_t, cpu_env);
13444 break;
13445 case OPC_DPSU_H_QBR:
13446 check_dsp(ctx);
13447 gen_helper_dpsu_h_qbr(t0, v1_t, v2_t, cpu_env);
13448 break;
13449 case OPC_DPA_W_PH:
13450 check_dspr2(ctx);
13451 gen_helper_dpa_w_ph(t0, v1_t, v2_t, cpu_env);
13452 break;
13453 case OPC_DPAX_W_PH:
13454 check_dspr2(ctx);
13455 gen_helper_dpax_w_ph(t0, v1_t, v2_t, cpu_env);
13456 break;
13457 case OPC_DPAQ_S_W_PH:
13458 check_dsp(ctx);
13459 gen_helper_dpaq_s_w_ph(t0, v1_t, v2_t, cpu_env);
13460 break;
13461 case OPC_DPAQX_S_W_PH:
13462 check_dspr2(ctx);
13463 gen_helper_dpaqx_s_w_ph(t0, v1_t, v2_t, cpu_env);
13464 break;
13465 case OPC_DPAQX_SA_W_PH:
13466 check_dspr2(ctx);
13467 gen_helper_dpaqx_sa_w_ph(t0, v1_t, v2_t, cpu_env);
13468 break;
13469 case OPC_DPS_W_PH:
13470 check_dspr2(ctx);
13471 gen_helper_dps_w_ph(t0, v1_t, v2_t, cpu_env);
13472 break;
13473 case OPC_DPSX_W_PH:
13474 check_dspr2(ctx);
13475 gen_helper_dpsx_w_ph(t0, v1_t, v2_t, cpu_env);
13476 break;
13477 case OPC_DPSQ_S_W_PH:
13478 check_dsp(ctx);
13479 gen_helper_dpsq_s_w_ph(t0, v1_t, v2_t, cpu_env);
13480 break;
13481 case OPC_DPSQX_S_W_PH:
13482 check_dspr2(ctx);
13483 gen_helper_dpsqx_s_w_ph(t0, v1_t, v2_t, cpu_env);
13484 break;
13485 case OPC_DPSQX_SA_W_PH:
13486 check_dspr2(ctx);
13487 gen_helper_dpsqx_sa_w_ph(t0, v1_t, v2_t, cpu_env);
13488 break;
13489 case OPC_MULSAQ_S_W_PH:
13490 check_dsp(ctx);
13491 gen_helper_mulsaq_s_w_ph(t0, v1_t, v2_t, cpu_env);
13492 break;
13493 case OPC_DPAQ_SA_L_W:
13494 check_dsp(ctx);
13495 gen_helper_dpaq_sa_l_w(t0, v1_t, v2_t, cpu_env);
13496 break;
13497 case OPC_DPSQ_SA_L_W:
13498 check_dsp(ctx);
13499 gen_helper_dpsq_sa_l_w(t0, v1_t, v2_t, cpu_env);
13500 break;
13501 case OPC_MAQ_S_W_PHL:
13502 check_dsp(ctx);
13503 gen_helper_maq_s_w_phl(t0, v1_t, v2_t, cpu_env);
13504 break;
13505 case OPC_MAQ_S_W_PHR:
13506 check_dsp(ctx);
13507 gen_helper_maq_s_w_phr(t0, v1_t, v2_t, cpu_env);
13508 break;
13509 case OPC_MAQ_SA_W_PHL:
13510 check_dsp(ctx);
13511 gen_helper_maq_sa_w_phl(t0, v1_t, v2_t, cpu_env);
13512 break;
13513 case OPC_MAQ_SA_W_PHR:
13514 check_dsp(ctx);
13515 gen_helper_maq_sa_w_phr(t0, v1_t, v2_t, cpu_env);
13516 break;
13517 case OPC_MULSA_W_PH:
13518 check_dspr2(ctx);
13519 gen_helper_mulsa_w_ph(t0, v1_t, v2_t, cpu_env);
13520 break;
13522 break;
13523 #ifdef TARGET_MIPS64
13524 case OPC_DPAQ_W_QH_DSP:
13526 int ac = ret & 0x03;
13527 tcg_gen_movi_i32(t0, ac);
13529 switch (op2) {
13530 case OPC_DMADD:
13531 check_dsp(ctx);
13532 gen_helper_dmadd(v1_t, v2_t, t0, cpu_env);
13533 break;
13534 case OPC_DMADDU:
13535 check_dsp(ctx);
13536 gen_helper_dmaddu(v1_t, v2_t, t0, cpu_env);
13537 break;
13538 case OPC_DMSUB:
13539 check_dsp(ctx);
13540 gen_helper_dmsub(v1_t, v2_t, t0, cpu_env);
13541 break;
13542 case OPC_DMSUBU:
13543 check_dsp(ctx);
13544 gen_helper_dmsubu(v1_t, v2_t, t0, cpu_env);
13545 break;
13546 case OPC_DPA_W_QH:
13547 check_dspr2(ctx);
13548 gen_helper_dpa_w_qh(v1_t, v2_t, t0, cpu_env);
13549 break;
13550 case OPC_DPAQ_S_W_QH:
13551 check_dsp(ctx);
13552 gen_helper_dpaq_s_w_qh(v1_t, v2_t, t0, cpu_env);
13553 break;
13554 case OPC_DPAQ_SA_L_PW:
13555 check_dsp(ctx);
13556 gen_helper_dpaq_sa_l_pw(v1_t, v2_t, t0, cpu_env);
13557 break;
13558 case OPC_DPAU_H_OBL:
13559 check_dsp(ctx);
13560 gen_helper_dpau_h_obl(v1_t, v2_t, t0, cpu_env);
13561 break;
13562 case OPC_DPAU_H_OBR:
13563 check_dsp(ctx);
13564 gen_helper_dpau_h_obr(v1_t, v2_t, t0, cpu_env);
13565 break;
13566 case OPC_DPS_W_QH:
13567 check_dspr2(ctx);
13568 gen_helper_dps_w_qh(v1_t, v2_t, t0, cpu_env);
13569 break;
13570 case OPC_DPSQ_S_W_QH:
13571 check_dsp(ctx);
13572 gen_helper_dpsq_s_w_qh(v1_t, v2_t, t0, cpu_env);
13573 break;
13574 case OPC_DPSQ_SA_L_PW:
13575 check_dsp(ctx);
13576 gen_helper_dpsq_sa_l_pw(v1_t, v2_t, t0, cpu_env);
13577 break;
13578 case OPC_DPSU_H_OBL:
13579 check_dsp(ctx);
13580 gen_helper_dpsu_h_obl(v1_t, v2_t, t0, cpu_env);
13581 break;
13582 case OPC_DPSU_H_OBR:
13583 check_dsp(ctx);
13584 gen_helper_dpsu_h_obr(v1_t, v2_t, t0, cpu_env);
13585 break;
13586 case OPC_MAQ_S_L_PWL:
13587 check_dsp(ctx);
13588 gen_helper_maq_s_l_pwl(v1_t, v2_t, t0, cpu_env);
13589 break;
13590 case OPC_MAQ_S_L_PWR:
13591 check_dsp(ctx);
13592 gen_helper_maq_s_l_pwr(v1_t, v2_t, t0, cpu_env);
13593 break;
13594 case OPC_MAQ_S_W_QHLL:
13595 check_dsp(ctx);
13596 gen_helper_maq_s_w_qhll(v1_t, v2_t, t0, cpu_env);
13597 break;
13598 case OPC_MAQ_SA_W_QHLL:
13599 check_dsp(ctx);
13600 gen_helper_maq_sa_w_qhll(v1_t, v2_t, t0, cpu_env);
13601 break;
13602 case OPC_MAQ_S_W_QHLR:
13603 check_dsp(ctx);
13604 gen_helper_maq_s_w_qhlr(v1_t, v2_t, t0, cpu_env);
13605 break;
13606 case OPC_MAQ_SA_W_QHLR:
13607 check_dsp(ctx);
13608 gen_helper_maq_sa_w_qhlr(v1_t, v2_t, t0, cpu_env);
13609 break;
13610 case OPC_MAQ_S_W_QHRL:
13611 check_dsp(ctx);
13612 gen_helper_maq_s_w_qhrl(v1_t, v2_t, t0, cpu_env);
13613 break;
13614 case OPC_MAQ_SA_W_QHRL:
13615 check_dsp(ctx);
13616 gen_helper_maq_sa_w_qhrl(v1_t, v2_t, t0, cpu_env);
13617 break;
13618 case OPC_MAQ_S_W_QHRR:
13619 check_dsp(ctx);
13620 gen_helper_maq_s_w_qhrr(v1_t, v2_t, t0, cpu_env);
13621 break;
13622 case OPC_MAQ_SA_W_QHRR:
13623 check_dsp(ctx);
13624 gen_helper_maq_sa_w_qhrr(v1_t, v2_t, t0, cpu_env);
13625 break;
13626 case OPC_MULSAQ_S_L_PW:
13627 check_dsp(ctx);
13628 gen_helper_mulsaq_s_l_pw(v1_t, v2_t, t0, cpu_env);
13629 break;
13630 case OPC_MULSAQ_S_W_QH:
13631 check_dsp(ctx);
13632 gen_helper_mulsaq_s_w_qh(v1_t, v2_t, t0, cpu_env);
13633 break;
13636 break;
13637 #endif
13638 case OPC_ADDU_QB_DSP:
13639 switch (op2) {
13640 case OPC_MULEU_S_PH_QBL:
13641 check_dsp(ctx);
13642 gen_helper_muleu_s_ph_qbl(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13643 break;
13644 case OPC_MULEU_S_PH_QBR:
13645 check_dsp(ctx);
13646 gen_helper_muleu_s_ph_qbr(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13647 break;
13648 case OPC_MULQ_RS_PH:
13649 check_dsp(ctx);
13650 gen_helper_mulq_rs_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13651 break;
13652 case OPC_MULEQ_S_W_PHL:
13653 check_dsp(ctx);
13654 gen_helper_muleq_s_w_phl(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13655 break;
13656 case OPC_MULEQ_S_W_PHR:
13657 check_dsp(ctx);
13658 gen_helper_muleq_s_w_phr(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13659 break;
13660 case OPC_MULQ_S_PH:
13661 check_dspr2(ctx);
13662 gen_helper_mulq_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13663 break;
13665 break;
13666 #ifdef TARGET_MIPS64
13667 case OPC_ADDU_OB_DSP:
13668 switch (op2) {
13669 case OPC_MULEQ_S_PW_QHL:
13670 check_dsp(ctx);
13671 gen_helper_muleq_s_pw_qhl(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13672 break;
13673 case OPC_MULEQ_S_PW_QHR:
13674 check_dsp(ctx);
13675 gen_helper_muleq_s_pw_qhr(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13676 break;
13677 case OPC_MULEU_S_QH_OBL:
13678 check_dsp(ctx);
13679 gen_helper_muleu_s_qh_obl(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13680 break;
13681 case OPC_MULEU_S_QH_OBR:
13682 check_dsp(ctx);
13683 gen_helper_muleu_s_qh_obr(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13684 break;
13685 case OPC_MULQ_RS_QH:
13686 check_dsp(ctx);
13687 gen_helper_mulq_rs_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13688 break;
13690 break;
13691 #endif
13694 tcg_temp_free_i32(t0);
13695 tcg_temp_free(v1_t);
13696 tcg_temp_free(v2_t);
13698 (void)opn; /* avoid a compiler warning */
13699 MIPS_DEBUG("%s", opn);
13703 static void gen_mipsdsp_bitinsn(DisasContext *ctx, uint32_t op1, uint32_t op2,
13704 int ret, int val)
13706 const char *opn = "mipsdsp Bit/ Manipulation";
13707 int16_t imm;
13708 TCGv t0;
13709 TCGv val_t;
13711 if (ret == 0) {
13712 /* Treat as NOP. */
13713 MIPS_DEBUG("NOP");
13714 return;
13717 t0 = tcg_temp_new();
13718 val_t = tcg_temp_new();
13719 gen_load_gpr(val_t, val);
13721 switch (op1) {
13722 case OPC_ABSQ_S_PH_DSP:
13723 switch (op2) {
13724 case OPC_BITREV:
13725 check_dsp(ctx);
13726 gen_helper_bitrev(cpu_gpr[ret], val_t);
13727 break;
13728 case OPC_REPL_QB:
13729 check_dsp(ctx);
13731 target_long result;
13732 imm = (ctx->opcode >> 16) & 0xFF;
13733 result = (uint32_t)imm << 24 |
13734 (uint32_t)imm << 16 |
13735 (uint32_t)imm << 8 |
13736 (uint32_t)imm;
13737 result = (int32_t)result;
13738 tcg_gen_movi_tl(cpu_gpr[ret], result);
13740 break;
13741 case OPC_REPLV_QB:
13742 check_dsp(ctx);
13743 tcg_gen_ext8u_tl(cpu_gpr[ret], val_t);
13744 tcg_gen_shli_tl(t0, cpu_gpr[ret], 8);
13745 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
13746 tcg_gen_shli_tl(t0, cpu_gpr[ret], 16);
13747 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
13748 tcg_gen_ext32s_tl(cpu_gpr[ret], cpu_gpr[ret]);
13749 break;
13750 case OPC_REPL_PH:
13751 check_dsp(ctx);
13753 imm = (ctx->opcode >> 16) & 0x03FF;
13754 imm = (int16_t)(imm << 6) >> 6;
13755 tcg_gen_movi_tl(cpu_gpr[ret], \
13756 (target_long)((int32_t)imm << 16 | \
13757 (uint16_t)imm));
13759 break;
13760 case OPC_REPLV_PH:
13761 check_dsp(ctx);
13762 tcg_gen_ext16u_tl(cpu_gpr[ret], val_t);
13763 tcg_gen_shli_tl(t0, cpu_gpr[ret], 16);
13764 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
13765 tcg_gen_ext32s_tl(cpu_gpr[ret], cpu_gpr[ret]);
13766 break;
13768 break;
13769 #ifdef TARGET_MIPS64
13770 case OPC_ABSQ_S_QH_DSP:
13771 switch (op2) {
13772 case OPC_REPL_OB:
13773 check_dsp(ctx);
13775 target_long temp;
13777 imm = (ctx->opcode >> 16) & 0xFF;
13778 temp = ((uint64_t)imm << 8) | (uint64_t)imm;
13779 temp = (temp << 16) | temp;
13780 temp = (temp << 32) | temp;
13781 tcg_gen_movi_tl(cpu_gpr[ret], temp);
13782 break;
13784 case OPC_REPL_PW:
13785 check_dsp(ctx);
13787 target_long temp;
13789 imm = (ctx->opcode >> 16) & 0x03FF;
13790 imm = (int16_t)(imm << 6) >> 6;
13791 temp = ((target_long)imm << 32) \
13792 | ((target_long)imm & 0xFFFFFFFF);
13793 tcg_gen_movi_tl(cpu_gpr[ret], temp);
13794 break;
13796 case OPC_REPL_QH:
13797 check_dsp(ctx);
13799 target_long temp;
13801 imm = (ctx->opcode >> 16) & 0x03FF;
13802 imm = (int16_t)(imm << 6) >> 6;
13804 temp = ((uint64_t)(uint16_t)imm << 48) |
13805 ((uint64_t)(uint16_t)imm << 32) |
13806 ((uint64_t)(uint16_t)imm << 16) |
13807 (uint64_t)(uint16_t)imm;
13808 tcg_gen_movi_tl(cpu_gpr[ret], temp);
13809 break;
13811 case OPC_REPLV_OB:
13812 check_dsp(ctx);
13813 tcg_gen_ext8u_tl(cpu_gpr[ret], val_t);
13814 tcg_gen_shli_tl(t0, cpu_gpr[ret], 8);
13815 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
13816 tcg_gen_shli_tl(t0, cpu_gpr[ret], 16);
13817 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
13818 tcg_gen_shli_tl(t0, cpu_gpr[ret], 32);
13819 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
13820 break;
13821 case OPC_REPLV_PW:
13822 check_dsp(ctx);
13823 tcg_gen_ext32u_i64(cpu_gpr[ret], val_t);
13824 tcg_gen_shli_tl(t0, cpu_gpr[ret], 32);
13825 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
13826 break;
13827 case OPC_REPLV_QH:
13828 check_dsp(ctx);
13829 tcg_gen_ext16u_tl(cpu_gpr[ret], val_t);
13830 tcg_gen_shli_tl(t0, cpu_gpr[ret], 16);
13831 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
13832 tcg_gen_shli_tl(t0, cpu_gpr[ret], 32);
13833 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
13834 break;
13836 break;
13837 #endif
13839 tcg_temp_free(t0);
13840 tcg_temp_free(val_t);
13842 (void)opn; /* avoid a compiler warning */
13843 MIPS_DEBUG("%s", opn);
13846 static void gen_mipsdsp_add_cmp_pick(DisasContext *ctx,
13847 uint32_t op1, uint32_t op2,
13848 int ret, int v1, int v2, int check_ret)
13850 const char *opn = "mipsdsp add compare pick";
13851 TCGv t1;
13852 TCGv v1_t;
13853 TCGv v2_t;
13855 if ((ret == 0) && (check_ret == 1)) {
13856 /* Treat as NOP. */
13857 MIPS_DEBUG("NOP");
13858 return;
13861 t1 = tcg_temp_new();
13862 v1_t = tcg_temp_new();
13863 v2_t = tcg_temp_new();
13865 gen_load_gpr(v1_t, v1);
13866 gen_load_gpr(v2_t, v2);
13868 switch (op1) {
13869 case OPC_CMPU_EQ_QB_DSP:
13870 switch (op2) {
13871 case OPC_CMPU_EQ_QB:
13872 check_dsp(ctx);
13873 gen_helper_cmpu_eq_qb(v1_t, v2_t, cpu_env);
13874 break;
13875 case OPC_CMPU_LT_QB:
13876 check_dsp(ctx);
13877 gen_helper_cmpu_lt_qb(v1_t, v2_t, cpu_env);
13878 break;
13879 case OPC_CMPU_LE_QB:
13880 check_dsp(ctx);
13881 gen_helper_cmpu_le_qb(v1_t, v2_t, cpu_env);
13882 break;
13883 case OPC_CMPGU_EQ_QB:
13884 check_dsp(ctx);
13885 gen_helper_cmpgu_eq_qb(cpu_gpr[ret], v1_t, v2_t);
13886 break;
13887 case OPC_CMPGU_LT_QB:
13888 check_dsp(ctx);
13889 gen_helper_cmpgu_lt_qb(cpu_gpr[ret], v1_t, v2_t);
13890 break;
13891 case OPC_CMPGU_LE_QB:
13892 check_dsp(ctx);
13893 gen_helper_cmpgu_le_qb(cpu_gpr[ret], v1_t, v2_t);
13894 break;
13895 case OPC_CMPGDU_EQ_QB:
13896 check_dspr2(ctx);
13897 gen_helper_cmpgu_eq_qb(t1, v1_t, v2_t);
13898 tcg_gen_mov_tl(cpu_gpr[ret], t1);
13899 tcg_gen_andi_tl(cpu_dspctrl, cpu_dspctrl, 0xF0FFFFFF);
13900 tcg_gen_shli_tl(t1, t1, 24);
13901 tcg_gen_or_tl(cpu_dspctrl, cpu_dspctrl, t1);
13902 break;
13903 case OPC_CMPGDU_LT_QB:
13904 check_dspr2(ctx);
13905 gen_helper_cmpgu_lt_qb(t1, v1_t, v2_t);
13906 tcg_gen_mov_tl(cpu_gpr[ret], t1);
13907 tcg_gen_andi_tl(cpu_dspctrl, cpu_dspctrl, 0xF0FFFFFF);
13908 tcg_gen_shli_tl(t1, t1, 24);
13909 tcg_gen_or_tl(cpu_dspctrl, cpu_dspctrl, t1);
13910 break;
13911 case OPC_CMPGDU_LE_QB:
13912 check_dspr2(ctx);
13913 gen_helper_cmpgu_le_qb(t1, v1_t, v2_t);
13914 tcg_gen_mov_tl(cpu_gpr[ret], t1);
13915 tcg_gen_andi_tl(cpu_dspctrl, cpu_dspctrl, 0xF0FFFFFF);
13916 tcg_gen_shli_tl(t1, t1, 24);
13917 tcg_gen_or_tl(cpu_dspctrl, cpu_dspctrl, t1);
13918 break;
13919 case OPC_CMP_EQ_PH:
13920 check_dsp(ctx);
13921 gen_helper_cmp_eq_ph(v1_t, v2_t, cpu_env);
13922 break;
13923 case OPC_CMP_LT_PH:
13924 check_dsp(ctx);
13925 gen_helper_cmp_lt_ph(v1_t, v2_t, cpu_env);
13926 break;
13927 case OPC_CMP_LE_PH:
13928 check_dsp(ctx);
13929 gen_helper_cmp_le_ph(v1_t, v2_t, cpu_env);
13930 break;
13931 case OPC_PICK_QB:
13932 check_dsp(ctx);
13933 gen_helper_pick_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13934 break;
13935 case OPC_PICK_PH:
13936 check_dsp(ctx);
13937 gen_helper_pick_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13938 break;
13939 case OPC_PACKRL_PH:
13940 check_dsp(ctx);
13941 gen_helper_packrl_ph(cpu_gpr[ret], v1_t, v2_t);
13942 break;
13944 break;
13945 #ifdef TARGET_MIPS64
13946 case OPC_CMPU_EQ_OB_DSP:
13947 switch (op2) {
13948 case OPC_CMP_EQ_PW:
13949 check_dsp(ctx);
13950 gen_helper_cmp_eq_pw(v1_t, v2_t, cpu_env);
13951 break;
13952 case OPC_CMP_LT_PW:
13953 check_dsp(ctx);
13954 gen_helper_cmp_lt_pw(v1_t, v2_t, cpu_env);
13955 break;
13956 case OPC_CMP_LE_PW:
13957 check_dsp(ctx);
13958 gen_helper_cmp_le_pw(v1_t, v2_t, cpu_env);
13959 break;
13960 case OPC_CMP_EQ_QH:
13961 check_dsp(ctx);
13962 gen_helper_cmp_eq_qh(v1_t, v2_t, cpu_env);
13963 break;
13964 case OPC_CMP_LT_QH:
13965 check_dsp(ctx);
13966 gen_helper_cmp_lt_qh(v1_t, v2_t, cpu_env);
13967 break;
13968 case OPC_CMP_LE_QH:
13969 check_dsp(ctx);
13970 gen_helper_cmp_le_qh(v1_t, v2_t, cpu_env);
13971 break;
13972 case OPC_CMPGDU_EQ_OB:
13973 check_dspr2(ctx);
13974 gen_helper_cmpgdu_eq_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13975 break;
13976 case OPC_CMPGDU_LT_OB:
13977 check_dspr2(ctx);
13978 gen_helper_cmpgdu_lt_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13979 break;
13980 case OPC_CMPGDU_LE_OB:
13981 check_dspr2(ctx);
13982 gen_helper_cmpgdu_le_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13983 break;
13984 case OPC_CMPGU_EQ_OB:
13985 check_dsp(ctx);
13986 gen_helper_cmpgu_eq_ob(cpu_gpr[ret], v1_t, v2_t);
13987 break;
13988 case OPC_CMPGU_LT_OB:
13989 check_dsp(ctx);
13990 gen_helper_cmpgu_lt_ob(cpu_gpr[ret], v1_t, v2_t);
13991 break;
13992 case OPC_CMPGU_LE_OB:
13993 check_dsp(ctx);
13994 gen_helper_cmpgu_le_ob(cpu_gpr[ret], v1_t, v2_t);
13995 break;
13996 case OPC_CMPU_EQ_OB:
13997 check_dsp(ctx);
13998 gen_helper_cmpu_eq_ob(v1_t, v2_t, cpu_env);
13999 break;
14000 case OPC_CMPU_LT_OB:
14001 check_dsp(ctx);
14002 gen_helper_cmpu_lt_ob(v1_t, v2_t, cpu_env);
14003 break;
14004 case OPC_CMPU_LE_OB:
14005 check_dsp(ctx);
14006 gen_helper_cmpu_le_ob(v1_t, v2_t, cpu_env);
14007 break;
14008 case OPC_PACKRL_PW:
14009 check_dsp(ctx);
14010 gen_helper_packrl_pw(cpu_gpr[ret], v1_t, v2_t);
14011 break;
14012 case OPC_PICK_OB:
14013 check_dsp(ctx);
14014 gen_helper_pick_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
14015 break;
14016 case OPC_PICK_PW:
14017 check_dsp(ctx);
14018 gen_helper_pick_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
14019 break;
14020 case OPC_PICK_QH:
14021 check_dsp(ctx);
14022 gen_helper_pick_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
14023 break;
14025 break;
14026 #endif
14029 tcg_temp_free(t1);
14030 tcg_temp_free(v1_t);
14031 tcg_temp_free(v2_t);
14033 (void)opn; /* avoid a compiler warning */
14034 MIPS_DEBUG("%s", opn);
14037 static void gen_mipsdsp_append(CPUMIPSState *env, DisasContext *ctx,
14038 uint32_t op1, int rt, int rs, int sa)
14040 const char *opn = "mipsdsp append/dappend";
14041 TCGv t0;
14043 check_dspr2(ctx);
14045 if (rt == 0) {
14046 /* Treat as NOP. */
14047 MIPS_DEBUG("NOP");
14048 return;
14051 t0 = tcg_temp_new();
14052 gen_load_gpr(t0, rs);
14054 switch (op1) {
14055 case OPC_APPEND_DSP:
14056 switch (MASK_APPEND(ctx->opcode)) {
14057 case OPC_APPEND:
14058 if (sa != 0) {
14059 tcg_gen_deposit_tl(cpu_gpr[rt], t0, cpu_gpr[rt], sa, 32 - sa);
14061 tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]);
14062 break;
14063 case OPC_PREPEND:
14064 if (sa != 0) {
14065 tcg_gen_ext32u_tl(cpu_gpr[rt], cpu_gpr[rt]);
14066 tcg_gen_shri_tl(cpu_gpr[rt], cpu_gpr[rt], sa);
14067 tcg_gen_shli_tl(t0, t0, 32 - sa);
14068 tcg_gen_or_tl(cpu_gpr[rt], cpu_gpr[rt], t0);
14070 tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]);
14071 break;
14072 case OPC_BALIGN:
14073 sa &= 3;
14074 if (sa != 0 && sa != 2) {
14075 tcg_gen_shli_tl(cpu_gpr[rt], cpu_gpr[rt], 8 * sa);
14076 tcg_gen_ext32u_tl(t0, t0);
14077 tcg_gen_shri_tl(t0, t0, 8 * (4 - sa));
14078 tcg_gen_or_tl(cpu_gpr[rt], cpu_gpr[rt], t0);
14080 tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]);
14081 break;
14082 default: /* Invalid */
14083 MIPS_INVAL("MASK APPEND");
14084 generate_exception(ctx, EXCP_RI);
14085 break;
14087 break;
14088 #ifdef TARGET_MIPS64
14089 case OPC_DAPPEND_DSP:
14090 switch (MASK_DAPPEND(ctx->opcode)) {
14091 case OPC_DAPPEND:
14092 if (sa != 0) {
14093 tcg_gen_deposit_tl(cpu_gpr[rt], t0, cpu_gpr[rt], sa, 64 - sa);
14095 break;
14096 case OPC_PREPENDD:
14097 tcg_gen_shri_tl(cpu_gpr[rt], cpu_gpr[rt], 0x20 | sa);
14098 tcg_gen_shli_tl(t0, t0, 64 - (0x20 | sa));
14099 tcg_gen_or_tl(cpu_gpr[rt], t0, t0);
14100 break;
14101 case OPC_PREPENDW:
14102 if (sa != 0) {
14103 tcg_gen_shri_tl(cpu_gpr[rt], cpu_gpr[rt], sa);
14104 tcg_gen_shli_tl(t0, t0, 64 - sa);
14105 tcg_gen_or_tl(cpu_gpr[rt], cpu_gpr[rt], t0);
14107 break;
14108 case OPC_DBALIGN:
14109 sa &= 7;
14110 if (sa != 0 && sa != 2 && sa != 4) {
14111 tcg_gen_shli_tl(cpu_gpr[rt], cpu_gpr[rt], 8 * sa);
14112 tcg_gen_shri_tl(t0, t0, 8 * (8 - sa));
14113 tcg_gen_or_tl(cpu_gpr[rt], cpu_gpr[rt], t0);
14115 break;
14116 default: /* Invalid */
14117 MIPS_INVAL("MASK DAPPEND");
14118 generate_exception(ctx, EXCP_RI);
14119 break;
14121 break;
14122 #endif
14124 tcg_temp_free(t0);
14125 (void)opn; /* avoid a compiler warning */
14126 MIPS_DEBUG("%s", opn);
14129 static void gen_mipsdsp_accinsn(DisasContext *ctx, uint32_t op1, uint32_t op2,
14130 int ret, int v1, int v2, int check_ret)
14133 const char *opn = "mipsdsp accumulator";
14134 TCGv t0;
14135 TCGv t1;
14136 TCGv v1_t;
14137 TCGv v2_t;
14138 int16_t imm;
14140 if ((ret == 0) && (check_ret == 1)) {
14141 /* Treat as NOP. */
14142 MIPS_DEBUG("NOP");
14143 return;
14146 t0 = tcg_temp_new();
14147 t1 = tcg_temp_new();
14148 v1_t = tcg_temp_new();
14149 v2_t = tcg_temp_new();
14151 gen_load_gpr(v1_t, v1);
14152 gen_load_gpr(v2_t, v2);
14154 switch (op1) {
14155 case OPC_EXTR_W_DSP:
14156 check_dsp(ctx);
14157 switch (op2) {
14158 case OPC_EXTR_W:
14159 tcg_gen_movi_tl(t0, v2);
14160 tcg_gen_movi_tl(t1, v1);
14161 gen_helper_extr_w(cpu_gpr[ret], t0, t1, cpu_env);
14162 break;
14163 case OPC_EXTR_R_W:
14164 tcg_gen_movi_tl(t0, v2);
14165 tcg_gen_movi_tl(t1, v1);
14166 gen_helper_extr_r_w(cpu_gpr[ret], t0, t1, cpu_env);
14167 break;
14168 case OPC_EXTR_RS_W:
14169 tcg_gen_movi_tl(t0, v2);
14170 tcg_gen_movi_tl(t1, v1);
14171 gen_helper_extr_rs_w(cpu_gpr[ret], t0, t1, cpu_env);
14172 break;
14173 case OPC_EXTR_S_H:
14174 tcg_gen_movi_tl(t0, v2);
14175 tcg_gen_movi_tl(t1, v1);
14176 gen_helper_extr_s_h(cpu_gpr[ret], t0, t1, cpu_env);
14177 break;
14178 case OPC_EXTRV_S_H:
14179 tcg_gen_movi_tl(t0, v2);
14180 gen_helper_extr_s_h(cpu_gpr[ret], t0, v1_t, cpu_env);
14181 break;
14182 case OPC_EXTRV_W:
14183 tcg_gen_movi_tl(t0, v2);
14184 gen_helper_extr_w(cpu_gpr[ret], t0, v1_t, cpu_env);
14185 break;
14186 case OPC_EXTRV_R_W:
14187 tcg_gen_movi_tl(t0, v2);
14188 gen_helper_extr_r_w(cpu_gpr[ret], t0, v1_t, cpu_env);
14189 break;
14190 case OPC_EXTRV_RS_W:
14191 tcg_gen_movi_tl(t0, v2);
14192 gen_helper_extr_rs_w(cpu_gpr[ret], t0, v1_t, cpu_env);
14193 break;
14194 case OPC_EXTP:
14195 tcg_gen_movi_tl(t0, v2);
14196 tcg_gen_movi_tl(t1, v1);
14197 gen_helper_extp(cpu_gpr[ret], t0, t1, cpu_env);
14198 break;
14199 case OPC_EXTPV:
14200 tcg_gen_movi_tl(t0, v2);
14201 gen_helper_extp(cpu_gpr[ret], t0, v1_t, cpu_env);
14202 break;
14203 case OPC_EXTPDP:
14204 tcg_gen_movi_tl(t0, v2);
14205 tcg_gen_movi_tl(t1, v1);
14206 gen_helper_extpdp(cpu_gpr[ret], t0, t1, cpu_env);
14207 break;
14208 case OPC_EXTPDPV:
14209 tcg_gen_movi_tl(t0, v2);
14210 gen_helper_extpdp(cpu_gpr[ret], t0, v1_t, cpu_env);
14211 break;
14212 case OPC_SHILO:
14213 imm = (ctx->opcode >> 20) & 0x3F;
14214 tcg_gen_movi_tl(t0, ret);
14215 tcg_gen_movi_tl(t1, imm);
14216 gen_helper_shilo(t0, t1, cpu_env);
14217 break;
14218 case OPC_SHILOV:
14219 tcg_gen_movi_tl(t0, ret);
14220 gen_helper_shilo(t0, v1_t, cpu_env);
14221 break;
14222 case OPC_MTHLIP:
14223 tcg_gen_movi_tl(t0, ret);
14224 gen_helper_mthlip(t0, v1_t, cpu_env);
14225 break;
14226 case OPC_WRDSP:
14227 imm = (ctx->opcode >> 11) & 0x3FF;
14228 tcg_gen_movi_tl(t0, imm);
14229 gen_helper_wrdsp(v1_t, t0, cpu_env);
14230 break;
14231 case OPC_RDDSP:
14232 imm = (ctx->opcode >> 16) & 0x03FF;
14233 tcg_gen_movi_tl(t0, imm);
14234 gen_helper_rddsp(cpu_gpr[ret], t0, cpu_env);
14235 break;
14237 break;
14238 #ifdef TARGET_MIPS64
14239 case OPC_DEXTR_W_DSP:
14240 check_dsp(ctx);
14241 switch (op2) {
14242 case OPC_DMTHLIP:
14243 tcg_gen_movi_tl(t0, ret);
14244 gen_helper_dmthlip(v1_t, t0, cpu_env);
14245 break;
14246 case OPC_DSHILO:
14248 int shift = (ctx->opcode >> 19) & 0x7F;
14249 int ac = (ctx->opcode >> 11) & 0x03;
14250 tcg_gen_movi_tl(t0, shift);
14251 tcg_gen_movi_tl(t1, ac);
14252 gen_helper_dshilo(t0, t1, cpu_env);
14253 break;
14255 case OPC_DSHILOV:
14257 int ac = (ctx->opcode >> 11) & 0x03;
14258 tcg_gen_movi_tl(t0, ac);
14259 gen_helper_dshilo(v1_t, t0, cpu_env);
14260 break;
14262 case OPC_DEXTP:
14263 tcg_gen_movi_tl(t0, v2);
14264 tcg_gen_movi_tl(t1, v1);
14266 gen_helper_dextp(cpu_gpr[ret], t0, t1, cpu_env);
14267 break;
14268 case OPC_DEXTPV:
14269 tcg_gen_movi_tl(t0, v2);
14270 gen_helper_dextp(cpu_gpr[ret], t0, v1_t, cpu_env);
14271 break;
14272 case OPC_DEXTPDP:
14273 tcg_gen_movi_tl(t0, v2);
14274 tcg_gen_movi_tl(t1, v1);
14275 gen_helper_dextpdp(cpu_gpr[ret], t0, t1, cpu_env);
14276 break;
14277 case OPC_DEXTPDPV:
14278 tcg_gen_movi_tl(t0, v2);
14279 gen_helper_dextpdp(cpu_gpr[ret], t0, v1_t, cpu_env);
14280 break;
14281 case OPC_DEXTR_L:
14282 tcg_gen_movi_tl(t0, v2);
14283 tcg_gen_movi_tl(t1, v1);
14284 gen_helper_dextr_l(cpu_gpr[ret], t0, t1, cpu_env);
14285 break;
14286 case OPC_DEXTR_R_L:
14287 tcg_gen_movi_tl(t0, v2);
14288 tcg_gen_movi_tl(t1, v1);
14289 gen_helper_dextr_r_l(cpu_gpr[ret], t0, t1, cpu_env);
14290 break;
14291 case OPC_DEXTR_RS_L:
14292 tcg_gen_movi_tl(t0, v2);
14293 tcg_gen_movi_tl(t1, v1);
14294 gen_helper_dextr_rs_l(cpu_gpr[ret], t0, t1, cpu_env);
14295 break;
14296 case OPC_DEXTR_W:
14297 tcg_gen_movi_tl(t0, v2);
14298 tcg_gen_movi_tl(t1, v1);
14299 gen_helper_dextr_w(cpu_gpr[ret], t0, t1, cpu_env);
14300 break;
14301 case OPC_DEXTR_R_W:
14302 tcg_gen_movi_tl(t0, v2);
14303 tcg_gen_movi_tl(t1, v1);
14304 gen_helper_dextr_r_w(cpu_gpr[ret], t0, t1, cpu_env);
14305 break;
14306 case OPC_DEXTR_RS_W:
14307 tcg_gen_movi_tl(t0, v2);
14308 tcg_gen_movi_tl(t1, v1);
14309 gen_helper_dextr_rs_w(cpu_gpr[ret], t0, t1, cpu_env);
14310 break;
14311 case OPC_DEXTR_S_H:
14312 tcg_gen_movi_tl(t0, v2);
14313 tcg_gen_movi_tl(t1, v1);
14314 gen_helper_dextr_s_h(cpu_gpr[ret], t0, t1, cpu_env);
14315 break;
14316 case OPC_DEXTRV_S_H:
14317 tcg_gen_movi_tl(t0, v2);
14318 tcg_gen_movi_tl(t1, v1);
14319 gen_helper_dextr_s_h(cpu_gpr[ret], t0, t1, cpu_env);
14320 break;
14321 case OPC_DEXTRV_L:
14322 tcg_gen_movi_tl(t0, v2);
14323 gen_helper_dextr_l(cpu_gpr[ret], t0, v1_t, cpu_env);
14324 break;
14325 case OPC_DEXTRV_R_L:
14326 tcg_gen_movi_tl(t0, v2);
14327 gen_helper_dextr_r_l(cpu_gpr[ret], t0, v1_t, cpu_env);
14328 break;
14329 case OPC_DEXTRV_RS_L:
14330 tcg_gen_movi_tl(t0, v2);
14331 gen_helper_dextr_rs_l(cpu_gpr[ret], t0, v1_t, cpu_env);
14332 break;
14333 case OPC_DEXTRV_W:
14334 tcg_gen_movi_tl(t0, v2);
14335 gen_helper_dextr_w(cpu_gpr[ret], t0, v1_t, cpu_env);
14336 break;
14337 case OPC_DEXTRV_R_W:
14338 tcg_gen_movi_tl(t0, v2);
14339 gen_helper_dextr_r_w(cpu_gpr[ret], t0, v1_t, cpu_env);
14340 break;
14341 case OPC_DEXTRV_RS_W:
14342 tcg_gen_movi_tl(t0, v2);
14343 gen_helper_dextr_rs_w(cpu_gpr[ret], t0, v1_t, cpu_env);
14344 break;
14346 break;
14347 #endif
14350 tcg_temp_free(t0);
14351 tcg_temp_free(t1);
14352 tcg_temp_free(v1_t);
14353 tcg_temp_free(v2_t);
14355 (void)opn; /* avoid a compiler warning */
14356 MIPS_DEBUG("%s", opn);
14359 /* End MIPSDSP functions. */
14361 static void decode_opc (CPUMIPSState *env, DisasContext *ctx)
14363 int32_t offset;
14364 int rs, rt, rd, sa;
14365 uint32_t op, op1, op2;
14366 int16_t imm;
14368 /* make sure instructions are on a word boundary */
14369 if (ctx->pc & 0x3) {
14370 env->CP0_BadVAddr = ctx->pc;
14371 generate_exception(ctx, EXCP_AdEL);
14372 return;
14375 /* Handle blikely not taken case */
14376 if ((ctx->hflags & MIPS_HFLAG_BMASK_BASE) == MIPS_HFLAG_BL) {
14377 int l1 = gen_new_label();
14379 MIPS_DEBUG("blikely condition (" TARGET_FMT_lx ")", ctx->pc + 4);
14380 tcg_gen_brcondi_tl(TCG_COND_NE, bcond, 0, l1);
14381 tcg_gen_movi_i32(hflags, ctx->hflags & ~MIPS_HFLAG_BMASK);
14382 gen_goto_tb(ctx, 1, ctx->pc + 4);
14383 gen_set_label(l1);
14386 if (unlikely(qemu_loglevel_mask(CPU_LOG_TB_OP | CPU_LOG_TB_OP_OPT))) {
14387 tcg_gen_debug_insn_start(ctx->pc);
14390 op = MASK_OP_MAJOR(ctx->opcode);
14391 rs = (ctx->opcode >> 21) & 0x1f;
14392 rt = (ctx->opcode >> 16) & 0x1f;
14393 rd = (ctx->opcode >> 11) & 0x1f;
14394 sa = (ctx->opcode >> 6) & 0x1f;
14395 imm = (int16_t)ctx->opcode;
14396 switch (op) {
14397 case OPC_SPECIAL:
14398 op1 = MASK_SPECIAL(ctx->opcode);
14399 switch (op1) {
14400 case OPC_SLL: /* Shift with immediate */
14401 case OPC_SRA:
14402 gen_shift_imm(ctx, op1, rd, rt, sa);
14403 break;
14404 case OPC_SRL:
14405 switch ((ctx->opcode >> 21) & 0x1f) {
14406 case 1:
14407 /* rotr is decoded as srl on non-R2 CPUs */
14408 if (ctx->insn_flags & ISA_MIPS32R2) {
14409 op1 = OPC_ROTR;
14411 /* Fallthrough */
14412 case 0:
14413 gen_shift_imm(ctx, op1, rd, rt, sa);
14414 break;
14415 default:
14416 generate_exception(ctx, EXCP_RI);
14417 break;
14419 break;
14420 case OPC_MOVN: /* Conditional move */
14421 case OPC_MOVZ:
14422 check_insn(ctx, ISA_MIPS4 | ISA_MIPS32 |
14423 INSN_LOONGSON2E | INSN_LOONGSON2F);
14424 gen_cond_move(ctx, op1, rd, rs, rt);
14425 break;
14426 case OPC_ADD ... OPC_SUBU:
14427 gen_arith(ctx, op1, rd, rs, rt);
14428 break;
14429 case OPC_SLLV: /* Shifts */
14430 case OPC_SRAV:
14431 gen_shift(ctx, op1, rd, rs, rt);
14432 break;
14433 case OPC_SRLV:
14434 switch ((ctx->opcode >> 6) & 0x1f) {
14435 case 1:
14436 /* rotrv is decoded as srlv on non-R2 CPUs */
14437 if (ctx->insn_flags & ISA_MIPS32R2) {
14438 op1 = OPC_ROTRV;
14440 /* Fallthrough */
14441 case 0:
14442 gen_shift(ctx, op1, rd, rs, rt);
14443 break;
14444 default:
14445 generate_exception(ctx, EXCP_RI);
14446 break;
14448 break;
14449 case OPC_SLT: /* Set on less than */
14450 case OPC_SLTU:
14451 gen_slt(ctx, op1, rd, rs, rt);
14452 break;
14453 case OPC_AND: /* Logic*/
14454 case OPC_OR:
14455 case OPC_NOR:
14456 case OPC_XOR:
14457 gen_logic(ctx, op1, rd, rs, rt);
14458 break;
14459 case OPC_MULT:
14460 case OPC_MULTU:
14461 if (sa) {
14462 check_insn(ctx, INSN_VR54XX);
14463 op1 = MASK_MUL_VR54XX(ctx->opcode);
14464 gen_mul_vr54xx(ctx, op1, rd, rs, rt);
14465 } else {
14466 gen_muldiv(ctx, op1, rd & 3, rs, rt);
14468 break;
14469 case OPC_DIV:
14470 case OPC_DIVU:
14471 gen_muldiv(ctx, op1, 0, rs, rt);
14472 break;
14473 case OPC_JR ... OPC_JALR:
14474 gen_compute_branch(ctx, op1, 4, rs, rd, sa);
14475 break;
14476 case OPC_TGE ... OPC_TEQ: /* Traps */
14477 case OPC_TNE:
14478 gen_trap(ctx, op1, rs, rt, -1);
14479 break;
14480 case OPC_MFHI: /* Move from HI/LO */
14481 case OPC_MFLO:
14482 gen_HILO(ctx, op1, rs & 3, rd);
14483 break;
14484 case OPC_MTHI:
14485 case OPC_MTLO: /* Move to HI/LO */
14486 gen_HILO(ctx, op1, rd & 3, rs);
14487 break;
14488 case OPC_PMON: /* Pmon entry point, also R4010 selsl */
14489 #ifdef MIPS_STRICT_STANDARD
14490 MIPS_INVAL("PMON / selsl");
14491 generate_exception(ctx, EXCP_RI);
14492 #else
14493 gen_helper_0e0i(pmon, sa);
14494 #endif
14495 break;
14496 case OPC_SYSCALL:
14497 generate_exception(ctx, EXCP_SYSCALL);
14498 ctx->bstate = BS_STOP;
14499 break;
14500 case OPC_BREAK:
14501 generate_exception(ctx, EXCP_BREAK);
14502 break;
14503 case OPC_SPIM:
14504 #ifdef MIPS_STRICT_STANDARD
14505 MIPS_INVAL("SPIM");
14506 generate_exception(ctx, EXCP_RI);
14507 #else
14508 /* Implemented as RI exception for now. */
14509 MIPS_INVAL("spim (unofficial)");
14510 generate_exception(ctx, EXCP_RI);
14511 #endif
14512 break;
14513 case OPC_SYNC:
14514 /* Treat as NOP. */
14515 break;
14517 case OPC_MOVCI:
14518 check_insn(ctx, ISA_MIPS4 | ISA_MIPS32);
14519 if (env->CP0_Config1 & (1 << CP0C1_FP)) {
14520 check_cp1_enabled(ctx);
14521 gen_movci(ctx, rd, rs, (ctx->opcode >> 18) & 0x7,
14522 (ctx->opcode >> 16) & 1);
14523 } else {
14524 generate_exception_err(ctx, EXCP_CpU, 1);
14526 break;
14528 #if defined(TARGET_MIPS64)
14529 /* MIPS64 specific opcodes */
14530 case OPC_DSLL:
14531 case OPC_DSRA:
14532 case OPC_DSLL32:
14533 case OPC_DSRA32:
14534 check_insn(ctx, ISA_MIPS3);
14535 check_mips_64(ctx);
14536 gen_shift_imm(ctx, op1, rd, rt, sa);
14537 break;
14538 case OPC_DSRL:
14539 switch ((ctx->opcode >> 21) & 0x1f) {
14540 case 1:
14541 /* drotr is decoded as dsrl on non-R2 CPUs */
14542 if (ctx->insn_flags & ISA_MIPS32R2) {
14543 op1 = OPC_DROTR;
14545 /* Fallthrough */
14546 case 0:
14547 check_insn(ctx, ISA_MIPS3);
14548 check_mips_64(ctx);
14549 gen_shift_imm(ctx, op1, rd, rt, sa);
14550 break;
14551 default:
14552 generate_exception(ctx, EXCP_RI);
14553 break;
14555 break;
14556 case OPC_DSRL32:
14557 switch ((ctx->opcode >> 21) & 0x1f) {
14558 case 1:
14559 /* drotr32 is decoded as dsrl32 on non-R2 CPUs */
14560 if (ctx->insn_flags & ISA_MIPS32R2) {
14561 op1 = OPC_DROTR32;
14563 /* Fallthrough */
14564 case 0:
14565 check_insn(ctx, ISA_MIPS3);
14566 check_mips_64(ctx);
14567 gen_shift_imm(ctx, op1, rd, rt, sa);
14568 break;
14569 default:
14570 generate_exception(ctx, EXCP_RI);
14571 break;
14573 break;
14574 case OPC_DADD ... OPC_DSUBU:
14575 check_insn(ctx, ISA_MIPS3);
14576 check_mips_64(ctx);
14577 gen_arith(ctx, op1, rd, rs, rt);
14578 break;
14579 case OPC_DSLLV:
14580 case OPC_DSRAV:
14581 check_insn(ctx, ISA_MIPS3);
14582 check_mips_64(ctx);
14583 gen_shift(ctx, op1, rd, rs, rt);
14584 break;
14585 case OPC_DSRLV:
14586 switch ((ctx->opcode >> 6) & 0x1f) {
14587 case 1:
14588 /* drotrv is decoded as dsrlv on non-R2 CPUs */
14589 if (ctx->insn_flags & ISA_MIPS32R2) {
14590 op1 = OPC_DROTRV;
14592 /* Fallthrough */
14593 case 0:
14594 check_insn(ctx, ISA_MIPS3);
14595 check_mips_64(ctx);
14596 gen_shift(ctx, op1, rd, rs, rt);
14597 break;
14598 default:
14599 generate_exception(ctx, EXCP_RI);
14600 break;
14602 break;
14603 case OPC_DMULT ... OPC_DDIVU:
14604 check_insn(ctx, ISA_MIPS3);
14605 check_mips_64(ctx);
14606 gen_muldiv(ctx, op1, 0, rs, rt);
14607 break;
14608 #endif
14609 default: /* Invalid */
14610 MIPS_INVAL("special");
14611 generate_exception(ctx, EXCP_RI);
14612 break;
14614 break;
14615 case OPC_SPECIAL2:
14616 op1 = MASK_SPECIAL2(ctx->opcode);
14617 switch (op1) {
14618 case OPC_MADD ... OPC_MADDU: /* Multiply and add/sub */
14619 case OPC_MSUB ... OPC_MSUBU:
14620 check_insn(ctx, ISA_MIPS32);
14621 gen_muldiv(ctx, op1, rd & 3, rs, rt);
14622 break;
14623 case OPC_MUL:
14624 gen_arith(ctx, op1, rd, rs, rt);
14625 break;
14626 case OPC_CLO:
14627 case OPC_CLZ:
14628 check_insn(ctx, ISA_MIPS32);
14629 gen_cl(ctx, op1, rd, rs);
14630 break;
14631 case OPC_SDBBP:
14632 /* XXX: not clear which exception should be raised
14633 * when in debug mode...
14635 check_insn(ctx, ISA_MIPS32);
14636 if (!(ctx->hflags & MIPS_HFLAG_DM)) {
14637 generate_exception(ctx, EXCP_DBp);
14638 } else {
14639 generate_exception(ctx, EXCP_DBp);
14641 /* Treat as NOP. */
14642 break;
14643 case OPC_DIV_G_2F:
14644 case OPC_DIVU_G_2F:
14645 case OPC_MULT_G_2F:
14646 case OPC_MULTU_G_2F:
14647 case OPC_MOD_G_2F:
14648 case OPC_MODU_G_2F:
14649 check_insn(ctx, INSN_LOONGSON2F);
14650 gen_loongson_integer(ctx, op1, rd, rs, rt);
14651 break;
14652 #if defined(TARGET_MIPS64)
14653 case OPC_DCLO:
14654 case OPC_DCLZ:
14655 check_insn(ctx, ISA_MIPS64);
14656 check_mips_64(ctx);
14657 gen_cl(ctx, op1, rd, rs);
14658 break;
14659 case OPC_DMULT_G_2F:
14660 case OPC_DMULTU_G_2F:
14661 case OPC_DDIV_G_2F:
14662 case OPC_DDIVU_G_2F:
14663 case OPC_DMOD_G_2F:
14664 case OPC_DMODU_G_2F:
14665 check_insn(ctx, INSN_LOONGSON2F);
14666 gen_loongson_integer(ctx, op1, rd, rs, rt);
14667 break;
14668 #endif
14669 default: /* Invalid */
14670 MIPS_INVAL("special2");
14671 generate_exception(ctx, EXCP_RI);
14672 break;
14674 break;
14675 case OPC_SPECIAL3:
14676 op1 = MASK_SPECIAL3(ctx->opcode);
14677 switch (op1) {
14678 case OPC_EXT:
14679 case OPC_INS:
14680 check_insn(ctx, ISA_MIPS32R2);
14681 gen_bitops(ctx, op1, rt, rs, sa, rd);
14682 break;
14683 case OPC_BSHFL:
14684 check_insn(ctx, ISA_MIPS32R2);
14685 op2 = MASK_BSHFL(ctx->opcode);
14686 gen_bshfl(ctx, op2, rt, rd);
14687 break;
14688 case OPC_RDHWR:
14689 gen_rdhwr(ctx, rt, rd);
14690 break;
14691 case OPC_FORK:
14692 check_insn(ctx, ASE_MT);
14694 TCGv t0 = tcg_temp_new();
14695 TCGv t1 = tcg_temp_new();
14697 gen_load_gpr(t0, rt);
14698 gen_load_gpr(t1, rs);
14699 gen_helper_fork(t0, t1);
14700 tcg_temp_free(t0);
14701 tcg_temp_free(t1);
14703 break;
14704 case OPC_YIELD:
14705 check_insn(ctx, ASE_MT);
14707 TCGv t0 = tcg_temp_new();
14709 save_cpu_state(ctx, 1);
14710 gen_load_gpr(t0, rs);
14711 gen_helper_yield(t0, cpu_env, t0);
14712 gen_store_gpr(t0, rd);
14713 tcg_temp_free(t0);
14715 break;
14716 case OPC_DIV_G_2E ... OPC_DIVU_G_2E:
14717 case OPC_MOD_G_2E ... OPC_MODU_G_2E:
14718 case OPC_MULT_G_2E ... OPC_MULTU_G_2E:
14719 /* OPC_MULT_G_2E, OPC_ADDUH_QB_DSP, OPC_MUL_PH_DSP have
14720 * the same mask and op1. */
14721 if ((ctx->insn_flags & ASE_DSPR2) && (op1 == OPC_MULT_G_2E)) {
14722 op2 = MASK_ADDUH_QB(ctx->opcode);
14723 switch (op2) {
14724 case OPC_ADDUH_QB:
14725 case OPC_ADDUH_R_QB:
14726 case OPC_ADDQH_PH:
14727 case OPC_ADDQH_R_PH:
14728 case OPC_ADDQH_W:
14729 case OPC_ADDQH_R_W:
14730 case OPC_SUBUH_QB:
14731 case OPC_SUBUH_R_QB:
14732 case OPC_SUBQH_PH:
14733 case OPC_SUBQH_R_PH:
14734 case OPC_SUBQH_W:
14735 case OPC_SUBQH_R_W:
14736 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
14737 break;
14738 case OPC_MUL_PH:
14739 case OPC_MUL_S_PH:
14740 case OPC_MULQ_S_W:
14741 case OPC_MULQ_RS_W:
14742 gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 1);
14743 break;
14744 default:
14745 MIPS_INVAL("MASK ADDUH.QB");
14746 generate_exception(ctx, EXCP_RI);
14747 break;
14749 } else if (ctx->insn_flags & INSN_LOONGSON2E) {
14750 gen_loongson_integer(ctx, op1, rd, rs, rt);
14751 } else {
14752 generate_exception(ctx, EXCP_RI);
14754 break;
14755 case OPC_LX_DSP:
14756 op2 = MASK_LX(ctx->opcode);
14757 switch (op2) {
14758 #if defined(TARGET_MIPS64)
14759 case OPC_LDX:
14760 #endif
14761 case OPC_LBUX:
14762 case OPC_LHX:
14763 case OPC_LWX:
14764 gen_mipsdsp_ld(ctx, op2, rd, rs, rt);
14765 break;
14766 default: /* Invalid */
14767 MIPS_INVAL("MASK LX");
14768 generate_exception(ctx, EXCP_RI);
14769 break;
14771 break;
14772 case OPC_ABSQ_S_PH_DSP:
14773 op2 = MASK_ABSQ_S_PH(ctx->opcode);
14774 switch (op2) {
14775 case OPC_ABSQ_S_QB:
14776 case OPC_ABSQ_S_PH:
14777 case OPC_ABSQ_S_W:
14778 case OPC_PRECEQ_W_PHL:
14779 case OPC_PRECEQ_W_PHR:
14780 case OPC_PRECEQU_PH_QBL:
14781 case OPC_PRECEQU_PH_QBR:
14782 case OPC_PRECEQU_PH_QBLA:
14783 case OPC_PRECEQU_PH_QBRA:
14784 case OPC_PRECEU_PH_QBL:
14785 case OPC_PRECEU_PH_QBR:
14786 case OPC_PRECEU_PH_QBLA:
14787 case OPC_PRECEU_PH_QBRA:
14788 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
14789 break;
14790 case OPC_BITREV:
14791 case OPC_REPL_QB:
14792 case OPC_REPLV_QB:
14793 case OPC_REPL_PH:
14794 case OPC_REPLV_PH:
14795 gen_mipsdsp_bitinsn(ctx, op1, op2, rd, rt);
14796 break;
14797 default:
14798 MIPS_INVAL("MASK ABSQ_S.PH");
14799 generate_exception(ctx, EXCP_RI);
14800 break;
14802 break;
14803 case OPC_ADDU_QB_DSP:
14804 op2 = MASK_ADDU_QB(ctx->opcode);
14805 switch (op2) {
14806 case OPC_ADDQ_PH:
14807 case OPC_ADDQ_S_PH:
14808 case OPC_ADDQ_S_W:
14809 case OPC_ADDU_QB:
14810 case OPC_ADDU_S_QB:
14811 case OPC_ADDU_PH:
14812 case OPC_ADDU_S_PH:
14813 case OPC_SUBQ_PH:
14814 case OPC_SUBQ_S_PH:
14815 case OPC_SUBQ_S_W:
14816 case OPC_SUBU_QB:
14817 case OPC_SUBU_S_QB:
14818 case OPC_SUBU_PH:
14819 case OPC_SUBU_S_PH:
14820 case OPC_ADDSC:
14821 case OPC_ADDWC:
14822 case OPC_MODSUB:
14823 case OPC_RADDU_W_QB:
14824 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
14825 break;
14826 case OPC_MULEU_S_PH_QBL:
14827 case OPC_MULEU_S_PH_QBR:
14828 case OPC_MULQ_RS_PH:
14829 case OPC_MULEQ_S_W_PHL:
14830 case OPC_MULEQ_S_W_PHR:
14831 case OPC_MULQ_S_PH:
14832 gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 1);
14833 break;
14834 default: /* Invalid */
14835 MIPS_INVAL("MASK ADDU.QB");
14836 generate_exception(ctx, EXCP_RI);
14837 break;
14840 break;
14841 case OPC_CMPU_EQ_QB_DSP:
14842 op2 = MASK_CMPU_EQ_QB(ctx->opcode);
14843 switch (op2) {
14844 case OPC_PRECR_SRA_PH_W:
14845 case OPC_PRECR_SRA_R_PH_W:
14846 gen_mipsdsp_arith(ctx, op1, op2, rt, rs, rd);
14847 break;
14848 case OPC_PRECR_QB_PH:
14849 case OPC_PRECRQ_QB_PH:
14850 case OPC_PRECRQ_PH_W:
14851 case OPC_PRECRQ_RS_PH_W:
14852 case OPC_PRECRQU_S_QB_PH:
14853 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
14854 break;
14855 case OPC_CMPU_EQ_QB:
14856 case OPC_CMPU_LT_QB:
14857 case OPC_CMPU_LE_QB:
14858 case OPC_CMP_EQ_PH:
14859 case OPC_CMP_LT_PH:
14860 case OPC_CMP_LE_PH:
14861 gen_mipsdsp_add_cmp_pick(ctx, op1, op2, rd, rs, rt, 0);
14862 break;
14863 case OPC_CMPGU_EQ_QB:
14864 case OPC_CMPGU_LT_QB:
14865 case OPC_CMPGU_LE_QB:
14866 case OPC_CMPGDU_EQ_QB:
14867 case OPC_CMPGDU_LT_QB:
14868 case OPC_CMPGDU_LE_QB:
14869 case OPC_PICK_QB:
14870 case OPC_PICK_PH:
14871 case OPC_PACKRL_PH:
14872 gen_mipsdsp_add_cmp_pick(ctx, op1, op2, rd, rs, rt, 1);
14873 break;
14874 default: /* Invalid */
14875 MIPS_INVAL("MASK CMPU.EQ.QB");
14876 generate_exception(ctx, EXCP_RI);
14877 break;
14879 break;
14880 case OPC_SHLL_QB_DSP:
14881 gen_mipsdsp_shift(ctx, op1, rd, rs, rt);
14882 break;
14883 case OPC_DPA_W_PH_DSP:
14884 op2 = MASK_DPA_W_PH(ctx->opcode);
14885 switch (op2) {
14886 case OPC_DPAU_H_QBL:
14887 case OPC_DPAU_H_QBR:
14888 case OPC_DPSU_H_QBL:
14889 case OPC_DPSU_H_QBR:
14890 case OPC_DPA_W_PH:
14891 case OPC_DPAX_W_PH:
14892 case OPC_DPAQ_S_W_PH:
14893 case OPC_DPAQX_S_W_PH:
14894 case OPC_DPAQX_SA_W_PH:
14895 case OPC_DPS_W_PH:
14896 case OPC_DPSX_W_PH:
14897 case OPC_DPSQ_S_W_PH:
14898 case OPC_DPSQX_S_W_PH:
14899 case OPC_DPSQX_SA_W_PH:
14900 case OPC_MULSAQ_S_W_PH:
14901 case OPC_DPAQ_SA_L_W:
14902 case OPC_DPSQ_SA_L_W:
14903 case OPC_MAQ_S_W_PHL:
14904 case OPC_MAQ_S_W_PHR:
14905 case OPC_MAQ_SA_W_PHL:
14906 case OPC_MAQ_SA_W_PHR:
14907 case OPC_MULSA_W_PH:
14908 gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 0);
14909 break;
14910 default: /* Invalid */
14911 MIPS_INVAL("MASK DPAW.PH");
14912 generate_exception(ctx, EXCP_RI);
14913 break;
14915 break;
14916 case OPC_INSV_DSP:
14917 op2 = MASK_INSV(ctx->opcode);
14918 switch (op2) {
14919 case OPC_INSV:
14920 check_dsp(ctx);
14922 TCGv t0, t1;
14924 if (rt == 0) {
14925 MIPS_DEBUG("NOP");
14926 break;
14929 t0 = tcg_temp_new();
14930 t1 = tcg_temp_new();
14932 gen_load_gpr(t0, rt);
14933 gen_load_gpr(t1, rs);
14935 gen_helper_insv(cpu_gpr[rt], cpu_env, t1, t0);
14937 tcg_temp_free(t0);
14938 tcg_temp_free(t1);
14939 break;
14941 default: /* Invalid */
14942 MIPS_INVAL("MASK INSV");
14943 generate_exception(ctx, EXCP_RI);
14944 break;
14946 break;
14947 case OPC_APPEND_DSP:
14948 gen_mipsdsp_append(env, ctx, op1, rt, rs, rd);
14949 break;
14950 case OPC_EXTR_W_DSP:
14951 op2 = MASK_EXTR_W(ctx->opcode);
14952 switch (op2) {
14953 case OPC_EXTR_W:
14954 case OPC_EXTR_R_W:
14955 case OPC_EXTR_RS_W:
14956 case OPC_EXTR_S_H:
14957 case OPC_EXTRV_S_H:
14958 case OPC_EXTRV_W:
14959 case OPC_EXTRV_R_W:
14960 case OPC_EXTRV_RS_W:
14961 case OPC_EXTP:
14962 case OPC_EXTPV:
14963 case OPC_EXTPDP:
14964 case OPC_EXTPDPV:
14965 gen_mipsdsp_accinsn(ctx, op1, op2, rt, rs, rd, 1);
14966 break;
14967 case OPC_RDDSP:
14968 gen_mipsdsp_accinsn(ctx, op1, op2, rd, rs, rt, 1);
14969 break;
14970 case OPC_SHILO:
14971 case OPC_SHILOV:
14972 case OPC_MTHLIP:
14973 case OPC_WRDSP:
14974 gen_mipsdsp_accinsn(ctx, op1, op2, rd, rs, rt, 0);
14975 break;
14976 default: /* Invalid */
14977 MIPS_INVAL("MASK EXTR.W");
14978 generate_exception(ctx, EXCP_RI);
14979 break;
14981 break;
14982 #if defined(TARGET_MIPS64)
14983 case OPC_DEXTM ... OPC_DEXT:
14984 case OPC_DINSM ... OPC_DINS:
14985 check_insn(ctx, ISA_MIPS64R2);
14986 check_mips_64(ctx);
14987 gen_bitops(ctx, op1, rt, rs, sa, rd);
14988 break;
14989 case OPC_DBSHFL:
14990 check_insn(ctx, ISA_MIPS64R2);
14991 check_mips_64(ctx);
14992 op2 = MASK_DBSHFL(ctx->opcode);
14993 gen_bshfl(ctx, op2, rt, rd);
14994 break;
14995 case OPC_DDIV_G_2E ... OPC_DDIVU_G_2E:
14996 case OPC_DMULT_G_2E ... OPC_DMULTU_G_2E:
14997 case OPC_DMOD_G_2E ... OPC_DMODU_G_2E:
14998 check_insn(ctx, INSN_LOONGSON2E);
14999 gen_loongson_integer(ctx, op1, rd, rs, rt);
15000 break;
15001 case OPC_ABSQ_S_QH_DSP:
15002 op2 = MASK_ABSQ_S_QH(ctx->opcode);
15003 switch (op2) {
15004 case OPC_PRECEQ_L_PWL:
15005 case OPC_PRECEQ_L_PWR:
15006 case OPC_PRECEQ_PW_QHL:
15007 case OPC_PRECEQ_PW_QHR:
15008 case OPC_PRECEQ_PW_QHLA:
15009 case OPC_PRECEQ_PW_QHRA:
15010 case OPC_PRECEQU_QH_OBL:
15011 case OPC_PRECEQU_QH_OBR:
15012 case OPC_PRECEQU_QH_OBLA:
15013 case OPC_PRECEQU_QH_OBRA:
15014 case OPC_PRECEU_QH_OBL:
15015 case OPC_PRECEU_QH_OBR:
15016 case OPC_PRECEU_QH_OBLA:
15017 case OPC_PRECEU_QH_OBRA:
15018 case OPC_ABSQ_S_OB:
15019 case OPC_ABSQ_S_PW:
15020 case OPC_ABSQ_S_QH:
15021 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
15022 break;
15023 case OPC_REPL_OB:
15024 case OPC_REPL_PW:
15025 case OPC_REPL_QH:
15026 case OPC_REPLV_OB:
15027 case OPC_REPLV_PW:
15028 case OPC_REPLV_QH:
15029 gen_mipsdsp_bitinsn(ctx, op1, op2, rd, rt);
15030 break;
15031 default: /* Invalid */
15032 MIPS_INVAL("MASK ABSQ_S.QH");
15033 generate_exception(ctx, EXCP_RI);
15034 break;
15036 break;
15037 case OPC_ADDU_OB_DSP:
15038 op2 = MASK_ADDU_OB(ctx->opcode);
15039 switch (op2) {
15040 case OPC_RADDU_L_OB:
15041 case OPC_SUBQ_PW:
15042 case OPC_SUBQ_S_PW:
15043 case OPC_SUBQ_QH:
15044 case OPC_SUBQ_S_QH:
15045 case OPC_SUBU_OB:
15046 case OPC_SUBU_S_OB:
15047 case OPC_SUBU_QH:
15048 case OPC_SUBU_S_QH:
15049 case OPC_SUBUH_OB:
15050 case OPC_SUBUH_R_OB:
15051 case OPC_ADDQ_PW:
15052 case OPC_ADDQ_S_PW:
15053 case OPC_ADDQ_QH:
15054 case OPC_ADDQ_S_QH:
15055 case OPC_ADDU_OB:
15056 case OPC_ADDU_S_OB:
15057 case OPC_ADDU_QH:
15058 case OPC_ADDU_S_QH:
15059 case OPC_ADDUH_OB:
15060 case OPC_ADDUH_R_OB:
15061 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
15062 break;
15063 case OPC_MULEQ_S_PW_QHL:
15064 case OPC_MULEQ_S_PW_QHR:
15065 case OPC_MULEU_S_QH_OBL:
15066 case OPC_MULEU_S_QH_OBR:
15067 case OPC_MULQ_RS_QH:
15068 gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 1);
15069 break;
15070 default: /* Invalid */
15071 MIPS_INVAL("MASK ADDU.OB");
15072 generate_exception(ctx, EXCP_RI);
15073 break;
15075 break;
15076 case OPC_CMPU_EQ_OB_DSP:
15077 op2 = MASK_CMPU_EQ_OB(ctx->opcode);
15078 switch (op2) {
15079 case OPC_PRECR_SRA_QH_PW:
15080 case OPC_PRECR_SRA_R_QH_PW:
15081 /* Return value is rt. */
15082 gen_mipsdsp_arith(ctx, op1, op2, rt, rs, rd);
15083 break;
15084 case OPC_PRECR_OB_QH:
15085 case OPC_PRECRQ_OB_QH:
15086 case OPC_PRECRQ_PW_L:
15087 case OPC_PRECRQ_QH_PW:
15088 case OPC_PRECRQ_RS_QH_PW:
15089 case OPC_PRECRQU_S_OB_QH:
15090 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
15091 break;
15092 case OPC_CMPU_EQ_OB:
15093 case OPC_CMPU_LT_OB:
15094 case OPC_CMPU_LE_OB:
15095 case OPC_CMP_EQ_QH:
15096 case OPC_CMP_LT_QH:
15097 case OPC_CMP_LE_QH:
15098 case OPC_CMP_EQ_PW:
15099 case OPC_CMP_LT_PW:
15100 case OPC_CMP_LE_PW:
15101 gen_mipsdsp_add_cmp_pick(ctx, op1, op2, rd, rs, rt, 0);
15102 break;
15103 case OPC_CMPGDU_EQ_OB:
15104 case OPC_CMPGDU_LT_OB:
15105 case OPC_CMPGDU_LE_OB:
15106 case OPC_CMPGU_EQ_OB:
15107 case OPC_CMPGU_LT_OB:
15108 case OPC_CMPGU_LE_OB:
15109 case OPC_PACKRL_PW:
15110 case OPC_PICK_OB:
15111 case OPC_PICK_PW:
15112 case OPC_PICK_QH:
15113 gen_mipsdsp_add_cmp_pick(ctx, op1, op2, rd, rs, rt, 1);
15114 break;
15115 default: /* Invalid */
15116 MIPS_INVAL("MASK CMPU_EQ.OB");
15117 generate_exception(ctx, EXCP_RI);
15118 break;
15120 break;
15121 case OPC_DAPPEND_DSP:
15122 gen_mipsdsp_append(env, ctx, op1, rt, rs, rd);
15123 break;
15124 case OPC_DEXTR_W_DSP:
15125 op2 = MASK_DEXTR_W(ctx->opcode);
15126 switch (op2) {
15127 case OPC_DEXTP:
15128 case OPC_DEXTPDP:
15129 case OPC_DEXTPDPV:
15130 case OPC_DEXTPV:
15131 case OPC_DEXTR_L:
15132 case OPC_DEXTR_R_L:
15133 case OPC_DEXTR_RS_L:
15134 case OPC_DEXTR_W:
15135 case OPC_DEXTR_R_W:
15136 case OPC_DEXTR_RS_W:
15137 case OPC_DEXTR_S_H:
15138 case OPC_DEXTRV_L:
15139 case OPC_DEXTRV_R_L:
15140 case OPC_DEXTRV_RS_L:
15141 case OPC_DEXTRV_S_H:
15142 case OPC_DEXTRV_W:
15143 case OPC_DEXTRV_R_W:
15144 case OPC_DEXTRV_RS_W:
15145 gen_mipsdsp_accinsn(ctx, op1, op2, rt, rs, rd, 1);
15146 break;
15147 case OPC_DMTHLIP:
15148 case OPC_DSHILO:
15149 case OPC_DSHILOV:
15150 gen_mipsdsp_accinsn(ctx, op1, op2, rd, rs, rt, 0);
15151 break;
15152 default: /* Invalid */
15153 MIPS_INVAL("MASK EXTR.W");
15154 generate_exception(ctx, EXCP_RI);
15155 break;
15157 break;
15158 case OPC_DPAQ_W_QH_DSP:
15159 op2 = MASK_DPAQ_W_QH(ctx->opcode);
15160 switch (op2) {
15161 case OPC_DPAU_H_OBL:
15162 case OPC_DPAU_H_OBR:
15163 case OPC_DPSU_H_OBL:
15164 case OPC_DPSU_H_OBR:
15165 case OPC_DPA_W_QH:
15166 case OPC_DPAQ_S_W_QH:
15167 case OPC_DPS_W_QH:
15168 case OPC_DPSQ_S_W_QH:
15169 case OPC_MULSAQ_S_W_QH:
15170 case OPC_DPAQ_SA_L_PW:
15171 case OPC_DPSQ_SA_L_PW:
15172 case OPC_MULSAQ_S_L_PW:
15173 gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 0);
15174 break;
15175 case OPC_MAQ_S_W_QHLL:
15176 case OPC_MAQ_S_W_QHLR:
15177 case OPC_MAQ_S_W_QHRL:
15178 case OPC_MAQ_S_W_QHRR:
15179 case OPC_MAQ_SA_W_QHLL:
15180 case OPC_MAQ_SA_W_QHLR:
15181 case OPC_MAQ_SA_W_QHRL:
15182 case OPC_MAQ_SA_W_QHRR:
15183 case OPC_MAQ_S_L_PWL:
15184 case OPC_MAQ_S_L_PWR:
15185 case OPC_DMADD:
15186 case OPC_DMADDU:
15187 case OPC_DMSUB:
15188 case OPC_DMSUBU:
15189 gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 0);
15190 break;
15191 default: /* Invalid */
15192 MIPS_INVAL("MASK DPAQ.W.QH");
15193 generate_exception(ctx, EXCP_RI);
15194 break;
15196 break;
15197 case OPC_DINSV_DSP:
15198 op2 = MASK_INSV(ctx->opcode);
15199 switch (op2) {
15200 case OPC_DINSV:
15202 TCGv t0, t1;
15204 if (rt == 0) {
15205 MIPS_DEBUG("NOP");
15206 break;
15208 check_dsp(ctx);
15210 t0 = tcg_temp_new();
15211 t1 = tcg_temp_new();
15213 gen_load_gpr(t0, rt);
15214 gen_load_gpr(t1, rs);
15216 gen_helper_dinsv(cpu_gpr[rt], cpu_env, t1, t0);
15217 break;
15219 default: /* Invalid */
15220 MIPS_INVAL("MASK DINSV");
15221 generate_exception(ctx, EXCP_RI);
15222 break;
15224 break;
15225 case OPC_SHLL_OB_DSP:
15226 gen_mipsdsp_shift(ctx, op1, rd, rs, rt);
15227 break;
15228 #endif
15229 default: /* Invalid */
15230 MIPS_INVAL("special3");
15231 generate_exception(ctx, EXCP_RI);
15232 break;
15234 break;
15235 case OPC_REGIMM:
15236 op1 = MASK_REGIMM(ctx->opcode);
15237 switch (op1) {
15238 case OPC_BLTZ ... OPC_BGEZL: /* REGIMM branches */
15239 case OPC_BLTZAL ... OPC_BGEZALL:
15240 gen_compute_branch(ctx, op1, 4, rs, -1, imm << 2);
15241 break;
15242 case OPC_TGEI ... OPC_TEQI: /* REGIMM traps */
15243 case OPC_TNEI:
15244 gen_trap(ctx, op1, rs, -1, imm);
15245 break;
15246 case OPC_SYNCI:
15247 check_insn(ctx, ISA_MIPS32R2);
15248 /* Treat as NOP. */
15249 break;
15250 case OPC_BPOSGE32: /* MIPS DSP branch */
15251 #if defined(TARGET_MIPS64)
15252 case OPC_BPOSGE64:
15253 #endif
15254 check_dsp(ctx);
15255 gen_compute_branch(ctx, op1, 4, -1, -2, (int32_t)imm << 2);
15256 break;
15257 default: /* Invalid */
15258 MIPS_INVAL("regimm");
15259 generate_exception(ctx, EXCP_RI);
15260 break;
15262 break;
15263 case OPC_CP0:
15264 check_cp0_enabled(ctx);
15265 op1 = MASK_CP0(ctx->opcode);
15266 switch (op1) {
15267 case OPC_MFC0:
15268 case OPC_MTC0:
15269 case OPC_MFTR:
15270 case OPC_MTTR:
15271 #if defined(TARGET_MIPS64)
15272 case OPC_DMFC0:
15273 case OPC_DMTC0:
15274 #endif
15275 #ifndef CONFIG_USER_ONLY
15276 gen_cp0(env, ctx, op1, rt, rd);
15277 #endif /* !CONFIG_USER_ONLY */
15278 break;
15279 case OPC_C0_FIRST ... OPC_C0_LAST:
15280 #ifndef CONFIG_USER_ONLY
15281 gen_cp0(env, ctx, MASK_C0(ctx->opcode), rt, rd);
15282 #endif /* !CONFIG_USER_ONLY */
15283 break;
15284 case OPC_MFMC0:
15285 #ifndef CONFIG_USER_ONLY
15287 TCGv t0 = tcg_temp_new();
15289 op2 = MASK_MFMC0(ctx->opcode);
15290 switch (op2) {
15291 case OPC_DMT:
15292 check_insn(ctx, ASE_MT);
15293 gen_helper_dmt(t0);
15294 gen_store_gpr(t0, rt);
15295 break;
15296 case OPC_EMT:
15297 check_insn(ctx, ASE_MT);
15298 gen_helper_emt(t0);
15299 gen_store_gpr(t0, rt);
15300 break;
15301 case OPC_DVPE:
15302 check_insn(ctx, ASE_MT);
15303 gen_helper_dvpe(t0, cpu_env);
15304 gen_store_gpr(t0, rt);
15305 break;
15306 case OPC_EVPE:
15307 check_insn(ctx, ASE_MT);
15308 gen_helper_evpe(t0, cpu_env);
15309 gen_store_gpr(t0, rt);
15310 break;
15311 case OPC_DI:
15312 check_insn(ctx, ISA_MIPS32R2);
15313 save_cpu_state(ctx, 1);
15314 gen_helper_di(t0, cpu_env);
15315 gen_store_gpr(t0, rt);
15316 /* Stop translation as we may have switched the execution mode */
15317 ctx->bstate = BS_STOP;
15318 break;
15319 case OPC_EI:
15320 check_insn(ctx, ISA_MIPS32R2);
15321 save_cpu_state(ctx, 1);
15322 gen_helper_ei(t0, cpu_env);
15323 gen_store_gpr(t0, rt);
15324 /* Stop translation as we may have switched the execution mode */
15325 ctx->bstate = BS_STOP;
15326 break;
15327 default: /* Invalid */
15328 MIPS_INVAL("mfmc0");
15329 generate_exception(ctx, EXCP_RI);
15330 break;
15332 tcg_temp_free(t0);
15334 #endif /* !CONFIG_USER_ONLY */
15335 break;
15336 case OPC_RDPGPR:
15337 check_insn(ctx, ISA_MIPS32R2);
15338 gen_load_srsgpr(rt, rd);
15339 break;
15340 case OPC_WRPGPR:
15341 check_insn(ctx, ISA_MIPS32R2);
15342 gen_store_srsgpr(rt, rd);
15343 break;
15344 default:
15345 MIPS_INVAL("cp0");
15346 generate_exception(ctx, EXCP_RI);
15347 break;
15349 break;
15350 case OPC_ADDI: /* Arithmetic with immediate opcode */
15351 case OPC_ADDIU:
15352 gen_arith_imm(ctx, op, rt, rs, imm);
15353 break;
15354 case OPC_SLTI: /* Set on less than with immediate opcode */
15355 case OPC_SLTIU:
15356 gen_slt_imm(ctx, op, rt, rs, imm);
15357 break;
15358 case OPC_ANDI: /* Arithmetic with immediate opcode */
15359 case OPC_LUI:
15360 case OPC_ORI:
15361 case OPC_XORI:
15362 gen_logic_imm(ctx, op, rt, rs, imm);
15363 break;
15364 case OPC_J ... OPC_JAL: /* Jump */
15365 offset = (int32_t)(ctx->opcode & 0x3FFFFFF) << 2;
15366 gen_compute_branch(ctx, op, 4, rs, rt, offset);
15367 break;
15368 case OPC_BEQ ... OPC_BGTZ: /* Branch */
15369 case OPC_BEQL ... OPC_BGTZL:
15370 gen_compute_branch(ctx, op, 4, rs, rt, imm << 2);
15371 break;
15372 case OPC_LB ... OPC_LWR: /* Load and stores */
15373 case OPC_LL:
15374 gen_ld(ctx, op, rt, rs, imm);
15375 break;
15376 case OPC_SB ... OPC_SW:
15377 case OPC_SWR:
15378 gen_st(ctx, op, rt, rs, imm);
15379 break;
15380 case OPC_SC:
15381 gen_st_cond(ctx, op, rt, rs, imm);
15382 break;
15383 case OPC_CACHE:
15384 check_cp0_enabled(ctx);
15385 check_insn(ctx, ISA_MIPS3 | ISA_MIPS32);
15386 /* Treat as NOP. */
15387 break;
15388 case OPC_PREF:
15389 check_insn(ctx, ISA_MIPS4 | ISA_MIPS32);
15390 /* Treat as NOP. */
15391 break;
15393 /* Floating point (COP1). */
15394 case OPC_LWC1:
15395 case OPC_LDC1:
15396 case OPC_SWC1:
15397 case OPC_SDC1:
15398 gen_cop1_ldst(env, ctx, op, rt, rs, imm);
15399 break;
15401 case OPC_CP1:
15402 if (env->CP0_Config1 & (1 << CP0C1_FP)) {
15403 check_cp1_enabled(ctx);
15404 op1 = MASK_CP1(ctx->opcode);
15405 switch (op1) {
15406 case OPC_MFHC1:
15407 case OPC_MTHC1:
15408 check_insn(ctx, ISA_MIPS32R2);
15409 case OPC_MFC1:
15410 case OPC_CFC1:
15411 case OPC_MTC1:
15412 case OPC_CTC1:
15413 gen_cp1(ctx, op1, rt, rd);
15414 break;
15415 #if defined(TARGET_MIPS64)
15416 case OPC_DMFC1:
15417 case OPC_DMTC1:
15418 check_insn(ctx, ISA_MIPS3);
15419 gen_cp1(ctx, op1, rt, rd);
15420 break;
15421 #endif
15422 case OPC_BC1ANY2:
15423 case OPC_BC1ANY4:
15424 check_cop1x(ctx);
15425 check_insn(ctx, ASE_MIPS3D);
15426 /* fall through */
15427 case OPC_BC1:
15428 gen_compute_branch1(ctx, MASK_BC1(ctx->opcode),
15429 (rt >> 2) & 0x7, imm << 2);
15430 break;
15431 case OPC_S_FMT:
15432 case OPC_D_FMT:
15433 case OPC_W_FMT:
15434 case OPC_L_FMT:
15435 case OPC_PS_FMT:
15436 gen_farith(ctx, ctx->opcode & FOP(0x3f, 0x1f), rt, rd, sa,
15437 (imm >> 8) & 0x7);
15438 break;
15439 default:
15440 MIPS_INVAL("cp1");
15441 generate_exception (ctx, EXCP_RI);
15442 break;
15444 } else {
15445 generate_exception_err(ctx, EXCP_CpU, 1);
15447 break;
15449 /* COP2. */
15450 case OPC_LWC2:
15451 case OPC_LDC2:
15452 case OPC_SWC2:
15453 case OPC_SDC2:
15454 /* COP2: Not implemented. */
15455 generate_exception_err(ctx, EXCP_CpU, 2);
15456 break;
15457 case OPC_CP2:
15458 check_insn(ctx, INSN_LOONGSON2F);
15459 /* Note that these instructions use different fields. */
15460 gen_loongson_multimedia(ctx, sa, rd, rt);
15461 break;
15463 case OPC_CP3:
15464 if (env->CP0_Config1 & (1 << CP0C1_FP)) {
15465 check_cp1_enabled(ctx);
15466 op1 = MASK_CP3(ctx->opcode);
15467 switch (op1) {
15468 case OPC_LWXC1:
15469 case OPC_LDXC1:
15470 case OPC_LUXC1:
15471 case OPC_SWXC1:
15472 case OPC_SDXC1:
15473 case OPC_SUXC1:
15474 gen_flt3_ldst(ctx, op1, sa, rd, rs, rt);
15475 break;
15476 case OPC_PREFX:
15477 /* Treat as NOP. */
15478 break;
15479 case OPC_ALNV_PS:
15480 case OPC_MADD_S:
15481 case OPC_MADD_D:
15482 case OPC_MADD_PS:
15483 case OPC_MSUB_S:
15484 case OPC_MSUB_D:
15485 case OPC_MSUB_PS:
15486 case OPC_NMADD_S:
15487 case OPC_NMADD_D:
15488 case OPC_NMADD_PS:
15489 case OPC_NMSUB_S:
15490 case OPC_NMSUB_D:
15491 case OPC_NMSUB_PS:
15492 gen_flt3_arith(ctx, op1, sa, rs, rd, rt);
15493 break;
15494 default:
15495 MIPS_INVAL("cp3");
15496 generate_exception (ctx, EXCP_RI);
15497 break;
15499 } else {
15500 generate_exception_err(ctx, EXCP_CpU, 1);
15502 break;
15504 #if defined(TARGET_MIPS64)
15505 /* MIPS64 opcodes */
15506 case OPC_LWU:
15507 case OPC_LDL ... OPC_LDR:
15508 case OPC_LLD:
15509 case OPC_LD:
15510 check_insn(ctx, ISA_MIPS3);
15511 check_mips_64(ctx);
15512 gen_ld(ctx, op, rt, rs, imm);
15513 break;
15514 case OPC_SDL ... OPC_SDR:
15515 case OPC_SD:
15516 check_insn(ctx, ISA_MIPS3);
15517 check_mips_64(ctx);
15518 gen_st(ctx, op, rt, rs, imm);
15519 break;
15520 case OPC_SCD:
15521 check_insn(ctx, ISA_MIPS3);
15522 check_mips_64(ctx);
15523 gen_st_cond(ctx, op, rt, rs, imm);
15524 break;
15525 case OPC_DADDI:
15526 case OPC_DADDIU:
15527 check_insn(ctx, ISA_MIPS3);
15528 check_mips_64(ctx);
15529 gen_arith_imm(ctx, op, rt, rs, imm);
15530 break;
15531 #endif
15532 case OPC_JALX:
15533 check_insn(ctx, ASE_MIPS16 | ASE_MICROMIPS);
15534 offset = (int32_t)(ctx->opcode & 0x3FFFFFF) << 2;
15535 gen_compute_branch(ctx, op, 4, rs, rt, offset);
15536 break;
15537 case OPC_MDMX:
15538 check_insn(ctx, ASE_MDMX);
15539 /* MDMX: Not implemented. */
15540 default: /* Invalid */
15541 MIPS_INVAL("major opcode");
15542 generate_exception(ctx, EXCP_RI);
15543 break;
15547 static inline void
15548 gen_intermediate_code_internal(MIPSCPU *cpu, TranslationBlock *tb,
15549 bool search_pc)
15551 CPUState *cs = CPU(cpu);
15552 CPUMIPSState *env = &cpu->env;
15553 DisasContext ctx;
15554 target_ulong pc_start;
15555 uint16_t *gen_opc_end;
15556 CPUBreakpoint *bp;
15557 int j, lj = -1;
15558 int num_insns;
15559 int max_insns;
15560 int insn_bytes;
15561 int is_delay;
15563 if (search_pc)
15564 qemu_log("search pc %d\n", search_pc);
15566 pc_start = tb->pc;
15567 gen_opc_end = tcg_ctx.gen_opc_buf + OPC_MAX_SIZE;
15568 ctx.pc = pc_start;
15569 ctx.saved_pc = -1;
15570 ctx.singlestep_enabled = cs->singlestep_enabled;
15571 ctx.insn_flags = env->insn_flags;
15572 ctx.tb = tb;
15573 ctx.bstate = BS_NONE;
15574 /* Restore delay slot state from the tb context. */
15575 ctx.hflags = (uint32_t)tb->flags; /* FIXME: maybe use 64 bits here? */
15576 restore_cpu_state(env, &ctx);
15577 #ifdef CONFIG_USER_ONLY
15578 ctx.mem_idx = MIPS_HFLAG_UM;
15579 #else
15580 ctx.mem_idx = ctx.hflags & MIPS_HFLAG_KSU;
15581 #endif
15582 num_insns = 0;
15583 max_insns = tb->cflags & CF_COUNT_MASK;
15584 if (max_insns == 0)
15585 max_insns = CF_COUNT_MASK;
15586 LOG_DISAS("\ntb %p idx %d hflags %04x\n", tb, ctx.mem_idx, ctx.hflags);
15587 gen_tb_start();
15588 while (ctx.bstate == BS_NONE) {
15589 if (unlikely(!QTAILQ_EMPTY(&env->breakpoints))) {
15590 QTAILQ_FOREACH(bp, &env->breakpoints, entry) {
15591 if (bp->pc == ctx.pc) {
15592 save_cpu_state(&ctx, 1);
15593 ctx.bstate = BS_BRANCH;
15594 gen_helper_0e0i(raise_exception, EXCP_DEBUG);
15595 /* Include the breakpoint location or the tb won't
15596 * be flushed when it must be. */
15597 ctx.pc += 4;
15598 goto done_generating;
15603 if (search_pc) {
15604 j = tcg_ctx.gen_opc_ptr - tcg_ctx.gen_opc_buf;
15605 if (lj < j) {
15606 lj++;
15607 while (lj < j)
15608 tcg_ctx.gen_opc_instr_start[lj++] = 0;
15610 tcg_ctx.gen_opc_pc[lj] = ctx.pc;
15611 gen_opc_hflags[lj] = ctx.hflags & MIPS_HFLAG_BMASK;
15612 gen_opc_btarget[lj] = ctx.btarget;
15613 tcg_ctx.gen_opc_instr_start[lj] = 1;
15614 tcg_ctx.gen_opc_icount[lj] = num_insns;
15616 if (num_insns + 1 == max_insns && (tb->cflags & CF_LAST_IO))
15617 gen_io_start();
15619 is_delay = ctx.hflags & MIPS_HFLAG_BMASK;
15620 if (!(ctx.hflags & MIPS_HFLAG_M16)) {
15621 ctx.opcode = cpu_ldl_code(env, ctx.pc);
15622 insn_bytes = 4;
15623 decode_opc(env, &ctx);
15624 } else if (ctx.insn_flags & ASE_MICROMIPS) {
15625 ctx.opcode = cpu_lduw_code(env, ctx.pc);
15626 insn_bytes = decode_micromips_opc(env, &ctx);
15627 } else if (ctx.insn_flags & ASE_MIPS16) {
15628 ctx.opcode = cpu_lduw_code(env, ctx.pc);
15629 insn_bytes = decode_mips16_opc(env, &ctx);
15630 } else {
15631 generate_exception(&ctx, EXCP_RI);
15632 ctx.bstate = BS_STOP;
15633 break;
15635 if (is_delay) {
15636 handle_delay_slot(&ctx, insn_bytes);
15638 ctx.pc += insn_bytes;
15640 num_insns++;
15642 /* Execute a branch and its delay slot as a single instruction.
15643 This is what GDB expects and is consistent with what the
15644 hardware does (e.g. if a delay slot instruction faults, the
15645 reported PC is the PC of the branch). */
15646 if (cs->singlestep_enabled && (ctx.hflags & MIPS_HFLAG_BMASK) == 0) {
15647 break;
15650 if ((ctx.pc & (TARGET_PAGE_SIZE - 1)) == 0)
15651 break;
15653 if (tcg_ctx.gen_opc_ptr >= gen_opc_end) {
15654 break;
15657 if (num_insns >= max_insns)
15658 break;
15660 if (singlestep)
15661 break;
15663 if (tb->cflags & CF_LAST_IO) {
15664 gen_io_end();
15666 if (cs->singlestep_enabled && ctx.bstate != BS_BRANCH) {
15667 save_cpu_state(&ctx, ctx.bstate == BS_NONE);
15668 gen_helper_0e0i(raise_exception, EXCP_DEBUG);
15669 } else {
15670 switch (ctx.bstate) {
15671 case BS_STOP:
15672 gen_goto_tb(&ctx, 0, ctx.pc);
15673 break;
15674 case BS_NONE:
15675 save_cpu_state(&ctx, 0);
15676 gen_goto_tb(&ctx, 0, ctx.pc);
15677 break;
15678 case BS_EXCP:
15679 tcg_gen_exit_tb(0);
15680 break;
15681 case BS_BRANCH:
15682 default:
15683 break;
15686 done_generating:
15687 gen_tb_end(tb, num_insns);
15688 *tcg_ctx.gen_opc_ptr = INDEX_op_end;
15689 if (search_pc) {
15690 j = tcg_ctx.gen_opc_ptr - tcg_ctx.gen_opc_buf;
15691 lj++;
15692 while (lj <= j)
15693 tcg_ctx.gen_opc_instr_start[lj++] = 0;
15694 } else {
15695 tb->size = ctx.pc - pc_start;
15696 tb->icount = num_insns;
15698 #ifdef DEBUG_DISAS
15699 LOG_DISAS("\n");
15700 if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM)) {
15701 qemu_log("IN: %s\n", lookup_symbol(pc_start));
15702 log_target_disas(env, pc_start, ctx.pc - pc_start, 0);
15703 qemu_log("\n");
15705 #endif
15708 void gen_intermediate_code (CPUMIPSState *env, struct TranslationBlock *tb)
15710 gen_intermediate_code_internal(mips_env_get_cpu(env), tb, false);
15713 void gen_intermediate_code_pc (CPUMIPSState *env, struct TranslationBlock *tb)
15715 gen_intermediate_code_internal(mips_env_get_cpu(env), tb, true);
15718 static void fpu_dump_state(CPUMIPSState *env, FILE *f, fprintf_function fpu_fprintf,
15719 int flags)
15721 int i;
15722 int is_fpu64 = !!(env->hflags & MIPS_HFLAG_F64);
15724 #define printfpr(fp) \
15725 do { \
15726 if (is_fpu64) \
15727 fpu_fprintf(f, "w:%08x d:%016" PRIx64 \
15728 " fd:%13g fs:%13g psu: %13g\n", \
15729 (fp)->w[FP_ENDIAN_IDX], (fp)->d, \
15730 (double)(fp)->fd, \
15731 (double)(fp)->fs[FP_ENDIAN_IDX], \
15732 (double)(fp)->fs[!FP_ENDIAN_IDX]); \
15733 else { \
15734 fpr_t tmp; \
15735 tmp.w[FP_ENDIAN_IDX] = (fp)->w[FP_ENDIAN_IDX]; \
15736 tmp.w[!FP_ENDIAN_IDX] = ((fp) + 1)->w[FP_ENDIAN_IDX]; \
15737 fpu_fprintf(f, "w:%08x d:%016" PRIx64 \
15738 " fd:%13g fs:%13g psu:%13g\n", \
15739 tmp.w[FP_ENDIAN_IDX], tmp.d, \
15740 (double)tmp.fd, \
15741 (double)tmp.fs[FP_ENDIAN_IDX], \
15742 (double)tmp.fs[!FP_ENDIAN_IDX]); \
15744 } while(0)
15747 fpu_fprintf(f, "CP1 FCR0 0x%08x FCR31 0x%08x SR.FR %d fp_status 0x%02x\n",
15748 env->active_fpu.fcr0, env->active_fpu.fcr31, is_fpu64,
15749 get_float_exception_flags(&env->active_fpu.fp_status));
15750 for (i = 0; i < 32; (is_fpu64) ? i++ : (i += 2)) {
15751 fpu_fprintf(f, "%3s: ", fregnames[i]);
15752 printfpr(&env->active_fpu.fpr[i]);
15755 #undef printfpr
15758 #if defined(TARGET_MIPS64) && defined(MIPS_DEBUG_SIGN_EXTENSIONS)
15759 /* Debug help: The architecture requires 32bit code to maintain proper
15760 sign-extended values on 64bit machines. */
15762 #define SIGN_EXT_P(val) ((((val) & ~0x7fffffff) == 0) || (((val) & ~0x7fffffff) == ~0x7fffffff))
15764 static void
15765 cpu_mips_check_sign_extensions (CPUMIPSState *env, FILE *f,
15766 fprintf_function cpu_fprintf,
15767 int flags)
15769 int i;
15771 if (!SIGN_EXT_P(env->active_tc.PC))
15772 cpu_fprintf(f, "BROKEN: pc=0x" TARGET_FMT_lx "\n", env->active_tc.PC);
15773 if (!SIGN_EXT_P(env->active_tc.HI[0]))
15774 cpu_fprintf(f, "BROKEN: HI=0x" TARGET_FMT_lx "\n", env->active_tc.HI[0]);
15775 if (!SIGN_EXT_P(env->active_tc.LO[0]))
15776 cpu_fprintf(f, "BROKEN: LO=0x" TARGET_FMT_lx "\n", env->active_tc.LO[0]);
15777 if (!SIGN_EXT_P(env->btarget))
15778 cpu_fprintf(f, "BROKEN: btarget=0x" TARGET_FMT_lx "\n", env->btarget);
15780 for (i = 0; i < 32; i++) {
15781 if (!SIGN_EXT_P(env->active_tc.gpr[i]))
15782 cpu_fprintf(f, "BROKEN: %s=0x" TARGET_FMT_lx "\n", regnames[i], env->active_tc.gpr[i]);
15785 if (!SIGN_EXT_P(env->CP0_EPC))
15786 cpu_fprintf(f, "BROKEN: EPC=0x" TARGET_FMT_lx "\n", env->CP0_EPC);
15787 if (!SIGN_EXT_P(env->lladdr))
15788 cpu_fprintf(f, "BROKEN: LLAddr=0x" TARGET_FMT_lx "\n", env->lladdr);
15790 #endif
15792 void mips_cpu_dump_state(CPUState *cs, FILE *f, fprintf_function cpu_fprintf,
15793 int flags)
15795 MIPSCPU *cpu = MIPS_CPU(cs);
15796 CPUMIPSState *env = &cpu->env;
15797 int i;
15799 cpu_fprintf(f, "pc=0x" TARGET_FMT_lx " HI=0x" TARGET_FMT_lx
15800 " LO=0x" TARGET_FMT_lx " ds %04x "
15801 TARGET_FMT_lx " " TARGET_FMT_ld "\n",
15802 env->active_tc.PC, env->active_tc.HI[0], env->active_tc.LO[0],
15803 env->hflags, env->btarget, env->bcond);
15804 for (i = 0; i < 32; i++) {
15805 if ((i & 3) == 0)
15806 cpu_fprintf(f, "GPR%02d:", i);
15807 cpu_fprintf(f, " %s " TARGET_FMT_lx, regnames[i], env->active_tc.gpr[i]);
15808 if ((i & 3) == 3)
15809 cpu_fprintf(f, "\n");
15812 cpu_fprintf(f, "CP0 Status 0x%08x Cause 0x%08x EPC 0x" TARGET_FMT_lx "\n",
15813 env->CP0_Status, env->CP0_Cause, env->CP0_EPC);
15814 cpu_fprintf(f, " Config0 0x%08x Config1 0x%08x LLAddr 0x" TARGET_FMT_lx "\n",
15815 env->CP0_Config0, env->CP0_Config1, env->lladdr);
15816 if (env->hflags & MIPS_HFLAG_FPU)
15817 fpu_dump_state(env, f, cpu_fprintf, flags);
15818 #if defined(TARGET_MIPS64) && defined(MIPS_DEBUG_SIGN_EXTENSIONS)
15819 cpu_mips_check_sign_extensions(env, f, cpu_fprintf, flags);
15820 #endif
15823 void mips_tcg_init(void)
15825 int i;
15826 static int inited;
15828 /* Initialize various static tables. */
15829 if (inited)
15830 return;
15832 cpu_env = tcg_global_reg_new_ptr(TCG_AREG0, "env");
15833 TCGV_UNUSED(cpu_gpr[0]);
15834 for (i = 1; i < 32; i++)
15835 cpu_gpr[i] = tcg_global_mem_new(TCG_AREG0,
15836 offsetof(CPUMIPSState, active_tc.gpr[i]),
15837 regnames[i]);
15839 for (i = 0; i < 32; i++) {
15840 int off = offsetof(CPUMIPSState, active_fpu.fpr[i]);
15841 fpu_f64[i] = tcg_global_mem_new_i64(TCG_AREG0, off, fregnames[i]);
15844 cpu_PC = tcg_global_mem_new(TCG_AREG0,
15845 offsetof(CPUMIPSState, active_tc.PC), "PC");
15846 for (i = 0; i < MIPS_DSP_ACC; i++) {
15847 cpu_HI[i] = tcg_global_mem_new(TCG_AREG0,
15848 offsetof(CPUMIPSState, active_tc.HI[i]),
15849 regnames_HI[i]);
15850 cpu_LO[i] = tcg_global_mem_new(TCG_AREG0,
15851 offsetof(CPUMIPSState, active_tc.LO[i]),
15852 regnames_LO[i]);
15853 cpu_ACX[i] = tcg_global_mem_new(TCG_AREG0,
15854 offsetof(CPUMIPSState, active_tc.ACX[i]),
15855 regnames_ACX[i]);
15857 cpu_dspctrl = tcg_global_mem_new(TCG_AREG0,
15858 offsetof(CPUMIPSState, active_tc.DSPControl),
15859 "DSPControl");
15860 bcond = tcg_global_mem_new(TCG_AREG0,
15861 offsetof(CPUMIPSState, bcond), "bcond");
15862 btarget = tcg_global_mem_new(TCG_AREG0,
15863 offsetof(CPUMIPSState, btarget), "btarget");
15864 hflags = tcg_global_mem_new_i32(TCG_AREG0,
15865 offsetof(CPUMIPSState, hflags), "hflags");
15867 fpu_fcr0 = tcg_global_mem_new_i32(TCG_AREG0,
15868 offsetof(CPUMIPSState, active_fpu.fcr0),
15869 "fcr0");
15870 fpu_fcr31 = tcg_global_mem_new_i32(TCG_AREG0,
15871 offsetof(CPUMIPSState, active_fpu.fcr31),
15872 "fcr31");
15874 inited = 1;
15877 #include "translate_init.c"
15879 MIPSCPU *cpu_mips_init(const char *cpu_model)
15881 MIPSCPU *cpu;
15882 CPUMIPSState *env;
15883 const mips_def_t *def;
15885 def = cpu_mips_find_by_name(cpu_model);
15886 if (!def)
15887 return NULL;
15888 cpu = MIPS_CPU(object_new(TYPE_MIPS_CPU));
15889 env = &cpu->env;
15890 env->cpu_model = def;
15892 #ifndef CONFIG_USER_ONLY
15893 mmu_init(env, def);
15894 #endif
15895 fpu_init(env, def);
15896 mvp_init(env, def);
15898 object_property_set_bool(OBJECT(cpu), true, "realized", NULL);
15900 return cpu;
15903 void cpu_state_reset(CPUMIPSState *env)
15905 #ifndef CONFIG_USER_ONLY
15906 MIPSCPU *cpu = mips_env_get_cpu(env);
15907 CPUState *cs = CPU(cpu);
15908 #endif
15910 /* Reset registers to their default values */
15911 env->CP0_PRid = env->cpu_model->CP0_PRid;
15912 env->CP0_Config0 = env->cpu_model->CP0_Config0;
15913 #ifdef TARGET_WORDS_BIGENDIAN
15914 env->CP0_Config0 |= (1 << CP0C0_BE);
15915 #endif
15916 env->CP0_Config1 = env->cpu_model->CP0_Config1;
15917 env->CP0_Config2 = env->cpu_model->CP0_Config2;
15918 env->CP0_Config3 = env->cpu_model->CP0_Config3;
15919 env->CP0_Config6 = env->cpu_model->CP0_Config6;
15920 env->CP0_Config7 = env->cpu_model->CP0_Config7;
15921 env->CP0_LLAddr_rw_bitmask = env->cpu_model->CP0_LLAddr_rw_bitmask
15922 << env->cpu_model->CP0_LLAddr_shift;
15923 env->CP0_LLAddr_shift = env->cpu_model->CP0_LLAddr_shift;
15924 env->SYNCI_Step = env->cpu_model->SYNCI_Step;
15925 env->CCRes = env->cpu_model->CCRes;
15926 env->CP0_Status_rw_bitmask = env->cpu_model->CP0_Status_rw_bitmask;
15927 env->CP0_TCStatus_rw_bitmask = env->cpu_model->CP0_TCStatus_rw_bitmask;
15928 env->CP0_SRSCtl = env->cpu_model->CP0_SRSCtl;
15929 env->current_tc = 0;
15930 env->SEGBITS = env->cpu_model->SEGBITS;
15931 env->SEGMask = (target_ulong)((1ULL << env->cpu_model->SEGBITS) - 1);
15932 #if defined(TARGET_MIPS64)
15933 if (env->cpu_model->insn_flags & ISA_MIPS3) {
15934 env->SEGMask |= 3ULL << 62;
15936 #endif
15937 env->PABITS = env->cpu_model->PABITS;
15938 env->PAMask = (target_ulong)((1ULL << env->cpu_model->PABITS) - 1);
15939 env->CP0_SRSConf0_rw_bitmask = env->cpu_model->CP0_SRSConf0_rw_bitmask;
15940 env->CP0_SRSConf0 = env->cpu_model->CP0_SRSConf0;
15941 env->CP0_SRSConf1_rw_bitmask = env->cpu_model->CP0_SRSConf1_rw_bitmask;
15942 env->CP0_SRSConf1 = env->cpu_model->CP0_SRSConf1;
15943 env->CP0_SRSConf2_rw_bitmask = env->cpu_model->CP0_SRSConf2_rw_bitmask;
15944 env->CP0_SRSConf2 = env->cpu_model->CP0_SRSConf2;
15945 env->CP0_SRSConf3_rw_bitmask = env->cpu_model->CP0_SRSConf3_rw_bitmask;
15946 env->CP0_SRSConf3 = env->cpu_model->CP0_SRSConf3;
15947 env->CP0_SRSConf4_rw_bitmask = env->cpu_model->CP0_SRSConf4_rw_bitmask;
15948 env->CP0_SRSConf4 = env->cpu_model->CP0_SRSConf4;
15949 env->active_fpu.fcr0 = env->cpu_model->CP1_fcr0;
15950 env->insn_flags = env->cpu_model->insn_flags;
15952 #if defined(CONFIG_USER_ONLY)
15953 env->CP0_Status = (MIPS_HFLAG_UM << CP0St_KSU);
15954 # ifdef TARGET_MIPS64
15955 /* Enable 64-bit register mode. */
15956 env->CP0_Status |= (1 << CP0St_PX);
15957 # endif
15958 # ifdef TARGET_ABI_MIPSN64
15959 /* Enable 64-bit address mode. */
15960 env->CP0_Status |= (1 << CP0St_UX);
15961 # endif
15962 /* Enable access to the CPUNum, SYNCI_Step, CC, and CCRes RDHWR
15963 hardware registers. */
15964 env->CP0_HWREna |= 0x0000000F;
15965 if (env->CP0_Config1 & (1 << CP0C1_FP)) {
15966 env->CP0_Status |= (1 << CP0St_CU1);
15968 if (env->CP0_Config3 & (1 << CP0C3_DSPP)) {
15969 env->CP0_Status |= (1 << CP0St_MX);
15971 # if defined(TARGET_MIPS64)
15972 /* For MIPS64, init FR bit to 1 if FPU unit is there and bit is writable. */
15973 if ((env->CP0_Config1 & (1 << CP0C1_FP)) &&
15974 (env->CP0_Status_rw_bitmask & (1 << CP0St_FR))) {
15975 env->CP0_Status |= (1 << CP0St_FR);
15977 # endif
15978 #else
15979 if (env->hflags & MIPS_HFLAG_BMASK) {
15980 /* If the exception was raised from a delay slot,
15981 come back to the jump. */
15982 env->CP0_ErrorEPC = env->active_tc.PC - 4;
15983 } else {
15984 env->CP0_ErrorEPC = env->active_tc.PC;
15986 env->active_tc.PC = (int32_t)0xBFC00000;
15987 env->CP0_Random = env->tlb->nb_tlb - 1;
15988 env->tlb->tlb_in_use = env->tlb->nb_tlb;
15989 env->CP0_Wired = 0;
15990 env->CP0_EBase = 0x80000000 | (cs->cpu_index & 0x3FF);
15991 env->CP0_Status = (1 << CP0St_BEV) | (1 << CP0St_ERL);
15992 /* vectored interrupts not implemented, timer on int 7,
15993 no performance counters. */
15994 env->CP0_IntCtl = 0xe0000000;
15996 int i;
15998 for (i = 0; i < 7; i++) {
15999 env->CP0_WatchLo[i] = 0;
16000 env->CP0_WatchHi[i] = 0x80000000;
16002 env->CP0_WatchLo[7] = 0;
16003 env->CP0_WatchHi[7] = 0;
16005 /* Count register increments in debug mode, EJTAG version 1 */
16006 env->CP0_Debug = (1 << CP0DB_CNT) | (0x1 << CP0DB_VER);
16008 if (env->CP0_Config3 & (1 << CP0C3_MT)) {
16009 int i;
16011 /* Only TC0 on VPE 0 starts as active. */
16012 for (i = 0; i < ARRAY_SIZE(env->tcs); i++) {
16013 env->tcs[i].CP0_TCBind = cs->cpu_index << CP0TCBd_CurVPE;
16014 env->tcs[i].CP0_TCHalt = 1;
16016 env->active_tc.CP0_TCHalt = 1;
16017 cs->halted = 1;
16019 if (cs->cpu_index == 0) {
16020 /* VPE0 starts up enabled. */
16021 env->mvp->CP0_MVPControl |= (1 << CP0MVPCo_EVP);
16022 env->CP0_VPEConf0 |= (1 << CP0VPEC0_MVP) | (1 << CP0VPEC0_VPA);
16024 /* TC0 starts up unhalted. */
16025 cs->halted = 0;
16026 env->active_tc.CP0_TCHalt = 0;
16027 env->tcs[0].CP0_TCHalt = 0;
16028 /* With thread 0 active. */
16029 env->active_tc.CP0_TCStatus = (1 << CP0TCSt_A);
16030 env->tcs[0].CP0_TCStatus = (1 << CP0TCSt_A);
16033 #endif
16034 compute_hflags(env);
16035 env->exception_index = EXCP_NONE;
16038 void restore_state_to_opc(CPUMIPSState *env, TranslationBlock *tb, int pc_pos)
16040 env->active_tc.PC = tcg_ctx.gen_opc_pc[pc_pos];
16041 env->hflags &= ~MIPS_HFLAG_BMASK;
16042 env->hflags |= gen_opc_hflags[pc_pos];
16043 switch (env->hflags & MIPS_HFLAG_BMASK_BASE) {
16044 case MIPS_HFLAG_BR:
16045 break;
16046 case MIPS_HFLAG_BC:
16047 case MIPS_HFLAG_BL:
16048 case MIPS_HFLAG_B:
16049 env->btarget = gen_opc_btarget[pc_pos];
16050 break;