accel: Report unknown accelerator as "not found" instead of "does not exist"
[qemu/ar7.git] / target-mips / translate.c
blob06db15032542ab043ae2eae314129bde3248308b
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"
27 #include "exec/cpu_ldst.h"
29 #include "exec/helper-proto.h"
30 #include "exec/helper-gen.h"
31 #include "sysemu/kvm.h"
33 #include "trace-tcg.h"
36 #define MIPS_DEBUG_DISAS 0
37 //#define MIPS_DEBUG_SIGN_EXTENSIONS
39 /* MIPS major opcodes */
40 #define MASK_OP_MAJOR(op) (op & (0x3F << 26))
42 enum {
43 /* indirect opcode tables */
44 OPC_SPECIAL = (0x00 << 26),
45 OPC_REGIMM = (0x01 << 26),
46 OPC_CP0 = (0x10 << 26),
47 OPC_CP1 = (0x11 << 26),
48 OPC_CP2 = (0x12 << 26),
49 OPC_CP3 = (0x13 << 26),
50 OPC_SPECIAL2 = (0x1C << 26),
51 OPC_SPECIAL3 = (0x1F << 26),
52 /* arithmetic with immediate */
53 OPC_ADDI = (0x08 << 26),
54 OPC_ADDIU = (0x09 << 26),
55 OPC_SLTI = (0x0A << 26),
56 OPC_SLTIU = (0x0B << 26),
57 /* logic with immediate */
58 OPC_ANDI = (0x0C << 26),
59 OPC_ORI = (0x0D << 26),
60 OPC_XORI = (0x0E << 26),
61 OPC_LUI = (0x0F << 26),
62 /* arithmetic with immediate */
63 OPC_DADDI = (0x18 << 26),
64 OPC_DADDIU = (0x19 << 26),
65 /* Jump and branches */
66 OPC_J = (0x02 << 26),
67 OPC_JAL = (0x03 << 26),
68 OPC_JALS = OPC_JAL | 0x5,
69 OPC_BEQ = (0x04 << 26), /* Unconditional if rs = rt = 0 (B) */
70 OPC_BEQL = (0x14 << 26),
71 OPC_BNE = (0x05 << 26),
72 OPC_BNEL = (0x15 << 26),
73 OPC_BLEZ = (0x06 << 26),
74 OPC_BLEZL = (0x16 << 26),
75 OPC_BGTZ = (0x07 << 26),
76 OPC_BGTZL = (0x17 << 26),
77 OPC_JALX = (0x1D << 26), /* MIPS 16 only */
78 OPC_JALXS = OPC_JALX | 0x5,
79 /* Load and stores */
80 OPC_LDL = (0x1A << 26),
81 OPC_LDR = (0x1B << 26),
82 OPC_LB = (0x20 << 26),
83 OPC_LH = (0x21 << 26),
84 OPC_LWL = (0x22 << 26),
85 OPC_LW = (0x23 << 26),
86 OPC_LWPC = OPC_LW | 0x5,
87 OPC_LBU = (0x24 << 26),
88 OPC_LHU = (0x25 << 26),
89 OPC_LWR = (0x26 << 26),
90 OPC_LWU = (0x27 << 26),
91 OPC_SB = (0x28 << 26),
92 OPC_SH = (0x29 << 26),
93 OPC_SWL = (0x2A << 26),
94 OPC_SW = (0x2B << 26),
95 OPC_SDL = (0x2C << 26),
96 OPC_SDR = (0x2D << 26),
97 OPC_SWR = (0x2E << 26),
98 OPC_LL = (0x30 << 26),
99 OPC_LLD = (0x34 << 26),
100 OPC_LD = (0x37 << 26),
101 OPC_LDPC = OPC_LD | 0x5,
102 OPC_SC = (0x38 << 26),
103 OPC_SCD = (0x3C << 26),
104 OPC_SD = (0x3F << 26),
105 /* Floating point load/store */
106 OPC_LWC1 = (0x31 << 26),
107 OPC_LWC2 = (0x32 << 26),
108 OPC_LDC1 = (0x35 << 26),
109 OPC_LDC2 = (0x36 << 26),
110 OPC_SWC1 = (0x39 << 26),
111 OPC_SWC2 = (0x3A << 26),
112 OPC_SDC1 = (0x3D << 26),
113 OPC_SDC2 = (0x3E << 26),
114 /* MDMX ASE specific */
115 OPC_MDMX = (0x1E << 26),
116 /* Cache and prefetch */
117 OPC_CACHE = (0x2F << 26),
118 OPC_PREF = (0x33 << 26),
119 /* Reserved major opcode */
120 OPC_MAJOR3B_RESERVED = (0x3B << 26),
123 /* MIPS special opcodes */
124 #define MASK_SPECIAL(op) MASK_OP_MAJOR(op) | (op & 0x3F)
126 enum {
127 /* Shifts */
128 OPC_SLL = 0x00 | OPC_SPECIAL,
129 /* NOP is SLL r0, r0, 0 */
130 /* SSNOP is SLL r0, r0, 1 */
131 /* EHB is SLL r0, r0, 3 */
132 OPC_SRL = 0x02 | OPC_SPECIAL, /* also ROTR */
133 OPC_ROTR = OPC_SRL | (1 << 21),
134 OPC_SRA = 0x03 | OPC_SPECIAL,
135 OPC_SLLV = 0x04 | OPC_SPECIAL,
136 OPC_SRLV = 0x06 | OPC_SPECIAL, /* also ROTRV */
137 OPC_ROTRV = OPC_SRLV | (1 << 6),
138 OPC_SRAV = 0x07 | OPC_SPECIAL,
139 OPC_DSLLV = 0x14 | OPC_SPECIAL,
140 OPC_DSRLV = 0x16 | OPC_SPECIAL, /* also DROTRV */
141 OPC_DROTRV = OPC_DSRLV | (1 << 6),
142 OPC_DSRAV = 0x17 | OPC_SPECIAL,
143 OPC_DSLL = 0x38 | OPC_SPECIAL,
144 OPC_DSRL = 0x3A | OPC_SPECIAL, /* also DROTR */
145 OPC_DROTR = OPC_DSRL | (1 << 21),
146 OPC_DSRA = 0x3B | OPC_SPECIAL,
147 OPC_DSLL32 = 0x3C | OPC_SPECIAL,
148 OPC_DSRL32 = 0x3E | OPC_SPECIAL, /* also DROTR32 */
149 OPC_DROTR32 = OPC_DSRL32 | (1 << 21),
150 OPC_DSRA32 = 0x3F | OPC_SPECIAL,
151 /* Multiplication / division */
152 OPC_MULT = 0x18 | OPC_SPECIAL,
153 OPC_MULTU = 0x19 | OPC_SPECIAL,
154 OPC_DIV = 0x1A | OPC_SPECIAL,
155 OPC_DIVU = 0x1B | OPC_SPECIAL,
156 OPC_DMULT = 0x1C | OPC_SPECIAL,
157 OPC_DMULTU = 0x1D | OPC_SPECIAL,
158 OPC_DDIV = 0x1E | OPC_SPECIAL,
159 OPC_DDIVU = 0x1F | OPC_SPECIAL,
160 /* 2 registers arithmetic / logic */
161 OPC_ADD = 0x20 | OPC_SPECIAL,
162 OPC_ADDU = 0x21 | OPC_SPECIAL,
163 OPC_SUB = 0x22 | OPC_SPECIAL,
164 OPC_SUBU = 0x23 | OPC_SPECIAL,
165 OPC_AND = 0x24 | OPC_SPECIAL,
166 OPC_OR = 0x25 | OPC_SPECIAL,
167 OPC_XOR = 0x26 | OPC_SPECIAL,
168 OPC_NOR = 0x27 | OPC_SPECIAL,
169 OPC_SLT = 0x2A | OPC_SPECIAL,
170 OPC_SLTU = 0x2B | OPC_SPECIAL,
171 OPC_DADD = 0x2C | OPC_SPECIAL,
172 OPC_DADDU = 0x2D | OPC_SPECIAL,
173 OPC_DSUB = 0x2E | OPC_SPECIAL,
174 OPC_DSUBU = 0x2F | OPC_SPECIAL,
175 /* Jumps */
176 OPC_JR = 0x08 | OPC_SPECIAL, /* Also JR.HB */
177 OPC_JALR = 0x09 | OPC_SPECIAL, /* Also JALR.HB */
178 OPC_JALRC = OPC_JALR | (0x5 << 6),
179 OPC_JALRS = 0x10 | OPC_SPECIAL | (0x5 << 6),
180 /* Traps */
181 OPC_TGE = 0x30 | OPC_SPECIAL,
182 OPC_TGEU = 0x31 | OPC_SPECIAL,
183 OPC_TLT = 0x32 | OPC_SPECIAL,
184 OPC_TLTU = 0x33 | OPC_SPECIAL,
185 OPC_TEQ = 0x34 | OPC_SPECIAL,
186 OPC_TNE = 0x36 | OPC_SPECIAL,
187 /* HI / LO registers load & stores */
188 OPC_MFHI = 0x10 | OPC_SPECIAL,
189 OPC_MTHI = 0x11 | OPC_SPECIAL,
190 OPC_MFLO = 0x12 | OPC_SPECIAL,
191 OPC_MTLO = 0x13 | OPC_SPECIAL,
192 /* Conditional moves */
193 OPC_MOVZ = 0x0A | OPC_SPECIAL,
194 OPC_MOVN = 0x0B | OPC_SPECIAL,
196 OPC_MOVCI = 0x01 | OPC_SPECIAL,
198 /* Special */
199 OPC_PMON = 0x05 | OPC_SPECIAL, /* unofficial */
200 OPC_SYSCALL = 0x0C | OPC_SPECIAL,
201 OPC_BREAK = 0x0D | OPC_SPECIAL,
202 OPC_SPIM = 0x0E | OPC_SPECIAL, /* unofficial */
203 OPC_SYNC = 0x0F | OPC_SPECIAL,
205 OPC_SPECIAL15_RESERVED = 0x15 | OPC_SPECIAL,
206 OPC_SPECIAL28_RESERVED = 0x28 | OPC_SPECIAL,
207 OPC_SPECIAL29_RESERVED = 0x29 | OPC_SPECIAL,
208 OPC_SPECIAL35_RESERVED = 0x35 | OPC_SPECIAL,
209 OPC_SPECIAL37_RESERVED = 0x37 | OPC_SPECIAL,
210 OPC_SPECIAL39_RESERVED = 0x39 | OPC_SPECIAL,
211 OPC_SPECIAL3D_RESERVED = 0x3D | OPC_SPECIAL,
214 /* Multiplication variants of the vr54xx. */
215 #define MASK_MUL_VR54XX(op) MASK_SPECIAL(op) | (op & (0x1F << 6))
217 enum {
218 OPC_VR54XX_MULS = (0x03 << 6) | OPC_MULT,
219 OPC_VR54XX_MULSU = (0x03 << 6) | OPC_MULTU,
220 OPC_VR54XX_MACC = (0x05 << 6) | OPC_MULT,
221 OPC_VR54XX_MACCU = (0x05 << 6) | OPC_MULTU,
222 OPC_VR54XX_MSAC = (0x07 << 6) | OPC_MULT,
223 OPC_VR54XX_MSACU = (0x07 << 6) | OPC_MULTU,
224 OPC_VR54XX_MULHI = (0x09 << 6) | OPC_MULT,
225 OPC_VR54XX_MULHIU = (0x09 << 6) | OPC_MULTU,
226 OPC_VR54XX_MULSHI = (0x0B << 6) | OPC_MULT,
227 OPC_VR54XX_MULSHIU = (0x0B << 6) | OPC_MULTU,
228 OPC_VR54XX_MACCHI = (0x0D << 6) | OPC_MULT,
229 OPC_VR54XX_MACCHIU = (0x0D << 6) | OPC_MULTU,
230 OPC_VR54XX_MSACHI = (0x0F << 6) | OPC_MULT,
231 OPC_VR54XX_MSACHIU = (0x0F << 6) | OPC_MULTU,
234 /* REGIMM (rt field) opcodes */
235 #define MASK_REGIMM(op) MASK_OP_MAJOR(op) | (op & (0x1F << 16))
237 enum {
238 OPC_BLTZ = (0x00 << 16) | OPC_REGIMM,
239 OPC_BLTZL = (0x02 << 16) | OPC_REGIMM,
240 OPC_BGEZ = (0x01 << 16) | OPC_REGIMM,
241 OPC_BGEZL = (0x03 << 16) | OPC_REGIMM,
242 OPC_BLTZAL = (0x10 << 16) | OPC_REGIMM,
243 OPC_BLTZALS = OPC_BLTZAL | 0x5, /* microMIPS */
244 OPC_BLTZALL = (0x12 << 16) | OPC_REGIMM,
245 OPC_BGEZAL = (0x11 << 16) | OPC_REGIMM,
246 OPC_BGEZALS = OPC_BGEZAL | 0x5, /* microMIPS */
247 OPC_BGEZALL = (0x13 << 16) | OPC_REGIMM,
248 OPC_TGEI = (0x08 << 16) | OPC_REGIMM,
249 OPC_TGEIU = (0x09 << 16) | OPC_REGIMM,
250 OPC_TLTI = (0x0A << 16) | OPC_REGIMM,
251 OPC_TLTIU = (0x0B << 16) | OPC_REGIMM,
252 OPC_TEQI = (0x0C << 16) | OPC_REGIMM,
253 OPC_TNEI = (0x0E << 16) | OPC_REGIMM,
254 OPC_SYNCI = (0x1F << 16) | OPC_REGIMM,
257 /* Special2 opcodes */
258 #define MASK_SPECIAL2(op) MASK_OP_MAJOR(op) | (op & 0x3F)
260 enum {
261 /* Multiply & xxx operations */
262 OPC_MADD = 0x00 | OPC_SPECIAL2,
263 OPC_MADDU = 0x01 | OPC_SPECIAL2,
264 OPC_MUL = 0x02 | OPC_SPECIAL2,
265 OPC_MSUB = 0x04 | OPC_SPECIAL2,
266 OPC_MSUBU = 0x05 | OPC_SPECIAL2,
267 /* Loongson 2F */
268 OPC_MULT_G_2F = 0x10 | OPC_SPECIAL2,
269 OPC_DMULT_G_2F = 0x11 | OPC_SPECIAL2,
270 OPC_MULTU_G_2F = 0x12 | OPC_SPECIAL2,
271 OPC_DMULTU_G_2F = 0x13 | OPC_SPECIAL2,
272 OPC_DIV_G_2F = 0x14 | OPC_SPECIAL2,
273 OPC_DDIV_G_2F = 0x15 | OPC_SPECIAL2,
274 OPC_DIVU_G_2F = 0x16 | OPC_SPECIAL2,
275 OPC_DDIVU_G_2F = 0x17 | OPC_SPECIAL2,
276 OPC_MOD_G_2F = 0x1c | OPC_SPECIAL2,
277 OPC_DMOD_G_2F = 0x1d | OPC_SPECIAL2,
278 OPC_MODU_G_2F = 0x1e | OPC_SPECIAL2,
279 OPC_DMODU_G_2F = 0x1f | OPC_SPECIAL2,
280 /* Misc */
281 OPC_CLZ = 0x20 | OPC_SPECIAL2,
282 OPC_CLO = 0x21 | OPC_SPECIAL2,
283 OPC_DCLZ = 0x24 | OPC_SPECIAL2,
284 OPC_DCLO = 0x25 | OPC_SPECIAL2,
285 /* Special */
286 OPC_SDBBP = 0x3F | OPC_SPECIAL2,
289 /* Special3 opcodes */
290 #define MASK_SPECIAL3(op) MASK_OP_MAJOR(op) | (op & 0x3F)
292 enum {
293 OPC_EXT = 0x00 | OPC_SPECIAL3,
294 OPC_DEXTM = 0x01 | OPC_SPECIAL3,
295 OPC_DEXTU = 0x02 | OPC_SPECIAL3,
296 OPC_DEXT = 0x03 | OPC_SPECIAL3,
297 OPC_INS = 0x04 | OPC_SPECIAL3,
298 OPC_DINSM = 0x05 | OPC_SPECIAL3,
299 OPC_DINSU = 0x06 | OPC_SPECIAL3,
300 OPC_DINS = 0x07 | OPC_SPECIAL3,
301 OPC_FORK = 0x08 | OPC_SPECIAL3,
302 OPC_YIELD = 0x09 | OPC_SPECIAL3,
303 OPC_BSHFL = 0x20 | OPC_SPECIAL3,
304 OPC_DBSHFL = 0x24 | OPC_SPECIAL3,
305 OPC_RDHWR = 0x3B | OPC_SPECIAL3,
307 /* Loongson 2E */
308 OPC_MULT_G_2E = 0x18 | OPC_SPECIAL3,
309 OPC_MULTU_G_2E = 0x19 | OPC_SPECIAL3,
310 OPC_DIV_G_2E = 0x1A | OPC_SPECIAL3,
311 OPC_DIVU_G_2E = 0x1B | OPC_SPECIAL3,
312 OPC_DMULT_G_2E = 0x1C | OPC_SPECIAL3,
313 OPC_DMULTU_G_2E = 0x1D | OPC_SPECIAL3,
314 OPC_DDIV_G_2E = 0x1E | OPC_SPECIAL3,
315 OPC_DDIVU_G_2E = 0x1F | OPC_SPECIAL3,
316 OPC_MOD_G_2E = 0x22 | OPC_SPECIAL3,
317 OPC_MODU_G_2E = 0x23 | OPC_SPECIAL3,
318 OPC_DMOD_G_2E = 0x26 | OPC_SPECIAL3,
319 OPC_DMODU_G_2E = 0x27 | OPC_SPECIAL3,
321 /* MIPS DSP Load */
322 OPC_LX_DSP = 0x0A | OPC_SPECIAL3,
323 /* MIPS DSP Arithmetic */
324 OPC_ADDU_QB_DSP = 0x10 | OPC_SPECIAL3,
325 OPC_ADDU_OB_DSP = 0x14 | OPC_SPECIAL3,
326 OPC_ABSQ_S_PH_DSP = 0x12 | OPC_SPECIAL3,
327 OPC_ABSQ_S_QH_DSP = 0x16 | OPC_SPECIAL3,
328 /* OPC_ADDUH_QB_DSP is same as OPC_MULT_G_2E. */
329 /* OPC_ADDUH_QB_DSP = 0x18 | OPC_SPECIAL3, */
330 OPC_CMPU_EQ_QB_DSP = 0x11 | OPC_SPECIAL3,
331 OPC_CMPU_EQ_OB_DSP = 0x15 | OPC_SPECIAL3,
332 /* MIPS DSP GPR-Based Shift Sub-class */
333 OPC_SHLL_QB_DSP = 0x13 | OPC_SPECIAL3,
334 OPC_SHLL_OB_DSP = 0x17 | OPC_SPECIAL3,
335 /* MIPS DSP Multiply Sub-class insns */
336 /* OPC_MUL_PH_DSP is same as OPC_ADDUH_QB_DSP. */
337 /* OPC_MUL_PH_DSP = 0x18 | OPC_SPECIAL3, */
338 OPC_DPA_W_PH_DSP = 0x30 | OPC_SPECIAL3,
339 OPC_DPAQ_W_QH_DSP = 0x34 | OPC_SPECIAL3,
340 /* DSP Bit/Manipulation Sub-class */
341 OPC_INSV_DSP = 0x0C | OPC_SPECIAL3,
342 OPC_DINSV_DSP = 0x0D | OPC_SPECIAL3,
343 /* MIPS DSP Append Sub-class */
344 OPC_APPEND_DSP = 0x31 | OPC_SPECIAL3,
345 OPC_DAPPEND_DSP = 0x35 | OPC_SPECIAL3,
346 /* MIPS DSP Accumulator and DSPControl Access Sub-class */
347 OPC_EXTR_W_DSP = 0x38 | OPC_SPECIAL3,
348 OPC_DEXTR_W_DSP = 0x3C | OPC_SPECIAL3,
351 /* BSHFL opcodes */
352 #define MASK_BSHFL(op) MASK_SPECIAL3(op) | (op & (0x1F << 6))
354 enum {
355 OPC_WSBH = (0x02 << 6) | OPC_BSHFL,
356 OPC_SEB = (0x10 << 6) | OPC_BSHFL,
357 OPC_SEH = (0x18 << 6) | OPC_BSHFL,
360 /* DBSHFL opcodes */
361 #define MASK_DBSHFL(op) MASK_SPECIAL3(op) | (op & (0x1F << 6))
363 enum {
364 OPC_DSBH = (0x02 << 6) | OPC_DBSHFL,
365 OPC_DSHD = (0x05 << 6) | OPC_DBSHFL,
368 /* MIPS DSP REGIMM opcodes */
369 enum {
370 OPC_BPOSGE32 = (0x1C << 16) | OPC_REGIMM,
371 OPC_BPOSGE64 = (0x1D << 16) | OPC_REGIMM,
374 #define MASK_LX(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
375 /* MIPS DSP Load */
376 enum {
377 OPC_LBUX = (0x06 << 6) | OPC_LX_DSP,
378 OPC_LHX = (0x04 << 6) | OPC_LX_DSP,
379 OPC_LWX = (0x00 << 6) | OPC_LX_DSP,
380 OPC_LDX = (0x08 << 6) | OPC_LX_DSP,
383 #define MASK_ADDU_QB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
384 enum {
385 /* MIPS DSP Arithmetic Sub-class */
386 OPC_ADDQ_PH = (0x0A << 6) | OPC_ADDU_QB_DSP,
387 OPC_ADDQ_S_PH = (0x0E << 6) | OPC_ADDU_QB_DSP,
388 OPC_ADDQ_S_W = (0x16 << 6) | OPC_ADDU_QB_DSP,
389 OPC_ADDU_QB = (0x00 << 6) | OPC_ADDU_QB_DSP,
390 OPC_ADDU_S_QB = (0x04 << 6) | OPC_ADDU_QB_DSP,
391 OPC_ADDU_PH = (0x08 << 6) | OPC_ADDU_QB_DSP,
392 OPC_ADDU_S_PH = (0x0C << 6) | OPC_ADDU_QB_DSP,
393 OPC_SUBQ_PH = (0x0B << 6) | OPC_ADDU_QB_DSP,
394 OPC_SUBQ_S_PH = (0x0F << 6) | OPC_ADDU_QB_DSP,
395 OPC_SUBQ_S_W = (0x17 << 6) | OPC_ADDU_QB_DSP,
396 OPC_SUBU_QB = (0x01 << 6) | OPC_ADDU_QB_DSP,
397 OPC_SUBU_S_QB = (0x05 << 6) | OPC_ADDU_QB_DSP,
398 OPC_SUBU_PH = (0x09 << 6) | OPC_ADDU_QB_DSP,
399 OPC_SUBU_S_PH = (0x0D << 6) | OPC_ADDU_QB_DSP,
400 OPC_ADDSC = (0x10 << 6) | OPC_ADDU_QB_DSP,
401 OPC_ADDWC = (0x11 << 6) | OPC_ADDU_QB_DSP,
402 OPC_MODSUB = (0x12 << 6) | OPC_ADDU_QB_DSP,
403 OPC_RADDU_W_QB = (0x14 << 6) | OPC_ADDU_QB_DSP,
404 /* MIPS DSP Multiply Sub-class insns */
405 OPC_MULEU_S_PH_QBL = (0x06 << 6) | OPC_ADDU_QB_DSP,
406 OPC_MULEU_S_PH_QBR = (0x07 << 6) | OPC_ADDU_QB_DSP,
407 OPC_MULQ_RS_PH = (0x1F << 6) | OPC_ADDU_QB_DSP,
408 OPC_MULEQ_S_W_PHL = (0x1C << 6) | OPC_ADDU_QB_DSP,
409 OPC_MULEQ_S_W_PHR = (0x1D << 6) | OPC_ADDU_QB_DSP,
410 OPC_MULQ_S_PH = (0x1E << 6) | OPC_ADDU_QB_DSP,
413 #define OPC_ADDUH_QB_DSP OPC_MULT_G_2E
414 #define MASK_ADDUH_QB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
415 enum {
416 /* MIPS DSP Arithmetic Sub-class */
417 OPC_ADDUH_QB = (0x00 << 6) | OPC_ADDUH_QB_DSP,
418 OPC_ADDUH_R_QB = (0x02 << 6) | OPC_ADDUH_QB_DSP,
419 OPC_ADDQH_PH = (0x08 << 6) | OPC_ADDUH_QB_DSP,
420 OPC_ADDQH_R_PH = (0x0A << 6) | OPC_ADDUH_QB_DSP,
421 OPC_ADDQH_W = (0x10 << 6) | OPC_ADDUH_QB_DSP,
422 OPC_ADDQH_R_W = (0x12 << 6) | OPC_ADDUH_QB_DSP,
423 OPC_SUBUH_QB = (0x01 << 6) | OPC_ADDUH_QB_DSP,
424 OPC_SUBUH_R_QB = (0x03 << 6) | OPC_ADDUH_QB_DSP,
425 OPC_SUBQH_PH = (0x09 << 6) | OPC_ADDUH_QB_DSP,
426 OPC_SUBQH_R_PH = (0x0B << 6) | OPC_ADDUH_QB_DSP,
427 OPC_SUBQH_W = (0x11 << 6) | OPC_ADDUH_QB_DSP,
428 OPC_SUBQH_R_W = (0x13 << 6) | OPC_ADDUH_QB_DSP,
429 /* MIPS DSP Multiply Sub-class insns */
430 OPC_MUL_PH = (0x0C << 6) | OPC_ADDUH_QB_DSP,
431 OPC_MUL_S_PH = (0x0E << 6) | OPC_ADDUH_QB_DSP,
432 OPC_MULQ_S_W = (0x16 << 6) | OPC_ADDUH_QB_DSP,
433 OPC_MULQ_RS_W = (0x17 << 6) | OPC_ADDUH_QB_DSP,
436 #define MASK_ABSQ_S_PH(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
437 enum {
438 /* MIPS DSP Arithmetic Sub-class */
439 OPC_ABSQ_S_QB = (0x01 << 6) | OPC_ABSQ_S_PH_DSP,
440 OPC_ABSQ_S_PH = (0x09 << 6) | OPC_ABSQ_S_PH_DSP,
441 OPC_ABSQ_S_W = (0x11 << 6) | OPC_ABSQ_S_PH_DSP,
442 OPC_PRECEQ_W_PHL = (0x0C << 6) | OPC_ABSQ_S_PH_DSP,
443 OPC_PRECEQ_W_PHR = (0x0D << 6) | OPC_ABSQ_S_PH_DSP,
444 OPC_PRECEQU_PH_QBL = (0x04 << 6) | OPC_ABSQ_S_PH_DSP,
445 OPC_PRECEQU_PH_QBR = (0x05 << 6) | OPC_ABSQ_S_PH_DSP,
446 OPC_PRECEQU_PH_QBLA = (0x06 << 6) | OPC_ABSQ_S_PH_DSP,
447 OPC_PRECEQU_PH_QBRA = (0x07 << 6) | OPC_ABSQ_S_PH_DSP,
448 OPC_PRECEU_PH_QBL = (0x1C << 6) | OPC_ABSQ_S_PH_DSP,
449 OPC_PRECEU_PH_QBR = (0x1D << 6) | OPC_ABSQ_S_PH_DSP,
450 OPC_PRECEU_PH_QBLA = (0x1E << 6) | OPC_ABSQ_S_PH_DSP,
451 OPC_PRECEU_PH_QBRA = (0x1F << 6) | OPC_ABSQ_S_PH_DSP,
452 /* DSP Bit/Manipulation Sub-class */
453 OPC_BITREV = (0x1B << 6) | OPC_ABSQ_S_PH_DSP,
454 OPC_REPL_QB = (0x02 << 6) | OPC_ABSQ_S_PH_DSP,
455 OPC_REPLV_QB = (0x03 << 6) | OPC_ABSQ_S_PH_DSP,
456 OPC_REPL_PH = (0x0A << 6) | OPC_ABSQ_S_PH_DSP,
457 OPC_REPLV_PH = (0x0B << 6) | OPC_ABSQ_S_PH_DSP,
460 #define MASK_CMPU_EQ_QB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
461 enum {
462 /* MIPS DSP Arithmetic Sub-class */
463 OPC_PRECR_QB_PH = (0x0D << 6) | OPC_CMPU_EQ_QB_DSP,
464 OPC_PRECRQ_QB_PH = (0x0C << 6) | OPC_CMPU_EQ_QB_DSP,
465 OPC_PRECR_SRA_PH_W = (0x1E << 6) | OPC_CMPU_EQ_QB_DSP,
466 OPC_PRECR_SRA_R_PH_W = (0x1F << 6) | OPC_CMPU_EQ_QB_DSP,
467 OPC_PRECRQ_PH_W = (0x14 << 6) | OPC_CMPU_EQ_QB_DSP,
468 OPC_PRECRQ_RS_PH_W = (0x15 << 6) | OPC_CMPU_EQ_QB_DSP,
469 OPC_PRECRQU_S_QB_PH = (0x0F << 6) | OPC_CMPU_EQ_QB_DSP,
470 /* DSP Compare-Pick Sub-class */
471 OPC_CMPU_EQ_QB = (0x00 << 6) | OPC_CMPU_EQ_QB_DSP,
472 OPC_CMPU_LT_QB = (0x01 << 6) | OPC_CMPU_EQ_QB_DSP,
473 OPC_CMPU_LE_QB = (0x02 << 6) | OPC_CMPU_EQ_QB_DSP,
474 OPC_CMPGU_EQ_QB = (0x04 << 6) | OPC_CMPU_EQ_QB_DSP,
475 OPC_CMPGU_LT_QB = (0x05 << 6) | OPC_CMPU_EQ_QB_DSP,
476 OPC_CMPGU_LE_QB = (0x06 << 6) | OPC_CMPU_EQ_QB_DSP,
477 OPC_CMPGDU_EQ_QB = (0x18 << 6) | OPC_CMPU_EQ_QB_DSP,
478 OPC_CMPGDU_LT_QB = (0x19 << 6) | OPC_CMPU_EQ_QB_DSP,
479 OPC_CMPGDU_LE_QB = (0x1A << 6) | OPC_CMPU_EQ_QB_DSP,
480 OPC_CMP_EQ_PH = (0x08 << 6) | OPC_CMPU_EQ_QB_DSP,
481 OPC_CMP_LT_PH = (0x09 << 6) | OPC_CMPU_EQ_QB_DSP,
482 OPC_CMP_LE_PH = (0x0A << 6) | OPC_CMPU_EQ_QB_DSP,
483 OPC_PICK_QB = (0x03 << 6) | OPC_CMPU_EQ_QB_DSP,
484 OPC_PICK_PH = (0x0B << 6) | OPC_CMPU_EQ_QB_DSP,
485 OPC_PACKRL_PH = (0x0E << 6) | OPC_CMPU_EQ_QB_DSP,
488 #define MASK_SHLL_QB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
489 enum {
490 /* MIPS DSP GPR-Based Shift Sub-class */
491 OPC_SHLL_QB = (0x00 << 6) | OPC_SHLL_QB_DSP,
492 OPC_SHLLV_QB = (0x02 << 6) | OPC_SHLL_QB_DSP,
493 OPC_SHLL_PH = (0x08 << 6) | OPC_SHLL_QB_DSP,
494 OPC_SHLLV_PH = (0x0A << 6) | OPC_SHLL_QB_DSP,
495 OPC_SHLL_S_PH = (0x0C << 6) | OPC_SHLL_QB_DSP,
496 OPC_SHLLV_S_PH = (0x0E << 6) | OPC_SHLL_QB_DSP,
497 OPC_SHLL_S_W = (0x14 << 6) | OPC_SHLL_QB_DSP,
498 OPC_SHLLV_S_W = (0x16 << 6) | OPC_SHLL_QB_DSP,
499 OPC_SHRL_QB = (0x01 << 6) | OPC_SHLL_QB_DSP,
500 OPC_SHRLV_QB = (0x03 << 6) | OPC_SHLL_QB_DSP,
501 OPC_SHRL_PH = (0x19 << 6) | OPC_SHLL_QB_DSP,
502 OPC_SHRLV_PH = (0x1B << 6) | OPC_SHLL_QB_DSP,
503 OPC_SHRA_QB = (0x04 << 6) | OPC_SHLL_QB_DSP,
504 OPC_SHRA_R_QB = (0x05 << 6) | OPC_SHLL_QB_DSP,
505 OPC_SHRAV_QB = (0x06 << 6) | OPC_SHLL_QB_DSP,
506 OPC_SHRAV_R_QB = (0x07 << 6) | OPC_SHLL_QB_DSP,
507 OPC_SHRA_PH = (0x09 << 6) | OPC_SHLL_QB_DSP,
508 OPC_SHRAV_PH = (0x0B << 6) | OPC_SHLL_QB_DSP,
509 OPC_SHRA_R_PH = (0x0D << 6) | OPC_SHLL_QB_DSP,
510 OPC_SHRAV_R_PH = (0x0F << 6) | OPC_SHLL_QB_DSP,
511 OPC_SHRA_R_W = (0x15 << 6) | OPC_SHLL_QB_DSP,
512 OPC_SHRAV_R_W = (0x17 << 6) | OPC_SHLL_QB_DSP,
515 #define MASK_DPA_W_PH(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
516 enum {
517 /* MIPS DSP Multiply Sub-class insns */
518 OPC_DPAU_H_QBL = (0x03 << 6) | OPC_DPA_W_PH_DSP,
519 OPC_DPAU_H_QBR = (0x07 << 6) | OPC_DPA_W_PH_DSP,
520 OPC_DPSU_H_QBL = (0x0B << 6) | OPC_DPA_W_PH_DSP,
521 OPC_DPSU_H_QBR = (0x0F << 6) | OPC_DPA_W_PH_DSP,
522 OPC_DPA_W_PH = (0x00 << 6) | OPC_DPA_W_PH_DSP,
523 OPC_DPAX_W_PH = (0x08 << 6) | OPC_DPA_W_PH_DSP,
524 OPC_DPAQ_S_W_PH = (0x04 << 6) | OPC_DPA_W_PH_DSP,
525 OPC_DPAQX_S_W_PH = (0x18 << 6) | OPC_DPA_W_PH_DSP,
526 OPC_DPAQX_SA_W_PH = (0x1A << 6) | OPC_DPA_W_PH_DSP,
527 OPC_DPS_W_PH = (0x01 << 6) | OPC_DPA_W_PH_DSP,
528 OPC_DPSX_W_PH = (0x09 << 6) | OPC_DPA_W_PH_DSP,
529 OPC_DPSQ_S_W_PH = (0x05 << 6) | OPC_DPA_W_PH_DSP,
530 OPC_DPSQX_S_W_PH = (0x19 << 6) | OPC_DPA_W_PH_DSP,
531 OPC_DPSQX_SA_W_PH = (0x1B << 6) | OPC_DPA_W_PH_DSP,
532 OPC_MULSAQ_S_W_PH = (0x06 << 6) | OPC_DPA_W_PH_DSP,
533 OPC_DPAQ_SA_L_W = (0x0C << 6) | OPC_DPA_W_PH_DSP,
534 OPC_DPSQ_SA_L_W = (0x0D << 6) | OPC_DPA_W_PH_DSP,
535 OPC_MAQ_S_W_PHL = (0x14 << 6) | OPC_DPA_W_PH_DSP,
536 OPC_MAQ_S_W_PHR = (0x16 << 6) | OPC_DPA_W_PH_DSP,
537 OPC_MAQ_SA_W_PHL = (0x10 << 6) | OPC_DPA_W_PH_DSP,
538 OPC_MAQ_SA_W_PHR = (0x12 << 6) | OPC_DPA_W_PH_DSP,
539 OPC_MULSA_W_PH = (0x02 << 6) | OPC_DPA_W_PH_DSP,
542 #define MASK_INSV(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
543 enum {
544 /* DSP Bit/Manipulation Sub-class */
545 OPC_INSV = (0x00 << 6) | OPC_INSV_DSP,
548 #define MASK_APPEND(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
549 enum {
550 /* MIPS DSP Append Sub-class */
551 OPC_APPEND = (0x00 << 6) | OPC_APPEND_DSP,
552 OPC_PREPEND = (0x01 << 6) | OPC_APPEND_DSP,
553 OPC_BALIGN = (0x10 << 6) | OPC_APPEND_DSP,
556 #define MASK_EXTR_W(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
557 enum {
558 /* MIPS DSP Accumulator and DSPControl Access Sub-class */
559 OPC_EXTR_W = (0x00 << 6) | OPC_EXTR_W_DSP,
560 OPC_EXTR_R_W = (0x04 << 6) | OPC_EXTR_W_DSP,
561 OPC_EXTR_RS_W = (0x06 << 6) | OPC_EXTR_W_DSP,
562 OPC_EXTR_S_H = (0x0E << 6) | OPC_EXTR_W_DSP,
563 OPC_EXTRV_S_H = (0x0F << 6) | OPC_EXTR_W_DSP,
564 OPC_EXTRV_W = (0x01 << 6) | OPC_EXTR_W_DSP,
565 OPC_EXTRV_R_W = (0x05 << 6) | OPC_EXTR_W_DSP,
566 OPC_EXTRV_RS_W = (0x07 << 6) | OPC_EXTR_W_DSP,
567 OPC_EXTP = (0x02 << 6) | OPC_EXTR_W_DSP,
568 OPC_EXTPV = (0x03 << 6) | OPC_EXTR_W_DSP,
569 OPC_EXTPDP = (0x0A << 6) | OPC_EXTR_W_DSP,
570 OPC_EXTPDPV = (0x0B << 6) | OPC_EXTR_W_DSP,
571 OPC_SHILO = (0x1A << 6) | OPC_EXTR_W_DSP,
572 OPC_SHILOV = (0x1B << 6) | OPC_EXTR_W_DSP,
573 OPC_MTHLIP = (0x1F << 6) | OPC_EXTR_W_DSP,
574 OPC_WRDSP = (0x13 << 6) | OPC_EXTR_W_DSP,
575 OPC_RDDSP = (0x12 << 6) | OPC_EXTR_W_DSP,
578 #define MASK_ABSQ_S_QH(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
579 enum {
580 /* MIPS DSP Arithmetic Sub-class */
581 OPC_PRECEQ_L_PWL = (0x14 << 6) | OPC_ABSQ_S_QH_DSP,
582 OPC_PRECEQ_L_PWR = (0x15 << 6) | OPC_ABSQ_S_QH_DSP,
583 OPC_PRECEQ_PW_QHL = (0x0C << 6) | OPC_ABSQ_S_QH_DSP,
584 OPC_PRECEQ_PW_QHR = (0x0D << 6) | OPC_ABSQ_S_QH_DSP,
585 OPC_PRECEQ_PW_QHLA = (0x0E << 6) | OPC_ABSQ_S_QH_DSP,
586 OPC_PRECEQ_PW_QHRA = (0x0F << 6) | OPC_ABSQ_S_QH_DSP,
587 OPC_PRECEQU_QH_OBL = (0x04 << 6) | OPC_ABSQ_S_QH_DSP,
588 OPC_PRECEQU_QH_OBR = (0x05 << 6) | OPC_ABSQ_S_QH_DSP,
589 OPC_PRECEQU_QH_OBLA = (0x06 << 6) | OPC_ABSQ_S_QH_DSP,
590 OPC_PRECEQU_QH_OBRA = (0x07 << 6) | OPC_ABSQ_S_QH_DSP,
591 OPC_PRECEU_QH_OBL = (0x1C << 6) | OPC_ABSQ_S_QH_DSP,
592 OPC_PRECEU_QH_OBR = (0x1D << 6) | OPC_ABSQ_S_QH_DSP,
593 OPC_PRECEU_QH_OBLA = (0x1E << 6) | OPC_ABSQ_S_QH_DSP,
594 OPC_PRECEU_QH_OBRA = (0x1F << 6) | OPC_ABSQ_S_QH_DSP,
595 OPC_ABSQ_S_OB = (0x01 << 6) | OPC_ABSQ_S_QH_DSP,
596 OPC_ABSQ_S_PW = (0x11 << 6) | OPC_ABSQ_S_QH_DSP,
597 OPC_ABSQ_S_QH = (0x09 << 6) | OPC_ABSQ_S_QH_DSP,
598 /* DSP Bit/Manipulation Sub-class */
599 OPC_REPL_OB = (0x02 << 6) | OPC_ABSQ_S_QH_DSP,
600 OPC_REPL_PW = (0x12 << 6) | OPC_ABSQ_S_QH_DSP,
601 OPC_REPL_QH = (0x0A << 6) | OPC_ABSQ_S_QH_DSP,
602 OPC_REPLV_OB = (0x03 << 6) | OPC_ABSQ_S_QH_DSP,
603 OPC_REPLV_PW = (0x13 << 6) | OPC_ABSQ_S_QH_DSP,
604 OPC_REPLV_QH = (0x0B << 6) | OPC_ABSQ_S_QH_DSP,
607 #define MASK_ADDU_OB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
608 enum {
609 /* MIPS DSP Multiply Sub-class insns */
610 OPC_MULEQ_S_PW_QHL = (0x1C << 6) | OPC_ADDU_OB_DSP,
611 OPC_MULEQ_S_PW_QHR = (0x1D << 6) | OPC_ADDU_OB_DSP,
612 OPC_MULEU_S_QH_OBL = (0x06 << 6) | OPC_ADDU_OB_DSP,
613 OPC_MULEU_S_QH_OBR = (0x07 << 6) | OPC_ADDU_OB_DSP,
614 OPC_MULQ_RS_QH = (0x1F << 6) | OPC_ADDU_OB_DSP,
615 /* MIPS DSP Arithmetic Sub-class */
616 OPC_RADDU_L_OB = (0x14 << 6) | OPC_ADDU_OB_DSP,
617 OPC_SUBQ_PW = (0x13 << 6) | OPC_ADDU_OB_DSP,
618 OPC_SUBQ_S_PW = (0x17 << 6) | OPC_ADDU_OB_DSP,
619 OPC_SUBQ_QH = (0x0B << 6) | OPC_ADDU_OB_DSP,
620 OPC_SUBQ_S_QH = (0x0F << 6) | OPC_ADDU_OB_DSP,
621 OPC_SUBU_OB = (0x01 << 6) | OPC_ADDU_OB_DSP,
622 OPC_SUBU_S_OB = (0x05 << 6) | OPC_ADDU_OB_DSP,
623 OPC_SUBU_QH = (0x09 << 6) | OPC_ADDU_OB_DSP,
624 OPC_SUBU_S_QH = (0x0D << 6) | OPC_ADDU_OB_DSP,
625 OPC_SUBUH_OB = (0x19 << 6) | OPC_ADDU_OB_DSP,
626 OPC_SUBUH_R_OB = (0x1B << 6) | OPC_ADDU_OB_DSP,
627 OPC_ADDQ_PW = (0x12 << 6) | OPC_ADDU_OB_DSP,
628 OPC_ADDQ_S_PW = (0x16 << 6) | OPC_ADDU_OB_DSP,
629 OPC_ADDQ_QH = (0x0A << 6) | OPC_ADDU_OB_DSP,
630 OPC_ADDQ_S_QH = (0x0E << 6) | OPC_ADDU_OB_DSP,
631 OPC_ADDU_OB = (0x00 << 6) | OPC_ADDU_OB_DSP,
632 OPC_ADDU_S_OB = (0x04 << 6) | OPC_ADDU_OB_DSP,
633 OPC_ADDU_QH = (0x08 << 6) | OPC_ADDU_OB_DSP,
634 OPC_ADDU_S_QH = (0x0C << 6) | OPC_ADDU_OB_DSP,
635 OPC_ADDUH_OB = (0x18 << 6) | OPC_ADDU_OB_DSP,
636 OPC_ADDUH_R_OB = (0x1A << 6) | OPC_ADDU_OB_DSP,
639 #define MASK_CMPU_EQ_OB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
640 enum {
641 /* DSP Compare-Pick Sub-class */
642 OPC_CMP_EQ_PW = (0x10 << 6) | OPC_CMPU_EQ_OB_DSP,
643 OPC_CMP_LT_PW = (0x11 << 6) | OPC_CMPU_EQ_OB_DSP,
644 OPC_CMP_LE_PW = (0x12 << 6) | OPC_CMPU_EQ_OB_DSP,
645 OPC_CMP_EQ_QH = (0x08 << 6) | OPC_CMPU_EQ_OB_DSP,
646 OPC_CMP_LT_QH = (0x09 << 6) | OPC_CMPU_EQ_OB_DSP,
647 OPC_CMP_LE_QH = (0x0A << 6) | OPC_CMPU_EQ_OB_DSP,
648 OPC_CMPGDU_EQ_OB = (0x18 << 6) | OPC_CMPU_EQ_OB_DSP,
649 OPC_CMPGDU_LT_OB = (0x19 << 6) | OPC_CMPU_EQ_OB_DSP,
650 OPC_CMPGDU_LE_OB = (0x1A << 6) | OPC_CMPU_EQ_OB_DSP,
651 OPC_CMPGU_EQ_OB = (0x04 << 6) | OPC_CMPU_EQ_OB_DSP,
652 OPC_CMPGU_LT_OB = (0x05 << 6) | OPC_CMPU_EQ_OB_DSP,
653 OPC_CMPGU_LE_OB = (0x06 << 6) | OPC_CMPU_EQ_OB_DSP,
654 OPC_CMPU_EQ_OB = (0x00 << 6) | OPC_CMPU_EQ_OB_DSP,
655 OPC_CMPU_LT_OB = (0x01 << 6) | OPC_CMPU_EQ_OB_DSP,
656 OPC_CMPU_LE_OB = (0x02 << 6) | OPC_CMPU_EQ_OB_DSP,
657 OPC_PACKRL_PW = (0x0E << 6) | OPC_CMPU_EQ_OB_DSP,
658 OPC_PICK_OB = (0x03 << 6) | OPC_CMPU_EQ_OB_DSP,
659 OPC_PICK_PW = (0x13 << 6) | OPC_CMPU_EQ_OB_DSP,
660 OPC_PICK_QH = (0x0B << 6) | OPC_CMPU_EQ_OB_DSP,
661 /* MIPS DSP Arithmetic Sub-class */
662 OPC_PRECR_OB_QH = (0x0D << 6) | OPC_CMPU_EQ_OB_DSP,
663 OPC_PRECR_SRA_QH_PW = (0x1E << 6) | OPC_CMPU_EQ_OB_DSP,
664 OPC_PRECR_SRA_R_QH_PW = (0x1F << 6) | OPC_CMPU_EQ_OB_DSP,
665 OPC_PRECRQ_OB_QH = (0x0C << 6) | OPC_CMPU_EQ_OB_DSP,
666 OPC_PRECRQ_PW_L = (0x1C << 6) | OPC_CMPU_EQ_OB_DSP,
667 OPC_PRECRQ_QH_PW = (0x14 << 6) | OPC_CMPU_EQ_OB_DSP,
668 OPC_PRECRQ_RS_QH_PW = (0x15 << 6) | OPC_CMPU_EQ_OB_DSP,
669 OPC_PRECRQU_S_OB_QH = (0x0F << 6) | OPC_CMPU_EQ_OB_DSP,
672 #define MASK_DAPPEND(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
673 enum {
674 /* DSP Append Sub-class */
675 OPC_DAPPEND = (0x00 << 6) | OPC_DAPPEND_DSP,
676 OPC_PREPENDD = (0x03 << 6) | OPC_DAPPEND_DSP,
677 OPC_PREPENDW = (0x01 << 6) | OPC_DAPPEND_DSP,
678 OPC_DBALIGN = (0x10 << 6) | OPC_DAPPEND_DSP,
681 #define MASK_DEXTR_W(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
682 enum {
683 /* MIPS DSP Accumulator and DSPControl Access Sub-class */
684 OPC_DMTHLIP = (0x1F << 6) | OPC_DEXTR_W_DSP,
685 OPC_DSHILO = (0x1A << 6) | OPC_DEXTR_W_DSP,
686 OPC_DEXTP = (0x02 << 6) | OPC_DEXTR_W_DSP,
687 OPC_DEXTPDP = (0x0A << 6) | OPC_DEXTR_W_DSP,
688 OPC_DEXTPDPV = (0x0B << 6) | OPC_DEXTR_W_DSP,
689 OPC_DEXTPV = (0x03 << 6) | OPC_DEXTR_W_DSP,
690 OPC_DEXTR_L = (0x10 << 6) | OPC_DEXTR_W_DSP,
691 OPC_DEXTR_R_L = (0x14 << 6) | OPC_DEXTR_W_DSP,
692 OPC_DEXTR_RS_L = (0x16 << 6) | OPC_DEXTR_W_DSP,
693 OPC_DEXTR_W = (0x00 << 6) | OPC_DEXTR_W_DSP,
694 OPC_DEXTR_R_W = (0x04 << 6) | OPC_DEXTR_W_DSP,
695 OPC_DEXTR_RS_W = (0x06 << 6) | OPC_DEXTR_W_DSP,
696 OPC_DEXTR_S_H = (0x0E << 6) | OPC_DEXTR_W_DSP,
697 OPC_DEXTRV_L = (0x11 << 6) | OPC_DEXTR_W_DSP,
698 OPC_DEXTRV_R_L = (0x15 << 6) | OPC_DEXTR_W_DSP,
699 OPC_DEXTRV_RS_L = (0x17 << 6) | OPC_DEXTR_W_DSP,
700 OPC_DEXTRV_S_H = (0x0F << 6) | OPC_DEXTR_W_DSP,
701 OPC_DEXTRV_W = (0x01 << 6) | OPC_DEXTR_W_DSP,
702 OPC_DEXTRV_R_W = (0x05 << 6) | OPC_DEXTR_W_DSP,
703 OPC_DEXTRV_RS_W = (0x07 << 6) | OPC_DEXTR_W_DSP,
704 OPC_DSHILOV = (0x1B << 6) | OPC_DEXTR_W_DSP,
707 #define MASK_DINSV(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
708 enum {
709 /* DSP Bit/Manipulation Sub-class */
710 OPC_DINSV = (0x00 << 6) | OPC_DINSV_DSP,
713 #define MASK_DPAQ_W_QH(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
714 enum {
715 /* MIPS DSP Multiply Sub-class insns */
716 OPC_DMADD = (0x19 << 6) | OPC_DPAQ_W_QH_DSP,
717 OPC_DMADDU = (0x1D << 6) | OPC_DPAQ_W_QH_DSP,
718 OPC_DMSUB = (0x1B << 6) | OPC_DPAQ_W_QH_DSP,
719 OPC_DMSUBU = (0x1F << 6) | OPC_DPAQ_W_QH_DSP,
720 OPC_DPA_W_QH = (0x00 << 6) | OPC_DPAQ_W_QH_DSP,
721 OPC_DPAQ_S_W_QH = (0x04 << 6) | OPC_DPAQ_W_QH_DSP,
722 OPC_DPAQ_SA_L_PW = (0x0C << 6) | OPC_DPAQ_W_QH_DSP,
723 OPC_DPAU_H_OBL = (0x03 << 6) | OPC_DPAQ_W_QH_DSP,
724 OPC_DPAU_H_OBR = (0x07 << 6) | OPC_DPAQ_W_QH_DSP,
725 OPC_DPS_W_QH = (0x01 << 6) | OPC_DPAQ_W_QH_DSP,
726 OPC_DPSQ_S_W_QH = (0x05 << 6) | OPC_DPAQ_W_QH_DSP,
727 OPC_DPSQ_SA_L_PW = (0x0D << 6) | OPC_DPAQ_W_QH_DSP,
728 OPC_DPSU_H_OBL = (0x0B << 6) | OPC_DPAQ_W_QH_DSP,
729 OPC_DPSU_H_OBR = (0x0F << 6) | OPC_DPAQ_W_QH_DSP,
730 OPC_MAQ_S_L_PWL = (0x1C << 6) | OPC_DPAQ_W_QH_DSP,
731 OPC_MAQ_S_L_PWR = (0x1E << 6) | OPC_DPAQ_W_QH_DSP,
732 OPC_MAQ_S_W_QHLL = (0x14 << 6) | OPC_DPAQ_W_QH_DSP,
733 OPC_MAQ_SA_W_QHLL = (0x10 << 6) | OPC_DPAQ_W_QH_DSP,
734 OPC_MAQ_S_W_QHLR = (0x15 << 6) | OPC_DPAQ_W_QH_DSP,
735 OPC_MAQ_SA_W_QHLR = (0x11 << 6) | OPC_DPAQ_W_QH_DSP,
736 OPC_MAQ_S_W_QHRL = (0x16 << 6) | OPC_DPAQ_W_QH_DSP,
737 OPC_MAQ_SA_W_QHRL = (0x12 << 6) | OPC_DPAQ_W_QH_DSP,
738 OPC_MAQ_S_W_QHRR = (0x17 << 6) | OPC_DPAQ_W_QH_DSP,
739 OPC_MAQ_SA_W_QHRR = (0x13 << 6) | OPC_DPAQ_W_QH_DSP,
740 OPC_MULSAQ_S_L_PW = (0x0E << 6) | OPC_DPAQ_W_QH_DSP,
741 OPC_MULSAQ_S_W_QH = (0x06 << 6) | OPC_DPAQ_W_QH_DSP,
744 #define MASK_SHLL_OB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
745 enum {
746 /* MIPS DSP GPR-Based Shift Sub-class */
747 OPC_SHLL_PW = (0x10 << 6) | OPC_SHLL_OB_DSP,
748 OPC_SHLL_S_PW = (0x14 << 6) | OPC_SHLL_OB_DSP,
749 OPC_SHLLV_OB = (0x02 << 6) | OPC_SHLL_OB_DSP,
750 OPC_SHLLV_PW = (0x12 << 6) | OPC_SHLL_OB_DSP,
751 OPC_SHLLV_S_PW = (0x16 << 6) | OPC_SHLL_OB_DSP,
752 OPC_SHLLV_QH = (0x0A << 6) | OPC_SHLL_OB_DSP,
753 OPC_SHLLV_S_QH = (0x0E << 6) | OPC_SHLL_OB_DSP,
754 OPC_SHRA_PW = (0x11 << 6) | OPC_SHLL_OB_DSP,
755 OPC_SHRA_R_PW = (0x15 << 6) | OPC_SHLL_OB_DSP,
756 OPC_SHRAV_OB = (0x06 << 6) | OPC_SHLL_OB_DSP,
757 OPC_SHRAV_R_OB = (0x07 << 6) | OPC_SHLL_OB_DSP,
758 OPC_SHRAV_PW = (0x13 << 6) | OPC_SHLL_OB_DSP,
759 OPC_SHRAV_R_PW = (0x17 << 6) | OPC_SHLL_OB_DSP,
760 OPC_SHRAV_QH = (0x0B << 6) | OPC_SHLL_OB_DSP,
761 OPC_SHRAV_R_QH = (0x0F << 6) | OPC_SHLL_OB_DSP,
762 OPC_SHRLV_OB = (0x03 << 6) | OPC_SHLL_OB_DSP,
763 OPC_SHRLV_QH = (0x1B << 6) | OPC_SHLL_OB_DSP,
764 OPC_SHLL_OB = (0x00 << 6) | OPC_SHLL_OB_DSP,
765 OPC_SHLL_QH = (0x08 << 6) | OPC_SHLL_OB_DSP,
766 OPC_SHLL_S_QH = (0x0C << 6) | OPC_SHLL_OB_DSP,
767 OPC_SHRA_OB = (0x04 << 6) | OPC_SHLL_OB_DSP,
768 OPC_SHRA_R_OB = (0x05 << 6) | OPC_SHLL_OB_DSP,
769 OPC_SHRA_QH = (0x09 << 6) | OPC_SHLL_OB_DSP,
770 OPC_SHRA_R_QH = (0x0D << 6) | OPC_SHLL_OB_DSP,
771 OPC_SHRL_OB = (0x01 << 6) | OPC_SHLL_OB_DSP,
772 OPC_SHRL_QH = (0x19 << 6) | OPC_SHLL_OB_DSP,
775 /* Coprocessor 0 (rs field) */
776 #define MASK_CP0(op) MASK_OP_MAJOR(op) | (op & (0x1F << 21))
778 enum {
779 OPC_MFC0 = (0x00 << 21) | OPC_CP0,
780 OPC_DMFC0 = (0x01 << 21) | OPC_CP0,
781 OPC_MTC0 = (0x04 << 21) | OPC_CP0,
782 OPC_DMTC0 = (0x05 << 21) | OPC_CP0,
783 OPC_MFTR = (0x08 << 21) | OPC_CP0,
784 OPC_RDPGPR = (0x0A << 21) | OPC_CP0,
785 OPC_MFMC0 = (0x0B << 21) | OPC_CP0,
786 OPC_MTTR = (0x0C << 21) | OPC_CP0,
787 OPC_WRPGPR = (0x0E << 21) | OPC_CP0,
788 OPC_C0 = (0x10 << 21) | OPC_CP0,
789 OPC_C0_FIRST = (0x10 << 21) | OPC_CP0,
790 OPC_C0_LAST = (0x1F << 21) | OPC_CP0,
793 /* MFMC0 opcodes */
794 #define MASK_MFMC0(op) MASK_CP0(op) | (op & 0xFFFF)
796 enum {
797 OPC_DMT = 0x01 | (0 << 5) | (0x0F << 6) | (0x01 << 11) | OPC_MFMC0,
798 OPC_EMT = 0x01 | (1 << 5) | (0x0F << 6) | (0x01 << 11) | OPC_MFMC0,
799 OPC_DVPE = 0x01 | (0 << 5) | OPC_MFMC0,
800 OPC_EVPE = 0x01 | (1 << 5) | OPC_MFMC0,
801 OPC_DI = (0 << 5) | (0x0C << 11) | OPC_MFMC0,
802 OPC_EI = (1 << 5) | (0x0C << 11) | OPC_MFMC0,
805 /* Coprocessor 0 (with rs == C0) */
806 #define MASK_C0(op) MASK_CP0(op) | (op & 0x3F)
808 enum {
809 OPC_TLBR = 0x01 | OPC_C0,
810 OPC_TLBWI = 0x02 | OPC_C0,
811 OPC_TLBWR = 0x06 | OPC_C0,
812 OPC_TLBP = 0x08 | OPC_C0,
813 OPC_RFE = 0x10 | OPC_C0,
814 OPC_ERET = 0x18 | OPC_C0,
815 OPC_DERET = 0x1F | OPC_C0,
816 OPC_WAIT = 0x20 | OPC_C0,
819 /* Coprocessor 1 (rs field) */
820 #define MASK_CP1(op) MASK_OP_MAJOR(op) | (op & (0x1F << 21))
822 /* Values for the fmt field in FP instructions */
823 enum {
824 /* 0 - 15 are reserved */
825 FMT_S = 16, /* single fp */
826 FMT_D = 17, /* double fp */
827 FMT_E = 18, /* extended fp */
828 FMT_Q = 19, /* quad fp */
829 FMT_W = 20, /* 32-bit fixed */
830 FMT_L = 21, /* 64-bit fixed */
831 FMT_PS = 22, /* paired single fp */
832 /* 23 - 31 are reserved */
835 enum {
836 OPC_MFC1 = (0x00 << 21) | OPC_CP1,
837 OPC_DMFC1 = (0x01 << 21) | OPC_CP1,
838 OPC_CFC1 = (0x02 << 21) | OPC_CP1,
839 OPC_MFHC1 = (0x03 << 21) | OPC_CP1,
840 OPC_MTC1 = (0x04 << 21) | OPC_CP1,
841 OPC_DMTC1 = (0x05 << 21) | OPC_CP1,
842 OPC_CTC1 = (0x06 << 21) | OPC_CP1,
843 OPC_MTHC1 = (0x07 << 21) | OPC_CP1,
844 OPC_BC1 = (0x08 << 21) | OPC_CP1, /* bc */
845 OPC_BC1ANY2 = (0x09 << 21) | OPC_CP1,
846 OPC_BC1ANY4 = (0x0A << 21) | OPC_CP1,
847 OPC_S_FMT = (FMT_S << 21) | OPC_CP1,
848 OPC_D_FMT = (FMT_D << 21) | OPC_CP1,
849 OPC_E_FMT = (FMT_E << 21) | OPC_CP1,
850 OPC_Q_FMT = (FMT_Q << 21) | OPC_CP1,
851 OPC_W_FMT = (FMT_W << 21) | OPC_CP1,
852 OPC_L_FMT = (FMT_L << 21) | OPC_CP1,
853 OPC_PS_FMT = (FMT_PS << 21) | OPC_CP1,
856 #define MASK_CP1_FUNC(op) MASK_CP1(op) | (op & 0x3F)
857 #define MASK_BC1(op) MASK_CP1(op) | (op & (0x3 << 16))
859 enum {
860 OPC_BC1F = (0x00 << 16) | OPC_BC1,
861 OPC_BC1T = (0x01 << 16) | OPC_BC1,
862 OPC_BC1FL = (0x02 << 16) | OPC_BC1,
863 OPC_BC1TL = (0x03 << 16) | OPC_BC1,
866 enum {
867 OPC_BC1FANY2 = (0x00 << 16) | OPC_BC1ANY2,
868 OPC_BC1TANY2 = (0x01 << 16) | OPC_BC1ANY2,
871 enum {
872 OPC_BC1FANY4 = (0x00 << 16) | OPC_BC1ANY4,
873 OPC_BC1TANY4 = (0x01 << 16) | OPC_BC1ANY4,
876 #define MASK_CP2(op) MASK_OP_MAJOR(op) | (op & (0x1F << 21))
878 enum {
879 OPC_MFC2 = (0x00 << 21) | OPC_CP2,
880 OPC_DMFC2 = (0x01 << 21) | OPC_CP2,
881 OPC_CFC2 = (0x02 << 21) | OPC_CP2,
882 OPC_MFHC2 = (0x03 << 21) | OPC_CP2,
883 OPC_MTC2 = (0x04 << 21) | OPC_CP2,
884 OPC_DMTC2 = (0x05 << 21) | OPC_CP2,
885 OPC_CTC2 = (0x06 << 21) | OPC_CP2,
886 OPC_MTHC2 = (0x07 << 21) | OPC_CP2,
887 OPC_BC2 = (0x08 << 21) | OPC_CP2,
890 #define MASK_LMI(op) (MASK_OP_MAJOR(op) | (op & (0x1F << 21)) | (op & 0x1F))
892 enum {
893 OPC_PADDSH = (24 << 21) | (0x00) | OPC_CP2,
894 OPC_PADDUSH = (25 << 21) | (0x00) | OPC_CP2,
895 OPC_PADDH = (26 << 21) | (0x00) | OPC_CP2,
896 OPC_PADDW = (27 << 21) | (0x00) | OPC_CP2,
897 OPC_PADDSB = (28 << 21) | (0x00) | OPC_CP2,
898 OPC_PADDUSB = (29 << 21) | (0x00) | OPC_CP2,
899 OPC_PADDB = (30 << 21) | (0x00) | OPC_CP2,
900 OPC_PADDD = (31 << 21) | (0x00) | OPC_CP2,
902 OPC_PSUBSH = (24 << 21) | (0x01) | OPC_CP2,
903 OPC_PSUBUSH = (25 << 21) | (0x01) | OPC_CP2,
904 OPC_PSUBH = (26 << 21) | (0x01) | OPC_CP2,
905 OPC_PSUBW = (27 << 21) | (0x01) | OPC_CP2,
906 OPC_PSUBSB = (28 << 21) | (0x01) | OPC_CP2,
907 OPC_PSUBUSB = (29 << 21) | (0x01) | OPC_CP2,
908 OPC_PSUBB = (30 << 21) | (0x01) | OPC_CP2,
909 OPC_PSUBD = (31 << 21) | (0x01) | OPC_CP2,
911 OPC_PSHUFH = (24 << 21) | (0x02) | OPC_CP2,
912 OPC_PACKSSWH = (25 << 21) | (0x02) | OPC_CP2,
913 OPC_PACKSSHB = (26 << 21) | (0x02) | OPC_CP2,
914 OPC_PACKUSHB = (27 << 21) | (0x02) | OPC_CP2,
915 OPC_XOR_CP2 = (28 << 21) | (0x02) | OPC_CP2,
916 OPC_NOR_CP2 = (29 << 21) | (0x02) | OPC_CP2,
917 OPC_AND_CP2 = (30 << 21) | (0x02) | OPC_CP2,
918 OPC_PANDN = (31 << 21) | (0x02) | OPC_CP2,
920 OPC_PUNPCKLHW = (24 << 21) | (0x03) | OPC_CP2,
921 OPC_PUNPCKHHW = (25 << 21) | (0x03) | OPC_CP2,
922 OPC_PUNPCKLBH = (26 << 21) | (0x03) | OPC_CP2,
923 OPC_PUNPCKHBH = (27 << 21) | (0x03) | OPC_CP2,
924 OPC_PINSRH_0 = (28 << 21) | (0x03) | OPC_CP2,
925 OPC_PINSRH_1 = (29 << 21) | (0x03) | OPC_CP2,
926 OPC_PINSRH_2 = (30 << 21) | (0x03) | OPC_CP2,
927 OPC_PINSRH_3 = (31 << 21) | (0x03) | OPC_CP2,
929 OPC_PAVGH = (24 << 21) | (0x08) | OPC_CP2,
930 OPC_PAVGB = (25 << 21) | (0x08) | OPC_CP2,
931 OPC_PMAXSH = (26 << 21) | (0x08) | OPC_CP2,
932 OPC_PMINSH = (27 << 21) | (0x08) | OPC_CP2,
933 OPC_PMAXUB = (28 << 21) | (0x08) | OPC_CP2,
934 OPC_PMINUB = (29 << 21) | (0x08) | OPC_CP2,
936 OPC_PCMPEQW = (24 << 21) | (0x09) | OPC_CP2,
937 OPC_PCMPGTW = (25 << 21) | (0x09) | OPC_CP2,
938 OPC_PCMPEQH = (26 << 21) | (0x09) | OPC_CP2,
939 OPC_PCMPGTH = (27 << 21) | (0x09) | OPC_CP2,
940 OPC_PCMPEQB = (28 << 21) | (0x09) | OPC_CP2,
941 OPC_PCMPGTB = (29 << 21) | (0x09) | OPC_CP2,
943 OPC_PSLLW = (24 << 21) | (0x0A) | OPC_CP2,
944 OPC_PSLLH = (25 << 21) | (0x0A) | OPC_CP2,
945 OPC_PMULLH = (26 << 21) | (0x0A) | OPC_CP2,
946 OPC_PMULHH = (27 << 21) | (0x0A) | OPC_CP2,
947 OPC_PMULUW = (28 << 21) | (0x0A) | OPC_CP2,
948 OPC_PMULHUH = (29 << 21) | (0x0A) | OPC_CP2,
950 OPC_PSRLW = (24 << 21) | (0x0B) | OPC_CP2,
951 OPC_PSRLH = (25 << 21) | (0x0B) | OPC_CP2,
952 OPC_PSRAW = (26 << 21) | (0x0B) | OPC_CP2,
953 OPC_PSRAH = (27 << 21) | (0x0B) | OPC_CP2,
954 OPC_PUNPCKLWD = (28 << 21) | (0x0B) | OPC_CP2,
955 OPC_PUNPCKHWD = (29 << 21) | (0x0B) | OPC_CP2,
957 OPC_ADDU_CP2 = (24 << 21) | (0x0C) | OPC_CP2,
958 OPC_OR_CP2 = (25 << 21) | (0x0C) | OPC_CP2,
959 OPC_ADD_CP2 = (26 << 21) | (0x0C) | OPC_CP2,
960 OPC_DADD_CP2 = (27 << 21) | (0x0C) | OPC_CP2,
961 OPC_SEQU_CP2 = (28 << 21) | (0x0C) | OPC_CP2,
962 OPC_SEQ_CP2 = (29 << 21) | (0x0C) | OPC_CP2,
964 OPC_SUBU_CP2 = (24 << 21) | (0x0D) | OPC_CP2,
965 OPC_PASUBUB = (25 << 21) | (0x0D) | OPC_CP2,
966 OPC_SUB_CP2 = (26 << 21) | (0x0D) | OPC_CP2,
967 OPC_DSUB_CP2 = (27 << 21) | (0x0D) | OPC_CP2,
968 OPC_SLTU_CP2 = (28 << 21) | (0x0D) | OPC_CP2,
969 OPC_SLT_CP2 = (29 << 21) | (0x0D) | OPC_CP2,
971 OPC_SLL_CP2 = (24 << 21) | (0x0E) | OPC_CP2,
972 OPC_DSLL_CP2 = (25 << 21) | (0x0E) | OPC_CP2,
973 OPC_PEXTRH = (26 << 21) | (0x0E) | OPC_CP2,
974 OPC_PMADDHW = (27 << 21) | (0x0E) | OPC_CP2,
975 OPC_SLEU_CP2 = (28 << 21) | (0x0E) | OPC_CP2,
976 OPC_SLE_CP2 = (29 << 21) | (0x0E) | OPC_CP2,
978 OPC_SRL_CP2 = (24 << 21) | (0x0F) | OPC_CP2,
979 OPC_DSRL_CP2 = (25 << 21) | (0x0F) | OPC_CP2,
980 OPC_SRA_CP2 = (26 << 21) | (0x0F) | OPC_CP2,
981 OPC_DSRA_CP2 = (27 << 21) | (0x0F) | OPC_CP2,
982 OPC_BIADD = (28 << 21) | (0x0F) | OPC_CP2,
983 OPC_PMOVMSKB = (29 << 21) | (0x0F) | OPC_CP2,
987 #define MASK_CP3(op) MASK_OP_MAJOR(op) | (op & 0x3F)
989 enum {
990 OPC_LWXC1 = 0x00 | OPC_CP3,
991 OPC_LDXC1 = 0x01 | OPC_CP3,
992 OPC_LUXC1 = 0x05 | OPC_CP3,
993 OPC_SWXC1 = 0x08 | OPC_CP3,
994 OPC_SDXC1 = 0x09 | OPC_CP3,
995 OPC_SUXC1 = 0x0D | OPC_CP3,
996 OPC_PREFX = 0x0F | OPC_CP3,
997 OPC_ALNV_PS = 0x1E | OPC_CP3,
998 OPC_MADD_S = 0x20 | OPC_CP3,
999 OPC_MADD_D = 0x21 | OPC_CP3,
1000 OPC_MADD_PS = 0x26 | OPC_CP3,
1001 OPC_MSUB_S = 0x28 | OPC_CP3,
1002 OPC_MSUB_D = 0x29 | OPC_CP3,
1003 OPC_MSUB_PS = 0x2E | OPC_CP3,
1004 OPC_NMADD_S = 0x30 | OPC_CP3,
1005 OPC_NMADD_D = 0x31 | OPC_CP3,
1006 OPC_NMADD_PS= 0x36 | OPC_CP3,
1007 OPC_NMSUB_S = 0x38 | OPC_CP3,
1008 OPC_NMSUB_D = 0x39 | OPC_CP3,
1009 OPC_NMSUB_PS= 0x3E | OPC_CP3,
1012 /* global register indices */
1013 static TCGv_ptr cpu_env;
1014 static TCGv cpu_gpr[32], cpu_PC;
1015 static TCGv cpu_HI[MIPS_DSP_ACC], cpu_LO[MIPS_DSP_ACC], cpu_ACX[MIPS_DSP_ACC];
1016 static TCGv cpu_dspctrl, btarget, bcond;
1017 static TCGv_i32 hflags;
1018 static TCGv_i32 fpu_fcr0, fpu_fcr31;
1019 static TCGv_i64 fpu_f64[32];
1021 static uint32_t gen_opc_hflags[OPC_BUF_SIZE];
1022 static target_ulong gen_opc_btarget[OPC_BUF_SIZE];
1024 #include "exec/gen-icount.h"
1026 #define gen_helper_0e0i(name, arg) do { \
1027 TCGv_i32 helper_tmp = tcg_const_i32(arg); \
1028 gen_helper_##name(cpu_env, helper_tmp); \
1029 tcg_temp_free_i32(helper_tmp); \
1030 } while(0)
1032 #define gen_helper_0e1i(name, arg1, arg2) do { \
1033 TCGv_i32 helper_tmp = tcg_const_i32(arg2); \
1034 gen_helper_##name(cpu_env, arg1, helper_tmp); \
1035 tcg_temp_free_i32(helper_tmp); \
1036 } while(0)
1038 #define gen_helper_1e0i(name, ret, arg1) do { \
1039 TCGv_i32 helper_tmp = tcg_const_i32(arg1); \
1040 gen_helper_##name(ret, cpu_env, helper_tmp); \
1041 tcg_temp_free_i32(helper_tmp); \
1042 } while(0)
1044 #define gen_helper_1e1i(name, ret, arg1, arg2) do { \
1045 TCGv_i32 helper_tmp = tcg_const_i32(arg2); \
1046 gen_helper_##name(ret, cpu_env, arg1, helper_tmp); \
1047 tcg_temp_free_i32(helper_tmp); \
1048 } while(0)
1050 #define gen_helper_0e2i(name, arg1, arg2, arg3) do { \
1051 TCGv_i32 helper_tmp = tcg_const_i32(arg3); \
1052 gen_helper_##name(cpu_env, arg1, arg2, helper_tmp); \
1053 tcg_temp_free_i32(helper_tmp); \
1054 } while(0)
1056 #define gen_helper_1e2i(name, ret, arg1, arg2, arg3) do { \
1057 TCGv_i32 helper_tmp = tcg_const_i32(arg3); \
1058 gen_helper_##name(ret, cpu_env, arg1, arg2, helper_tmp); \
1059 tcg_temp_free_i32(helper_tmp); \
1060 } while(0)
1062 #define gen_helper_0e3i(name, arg1, arg2, arg3, arg4) do { \
1063 TCGv_i32 helper_tmp = tcg_const_i32(arg4); \
1064 gen_helper_##name(cpu_env, arg1, arg2, arg3, helper_tmp); \
1065 tcg_temp_free_i32(helper_tmp); \
1066 } while(0)
1068 typedef struct DisasContext {
1069 struct TranslationBlock *tb;
1070 target_ulong pc, saved_pc;
1071 uint32_t opcode;
1072 int singlestep_enabled;
1073 int insn_flags;
1074 int32_t CP0_Config1;
1075 /* Routine used to access memory */
1076 int mem_idx;
1077 uint32_t hflags, saved_hflags;
1078 int bstate;
1079 target_ulong btarget;
1080 bool ulri;
1081 } DisasContext;
1083 enum {
1084 BS_NONE = 0, /* We go out of the TB without reaching a branch or an
1085 * exception condition */
1086 BS_STOP = 1, /* We want to stop translation for any reason */
1087 BS_BRANCH = 2, /* We reached a branch condition */
1088 BS_EXCP = 3, /* We reached an exception condition */
1091 static const char * const regnames[] = {
1092 "r0", "at", "v0", "v1", "a0", "a1", "a2", "a3",
1093 "t0", "t1", "t2", "t3", "t4", "t5", "t6", "t7",
1094 "s0", "s1", "s2", "s3", "s4", "s5", "s6", "s7",
1095 "t8", "t9", "k0", "k1", "gp", "sp", "s8", "ra",
1098 static const char * const regnames_HI[] = {
1099 "HI0", "HI1", "HI2", "HI3",
1102 static const char * const regnames_LO[] = {
1103 "LO0", "LO1", "LO2", "LO3",
1106 static const char * const regnames_ACX[] = {
1107 "ACX0", "ACX1", "ACX2", "ACX3",
1110 static const char * const fregnames[] = {
1111 "f0", "f1", "f2", "f3", "f4", "f5", "f6", "f7",
1112 "f8", "f9", "f10", "f11", "f12", "f13", "f14", "f15",
1113 "f16", "f17", "f18", "f19", "f20", "f21", "f22", "f23",
1114 "f24", "f25", "f26", "f27", "f28", "f29", "f30", "f31",
1117 #define MIPS_DEBUG(fmt, ...) \
1118 do { \
1119 if (MIPS_DEBUG_DISAS) { \
1120 qemu_log_mask(CPU_LOG_TB_IN_ASM, \
1121 TARGET_FMT_lx ": %08x " fmt "\n", \
1122 ctx->pc, ctx->opcode , ## __VA_ARGS__); \
1124 } while (0)
1126 #define LOG_DISAS(...) \
1127 do { \
1128 if (MIPS_DEBUG_DISAS) { \
1129 qemu_log_mask(CPU_LOG_TB_IN_ASM, ## __VA_ARGS__); \
1131 } while (0)
1133 #define MIPS_INVAL(op) \
1134 MIPS_DEBUG("Invalid %s %03x %03x %03x", op, ctx->opcode >> 26, \
1135 ctx->opcode & 0x3F, ((ctx->opcode >> 16) & 0x1F))
1137 /* General purpose registers moves. */
1138 static inline void gen_load_gpr (TCGv t, int reg)
1140 if (reg == 0)
1141 tcg_gen_movi_tl(t, 0);
1142 else
1143 tcg_gen_mov_tl(t, cpu_gpr[reg]);
1146 static inline void gen_store_gpr (TCGv t, int reg)
1148 if (reg != 0)
1149 tcg_gen_mov_tl(cpu_gpr[reg], t);
1152 /* Moves to/from ACX register. */
1153 static inline void gen_load_ACX (TCGv t, int reg)
1155 tcg_gen_mov_tl(t, cpu_ACX[reg]);
1158 static inline void gen_store_ACX (TCGv t, int reg)
1160 tcg_gen_mov_tl(cpu_ACX[reg], t);
1163 /* Moves to/from shadow registers. */
1164 static inline void gen_load_srsgpr (int from, int to)
1166 TCGv t0 = tcg_temp_new();
1168 if (from == 0)
1169 tcg_gen_movi_tl(t0, 0);
1170 else {
1171 TCGv_i32 t2 = tcg_temp_new_i32();
1172 TCGv_ptr addr = tcg_temp_new_ptr();
1174 tcg_gen_ld_i32(t2, cpu_env, offsetof(CPUMIPSState, CP0_SRSCtl));
1175 tcg_gen_shri_i32(t2, t2, CP0SRSCtl_PSS);
1176 tcg_gen_andi_i32(t2, t2, 0xf);
1177 tcg_gen_muli_i32(t2, t2, sizeof(target_ulong) * 32);
1178 tcg_gen_ext_i32_ptr(addr, t2);
1179 tcg_gen_add_ptr(addr, cpu_env, addr);
1181 tcg_gen_ld_tl(t0, addr, sizeof(target_ulong) * from);
1182 tcg_temp_free_ptr(addr);
1183 tcg_temp_free_i32(t2);
1185 gen_store_gpr(t0, to);
1186 tcg_temp_free(t0);
1189 static inline void gen_store_srsgpr (int from, int to)
1191 if (to != 0) {
1192 TCGv t0 = tcg_temp_new();
1193 TCGv_i32 t2 = tcg_temp_new_i32();
1194 TCGv_ptr addr = tcg_temp_new_ptr();
1196 gen_load_gpr(t0, from);
1197 tcg_gen_ld_i32(t2, cpu_env, offsetof(CPUMIPSState, CP0_SRSCtl));
1198 tcg_gen_shri_i32(t2, t2, CP0SRSCtl_PSS);
1199 tcg_gen_andi_i32(t2, t2, 0xf);
1200 tcg_gen_muli_i32(t2, t2, sizeof(target_ulong) * 32);
1201 tcg_gen_ext_i32_ptr(addr, t2);
1202 tcg_gen_add_ptr(addr, cpu_env, addr);
1204 tcg_gen_st_tl(t0, addr, sizeof(target_ulong) * to);
1205 tcg_temp_free_ptr(addr);
1206 tcg_temp_free_i32(t2);
1207 tcg_temp_free(t0);
1211 /* Floating point register moves. */
1212 static void gen_load_fpr32(TCGv_i32 t, int reg)
1214 tcg_gen_trunc_i64_i32(t, fpu_f64[reg]);
1217 static void gen_store_fpr32(TCGv_i32 t, int reg)
1219 TCGv_i64 t64 = tcg_temp_new_i64();
1220 tcg_gen_extu_i32_i64(t64, t);
1221 tcg_gen_deposit_i64(fpu_f64[reg], fpu_f64[reg], t64, 0, 32);
1222 tcg_temp_free_i64(t64);
1225 static void gen_load_fpr32h(DisasContext *ctx, TCGv_i32 t, int reg)
1227 if (ctx->hflags & MIPS_HFLAG_F64) {
1228 TCGv_i64 t64 = tcg_temp_new_i64();
1229 tcg_gen_shri_i64(t64, fpu_f64[reg], 32);
1230 tcg_gen_trunc_i64_i32(t, t64);
1231 tcg_temp_free_i64(t64);
1232 } else {
1233 gen_load_fpr32(t, reg | 1);
1237 static void gen_store_fpr32h(DisasContext *ctx, TCGv_i32 t, int reg)
1239 if (ctx->hflags & MIPS_HFLAG_F64) {
1240 TCGv_i64 t64 = tcg_temp_new_i64();
1241 tcg_gen_extu_i32_i64(t64, t);
1242 tcg_gen_deposit_i64(fpu_f64[reg], fpu_f64[reg], t64, 32, 32);
1243 tcg_temp_free_i64(t64);
1244 } else {
1245 gen_store_fpr32(t, reg | 1);
1249 static void gen_load_fpr64(DisasContext *ctx, TCGv_i64 t, int reg)
1251 if (ctx->hflags & MIPS_HFLAG_F64) {
1252 tcg_gen_mov_i64(t, fpu_f64[reg]);
1253 } else {
1254 tcg_gen_concat32_i64(t, fpu_f64[reg & ~1], fpu_f64[reg | 1]);
1258 static void gen_store_fpr64(DisasContext *ctx, TCGv_i64 t, int reg)
1260 if (ctx->hflags & MIPS_HFLAG_F64) {
1261 tcg_gen_mov_i64(fpu_f64[reg], t);
1262 } else {
1263 TCGv_i64 t0;
1264 tcg_gen_deposit_i64(fpu_f64[reg & ~1], fpu_f64[reg & ~1], t, 0, 32);
1265 t0 = tcg_temp_new_i64();
1266 tcg_gen_shri_i64(t0, t, 32);
1267 tcg_gen_deposit_i64(fpu_f64[reg | 1], fpu_f64[reg | 1], t0, 0, 32);
1268 tcg_temp_free_i64(t0);
1272 static inline int get_fp_bit (int cc)
1274 if (cc)
1275 return 24 + cc;
1276 else
1277 return 23;
1280 /* Tests */
1281 static inline void gen_save_pc(target_ulong pc)
1283 tcg_gen_movi_tl(cpu_PC, pc);
1286 static inline void save_cpu_state (DisasContext *ctx, int do_save_pc)
1288 LOG_DISAS("hflags %08x saved %08x\n", ctx->hflags, ctx->saved_hflags);
1289 if (do_save_pc && ctx->pc != ctx->saved_pc) {
1290 gen_save_pc(ctx->pc);
1291 ctx->saved_pc = ctx->pc;
1293 if (ctx->hflags != ctx->saved_hflags) {
1294 tcg_gen_movi_i32(hflags, ctx->hflags);
1295 ctx->saved_hflags = ctx->hflags;
1296 switch (ctx->hflags & MIPS_HFLAG_BMASK_BASE) {
1297 case MIPS_HFLAG_BR:
1298 break;
1299 case MIPS_HFLAG_BC:
1300 case MIPS_HFLAG_BL:
1301 case MIPS_HFLAG_B:
1302 tcg_gen_movi_tl(btarget, ctx->btarget);
1303 break;
1308 static inline void restore_cpu_state (CPUMIPSState *env, DisasContext *ctx)
1310 ctx->saved_hflags = ctx->hflags;
1311 switch (ctx->hflags & MIPS_HFLAG_BMASK_BASE) {
1312 case MIPS_HFLAG_BR:
1313 break;
1314 case MIPS_HFLAG_BC:
1315 case MIPS_HFLAG_BL:
1316 case MIPS_HFLAG_B:
1317 ctx->btarget = env->btarget;
1318 break;
1322 static inline void
1323 generate_exception_err (DisasContext *ctx, int excp, int err)
1325 TCGv_i32 texcp = tcg_const_i32(excp);
1326 TCGv_i32 terr = tcg_const_i32(err);
1327 save_cpu_state(ctx, 1);
1328 gen_helper_raise_exception_err(cpu_env, texcp, terr);
1329 tcg_temp_free_i32(terr);
1330 tcg_temp_free_i32(texcp);
1333 static inline void
1334 generate_exception (DisasContext *ctx, int excp)
1336 save_cpu_state(ctx, 1);
1337 gen_helper_0e0i(raise_exception, excp);
1340 /* Addresses computation */
1341 static inline void gen_op_addr_add (DisasContext *ctx, TCGv ret, TCGv arg0, TCGv arg1)
1343 tcg_gen_add_tl(ret, arg0, arg1);
1345 #if defined(TARGET_MIPS64)
1346 /* For compatibility with 32-bit code, data reference in user mode
1347 with Status_UX = 0 should be casted to 32-bit and sign extended.
1348 See the MIPS64 PRA manual, section 4.10. */
1349 if (((ctx->hflags & MIPS_HFLAG_KSU) == MIPS_HFLAG_UM) &&
1350 !(ctx->hflags & MIPS_HFLAG_UX)) {
1351 tcg_gen_ext32s_i64(ret, ret);
1353 #endif
1356 static inline void check_cp0_enabled(DisasContext *ctx)
1358 if (unlikely(!(ctx->hflags & MIPS_HFLAG_CP0)))
1359 generate_exception_err(ctx, EXCP_CpU, 0);
1362 static inline void check_cp1_enabled(DisasContext *ctx)
1364 if (unlikely(!(ctx->hflags & MIPS_HFLAG_FPU)))
1365 generate_exception_err(ctx, EXCP_CpU, 1);
1368 /* Verify that the processor is running with COP1X instructions enabled.
1369 This is associated with the nabla symbol in the MIPS32 and MIPS64
1370 opcode tables. */
1372 static inline void check_cop1x(DisasContext *ctx)
1374 if (unlikely(!(ctx->hflags & MIPS_HFLAG_COP1X)))
1375 generate_exception(ctx, EXCP_RI);
1378 /* Verify that the processor is running with 64-bit floating-point
1379 operations enabled. */
1381 static inline void check_cp1_64bitmode(DisasContext *ctx)
1383 if (unlikely(~ctx->hflags & (MIPS_HFLAG_F64 | MIPS_HFLAG_COP1X)))
1384 generate_exception(ctx, EXCP_RI);
1388 * Verify if floating point register is valid; an operation is not defined
1389 * if bit 0 of any register specification is set and the FR bit in the
1390 * Status register equals zero, since the register numbers specify an
1391 * even-odd pair of adjacent coprocessor general registers. When the FR bit
1392 * in the Status register equals one, both even and odd register numbers
1393 * are valid. This limitation exists only for 64 bit wide (d,l,ps) registers.
1395 * Multiple 64 bit wide registers can be checked by calling
1396 * gen_op_cp1_registers(freg1 | freg2 | ... | fregN);
1398 static inline void check_cp1_registers(DisasContext *ctx, int regs)
1400 if (unlikely(!(ctx->hflags & MIPS_HFLAG_F64) && (regs & 1)))
1401 generate_exception(ctx, EXCP_RI);
1404 /* Verify that the processor is running with DSP instructions enabled.
1405 This is enabled by CP0 Status register MX(24) bit.
1408 static inline void check_dsp(DisasContext *ctx)
1410 if (unlikely(!(ctx->hflags & MIPS_HFLAG_DSP))) {
1411 if (ctx->insn_flags & ASE_DSP) {
1412 generate_exception(ctx, EXCP_DSPDIS);
1413 } else {
1414 generate_exception(ctx, EXCP_RI);
1419 static inline void check_dspr2(DisasContext *ctx)
1421 if (unlikely(!(ctx->hflags & MIPS_HFLAG_DSPR2))) {
1422 if (ctx->insn_flags & ASE_DSP) {
1423 generate_exception(ctx, EXCP_DSPDIS);
1424 } else {
1425 generate_exception(ctx, EXCP_RI);
1430 /* This code generates a "reserved instruction" exception if the
1431 CPU does not support the instruction set corresponding to flags. */
1432 static inline void check_insn(DisasContext *ctx, int flags)
1434 if (unlikely(!(ctx->insn_flags & flags))) {
1435 generate_exception(ctx, EXCP_RI);
1439 /* This code generates a "reserved instruction" exception if 64-bit
1440 instructions are not enabled. */
1441 static inline void check_mips_64(DisasContext *ctx)
1443 if (unlikely(!(ctx->hflags & MIPS_HFLAG_64)))
1444 generate_exception(ctx, EXCP_RI);
1447 /* Define small wrappers for gen_load_fpr* so that we have a uniform
1448 calling interface for 32 and 64-bit FPRs. No sense in changing
1449 all callers for gen_load_fpr32 when we need the CTX parameter for
1450 this one use. */
1451 #define gen_ldcmp_fpr32(ctx, x, y) gen_load_fpr32(x, y)
1452 #define gen_ldcmp_fpr64(ctx, x, y) gen_load_fpr64(ctx, x, y)
1453 #define FOP_CONDS(type, abs, fmt, ifmt, bits) \
1454 static inline void gen_cmp ## type ## _ ## fmt(DisasContext *ctx, int n, \
1455 int ft, int fs, int cc) \
1457 TCGv_i##bits fp0 = tcg_temp_new_i##bits (); \
1458 TCGv_i##bits fp1 = tcg_temp_new_i##bits (); \
1459 switch (ifmt) { \
1460 case FMT_PS: \
1461 check_cp1_64bitmode(ctx); \
1462 break; \
1463 case FMT_D: \
1464 if (abs) { \
1465 check_cop1x(ctx); \
1467 check_cp1_registers(ctx, fs | ft); \
1468 break; \
1469 case FMT_S: \
1470 if (abs) { \
1471 check_cop1x(ctx); \
1473 break; \
1475 gen_ldcmp_fpr##bits (ctx, fp0, fs); \
1476 gen_ldcmp_fpr##bits (ctx, fp1, ft); \
1477 switch (n) { \
1478 case 0: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _f, fp0, fp1, cc); break;\
1479 case 1: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _un, fp0, fp1, cc); break;\
1480 case 2: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _eq, fp0, fp1, cc); break;\
1481 case 3: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ueq, fp0, fp1, cc); break;\
1482 case 4: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _olt, fp0, fp1, cc); break;\
1483 case 5: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ult, fp0, fp1, cc); break;\
1484 case 6: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ole, fp0, fp1, cc); break;\
1485 case 7: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ule, fp0, fp1, cc); break;\
1486 case 8: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _sf, fp0, fp1, cc); break;\
1487 case 9: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ngle, fp0, fp1, cc); break;\
1488 case 10: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _seq, fp0, fp1, cc); break;\
1489 case 11: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ngl, fp0, fp1, cc); break;\
1490 case 12: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _lt, fp0, fp1, cc); break;\
1491 case 13: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _nge, fp0, fp1, cc); break;\
1492 case 14: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _le, fp0, fp1, cc); break;\
1493 case 15: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ngt, fp0, fp1, cc); break;\
1494 default: abort(); \
1496 tcg_temp_free_i##bits (fp0); \
1497 tcg_temp_free_i##bits (fp1); \
1500 FOP_CONDS(, 0, d, FMT_D, 64)
1501 FOP_CONDS(abs, 1, d, FMT_D, 64)
1502 FOP_CONDS(, 0, s, FMT_S, 32)
1503 FOP_CONDS(abs, 1, s, FMT_S, 32)
1504 FOP_CONDS(, 0, ps, FMT_PS, 64)
1505 FOP_CONDS(abs, 1, ps, FMT_PS, 64)
1506 #undef FOP_CONDS
1507 #undef gen_ldcmp_fpr32
1508 #undef gen_ldcmp_fpr64
1510 /* load/store instructions. */
1511 #ifdef CONFIG_USER_ONLY
1512 #define OP_LD_ATOMIC(insn,fname) \
1513 static inline void op_ld_##insn(TCGv ret, TCGv arg1, DisasContext *ctx) \
1515 TCGv t0 = tcg_temp_new(); \
1516 tcg_gen_mov_tl(t0, arg1); \
1517 tcg_gen_qemu_##fname(ret, arg1, ctx->mem_idx); \
1518 tcg_gen_st_tl(t0, cpu_env, offsetof(CPUMIPSState, lladdr)); \
1519 tcg_gen_st_tl(ret, cpu_env, offsetof(CPUMIPSState, llval)); \
1520 tcg_temp_free(t0); \
1522 #else
1523 #define OP_LD_ATOMIC(insn,fname) \
1524 static inline void op_ld_##insn(TCGv ret, TCGv arg1, DisasContext *ctx) \
1526 gen_helper_1e1i(insn, ret, arg1, ctx->mem_idx); \
1528 #endif
1529 OP_LD_ATOMIC(ll,ld32s);
1530 #if defined(TARGET_MIPS64)
1531 OP_LD_ATOMIC(lld,ld64);
1532 #endif
1533 #undef OP_LD_ATOMIC
1535 #ifdef CONFIG_USER_ONLY
1536 #define OP_ST_ATOMIC(insn,fname,ldname,almask) \
1537 static inline void op_st_##insn(TCGv arg1, TCGv arg2, int rt, DisasContext *ctx) \
1539 TCGv t0 = tcg_temp_new(); \
1540 int l1 = gen_new_label(); \
1541 int l2 = gen_new_label(); \
1543 tcg_gen_andi_tl(t0, arg2, almask); \
1544 tcg_gen_brcondi_tl(TCG_COND_EQ, t0, 0, l1); \
1545 tcg_gen_st_tl(arg2, cpu_env, offsetof(CPUMIPSState, CP0_BadVAddr)); \
1546 generate_exception(ctx, EXCP_AdES); \
1547 gen_set_label(l1); \
1548 tcg_gen_ld_tl(t0, cpu_env, offsetof(CPUMIPSState, lladdr)); \
1549 tcg_gen_brcond_tl(TCG_COND_NE, arg2, t0, l2); \
1550 tcg_gen_movi_tl(t0, rt | ((almask << 3) & 0x20)); \
1551 tcg_gen_st_tl(t0, cpu_env, offsetof(CPUMIPSState, llreg)); \
1552 tcg_gen_st_tl(arg1, cpu_env, offsetof(CPUMIPSState, llnewval)); \
1553 gen_helper_0e0i(raise_exception, EXCP_SC); \
1554 gen_set_label(l2); \
1555 tcg_gen_movi_tl(t0, 0); \
1556 gen_store_gpr(t0, rt); \
1557 tcg_temp_free(t0); \
1559 #else
1560 #define OP_ST_ATOMIC(insn,fname,ldname,almask) \
1561 static inline void op_st_##insn(TCGv arg1, TCGv arg2, int rt, DisasContext *ctx) \
1563 TCGv t0 = tcg_temp_new(); \
1564 gen_helper_1e2i(insn, t0, arg1, arg2, ctx->mem_idx); \
1565 gen_store_gpr(t0, rt); \
1566 tcg_temp_free(t0); \
1568 #endif
1569 OP_ST_ATOMIC(sc,st32,ld32s,0x3);
1570 #if defined(TARGET_MIPS64)
1571 OP_ST_ATOMIC(scd,st64,ld64,0x7);
1572 #endif
1573 #undef OP_ST_ATOMIC
1575 static void gen_base_offset_addr (DisasContext *ctx, TCGv addr,
1576 int base, int16_t offset)
1578 if (base == 0) {
1579 tcg_gen_movi_tl(addr, offset);
1580 } else if (offset == 0) {
1581 gen_load_gpr(addr, base);
1582 } else {
1583 tcg_gen_movi_tl(addr, offset);
1584 gen_op_addr_add(ctx, addr, cpu_gpr[base], addr);
1588 static target_ulong pc_relative_pc (DisasContext *ctx)
1590 target_ulong pc = ctx->pc;
1592 if (ctx->hflags & MIPS_HFLAG_BMASK) {
1593 int branch_bytes = ctx->hflags & MIPS_HFLAG_BDS16 ? 2 : 4;
1595 pc -= branch_bytes;
1598 pc &= ~(target_ulong)3;
1599 return pc;
1602 /* Load */
1603 static void gen_ld(DisasContext *ctx, uint32_t opc,
1604 int rt, int base, int16_t offset)
1606 const char *opn = "ld";
1607 TCGv t0, t1, t2;
1609 if (rt == 0 && ctx->insn_flags & (INSN_LOONGSON2E | INSN_LOONGSON2F)) {
1610 /* Loongson CPU uses a load to zero register for prefetch.
1611 We emulate it as a NOP. On other CPU we must perform the
1612 actual memory access. */
1613 MIPS_DEBUG("NOP");
1614 return;
1617 t0 = tcg_temp_new();
1618 gen_base_offset_addr(ctx, t0, base, offset);
1620 switch (opc) {
1621 #if defined(TARGET_MIPS64)
1622 case OPC_LWU:
1623 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TEUL);
1624 gen_store_gpr(t0, rt);
1625 opn = "lwu";
1626 break;
1627 case OPC_LD:
1628 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TEQ);
1629 gen_store_gpr(t0, rt);
1630 opn = "ld";
1631 break;
1632 case OPC_LLD:
1633 save_cpu_state(ctx, 1);
1634 op_ld_lld(t0, t0, ctx);
1635 gen_store_gpr(t0, rt);
1636 opn = "lld";
1637 break;
1638 case OPC_LDL:
1639 t1 = tcg_temp_new();
1640 tcg_gen_andi_tl(t1, t0, 7);
1641 #ifndef TARGET_WORDS_BIGENDIAN
1642 tcg_gen_xori_tl(t1, t1, 7);
1643 #endif
1644 tcg_gen_shli_tl(t1, t1, 3);
1645 tcg_gen_andi_tl(t0, t0, ~7);
1646 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TEQ);
1647 tcg_gen_shl_tl(t0, t0, t1);
1648 tcg_gen_xori_tl(t1, t1, 63);
1649 t2 = tcg_const_tl(0x7fffffffffffffffull);
1650 tcg_gen_shr_tl(t2, t2, t1);
1651 gen_load_gpr(t1, rt);
1652 tcg_gen_and_tl(t1, t1, t2);
1653 tcg_temp_free(t2);
1654 tcg_gen_or_tl(t0, t0, t1);
1655 tcg_temp_free(t1);
1656 gen_store_gpr(t0, rt);
1657 opn = "ldl";
1658 break;
1659 case OPC_LDR:
1660 t1 = tcg_temp_new();
1661 tcg_gen_andi_tl(t1, t0, 7);
1662 #ifdef TARGET_WORDS_BIGENDIAN
1663 tcg_gen_xori_tl(t1, t1, 7);
1664 #endif
1665 tcg_gen_shli_tl(t1, t1, 3);
1666 tcg_gen_andi_tl(t0, t0, ~7);
1667 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TEQ);
1668 tcg_gen_shr_tl(t0, t0, t1);
1669 tcg_gen_xori_tl(t1, t1, 63);
1670 t2 = tcg_const_tl(0xfffffffffffffffeull);
1671 tcg_gen_shl_tl(t2, t2, t1);
1672 gen_load_gpr(t1, rt);
1673 tcg_gen_and_tl(t1, t1, t2);
1674 tcg_temp_free(t2);
1675 tcg_gen_or_tl(t0, t0, t1);
1676 tcg_temp_free(t1);
1677 gen_store_gpr(t0, rt);
1678 opn = "ldr";
1679 break;
1680 case OPC_LDPC:
1681 t1 = tcg_const_tl(pc_relative_pc(ctx));
1682 gen_op_addr_add(ctx, t0, t0, t1);
1683 tcg_temp_free(t1);
1684 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TEQ);
1685 gen_store_gpr(t0, rt);
1686 opn = "ldpc";
1687 break;
1688 #endif
1689 case OPC_LWPC:
1690 t1 = tcg_const_tl(pc_relative_pc(ctx));
1691 gen_op_addr_add(ctx, t0, t0, t1);
1692 tcg_temp_free(t1);
1693 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TESL);
1694 gen_store_gpr(t0, rt);
1695 opn = "lwpc";
1696 break;
1697 case OPC_LW:
1698 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TESL);
1699 gen_store_gpr(t0, rt);
1700 opn = "lw";
1701 break;
1702 case OPC_LH:
1703 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TESW);
1704 gen_store_gpr(t0, rt);
1705 opn = "lh";
1706 break;
1707 case OPC_LHU:
1708 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TEUW);
1709 gen_store_gpr(t0, rt);
1710 opn = "lhu";
1711 break;
1712 case OPC_LB:
1713 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_SB);
1714 gen_store_gpr(t0, rt);
1715 opn = "lb";
1716 break;
1717 case OPC_LBU:
1718 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_UB);
1719 gen_store_gpr(t0, rt);
1720 opn = "lbu";
1721 break;
1722 case OPC_LWL:
1723 t1 = tcg_temp_new();
1724 tcg_gen_andi_tl(t1, t0, 3);
1725 #ifndef TARGET_WORDS_BIGENDIAN
1726 tcg_gen_xori_tl(t1, t1, 3);
1727 #endif
1728 tcg_gen_shli_tl(t1, t1, 3);
1729 tcg_gen_andi_tl(t0, t0, ~3);
1730 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TEUL);
1731 tcg_gen_shl_tl(t0, t0, t1);
1732 tcg_gen_xori_tl(t1, t1, 31);
1733 t2 = tcg_const_tl(0x7fffffffull);
1734 tcg_gen_shr_tl(t2, t2, t1);
1735 gen_load_gpr(t1, rt);
1736 tcg_gen_and_tl(t1, t1, t2);
1737 tcg_temp_free(t2);
1738 tcg_gen_or_tl(t0, t0, t1);
1739 tcg_temp_free(t1);
1740 tcg_gen_ext32s_tl(t0, t0);
1741 gen_store_gpr(t0, rt);
1742 opn = "lwl";
1743 break;
1744 case OPC_LWR:
1745 t1 = tcg_temp_new();
1746 tcg_gen_andi_tl(t1, t0, 3);
1747 #ifdef TARGET_WORDS_BIGENDIAN
1748 tcg_gen_xori_tl(t1, t1, 3);
1749 #endif
1750 tcg_gen_shli_tl(t1, t1, 3);
1751 tcg_gen_andi_tl(t0, t0, ~3);
1752 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TEUL);
1753 tcg_gen_shr_tl(t0, t0, t1);
1754 tcg_gen_xori_tl(t1, t1, 31);
1755 t2 = tcg_const_tl(0xfffffffeull);
1756 tcg_gen_shl_tl(t2, t2, t1);
1757 gen_load_gpr(t1, rt);
1758 tcg_gen_and_tl(t1, t1, t2);
1759 tcg_temp_free(t2);
1760 tcg_gen_or_tl(t0, t0, t1);
1761 tcg_temp_free(t1);
1762 tcg_gen_ext32s_tl(t0, t0);
1763 gen_store_gpr(t0, rt);
1764 opn = "lwr";
1765 break;
1766 case OPC_LL:
1767 save_cpu_state(ctx, 1);
1768 op_ld_ll(t0, t0, ctx);
1769 gen_store_gpr(t0, rt);
1770 opn = "ll";
1771 break;
1773 (void)opn; /* avoid a compiler warning */
1774 MIPS_DEBUG("%s %s, %d(%s)", opn, regnames[rt], offset, regnames[base]);
1775 tcg_temp_free(t0);
1778 /* Store */
1779 static void gen_st (DisasContext *ctx, uint32_t opc, int rt,
1780 int base, int16_t offset)
1782 const char *opn = "st";
1783 TCGv t0 = tcg_temp_new();
1784 TCGv t1 = tcg_temp_new();
1786 gen_base_offset_addr(ctx, t0, base, offset);
1787 gen_load_gpr(t1, rt);
1788 switch (opc) {
1789 #if defined(TARGET_MIPS64)
1790 case OPC_SD:
1791 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEQ);
1792 opn = "sd";
1793 break;
1794 case OPC_SDL:
1795 save_cpu_state(ctx, 1);
1796 gen_helper_0e2i(sdl, t1, t0, ctx->mem_idx);
1797 opn = "sdl";
1798 break;
1799 case OPC_SDR:
1800 save_cpu_state(ctx, 1);
1801 gen_helper_0e2i(sdr, t1, t0, ctx->mem_idx);
1802 opn = "sdr";
1803 break;
1804 #endif
1805 case OPC_SW:
1806 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL);
1807 opn = "sw";
1808 break;
1809 case OPC_SH:
1810 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUW);
1811 opn = "sh";
1812 break;
1813 case OPC_SB:
1814 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_8);
1815 opn = "sb";
1816 break;
1817 case OPC_SWL:
1818 save_cpu_state(ctx, 1);
1819 gen_helper_0e2i(swl, t1, t0, ctx->mem_idx);
1820 opn = "swl";
1821 break;
1822 case OPC_SWR:
1823 save_cpu_state(ctx, 1);
1824 gen_helper_0e2i(swr, t1, t0, ctx->mem_idx);
1825 opn = "swr";
1826 break;
1828 (void)opn; /* avoid a compiler warning */
1829 MIPS_DEBUG("%s %s, %d(%s)", opn, regnames[rt], offset, regnames[base]);
1830 tcg_temp_free(t0);
1831 tcg_temp_free(t1);
1835 /* Store conditional */
1836 static void gen_st_cond (DisasContext *ctx, uint32_t opc, int rt,
1837 int base, int16_t offset)
1839 const char *opn = "st_cond";
1840 TCGv t0, t1;
1842 #ifdef CONFIG_USER_ONLY
1843 t0 = tcg_temp_local_new();
1844 t1 = tcg_temp_local_new();
1845 #else
1846 t0 = tcg_temp_new();
1847 t1 = tcg_temp_new();
1848 #endif
1849 gen_base_offset_addr(ctx, t0, base, offset);
1850 gen_load_gpr(t1, rt);
1851 switch (opc) {
1852 #if defined(TARGET_MIPS64)
1853 case OPC_SCD:
1854 save_cpu_state(ctx, 1);
1855 op_st_scd(t1, t0, rt, ctx);
1856 opn = "scd";
1857 break;
1858 #endif
1859 case OPC_SC:
1860 save_cpu_state(ctx, 1);
1861 op_st_sc(t1, t0, rt, ctx);
1862 opn = "sc";
1863 break;
1865 (void)opn; /* avoid a compiler warning */
1866 MIPS_DEBUG("%s %s, %d(%s)", opn, regnames[rt], offset, regnames[base]);
1867 tcg_temp_free(t1);
1868 tcg_temp_free(t0);
1871 /* Load and store */
1872 static void gen_flt_ldst (DisasContext *ctx, uint32_t opc, int ft,
1873 int base, int16_t offset)
1875 const char *opn = "flt_ldst";
1876 TCGv t0 = tcg_temp_new();
1878 gen_base_offset_addr(ctx, t0, base, offset);
1879 /* Don't do NOP if destination is zero: we must perform the actual
1880 memory access. */
1881 switch (opc) {
1882 case OPC_LWC1:
1884 TCGv_i32 fp0 = tcg_temp_new_i32();
1885 tcg_gen_qemu_ld_i32(fp0, t0, ctx->mem_idx, MO_TESL);
1886 gen_store_fpr32(fp0, ft);
1887 tcg_temp_free_i32(fp0);
1889 opn = "lwc1";
1890 break;
1891 case OPC_SWC1:
1893 TCGv_i32 fp0 = tcg_temp_new_i32();
1894 gen_load_fpr32(fp0, ft);
1895 tcg_gen_qemu_st_i32(fp0, t0, ctx->mem_idx, MO_TEUL);
1896 tcg_temp_free_i32(fp0);
1898 opn = "swc1";
1899 break;
1900 case OPC_LDC1:
1902 TCGv_i64 fp0 = tcg_temp_new_i64();
1903 tcg_gen_qemu_ld_i64(fp0, t0, ctx->mem_idx, MO_TEQ);
1904 gen_store_fpr64(ctx, fp0, ft);
1905 tcg_temp_free_i64(fp0);
1907 opn = "ldc1";
1908 break;
1909 case OPC_SDC1:
1911 TCGv_i64 fp0 = tcg_temp_new_i64();
1912 gen_load_fpr64(ctx, fp0, ft);
1913 tcg_gen_qemu_st_i64(fp0, t0, ctx->mem_idx, MO_TEQ);
1914 tcg_temp_free_i64(fp0);
1916 opn = "sdc1";
1917 break;
1918 default:
1919 MIPS_INVAL(opn);
1920 generate_exception(ctx, EXCP_RI);
1921 goto out;
1923 (void)opn; /* avoid a compiler warning */
1924 MIPS_DEBUG("%s %s, %d(%s)", opn, fregnames[ft], offset, regnames[base]);
1925 out:
1926 tcg_temp_free(t0);
1929 static void gen_cop1_ldst(DisasContext *ctx, uint32_t op, int rt,
1930 int rs, int16_t imm)
1932 if (ctx->CP0_Config1 & (1 << CP0C1_FP)) {
1933 check_cp1_enabled(ctx);
1934 gen_flt_ldst(ctx, op, rt, rs, imm);
1935 } else {
1936 generate_exception_err(ctx, EXCP_CpU, 1);
1940 /* Arithmetic with immediate operand */
1941 static void gen_arith_imm(DisasContext *ctx, uint32_t opc,
1942 int rt, int rs, int16_t imm)
1944 target_ulong uimm = (target_long)imm; /* Sign extend to 32/64 bits */
1945 const char *opn = "imm arith";
1947 if (rt == 0 && opc != OPC_ADDI && opc != OPC_DADDI) {
1948 /* If no destination, treat it as a NOP.
1949 For addi, we must generate the overflow exception when needed. */
1950 MIPS_DEBUG("NOP");
1951 return;
1953 switch (opc) {
1954 case OPC_ADDI:
1956 TCGv t0 = tcg_temp_local_new();
1957 TCGv t1 = tcg_temp_new();
1958 TCGv t2 = tcg_temp_new();
1959 int l1 = gen_new_label();
1961 gen_load_gpr(t1, rs);
1962 tcg_gen_addi_tl(t0, t1, uimm);
1963 tcg_gen_ext32s_tl(t0, t0);
1965 tcg_gen_xori_tl(t1, t1, ~uimm);
1966 tcg_gen_xori_tl(t2, t0, uimm);
1967 tcg_gen_and_tl(t1, t1, t2);
1968 tcg_temp_free(t2);
1969 tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
1970 tcg_temp_free(t1);
1971 /* operands of same sign, result different sign */
1972 generate_exception(ctx, EXCP_OVERFLOW);
1973 gen_set_label(l1);
1974 tcg_gen_ext32s_tl(t0, t0);
1975 gen_store_gpr(t0, rt);
1976 tcg_temp_free(t0);
1978 opn = "addi";
1979 break;
1980 case OPC_ADDIU:
1981 if (rs != 0) {
1982 tcg_gen_addi_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
1983 tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]);
1984 } else {
1985 tcg_gen_movi_tl(cpu_gpr[rt], uimm);
1987 opn = "addiu";
1988 break;
1989 #if defined(TARGET_MIPS64)
1990 case OPC_DADDI:
1992 TCGv t0 = tcg_temp_local_new();
1993 TCGv t1 = tcg_temp_new();
1994 TCGv t2 = tcg_temp_new();
1995 int l1 = gen_new_label();
1997 gen_load_gpr(t1, rs);
1998 tcg_gen_addi_tl(t0, t1, uimm);
2000 tcg_gen_xori_tl(t1, t1, ~uimm);
2001 tcg_gen_xori_tl(t2, t0, uimm);
2002 tcg_gen_and_tl(t1, t1, t2);
2003 tcg_temp_free(t2);
2004 tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
2005 tcg_temp_free(t1);
2006 /* operands of same sign, result different sign */
2007 generate_exception(ctx, EXCP_OVERFLOW);
2008 gen_set_label(l1);
2009 gen_store_gpr(t0, rt);
2010 tcg_temp_free(t0);
2012 opn = "daddi";
2013 break;
2014 case OPC_DADDIU:
2015 if (rs != 0) {
2016 tcg_gen_addi_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
2017 } else {
2018 tcg_gen_movi_tl(cpu_gpr[rt], uimm);
2020 opn = "daddiu";
2021 break;
2022 #endif
2024 (void)opn; /* avoid a compiler warning */
2025 MIPS_DEBUG("%s %s, %s, " TARGET_FMT_lx, opn, regnames[rt], regnames[rs], uimm);
2028 /* Logic with immediate operand */
2029 static void gen_logic_imm(DisasContext *ctx, uint32_t opc,
2030 int rt, int rs, int16_t imm)
2032 target_ulong uimm;
2034 if (rt == 0) {
2035 /* If no destination, treat it as a NOP. */
2036 MIPS_DEBUG("NOP");
2037 return;
2039 uimm = (uint16_t)imm;
2040 switch (opc) {
2041 case OPC_ANDI:
2042 if (likely(rs != 0))
2043 tcg_gen_andi_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
2044 else
2045 tcg_gen_movi_tl(cpu_gpr[rt], 0);
2046 MIPS_DEBUG("andi %s, %s, " TARGET_FMT_lx, regnames[rt],
2047 regnames[rs], uimm);
2048 break;
2049 case OPC_ORI:
2050 if (rs != 0)
2051 tcg_gen_ori_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
2052 else
2053 tcg_gen_movi_tl(cpu_gpr[rt], uimm);
2054 MIPS_DEBUG("ori %s, %s, " TARGET_FMT_lx, regnames[rt],
2055 regnames[rs], uimm);
2056 break;
2057 case OPC_XORI:
2058 if (likely(rs != 0))
2059 tcg_gen_xori_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
2060 else
2061 tcg_gen_movi_tl(cpu_gpr[rt], uimm);
2062 MIPS_DEBUG("xori %s, %s, " TARGET_FMT_lx, regnames[rt],
2063 regnames[rs], uimm);
2064 break;
2065 case OPC_LUI:
2066 tcg_gen_movi_tl(cpu_gpr[rt], imm << 16);
2067 MIPS_DEBUG("lui %s, " TARGET_FMT_lx, regnames[rt], uimm);
2068 break;
2070 default:
2071 MIPS_DEBUG("Unknown logical immediate opcode %08x", opc);
2072 break;
2076 /* Set on less than with immediate operand */
2077 static void gen_slt_imm(DisasContext *ctx, uint32_t opc,
2078 int rt, int rs, int16_t imm)
2080 target_ulong uimm = (target_long)imm; /* Sign extend to 32/64 bits */
2081 const char *opn = "imm arith";
2082 TCGv t0;
2084 if (rt == 0) {
2085 /* If no destination, treat it as a NOP. */
2086 MIPS_DEBUG("NOP");
2087 return;
2089 t0 = tcg_temp_new();
2090 gen_load_gpr(t0, rs);
2091 switch (opc) {
2092 case OPC_SLTI:
2093 tcg_gen_setcondi_tl(TCG_COND_LT, cpu_gpr[rt], t0, uimm);
2094 opn = "slti";
2095 break;
2096 case OPC_SLTIU:
2097 tcg_gen_setcondi_tl(TCG_COND_LTU, cpu_gpr[rt], t0, uimm);
2098 opn = "sltiu";
2099 break;
2101 (void)opn; /* avoid a compiler warning */
2102 MIPS_DEBUG("%s %s, %s, " TARGET_FMT_lx, opn, regnames[rt], regnames[rs], uimm);
2103 tcg_temp_free(t0);
2106 /* Shifts with immediate operand */
2107 static void gen_shift_imm(DisasContext *ctx, uint32_t opc,
2108 int rt, int rs, int16_t imm)
2110 target_ulong uimm = ((uint16_t)imm) & 0x1f;
2111 const char *opn = "imm shift";
2112 TCGv t0;
2114 if (rt == 0) {
2115 /* If no destination, treat it as a NOP. */
2116 MIPS_DEBUG("NOP");
2117 return;
2120 t0 = tcg_temp_new();
2121 gen_load_gpr(t0, rs);
2122 switch (opc) {
2123 case OPC_SLL:
2124 tcg_gen_shli_tl(t0, t0, uimm);
2125 tcg_gen_ext32s_tl(cpu_gpr[rt], t0);
2126 opn = "sll";
2127 break;
2128 case OPC_SRA:
2129 tcg_gen_sari_tl(cpu_gpr[rt], t0, uimm);
2130 opn = "sra";
2131 break;
2132 case OPC_SRL:
2133 if (uimm != 0) {
2134 tcg_gen_ext32u_tl(t0, t0);
2135 tcg_gen_shri_tl(cpu_gpr[rt], t0, uimm);
2136 } else {
2137 tcg_gen_ext32s_tl(cpu_gpr[rt], t0);
2139 opn = "srl";
2140 break;
2141 case OPC_ROTR:
2142 if (uimm != 0) {
2143 TCGv_i32 t1 = tcg_temp_new_i32();
2145 tcg_gen_trunc_tl_i32(t1, t0);
2146 tcg_gen_rotri_i32(t1, t1, uimm);
2147 tcg_gen_ext_i32_tl(cpu_gpr[rt], t1);
2148 tcg_temp_free_i32(t1);
2149 } else {
2150 tcg_gen_ext32s_tl(cpu_gpr[rt], t0);
2152 opn = "rotr";
2153 break;
2154 #if defined(TARGET_MIPS64)
2155 case OPC_DSLL:
2156 tcg_gen_shli_tl(cpu_gpr[rt], t0, uimm);
2157 opn = "dsll";
2158 break;
2159 case OPC_DSRA:
2160 tcg_gen_sari_tl(cpu_gpr[rt], t0, uimm);
2161 opn = "dsra";
2162 break;
2163 case OPC_DSRL:
2164 tcg_gen_shri_tl(cpu_gpr[rt], t0, uimm);
2165 opn = "dsrl";
2166 break;
2167 case OPC_DROTR:
2168 if (uimm != 0) {
2169 tcg_gen_rotri_tl(cpu_gpr[rt], t0, uimm);
2170 } else {
2171 tcg_gen_mov_tl(cpu_gpr[rt], t0);
2173 opn = "drotr";
2174 break;
2175 case OPC_DSLL32:
2176 tcg_gen_shli_tl(cpu_gpr[rt], t0, uimm + 32);
2177 opn = "dsll32";
2178 break;
2179 case OPC_DSRA32:
2180 tcg_gen_sari_tl(cpu_gpr[rt], t0, uimm + 32);
2181 opn = "dsra32";
2182 break;
2183 case OPC_DSRL32:
2184 tcg_gen_shri_tl(cpu_gpr[rt], t0, uimm + 32);
2185 opn = "dsrl32";
2186 break;
2187 case OPC_DROTR32:
2188 tcg_gen_rotri_tl(cpu_gpr[rt], t0, uimm + 32);
2189 opn = "drotr32";
2190 break;
2191 #endif
2193 (void)opn; /* avoid a compiler warning */
2194 MIPS_DEBUG("%s %s, %s, " TARGET_FMT_lx, opn, regnames[rt], regnames[rs], uimm);
2195 tcg_temp_free(t0);
2198 /* Arithmetic */
2199 static void gen_arith(DisasContext *ctx, uint32_t opc,
2200 int rd, int rs, int rt)
2202 const char *opn = "arith";
2204 if (rd == 0 && opc != OPC_ADD && opc != OPC_SUB
2205 && opc != OPC_DADD && opc != OPC_DSUB) {
2206 /* If no destination, treat it as a NOP.
2207 For add & sub, we must generate the overflow exception when needed. */
2208 MIPS_DEBUG("NOP");
2209 return;
2212 switch (opc) {
2213 case OPC_ADD:
2215 TCGv t0 = tcg_temp_local_new();
2216 TCGv t1 = tcg_temp_new();
2217 TCGv t2 = tcg_temp_new();
2218 int l1 = gen_new_label();
2220 gen_load_gpr(t1, rs);
2221 gen_load_gpr(t2, rt);
2222 tcg_gen_add_tl(t0, t1, t2);
2223 tcg_gen_ext32s_tl(t0, t0);
2224 tcg_gen_xor_tl(t1, t1, t2);
2225 tcg_gen_xor_tl(t2, t0, t2);
2226 tcg_gen_andc_tl(t1, t2, t1);
2227 tcg_temp_free(t2);
2228 tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
2229 tcg_temp_free(t1);
2230 /* operands of same sign, result different sign */
2231 generate_exception(ctx, EXCP_OVERFLOW);
2232 gen_set_label(l1);
2233 gen_store_gpr(t0, rd);
2234 tcg_temp_free(t0);
2236 opn = "add";
2237 break;
2238 case OPC_ADDU:
2239 if (rs != 0 && rt != 0) {
2240 tcg_gen_add_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2241 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
2242 } else if (rs == 0 && rt != 0) {
2243 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rt]);
2244 } else if (rs != 0 && rt == 0) {
2245 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
2246 } else {
2247 tcg_gen_movi_tl(cpu_gpr[rd], 0);
2249 opn = "addu";
2250 break;
2251 case OPC_SUB:
2253 TCGv t0 = tcg_temp_local_new();
2254 TCGv t1 = tcg_temp_new();
2255 TCGv t2 = tcg_temp_new();
2256 int l1 = gen_new_label();
2258 gen_load_gpr(t1, rs);
2259 gen_load_gpr(t2, rt);
2260 tcg_gen_sub_tl(t0, t1, t2);
2261 tcg_gen_ext32s_tl(t0, t0);
2262 tcg_gen_xor_tl(t2, t1, t2);
2263 tcg_gen_xor_tl(t1, t0, t1);
2264 tcg_gen_and_tl(t1, t1, t2);
2265 tcg_temp_free(t2);
2266 tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
2267 tcg_temp_free(t1);
2268 /* operands of different sign, first operand and result different sign */
2269 generate_exception(ctx, EXCP_OVERFLOW);
2270 gen_set_label(l1);
2271 gen_store_gpr(t0, rd);
2272 tcg_temp_free(t0);
2274 opn = "sub";
2275 break;
2276 case OPC_SUBU:
2277 if (rs != 0 && rt != 0) {
2278 tcg_gen_sub_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2279 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
2280 } else if (rs == 0 && rt != 0) {
2281 tcg_gen_neg_tl(cpu_gpr[rd], cpu_gpr[rt]);
2282 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
2283 } else if (rs != 0 && rt == 0) {
2284 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
2285 } else {
2286 tcg_gen_movi_tl(cpu_gpr[rd], 0);
2288 opn = "subu";
2289 break;
2290 #if defined(TARGET_MIPS64)
2291 case OPC_DADD:
2293 TCGv t0 = tcg_temp_local_new();
2294 TCGv t1 = tcg_temp_new();
2295 TCGv t2 = tcg_temp_new();
2296 int l1 = gen_new_label();
2298 gen_load_gpr(t1, rs);
2299 gen_load_gpr(t2, rt);
2300 tcg_gen_add_tl(t0, t1, t2);
2301 tcg_gen_xor_tl(t1, t1, t2);
2302 tcg_gen_xor_tl(t2, t0, t2);
2303 tcg_gen_andc_tl(t1, t2, t1);
2304 tcg_temp_free(t2);
2305 tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
2306 tcg_temp_free(t1);
2307 /* operands of same sign, result different sign */
2308 generate_exception(ctx, EXCP_OVERFLOW);
2309 gen_set_label(l1);
2310 gen_store_gpr(t0, rd);
2311 tcg_temp_free(t0);
2313 opn = "dadd";
2314 break;
2315 case OPC_DADDU:
2316 if (rs != 0 && rt != 0) {
2317 tcg_gen_add_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2318 } else if (rs == 0 && rt != 0) {
2319 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rt]);
2320 } else if (rs != 0 && rt == 0) {
2321 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
2322 } else {
2323 tcg_gen_movi_tl(cpu_gpr[rd], 0);
2325 opn = "daddu";
2326 break;
2327 case OPC_DSUB:
2329 TCGv t0 = tcg_temp_local_new();
2330 TCGv t1 = tcg_temp_new();
2331 TCGv t2 = tcg_temp_new();
2332 int l1 = gen_new_label();
2334 gen_load_gpr(t1, rs);
2335 gen_load_gpr(t2, rt);
2336 tcg_gen_sub_tl(t0, t1, t2);
2337 tcg_gen_xor_tl(t2, t1, t2);
2338 tcg_gen_xor_tl(t1, t0, t1);
2339 tcg_gen_and_tl(t1, t1, t2);
2340 tcg_temp_free(t2);
2341 tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
2342 tcg_temp_free(t1);
2343 /* operands of different sign, first operand and result different sign */
2344 generate_exception(ctx, EXCP_OVERFLOW);
2345 gen_set_label(l1);
2346 gen_store_gpr(t0, rd);
2347 tcg_temp_free(t0);
2349 opn = "dsub";
2350 break;
2351 case OPC_DSUBU:
2352 if (rs != 0 && rt != 0) {
2353 tcg_gen_sub_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2354 } else if (rs == 0 && rt != 0) {
2355 tcg_gen_neg_tl(cpu_gpr[rd], cpu_gpr[rt]);
2356 } else if (rs != 0 && rt == 0) {
2357 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
2358 } else {
2359 tcg_gen_movi_tl(cpu_gpr[rd], 0);
2361 opn = "dsubu";
2362 break;
2363 #endif
2364 case OPC_MUL:
2365 if (likely(rs != 0 && rt != 0)) {
2366 tcg_gen_mul_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2367 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
2368 } else {
2369 tcg_gen_movi_tl(cpu_gpr[rd], 0);
2371 opn = "mul";
2372 break;
2374 (void)opn; /* avoid a compiler warning */
2375 MIPS_DEBUG("%s %s, %s, %s", opn, regnames[rd], regnames[rs], regnames[rt]);
2378 /* Conditional move */
2379 static void gen_cond_move(DisasContext *ctx, uint32_t opc,
2380 int rd, int rs, int rt)
2382 const char *opn = "cond move";
2383 TCGv t0, t1, t2;
2385 if (rd == 0) {
2386 /* If no destination, treat it as a NOP. */
2387 MIPS_DEBUG("NOP");
2388 return;
2391 t0 = tcg_temp_new();
2392 gen_load_gpr(t0, rt);
2393 t1 = tcg_const_tl(0);
2394 t2 = tcg_temp_new();
2395 gen_load_gpr(t2, rs);
2396 switch (opc) {
2397 case OPC_MOVN:
2398 tcg_gen_movcond_tl(TCG_COND_NE, cpu_gpr[rd], t0, t1, t2, cpu_gpr[rd]);
2399 opn = "movn";
2400 break;
2401 case OPC_MOVZ:
2402 tcg_gen_movcond_tl(TCG_COND_EQ, cpu_gpr[rd], t0, t1, t2, cpu_gpr[rd]);
2403 opn = "movz";
2404 break;
2406 tcg_temp_free(t2);
2407 tcg_temp_free(t1);
2408 tcg_temp_free(t0);
2410 (void)opn; /* avoid a compiler warning */
2411 MIPS_DEBUG("%s %s, %s, %s", opn, regnames[rd], regnames[rs], regnames[rt]);
2414 /* Logic */
2415 static void gen_logic(DisasContext *ctx, uint32_t opc,
2416 int rd, int rs, int rt)
2418 const char *opn = "logic";
2420 if (rd == 0) {
2421 /* If no destination, treat it as a NOP. */
2422 MIPS_DEBUG("NOP");
2423 return;
2426 switch (opc) {
2427 case OPC_AND:
2428 if (likely(rs != 0 && rt != 0)) {
2429 tcg_gen_and_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2430 } else {
2431 tcg_gen_movi_tl(cpu_gpr[rd], 0);
2433 opn = "and";
2434 break;
2435 case OPC_NOR:
2436 if (rs != 0 && rt != 0) {
2437 tcg_gen_nor_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2438 } else if (rs == 0 && rt != 0) {
2439 tcg_gen_not_tl(cpu_gpr[rd], cpu_gpr[rt]);
2440 } else if (rs != 0 && rt == 0) {
2441 tcg_gen_not_tl(cpu_gpr[rd], cpu_gpr[rs]);
2442 } else {
2443 tcg_gen_movi_tl(cpu_gpr[rd], ~((target_ulong)0));
2445 opn = "nor";
2446 break;
2447 case OPC_OR:
2448 if (likely(rs != 0 && rt != 0)) {
2449 tcg_gen_or_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2450 } else if (rs == 0 && rt != 0) {
2451 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rt]);
2452 } else if (rs != 0 && rt == 0) {
2453 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
2454 } else {
2455 tcg_gen_movi_tl(cpu_gpr[rd], 0);
2457 opn = "or";
2458 break;
2459 case OPC_XOR:
2460 if (likely(rs != 0 && rt != 0)) {
2461 tcg_gen_xor_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2462 } else if (rs == 0 && rt != 0) {
2463 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rt]);
2464 } else if (rs != 0 && rt == 0) {
2465 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
2466 } else {
2467 tcg_gen_movi_tl(cpu_gpr[rd], 0);
2469 opn = "xor";
2470 break;
2472 (void)opn; /* avoid a compiler warning */
2473 MIPS_DEBUG("%s %s, %s, %s", opn, regnames[rd], regnames[rs], regnames[rt]);
2476 /* Set on lower than */
2477 static void gen_slt(DisasContext *ctx, uint32_t opc,
2478 int rd, int rs, int rt)
2480 const char *opn = "slt";
2481 TCGv t0, t1;
2483 if (rd == 0) {
2484 /* If no destination, treat it as a NOP. */
2485 MIPS_DEBUG("NOP");
2486 return;
2489 t0 = tcg_temp_new();
2490 t1 = tcg_temp_new();
2491 gen_load_gpr(t0, rs);
2492 gen_load_gpr(t1, rt);
2493 switch (opc) {
2494 case OPC_SLT:
2495 tcg_gen_setcond_tl(TCG_COND_LT, cpu_gpr[rd], t0, t1);
2496 opn = "slt";
2497 break;
2498 case OPC_SLTU:
2499 tcg_gen_setcond_tl(TCG_COND_LTU, cpu_gpr[rd], t0, t1);
2500 opn = "sltu";
2501 break;
2503 (void)opn; /* avoid a compiler warning */
2504 MIPS_DEBUG("%s %s, %s, %s", opn, regnames[rd], regnames[rs], regnames[rt]);
2505 tcg_temp_free(t0);
2506 tcg_temp_free(t1);
2509 /* Shifts */
2510 static void gen_shift(DisasContext *ctx, uint32_t opc,
2511 int rd, int rs, int rt)
2513 const char *opn = "shifts";
2514 TCGv t0, t1;
2516 if (rd == 0) {
2517 /* If no destination, treat it as a NOP.
2518 For add & sub, we must generate the overflow exception when needed. */
2519 MIPS_DEBUG("NOP");
2520 return;
2523 t0 = tcg_temp_new();
2524 t1 = tcg_temp_new();
2525 gen_load_gpr(t0, rs);
2526 gen_load_gpr(t1, rt);
2527 switch (opc) {
2528 case OPC_SLLV:
2529 tcg_gen_andi_tl(t0, t0, 0x1f);
2530 tcg_gen_shl_tl(t0, t1, t0);
2531 tcg_gen_ext32s_tl(cpu_gpr[rd], t0);
2532 opn = "sllv";
2533 break;
2534 case OPC_SRAV:
2535 tcg_gen_andi_tl(t0, t0, 0x1f);
2536 tcg_gen_sar_tl(cpu_gpr[rd], t1, t0);
2537 opn = "srav";
2538 break;
2539 case OPC_SRLV:
2540 tcg_gen_ext32u_tl(t1, t1);
2541 tcg_gen_andi_tl(t0, t0, 0x1f);
2542 tcg_gen_shr_tl(t0, t1, t0);
2543 tcg_gen_ext32s_tl(cpu_gpr[rd], t0);
2544 opn = "srlv";
2545 break;
2546 case OPC_ROTRV:
2548 TCGv_i32 t2 = tcg_temp_new_i32();
2549 TCGv_i32 t3 = tcg_temp_new_i32();
2551 tcg_gen_trunc_tl_i32(t2, t0);
2552 tcg_gen_trunc_tl_i32(t3, t1);
2553 tcg_gen_andi_i32(t2, t2, 0x1f);
2554 tcg_gen_rotr_i32(t2, t3, t2);
2555 tcg_gen_ext_i32_tl(cpu_gpr[rd], t2);
2556 tcg_temp_free_i32(t2);
2557 tcg_temp_free_i32(t3);
2558 opn = "rotrv";
2560 break;
2561 #if defined(TARGET_MIPS64)
2562 case OPC_DSLLV:
2563 tcg_gen_andi_tl(t0, t0, 0x3f);
2564 tcg_gen_shl_tl(cpu_gpr[rd], t1, t0);
2565 opn = "dsllv";
2566 break;
2567 case OPC_DSRAV:
2568 tcg_gen_andi_tl(t0, t0, 0x3f);
2569 tcg_gen_sar_tl(cpu_gpr[rd], t1, t0);
2570 opn = "dsrav";
2571 break;
2572 case OPC_DSRLV:
2573 tcg_gen_andi_tl(t0, t0, 0x3f);
2574 tcg_gen_shr_tl(cpu_gpr[rd], t1, t0);
2575 opn = "dsrlv";
2576 break;
2577 case OPC_DROTRV:
2578 tcg_gen_andi_tl(t0, t0, 0x3f);
2579 tcg_gen_rotr_tl(cpu_gpr[rd], t1, t0);
2580 opn = "drotrv";
2581 break;
2582 #endif
2584 (void)opn; /* avoid a compiler warning */
2585 MIPS_DEBUG("%s %s, %s, %s", opn, regnames[rd], regnames[rs], regnames[rt]);
2586 tcg_temp_free(t0);
2587 tcg_temp_free(t1);
2590 /* Arithmetic on HI/LO registers */
2591 static void gen_HILO(DisasContext *ctx, uint32_t opc, int acc, int reg)
2593 const char *opn = "hilo";
2595 if (reg == 0 && (opc == OPC_MFHI || opc == OPC_MFLO)) {
2596 /* Treat as NOP. */
2597 MIPS_DEBUG("NOP");
2598 return;
2601 if (acc != 0) {
2602 check_dsp(ctx);
2605 switch (opc) {
2606 case OPC_MFHI:
2607 #if defined(TARGET_MIPS64)
2608 if (acc != 0) {
2609 tcg_gen_ext32s_tl(cpu_gpr[reg], cpu_HI[acc]);
2610 } else
2611 #endif
2613 tcg_gen_mov_tl(cpu_gpr[reg], cpu_HI[acc]);
2615 opn = "mfhi";
2616 break;
2617 case OPC_MFLO:
2618 #if defined(TARGET_MIPS64)
2619 if (acc != 0) {
2620 tcg_gen_ext32s_tl(cpu_gpr[reg], cpu_LO[acc]);
2621 } else
2622 #endif
2624 tcg_gen_mov_tl(cpu_gpr[reg], cpu_LO[acc]);
2626 opn = "mflo";
2627 break;
2628 case OPC_MTHI:
2629 if (reg != 0) {
2630 #if defined(TARGET_MIPS64)
2631 if (acc != 0) {
2632 tcg_gen_ext32s_tl(cpu_HI[acc], cpu_gpr[reg]);
2633 } else
2634 #endif
2636 tcg_gen_mov_tl(cpu_HI[acc], cpu_gpr[reg]);
2638 } else {
2639 tcg_gen_movi_tl(cpu_HI[acc], 0);
2641 opn = "mthi";
2642 break;
2643 case OPC_MTLO:
2644 if (reg != 0) {
2645 #if defined(TARGET_MIPS64)
2646 if (acc != 0) {
2647 tcg_gen_ext32s_tl(cpu_LO[acc], cpu_gpr[reg]);
2648 } else
2649 #endif
2651 tcg_gen_mov_tl(cpu_LO[acc], cpu_gpr[reg]);
2653 } else {
2654 tcg_gen_movi_tl(cpu_LO[acc], 0);
2656 opn = "mtlo";
2657 break;
2659 (void)opn; /* avoid a compiler warning */
2660 MIPS_DEBUG("%s %s", opn, regnames[reg]);
2663 static void gen_muldiv(DisasContext *ctx, uint32_t opc,
2664 int acc, int rs, int rt)
2666 const char *opn = "mul/div";
2667 TCGv t0, t1;
2669 t0 = tcg_temp_new();
2670 t1 = tcg_temp_new();
2672 gen_load_gpr(t0, rs);
2673 gen_load_gpr(t1, rt);
2675 if (acc != 0) {
2676 check_dsp(ctx);
2679 switch (opc) {
2680 case OPC_DIV:
2682 TCGv t2 = tcg_temp_new();
2683 TCGv t3 = tcg_temp_new();
2684 tcg_gen_ext32s_tl(t0, t0);
2685 tcg_gen_ext32s_tl(t1, t1);
2686 tcg_gen_setcondi_tl(TCG_COND_EQ, t2, t0, INT_MIN);
2687 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, -1);
2688 tcg_gen_and_tl(t2, t2, t3);
2689 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, 0);
2690 tcg_gen_or_tl(t2, t2, t3);
2691 tcg_gen_movi_tl(t3, 0);
2692 tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, t3, t2, t1);
2693 tcg_gen_div_tl(cpu_LO[acc], t0, t1);
2694 tcg_gen_rem_tl(cpu_HI[acc], t0, t1);
2695 tcg_gen_ext32s_tl(cpu_LO[acc], cpu_LO[acc]);
2696 tcg_gen_ext32s_tl(cpu_HI[acc], cpu_HI[acc]);
2697 tcg_temp_free(t3);
2698 tcg_temp_free(t2);
2700 opn = "div";
2701 break;
2702 case OPC_DIVU:
2704 TCGv t2 = tcg_const_tl(0);
2705 TCGv t3 = tcg_const_tl(1);
2706 tcg_gen_ext32u_tl(t0, t0);
2707 tcg_gen_ext32u_tl(t1, t1);
2708 tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1, t2, t3, t1);
2709 tcg_gen_divu_tl(cpu_LO[acc], t0, t1);
2710 tcg_gen_remu_tl(cpu_HI[acc], t0, t1);
2711 tcg_gen_ext32s_tl(cpu_LO[acc], cpu_LO[acc]);
2712 tcg_gen_ext32s_tl(cpu_HI[acc], cpu_HI[acc]);
2713 tcg_temp_free(t3);
2714 tcg_temp_free(t2);
2716 opn = "divu";
2717 break;
2718 case OPC_MULT:
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_muls2_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 = "mult";
2731 break;
2732 case OPC_MULTU:
2734 TCGv_i32 t2 = tcg_temp_new_i32();
2735 TCGv_i32 t3 = tcg_temp_new_i32();
2736 tcg_gen_trunc_tl_i32(t2, t0);
2737 tcg_gen_trunc_tl_i32(t3, t1);
2738 tcg_gen_mulu2_i32(t2, t3, t2, t3);
2739 tcg_gen_ext_i32_tl(cpu_LO[acc], t2);
2740 tcg_gen_ext_i32_tl(cpu_HI[acc], t3);
2741 tcg_temp_free_i32(t2);
2742 tcg_temp_free_i32(t3);
2744 opn = "multu";
2745 break;
2746 #if defined(TARGET_MIPS64)
2747 case OPC_DDIV:
2749 TCGv t2 = tcg_temp_new();
2750 TCGv t3 = tcg_temp_new();
2751 tcg_gen_setcondi_tl(TCG_COND_EQ, t2, t0, -1LL << 63);
2752 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, -1LL);
2753 tcg_gen_and_tl(t2, t2, t3);
2754 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, 0);
2755 tcg_gen_or_tl(t2, t2, t3);
2756 tcg_gen_movi_tl(t3, 0);
2757 tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, t3, t2, t1);
2758 tcg_gen_div_tl(cpu_LO[acc], t0, t1);
2759 tcg_gen_rem_tl(cpu_HI[acc], t0, t1);
2760 tcg_temp_free(t3);
2761 tcg_temp_free(t2);
2763 opn = "ddiv";
2764 break;
2765 case OPC_DDIVU:
2767 TCGv t2 = tcg_const_tl(0);
2768 TCGv t3 = tcg_const_tl(1);
2769 tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1, t2, t3, t1);
2770 tcg_gen_divu_i64(cpu_LO[acc], t0, t1);
2771 tcg_gen_remu_i64(cpu_HI[acc], t0, t1);
2772 tcg_temp_free(t3);
2773 tcg_temp_free(t2);
2775 opn = "ddivu";
2776 break;
2777 case OPC_DMULT:
2778 tcg_gen_muls2_i64(cpu_LO[acc], cpu_HI[acc], t0, t1);
2779 opn = "dmult";
2780 break;
2781 case OPC_DMULTU:
2782 tcg_gen_mulu2_i64(cpu_LO[acc], cpu_HI[acc], t0, t1);
2783 opn = "dmultu";
2784 break;
2785 #endif
2786 case OPC_MADD:
2788 TCGv_i64 t2 = tcg_temp_new_i64();
2789 TCGv_i64 t3 = tcg_temp_new_i64();
2791 tcg_gen_ext_tl_i64(t2, t0);
2792 tcg_gen_ext_tl_i64(t3, t1);
2793 tcg_gen_mul_i64(t2, t2, t3);
2794 tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]);
2795 tcg_gen_add_i64(t2, t2, t3);
2796 tcg_temp_free_i64(t3);
2797 tcg_gen_trunc_i64_tl(t0, t2);
2798 tcg_gen_shri_i64(t2, t2, 32);
2799 tcg_gen_trunc_i64_tl(t1, t2);
2800 tcg_temp_free_i64(t2);
2801 tcg_gen_ext32s_tl(cpu_LO[acc], t0);
2802 tcg_gen_ext32s_tl(cpu_HI[acc], t1);
2804 opn = "madd";
2805 break;
2806 case OPC_MADDU:
2808 TCGv_i64 t2 = tcg_temp_new_i64();
2809 TCGv_i64 t3 = tcg_temp_new_i64();
2811 tcg_gen_ext32u_tl(t0, t0);
2812 tcg_gen_ext32u_tl(t1, t1);
2813 tcg_gen_extu_tl_i64(t2, t0);
2814 tcg_gen_extu_tl_i64(t3, t1);
2815 tcg_gen_mul_i64(t2, t2, t3);
2816 tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]);
2817 tcg_gen_add_i64(t2, t2, t3);
2818 tcg_temp_free_i64(t3);
2819 tcg_gen_trunc_i64_tl(t0, t2);
2820 tcg_gen_shri_i64(t2, t2, 32);
2821 tcg_gen_trunc_i64_tl(t1, t2);
2822 tcg_temp_free_i64(t2);
2823 tcg_gen_ext32s_tl(cpu_LO[acc], t0);
2824 tcg_gen_ext32s_tl(cpu_HI[acc], t1);
2826 opn = "maddu";
2827 break;
2828 case OPC_MSUB:
2830 TCGv_i64 t2 = tcg_temp_new_i64();
2831 TCGv_i64 t3 = tcg_temp_new_i64();
2833 tcg_gen_ext_tl_i64(t2, t0);
2834 tcg_gen_ext_tl_i64(t3, t1);
2835 tcg_gen_mul_i64(t2, t2, t3);
2836 tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]);
2837 tcg_gen_sub_i64(t2, t3, t2);
2838 tcg_temp_free_i64(t3);
2839 tcg_gen_trunc_i64_tl(t0, t2);
2840 tcg_gen_shri_i64(t2, t2, 32);
2841 tcg_gen_trunc_i64_tl(t1, t2);
2842 tcg_temp_free_i64(t2);
2843 tcg_gen_ext32s_tl(cpu_LO[acc], t0);
2844 tcg_gen_ext32s_tl(cpu_HI[acc], t1);
2846 opn = "msub";
2847 break;
2848 case OPC_MSUBU:
2850 TCGv_i64 t2 = tcg_temp_new_i64();
2851 TCGv_i64 t3 = tcg_temp_new_i64();
2853 tcg_gen_ext32u_tl(t0, t0);
2854 tcg_gen_ext32u_tl(t1, t1);
2855 tcg_gen_extu_tl_i64(t2, t0);
2856 tcg_gen_extu_tl_i64(t3, t1);
2857 tcg_gen_mul_i64(t2, t2, t3);
2858 tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]);
2859 tcg_gen_sub_i64(t2, t3, t2);
2860 tcg_temp_free_i64(t3);
2861 tcg_gen_trunc_i64_tl(t0, t2);
2862 tcg_gen_shri_i64(t2, t2, 32);
2863 tcg_gen_trunc_i64_tl(t1, t2);
2864 tcg_temp_free_i64(t2);
2865 tcg_gen_ext32s_tl(cpu_LO[acc], t0);
2866 tcg_gen_ext32s_tl(cpu_HI[acc], t1);
2868 opn = "msubu";
2869 break;
2870 default:
2871 MIPS_INVAL(opn);
2872 generate_exception(ctx, EXCP_RI);
2873 goto out;
2875 (void)opn; /* avoid a compiler warning */
2876 MIPS_DEBUG("%s %s %s", opn, regnames[rs], regnames[rt]);
2877 out:
2878 tcg_temp_free(t0);
2879 tcg_temp_free(t1);
2882 static void gen_mul_vr54xx (DisasContext *ctx, uint32_t opc,
2883 int rd, int rs, int rt)
2885 const char *opn = "mul vr54xx";
2886 TCGv t0 = tcg_temp_new();
2887 TCGv t1 = tcg_temp_new();
2889 gen_load_gpr(t0, rs);
2890 gen_load_gpr(t1, rt);
2892 switch (opc) {
2893 case OPC_VR54XX_MULS:
2894 gen_helper_muls(t0, cpu_env, t0, t1);
2895 opn = "muls";
2896 break;
2897 case OPC_VR54XX_MULSU:
2898 gen_helper_mulsu(t0, cpu_env, t0, t1);
2899 opn = "mulsu";
2900 break;
2901 case OPC_VR54XX_MACC:
2902 gen_helper_macc(t0, cpu_env, t0, t1);
2903 opn = "macc";
2904 break;
2905 case OPC_VR54XX_MACCU:
2906 gen_helper_maccu(t0, cpu_env, t0, t1);
2907 opn = "maccu";
2908 break;
2909 case OPC_VR54XX_MSAC:
2910 gen_helper_msac(t0, cpu_env, t0, t1);
2911 opn = "msac";
2912 break;
2913 case OPC_VR54XX_MSACU:
2914 gen_helper_msacu(t0, cpu_env, t0, t1);
2915 opn = "msacu";
2916 break;
2917 case OPC_VR54XX_MULHI:
2918 gen_helper_mulhi(t0, cpu_env, t0, t1);
2919 opn = "mulhi";
2920 break;
2921 case OPC_VR54XX_MULHIU:
2922 gen_helper_mulhiu(t0, cpu_env, t0, t1);
2923 opn = "mulhiu";
2924 break;
2925 case OPC_VR54XX_MULSHI:
2926 gen_helper_mulshi(t0, cpu_env, t0, t1);
2927 opn = "mulshi";
2928 break;
2929 case OPC_VR54XX_MULSHIU:
2930 gen_helper_mulshiu(t0, cpu_env, t0, t1);
2931 opn = "mulshiu";
2932 break;
2933 case OPC_VR54XX_MACCHI:
2934 gen_helper_macchi(t0, cpu_env, t0, t1);
2935 opn = "macchi";
2936 break;
2937 case OPC_VR54XX_MACCHIU:
2938 gen_helper_macchiu(t0, cpu_env, t0, t1);
2939 opn = "macchiu";
2940 break;
2941 case OPC_VR54XX_MSACHI:
2942 gen_helper_msachi(t0, cpu_env, t0, t1);
2943 opn = "msachi";
2944 break;
2945 case OPC_VR54XX_MSACHIU:
2946 gen_helper_msachiu(t0, cpu_env, t0, t1);
2947 opn = "msachiu";
2948 break;
2949 default:
2950 MIPS_INVAL("mul vr54xx");
2951 generate_exception(ctx, EXCP_RI);
2952 goto out;
2954 gen_store_gpr(t0, rd);
2955 (void)opn; /* avoid a compiler warning */
2956 MIPS_DEBUG("%s %s, %s, %s", opn, regnames[rd], regnames[rs], regnames[rt]);
2958 out:
2959 tcg_temp_free(t0);
2960 tcg_temp_free(t1);
2963 static void gen_cl (DisasContext *ctx, uint32_t opc,
2964 int rd, int rs)
2966 const char *opn = "CLx";
2967 TCGv t0;
2969 if (rd == 0) {
2970 /* Treat as NOP. */
2971 MIPS_DEBUG("NOP");
2972 return;
2974 t0 = tcg_temp_new();
2975 gen_load_gpr(t0, rs);
2976 switch (opc) {
2977 case OPC_CLO:
2978 gen_helper_clo(cpu_gpr[rd], t0);
2979 opn = "clo";
2980 break;
2981 case OPC_CLZ:
2982 gen_helper_clz(cpu_gpr[rd], t0);
2983 opn = "clz";
2984 break;
2985 #if defined(TARGET_MIPS64)
2986 case OPC_DCLO:
2987 gen_helper_dclo(cpu_gpr[rd], t0);
2988 opn = "dclo";
2989 break;
2990 case OPC_DCLZ:
2991 gen_helper_dclz(cpu_gpr[rd], t0);
2992 opn = "dclz";
2993 break;
2994 #endif
2996 (void)opn; /* avoid a compiler warning */
2997 MIPS_DEBUG("%s %s, %s", opn, regnames[rd], regnames[rs]);
2998 tcg_temp_free(t0);
3001 /* Godson integer instructions */
3002 static void gen_loongson_integer(DisasContext *ctx, uint32_t opc,
3003 int rd, int rs, int rt)
3005 const char *opn = "loongson";
3006 TCGv t0, t1;
3008 if (rd == 0) {
3009 /* Treat as NOP. */
3010 MIPS_DEBUG("NOP");
3011 return;
3014 switch (opc) {
3015 case OPC_MULT_G_2E:
3016 case OPC_MULT_G_2F:
3017 case OPC_MULTU_G_2E:
3018 case OPC_MULTU_G_2F:
3019 #if defined(TARGET_MIPS64)
3020 case OPC_DMULT_G_2E:
3021 case OPC_DMULT_G_2F:
3022 case OPC_DMULTU_G_2E:
3023 case OPC_DMULTU_G_2F:
3024 #endif
3025 t0 = tcg_temp_new();
3026 t1 = tcg_temp_new();
3027 break;
3028 default:
3029 t0 = tcg_temp_local_new();
3030 t1 = tcg_temp_local_new();
3031 break;
3034 gen_load_gpr(t0, rs);
3035 gen_load_gpr(t1, rt);
3037 switch (opc) {
3038 case OPC_MULT_G_2E:
3039 case OPC_MULT_G_2F:
3040 tcg_gen_mul_tl(cpu_gpr[rd], t0, t1);
3041 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3042 opn = "mult.g";
3043 break;
3044 case OPC_MULTU_G_2E:
3045 case OPC_MULTU_G_2F:
3046 tcg_gen_ext32u_tl(t0, t0);
3047 tcg_gen_ext32u_tl(t1, t1);
3048 tcg_gen_mul_tl(cpu_gpr[rd], t0, t1);
3049 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3050 opn = "multu.g";
3051 break;
3052 case OPC_DIV_G_2E:
3053 case OPC_DIV_G_2F:
3055 int l1 = gen_new_label();
3056 int l2 = gen_new_label();
3057 int l3 = gen_new_label();
3058 tcg_gen_ext32s_tl(t0, t0);
3059 tcg_gen_ext32s_tl(t1, t1);
3060 tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
3061 tcg_gen_movi_tl(cpu_gpr[rd], 0);
3062 tcg_gen_br(l3);
3063 gen_set_label(l1);
3064 tcg_gen_brcondi_tl(TCG_COND_NE, t0, INT_MIN, l2);
3065 tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1, l2);
3066 tcg_gen_mov_tl(cpu_gpr[rd], t0);
3067 tcg_gen_br(l3);
3068 gen_set_label(l2);
3069 tcg_gen_div_tl(cpu_gpr[rd], t0, t1);
3070 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3071 gen_set_label(l3);
3073 opn = "div.g";
3074 break;
3075 case OPC_DIVU_G_2E:
3076 case OPC_DIVU_G_2F:
3078 int l1 = gen_new_label();
3079 int l2 = gen_new_label();
3080 tcg_gen_ext32u_tl(t0, t0);
3081 tcg_gen_ext32u_tl(t1, t1);
3082 tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
3083 tcg_gen_movi_tl(cpu_gpr[rd], 0);
3084 tcg_gen_br(l2);
3085 gen_set_label(l1);
3086 tcg_gen_divu_tl(cpu_gpr[rd], t0, t1);
3087 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3088 gen_set_label(l2);
3090 opn = "divu.g";
3091 break;
3092 case OPC_MOD_G_2E:
3093 case OPC_MOD_G_2F:
3095 int l1 = gen_new_label();
3096 int l2 = gen_new_label();
3097 int l3 = gen_new_label();
3098 tcg_gen_ext32u_tl(t0, t0);
3099 tcg_gen_ext32u_tl(t1, t1);
3100 tcg_gen_brcondi_tl(TCG_COND_EQ, t1, 0, l1);
3101 tcg_gen_brcondi_tl(TCG_COND_NE, t0, INT_MIN, l2);
3102 tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1, l2);
3103 gen_set_label(l1);
3104 tcg_gen_movi_tl(cpu_gpr[rd], 0);
3105 tcg_gen_br(l3);
3106 gen_set_label(l2);
3107 tcg_gen_rem_tl(cpu_gpr[rd], t0, t1);
3108 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3109 gen_set_label(l3);
3111 opn = "mod.g";
3112 break;
3113 case OPC_MODU_G_2E:
3114 case OPC_MODU_G_2F:
3116 int l1 = gen_new_label();
3117 int l2 = gen_new_label();
3118 tcg_gen_ext32u_tl(t0, t0);
3119 tcg_gen_ext32u_tl(t1, t1);
3120 tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
3121 tcg_gen_movi_tl(cpu_gpr[rd], 0);
3122 tcg_gen_br(l2);
3123 gen_set_label(l1);
3124 tcg_gen_remu_tl(cpu_gpr[rd], t0, t1);
3125 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3126 gen_set_label(l2);
3128 opn = "modu.g";
3129 break;
3130 #if defined(TARGET_MIPS64)
3131 case OPC_DMULT_G_2E:
3132 case OPC_DMULT_G_2F:
3133 tcg_gen_mul_tl(cpu_gpr[rd], t0, t1);
3134 opn = "dmult.g";
3135 break;
3136 case OPC_DMULTU_G_2E:
3137 case OPC_DMULTU_G_2F:
3138 tcg_gen_mul_tl(cpu_gpr[rd], t0, t1);
3139 opn = "dmultu.g";
3140 break;
3141 case OPC_DDIV_G_2E:
3142 case OPC_DDIV_G_2F:
3144 int l1 = gen_new_label();
3145 int l2 = gen_new_label();
3146 int l3 = gen_new_label();
3147 tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
3148 tcg_gen_movi_tl(cpu_gpr[rd], 0);
3149 tcg_gen_br(l3);
3150 gen_set_label(l1);
3151 tcg_gen_brcondi_tl(TCG_COND_NE, t0, -1LL << 63, l2);
3152 tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1LL, l2);
3153 tcg_gen_mov_tl(cpu_gpr[rd], t0);
3154 tcg_gen_br(l3);
3155 gen_set_label(l2);
3156 tcg_gen_div_tl(cpu_gpr[rd], t0, t1);
3157 gen_set_label(l3);
3159 opn = "ddiv.g";
3160 break;
3161 case OPC_DDIVU_G_2E:
3162 case OPC_DDIVU_G_2F:
3164 int l1 = gen_new_label();
3165 int l2 = gen_new_label();
3166 tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
3167 tcg_gen_movi_tl(cpu_gpr[rd], 0);
3168 tcg_gen_br(l2);
3169 gen_set_label(l1);
3170 tcg_gen_divu_tl(cpu_gpr[rd], t0, t1);
3171 gen_set_label(l2);
3173 opn = "ddivu.g";
3174 break;
3175 case OPC_DMOD_G_2E:
3176 case OPC_DMOD_G_2F:
3178 int l1 = gen_new_label();
3179 int l2 = gen_new_label();
3180 int l3 = gen_new_label();
3181 tcg_gen_brcondi_tl(TCG_COND_EQ, t1, 0, l1);
3182 tcg_gen_brcondi_tl(TCG_COND_NE, t0, -1LL << 63, l2);
3183 tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1LL, l2);
3184 gen_set_label(l1);
3185 tcg_gen_movi_tl(cpu_gpr[rd], 0);
3186 tcg_gen_br(l3);
3187 gen_set_label(l2);
3188 tcg_gen_rem_tl(cpu_gpr[rd], t0, t1);
3189 gen_set_label(l3);
3191 opn = "dmod.g";
3192 break;
3193 case OPC_DMODU_G_2E:
3194 case OPC_DMODU_G_2F:
3196 int l1 = gen_new_label();
3197 int l2 = gen_new_label();
3198 tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
3199 tcg_gen_movi_tl(cpu_gpr[rd], 0);
3200 tcg_gen_br(l2);
3201 gen_set_label(l1);
3202 tcg_gen_remu_tl(cpu_gpr[rd], t0, t1);
3203 gen_set_label(l2);
3205 opn = "dmodu.g";
3206 break;
3207 #endif
3210 (void)opn; /* avoid a compiler warning */
3211 MIPS_DEBUG("%s %s, %s", opn, regnames[rd], regnames[rs]);
3212 tcg_temp_free(t0);
3213 tcg_temp_free(t1);
3216 /* Loongson multimedia instructions */
3217 static void gen_loongson_multimedia(DisasContext *ctx, int rd, int rs, int rt)
3219 const char *opn = "loongson_cp2";
3220 uint32_t opc, shift_max;
3221 TCGv_i64 t0, t1;
3223 opc = MASK_LMI(ctx->opcode);
3224 switch (opc) {
3225 case OPC_ADD_CP2:
3226 case OPC_SUB_CP2:
3227 case OPC_DADD_CP2:
3228 case OPC_DSUB_CP2:
3229 t0 = tcg_temp_local_new_i64();
3230 t1 = tcg_temp_local_new_i64();
3231 break;
3232 default:
3233 t0 = tcg_temp_new_i64();
3234 t1 = tcg_temp_new_i64();
3235 break;
3238 gen_load_fpr64(ctx, t0, rs);
3239 gen_load_fpr64(ctx, t1, rt);
3241 #define LMI_HELPER(UP, LO) \
3242 case OPC_##UP: gen_helper_##LO(t0, t0, t1); opn = #LO; break
3243 #define LMI_HELPER_1(UP, LO) \
3244 case OPC_##UP: gen_helper_##LO(t0, t0); opn = #LO; break
3245 #define LMI_DIRECT(UP, LO, OP) \
3246 case OPC_##UP: tcg_gen_##OP##_i64(t0, t0, t1); opn = #LO; break
3248 switch (opc) {
3249 LMI_HELPER(PADDSH, paddsh);
3250 LMI_HELPER(PADDUSH, paddush);
3251 LMI_HELPER(PADDH, paddh);
3252 LMI_HELPER(PADDW, paddw);
3253 LMI_HELPER(PADDSB, paddsb);
3254 LMI_HELPER(PADDUSB, paddusb);
3255 LMI_HELPER(PADDB, paddb);
3257 LMI_HELPER(PSUBSH, psubsh);
3258 LMI_HELPER(PSUBUSH, psubush);
3259 LMI_HELPER(PSUBH, psubh);
3260 LMI_HELPER(PSUBW, psubw);
3261 LMI_HELPER(PSUBSB, psubsb);
3262 LMI_HELPER(PSUBUSB, psubusb);
3263 LMI_HELPER(PSUBB, psubb);
3265 LMI_HELPER(PSHUFH, pshufh);
3266 LMI_HELPER(PACKSSWH, packsswh);
3267 LMI_HELPER(PACKSSHB, packsshb);
3268 LMI_HELPER(PACKUSHB, packushb);
3270 LMI_HELPER(PUNPCKLHW, punpcklhw);
3271 LMI_HELPER(PUNPCKHHW, punpckhhw);
3272 LMI_HELPER(PUNPCKLBH, punpcklbh);
3273 LMI_HELPER(PUNPCKHBH, punpckhbh);
3274 LMI_HELPER(PUNPCKLWD, punpcklwd);
3275 LMI_HELPER(PUNPCKHWD, punpckhwd);
3277 LMI_HELPER(PAVGH, pavgh);
3278 LMI_HELPER(PAVGB, pavgb);
3279 LMI_HELPER(PMAXSH, pmaxsh);
3280 LMI_HELPER(PMINSH, pminsh);
3281 LMI_HELPER(PMAXUB, pmaxub);
3282 LMI_HELPER(PMINUB, pminub);
3284 LMI_HELPER(PCMPEQW, pcmpeqw);
3285 LMI_HELPER(PCMPGTW, pcmpgtw);
3286 LMI_HELPER(PCMPEQH, pcmpeqh);
3287 LMI_HELPER(PCMPGTH, pcmpgth);
3288 LMI_HELPER(PCMPEQB, pcmpeqb);
3289 LMI_HELPER(PCMPGTB, pcmpgtb);
3291 LMI_HELPER(PSLLW, psllw);
3292 LMI_HELPER(PSLLH, psllh);
3293 LMI_HELPER(PSRLW, psrlw);
3294 LMI_HELPER(PSRLH, psrlh);
3295 LMI_HELPER(PSRAW, psraw);
3296 LMI_HELPER(PSRAH, psrah);
3298 LMI_HELPER(PMULLH, pmullh);
3299 LMI_HELPER(PMULHH, pmulhh);
3300 LMI_HELPER(PMULHUH, pmulhuh);
3301 LMI_HELPER(PMADDHW, pmaddhw);
3303 LMI_HELPER(PASUBUB, pasubub);
3304 LMI_HELPER_1(BIADD, biadd);
3305 LMI_HELPER_1(PMOVMSKB, pmovmskb);
3307 LMI_DIRECT(PADDD, paddd, add);
3308 LMI_DIRECT(PSUBD, psubd, sub);
3309 LMI_DIRECT(XOR_CP2, xor, xor);
3310 LMI_DIRECT(NOR_CP2, nor, nor);
3311 LMI_DIRECT(AND_CP2, and, and);
3312 LMI_DIRECT(PANDN, pandn, andc);
3313 LMI_DIRECT(OR, or, or);
3315 case OPC_PINSRH_0:
3316 tcg_gen_deposit_i64(t0, t0, t1, 0, 16);
3317 opn = "pinsrh_0";
3318 break;
3319 case OPC_PINSRH_1:
3320 tcg_gen_deposit_i64(t0, t0, t1, 16, 16);
3321 opn = "pinsrh_1";
3322 break;
3323 case OPC_PINSRH_2:
3324 tcg_gen_deposit_i64(t0, t0, t1, 32, 16);
3325 opn = "pinsrh_2";
3326 break;
3327 case OPC_PINSRH_3:
3328 tcg_gen_deposit_i64(t0, t0, t1, 48, 16);
3329 opn = "pinsrh_3";
3330 break;
3332 case OPC_PEXTRH:
3333 tcg_gen_andi_i64(t1, t1, 3);
3334 tcg_gen_shli_i64(t1, t1, 4);
3335 tcg_gen_shr_i64(t0, t0, t1);
3336 tcg_gen_ext16u_i64(t0, t0);
3337 opn = "pextrh";
3338 break;
3340 case OPC_ADDU_CP2:
3341 tcg_gen_add_i64(t0, t0, t1);
3342 tcg_gen_ext32s_i64(t0, t0);
3343 opn = "addu";
3344 break;
3345 case OPC_SUBU_CP2:
3346 tcg_gen_sub_i64(t0, t0, t1);
3347 tcg_gen_ext32s_i64(t0, t0);
3348 opn = "addu";
3349 break;
3351 case OPC_SLL_CP2:
3352 opn = "sll";
3353 shift_max = 32;
3354 goto do_shift;
3355 case OPC_SRL_CP2:
3356 opn = "srl";
3357 shift_max = 32;
3358 goto do_shift;
3359 case OPC_SRA_CP2:
3360 opn = "sra";
3361 shift_max = 32;
3362 goto do_shift;
3363 case OPC_DSLL_CP2:
3364 opn = "dsll";
3365 shift_max = 64;
3366 goto do_shift;
3367 case OPC_DSRL_CP2:
3368 opn = "dsrl";
3369 shift_max = 64;
3370 goto do_shift;
3371 case OPC_DSRA_CP2:
3372 opn = "dsra";
3373 shift_max = 64;
3374 goto do_shift;
3375 do_shift:
3376 /* Make sure shift count isn't TCG undefined behaviour. */
3377 tcg_gen_andi_i64(t1, t1, shift_max - 1);
3379 switch (opc) {
3380 case OPC_SLL_CP2:
3381 case OPC_DSLL_CP2:
3382 tcg_gen_shl_i64(t0, t0, t1);
3383 break;
3384 case OPC_SRA_CP2:
3385 case OPC_DSRA_CP2:
3386 /* Since SRA is UndefinedResult without sign-extended inputs,
3387 we can treat SRA and DSRA the same. */
3388 tcg_gen_sar_i64(t0, t0, t1);
3389 break;
3390 case OPC_SRL_CP2:
3391 /* We want to shift in zeros for SRL; zero-extend first. */
3392 tcg_gen_ext32u_i64(t0, t0);
3393 /* FALLTHRU */
3394 case OPC_DSRL_CP2:
3395 tcg_gen_shr_i64(t0, t0, t1);
3396 break;
3399 if (shift_max == 32) {
3400 tcg_gen_ext32s_i64(t0, t0);
3403 /* Shifts larger than MAX produce zero. */
3404 tcg_gen_setcondi_i64(TCG_COND_LTU, t1, t1, shift_max);
3405 tcg_gen_neg_i64(t1, t1);
3406 tcg_gen_and_i64(t0, t0, t1);
3407 break;
3409 case OPC_ADD_CP2:
3410 case OPC_DADD_CP2:
3412 TCGv_i64 t2 = tcg_temp_new_i64();
3413 int lab = gen_new_label();
3415 tcg_gen_mov_i64(t2, t0);
3416 tcg_gen_add_i64(t0, t1, t2);
3417 if (opc == OPC_ADD_CP2) {
3418 tcg_gen_ext32s_i64(t0, t0);
3420 tcg_gen_xor_i64(t1, t1, t2);
3421 tcg_gen_xor_i64(t2, t2, t0);
3422 tcg_gen_andc_i64(t1, t2, t1);
3423 tcg_temp_free_i64(t2);
3424 tcg_gen_brcondi_i64(TCG_COND_GE, t1, 0, lab);
3425 generate_exception(ctx, EXCP_OVERFLOW);
3426 gen_set_label(lab);
3428 opn = (opc == OPC_ADD_CP2 ? "add" : "dadd");
3429 break;
3432 case OPC_SUB_CP2:
3433 case OPC_DSUB_CP2:
3435 TCGv_i64 t2 = tcg_temp_new_i64();
3436 int lab = gen_new_label();
3438 tcg_gen_mov_i64(t2, t0);
3439 tcg_gen_sub_i64(t0, t1, t2);
3440 if (opc == OPC_SUB_CP2) {
3441 tcg_gen_ext32s_i64(t0, t0);
3443 tcg_gen_xor_i64(t1, t1, t2);
3444 tcg_gen_xor_i64(t2, t2, t0);
3445 tcg_gen_and_i64(t1, t1, t2);
3446 tcg_temp_free_i64(t2);
3447 tcg_gen_brcondi_i64(TCG_COND_GE, t1, 0, lab);
3448 generate_exception(ctx, EXCP_OVERFLOW);
3449 gen_set_label(lab);
3451 opn = (opc == OPC_SUB_CP2 ? "sub" : "dsub");
3452 break;
3455 case OPC_PMULUW:
3456 tcg_gen_ext32u_i64(t0, t0);
3457 tcg_gen_ext32u_i64(t1, t1);
3458 tcg_gen_mul_i64(t0, t0, t1);
3459 opn = "pmuluw";
3460 break;
3462 case OPC_SEQU_CP2:
3463 case OPC_SEQ_CP2:
3464 case OPC_SLTU_CP2:
3465 case OPC_SLT_CP2:
3466 case OPC_SLEU_CP2:
3467 case OPC_SLE_CP2:
3468 /* ??? Document is unclear: Set FCC[CC]. Does that mean the
3469 FD field is the CC field? */
3470 default:
3471 MIPS_INVAL(opn);
3472 generate_exception(ctx, EXCP_RI);
3473 return;
3476 #undef LMI_HELPER
3477 #undef LMI_DIRECT
3479 gen_store_fpr64(ctx, t0, rd);
3481 (void)opn; /* avoid a compiler warning */
3482 MIPS_DEBUG("%s %s, %s, %s", opn,
3483 fregnames[rd], fregnames[rs], fregnames[rt]);
3484 tcg_temp_free_i64(t0);
3485 tcg_temp_free_i64(t1);
3488 /* Traps */
3489 static void gen_trap (DisasContext *ctx, uint32_t opc,
3490 int rs, int rt, int16_t imm)
3492 int cond;
3493 TCGv t0 = tcg_temp_new();
3494 TCGv t1 = tcg_temp_new();
3496 cond = 0;
3497 /* Load needed operands */
3498 switch (opc) {
3499 case OPC_TEQ:
3500 case OPC_TGE:
3501 case OPC_TGEU:
3502 case OPC_TLT:
3503 case OPC_TLTU:
3504 case OPC_TNE:
3505 /* Compare two registers */
3506 if (rs != rt) {
3507 gen_load_gpr(t0, rs);
3508 gen_load_gpr(t1, rt);
3509 cond = 1;
3511 break;
3512 case OPC_TEQI:
3513 case OPC_TGEI:
3514 case OPC_TGEIU:
3515 case OPC_TLTI:
3516 case OPC_TLTIU:
3517 case OPC_TNEI:
3518 /* Compare register to immediate */
3519 if (rs != 0 || imm != 0) {
3520 gen_load_gpr(t0, rs);
3521 tcg_gen_movi_tl(t1, (int32_t)imm);
3522 cond = 1;
3524 break;
3526 if (cond == 0) {
3527 switch (opc) {
3528 case OPC_TEQ: /* rs == rs */
3529 case OPC_TEQI: /* r0 == 0 */
3530 case OPC_TGE: /* rs >= rs */
3531 case OPC_TGEI: /* r0 >= 0 */
3532 case OPC_TGEU: /* rs >= rs unsigned */
3533 case OPC_TGEIU: /* r0 >= 0 unsigned */
3534 /* Always trap */
3535 generate_exception(ctx, EXCP_TRAP);
3536 break;
3537 case OPC_TLT: /* rs < rs */
3538 case OPC_TLTI: /* r0 < 0 */
3539 case OPC_TLTU: /* rs < rs unsigned */
3540 case OPC_TLTIU: /* r0 < 0 unsigned */
3541 case OPC_TNE: /* rs != rs */
3542 case OPC_TNEI: /* r0 != 0 */
3543 /* Never trap: treat as NOP. */
3544 break;
3546 } else {
3547 int l1 = gen_new_label();
3549 switch (opc) {
3550 case OPC_TEQ:
3551 case OPC_TEQI:
3552 tcg_gen_brcond_tl(TCG_COND_NE, t0, t1, l1);
3553 break;
3554 case OPC_TGE:
3555 case OPC_TGEI:
3556 tcg_gen_brcond_tl(TCG_COND_LT, t0, t1, l1);
3557 break;
3558 case OPC_TGEU:
3559 case OPC_TGEIU:
3560 tcg_gen_brcond_tl(TCG_COND_LTU, t0, t1, l1);
3561 break;
3562 case OPC_TLT:
3563 case OPC_TLTI:
3564 tcg_gen_brcond_tl(TCG_COND_GE, t0, t1, l1);
3565 break;
3566 case OPC_TLTU:
3567 case OPC_TLTIU:
3568 tcg_gen_brcond_tl(TCG_COND_GEU, t0, t1, l1);
3569 break;
3570 case OPC_TNE:
3571 case OPC_TNEI:
3572 tcg_gen_brcond_tl(TCG_COND_EQ, t0, t1, l1);
3573 break;
3575 generate_exception(ctx, EXCP_TRAP);
3576 gen_set_label(l1);
3578 tcg_temp_free(t0);
3579 tcg_temp_free(t1);
3582 static inline void gen_goto_tb(DisasContext *ctx, int n, target_ulong dest)
3584 TranslationBlock *tb;
3585 tb = ctx->tb;
3586 if ((tb->pc & TARGET_PAGE_MASK) == (dest & TARGET_PAGE_MASK) &&
3587 likely(!ctx->singlestep_enabled)) {
3588 tcg_gen_goto_tb(n);
3589 gen_save_pc(dest);
3590 tcg_gen_exit_tb((uintptr_t)tb + n);
3591 } else {
3592 gen_save_pc(dest);
3593 if (ctx->singlestep_enabled) {
3594 save_cpu_state(ctx, 0);
3595 gen_helper_0e0i(raise_exception, EXCP_DEBUG);
3597 tcg_gen_exit_tb(0);
3601 /* Branches (before delay slot) */
3602 static void gen_compute_branch (DisasContext *ctx, uint32_t opc,
3603 int insn_bytes,
3604 int rs, int rt, int32_t offset)
3606 target_ulong btgt = -1;
3607 int blink = 0;
3608 int bcond_compute = 0;
3609 TCGv t0 = tcg_temp_new();
3610 TCGv t1 = tcg_temp_new();
3612 if (ctx->hflags & MIPS_HFLAG_BMASK) {
3613 #ifdef MIPS_DEBUG_DISAS
3614 LOG_DISAS("Branch in delay slot at PC 0x" TARGET_FMT_lx "\n", ctx->pc);
3615 #endif
3616 generate_exception(ctx, EXCP_RI);
3617 goto out;
3620 /* Load needed operands */
3621 switch (opc) {
3622 case OPC_BEQ:
3623 case OPC_BEQL:
3624 case OPC_BNE:
3625 case OPC_BNEL:
3626 /* Compare two registers */
3627 if (rs != rt) {
3628 gen_load_gpr(t0, rs);
3629 gen_load_gpr(t1, rt);
3630 bcond_compute = 1;
3632 btgt = ctx->pc + insn_bytes + offset;
3633 break;
3634 case OPC_BGEZ:
3635 case OPC_BGEZAL:
3636 case OPC_BGEZALS:
3637 case OPC_BGEZALL:
3638 case OPC_BGEZL:
3639 case OPC_BGTZ:
3640 case OPC_BGTZL:
3641 case OPC_BLEZ:
3642 case OPC_BLEZL:
3643 case OPC_BLTZ:
3644 case OPC_BLTZAL:
3645 case OPC_BLTZALS:
3646 case OPC_BLTZALL:
3647 case OPC_BLTZL:
3648 /* Compare to zero */
3649 if (rs != 0) {
3650 gen_load_gpr(t0, rs);
3651 bcond_compute = 1;
3653 btgt = ctx->pc + insn_bytes + offset;
3654 break;
3655 case OPC_BPOSGE32:
3656 #if defined(TARGET_MIPS64)
3657 case OPC_BPOSGE64:
3658 tcg_gen_andi_tl(t0, cpu_dspctrl, 0x7F);
3659 #else
3660 tcg_gen_andi_tl(t0, cpu_dspctrl, 0x3F);
3661 #endif
3662 bcond_compute = 1;
3663 btgt = ctx->pc + insn_bytes + offset;
3664 break;
3665 case OPC_J:
3666 case OPC_JAL:
3667 case OPC_JALX:
3668 case OPC_JALS:
3669 case OPC_JALXS:
3670 /* Jump to immediate */
3671 btgt = ((ctx->pc + insn_bytes) & (int32_t)0xF0000000) | (uint32_t)offset;
3672 break;
3673 case OPC_JR:
3674 case OPC_JALR:
3675 case OPC_JALRC:
3676 case OPC_JALRS:
3677 /* Jump to register */
3678 if (offset != 0 && offset != 16) {
3679 /* Hint = 0 is JR/JALR, hint 16 is JR.HB/JALR.HB, the
3680 others are reserved. */
3681 MIPS_INVAL("jump hint");
3682 generate_exception(ctx, EXCP_RI);
3683 goto out;
3685 gen_load_gpr(btarget, rs);
3686 break;
3687 default:
3688 MIPS_INVAL("branch/jump");
3689 generate_exception(ctx, EXCP_RI);
3690 goto out;
3692 if (bcond_compute == 0) {
3693 /* No condition to be computed */
3694 switch (opc) {
3695 case OPC_BEQ: /* rx == rx */
3696 case OPC_BEQL: /* rx == rx likely */
3697 case OPC_BGEZ: /* 0 >= 0 */
3698 case OPC_BGEZL: /* 0 >= 0 likely */
3699 case OPC_BLEZ: /* 0 <= 0 */
3700 case OPC_BLEZL: /* 0 <= 0 likely */
3701 /* Always take */
3702 ctx->hflags |= MIPS_HFLAG_B;
3703 MIPS_DEBUG("balways");
3704 break;
3705 case OPC_BGEZALS:
3706 case OPC_BGEZAL: /* 0 >= 0 */
3707 case OPC_BGEZALL: /* 0 >= 0 likely */
3708 ctx->hflags |= (opc == OPC_BGEZALS
3709 ? MIPS_HFLAG_BDS16
3710 : MIPS_HFLAG_BDS32);
3711 /* Always take and link */
3712 blink = 31;
3713 ctx->hflags |= MIPS_HFLAG_B;
3714 MIPS_DEBUG("balways and link");
3715 break;
3716 case OPC_BNE: /* rx != rx */
3717 case OPC_BGTZ: /* 0 > 0 */
3718 case OPC_BLTZ: /* 0 < 0 */
3719 /* Treat as NOP. */
3720 MIPS_DEBUG("bnever (NOP)");
3721 goto out;
3722 case OPC_BLTZALS:
3723 case OPC_BLTZAL: /* 0 < 0 */
3724 ctx->hflags |= (opc == OPC_BLTZALS
3725 ? MIPS_HFLAG_BDS16
3726 : MIPS_HFLAG_BDS32);
3727 /* Handle as an unconditional branch to get correct delay
3728 slot checking. */
3729 blink = 31;
3730 btgt = ctx->pc + (opc == OPC_BLTZALS ? 6 : 8);
3731 ctx->hflags |= MIPS_HFLAG_B;
3732 MIPS_DEBUG("bnever and link");
3733 break;
3734 case OPC_BLTZALL: /* 0 < 0 likely */
3735 tcg_gen_movi_tl(cpu_gpr[31], ctx->pc + 8);
3736 /* Skip the instruction in the delay slot */
3737 MIPS_DEBUG("bnever, link and skip");
3738 ctx->pc += 4;
3739 goto out;
3740 case OPC_BNEL: /* rx != rx likely */
3741 case OPC_BGTZL: /* 0 > 0 likely */
3742 case OPC_BLTZL: /* 0 < 0 likely */
3743 /* Skip the instruction in the delay slot */
3744 MIPS_DEBUG("bnever and skip");
3745 ctx->pc += 4;
3746 goto out;
3747 case OPC_J:
3748 ctx->hflags |= MIPS_HFLAG_B;
3749 MIPS_DEBUG("j " TARGET_FMT_lx, btgt);
3750 break;
3751 case OPC_JALXS:
3752 case OPC_JALX:
3753 ctx->hflags |= MIPS_HFLAG_BX;
3754 /* Fallthrough */
3755 case OPC_JALS:
3756 case OPC_JAL:
3757 blink = 31;
3758 ctx->hflags |= MIPS_HFLAG_B;
3759 ctx->hflags |= ((opc == OPC_JALS || opc == OPC_JALXS)
3760 ? MIPS_HFLAG_BDS16
3761 : MIPS_HFLAG_BDS32);
3762 MIPS_DEBUG("jal " TARGET_FMT_lx, btgt);
3763 break;
3764 case OPC_JR:
3765 ctx->hflags |= MIPS_HFLAG_BR;
3766 if (insn_bytes == 4)
3767 ctx->hflags |= MIPS_HFLAG_BDS32;
3768 MIPS_DEBUG("jr %s", regnames[rs]);
3769 break;
3770 case OPC_JALRS:
3771 case OPC_JALR:
3772 case OPC_JALRC:
3773 blink = rt;
3774 ctx->hflags |= MIPS_HFLAG_BR;
3775 ctx->hflags |= (opc == OPC_JALRS
3776 ? MIPS_HFLAG_BDS16
3777 : MIPS_HFLAG_BDS32);
3778 MIPS_DEBUG("jalr %s, %s", regnames[rt], regnames[rs]);
3779 break;
3780 default:
3781 MIPS_INVAL("branch/jump");
3782 generate_exception(ctx, EXCP_RI);
3783 goto out;
3785 } else {
3786 switch (opc) {
3787 case OPC_BEQ:
3788 tcg_gen_setcond_tl(TCG_COND_EQ, bcond, t0, t1);
3789 MIPS_DEBUG("beq %s, %s, " TARGET_FMT_lx,
3790 regnames[rs], regnames[rt], btgt);
3791 goto not_likely;
3792 case OPC_BEQL:
3793 tcg_gen_setcond_tl(TCG_COND_EQ, bcond, t0, t1);
3794 MIPS_DEBUG("beql %s, %s, " TARGET_FMT_lx,
3795 regnames[rs], regnames[rt], btgt);
3796 goto likely;
3797 case OPC_BNE:
3798 tcg_gen_setcond_tl(TCG_COND_NE, bcond, t0, t1);
3799 MIPS_DEBUG("bne %s, %s, " TARGET_FMT_lx,
3800 regnames[rs], regnames[rt], btgt);
3801 goto not_likely;
3802 case OPC_BNEL:
3803 tcg_gen_setcond_tl(TCG_COND_NE, bcond, t0, t1);
3804 MIPS_DEBUG("bnel %s, %s, " TARGET_FMT_lx,
3805 regnames[rs], regnames[rt], btgt);
3806 goto likely;
3807 case OPC_BGEZ:
3808 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 0);
3809 MIPS_DEBUG("bgez %s, " TARGET_FMT_lx, regnames[rs], btgt);
3810 goto not_likely;
3811 case OPC_BGEZL:
3812 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 0);
3813 MIPS_DEBUG("bgezl %s, " TARGET_FMT_lx, regnames[rs], btgt);
3814 goto likely;
3815 case OPC_BGEZALS:
3816 case OPC_BGEZAL:
3817 ctx->hflags |= (opc == OPC_BGEZALS
3818 ? MIPS_HFLAG_BDS16
3819 : MIPS_HFLAG_BDS32);
3820 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 0);
3821 MIPS_DEBUG("bgezal %s, " TARGET_FMT_lx, regnames[rs], btgt);
3822 blink = 31;
3823 goto not_likely;
3824 case OPC_BGEZALL:
3825 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 0);
3826 blink = 31;
3827 MIPS_DEBUG("bgezall %s, " TARGET_FMT_lx, regnames[rs], btgt);
3828 goto likely;
3829 case OPC_BGTZ:
3830 tcg_gen_setcondi_tl(TCG_COND_GT, bcond, t0, 0);
3831 MIPS_DEBUG("bgtz %s, " TARGET_FMT_lx, regnames[rs], btgt);
3832 goto not_likely;
3833 case OPC_BGTZL:
3834 tcg_gen_setcondi_tl(TCG_COND_GT, bcond, t0, 0);
3835 MIPS_DEBUG("bgtzl %s, " TARGET_FMT_lx, regnames[rs], btgt);
3836 goto likely;
3837 case OPC_BLEZ:
3838 tcg_gen_setcondi_tl(TCG_COND_LE, bcond, t0, 0);
3839 MIPS_DEBUG("blez %s, " TARGET_FMT_lx, regnames[rs], btgt);
3840 goto not_likely;
3841 case OPC_BLEZL:
3842 tcg_gen_setcondi_tl(TCG_COND_LE, bcond, t0, 0);
3843 MIPS_DEBUG("blezl %s, " TARGET_FMT_lx, regnames[rs], btgt);
3844 goto likely;
3845 case OPC_BLTZ:
3846 tcg_gen_setcondi_tl(TCG_COND_LT, bcond, t0, 0);
3847 MIPS_DEBUG("bltz %s, " TARGET_FMT_lx, regnames[rs], btgt);
3848 goto not_likely;
3849 case OPC_BLTZL:
3850 tcg_gen_setcondi_tl(TCG_COND_LT, bcond, t0, 0);
3851 MIPS_DEBUG("bltzl %s, " TARGET_FMT_lx, regnames[rs], btgt);
3852 goto likely;
3853 case OPC_BPOSGE32:
3854 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 32);
3855 MIPS_DEBUG("bposge32 " TARGET_FMT_lx, btgt);
3856 goto not_likely;
3857 #if defined(TARGET_MIPS64)
3858 case OPC_BPOSGE64:
3859 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 64);
3860 MIPS_DEBUG("bposge64 " TARGET_FMT_lx, btgt);
3861 goto not_likely;
3862 #endif
3863 case OPC_BLTZALS:
3864 case OPC_BLTZAL:
3865 ctx->hflags |= (opc == OPC_BLTZALS
3866 ? MIPS_HFLAG_BDS16
3867 : MIPS_HFLAG_BDS32);
3868 tcg_gen_setcondi_tl(TCG_COND_LT, bcond, t0, 0);
3869 blink = 31;
3870 MIPS_DEBUG("bltzal %s, " TARGET_FMT_lx, regnames[rs], btgt);
3871 not_likely:
3872 ctx->hflags |= MIPS_HFLAG_BC;
3873 break;
3874 case OPC_BLTZALL:
3875 tcg_gen_setcondi_tl(TCG_COND_LT, bcond, t0, 0);
3876 blink = 31;
3877 MIPS_DEBUG("bltzall %s, " TARGET_FMT_lx, regnames[rs], btgt);
3878 likely:
3879 ctx->hflags |= MIPS_HFLAG_BL;
3880 break;
3881 default:
3882 MIPS_INVAL("conditional branch/jump");
3883 generate_exception(ctx, EXCP_RI);
3884 goto out;
3887 MIPS_DEBUG("enter ds: link %d cond %02x target " TARGET_FMT_lx,
3888 blink, ctx->hflags, btgt);
3890 ctx->btarget = btgt;
3891 if (blink > 0) {
3892 int post_delay = insn_bytes;
3893 int lowbit = !!(ctx->hflags & MIPS_HFLAG_M16);
3895 if (opc != OPC_JALRC)
3896 post_delay += ((ctx->hflags & MIPS_HFLAG_BDS16) ? 2 : 4);
3898 tcg_gen_movi_tl(cpu_gpr[blink], ctx->pc + post_delay + lowbit);
3901 out:
3902 if (insn_bytes == 2)
3903 ctx->hflags |= MIPS_HFLAG_B16;
3904 tcg_temp_free(t0);
3905 tcg_temp_free(t1);
3908 /* special3 bitfield operations */
3909 static void gen_bitops (DisasContext *ctx, uint32_t opc, int rt,
3910 int rs, int lsb, int msb)
3912 TCGv t0 = tcg_temp_new();
3913 TCGv t1 = tcg_temp_new();
3915 gen_load_gpr(t1, rs);
3916 switch (opc) {
3917 case OPC_EXT:
3918 if (lsb + msb > 31)
3919 goto fail;
3920 tcg_gen_shri_tl(t0, t1, lsb);
3921 if (msb != 31) {
3922 tcg_gen_andi_tl(t0, t0, (1 << (msb + 1)) - 1);
3923 } else {
3924 tcg_gen_ext32s_tl(t0, t0);
3926 break;
3927 #if defined(TARGET_MIPS64)
3928 case OPC_DEXTM:
3929 tcg_gen_shri_tl(t0, t1, lsb);
3930 if (msb != 31) {
3931 tcg_gen_andi_tl(t0, t0, (1ULL << (msb + 1 + 32)) - 1);
3933 break;
3934 case OPC_DEXTU:
3935 tcg_gen_shri_tl(t0, t1, lsb + 32);
3936 tcg_gen_andi_tl(t0, t0, (1ULL << (msb + 1)) - 1);
3937 break;
3938 case OPC_DEXT:
3939 tcg_gen_shri_tl(t0, t1, lsb);
3940 tcg_gen_andi_tl(t0, t0, (1ULL << (msb + 1)) - 1);
3941 break;
3942 #endif
3943 case OPC_INS:
3944 if (lsb > msb)
3945 goto fail;
3946 gen_load_gpr(t0, rt);
3947 tcg_gen_deposit_tl(t0, t0, t1, lsb, msb - lsb + 1);
3948 tcg_gen_ext32s_tl(t0, t0);
3949 break;
3950 #if defined(TARGET_MIPS64)
3951 case OPC_DINSM:
3952 gen_load_gpr(t0, rt);
3953 tcg_gen_deposit_tl(t0, t0, t1, lsb, msb + 32 - lsb + 1);
3954 break;
3955 case OPC_DINSU:
3956 gen_load_gpr(t0, rt);
3957 tcg_gen_deposit_tl(t0, t0, t1, lsb + 32, msb - lsb + 1);
3958 break;
3959 case OPC_DINS:
3960 gen_load_gpr(t0, rt);
3961 tcg_gen_deposit_tl(t0, t0, t1, lsb, msb - lsb + 1);
3962 break;
3963 #endif
3964 default:
3965 fail:
3966 MIPS_INVAL("bitops");
3967 generate_exception(ctx, EXCP_RI);
3968 tcg_temp_free(t0);
3969 tcg_temp_free(t1);
3970 return;
3972 gen_store_gpr(t0, rt);
3973 tcg_temp_free(t0);
3974 tcg_temp_free(t1);
3977 static void gen_bshfl (DisasContext *ctx, uint32_t op2, int rt, int rd)
3979 TCGv t0;
3981 if (rd == 0) {
3982 /* If no destination, treat it as a NOP. */
3983 MIPS_DEBUG("NOP");
3984 return;
3987 t0 = tcg_temp_new();
3988 gen_load_gpr(t0, rt);
3989 switch (op2) {
3990 case OPC_WSBH:
3992 TCGv t1 = tcg_temp_new();
3994 tcg_gen_shri_tl(t1, t0, 8);
3995 tcg_gen_andi_tl(t1, t1, 0x00FF00FF);
3996 tcg_gen_shli_tl(t0, t0, 8);
3997 tcg_gen_andi_tl(t0, t0, ~0x00FF00FF);
3998 tcg_gen_or_tl(t0, t0, t1);
3999 tcg_temp_free(t1);
4000 tcg_gen_ext32s_tl(cpu_gpr[rd], t0);
4002 break;
4003 case OPC_SEB:
4004 tcg_gen_ext8s_tl(cpu_gpr[rd], t0);
4005 break;
4006 case OPC_SEH:
4007 tcg_gen_ext16s_tl(cpu_gpr[rd], t0);
4008 break;
4009 #if defined(TARGET_MIPS64)
4010 case OPC_DSBH:
4012 TCGv t1 = tcg_temp_new();
4014 tcg_gen_shri_tl(t1, t0, 8);
4015 tcg_gen_andi_tl(t1, t1, 0x00FF00FF00FF00FFULL);
4016 tcg_gen_shli_tl(t0, t0, 8);
4017 tcg_gen_andi_tl(t0, t0, ~0x00FF00FF00FF00FFULL);
4018 tcg_gen_or_tl(cpu_gpr[rd], t0, t1);
4019 tcg_temp_free(t1);
4021 break;
4022 case OPC_DSHD:
4024 TCGv t1 = tcg_temp_new();
4026 tcg_gen_shri_tl(t1, t0, 16);
4027 tcg_gen_andi_tl(t1, t1, 0x0000FFFF0000FFFFULL);
4028 tcg_gen_shli_tl(t0, t0, 16);
4029 tcg_gen_andi_tl(t0, t0, ~0x0000FFFF0000FFFFULL);
4030 tcg_gen_or_tl(t0, t0, t1);
4031 tcg_gen_shri_tl(t1, t0, 32);
4032 tcg_gen_shli_tl(t0, t0, 32);
4033 tcg_gen_or_tl(cpu_gpr[rd], t0, t1);
4034 tcg_temp_free(t1);
4036 break;
4037 #endif
4038 default:
4039 MIPS_INVAL("bsfhl");
4040 generate_exception(ctx, EXCP_RI);
4041 tcg_temp_free(t0);
4042 return;
4044 tcg_temp_free(t0);
4047 #ifndef CONFIG_USER_ONLY
4048 /* CP0 (MMU and control) */
4049 static inline void gen_mfc0_load32 (TCGv arg, target_ulong off)
4051 TCGv_i32 t0 = tcg_temp_new_i32();
4053 tcg_gen_ld_i32(t0, cpu_env, off);
4054 tcg_gen_ext_i32_tl(arg, t0);
4055 tcg_temp_free_i32(t0);
4058 static inline void gen_mfc0_load64 (TCGv arg, target_ulong off)
4060 tcg_gen_ld_tl(arg, cpu_env, off);
4061 tcg_gen_ext32s_tl(arg, arg);
4064 static inline void gen_mtc0_store32 (TCGv arg, target_ulong off)
4066 TCGv_i32 t0 = tcg_temp_new_i32();
4068 tcg_gen_trunc_tl_i32(t0, arg);
4069 tcg_gen_st_i32(t0, cpu_env, off);
4070 tcg_temp_free_i32(t0);
4073 static inline void gen_mtc0_store64 (TCGv arg, target_ulong off)
4075 tcg_gen_ext32s_tl(arg, arg);
4076 tcg_gen_st_tl(arg, cpu_env, off);
4079 static void gen_mfc0(DisasContext *ctx, TCGv arg, int reg, int sel)
4081 const char *rn = "invalid";
4083 if (sel != 0)
4084 check_insn(ctx, ISA_MIPS32);
4086 switch (reg) {
4087 case 0:
4088 switch (sel) {
4089 case 0:
4090 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Index));
4091 rn = "Index";
4092 break;
4093 case 1:
4094 check_insn(ctx, ASE_MT);
4095 gen_helper_mfc0_mvpcontrol(arg, cpu_env);
4096 rn = "MVPControl";
4097 break;
4098 case 2:
4099 check_insn(ctx, ASE_MT);
4100 gen_helper_mfc0_mvpconf0(arg, cpu_env);
4101 rn = "MVPConf0";
4102 break;
4103 case 3:
4104 check_insn(ctx, ASE_MT);
4105 gen_helper_mfc0_mvpconf1(arg, cpu_env);
4106 rn = "MVPConf1";
4107 break;
4108 default:
4109 goto die;
4111 break;
4112 case 1:
4113 switch (sel) {
4114 case 0:
4115 gen_helper_mfc0_random(arg, cpu_env);
4116 rn = "Random";
4117 break;
4118 case 1:
4119 check_insn(ctx, ASE_MT);
4120 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEControl));
4121 rn = "VPEControl";
4122 break;
4123 case 2:
4124 check_insn(ctx, ASE_MT);
4125 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEConf0));
4126 rn = "VPEConf0";
4127 break;
4128 case 3:
4129 check_insn(ctx, ASE_MT);
4130 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEConf1));
4131 rn = "VPEConf1";
4132 break;
4133 case 4:
4134 check_insn(ctx, ASE_MT);
4135 gen_mfc0_load64(arg, offsetof(CPUMIPSState, CP0_YQMask));
4136 rn = "YQMask";
4137 break;
4138 case 5:
4139 check_insn(ctx, ASE_MT);
4140 gen_mfc0_load64(arg, offsetof(CPUMIPSState, CP0_VPESchedule));
4141 rn = "VPESchedule";
4142 break;
4143 case 6:
4144 check_insn(ctx, ASE_MT);
4145 gen_mfc0_load64(arg, offsetof(CPUMIPSState, CP0_VPEScheFBack));
4146 rn = "VPEScheFBack";
4147 break;
4148 case 7:
4149 check_insn(ctx, ASE_MT);
4150 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEOpt));
4151 rn = "VPEOpt";
4152 break;
4153 default:
4154 goto die;
4156 break;
4157 case 2:
4158 switch (sel) {
4159 case 0:
4160 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EntryLo0));
4161 tcg_gen_ext32s_tl(arg, arg);
4162 rn = "EntryLo0";
4163 break;
4164 case 1:
4165 check_insn(ctx, ASE_MT);
4166 gen_helper_mfc0_tcstatus(arg, cpu_env);
4167 rn = "TCStatus";
4168 break;
4169 case 2:
4170 check_insn(ctx, ASE_MT);
4171 gen_helper_mfc0_tcbind(arg, cpu_env);
4172 rn = "TCBind";
4173 break;
4174 case 3:
4175 check_insn(ctx, ASE_MT);
4176 gen_helper_mfc0_tcrestart(arg, cpu_env);
4177 rn = "TCRestart";
4178 break;
4179 case 4:
4180 check_insn(ctx, ASE_MT);
4181 gen_helper_mfc0_tchalt(arg, cpu_env);
4182 rn = "TCHalt";
4183 break;
4184 case 5:
4185 check_insn(ctx, ASE_MT);
4186 gen_helper_mfc0_tccontext(arg, cpu_env);
4187 rn = "TCContext";
4188 break;
4189 case 6:
4190 check_insn(ctx, ASE_MT);
4191 gen_helper_mfc0_tcschedule(arg, cpu_env);
4192 rn = "TCSchedule";
4193 break;
4194 case 7:
4195 check_insn(ctx, ASE_MT);
4196 gen_helper_mfc0_tcschefback(arg, cpu_env);
4197 rn = "TCScheFBack";
4198 break;
4199 default:
4200 goto die;
4202 break;
4203 case 3:
4204 switch (sel) {
4205 case 0:
4206 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EntryLo1));
4207 tcg_gen_ext32s_tl(arg, arg);
4208 rn = "EntryLo1";
4209 break;
4210 default:
4211 goto die;
4213 break;
4214 case 4:
4215 switch (sel) {
4216 case 0:
4217 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_Context));
4218 tcg_gen_ext32s_tl(arg, arg);
4219 rn = "Context";
4220 break;
4221 case 1:
4222 // gen_helper_mfc0_contextconfig(arg); /* SmartMIPS ASE */
4223 rn = "ContextConfig";
4224 goto die;
4225 // break;
4226 case 2:
4227 if (ctx->ulri) {
4228 tcg_gen_ld32s_tl(arg, cpu_env,
4229 offsetof(CPUMIPSState,
4230 active_tc.CP0_UserLocal));
4231 rn = "UserLocal";
4232 } else {
4233 tcg_gen_movi_tl(arg, 0);
4235 break;
4236 default:
4237 goto die;
4239 break;
4240 case 5:
4241 switch (sel) {
4242 case 0:
4243 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PageMask));
4244 rn = "PageMask";
4245 break;
4246 case 1:
4247 check_insn(ctx, ISA_MIPS32R2);
4248 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PageGrain));
4249 rn = "PageGrain";
4250 break;
4251 default:
4252 goto die;
4254 break;
4255 case 6:
4256 switch (sel) {
4257 case 0:
4258 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Wired));
4259 rn = "Wired";
4260 break;
4261 case 1:
4262 check_insn(ctx, ISA_MIPS32R2);
4263 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf0));
4264 rn = "SRSConf0";
4265 break;
4266 case 2:
4267 check_insn(ctx, ISA_MIPS32R2);
4268 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf1));
4269 rn = "SRSConf1";
4270 break;
4271 case 3:
4272 check_insn(ctx, ISA_MIPS32R2);
4273 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf2));
4274 rn = "SRSConf2";
4275 break;
4276 case 4:
4277 check_insn(ctx, ISA_MIPS32R2);
4278 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf3));
4279 rn = "SRSConf3";
4280 break;
4281 case 5:
4282 check_insn(ctx, ISA_MIPS32R2);
4283 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf4));
4284 rn = "SRSConf4";
4285 break;
4286 default:
4287 goto die;
4289 break;
4290 case 7:
4291 switch (sel) {
4292 case 0:
4293 check_insn(ctx, ISA_MIPS32R2);
4294 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_HWREna));
4295 rn = "HWREna";
4296 break;
4297 default:
4298 goto die;
4300 break;
4301 case 8:
4302 switch (sel) {
4303 case 0:
4304 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_BadVAddr));
4305 tcg_gen_ext32s_tl(arg, arg);
4306 rn = "BadVAddr";
4307 break;
4308 default:
4309 goto die;
4311 break;
4312 case 9:
4313 switch (sel) {
4314 case 0:
4315 /* Mark as an IO operation because we read the time. */
4316 if (use_icount)
4317 gen_io_start();
4318 gen_helper_mfc0_count(arg, cpu_env);
4319 if (use_icount) {
4320 gen_io_end();
4322 /* Break the TB to be able to take timer interrupts immediately
4323 after reading count. */
4324 ctx->bstate = BS_STOP;
4325 rn = "Count";
4326 break;
4327 /* 6,7 are implementation dependent */
4328 default:
4329 goto die;
4331 break;
4332 case 10:
4333 switch (sel) {
4334 case 0:
4335 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EntryHi));
4336 tcg_gen_ext32s_tl(arg, arg);
4337 rn = "EntryHi";
4338 break;
4339 default:
4340 goto die;
4342 break;
4343 case 11:
4344 switch (sel) {
4345 case 0:
4346 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Compare));
4347 rn = "Compare";
4348 break;
4349 /* 6,7 are implementation dependent */
4350 default:
4351 goto die;
4353 break;
4354 case 12:
4355 switch (sel) {
4356 case 0:
4357 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Status));
4358 rn = "Status";
4359 break;
4360 case 1:
4361 check_insn(ctx, ISA_MIPS32R2);
4362 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_IntCtl));
4363 rn = "IntCtl";
4364 break;
4365 case 2:
4366 check_insn(ctx, ISA_MIPS32R2);
4367 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSCtl));
4368 rn = "SRSCtl";
4369 break;
4370 case 3:
4371 check_insn(ctx, ISA_MIPS32R2);
4372 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSMap));
4373 rn = "SRSMap";
4374 break;
4375 default:
4376 goto die;
4378 break;
4379 case 13:
4380 switch (sel) {
4381 case 0:
4382 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Cause));
4383 rn = "Cause";
4384 break;
4385 default:
4386 goto die;
4388 break;
4389 case 14:
4390 switch (sel) {
4391 case 0:
4392 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EPC));
4393 tcg_gen_ext32s_tl(arg, arg);
4394 rn = "EPC";
4395 break;
4396 default:
4397 goto die;
4399 break;
4400 case 15:
4401 switch (sel) {
4402 case 0:
4403 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PRid));
4404 rn = "PRid";
4405 break;
4406 case 1:
4407 check_insn(ctx, ISA_MIPS32R2);
4408 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_EBase));
4409 rn = "EBase";
4410 break;
4411 default:
4412 goto die;
4414 break;
4415 case 16:
4416 switch (sel) {
4417 case 0:
4418 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config0));
4419 rn = "Config";
4420 break;
4421 case 1:
4422 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config1));
4423 rn = "Config1";
4424 break;
4425 case 2:
4426 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config2));
4427 rn = "Config2";
4428 break;
4429 case 3:
4430 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config3));
4431 rn = "Config3";
4432 break;
4433 case 4:
4434 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config4));
4435 rn = "Config4";
4436 break;
4437 case 5:
4438 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config5));
4439 rn = "Config5";
4440 break;
4441 /* 6,7 are implementation dependent */
4442 case 6:
4443 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config6));
4444 rn = "Config6";
4445 break;
4446 case 7:
4447 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config7));
4448 rn = "Config7";
4449 break;
4450 default:
4451 goto die;
4453 break;
4454 case 17:
4455 switch (sel) {
4456 case 0:
4457 gen_helper_mfc0_lladdr(arg, cpu_env);
4458 rn = "LLAddr";
4459 break;
4460 default:
4461 goto die;
4463 break;
4464 case 18:
4465 switch (sel) {
4466 case 0 ... 7:
4467 gen_helper_1e0i(mfc0_watchlo, arg, sel);
4468 rn = "WatchLo";
4469 break;
4470 default:
4471 goto die;
4473 break;
4474 case 19:
4475 switch (sel) {
4476 case 0 ...7:
4477 gen_helper_1e0i(mfc0_watchhi, arg, sel);
4478 rn = "WatchHi";
4479 break;
4480 default:
4481 goto die;
4483 break;
4484 case 20:
4485 switch (sel) {
4486 case 0:
4487 #if defined(TARGET_MIPS64)
4488 check_insn(ctx, ISA_MIPS3);
4489 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_XContext));
4490 tcg_gen_ext32s_tl(arg, arg);
4491 rn = "XContext";
4492 break;
4493 #endif
4494 default:
4495 goto die;
4497 break;
4498 case 21:
4499 /* Officially reserved, but sel 0 is used for R1x000 framemask */
4500 switch (sel) {
4501 case 0:
4502 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Framemask));
4503 rn = "Framemask";
4504 break;
4505 default:
4506 goto die;
4508 break;
4509 case 22:
4510 tcg_gen_movi_tl(arg, 0); /* unimplemented */
4511 rn = "'Diagnostic"; /* implementation dependent */
4512 break;
4513 case 23:
4514 switch (sel) {
4515 case 0:
4516 gen_helper_mfc0_debug(arg, cpu_env); /* EJTAG support */
4517 rn = "Debug";
4518 break;
4519 case 1:
4520 // gen_helper_mfc0_tracecontrol(arg); /* PDtrace support */
4521 rn = "TraceControl";
4522 // break;
4523 case 2:
4524 // gen_helper_mfc0_tracecontrol2(arg); /* PDtrace support */
4525 rn = "TraceControl2";
4526 // break;
4527 case 3:
4528 // gen_helper_mfc0_usertracedata(arg); /* PDtrace support */
4529 rn = "UserTraceData";
4530 // break;
4531 case 4:
4532 // gen_helper_mfc0_tracebpc(arg); /* PDtrace support */
4533 rn = "TraceBPC";
4534 // break;
4535 default:
4536 goto die;
4538 break;
4539 case 24:
4540 switch (sel) {
4541 case 0:
4542 /* EJTAG support */
4543 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_DEPC));
4544 tcg_gen_ext32s_tl(arg, arg);
4545 rn = "DEPC";
4546 break;
4547 default:
4548 goto die;
4550 break;
4551 case 25:
4552 switch (sel) {
4553 case 0:
4554 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Performance0));
4555 rn = "Performance0";
4556 break;
4557 case 1:
4558 // gen_helper_mfc0_performance1(arg);
4559 rn = "Performance1";
4560 // break;
4561 case 2:
4562 // gen_helper_mfc0_performance2(arg);
4563 rn = "Performance2";
4564 // break;
4565 case 3:
4566 // gen_helper_mfc0_performance3(arg);
4567 rn = "Performance3";
4568 // break;
4569 case 4:
4570 // gen_helper_mfc0_performance4(arg);
4571 rn = "Performance4";
4572 // break;
4573 case 5:
4574 // gen_helper_mfc0_performance5(arg);
4575 rn = "Performance5";
4576 // break;
4577 case 6:
4578 // gen_helper_mfc0_performance6(arg);
4579 rn = "Performance6";
4580 // break;
4581 case 7:
4582 // gen_helper_mfc0_performance7(arg);
4583 rn = "Performance7";
4584 // break;
4585 default:
4586 goto die;
4588 break;
4589 case 26:
4590 tcg_gen_movi_tl(arg, 0); /* unimplemented */
4591 rn = "ECC";
4592 break;
4593 case 27:
4594 switch (sel) {
4595 case 0 ... 3:
4596 tcg_gen_movi_tl(arg, 0); /* unimplemented */
4597 rn = "CacheErr";
4598 break;
4599 default:
4600 goto die;
4602 break;
4603 case 28:
4604 switch (sel) {
4605 case 0:
4606 case 2:
4607 case 4:
4608 case 6:
4609 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_TagLo));
4610 rn = "TagLo";
4611 break;
4612 case 1:
4613 case 3:
4614 case 5:
4615 case 7:
4616 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DataLo));
4617 rn = "DataLo";
4618 break;
4619 default:
4620 goto die;
4622 break;
4623 case 29:
4624 switch (sel) {
4625 case 0:
4626 case 2:
4627 case 4:
4628 case 6:
4629 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_TagHi));
4630 rn = "TagHi";
4631 break;
4632 case 1:
4633 case 3:
4634 case 5:
4635 case 7:
4636 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DataHi));
4637 rn = "DataHi";
4638 break;
4639 default:
4640 goto die;
4642 break;
4643 case 30:
4644 switch (sel) {
4645 case 0:
4646 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_ErrorEPC));
4647 tcg_gen_ext32s_tl(arg, arg);
4648 rn = "ErrorEPC";
4649 break;
4650 default:
4651 goto die;
4653 break;
4654 case 31:
4655 switch (sel) {
4656 case 0:
4657 /* EJTAG support */
4658 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DESAVE));
4659 rn = "DESAVE";
4660 break;
4661 default:
4662 goto die;
4664 break;
4665 default:
4666 goto die;
4668 (void)rn; /* avoid a compiler warning */
4669 LOG_DISAS("mfc0 %s (reg %d sel %d)\n", rn, reg, sel);
4670 return;
4672 die:
4673 LOG_DISAS("mfc0 %s (reg %d sel %d)\n", rn, reg, sel);
4674 generate_exception(ctx, EXCP_RI);
4677 static void gen_mtc0(DisasContext *ctx, TCGv arg, int reg, int sel)
4679 const char *rn = "invalid";
4681 if (sel != 0)
4682 check_insn(ctx, ISA_MIPS32);
4684 if (use_icount)
4685 gen_io_start();
4687 switch (reg) {
4688 case 0:
4689 switch (sel) {
4690 case 0:
4691 gen_helper_mtc0_index(cpu_env, arg);
4692 rn = "Index";
4693 break;
4694 case 1:
4695 check_insn(ctx, ASE_MT);
4696 gen_helper_mtc0_mvpcontrol(cpu_env, arg);
4697 rn = "MVPControl";
4698 break;
4699 case 2:
4700 check_insn(ctx, ASE_MT);
4701 /* ignored */
4702 rn = "MVPConf0";
4703 break;
4704 case 3:
4705 check_insn(ctx, ASE_MT);
4706 /* ignored */
4707 rn = "MVPConf1";
4708 break;
4709 default:
4710 goto die;
4712 break;
4713 case 1:
4714 switch (sel) {
4715 case 0:
4716 /* ignored */
4717 rn = "Random";
4718 break;
4719 case 1:
4720 check_insn(ctx, ASE_MT);
4721 gen_helper_mtc0_vpecontrol(cpu_env, arg);
4722 rn = "VPEControl";
4723 break;
4724 case 2:
4725 check_insn(ctx, ASE_MT);
4726 gen_helper_mtc0_vpeconf0(cpu_env, arg);
4727 rn = "VPEConf0";
4728 break;
4729 case 3:
4730 check_insn(ctx, ASE_MT);
4731 gen_helper_mtc0_vpeconf1(cpu_env, arg);
4732 rn = "VPEConf1";
4733 break;
4734 case 4:
4735 check_insn(ctx, ASE_MT);
4736 gen_helper_mtc0_yqmask(cpu_env, arg);
4737 rn = "YQMask";
4738 break;
4739 case 5:
4740 check_insn(ctx, ASE_MT);
4741 gen_mtc0_store64(arg, offsetof(CPUMIPSState, CP0_VPESchedule));
4742 rn = "VPESchedule";
4743 break;
4744 case 6:
4745 check_insn(ctx, ASE_MT);
4746 gen_mtc0_store64(arg, offsetof(CPUMIPSState, CP0_VPEScheFBack));
4747 rn = "VPEScheFBack";
4748 break;
4749 case 7:
4750 check_insn(ctx, ASE_MT);
4751 gen_helper_mtc0_vpeopt(cpu_env, arg);
4752 rn = "VPEOpt";
4753 break;
4754 default:
4755 goto die;
4757 break;
4758 case 2:
4759 switch (sel) {
4760 case 0:
4761 gen_helper_mtc0_entrylo0(cpu_env, arg);
4762 rn = "EntryLo0";
4763 break;
4764 case 1:
4765 check_insn(ctx, ASE_MT);
4766 gen_helper_mtc0_tcstatus(cpu_env, arg);
4767 rn = "TCStatus";
4768 break;
4769 case 2:
4770 check_insn(ctx, ASE_MT);
4771 gen_helper_mtc0_tcbind(cpu_env, arg);
4772 rn = "TCBind";
4773 break;
4774 case 3:
4775 check_insn(ctx, ASE_MT);
4776 gen_helper_mtc0_tcrestart(cpu_env, arg);
4777 rn = "TCRestart";
4778 break;
4779 case 4:
4780 check_insn(ctx, ASE_MT);
4781 gen_helper_mtc0_tchalt(cpu_env, arg);
4782 rn = "TCHalt";
4783 break;
4784 case 5:
4785 check_insn(ctx, ASE_MT);
4786 gen_helper_mtc0_tccontext(cpu_env, arg);
4787 rn = "TCContext";
4788 break;
4789 case 6:
4790 check_insn(ctx, ASE_MT);
4791 gen_helper_mtc0_tcschedule(cpu_env, arg);
4792 rn = "TCSchedule";
4793 break;
4794 case 7:
4795 check_insn(ctx, ASE_MT);
4796 gen_helper_mtc0_tcschefback(cpu_env, arg);
4797 rn = "TCScheFBack";
4798 break;
4799 default:
4800 goto die;
4802 break;
4803 case 3:
4804 switch (sel) {
4805 case 0:
4806 gen_helper_mtc0_entrylo1(cpu_env, arg);
4807 rn = "EntryLo1";
4808 break;
4809 default:
4810 goto die;
4812 break;
4813 case 4:
4814 switch (sel) {
4815 case 0:
4816 gen_helper_mtc0_context(cpu_env, arg);
4817 rn = "Context";
4818 break;
4819 case 1:
4820 // gen_helper_mtc0_contextconfig(cpu_env, arg); /* SmartMIPS ASE */
4821 rn = "ContextConfig";
4822 goto die;
4823 // break;
4824 case 2:
4825 if (ctx->ulri) {
4826 tcg_gen_st_tl(arg, cpu_env,
4827 offsetof(CPUMIPSState, active_tc.CP0_UserLocal));
4828 rn = "UserLocal";
4830 break;
4831 default:
4832 goto die;
4834 break;
4835 case 5:
4836 switch (sel) {
4837 case 0:
4838 gen_helper_mtc0_pagemask(cpu_env, arg);
4839 rn = "PageMask";
4840 break;
4841 case 1:
4842 check_insn(ctx, ISA_MIPS32R2);
4843 gen_helper_mtc0_pagegrain(cpu_env, arg);
4844 rn = "PageGrain";
4845 break;
4846 default:
4847 goto die;
4849 break;
4850 case 6:
4851 switch (sel) {
4852 case 0:
4853 gen_helper_mtc0_wired(cpu_env, arg);
4854 rn = "Wired";
4855 break;
4856 case 1:
4857 check_insn(ctx, ISA_MIPS32R2);
4858 gen_helper_mtc0_srsconf0(cpu_env, arg);
4859 rn = "SRSConf0";
4860 break;
4861 case 2:
4862 check_insn(ctx, ISA_MIPS32R2);
4863 gen_helper_mtc0_srsconf1(cpu_env, arg);
4864 rn = "SRSConf1";
4865 break;
4866 case 3:
4867 check_insn(ctx, ISA_MIPS32R2);
4868 gen_helper_mtc0_srsconf2(cpu_env, arg);
4869 rn = "SRSConf2";
4870 break;
4871 case 4:
4872 check_insn(ctx, ISA_MIPS32R2);
4873 gen_helper_mtc0_srsconf3(cpu_env, arg);
4874 rn = "SRSConf3";
4875 break;
4876 case 5:
4877 check_insn(ctx, ISA_MIPS32R2);
4878 gen_helper_mtc0_srsconf4(cpu_env, arg);
4879 rn = "SRSConf4";
4880 break;
4881 default:
4882 goto die;
4884 break;
4885 case 7:
4886 switch (sel) {
4887 case 0:
4888 check_insn(ctx, ISA_MIPS32R2);
4889 gen_helper_mtc0_hwrena(cpu_env, arg);
4890 ctx->bstate = BS_STOP;
4891 rn = "HWREna";
4892 break;
4893 default:
4894 goto die;
4896 break;
4897 case 8:
4898 /* ignored */
4899 rn = "BadVAddr";
4900 break;
4901 case 9:
4902 switch (sel) {
4903 case 0:
4904 gen_helper_mtc0_count(cpu_env, arg);
4905 rn = "Count";
4906 break;
4907 /* 6,7 are implementation dependent */
4908 default:
4909 goto die;
4911 break;
4912 case 10:
4913 switch (sel) {
4914 case 0:
4915 gen_helper_mtc0_entryhi(cpu_env, arg);
4916 rn = "EntryHi";
4917 break;
4918 default:
4919 goto die;
4921 break;
4922 case 11:
4923 switch (sel) {
4924 case 0:
4925 gen_helper_mtc0_compare(cpu_env, arg);
4926 rn = "Compare";
4927 break;
4928 /* 6,7 are implementation dependent */
4929 default:
4930 goto die;
4932 break;
4933 case 12:
4934 switch (sel) {
4935 case 0:
4936 save_cpu_state(ctx, 1);
4937 gen_helper_mtc0_status(cpu_env, arg);
4938 /* BS_STOP isn't good enough here, hflags may have changed. */
4939 gen_save_pc(ctx->pc + 4);
4940 ctx->bstate = BS_EXCP;
4941 rn = "Status";
4942 break;
4943 case 1:
4944 check_insn(ctx, ISA_MIPS32R2);
4945 gen_helper_mtc0_intctl(cpu_env, arg);
4946 /* Stop translation as we may have switched the execution mode */
4947 ctx->bstate = BS_STOP;
4948 rn = "IntCtl";
4949 break;
4950 case 2:
4951 check_insn(ctx, ISA_MIPS32R2);
4952 gen_helper_mtc0_srsctl(cpu_env, arg);
4953 /* Stop translation as we may have switched the execution mode */
4954 ctx->bstate = BS_STOP;
4955 rn = "SRSCtl";
4956 break;
4957 case 3:
4958 check_insn(ctx, ISA_MIPS32R2);
4959 gen_mtc0_store32(arg, offsetof(CPUMIPSState, CP0_SRSMap));
4960 /* Stop translation as we may have switched the execution mode */
4961 ctx->bstate = BS_STOP;
4962 rn = "SRSMap";
4963 break;
4964 default:
4965 goto die;
4967 break;
4968 case 13:
4969 switch (sel) {
4970 case 0:
4971 save_cpu_state(ctx, 1);
4972 gen_helper_mtc0_cause(cpu_env, arg);
4973 rn = "Cause";
4974 break;
4975 default:
4976 goto die;
4978 break;
4979 case 14:
4980 switch (sel) {
4981 case 0:
4982 gen_mtc0_store64(arg, offsetof(CPUMIPSState, CP0_EPC));
4983 rn = "EPC";
4984 break;
4985 default:
4986 goto die;
4988 break;
4989 case 15:
4990 switch (sel) {
4991 case 0:
4992 /* ignored */
4993 rn = "PRid";
4994 break;
4995 case 1:
4996 check_insn(ctx, ISA_MIPS32R2);
4997 gen_helper_mtc0_ebase(cpu_env, arg);
4998 rn = "EBase";
4999 break;
5000 default:
5001 goto die;
5003 break;
5004 case 16:
5005 switch (sel) {
5006 case 0:
5007 gen_helper_mtc0_config0(cpu_env, arg);
5008 rn = "Config";
5009 /* Stop translation as we may have switched the execution mode */
5010 ctx->bstate = BS_STOP;
5011 break;
5012 case 1:
5013 /* ignored, read only */
5014 rn = "Config1";
5015 break;
5016 case 2:
5017 gen_helper_mtc0_config2(cpu_env, arg);
5018 rn = "Config2";
5019 /* Stop translation as we may have switched the execution mode */
5020 ctx->bstate = BS_STOP;
5021 break;
5022 case 3:
5023 /* ignored, read only */
5024 rn = "Config3";
5025 break;
5026 case 4:
5027 gen_helper_mtc0_config4(cpu_env, arg);
5028 rn = "Config4";
5029 ctx->bstate = BS_STOP;
5030 break;
5031 case 5:
5032 gen_helper_mtc0_config5(cpu_env, arg);
5033 rn = "Config5";
5034 /* Stop translation as we may have switched the execution mode */
5035 ctx->bstate = BS_STOP;
5036 break;
5037 /* 6,7 are implementation dependent */
5038 case 6:
5039 /* ignored */
5040 rn = "Config6";
5041 break;
5042 case 7:
5043 /* ignored */
5044 rn = "Config7";
5045 break;
5046 default:
5047 rn = "Invalid config selector";
5048 goto die;
5050 break;
5051 case 17:
5052 switch (sel) {
5053 case 0:
5054 gen_helper_mtc0_lladdr(cpu_env, arg);
5055 rn = "LLAddr";
5056 break;
5057 default:
5058 goto die;
5060 break;
5061 case 18:
5062 switch (sel) {
5063 case 0 ... 7:
5064 gen_helper_0e1i(mtc0_watchlo, arg, sel);
5065 rn = "WatchLo";
5066 break;
5067 default:
5068 goto die;
5070 break;
5071 case 19:
5072 switch (sel) {
5073 case 0 ... 7:
5074 gen_helper_0e1i(mtc0_watchhi, arg, sel);
5075 rn = "WatchHi";
5076 break;
5077 default:
5078 goto die;
5080 break;
5081 case 20:
5082 switch (sel) {
5083 case 0:
5084 #if defined(TARGET_MIPS64)
5085 check_insn(ctx, ISA_MIPS3);
5086 gen_helper_mtc0_xcontext(cpu_env, arg);
5087 rn = "XContext";
5088 break;
5089 #endif
5090 default:
5091 goto die;
5093 break;
5094 case 21:
5095 /* Officially reserved, but sel 0 is used for R1x000 framemask */
5096 switch (sel) {
5097 case 0:
5098 gen_helper_mtc0_framemask(cpu_env, arg);
5099 rn = "Framemask";
5100 break;
5101 default:
5102 goto die;
5104 break;
5105 case 22:
5106 /* ignored */
5107 rn = "Diagnostic"; /* implementation dependent */
5108 break;
5109 case 23:
5110 switch (sel) {
5111 case 0:
5112 gen_helper_mtc0_debug(cpu_env, arg); /* EJTAG support */
5113 /* BS_STOP isn't good enough here, hflags may have changed. */
5114 gen_save_pc(ctx->pc + 4);
5115 ctx->bstate = BS_EXCP;
5116 rn = "Debug";
5117 break;
5118 case 1:
5119 // gen_helper_mtc0_tracecontrol(cpu_env, arg); /* PDtrace support */
5120 rn = "TraceControl";
5121 /* Stop translation as we may have switched the execution mode */
5122 ctx->bstate = BS_STOP;
5123 // break;
5124 case 2:
5125 // gen_helper_mtc0_tracecontrol2(cpu_env, arg); /* PDtrace support */
5126 rn = "TraceControl2";
5127 /* Stop translation as we may have switched the execution mode */
5128 ctx->bstate = BS_STOP;
5129 // break;
5130 case 3:
5131 /* Stop translation as we may have switched the execution mode */
5132 ctx->bstate = BS_STOP;
5133 // gen_helper_mtc0_usertracedata(cpu_env, arg); /* PDtrace support */
5134 rn = "UserTraceData";
5135 /* Stop translation as we may have switched the execution mode */
5136 ctx->bstate = BS_STOP;
5137 // break;
5138 case 4:
5139 // gen_helper_mtc0_tracebpc(cpu_env, arg); /* PDtrace support */
5140 /* Stop translation as we may have switched the execution mode */
5141 ctx->bstate = BS_STOP;
5142 rn = "TraceBPC";
5143 // break;
5144 default:
5145 goto die;
5147 break;
5148 case 24:
5149 switch (sel) {
5150 case 0:
5151 /* EJTAG support */
5152 gen_mtc0_store64(arg, offsetof(CPUMIPSState, CP0_DEPC));
5153 rn = "DEPC";
5154 break;
5155 default:
5156 goto die;
5158 break;
5159 case 25:
5160 switch (sel) {
5161 case 0:
5162 gen_helper_mtc0_performance0(cpu_env, arg);
5163 rn = "Performance0";
5164 break;
5165 case 1:
5166 // gen_helper_mtc0_performance1(arg);
5167 rn = "Performance1";
5168 // break;
5169 case 2:
5170 // gen_helper_mtc0_performance2(arg);
5171 rn = "Performance2";
5172 // break;
5173 case 3:
5174 // gen_helper_mtc0_performance3(arg);
5175 rn = "Performance3";
5176 // break;
5177 case 4:
5178 // gen_helper_mtc0_performance4(arg);
5179 rn = "Performance4";
5180 // break;
5181 case 5:
5182 // gen_helper_mtc0_performance5(arg);
5183 rn = "Performance5";
5184 // break;
5185 case 6:
5186 // gen_helper_mtc0_performance6(arg);
5187 rn = "Performance6";
5188 // break;
5189 case 7:
5190 // gen_helper_mtc0_performance7(arg);
5191 rn = "Performance7";
5192 // break;
5193 default:
5194 goto die;
5196 break;
5197 case 26:
5198 /* ignored */
5199 rn = "ECC";
5200 break;
5201 case 27:
5202 switch (sel) {
5203 case 0 ... 3:
5204 /* ignored */
5205 rn = "CacheErr";
5206 break;
5207 default:
5208 goto die;
5210 break;
5211 case 28:
5212 switch (sel) {
5213 case 0:
5214 case 2:
5215 case 4:
5216 case 6:
5217 gen_helper_mtc0_taglo(cpu_env, arg);
5218 rn = "TagLo";
5219 break;
5220 case 1:
5221 case 3:
5222 case 5:
5223 case 7:
5224 gen_helper_mtc0_datalo(cpu_env, arg);
5225 rn = "DataLo";
5226 break;
5227 default:
5228 goto die;
5230 break;
5231 case 29:
5232 switch (sel) {
5233 case 0:
5234 case 2:
5235 case 4:
5236 case 6:
5237 gen_helper_mtc0_taghi(cpu_env, arg);
5238 rn = "TagHi";
5239 break;
5240 case 1:
5241 case 3:
5242 case 5:
5243 case 7:
5244 gen_helper_mtc0_datahi(cpu_env, arg);
5245 rn = "DataHi";
5246 break;
5247 default:
5248 rn = "invalid sel";
5249 goto die;
5251 break;
5252 case 30:
5253 switch (sel) {
5254 case 0:
5255 gen_mtc0_store64(arg, offsetof(CPUMIPSState, CP0_ErrorEPC));
5256 rn = "ErrorEPC";
5257 break;
5258 default:
5259 goto die;
5261 break;
5262 case 31:
5263 switch (sel) {
5264 case 0:
5265 /* EJTAG support */
5266 gen_mtc0_store32(arg, offsetof(CPUMIPSState, CP0_DESAVE));
5267 rn = "DESAVE";
5268 break;
5269 default:
5270 goto die;
5272 /* Stop translation as we may have switched the execution mode */
5273 ctx->bstate = BS_STOP;
5274 break;
5275 default:
5276 goto die;
5278 (void)rn; /* avoid a compiler warning */
5279 LOG_DISAS("mtc0 %s (reg %d sel %d)\n", rn, reg, sel);
5280 /* For simplicity assume that all writes can cause interrupts. */
5281 if (use_icount) {
5282 gen_io_end();
5283 ctx->bstate = BS_STOP;
5285 return;
5287 die:
5288 LOG_DISAS("mtc0 %s (reg %d sel %d)\n", rn, reg, sel);
5289 generate_exception(ctx, EXCP_RI);
5292 #if defined(TARGET_MIPS64)
5293 static void gen_dmfc0(DisasContext *ctx, TCGv arg, int reg, int sel)
5295 const char *rn = "invalid";
5297 if (sel != 0)
5298 check_insn(ctx, ISA_MIPS64);
5300 switch (reg) {
5301 case 0:
5302 switch (sel) {
5303 case 0:
5304 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Index));
5305 rn = "Index";
5306 break;
5307 case 1:
5308 check_insn(ctx, ASE_MT);
5309 gen_helper_mfc0_mvpcontrol(arg, cpu_env);
5310 rn = "MVPControl";
5311 break;
5312 case 2:
5313 check_insn(ctx, ASE_MT);
5314 gen_helper_mfc0_mvpconf0(arg, cpu_env);
5315 rn = "MVPConf0";
5316 break;
5317 case 3:
5318 check_insn(ctx, ASE_MT);
5319 gen_helper_mfc0_mvpconf1(arg, cpu_env);
5320 rn = "MVPConf1";
5321 break;
5322 default:
5323 goto die;
5325 break;
5326 case 1:
5327 switch (sel) {
5328 case 0:
5329 gen_helper_mfc0_random(arg, cpu_env);
5330 rn = "Random";
5331 break;
5332 case 1:
5333 check_insn(ctx, ASE_MT);
5334 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEControl));
5335 rn = "VPEControl";
5336 break;
5337 case 2:
5338 check_insn(ctx, ASE_MT);
5339 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEConf0));
5340 rn = "VPEConf0";
5341 break;
5342 case 3:
5343 check_insn(ctx, ASE_MT);
5344 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEConf1));
5345 rn = "VPEConf1";
5346 break;
5347 case 4:
5348 check_insn(ctx, ASE_MT);
5349 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_YQMask));
5350 rn = "YQMask";
5351 break;
5352 case 5:
5353 check_insn(ctx, ASE_MT);
5354 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_VPESchedule));
5355 rn = "VPESchedule";
5356 break;
5357 case 6:
5358 check_insn(ctx, ASE_MT);
5359 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_VPEScheFBack));
5360 rn = "VPEScheFBack";
5361 break;
5362 case 7:
5363 check_insn(ctx, ASE_MT);
5364 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEOpt));
5365 rn = "VPEOpt";
5366 break;
5367 default:
5368 goto die;
5370 break;
5371 case 2:
5372 switch (sel) {
5373 case 0:
5374 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EntryLo0));
5375 rn = "EntryLo0";
5376 break;
5377 case 1:
5378 check_insn(ctx, ASE_MT);
5379 gen_helper_mfc0_tcstatus(arg, cpu_env);
5380 rn = "TCStatus";
5381 break;
5382 case 2:
5383 check_insn(ctx, ASE_MT);
5384 gen_helper_mfc0_tcbind(arg, cpu_env);
5385 rn = "TCBind";
5386 break;
5387 case 3:
5388 check_insn(ctx, ASE_MT);
5389 gen_helper_dmfc0_tcrestart(arg, cpu_env);
5390 rn = "TCRestart";
5391 break;
5392 case 4:
5393 check_insn(ctx, ASE_MT);
5394 gen_helper_dmfc0_tchalt(arg, cpu_env);
5395 rn = "TCHalt";
5396 break;
5397 case 5:
5398 check_insn(ctx, ASE_MT);
5399 gen_helper_dmfc0_tccontext(arg, cpu_env);
5400 rn = "TCContext";
5401 break;
5402 case 6:
5403 check_insn(ctx, ASE_MT);
5404 gen_helper_dmfc0_tcschedule(arg, cpu_env);
5405 rn = "TCSchedule";
5406 break;
5407 case 7:
5408 check_insn(ctx, ASE_MT);
5409 gen_helper_dmfc0_tcschefback(arg, cpu_env);
5410 rn = "TCScheFBack";
5411 break;
5412 default:
5413 goto die;
5415 break;
5416 case 3:
5417 switch (sel) {
5418 case 0:
5419 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EntryLo1));
5420 rn = "EntryLo1";
5421 break;
5422 default:
5423 goto die;
5425 break;
5426 case 4:
5427 switch (sel) {
5428 case 0:
5429 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_Context));
5430 rn = "Context";
5431 break;
5432 case 1:
5433 // gen_helper_dmfc0_contextconfig(arg); /* SmartMIPS ASE */
5434 rn = "ContextConfig";
5435 goto die;
5436 // break;
5437 case 2:
5438 if (ctx->ulri) {
5439 tcg_gen_ld_tl(arg, cpu_env,
5440 offsetof(CPUMIPSState, active_tc.CP0_UserLocal));
5441 rn = "UserLocal";
5442 } else {
5443 tcg_gen_movi_tl(arg, 0);
5445 break;
5446 default:
5447 goto die;
5449 break;
5450 case 5:
5451 switch (sel) {
5452 case 0:
5453 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PageMask));
5454 rn = "PageMask";
5455 break;
5456 case 1:
5457 check_insn(ctx, ISA_MIPS32R2);
5458 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PageGrain));
5459 rn = "PageGrain";
5460 break;
5461 default:
5462 goto die;
5464 break;
5465 case 6:
5466 switch (sel) {
5467 case 0:
5468 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Wired));
5469 rn = "Wired";
5470 break;
5471 case 1:
5472 check_insn(ctx, ISA_MIPS32R2);
5473 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf0));
5474 rn = "SRSConf0";
5475 break;
5476 case 2:
5477 check_insn(ctx, ISA_MIPS32R2);
5478 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf1));
5479 rn = "SRSConf1";
5480 break;
5481 case 3:
5482 check_insn(ctx, ISA_MIPS32R2);
5483 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf2));
5484 rn = "SRSConf2";
5485 break;
5486 case 4:
5487 check_insn(ctx, ISA_MIPS32R2);
5488 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf3));
5489 rn = "SRSConf3";
5490 break;
5491 case 5:
5492 check_insn(ctx, ISA_MIPS32R2);
5493 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf4));
5494 rn = "SRSConf4";
5495 break;
5496 default:
5497 goto die;
5499 break;
5500 case 7:
5501 switch (sel) {
5502 case 0:
5503 check_insn(ctx, ISA_MIPS32R2);
5504 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_HWREna));
5505 rn = "HWREna";
5506 break;
5507 default:
5508 goto die;
5510 break;
5511 case 8:
5512 switch (sel) {
5513 case 0:
5514 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_BadVAddr));
5515 rn = "BadVAddr";
5516 break;
5517 default:
5518 goto die;
5520 break;
5521 case 9:
5522 switch (sel) {
5523 case 0:
5524 /* Mark as an IO operation because we read the time. */
5525 if (use_icount)
5526 gen_io_start();
5527 gen_helper_mfc0_count(arg, cpu_env);
5528 if (use_icount) {
5529 gen_io_end();
5531 /* Break the TB to be able to take timer interrupts immediately
5532 after reading count. */
5533 ctx->bstate = BS_STOP;
5534 rn = "Count";
5535 break;
5536 /* 6,7 are implementation dependent */
5537 default:
5538 goto die;
5540 break;
5541 case 10:
5542 switch (sel) {
5543 case 0:
5544 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EntryHi));
5545 rn = "EntryHi";
5546 break;
5547 default:
5548 goto die;
5550 break;
5551 case 11:
5552 switch (sel) {
5553 case 0:
5554 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Compare));
5555 rn = "Compare";
5556 break;
5557 /* 6,7 are implementation dependent */
5558 default:
5559 goto die;
5561 break;
5562 case 12:
5563 switch (sel) {
5564 case 0:
5565 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Status));
5566 rn = "Status";
5567 break;
5568 case 1:
5569 check_insn(ctx, ISA_MIPS32R2);
5570 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_IntCtl));
5571 rn = "IntCtl";
5572 break;
5573 case 2:
5574 check_insn(ctx, ISA_MIPS32R2);
5575 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSCtl));
5576 rn = "SRSCtl";
5577 break;
5578 case 3:
5579 check_insn(ctx, ISA_MIPS32R2);
5580 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSMap));
5581 rn = "SRSMap";
5582 break;
5583 default:
5584 goto die;
5586 break;
5587 case 13:
5588 switch (sel) {
5589 case 0:
5590 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Cause));
5591 rn = "Cause";
5592 break;
5593 default:
5594 goto die;
5596 break;
5597 case 14:
5598 switch (sel) {
5599 case 0:
5600 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EPC));
5601 rn = "EPC";
5602 break;
5603 default:
5604 goto die;
5606 break;
5607 case 15:
5608 switch (sel) {
5609 case 0:
5610 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PRid));
5611 rn = "PRid";
5612 break;
5613 case 1:
5614 check_insn(ctx, ISA_MIPS32R2);
5615 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_EBase));
5616 rn = "EBase";
5617 break;
5618 default:
5619 goto die;
5621 break;
5622 case 16:
5623 switch (sel) {
5624 case 0:
5625 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config0));
5626 rn = "Config";
5627 break;
5628 case 1:
5629 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config1));
5630 rn = "Config1";
5631 break;
5632 case 2:
5633 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config2));
5634 rn = "Config2";
5635 break;
5636 case 3:
5637 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config3));
5638 rn = "Config3";
5639 break;
5640 /* 6,7 are implementation dependent */
5641 case 6:
5642 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config6));
5643 rn = "Config6";
5644 break;
5645 case 7:
5646 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config7));
5647 rn = "Config7";
5648 break;
5649 default:
5650 goto die;
5652 break;
5653 case 17:
5654 switch (sel) {
5655 case 0:
5656 gen_helper_dmfc0_lladdr(arg, cpu_env);
5657 rn = "LLAddr";
5658 break;
5659 default:
5660 goto die;
5662 break;
5663 case 18:
5664 switch (sel) {
5665 case 0 ... 7:
5666 gen_helper_1e0i(dmfc0_watchlo, arg, sel);
5667 rn = "WatchLo";
5668 break;
5669 default:
5670 goto die;
5672 break;
5673 case 19:
5674 switch (sel) {
5675 case 0 ... 7:
5676 gen_helper_1e0i(mfc0_watchhi, arg, sel);
5677 rn = "WatchHi";
5678 break;
5679 default:
5680 goto die;
5682 break;
5683 case 20:
5684 switch (sel) {
5685 case 0:
5686 check_insn(ctx, ISA_MIPS3);
5687 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_XContext));
5688 rn = "XContext";
5689 break;
5690 default:
5691 goto die;
5693 break;
5694 case 21:
5695 /* Officially reserved, but sel 0 is used for R1x000 framemask */
5696 switch (sel) {
5697 case 0:
5698 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Framemask));
5699 rn = "Framemask";
5700 break;
5701 default:
5702 goto die;
5704 break;
5705 case 22:
5706 tcg_gen_movi_tl(arg, 0); /* unimplemented */
5707 rn = "'Diagnostic"; /* implementation dependent */
5708 break;
5709 case 23:
5710 switch (sel) {
5711 case 0:
5712 gen_helper_mfc0_debug(arg, cpu_env); /* EJTAG support */
5713 rn = "Debug";
5714 break;
5715 case 1:
5716 // gen_helper_dmfc0_tracecontrol(arg, cpu_env); /* PDtrace support */
5717 rn = "TraceControl";
5718 // break;
5719 case 2:
5720 // gen_helper_dmfc0_tracecontrol2(arg, cpu_env); /* PDtrace support */
5721 rn = "TraceControl2";
5722 // break;
5723 case 3:
5724 // gen_helper_dmfc0_usertracedata(arg, cpu_env); /* PDtrace support */
5725 rn = "UserTraceData";
5726 // break;
5727 case 4:
5728 // gen_helper_dmfc0_tracebpc(arg, cpu_env); /* PDtrace support */
5729 rn = "TraceBPC";
5730 // break;
5731 default:
5732 goto die;
5734 break;
5735 case 24:
5736 switch (sel) {
5737 case 0:
5738 /* EJTAG support */
5739 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_DEPC));
5740 rn = "DEPC";
5741 break;
5742 default:
5743 goto die;
5745 break;
5746 case 25:
5747 switch (sel) {
5748 case 0:
5749 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Performance0));
5750 rn = "Performance0";
5751 break;
5752 case 1:
5753 // gen_helper_dmfc0_performance1(arg);
5754 rn = "Performance1";
5755 // break;
5756 case 2:
5757 // gen_helper_dmfc0_performance2(arg);
5758 rn = "Performance2";
5759 // break;
5760 case 3:
5761 // gen_helper_dmfc0_performance3(arg);
5762 rn = "Performance3";
5763 // break;
5764 case 4:
5765 // gen_helper_dmfc0_performance4(arg);
5766 rn = "Performance4";
5767 // break;
5768 case 5:
5769 // gen_helper_dmfc0_performance5(arg);
5770 rn = "Performance5";
5771 // break;
5772 case 6:
5773 // gen_helper_dmfc0_performance6(arg);
5774 rn = "Performance6";
5775 // break;
5776 case 7:
5777 // gen_helper_dmfc0_performance7(arg);
5778 rn = "Performance7";
5779 // break;
5780 default:
5781 goto die;
5783 break;
5784 case 26:
5785 tcg_gen_movi_tl(arg, 0); /* unimplemented */
5786 rn = "ECC";
5787 break;
5788 case 27:
5789 switch (sel) {
5790 /* ignored */
5791 case 0 ... 3:
5792 tcg_gen_movi_tl(arg, 0); /* unimplemented */
5793 rn = "CacheErr";
5794 break;
5795 default:
5796 goto die;
5798 break;
5799 case 28:
5800 switch (sel) {
5801 case 0:
5802 case 2:
5803 case 4:
5804 case 6:
5805 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_TagLo));
5806 rn = "TagLo";
5807 break;
5808 case 1:
5809 case 3:
5810 case 5:
5811 case 7:
5812 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DataLo));
5813 rn = "DataLo";
5814 break;
5815 default:
5816 goto die;
5818 break;
5819 case 29:
5820 switch (sel) {
5821 case 0:
5822 case 2:
5823 case 4:
5824 case 6:
5825 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_TagHi));
5826 rn = "TagHi";
5827 break;
5828 case 1:
5829 case 3:
5830 case 5:
5831 case 7:
5832 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DataHi));
5833 rn = "DataHi";
5834 break;
5835 default:
5836 goto die;
5838 break;
5839 case 30:
5840 switch (sel) {
5841 case 0:
5842 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_ErrorEPC));
5843 rn = "ErrorEPC";
5844 break;
5845 default:
5846 goto die;
5848 break;
5849 case 31:
5850 switch (sel) {
5851 case 0:
5852 /* EJTAG support */
5853 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DESAVE));
5854 rn = "DESAVE";
5855 break;
5856 default:
5857 goto die;
5859 break;
5860 default:
5861 goto die;
5863 (void)rn; /* avoid a compiler warning */
5864 LOG_DISAS("dmfc0 %s (reg %d sel %d)\n", rn, reg, sel);
5865 return;
5867 die:
5868 LOG_DISAS("dmfc0 %s (reg %d sel %d)\n", rn, reg, sel);
5869 generate_exception(ctx, EXCP_RI);
5872 static void gen_dmtc0(DisasContext *ctx, TCGv arg, int reg, int sel)
5874 const char *rn = "invalid";
5876 if (sel != 0)
5877 check_insn(ctx, ISA_MIPS64);
5879 if (use_icount)
5880 gen_io_start();
5882 switch (reg) {
5883 case 0:
5884 switch (sel) {
5885 case 0:
5886 gen_helper_mtc0_index(cpu_env, arg);
5887 rn = "Index";
5888 break;
5889 case 1:
5890 check_insn(ctx, ASE_MT);
5891 gen_helper_mtc0_mvpcontrol(cpu_env, arg);
5892 rn = "MVPControl";
5893 break;
5894 case 2:
5895 check_insn(ctx, ASE_MT);
5896 /* ignored */
5897 rn = "MVPConf0";
5898 break;
5899 case 3:
5900 check_insn(ctx, ASE_MT);
5901 /* ignored */
5902 rn = "MVPConf1";
5903 break;
5904 default:
5905 goto die;
5907 break;
5908 case 1:
5909 switch (sel) {
5910 case 0:
5911 /* ignored */
5912 rn = "Random";
5913 break;
5914 case 1:
5915 check_insn(ctx, ASE_MT);
5916 gen_helper_mtc0_vpecontrol(cpu_env, arg);
5917 rn = "VPEControl";
5918 break;
5919 case 2:
5920 check_insn(ctx, ASE_MT);
5921 gen_helper_mtc0_vpeconf0(cpu_env, arg);
5922 rn = "VPEConf0";
5923 break;
5924 case 3:
5925 check_insn(ctx, ASE_MT);
5926 gen_helper_mtc0_vpeconf1(cpu_env, arg);
5927 rn = "VPEConf1";
5928 break;
5929 case 4:
5930 check_insn(ctx, ASE_MT);
5931 gen_helper_mtc0_yqmask(cpu_env, arg);
5932 rn = "YQMask";
5933 break;
5934 case 5:
5935 check_insn(ctx, ASE_MT);
5936 tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_VPESchedule));
5937 rn = "VPESchedule";
5938 break;
5939 case 6:
5940 check_insn(ctx, ASE_MT);
5941 tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_VPEScheFBack));
5942 rn = "VPEScheFBack";
5943 break;
5944 case 7:
5945 check_insn(ctx, ASE_MT);
5946 gen_helper_mtc0_vpeopt(cpu_env, arg);
5947 rn = "VPEOpt";
5948 break;
5949 default:
5950 goto die;
5952 break;
5953 case 2:
5954 switch (sel) {
5955 case 0:
5956 gen_helper_mtc0_entrylo0(cpu_env, arg);
5957 rn = "EntryLo0";
5958 break;
5959 case 1:
5960 check_insn(ctx, ASE_MT);
5961 gen_helper_mtc0_tcstatus(cpu_env, arg);
5962 rn = "TCStatus";
5963 break;
5964 case 2:
5965 check_insn(ctx, ASE_MT);
5966 gen_helper_mtc0_tcbind(cpu_env, arg);
5967 rn = "TCBind";
5968 break;
5969 case 3:
5970 check_insn(ctx, ASE_MT);
5971 gen_helper_mtc0_tcrestart(cpu_env, arg);
5972 rn = "TCRestart";
5973 break;
5974 case 4:
5975 check_insn(ctx, ASE_MT);
5976 gen_helper_mtc0_tchalt(cpu_env, arg);
5977 rn = "TCHalt";
5978 break;
5979 case 5:
5980 check_insn(ctx, ASE_MT);
5981 gen_helper_mtc0_tccontext(cpu_env, arg);
5982 rn = "TCContext";
5983 break;
5984 case 6:
5985 check_insn(ctx, ASE_MT);
5986 gen_helper_mtc0_tcschedule(cpu_env, arg);
5987 rn = "TCSchedule";
5988 break;
5989 case 7:
5990 check_insn(ctx, ASE_MT);
5991 gen_helper_mtc0_tcschefback(cpu_env, arg);
5992 rn = "TCScheFBack";
5993 break;
5994 default:
5995 goto die;
5997 break;
5998 case 3:
5999 switch (sel) {
6000 case 0:
6001 gen_helper_mtc0_entrylo1(cpu_env, arg);
6002 rn = "EntryLo1";
6003 break;
6004 default:
6005 goto die;
6007 break;
6008 case 4:
6009 switch (sel) {
6010 case 0:
6011 gen_helper_mtc0_context(cpu_env, arg);
6012 rn = "Context";
6013 break;
6014 case 1:
6015 // gen_helper_mtc0_contextconfig(cpu_env, arg); /* SmartMIPS ASE */
6016 rn = "ContextConfig";
6017 goto die;
6018 // break;
6019 case 2:
6020 if (ctx->ulri) {
6021 tcg_gen_st_tl(arg, cpu_env,
6022 offsetof(CPUMIPSState, active_tc.CP0_UserLocal));
6023 rn = "UserLocal";
6025 break;
6026 default:
6027 goto die;
6029 break;
6030 case 5:
6031 switch (sel) {
6032 case 0:
6033 gen_helper_mtc0_pagemask(cpu_env, arg);
6034 rn = "PageMask";
6035 break;
6036 case 1:
6037 check_insn(ctx, ISA_MIPS32R2);
6038 gen_helper_mtc0_pagegrain(cpu_env, arg);
6039 rn = "PageGrain";
6040 break;
6041 default:
6042 goto die;
6044 break;
6045 case 6:
6046 switch (sel) {
6047 case 0:
6048 gen_helper_mtc0_wired(cpu_env, arg);
6049 rn = "Wired";
6050 break;
6051 case 1:
6052 check_insn(ctx, ISA_MIPS32R2);
6053 gen_helper_mtc0_srsconf0(cpu_env, arg);
6054 rn = "SRSConf0";
6055 break;
6056 case 2:
6057 check_insn(ctx, ISA_MIPS32R2);
6058 gen_helper_mtc0_srsconf1(cpu_env, arg);
6059 rn = "SRSConf1";
6060 break;
6061 case 3:
6062 check_insn(ctx, ISA_MIPS32R2);
6063 gen_helper_mtc0_srsconf2(cpu_env, arg);
6064 rn = "SRSConf2";
6065 break;
6066 case 4:
6067 check_insn(ctx, ISA_MIPS32R2);
6068 gen_helper_mtc0_srsconf3(cpu_env, arg);
6069 rn = "SRSConf3";
6070 break;
6071 case 5:
6072 check_insn(ctx, ISA_MIPS32R2);
6073 gen_helper_mtc0_srsconf4(cpu_env, arg);
6074 rn = "SRSConf4";
6075 break;
6076 default:
6077 goto die;
6079 break;
6080 case 7:
6081 switch (sel) {
6082 case 0:
6083 check_insn(ctx, ISA_MIPS32R2);
6084 gen_helper_mtc0_hwrena(cpu_env, arg);
6085 ctx->bstate = BS_STOP;
6086 rn = "HWREna";
6087 break;
6088 default:
6089 goto die;
6091 break;
6092 case 8:
6093 /* ignored */
6094 rn = "BadVAddr";
6095 break;
6096 case 9:
6097 switch (sel) {
6098 case 0:
6099 gen_helper_mtc0_count(cpu_env, arg);
6100 rn = "Count";
6101 break;
6102 /* 6,7 are implementation dependent */
6103 default:
6104 goto die;
6106 /* Stop translation as we may have switched the execution mode */
6107 ctx->bstate = BS_STOP;
6108 break;
6109 case 10:
6110 switch (sel) {
6111 case 0:
6112 gen_helper_mtc0_entryhi(cpu_env, arg);
6113 rn = "EntryHi";
6114 break;
6115 default:
6116 goto die;
6118 break;
6119 case 11:
6120 switch (sel) {
6121 case 0:
6122 gen_helper_mtc0_compare(cpu_env, arg);
6123 rn = "Compare";
6124 break;
6125 /* 6,7 are implementation dependent */
6126 default:
6127 goto die;
6129 /* Stop translation as we may have switched the execution mode */
6130 ctx->bstate = BS_STOP;
6131 break;
6132 case 12:
6133 switch (sel) {
6134 case 0:
6135 save_cpu_state(ctx, 1);
6136 gen_helper_mtc0_status(cpu_env, arg);
6137 /* BS_STOP isn't good enough here, hflags may have changed. */
6138 gen_save_pc(ctx->pc + 4);
6139 ctx->bstate = BS_EXCP;
6140 rn = "Status";
6141 break;
6142 case 1:
6143 check_insn(ctx, ISA_MIPS32R2);
6144 gen_helper_mtc0_intctl(cpu_env, arg);
6145 /* Stop translation as we may have switched the execution mode */
6146 ctx->bstate = BS_STOP;
6147 rn = "IntCtl";
6148 break;
6149 case 2:
6150 check_insn(ctx, ISA_MIPS32R2);
6151 gen_helper_mtc0_srsctl(cpu_env, arg);
6152 /* Stop translation as we may have switched the execution mode */
6153 ctx->bstate = BS_STOP;
6154 rn = "SRSCtl";
6155 break;
6156 case 3:
6157 check_insn(ctx, ISA_MIPS32R2);
6158 gen_mtc0_store32(arg, offsetof(CPUMIPSState, CP0_SRSMap));
6159 /* Stop translation as we may have switched the execution mode */
6160 ctx->bstate = BS_STOP;
6161 rn = "SRSMap";
6162 break;
6163 default:
6164 goto die;
6166 break;
6167 case 13:
6168 switch (sel) {
6169 case 0:
6170 save_cpu_state(ctx, 1);
6171 /* Mark as an IO operation because we may trigger a software
6172 interrupt. */
6173 if (use_icount) {
6174 gen_io_start();
6176 gen_helper_mtc0_cause(cpu_env, arg);
6177 if (use_icount) {
6178 gen_io_end();
6180 /* Stop translation as we may have triggered an intetrupt */
6181 ctx->bstate = BS_STOP;
6182 rn = "Cause";
6183 break;
6184 default:
6185 goto die;
6187 break;
6188 case 14:
6189 switch (sel) {
6190 case 0:
6191 tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EPC));
6192 rn = "EPC";
6193 break;
6194 default:
6195 goto die;
6197 break;
6198 case 15:
6199 switch (sel) {
6200 case 0:
6201 /* ignored */
6202 rn = "PRid";
6203 break;
6204 case 1:
6205 check_insn(ctx, ISA_MIPS32R2);
6206 gen_helper_mtc0_ebase(cpu_env, arg);
6207 rn = "EBase";
6208 break;
6209 default:
6210 goto die;
6212 break;
6213 case 16:
6214 switch (sel) {
6215 case 0:
6216 gen_helper_mtc0_config0(cpu_env, arg);
6217 rn = "Config";
6218 /* Stop translation as we may have switched the execution mode */
6219 ctx->bstate = BS_STOP;
6220 break;
6221 case 1:
6222 /* ignored, read only */
6223 rn = "Config1";
6224 break;
6225 case 2:
6226 gen_helper_mtc0_config2(cpu_env, arg);
6227 rn = "Config2";
6228 /* Stop translation as we may have switched the execution mode */
6229 ctx->bstate = BS_STOP;
6230 break;
6231 case 3:
6232 /* ignored */
6233 rn = "Config3";
6234 break;
6235 /* 6,7 are implementation dependent */
6236 default:
6237 rn = "Invalid config selector";
6238 goto die;
6240 break;
6241 case 17:
6242 switch (sel) {
6243 case 0:
6244 gen_helper_mtc0_lladdr(cpu_env, arg);
6245 rn = "LLAddr";
6246 break;
6247 default:
6248 goto die;
6250 break;
6251 case 18:
6252 switch (sel) {
6253 case 0 ... 7:
6254 gen_helper_0e1i(mtc0_watchlo, arg, sel);
6255 rn = "WatchLo";
6256 break;
6257 default:
6258 goto die;
6260 break;
6261 case 19:
6262 switch (sel) {
6263 case 0 ... 7:
6264 gen_helper_0e1i(mtc0_watchhi, arg, sel);
6265 rn = "WatchHi";
6266 break;
6267 default:
6268 goto die;
6270 break;
6271 case 20:
6272 switch (sel) {
6273 case 0:
6274 check_insn(ctx, ISA_MIPS3);
6275 gen_helper_mtc0_xcontext(cpu_env, arg);
6276 rn = "XContext";
6277 break;
6278 default:
6279 goto die;
6281 break;
6282 case 21:
6283 /* Officially reserved, but sel 0 is used for R1x000 framemask */
6284 switch (sel) {
6285 case 0:
6286 gen_helper_mtc0_framemask(cpu_env, arg);
6287 rn = "Framemask";
6288 break;
6289 default:
6290 goto die;
6292 break;
6293 case 22:
6294 /* ignored */
6295 rn = "Diagnostic"; /* implementation dependent */
6296 break;
6297 case 23:
6298 switch (sel) {
6299 case 0:
6300 gen_helper_mtc0_debug(cpu_env, arg); /* EJTAG support */
6301 /* BS_STOP isn't good enough here, hflags may have changed. */
6302 gen_save_pc(ctx->pc + 4);
6303 ctx->bstate = BS_EXCP;
6304 rn = "Debug";
6305 break;
6306 case 1:
6307 // gen_helper_mtc0_tracecontrol(cpu_env, arg); /* PDtrace support */
6308 /* Stop translation as we may have switched the execution mode */
6309 ctx->bstate = BS_STOP;
6310 rn = "TraceControl";
6311 // break;
6312 case 2:
6313 // gen_helper_mtc0_tracecontrol2(cpu_env, arg); /* PDtrace support */
6314 /* Stop translation as we may have switched the execution mode */
6315 ctx->bstate = BS_STOP;
6316 rn = "TraceControl2";
6317 // break;
6318 case 3:
6319 // gen_helper_mtc0_usertracedata(cpu_env, arg); /* PDtrace support */
6320 /* Stop translation as we may have switched the execution mode */
6321 ctx->bstate = BS_STOP;
6322 rn = "UserTraceData";
6323 // break;
6324 case 4:
6325 // gen_helper_mtc0_tracebpc(cpu_env, arg); /* PDtrace support */
6326 /* Stop translation as we may have switched the execution mode */
6327 ctx->bstate = BS_STOP;
6328 rn = "TraceBPC";
6329 // break;
6330 default:
6331 goto die;
6333 break;
6334 case 24:
6335 switch (sel) {
6336 case 0:
6337 /* EJTAG support */
6338 tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_DEPC));
6339 rn = "DEPC";
6340 break;
6341 default:
6342 goto die;
6344 break;
6345 case 25:
6346 switch (sel) {
6347 case 0:
6348 gen_helper_mtc0_performance0(cpu_env, arg);
6349 rn = "Performance0";
6350 break;
6351 case 1:
6352 // gen_helper_mtc0_performance1(cpu_env, arg);
6353 rn = "Performance1";
6354 // break;
6355 case 2:
6356 // gen_helper_mtc0_performance2(cpu_env, arg);
6357 rn = "Performance2";
6358 // break;
6359 case 3:
6360 // gen_helper_mtc0_performance3(cpu_env, arg);
6361 rn = "Performance3";
6362 // break;
6363 case 4:
6364 // gen_helper_mtc0_performance4(cpu_env, arg);
6365 rn = "Performance4";
6366 // break;
6367 case 5:
6368 // gen_helper_mtc0_performance5(cpu_env, arg);
6369 rn = "Performance5";
6370 // break;
6371 case 6:
6372 // gen_helper_mtc0_performance6(cpu_env, arg);
6373 rn = "Performance6";
6374 // break;
6375 case 7:
6376 // gen_helper_mtc0_performance7(cpu_env, arg);
6377 rn = "Performance7";
6378 // break;
6379 default:
6380 goto die;
6382 break;
6383 case 26:
6384 /* ignored */
6385 rn = "ECC";
6386 break;
6387 case 27:
6388 switch (sel) {
6389 case 0 ... 3:
6390 /* ignored */
6391 rn = "CacheErr";
6392 break;
6393 default:
6394 goto die;
6396 break;
6397 case 28:
6398 switch (sel) {
6399 case 0:
6400 case 2:
6401 case 4:
6402 case 6:
6403 gen_helper_mtc0_taglo(cpu_env, arg);
6404 rn = "TagLo";
6405 break;
6406 case 1:
6407 case 3:
6408 case 5:
6409 case 7:
6410 gen_helper_mtc0_datalo(cpu_env, arg);
6411 rn = "DataLo";
6412 break;
6413 default:
6414 goto die;
6416 break;
6417 case 29:
6418 switch (sel) {
6419 case 0:
6420 case 2:
6421 case 4:
6422 case 6:
6423 gen_helper_mtc0_taghi(cpu_env, arg);
6424 rn = "TagHi";
6425 break;
6426 case 1:
6427 case 3:
6428 case 5:
6429 case 7:
6430 gen_helper_mtc0_datahi(cpu_env, arg);
6431 rn = "DataHi";
6432 break;
6433 default:
6434 rn = "invalid sel";
6435 goto die;
6437 break;
6438 case 30:
6439 switch (sel) {
6440 case 0:
6441 tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_ErrorEPC));
6442 rn = "ErrorEPC";
6443 break;
6444 default:
6445 goto die;
6447 break;
6448 case 31:
6449 switch (sel) {
6450 case 0:
6451 /* EJTAG support */
6452 gen_mtc0_store32(arg, offsetof(CPUMIPSState, CP0_DESAVE));
6453 rn = "DESAVE";
6454 break;
6455 default:
6456 goto die;
6458 /* Stop translation as we may have switched the execution mode */
6459 ctx->bstate = BS_STOP;
6460 break;
6461 default:
6462 goto die;
6464 (void)rn; /* avoid a compiler warning */
6465 LOG_DISAS("dmtc0 %s (reg %d sel %d)\n", rn, reg, sel);
6466 /* For simplicity assume that all writes can cause interrupts. */
6467 if (use_icount) {
6468 gen_io_end();
6469 ctx->bstate = BS_STOP;
6471 return;
6473 die:
6474 LOG_DISAS("dmtc0 %s (reg %d sel %d)\n", rn, reg, sel);
6475 generate_exception(ctx, EXCP_RI);
6477 #endif /* TARGET_MIPS64 */
6479 static void gen_mftr(CPUMIPSState *env, DisasContext *ctx, int rt, int rd,
6480 int u, int sel, int h)
6482 int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
6483 TCGv t0 = tcg_temp_local_new();
6485 if ((env->CP0_VPEConf0 & (1 << CP0VPEC0_MVP)) == 0 &&
6486 ((env->tcs[other_tc].CP0_TCBind & (0xf << CP0TCBd_CurVPE)) !=
6487 (env->active_tc.CP0_TCBind & (0xf << CP0TCBd_CurVPE))))
6488 tcg_gen_movi_tl(t0, -1);
6489 else if ((env->CP0_VPEControl & (0xff << CP0VPECo_TargTC)) >
6490 (env->mvp->CP0_MVPConf0 & (0xff << CP0MVPC0_PTC)))
6491 tcg_gen_movi_tl(t0, -1);
6492 else if (u == 0) {
6493 switch (rt) {
6494 case 1:
6495 switch (sel) {
6496 case 1:
6497 gen_helper_mftc0_vpecontrol(t0, cpu_env);
6498 break;
6499 case 2:
6500 gen_helper_mftc0_vpeconf0(t0, cpu_env);
6501 break;
6502 default:
6503 goto die;
6504 break;
6506 break;
6507 case 2:
6508 switch (sel) {
6509 case 1:
6510 gen_helper_mftc0_tcstatus(t0, cpu_env);
6511 break;
6512 case 2:
6513 gen_helper_mftc0_tcbind(t0, cpu_env);
6514 break;
6515 case 3:
6516 gen_helper_mftc0_tcrestart(t0, cpu_env);
6517 break;
6518 case 4:
6519 gen_helper_mftc0_tchalt(t0, cpu_env);
6520 break;
6521 case 5:
6522 gen_helper_mftc0_tccontext(t0, cpu_env);
6523 break;
6524 case 6:
6525 gen_helper_mftc0_tcschedule(t0, cpu_env);
6526 break;
6527 case 7:
6528 gen_helper_mftc0_tcschefback(t0, cpu_env);
6529 break;
6530 default:
6531 gen_mfc0(ctx, t0, rt, sel);
6532 break;
6534 break;
6535 case 10:
6536 switch (sel) {
6537 case 0:
6538 gen_helper_mftc0_entryhi(t0, cpu_env);
6539 break;
6540 default:
6541 gen_mfc0(ctx, t0, rt, sel);
6542 break;
6544 case 12:
6545 switch (sel) {
6546 case 0:
6547 gen_helper_mftc0_status(t0, cpu_env);
6548 break;
6549 default:
6550 gen_mfc0(ctx, t0, rt, sel);
6551 break;
6553 case 13:
6554 switch (sel) {
6555 case 0:
6556 gen_helper_mftc0_cause(t0, cpu_env);
6557 break;
6558 default:
6559 goto die;
6560 break;
6562 break;
6563 case 14:
6564 switch (sel) {
6565 case 0:
6566 gen_helper_mftc0_epc(t0, cpu_env);
6567 break;
6568 default:
6569 goto die;
6570 break;
6572 break;
6573 case 15:
6574 switch (sel) {
6575 case 1:
6576 gen_helper_mftc0_ebase(t0, cpu_env);
6577 break;
6578 default:
6579 goto die;
6580 break;
6582 break;
6583 case 16:
6584 switch (sel) {
6585 case 0 ... 7:
6586 gen_helper_mftc0_configx(t0, cpu_env, tcg_const_tl(sel));
6587 break;
6588 default:
6589 goto die;
6590 break;
6592 break;
6593 case 23:
6594 switch (sel) {
6595 case 0:
6596 gen_helper_mftc0_debug(t0, cpu_env);
6597 break;
6598 default:
6599 gen_mfc0(ctx, t0, rt, sel);
6600 break;
6602 break;
6603 default:
6604 gen_mfc0(ctx, t0, rt, sel);
6606 } else switch (sel) {
6607 /* GPR registers. */
6608 case 0:
6609 gen_helper_1e0i(mftgpr, t0, rt);
6610 break;
6611 /* Auxiliary CPU registers */
6612 case 1:
6613 switch (rt) {
6614 case 0:
6615 gen_helper_1e0i(mftlo, t0, 0);
6616 break;
6617 case 1:
6618 gen_helper_1e0i(mfthi, t0, 0);
6619 break;
6620 case 2:
6621 gen_helper_1e0i(mftacx, t0, 0);
6622 break;
6623 case 4:
6624 gen_helper_1e0i(mftlo, t0, 1);
6625 break;
6626 case 5:
6627 gen_helper_1e0i(mfthi, t0, 1);
6628 break;
6629 case 6:
6630 gen_helper_1e0i(mftacx, t0, 1);
6631 break;
6632 case 8:
6633 gen_helper_1e0i(mftlo, t0, 2);
6634 break;
6635 case 9:
6636 gen_helper_1e0i(mfthi, t0, 2);
6637 break;
6638 case 10:
6639 gen_helper_1e0i(mftacx, t0, 2);
6640 break;
6641 case 12:
6642 gen_helper_1e0i(mftlo, t0, 3);
6643 break;
6644 case 13:
6645 gen_helper_1e0i(mfthi, t0, 3);
6646 break;
6647 case 14:
6648 gen_helper_1e0i(mftacx, t0, 3);
6649 break;
6650 case 16:
6651 gen_helper_mftdsp(t0, cpu_env);
6652 break;
6653 default:
6654 goto die;
6656 break;
6657 /* Floating point (COP1). */
6658 case 2:
6659 /* XXX: For now we support only a single FPU context. */
6660 if (h == 0) {
6661 TCGv_i32 fp0 = tcg_temp_new_i32();
6663 gen_load_fpr32(fp0, rt);
6664 tcg_gen_ext_i32_tl(t0, fp0);
6665 tcg_temp_free_i32(fp0);
6666 } else {
6667 TCGv_i32 fp0 = tcg_temp_new_i32();
6669 gen_load_fpr32h(ctx, fp0, rt);
6670 tcg_gen_ext_i32_tl(t0, fp0);
6671 tcg_temp_free_i32(fp0);
6673 break;
6674 case 3:
6675 /* XXX: For now we support only a single FPU context. */
6676 gen_helper_1e0i(cfc1, t0, rt);
6677 break;
6678 /* COP2: Not implemented. */
6679 case 4:
6680 case 5:
6681 /* fall through */
6682 default:
6683 goto die;
6685 LOG_DISAS("mftr (reg %d u %d sel %d h %d)\n", rt, u, sel, h);
6686 gen_store_gpr(t0, rd);
6687 tcg_temp_free(t0);
6688 return;
6690 die:
6691 tcg_temp_free(t0);
6692 LOG_DISAS("mftr (reg %d u %d sel %d h %d)\n", rt, u, sel, h);
6693 generate_exception(ctx, EXCP_RI);
6696 static void gen_mttr(CPUMIPSState *env, DisasContext *ctx, int rd, int rt,
6697 int u, int sel, int h)
6699 int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
6700 TCGv t0 = tcg_temp_local_new();
6702 gen_load_gpr(t0, rt);
6703 if ((env->CP0_VPEConf0 & (1 << CP0VPEC0_MVP)) == 0 &&
6704 ((env->tcs[other_tc].CP0_TCBind & (0xf << CP0TCBd_CurVPE)) !=
6705 (env->active_tc.CP0_TCBind & (0xf << CP0TCBd_CurVPE))))
6706 /* NOP */ ;
6707 else if ((env->CP0_VPEControl & (0xff << CP0VPECo_TargTC)) >
6708 (env->mvp->CP0_MVPConf0 & (0xff << CP0MVPC0_PTC)))
6709 /* NOP */ ;
6710 else if (u == 0) {
6711 switch (rd) {
6712 case 1:
6713 switch (sel) {
6714 case 1:
6715 gen_helper_mttc0_vpecontrol(cpu_env, t0);
6716 break;
6717 case 2:
6718 gen_helper_mttc0_vpeconf0(cpu_env, t0);
6719 break;
6720 default:
6721 goto die;
6722 break;
6724 break;
6725 case 2:
6726 switch (sel) {
6727 case 1:
6728 gen_helper_mttc0_tcstatus(cpu_env, t0);
6729 break;
6730 case 2:
6731 gen_helper_mttc0_tcbind(cpu_env, t0);
6732 break;
6733 case 3:
6734 gen_helper_mttc0_tcrestart(cpu_env, t0);
6735 break;
6736 case 4:
6737 gen_helper_mttc0_tchalt(cpu_env, t0);
6738 break;
6739 case 5:
6740 gen_helper_mttc0_tccontext(cpu_env, t0);
6741 break;
6742 case 6:
6743 gen_helper_mttc0_tcschedule(cpu_env, t0);
6744 break;
6745 case 7:
6746 gen_helper_mttc0_tcschefback(cpu_env, t0);
6747 break;
6748 default:
6749 gen_mtc0(ctx, t0, rd, sel);
6750 break;
6752 break;
6753 case 10:
6754 switch (sel) {
6755 case 0:
6756 gen_helper_mttc0_entryhi(cpu_env, t0);
6757 break;
6758 default:
6759 gen_mtc0(ctx, t0, rd, sel);
6760 break;
6762 case 12:
6763 switch (sel) {
6764 case 0:
6765 gen_helper_mttc0_status(cpu_env, t0);
6766 break;
6767 default:
6768 gen_mtc0(ctx, t0, rd, sel);
6769 break;
6771 case 13:
6772 switch (sel) {
6773 case 0:
6774 gen_helper_mttc0_cause(cpu_env, t0);
6775 break;
6776 default:
6777 goto die;
6778 break;
6780 break;
6781 case 15:
6782 switch (sel) {
6783 case 1:
6784 gen_helper_mttc0_ebase(cpu_env, t0);
6785 break;
6786 default:
6787 goto die;
6788 break;
6790 break;
6791 case 23:
6792 switch (sel) {
6793 case 0:
6794 gen_helper_mttc0_debug(cpu_env, t0);
6795 break;
6796 default:
6797 gen_mtc0(ctx, t0, rd, sel);
6798 break;
6800 break;
6801 default:
6802 gen_mtc0(ctx, t0, rd, sel);
6804 } else switch (sel) {
6805 /* GPR registers. */
6806 case 0:
6807 gen_helper_0e1i(mttgpr, t0, rd);
6808 break;
6809 /* Auxiliary CPU registers */
6810 case 1:
6811 switch (rd) {
6812 case 0:
6813 gen_helper_0e1i(mttlo, t0, 0);
6814 break;
6815 case 1:
6816 gen_helper_0e1i(mtthi, t0, 0);
6817 break;
6818 case 2:
6819 gen_helper_0e1i(mttacx, t0, 0);
6820 break;
6821 case 4:
6822 gen_helper_0e1i(mttlo, t0, 1);
6823 break;
6824 case 5:
6825 gen_helper_0e1i(mtthi, t0, 1);
6826 break;
6827 case 6:
6828 gen_helper_0e1i(mttacx, t0, 1);
6829 break;
6830 case 8:
6831 gen_helper_0e1i(mttlo, t0, 2);
6832 break;
6833 case 9:
6834 gen_helper_0e1i(mtthi, t0, 2);
6835 break;
6836 case 10:
6837 gen_helper_0e1i(mttacx, t0, 2);
6838 break;
6839 case 12:
6840 gen_helper_0e1i(mttlo, t0, 3);
6841 break;
6842 case 13:
6843 gen_helper_0e1i(mtthi, t0, 3);
6844 break;
6845 case 14:
6846 gen_helper_0e1i(mttacx, t0, 3);
6847 break;
6848 case 16:
6849 gen_helper_mttdsp(cpu_env, t0);
6850 break;
6851 default:
6852 goto die;
6854 break;
6855 /* Floating point (COP1). */
6856 case 2:
6857 /* XXX: For now we support only a single FPU context. */
6858 if (h == 0) {
6859 TCGv_i32 fp0 = tcg_temp_new_i32();
6861 tcg_gen_trunc_tl_i32(fp0, t0);
6862 gen_store_fpr32(fp0, rd);
6863 tcg_temp_free_i32(fp0);
6864 } else {
6865 TCGv_i32 fp0 = tcg_temp_new_i32();
6867 tcg_gen_trunc_tl_i32(fp0, t0);
6868 gen_store_fpr32h(ctx, fp0, rd);
6869 tcg_temp_free_i32(fp0);
6871 break;
6872 case 3:
6873 /* XXX: For now we support only a single FPU context. */
6875 TCGv_i32 fs_tmp = tcg_const_i32(rd);
6877 gen_helper_0e2i(ctc1, t0, fs_tmp, rt);
6878 tcg_temp_free_i32(fs_tmp);
6880 break;
6881 /* COP2: Not implemented. */
6882 case 4:
6883 case 5:
6884 /* fall through */
6885 default:
6886 goto die;
6888 LOG_DISAS("mttr (reg %d u %d sel %d h %d)\n", rd, u, sel, h);
6889 tcg_temp_free(t0);
6890 return;
6892 die:
6893 tcg_temp_free(t0);
6894 LOG_DISAS("mttr (reg %d u %d sel %d h %d)\n", rd, u, sel, h);
6895 generate_exception(ctx, EXCP_RI);
6898 static void gen_cp0 (CPUMIPSState *env, DisasContext *ctx, uint32_t opc, int rt, int rd)
6900 const char *opn = "ldst";
6902 check_cp0_enabled(ctx);
6903 switch (opc) {
6904 case OPC_MFC0:
6905 if (rt == 0) {
6906 /* Treat as NOP. */
6907 return;
6909 gen_mfc0(ctx, cpu_gpr[rt], rd, ctx->opcode & 0x7);
6910 opn = "mfc0";
6911 break;
6912 case OPC_MTC0:
6914 TCGv t0 = tcg_temp_new();
6916 gen_load_gpr(t0, rt);
6917 gen_mtc0(ctx, t0, rd, ctx->opcode & 0x7);
6918 tcg_temp_free(t0);
6920 opn = "mtc0";
6921 break;
6922 #if defined(TARGET_MIPS64)
6923 case OPC_DMFC0:
6924 check_insn(ctx, ISA_MIPS3);
6925 if (rt == 0) {
6926 /* Treat as NOP. */
6927 return;
6929 gen_dmfc0(ctx, cpu_gpr[rt], rd, ctx->opcode & 0x7);
6930 opn = "dmfc0";
6931 break;
6932 case OPC_DMTC0:
6933 check_insn(ctx, ISA_MIPS3);
6935 TCGv t0 = tcg_temp_new();
6937 gen_load_gpr(t0, rt);
6938 gen_dmtc0(ctx, t0, rd, ctx->opcode & 0x7);
6939 tcg_temp_free(t0);
6941 opn = "dmtc0";
6942 break;
6943 #endif
6944 case OPC_MFTR:
6945 check_insn(ctx, ASE_MT);
6946 if (rd == 0) {
6947 /* Treat as NOP. */
6948 return;
6950 gen_mftr(env, ctx, rt, rd, (ctx->opcode >> 5) & 1,
6951 ctx->opcode & 0x7, (ctx->opcode >> 4) & 1);
6952 opn = "mftr";
6953 break;
6954 case OPC_MTTR:
6955 check_insn(ctx, ASE_MT);
6956 gen_mttr(env, ctx, rd, rt, (ctx->opcode >> 5) & 1,
6957 ctx->opcode & 0x7, (ctx->opcode >> 4) & 1);
6958 opn = "mttr";
6959 break;
6960 case OPC_TLBWI:
6961 opn = "tlbwi";
6962 if (!env->tlb->helper_tlbwi)
6963 goto die;
6964 gen_helper_tlbwi(cpu_env);
6965 break;
6966 case OPC_TLBWR:
6967 opn = "tlbwr";
6968 if (!env->tlb->helper_tlbwr)
6969 goto die;
6970 gen_helper_tlbwr(cpu_env);
6971 break;
6972 case OPC_TLBP:
6973 opn = "tlbp";
6974 if (!env->tlb->helper_tlbp)
6975 goto die;
6976 gen_helper_tlbp(cpu_env);
6977 break;
6978 case OPC_TLBR:
6979 opn = "tlbr";
6980 if (!env->tlb->helper_tlbr)
6981 goto die;
6982 gen_helper_tlbr(cpu_env);
6983 break;
6984 case OPC_ERET:
6985 opn = "eret";
6986 check_insn(ctx, ISA_MIPS2);
6987 gen_helper_eret(cpu_env);
6988 ctx->bstate = BS_EXCP;
6989 break;
6990 case OPC_DERET:
6991 opn = "deret";
6992 check_insn(ctx, ISA_MIPS32);
6993 if (!(ctx->hflags & MIPS_HFLAG_DM)) {
6994 MIPS_INVAL(opn);
6995 generate_exception(ctx, EXCP_RI);
6996 } else {
6997 gen_helper_deret(cpu_env);
6998 ctx->bstate = BS_EXCP;
7000 break;
7001 case OPC_WAIT:
7002 opn = "wait";
7003 check_insn(ctx, ISA_MIPS3 | ISA_MIPS32);
7004 /* If we get an exception, we want to restart at next instruction */
7005 ctx->pc += 4;
7006 save_cpu_state(ctx, 1);
7007 ctx->pc -= 4;
7008 gen_helper_wait(cpu_env);
7009 ctx->bstate = BS_EXCP;
7010 break;
7011 default:
7012 die:
7013 MIPS_INVAL(opn);
7014 generate_exception(ctx, EXCP_RI);
7015 return;
7017 (void)opn; /* avoid a compiler warning */
7018 MIPS_DEBUG("%s %s %d", opn, regnames[rt], rd);
7020 #endif /* !CONFIG_USER_ONLY */
7022 /* CP1 Branches (before delay slot) */
7023 static void gen_compute_branch1(DisasContext *ctx, uint32_t op,
7024 int32_t cc, int32_t offset)
7026 target_ulong btarget;
7027 const char *opn = "cp1 cond branch";
7028 TCGv_i32 t0 = tcg_temp_new_i32();
7030 if (cc != 0)
7031 check_insn(ctx, ISA_MIPS4 | ISA_MIPS32);
7033 btarget = ctx->pc + 4 + offset;
7035 switch (op) {
7036 case OPC_BC1F:
7037 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
7038 tcg_gen_not_i32(t0, t0);
7039 tcg_gen_andi_i32(t0, t0, 1);
7040 tcg_gen_extu_i32_tl(bcond, t0);
7041 opn = "bc1f";
7042 goto not_likely;
7043 case OPC_BC1FL:
7044 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
7045 tcg_gen_not_i32(t0, t0);
7046 tcg_gen_andi_i32(t0, t0, 1);
7047 tcg_gen_extu_i32_tl(bcond, t0);
7048 opn = "bc1fl";
7049 goto likely;
7050 case OPC_BC1T:
7051 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
7052 tcg_gen_andi_i32(t0, t0, 1);
7053 tcg_gen_extu_i32_tl(bcond, t0);
7054 opn = "bc1t";
7055 goto not_likely;
7056 case OPC_BC1TL:
7057 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
7058 tcg_gen_andi_i32(t0, t0, 1);
7059 tcg_gen_extu_i32_tl(bcond, t0);
7060 opn = "bc1tl";
7061 likely:
7062 ctx->hflags |= MIPS_HFLAG_BL;
7063 break;
7064 case OPC_BC1FANY2:
7066 TCGv_i32 t1 = tcg_temp_new_i32();
7067 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
7068 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+1));
7069 tcg_gen_nand_i32(t0, t0, t1);
7070 tcg_temp_free_i32(t1);
7071 tcg_gen_andi_i32(t0, t0, 1);
7072 tcg_gen_extu_i32_tl(bcond, t0);
7074 opn = "bc1any2f";
7075 goto not_likely;
7076 case OPC_BC1TANY2:
7078 TCGv_i32 t1 = tcg_temp_new_i32();
7079 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
7080 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+1));
7081 tcg_gen_or_i32(t0, t0, t1);
7082 tcg_temp_free_i32(t1);
7083 tcg_gen_andi_i32(t0, t0, 1);
7084 tcg_gen_extu_i32_tl(bcond, t0);
7086 opn = "bc1any2t";
7087 goto not_likely;
7088 case OPC_BC1FANY4:
7090 TCGv_i32 t1 = tcg_temp_new_i32();
7091 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
7092 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+1));
7093 tcg_gen_and_i32(t0, t0, t1);
7094 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+2));
7095 tcg_gen_and_i32(t0, t0, t1);
7096 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+3));
7097 tcg_gen_nand_i32(t0, t0, t1);
7098 tcg_temp_free_i32(t1);
7099 tcg_gen_andi_i32(t0, t0, 1);
7100 tcg_gen_extu_i32_tl(bcond, t0);
7102 opn = "bc1any4f";
7103 goto not_likely;
7104 case OPC_BC1TANY4:
7106 TCGv_i32 t1 = tcg_temp_new_i32();
7107 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
7108 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+1));
7109 tcg_gen_or_i32(t0, t0, t1);
7110 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+2));
7111 tcg_gen_or_i32(t0, t0, t1);
7112 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+3));
7113 tcg_gen_or_i32(t0, t0, t1);
7114 tcg_temp_free_i32(t1);
7115 tcg_gen_andi_i32(t0, t0, 1);
7116 tcg_gen_extu_i32_tl(bcond, t0);
7118 opn = "bc1any4t";
7119 not_likely:
7120 ctx->hflags |= MIPS_HFLAG_BC;
7121 break;
7122 default:
7123 MIPS_INVAL(opn);
7124 generate_exception (ctx, EXCP_RI);
7125 goto out;
7127 (void)opn; /* avoid a compiler warning */
7128 MIPS_DEBUG("%s: cond %02x target " TARGET_FMT_lx, opn,
7129 ctx->hflags, btarget);
7130 ctx->btarget = btarget;
7132 out:
7133 tcg_temp_free_i32(t0);
7136 /* Coprocessor 1 (FPU) */
7138 #define FOP(func, fmt) (((fmt) << 21) | (func))
7140 enum fopcode {
7141 OPC_ADD_S = FOP(0, FMT_S),
7142 OPC_SUB_S = FOP(1, FMT_S),
7143 OPC_MUL_S = FOP(2, FMT_S),
7144 OPC_DIV_S = FOP(3, FMT_S),
7145 OPC_SQRT_S = FOP(4, FMT_S),
7146 OPC_ABS_S = FOP(5, FMT_S),
7147 OPC_MOV_S = FOP(6, FMT_S),
7148 OPC_NEG_S = FOP(7, FMT_S),
7149 OPC_ROUND_L_S = FOP(8, FMT_S),
7150 OPC_TRUNC_L_S = FOP(9, FMT_S),
7151 OPC_CEIL_L_S = FOP(10, FMT_S),
7152 OPC_FLOOR_L_S = FOP(11, FMT_S),
7153 OPC_ROUND_W_S = FOP(12, FMT_S),
7154 OPC_TRUNC_W_S = FOP(13, FMT_S),
7155 OPC_CEIL_W_S = FOP(14, FMT_S),
7156 OPC_FLOOR_W_S = FOP(15, FMT_S),
7157 OPC_MOVCF_S = FOP(17, FMT_S),
7158 OPC_MOVZ_S = FOP(18, FMT_S),
7159 OPC_MOVN_S = FOP(19, FMT_S),
7160 OPC_RECIP_S = FOP(21, FMT_S),
7161 OPC_RSQRT_S = FOP(22, FMT_S),
7162 OPC_RECIP2_S = FOP(28, FMT_S),
7163 OPC_RECIP1_S = FOP(29, FMT_S),
7164 OPC_RSQRT1_S = FOP(30, FMT_S),
7165 OPC_RSQRT2_S = FOP(31, FMT_S),
7166 OPC_CVT_D_S = FOP(33, FMT_S),
7167 OPC_CVT_W_S = FOP(36, FMT_S),
7168 OPC_CVT_L_S = FOP(37, FMT_S),
7169 OPC_CVT_PS_S = FOP(38, FMT_S),
7170 OPC_CMP_F_S = FOP (48, FMT_S),
7171 OPC_CMP_UN_S = FOP (49, FMT_S),
7172 OPC_CMP_EQ_S = FOP (50, FMT_S),
7173 OPC_CMP_UEQ_S = FOP (51, FMT_S),
7174 OPC_CMP_OLT_S = FOP (52, FMT_S),
7175 OPC_CMP_ULT_S = FOP (53, FMT_S),
7176 OPC_CMP_OLE_S = FOP (54, FMT_S),
7177 OPC_CMP_ULE_S = FOP (55, FMT_S),
7178 OPC_CMP_SF_S = FOP (56, FMT_S),
7179 OPC_CMP_NGLE_S = FOP (57, FMT_S),
7180 OPC_CMP_SEQ_S = FOP (58, FMT_S),
7181 OPC_CMP_NGL_S = FOP (59, FMT_S),
7182 OPC_CMP_LT_S = FOP (60, FMT_S),
7183 OPC_CMP_NGE_S = FOP (61, FMT_S),
7184 OPC_CMP_LE_S = FOP (62, FMT_S),
7185 OPC_CMP_NGT_S = FOP (63, FMT_S),
7187 OPC_ADD_D = FOP(0, FMT_D),
7188 OPC_SUB_D = FOP(1, FMT_D),
7189 OPC_MUL_D = FOP(2, FMT_D),
7190 OPC_DIV_D = FOP(3, FMT_D),
7191 OPC_SQRT_D = FOP(4, FMT_D),
7192 OPC_ABS_D = FOP(5, FMT_D),
7193 OPC_MOV_D = FOP(6, FMT_D),
7194 OPC_NEG_D = FOP(7, FMT_D),
7195 OPC_ROUND_L_D = FOP(8, FMT_D),
7196 OPC_TRUNC_L_D = FOP(9, FMT_D),
7197 OPC_CEIL_L_D = FOP(10, FMT_D),
7198 OPC_FLOOR_L_D = FOP(11, FMT_D),
7199 OPC_ROUND_W_D = FOP(12, FMT_D),
7200 OPC_TRUNC_W_D = FOP(13, FMT_D),
7201 OPC_CEIL_W_D = FOP(14, FMT_D),
7202 OPC_FLOOR_W_D = FOP(15, FMT_D),
7203 OPC_MOVCF_D = FOP(17, FMT_D),
7204 OPC_MOVZ_D = FOP(18, FMT_D),
7205 OPC_MOVN_D = FOP(19, FMT_D),
7206 OPC_RECIP_D = FOP(21, FMT_D),
7207 OPC_RSQRT_D = FOP(22, FMT_D),
7208 OPC_RECIP2_D = FOP(28, FMT_D),
7209 OPC_RECIP1_D = FOP(29, FMT_D),
7210 OPC_RSQRT1_D = FOP(30, FMT_D),
7211 OPC_RSQRT2_D = FOP(31, FMT_D),
7212 OPC_CVT_S_D = FOP(32, FMT_D),
7213 OPC_CVT_W_D = FOP(36, FMT_D),
7214 OPC_CVT_L_D = FOP(37, FMT_D),
7215 OPC_CMP_F_D = FOP (48, FMT_D),
7216 OPC_CMP_UN_D = FOP (49, FMT_D),
7217 OPC_CMP_EQ_D = FOP (50, FMT_D),
7218 OPC_CMP_UEQ_D = FOP (51, FMT_D),
7219 OPC_CMP_OLT_D = FOP (52, FMT_D),
7220 OPC_CMP_ULT_D = FOP (53, FMT_D),
7221 OPC_CMP_OLE_D = FOP (54, FMT_D),
7222 OPC_CMP_ULE_D = FOP (55, FMT_D),
7223 OPC_CMP_SF_D = FOP (56, FMT_D),
7224 OPC_CMP_NGLE_D = FOP (57, FMT_D),
7225 OPC_CMP_SEQ_D = FOP (58, FMT_D),
7226 OPC_CMP_NGL_D = FOP (59, FMT_D),
7227 OPC_CMP_LT_D = FOP (60, FMT_D),
7228 OPC_CMP_NGE_D = FOP (61, FMT_D),
7229 OPC_CMP_LE_D = FOP (62, FMT_D),
7230 OPC_CMP_NGT_D = FOP (63, FMT_D),
7232 OPC_CVT_S_W = FOP(32, FMT_W),
7233 OPC_CVT_D_W = FOP(33, FMT_W),
7234 OPC_CVT_S_L = FOP(32, FMT_L),
7235 OPC_CVT_D_L = FOP(33, FMT_L),
7236 OPC_CVT_PS_PW = FOP(38, FMT_W),
7238 OPC_ADD_PS = FOP(0, FMT_PS),
7239 OPC_SUB_PS = FOP(1, FMT_PS),
7240 OPC_MUL_PS = FOP(2, FMT_PS),
7241 OPC_DIV_PS = FOP(3, FMT_PS),
7242 OPC_ABS_PS = FOP(5, FMT_PS),
7243 OPC_MOV_PS = FOP(6, FMT_PS),
7244 OPC_NEG_PS = FOP(7, FMT_PS),
7245 OPC_MOVCF_PS = FOP(17, FMT_PS),
7246 OPC_MOVZ_PS = FOP(18, FMT_PS),
7247 OPC_MOVN_PS = FOP(19, FMT_PS),
7248 OPC_ADDR_PS = FOP(24, FMT_PS),
7249 OPC_MULR_PS = FOP(26, FMT_PS),
7250 OPC_RECIP2_PS = FOP(28, FMT_PS),
7251 OPC_RECIP1_PS = FOP(29, FMT_PS),
7252 OPC_RSQRT1_PS = FOP(30, FMT_PS),
7253 OPC_RSQRT2_PS = FOP(31, FMT_PS),
7255 OPC_CVT_S_PU = FOP(32, FMT_PS),
7256 OPC_CVT_PW_PS = FOP(36, FMT_PS),
7257 OPC_CVT_S_PL = FOP(40, FMT_PS),
7258 OPC_PLL_PS = FOP(44, FMT_PS),
7259 OPC_PLU_PS = FOP(45, FMT_PS),
7260 OPC_PUL_PS = FOP(46, FMT_PS),
7261 OPC_PUU_PS = FOP(47, FMT_PS),
7262 OPC_CMP_F_PS = FOP (48, FMT_PS),
7263 OPC_CMP_UN_PS = FOP (49, FMT_PS),
7264 OPC_CMP_EQ_PS = FOP (50, FMT_PS),
7265 OPC_CMP_UEQ_PS = FOP (51, FMT_PS),
7266 OPC_CMP_OLT_PS = FOP (52, FMT_PS),
7267 OPC_CMP_ULT_PS = FOP (53, FMT_PS),
7268 OPC_CMP_OLE_PS = FOP (54, FMT_PS),
7269 OPC_CMP_ULE_PS = FOP (55, FMT_PS),
7270 OPC_CMP_SF_PS = FOP (56, FMT_PS),
7271 OPC_CMP_NGLE_PS = FOP (57, FMT_PS),
7272 OPC_CMP_SEQ_PS = FOP (58, FMT_PS),
7273 OPC_CMP_NGL_PS = FOP (59, FMT_PS),
7274 OPC_CMP_LT_PS = FOP (60, FMT_PS),
7275 OPC_CMP_NGE_PS = FOP (61, FMT_PS),
7276 OPC_CMP_LE_PS = FOP (62, FMT_PS),
7277 OPC_CMP_NGT_PS = FOP (63, FMT_PS),
7280 static void gen_cp1 (DisasContext *ctx, uint32_t opc, int rt, int fs)
7282 const char *opn = "cp1 move";
7283 TCGv t0 = tcg_temp_new();
7285 switch (opc) {
7286 case OPC_MFC1:
7288 TCGv_i32 fp0 = tcg_temp_new_i32();
7290 gen_load_fpr32(fp0, fs);
7291 tcg_gen_ext_i32_tl(t0, fp0);
7292 tcg_temp_free_i32(fp0);
7294 gen_store_gpr(t0, rt);
7295 opn = "mfc1";
7296 break;
7297 case OPC_MTC1:
7298 gen_load_gpr(t0, rt);
7300 TCGv_i32 fp0 = tcg_temp_new_i32();
7302 tcg_gen_trunc_tl_i32(fp0, t0);
7303 gen_store_fpr32(fp0, fs);
7304 tcg_temp_free_i32(fp0);
7306 opn = "mtc1";
7307 break;
7308 case OPC_CFC1:
7309 gen_helper_1e0i(cfc1, t0, fs);
7310 gen_store_gpr(t0, rt);
7311 opn = "cfc1";
7312 break;
7313 case OPC_CTC1:
7314 gen_load_gpr(t0, rt);
7316 TCGv_i32 fs_tmp = tcg_const_i32(fs);
7318 gen_helper_0e2i(ctc1, t0, fs_tmp, rt);
7319 tcg_temp_free_i32(fs_tmp);
7321 opn = "ctc1";
7322 break;
7323 #if defined(TARGET_MIPS64)
7324 case OPC_DMFC1:
7325 gen_load_fpr64(ctx, t0, fs);
7326 gen_store_gpr(t0, rt);
7327 opn = "dmfc1";
7328 break;
7329 case OPC_DMTC1:
7330 gen_load_gpr(t0, rt);
7331 gen_store_fpr64(ctx, t0, fs);
7332 opn = "dmtc1";
7333 break;
7334 #endif
7335 case OPC_MFHC1:
7337 TCGv_i32 fp0 = tcg_temp_new_i32();
7339 gen_load_fpr32h(ctx, fp0, fs);
7340 tcg_gen_ext_i32_tl(t0, fp0);
7341 tcg_temp_free_i32(fp0);
7343 gen_store_gpr(t0, rt);
7344 opn = "mfhc1";
7345 break;
7346 case OPC_MTHC1:
7347 gen_load_gpr(t0, rt);
7349 TCGv_i32 fp0 = tcg_temp_new_i32();
7351 tcg_gen_trunc_tl_i32(fp0, t0);
7352 gen_store_fpr32h(ctx, fp0, fs);
7353 tcg_temp_free_i32(fp0);
7355 opn = "mthc1";
7356 break;
7357 default:
7358 MIPS_INVAL(opn);
7359 generate_exception (ctx, EXCP_RI);
7360 goto out;
7362 (void)opn; /* avoid a compiler warning */
7363 MIPS_DEBUG("%s %s %s", opn, regnames[rt], fregnames[fs]);
7365 out:
7366 tcg_temp_free(t0);
7369 static void gen_movci (DisasContext *ctx, int rd, int rs, int cc, int tf)
7371 int l1;
7372 TCGCond cond;
7373 TCGv_i32 t0;
7375 if (rd == 0) {
7376 /* Treat as NOP. */
7377 return;
7380 if (tf)
7381 cond = TCG_COND_EQ;
7382 else
7383 cond = TCG_COND_NE;
7385 l1 = gen_new_label();
7386 t0 = tcg_temp_new_i32();
7387 tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc));
7388 tcg_gen_brcondi_i32(cond, t0, 0, l1);
7389 tcg_temp_free_i32(t0);
7390 if (rs == 0) {
7391 tcg_gen_movi_tl(cpu_gpr[rd], 0);
7392 } else {
7393 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
7395 gen_set_label(l1);
7398 static inline void gen_movcf_s (int fs, int fd, int cc, int tf)
7400 int cond;
7401 TCGv_i32 t0 = tcg_temp_new_i32();
7402 int l1 = gen_new_label();
7404 if (tf)
7405 cond = TCG_COND_EQ;
7406 else
7407 cond = TCG_COND_NE;
7409 tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc));
7410 tcg_gen_brcondi_i32(cond, t0, 0, l1);
7411 gen_load_fpr32(t0, fs);
7412 gen_store_fpr32(t0, fd);
7413 gen_set_label(l1);
7414 tcg_temp_free_i32(t0);
7417 static inline void gen_movcf_d (DisasContext *ctx, int fs, int fd, int cc, int tf)
7419 int cond;
7420 TCGv_i32 t0 = tcg_temp_new_i32();
7421 TCGv_i64 fp0;
7422 int l1 = gen_new_label();
7424 if (tf)
7425 cond = TCG_COND_EQ;
7426 else
7427 cond = TCG_COND_NE;
7429 tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc));
7430 tcg_gen_brcondi_i32(cond, t0, 0, l1);
7431 tcg_temp_free_i32(t0);
7432 fp0 = tcg_temp_new_i64();
7433 gen_load_fpr64(ctx, fp0, fs);
7434 gen_store_fpr64(ctx, fp0, fd);
7435 tcg_temp_free_i64(fp0);
7436 gen_set_label(l1);
7439 static inline void gen_movcf_ps(DisasContext *ctx, int fs, int fd,
7440 int cc, int tf)
7442 int cond;
7443 TCGv_i32 t0 = tcg_temp_new_i32();
7444 int l1 = gen_new_label();
7445 int l2 = gen_new_label();
7447 if (tf)
7448 cond = TCG_COND_EQ;
7449 else
7450 cond = TCG_COND_NE;
7452 tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc));
7453 tcg_gen_brcondi_i32(cond, t0, 0, l1);
7454 gen_load_fpr32(t0, fs);
7455 gen_store_fpr32(t0, fd);
7456 gen_set_label(l1);
7458 tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc+1));
7459 tcg_gen_brcondi_i32(cond, t0, 0, l2);
7460 gen_load_fpr32h(ctx, t0, fs);
7461 gen_store_fpr32h(ctx, t0, fd);
7462 tcg_temp_free_i32(t0);
7463 gen_set_label(l2);
7467 static void gen_farith (DisasContext *ctx, enum fopcode op1,
7468 int ft, int fs, int fd, int cc)
7470 const char *opn = "farith";
7471 const char *condnames[] = {
7472 "c.f",
7473 "c.un",
7474 "c.eq",
7475 "c.ueq",
7476 "c.olt",
7477 "c.ult",
7478 "c.ole",
7479 "c.ule",
7480 "c.sf",
7481 "c.ngle",
7482 "c.seq",
7483 "c.ngl",
7484 "c.lt",
7485 "c.nge",
7486 "c.le",
7487 "c.ngt",
7489 const char *condnames_abs[] = {
7490 "cabs.f",
7491 "cabs.un",
7492 "cabs.eq",
7493 "cabs.ueq",
7494 "cabs.olt",
7495 "cabs.ult",
7496 "cabs.ole",
7497 "cabs.ule",
7498 "cabs.sf",
7499 "cabs.ngle",
7500 "cabs.seq",
7501 "cabs.ngl",
7502 "cabs.lt",
7503 "cabs.nge",
7504 "cabs.le",
7505 "cabs.ngt",
7507 enum { BINOP, CMPOP, OTHEROP } optype = OTHEROP;
7508 uint32_t func = ctx->opcode & 0x3f;
7510 switch (op1) {
7511 case OPC_ADD_S:
7513 TCGv_i32 fp0 = tcg_temp_new_i32();
7514 TCGv_i32 fp1 = tcg_temp_new_i32();
7516 gen_load_fpr32(fp0, fs);
7517 gen_load_fpr32(fp1, ft);
7518 gen_helper_float_add_s(fp0, cpu_env, fp0, fp1);
7519 tcg_temp_free_i32(fp1);
7520 gen_store_fpr32(fp0, fd);
7521 tcg_temp_free_i32(fp0);
7523 opn = "add.s";
7524 optype = BINOP;
7525 break;
7526 case OPC_SUB_S:
7528 TCGv_i32 fp0 = tcg_temp_new_i32();
7529 TCGv_i32 fp1 = tcg_temp_new_i32();
7531 gen_load_fpr32(fp0, fs);
7532 gen_load_fpr32(fp1, ft);
7533 gen_helper_float_sub_s(fp0, cpu_env, fp0, fp1);
7534 tcg_temp_free_i32(fp1);
7535 gen_store_fpr32(fp0, fd);
7536 tcg_temp_free_i32(fp0);
7538 opn = "sub.s";
7539 optype = BINOP;
7540 break;
7541 case OPC_MUL_S:
7543 TCGv_i32 fp0 = tcg_temp_new_i32();
7544 TCGv_i32 fp1 = tcg_temp_new_i32();
7546 gen_load_fpr32(fp0, fs);
7547 gen_load_fpr32(fp1, ft);
7548 gen_helper_float_mul_s(fp0, cpu_env, fp0, fp1);
7549 tcg_temp_free_i32(fp1);
7550 gen_store_fpr32(fp0, fd);
7551 tcg_temp_free_i32(fp0);
7553 opn = "mul.s";
7554 optype = BINOP;
7555 break;
7556 case OPC_DIV_S:
7558 TCGv_i32 fp0 = tcg_temp_new_i32();
7559 TCGv_i32 fp1 = tcg_temp_new_i32();
7561 gen_load_fpr32(fp0, fs);
7562 gen_load_fpr32(fp1, ft);
7563 gen_helper_float_div_s(fp0, cpu_env, fp0, fp1);
7564 tcg_temp_free_i32(fp1);
7565 gen_store_fpr32(fp0, fd);
7566 tcg_temp_free_i32(fp0);
7568 opn = "div.s";
7569 optype = BINOP;
7570 break;
7571 case OPC_SQRT_S:
7573 TCGv_i32 fp0 = tcg_temp_new_i32();
7575 gen_load_fpr32(fp0, fs);
7576 gen_helper_float_sqrt_s(fp0, cpu_env, fp0);
7577 gen_store_fpr32(fp0, fd);
7578 tcg_temp_free_i32(fp0);
7580 opn = "sqrt.s";
7581 break;
7582 case OPC_ABS_S:
7584 TCGv_i32 fp0 = tcg_temp_new_i32();
7586 gen_load_fpr32(fp0, fs);
7587 gen_helper_float_abs_s(fp0, fp0);
7588 gen_store_fpr32(fp0, fd);
7589 tcg_temp_free_i32(fp0);
7591 opn = "abs.s";
7592 break;
7593 case OPC_MOV_S:
7595 TCGv_i32 fp0 = tcg_temp_new_i32();
7597 gen_load_fpr32(fp0, fs);
7598 gen_store_fpr32(fp0, fd);
7599 tcg_temp_free_i32(fp0);
7601 opn = "mov.s";
7602 break;
7603 case OPC_NEG_S:
7605 TCGv_i32 fp0 = tcg_temp_new_i32();
7607 gen_load_fpr32(fp0, fs);
7608 gen_helper_float_chs_s(fp0, fp0);
7609 gen_store_fpr32(fp0, fd);
7610 tcg_temp_free_i32(fp0);
7612 opn = "neg.s";
7613 break;
7614 case OPC_ROUND_L_S:
7615 check_cp1_64bitmode(ctx);
7617 TCGv_i32 fp32 = tcg_temp_new_i32();
7618 TCGv_i64 fp64 = tcg_temp_new_i64();
7620 gen_load_fpr32(fp32, fs);
7621 gen_helper_float_roundl_s(fp64, cpu_env, fp32);
7622 tcg_temp_free_i32(fp32);
7623 gen_store_fpr64(ctx, fp64, fd);
7624 tcg_temp_free_i64(fp64);
7626 opn = "round.l.s";
7627 break;
7628 case OPC_TRUNC_L_S:
7629 check_cp1_64bitmode(ctx);
7631 TCGv_i32 fp32 = tcg_temp_new_i32();
7632 TCGv_i64 fp64 = tcg_temp_new_i64();
7634 gen_load_fpr32(fp32, fs);
7635 gen_helper_float_truncl_s(fp64, cpu_env, fp32);
7636 tcg_temp_free_i32(fp32);
7637 gen_store_fpr64(ctx, fp64, fd);
7638 tcg_temp_free_i64(fp64);
7640 opn = "trunc.l.s";
7641 break;
7642 case OPC_CEIL_L_S:
7643 check_cp1_64bitmode(ctx);
7645 TCGv_i32 fp32 = tcg_temp_new_i32();
7646 TCGv_i64 fp64 = tcg_temp_new_i64();
7648 gen_load_fpr32(fp32, fs);
7649 gen_helper_float_ceill_s(fp64, cpu_env, fp32);
7650 tcg_temp_free_i32(fp32);
7651 gen_store_fpr64(ctx, fp64, fd);
7652 tcg_temp_free_i64(fp64);
7654 opn = "ceil.l.s";
7655 break;
7656 case OPC_FLOOR_L_S:
7657 check_cp1_64bitmode(ctx);
7659 TCGv_i32 fp32 = tcg_temp_new_i32();
7660 TCGv_i64 fp64 = tcg_temp_new_i64();
7662 gen_load_fpr32(fp32, fs);
7663 gen_helper_float_floorl_s(fp64, cpu_env, fp32);
7664 tcg_temp_free_i32(fp32);
7665 gen_store_fpr64(ctx, fp64, fd);
7666 tcg_temp_free_i64(fp64);
7668 opn = "floor.l.s";
7669 break;
7670 case OPC_ROUND_W_S:
7672 TCGv_i32 fp0 = tcg_temp_new_i32();
7674 gen_load_fpr32(fp0, fs);
7675 gen_helper_float_roundw_s(fp0, cpu_env, fp0);
7676 gen_store_fpr32(fp0, fd);
7677 tcg_temp_free_i32(fp0);
7679 opn = "round.w.s";
7680 break;
7681 case OPC_TRUNC_W_S:
7683 TCGv_i32 fp0 = tcg_temp_new_i32();
7685 gen_load_fpr32(fp0, fs);
7686 gen_helper_float_truncw_s(fp0, cpu_env, fp0);
7687 gen_store_fpr32(fp0, fd);
7688 tcg_temp_free_i32(fp0);
7690 opn = "trunc.w.s";
7691 break;
7692 case OPC_CEIL_W_S:
7694 TCGv_i32 fp0 = tcg_temp_new_i32();
7696 gen_load_fpr32(fp0, fs);
7697 gen_helper_float_ceilw_s(fp0, cpu_env, fp0);
7698 gen_store_fpr32(fp0, fd);
7699 tcg_temp_free_i32(fp0);
7701 opn = "ceil.w.s";
7702 break;
7703 case OPC_FLOOR_W_S:
7705 TCGv_i32 fp0 = tcg_temp_new_i32();
7707 gen_load_fpr32(fp0, fs);
7708 gen_helper_float_floorw_s(fp0, cpu_env, fp0);
7709 gen_store_fpr32(fp0, fd);
7710 tcg_temp_free_i32(fp0);
7712 opn = "floor.w.s";
7713 break;
7714 case OPC_MOVCF_S:
7715 gen_movcf_s(fs, fd, (ft >> 2) & 0x7, ft & 0x1);
7716 opn = "movcf.s";
7717 break;
7718 case OPC_MOVZ_S:
7720 int l1 = gen_new_label();
7721 TCGv_i32 fp0;
7723 if (ft != 0) {
7724 tcg_gen_brcondi_tl(TCG_COND_NE, cpu_gpr[ft], 0, l1);
7726 fp0 = tcg_temp_new_i32();
7727 gen_load_fpr32(fp0, fs);
7728 gen_store_fpr32(fp0, fd);
7729 tcg_temp_free_i32(fp0);
7730 gen_set_label(l1);
7732 opn = "movz.s";
7733 break;
7734 case OPC_MOVN_S:
7736 int l1 = gen_new_label();
7737 TCGv_i32 fp0;
7739 if (ft != 0) {
7740 tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_gpr[ft], 0, l1);
7741 fp0 = tcg_temp_new_i32();
7742 gen_load_fpr32(fp0, fs);
7743 gen_store_fpr32(fp0, fd);
7744 tcg_temp_free_i32(fp0);
7745 gen_set_label(l1);
7748 opn = "movn.s";
7749 break;
7750 case OPC_RECIP_S:
7751 check_cop1x(ctx);
7753 TCGv_i32 fp0 = tcg_temp_new_i32();
7755 gen_load_fpr32(fp0, fs);
7756 gen_helper_float_recip_s(fp0, cpu_env, fp0);
7757 gen_store_fpr32(fp0, fd);
7758 tcg_temp_free_i32(fp0);
7760 opn = "recip.s";
7761 break;
7762 case OPC_RSQRT_S:
7763 check_cop1x(ctx);
7765 TCGv_i32 fp0 = tcg_temp_new_i32();
7767 gen_load_fpr32(fp0, fs);
7768 gen_helper_float_rsqrt_s(fp0, cpu_env, fp0);
7769 gen_store_fpr32(fp0, fd);
7770 tcg_temp_free_i32(fp0);
7772 opn = "rsqrt.s";
7773 break;
7774 case OPC_RECIP2_S:
7775 check_cp1_64bitmode(ctx);
7777 TCGv_i32 fp0 = tcg_temp_new_i32();
7778 TCGv_i32 fp1 = tcg_temp_new_i32();
7780 gen_load_fpr32(fp0, fs);
7781 gen_load_fpr32(fp1, ft);
7782 gen_helper_float_recip2_s(fp0, cpu_env, fp0, fp1);
7783 tcg_temp_free_i32(fp1);
7784 gen_store_fpr32(fp0, fd);
7785 tcg_temp_free_i32(fp0);
7787 opn = "recip2.s";
7788 break;
7789 case OPC_RECIP1_S:
7790 check_cp1_64bitmode(ctx);
7792 TCGv_i32 fp0 = tcg_temp_new_i32();
7794 gen_load_fpr32(fp0, fs);
7795 gen_helper_float_recip1_s(fp0, cpu_env, fp0);
7796 gen_store_fpr32(fp0, fd);
7797 tcg_temp_free_i32(fp0);
7799 opn = "recip1.s";
7800 break;
7801 case OPC_RSQRT1_S:
7802 check_cp1_64bitmode(ctx);
7804 TCGv_i32 fp0 = tcg_temp_new_i32();
7806 gen_load_fpr32(fp0, fs);
7807 gen_helper_float_rsqrt1_s(fp0, cpu_env, fp0);
7808 gen_store_fpr32(fp0, fd);
7809 tcg_temp_free_i32(fp0);
7811 opn = "rsqrt1.s";
7812 break;
7813 case OPC_RSQRT2_S:
7814 check_cp1_64bitmode(ctx);
7816 TCGv_i32 fp0 = tcg_temp_new_i32();
7817 TCGv_i32 fp1 = tcg_temp_new_i32();
7819 gen_load_fpr32(fp0, fs);
7820 gen_load_fpr32(fp1, ft);
7821 gen_helper_float_rsqrt2_s(fp0, cpu_env, fp0, fp1);
7822 tcg_temp_free_i32(fp1);
7823 gen_store_fpr32(fp0, fd);
7824 tcg_temp_free_i32(fp0);
7826 opn = "rsqrt2.s";
7827 break;
7828 case OPC_CVT_D_S:
7829 check_cp1_registers(ctx, fd);
7831 TCGv_i32 fp32 = tcg_temp_new_i32();
7832 TCGv_i64 fp64 = tcg_temp_new_i64();
7834 gen_load_fpr32(fp32, fs);
7835 gen_helper_float_cvtd_s(fp64, cpu_env, fp32);
7836 tcg_temp_free_i32(fp32);
7837 gen_store_fpr64(ctx, fp64, fd);
7838 tcg_temp_free_i64(fp64);
7840 opn = "cvt.d.s";
7841 break;
7842 case OPC_CVT_W_S:
7844 TCGv_i32 fp0 = tcg_temp_new_i32();
7846 gen_load_fpr32(fp0, fs);
7847 gen_helper_float_cvtw_s(fp0, cpu_env, fp0);
7848 gen_store_fpr32(fp0, fd);
7849 tcg_temp_free_i32(fp0);
7851 opn = "cvt.w.s";
7852 break;
7853 case OPC_CVT_L_S:
7854 check_cp1_64bitmode(ctx);
7856 TCGv_i32 fp32 = tcg_temp_new_i32();
7857 TCGv_i64 fp64 = tcg_temp_new_i64();
7859 gen_load_fpr32(fp32, fs);
7860 gen_helper_float_cvtl_s(fp64, cpu_env, fp32);
7861 tcg_temp_free_i32(fp32);
7862 gen_store_fpr64(ctx, fp64, fd);
7863 tcg_temp_free_i64(fp64);
7865 opn = "cvt.l.s";
7866 break;
7867 case OPC_CVT_PS_S:
7868 check_cp1_64bitmode(ctx);
7870 TCGv_i64 fp64 = tcg_temp_new_i64();
7871 TCGv_i32 fp32_0 = tcg_temp_new_i32();
7872 TCGv_i32 fp32_1 = tcg_temp_new_i32();
7874 gen_load_fpr32(fp32_0, fs);
7875 gen_load_fpr32(fp32_1, ft);
7876 tcg_gen_concat_i32_i64(fp64, fp32_1, fp32_0);
7877 tcg_temp_free_i32(fp32_1);
7878 tcg_temp_free_i32(fp32_0);
7879 gen_store_fpr64(ctx, fp64, fd);
7880 tcg_temp_free_i64(fp64);
7882 opn = "cvt.ps.s";
7883 break;
7884 case OPC_CMP_F_S:
7885 case OPC_CMP_UN_S:
7886 case OPC_CMP_EQ_S:
7887 case OPC_CMP_UEQ_S:
7888 case OPC_CMP_OLT_S:
7889 case OPC_CMP_ULT_S:
7890 case OPC_CMP_OLE_S:
7891 case OPC_CMP_ULE_S:
7892 case OPC_CMP_SF_S:
7893 case OPC_CMP_NGLE_S:
7894 case OPC_CMP_SEQ_S:
7895 case OPC_CMP_NGL_S:
7896 case OPC_CMP_LT_S:
7897 case OPC_CMP_NGE_S:
7898 case OPC_CMP_LE_S:
7899 case OPC_CMP_NGT_S:
7900 if (ctx->opcode & (1 << 6)) {
7901 gen_cmpabs_s(ctx, func-48, ft, fs, cc);
7902 opn = condnames_abs[func-48];
7903 } else {
7904 gen_cmp_s(ctx, func-48, ft, fs, cc);
7905 opn = condnames[func-48];
7907 break;
7908 case OPC_ADD_D:
7909 check_cp1_registers(ctx, fs | ft | fd);
7911 TCGv_i64 fp0 = tcg_temp_new_i64();
7912 TCGv_i64 fp1 = tcg_temp_new_i64();
7914 gen_load_fpr64(ctx, fp0, fs);
7915 gen_load_fpr64(ctx, fp1, ft);
7916 gen_helper_float_add_d(fp0, cpu_env, fp0, fp1);
7917 tcg_temp_free_i64(fp1);
7918 gen_store_fpr64(ctx, fp0, fd);
7919 tcg_temp_free_i64(fp0);
7921 opn = "add.d";
7922 optype = BINOP;
7923 break;
7924 case OPC_SUB_D:
7925 check_cp1_registers(ctx, fs | ft | fd);
7927 TCGv_i64 fp0 = tcg_temp_new_i64();
7928 TCGv_i64 fp1 = tcg_temp_new_i64();
7930 gen_load_fpr64(ctx, fp0, fs);
7931 gen_load_fpr64(ctx, fp1, ft);
7932 gen_helper_float_sub_d(fp0, cpu_env, fp0, fp1);
7933 tcg_temp_free_i64(fp1);
7934 gen_store_fpr64(ctx, fp0, fd);
7935 tcg_temp_free_i64(fp0);
7937 opn = "sub.d";
7938 optype = BINOP;
7939 break;
7940 case OPC_MUL_D:
7941 check_cp1_registers(ctx, fs | ft | fd);
7943 TCGv_i64 fp0 = tcg_temp_new_i64();
7944 TCGv_i64 fp1 = tcg_temp_new_i64();
7946 gen_load_fpr64(ctx, fp0, fs);
7947 gen_load_fpr64(ctx, fp1, ft);
7948 gen_helper_float_mul_d(fp0, cpu_env, fp0, fp1);
7949 tcg_temp_free_i64(fp1);
7950 gen_store_fpr64(ctx, fp0, fd);
7951 tcg_temp_free_i64(fp0);
7953 opn = "mul.d";
7954 optype = BINOP;
7955 break;
7956 case OPC_DIV_D:
7957 check_cp1_registers(ctx, fs | ft | fd);
7959 TCGv_i64 fp0 = tcg_temp_new_i64();
7960 TCGv_i64 fp1 = tcg_temp_new_i64();
7962 gen_load_fpr64(ctx, fp0, fs);
7963 gen_load_fpr64(ctx, fp1, ft);
7964 gen_helper_float_div_d(fp0, cpu_env, fp0, fp1);
7965 tcg_temp_free_i64(fp1);
7966 gen_store_fpr64(ctx, fp0, fd);
7967 tcg_temp_free_i64(fp0);
7969 opn = "div.d";
7970 optype = BINOP;
7971 break;
7972 case OPC_SQRT_D:
7973 check_cp1_registers(ctx, fs | fd);
7975 TCGv_i64 fp0 = tcg_temp_new_i64();
7977 gen_load_fpr64(ctx, fp0, fs);
7978 gen_helper_float_sqrt_d(fp0, cpu_env, fp0);
7979 gen_store_fpr64(ctx, fp0, fd);
7980 tcg_temp_free_i64(fp0);
7982 opn = "sqrt.d";
7983 break;
7984 case OPC_ABS_D:
7985 check_cp1_registers(ctx, fs | fd);
7987 TCGv_i64 fp0 = tcg_temp_new_i64();
7989 gen_load_fpr64(ctx, fp0, fs);
7990 gen_helper_float_abs_d(fp0, fp0);
7991 gen_store_fpr64(ctx, fp0, fd);
7992 tcg_temp_free_i64(fp0);
7994 opn = "abs.d";
7995 break;
7996 case OPC_MOV_D:
7997 check_cp1_registers(ctx, fs | fd);
7999 TCGv_i64 fp0 = tcg_temp_new_i64();
8001 gen_load_fpr64(ctx, fp0, fs);
8002 gen_store_fpr64(ctx, fp0, fd);
8003 tcg_temp_free_i64(fp0);
8005 opn = "mov.d";
8006 break;
8007 case OPC_NEG_D:
8008 check_cp1_registers(ctx, fs | fd);
8010 TCGv_i64 fp0 = tcg_temp_new_i64();
8012 gen_load_fpr64(ctx, fp0, fs);
8013 gen_helper_float_chs_d(fp0, fp0);
8014 gen_store_fpr64(ctx, fp0, fd);
8015 tcg_temp_free_i64(fp0);
8017 opn = "neg.d";
8018 break;
8019 case OPC_ROUND_L_D:
8020 check_cp1_64bitmode(ctx);
8022 TCGv_i64 fp0 = tcg_temp_new_i64();
8024 gen_load_fpr64(ctx, fp0, fs);
8025 gen_helper_float_roundl_d(fp0, cpu_env, fp0);
8026 gen_store_fpr64(ctx, fp0, fd);
8027 tcg_temp_free_i64(fp0);
8029 opn = "round.l.d";
8030 break;
8031 case OPC_TRUNC_L_D:
8032 check_cp1_64bitmode(ctx);
8034 TCGv_i64 fp0 = tcg_temp_new_i64();
8036 gen_load_fpr64(ctx, fp0, fs);
8037 gen_helper_float_truncl_d(fp0, cpu_env, fp0);
8038 gen_store_fpr64(ctx, fp0, fd);
8039 tcg_temp_free_i64(fp0);
8041 opn = "trunc.l.d";
8042 break;
8043 case OPC_CEIL_L_D:
8044 check_cp1_64bitmode(ctx);
8046 TCGv_i64 fp0 = tcg_temp_new_i64();
8048 gen_load_fpr64(ctx, fp0, fs);
8049 gen_helper_float_ceill_d(fp0, cpu_env, fp0);
8050 gen_store_fpr64(ctx, fp0, fd);
8051 tcg_temp_free_i64(fp0);
8053 opn = "ceil.l.d";
8054 break;
8055 case OPC_FLOOR_L_D:
8056 check_cp1_64bitmode(ctx);
8058 TCGv_i64 fp0 = tcg_temp_new_i64();
8060 gen_load_fpr64(ctx, fp0, fs);
8061 gen_helper_float_floorl_d(fp0, cpu_env, fp0);
8062 gen_store_fpr64(ctx, fp0, fd);
8063 tcg_temp_free_i64(fp0);
8065 opn = "floor.l.d";
8066 break;
8067 case OPC_ROUND_W_D:
8068 check_cp1_registers(ctx, fs);
8070 TCGv_i32 fp32 = tcg_temp_new_i32();
8071 TCGv_i64 fp64 = tcg_temp_new_i64();
8073 gen_load_fpr64(ctx, fp64, fs);
8074 gen_helper_float_roundw_d(fp32, cpu_env, fp64);
8075 tcg_temp_free_i64(fp64);
8076 gen_store_fpr32(fp32, fd);
8077 tcg_temp_free_i32(fp32);
8079 opn = "round.w.d";
8080 break;
8081 case OPC_TRUNC_W_D:
8082 check_cp1_registers(ctx, fs);
8084 TCGv_i32 fp32 = tcg_temp_new_i32();
8085 TCGv_i64 fp64 = tcg_temp_new_i64();
8087 gen_load_fpr64(ctx, fp64, fs);
8088 gen_helper_float_truncw_d(fp32, cpu_env, fp64);
8089 tcg_temp_free_i64(fp64);
8090 gen_store_fpr32(fp32, fd);
8091 tcg_temp_free_i32(fp32);
8093 opn = "trunc.w.d";
8094 break;
8095 case OPC_CEIL_W_D:
8096 check_cp1_registers(ctx, fs);
8098 TCGv_i32 fp32 = tcg_temp_new_i32();
8099 TCGv_i64 fp64 = tcg_temp_new_i64();
8101 gen_load_fpr64(ctx, fp64, fs);
8102 gen_helper_float_ceilw_d(fp32, cpu_env, fp64);
8103 tcg_temp_free_i64(fp64);
8104 gen_store_fpr32(fp32, fd);
8105 tcg_temp_free_i32(fp32);
8107 opn = "ceil.w.d";
8108 break;
8109 case OPC_FLOOR_W_D:
8110 check_cp1_registers(ctx, fs);
8112 TCGv_i32 fp32 = tcg_temp_new_i32();
8113 TCGv_i64 fp64 = tcg_temp_new_i64();
8115 gen_load_fpr64(ctx, fp64, fs);
8116 gen_helper_float_floorw_d(fp32, cpu_env, fp64);
8117 tcg_temp_free_i64(fp64);
8118 gen_store_fpr32(fp32, fd);
8119 tcg_temp_free_i32(fp32);
8121 opn = "floor.w.d";
8122 break;
8123 case OPC_MOVCF_D:
8124 gen_movcf_d(ctx, fs, fd, (ft >> 2) & 0x7, ft & 0x1);
8125 opn = "movcf.d";
8126 break;
8127 case OPC_MOVZ_D:
8129 int l1 = gen_new_label();
8130 TCGv_i64 fp0;
8132 if (ft != 0) {
8133 tcg_gen_brcondi_tl(TCG_COND_NE, cpu_gpr[ft], 0, l1);
8135 fp0 = tcg_temp_new_i64();
8136 gen_load_fpr64(ctx, fp0, fs);
8137 gen_store_fpr64(ctx, fp0, fd);
8138 tcg_temp_free_i64(fp0);
8139 gen_set_label(l1);
8141 opn = "movz.d";
8142 break;
8143 case OPC_MOVN_D:
8145 int l1 = gen_new_label();
8146 TCGv_i64 fp0;
8148 if (ft != 0) {
8149 tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_gpr[ft], 0, l1);
8150 fp0 = tcg_temp_new_i64();
8151 gen_load_fpr64(ctx, fp0, fs);
8152 gen_store_fpr64(ctx, fp0, fd);
8153 tcg_temp_free_i64(fp0);
8154 gen_set_label(l1);
8157 opn = "movn.d";
8158 break;
8159 case OPC_RECIP_D:
8160 check_cp1_64bitmode(ctx);
8162 TCGv_i64 fp0 = tcg_temp_new_i64();
8164 gen_load_fpr64(ctx, fp0, fs);
8165 gen_helper_float_recip_d(fp0, cpu_env, fp0);
8166 gen_store_fpr64(ctx, fp0, fd);
8167 tcg_temp_free_i64(fp0);
8169 opn = "recip.d";
8170 break;
8171 case OPC_RSQRT_D:
8172 check_cp1_64bitmode(ctx);
8174 TCGv_i64 fp0 = tcg_temp_new_i64();
8176 gen_load_fpr64(ctx, fp0, fs);
8177 gen_helper_float_rsqrt_d(fp0, cpu_env, fp0);
8178 gen_store_fpr64(ctx, fp0, fd);
8179 tcg_temp_free_i64(fp0);
8181 opn = "rsqrt.d";
8182 break;
8183 case OPC_RECIP2_D:
8184 check_cp1_64bitmode(ctx);
8186 TCGv_i64 fp0 = tcg_temp_new_i64();
8187 TCGv_i64 fp1 = tcg_temp_new_i64();
8189 gen_load_fpr64(ctx, fp0, fs);
8190 gen_load_fpr64(ctx, fp1, ft);
8191 gen_helper_float_recip2_d(fp0, cpu_env, fp0, fp1);
8192 tcg_temp_free_i64(fp1);
8193 gen_store_fpr64(ctx, fp0, fd);
8194 tcg_temp_free_i64(fp0);
8196 opn = "recip2.d";
8197 break;
8198 case OPC_RECIP1_D:
8199 check_cp1_64bitmode(ctx);
8201 TCGv_i64 fp0 = tcg_temp_new_i64();
8203 gen_load_fpr64(ctx, fp0, fs);
8204 gen_helper_float_recip1_d(fp0, cpu_env, fp0);
8205 gen_store_fpr64(ctx, fp0, fd);
8206 tcg_temp_free_i64(fp0);
8208 opn = "recip1.d";
8209 break;
8210 case OPC_RSQRT1_D:
8211 check_cp1_64bitmode(ctx);
8213 TCGv_i64 fp0 = tcg_temp_new_i64();
8215 gen_load_fpr64(ctx, fp0, fs);
8216 gen_helper_float_rsqrt1_d(fp0, cpu_env, fp0);
8217 gen_store_fpr64(ctx, fp0, fd);
8218 tcg_temp_free_i64(fp0);
8220 opn = "rsqrt1.d";
8221 break;
8222 case OPC_RSQRT2_D:
8223 check_cp1_64bitmode(ctx);
8225 TCGv_i64 fp0 = tcg_temp_new_i64();
8226 TCGv_i64 fp1 = tcg_temp_new_i64();
8228 gen_load_fpr64(ctx, fp0, fs);
8229 gen_load_fpr64(ctx, fp1, ft);
8230 gen_helper_float_rsqrt2_d(fp0, cpu_env, fp0, fp1);
8231 tcg_temp_free_i64(fp1);
8232 gen_store_fpr64(ctx, fp0, fd);
8233 tcg_temp_free_i64(fp0);
8235 opn = "rsqrt2.d";
8236 break;
8237 case OPC_CMP_F_D:
8238 case OPC_CMP_UN_D:
8239 case OPC_CMP_EQ_D:
8240 case OPC_CMP_UEQ_D:
8241 case OPC_CMP_OLT_D:
8242 case OPC_CMP_ULT_D:
8243 case OPC_CMP_OLE_D:
8244 case OPC_CMP_ULE_D:
8245 case OPC_CMP_SF_D:
8246 case OPC_CMP_NGLE_D:
8247 case OPC_CMP_SEQ_D:
8248 case OPC_CMP_NGL_D:
8249 case OPC_CMP_LT_D:
8250 case OPC_CMP_NGE_D:
8251 case OPC_CMP_LE_D:
8252 case OPC_CMP_NGT_D:
8253 if (ctx->opcode & (1 << 6)) {
8254 gen_cmpabs_d(ctx, func-48, ft, fs, cc);
8255 opn = condnames_abs[func-48];
8256 } else {
8257 gen_cmp_d(ctx, func-48, ft, fs, cc);
8258 opn = condnames[func-48];
8260 break;
8261 case OPC_CVT_S_D:
8262 check_cp1_registers(ctx, fs);
8264 TCGv_i32 fp32 = tcg_temp_new_i32();
8265 TCGv_i64 fp64 = tcg_temp_new_i64();
8267 gen_load_fpr64(ctx, fp64, fs);
8268 gen_helper_float_cvts_d(fp32, cpu_env, fp64);
8269 tcg_temp_free_i64(fp64);
8270 gen_store_fpr32(fp32, fd);
8271 tcg_temp_free_i32(fp32);
8273 opn = "cvt.s.d";
8274 break;
8275 case OPC_CVT_W_D:
8276 check_cp1_registers(ctx, fs);
8278 TCGv_i32 fp32 = tcg_temp_new_i32();
8279 TCGv_i64 fp64 = tcg_temp_new_i64();
8281 gen_load_fpr64(ctx, fp64, fs);
8282 gen_helper_float_cvtw_d(fp32, cpu_env, fp64);
8283 tcg_temp_free_i64(fp64);
8284 gen_store_fpr32(fp32, fd);
8285 tcg_temp_free_i32(fp32);
8287 opn = "cvt.w.d";
8288 break;
8289 case OPC_CVT_L_D:
8290 check_cp1_64bitmode(ctx);
8292 TCGv_i64 fp0 = tcg_temp_new_i64();
8294 gen_load_fpr64(ctx, fp0, fs);
8295 gen_helper_float_cvtl_d(fp0, cpu_env, fp0);
8296 gen_store_fpr64(ctx, fp0, fd);
8297 tcg_temp_free_i64(fp0);
8299 opn = "cvt.l.d";
8300 break;
8301 case OPC_CVT_S_W:
8303 TCGv_i32 fp0 = tcg_temp_new_i32();
8305 gen_load_fpr32(fp0, fs);
8306 gen_helper_float_cvts_w(fp0, cpu_env, fp0);
8307 gen_store_fpr32(fp0, fd);
8308 tcg_temp_free_i32(fp0);
8310 opn = "cvt.s.w";
8311 break;
8312 case OPC_CVT_D_W:
8313 check_cp1_registers(ctx, fd);
8315 TCGv_i32 fp32 = tcg_temp_new_i32();
8316 TCGv_i64 fp64 = tcg_temp_new_i64();
8318 gen_load_fpr32(fp32, fs);
8319 gen_helper_float_cvtd_w(fp64, cpu_env, fp32);
8320 tcg_temp_free_i32(fp32);
8321 gen_store_fpr64(ctx, fp64, fd);
8322 tcg_temp_free_i64(fp64);
8324 opn = "cvt.d.w";
8325 break;
8326 case OPC_CVT_S_L:
8327 check_cp1_64bitmode(ctx);
8329 TCGv_i32 fp32 = tcg_temp_new_i32();
8330 TCGv_i64 fp64 = tcg_temp_new_i64();
8332 gen_load_fpr64(ctx, fp64, fs);
8333 gen_helper_float_cvts_l(fp32, cpu_env, fp64);
8334 tcg_temp_free_i64(fp64);
8335 gen_store_fpr32(fp32, fd);
8336 tcg_temp_free_i32(fp32);
8338 opn = "cvt.s.l";
8339 break;
8340 case OPC_CVT_D_L:
8341 check_cp1_64bitmode(ctx);
8343 TCGv_i64 fp0 = tcg_temp_new_i64();
8345 gen_load_fpr64(ctx, fp0, fs);
8346 gen_helper_float_cvtd_l(fp0, cpu_env, fp0);
8347 gen_store_fpr64(ctx, fp0, fd);
8348 tcg_temp_free_i64(fp0);
8350 opn = "cvt.d.l";
8351 break;
8352 case OPC_CVT_PS_PW:
8353 check_cp1_64bitmode(ctx);
8355 TCGv_i64 fp0 = tcg_temp_new_i64();
8357 gen_load_fpr64(ctx, fp0, fs);
8358 gen_helper_float_cvtps_pw(fp0, cpu_env, fp0);
8359 gen_store_fpr64(ctx, fp0, fd);
8360 tcg_temp_free_i64(fp0);
8362 opn = "cvt.ps.pw";
8363 break;
8364 case OPC_ADD_PS:
8365 check_cp1_64bitmode(ctx);
8367 TCGv_i64 fp0 = tcg_temp_new_i64();
8368 TCGv_i64 fp1 = tcg_temp_new_i64();
8370 gen_load_fpr64(ctx, fp0, fs);
8371 gen_load_fpr64(ctx, fp1, ft);
8372 gen_helper_float_add_ps(fp0, cpu_env, fp0, fp1);
8373 tcg_temp_free_i64(fp1);
8374 gen_store_fpr64(ctx, fp0, fd);
8375 tcg_temp_free_i64(fp0);
8377 opn = "add.ps";
8378 break;
8379 case OPC_SUB_PS:
8380 check_cp1_64bitmode(ctx);
8382 TCGv_i64 fp0 = tcg_temp_new_i64();
8383 TCGv_i64 fp1 = tcg_temp_new_i64();
8385 gen_load_fpr64(ctx, fp0, fs);
8386 gen_load_fpr64(ctx, fp1, ft);
8387 gen_helper_float_sub_ps(fp0, cpu_env, fp0, fp1);
8388 tcg_temp_free_i64(fp1);
8389 gen_store_fpr64(ctx, fp0, fd);
8390 tcg_temp_free_i64(fp0);
8392 opn = "sub.ps";
8393 break;
8394 case OPC_MUL_PS:
8395 check_cp1_64bitmode(ctx);
8397 TCGv_i64 fp0 = tcg_temp_new_i64();
8398 TCGv_i64 fp1 = tcg_temp_new_i64();
8400 gen_load_fpr64(ctx, fp0, fs);
8401 gen_load_fpr64(ctx, fp1, ft);
8402 gen_helper_float_mul_ps(fp0, cpu_env, fp0, fp1);
8403 tcg_temp_free_i64(fp1);
8404 gen_store_fpr64(ctx, fp0, fd);
8405 tcg_temp_free_i64(fp0);
8407 opn = "mul.ps";
8408 break;
8409 case OPC_ABS_PS:
8410 check_cp1_64bitmode(ctx);
8412 TCGv_i64 fp0 = tcg_temp_new_i64();
8414 gen_load_fpr64(ctx, fp0, fs);
8415 gen_helper_float_abs_ps(fp0, fp0);
8416 gen_store_fpr64(ctx, fp0, fd);
8417 tcg_temp_free_i64(fp0);
8419 opn = "abs.ps";
8420 break;
8421 case OPC_MOV_PS:
8422 check_cp1_64bitmode(ctx);
8424 TCGv_i64 fp0 = tcg_temp_new_i64();
8426 gen_load_fpr64(ctx, fp0, fs);
8427 gen_store_fpr64(ctx, fp0, fd);
8428 tcg_temp_free_i64(fp0);
8430 opn = "mov.ps";
8431 break;
8432 case OPC_NEG_PS:
8433 check_cp1_64bitmode(ctx);
8435 TCGv_i64 fp0 = tcg_temp_new_i64();
8437 gen_load_fpr64(ctx, fp0, fs);
8438 gen_helper_float_chs_ps(fp0, fp0);
8439 gen_store_fpr64(ctx, fp0, fd);
8440 tcg_temp_free_i64(fp0);
8442 opn = "neg.ps";
8443 break;
8444 case OPC_MOVCF_PS:
8445 check_cp1_64bitmode(ctx);
8446 gen_movcf_ps(ctx, fs, fd, (ft >> 2) & 0x7, ft & 0x1);
8447 opn = "movcf.ps";
8448 break;
8449 case OPC_MOVZ_PS:
8450 check_cp1_64bitmode(ctx);
8452 int l1 = gen_new_label();
8453 TCGv_i64 fp0;
8455 if (ft != 0)
8456 tcg_gen_brcondi_tl(TCG_COND_NE, cpu_gpr[ft], 0, l1);
8457 fp0 = tcg_temp_new_i64();
8458 gen_load_fpr64(ctx, fp0, fs);
8459 gen_store_fpr64(ctx, fp0, fd);
8460 tcg_temp_free_i64(fp0);
8461 gen_set_label(l1);
8463 opn = "movz.ps";
8464 break;
8465 case OPC_MOVN_PS:
8466 check_cp1_64bitmode(ctx);
8468 int l1 = gen_new_label();
8469 TCGv_i64 fp0;
8471 if (ft != 0) {
8472 tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_gpr[ft], 0, l1);
8473 fp0 = tcg_temp_new_i64();
8474 gen_load_fpr64(ctx, fp0, fs);
8475 gen_store_fpr64(ctx, fp0, fd);
8476 tcg_temp_free_i64(fp0);
8477 gen_set_label(l1);
8480 opn = "movn.ps";
8481 break;
8482 case OPC_ADDR_PS:
8483 check_cp1_64bitmode(ctx);
8485 TCGv_i64 fp0 = tcg_temp_new_i64();
8486 TCGv_i64 fp1 = tcg_temp_new_i64();
8488 gen_load_fpr64(ctx, fp0, ft);
8489 gen_load_fpr64(ctx, fp1, fs);
8490 gen_helper_float_addr_ps(fp0, cpu_env, fp0, fp1);
8491 tcg_temp_free_i64(fp1);
8492 gen_store_fpr64(ctx, fp0, fd);
8493 tcg_temp_free_i64(fp0);
8495 opn = "addr.ps";
8496 break;
8497 case OPC_MULR_PS:
8498 check_cp1_64bitmode(ctx);
8500 TCGv_i64 fp0 = tcg_temp_new_i64();
8501 TCGv_i64 fp1 = tcg_temp_new_i64();
8503 gen_load_fpr64(ctx, fp0, ft);
8504 gen_load_fpr64(ctx, fp1, fs);
8505 gen_helper_float_mulr_ps(fp0, cpu_env, fp0, fp1);
8506 tcg_temp_free_i64(fp1);
8507 gen_store_fpr64(ctx, fp0, fd);
8508 tcg_temp_free_i64(fp0);
8510 opn = "mulr.ps";
8511 break;
8512 case OPC_RECIP2_PS:
8513 check_cp1_64bitmode(ctx);
8515 TCGv_i64 fp0 = tcg_temp_new_i64();
8516 TCGv_i64 fp1 = tcg_temp_new_i64();
8518 gen_load_fpr64(ctx, fp0, fs);
8519 gen_load_fpr64(ctx, fp1, ft);
8520 gen_helper_float_recip2_ps(fp0, cpu_env, fp0, fp1);
8521 tcg_temp_free_i64(fp1);
8522 gen_store_fpr64(ctx, fp0, fd);
8523 tcg_temp_free_i64(fp0);
8525 opn = "recip2.ps";
8526 break;
8527 case OPC_RECIP1_PS:
8528 check_cp1_64bitmode(ctx);
8530 TCGv_i64 fp0 = tcg_temp_new_i64();
8532 gen_load_fpr64(ctx, fp0, fs);
8533 gen_helper_float_recip1_ps(fp0, cpu_env, fp0);
8534 gen_store_fpr64(ctx, fp0, fd);
8535 tcg_temp_free_i64(fp0);
8537 opn = "recip1.ps";
8538 break;
8539 case OPC_RSQRT1_PS:
8540 check_cp1_64bitmode(ctx);
8542 TCGv_i64 fp0 = tcg_temp_new_i64();
8544 gen_load_fpr64(ctx, fp0, fs);
8545 gen_helper_float_rsqrt1_ps(fp0, cpu_env, fp0);
8546 gen_store_fpr64(ctx, fp0, fd);
8547 tcg_temp_free_i64(fp0);
8549 opn = "rsqrt1.ps";
8550 break;
8551 case OPC_RSQRT2_PS:
8552 check_cp1_64bitmode(ctx);
8554 TCGv_i64 fp0 = tcg_temp_new_i64();
8555 TCGv_i64 fp1 = tcg_temp_new_i64();
8557 gen_load_fpr64(ctx, fp0, fs);
8558 gen_load_fpr64(ctx, fp1, ft);
8559 gen_helper_float_rsqrt2_ps(fp0, cpu_env, fp0, fp1);
8560 tcg_temp_free_i64(fp1);
8561 gen_store_fpr64(ctx, fp0, fd);
8562 tcg_temp_free_i64(fp0);
8564 opn = "rsqrt2.ps";
8565 break;
8566 case OPC_CVT_S_PU:
8567 check_cp1_64bitmode(ctx);
8569 TCGv_i32 fp0 = tcg_temp_new_i32();
8571 gen_load_fpr32h(ctx, fp0, fs);
8572 gen_helper_float_cvts_pu(fp0, cpu_env, fp0);
8573 gen_store_fpr32(fp0, fd);
8574 tcg_temp_free_i32(fp0);
8576 opn = "cvt.s.pu";
8577 break;
8578 case OPC_CVT_PW_PS:
8579 check_cp1_64bitmode(ctx);
8581 TCGv_i64 fp0 = tcg_temp_new_i64();
8583 gen_load_fpr64(ctx, fp0, fs);
8584 gen_helper_float_cvtpw_ps(fp0, cpu_env, fp0);
8585 gen_store_fpr64(ctx, fp0, fd);
8586 tcg_temp_free_i64(fp0);
8588 opn = "cvt.pw.ps";
8589 break;
8590 case OPC_CVT_S_PL:
8591 check_cp1_64bitmode(ctx);
8593 TCGv_i32 fp0 = tcg_temp_new_i32();
8595 gen_load_fpr32(fp0, fs);
8596 gen_helper_float_cvts_pl(fp0, cpu_env, fp0);
8597 gen_store_fpr32(fp0, fd);
8598 tcg_temp_free_i32(fp0);
8600 opn = "cvt.s.pl";
8601 break;
8602 case OPC_PLL_PS:
8603 check_cp1_64bitmode(ctx);
8605 TCGv_i32 fp0 = tcg_temp_new_i32();
8606 TCGv_i32 fp1 = tcg_temp_new_i32();
8608 gen_load_fpr32(fp0, fs);
8609 gen_load_fpr32(fp1, ft);
8610 gen_store_fpr32h(ctx, fp0, fd);
8611 gen_store_fpr32(fp1, fd);
8612 tcg_temp_free_i32(fp0);
8613 tcg_temp_free_i32(fp1);
8615 opn = "pll.ps";
8616 break;
8617 case OPC_PLU_PS:
8618 check_cp1_64bitmode(ctx);
8620 TCGv_i32 fp0 = tcg_temp_new_i32();
8621 TCGv_i32 fp1 = tcg_temp_new_i32();
8623 gen_load_fpr32(fp0, fs);
8624 gen_load_fpr32h(ctx, fp1, ft);
8625 gen_store_fpr32(fp1, fd);
8626 gen_store_fpr32h(ctx, fp0, fd);
8627 tcg_temp_free_i32(fp0);
8628 tcg_temp_free_i32(fp1);
8630 opn = "plu.ps";
8631 break;
8632 case OPC_PUL_PS:
8633 check_cp1_64bitmode(ctx);
8635 TCGv_i32 fp0 = tcg_temp_new_i32();
8636 TCGv_i32 fp1 = tcg_temp_new_i32();
8638 gen_load_fpr32h(ctx, fp0, fs);
8639 gen_load_fpr32(fp1, ft);
8640 gen_store_fpr32(fp1, fd);
8641 gen_store_fpr32h(ctx, fp0, fd);
8642 tcg_temp_free_i32(fp0);
8643 tcg_temp_free_i32(fp1);
8645 opn = "pul.ps";
8646 break;
8647 case OPC_PUU_PS:
8648 check_cp1_64bitmode(ctx);
8650 TCGv_i32 fp0 = tcg_temp_new_i32();
8651 TCGv_i32 fp1 = tcg_temp_new_i32();
8653 gen_load_fpr32h(ctx, fp0, fs);
8654 gen_load_fpr32h(ctx, fp1, ft);
8655 gen_store_fpr32(fp1, fd);
8656 gen_store_fpr32h(ctx, fp0, fd);
8657 tcg_temp_free_i32(fp0);
8658 tcg_temp_free_i32(fp1);
8660 opn = "puu.ps";
8661 break;
8662 case OPC_CMP_F_PS:
8663 case OPC_CMP_UN_PS:
8664 case OPC_CMP_EQ_PS:
8665 case OPC_CMP_UEQ_PS:
8666 case OPC_CMP_OLT_PS:
8667 case OPC_CMP_ULT_PS:
8668 case OPC_CMP_OLE_PS:
8669 case OPC_CMP_ULE_PS:
8670 case OPC_CMP_SF_PS:
8671 case OPC_CMP_NGLE_PS:
8672 case OPC_CMP_SEQ_PS:
8673 case OPC_CMP_NGL_PS:
8674 case OPC_CMP_LT_PS:
8675 case OPC_CMP_NGE_PS:
8676 case OPC_CMP_LE_PS:
8677 case OPC_CMP_NGT_PS:
8678 if (ctx->opcode & (1 << 6)) {
8679 gen_cmpabs_ps(ctx, func-48, ft, fs, cc);
8680 opn = condnames_abs[func-48];
8681 } else {
8682 gen_cmp_ps(ctx, func-48, ft, fs, cc);
8683 opn = condnames[func-48];
8685 break;
8686 default:
8687 MIPS_INVAL(opn);
8688 generate_exception (ctx, EXCP_RI);
8689 return;
8691 (void)opn; /* avoid a compiler warning */
8692 switch (optype) {
8693 case BINOP:
8694 MIPS_DEBUG("%s %s, %s, %s", opn, fregnames[fd], fregnames[fs], fregnames[ft]);
8695 break;
8696 case CMPOP:
8697 MIPS_DEBUG("%s %s,%s", opn, fregnames[fs], fregnames[ft]);
8698 break;
8699 default:
8700 MIPS_DEBUG("%s %s,%s", opn, fregnames[fd], fregnames[fs]);
8701 break;
8705 /* Coprocessor 3 (FPU) */
8706 static void gen_flt3_ldst (DisasContext *ctx, uint32_t opc,
8707 int fd, int fs, int base, int index)
8709 const char *opn = "extended float load/store";
8710 int store = 0;
8711 TCGv t0 = tcg_temp_new();
8713 if (base == 0) {
8714 gen_load_gpr(t0, index);
8715 } else if (index == 0) {
8716 gen_load_gpr(t0, base);
8717 } else {
8718 gen_op_addr_add(ctx, t0, cpu_gpr[base], cpu_gpr[index]);
8720 /* Don't do NOP if destination is zero: we must perform the actual
8721 memory access. */
8722 switch (opc) {
8723 case OPC_LWXC1:
8724 check_cop1x(ctx);
8726 TCGv_i32 fp0 = tcg_temp_new_i32();
8728 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TESL);
8729 tcg_gen_trunc_tl_i32(fp0, t0);
8730 gen_store_fpr32(fp0, fd);
8731 tcg_temp_free_i32(fp0);
8733 opn = "lwxc1";
8734 break;
8735 case OPC_LDXC1:
8736 check_cop1x(ctx);
8737 check_cp1_registers(ctx, fd);
8739 TCGv_i64 fp0 = tcg_temp_new_i64();
8740 tcg_gen_qemu_ld_i64(fp0, t0, ctx->mem_idx, MO_TEQ);
8741 gen_store_fpr64(ctx, fp0, fd);
8742 tcg_temp_free_i64(fp0);
8744 opn = "ldxc1";
8745 break;
8746 case OPC_LUXC1:
8747 check_cp1_64bitmode(ctx);
8748 tcg_gen_andi_tl(t0, t0, ~0x7);
8750 TCGv_i64 fp0 = tcg_temp_new_i64();
8752 tcg_gen_qemu_ld_i64(fp0, t0, ctx->mem_idx, MO_TEQ);
8753 gen_store_fpr64(ctx, fp0, fd);
8754 tcg_temp_free_i64(fp0);
8756 opn = "luxc1";
8757 break;
8758 case OPC_SWXC1:
8759 check_cop1x(ctx);
8761 TCGv_i32 fp0 = tcg_temp_new_i32();
8762 gen_load_fpr32(fp0, fs);
8763 tcg_gen_qemu_st_i32(fp0, t0, ctx->mem_idx, MO_TEUL);
8764 tcg_temp_free_i32(fp0);
8766 opn = "swxc1";
8767 store = 1;
8768 break;
8769 case OPC_SDXC1:
8770 check_cop1x(ctx);
8771 check_cp1_registers(ctx, fs);
8773 TCGv_i64 fp0 = tcg_temp_new_i64();
8774 gen_load_fpr64(ctx, fp0, fs);
8775 tcg_gen_qemu_st_i64(fp0, t0, ctx->mem_idx, MO_TEQ);
8776 tcg_temp_free_i64(fp0);
8778 opn = "sdxc1";
8779 store = 1;
8780 break;
8781 case OPC_SUXC1:
8782 check_cp1_64bitmode(ctx);
8783 tcg_gen_andi_tl(t0, t0, ~0x7);
8785 TCGv_i64 fp0 = tcg_temp_new_i64();
8786 gen_load_fpr64(ctx, fp0, fs);
8787 tcg_gen_qemu_st_i64(fp0, t0, ctx->mem_idx, MO_TEQ);
8788 tcg_temp_free_i64(fp0);
8790 opn = "suxc1";
8791 store = 1;
8792 break;
8794 tcg_temp_free(t0);
8795 (void)opn; (void)store; /* avoid compiler warnings */
8796 MIPS_DEBUG("%s %s, %s(%s)", opn, fregnames[store ? fs : fd],
8797 regnames[index], regnames[base]);
8800 static void gen_flt3_arith (DisasContext *ctx, uint32_t opc,
8801 int fd, int fr, int fs, int ft)
8803 const char *opn = "flt3_arith";
8805 switch (opc) {
8806 case OPC_ALNV_PS:
8807 check_cp1_64bitmode(ctx);
8809 TCGv t0 = tcg_temp_local_new();
8810 TCGv_i32 fp = tcg_temp_new_i32();
8811 TCGv_i32 fph = tcg_temp_new_i32();
8812 int l1 = gen_new_label();
8813 int l2 = gen_new_label();
8815 gen_load_gpr(t0, fr);
8816 tcg_gen_andi_tl(t0, t0, 0x7);
8818 tcg_gen_brcondi_tl(TCG_COND_NE, t0, 0, l1);
8819 gen_load_fpr32(fp, fs);
8820 gen_load_fpr32h(ctx, fph, fs);
8821 gen_store_fpr32(fp, fd);
8822 gen_store_fpr32h(ctx, fph, fd);
8823 tcg_gen_br(l2);
8824 gen_set_label(l1);
8825 tcg_gen_brcondi_tl(TCG_COND_NE, t0, 4, l2);
8826 tcg_temp_free(t0);
8827 #ifdef TARGET_WORDS_BIGENDIAN
8828 gen_load_fpr32(fp, fs);
8829 gen_load_fpr32h(ctx, fph, ft);
8830 gen_store_fpr32h(ctx, fp, fd);
8831 gen_store_fpr32(fph, fd);
8832 #else
8833 gen_load_fpr32h(ctx, fph, fs);
8834 gen_load_fpr32(fp, ft);
8835 gen_store_fpr32(fph, fd);
8836 gen_store_fpr32h(ctx, fp, fd);
8837 #endif
8838 gen_set_label(l2);
8839 tcg_temp_free_i32(fp);
8840 tcg_temp_free_i32(fph);
8842 opn = "alnv.ps";
8843 break;
8844 case OPC_MADD_S:
8845 check_cop1x(ctx);
8847 TCGv_i32 fp0 = tcg_temp_new_i32();
8848 TCGv_i32 fp1 = tcg_temp_new_i32();
8849 TCGv_i32 fp2 = tcg_temp_new_i32();
8851 gen_load_fpr32(fp0, fs);
8852 gen_load_fpr32(fp1, ft);
8853 gen_load_fpr32(fp2, fr);
8854 gen_helper_float_madd_s(fp2, cpu_env, fp0, fp1, fp2);
8855 tcg_temp_free_i32(fp0);
8856 tcg_temp_free_i32(fp1);
8857 gen_store_fpr32(fp2, fd);
8858 tcg_temp_free_i32(fp2);
8860 opn = "madd.s";
8861 break;
8862 case OPC_MADD_D:
8863 check_cop1x(ctx);
8864 check_cp1_registers(ctx, fd | fs | ft | fr);
8866 TCGv_i64 fp0 = tcg_temp_new_i64();
8867 TCGv_i64 fp1 = tcg_temp_new_i64();
8868 TCGv_i64 fp2 = tcg_temp_new_i64();
8870 gen_load_fpr64(ctx, fp0, fs);
8871 gen_load_fpr64(ctx, fp1, ft);
8872 gen_load_fpr64(ctx, fp2, fr);
8873 gen_helper_float_madd_d(fp2, cpu_env, fp0, fp1, fp2);
8874 tcg_temp_free_i64(fp0);
8875 tcg_temp_free_i64(fp1);
8876 gen_store_fpr64(ctx, fp2, fd);
8877 tcg_temp_free_i64(fp2);
8879 opn = "madd.d";
8880 break;
8881 case OPC_MADD_PS:
8882 check_cp1_64bitmode(ctx);
8884 TCGv_i64 fp0 = tcg_temp_new_i64();
8885 TCGv_i64 fp1 = tcg_temp_new_i64();
8886 TCGv_i64 fp2 = tcg_temp_new_i64();
8888 gen_load_fpr64(ctx, fp0, fs);
8889 gen_load_fpr64(ctx, fp1, ft);
8890 gen_load_fpr64(ctx, fp2, fr);
8891 gen_helper_float_madd_ps(fp2, cpu_env, fp0, fp1, fp2);
8892 tcg_temp_free_i64(fp0);
8893 tcg_temp_free_i64(fp1);
8894 gen_store_fpr64(ctx, fp2, fd);
8895 tcg_temp_free_i64(fp2);
8897 opn = "madd.ps";
8898 break;
8899 case OPC_MSUB_S:
8900 check_cop1x(ctx);
8902 TCGv_i32 fp0 = tcg_temp_new_i32();
8903 TCGv_i32 fp1 = tcg_temp_new_i32();
8904 TCGv_i32 fp2 = tcg_temp_new_i32();
8906 gen_load_fpr32(fp0, fs);
8907 gen_load_fpr32(fp1, ft);
8908 gen_load_fpr32(fp2, fr);
8909 gen_helper_float_msub_s(fp2, cpu_env, fp0, fp1, fp2);
8910 tcg_temp_free_i32(fp0);
8911 tcg_temp_free_i32(fp1);
8912 gen_store_fpr32(fp2, fd);
8913 tcg_temp_free_i32(fp2);
8915 opn = "msub.s";
8916 break;
8917 case OPC_MSUB_D:
8918 check_cop1x(ctx);
8919 check_cp1_registers(ctx, fd | fs | ft | fr);
8921 TCGv_i64 fp0 = tcg_temp_new_i64();
8922 TCGv_i64 fp1 = tcg_temp_new_i64();
8923 TCGv_i64 fp2 = tcg_temp_new_i64();
8925 gen_load_fpr64(ctx, fp0, fs);
8926 gen_load_fpr64(ctx, fp1, ft);
8927 gen_load_fpr64(ctx, fp2, fr);
8928 gen_helper_float_msub_d(fp2, cpu_env, fp0, fp1, fp2);
8929 tcg_temp_free_i64(fp0);
8930 tcg_temp_free_i64(fp1);
8931 gen_store_fpr64(ctx, fp2, fd);
8932 tcg_temp_free_i64(fp2);
8934 opn = "msub.d";
8935 break;
8936 case OPC_MSUB_PS:
8937 check_cp1_64bitmode(ctx);
8939 TCGv_i64 fp0 = tcg_temp_new_i64();
8940 TCGv_i64 fp1 = tcg_temp_new_i64();
8941 TCGv_i64 fp2 = tcg_temp_new_i64();
8943 gen_load_fpr64(ctx, fp0, fs);
8944 gen_load_fpr64(ctx, fp1, ft);
8945 gen_load_fpr64(ctx, fp2, fr);
8946 gen_helper_float_msub_ps(fp2, cpu_env, fp0, fp1, fp2);
8947 tcg_temp_free_i64(fp0);
8948 tcg_temp_free_i64(fp1);
8949 gen_store_fpr64(ctx, fp2, fd);
8950 tcg_temp_free_i64(fp2);
8952 opn = "msub.ps";
8953 break;
8954 case OPC_NMADD_S:
8955 check_cop1x(ctx);
8957 TCGv_i32 fp0 = tcg_temp_new_i32();
8958 TCGv_i32 fp1 = tcg_temp_new_i32();
8959 TCGv_i32 fp2 = tcg_temp_new_i32();
8961 gen_load_fpr32(fp0, fs);
8962 gen_load_fpr32(fp1, ft);
8963 gen_load_fpr32(fp2, fr);
8964 gen_helper_float_nmadd_s(fp2, cpu_env, fp0, fp1, fp2);
8965 tcg_temp_free_i32(fp0);
8966 tcg_temp_free_i32(fp1);
8967 gen_store_fpr32(fp2, fd);
8968 tcg_temp_free_i32(fp2);
8970 opn = "nmadd.s";
8971 break;
8972 case OPC_NMADD_D:
8973 check_cop1x(ctx);
8974 check_cp1_registers(ctx, fd | fs | ft | fr);
8976 TCGv_i64 fp0 = tcg_temp_new_i64();
8977 TCGv_i64 fp1 = tcg_temp_new_i64();
8978 TCGv_i64 fp2 = tcg_temp_new_i64();
8980 gen_load_fpr64(ctx, fp0, fs);
8981 gen_load_fpr64(ctx, fp1, ft);
8982 gen_load_fpr64(ctx, fp2, fr);
8983 gen_helper_float_nmadd_d(fp2, cpu_env, fp0, fp1, fp2);
8984 tcg_temp_free_i64(fp0);
8985 tcg_temp_free_i64(fp1);
8986 gen_store_fpr64(ctx, fp2, fd);
8987 tcg_temp_free_i64(fp2);
8989 opn = "nmadd.d";
8990 break;
8991 case OPC_NMADD_PS:
8992 check_cp1_64bitmode(ctx);
8994 TCGv_i64 fp0 = tcg_temp_new_i64();
8995 TCGv_i64 fp1 = tcg_temp_new_i64();
8996 TCGv_i64 fp2 = tcg_temp_new_i64();
8998 gen_load_fpr64(ctx, fp0, fs);
8999 gen_load_fpr64(ctx, fp1, ft);
9000 gen_load_fpr64(ctx, fp2, fr);
9001 gen_helper_float_nmadd_ps(fp2, cpu_env, fp0, fp1, fp2);
9002 tcg_temp_free_i64(fp0);
9003 tcg_temp_free_i64(fp1);
9004 gen_store_fpr64(ctx, fp2, fd);
9005 tcg_temp_free_i64(fp2);
9007 opn = "nmadd.ps";
9008 break;
9009 case OPC_NMSUB_S:
9010 check_cop1x(ctx);
9012 TCGv_i32 fp0 = tcg_temp_new_i32();
9013 TCGv_i32 fp1 = tcg_temp_new_i32();
9014 TCGv_i32 fp2 = tcg_temp_new_i32();
9016 gen_load_fpr32(fp0, fs);
9017 gen_load_fpr32(fp1, ft);
9018 gen_load_fpr32(fp2, fr);
9019 gen_helper_float_nmsub_s(fp2, cpu_env, fp0, fp1, fp2);
9020 tcg_temp_free_i32(fp0);
9021 tcg_temp_free_i32(fp1);
9022 gen_store_fpr32(fp2, fd);
9023 tcg_temp_free_i32(fp2);
9025 opn = "nmsub.s";
9026 break;
9027 case OPC_NMSUB_D:
9028 check_cop1x(ctx);
9029 check_cp1_registers(ctx, fd | fs | ft | fr);
9031 TCGv_i64 fp0 = tcg_temp_new_i64();
9032 TCGv_i64 fp1 = tcg_temp_new_i64();
9033 TCGv_i64 fp2 = tcg_temp_new_i64();
9035 gen_load_fpr64(ctx, fp0, fs);
9036 gen_load_fpr64(ctx, fp1, ft);
9037 gen_load_fpr64(ctx, fp2, fr);
9038 gen_helper_float_nmsub_d(fp2, cpu_env, fp0, fp1, fp2);
9039 tcg_temp_free_i64(fp0);
9040 tcg_temp_free_i64(fp1);
9041 gen_store_fpr64(ctx, fp2, fd);
9042 tcg_temp_free_i64(fp2);
9044 opn = "nmsub.d";
9045 break;
9046 case OPC_NMSUB_PS:
9047 check_cp1_64bitmode(ctx);
9049 TCGv_i64 fp0 = tcg_temp_new_i64();
9050 TCGv_i64 fp1 = tcg_temp_new_i64();
9051 TCGv_i64 fp2 = tcg_temp_new_i64();
9053 gen_load_fpr64(ctx, fp0, fs);
9054 gen_load_fpr64(ctx, fp1, ft);
9055 gen_load_fpr64(ctx, fp2, fr);
9056 gen_helper_float_nmsub_ps(fp2, cpu_env, fp0, fp1, fp2);
9057 tcg_temp_free_i64(fp0);
9058 tcg_temp_free_i64(fp1);
9059 gen_store_fpr64(ctx, fp2, fd);
9060 tcg_temp_free_i64(fp2);
9062 opn = "nmsub.ps";
9063 break;
9064 default:
9065 MIPS_INVAL(opn);
9066 generate_exception (ctx, EXCP_RI);
9067 return;
9069 (void)opn; /* avoid a compiler warning */
9070 MIPS_DEBUG("%s %s, %s, %s, %s", opn, fregnames[fd], fregnames[fr],
9071 fregnames[fs], fregnames[ft]);
9074 static void gen_rdhwr(DisasContext *ctx, int rt, int rd)
9076 TCGv t0;
9078 #if !defined(CONFIG_USER_ONLY)
9079 /* The Linux kernel will emulate rdhwr if it's not supported natively.
9080 Therefore only check the ISA in system mode. */
9081 check_insn(ctx, ISA_MIPS32R2);
9082 #endif
9083 t0 = tcg_temp_new();
9085 switch (rd) {
9086 case 0:
9087 save_cpu_state(ctx, 1);
9088 gen_helper_rdhwr_cpunum(t0, cpu_env);
9089 gen_store_gpr(t0, rt);
9090 break;
9091 case 1:
9092 save_cpu_state(ctx, 1);
9093 gen_helper_rdhwr_synci_step(t0, cpu_env);
9094 gen_store_gpr(t0, rt);
9095 break;
9096 case 2:
9097 save_cpu_state(ctx, 1);
9098 gen_helper_rdhwr_cc(t0, cpu_env);
9099 gen_store_gpr(t0, rt);
9100 break;
9101 case 3:
9102 save_cpu_state(ctx, 1);
9103 gen_helper_rdhwr_ccres(t0, cpu_env);
9104 gen_store_gpr(t0, rt);
9105 break;
9106 case 29:
9107 #if defined(CONFIG_USER_ONLY)
9108 tcg_gen_ld_tl(t0, cpu_env,
9109 offsetof(CPUMIPSState, active_tc.CP0_UserLocal));
9110 gen_store_gpr(t0, rt);
9111 break;
9112 #else
9113 if ((ctx->hflags & MIPS_HFLAG_CP0) ||
9114 (ctx->hflags & MIPS_HFLAG_HWRENA_ULR)) {
9115 tcg_gen_ld_tl(t0, cpu_env,
9116 offsetof(CPUMIPSState, active_tc.CP0_UserLocal));
9117 gen_store_gpr(t0, rt);
9118 } else {
9119 generate_exception(ctx, EXCP_RI);
9121 break;
9122 #endif
9123 default: /* Invalid */
9124 MIPS_INVAL("rdhwr");
9125 generate_exception(ctx, EXCP_RI);
9126 break;
9128 tcg_temp_free(t0);
9131 static void handle_delay_slot(DisasContext *ctx, int insn_bytes)
9133 if (ctx->hflags & MIPS_HFLAG_BMASK) {
9134 int proc_hflags = ctx->hflags & MIPS_HFLAG_BMASK;
9135 /* Branches completion */
9136 ctx->hflags &= ~MIPS_HFLAG_BMASK;
9137 ctx->bstate = BS_BRANCH;
9138 save_cpu_state(ctx, 0);
9139 /* FIXME: Need to clear can_do_io. */
9140 switch (proc_hflags & MIPS_HFLAG_BMASK_BASE) {
9141 case MIPS_HFLAG_B:
9142 /* unconditional branch */
9143 MIPS_DEBUG("unconditional branch");
9144 if (proc_hflags & MIPS_HFLAG_BX) {
9145 tcg_gen_xori_i32(hflags, hflags, MIPS_HFLAG_M16);
9147 gen_goto_tb(ctx, 0, ctx->btarget);
9148 break;
9149 case MIPS_HFLAG_BL:
9150 /* blikely taken case */
9151 MIPS_DEBUG("blikely branch taken");
9152 gen_goto_tb(ctx, 0, ctx->btarget);
9153 break;
9154 case MIPS_HFLAG_BC:
9155 /* Conditional branch */
9156 MIPS_DEBUG("conditional branch");
9158 int l1 = gen_new_label();
9160 tcg_gen_brcondi_tl(TCG_COND_NE, bcond, 0, l1);
9161 gen_goto_tb(ctx, 1, ctx->pc + insn_bytes);
9162 gen_set_label(l1);
9163 gen_goto_tb(ctx, 0, ctx->btarget);
9165 break;
9166 case MIPS_HFLAG_BR:
9167 /* unconditional branch to register */
9168 MIPS_DEBUG("branch to register");
9169 if (ctx->insn_flags & (ASE_MIPS16 | ASE_MICROMIPS)) {
9170 TCGv t0 = tcg_temp_new();
9171 TCGv_i32 t1 = tcg_temp_new_i32();
9173 tcg_gen_andi_tl(t0, btarget, 0x1);
9174 tcg_gen_trunc_tl_i32(t1, t0);
9175 tcg_temp_free(t0);
9176 tcg_gen_andi_i32(hflags, hflags, ~(uint32_t)MIPS_HFLAG_M16);
9177 tcg_gen_shli_i32(t1, t1, MIPS_HFLAG_M16_SHIFT);
9178 tcg_gen_or_i32(hflags, hflags, t1);
9179 tcg_temp_free_i32(t1);
9181 tcg_gen_andi_tl(cpu_PC, btarget, ~(target_ulong)0x1);
9182 } else {
9183 tcg_gen_mov_tl(cpu_PC, btarget);
9185 if (ctx->singlestep_enabled) {
9186 save_cpu_state(ctx, 0);
9187 gen_helper_0e0i(raise_exception, EXCP_DEBUG);
9189 tcg_gen_exit_tb(0);
9190 break;
9191 default:
9192 MIPS_DEBUG("unknown branch");
9193 break;
9198 /* ISA extensions (ASEs) */
9199 /* MIPS16 extension to MIPS32 */
9201 /* MIPS16 major opcodes */
9202 enum {
9203 M16_OPC_ADDIUSP = 0x00,
9204 M16_OPC_ADDIUPC = 0x01,
9205 M16_OPC_B = 0x02,
9206 M16_OPC_JAL = 0x03,
9207 M16_OPC_BEQZ = 0x04,
9208 M16_OPC_BNEQZ = 0x05,
9209 M16_OPC_SHIFT = 0x06,
9210 M16_OPC_LD = 0x07,
9211 M16_OPC_RRIA = 0x08,
9212 M16_OPC_ADDIU8 = 0x09,
9213 M16_OPC_SLTI = 0x0a,
9214 M16_OPC_SLTIU = 0x0b,
9215 M16_OPC_I8 = 0x0c,
9216 M16_OPC_LI = 0x0d,
9217 M16_OPC_CMPI = 0x0e,
9218 M16_OPC_SD = 0x0f,
9219 M16_OPC_LB = 0x10,
9220 M16_OPC_LH = 0x11,
9221 M16_OPC_LWSP = 0x12,
9222 M16_OPC_LW = 0x13,
9223 M16_OPC_LBU = 0x14,
9224 M16_OPC_LHU = 0x15,
9225 M16_OPC_LWPC = 0x16,
9226 M16_OPC_LWU = 0x17,
9227 M16_OPC_SB = 0x18,
9228 M16_OPC_SH = 0x19,
9229 M16_OPC_SWSP = 0x1a,
9230 M16_OPC_SW = 0x1b,
9231 M16_OPC_RRR = 0x1c,
9232 M16_OPC_RR = 0x1d,
9233 M16_OPC_EXTEND = 0x1e,
9234 M16_OPC_I64 = 0x1f
9237 /* I8 funct field */
9238 enum {
9239 I8_BTEQZ = 0x0,
9240 I8_BTNEZ = 0x1,
9241 I8_SWRASP = 0x2,
9242 I8_ADJSP = 0x3,
9243 I8_SVRS = 0x4,
9244 I8_MOV32R = 0x5,
9245 I8_MOVR32 = 0x7
9248 /* RRR f field */
9249 enum {
9250 RRR_DADDU = 0x0,
9251 RRR_ADDU = 0x1,
9252 RRR_DSUBU = 0x2,
9253 RRR_SUBU = 0x3
9256 /* RR funct field */
9257 enum {
9258 RR_JR = 0x00,
9259 RR_SDBBP = 0x01,
9260 RR_SLT = 0x02,
9261 RR_SLTU = 0x03,
9262 RR_SLLV = 0x04,
9263 RR_BREAK = 0x05,
9264 RR_SRLV = 0x06,
9265 RR_SRAV = 0x07,
9266 RR_DSRL = 0x08,
9267 RR_CMP = 0x0a,
9268 RR_NEG = 0x0b,
9269 RR_AND = 0x0c,
9270 RR_OR = 0x0d,
9271 RR_XOR = 0x0e,
9272 RR_NOT = 0x0f,
9273 RR_MFHI = 0x10,
9274 RR_CNVT = 0x11,
9275 RR_MFLO = 0x12,
9276 RR_DSRA = 0x13,
9277 RR_DSLLV = 0x14,
9278 RR_DSRLV = 0x16,
9279 RR_DSRAV = 0x17,
9280 RR_MULT = 0x18,
9281 RR_MULTU = 0x19,
9282 RR_DIV = 0x1a,
9283 RR_DIVU = 0x1b,
9284 RR_DMULT = 0x1c,
9285 RR_DMULTU = 0x1d,
9286 RR_DDIV = 0x1e,
9287 RR_DDIVU = 0x1f
9290 /* I64 funct field */
9291 enum {
9292 I64_LDSP = 0x0,
9293 I64_SDSP = 0x1,
9294 I64_SDRASP = 0x2,
9295 I64_DADJSP = 0x3,
9296 I64_LDPC = 0x4,
9297 I64_DADDIU5 = 0x5,
9298 I64_DADDIUPC = 0x6,
9299 I64_DADDIUSP = 0x7
9302 /* RR ry field for CNVT */
9303 enum {
9304 RR_RY_CNVT_ZEB = 0x0,
9305 RR_RY_CNVT_ZEH = 0x1,
9306 RR_RY_CNVT_ZEW = 0x2,
9307 RR_RY_CNVT_SEB = 0x4,
9308 RR_RY_CNVT_SEH = 0x5,
9309 RR_RY_CNVT_SEW = 0x6,
9312 static int xlat (int r)
9314 static int map[] = { 16, 17, 2, 3, 4, 5, 6, 7 };
9316 return map[r];
9319 static void gen_mips16_save (DisasContext *ctx,
9320 int xsregs, int aregs,
9321 int do_ra, int do_s0, int do_s1,
9322 int framesize)
9324 TCGv t0 = tcg_temp_new();
9325 TCGv t1 = tcg_temp_new();
9326 int args, astatic;
9328 switch (aregs) {
9329 case 0:
9330 case 1:
9331 case 2:
9332 case 3:
9333 case 11:
9334 args = 0;
9335 break;
9336 case 4:
9337 case 5:
9338 case 6:
9339 case 7:
9340 args = 1;
9341 break;
9342 case 8:
9343 case 9:
9344 case 10:
9345 args = 2;
9346 break;
9347 case 12:
9348 case 13:
9349 args = 3;
9350 break;
9351 case 14:
9352 args = 4;
9353 break;
9354 default:
9355 generate_exception(ctx, EXCP_RI);
9356 return;
9359 switch (args) {
9360 case 4:
9361 gen_base_offset_addr(ctx, t0, 29, 12);
9362 gen_load_gpr(t1, 7);
9363 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL);
9364 /* Fall through */
9365 case 3:
9366 gen_base_offset_addr(ctx, t0, 29, 8);
9367 gen_load_gpr(t1, 6);
9368 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL);
9369 /* Fall through */
9370 case 2:
9371 gen_base_offset_addr(ctx, t0, 29, 4);
9372 gen_load_gpr(t1, 5);
9373 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL);
9374 /* Fall through */
9375 case 1:
9376 gen_base_offset_addr(ctx, t0, 29, 0);
9377 gen_load_gpr(t1, 4);
9378 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL);
9381 gen_load_gpr(t0, 29);
9383 #define DECR_AND_STORE(reg) do { \
9384 tcg_gen_subi_tl(t0, t0, 4); \
9385 gen_load_gpr(t1, reg); \
9386 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL); \
9387 } while (0)
9389 if (do_ra) {
9390 DECR_AND_STORE(31);
9393 switch (xsregs) {
9394 case 7:
9395 DECR_AND_STORE(30);
9396 /* Fall through */
9397 case 6:
9398 DECR_AND_STORE(23);
9399 /* Fall through */
9400 case 5:
9401 DECR_AND_STORE(22);
9402 /* Fall through */
9403 case 4:
9404 DECR_AND_STORE(21);
9405 /* Fall through */
9406 case 3:
9407 DECR_AND_STORE(20);
9408 /* Fall through */
9409 case 2:
9410 DECR_AND_STORE(19);
9411 /* Fall through */
9412 case 1:
9413 DECR_AND_STORE(18);
9416 if (do_s1) {
9417 DECR_AND_STORE(17);
9419 if (do_s0) {
9420 DECR_AND_STORE(16);
9423 switch (aregs) {
9424 case 0:
9425 case 4:
9426 case 8:
9427 case 12:
9428 case 14:
9429 astatic = 0;
9430 break;
9431 case 1:
9432 case 5:
9433 case 9:
9434 case 13:
9435 astatic = 1;
9436 break;
9437 case 2:
9438 case 6:
9439 case 10:
9440 astatic = 2;
9441 break;
9442 case 3:
9443 case 7:
9444 astatic = 3;
9445 break;
9446 case 11:
9447 astatic = 4;
9448 break;
9449 default:
9450 generate_exception(ctx, EXCP_RI);
9451 return;
9454 if (astatic > 0) {
9455 DECR_AND_STORE(7);
9456 if (astatic > 1) {
9457 DECR_AND_STORE(6);
9458 if (astatic > 2) {
9459 DECR_AND_STORE(5);
9460 if (astatic > 3) {
9461 DECR_AND_STORE(4);
9466 #undef DECR_AND_STORE
9468 tcg_gen_subi_tl(cpu_gpr[29], cpu_gpr[29], framesize);
9469 tcg_temp_free(t0);
9470 tcg_temp_free(t1);
9473 static void gen_mips16_restore (DisasContext *ctx,
9474 int xsregs, int aregs,
9475 int do_ra, int do_s0, int do_s1,
9476 int framesize)
9478 int astatic;
9479 TCGv t0 = tcg_temp_new();
9480 TCGv t1 = tcg_temp_new();
9482 tcg_gen_addi_tl(t0, cpu_gpr[29], framesize);
9484 #define DECR_AND_LOAD(reg) do { \
9485 tcg_gen_subi_tl(t0, t0, 4); \
9486 tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_TESL); \
9487 gen_store_gpr(t1, reg); \
9488 } while (0)
9490 if (do_ra) {
9491 DECR_AND_LOAD(31);
9494 switch (xsregs) {
9495 case 7:
9496 DECR_AND_LOAD(30);
9497 /* Fall through */
9498 case 6:
9499 DECR_AND_LOAD(23);
9500 /* Fall through */
9501 case 5:
9502 DECR_AND_LOAD(22);
9503 /* Fall through */
9504 case 4:
9505 DECR_AND_LOAD(21);
9506 /* Fall through */
9507 case 3:
9508 DECR_AND_LOAD(20);
9509 /* Fall through */
9510 case 2:
9511 DECR_AND_LOAD(19);
9512 /* Fall through */
9513 case 1:
9514 DECR_AND_LOAD(18);
9517 if (do_s1) {
9518 DECR_AND_LOAD(17);
9520 if (do_s0) {
9521 DECR_AND_LOAD(16);
9524 switch (aregs) {
9525 case 0:
9526 case 4:
9527 case 8:
9528 case 12:
9529 case 14:
9530 astatic = 0;
9531 break;
9532 case 1:
9533 case 5:
9534 case 9:
9535 case 13:
9536 astatic = 1;
9537 break;
9538 case 2:
9539 case 6:
9540 case 10:
9541 astatic = 2;
9542 break;
9543 case 3:
9544 case 7:
9545 astatic = 3;
9546 break;
9547 case 11:
9548 astatic = 4;
9549 break;
9550 default:
9551 generate_exception(ctx, EXCP_RI);
9552 return;
9555 if (astatic > 0) {
9556 DECR_AND_LOAD(7);
9557 if (astatic > 1) {
9558 DECR_AND_LOAD(6);
9559 if (astatic > 2) {
9560 DECR_AND_LOAD(5);
9561 if (astatic > 3) {
9562 DECR_AND_LOAD(4);
9567 #undef DECR_AND_LOAD
9569 tcg_gen_addi_tl(cpu_gpr[29], cpu_gpr[29], framesize);
9570 tcg_temp_free(t0);
9571 tcg_temp_free(t1);
9574 static void gen_addiupc (DisasContext *ctx, int rx, int imm,
9575 int is_64_bit, int extended)
9577 TCGv t0;
9579 if (extended && (ctx->hflags & MIPS_HFLAG_BMASK)) {
9580 generate_exception(ctx, EXCP_RI);
9581 return;
9584 t0 = tcg_temp_new();
9586 tcg_gen_movi_tl(t0, pc_relative_pc(ctx));
9587 tcg_gen_addi_tl(cpu_gpr[rx], t0, imm);
9588 if (!is_64_bit) {
9589 tcg_gen_ext32s_tl(cpu_gpr[rx], cpu_gpr[rx]);
9592 tcg_temp_free(t0);
9595 #if defined(TARGET_MIPS64)
9596 static void decode_i64_mips16 (DisasContext *ctx,
9597 int ry, int funct, int16_t offset,
9598 int extended)
9600 switch (funct) {
9601 case I64_LDSP:
9602 check_mips_64(ctx);
9603 offset = extended ? offset : offset << 3;
9604 gen_ld(ctx, OPC_LD, ry, 29, offset);
9605 break;
9606 case I64_SDSP:
9607 check_mips_64(ctx);
9608 offset = extended ? offset : offset << 3;
9609 gen_st(ctx, OPC_SD, ry, 29, offset);
9610 break;
9611 case I64_SDRASP:
9612 check_mips_64(ctx);
9613 offset = extended ? offset : (ctx->opcode & 0xff) << 3;
9614 gen_st(ctx, OPC_SD, 31, 29, offset);
9615 break;
9616 case I64_DADJSP:
9617 check_mips_64(ctx);
9618 offset = extended ? offset : ((int8_t)ctx->opcode) << 3;
9619 gen_arith_imm(ctx, OPC_DADDIU, 29, 29, offset);
9620 break;
9621 case I64_LDPC:
9622 if (extended && (ctx->hflags & MIPS_HFLAG_BMASK)) {
9623 generate_exception(ctx, EXCP_RI);
9624 } else {
9625 offset = extended ? offset : offset << 3;
9626 gen_ld(ctx, OPC_LDPC, ry, 0, offset);
9628 break;
9629 case I64_DADDIU5:
9630 check_mips_64(ctx);
9631 offset = extended ? offset : ((int8_t)(offset << 3)) >> 3;
9632 gen_arith_imm(ctx, OPC_DADDIU, ry, ry, offset);
9633 break;
9634 case I64_DADDIUPC:
9635 check_mips_64(ctx);
9636 offset = extended ? offset : offset << 2;
9637 gen_addiupc(ctx, ry, offset, 1, extended);
9638 break;
9639 case I64_DADDIUSP:
9640 check_mips_64(ctx);
9641 offset = extended ? offset : offset << 2;
9642 gen_arith_imm(ctx, OPC_DADDIU, ry, 29, offset);
9643 break;
9646 #endif
9648 static int decode_extended_mips16_opc (CPUMIPSState *env, DisasContext *ctx)
9650 int extend = cpu_lduw_code(env, ctx->pc + 2);
9651 int op, rx, ry, funct, sa;
9652 int16_t imm, offset;
9654 ctx->opcode = (ctx->opcode << 16) | extend;
9655 op = (ctx->opcode >> 11) & 0x1f;
9656 sa = (ctx->opcode >> 22) & 0x1f;
9657 funct = (ctx->opcode >> 8) & 0x7;
9658 rx = xlat((ctx->opcode >> 8) & 0x7);
9659 ry = xlat((ctx->opcode >> 5) & 0x7);
9660 offset = imm = (int16_t) (((ctx->opcode >> 16) & 0x1f) << 11
9661 | ((ctx->opcode >> 21) & 0x3f) << 5
9662 | (ctx->opcode & 0x1f));
9664 /* The extended opcodes cleverly reuse the opcodes from their 16-bit
9665 counterparts. */
9666 switch (op) {
9667 case M16_OPC_ADDIUSP:
9668 gen_arith_imm(ctx, OPC_ADDIU, rx, 29, imm);
9669 break;
9670 case M16_OPC_ADDIUPC:
9671 gen_addiupc(ctx, rx, imm, 0, 1);
9672 break;
9673 case M16_OPC_B:
9674 gen_compute_branch(ctx, OPC_BEQ, 4, 0, 0, offset << 1);
9675 /* No delay slot, so just process as a normal instruction */
9676 break;
9677 case M16_OPC_BEQZ:
9678 gen_compute_branch(ctx, OPC_BEQ, 4, rx, 0, offset << 1);
9679 /* No delay slot, so just process as a normal instruction */
9680 break;
9681 case M16_OPC_BNEQZ:
9682 gen_compute_branch(ctx, OPC_BNE, 4, rx, 0, offset << 1);
9683 /* No delay slot, so just process as a normal instruction */
9684 break;
9685 case M16_OPC_SHIFT:
9686 switch (ctx->opcode & 0x3) {
9687 case 0x0:
9688 gen_shift_imm(ctx, OPC_SLL, rx, ry, sa);
9689 break;
9690 case 0x1:
9691 #if defined(TARGET_MIPS64)
9692 check_mips_64(ctx);
9693 gen_shift_imm(ctx, OPC_DSLL, rx, ry, sa);
9694 #else
9695 generate_exception(ctx, EXCP_RI);
9696 #endif
9697 break;
9698 case 0x2:
9699 gen_shift_imm(ctx, OPC_SRL, rx, ry, sa);
9700 break;
9701 case 0x3:
9702 gen_shift_imm(ctx, OPC_SRA, rx, ry, sa);
9703 break;
9705 break;
9706 #if defined(TARGET_MIPS64)
9707 case M16_OPC_LD:
9708 check_mips_64(ctx);
9709 gen_ld(ctx, OPC_LD, ry, rx, offset);
9710 break;
9711 #endif
9712 case M16_OPC_RRIA:
9713 imm = ctx->opcode & 0xf;
9714 imm = imm | ((ctx->opcode >> 20) & 0x7f) << 4;
9715 imm = imm | ((ctx->opcode >> 16) & 0xf) << 11;
9716 imm = (int16_t) (imm << 1) >> 1;
9717 if ((ctx->opcode >> 4) & 0x1) {
9718 #if defined(TARGET_MIPS64)
9719 check_mips_64(ctx);
9720 gen_arith_imm(ctx, OPC_DADDIU, ry, rx, imm);
9721 #else
9722 generate_exception(ctx, EXCP_RI);
9723 #endif
9724 } else {
9725 gen_arith_imm(ctx, OPC_ADDIU, ry, rx, imm);
9727 break;
9728 case M16_OPC_ADDIU8:
9729 gen_arith_imm(ctx, OPC_ADDIU, rx, rx, imm);
9730 break;
9731 case M16_OPC_SLTI:
9732 gen_slt_imm(ctx, OPC_SLTI, 24, rx, imm);
9733 break;
9734 case M16_OPC_SLTIU:
9735 gen_slt_imm(ctx, OPC_SLTIU, 24, rx, imm);
9736 break;
9737 case M16_OPC_I8:
9738 switch (funct) {
9739 case I8_BTEQZ:
9740 gen_compute_branch(ctx, OPC_BEQ, 4, 24, 0, offset << 1);
9741 break;
9742 case I8_BTNEZ:
9743 gen_compute_branch(ctx, OPC_BNE, 4, 24, 0, offset << 1);
9744 break;
9745 case I8_SWRASP:
9746 gen_st(ctx, OPC_SW, 31, 29, imm);
9747 break;
9748 case I8_ADJSP:
9749 gen_arith_imm(ctx, OPC_ADDIU, 29, 29, imm);
9750 break;
9751 case I8_SVRS:
9753 int xsregs = (ctx->opcode >> 24) & 0x7;
9754 int aregs = (ctx->opcode >> 16) & 0xf;
9755 int do_ra = (ctx->opcode >> 6) & 0x1;
9756 int do_s0 = (ctx->opcode >> 5) & 0x1;
9757 int do_s1 = (ctx->opcode >> 4) & 0x1;
9758 int framesize = (((ctx->opcode >> 20) & 0xf) << 4
9759 | (ctx->opcode & 0xf)) << 3;
9761 if (ctx->opcode & (1 << 7)) {
9762 gen_mips16_save(ctx, xsregs, aregs,
9763 do_ra, do_s0, do_s1,
9764 framesize);
9765 } else {
9766 gen_mips16_restore(ctx, xsregs, aregs,
9767 do_ra, do_s0, do_s1,
9768 framesize);
9771 break;
9772 default:
9773 generate_exception(ctx, EXCP_RI);
9774 break;
9776 break;
9777 case M16_OPC_LI:
9778 tcg_gen_movi_tl(cpu_gpr[rx], (uint16_t) imm);
9779 break;
9780 case M16_OPC_CMPI:
9781 tcg_gen_xori_tl(cpu_gpr[24], cpu_gpr[rx], (uint16_t) imm);
9782 break;
9783 #if defined(TARGET_MIPS64)
9784 case M16_OPC_SD:
9785 gen_st(ctx, OPC_SD, ry, rx, offset);
9786 break;
9787 #endif
9788 case M16_OPC_LB:
9789 gen_ld(ctx, OPC_LB, ry, rx, offset);
9790 break;
9791 case M16_OPC_LH:
9792 gen_ld(ctx, OPC_LH, ry, rx, offset);
9793 break;
9794 case M16_OPC_LWSP:
9795 gen_ld(ctx, OPC_LW, rx, 29, offset);
9796 break;
9797 case M16_OPC_LW:
9798 gen_ld(ctx, OPC_LW, ry, rx, offset);
9799 break;
9800 case M16_OPC_LBU:
9801 gen_ld(ctx, OPC_LBU, ry, rx, offset);
9802 break;
9803 case M16_OPC_LHU:
9804 gen_ld(ctx, OPC_LHU, ry, rx, offset);
9805 break;
9806 case M16_OPC_LWPC:
9807 gen_ld(ctx, OPC_LWPC, rx, 0, offset);
9808 break;
9809 #if defined(TARGET_MIPS64)
9810 case M16_OPC_LWU:
9811 gen_ld(ctx, OPC_LWU, ry, rx, offset);
9812 break;
9813 #endif
9814 case M16_OPC_SB:
9815 gen_st(ctx, OPC_SB, ry, rx, offset);
9816 break;
9817 case M16_OPC_SH:
9818 gen_st(ctx, OPC_SH, ry, rx, offset);
9819 break;
9820 case M16_OPC_SWSP:
9821 gen_st(ctx, OPC_SW, rx, 29, offset);
9822 break;
9823 case M16_OPC_SW:
9824 gen_st(ctx, OPC_SW, ry, rx, offset);
9825 break;
9826 #if defined(TARGET_MIPS64)
9827 case M16_OPC_I64:
9828 decode_i64_mips16(ctx, ry, funct, offset, 1);
9829 break;
9830 #endif
9831 default:
9832 generate_exception(ctx, EXCP_RI);
9833 break;
9836 return 4;
9839 static int decode_mips16_opc (CPUMIPSState *env, DisasContext *ctx)
9841 int rx, ry;
9842 int sa;
9843 int op, cnvt_op, op1, offset;
9844 int funct;
9845 int n_bytes;
9847 op = (ctx->opcode >> 11) & 0x1f;
9848 sa = (ctx->opcode >> 2) & 0x7;
9849 sa = sa == 0 ? 8 : sa;
9850 rx = xlat((ctx->opcode >> 8) & 0x7);
9851 cnvt_op = (ctx->opcode >> 5) & 0x7;
9852 ry = xlat((ctx->opcode >> 5) & 0x7);
9853 op1 = offset = ctx->opcode & 0x1f;
9855 n_bytes = 2;
9857 switch (op) {
9858 case M16_OPC_ADDIUSP:
9860 int16_t imm = ((uint8_t) ctx->opcode) << 2;
9862 gen_arith_imm(ctx, OPC_ADDIU, rx, 29, imm);
9864 break;
9865 case M16_OPC_ADDIUPC:
9866 gen_addiupc(ctx, rx, ((uint8_t) ctx->opcode) << 2, 0, 0);
9867 break;
9868 case M16_OPC_B:
9869 offset = (ctx->opcode & 0x7ff) << 1;
9870 offset = (int16_t)(offset << 4) >> 4;
9871 gen_compute_branch(ctx, OPC_BEQ, 2, 0, 0, offset);
9872 /* No delay slot, so just process as a normal instruction */
9873 break;
9874 case M16_OPC_JAL:
9875 offset = cpu_lduw_code(env, ctx->pc + 2);
9876 offset = (((ctx->opcode & 0x1f) << 21)
9877 | ((ctx->opcode >> 5) & 0x1f) << 16
9878 | offset) << 2;
9879 op = ((ctx->opcode >> 10) & 0x1) ? OPC_JALXS : OPC_JALS;
9880 gen_compute_branch(ctx, op, 4, rx, ry, offset);
9881 n_bytes = 4;
9882 break;
9883 case M16_OPC_BEQZ:
9884 gen_compute_branch(ctx, OPC_BEQ, 2, rx, 0, ((int8_t)ctx->opcode) << 1);
9885 /* No delay slot, so just process as a normal instruction */
9886 break;
9887 case M16_OPC_BNEQZ:
9888 gen_compute_branch(ctx, OPC_BNE, 2, rx, 0, ((int8_t)ctx->opcode) << 1);
9889 /* No delay slot, so just process as a normal instruction */
9890 break;
9891 case M16_OPC_SHIFT:
9892 switch (ctx->opcode & 0x3) {
9893 case 0x0:
9894 gen_shift_imm(ctx, OPC_SLL, rx, ry, sa);
9895 break;
9896 case 0x1:
9897 #if defined(TARGET_MIPS64)
9898 check_mips_64(ctx);
9899 gen_shift_imm(ctx, OPC_DSLL, rx, ry, sa);
9900 #else
9901 generate_exception(ctx, EXCP_RI);
9902 #endif
9903 break;
9904 case 0x2:
9905 gen_shift_imm(ctx, OPC_SRL, rx, ry, sa);
9906 break;
9907 case 0x3:
9908 gen_shift_imm(ctx, OPC_SRA, rx, ry, sa);
9909 break;
9911 break;
9912 #if defined(TARGET_MIPS64)
9913 case M16_OPC_LD:
9914 check_mips_64(ctx);
9915 gen_ld(ctx, OPC_LD, ry, rx, offset << 3);
9916 break;
9917 #endif
9918 case M16_OPC_RRIA:
9920 int16_t imm = (int8_t)((ctx->opcode & 0xf) << 4) >> 4;
9922 if ((ctx->opcode >> 4) & 1) {
9923 #if defined(TARGET_MIPS64)
9924 check_mips_64(ctx);
9925 gen_arith_imm(ctx, OPC_DADDIU, ry, rx, imm);
9926 #else
9927 generate_exception(ctx, EXCP_RI);
9928 #endif
9929 } else {
9930 gen_arith_imm(ctx, OPC_ADDIU, ry, rx, imm);
9933 break;
9934 case M16_OPC_ADDIU8:
9936 int16_t imm = (int8_t) ctx->opcode;
9938 gen_arith_imm(ctx, OPC_ADDIU, rx, rx, imm);
9940 break;
9941 case M16_OPC_SLTI:
9943 int16_t imm = (uint8_t) ctx->opcode;
9944 gen_slt_imm(ctx, OPC_SLTI, 24, rx, imm);
9946 break;
9947 case M16_OPC_SLTIU:
9949 int16_t imm = (uint8_t) ctx->opcode;
9950 gen_slt_imm(ctx, OPC_SLTIU, 24, rx, imm);
9952 break;
9953 case M16_OPC_I8:
9955 int reg32;
9957 funct = (ctx->opcode >> 8) & 0x7;
9958 switch (funct) {
9959 case I8_BTEQZ:
9960 gen_compute_branch(ctx, OPC_BEQ, 2, 24, 0,
9961 ((int8_t)ctx->opcode) << 1);
9962 break;
9963 case I8_BTNEZ:
9964 gen_compute_branch(ctx, OPC_BNE, 2, 24, 0,
9965 ((int8_t)ctx->opcode) << 1);
9966 break;
9967 case I8_SWRASP:
9968 gen_st(ctx, OPC_SW, 31, 29, (ctx->opcode & 0xff) << 2);
9969 break;
9970 case I8_ADJSP:
9971 gen_arith_imm(ctx, OPC_ADDIU, 29, 29,
9972 ((int8_t)ctx->opcode) << 3);
9973 break;
9974 case I8_SVRS:
9976 int do_ra = ctx->opcode & (1 << 6);
9977 int do_s0 = ctx->opcode & (1 << 5);
9978 int do_s1 = ctx->opcode & (1 << 4);
9979 int framesize = ctx->opcode & 0xf;
9981 if (framesize == 0) {
9982 framesize = 128;
9983 } else {
9984 framesize = framesize << 3;
9987 if (ctx->opcode & (1 << 7)) {
9988 gen_mips16_save(ctx, 0, 0,
9989 do_ra, do_s0, do_s1, framesize);
9990 } else {
9991 gen_mips16_restore(ctx, 0, 0,
9992 do_ra, do_s0, do_s1, framesize);
9995 break;
9996 case I8_MOV32R:
9998 int rz = xlat(ctx->opcode & 0x7);
10000 reg32 = (((ctx->opcode >> 3) & 0x3) << 3) |
10001 ((ctx->opcode >> 5) & 0x7);
10002 gen_arith(ctx, OPC_ADDU, reg32, rz, 0);
10004 break;
10005 case I8_MOVR32:
10006 reg32 = ctx->opcode & 0x1f;
10007 gen_arith(ctx, OPC_ADDU, ry, reg32, 0);
10008 break;
10009 default:
10010 generate_exception(ctx, EXCP_RI);
10011 break;
10014 break;
10015 case M16_OPC_LI:
10017 int16_t imm = (uint8_t) ctx->opcode;
10019 gen_arith_imm(ctx, OPC_ADDIU, rx, 0, imm);
10021 break;
10022 case M16_OPC_CMPI:
10024 int16_t imm = (uint8_t) ctx->opcode;
10025 gen_logic_imm(ctx, OPC_XORI, 24, rx, imm);
10027 break;
10028 #if defined(TARGET_MIPS64)
10029 case M16_OPC_SD:
10030 check_mips_64(ctx);
10031 gen_st(ctx, OPC_SD, ry, rx, offset << 3);
10032 break;
10033 #endif
10034 case M16_OPC_LB:
10035 gen_ld(ctx, OPC_LB, ry, rx, offset);
10036 break;
10037 case M16_OPC_LH:
10038 gen_ld(ctx, OPC_LH, ry, rx, offset << 1);
10039 break;
10040 case M16_OPC_LWSP:
10041 gen_ld(ctx, OPC_LW, rx, 29, ((uint8_t)ctx->opcode) << 2);
10042 break;
10043 case M16_OPC_LW:
10044 gen_ld(ctx, OPC_LW, ry, rx, offset << 2);
10045 break;
10046 case M16_OPC_LBU:
10047 gen_ld(ctx, OPC_LBU, ry, rx, offset);
10048 break;
10049 case M16_OPC_LHU:
10050 gen_ld(ctx, OPC_LHU, ry, rx, offset << 1);
10051 break;
10052 case M16_OPC_LWPC:
10053 gen_ld(ctx, OPC_LWPC, rx, 0, ((uint8_t)ctx->opcode) << 2);
10054 break;
10055 #if defined (TARGET_MIPS64)
10056 case M16_OPC_LWU:
10057 check_mips_64(ctx);
10058 gen_ld(ctx, OPC_LWU, ry, rx, offset << 2);
10059 break;
10060 #endif
10061 case M16_OPC_SB:
10062 gen_st(ctx, OPC_SB, ry, rx, offset);
10063 break;
10064 case M16_OPC_SH:
10065 gen_st(ctx, OPC_SH, ry, rx, offset << 1);
10066 break;
10067 case M16_OPC_SWSP:
10068 gen_st(ctx, OPC_SW, rx, 29, ((uint8_t)ctx->opcode) << 2);
10069 break;
10070 case M16_OPC_SW:
10071 gen_st(ctx, OPC_SW, ry, rx, offset << 2);
10072 break;
10073 case M16_OPC_RRR:
10075 int rz = xlat((ctx->opcode >> 2) & 0x7);
10076 int mips32_op;
10078 switch (ctx->opcode & 0x3) {
10079 case RRR_ADDU:
10080 mips32_op = OPC_ADDU;
10081 break;
10082 case RRR_SUBU:
10083 mips32_op = OPC_SUBU;
10084 break;
10085 #if defined(TARGET_MIPS64)
10086 case RRR_DADDU:
10087 mips32_op = OPC_DADDU;
10088 check_mips_64(ctx);
10089 break;
10090 case RRR_DSUBU:
10091 mips32_op = OPC_DSUBU;
10092 check_mips_64(ctx);
10093 break;
10094 #endif
10095 default:
10096 generate_exception(ctx, EXCP_RI);
10097 goto done;
10100 gen_arith(ctx, mips32_op, rz, rx, ry);
10101 done:
10104 break;
10105 case M16_OPC_RR:
10106 switch (op1) {
10107 case RR_JR:
10109 int nd = (ctx->opcode >> 7) & 0x1;
10110 int link = (ctx->opcode >> 6) & 0x1;
10111 int ra = (ctx->opcode >> 5) & 0x1;
10113 if (link) {
10114 op = nd ? OPC_JALRC : OPC_JALRS;
10115 } else {
10116 op = OPC_JR;
10119 gen_compute_branch(ctx, op, 2, ra ? 31 : rx, 31, 0);
10121 break;
10122 case RR_SDBBP:
10123 /* XXX: not clear which exception should be raised
10124 * when in debug mode...
10126 check_insn(ctx, ISA_MIPS32);
10127 if (!(ctx->hflags & MIPS_HFLAG_DM)) {
10128 generate_exception(ctx, EXCP_DBp);
10129 } else {
10130 generate_exception(ctx, EXCP_DBp);
10132 break;
10133 case RR_SLT:
10134 gen_slt(ctx, OPC_SLT, 24, rx, ry);
10135 break;
10136 case RR_SLTU:
10137 gen_slt(ctx, OPC_SLTU, 24, rx, ry);
10138 break;
10139 case RR_BREAK:
10140 generate_exception(ctx, EXCP_BREAK);
10141 break;
10142 case RR_SLLV:
10143 gen_shift(ctx, OPC_SLLV, ry, rx, ry);
10144 break;
10145 case RR_SRLV:
10146 gen_shift(ctx, OPC_SRLV, ry, rx, ry);
10147 break;
10148 case RR_SRAV:
10149 gen_shift(ctx, OPC_SRAV, ry, rx, ry);
10150 break;
10151 #if defined (TARGET_MIPS64)
10152 case RR_DSRL:
10153 check_mips_64(ctx);
10154 gen_shift_imm(ctx, OPC_DSRL, ry, ry, sa);
10155 break;
10156 #endif
10157 case RR_CMP:
10158 gen_logic(ctx, OPC_XOR, 24, rx, ry);
10159 break;
10160 case RR_NEG:
10161 gen_arith(ctx, OPC_SUBU, rx, 0, ry);
10162 break;
10163 case RR_AND:
10164 gen_logic(ctx, OPC_AND, rx, rx, ry);
10165 break;
10166 case RR_OR:
10167 gen_logic(ctx, OPC_OR, rx, rx, ry);
10168 break;
10169 case RR_XOR:
10170 gen_logic(ctx, OPC_XOR, rx, rx, ry);
10171 break;
10172 case RR_NOT:
10173 gen_logic(ctx, OPC_NOR, rx, ry, 0);
10174 break;
10175 case RR_MFHI:
10176 gen_HILO(ctx, OPC_MFHI, 0, rx);
10177 break;
10178 case RR_CNVT:
10179 switch (cnvt_op) {
10180 case RR_RY_CNVT_ZEB:
10181 tcg_gen_ext8u_tl(cpu_gpr[rx], cpu_gpr[rx]);
10182 break;
10183 case RR_RY_CNVT_ZEH:
10184 tcg_gen_ext16u_tl(cpu_gpr[rx], cpu_gpr[rx]);
10185 break;
10186 case RR_RY_CNVT_SEB:
10187 tcg_gen_ext8s_tl(cpu_gpr[rx], cpu_gpr[rx]);
10188 break;
10189 case RR_RY_CNVT_SEH:
10190 tcg_gen_ext16s_tl(cpu_gpr[rx], cpu_gpr[rx]);
10191 break;
10192 #if defined (TARGET_MIPS64)
10193 case RR_RY_CNVT_ZEW:
10194 check_mips_64(ctx);
10195 tcg_gen_ext32u_tl(cpu_gpr[rx], cpu_gpr[rx]);
10196 break;
10197 case RR_RY_CNVT_SEW:
10198 check_mips_64(ctx);
10199 tcg_gen_ext32s_tl(cpu_gpr[rx], cpu_gpr[rx]);
10200 break;
10201 #endif
10202 default:
10203 generate_exception(ctx, EXCP_RI);
10204 break;
10206 break;
10207 case RR_MFLO:
10208 gen_HILO(ctx, OPC_MFLO, 0, rx);
10209 break;
10210 #if defined (TARGET_MIPS64)
10211 case RR_DSRA:
10212 check_mips_64(ctx);
10213 gen_shift_imm(ctx, OPC_DSRA, ry, ry, sa);
10214 break;
10215 case RR_DSLLV:
10216 check_mips_64(ctx);
10217 gen_shift(ctx, OPC_DSLLV, ry, rx, ry);
10218 break;
10219 case RR_DSRLV:
10220 check_mips_64(ctx);
10221 gen_shift(ctx, OPC_DSRLV, ry, rx, ry);
10222 break;
10223 case RR_DSRAV:
10224 check_mips_64(ctx);
10225 gen_shift(ctx, OPC_DSRAV, ry, rx, ry);
10226 break;
10227 #endif
10228 case RR_MULT:
10229 gen_muldiv(ctx, OPC_MULT, 0, rx, ry);
10230 break;
10231 case RR_MULTU:
10232 gen_muldiv(ctx, OPC_MULTU, 0, rx, ry);
10233 break;
10234 case RR_DIV:
10235 gen_muldiv(ctx, OPC_DIV, 0, rx, ry);
10236 break;
10237 case RR_DIVU:
10238 gen_muldiv(ctx, OPC_DIVU, 0, rx, ry);
10239 break;
10240 #if defined (TARGET_MIPS64)
10241 case RR_DMULT:
10242 check_mips_64(ctx);
10243 gen_muldiv(ctx, OPC_DMULT, 0, rx, ry);
10244 break;
10245 case RR_DMULTU:
10246 check_mips_64(ctx);
10247 gen_muldiv(ctx, OPC_DMULTU, 0, rx, ry);
10248 break;
10249 case RR_DDIV:
10250 check_mips_64(ctx);
10251 gen_muldiv(ctx, OPC_DDIV, 0, rx, ry);
10252 break;
10253 case RR_DDIVU:
10254 check_mips_64(ctx);
10255 gen_muldiv(ctx, OPC_DDIVU, 0, rx, ry);
10256 break;
10257 #endif
10258 default:
10259 generate_exception(ctx, EXCP_RI);
10260 break;
10262 break;
10263 case M16_OPC_EXTEND:
10264 decode_extended_mips16_opc(env, ctx);
10265 n_bytes = 4;
10266 break;
10267 #if defined(TARGET_MIPS64)
10268 case M16_OPC_I64:
10269 funct = (ctx->opcode >> 8) & 0x7;
10270 decode_i64_mips16(ctx, ry, funct, offset, 0);
10271 break;
10272 #endif
10273 default:
10274 generate_exception(ctx, EXCP_RI);
10275 break;
10278 return n_bytes;
10281 /* microMIPS extension to MIPS32/MIPS64 */
10284 * microMIPS32/microMIPS64 major opcodes
10286 * 1. MIPS Architecture for Programmers Volume II-B:
10287 * The microMIPS32 Instruction Set (Revision 3.05)
10289 * Table 6.2 microMIPS32 Encoding of Major Opcode Field
10291 * 2. MIPS Architecture For Programmers Volume II-A:
10292 * The MIPS64 Instruction Set (Revision 3.51)
10295 enum {
10296 POOL32A = 0x00,
10297 POOL16A = 0x01,
10298 LBU16 = 0x02,
10299 MOVE16 = 0x03,
10300 ADDI32 = 0x04,
10301 LBU32 = 0x05,
10302 SB32 = 0x06,
10303 LB32 = 0x07,
10305 POOL32B = 0x08,
10306 POOL16B = 0x09,
10307 LHU16 = 0x0a,
10308 ANDI16 = 0x0b,
10309 ADDIU32 = 0x0c,
10310 LHU32 = 0x0d,
10311 SH32 = 0x0e,
10312 LH32 = 0x0f,
10314 POOL32I = 0x10,
10315 POOL16C = 0x11,
10316 LWSP16 = 0x12,
10317 POOL16D = 0x13,
10318 ORI32 = 0x14,
10319 POOL32F = 0x15,
10320 POOL32S = 0x16, /* MIPS64 */
10321 DADDIU32 = 0x17, /* MIPS64 */
10323 /* 0x1f is reserved */
10324 POOL32C = 0x18,
10325 LWGP16 = 0x19,
10326 LW16 = 0x1a,
10327 POOL16E = 0x1b,
10328 XORI32 = 0x1c,
10329 JALS32 = 0x1d,
10330 ADDIUPC = 0x1e,
10332 /* 0x20 is reserved */
10333 RES_20 = 0x20,
10334 POOL16F = 0x21,
10335 SB16 = 0x22,
10336 BEQZ16 = 0x23,
10337 SLTI32 = 0x24,
10338 BEQ32 = 0x25,
10339 SWC132 = 0x26,
10340 LWC132 = 0x27,
10342 /* 0x28 and 0x29 are reserved */
10343 RES_28 = 0x28,
10344 RES_29 = 0x29,
10345 SH16 = 0x2a,
10346 BNEZ16 = 0x2b,
10347 SLTIU32 = 0x2c,
10348 BNE32 = 0x2d,
10349 SDC132 = 0x2e,
10350 LDC132 = 0x2f,
10352 /* 0x30 and 0x31 are reserved */
10353 RES_30 = 0x30,
10354 RES_31 = 0x31,
10355 SWSP16 = 0x32,
10356 B16 = 0x33,
10357 ANDI32 = 0x34,
10358 J32 = 0x35,
10359 SD32 = 0x36, /* MIPS64 */
10360 LD32 = 0x37, /* MIPS64 */
10362 /* 0x38 and 0x39 are reserved */
10363 RES_38 = 0x38,
10364 RES_39 = 0x39,
10365 SW16 = 0x3a,
10366 LI16 = 0x3b,
10367 JALX32 = 0x3c,
10368 JAL32 = 0x3d,
10369 SW32 = 0x3e,
10370 LW32 = 0x3f
10373 /* POOL32A encoding of minor opcode field */
10375 enum {
10376 /* These opcodes are distinguished only by bits 9..6; those bits are
10377 * what are recorded below. */
10378 SLL32 = 0x0,
10379 SRL32 = 0x1,
10380 SRA = 0x2,
10381 ROTR = 0x3,
10383 SLLV = 0x0,
10384 SRLV = 0x1,
10385 SRAV = 0x2,
10386 ROTRV = 0x3,
10387 ADD = 0x4,
10388 ADDU32 = 0x5,
10389 SUB = 0x6,
10390 SUBU32 = 0x7,
10391 MUL = 0x8,
10392 AND = 0x9,
10393 OR32 = 0xa,
10394 NOR = 0xb,
10395 XOR32 = 0xc,
10396 SLT = 0xd,
10397 SLTU = 0xe,
10399 MOVN = 0x0,
10400 MOVZ = 0x1,
10401 LWXS = 0x4,
10403 /* The following can be distinguished by their lower 6 bits. */
10404 INS = 0x0c,
10405 EXT = 0x2c,
10406 POOL32AXF = 0x3c
10409 /* POOL32AXF encoding of minor opcode field extension */
10412 * 1. MIPS Architecture for Programmers Volume II-B:
10413 * The microMIPS32 Instruction Set (Revision 3.05)
10415 * Table 6.5 POOL32Axf Encoding of Minor Opcode Extension Field
10417 * 2. MIPS Architecture for Programmers VolumeIV-e:
10418 * The MIPS DSP Application-Specific Extension
10419 * to the microMIPS32 Architecture (Revision 2.34)
10421 * Table 5.5 POOL32Axf Encoding of Minor Opcode Extension Field
10424 enum {
10425 /* bits 11..6 */
10426 TEQ = 0x00,
10427 TGE = 0x08,
10428 TGEU = 0x10,
10429 TLT = 0x20,
10430 TLTU = 0x28,
10431 TNE = 0x30,
10433 MFC0 = 0x03,
10434 MTC0 = 0x0b,
10436 /* begin of microMIPS32 DSP */
10438 /* bits 13..12 for 0x01 */
10439 MFHI_ACC = 0x0,
10440 MFLO_ACC = 0x1,
10441 MTHI_ACC = 0x2,
10442 MTLO_ACC = 0x3,
10444 /* bits 13..12 for 0x2a */
10445 MADD_ACC = 0x0,
10446 MADDU_ACC = 0x1,
10447 MSUB_ACC = 0x2,
10448 MSUBU_ACC = 0x3,
10450 /* bits 13..12 for 0x32 */
10451 MULT_ACC = 0x0,
10452 MULTU_ACC = 0x1,
10454 /* end of microMIPS32 DSP */
10456 /* bits 15..12 for 0x2c */
10457 SEB = 0x2,
10458 SEH = 0x3,
10459 CLO = 0x4,
10460 CLZ = 0x5,
10461 RDHWR = 0x6,
10462 WSBH = 0x7,
10463 MULT = 0x8,
10464 MULTU = 0x9,
10465 DIV = 0xa,
10466 DIVU = 0xb,
10467 MADD = 0xc,
10468 MADDU = 0xd,
10469 MSUB = 0xe,
10470 MSUBU = 0xf,
10472 /* bits 15..12 for 0x34 */
10473 MFC2 = 0x4,
10474 MTC2 = 0x5,
10475 MFHC2 = 0x8,
10476 MTHC2 = 0x9,
10477 CFC2 = 0xc,
10478 CTC2 = 0xd,
10480 /* bits 15..12 for 0x3c */
10481 JALR = 0x0,
10482 JR = 0x0, /* alias */
10483 JALR_HB = 0x1,
10484 JALRS = 0x4,
10485 JALRS_HB = 0x5,
10487 /* bits 15..12 for 0x05 */
10488 RDPGPR = 0xe,
10489 WRPGPR = 0xf,
10491 /* bits 15..12 for 0x0d */
10492 TLBP = 0x0,
10493 TLBR = 0x1,
10494 TLBWI = 0x2,
10495 TLBWR = 0x3,
10496 WAIT = 0x9,
10497 IRET = 0xd,
10498 DERET = 0xe,
10499 ERET = 0xf,
10501 /* bits 15..12 for 0x15 */
10502 DMT = 0x0,
10503 DVPE = 0x1,
10504 EMT = 0x2,
10505 EVPE = 0x3,
10507 /* bits 15..12 for 0x1d */
10508 DI = 0x4,
10509 EI = 0x5,
10511 /* bits 15..12 for 0x2d */
10512 SYNC = 0x6,
10513 SYSCALL = 0x8,
10514 SDBBP = 0xd,
10516 /* bits 15..12 for 0x35 */
10517 MFHI32 = 0x0,
10518 MFLO32 = 0x1,
10519 MTHI32 = 0x2,
10520 MTLO32 = 0x3,
10523 /* POOL32B encoding of minor opcode field (bits 15..12) */
10525 enum {
10526 LWC2 = 0x0,
10527 LWP = 0x1,
10528 LDP = 0x4,
10529 LWM32 = 0x5,
10530 CACHE = 0x6,
10531 LDM = 0x7,
10532 SWC2 = 0x8,
10533 SWP = 0x9,
10534 SDP = 0xc,
10535 SWM32 = 0xd,
10536 SDM = 0xf
10539 /* POOL32C encoding of minor opcode field (bits 15..12) */
10541 enum {
10542 LWL = 0x0,
10543 SWL = 0x8,
10544 LWR = 0x1,
10545 SWR = 0x9,
10546 PREF = 0x2,
10547 /* 0xa is reserved */
10548 LL = 0x3,
10549 SC = 0xb,
10550 LDL = 0x4,
10551 SDL = 0xc,
10552 LDR = 0x5,
10553 SDR = 0xd,
10554 /* 0x6 is reserved */
10555 LWU = 0xe,
10556 LLD = 0x7,
10557 SCD = 0xf
10560 /* POOL32F encoding of minor opcode field (bits 5..0) */
10562 enum {
10563 /* These are the bit 7..6 values */
10564 ADD_FMT = 0x0,
10565 MOVN_FMT = 0x0,
10567 SUB_FMT = 0x1,
10568 MOVZ_FMT = 0x1,
10570 MUL_FMT = 0x2,
10572 DIV_FMT = 0x3,
10574 /* These are the bit 8..6 values */
10575 RSQRT2_FMT = 0x0,
10576 MOVF_FMT = 0x0,
10578 LWXC1 = 0x1,
10579 MOVT_FMT = 0x1,
10581 PLL_PS = 0x2,
10582 SWXC1 = 0x2,
10584 PLU_PS = 0x3,
10585 LDXC1 = 0x3,
10587 PUL_PS = 0x4,
10588 SDXC1 = 0x4,
10589 RECIP2_FMT = 0x4,
10591 PUU_PS = 0x5,
10592 LUXC1 = 0x5,
10594 CVT_PS_S = 0x6,
10595 SUXC1 = 0x6,
10596 ADDR_PS = 0x6,
10597 PREFX = 0x6,
10599 MULR_PS = 0x7,
10601 MADD_S = 0x01,
10602 MADD_D = 0x09,
10603 MADD_PS = 0x11,
10604 ALNV_PS = 0x19,
10605 MSUB_S = 0x21,
10606 MSUB_D = 0x29,
10607 MSUB_PS = 0x31,
10609 NMADD_S = 0x02,
10610 NMADD_D = 0x0a,
10611 NMADD_PS = 0x12,
10612 NMSUB_S = 0x22,
10613 NMSUB_D = 0x2a,
10614 NMSUB_PS = 0x32,
10616 POOL32FXF = 0x3b,
10618 CABS_COND_FMT = 0x1c, /* MIPS3D */
10619 C_COND_FMT = 0x3c
10622 /* POOL32Fxf encoding of minor opcode extension field */
10624 enum {
10625 CVT_L = 0x04,
10626 RSQRT_FMT = 0x08,
10627 FLOOR_L = 0x0c,
10628 CVT_PW_PS = 0x1c,
10629 CVT_W = 0x24,
10630 SQRT_FMT = 0x28,
10631 FLOOR_W = 0x2c,
10632 CVT_PS_PW = 0x3c,
10633 CFC1 = 0x40,
10634 RECIP_FMT = 0x48,
10635 CEIL_L = 0x4c,
10636 CTC1 = 0x60,
10637 CEIL_W = 0x6c,
10638 MFC1 = 0x80,
10639 CVT_S_PL = 0x84,
10640 TRUNC_L = 0x8c,
10641 MTC1 = 0xa0,
10642 CVT_S_PU = 0xa4,
10643 TRUNC_W = 0xac,
10644 MFHC1 = 0xc0,
10645 ROUND_L = 0xcc,
10646 MTHC1 = 0xe0,
10647 ROUND_W = 0xec,
10649 MOV_FMT = 0x01,
10650 MOVF = 0x05,
10651 ABS_FMT = 0x0d,
10652 RSQRT1_FMT = 0x1d,
10653 MOVT = 0x25,
10654 NEG_FMT = 0x2d,
10655 CVT_D = 0x4d,
10656 RECIP1_FMT = 0x5d,
10657 CVT_S = 0x6d
10660 /* POOL32I encoding of minor opcode field (bits 25..21) */
10662 enum {
10663 BLTZ = 0x00,
10664 BLTZAL = 0x01,
10665 BGEZ = 0x02,
10666 BGEZAL = 0x03,
10667 BLEZ = 0x04,
10668 BNEZC = 0x05,
10669 BGTZ = 0x06,
10670 BEQZC = 0x07,
10671 TLTI = 0x08,
10672 TGEI = 0x09,
10673 TLTIU = 0x0a,
10674 TGEIU = 0x0b,
10675 TNEI = 0x0c,
10676 LUI = 0x0d,
10677 TEQI = 0x0e,
10678 SYNCI = 0x10,
10679 BLTZALS = 0x11,
10680 BGEZALS = 0x13,
10681 BC2F = 0x14,
10682 BC2T = 0x15,
10683 BPOSGE64 = 0x1a,
10684 BPOSGE32 = 0x1b,
10685 /* These overlap and are distinguished by bit16 of the instruction */
10686 BC1F = 0x1c,
10687 BC1T = 0x1d,
10688 BC1ANY2F = 0x1c,
10689 BC1ANY2T = 0x1d,
10690 BC1ANY4F = 0x1e,
10691 BC1ANY4T = 0x1f
10694 /* POOL16A encoding of minor opcode field */
10696 enum {
10697 ADDU16 = 0x0,
10698 SUBU16 = 0x1
10701 /* POOL16B encoding of minor opcode field */
10703 enum {
10704 SLL16 = 0x0,
10705 SRL16 = 0x1
10708 /* POOL16C encoding of minor opcode field */
10710 enum {
10711 NOT16 = 0x00,
10712 XOR16 = 0x04,
10713 AND16 = 0x08,
10714 OR16 = 0x0c,
10715 LWM16 = 0x10,
10716 SWM16 = 0x14,
10717 JR16 = 0x18,
10718 JRC16 = 0x1a,
10719 JALR16 = 0x1c,
10720 JALR16S = 0x1e,
10721 MFHI16 = 0x20,
10722 MFLO16 = 0x24,
10723 BREAK16 = 0x28,
10724 SDBBP16 = 0x2c,
10725 JRADDIUSP = 0x30
10728 /* POOL16D encoding of minor opcode field */
10730 enum {
10731 ADDIUS5 = 0x0,
10732 ADDIUSP = 0x1
10735 /* POOL16E encoding of minor opcode field */
10737 enum {
10738 ADDIUR2 = 0x0,
10739 ADDIUR1SP = 0x1
10742 static int mmreg (int r)
10744 static const int map[] = { 16, 17, 2, 3, 4, 5, 6, 7 };
10746 return map[r];
10749 /* Used for 16-bit store instructions. */
10750 static int mmreg2 (int r)
10752 static const int map[] = { 0, 17, 2, 3, 4, 5, 6, 7 };
10754 return map[r];
10757 #define uMIPS_RD(op) ((op >> 7) & 0x7)
10758 #define uMIPS_RS(op) ((op >> 4) & 0x7)
10759 #define uMIPS_RS2(op) uMIPS_RS(op)
10760 #define uMIPS_RS1(op) ((op >> 1) & 0x7)
10761 #define uMIPS_RD5(op) ((op >> 5) & 0x1f)
10762 #define uMIPS_RS5(op) (op & 0x1f)
10764 /* Signed immediate */
10765 #define SIMM(op, start, width) \
10766 ((int32_t)(((op >> start) & ((~0U) >> (32-width))) \
10767 << (32-width)) \
10768 >> (32-width))
10769 /* Zero-extended immediate */
10770 #define ZIMM(op, start, width) ((op >> start) & ((~0U) >> (32-width)))
10772 static void gen_addiur1sp(DisasContext *ctx)
10774 int rd = mmreg(uMIPS_RD(ctx->opcode));
10776 gen_arith_imm(ctx, OPC_ADDIU, rd, 29, ((ctx->opcode >> 1) & 0x3f) << 2);
10779 static void gen_addiur2(DisasContext *ctx)
10781 static const int decoded_imm[] = { 1, 4, 8, 12, 16, 20, 24, -1 };
10782 int rd = mmreg(uMIPS_RD(ctx->opcode));
10783 int rs = mmreg(uMIPS_RS(ctx->opcode));
10785 gen_arith_imm(ctx, OPC_ADDIU, rd, rs, decoded_imm[ZIMM(ctx->opcode, 1, 3)]);
10788 static void gen_addiusp(DisasContext *ctx)
10790 int encoded = ZIMM(ctx->opcode, 1, 9);
10791 int decoded;
10793 if (encoded <= 1) {
10794 decoded = 256 + encoded;
10795 } else if (encoded <= 255) {
10796 decoded = encoded;
10797 } else if (encoded <= 509) {
10798 decoded = encoded - 512;
10799 } else {
10800 decoded = encoded - 768;
10803 gen_arith_imm(ctx, OPC_ADDIU, 29, 29, decoded << 2);
10806 static void gen_addius5(DisasContext *ctx)
10808 int imm = SIMM(ctx->opcode, 1, 4);
10809 int rd = (ctx->opcode >> 5) & 0x1f;
10811 gen_arith_imm(ctx, OPC_ADDIU, rd, rd, imm);
10814 static void gen_andi16(DisasContext *ctx)
10816 static const int decoded_imm[] = { 128, 1, 2, 3, 4, 7, 8, 15, 16,
10817 31, 32, 63, 64, 255, 32768, 65535 };
10818 int rd = mmreg(uMIPS_RD(ctx->opcode));
10819 int rs = mmreg(uMIPS_RS(ctx->opcode));
10820 int encoded = ZIMM(ctx->opcode, 0, 4);
10822 gen_logic_imm(ctx, OPC_ANDI, rd, rs, decoded_imm[encoded]);
10825 static void gen_ldst_multiple (DisasContext *ctx, uint32_t opc, int reglist,
10826 int base, int16_t offset)
10828 const char *opn = "ldst_multiple";
10829 TCGv t0, t1;
10830 TCGv_i32 t2;
10832 if (ctx->hflags & MIPS_HFLAG_BMASK) {
10833 generate_exception(ctx, EXCP_RI);
10834 return;
10837 t0 = tcg_temp_new();
10839 gen_base_offset_addr(ctx, t0, base, offset);
10841 t1 = tcg_const_tl(reglist);
10842 t2 = tcg_const_i32(ctx->mem_idx);
10844 save_cpu_state(ctx, 1);
10845 switch (opc) {
10846 case LWM32:
10847 gen_helper_lwm(cpu_env, t0, t1, t2);
10848 opn = "lwm";
10849 break;
10850 case SWM32:
10851 gen_helper_swm(cpu_env, t0, t1, t2);
10852 opn = "swm";
10853 break;
10854 #ifdef TARGET_MIPS64
10855 case LDM:
10856 gen_helper_ldm(cpu_env, t0, t1, t2);
10857 opn = "ldm";
10858 break;
10859 case SDM:
10860 gen_helper_sdm(cpu_env, t0, t1, t2);
10861 opn = "sdm";
10862 break;
10863 #endif
10865 (void)opn;
10866 MIPS_DEBUG("%s, %x, %d(%s)", opn, reglist, offset, regnames[base]);
10867 tcg_temp_free(t0);
10868 tcg_temp_free(t1);
10869 tcg_temp_free_i32(t2);
10873 static void gen_pool16c_insn(DisasContext *ctx)
10875 int rd = mmreg((ctx->opcode >> 3) & 0x7);
10876 int rs = mmreg(ctx->opcode & 0x7);
10877 int opc;
10879 switch (((ctx->opcode) >> 4) & 0x3f) {
10880 case NOT16 + 0:
10881 case NOT16 + 1:
10882 case NOT16 + 2:
10883 case NOT16 + 3:
10884 gen_logic(ctx, OPC_NOR, rd, rs, 0);
10885 break;
10886 case XOR16 + 0:
10887 case XOR16 + 1:
10888 case XOR16 + 2:
10889 case XOR16 + 3:
10890 gen_logic(ctx, OPC_XOR, rd, rd, rs);
10891 break;
10892 case AND16 + 0:
10893 case AND16 + 1:
10894 case AND16 + 2:
10895 case AND16 + 3:
10896 gen_logic(ctx, OPC_AND, rd, rd, rs);
10897 break;
10898 case OR16 + 0:
10899 case OR16 + 1:
10900 case OR16 + 2:
10901 case OR16 + 3:
10902 gen_logic(ctx, OPC_OR, rd, rd, rs);
10903 break;
10904 case LWM16 + 0:
10905 case LWM16 + 1:
10906 case LWM16 + 2:
10907 case LWM16 + 3:
10909 static const int lwm_convert[] = { 0x11, 0x12, 0x13, 0x14 };
10910 int offset = ZIMM(ctx->opcode, 0, 4);
10912 gen_ldst_multiple(ctx, LWM32, lwm_convert[(ctx->opcode >> 4) & 0x3],
10913 29, offset << 2);
10915 break;
10916 case SWM16 + 0:
10917 case SWM16 + 1:
10918 case SWM16 + 2:
10919 case SWM16 + 3:
10921 static const int swm_convert[] = { 0x11, 0x12, 0x13, 0x14 };
10922 int offset = ZIMM(ctx->opcode, 0, 4);
10924 gen_ldst_multiple(ctx, SWM32, swm_convert[(ctx->opcode >> 4) & 0x3],
10925 29, offset << 2);
10927 break;
10928 case JR16 + 0:
10929 case JR16 + 1:
10931 int reg = ctx->opcode & 0x1f;
10933 gen_compute_branch(ctx, OPC_JR, 2, reg, 0, 0);
10935 break;
10936 case JRC16 + 0:
10937 case JRC16 + 1:
10939 int reg = ctx->opcode & 0x1f;
10941 gen_compute_branch(ctx, OPC_JR, 2, reg, 0, 0);
10942 /* Let normal delay slot handling in our caller take us
10943 to the branch target. */
10945 break;
10946 case JALR16 + 0:
10947 case JALR16 + 1:
10948 opc = OPC_JALR;
10949 goto do_jalr;
10950 case JALR16S + 0:
10951 case JALR16S + 1:
10952 opc = OPC_JALRS;
10953 do_jalr:
10955 int reg = ctx->opcode & 0x1f;
10957 gen_compute_branch(ctx, opc, 2, reg, 31, 0);
10959 break;
10960 case MFHI16 + 0:
10961 case MFHI16 + 1:
10962 gen_HILO(ctx, OPC_MFHI, 0, uMIPS_RS5(ctx->opcode));
10963 break;
10964 case MFLO16 + 0:
10965 case MFLO16 + 1:
10966 gen_HILO(ctx, OPC_MFLO, 0, uMIPS_RS5(ctx->opcode));
10967 break;
10968 case BREAK16:
10969 generate_exception(ctx, EXCP_BREAK);
10970 break;
10971 case SDBBP16:
10972 /* XXX: not clear which exception should be raised
10973 * when in debug mode...
10975 check_insn(ctx, ISA_MIPS32);
10976 if (!(ctx->hflags & MIPS_HFLAG_DM)) {
10977 generate_exception(ctx, EXCP_DBp);
10978 } else {
10979 generate_exception(ctx, EXCP_DBp);
10981 break;
10982 case JRADDIUSP + 0:
10983 case JRADDIUSP + 1:
10985 int imm = ZIMM(ctx->opcode, 0, 5);
10987 gen_compute_branch(ctx, OPC_JR, 2, 31, 0, 0);
10988 gen_arith_imm(ctx, OPC_ADDIU, 29, 29, imm << 2);
10989 /* Let normal delay slot handling in our caller take us
10990 to the branch target. */
10992 break;
10993 default:
10994 generate_exception(ctx, EXCP_RI);
10995 break;
10999 static void gen_ldxs (DisasContext *ctx, int base, int index, int rd)
11001 TCGv t0 = tcg_temp_new();
11002 TCGv t1 = tcg_temp_new();
11004 gen_load_gpr(t0, base);
11006 if (index != 0) {
11007 gen_load_gpr(t1, index);
11008 tcg_gen_shli_tl(t1, t1, 2);
11009 gen_op_addr_add(ctx, t0, t1, t0);
11012 tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_TESL);
11013 gen_store_gpr(t1, rd);
11015 tcg_temp_free(t0);
11016 tcg_temp_free(t1);
11019 static void gen_ldst_pair (DisasContext *ctx, uint32_t opc, int rd,
11020 int base, int16_t offset)
11022 const char *opn = "ldst_pair";
11023 TCGv t0, t1;
11025 if (ctx->hflags & MIPS_HFLAG_BMASK || rd == 31) {
11026 generate_exception(ctx, EXCP_RI);
11027 return;
11030 t0 = tcg_temp_new();
11031 t1 = tcg_temp_new();
11033 gen_base_offset_addr(ctx, t0, base, offset);
11035 switch (opc) {
11036 case LWP:
11037 if (rd == base) {
11038 generate_exception(ctx, EXCP_RI);
11039 return;
11041 tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_TESL);
11042 gen_store_gpr(t1, rd);
11043 tcg_gen_movi_tl(t1, 4);
11044 gen_op_addr_add(ctx, t0, t0, t1);
11045 tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_TESL);
11046 gen_store_gpr(t1, rd+1);
11047 opn = "lwp";
11048 break;
11049 case SWP:
11050 gen_load_gpr(t1, rd);
11051 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL);
11052 tcg_gen_movi_tl(t1, 4);
11053 gen_op_addr_add(ctx, t0, t0, t1);
11054 gen_load_gpr(t1, rd+1);
11055 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL);
11056 opn = "swp";
11057 break;
11058 #ifdef TARGET_MIPS64
11059 case LDP:
11060 if (rd == base) {
11061 generate_exception(ctx, EXCP_RI);
11062 return;
11064 tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_TEQ);
11065 gen_store_gpr(t1, rd);
11066 tcg_gen_movi_tl(t1, 8);
11067 gen_op_addr_add(ctx, t0, t0, t1);
11068 tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_TEQ);
11069 gen_store_gpr(t1, rd+1);
11070 opn = "ldp";
11071 break;
11072 case SDP:
11073 gen_load_gpr(t1, rd);
11074 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEQ);
11075 tcg_gen_movi_tl(t1, 8);
11076 gen_op_addr_add(ctx, t0, t0, t1);
11077 gen_load_gpr(t1, rd+1);
11078 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEQ);
11079 opn = "sdp";
11080 break;
11081 #endif
11083 (void)opn; /* avoid a compiler warning */
11084 MIPS_DEBUG("%s, %s, %d(%s)", opn, regnames[rd], offset, regnames[base]);
11085 tcg_temp_free(t0);
11086 tcg_temp_free(t1);
11089 static void gen_pool32axf (CPUMIPSState *env, DisasContext *ctx, int rt, int rs)
11091 int extension = (ctx->opcode >> 6) & 0x3f;
11092 int minor = (ctx->opcode >> 12) & 0xf;
11093 uint32_t mips32_op;
11095 switch (extension) {
11096 case TEQ:
11097 mips32_op = OPC_TEQ;
11098 goto do_trap;
11099 case TGE:
11100 mips32_op = OPC_TGE;
11101 goto do_trap;
11102 case TGEU:
11103 mips32_op = OPC_TGEU;
11104 goto do_trap;
11105 case TLT:
11106 mips32_op = OPC_TLT;
11107 goto do_trap;
11108 case TLTU:
11109 mips32_op = OPC_TLTU;
11110 goto do_trap;
11111 case TNE:
11112 mips32_op = OPC_TNE;
11113 do_trap:
11114 gen_trap(ctx, mips32_op, rs, rt, -1);
11115 break;
11116 #ifndef CONFIG_USER_ONLY
11117 case MFC0:
11118 case MFC0 + 32:
11119 check_cp0_enabled(ctx);
11120 if (rt == 0) {
11121 /* Treat as NOP. */
11122 break;
11124 gen_mfc0(ctx, cpu_gpr[rt], rs, (ctx->opcode >> 11) & 0x7);
11125 break;
11126 case MTC0:
11127 case MTC0 + 32:
11128 check_cp0_enabled(ctx);
11130 TCGv t0 = tcg_temp_new();
11132 gen_load_gpr(t0, rt);
11133 gen_mtc0(ctx, t0, rs, (ctx->opcode >> 11) & 0x7);
11134 tcg_temp_free(t0);
11136 break;
11137 #endif
11138 case 0x2a:
11139 switch (minor & 3) {
11140 case MADD_ACC:
11141 gen_muldiv(ctx, OPC_MADD, (ctx->opcode >> 14) & 3, rs, rt);
11142 break;
11143 case MADDU_ACC:
11144 gen_muldiv(ctx, OPC_MADDU, (ctx->opcode >> 14) & 3, rs, rt);
11145 break;
11146 case MSUB_ACC:
11147 gen_muldiv(ctx, OPC_MSUB, (ctx->opcode >> 14) & 3, rs, rt);
11148 break;
11149 case MSUBU_ACC:
11150 gen_muldiv(ctx, OPC_MSUBU, (ctx->opcode >> 14) & 3, rs, rt);
11151 break;
11152 default:
11153 goto pool32axf_invalid;
11155 break;
11156 case 0x32:
11157 switch (minor & 3) {
11158 case MULT_ACC:
11159 gen_muldiv(ctx, OPC_MULT, (ctx->opcode >> 14) & 3, rs, rt);
11160 break;
11161 case MULTU_ACC:
11162 gen_muldiv(ctx, OPC_MULTU, (ctx->opcode >> 14) & 3, rs, rt);
11163 break;
11164 default:
11165 goto pool32axf_invalid;
11167 break;
11168 case 0x2c:
11169 switch (minor) {
11170 case SEB:
11171 gen_bshfl(ctx, OPC_SEB, rs, rt);
11172 break;
11173 case SEH:
11174 gen_bshfl(ctx, OPC_SEH, rs, rt);
11175 break;
11176 case CLO:
11177 mips32_op = OPC_CLO;
11178 goto do_cl;
11179 case CLZ:
11180 mips32_op = OPC_CLZ;
11181 do_cl:
11182 check_insn(ctx, ISA_MIPS32);
11183 gen_cl(ctx, mips32_op, rt, rs);
11184 break;
11185 case RDHWR:
11186 gen_rdhwr(ctx, rt, rs);
11187 break;
11188 case WSBH:
11189 gen_bshfl(ctx, OPC_WSBH, rs, rt);
11190 break;
11191 case MULT:
11192 mips32_op = OPC_MULT;
11193 goto do_mul;
11194 case MULTU:
11195 mips32_op = OPC_MULTU;
11196 goto do_mul;
11197 case DIV:
11198 mips32_op = OPC_DIV;
11199 goto do_div;
11200 case DIVU:
11201 mips32_op = OPC_DIVU;
11202 goto do_div;
11203 do_div:
11204 check_insn(ctx, ISA_MIPS32);
11205 gen_muldiv(ctx, mips32_op, 0, rs, rt);
11206 break;
11207 case MADD:
11208 mips32_op = OPC_MADD;
11209 goto do_mul;
11210 case MADDU:
11211 mips32_op = OPC_MADDU;
11212 goto do_mul;
11213 case MSUB:
11214 mips32_op = OPC_MSUB;
11215 goto do_mul;
11216 case MSUBU:
11217 mips32_op = OPC_MSUBU;
11218 do_mul:
11219 check_insn(ctx, ISA_MIPS32);
11220 gen_muldiv(ctx, mips32_op, 0, rs, rt);
11221 break;
11222 default:
11223 goto pool32axf_invalid;
11225 break;
11226 case 0x34:
11227 switch (minor) {
11228 case MFC2:
11229 case MTC2:
11230 case MFHC2:
11231 case MTHC2:
11232 case CFC2:
11233 case CTC2:
11234 generate_exception_err(ctx, EXCP_CpU, 2);
11235 break;
11236 default:
11237 goto pool32axf_invalid;
11239 break;
11240 case 0x3c:
11241 switch (minor) {
11242 case JALR:
11243 case JALR_HB:
11244 gen_compute_branch (ctx, OPC_JALR, 4, rs, rt, 0);
11245 break;
11246 case JALRS:
11247 case JALRS_HB:
11248 gen_compute_branch (ctx, OPC_JALRS, 4, rs, rt, 0);
11249 break;
11250 default:
11251 goto pool32axf_invalid;
11253 break;
11254 case 0x05:
11255 switch (minor) {
11256 case RDPGPR:
11257 check_cp0_enabled(ctx);
11258 check_insn(ctx, ISA_MIPS32R2);
11259 gen_load_srsgpr(rt, rs);
11260 break;
11261 case WRPGPR:
11262 check_cp0_enabled(ctx);
11263 check_insn(ctx, ISA_MIPS32R2);
11264 gen_store_srsgpr(rt, rs);
11265 break;
11266 default:
11267 goto pool32axf_invalid;
11269 break;
11270 #ifndef CONFIG_USER_ONLY
11271 case 0x0d:
11272 switch (minor) {
11273 case TLBP:
11274 mips32_op = OPC_TLBP;
11275 goto do_cp0;
11276 case TLBR:
11277 mips32_op = OPC_TLBR;
11278 goto do_cp0;
11279 case TLBWI:
11280 mips32_op = OPC_TLBWI;
11281 goto do_cp0;
11282 case TLBWR:
11283 mips32_op = OPC_TLBWR;
11284 goto do_cp0;
11285 case WAIT:
11286 mips32_op = OPC_WAIT;
11287 goto do_cp0;
11288 case DERET:
11289 mips32_op = OPC_DERET;
11290 goto do_cp0;
11291 case ERET:
11292 mips32_op = OPC_ERET;
11293 do_cp0:
11294 gen_cp0(env, ctx, mips32_op, rt, rs);
11295 break;
11296 default:
11297 goto pool32axf_invalid;
11299 break;
11300 case 0x1d:
11301 switch (minor) {
11302 case DI:
11303 check_cp0_enabled(ctx);
11305 TCGv t0 = tcg_temp_new();
11307 save_cpu_state(ctx, 1);
11308 gen_helper_di(t0, cpu_env);
11309 gen_store_gpr(t0, rs);
11310 /* Stop translation as we may have switched the execution mode */
11311 ctx->bstate = BS_STOP;
11312 tcg_temp_free(t0);
11314 break;
11315 case EI:
11316 check_cp0_enabled(ctx);
11318 TCGv t0 = tcg_temp_new();
11320 save_cpu_state(ctx, 1);
11321 gen_helper_ei(t0, cpu_env);
11322 gen_store_gpr(t0, rs);
11323 /* Stop translation as we may have switched the execution mode */
11324 ctx->bstate = BS_STOP;
11325 tcg_temp_free(t0);
11327 break;
11328 default:
11329 goto pool32axf_invalid;
11331 break;
11332 #endif
11333 case 0x2d:
11334 switch (minor) {
11335 case SYNC:
11336 /* NOP */
11337 break;
11338 case SYSCALL:
11339 generate_exception(ctx, EXCP_SYSCALL);
11340 ctx->bstate = BS_STOP;
11341 break;
11342 case SDBBP:
11343 check_insn(ctx, ISA_MIPS32);
11344 if (!(ctx->hflags & MIPS_HFLAG_DM)) {
11345 generate_exception(ctx, EXCP_DBp);
11346 } else {
11347 generate_exception(ctx, EXCP_DBp);
11349 break;
11350 default:
11351 goto pool32axf_invalid;
11353 break;
11354 case 0x01:
11355 switch (minor & 3) {
11356 case MFHI_ACC:
11357 gen_HILO(ctx, OPC_MFHI, minor >> 2, rs);
11358 break;
11359 case MFLO_ACC:
11360 gen_HILO(ctx, OPC_MFLO, minor >> 2, rs);
11361 break;
11362 case MTHI_ACC:
11363 gen_HILO(ctx, OPC_MTHI, minor >> 2, rs);
11364 break;
11365 case MTLO_ACC:
11366 gen_HILO(ctx, OPC_MTLO, minor >> 2, rs);
11367 break;
11368 default:
11369 goto pool32axf_invalid;
11371 break;
11372 case 0x35:
11373 switch (minor) {
11374 case MFHI32:
11375 gen_HILO(ctx, OPC_MFHI, 0, rs);
11376 break;
11377 case MFLO32:
11378 gen_HILO(ctx, OPC_MFLO, 0, rs);
11379 break;
11380 case MTHI32:
11381 gen_HILO(ctx, OPC_MTHI, 0, rs);
11382 break;
11383 case MTLO32:
11384 gen_HILO(ctx, OPC_MTLO, 0, rs);
11385 break;
11386 default:
11387 goto pool32axf_invalid;
11389 break;
11390 default:
11391 pool32axf_invalid:
11392 MIPS_INVAL("pool32axf");
11393 generate_exception(ctx, EXCP_RI);
11394 break;
11398 /* Values for microMIPS fmt field. Variable-width, depending on which
11399 formats the instruction supports. */
11401 enum {
11402 FMT_SD_S = 0,
11403 FMT_SD_D = 1,
11405 FMT_SDPS_S = 0,
11406 FMT_SDPS_D = 1,
11407 FMT_SDPS_PS = 2,
11409 FMT_SWL_S = 0,
11410 FMT_SWL_W = 1,
11411 FMT_SWL_L = 2,
11413 FMT_DWL_D = 0,
11414 FMT_DWL_W = 1,
11415 FMT_DWL_L = 2
11418 static void gen_pool32fxf(DisasContext *ctx, int rt, int rs)
11420 int extension = (ctx->opcode >> 6) & 0x3ff;
11421 uint32_t mips32_op;
11423 #define FLOAT_1BIT_FMT(opc, fmt) (fmt << 8) | opc
11424 #define FLOAT_2BIT_FMT(opc, fmt) (fmt << 7) | opc
11425 #define COND_FLOAT_MOV(opc, cond) (cond << 7) | opc
11427 switch (extension) {
11428 case FLOAT_1BIT_FMT(CFC1, 0):
11429 mips32_op = OPC_CFC1;
11430 goto do_cp1;
11431 case FLOAT_1BIT_FMT(CTC1, 0):
11432 mips32_op = OPC_CTC1;
11433 goto do_cp1;
11434 case FLOAT_1BIT_FMT(MFC1, 0):
11435 mips32_op = OPC_MFC1;
11436 goto do_cp1;
11437 case FLOAT_1BIT_FMT(MTC1, 0):
11438 mips32_op = OPC_MTC1;
11439 goto do_cp1;
11440 case FLOAT_1BIT_FMT(MFHC1, 0):
11441 mips32_op = OPC_MFHC1;
11442 goto do_cp1;
11443 case FLOAT_1BIT_FMT(MTHC1, 0):
11444 mips32_op = OPC_MTHC1;
11445 do_cp1:
11446 gen_cp1(ctx, mips32_op, rt, rs);
11447 break;
11449 /* Reciprocal square root */
11450 case FLOAT_1BIT_FMT(RSQRT_FMT, FMT_SD_S):
11451 mips32_op = OPC_RSQRT_S;
11452 goto do_unaryfp;
11453 case FLOAT_1BIT_FMT(RSQRT_FMT, FMT_SD_D):
11454 mips32_op = OPC_RSQRT_D;
11455 goto do_unaryfp;
11457 /* Square root */
11458 case FLOAT_1BIT_FMT(SQRT_FMT, FMT_SD_S):
11459 mips32_op = OPC_SQRT_S;
11460 goto do_unaryfp;
11461 case FLOAT_1BIT_FMT(SQRT_FMT, FMT_SD_D):
11462 mips32_op = OPC_SQRT_D;
11463 goto do_unaryfp;
11465 /* Reciprocal */
11466 case FLOAT_1BIT_FMT(RECIP_FMT, FMT_SD_S):
11467 mips32_op = OPC_RECIP_S;
11468 goto do_unaryfp;
11469 case FLOAT_1BIT_FMT(RECIP_FMT, FMT_SD_D):
11470 mips32_op = OPC_RECIP_D;
11471 goto do_unaryfp;
11473 /* Floor */
11474 case FLOAT_1BIT_FMT(FLOOR_L, FMT_SD_S):
11475 mips32_op = OPC_FLOOR_L_S;
11476 goto do_unaryfp;
11477 case FLOAT_1BIT_FMT(FLOOR_L, FMT_SD_D):
11478 mips32_op = OPC_FLOOR_L_D;
11479 goto do_unaryfp;
11480 case FLOAT_1BIT_FMT(FLOOR_W, FMT_SD_S):
11481 mips32_op = OPC_FLOOR_W_S;
11482 goto do_unaryfp;
11483 case FLOAT_1BIT_FMT(FLOOR_W, FMT_SD_D):
11484 mips32_op = OPC_FLOOR_W_D;
11485 goto do_unaryfp;
11487 /* Ceiling */
11488 case FLOAT_1BIT_FMT(CEIL_L, FMT_SD_S):
11489 mips32_op = OPC_CEIL_L_S;
11490 goto do_unaryfp;
11491 case FLOAT_1BIT_FMT(CEIL_L, FMT_SD_D):
11492 mips32_op = OPC_CEIL_L_D;
11493 goto do_unaryfp;
11494 case FLOAT_1BIT_FMT(CEIL_W, FMT_SD_S):
11495 mips32_op = OPC_CEIL_W_S;
11496 goto do_unaryfp;
11497 case FLOAT_1BIT_FMT(CEIL_W, FMT_SD_D):
11498 mips32_op = OPC_CEIL_W_D;
11499 goto do_unaryfp;
11501 /* Truncation */
11502 case FLOAT_1BIT_FMT(TRUNC_L, FMT_SD_S):
11503 mips32_op = OPC_TRUNC_L_S;
11504 goto do_unaryfp;
11505 case FLOAT_1BIT_FMT(TRUNC_L, FMT_SD_D):
11506 mips32_op = OPC_TRUNC_L_D;
11507 goto do_unaryfp;
11508 case FLOAT_1BIT_FMT(TRUNC_W, FMT_SD_S):
11509 mips32_op = OPC_TRUNC_W_S;
11510 goto do_unaryfp;
11511 case FLOAT_1BIT_FMT(TRUNC_W, FMT_SD_D):
11512 mips32_op = OPC_TRUNC_W_D;
11513 goto do_unaryfp;
11515 /* Round */
11516 case FLOAT_1BIT_FMT(ROUND_L, FMT_SD_S):
11517 mips32_op = OPC_ROUND_L_S;
11518 goto do_unaryfp;
11519 case FLOAT_1BIT_FMT(ROUND_L, FMT_SD_D):
11520 mips32_op = OPC_ROUND_L_D;
11521 goto do_unaryfp;
11522 case FLOAT_1BIT_FMT(ROUND_W, FMT_SD_S):
11523 mips32_op = OPC_ROUND_W_S;
11524 goto do_unaryfp;
11525 case FLOAT_1BIT_FMT(ROUND_W, FMT_SD_D):
11526 mips32_op = OPC_ROUND_W_D;
11527 goto do_unaryfp;
11529 /* Integer to floating-point conversion */
11530 case FLOAT_1BIT_FMT(CVT_L, FMT_SD_S):
11531 mips32_op = OPC_CVT_L_S;
11532 goto do_unaryfp;
11533 case FLOAT_1BIT_FMT(CVT_L, FMT_SD_D):
11534 mips32_op = OPC_CVT_L_D;
11535 goto do_unaryfp;
11536 case FLOAT_1BIT_FMT(CVT_W, FMT_SD_S):
11537 mips32_op = OPC_CVT_W_S;
11538 goto do_unaryfp;
11539 case FLOAT_1BIT_FMT(CVT_W, FMT_SD_D):
11540 mips32_op = OPC_CVT_W_D;
11541 goto do_unaryfp;
11543 /* Paired-foo conversions */
11544 case FLOAT_1BIT_FMT(CVT_S_PL, 0):
11545 mips32_op = OPC_CVT_S_PL;
11546 goto do_unaryfp;
11547 case FLOAT_1BIT_FMT(CVT_S_PU, 0):
11548 mips32_op = OPC_CVT_S_PU;
11549 goto do_unaryfp;
11550 case FLOAT_1BIT_FMT(CVT_PW_PS, 0):
11551 mips32_op = OPC_CVT_PW_PS;
11552 goto do_unaryfp;
11553 case FLOAT_1BIT_FMT(CVT_PS_PW, 0):
11554 mips32_op = OPC_CVT_PS_PW;
11555 goto do_unaryfp;
11557 /* Floating-point moves */
11558 case FLOAT_2BIT_FMT(MOV_FMT, FMT_SDPS_S):
11559 mips32_op = OPC_MOV_S;
11560 goto do_unaryfp;
11561 case FLOAT_2BIT_FMT(MOV_FMT, FMT_SDPS_D):
11562 mips32_op = OPC_MOV_D;
11563 goto do_unaryfp;
11564 case FLOAT_2BIT_FMT(MOV_FMT, FMT_SDPS_PS):
11565 mips32_op = OPC_MOV_PS;
11566 goto do_unaryfp;
11568 /* Absolute value */
11569 case FLOAT_2BIT_FMT(ABS_FMT, FMT_SDPS_S):
11570 mips32_op = OPC_ABS_S;
11571 goto do_unaryfp;
11572 case FLOAT_2BIT_FMT(ABS_FMT, FMT_SDPS_D):
11573 mips32_op = OPC_ABS_D;
11574 goto do_unaryfp;
11575 case FLOAT_2BIT_FMT(ABS_FMT, FMT_SDPS_PS):
11576 mips32_op = OPC_ABS_PS;
11577 goto do_unaryfp;
11579 /* Negation */
11580 case FLOAT_2BIT_FMT(NEG_FMT, FMT_SDPS_S):
11581 mips32_op = OPC_NEG_S;
11582 goto do_unaryfp;
11583 case FLOAT_2BIT_FMT(NEG_FMT, FMT_SDPS_D):
11584 mips32_op = OPC_NEG_D;
11585 goto do_unaryfp;
11586 case FLOAT_2BIT_FMT(NEG_FMT, FMT_SDPS_PS):
11587 mips32_op = OPC_NEG_PS;
11588 goto do_unaryfp;
11590 /* Reciprocal square root step */
11591 case FLOAT_2BIT_FMT(RSQRT1_FMT, FMT_SDPS_S):
11592 mips32_op = OPC_RSQRT1_S;
11593 goto do_unaryfp;
11594 case FLOAT_2BIT_FMT(RSQRT1_FMT, FMT_SDPS_D):
11595 mips32_op = OPC_RSQRT1_D;
11596 goto do_unaryfp;
11597 case FLOAT_2BIT_FMT(RSQRT1_FMT, FMT_SDPS_PS):
11598 mips32_op = OPC_RSQRT1_PS;
11599 goto do_unaryfp;
11601 /* Reciprocal step */
11602 case FLOAT_2BIT_FMT(RECIP1_FMT, FMT_SDPS_S):
11603 mips32_op = OPC_RECIP1_S;
11604 goto do_unaryfp;
11605 case FLOAT_2BIT_FMT(RECIP1_FMT, FMT_SDPS_D):
11606 mips32_op = OPC_RECIP1_S;
11607 goto do_unaryfp;
11608 case FLOAT_2BIT_FMT(RECIP1_FMT, FMT_SDPS_PS):
11609 mips32_op = OPC_RECIP1_PS;
11610 goto do_unaryfp;
11612 /* Conversions from double */
11613 case FLOAT_2BIT_FMT(CVT_D, FMT_SWL_S):
11614 mips32_op = OPC_CVT_D_S;
11615 goto do_unaryfp;
11616 case FLOAT_2BIT_FMT(CVT_D, FMT_SWL_W):
11617 mips32_op = OPC_CVT_D_W;
11618 goto do_unaryfp;
11619 case FLOAT_2BIT_FMT(CVT_D, FMT_SWL_L):
11620 mips32_op = OPC_CVT_D_L;
11621 goto do_unaryfp;
11623 /* Conversions from single */
11624 case FLOAT_2BIT_FMT(CVT_S, FMT_DWL_D):
11625 mips32_op = OPC_CVT_S_D;
11626 goto do_unaryfp;
11627 case FLOAT_2BIT_FMT(CVT_S, FMT_DWL_W):
11628 mips32_op = OPC_CVT_S_W;
11629 goto do_unaryfp;
11630 case FLOAT_2BIT_FMT(CVT_S, FMT_DWL_L):
11631 mips32_op = OPC_CVT_S_L;
11632 do_unaryfp:
11633 gen_farith(ctx, mips32_op, -1, rs, rt, 0);
11634 break;
11636 /* Conditional moves on floating-point codes */
11637 case COND_FLOAT_MOV(MOVT, 0):
11638 case COND_FLOAT_MOV(MOVT, 1):
11639 case COND_FLOAT_MOV(MOVT, 2):
11640 case COND_FLOAT_MOV(MOVT, 3):
11641 case COND_FLOAT_MOV(MOVT, 4):
11642 case COND_FLOAT_MOV(MOVT, 5):
11643 case COND_FLOAT_MOV(MOVT, 6):
11644 case COND_FLOAT_MOV(MOVT, 7):
11645 gen_movci(ctx, rt, rs, (ctx->opcode >> 13) & 0x7, 1);
11646 break;
11647 case COND_FLOAT_MOV(MOVF, 0):
11648 case COND_FLOAT_MOV(MOVF, 1):
11649 case COND_FLOAT_MOV(MOVF, 2):
11650 case COND_FLOAT_MOV(MOVF, 3):
11651 case COND_FLOAT_MOV(MOVF, 4):
11652 case COND_FLOAT_MOV(MOVF, 5):
11653 case COND_FLOAT_MOV(MOVF, 6):
11654 case COND_FLOAT_MOV(MOVF, 7):
11655 gen_movci(ctx, rt, rs, (ctx->opcode >> 13) & 0x7, 0);
11656 break;
11657 default:
11658 MIPS_INVAL("pool32fxf");
11659 generate_exception(ctx, EXCP_RI);
11660 break;
11664 static void decode_micromips32_opc (CPUMIPSState *env, DisasContext *ctx,
11665 uint16_t insn_hw1)
11667 int32_t offset;
11668 uint16_t insn;
11669 int rt, rs, rd, rr;
11670 int16_t imm;
11671 uint32_t op, minor, mips32_op;
11672 uint32_t cond, fmt, cc;
11674 insn = cpu_lduw_code(env, ctx->pc + 2);
11675 ctx->opcode = (ctx->opcode << 16) | insn;
11677 rt = (ctx->opcode >> 21) & 0x1f;
11678 rs = (ctx->opcode >> 16) & 0x1f;
11679 rd = (ctx->opcode >> 11) & 0x1f;
11680 rr = (ctx->opcode >> 6) & 0x1f;
11681 imm = (int16_t) ctx->opcode;
11683 op = (ctx->opcode >> 26) & 0x3f;
11684 switch (op) {
11685 case POOL32A:
11686 minor = ctx->opcode & 0x3f;
11687 switch (minor) {
11688 case 0x00:
11689 minor = (ctx->opcode >> 6) & 0xf;
11690 switch (minor) {
11691 case SLL32:
11692 mips32_op = OPC_SLL;
11693 goto do_shifti;
11694 case SRA:
11695 mips32_op = OPC_SRA;
11696 goto do_shifti;
11697 case SRL32:
11698 mips32_op = OPC_SRL;
11699 goto do_shifti;
11700 case ROTR:
11701 mips32_op = OPC_ROTR;
11702 do_shifti:
11703 gen_shift_imm(ctx, mips32_op, rt, rs, rd);
11704 break;
11705 default:
11706 goto pool32a_invalid;
11708 break;
11709 case 0x10:
11710 minor = (ctx->opcode >> 6) & 0xf;
11711 switch (minor) {
11712 /* Arithmetic */
11713 case ADD:
11714 mips32_op = OPC_ADD;
11715 goto do_arith;
11716 case ADDU32:
11717 mips32_op = OPC_ADDU;
11718 goto do_arith;
11719 case SUB:
11720 mips32_op = OPC_SUB;
11721 goto do_arith;
11722 case SUBU32:
11723 mips32_op = OPC_SUBU;
11724 goto do_arith;
11725 case MUL:
11726 mips32_op = OPC_MUL;
11727 do_arith:
11728 gen_arith(ctx, mips32_op, rd, rs, rt);
11729 break;
11730 /* Shifts */
11731 case SLLV:
11732 mips32_op = OPC_SLLV;
11733 goto do_shift;
11734 case SRLV:
11735 mips32_op = OPC_SRLV;
11736 goto do_shift;
11737 case SRAV:
11738 mips32_op = OPC_SRAV;
11739 goto do_shift;
11740 case ROTRV:
11741 mips32_op = OPC_ROTRV;
11742 do_shift:
11743 gen_shift(ctx, mips32_op, rd, rs, rt);
11744 break;
11745 /* Logical operations */
11746 case AND:
11747 mips32_op = OPC_AND;
11748 goto do_logic;
11749 case OR32:
11750 mips32_op = OPC_OR;
11751 goto do_logic;
11752 case NOR:
11753 mips32_op = OPC_NOR;
11754 goto do_logic;
11755 case XOR32:
11756 mips32_op = OPC_XOR;
11757 do_logic:
11758 gen_logic(ctx, mips32_op, rd, rs, rt);
11759 break;
11760 /* Set less than */
11761 case SLT:
11762 mips32_op = OPC_SLT;
11763 goto do_slt;
11764 case SLTU:
11765 mips32_op = OPC_SLTU;
11766 do_slt:
11767 gen_slt(ctx, mips32_op, rd, rs, rt);
11768 break;
11769 default:
11770 goto pool32a_invalid;
11772 break;
11773 case 0x18:
11774 minor = (ctx->opcode >> 6) & 0xf;
11775 switch (minor) {
11776 /* Conditional moves */
11777 case MOVN:
11778 mips32_op = OPC_MOVN;
11779 goto do_cmov;
11780 case MOVZ:
11781 mips32_op = OPC_MOVZ;
11782 do_cmov:
11783 gen_cond_move(ctx, mips32_op, rd, rs, rt);
11784 break;
11785 case LWXS:
11786 gen_ldxs(ctx, rs, rt, rd);
11787 break;
11788 default:
11789 goto pool32a_invalid;
11791 break;
11792 case INS:
11793 gen_bitops(ctx, OPC_INS, rt, rs, rr, rd);
11794 return;
11795 case EXT:
11796 gen_bitops(ctx, OPC_EXT, rt, rs, rr, rd);
11797 return;
11798 case POOL32AXF:
11799 gen_pool32axf(env, ctx, rt, rs);
11800 break;
11801 case 0x07:
11802 generate_exception(ctx, EXCP_BREAK);
11803 break;
11804 default:
11805 pool32a_invalid:
11806 MIPS_INVAL("pool32a");
11807 generate_exception(ctx, EXCP_RI);
11808 break;
11810 break;
11811 case POOL32B:
11812 minor = (ctx->opcode >> 12) & 0xf;
11813 switch (minor) {
11814 case CACHE:
11815 check_cp0_enabled(ctx);
11816 /* Treat as no-op. */
11817 break;
11818 case LWC2:
11819 case SWC2:
11820 /* COP2: Not implemented. */
11821 generate_exception_err(ctx, EXCP_CpU, 2);
11822 break;
11823 case LWP:
11824 case SWP:
11825 #ifdef TARGET_MIPS64
11826 case LDP:
11827 case SDP:
11828 #endif
11829 gen_ldst_pair(ctx, minor, rt, rs, SIMM(ctx->opcode, 0, 12));
11830 break;
11831 case LWM32:
11832 case SWM32:
11833 #ifdef TARGET_MIPS64
11834 case LDM:
11835 case SDM:
11836 #endif
11837 gen_ldst_multiple(ctx, minor, rt, rs, SIMM(ctx->opcode, 0, 12));
11838 break;
11839 default:
11840 MIPS_INVAL("pool32b");
11841 generate_exception(ctx, EXCP_RI);
11842 break;
11844 break;
11845 case POOL32F:
11846 if (ctx->CP0_Config1 & (1 << CP0C1_FP)) {
11847 minor = ctx->opcode & 0x3f;
11848 check_cp1_enabled(ctx);
11849 switch (minor) {
11850 case ALNV_PS:
11851 mips32_op = OPC_ALNV_PS;
11852 goto do_madd;
11853 case MADD_S:
11854 mips32_op = OPC_MADD_S;
11855 goto do_madd;
11856 case MADD_D:
11857 mips32_op = OPC_MADD_D;
11858 goto do_madd;
11859 case MADD_PS:
11860 mips32_op = OPC_MADD_PS;
11861 goto do_madd;
11862 case MSUB_S:
11863 mips32_op = OPC_MSUB_S;
11864 goto do_madd;
11865 case MSUB_D:
11866 mips32_op = OPC_MSUB_D;
11867 goto do_madd;
11868 case MSUB_PS:
11869 mips32_op = OPC_MSUB_PS;
11870 goto do_madd;
11871 case NMADD_S:
11872 mips32_op = OPC_NMADD_S;
11873 goto do_madd;
11874 case NMADD_D:
11875 mips32_op = OPC_NMADD_D;
11876 goto do_madd;
11877 case NMADD_PS:
11878 mips32_op = OPC_NMADD_PS;
11879 goto do_madd;
11880 case NMSUB_S:
11881 mips32_op = OPC_NMSUB_S;
11882 goto do_madd;
11883 case NMSUB_D:
11884 mips32_op = OPC_NMSUB_D;
11885 goto do_madd;
11886 case NMSUB_PS:
11887 mips32_op = OPC_NMSUB_PS;
11888 do_madd:
11889 gen_flt3_arith(ctx, mips32_op, rd, rr, rs, rt);
11890 break;
11891 case CABS_COND_FMT:
11892 cond = (ctx->opcode >> 6) & 0xf;
11893 cc = (ctx->opcode >> 13) & 0x7;
11894 fmt = (ctx->opcode >> 10) & 0x3;
11895 switch (fmt) {
11896 case 0x0:
11897 gen_cmpabs_s(ctx, cond, rt, rs, cc);
11898 break;
11899 case 0x1:
11900 gen_cmpabs_d(ctx, cond, rt, rs, cc);
11901 break;
11902 case 0x2:
11903 gen_cmpabs_ps(ctx, cond, rt, rs, cc);
11904 break;
11905 default:
11906 goto pool32f_invalid;
11908 break;
11909 case C_COND_FMT:
11910 cond = (ctx->opcode >> 6) & 0xf;
11911 cc = (ctx->opcode >> 13) & 0x7;
11912 fmt = (ctx->opcode >> 10) & 0x3;
11913 switch (fmt) {
11914 case 0x0:
11915 gen_cmp_s(ctx, cond, rt, rs, cc);
11916 break;
11917 case 0x1:
11918 gen_cmp_d(ctx, cond, rt, rs, cc);
11919 break;
11920 case 0x2:
11921 gen_cmp_ps(ctx, cond, rt, rs, cc);
11922 break;
11923 default:
11924 goto pool32f_invalid;
11926 break;
11927 case POOL32FXF:
11928 gen_pool32fxf(ctx, rt, rs);
11929 break;
11930 case 0x00:
11931 /* PLL foo */
11932 switch ((ctx->opcode >> 6) & 0x7) {
11933 case PLL_PS:
11934 mips32_op = OPC_PLL_PS;
11935 goto do_ps;
11936 case PLU_PS:
11937 mips32_op = OPC_PLU_PS;
11938 goto do_ps;
11939 case PUL_PS:
11940 mips32_op = OPC_PUL_PS;
11941 goto do_ps;
11942 case PUU_PS:
11943 mips32_op = OPC_PUU_PS;
11944 goto do_ps;
11945 case CVT_PS_S:
11946 mips32_op = OPC_CVT_PS_S;
11947 do_ps:
11948 gen_farith(ctx, mips32_op, rt, rs, rd, 0);
11949 break;
11950 default:
11951 goto pool32f_invalid;
11953 break;
11954 case 0x08:
11955 /* [LS][WDU]XC1 */
11956 switch ((ctx->opcode >> 6) & 0x7) {
11957 case LWXC1:
11958 mips32_op = OPC_LWXC1;
11959 goto do_ldst_cp1;
11960 case SWXC1:
11961 mips32_op = OPC_SWXC1;
11962 goto do_ldst_cp1;
11963 case LDXC1:
11964 mips32_op = OPC_LDXC1;
11965 goto do_ldst_cp1;
11966 case SDXC1:
11967 mips32_op = OPC_SDXC1;
11968 goto do_ldst_cp1;
11969 case LUXC1:
11970 mips32_op = OPC_LUXC1;
11971 goto do_ldst_cp1;
11972 case SUXC1:
11973 mips32_op = OPC_SUXC1;
11974 do_ldst_cp1:
11975 gen_flt3_ldst(ctx, mips32_op, rd, rd, rt, rs);
11976 break;
11977 default:
11978 goto pool32f_invalid;
11980 break;
11981 case 0x18:
11982 /* 3D insns */
11983 fmt = (ctx->opcode >> 9) & 0x3;
11984 switch ((ctx->opcode >> 6) & 0x7) {
11985 case RSQRT2_FMT:
11986 switch (fmt) {
11987 case FMT_SDPS_S:
11988 mips32_op = OPC_RSQRT2_S;
11989 goto do_3d;
11990 case FMT_SDPS_D:
11991 mips32_op = OPC_RSQRT2_D;
11992 goto do_3d;
11993 case FMT_SDPS_PS:
11994 mips32_op = OPC_RSQRT2_PS;
11995 goto do_3d;
11996 default:
11997 goto pool32f_invalid;
11999 break;
12000 case RECIP2_FMT:
12001 switch (fmt) {
12002 case FMT_SDPS_S:
12003 mips32_op = OPC_RECIP2_S;
12004 goto do_3d;
12005 case FMT_SDPS_D:
12006 mips32_op = OPC_RECIP2_D;
12007 goto do_3d;
12008 case FMT_SDPS_PS:
12009 mips32_op = OPC_RECIP2_PS;
12010 goto do_3d;
12011 default:
12012 goto pool32f_invalid;
12014 break;
12015 case ADDR_PS:
12016 mips32_op = OPC_ADDR_PS;
12017 goto do_3d;
12018 case MULR_PS:
12019 mips32_op = OPC_MULR_PS;
12020 do_3d:
12021 gen_farith(ctx, mips32_op, rt, rs, rd, 0);
12022 break;
12023 default:
12024 goto pool32f_invalid;
12026 break;
12027 case 0x20:
12028 /* MOV[FT].fmt and PREFX */
12029 cc = (ctx->opcode >> 13) & 0x7;
12030 fmt = (ctx->opcode >> 9) & 0x3;
12031 switch ((ctx->opcode >> 6) & 0x7) {
12032 case MOVF_FMT:
12033 switch (fmt) {
12034 case FMT_SDPS_S:
12035 gen_movcf_s(rs, rt, cc, 0);
12036 break;
12037 case FMT_SDPS_D:
12038 gen_movcf_d(ctx, rs, rt, cc, 0);
12039 break;
12040 case FMT_SDPS_PS:
12041 gen_movcf_ps(ctx, rs, rt, cc, 0);
12042 break;
12043 default:
12044 goto pool32f_invalid;
12046 break;
12047 case MOVT_FMT:
12048 switch (fmt) {
12049 case FMT_SDPS_S:
12050 gen_movcf_s(rs, rt, cc, 1);
12051 break;
12052 case FMT_SDPS_D:
12053 gen_movcf_d(ctx, rs, rt, cc, 1);
12054 break;
12055 case FMT_SDPS_PS:
12056 gen_movcf_ps(ctx, rs, rt, cc, 1);
12057 break;
12058 default:
12059 goto pool32f_invalid;
12061 break;
12062 case PREFX:
12063 break;
12064 default:
12065 goto pool32f_invalid;
12067 break;
12068 #define FINSN_3ARG_SDPS(prfx) \
12069 switch ((ctx->opcode >> 8) & 0x3) { \
12070 case FMT_SDPS_S: \
12071 mips32_op = OPC_##prfx##_S; \
12072 goto do_fpop; \
12073 case FMT_SDPS_D: \
12074 mips32_op = OPC_##prfx##_D; \
12075 goto do_fpop; \
12076 case FMT_SDPS_PS: \
12077 mips32_op = OPC_##prfx##_PS; \
12078 goto do_fpop; \
12079 default: \
12080 goto pool32f_invalid; \
12082 case 0x30:
12083 /* regular FP ops */
12084 switch ((ctx->opcode >> 6) & 0x3) {
12085 case ADD_FMT:
12086 FINSN_3ARG_SDPS(ADD);
12087 break;
12088 case SUB_FMT:
12089 FINSN_3ARG_SDPS(SUB);
12090 break;
12091 case MUL_FMT:
12092 FINSN_3ARG_SDPS(MUL);
12093 break;
12094 case DIV_FMT:
12095 fmt = (ctx->opcode >> 8) & 0x3;
12096 if (fmt == 1) {
12097 mips32_op = OPC_DIV_D;
12098 } else if (fmt == 0) {
12099 mips32_op = OPC_DIV_S;
12100 } else {
12101 goto pool32f_invalid;
12103 goto do_fpop;
12104 default:
12105 goto pool32f_invalid;
12107 break;
12108 case 0x38:
12109 /* cmovs */
12110 switch ((ctx->opcode >> 6) & 0x3) {
12111 case MOVN_FMT:
12112 FINSN_3ARG_SDPS(MOVN);
12113 break;
12114 case MOVZ_FMT:
12115 FINSN_3ARG_SDPS(MOVZ);
12116 break;
12117 default:
12118 goto pool32f_invalid;
12120 break;
12121 do_fpop:
12122 gen_farith(ctx, mips32_op, rt, rs, rd, 0);
12123 break;
12124 default:
12125 pool32f_invalid:
12126 MIPS_INVAL("pool32f");
12127 generate_exception(ctx, EXCP_RI);
12128 break;
12130 } else {
12131 generate_exception_err(ctx, EXCP_CpU, 1);
12133 break;
12134 case POOL32I:
12135 minor = (ctx->opcode >> 21) & 0x1f;
12136 switch (minor) {
12137 case BLTZ:
12138 mips32_op = OPC_BLTZ;
12139 goto do_branch;
12140 case BLTZAL:
12141 mips32_op = OPC_BLTZAL;
12142 goto do_branch;
12143 case BLTZALS:
12144 mips32_op = OPC_BLTZALS;
12145 goto do_branch;
12146 case BGEZ:
12147 mips32_op = OPC_BGEZ;
12148 goto do_branch;
12149 case BGEZAL:
12150 mips32_op = OPC_BGEZAL;
12151 goto do_branch;
12152 case BGEZALS:
12153 mips32_op = OPC_BGEZALS;
12154 goto do_branch;
12155 case BLEZ:
12156 mips32_op = OPC_BLEZ;
12157 goto do_branch;
12158 case BGTZ:
12159 mips32_op = OPC_BGTZ;
12160 do_branch:
12161 gen_compute_branch(ctx, mips32_op, 4, rs, -1, imm << 1);
12162 break;
12164 /* Traps */
12165 case TLTI:
12166 mips32_op = OPC_TLTI;
12167 goto do_trapi;
12168 case TGEI:
12169 mips32_op = OPC_TGEI;
12170 goto do_trapi;
12171 case TLTIU:
12172 mips32_op = OPC_TLTIU;
12173 goto do_trapi;
12174 case TGEIU:
12175 mips32_op = OPC_TGEIU;
12176 goto do_trapi;
12177 case TNEI:
12178 mips32_op = OPC_TNEI;
12179 goto do_trapi;
12180 case TEQI:
12181 mips32_op = OPC_TEQI;
12182 do_trapi:
12183 gen_trap(ctx, mips32_op, rs, -1, imm);
12184 break;
12186 case BNEZC:
12187 case BEQZC:
12188 gen_compute_branch(ctx, minor == BNEZC ? OPC_BNE : OPC_BEQ,
12189 4, rs, 0, imm << 1);
12190 /* Compact branches don't have a delay slot, so just let
12191 the normal delay slot handling take us to the branch
12192 target. */
12193 break;
12194 case LUI:
12195 gen_logic_imm(ctx, OPC_LUI, rs, -1, imm);
12196 break;
12197 case SYNCI:
12198 break;
12199 case BC2F:
12200 case BC2T:
12201 /* COP2: Not implemented. */
12202 generate_exception_err(ctx, EXCP_CpU, 2);
12203 break;
12204 case BC1F:
12205 mips32_op = (ctx->opcode & (1 << 16)) ? OPC_BC1FANY2 : OPC_BC1F;
12206 goto do_cp1branch;
12207 case BC1T:
12208 mips32_op = (ctx->opcode & (1 << 16)) ? OPC_BC1TANY2 : OPC_BC1T;
12209 goto do_cp1branch;
12210 case BC1ANY4F:
12211 mips32_op = OPC_BC1FANY4;
12212 goto do_cp1mips3d;
12213 case BC1ANY4T:
12214 mips32_op = OPC_BC1TANY4;
12215 do_cp1mips3d:
12216 check_cop1x(ctx);
12217 check_insn(ctx, ASE_MIPS3D);
12218 /* Fall through */
12219 do_cp1branch:
12220 gen_compute_branch1(ctx, mips32_op,
12221 (ctx->opcode >> 18) & 0x7, imm << 1);
12222 break;
12223 case BPOSGE64:
12224 case BPOSGE32:
12225 /* MIPS DSP: not implemented */
12226 /* Fall through */
12227 default:
12228 MIPS_INVAL("pool32i");
12229 generate_exception(ctx, EXCP_RI);
12230 break;
12232 break;
12233 case POOL32C:
12234 minor = (ctx->opcode >> 12) & 0xf;
12235 switch (minor) {
12236 case LWL:
12237 mips32_op = OPC_LWL;
12238 goto do_ld_lr;
12239 case SWL:
12240 mips32_op = OPC_SWL;
12241 goto do_st_lr;
12242 case LWR:
12243 mips32_op = OPC_LWR;
12244 goto do_ld_lr;
12245 case SWR:
12246 mips32_op = OPC_SWR;
12247 goto do_st_lr;
12248 #if defined(TARGET_MIPS64)
12249 case LDL:
12250 mips32_op = OPC_LDL;
12251 goto do_ld_lr;
12252 case SDL:
12253 mips32_op = OPC_SDL;
12254 goto do_st_lr;
12255 case LDR:
12256 mips32_op = OPC_LDR;
12257 goto do_ld_lr;
12258 case SDR:
12259 mips32_op = OPC_SDR;
12260 goto do_st_lr;
12261 case LWU:
12262 mips32_op = OPC_LWU;
12263 goto do_ld_lr;
12264 case LLD:
12265 mips32_op = OPC_LLD;
12266 goto do_ld_lr;
12267 #endif
12268 case LL:
12269 mips32_op = OPC_LL;
12270 goto do_ld_lr;
12271 do_ld_lr:
12272 gen_ld(ctx, mips32_op, rt, rs, SIMM(ctx->opcode, 0, 12));
12273 break;
12274 do_st_lr:
12275 gen_st(ctx, mips32_op, rt, rs, SIMM(ctx->opcode, 0, 12));
12276 break;
12277 case SC:
12278 gen_st_cond(ctx, OPC_SC, rt, rs, SIMM(ctx->opcode, 0, 12));
12279 break;
12280 #if defined(TARGET_MIPS64)
12281 case SCD:
12282 gen_st_cond(ctx, OPC_SCD, rt, rs, SIMM(ctx->opcode, 0, 12));
12283 break;
12284 #endif
12285 case PREF:
12286 /* Treat as no-op */
12287 break;
12288 default:
12289 MIPS_INVAL("pool32c");
12290 generate_exception(ctx, EXCP_RI);
12291 break;
12293 break;
12294 case ADDI32:
12295 mips32_op = OPC_ADDI;
12296 goto do_addi;
12297 case ADDIU32:
12298 mips32_op = OPC_ADDIU;
12299 do_addi:
12300 gen_arith_imm(ctx, mips32_op, rt, rs, imm);
12301 break;
12303 /* Logical operations */
12304 case ORI32:
12305 mips32_op = OPC_ORI;
12306 goto do_logici;
12307 case XORI32:
12308 mips32_op = OPC_XORI;
12309 goto do_logici;
12310 case ANDI32:
12311 mips32_op = OPC_ANDI;
12312 do_logici:
12313 gen_logic_imm(ctx, mips32_op, rt, rs, imm);
12314 break;
12316 /* Set less than immediate */
12317 case SLTI32:
12318 mips32_op = OPC_SLTI;
12319 goto do_slti;
12320 case SLTIU32:
12321 mips32_op = OPC_SLTIU;
12322 do_slti:
12323 gen_slt_imm(ctx, mips32_op, rt, rs, imm);
12324 break;
12325 case JALX32:
12326 offset = (int32_t)(ctx->opcode & 0x3FFFFFF) << 2;
12327 gen_compute_branch(ctx, OPC_JALX, 4, rt, rs, offset);
12328 break;
12329 case JALS32:
12330 offset = (int32_t)(ctx->opcode & 0x3FFFFFF) << 1;
12331 gen_compute_branch(ctx, OPC_JALS, 4, rt, rs, offset);
12332 break;
12333 case BEQ32:
12334 gen_compute_branch(ctx, OPC_BEQ, 4, rt, rs, imm << 1);
12335 break;
12336 case BNE32:
12337 gen_compute_branch(ctx, OPC_BNE, 4, rt, rs, imm << 1);
12338 break;
12339 case J32:
12340 gen_compute_branch(ctx, OPC_J, 4, rt, rs,
12341 (int32_t)(ctx->opcode & 0x3FFFFFF) << 1);
12342 break;
12343 case JAL32:
12344 gen_compute_branch(ctx, OPC_JAL, 4, rt, rs,
12345 (int32_t)(ctx->opcode & 0x3FFFFFF) << 1);
12346 break;
12347 /* Floating point (COP1) */
12348 case LWC132:
12349 mips32_op = OPC_LWC1;
12350 goto do_cop1;
12351 case LDC132:
12352 mips32_op = OPC_LDC1;
12353 goto do_cop1;
12354 case SWC132:
12355 mips32_op = OPC_SWC1;
12356 goto do_cop1;
12357 case SDC132:
12358 mips32_op = OPC_SDC1;
12359 do_cop1:
12360 gen_cop1_ldst(ctx, mips32_op, rt, rs, imm);
12361 break;
12362 case ADDIUPC:
12364 int reg = mmreg(ZIMM(ctx->opcode, 23, 3));
12365 int offset = SIMM(ctx->opcode, 0, 23) << 2;
12367 gen_addiupc(ctx, reg, offset, 0, 0);
12369 break;
12370 /* Loads and stores */
12371 case LB32:
12372 mips32_op = OPC_LB;
12373 goto do_ld;
12374 case LBU32:
12375 mips32_op = OPC_LBU;
12376 goto do_ld;
12377 case LH32:
12378 mips32_op = OPC_LH;
12379 goto do_ld;
12380 case LHU32:
12381 mips32_op = OPC_LHU;
12382 goto do_ld;
12383 case LW32:
12384 mips32_op = OPC_LW;
12385 goto do_ld;
12386 #ifdef TARGET_MIPS64
12387 case LD32:
12388 mips32_op = OPC_LD;
12389 goto do_ld;
12390 case SD32:
12391 mips32_op = OPC_SD;
12392 goto do_st;
12393 #endif
12394 case SB32:
12395 mips32_op = OPC_SB;
12396 goto do_st;
12397 case SH32:
12398 mips32_op = OPC_SH;
12399 goto do_st;
12400 case SW32:
12401 mips32_op = OPC_SW;
12402 goto do_st;
12403 do_ld:
12404 gen_ld(ctx, mips32_op, rt, rs, imm);
12405 break;
12406 do_st:
12407 gen_st(ctx, mips32_op, rt, rs, imm);
12408 break;
12409 default:
12410 generate_exception(ctx, EXCP_RI);
12411 break;
12415 static int decode_micromips_opc (CPUMIPSState *env, DisasContext *ctx)
12417 uint32_t op;
12419 /* make sure instructions are on a halfword boundary */
12420 if (ctx->pc & 0x1) {
12421 env->CP0_BadVAddr = ctx->pc;
12422 generate_exception(ctx, EXCP_AdEL);
12423 ctx->bstate = BS_STOP;
12424 return 2;
12427 op = (ctx->opcode >> 10) & 0x3f;
12428 /* Enforce properly-sized instructions in a delay slot */
12429 if (ctx->hflags & MIPS_HFLAG_BMASK) {
12430 int bits = ctx->hflags & MIPS_HFLAG_BMASK_EXT;
12432 switch (op) {
12433 case POOL32A:
12434 case POOL32B:
12435 case POOL32I:
12436 case POOL32C:
12437 case ADDI32:
12438 case ADDIU32:
12439 case ORI32:
12440 case XORI32:
12441 case SLTI32:
12442 case SLTIU32:
12443 case ANDI32:
12444 case JALX32:
12445 case LBU32:
12446 case LHU32:
12447 case POOL32F:
12448 case JALS32:
12449 case BEQ32:
12450 case BNE32:
12451 case J32:
12452 case JAL32:
12453 case SB32:
12454 case SH32:
12455 case POOL32S:
12456 case ADDIUPC:
12457 case SWC132:
12458 case SDC132:
12459 case SD32:
12460 case SW32:
12461 case LB32:
12462 case LH32:
12463 case DADDIU32:
12464 case LWC132:
12465 case LDC132:
12466 case LD32:
12467 case LW32:
12468 if (bits & MIPS_HFLAG_BDS16) {
12469 generate_exception(ctx, EXCP_RI);
12470 /* Just stop translation; the user is confused. */
12471 ctx->bstate = BS_STOP;
12472 return 2;
12474 break;
12475 case POOL16A:
12476 case POOL16B:
12477 case POOL16C:
12478 case LWGP16:
12479 case POOL16F:
12480 case LBU16:
12481 case LHU16:
12482 case LWSP16:
12483 case LW16:
12484 case SB16:
12485 case SH16:
12486 case SWSP16:
12487 case SW16:
12488 case MOVE16:
12489 case ANDI16:
12490 case POOL16D:
12491 case POOL16E:
12492 case BEQZ16:
12493 case BNEZ16:
12494 case B16:
12495 case LI16:
12496 if (bits & MIPS_HFLAG_BDS32) {
12497 generate_exception(ctx, EXCP_RI);
12498 /* Just stop translation; the user is confused. */
12499 ctx->bstate = BS_STOP;
12500 return 2;
12502 break;
12503 default:
12504 break;
12507 switch (op) {
12508 case POOL16A:
12510 int rd = mmreg(uMIPS_RD(ctx->opcode));
12511 int rs1 = mmreg(uMIPS_RS1(ctx->opcode));
12512 int rs2 = mmreg(uMIPS_RS2(ctx->opcode));
12513 uint32_t opc = 0;
12515 switch (ctx->opcode & 0x1) {
12516 case ADDU16:
12517 opc = OPC_ADDU;
12518 break;
12519 case SUBU16:
12520 opc = OPC_SUBU;
12521 break;
12524 gen_arith(ctx, opc, rd, rs1, rs2);
12526 break;
12527 case POOL16B:
12529 int rd = mmreg(uMIPS_RD(ctx->opcode));
12530 int rs = mmreg(uMIPS_RS(ctx->opcode));
12531 int amount = (ctx->opcode >> 1) & 0x7;
12532 uint32_t opc = 0;
12533 amount = amount == 0 ? 8 : amount;
12535 switch (ctx->opcode & 0x1) {
12536 case SLL16:
12537 opc = OPC_SLL;
12538 break;
12539 case SRL16:
12540 opc = OPC_SRL;
12541 break;
12544 gen_shift_imm(ctx, opc, rd, rs, amount);
12546 break;
12547 case POOL16C:
12548 gen_pool16c_insn(ctx);
12549 break;
12550 case LWGP16:
12552 int rd = mmreg(uMIPS_RD(ctx->opcode));
12553 int rb = 28; /* GP */
12554 int16_t offset = SIMM(ctx->opcode, 0, 7) << 2;
12556 gen_ld(ctx, OPC_LW, rd, rb, offset);
12558 break;
12559 case POOL16F:
12560 if (ctx->opcode & 1) {
12561 generate_exception(ctx, EXCP_RI);
12562 } else {
12563 /* MOVEP */
12564 int enc_dest = uMIPS_RD(ctx->opcode);
12565 int enc_rt = uMIPS_RS2(ctx->opcode);
12566 int enc_rs = uMIPS_RS1(ctx->opcode);
12567 int rd, rs, re, rt;
12568 static const int rd_enc[] = { 5, 5, 6, 4, 4, 4, 4, 4 };
12569 static const int re_enc[] = { 6, 7, 7, 21, 22, 5, 6, 7 };
12570 static const int rs_rt_enc[] = { 0, 17, 2, 3, 16, 18, 19, 20 };
12572 rd = rd_enc[enc_dest];
12573 re = re_enc[enc_dest];
12574 rs = rs_rt_enc[enc_rs];
12575 rt = rs_rt_enc[enc_rt];
12577 gen_arith_imm(ctx, OPC_ADDIU, rd, rs, 0);
12578 gen_arith_imm(ctx, OPC_ADDIU, re, rt, 0);
12580 break;
12581 case LBU16:
12583 int rd = mmreg(uMIPS_RD(ctx->opcode));
12584 int rb = mmreg(uMIPS_RS(ctx->opcode));
12585 int16_t offset = ZIMM(ctx->opcode, 0, 4);
12586 offset = (offset == 0xf ? -1 : offset);
12588 gen_ld(ctx, OPC_LBU, rd, rb, offset);
12590 break;
12591 case LHU16:
12593 int rd = mmreg(uMIPS_RD(ctx->opcode));
12594 int rb = mmreg(uMIPS_RS(ctx->opcode));
12595 int16_t offset = ZIMM(ctx->opcode, 0, 4) << 1;
12597 gen_ld(ctx, OPC_LHU, rd, rb, offset);
12599 break;
12600 case LWSP16:
12602 int rd = (ctx->opcode >> 5) & 0x1f;
12603 int rb = 29; /* SP */
12604 int16_t offset = ZIMM(ctx->opcode, 0, 5) << 2;
12606 gen_ld(ctx, OPC_LW, rd, rb, offset);
12608 break;
12609 case LW16:
12611 int rd = mmreg(uMIPS_RD(ctx->opcode));
12612 int rb = mmreg(uMIPS_RS(ctx->opcode));
12613 int16_t offset = ZIMM(ctx->opcode, 0, 4) << 2;
12615 gen_ld(ctx, OPC_LW, rd, rb, offset);
12617 break;
12618 case SB16:
12620 int rd = mmreg2(uMIPS_RD(ctx->opcode));
12621 int rb = mmreg(uMIPS_RS(ctx->opcode));
12622 int16_t offset = ZIMM(ctx->opcode, 0, 4);
12624 gen_st(ctx, OPC_SB, rd, rb, offset);
12626 break;
12627 case SH16:
12629 int rd = mmreg2(uMIPS_RD(ctx->opcode));
12630 int rb = mmreg(uMIPS_RS(ctx->opcode));
12631 int16_t offset = ZIMM(ctx->opcode, 0, 4) << 1;
12633 gen_st(ctx, OPC_SH, rd, rb, offset);
12635 break;
12636 case SWSP16:
12638 int rd = (ctx->opcode >> 5) & 0x1f;
12639 int rb = 29; /* SP */
12640 int16_t offset = ZIMM(ctx->opcode, 0, 5) << 2;
12642 gen_st(ctx, OPC_SW, rd, rb, offset);
12644 break;
12645 case SW16:
12647 int rd = mmreg2(uMIPS_RD(ctx->opcode));
12648 int rb = mmreg(uMIPS_RS(ctx->opcode));
12649 int16_t offset = ZIMM(ctx->opcode, 0, 4) << 2;
12651 gen_st(ctx, OPC_SW, rd, rb, offset);
12653 break;
12654 case MOVE16:
12656 int rd = uMIPS_RD5(ctx->opcode);
12657 int rs = uMIPS_RS5(ctx->opcode);
12659 gen_arith_imm(ctx, OPC_ADDIU, rd, rs, 0);
12661 break;
12662 case ANDI16:
12663 gen_andi16(ctx);
12664 break;
12665 case POOL16D:
12666 switch (ctx->opcode & 0x1) {
12667 case ADDIUS5:
12668 gen_addius5(ctx);
12669 break;
12670 case ADDIUSP:
12671 gen_addiusp(ctx);
12672 break;
12674 break;
12675 case POOL16E:
12676 switch (ctx->opcode & 0x1) {
12677 case ADDIUR2:
12678 gen_addiur2(ctx);
12679 break;
12680 case ADDIUR1SP:
12681 gen_addiur1sp(ctx);
12682 break;
12684 break;
12685 case B16:
12686 gen_compute_branch(ctx, OPC_BEQ, 2, 0, 0,
12687 SIMM(ctx->opcode, 0, 10) << 1);
12688 break;
12689 case BNEZ16:
12690 case BEQZ16:
12691 gen_compute_branch(ctx, op == BNEZ16 ? OPC_BNE : OPC_BEQ, 2,
12692 mmreg(uMIPS_RD(ctx->opcode)),
12693 0, SIMM(ctx->opcode, 0, 7) << 1);
12694 break;
12695 case LI16:
12697 int reg = mmreg(uMIPS_RD(ctx->opcode));
12698 int imm = ZIMM(ctx->opcode, 0, 7);
12700 imm = (imm == 0x7f ? -1 : imm);
12701 tcg_gen_movi_tl(cpu_gpr[reg], imm);
12703 break;
12704 case RES_20:
12705 case RES_28:
12706 case RES_29:
12707 case RES_30:
12708 case RES_31:
12709 case RES_38:
12710 case RES_39:
12711 generate_exception(ctx, EXCP_RI);
12712 break;
12713 default:
12714 decode_micromips32_opc (env, ctx, op);
12715 return 4;
12718 return 2;
12721 /* SmartMIPS extension to MIPS32 */
12723 #if defined(TARGET_MIPS64)
12725 /* MDMX extension to MIPS64 */
12727 #endif
12729 /* MIPSDSP functions. */
12730 static void gen_mipsdsp_ld(DisasContext *ctx, uint32_t opc,
12731 int rd, int base, int offset)
12733 const char *opn = "ldx";
12734 TCGv t0;
12736 check_dsp(ctx);
12737 t0 = tcg_temp_new();
12739 if (base == 0) {
12740 gen_load_gpr(t0, offset);
12741 } else if (offset == 0) {
12742 gen_load_gpr(t0, base);
12743 } else {
12744 gen_op_addr_add(ctx, t0, cpu_gpr[base], cpu_gpr[offset]);
12747 switch (opc) {
12748 case OPC_LBUX:
12749 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_UB);
12750 gen_store_gpr(t0, rd);
12751 opn = "lbux";
12752 break;
12753 case OPC_LHX:
12754 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TESW);
12755 gen_store_gpr(t0, rd);
12756 opn = "lhx";
12757 break;
12758 case OPC_LWX:
12759 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TESL);
12760 gen_store_gpr(t0, rd);
12761 opn = "lwx";
12762 break;
12763 #if defined(TARGET_MIPS64)
12764 case OPC_LDX:
12765 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TEQ);
12766 gen_store_gpr(t0, rd);
12767 opn = "ldx";
12768 break;
12769 #endif
12771 (void)opn; /* avoid a compiler warning */
12772 MIPS_DEBUG("%s %s, %s(%s)", opn,
12773 regnames[rd], regnames[offset], regnames[base]);
12774 tcg_temp_free(t0);
12777 static void gen_mipsdsp_arith(DisasContext *ctx, uint32_t op1, uint32_t op2,
12778 int ret, int v1, int v2)
12780 const char *opn = "mipsdsp arith";
12781 TCGv v1_t;
12782 TCGv v2_t;
12784 if (ret == 0) {
12785 /* Treat as NOP. */
12786 MIPS_DEBUG("NOP");
12787 return;
12790 v1_t = tcg_temp_new();
12791 v2_t = tcg_temp_new();
12793 gen_load_gpr(v1_t, v1);
12794 gen_load_gpr(v2_t, v2);
12796 switch (op1) {
12797 /* OPC_MULT_G_2E is equal OPC_ADDUH_QB_DSP */
12798 case OPC_MULT_G_2E:
12799 check_dspr2(ctx);
12800 switch (op2) {
12801 case OPC_ADDUH_QB:
12802 gen_helper_adduh_qb(cpu_gpr[ret], v1_t, v2_t);
12803 break;
12804 case OPC_ADDUH_R_QB:
12805 gen_helper_adduh_r_qb(cpu_gpr[ret], v1_t, v2_t);
12806 break;
12807 case OPC_ADDQH_PH:
12808 gen_helper_addqh_ph(cpu_gpr[ret], v1_t, v2_t);
12809 break;
12810 case OPC_ADDQH_R_PH:
12811 gen_helper_addqh_r_ph(cpu_gpr[ret], v1_t, v2_t);
12812 break;
12813 case OPC_ADDQH_W:
12814 gen_helper_addqh_w(cpu_gpr[ret], v1_t, v2_t);
12815 break;
12816 case OPC_ADDQH_R_W:
12817 gen_helper_addqh_r_w(cpu_gpr[ret], v1_t, v2_t);
12818 break;
12819 case OPC_SUBUH_QB:
12820 gen_helper_subuh_qb(cpu_gpr[ret], v1_t, v2_t);
12821 break;
12822 case OPC_SUBUH_R_QB:
12823 gen_helper_subuh_r_qb(cpu_gpr[ret], v1_t, v2_t);
12824 break;
12825 case OPC_SUBQH_PH:
12826 gen_helper_subqh_ph(cpu_gpr[ret], v1_t, v2_t);
12827 break;
12828 case OPC_SUBQH_R_PH:
12829 gen_helper_subqh_r_ph(cpu_gpr[ret], v1_t, v2_t);
12830 break;
12831 case OPC_SUBQH_W:
12832 gen_helper_subqh_w(cpu_gpr[ret], v1_t, v2_t);
12833 break;
12834 case OPC_SUBQH_R_W:
12835 gen_helper_subqh_r_w(cpu_gpr[ret], v1_t, v2_t);
12836 break;
12838 break;
12839 case OPC_ABSQ_S_PH_DSP:
12840 switch (op2) {
12841 case OPC_ABSQ_S_QB:
12842 check_dspr2(ctx);
12843 gen_helper_absq_s_qb(cpu_gpr[ret], v2_t, cpu_env);
12844 break;
12845 case OPC_ABSQ_S_PH:
12846 check_dsp(ctx);
12847 gen_helper_absq_s_ph(cpu_gpr[ret], v2_t, cpu_env);
12848 break;
12849 case OPC_ABSQ_S_W:
12850 check_dsp(ctx);
12851 gen_helper_absq_s_w(cpu_gpr[ret], v2_t, cpu_env);
12852 break;
12853 case OPC_PRECEQ_W_PHL:
12854 check_dsp(ctx);
12855 tcg_gen_andi_tl(cpu_gpr[ret], v2_t, 0xFFFF0000);
12856 tcg_gen_ext32s_tl(cpu_gpr[ret], cpu_gpr[ret]);
12857 break;
12858 case OPC_PRECEQ_W_PHR:
12859 check_dsp(ctx);
12860 tcg_gen_andi_tl(cpu_gpr[ret], v2_t, 0x0000FFFF);
12861 tcg_gen_shli_tl(cpu_gpr[ret], cpu_gpr[ret], 16);
12862 tcg_gen_ext32s_tl(cpu_gpr[ret], cpu_gpr[ret]);
12863 break;
12864 case OPC_PRECEQU_PH_QBL:
12865 check_dsp(ctx);
12866 gen_helper_precequ_ph_qbl(cpu_gpr[ret], v2_t);
12867 break;
12868 case OPC_PRECEQU_PH_QBR:
12869 check_dsp(ctx);
12870 gen_helper_precequ_ph_qbr(cpu_gpr[ret], v2_t);
12871 break;
12872 case OPC_PRECEQU_PH_QBLA:
12873 check_dsp(ctx);
12874 gen_helper_precequ_ph_qbla(cpu_gpr[ret], v2_t);
12875 break;
12876 case OPC_PRECEQU_PH_QBRA:
12877 check_dsp(ctx);
12878 gen_helper_precequ_ph_qbra(cpu_gpr[ret], v2_t);
12879 break;
12880 case OPC_PRECEU_PH_QBL:
12881 check_dsp(ctx);
12882 gen_helper_preceu_ph_qbl(cpu_gpr[ret], v2_t);
12883 break;
12884 case OPC_PRECEU_PH_QBR:
12885 check_dsp(ctx);
12886 gen_helper_preceu_ph_qbr(cpu_gpr[ret], v2_t);
12887 break;
12888 case OPC_PRECEU_PH_QBLA:
12889 check_dsp(ctx);
12890 gen_helper_preceu_ph_qbla(cpu_gpr[ret], v2_t);
12891 break;
12892 case OPC_PRECEU_PH_QBRA:
12893 check_dsp(ctx);
12894 gen_helper_preceu_ph_qbra(cpu_gpr[ret], v2_t);
12895 break;
12897 break;
12898 case OPC_ADDU_QB_DSP:
12899 switch (op2) {
12900 case OPC_ADDQ_PH:
12901 check_dsp(ctx);
12902 gen_helper_addq_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12903 break;
12904 case OPC_ADDQ_S_PH:
12905 check_dsp(ctx);
12906 gen_helper_addq_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12907 break;
12908 case OPC_ADDQ_S_W:
12909 check_dsp(ctx);
12910 gen_helper_addq_s_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12911 break;
12912 case OPC_ADDU_QB:
12913 check_dsp(ctx);
12914 gen_helper_addu_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12915 break;
12916 case OPC_ADDU_S_QB:
12917 check_dsp(ctx);
12918 gen_helper_addu_s_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12919 break;
12920 case OPC_ADDU_PH:
12921 check_dspr2(ctx);
12922 gen_helper_addu_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12923 break;
12924 case OPC_ADDU_S_PH:
12925 check_dspr2(ctx);
12926 gen_helper_addu_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12927 break;
12928 case OPC_SUBQ_PH:
12929 check_dsp(ctx);
12930 gen_helper_subq_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12931 break;
12932 case OPC_SUBQ_S_PH:
12933 check_dsp(ctx);
12934 gen_helper_subq_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12935 break;
12936 case OPC_SUBQ_S_W:
12937 check_dsp(ctx);
12938 gen_helper_subq_s_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12939 break;
12940 case OPC_SUBU_QB:
12941 check_dsp(ctx);
12942 gen_helper_subu_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12943 break;
12944 case OPC_SUBU_S_QB:
12945 check_dsp(ctx);
12946 gen_helper_subu_s_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12947 break;
12948 case OPC_SUBU_PH:
12949 check_dspr2(ctx);
12950 gen_helper_subu_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12951 break;
12952 case OPC_SUBU_S_PH:
12953 check_dspr2(ctx);
12954 gen_helper_subu_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12955 break;
12956 case OPC_ADDSC:
12957 check_dsp(ctx);
12958 gen_helper_addsc(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12959 break;
12960 case OPC_ADDWC:
12961 check_dsp(ctx);
12962 gen_helper_addwc(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12963 break;
12964 case OPC_MODSUB:
12965 check_dsp(ctx);
12966 gen_helper_modsub(cpu_gpr[ret], v1_t, v2_t);
12967 break;
12968 case OPC_RADDU_W_QB:
12969 check_dsp(ctx);
12970 gen_helper_raddu_w_qb(cpu_gpr[ret], v1_t);
12971 break;
12973 break;
12974 case OPC_CMPU_EQ_QB_DSP:
12975 switch (op2) {
12976 case OPC_PRECR_QB_PH:
12977 check_dspr2(ctx);
12978 gen_helper_precr_qb_ph(cpu_gpr[ret], v1_t, v2_t);
12979 break;
12980 case OPC_PRECRQ_QB_PH:
12981 check_dsp(ctx);
12982 gen_helper_precrq_qb_ph(cpu_gpr[ret], v1_t, v2_t);
12983 break;
12984 case OPC_PRECR_SRA_PH_W:
12985 check_dspr2(ctx);
12987 TCGv_i32 sa_t = tcg_const_i32(v2);
12988 gen_helper_precr_sra_ph_w(cpu_gpr[ret], sa_t, v1_t,
12989 cpu_gpr[ret]);
12990 tcg_temp_free_i32(sa_t);
12991 break;
12993 case OPC_PRECR_SRA_R_PH_W:
12994 check_dspr2(ctx);
12996 TCGv_i32 sa_t = tcg_const_i32(v2);
12997 gen_helper_precr_sra_r_ph_w(cpu_gpr[ret], sa_t, v1_t,
12998 cpu_gpr[ret]);
12999 tcg_temp_free_i32(sa_t);
13000 break;
13002 case OPC_PRECRQ_PH_W:
13003 check_dsp(ctx);
13004 gen_helper_precrq_ph_w(cpu_gpr[ret], v1_t, v2_t);
13005 break;
13006 case OPC_PRECRQ_RS_PH_W:
13007 check_dsp(ctx);
13008 gen_helper_precrq_rs_ph_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13009 break;
13010 case OPC_PRECRQU_S_QB_PH:
13011 check_dsp(ctx);
13012 gen_helper_precrqu_s_qb_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13013 break;
13015 break;
13016 #ifdef TARGET_MIPS64
13017 case OPC_ABSQ_S_QH_DSP:
13018 switch (op2) {
13019 case OPC_PRECEQ_L_PWL:
13020 check_dsp(ctx);
13021 tcg_gen_andi_tl(cpu_gpr[ret], v2_t, 0xFFFFFFFF00000000ull);
13022 break;
13023 case OPC_PRECEQ_L_PWR:
13024 check_dsp(ctx);
13025 tcg_gen_shli_tl(cpu_gpr[ret], v2_t, 32);
13026 break;
13027 case OPC_PRECEQ_PW_QHL:
13028 check_dsp(ctx);
13029 gen_helper_preceq_pw_qhl(cpu_gpr[ret], v2_t);
13030 break;
13031 case OPC_PRECEQ_PW_QHR:
13032 check_dsp(ctx);
13033 gen_helper_preceq_pw_qhr(cpu_gpr[ret], v2_t);
13034 break;
13035 case OPC_PRECEQ_PW_QHLA:
13036 check_dsp(ctx);
13037 gen_helper_preceq_pw_qhla(cpu_gpr[ret], v2_t);
13038 break;
13039 case OPC_PRECEQ_PW_QHRA:
13040 check_dsp(ctx);
13041 gen_helper_preceq_pw_qhra(cpu_gpr[ret], v2_t);
13042 break;
13043 case OPC_PRECEQU_QH_OBL:
13044 check_dsp(ctx);
13045 gen_helper_precequ_qh_obl(cpu_gpr[ret], v2_t);
13046 break;
13047 case OPC_PRECEQU_QH_OBR:
13048 check_dsp(ctx);
13049 gen_helper_precequ_qh_obr(cpu_gpr[ret], v2_t);
13050 break;
13051 case OPC_PRECEQU_QH_OBLA:
13052 check_dsp(ctx);
13053 gen_helper_precequ_qh_obla(cpu_gpr[ret], v2_t);
13054 break;
13055 case OPC_PRECEQU_QH_OBRA:
13056 check_dsp(ctx);
13057 gen_helper_precequ_qh_obra(cpu_gpr[ret], v2_t);
13058 break;
13059 case OPC_PRECEU_QH_OBL:
13060 check_dsp(ctx);
13061 gen_helper_preceu_qh_obl(cpu_gpr[ret], v2_t);
13062 break;
13063 case OPC_PRECEU_QH_OBR:
13064 check_dsp(ctx);
13065 gen_helper_preceu_qh_obr(cpu_gpr[ret], v2_t);
13066 break;
13067 case OPC_PRECEU_QH_OBLA:
13068 check_dsp(ctx);
13069 gen_helper_preceu_qh_obla(cpu_gpr[ret], v2_t);
13070 break;
13071 case OPC_PRECEU_QH_OBRA:
13072 check_dsp(ctx);
13073 gen_helper_preceu_qh_obra(cpu_gpr[ret], v2_t);
13074 break;
13075 case OPC_ABSQ_S_OB:
13076 check_dspr2(ctx);
13077 gen_helper_absq_s_ob(cpu_gpr[ret], v2_t, cpu_env);
13078 break;
13079 case OPC_ABSQ_S_PW:
13080 check_dsp(ctx);
13081 gen_helper_absq_s_pw(cpu_gpr[ret], v2_t, cpu_env);
13082 break;
13083 case OPC_ABSQ_S_QH:
13084 check_dsp(ctx);
13085 gen_helper_absq_s_qh(cpu_gpr[ret], v2_t, cpu_env);
13086 break;
13088 break;
13089 case OPC_ADDU_OB_DSP:
13090 switch (op2) {
13091 case OPC_RADDU_L_OB:
13092 check_dsp(ctx);
13093 gen_helper_raddu_l_ob(cpu_gpr[ret], v1_t);
13094 break;
13095 case OPC_SUBQ_PW:
13096 check_dsp(ctx);
13097 gen_helper_subq_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13098 break;
13099 case OPC_SUBQ_S_PW:
13100 check_dsp(ctx);
13101 gen_helper_subq_s_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13102 break;
13103 case OPC_SUBQ_QH:
13104 check_dsp(ctx);
13105 gen_helper_subq_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13106 break;
13107 case OPC_SUBQ_S_QH:
13108 check_dsp(ctx);
13109 gen_helper_subq_s_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13110 break;
13111 case OPC_SUBU_OB:
13112 check_dsp(ctx);
13113 gen_helper_subu_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13114 break;
13115 case OPC_SUBU_S_OB:
13116 check_dsp(ctx);
13117 gen_helper_subu_s_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13118 break;
13119 case OPC_SUBU_QH:
13120 check_dspr2(ctx);
13121 gen_helper_subu_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13122 break;
13123 case OPC_SUBU_S_QH:
13124 check_dspr2(ctx);
13125 gen_helper_subu_s_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13126 break;
13127 case OPC_SUBUH_OB:
13128 check_dspr2(ctx);
13129 gen_helper_subuh_ob(cpu_gpr[ret], v1_t, v2_t);
13130 break;
13131 case OPC_SUBUH_R_OB:
13132 check_dspr2(ctx);
13133 gen_helper_subuh_r_ob(cpu_gpr[ret], v1_t, v2_t);
13134 break;
13135 case OPC_ADDQ_PW:
13136 check_dsp(ctx);
13137 gen_helper_addq_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13138 break;
13139 case OPC_ADDQ_S_PW:
13140 check_dsp(ctx);
13141 gen_helper_addq_s_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13142 break;
13143 case OPC_ADDQ_QH:
13144 check_dsp(ctx);
13145 gen_helper_addq_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13146 break;
13147 case OPC_ADDQ_S_QH:
13148 check_dsp(ctx);
13149 gen_helper_addq_s_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13150 break;
13151 case OPC_ADDU_OB:
13152 check_dsp(ctx);
13153 gen_helper_addu_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13154 break;
13155 case OPC_ADDU_S_OB:
13156 check_dsp(ctx);
13157 gen_helper_addu_s_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13158 break;
13159 case OPC_ADDU_QH:
13160 check_dspr2(ctx);
13161 gen_helper_addu_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13162 break;
13163 case OPC_ADDU_S_QH:
13164 check_dspr2(ctx);
13165 gen_helper_addu_s_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13166 break;
13167 case OPC_ADDUH_OB:
13168 check_dspr2(ctx);
13169 gen_helper_adduh_ob(cpu_gpr[ret], v1_t, v2_t);
13170 break;
13171 case OPC_ADDUH_R_OB:
13172 check_dspr2(ctx);
13173 gen_helper_adduh_r_ob(cpu_gpr[ret], v1_t, v2_t);
13174 break;
13176 break;
13177 case OPC_CMPU_EQ_OB_DSP:
13178 switch (op2) {
13179 case OPC_PRECR_OB_QH:
13180 check_dspr2(ctx);
13181 gen_helper_precr_ob_qh(cpu_gpr[ret], v1_t, v2_t);
13182 break;
13183 case OPC_PRECR_SRA_QH_PW:
13184 check_dspr2(ctx);
13186 TCGv_i32 ret_t = tcg_const_i32(ret);
13187 gen_helper_precr_sra_qh_pw(v2_t, v1_t, v2_t, ret_t);
13188 tcg_temp_free_i32(ret_t);
13189 break;
13191 case OPC_PRECR_SRA_R_QH_PW:
13192 check_dspr2(ctx);
13194 TCGv_i32 sa_v = tcg_const_i32(ret);
13195 gen_helper_precr_sra_r_qh_pw(v2_t, v1_t, v2_t, sa_v);
13196 tcg_temp_free_i32(sa_v);
13197 break;
13199 case OPC_PRECRQ_OB_QH:
13200 check_dsp(ctx);
13201 gen_helper_precrq_ob_qh(cpu_gpr[ret], v1_t, v2_t);
13202 break;
13203 case OPC_PRECRQ_PW_L:
13204 check_dsp(ctx);
13205 gen_helper_precrq_pw_l(cpu_gpr[ret], v1_t, v2_t);
13206 break;
13207 case OPC_PRECRQ_QH_PW:
13208 check_dsp(ctx);
13209 gen_helper_precrq_qh_pw(cpu_gpr[ret], v1_t, v2_t);
13210 break;
13211 case OPC_PRECRQ_RS_QH_PW:
13212 check_dsp(ctx);
13213 gen_helper_precrq_rs_qh_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13214 break;
13215 case OPC_PRECRQU_S_OB_QH:
13216 check_dsp(ctx);
13217 gen_helper_precrqu_s_ob_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13218 break;
13220 break;
13221 #endif
13224 tcg_temp_free(v1_t);
13225 tcg_temp_free(v2_t);
13227 (void)opn; /* avoid a compiler warning */
13228 MIPS_DEBUG("%s", opn);
13231 static void gen_mipsdsp_shift(DisasContext *ctx, uint32_t opc,
13232 int ret, int v1, int v2)
13234 uint32_t op2;
13235 const char *opn = "mipsdsp shift";
13236 TCGv t0;
13237 TCGv v1_t;
13238 TCGv v2_t;
13240 if (ret == 0) {
13241 /* Treat as NOP. */
13242 MIPS_DEBUG("NOP");
13243 return;
13246 t0 = tcg_temp_new();
13247 v1_t = tcg_temp_new();
13248 v2_t = tcg_temp_new();
13250 tcg_gen_movi_tl(t0, v1);
13251 gen_load_gpr(v1_t, v1);
13252 gen_load_gpr(v2_t, v2);
13254 switch (opc) {
13255 case OPC_SHLL_QB_DSP:
13257 op2 = MASK_SHLL_QB(ctx->opcode);
13258 switch (op2) {
13259 case OPC_SHLL_QB:
13260 check_dsp(ctx);
13261 gen_helper_shll_qb(cpu_gpr[ret], t0, v2_t, cpu_env);
13262 break;
13263 case OPC_SHLLV_QB:
13264 check_dsp(ctx);
13265 gen_helper_shll_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13266 break;
13267 case OPC_SHLL_PH:
13268 check_dsp(ctx);
13269 gen_helper_shll_ph(cpu_gpr[ret], t0, v2_t, cpu_env);
13270 break;
13271 case OPC_SHLLV_PH:
13272 check_dsp(ctx);
13273 gen_helper_shll_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13274 break;
13275 case OPC_SHLL_S_PH:
13276 check_dsp(ctx);
13277 gen_helper_shll_s_ph(cpu_gpr[ret], t0, v2_t, cpu_env);
13278 break;
13279 case OPC_SHLLV_S_PH:
13280 check_dsp(ctx);
13281 gen_helper_shll_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13282 break;
13283 case OPC_SHLL_S_W:
13284 check_dsp(ctx);
13285 gen_helper_shll_s_w(cpu_gpr[ret], t0, v2_t, cpu_env);
13286 break;
13287 case OPC_SHLLV_S_W:
13288 check_dsp(ctx);
13289 gen_helper_shll_s_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13290 break;
13291 case OPC_SHRL_QB:
13292 check_dsp(ctx);
13293 gen_helper_shrl_qb(cpu_gpr[ret], t0, v2_t);
13294 break;
13295 case OPC_SHRLV_QB:
13296 check_dsp(ctx);
13297 gen_helper_shrl_qb(cpu_gpr[ret], v1_t, v2_t);
13298 break;
13299 case OPC_SHRL_PH:
13300 check_dspr2(ctx);
13301 gen_helper_shrl_ph(cpu_gpr[ret], t0, v2_t);
13302 break;
13303 case OPC_SHRLV_PH:
13304 check_dspr2(ctx);
13305 gen_helper_shrl_ph(cpu_gpr[ret], v1_t, v2_t);
13306 break;
13307 case OPC_SHRA_QB:
13308 check_dspr2(ctx);
13309 gen_helper_shra_qb(cpu_gpr[ret], t0, v2_t);
13310 break;
13311 case OPC_SHRA_R_QB:
13312 check_dspr2(ctx);
13313 gen_helper_shra_r_qb(cpu_gpr[ret], t0, v2_t);
13314 break;
13315 case OPC_SHRAV_QB:
13316 check_dspr2(ctx);
13317 gen_helper_shra_qb(cpu_gpr[ret], v1_t, v2_t);
13318 break;
13319 case OPC_SHRAV_R_QB:
13320 check_dspr2(ctx);
13321 gen_helper_shra_r_qb(cpu_gpr[ret], v1_t, v2_t);
13322 break;
13323 case OPC_SHRA_PH:
13324 check_dsp(ctx);
13325 gen_helper_shra_ph(cpu_gpr[ret], t0, v2_t);
13326 break;
13327 case OPC_SHRA_R_PH:
13328 check_dsp(ctx);
13329 gen_helper_shra_r_ph(cpu_gpr[ret], t0, v2_t);
13330 break;
13331 case OPC_SHRAV_PH:
13332 check_dsp(ctx);
13333 gen_helper_shra_ph(cpu_gpr[ret], v1_t, v2_t);
13334 break;
13335 case OPC_SHRAV_R_PH:
13336 check_dsp(ctx);
13337 gen_helper_shra_r_ph(cpu_gpr[ret], v1_t, v2_t);
13338 break;
13339 case OPC_SHRA_R_W:
13340 check_dsp(ctx);
13341 gen_helper_shra_r_w(cpu_gpr[ret], t0, v2_t);
13342 break;
13343 case OPC_SHRAV_R_W:
13344 check_dsp(ctx);
13345 gen_helper_shra_r_w(cpu_gpr[ret], v1_t, v2_t);
13346 break;
13347 default: /* Invalid */
13348 MIPS_INVAL("MASK SHLL.QB");
13349 generate_exception(ctx, EXCP_RI);
13350 break;
13352 break;
13354 #ifdef TARGET_MIPS64
13355 case OPC_SHLL_OB_DSP:
13356 op2 = MASK_SHLL_OB(ctx->opcode);
13357 switch (op2) {
13358 case OPC_SHLL_PW:
13359 check_dsp(ctx);
13360 gen_helper_shll_pw(cpu_gpr[ret], v2_t, t0, cpu_env);
13361 break;
13362 case OPC_SHLLV_PW:
13363 check_dsp(ctx);
13364 gen_helper_shll_pw(cpu_gpr[ret], v2_t, v1_t, cpu_env);
13365 break;
13366 case OPC_SHLL_S_PW:
13367 check_dsp(ctx);
13368 gen_helper_shll_s_pw(cpu_gpr[ret], v2_t, t0, cpu_env);
13369 break;
13370 case OPC_SHLLV_S_PW:
13371 check_dsp(ctx);
13372 gen_helper_shll_s_pw(cpu_gpr[ret], v2_t, v1_t, cpu_env);
13373 break;
13374 case OPC_SHLL_OB:
13375 check_dsp(ctx);
13376 gen_helper_shll_ob(cpu_gpr[ret], v2_t, t0, cpu_env);
13377 break;
13378 case OPC_SHLLV_OB:
13379 check_dsp(ctx);
13380 gen_helper_shll_ob(cpu_gpr[ret], v2_t, v1_t, cpu_env);
13381 break;
13382 case OPC_SHLL_QH:
13383 check_dsp(ctx);
13384 gen_helper_shll_qh(cpu_gpr[ret], v2_t, t0, cpu_env);
13385 break;
13386 case OPC_SHLLV_QH:
13387 check_dsp(ctx);
13388 gen_helper_shll_qh(cpu_gpr[ret], v2_t, v1_t, cpu_env);
13389 break;
13390 case OPC_SHLL_S_QH:
13391 check_dsp(ctx);
13392 gen_helper_shll_s_qh(cpu_gpr[ret], v2_t, t0, cpu_env);
13393 break;
13394 case OPC_SHLLV_S_QH:
13395 check_dsp(ctx);
13396 gen_helper_shll_s_qh(cpu_gpr[ret], v2_t, v1_t, cpu_env);
13397 break;
13398 case OPC_SHRA_OB:
13399 check_dspr2(ctx);
13400 gen_helper_shra_ob(cpu_gpr[ret], v2_t, t0);
13401 break;
13402 case OPC_SHRAV_OB:
13403 check_dspr2(ctx);
13404 gen_helper_shra_ob(cpu_gpr[ret], v2_t, v1_t);
13405 break;
13406 case OPC_SHRA_R_OB:
13407 check_dspr2(ctx);
13408 gen_helper_shra_r_ob(cpu_gpr[ret], v2_t, t0);
13409 break;
13410 case OPC_SHRAV_R_OB:
13411 check_dspr2(ctx);
13412 gen_helper_shra_r_ob(cpu_gpr[ret], v2_t, v1_t);
13413 break;
13414 case OPC_SHRA_PW:
13415 check_dsp(ctx);
13416 gen_helper_shra_pw(cpu_gpr[ret], v2_t, t0);
13417 break;
13418 case OPC_SHRAV_PW:
13419 check_dsp(ctx);
13420 gen_helper_shra_pw(cpu_gpr[ret], v2_t, v1_t);
13421 break;
13422 case OPC_SHRA_R_PW:
13423 check_dsp(ctx);
13424 gen_helper_shra_r_pw(cpu_gpr[ret], v2_t, t0);
13425 break;
13426 case OPC_SHRAV_R_PW:
13427 check_dsp(ctx);
13428 gen_helper_shra_r_pw(cpu_gpr[ret], v2_t, v1_t);
13429 break;
13430 case OPC_SHRA_QH:
13431 check_dsp(ctx);
13432 gen_helper_shra_qh(cpu_gpr[ret], v2_t, t0);
13433 break;
13434 case OPC_SHRAV_QH:
13435 check_dsp(ctx);
13436 gen_helper_shra_qh(cpu_gpr[ret], v2_t, v1_t);
13437 break;
13438 case OPC_SHRA_R_QH:
13439 check_dsp(ctx);
13440 gen_helper_shra_r_qh(cpu_gpr[ret], v2_t, t0);
13441 break;
13442 case OPC_SHRAV_R_QH:
13443 check_dsp(ctx);
13444 gen_helper_shra_r_qh(cpu_gpr[ret], v2_t, v1_t);
13445 break;
13446 case OPC_SHRL_OB:
13447 check_dsp(ctx);
13448 gen_helper_shrl_ob(cpu_gpr[ret], v2_t, t0);
13449 break;
13450 case OPC_SHRLV_OB:
13451 check_dsp(ctx);
13452 gen_helper_shrl_ob(cpu_gpr[ret], v2_t, v1_t);
13453 break;
13454 case OPC_SHRL_QH:
13455 check_dspr2(ctx);
13456 gen_helper_shrl_qh(cpu_gpr[ret], v2_t, t0);
13457 break;
13458 case OPC_SHRLV_QH:
13459 check_dspr2(ctx);
13460 gen_helper_shrl_qh(cpu_gpr[ret], v2_t, v1_t);
13461 break;
13462 default: /* Invalid */
13463 MIPS_INVAL("MASK SHLL.OB");
13464 generate_exception(ctx, EXCP_RI);
13465 break;
13467 break;
13468 #endif
13471 tcg_temp_free(t0);
13472 tcg_temp_free(v1_t);
13473 tcg_temp_free(v2_t);
13474 (void)opn; /* avoid a compiler warning */
13475 MIPS_DEBUG("%s", opn);
13478 static void gen_mipsdsp_multiply(DisasContext *ctx, uint32_t op1, uint32_t op2,
13479 int ret, int v1, int v2, int check_ret)
13481 const char *opn = "mipsdsp multiply";
13482 TCGv_i32 t0;
13483 TCGv v1_t;
13484 TCGv v2_t;
13486 if ((ret == 0) && (check_ret == 1)) {
13487 /* Treat as NOP. */
13488 MIPS_DEBUG("NOP");
13489 return;
13492 t0 = tcg_temp_new_i32();
13493 v1_t = tcg_temp_new();
13494 v2_t = tcg_temp_new();
13496 tcg_gen_movi_i32(t0, ret);
13497 gen_load_gpr(v1_t, v1);
13498 gen_load_gpr(v2_t, v2);
13500 switch (op1) {
13501 /* OPC_MULT_G_2E, OPC_ADDUH_QB_DSP, OPC_MUL_PH_DSP have
13502 * the same mask and op1. */
13503 case OPC_MULT_G_2E:
13504 check_dspr2(ctx);
13505 switch (op2) {
13506 case OPC_MUL_PH:
13507 gen_helper_mul_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13508 break;
13509 case OPC_MUL_S_PH:
13510 gen_helper_mul_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13511 break;
13512 case OPC_MULQ_S_W:
13513 gen_helper_mulq_s_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13514 break;
13515 case OPC_MULQ_RS_W:
13516 gen_helper_mulq_rs_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13517 break;
13519 break;
13520 case OPC_DPA_W_PH_DSP:
13521 switch (op2) {
13522 case OPC_DPAU_H_QBL:
13523 check_dsp(ctx);
13524 gen_helper_dpau_h_qbl(t0, v1_t, v2_t, cpu_env);
13525 break;
13526 case OPC_DPAU_H_QBR:
13527 check_dsp(ctx);
13528 gen_helper_dpau_h_qbr(t0, v1_t, v2_t, cpu_env);
13529 break;
13530 case OPC_DPSU_H_QBL:
13531 check_dsp(ctx);
13532 gen_helper_dpsu_h_qbl(t0, v1_t, v2_t, cpu_env);
13533 break;
13534 case OPC_DPSU_H_QBR:
13535 check_dsp(ctx);
13536 gen_helper_dpsu_h_qbr(t0, v1_t, v2_t, cpu_env);
13537 break;
13538 case OPC_DPA_W_PH:
13539 check_dspr2(ctx);
13540 gen_helper_dpa_w_ph(t0, v1_t, v2_t, cpu_env);
13541 break;
13542 case OPC_DPAX_W_PH:
13543 check_dspr2(ctx);
13544 gen_helper_dpax_w_ph(t0, v1_t, v2_t, cpu_env);
13545 break;
13546 case OPC_DPAQ_S_W_PH:
13547 check_dsp(ctx);
13548 gen_helper_dpaq_s_w_ph(t0, v1_t, v2_t, cpu_env);
13549 break;
13550 case OPC_DPAQX_S_W_PH:
13551 check_dspr2(ctx);
13552 gen_helper_dpaqx_s_w_ph(t0, v1_t, v2_t, cpu_env);
13553 break;
13554 case OPC_DPAQX_SA_W_PH:
13555 check_dspr2(ctx);
13556 gen_helper_dpaqx_sa_w_ph(t0, v1_t, v2_t, cpu_env);
13557 break;
13558 case OPC_DPS_W_PH:
13559 check_dspr2(ctx);
13560 gen_helper_dps_w_ph(t0, v1_t, v2_t, cpu_env);
13561 break;
13562 case OPC_DPSX_W_PH:
13563 check_dspr2(ctx);
13564 gen_helper_dpsx_w_ph(t0, v1_t, v2_t, cpu_env);
13565 break;
13566 case OPC_DPSQ_S_W_PH:
13567 check_dsp(ctx);
13568 gen_helper_dpsq_s_w_ph(t0, v1_t, v2_t, cpu_env);
13569 break;
13570 case OPC_DPSQX_S_W_PH:
13571 check_dspr2(ctx);
13572 gen_helper_dpsqx_s_w_ph(t0, v1_t, v2_t, cpu_env);
13573 break;
13574 case OPC_DPSQX_SA_W_PH:
13575 check_dspr2(ctx);
13576 gen_helper_dpsqx_sa_w_ph(t0, v1_t, v2_t, cpu_env);
13577 break;
13578 case OPC_MULSAQ_S_W_PH:
13579 check_dsp(ctx);
13580 gen_helper_mulsaq_s_w_ph(t0, v1_t, v2_t, cpu_env);
13581 break;
13582 case OPC_DPAQ_SA_L_W:
13583 check_dsp(ctx);
13584 gen_helper_dpaq_sa_l_w(t0, v1_t, v2_t, cpu_env);
13585 break;
13586 case OPC_DPSQ_SA_L_W:
13587 check_dsp(ctx);
13588 gen_helper_dpsq_sa_l_w(t0, v1_t, v2_t, cpu_env);
13589 break;
13590 case OPC_MAQ_S_W_PHL:
13591 check_dsp(ctx);
13592 gen_helper_maq_s_w_phl(t0, v1_t, v2_t, cpu_env);
13593 break;
13594 case OPC_MAQ_S_W_PHR:
13595 check_dsp(ctx);
13596 gen_helper_maq_s_w_phr(t0, v1_t, v2_t, cpu_env);
13597 break;
13598 case OPC_MAQ_SA_W_PHL:
13599 check_dsp(ctx);
13600 gen_helper_maq_sa_w_phl(t0, v1_t, v2_t, cpu_env);
13601 break;
13602 case OPC_MAQ_SA_W_PHR:
13603 check_dsp(ctx);
13604 gen_helper_maq_sa_w_phr(t0, v1_t, v2_t, cpu_env);
13605 break;
13606 case OPC_MULSA_W_PH:
13607 check_dspr2(ctx);
13608 gen_helper_mulsa_w_ph(t0, v1_t, v2_t, cpu_env);
13609 break;
13611 break;
13612 #ifdef TARGET_MIPS64
13613 case OPC_DPAQ_W_QH_DSP:
13615 int ac = ret & 0x03;
13616 tcg_gen_movi_i32(t0, ac);
13618 switch (op2) {
13619 case OPC_DMADD:
13620 check_dsp(ctx);
13621 gen_helper_dmadd(v1_t, v2_t, t0, cpu_env);
13622 break;
13623 case OPC_DMADDU:
13624 check_dsp(ctx);
13625 gen_helper_dmaddu(v1_t, v2_t, t0, cpu_env);
13626 break;
13627 case OPC_DMSUB:
13628 check_dsp(ctx);
13629 gen_helper_dmsub(v1_t, v2_t, t0, cpu_env);
13630 break;
13631 case OPC_DMSUBU:
13632 check_dsp(ctx);
13633 gen_helper_dmsubu(v1_t, v2_t, t0, cpu_env);
13634 break;
13635 case OPC_DPA_W_QH:
13636 check_dspr2(ctx);
13637 gen_helper_dpa_w_qh(v1_t, v2_t, t0, cpu_env);
13638 break;
13639 case OPC_DPAQ_S_W_QH:
13640 check_dsp(ctx);
13641 gen_helper_dpaq_s_w_qh(v1_t, v2_t, t0, cpu_env);
13642 break;
13643 case OPC_DPAQ_SA_L_PW:
13644 check_dsp(ctx);
13645 gen_helper_dpaq_sa_l_pw(v1_t, v2_t, t0, cpu_env);
13646 break;
13647 case OPC_DPAU_H_OBL:
13648 check_dsp(ctx);
13649 gen_helper_dpau_h_obl(v1_t, v2_t, t0, cpu_env);
13650 break;
13651 case OPC_DPAU_H_OBR:
13652 check_dsp(ctx);
13653 gen_helper_dpau_h_obr(v1_t, v2_t, t0, cpu_env);
13654 break;
13655 case OPC_DPS_W_QH:
13656 check_dspr2(ctx);
13657 gen_helper_dps_w_qh(v1_t, v2_t, t0, cpu_env);
13658 break;
13659 case OPC_DPSQ_S_W_QH:
13660 check_dsp(ctx);
13661 gen_helper_dpsq_s_w_qh(v1_t, v2_t, t0, cpu_env);
13662 break;
13663 case OPC_DPSQ_SA_L_PW:
13664 check_dsp(ctx);
13665 gen_helper_dpsq_sa_l_pw(v1_t, v2_t, t0, cpu_env);
13666 break;
13667 case OPC_DPSU_H_OBL:
13668 check_dsp(ctx);
13669 gen_helper_dpsu_h_obl(v1_t, v2_t, t0, cpu_env);
13670 break;
13671 case OPC_DPSU_H_OBR:
13672 check_dsp(ctx);
13673 gen_helper_dpsu_h_obr(v1_t, v2_t, t0, cpu_env);
13674 break;
13675 case OPC_MAQ_S_L_PWL:
13676 check_dsp(ctx);
13677 gen_helper_maq_s_l_pwl(v1_t, v2_t, t0, cpu_env);
13678 break;
13679 case OPC_MAQ_S_L_PWR:
13680 check_dsp(ctx);
13681 gen_helper_maq_s_l_pwr(v1_t, v2_t, t0, cpu_env);
13682 break;
13683 case OPC_MAQ_S_W_QHLL:
13684 check_dsp(ctx);
13685 gen_helper_maq_s_w_qhll(v1_t, v2_t, t0, cpu_env);
13686 break;
13687 case OPC_MAQ_SA_W_QHLL:
13688 check_dsp(ctx);
13689 gen_helper_maq_sa_w_qhll(v1_t, v2_t, t0, cpu_env);
13690 break;
13691 case OPC_MAQ_S_W_QHLR:
13692 check_dsp(ctx);
13693 gen_helper_maq_s_w_qhlr(v1_t, v2_t, t0, cpu_env);
13694 break;
13695 case OPC_MAQ_SA_W_QHLR:
13696 check_dsp(ctx);
13697 gen_helper_maq_sa_w_qhlr(v1_t, v2_t, t0, cpu_env);
13698 break;
13699 case OPC_MAQ_S_W_QHRL:
13700 check_dsp(ctx);
13701 gen_helper_maq_s_w_qhrl(v1_t, v2_t, t0, cpu_env);
13702 break;
13703 case OPC_MAQ_SA_W_QHRL:
13704 check_dsp(ctx);
13705 gen_helper_maq_sa_w_qhrl(v1_t, v2_t, t0, cpu_env);
13706 break;
13707 case OPC_MAQ_S_W_QHRR:
13708 check_dsp(ctx);
13709 gen_helper_maq_s_w_qhrr(v1_t, v2_t, t0, cpu_env);
13710 break;
13711 case OPC_MAQ_SA_W_QHRR:
13712 check_dsp(ctx);
13713 gen_helper_maq_sa_w_qhrr(v1_t, v2_t, t0, cpu_env);
13714 break;
13715 case OPC_MULSAQ_S_L_PW:
13716 check_dsp(ctx);
13717 gen_helper_mulsaq_s_l_pw(v1_t, v2_t, t0, cpu_env);
13718 break;
13719 case OPC_MULSAQ_S_W_QH:
13720 check_dsp(ctx);
13721 gen_helper_mulsaq_s_w_qh(v1_t, v2_t, t0, cpu_env);
13722 break;
13725 break;
13726 #endif
13727 case OPC_ADDU_QB_DSP:
13728 switch (op2) {
13729 case OPC_MULEU_S_PH_QBL:
13730 check_dsp(ctx);
13731 gen_helper_muleu_s_ph_qbl(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13732 break;
13733 case OPC_MULEU_S_PH_QBR:
13734 check_dsp(ctx);
13735 gen_helper_muleu_s_ph_qbr(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13736 break;
13737 case OPC_MULQ_RS_PH:
13738 check_dsp(ctx);
13739 gen_helper_mulq_rs_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13740 break;
13741 case OPC_MULEQ_S_W_PHL:
13742 check_dsp(ctx);
13743 gen_helper_muleq_s_w_phl(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13744 break;
13745 case OPC_MULEQ_S_W_PHR:
13746 check_dsp(ctx);
13747 gen_helper_muleq_s_w_phr(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13748 break;
13749 case OPC_MULQ_S_PH:
13750 check_dspr2(ctx);
13751 gen_helper_mulq_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13752 break;
13754 break;
13755 #ifdef TARGET_MIPS64
13756 case OPC_ADDU_OB_DSP:
13757 switch (op2) {
13758 case OPC_MULEQ_S_PW_QHL:
13759 check_dsp(ctx);
13760 gen_helper_muleq_s_pw_qhl(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13761 break;
13762 case OPC_MULEQ_S_PW_QHR:
13763 check_dsp(ctx);
13764 gen_helper_muleq_s_pw_qhr(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13765 break;
13766 case OPC_MULEU_S_QH_OBL:
13767 check_dsp(ctx);
13768 gen_helper_muleu_s_qh_obl(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13769 break;
13770 case OPC_MULEU_S_QH_OBR:
13771 check_dsp(ctx);
13772 gen_helper_muleu_s_qh_obr(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13773 break;
13774 case OPC_MULQ_RS_QH:
13775 check_dsp(ctx);
13776 gen_helper_mulq_rs_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13777 break;
13779 break;
13780 #endif
13783 tcg_temp_free_i32(t0);
13784 tcg_temp_free(v1_t);
13785 tcg_temp_free(v2_t);
13787 (void)opn; /* avoid a compiler warning */
13788 MIPS_DEBUG("%s", opn);
13792 static void gen_mipsdsp_bitinsn(DisasContext *ctx, uint32_t op1, uint32_t op2,
13793 int ret, int val)
13795 const char *opn = "mipsdsp Bit/ Manipulation";
13796 int16_t imm;
13797 TCGv t0;
13798 TCGv val_t;
13800 if (ret == 0) {
13801 /* Treat as NOP. */
13802 MIPS_DEBUG("NOP");
13803 return;
13806 t0 = tcg_temp_new();
13807 val_t = tcg_temp_new();
13808 gen_load_gpr(val_t, val);
13810 switch (op1) {
13811 case OPC_ABSQ_S_PH_DSP:
13812 switch (op2) {
13813 case OPC_BITREV:
13814 check_dsp(ctx);
13815 gen_helper_bitrev(cpu_gpr[ret], val_t);
13816 break;
13817 case OPC_REPL_QB:
13818 check_dsp(ctx);
13820 target_long result;
13821 imm = (ctx->opcode >> 16) & 0xFF;
13822 result = (uint32_t)imm << 24 |
13823 (uint32_t)imm << 16 |
13824 (uint32_t)imm << 8 |
13825 (uint32_t)imm;
13826 result = (int32_t)result;
13827 tcg_gen_movi_tl(cpu_gpr[ret], result);
13829 break;
13830 case OPC_REPLV_QB:
13831 check_dsp(ctx);
13832 tcg_gen_ext8u_tl(cpu_gpr[ret], val_t);
13833 tcg_gen_shli_tl(t0, cpu_gpr[ret], 8);
13834 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
13835 tcg_gen_shli_tl(t0, cpu_gpr[ret], 16);
13836 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
13837 tcg_gen_ext32s_tl(cpu_gpr[ret], cpu_gpr[ret]);
13838 break;
13839 case OPC_REPL_PH:
13840 check_dsp(ctx);
13842 imm = (ctx->opcode >> 16) & 0x03FF;
13843 imm = (int16_t)(imm << 6) >> 6;
13844 tcg_gen_movi_tl(cpu_gpr[ret], \
13845 (target_long)((int32_t)imm << 16 | \
13846 (uint16_t)imm));
13848 break;
13849 case OPC_REPLV_PH:
13850 check_dsp(ctx);
13851 tcg_gen_ext16u_tl(cpu_gpr[ret], val_t);
13852 tcg_gen_shli_tl(t0, cpu_gpr[ret], 16);
13853 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
13854 tcg_gen_ext32s_tl(cpu_gpr[ret], cpu_gpr[ret]);
13855 break;
13857 break;
13858 #ifdef TARGET_MIPS64
13859 case OPC_ABSQ_S_QH_DSP:
13860 switch (op2) {
13861 case OPC_REPL_OB:
13862 check_dsp(ctx);
13864 target_long temp;
13866 imm = (ctx->opcode >> 16) & 0xFF;
13867 temp = ((uint64_t)imm << 8) | (uint64_t)imm;
13868 temp = (temp << 16) | temp;
13869 temp = (temp << 32) | temp;
13870 tcg_gen_movi_tl(cpu_gpr[ret], temp);
13871 break;
13873 case OPC_REPL_PW:
13874 check_dsp(ctx);
13876 target_long temp;
13878 imm = (ctx->opcode >> 16) & 0x03FF;
13879 imm = (int16_t)(imm << 6) >> 6;
13880 temp = ((target_long)imm << 32) \
13881 | ((target_long)imm & 0xFFFFFFFF);
13882 tcg_gen_movi_tl(cpu_gpr[ret], temp);
13883 break;
13885 case OPC_REPL_QH:
13886 check_dsp(ctx);
13888 target_long temp;
13890 imm = (ctx->opcode >> 16) & 0x03FF;
13891 imm = (int16_t)(imm << 6) >> 6;
13893 temp = ((uint64_t)(uint16_t)imm << 48) |
13894 ((uint64_t)(uint16_t)imm << 32) |
13895 ((uint64_t)(uint16_t)imm << 16) |
13896 (uint64_t)(uint16_t)imm;
13897 tcg_gen_movi_tl(cpu_gpr[ret], temp);
13898 break;
13900 case OPC_REPLV_OB:
13901 check_dsp(ctx);
13902 tcg_gen_ext8u_tl(cpu_gpr[ret], val_t);
13903 tcg_gen_shli_tl(t0, cpu_gpr[ret], 8);
13904 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
13905 tcg_gen_shli_tl(t0, cpu_gpr[ret], 16);
13906 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
13907 tcg_gen_shli_tl(t0, cpu_gpr[ret], 32);
13908 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
13909 break;
13910 case OPC_REPLV_PW:
13911 check_dsp(ctx);
13912 tcg_gen_ext32u_i64(cpu_gpr[ret], val_t);
13913 tcg_gen_shli_tl(t0, cpu_gpr[ret], 32);
13914 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
13915 break;
13916 case OPC_REPLV_QH:
13917 check_dsp(ctx);
13918 tcg_gen_ext16u_tl(cpu_gpr[ret], val_t);
13919 tcg_gen_shli_tl(t0, cpu_gpr[ret], 16);
13920 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
13921 tcg_gen_shli_tl(t0, cpu_gpr[ret], 32);
13922 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
13923 break;
13925 break;
13926 #endif
13928 tcg_temp_free(t0);
13929 tcg_temp_free(val_t);
13931 (void)opn; /* avoid a compiler warning */
13932 MIPS_DEBUG("%s", opn);
13935 static void gen_mipsdsp_add_cmp_pick(DisasContext *ctx,
13936 uint32_t op1, uint32_t op2,
13937 int ret, int v1, int v2, int check_ret)
13939 const char *opn = "mipsdsp add compare pick";
13940 TCGv t1;
13941 TCGv v1_t;
13942 TCGv v2_t;
13944 if ((ret == 0) && (check_ret == 1)) {
13945 /* Treat as NOP. */
13946 MIPS_DEBUG("NOP");
13947 return;
13950 t1 = tcg_temp_new();
13951 v1_t = tcg_temp_new();
13952 v2_t = tcg_temp_new();
13954 gen_load_gpr(v1_t, v1);
13955 gen_load_gpr(v2_t, v2);
13957 switch (op1) {
13958 case OPC_CMPU_EQ_QB_DSP:
13959 switch (op2) {
13960 case OPC_CMPU_EQ_QB:
13961 check_dsp(ctx);
13962 gen_helper_cmpu_eq_qb(v1_t, v2_t, cpu_env);
13963 break;
13964 case OPC_CMPU_LT_QB:
13965 check_dsp(ctx);
13966 gen_helper_cmpu_lt_qb(v1_t, v2_t, cpu_env);
13967 break;
13968 case OPC_CMPU_LE_QB:
13969 check_dsp(ctx);
13970 gen_helper_cmpu_le_qb(v1_t, v2_t, cpu_env);
13971 break;
13972 case OPC_CMPGU_EQ_QB:
13973 check_dsp(ctx);
13974 gen_helper_cmpgu_eq_qb(cpu_gpr[ret], v1_t, v2_t);
13975 break;
13976 case OPC_CMPGU_LT_QB:
13977 check_dsp(ctx);
13978 gen_helper_cmpgu_lt_qb(cpu_gpr[ret], v1_t, v2_t);
13979 break;
13980 case OPC_CMPGU_LE_QB:
13981 check_dsp(ctx);
13982 gen_helper_cmpgu_le_qb(cpu_gpr[ret], v1_t, v2_t);
13983 break;
13984 case OPC_CMPGDU_EQ_QB:
13985 check_dspr2(ctx);
13986 gen_helper_cmpgu_eq_qb(t1, v1_t, v2_t);
13987 tcg_gen_mov_tl(cpu_gpr[ret], t1);
13988 tcg_gen_andi_tl(cpu_dspctrl, cpu_dspctrl, 0xF0FFFFFF);
13989 tcg_gen_shli_tl(t1, t1, 24);
13990 tcg_gen_or_tl(cpu_dspctrl, cpu_dspctrl, t1);
13991 break;
13992 case OPC_CMPGDU_LT_QB:
13993 check_dspr2(ctx);
13994 gen_helper_cmpgu_lt_qb(t1, v1_t, v2_t);
13995 tcg_gen_mov_tl(cpu_gpr[ret], t1);
13996 tcg_gen_andi_tl(cpu_dspctrl, cpu_dspctrl, 0xF0FFFFFF);
13997 tcg_gen_shli_tl(t1, t1, 24);
13998 tcg_gen_or_tl(cpu_dspctrl, cpu_dspctrl, t1);
13999 break;
14000 case OPC_CMPGDU_LE_QB:
14001 check_dspr2(ctx);
14002 gen_helper_cmpgu_le_qb(t1, v1_t, v2_t);
14003 tcg_gen_mov_tl(cpu_gpr[ret], t1);
14004 tcg_gen_andi_tl(cpu_dspctrl, cpu_dspctrl, 0xF0FFFFFF);
14005 tcg_gen_shli_tl(t1, t1, 24);
14006 tcg_gen_or_tl(cpu_dspctrl, cpu_dspctrl, t1);
14007 break;
14008 case OPC_CMP_EQ_PH:
14009 check_dsp(ctx);
14010 gen_helper_cmp_eq_ph(v1_t, v2_t, cpu_env);
14011 break;
14012 case OPC_CMP_LT_PH:
14013 check_dsp(ctx);
14014 gen_helper_cmp_lt_ph(v1_t, v2_t, cpu_env);
14015 break;
14016 case OPC_CMP_LE_PH:
14017 check_dsp(ctx);
14018 gen_helper_cmp_le_ph(v1_t, v2_t, cpu_env);
14019 break;
14020 case OPC_PICK_QB:
14021 check_dsp(ctx);
14022 gen_helper_pick_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
14023 break;
14024 case OPC_PICK_PH:
14025 check_dsp(ctx);
14026 gen_helper_pick_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
14027 break;
14028 case OPC_PACKRL_PH:
14029 check_dsp(ctx);
14030 gen_helper_packrl_ph(cpu_gpr[ret], v1_t, v2_t);
14031 break;
14033 break;
14034 #ifdef TARGET_MIPS64
14035 case OPC_CMPU_EQ_OB_DSP:
14036 switch (op2) {
14037 case OPC_CMP_EQ_PW:
14038 check_dsp(ctx);
14039 gen_helper_cmp_eq_pw(v1_t, v2_t, cpu_env);
14040 break;
14041 case OPC_CMP_LT_PW:
14042 check_dsp(ctx);
14043 gen_helper_cmp_lt_pw(v1_t, v2_t, cpu_env);
14044 break;
14045 case OPC_CMP_LE_PW:
14046 check_dsp(ctx);
14047 gen_helper_cmp_le_pw(v1_t, v2_t, cpu_env);
14048 break;
14049 case OPC_CMP_EQ_QH:
14050 check_dsp(ctx);
14051 gen_helper_cmp_eq_qh(v1_t, v2_t, cpu_env);
14052 break;
14053 case OPC_CMP_LT_QH:
14054 check_dsp(ctx);
14055 gen_helper_cmp_lt_qh(v1_t, v2_t, cpu_env);
14056 break;
14057 case OPC_CMP_LE_QH:
14058 check_dsp(ctx);
14059 gen_helper_cmp_le_qh(v1_t, v2_t, cpu_env);
14060 break;
14061 case OPC_CMPGDU_EQ_OB:
14062 check_dspr2(ctx);
14063 gen_helper_cmpgdu_eq_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
14064 break;
14065 case OPC_CMPGDU_LT_OB:
14066 check_dspr2(ctx);
14067 gen_helper_cmpgdu_lt_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
14068 break;
14069 case OPC_CMPGDU_LE_OB:
14070 check_dspr2(ctx);
14071 gen_helper_cmpgdu_le_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
14072 break;
14073 case OPC_CMPGU_EQ_OB:
14074 check_dsp(ctx);
14075 gen_helper_cmpgu_eq_ob(cpu_gpr[ret], v1_t, v2_t);
14076 break;
14077 case OPC_CMPGU_LT_OB:
14078 check_dsp(ctx);
14079 gen_helper_cmpgu_lt_ob(cpu_gpr[ret], v1_t, v2_t);
14080 break;
14081 case OPC_CMPGU_LE_OB:
14082 check_dsp(ctx);
14083 gen_helper_cmpgu_le_ob(cpu_gpr[ret], v1_t, v2_t);
14084 break;
14085 case OPC_CMPU_EQ_OB:
14086 check_dsp(ctx);
14087 gen_helper_cmpu_eq_ob(v1_t, v2_t, cpu_env);
14088 break;
14089 case OPC_CMPU_LT_OB:
14090 check_dsp(ctx);
14091 gen_helper_cmpu_lt_ob(v1_t, v2_t, cpu_env);
14092 break;
14093 case OPC_CMPU_LE_OB:
14094 check_dsp(ctx);
14095 gen_helper_cmpu_le_ob(v1_t, v2_t, cpu_env);
14096 break;
14097 case OPC_PACKRL_PW:
14098 check_dsp(ctx);
14099 gen_helper_packrl_pw(cpu_gpr[ret], v1_t, v2_t);
14100 break;
14101 case OPC_PICK_OB:
14102 check_dsp(ctx);
14103 gen_helper_pick_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
14104 break;
14105 case OPC_PICK_PW:
14106 check_dsp(ctx);
14107 gen_helper_pick_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
14108 break;
14109 case OPC_PICK_QH:
14110 check_dsp(ctx);
14111 gen_helper_pick_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
14112 break;
14114 break;
14115 #endif
14118 tcg_temp_free(t1);
14119 tcg_temp_free(v1_t);
14120 tcg_temp_free(v2_t);
14122 (void)opn; /* avoid a compiler warning */
14123 MIPS_DEBUG("%s", opn);
14126 static void gen_mipsdsp_append(CPUMIPSState *env, DisasContext *ctx,
14127 uint32_t op1, int rt, int rs, int sa)
14129 const char *opn = "mipsdsp append/dappend";
14130 TCGv t0;
14132 check_dspr2(ctx);
14134 if (rt == 0) {
14135 /* Treat as NOP. */
14136 MIPS_DEBUG("NOP");
14137 return;
14140 t0 = tcg_temp_new();
14141 gen_load_gpr(t0, rs);
14143 switch (op1) {
14144 case OPC_APPEND_DSP:
14145 switch (MASK_APPEND(ctx->opcode)) {
14146 case OPC_APPEND:
14147 if (sa != 0) {
14148 tcg_gen_deposit_tl(cpu_gpr[rt], t0, cpu_gpr[rt], sa, 32 - sa);
14150 tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]);
14151 break;
14152 case OPC_PREPEND:
14153 if (sa != 0) {
14154 tcg_gen_ext32u_tl(cpu_gpr[rt], cpu_gpr[rt]);
14155 tcg_gen_shri_tl(cpu_gpr[rt], cpu_gpr[rt], sa);
14156 tcg_gen_shli_tl(t0, t0, 32 - sa);
14157 tcg_gen_or_tl(cpu_gpr[rt], cpu_gpr[rt], t0);
14159 tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]);
14160 break;
14161 case OPC_BALIGN:
14162 sa &= 3;
14163 if (sa != 0 && sa != 2) {
14164 tcg_gen_shli_tl(cpu_gpr[rt], cpu_gpr[rt], 8 * sa);
14165 tcg_gen_ext32u_tl(t0, t0);
14166 tcg_gen_shri_tl(t0, t0, 8 * (4 - sa));
14167 tcg_gen_or_tl(cpu_gpr[rt], cpu_gpr[rt], t0);
14169 tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]);
14170 break;
14171 default: /* Invalid */
14172 MIPS_INVAL("MASK APPEND");
14173 generate_exception(ctx, EXCP_RI);
14174 break;
14176 break;
14177 #ifdef TARGET_MIPS64
14178 case OPC_DAPPEND_DSP:
14179 switch (MASK_DAPPEND(ctx->opcode)) {
14180 case OPC_DAPPEND:
14181 if (sa != 0) {
14182 tcg_gen_deposit_tl(cpu_gpr[rt], t0, cpu_gpr[rt], sa, 64 - sa);
14184 break;
14185 case OPC_PREPENDD:
14186 tcg_gen_shri_tl(cpu_gpr[rt], cpu_gpr[rt], 0x20 | sa);
14187 tcg_gen_shli_tl(t0, t0, 64 - (0x20 | sa));
14188 tcg_gen_or_tl(cpu_gpr[rt], t0, t0);
14189 break;
14190 case OPC_PREPENDW:
14191 if (sa != 0) {
14192 tcg_gen_shri_tl(cpu_gpr[rt], cpu_gpr[rt], sa);
14193 tcg_gen_shli_tl(t0, t0, 64 - sa);
14194 tcg_gen_or_tl(cpu_gpr[rt], cpu_gpr[rt], t0);
14196 break;
14197 case OPC_DBALIGN:
14198 sa &= 7;
14199 if (sa != 0 && sa != 2 && sa != 4) {
14200 tcg_gen_shli_tl(cpu_gpr[rt], cpu_gpr[rt], 8 * sa);
14201 tcg_gen_shri_tl(t0, t0, 8 * (8 - sa));
14202 tcg_gen_or_tl(cpu_gpr[rt], cpu_gpr[rt], t0);
14204 break;
14205 default: /* Invalid */
14206 MIPS_INVAL("MASK DAPPEND");
14207 generate_exception(ctx, EXCP_RI);
14208 break;
14210 break;
14211 #endif
14213 tcg_temp_free(t0);
14214 (void)opn; /* avoid a compiler warning */
14215 MIPS_DEBUG("%s", opn);
14218 static void gen_mipsdsp_accinsn(DisasContext *ctx, uint32_t op1, uint32_t op2,
14219 int ret, int v1, int v2, int check_ret)
14222 const char *opn = "mipsdsp accumulator";
14223 TCGv t0;
14224 TCGv t1;
14225 TCGv v1_t;
14226 TCGv v2_t;
14227 int16_t imm;
14229 if ((ret == 0) && (check_ret == 1)) {
14230 /* Treat as NOP. */
14231 MIPS_DEBUG("NOP");
14232 return;
14235 t0 = tcg_temp_new();
14236 t1 = tcg_temp_new();
14237 v1_t = tcg_temp_new();
14238 v2_t = tcg_temp_new();
14240 gen_load_gpr(v1_t, v1);
14241 gen_load_gpr(v2_t, v2);
14243 switch (op1) {
14244 case OPC_EXTR_W_DSP:
14245 check_dsp(ctx);
14246 switch (op2) {
14247 case OPC_EXTR_W:
14248 tcg_gen_movi_tl(t0, v2);
14249 tcg_gen_movi_tl(t1, v1);
14250 gen_helper_extr_w(cpu_gpr[ret], t0, t1, cpu_env);
14251 break;
14252 case OPC_EXTR_R_W:
14253 tcg_gen_movi_tl(t0, v2);
14254 tcg_gen_movi_tl(t1, v1);
14255 gen_helper_extr_r_w(cpu_gpr[ret], t0, t1, cpu_env);
14256 break;
14257 case OPC_EXTR_RS_W:
14258 tcg_gen_movi_tl(t0, v2);
14259 tcg_gen_movi_tl(t1, v1);
14260 gen_helper_extr_rs_w(cpu_gpr[ret], t0, t1, cpu_env);
14261 break;
14262 case OPC_EXTR_S_H:
14263 tcg_gen_movi_tl(t0, v2);
14264 tcg_gen_movi_tl(t1, v1);
14265 gen_helper_extr_s_h(cpu_gpr[ret], t0, t1, cpu_env);
14266 break;
14267 case OPC_EXTRV_S_H:
14268 tcg_gen_movi_tl(t0, v2);
14269 gen_helper_extr_s_h(cpu_gpr[ret], t0, v1_t, cpu_env);
14270 break;
14271 case OPC_EXTRV_W:
14272 tcg_gen_movi_tl(t0, v2);
14273 gen_helper_extr_w(cpu_gpr[ret], t0, v1_t, cpu_env);
14274 break;
14275 case OPC_EXTRV_R_W:
14276 tcg_gen_movi_tl(t0, v2);
14277 gen_helper_extr_r_w(cpu_gpr[ret], t0, v1_t, cpu_env);
14278 break;
14279 case OPC_EXTRV_RS_W:
14280 tcg_gen_movi_tl(t0, v2);
14281 gen_helper_extr_rs_w(cpu_gpr[ret], t0, v1_t, cpu_env);
14282 break;
14283 case OPC_EXTP:
14284 tcg_gen_movi_tl(t0, v2);
14285 tcg_gen_movi_tl(t1, v1);
14286 gen_helper_extp(cpu_gpr[ret], t0, t1, cpu_env);
14287 break;
14288 case OPC_EXTPV:
14289 tcg_gen_movi_tl(t0, v2);
14290 gen_helper_extp(cpu_gpr[ret], t0, v1_t, cpu_env);
14291 break;
14292 case OPC_EXTPDP:
14293 tcg_gen_movi_tl(t0, v2);
14294 tcg_gen_movi_tl(t1, v1);
14295 gen_helper_extpdp(cpu_gpr[ret], t0, t1, cpu_env);
14296 break;
14297 case OPC_EXTPDPV:
14298 tcg_gen_movi_tl(t0, v2);
14299 gen_helper_extpdp(cpu_gpr[ret], t0, v1_t, cpu_env);
14300 break;
14301 case OPC_SHILO:
14302 imm = (ctx->opcode >> 20) & 0x3F;
14303 tcg_gen_movi_tl(t0, ret);
14304 tcg_gen_movi_tl(t1, imm);
14305 gen_helper_shilo(t0, t1, cpu_env);
14306 break;
14307 case OPC_SHILOV:
14308 tcg_gen_movi_tl(t0, ret);
14309 gen_helper_shilo(t0, v1_t, cpu_env);
14310 break;
14311 case OPC_MTHLIP:
14312 tcg_gen_movi_tl(t0, ret);
14313 gen_helper_mthlip(t0, v1_t, cpu_env);
14314 break;
14315 case OPC_WRDSP:
14316 imm = (ctx->opcode >> 11) & 0x3FF;
14317 tcg_gen_movi_tl(t0, imm);
14318 gen_helper_wrdsp(v1_t, t0, cpu_env);
14319 break;
14320 case OPC_RDDSP:
14321 imm = (ctx->opcode >> 16) & 0x03FF;
14322 tcg_gen_movi_tl(t0, imm);
14323 gen_helper_rddsp(cpu_gpr[ret], t0, cpu_env);
14324 break;
14326 break;
14327 #ifdef TARGET_MIPS64
14328 case OPC_DEXTR_W_DSP:
14329 check_dsp(ctx);
14330 switch (op2) {
14331 case OPC_DMTHLIP:
14332 tcg_gen_movi_tl(t0, ret);
14333 gen_helper_dmthlip(v1_t, t0, cpu_env);
14334 break;
14335 case OPC_DSHILO:
14337 int shift = (ctx->opcode >> 19) & 0x7F;
14338 int ac = (ctx->opcode >> 11) & 0x03;
14339 tcg_gen_movi_tl(t0, shift);
14340 tcg_gen_movi_tl(t1, ac);
14341 gen_helper_dshilo(t0, t1, cpu_env);
14342 break;
14344 case OPC_DSHILOV:
14346 int ac = (ctx->opcode >> 11) & 0x03;
14347 tcg_gen_movi_tl(t0, ac);
14348 gen_helper_dshilo(v1_t, t0, cpu_env);
14349 break;
14351 case OPC_DEXTP:
14352 tcg_gen_movi_tl(t0, v2);
14353 tcg_gen_movi_tl(t1, v1);
14355 gen_helper_dextp(cpu_gpr[ret], t0, t1, cpu_env);
14356 break;
14357 case OPC_DEXTPV:
14358 tcg_gen_movi_tl(t0, v2);
14359 gen_helper_dextp(cpu_gpr[ret], t0, v1_t, cpu_env);
14360 break;
14361 case OPC_DEXTPDP:
14362 tcg_gen_movi_tl(t0, v2);
14363 tcg_gen_movi_tl(t1, v1);
14364 gen_helper_dextpdp(cpu_gpr[ret], t0, t1, cpu_env);
14365 break;
14366 case OPC_DEXTPDPV:
14367 tcg_gen_movi_tl(t0, v2);
14368 gen_helper_dextpdp(cpu_gpr[ret], t0, v1_t, cpu_env);
14369 break;
14370 case OPC_DEXTR_L:
14371 tcg_gen_movi_tl(t0, v2);
14372 tcg_gen_movi_tl(t1, v1);
14373 gen_helper_dextr_l(cpu_gpr[ret], t0, t1, cpu_env);
14374 break;
14375 case OPC_DEXTR_R_L:
14376 tcg_gen_movi_tl(t0, v2);
14377 tcg_gen_movi_tl(t1, v1);
14378 gen_helper_dextr_r_l(cpu_gpr[ret], t0, t1, cpu_env);
14379 break;
14380 case OPC_DEXTR_RS_L:
14381 tcg_gen_movi_tl(t0, v2);
14382 tcg_gen_movi_tl(t1, v1);
14383 gen_helper_dextr_rs_l(cpu_gpr[ret], t0, t1, cpu_env);
14384 break;
14385 case OPC_DEXTR_W:
14386 tcg_gen_movi_tl(t0, v2);
14387 tcg_gen_movi_tl(t1, v1);
14388 gen_helper_dextr_w(cpu_gpr[ret], t0, t1, cpu_env);
14389 break;
14390 case OPC_DEXTR_R_W:
14391 tcg_gen_movi_tl(t0, v2);
14392 tcg_gen_movi_tl(t1, v1);
14393 gen_helper_dextr_r_w(cpu_gpr[ret], t0, t1, cpu_env);
14394 break;
14395 case OPC_DEXTR_RS_W:
14396 tcg_gen_movi_tl(t0, v2);
14397 tcg_gen_movi_tl(t1, v1);
14398 gen_helper_dextr_rs_w(cpu_gpr[ret], t0, t1, cpu_env);
14399 break;
14400 case OPC_DEXTR_S_H:
14401 tcg_gen_movi_tl(t0, v2);
14402 tcg_gen_movi_tl(t1, v1);
14403 gen_helper_dextr_s_h(cpu_gpr[ret], t0, t1, cpu_env);
14404 break;
14405 case OPC_DEXTRV_S_H:
14406 tcg_gen_movi_tl(t0, v2);
14407 tcg_gen_movi_tl(t1, v1);
14408 gen_helper_dextr_s_h(cpu_gpr[ret], t0, t1, cpu_env);
14409 break;
14410 case OPC_DEXTRV_L:
14411 tcg_gen_movi_tl(t0, v2);
14412 gen_helper_dextr_l(cpu_gpr[ret], t0, v1_t, cpu_env);
14413 break;
14414 case OPC_DEXTRV_R_L:
14415 tcg_gen_movi_tl(t0, v2);
14416 gen_helper_dextr_r_l(cpu_gpr[ret], t0, v1_t, cpu_env);
14417 break;
14418 case OPC_DEXTRV_RS_L:
14419 tcg_gen_movi_tl(t0, v2);
14420 gen_helper_dextr_rs_l(cpu_gpr[ret], t0, v1_t, cpu_env);
14421 break;
14422 case OPC_DEXTRV_W:
14423 tcg_gen_movi_tl(t0, v2);
14424 gen_helper_dextr_w(cpu_gpr[ret], t0, v1_t, cpu_env);
14425 break;
14426 case OPC_DEXTRV_R_W:
14427 tcg_gen_movi_tl(t0, v2);
14428 gen_helper_dextr_r_w(cpu_gpr[ret], t0, v1_t, cpu_env);
14429 break;
14430 case OPC_DEXTRV_RS_W:
14431 tcg_gen_movi_tl(t0, v2);
14432 gen_helper_dextr_rs_w(cpu_gpr[ret], t0, v1_t, cpu_env);
14433 break;
14435 break;
14436 #endif
14439 tcg_temp_free(t0);
14440 tcg_temp_free(t1);
14441 tcg_temp_free(v1_t);
14442 tcg_temp_free(v2_t);
14444 (void)opn; /* avoid a compiler warning */
14445 MIPS_DEBUG("%s", opn);
14448 /* End MIPSDSP functions. */
14450 static void decode_opc (CPUMIPSState *env, DisasContext *ctx)
14452 int32_t offset;
14453 int rs, rt, rd, sa;
14454 uint32_t op, op1, op2;
14455 int16_t imm;
14457 /* make sure instructions are on a word boundary */
14458 if (ctx->pc & 0x3) {
14459 env->CP0_BadVAddr = ctx->pc;
14460 generate_exception(ctx, EXCP_AdEL);
14461 return;
14464 /* Handle blikely not taken case */
14465 if ((ctx->hflags & MIPS_HFLAG_BMASK_BASE) == MIPS_HFLAG_BL) {
14466 int l1 = gen_new_label();
14468 MIPS_DEBUG("blikely condition (" TARGET_FMT_lx ")", ctx->pc + 4);
14469 tcg_gen_brcondi_tl(TCG_COND_NE, bcond, 0, l1);
14470 tcg_gen_movi_i32(hflags, ctx->hflags & ~MIPS_HFLAG_BMASK);
14471 gen_goto_tb(ctx, 1, ctx->pc + 4);
14472 gen_set_label(l1);
14475 if (unlikely(qemu_loglevel_mask(CPU_LOG_TB_OP | CPU_LOG_TB_OP_OPT))) {
14476 tcg_gen_debug_insn_start(ctx->pc);
14479 op = MASK_OP_MAJOR(ctx->opcode);
14480 rs = (ctx->opcode >> 21) & 0x1f;
14481 rt = (ctx->opcode >> 16) & 0x1f;
14482 rd = (ctx->opcode >> 11) & 0x1f;
14483 sa = (ctx->opcode >> 6) & 0x1f;
14484 imm = (int16_t)ctx->opcode;
14485 switch (op) {
14486 case OPC_SPECIAL:
14487 op1 = MASK_SPECIAL(ctx->opcode);
14488 switch (op1) {
14489 case OPC_SLL: /* Shift with immediate */
14490 case OPC_SRA:
14491 gen_shift_imm(ctx, op1, rd, rt, sa);
14492 break;
14493 case OPC_SRL:
14494 switch ((ctx->opcode >> 21) & 0x1f) {
14495 case 1:
14496 /* rotr is decoded as srl on non-R2 CPUs */
14497 if (ctx->insn_flags & ISA_MIPS32R2) {
14498 op1 = OPC_ROTR;
14500 /* Fallthrough */
14501 case 0:
14502 gen_shift_imm(ctx, op1, rd, rt, sa);
14503 break;
14504 default:
14505 generate_exception(ctx, EXCP_RI);
14506 break;
14508 break;
14509 case OPC_MOVN: /* Conditional move */
14510 case OPC_MOVZ:
14511 check_insn(ctx, ISA_MIPS4 | ISA_MIPS32 |
14512 INSN_LOONGSON2E | INSN_LOONGSON2F);
14513 gen_cond_move(ctx, op1, rd, rs, rt);
14514 break;
14515 case OPC_ADD ... OPC_SUBU:
14516 gen_arith(ctx, op1, rd, rs, rt);
14517 break;
14518 case OPC_SLLV: /* Shifts */
14519 case OPC_SRAV:
14520 gen_shift(ctx, op1, rd, rs, rt);
14521 break;
14522 case OPC_SRLV:
14523 switch ((ctx->opcode >> 6) & 0x1f) {
14524 case 1:
14525 /* rotrv is decoded as srlv on non-R2 CPUs */
14526 if (ctx->insn_flags & ISA_MIPS32R2) {
14527 op1 = OPC_ROTRV;
14529 /* Fallthrough */
14530 case 0:
14531 gen_shift(ctx, op1, rd, rs, rt);
14532 break;
14533 default:
14534 generate_exception(ctx, EXCP_RI);
14535 break;
14537 break;
14538 case OPC_SLT: /* Set on less than */
14539 case OPC_SLTU:
14540 gen_slt(ctx, op1, rd, rs, rt);
14541 break;
14542 case OPC_AND: /* Logic*/
14543 case OPC_OR:
14544 case OPC_NOR:
14545 case OPC_XOR:
14546 gen_logic(ctx, op1, rd, rs, rt);
14547 break;
14548 case OPC_MULT:
14549 case OPC_MULTU:
14550 if (sa) {
14551 check_insn(ctx, INSN_VR54XX);
14552 op1 = MASK_MUL_VR54XX(ctx->opcode);
14553 gen_mul_vr54xx(ctx, op1, rd, rs, rt);
14554 } else {
14555 gen_muldiv(ctx, op1, rd & 3, rs, rt);
14557 break;
14558 case OPC_DIV:
14559 case OPC_DIVU:
14560 gen_muldiv(ctx, op1, 0, rs, rt);
14561 break;
14562 case OPC_JR ... OPC_JALR:
14563 gen_compute_branch(ctx, op1, 4, rs, rd, sa);
14564 break;
14565 case OPC_TGE ... OPC_TEQ: /* Traps */
14566 case OPC_TNE:
14567 gen_trap(ctx, op1, rs, rt, -1);
14568 break;
14569 case OPC_MFHI: /* Move from HI/LO */
14570 case OPC_MFLO:
14571 gen_HILO(ctx, op1, rs & 3, rd);
14572 break;
14573 case OPC_MTHI:
14574 case OPC_MTLO: /* Move to HI/LO */
14575 gen_HILO(ctx, op1, rd & 3, rs);
14576 break;
14577 case OPC_PMON: /* Pmon entry point, also R4010 selsl */
14578 #ifdef MIPS_STRICT_STANDARD
14579 MIPS_INVAL("PMON / selsl");
14580 generate_exception(ctx, EXCP_RI);
14581 #else
14582 gen_helper_0e0i(pmon, sa);
14583 #endif
14584 break;
14585 case OPC_SYSCALL:
14586 generate_exception(ctx, EXCP_SYSCALL);
14587 ctx->bstate = BS_STOP;
14588 break;
14589 case OPC_BREAK:
14590 generate_exception(ctx, EXCP_BREAK);
14591 break;
14592 case OPC_SPIM:
14593 #ifdef MIPS_STRICT_STANDARD
14594 MIPS_INVAL("SPIM");
14595 generate_exception(ctx, EXCP_RI);
14596 #else
14597 /* Implemented as RI exception for now. */
14598 MIPS_INVAL("spim (unofficial)");
14599 generate_exception(ctx, EXCP_RI);
14600 #endif
14601 break;
14602 case OPC_SYNC:
14603 /* Treat as NOP. */
14604 break;
14606 case OPC_MOVCI:
14607 check_insn(ctx, ISA_MIPS4 | ISA_MIPS32);
14608 if (ctx->CP0_Config1 & (1 << CP0C1_FP)) {
14609 check_cp1_enabled(ctx);
14610 gen_movci(ctx, rd, rs, (ctx->opcode >> 18) & 0x7,
14611 (ctx->opcode >> 16) & 1);
14612 } else {
14613 generate_exception_err(ctx, EXCP_CpU, 1);
14615 break;
14617 #if defined(TARGET_MIPS64)
14618 /* MIPS64 specific opcodes */
14619 case OPC_DSLL:
14620 case OPC_DSRA:
14621 case OPC_DSLL32:
14622 case OPC_DSRA32:
14623 check_insn(ctx, ISA_MIPS3);
14624 check_mips_64(ctx);
14625 gen_shift_imm(ctx, op1, rd, rt, sa);
14626 break;
14627 case OPC_DSRL:
14628 switch ((ctx->opcode >> 21) & 0x1f) {
14629 case 1:
14630 /* drotr is decoded as dsrl on non-R2 CPUs */
14631 if (ctx->insn_flags & ISA_MIPS32R2) {
14632 op1 = OPC_DROTR;
14634 /* Fallthrough */
14635 case 0:
14636 check_insn(ctx, ISA_MIPS3);
14637 check_mips_64(ctx);
14638 gen_shift_imm(ctx, op1, rd, rt, sa);
14639 break;
14640 default:
14641 generate_exception(ctx, EXCP_RI);
14642 break;
14644 break;
14645 case OPC_DSRL32:
14646 switch ((ctx->opcode >> 21) & 0x1f) {
14647 case 1:
14648 /* drotr32 is decoded as dsrl32 on non-R2 CPUs */
14649 if (ctx->insn_flags & ISA_MIPS32R2) {
14650 op1 = OPC_DROTR32;
14652 /* Fallthrough */
14653 case 0:
14654 check_insn(ctx, ISA_MIPS3);
14655 check_mips_64(ctx);
14656 gen_shift_imm(ctx, op1, rd, rt, sa);
14657 break;
14658 default:
14659 generate_exception(ctx, EXCP_RI);
14660 break;
14662 break;
14663 case OPC_DADD ... OPC_DSUBU:
14664 check_insn(ctx, ISA_MIPS3);
14665 check_mips_64(ctx);
14666 gen_arith(ctx, op1, rd, rs, rt);
14667 break;
14668 case OPC_DSLLV:
14669 case OPC_DSRAV:
14670 check_insn(ctx, ISA_MIPS3);
14671 check_mips_64(ctx);
14672 gen_shift(ctx, op1, rd, rs, rt);
14673 break;
14674 case OPC_DSRLV:
14675 switch ((ctx->opcode >> 6) & 0x1f) {
14676 case 1:
14677 /* drotrv is decoded as dsrlv on non-R2 CPUs */
14678 if (ctx->insn_flags & ISA_MIPS32R2) {
14679 op1 = OPC_DROTRV;
14681 /* Fallthrough */
14682 case 0:
14683 check_insn(ctx, ISA_MIPS3);
14684 check_mips_64(ctx);
14685 gen_shift(ctx, op1, rd, rs, rt);
14686 break;
14687 default:
14688 generate_exception(ctx, EXCP_RI);
14689 break;
14691 break;
14692 case OPC_DMULT ... OPC_DDIVU:
14693 check_insn(ctx, ISA_MIPS3);
14694 check_mips_64(ctx);
14695 gen_muldiv(ctx, op1, 0, rs, rt);
14696 break;
14697 #endif
14698 default: /* Invalid */
14699 MIPS_INVAL("special");
14700 generate_exception(ctx, EXCP_RI);
14701 break;
14703 break;
14704 case OPC_SPECIAL2:
14705 op1 = MASK_SPECIAL2(ctx->opcode);
14706 switch (op1) {
14707 case OPC_MADD ... OPC_MADDU: /* Multiply and add/sub */
14708 case OPC_MSUB ... OPC_MSUBU:
14709 check_insn(ctx, ISA_MIPS32);
14710 gen_muldiv(ctx, op1, rd & 3, rs, rt);
14711 break;
14712 case OPC_MUL:
14713 gen_arith(ctx, op1, rd, rs, rt);
14714 break;
14715 case OPC_CLO:
14716 case OPC_CLZ:
14717 check_insn(ctx, ISA_MIPS32);
14718 gen_cl(ctx, op1, rd, rs);
14719 break;
14720 case OPC_SDBBP:
14721 /* XXX: not clear which exception should be raised
14722 * when in debug mode...
14724 check_insn(ctx, ISA_MIPS32);
14725 if (!(ctx->hflags & MIPS_HFLAG_DM)) {
14726 generate_exception(ctx, EXCP_DBp);
14727 } else {
14728 generate_exception(ctx, EXCP_DBp);
14730 /* Treat as NOP. */
14731 break;
14732 case OPC_DIV_G_2F:
14733 case OPC_DIVU_G_2F:
14734 case OPC_MULT_G_2F:
14735 case OPC_MULTU_G_2F:
14736 case OPC_MOD_G_2F:
14737 case OPC_MODU_G_2F:
14738 check_insn(ctx, INSN_LOONGSON2F);
14739 gen_loongson_integer(ctx, op1, rd, rs, rt);
14740 break;
14741 #if defined(TARGET_MIPS64)
14742 case OPC_DCLO:
14743 case OPC_DCLZ:
14744 check_insn(ctx, ISA_MIPS64);
14745 check_mips_64(ctx);
14746 gen_cl(ctx, op1, rd, rs);
14747 break;
14748 case OPC_DMULT_G_2F:
14749 case OPC_DMULTU_G_2F:
14750 case OPC_DDIV_G_2F:
14751 case OPC_DDIVU_G_2F:
14752 case OPC_DMOD_G_2F:
14753 case OPC_DMODU_G_2F:
14754 check_insn(ctx, INSN_LOONGSON2F);
14755 gen_loongson_integer(ctx, op1, rd, rs, rt);
14756 break;
14757 #endif
14758 default: /* Invalid */
14759 MIPS_INVAL("special2");
14760 generate_exception(ctx, EXCP_RI);
14761 break;
14763 break;
14764 case OPC_SPECIAL3:
14765 op1 = MASK_SPECIAL3(ctx->opcode);
14766 switch (op1) {
14767 case OPC_EXT:
14768 case OPC_INS:
14769 check_insn(ctx, ISA_MIPS32R2);
14770 gen_bitops(ctx, op1, rt, rs, sa, rd);
14771 break;
14772 case OPC_BSHFL:
14773 check_insn(ctx, ISA_MIPS32R2);
14774 op2 = MASK_BSHFL(ctx->opcode);
14775 gen_bshfl(ctx, op2, rt, rd);
14776 break;
14777 case OPC_RDHWR:
14778 gen_rdhwr(ctx, rt, rd);
14779 break;
14780 case OPC_FORK:
14781 check_insn(ctx, ASE_MT);
14783 TCGv t0 = tcg_temp_new();
14784 TCGv t1 = tcg_temp_new();
14786 gen_load_gpr(t0, rt);
14787 gen_load_gpr(t1, rs);
14788 gen_helper_fork(t0, t1);
14789 tcg_temp_free(t0);
14790 tcg_temp_free(t1);
14792 break;
14793 case OPC_YIELD:
14794 check_insn(ctx, ASE_MT);
14796 TCGv t0 = tcg_temp_new();
14798 save_cpu_state(ctx, 1);
14799 gen_load_gpr(t0, rs);
14800 gen_helper_yield(t0, cpu_env, t0);
14801 gen_store_gpr(t0, rd);
14802 tcg_temp_free(t0);
14804 break;
14805 case OPC_DIV_G_2E ... OPC_DIVU_G_2E:
14806 case OPC_MOD_G_2E ... OPC_MODU_G_2E:
14807 case OPC_MULT_G_2E ... OPC_MULTU_G_2E:
14808 /* OPC_MULT_G_2E, OPC_ADDUH_QB_DSP, OPC_MUL_PH_DSP have
14809 * the same mask and op1. */
14810 if ((ctx->insn_flags & ASE_DSPR2) && (op1 == OPC_MULT_G_2E)) {
14811 op2 = MASK_ADDUH_QB(ctx->opcode);
14812 switch (op2) {
14813 case OPC_ADDUH_QB:
14814 case OPC_ADDUH_R_QB:
14815 case OPC_ADDQH_PH:
14816 case OPC_ADDQH_R_PH:
14817 case OPC_ADDQH_W:
14818 case OPC_ADDQH_R_W:
14819 case OPC_SUBUH_QB:
14820 case OPC_SUBUH_R_QB:
14821 case OPC_SUBQH_PH:
14822 case OPC_SUBQH_R_PH:
14823 case OPC_SUBQH_W:
14824 case OPC_SUBQH_R_W:
14825 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
14826 break;
14827 case OPC_MUL_PH:
14828 case OPC_MUL_S_PH:
14829 case OPC_MULQ_S_W:
14830 case OPC_MULQ_RS_W:
14831 gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 1);
14832 break;
14833 default:
14834 MIPS_INVAL("MASK ADDUH.QB");
14835 generate_exception(ctx, EXCP_RI);
14836 break;
14838 } else if (ctx->insn_flags & INSN_LOONGSON2E) {
14839 gen_loongson_integer(ctx, op1, rd, rs, rt);
14840 } else {
14841 generate_exception(ctx, EXCP_RI);
14843 break;
14844 case OPC_LX_DSP:
14845 op2 = MASK_LX(ctx->opcode);
14846 switch (op2) {
14847 #if defined(TARGET_MIPS64)
14848 case OPC_LDX:
14849 #endif
14850 case OPC_LBUX:
14851 case OPC_LHX:
14852 case OPC_LWX:
14853 gen_mipsdsp_ld(ctx, op2, rd, rs, rt);
14854 break;
14855 default: /* Invalid */
14856 MIPS_INVAL("MASK LX");
14857 generate_exception(ctx, EXCP_RI);
14858 break;
14860 break;
14861 case OPC_ABSQ_S_PH_DSP:
14862 op2 = MASK_ABSQ_S_PH(ctx->opcode);
14863 switch (op2) {
14864 case OPC_ABSQ_S_QB:
14865 case OPC_ABSQ_S_PH:
14866 case OPC_ABSQ_S_W:
14867 case OPC_PRECEQ_W_PHL:
14868 case OPC_PRECEQ_W_PHR:
14869 case OPC_PRECEQU_PH_QBL:
14870 case OPC_PRECEQU_PH_QBR:
14871 case OPC_PRECEQU_PH_QBLA:
14872 case OPC_PRECEQU_PH_QBRA:
14873 case OPC_PRECEU_PH_QBL:
14874 case OPC_PRECEU_PH_QBR:
14875 case OPC_PRECEU_PH_QBLA:
14876 case OPC_PRECEU_PH_QBRA:
14877 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
14878 break;
14879 case OPC_BITREV:
14880 case OPC_REPL_QB:
14881 case OPC_REPLV_QB:
14882 case OPC_REPL_PH:
14883 case OPC_REPLV_PH:
14884 gen_mipsdsp_bitinsn(ctx, op1, op2, rd, rt);
14885 break;
14886 default:
14887 MIPS_INVAL("MASK ABSQ_S.PH");
14888 generate_exception(ctx, EXCP_RI);
14889 break;
14891 break;
14892 case OPC_ADDU_QB_DSP:
14893 op2 = MASK_ADDU_QB(ctx->opcode);
14894 switch (op2) {
14895 case OPC_ADDQ_PH:
14896 case OPC_ADDQ_S_PH:
14897 case OPC_ADDQ_S_W:
14898 case OPC_ADDU_QB:
14899 case OPC_ADDU_S_QB:
14900 case OPC_ADDU_PH:
14901 case OPC_ADDU_S_PH:
14902 case OPC_SUBQ_PH:
14903 case OPC_SUBQ_S_PH:
14904 case OPC_SUBQ_S_W:
14905 case OPC_SUBU_QB:
14906 case OPC_SUBU_S_QB:
14907 case OPC_SUBU_PH:
14908 case OPC_SUBU_S_PH:
14909 case OPC_ADDSC:
14910 case OPC_ADDWC:
14911 case OPC_MODSUB:
14912 case OPC_RADDU_W_QB:
14913 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
14914 break;
14915 case OPC_MULEU_S_PH_QBL:
14916 case OPC_MULEU_S_PH_QBR:
14917 case OPC_MULQ_RS_PH:
14918 case OPC_MULEQ_S_W_PHL:
14919 case OPC_MULEQ_S_W_PHR:
14920 case OPC_MULQ_S_PH:
14921 gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 1);
14922 break;
14923 default: /* Invalid */
14924 MIPS_INVAL("MASK ADDU.QB");
14925 generate_exception(ctx, EXCP_RI);
14926 break;
14929 break;
14930 case OPC_CMPU_EQ_QB_DSP:
14931 op2 = MASK_CMPU_EQ_QB(ctx->opcode);
14932 switch (op2) {
14933 case OPC_PRECR_SRA_PH_W:
14934 case OPC_PRECR_SRA_R_PH_W:
14935 gen_mipsdsp_arith(ctx, op1, op2, rt, rs, rd);
14936 break;
14937 case OPC_PRECR_QB_PH:
14938 case OPC_PRECRQ_QB_PH:
14939 case OPC_PRECRQ_PH_W:
14940 case OPC_PRECRQ_RS_PH_W:
14941 case OPC_PRECRQU_S_QB_PH:
14942 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
14943 break;
14944 case OPC_CMPU_EQ_QB:
14945 case OPC_CMPU_LT_QB:
14946 case OPC_CMPU_LE_QB:
14947 case OPC_CMP_EQ_PH:
14948 case OPC_CMP_LT_PH:
14949 case OPC_CMP_LE_PH:
14950 gen_mipsdsp_add_cmp_pick(ctx, op1, op2, rd, rs, rt, 0);
14951 break;
14952 case OPC_CMPGU_EQ_QB:
14953 case OPC_CMPGU_LT_QB:
14954 case OPC_CMPGU_LE_QB:
14955 case OPC_CMPGDU_EQ_QB:
14956 case OPC_CMPGDU_LT_QB:
14957 case OPC_CMPGDU_LE_QB:
14958 case OPC_PICK_QB:
14959 case OPC_PICK_PH:
14960 case OPC_PACKRL_PH:
14961 gen_mipsdsp_add_cmp_pick(ctx, op1, op2, rd, rs, rt, 1);
14962 break;
14963 default: /* Invalid */
14964 MIPS_INVAL("MASK CMPU.EQ.QB");
14965 generate_exception(ctx, EXCP_RI);
14966 break;
14968 break;
14969 case OPC_SHLL_QB_DSP:
14970 gen_mipsdsp_shift(ctx, op1, rd, rs, rt);
14971 break;
14972 case OPC_DPA_W_PH_DSP:
14973 op2 = MASK_DPA_W_PH(ctx->opcode);
14974 switch (op2) {
14975 case OPC_DPAU_H_QBL:
14976 case OPC_DPAU_H_QBR:
14977 case OPC_DPSU_H_QBL:
14978 case OPC_DPSU_H_QBR:
14979 case OPC_DPA_W_PH:
14980 case OPC_DPAX_W_PH:
14981 case OPC_DPAQ_S_W_PH:
14982 case OPC_DPAQX_S_W_PH:
14983 case OPC_DPAQX_SA_W_PH:
14984 case OPC_DPS_W_PH:
14985 case OPC_DPSX_W_PH:
14986 case OPC_DPSQ_S_W_PH:
14987 case OPC_DPSQX_S_W_PH:
14988 case OPC_DPSQX_SA_W_PH:
14989 case OPC_MULSAQ_S_W_PH:
14990 case OPC_DPAQ_SA_L_W:
14991 case OPC_DPSQ_SA_L_W:
14992 case OPC_MAQ_S_W_PHL:
14993 case OPC_MAQ_S_W_PHR:
14994 case OPC_MAQ_SA_W_PHL:
14995 case OPC_MAQ_SA_W_PHR:
14996 case OPC_MULSA_W_PH:
14997 gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 0);
14998 break;
14999 default: /* Invalid */
15000 MIPS_INVAL("MASK DPAW.PH");
15001 generate_exception(ctx, EXCP_RI);
15002 break;
15004 break;
15005 case OPC_INSV_DSP:
15006 op2 = MASK_INSV(ctx->opcode);
15007 switch (op2) {
15008 case OPC_INSV:
15009 check_dsp(ctx);
15011 TCGv t0, t1;
15013 if (rt == 0) {
15014 MIPS_DEBUG("NOP");
15015 break;
15018 t0 = tcg_temp_new();
15019 t1 = tcg_temp_new();
15021 gen_load_gpr(t0, rt);
15022 gen_load_gpr(t1, rs);
15024 gen_helper_insv(cpu_gpr[rt], cpu_env, t1, t0);
15026 tcg_temp_free(t0);
15027 tcg_temp_free(t1);
15028 break;
15030 default: /* Invalid */
15031 MIPS_INVAL("MASK INSV");
15032 generate_exception(ctx, EXCP_RI);
15033 break;
15035 break;
15036 case OPC_APPEND_DSP:
15037 gen_mipsdsp_append(env, ctx, op1, rt, rs, rd);
15038 break;
15039 case OPC_EXTR_W_DSP:
15040 op2 = MASK_EXTR_W(ctx->opcode);
15041 switch (op2) {
15042 case OPC_EXTR_W:
15043 case OPC_EXTR_R_W:
15044 case OPC_EXTR_RS_W:
15045 case OPC_EXTR_S_H:
15046 case OPC_EXTRV_S_H:
15047 case OPC_EXTRV_W:
15048 case OPC_EXTRV_R_W:
15049 case OPC_EXTRV_RS_W:
15050 case OPC_EXTP:
15051 case OPC_EXTPV:
15052 case OPC_EXTPDP:
15053 case OPC_EXTPDPV:
15054 gen_mipsdsp_accinsn(ctx, op1, op2, rt, rs, rd, 1);
15055 break;
15056 case OPC_RDDSP:
15057 gen_mipsdsp_accinsn(ctx, op1, op2, rd, rs, rt, 1);
15058 break;
15059 case OPC_SHILO:
15060 case OPC_SHILOV:
15061 case OPC_MTHLIP:
15062 case OPC_WRDSP:
15063 gen_mipsdsp_accinsn(ctx, op1, op2, rd, rs, rt, 0);
15064 break;
15065 default: /* Invalid */
15066 MIPS_INVAL("MASK EXTR.W");
15067 generate_exception(ctx, EXCP_RI);
15068 break;
15070 break;
15071 #if defined(TARGET_MIPS64)
15072 case OPC_DEXTM ... OPC_DEXT:
15073 case OPC_DINSM ... OPC_DINS:
15074 check_insn(ctx, ISA_MIPS64R2);
15075 check_mips_64(ctx);
15076 gen_bitops(ctx, op1, rt, rs, sa, rd);
15077 break;
15078 case OPC_DBSHFL:
15079 check_insn(ctx, ISA_MIPS64R2);
15080 check_mips_64(ctx);
15081 op2 = MASK_DBSHFL(ctx->opcode);
15082 gen_bshfl(ctx, op2, rt, rd);
15083 break;
15084 case OPC_DDIV_G_2E ... OPC_DDIVU_G_2E:
15085 case OPC_DMULT_G_2E ... OPC_DMULTU_G_2E:
15086 case OPC_DMOD_G_2E ... OPC_DMODU_G_2E:
15087 check_insn(ctx, INSN_LOONGSON2E);
15088 gen_loongson_integer(ctx, op1, rd, rs, rt);
15089 break;
15090 case OPC_ABSQ_S_QH_DSP:
15091 op2 = MASK_ABSQ_S_QH(ctx->opcode);
15092 switch (op2) {
15093 case OPC_PRECEQ_L_PWL:
15094 case OPC_PRECEQ_L_PWR:
15095 case OPC_PRECEQ_PW_QHL:
15096 case OPC_PRECEQ_PW_QHR:
15097 case OPC_PRECEQ_PW_QHLA:
15098 case OPC_PRECEQ_PW_QHRA:
15099 case OPC_PRECEQU_QH_OBL:
15100 case OPC_PRECEQU_QH_OBR:
15101 case OPC_PRECEQU_QH_OBLA:
15102 case OPC_PRECEQU_QH_OBRA:
15103 case OPC_PRECEU_QH_OBL:
15104 case OPC_PRECEU_QH_OBR:
15105 case OPC_PRECEU_QH_OBLA:
15106 case OPC_PRECEU_QH_OBRA:
15107 case OPC_ABSQ_S_OB:
15108 case OPC_ABSQ_S_PW:
15109 case OPC_ABSQ_S_QH:
15110 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
15111 break;
15112 case OPC_REPL_OB:
15113 case OPC_REPL_PW:
15114 case OPC_REPL_QH:
15115 case OPC_REPLV_OB:
15116 case OPC_REPLV_PW:
15117 case OPC_REPLV_QH:
15118 gen_mipsdsp_bitinsn(ctx, op1, op2, rd, rt);
15119 break;
15120 default: /* Invalid */
15121 MIPS_INVAL("MASK ABSQ_S.QH");
15122 generate_exception(ctx, EXCP_RI);
15123 break;
15125 break;
15126 case OPC_ADDU_OB_DSP:
15127 op2 = MASK_ADDU_OB(ctx->opcode);
15128 switch (op2) {
15129 case OPC_RADDU_L_OB:
15130 case OPC_SUBQ_PW:
15131 case OPC_SUBQ_S_PW:
15132 case OPC_SUBQ_QH:
15133 case OPC_SUBQ_S_QH:
15134 case OPC_SUBU_OB:
15135 case OPC_SUBU_S_OB:
15136 case OPC_SUBU_QH:
15137 case OPC_SUBU_S_QH:
15138 case OPC_SUBUH_OB:
15139 case OPC_SUBUH_R_OB:
15140 case OPC_ADDQ_PW:
15141 case OPC_ADDQ_S_PW:
15142 case OPC_ADDQ_QH:
15143 case OPC_ADDQ_S_QH:
15144 case OPC_ADDU_OB:
15145 case OPC_ADDU_S_OB:
15146 case OPC_ADDU_QH:
15147 case OPC_ADDU_S_QH:
15148 case OPC_ADDUH_OB:
15149 case OPC_ADDUH_R_OB:
15150 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
15151 break;
15152 case OPC_MULEQ_S_PW_QHL:
15153 case OPC_MULEQ_S_PW_QHR:
15154 case OPC_MULEU_S_QH_OBL:
15155 case OPC_MULEU_S_QH_OBR:
15156 case OPC_MULQ_RS_QH:
15157 gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 1);
15158 break;
15159 default: /* Invalid */
15160 MIPS_INVAL("MASK ADDU.OB");
15161 generate_exception(ctx, EXCP_RI);
15162 break;
15164 break;
15165 case OPC_CMPU_EQ_OB_DSP:
15166 op2 = MASK_CMPU_EQ_OB(ctx->opcode);
15167 switch (op2) {
15168 case OPC_PRECR_SRA_QH_PW:
15169 case OPC_PRECR_SRA_R_QH_PW:
15170 /* Return value is rt. */
15171 gen_mipsdsp_arith(ctx, op1, op2, rt, rs, rd);
15172 break;
15173 case OPC_PRECR_OB_QH:
15174 case OPC_PRECRQ_OB_QH:
15175 case OPC_PRECRQ_PW_L:
15176 case OPC_PRECRQ_QH_PW:
15177 case OPC_PRECRQ_RS_QH_PW:
15178 case OPC_PRECRQU_S_OB_QH:
15179 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
15180 break;
15181 case OPC_CMPU_EQ_OB:
15182 case OPC_CMPU_LT_OB:
15183 case OPC_CMPU_LE_OB:
15184 case OPC_CMP_EQ_QH:
15185 case OPC_CMP_LT_QH:
15186 case OPC_CMP_LE_QH:
15187 case OPC_CMP_EQ_PW:
15188 case OPC_CMP_LT_PW:
15189 case OPC_CMP_LE_PW:
15190 gen_mipsdsp_add_cmp_pick(ctx, op1, op2, rd, rs, rt, 0);
15191 break;
15192 case OPC_CMPGDU_EQ_OB:
15193 case OPC_CMPGDU_LT_OB:
15194 case OPC_CMPGDU_LE_OB:
15195 case OPC_CMPGU_EQ_OB:
15196 case OPC_CMPGU_LT_OB:
15197 case OPC_CMPGU_LE_OB:
15198 case OPC_PACKRL_PW:
15199 case OPC_PICK_OB:
15200 case OPC_PICK_PW:
15201 case OPC_PICK_QH:
15202 gen_mipsdsp_add_cmp_pick(ctx, op1, op2, rd, rs, rt, 1);
15203 break;
15204 default: /* Invalid */
15205 MIPS_INVAL("MASK CMPU_EQ.OB");
15206 generate_exception(ctx, EXCP_RI);
15207 break;
15209 break;
15210 case OPC_DAPPEND_DSP:
15211 gen_mipsdsp_append(env, ctx, op1, rt, rs, rd);
15212 break;
15213 case OPC_DEXTR_W_DSP:
15214 op2 = MASK_DEXTR_W(ctx->opcode);
15215 switch (op2) {
15216 case OPC_DEXTP:
15217 case OPC_DEXTPDP:
15218 case OPC_DEXTPDPV:
15219 case OPC_DEXTPV:
15220 case OPC_DEXTR_L:
15221 case OPC_DEXTR_R_L:
15222 case OPC_DEXTR_RS_L:
15223 case OPC_DEXTR_W:
15224 case OPC_DEXTR_R_W:
15225 case OPC_DEXTR_RS_W:
15226 case OPC_DEXTR_S_H:
15227 case OPC_DEXTRV_L:
15228 case OPC_DEXTRV_R_L:
15229 case OPC_DEXTRV_RS_L:
15230 case OPC_DEXTRV_S_H:
15231 case OPC_DEXTRV_W:
15232 case OPC_DEXTRV_R_W:
15233 case OPC_DEXTRV_RS_W:
15234 gen_mipsdsp_accinsn(ctx, op1, op2, rt, rs, rd, 1);
15235 break;
15236 case OPC_DMTHLIP:
15237 case OPC_DSHILO:
15238 case OPC_DSHILOV:
15239 gen_mipsdsp_accinsn(ctx, op1, op2, rd, rs, rt, 0);
15240 break;
15241 default: /* Invalid */
15242 MIPS_INVAL("MASK EXTR.W");
15243 generate_exception(ctx, EXCP_RI);
15244 break;
15246 break;
15247 case OPC_DPAQ_W_QH_DSP:
15248 op2 = MASK_DPAQ_W_QH(ctx->opcode);
15249 switch (op2) {
15250 case OPC_DPAU_H_OBL:
15251 case OPC_DPAU_H_OBR:
15252 case OPC_DPSU_H_OBL:
15253 case OPC_DPSU_H_OBR:
15254 case OPC_DPA_W_QH:
15255 case OPC_DPAQ_S_W_QH:
15256 case OPC_DPS_W_QH:
15257 case OPC_DPSQ_S_W_QH:
15258 case OPC_MULSAQ_S_W_QH:
15259 case OPC_DPAQ_SA_L_PW:
15260 case OPC_DPSQ_SA_L_PW:
15261 case OPC_MULSAQ_S_L_PW:
15262 gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 0);
15263 break;
15264 case OPC_MAQ_S_W_QHLL:
15265 case OPC_MAQ_S_W_QHLR:
15266 case OPC_MAQ_S_W_QHRL:
15267 case OPC_MAQ_S_W_QHRR:
15268 case OPC_MAQ_SA_W_QHLL:
15269 case OPC_MAQ_SA_W_QHLR:
15270 case OPC_MAQ_SA_W_QHRL:
15271 case OPC_MAQ_SA_W_QHRR:
15272 case OPC_MAQ_S_L_PWL:
15273 case OPC_MAQ_S_L_PWR:
15274 case OPC_DMADD:
15275 case OPC_DMADDU:
15276 case OPC_DMSUB:
15277 case OPC_DMSUBU:
15278 gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 0);
15279 break;
15280 default: /* Invalid */
15281 MIPS_INVAL("MASK DPAQ.W.QH");
15282 generate_exception(ctx, EXCP_RI);
15283 break;
15285 break;
15286 case OPC_DINSV_DSP:
15287 op2 = MASK_INSV(ctx->opcode);
15288 switch (op2) {
15289 case OPC_DINSV:
15291 TCGv t0, t1;
15293 if (rt == 0) {
15294 MIPS_DEBUG("NOP");
15295 break;
15297 check_dsp(ctx);
15299 t0 = tcg_temp_new();
15300 t1 = tcg_temp_new();
15302 gen_load_gpr(t0, rt);
15303 gen_load_gpr(t1, rs);
15305 gen_helper_dinsv(cpu_gpr[rt], cpu_env, t1, t0);
15307 tcg_temp_free(t0);
15308 tcg_temp_free(t1);
15309 break;
15311 default: /* Invalid */
15312 MIPS_INVAL("MASK DINSV");
15313 generate_exception(ctx, EXCP_RI);
15314 break;
15316 break;
15317 case OPC_SHLL_OB_DSP:
15318 gen_mipsdsp_shift(ctx, op1, rd, rs, rt);
15319 break;
15320 #endif
15321 default: /* Invalid */
15322 MIPS_INVAL("special3");
15323 generate_exception(ctx, EXCP_RI);
15324 break;
15326 break;
15327 case OPC_REGIMM:
15328 op1 = MASK_REGIMM(ctx->opcode);
15329 switch (op1) {
15330 case OPC_BLTZ ... OPC_BGEZL: /* REGIMM branches */
15331 case OPC_BLTZAL ... OPC_BGEZALL:
15332 gen_compute_branch(ctx, op1, 4, rs, -1, imm << 2);
15333 break;
15334 case OPC_TGEI ... OPC_TEQI: /* REGIMM traps */
15335 case OPC_TNEI:
15336 gen_trap(ctx, op1, rs, -1, imm);
15337 break;
15338 case OPC_SYNCI:
15339 check_insn(ctx, ISA_MIPS32R2);
15340 /* Treat as NOP. */
15341 break;
15342 case OPC_BPOSGE32: /* MIPS DSP branch */
15343 #if defined(TARGET_MIPS64)
15344 case OPC_BPOSGE64:
15345 #endif
15346 check_dsp(ctx);
15347 gen_compute_branch(ctx, op1, 4, -1, -2, (int32_t)imm << 2);
15348 break;
15349 default: /* Invalid */
15350 MIPS_INVAL("regimm");
15351 generate_exception(ctx, EXCP_RI);
15352 break;
15354 break;
15355 case OPC_CP0:
15356 check_cp0_enabled(ctx);
15357 op1 = MASK_CP0(ctx->opcode);
15358 switch (op1) {
15359 case OPC_MFC0:
15360 case OPC_MTC0:
15361 case OPC_MFTR:
15362 case OPC_MTTR:
15363 #if defined(TARGET_MIPS64)
15364 case OPC_DMFC0:
15365 case OPC_DMTC0:
15366 #endif
15367 #ifndef CONFIG_USER_ONLY
15368 gen_cp0(env, ctx, op1, rt, rd);
15369 #endif /* !CONFIG_USER_ONLY */
15370 break;
15371 case OPC_C0_FIRST ... OPC_C0_LAST:
15372 #ifndef CONFIG_USER_ONLY
15373 gen_cp0(env, ctx, MASK_C0(ctx->opcode), rt, rd);
15374 #endif /* !CONFIG_USER_ONLY */
15375 break;
15376 case OPC_MFMC0:
15377 #ifndef CONFIG_USER_ONLY
15379 TCGv t0 = tcg_temp_new();
15381 op2 = MASK_MFMC0(ctx->opcode);
15382 switch (op2) {
15383 case OPC_DMT:
15384 check_insn(ctx, ASE_MT);
15385 gen_helper_dmt(t0);
15386 gen_store_gpr(t0, rt);
15387 break;
15388 case OPC_EMT:
15389 check_insn(ctx, ASE_MT);
15390 gen_helper_emt(t0);
15391 gen_store_gpr(t0, rt);
15392 break;
15393 case OPC_DVPE:
15394 check_insn(ctx, ASE_MT);
15395 gen_helper_dvpe(t0, cpu_env);
15396 gen_store_gpr(t0, rt);
15397 break;
15398 case OPC_EVPE:
15399 check_insn(ctx, ASE_MT);
15400 gen_helper_evpe(t0, cpu_env);
15401 gen_store_gpr(t0, rt);
15402 break;
15403 case OPC_DI:
15404 check_insn(ctx, ISA_MIPS32R2);
15405 save_cpu_state(ctx, 1);
15406 gen_helper_di(t0, cpu_env);
15407 gen_store_gpr(t0, rt);
15408 /* Stop translation as we may have switched the execution mode */
15409 ctx->bstate = BS_STOP;
15410 break;
15411 case OPC_EI:
15412 check_insn(ctx, ISA_MIPS32R2);
15413 save_cpu_state(ctx, 1);
15414 gen_helper_ei(t0, cpu_env);
15415 gen_store_gpr(t0, rt);
15416 /* Stop translation as we may have switched the execution mode */
15417 ctx->bstate = BS_STOP;
15418 break;
15419 default: /* Invalid */
15420 MIPS_INVAL("mfmc0");
15421 generate_exception(ctx, EXCP_RI);
15422 break;
15424 tcg_temp_free(t0);
15426 #endif /* !CONFIG_USER_ONLY */
15427 break;
15428 case OPC_RDPGPR:
15429 check_insn(ctx, ISA_MIPS32R2);
15430 gen_load_srsgpr(rt, rd);
15431 break;
15432 case OPC_WRPGPR:
15433 check_insn(ctx, ISA_MIPS32R2);
15434 gen_store_srsgpr(rt, rd);
15435 break;
15436 default:
15437 MIPS_INVAL("cp0");
15438 generate_exception(ctx, EXCP_RI);
15439 break;
15441 break;
15442 case OPC_ADDI: /* Arithmetic with immediate opcode */
15443 case OPC_ADDIU:
15444 gen_arith_imm(ctx, op, rt, rs, imm);
15445 break;
15446 case OPC_SLTI: /* Set on less than with immediate opcode */
15447 case OPC_SLTIU:
15448 gen_slt_imm(ctx, op, rt, rs, imm);
15449 break;
15450 case OPC_ANDI: /* Arithmetic with immediate opcode */
15451 case OPC_LUI:
15452 case OPC_ORI:
15453 case OPC_XORI:
15454 gen_logic_imm(ctx, op, rt, rs, imm);
15455 break;
15456 case OPC_J ... OPC_JAL: /* Jump */
15457 offset = (int32_t)(ctx->opcode & 0x3FFFFFF) << 2;
15458 gen_compute_branch(ctx, op, 4, rs, rt, offset);
15459 break;
15460 case OPC_BEQ ... OPC_BGTZ: /* Branch */
15461 case OPC_BEQL ... OPC_BGTZL:
15462 gen_compute_branch(ctx, op, 4, rs, rt, imm << 2);
15463 break;
15464 case OPC_LB ... OPC_LWR: /* Load and stores */
15465 case OPC_LL:
15466 gen_ld(ctx, op, rt, rs, imm);
15467 break;
15468 case OPC_SB ... OPC_SW:
15469 case OPC_SWR:
15470 gen_st(ctx, op, rt, rs, imm);
15471 break;
15472 case OPC_SC:
15473 gen_st_cond(ctx, op, rt, rs, imm);
15474 break;
15475 case OPC_CACHE:
15476 check_cp0_enabled(ctx);
15477 check_insn(ctx, ISA_MIPS3 | ISA_MIPS32);
15478 /* Treat as NOP. */
15479 break;
15480 case OPC_PREF:
15481 check_insn(ctx, ISA_MIPS4 | ISA_MIPS32);
15482 /* Treat as NOP. */
15483 break;
15485 /* Floating point (COP1). */
15486 case OPC_LWC1:
15487 case OPC_LDC1:
15488 case OPC_SWC1:
15489 case OPC_SDC1:
15490 gen_cop1_ldst(ctx, op, rt, rs, imm);
15491 break;
15493 case OPC_CP1:
15494 if (ctx->CP0_Config1 & (1 << CP0C1_FP)) {
15495 check_cp1_enabled(ctx);
15496 op1 = MASK_CP1(ctx->opcode);
15497 switch (op1) {
15498 case OPC_MFHC1:
15499 case OPC_MTHC1:
15500 check_insn(ctx, ISA_MIPS32R2);
15501 case OPC_MFC1:
15502 case OPC_CFC1:
15503 case OPC_MTC1:
15504 case OPC_CTC1:
15505 gen_cp1(ctx, op1, rt, rd);
15506 break;
15507 #if defined(TARGET_MIPS64)
15508 case OPC_DMFC1:
15509 case OPC_DMTC1:
15510 check_insn(ctx, ISA_MIPS3);
15511 gen_cp1(ctx, op1, rt, rd);
15512 break;
15513 #endif
15514 case OPC_BC1ANY2:
15515 case OPC_BC1ANY4:
15516 check_cop1x(ctx);
15517 check_insn(ctx, ASE_MIPS3D);
15518 /* fall through */
15519 case OPC_BC1:
15520 gen_compute_branch1(ctx, MASK_BC1(ctx->opcode),
15521 (rt >> 2) & 0x7, imm << 2);
15522 break;
15523 case OPC_S_FMT:
15524 case OPC_D_FMT:
15525 case OPC_W_FMT:
15526 case OPC_L_FMT:
15527 case OPC_PS_FMT:
15528 gen_farith(ctx, ctx->opcode & FOP(0x3f, 0x1f), rt, rd, sa,
15529 (imm >> 8) & 0x7);
15530 break;
15531 default:
15532 MIPS_INVAL("cp1");
15533 generate_exception (ctx, EXCP_RI);
15534 break;
15536 } else {
15537 generate_exception_err(ctx, EXCP_CpU, 1);
15539 break;
15541 /* COP2. */
15542 case OPC_LWC2:
15543 case OPC_LDC2:
15544 case OPC_SWC2:
15545 case OPC_SDC2:
15546 /* COP2: Not implemented. */
15547 generate_exception_err(ctx, EXCP_CpU, 2);
15548 break;
15549 case OPC_CP2:
15550 check_insn(ctx, INSN_LOONGSON2F);
15551 /* Note that these instructions use different fields. */
15552 gen_loongson_multimedia(ctx, sa, rd, rt);
15553 break;
15555 case OPC_CP3:
15556 if (ctx->CP0_Config1 & (1 << CP0C1_FP)) {
15557 check_cp1_enabled(ctx);
15558 op1 = MASK_CP3(ctx->opcode);
15559 switch (op1) {
15560 case OPC_LWXC1:
15561 case OPC_LDXC1:
15562 case OPC_LUXC1:
15563 case OPC_SWXC1:
15564 case OPC_SDXC1:
15565 case OPC_SUXC1:
15566 gen_flt3_ldst(ctx, op1, sa, rd, rs, rt);
15567 break;
15568 case OPC_PREFX:
15569 /* Treat as NOP. */
15570 break;
15571 case OPC_ALNV_PS:
15572 case OPC_MADD_S:
15573 case OPC_MADD_D:
15574 case OPC_MADD_PS:
15575 case OPC_MSUB_S:
15576 case OPC_MSUB_D:
15577 case OPC_MSUB_PS:
15578 case OPC_NMADD_S:
15579 case OPC_NMADD_D:
15580 case OPC_NMADD_PS:
15581 case OPC_NMSUB_S:
15582 case OPC_NMSUB_D:
15583 case OPC_NMSUB_PS:
15584 gen_flt3_arith(ctx, op1, sa, rs, rd, rt);
15585 break;
15586 default:
15587 MIPS_INVAL("cp3");
15588 generate_exception (ctx, EXCP_RI);
15589 break;
15591 } else {
15592 generate_exception_err(ctx, EXCP_CpU, 1);
15594 break;
15596 #if defined(TARGET_MIPS64)
15597 /* MIPS64 opcodes */
15598 case OPC_LWU:
15599 case OPC_LDL ... OPC_LDR:
15600 case OPC_LLD:
15601 case OPC_LD:
15602 check_insn(ctx, ISA_MIPS3);
15603 check_mips_64(ctx);
15604 gen_ld(ctx, op, rt, rs, imm);
15605 break;
15606 case OPC_SDL ... OPC_SDR:
15607 case OPC_SD:
15608 check_insn(ctx, ISA_MIPS3);
15609 check_mips_64(ctx);
15610 gen_st(ctx, op, rt, rs, imm);
15611 break;
15612 case OPC_SCD:
15613 check_insn(ctx, ISA_MIPS3);
15614 check_mips_64(ctx);
15615 gen_st_cond(ctx, op, rt, rs, imm);
15616 break;
15617 case OPC_DADDI:
15618 case OPC_DADDIU:
15619 check_insn(ctx, ISA_MIPS3);
15620 check_mips_64(ctx);
15621 gen_arith_imm(ctx, op, rt, rs, imm);
15622 break;
15623 #endif
15624 case OPC_JALX:
15625 check_insn(ctx, ASE_MIPS16 | ASE_MICROMIPS);
15626 offset = (int32_t)(ctx->opcode & 0x3FFFFFF) << 2;
15627 gen_compute_branch(ctx, op, 4, rs, rt, offset);
15628 break;
15629 case OPC_MDMX:
15630 check_insn(ctx, ASE_MDMX);
15631 /* MDMX: Not implemented. */
15632 default: /* Invalid */
15633 MIPS_INVAL("major opcode");
15634 generate_exception(ctx, EXCP_RI);
15635 break;
15639 static inline void
15640 gen_intermediate_code_internal(MIPSCPU *cpu, TranslationBlock *tb,
15641 bool search_pc)
15643 CPUState *cs = CPU(cpu);
15644 CPUMIPSState *env = &cpu->env;
15645 DisasContext ctx;
15646 target_ulong pc_start;
15647 uint16_t *gen_opc_end;
15648 CPUBreakpoint *bp;
15649 int j, lj = -1;
15650 int num_insns;
15651 int max_insns;
15652 int insn_bytes;
15653 int is_delay;
15655 if (search_pc)
15656 qemu_log("search pc %d\n", search_pc);
15658 pc_start = tb->pc;
15659 gen_opc_end = tcg_ctx.gen_opc_buf + OPC_MAX_SIZE;
15660 ctx.pc = pc_start;
15661 ctx.saved_pc = -1;
15662 ctx.singlestep_enabled = cs->singlestep_enabled;
15663 ctx.insn_flags = env->insn_flags;
15664 ctx.CP0_Config1 = env->CP0_Config1;
15665 ctx.tb = tb;
15666 ctx.bstate = BS_NONE;
15667 /* Restore delay slot state from the tb context. */
15668 ctx.hflags = (uint32_t)tb->flags; /* FIXME: maybe use 64 bits here? */
15669 ctx.ulri = env->CP0_Config3 & (1 << CP0C3_ULRI);
15670 restore_cpu_state(env, &ctx);
15671 #ifdef CONFIG_USER_ONLY
15672 ctx.mem_idx = MIPS_HFLAG_UM;
15673 #else
15674 ctx.mem_idx = ctx.hflags & MIPS_HFLAG_KSU;
15675 #endif
15676 num_insns = 0;
15677 max_insns = tb->cflags & CF_COUNT_MASK;
15678 if (max_insns == 0)
15679 max_insns = CF_COUNT_MASK;
15680 LOG_DISAS("\ntb %p idx %d hflags %04x\n", tb, ctx.mem_idx, ctx.hflags);
15681 gen_tb_start();
15682 while (ctx.bstate == BS_NONE) {
15683 if (unlikely(!QTAILQ_EMPTY(&cs->breakpoints))) {
15684 QTAILQ_FOREACH(bp, &cs->breakpoints, entry) {
15685 if (bp->pc == ctx.pc) {
15686 save_cpu_state(&ctx, 1);
15687 ctx.bstate = BS_BRANCH;
15688 gen_helper_0e0i(raise_exception, EXCP_DEBUG);
15689 /* Include the breakpoint location or the tb won't
15690 * be flushed when it must be. */
15691 ctx.pc += 4;
15692 goto done_generating;
15697 if (search_pc) {
15698 j = tcg_ctx.gen_opc_ptr - tcg_ctx.gen_opc_buf;
15699 if (lj < j) {
15700 lj++;
15701 while (lj < j)
15702 tcg_ctx.gen_opc_instr_start[lj++] = 0;
15704 tcg_ctx.gen_opc_pc[lj] = ctx.pc;
15705 gen_opc_hflags[lj] = ctx.hflags & MIPS_HFLAG_BMASK;
15706 gen_opc_btarget[lj] = ctx.btarget;
15707 tcg_ctx.gen_opc_instr_start[lj] = 1;
15708 tcg_ctx.gen_opc_icount[lj] = num_insns;
15710 if (num_insns + 1 == max_insns && (tb->cflags & CF_LAST_IO))
15711 gen_io_start();
15713 is_delay = ctx.hflags & MIPS_HFLAG_BMASK;
15714 if (!(ctx.hflags & MIPS_HFLAG_M16)) {
15715 ctx.opcode = cpu_ldl_code(env, ctx.pc);
15716 insn_bytes = 4;
15717 decode_opc(env, &ctx);
15718 } else if (ctx.insn_flags & ASE_MICROMIPS) {
15719 ctx.opcode = cpu_lduw_code(env, ctx.pc);
15720 insn_bytes = decode_micromips_opc(env, &ctx);
15721 } else if (ctx.insn_flags & ASE_MIPS16) {
15722 ctx.opcode = cpu_lduw_code(env, ctx.pc);
15723 insn_bytes = decode_mips16_opc(env, &ctx);
15724 } else {
15725 generate_exception(&ctx, EXCP_RI);
15726 ctx.bstate = BS_STOP;
15727 break;
15729 if (is_delay) {
15730 handle_delay_slot(&ctx, insn_bytes);
15732 ctx.pc += insn_bytes;
15734 num_insns++;
15736 /* Execute a branch and its delay slot as a single instruction.
15737 This is what GDB expects and is consistent with what the
15738 hardware does (e.g. if a delay slot instruction faults, the
15739 reported PC is the PC of the branch). */
15740 if (cs->singlestep_enabled && (ctx.hflags & MIPS_HFLAG_BMASK) == 0) {
15741 break;
15744 if ((ctx.pc & (TARGET_PAGE_SIZE - 1)) == 0)
15745 break;
15747 if (tcg_ctx.gen_opc_ptr >= gen_opc_end) {
15748 break;
15751 if (num_insns >= max_insns)
15752 break;
15754 if (singlestep)
15755 break;
15757 if (tb->cflags & CF_LAST_IO) {
15758 gen_io_end();
15760 if (cs->singlestep_enabled && ctx.bstate != BS_BRANCH) {
15761 save_cpu_state(&ctx, ctx.bstate == BS_NONE);
15762 gen_helper_0e0i(raise_exception, EXCP_DEBUG);
15763 } else {
15764 switch (ctx.bstate) {
15765 case BS_STOP:
15766 gen_goto_tb(&ctx, 0, ctx.pc);
15767 break;
15768 case BS_NONE:
15769 save_cpu_state(&ctx, 0);
15770 gen_goto_tb(&ctx, 0, ctx.pc);
15771 break;
15772 case BS_EXCP:
15773 tcg_gen_exit_tb(0);
15774 break;
15775 case BS_BRANCH:
15776 default:
15777 break;
15780 done_generating:
15781 gen_tb_end(tb, num_insns);
15782 *tcg_ctx.gen_opc_ptr = INDEX_op_end;
15783 if (search_pc) {
15784 j = tcg_ctx.gen_opc_ptr - tcg_ctx.gen_opc_buf;
15785 lj++;
15786 while (lj <= j)
15787 tcg_ctx.gen_opc_instr_start[lj++] = 0;
15788 } else {
15789 tb->size = ctx.pc - pc_start;
15790 tb->icount = num_insns;
15792 #ifdef DEBUG_DISAS
15793 LOG_DISAS("\n");
15794 if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM)) {
15795 qemu_log("IN: %s\n", lookup_symbol(pc_start));
15796 log_target_disas(env, pc_start, ctx.pc - pc_start, 0);
15797 qemu_log("\n");
15799 #endif
15802 void gen_intermediate_code (CPUMIPSState *env, struct TranslationBlock *tb)
15804 gen_intermediate_code_internal(mips_env_get_cpu(env), tb, false);
15807 void gen_intermediate_code_pc (CPUMIPSState *env, struct TranslationBlock *tb)
15809 gen_intermediate_code_internal(mips_env_get_cpu(env), tb, true);
15812 static void fpu_dump_state(CPUMIPSState *env, FILE *f, fprintf_function fpu_fprintf,
15813 int flags)
15815 int i;
15816 int is_fpu64 = !!(env->hflags & MIPS_HFLAG_F64);
15818 #define printfpr(fp) \
15819 do { \
15820 if (is_fpu64) \
15821 fpu_fprintf(f, "w:%08x d:%016" PRIx64 \
15822 " fd:%13g fs:%13g psu: %13g\n", \
15823 (fp)->w[FP_ENDIAN_IDX], (fp)->d, \
15824 (double)(fp)->fd, \
15825 (double)(fp)->fs[FP_ENDIAN_IDX], \
15826 (double)(fp)->fs[!FP_ENDIAN_IDX]); \
15827 else { \
15828 fpr_t tmp; \
15829 tmp.w[FP_ENDIAN_IDX] = (fp)->w[FP_ENDIAN_IDX]; \
15830 tmp.w[!FP_ENDIAN_IDX] = ((fp) + 1)->w[FP_ENDIAN_IDX]; \
15831 fpu_fprintf(f, "w:%08x d:%016" PRIx64 \
15832 " fd:%13g fs:%13g psu:%13g\n", \
15833 tmp.w[FP_ENDIAN_IDX], tmp.d, \
15834 (double)tmp.fd, \
15835 (double)tmp.fs[FP_ENDIAN_IDX], \
15836 (double)tmp.fs[!FP_ENDIAN_IDX]); \
15838 } while(0)
15841 fpu_fprintf(f, "CP1 FCR0 0x%08x FCR31 0x%08x SR.FR %d fp_status 0x%02x\n",
15842 env->active_fpu.fcr0, env->active_fpu.fcr31, is_fpu64,
15843 get_float_exception_flags(&env->active_fpu.fp_status));
15844 for (i = 0; i < 32; (is_fpu64) ? i++ : (i += 2)) {
15845 fpu_fprintf(f, "%3s: ", fregnames[i]);
15846 printfpr(&env->active_fpu.fpr[i]);
15849 #undef printfpr
15852 #if defined(TARGET_MIPS64) && defined(MIPS_DEBUG_SIGN_EXTENSIONS)
15853 /* Debug help: The architecture requires 32bit code to maintain proper
15854 sign-extended values on 64bit machines. */
15856 #define SIGN_EXT_P(val) ((((val) & ~0x7fffffff) == 0) || (((val) & ~0x7fffffff) == ~0x7fffffff))
15858 static void
15859 cpu_mips_check_sign_extensions (CPUMIPSState *env, FILE *f,
15860 fprintf_function cpu_fprintf,
15861 int flags)
15863 int i;
15865 if (!SIGN_EXT_P(env->active_tc.PC))
15866 cpu_fprintf(f, "BROKEN: pc=0x" TARGET_FMT_lx "\n", env->active_tc.PC);
15867 if (!SIGN_EXT_P(env->active_tc.HI[0]))
15868 cpu_fprintf(f, "BROKEN: HI=0x" TARGET_FMT_lx "\n", env->active_tc.HI[0]);
15869 if (!SIGN_EXT_P(env->active_tc.LO[0]))
15870 cpu_fprintf(f, "BROKEN: LO=0x" TARGET_FMT_lx "\n", env->active_tc.LO[0]);
15871 if (!SIGN_EXT_P(env->btarget))
15872 cpu_fprintf(f, "BROKEN: btarget=0x" TARGET_FMT_lx "\n", env->btarget);
15874 for (i = 0; i < 32; i++) {
15875 if (!SIGN_EXT_P(env->active_tc.gpr[i]))
15876 cpu_fprintf(f, "BROKEN: %s=0x" TARGET_FMT_lx "\n", regnames[i], env->active_tc.gpr[i]);
15879 if (!SIGN_EXT_P(env->CP0_EPC))
15880 cpu_fprintf(f, "BROKEN: EPC=0x" TARGET_FMT_lx "\n", env->CP0_EPC);
15881 if (!SIGN_EXT_P(env->lladdr))
15882 cpu_fprintf(f, "BROKEN: LLAddr=0x" TARGET_FMT_lx "\n", env->lladdr);
15884 #endif
15886 void mips_cpu_dump_state(CPUState *cs, FILE *f, fprintf_function cpu_fprintf,
15887 int flags)
15889 MIPSCPU *cpu = MIPS_CPU(cs);
15890 CPUMIPSState *env = &cpu->env;
15891 int i;
15893 cpu_fprintf(f, "pc=0x" TARGET_FMT_lx " HI=0x" TARGET_FMT_lx
15894 " LO=0x" TARGET_FMT_lx " ds %04x "
15895 TARGET_FMT_lx " " TARGET_FMT_ld "\n",
15896 env->active_tc.PC, env->active_tc.HI[0], env->active_tc.LO[0],
15897 env->hflags, env->btarget, env->bcond);
15898 for (i = 0; i < 32; i++) {
15899 if ((i & 3) == 0)
15900 cpu_fprintf(f, "GPR%02d:", i);
15901 cpu_fprintf(f, " %s " TARGET_FMT_lx, regnames[i], env->active_tc.gpr[i]);
15902 if ((i & 3) == 3)
15903 cpu_fprintf(f, "\n");
15906 cpu_fprintf(f, "CP0 Status 0x%08x Cause 0x%08x EPC 0x" TARGET_FMT_lx "\n",
15907 env->CP0_Status, env->CP0_Cause, env->CP0_EPC);
15908 cpu_fprintf(f, " Config0 0x%08x Config1 0x%08x LLAddr 0x" TARGET_FMT_lx "\n",
15909 env->CP0_Config0, env->CP0_Config1, env->lladdr);
15910 if (env->hflags & MIPS_HFLAG_FPU)
15911 fpu_dump_state(env, f, cpu_fprintf, flags);
15912 #if defined(TARGET_MIPS64) && defined(MIPS_DEBUG_SIGN_EXTENSIONS)
15913 cpu_mips_check_sign_extensions(env, f, cpu_fprintf, flags);
15914 #endif
15917 void mips_tcg_init(void)
15919 int i;
15920 static int inited;
15922 /* Initialize various static tables. */
15923 if (inited)
15924 return;
15926 cpu_env = tcg_global_reg_new_ptr(TCG_AREG0, "env");
15927 TCGV_UNUSED(cpu_gpr[0]);
15928 for (i = 1; i < 32; i++)
15929 cpu_gpr[i] = tcg_global_mem_new(TCG_AREG0,
15930 offsetof(CPUMIPSState, active_tc.gpr[i]),
15931 regnames[i]);
15933 for (i = 0; i < 32; i++) {
15934 int off = offsetof(CPUMIPSState, active_fpu.fpr[i]);
15935 fpu_f64[i] = tcg_global_mem_new_i64(TCG_AREG0, off, fregnames[i]);
15938 cpu_PC = tcg_global_mem_new(TCG_AREG0,
15939 offsetof(CPUMIPSState, active_tc.PC), "PC");
15940 for (i = 0; i < MIPS_DSP_ACC; i++) {
15941 cpu_HI[i] = tcg_global_mem_new(TCG_AREG0,
15942 offsetof(CPUMIPSState, active_tc.HI[i]),
15943 regnames_HI[i]);
15944 cpu_LO[i] = tcg_global_mem_new(TCG_AREG0,
15945 offsetof(CPUMIPSState, active_tc.LO[i]),
15946 regnames_LO[i]);
15947 cpu_ACX[i] = tcg_global_mem_new(TCG_AREG0,
15948 offsetof(CPUMIPSState, active_tc.ACX[i]),
15949 regnames_ACX[i]);
15951 cpu_dspctrl = tcg_global_mem_new(TCG_AREG0,
15952 offsetof(CPUMIPSState, active_tc.DSPControl),
15953 "DSPControl");
15954 bcond = tcg_global_mem_new(TCG_AREG0,
15955 offsetof(CPUMIPSState, bcond), "bcond");
15956 btarget = tcg_global_mem_new(TCG_AREG0,
15957 offsetof(CPUMIPSState, btarget), "btarget");
15958 hflags = tcg_global_mem_new_i32(TCG_AREG0,
15959 offsetof(CPUMIPSState, hflags), "hflags");
15961 fpu_fcr0 = tcg_global_mem_new_i32(TCG_AREG0,
15962 offsetof(CPUMIPSState, active_fpu.fcr0),
15963 "fcr0");
15964 fpu_fcr31 = tcg_global_mem_new_i32(TCG_AREG0,
15965 offsetof(CPUMIPSState, active_fpu.fcr31),
15966 "fcr31");
15968 inited = 1;
15971 #include "translate_init.c"
15973 MIPSCPU *cpu_mips_init(const char *cpu_model)
15975 MIPSCPU *cpu;
15976 CPUMIPSState *env;
15977 const mips_def_t *def;
15979 def = cpu_mips_find_by_name(cpu_model);
15980 if (!def)
15981 return NULL;
15982 cpu = MIPS_CPU(object_new(TYPE_MIPS_CPU));
15983 env = &cpu->env;
15984 env->cpu_model = def;
15986 #ifndef CONFIG_USER_ONLY
15987 mmu_init(env, def);
15988 #endif
15989 fpu_init(env, def);
15990 mvp_init(env, def);
15992 object_property_set_bool(OBJECT(cpu), true, "realized", NULL);
15994 return cpu;
15997 void cpu_state_reset(CPUMIPSState *env)
15999 MIPSCPU *cpu = mips_env_get_cpu(env);
16000 CPUState *cs = CPU(cpu);
16002 /* Reset registers to their default values */
16003 env->CP0_PRid = env->cpu_model->CP0_PRid;
16004 env->CP0_Config0 = env->cpu_model->CP0_Config0;
16005 #ifdef TARGET_WORDS_BIGENDIAN
16006 env->CP0_Config0 |= (1 << CP0C0_BE);
16007 #endif
16008 env->CP0_Config1 = env->cpu_model->CP0_Config1;
16009 env->CP0_Config2 = env->cpu_model->CP0_Config2;
16010 env->CP0_Config3 = env->cpu_model->CP0_Config3;
16011 env->CP0_Config4 = env->cpu_model->CP0_Config4;
16012 env->CP0_Config4_rw_bitmask = env->cpu_model->CP0_Config4_rw_bitmask;
16013 env->CP0_Config5 = env->cpu_model->CP0_Config5;
16014 env->CP0_Config5_rw_bitmask = env->cpu_model->CP0_Config5_rw_bitmask;
16015 env->CP0_Config6 = env->cpu_model->CP0_Config6;
16016 env->CP0_Config7 = env->cpu_model->CP0_Config7;
16017 env->CP0_LLAddr_rw_bitmask = env->cpu_model->CP0_LLAddr_rw_bitmask
16018 << env->cpu_model->CP0_LLAddr_shift;
16019 env->CP0_LLAddr_shift = env->cpu_model->CP0_LLAddr_shift;
16020 env->SYNCI_Step = env->cpu_model->SYNCI_Step;
16021 env->CCRes = env->cpu_model->CCRes;
16022 env->CP0_Status_rw_bitmask = env->cpu_model->CP0_Status_rw_bitmask;
16023 env->CP0_TCStatus_rw_bitmask = env->cpu_model->CP0_TCStatus_rw_bitmask;
16024 env->CP0_SRSCtl = env->cpu_model->CP0_SRSCtl;
16025 env->current_tc = 0;
16026 env->SEGBITS = env->cpu_model->SEGBITS;
16027 env->SEGMask = (target_ulong)((1ULL << env->cpu_model->SEGBITS) - 1);
16028 #if defined(TARGET_MIPS64)
16029 if (env->cpu_model->insn_flags & ISA_MIPS3) {
16030 env->SEGMask |= 3ULL << 62;
16032 #endif
16033 env->PABITS = env->cpu_model->PABITS;
16034 env->PAMask = (target_ulong)((1ULL << env->cpu_model->PABITS) - 1);
16035 env->CP0_SRSConf0_rw_bitmask = env->cpu_model->CP0_SRSConf0_rw_bitmask;
16036 env->CP0_SRSConf0 = env->cpu_model->CP0_SRSConf0;
16037 env->CP0_SRSConf1_rw_bitmask = env->cpu_model->CP0_SRSConf1_rw_bitmask;
16038 env->CP0_SRSConf1 = env->cpu_model->CP0_SRSConf1;
16039 env->CP0_SRSConf2_rw_bitmask = env->cpu_model->CP0_SRSConf2_rw_bitmask;
16040 env->CP0_SRSConf2 = env->cpu_model->CP0_SRSConf2;
16041 env->CP0_SRSConf3_rw_bitmask = env->cpu_model->CP0_SRSConf3_rw_bitmask;
16042 env->CP0_SRSConf3 = env->cpu_model->CP0_SRSConf3;
16043 env->CP0_SRSConf4_rw_bitmask = env->cpu_model->CP0_SRSConf4_rw_bitmask;
16044 env->CP0_SRSConf4 = env->cpu_model->CP0_SRSConf4;
16045 env->active_fpu.fcr0 = env->cpu_model->CP1_fcr0;
16046 env->insn_flags = env->cpu_model->insn_flags;
16048 #if defined(CONFIG_USER_ONLY)
16049 env->CP0_Status = (MIPS_HFLAG_UM << CP0St_KSU);
16050 # ifdef TARGET_MIPS64
16051 /* Enable 64-bit register mode. */
16052 env->CP0_Status |= (1 << CP0St_PX);
16053 # endif
16054 # ifdef TARGET_ABI_MIPSN64
16055 /* Enable 64-bit address mode. */
16056 env->CP0_Status |= (1 << CP0St_UX);
16057 # endif
16058 /* Enable access to the CPUNum, SYNCI_Step, CC, and CCRes RDHWR
16059 hardware registers. */
16060 env->CP0_HWREna |= 0x0000000F;
16061 if (env->CP0_Config1 & (1 << CP0C1_FP)) {
16062 env->CP0_Status |= (1 << CP0St_CU1);
16064 if (env->CP0_Config3 & (1 << CP0C3_DSPP)) {
16065 env->CP0_Status |= (1 << CP0St_MX);
16067 # if defined(TARGET_MIPS64)
16068 /* For MIPS64, init FR bit to 1 if FPU unit is there and bit is writable. */
16069 if ((env->CP0_Config1 & (1 << CP0C1_FP)) &&
16070 (env->CP0_Status_rw_bitmask & (1 << CP0St_FR))) {
16071 env->CP0_Status |= (1 << CP0St_FR);
16073 # endif
16074 #else
16075 if (env->hflags & MIPS_HFLAG_BMASK) {
16076 /* If the exception was raised from a delay slot,
16077 come back to the jump. */
16078 env->CP0_ErrorEPC = env->active_tc.PC - 4;
16079 } else {
16080 env->CP0_ErrorEPC = env->active_tc.PC;
16082 env->active_tc.PC = (int32_t)0xBFC00000;
16083 env->CP0_Random = env->tlb->nb_tlb - 1;
16084 env->tlb->tlb_in_use = env->tlb->nb_tlb;
16085 env->CP0_Wired = 0;
16086 env->CP0_EBase = (cs->cpu_index & 0x3FF);
16087 if (kvm_enabled()) {
16088 env->CP0_EBase |= 0x40000000;
16089 } else {
16090 env->CP0_EBase |= 0x80000000;
16092 env->CP0_Status = (1 << CP0St_BEV) | (1 << CP0St_ERL);
16093 /* vectored interrupts not implemented, timer on int 7,
16094 no performance counters. */
16095 env->CP0_IntCtl = 0xe0000000;
16097 int i;
16099 for (i = 0; i < 7; i++) {
16100 env->CP0_WatchLo[i] = 0;
16101 env->CP0_WatchHi[i] = 0x80000000;
16103 env->CP0_WatchLo[7] = 0;
16104 env->CP0_WatchHi[7] = 0;
16106 /* Count register increments in debug mode, EJTAG version 1 */
16107 env->CP0_Debug = (1 << CP0DB_CNT) | (0x1 << CP0DB_VER);
16109 cpu_mips_store_count(env, 1);
16111 if (env->CP0_Config3 & (1 << CP0C3_MT)) {
16112 int i;
16114 /* Only TC0 on VPE 0 starts as active. */
16115 for (i = 0; i < ARRAY_SIZE(env->tcs); i++) {
16116 env->tcs[i].CP0_TCBind = cs->cpu_index << CP0TCBd_CurVPE;
16117 env->tcs[i].CP0_TCHalt = 1;
16119 env->active_tc.CP0_TCHalt = 1;
16120 cs->halted = 1;
16122 if (cs->cpu_index == 0) {
16123 /* VPE0 starts up enabled. */
16124 env->mvp->CP0_MVPControl |= (1 << CP0MVPCo_EVP);
16125 env->CP0_VPEConf0 |= (1 << CP0VPEC0_MVP) | (1 << CP0VPEC0_VPA);
16127 /* TC0 starts up unhalted. */
16128 cs->halted = 0;
16129 env->active_tc.CP0_TCHalt = 0;
16130 env->tcs[0].CP0_TCHalt = 0;
16131 /* With thread 0 active. */
16132 env->active_tc.CP0_TCStatus = (1 << CP0TCSt_A);
16133 env->tcs[0].CP0_TCStatus = (1 << CP0TCSt_A);
16136 #endif
16137 compute_hflags(env);
16138 cs->exception_index = EXCP_NONE;
16141 void restore_state_to_opc(CPUMIPSState *env, TranslationBlock *tb, int pc_pos)
16143 env->active_tc.PC = tcg_ctx.gen_opc_pc[pc_pos];
16144 env->hflags &= ~MIPS_HFLAG_BMASK;
16145 env->hflags |= gen_opc_hflags[pc_pos];
16146 switch (env->hflags & MIPS_HFLAG_BMASK_BASE) {
16147 case MIPS_HFLAG_BR:
16148 break;
16149 case MIPS_HFLAG_BC:
16150 case MIPS_HFLAG_BL:
16151 case MIPS_HFLAG_B:
16152 env->btarget = gen_opc_btarget[pc_pos];
16153 break;