qcow2: use start_of_cluster() and offset_into_cluster() everywhere
[qemu.git] / target-mips / translate.c
blob67f326b20511db67021184528304132fdf840369
1 /*
2 * MIPS32 emulation for qemu: main translation routines.
4 * Copyright (c) 2004-2005 Jocelyn Mayer
5 * Copyright (c) 2006 Marius Groeger (FPU operations)
6 * Copyright (c) 2006 Thiemo Seufer (MIPS32R2 support)
7 * Copyright (c) 2009 CodeSourcery (MIPS16 and microMIPS support)
8 * Copyright (c) 2012 Jia Liu & Dongxue Zhang (MIPS ASE DSP support)
10 * This library is free software; you can redistribute it and/or
11 * modify it under the terms of the GNU Lesser General Public
12 * License as published by the Free Software Foundation; either
13 * version 2 of the License, or (at your option) any later version.
15 * This library is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
18 * Lesser General Public License for more details.
20 * You should have received a copy of the GNU Lesser General Public
21 * License along with this library; if not, see <http://www.gnu.org/licenses/>.
24 #include "cpu.h"
25 #include "disas/disas.h"
26 #include "tcg-op.h"
28 #include "helper.h"
29 #define GEN_HELPER 1
30 #include "helper.h"
32 #define MIPS_DEBUG_DISAS 0
33 //#define MIPS_DEBUG_SIGN_EXTENSIONS
35 /* MIPS major opcodes */
36 #define MASK_OP_MAJOR(op) (op & (0x3F << 26))
38 enum {
39 /* indirect opcode tables */
40 OPC_SPECIAL = (0x00 << 26),
41 OPC_REGIMM = (0x01 << 26),
42 OPC_CP0 = (0x10 << 26),
43 OPC_CP1 = (0x11 << 26),
44 OPC_CP2 = (0x12 << 26),
45 OPC_CP3 = (0x13 << 26),
46 OPC_SPECIAL2 = (0x1C << 26),
47 OPC_SPECIAL3 = (0x1F << 26),
48 /* arithmetic with immediate */
49 OPC_ADDI = (0x08 << 26),
50 OPC_ADDIU = (0x09 << 26),
51 OPC_SLTI = (0x0A << 26),
52 OPC_SLTIU = (0x0B << 26),
53 /* logic with immediate */
54 OPC_ANDI = (0x0C << 26),
55 OPC_ORI = (0x0D << 26),
56 OPC_XORI = (0x0E << 26),
57 OPC_LUI = (0x0F << 26),
58 /* arithmetic with immediate */
59 OPC_DADDI = (0x18 << 26),
60 OPC_DADDIU = (0x19 << 26),
61 /* Jump and branches */
62 OPC_J = (0x02 << 26),
63 OPC_JAL = (0x03 << 26),
64 OPC_JALS = OPC_JAL | 0x5,
65 OPC_BEQ = (0x04 << 26), /* Unconditional if rs = rt = 0 (B) */
66 OPC_BEQL = (0x14 << 26),
67 OPC_BNE = (0x05 << 26),
68 OPC_BNEL = (0x15 << 26),
69 OPC_BLEZ = (0x06 << 26),
70 OPC_BLEZL = (0x16 << 26),
71 OPC_BGTZ = (0x07 << 26),
72 OPC_BGTZL = (0x17 << 26),
73 OPC_JALX = (0x1D << 26), /* MIPS 16 only */
74 OPC_JALXS = OPC_JALX | 0x5,
75 /* Load and stores */
76 OPC_LDL = (0x1A << 26),
77 OPC_LDR = (0x1B << 26),
78 OPC_LB = (0x20 << 26),
79 OPC_LH = (0x21 << 26),
80 OPC_LWL = (0x22 << 26),
81 OPC_LW = (0x23 << 26),
82 OPC_LWPC = OPC_LW | 0x5,
83 OPC_LBU = (0x24 << 26),
84 OPC_LHU = (0x25 << 26),
85 OPC_LWR = (0x26 << 26),
86 OPC_LWU = (0x27 << 26),
87 OPC_SB = (0x28 << 26),
88 OPC_SH = (0x29 << 26),
89 OPC_SWL = (0x2A << 26),
90 OPC_SW = (0x2B << 26),
91 OPC_SDL = (0x2C << 26),
92 OPC_SDR = (0x2D << 26),
93 OPC_SWR = (0x2E << 26),
94 OPC_LL = (0x30 << 26),
95 OPC_LLD = (0x34 << 26),
96 OPC_LD = (0x37 << 26),
97 OPC_LDPC = OPC_LD | 0x5,
98 OPC_SC = (0x38 << 26),
99 OPC_SCD = (0x3C << 26),
100 OPC_SD = (0x3F << 26),
101 /* Floating point load/store */
102 OPC_LWC1 = (0x31 << 26),
103 OPC_LWC2 = (0x32 << 26),
104 OPC_LDC1 = (0x35 << 26),
105 OPC_LDC2 = (0x36 << 26),
106 OPC_SWC1 = (0x39 << 26),
107 OPC_SWC2 = (0x3A << 26),
108 OPC_SDC1 = (0x3D << 26),
109 OPC_SDC2 = (0x3E << 26),
110 /* MDMX ASE specific */
111 OPC_MDMX = (0x1E << 26),
112 /* Cache and prefetch */
113 OPC_CACHE = (0x2F << 26),
114 OPC_PREF = (0x33 << 26),
115 /* Reserved major opcode */
116 OPC_MAJOR3B_RESERVED = (0x3B << 26),
119 /* MIPS special opcodes */
120 #define MASK_SPECIAL(op) MASK_OP_MAJOR(op) | (op & 0x3F)
122 enum {
123 /* Shifts */
124 OPC_SLL = 0x00 | OPC_SPECIAL,
125 /* NOP is SLL r0, r0, 0 */
126 /* SSNOP is SLL r0, r0, 1 */
127 /* EHB is SLL r0, r0, 3 */
128 OPC_SRL = 0x02 | OPC_SPECIAL, /* also ROTR */
129 OPC_ROTR = OPC_SRL | (1 << 21),
130 OPC_SRA = 0x03 | OPC_SPECIAL,
131 OPC_SLLV = 0x04 | OPC_SPECIAL,
132 OPC_SRLV = 0x06 | OPC_SPECIAL, /* also ROTRV */
133 OPC_ROTRV = OPC_SRLV | (1 << 6),
134 OPC_SRAV = 0x07 | OPC_SPECIAL,
135 OPC_DSLLV = 0x14 | OPC_SPECIAL,
136 OPC_DSRLV = 0x16 | OPC_SPECIAL, /* also DROTRV */
137 OPC_DROTRV = OPC_DSRLV | (1 << 6),
138 OPC_DSRAV = 0x17 | OPC_SPECIAL,
139 OPC_DSLL = 0x38 | OPC_SPECIAL,
140 OPC_DSRL = 0x3A | OPC_SPECIAL, /* also DROTR */
141 OPC_DROTR = OPC_DSRL | (1 << 21),
142 OPC_DSRA = 0x3B | OPC_SPECIAL,
143 OPC_DSLL32 = 0x3C | OPC_SPECIAL,
144 OPC_DSRL32 = 0x3E | OPC_SPECIAL, /* also DROTR32 */
145 OPC_DROTR32 = OPC_DSRL32 | (1 << 21),
146 OPC_DSRA32 = 0x3F | OPC_SPECIAL,
147 /* Multiplication / division */
148 OPC_MULT = 0x18 | OPC_SPECIAL,
149 OPC_MULTU = 0x19 | OPC_SPECIAL,
150 OPC_DIV = 0x1A | OPC_SPECIAL,
151 OPC_DIVU = 0x1B | OPC_SPECIAL,
152 OPC_DMULT = 0x1C | OPC_SPECIAL,
153 OPC_DMULTU = 0x1D | OPC_SPECIAL,
154 OPC_DDIV = 0x1E | OPC_SPECIAL,
155 OPC_DDIVU = 0x1F | OPC_SPECIAL,
156 /* 2 registers arithmetic / logic */
157 OPC_ADD = 0x20 | OPC_SPECIAL,
158 OPC_ADDU = 0x21 | OPC_SPECIAL,
159 OPC_SUB = 0x22 | OPC_SPECIAL,
160 OPC_SUBU = 0x23 | OPC_SPECIAL,
161 OPC_AND = 0x24 | OPC_SPECIAL,
162 OPC_OR = 0x25 | OPC_SPECIAL,
163 OPC_XOR = 0x26 | OPC_SPECIAL,
164 OPC_NOR = 0x27 | OPC_SPECIAL,
165 OPC_SLT = 0x2A | OPC_SPECIAL,
166 OPC_SLTU = 0x2B | OPC_SPECIAL,
167 OPC_DADD = 0x2C | OPC_SPECIAL,
168 OPC_DADDU = 0x2D | OPC_SPECIAL,
169 OPC_DSUB = 0x2E | OPC_SPECIAL,
170 OPC_DSUBU = 0x2F | OPC_SPECIAL,
171 /* Jumps */
172 OPC_JR = 0x08 | OPC_SPECIAL, /* Also JR.HB */
173 OPC_JALR = 0x09 | OPC_SPECIAL, /* Also JALR.HB */
174 OPC_JALRC = OPC_JALR | (0x5 << 6),
175 OPC_JALRS = 0x10 | OPC_SPECIAL | (0x5 << 6),
176 /* Traps */
177 OPC_TGE = 0x30 | OPC_SPECIAL,
178 OPC_TGEU = 0x31 | OPC_SPECIAL,
179 OPC_TLT = 0x32 | OPC_SPECIAL,
180 OPC_TLTU = 0x33 | OPC_SPECIAL,
181 OPC_TEQ = 0x34 | OPC_SPECIAL,
182 OPC_TNE = 0x36 | OPC_SPECIAL,
183 /* HI / LO registers load & stores */
184 OPC_MFHI = 0x10 | OPC_SPECIAL,
185 OPC_MTHI = 0x11 | OPC_SPECIAL,
186 OPC_MFLO = 0x12 | OPC_SPECIAL,
187 OPC_MTLO = 0x13 | OPC_SPECIAL,
188 /* Conditional moves */
189 OPC_MOVZ = 0x0A | OPC_SPECIAL,
190 OPC_MOVN = 0x0B | OPC_SPECIAL,
192 OPC_MOVCI = 0x01 | OPC_SPECIAL,
194 /* Special */
195 OPC_PMON = 0x05 | OPC_SPECIAL, /* unofficial */
196 OPC_SYSCALL = 0x0C | OPC_SPECIAL,
197 OPC_BREAK = 0x0D | OPC_SPECIAL,
198 OPC_SPIM = 0x0E | OPC_SPECIAL, /* unofficial */
199 OPC_SYNC = 0x0F | OPC_SPECIAL,
201 OPC_SPECIAL15_RESERVED = 0x15 | OPC_SPECIAL,
202 OPC_SPECIAL28_RESERVED = 0x28 | OPC_SPECIAL,
203 OPC_SPECIAL29_RESERVED = 0x29 | OPC_SPECIAL,
204 OPC_SPECIAL35_RESERVED = 0x35 | OPC_SPECIAL,
205 OPC_SPECIAL37_RESERVED = 0x37 | OPC_SPECIAL,
206 OPC_SPECIAL39_RESERVED = 0x39 | OPC_SPECIAL,
207 OPC_SPECIAL3D_RESERVED = 0x3D | OPC_SPECIAL,
210 /* Multiplication variants of the vr54xx. */
211 #define MASK_MUL_VR54XX(op) MASK_SPECIAL(op) | (op & (0x1F << 6))
213 enum {
214 OPC_VR54XX_MULS = (0x03 << 6) | OPC_MULT,
215 OPC_VR54XX_MULSU = (0x03 << 6) | OPC_MULTU,
216 OPC_VR54XX_MACC = (0x05 << 6) | OPC_MULT,
217 OPC_VR54XX_MACCU = (0x05 << 6) | OPC_MULTU,
218 OPC_VR54XX_MSAC = (0x07 << 6) | OPC_MULT,
219 OPC_VR54XX_MSACU = (0x07 << 6) | OPC_MULTU,
220 OPC_VR54XX_MULHI = (0x09 << 6) | OPC_MULT,
221 OPC_VR54XX_MULHIU = (0x09 << 6) | OPC_MULTU,
222 OPC_VR54XX_MULSHI = (0x0B << 6) | OPC_MULT,
223 OPC_VR54XX_MULSHIU = (0x0B << 6) | OPC_MULTU,
224 OPC_VR54XX_MACCHI = (0x0D << 6) | OPC_MULT,
225 OPC_VR54XX_MACCHIU = (0x0D << 6) | OPC_MULTU,
226 OPC_VR54XX_MSACHI = (0x0F << 6) | OPC_MULT,
227 OPC_VR54XX_MSACHIU = (0x0F << 6) | OPC_MULTU,
230 /* REGIMM (rt field) opcodes */
231 #define MASK_REGIMM(op) MASK_OP_MAJOR(op) | (op & (0x1F << 16))
233 enum {
234 OPC_BLTZ = (0x00 << 16) | OPC_REGIMM,
235 OPC_BLTZL = (0x02 << 16) | OPC_REGIMM,
236 OPC_BGEZ = (0x01 << 16) | OPC_REGIMM,
237 OPC_BGEZL = (0x03 << 16) | OPC_REGIMM,
238 OPC_BLTZAL = (0x10 << 16) | OPC_REGIMM,
239 OPC_BLTZALS = OPC_BLTZAL | 0x5, /* microMIPS */
240 OPC_BLTZALL = (0x12 << 16) | OPC_REGIMM,
241 OPC_BGEZAL = (0x11 << 16) | OPC_REGIMM,
242 OPC_BGEZALS = OPC_BGEZAL | 0x5, /* microMIPS */
243 OPC_BGEZALL = (0x13 << 16) | OPC_REGIMM,
244 OPC_TGEI = (0x08 << 16) | OPC_REGIMM,
245 OPC_TGEIU = (0x09 << 16) | OPC_REGIMM,
246 OPC_TLTI = (0x0A << 16) | OPC_REGIMM,
247 OPC_TLTIU = (0x0B << 16) | OPC_REGIMM,
248 OPC_TEQI = (0x0C << 16) | OPC_REGIMM,
249 OPC_TNEI = (0x0E << 16) | OPC_REGIMM,
250 OPC_SYNCI = (0x1F << 16) | OPC_REGIMM,
253 /* Special2 opcodes */
254 #define MASK_SPECIAL2(op) MASK_OP_MAJOR(op) | (op & 0x3F)
256 enum {
257 /* Multiply & xxx operations */
258 OPC_MADD = 0x00 | OPC_SPECIAL2,
259 OPC_MADDU = 0x01 | OPC_SPECIAL2,
260 OPC_MUL = 0x02 | OPC_SPECIAL2,
261 OPC_MSUB = 0x04 | OPC_SPECIAL2,
262 OPC_MSUBU = 0x05 | OPC_SPECIAL2,
263 /* Loongson 2F */
264 OPC_MULT_G_2F = 0x10 | OPC_SPECIAL2,
265 OPC_DMULT_G_2F = 0x11 | OPC_SPECIAL2,
266 OPC_MULTU_G_2F = 0x12 | OPC_SPECIAL2,
267 OPC_DMULTU_G_2F = 0x13 | OPC_SPECIAL2,
268 OPC_DIV_G_2F = 0x14 | OPC_SPECIAL2,
269 OPC_DDIV_G_2F = 0x15 | OPC_SPECIAL2,
270 OPC_DIVU_G_2F = 0x16 | OPC_SPECIAL2,
271 OPC_DDIVU_G_2F = 0x17 | OPC_SPECIAL2,
272 OPC_MOD_G_2F = 0x1c | OPC_SPECIAL2,
273 OPC_DMOD_G_2F = 0x1d | OPC_SPECIAL2,
274 OPC_MODU_G_2F = 0x1e | OPC_SPECIAL2,
275 OPC_DMODU_G_2F = 0x1f | OPC_SPECIAL2,
276 /* Misc */
277 OPC_CLZ = 0x20 | OPC_SPECIAL2,
278 OPC_CLO = 0x21 | OPC_SPECIAL2,
279 OPC_DCLZ = 0x24 | OPC_SPECIAL2,
280 OPC_DCLO = 0x25 | OPC_SPECIAL2,
281 /* Special */
282 OPC_SDBBP = 0x3F | OPC_SPECIAL2,
285 /* Special3 opcodes */
286 #define MASK_SPECIAL3(op) MASK_OP_MAJOR(op) | (op & 0x3F)
288 enum {
289 OPC_EXT = 0x00 | OPC_SPECIAL3,
290 OPC_DEXTM = 0x01 | OPC_SPECIAL3,
291 OPC_DEXTU = 0x02 | OPC_SPECIAL3,
292 OPC_DEXT = 0x03 | OPC_SPECIAL3,
293 OPC_INS = 0x04 | OPC_SPECIAL3,
294 OPC_DINSM = 0x05 | OPC_SPECIAL3,
295 OPC_DINSU = 0x06 | OPC_SPECIAL3,
296 OPC_DINS = 0x07 | OPC_SPECIAL3,
297 OPC_FORK = 0x08 | OPC_SPECIAL3,
298 OPC_YIELD = 0x09 | OPC_SPECIAL3,
299 OPC_BSHFL = 0x20 | OPC_SPECIAL3,
300 OPC_DBSHFL = 0x24 | OPC_SPECIAL3,
301 OPC_RDHWR = 0x3B | OPC_SPECIAL3,
303 /* Loongson 2E */
304 OPC_MULT_G_2E = 0x18 | OPC_SPECIAL3,
305 OPC_MULTU_G_2E = 0x19 | OPC_SPECIAL3,
306 OPC_DIV_G_2E = 0x1A | OPC_SPECIAL3,
307 OPC_DIVU_G_2E = 0x1B | OPC_SPECIAL3,
308 OPC_DMULT_G_2E = 0x1C | OPC_SPECIAL3,
309 OPC_DMULTU_G_2E = 0x1D | OPC_SPECIAL3,
310 OPC_DDIV_G_2E = 0x1E | OPC_SPECIAL3,
311 OPC_DDIVU_G_2E = 0x1F | OPC_SPECIAL3,
312 OPC_MOD_G_2E = 0x22 | OPC_SPECIAL3,
313 OPC_MODU_G_2E = 0x23 | OPC_SPECIAL3,
314 OPC_DMOD_G_2E = 0x26 | OPC_SPECIAL3,
315 OPC_DMODU_G_2E = 0x27 | OPC_SPECIAL3,
317 /* MIPS DSP Load */
318 OPC_LX_DSP = 0x0A | OPC_SPECIAL3,
319 /* MIPS DSP Arithmetic */
320 OPC_ADDU_QB_DSP = 0x10 | OPC_SPECIAL3,
321 OPC_ADDU_OB_DSP = 0x14 | OPC_SPECIAL3,
322 OPC_ABSQ_S_PH_DSP = 0x12 | OPC_SPECIAL3,
323 OPC_ABSQ_S_QH_DSP = 0x16 | OPC_SPECIAL3,
324 /* OPC_ADDUH_QB_DSP is same as OPC_MULT_G_2E. */
325 /* OPC_ADDUH_QB_DSP = 0x18 | OPC_SPECIAL3, */
326 OPC_CMPU_EQ_QB_DSP = 0x11 | OPC_SPECIAL3,
327 OPC_CMPU_EQ_OB_DSP = 0x15 | OPC_SPECIAL3,
328 /* MIPS DSP GPR-Based Shift Sub-class */
329 OPC_SHLL_QB_DSP = 0x13 | OPC_SPECIAL3,
330 OPC_SHLL_OB_DSP = 0x17 | OPC_SPECIAL3,
331 /* MIPS DSP Multiply Sub-class insns */
332 /* OPC_MUL_PH_DSP is same as OPC_ADDUH_QB_DSP. */
333 /* OPC_MUL_PH_DSP = 0x18 | OPC_SPECIAL3, */
334 OPC_DPA_W_PH_DSP = 0x30 | OPC_SPECIAL3,
335 OPC_DPAQ_W_QH_DSP = 0x34 | OPC_SPECIAL3,
336 /* DSP Bit/Manipulation Sub-class */
337 OPC_INSV_DSP = 0x0C | OPC_SPECIAL3,
338 OPC_DINSV_DSP = 0x0D | OPC_SPECIAL3,
339 /* MIPS DSP Append Sub-class */
340 OPC_APPEND_DSP = 0x31 | OPC_SPECIAL3,
341 OPC_DAPPEND_DSP = 0x35 | OPC_SPECIAL3,
342 /* MIPS DSP Accumulator and DSPControl Access Sub-class */
343 OPC_EXTR_W_DSP = 0x38 | OPC_SPECIAL3,
344 OPC_DEXTR_W_DSP = 0x3C | OPC_SPECIAL3,
347 /* BSHFL opcodes */
348 #define MASK_BSHFL(op) MASK_SPECIAL3(op) | (op & (0x1F << 6))
350 enum {
351 OPC_WSBH = (0x02 << 6) | OPC_BSHFL,
352 OPC_SEB = (0x10 << 6) | OPC_BSHFL,
353 OPC_SEH = (0x18 << 6) | OPC_BSHFL,
356 /* DBSHFL opcodes */
357 #define MASK_DBSHFL(op) MASK_SPECIAL3(op) | (op & (0x1F << 6))
359 enum {
360 OPC_DSBH = (0x02 << 6) | OPC_DBSHFL,
361 OPC_DSHD = (0x05 << 6) | OPC_DBSHFL,
364 /* MIPS DSP REGIMM opcodes */
365 enum {
366 OPC_BPOSGE32 = (0x1C << 16) | OPC_REGIMM,
367 OPC_BPOSGE64 = (0x1D << 16) | OPC_REGIMM,
370 #define MASK_LX(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
371 /* MIPS DSP Load */
372 enum {
373 OPC_LBUX = (0x06 << 6) | OPC_LX_DSP,
374 OPC_LHX = (0x04 << 6) | OPC_LX_DSP,
375 OPC_LWX = (0x00 << 6) | OPC_LX_DSP,
376 OPC_LDX = (0x08 << 6) | OPC_LX_DSP,
379 #define MASK_ADDU_QB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
380 enum {
381 /* MIPS DSP Arithmetic Sub-class */
382 OPC_ADDQ_PH = (0x0A << 6) | OPC_ADDU_QB_DSP,
383 OPC_ADDQ_S_PH = (0x0E << 6) | OPC_ADDU_QB_DSP,
384 OPC_ADDQ_S_W = (0x16 << 6) | OPC_ADDU_QB_DSP,
385 OPC_ADDU_QB = (0x00 << 6) | OPC_ADDU_QB_DSP,
386 OPC_ADDU_S_QB = (0x04 << 6) | OPC_ADDU_QB_DSP,
387 OPC_ADDU_PH = (0x08 << 6) | OPC_ADDU_QB_DSP,
388 OPC_ADDU_S_PH = (0x0C << 6) | OPC_ADDU_QB_DSP,
389 OPC_SUBQ_PH = (0x0B << 6) | OPC_ADDU_QB_DSP,
390 OPC_SUBQ_S_PH = (0x0F << 6) | OPC_ADDU_QB_DSP,
391 OPC_SUBQ_S_W = (0x17 << 6) | OPC_ADDU_QB_DSP,
392 OPC_SUBU_QB = (0x01 << 6) | OPC_ADDU_QB_DSP,
393 OPC_SUBU_S_QB = (0x05 << 6) | OPC_ADDU_QB_DSP,
394 OPC_SUBU_PH = (0x09 << 6) | OPC_ADDU_QB_DSP,
395 OPC_SUBU_S_PH = (0x0D << 6) | OPC_ADDU_QB_DSP,
396 OPC_ADDSC = (0x10 << 6) | OPC_ADDU_QB_DSP,
397 OPC_ADDWC = (0x11 << 6) | OPC_ADDU_QB_DSP,
398 OPC_MODSUB = (0x12 << 6) | OPC_ADDU_QB_DSP,
399 OPC_RADDU_W_QB = (0x14 << 6) | OPC_ADDU_QB_DSP,
400 /* MIPS DSP Multiply Sub-class insns */
401 OPC_MULEU_S_PH_QBL = (0x06 << 6) | OPC_ADDU_QB_DSP,
402 OPC_MULEU_S_PH_QBR = (0x07 << 6) | OPC_ADDU_QB_DSP,
403 OPC_MULQ_RS_PH = (0x1F << 6) | OPC_ADDU_QB_DSP,
404 OPC_MULEQ_S_W_PHL = (0x1C << 6) | OPC_ADDU_QB_DSP,
405 OPC_MULEQ_S_W_PHR = (0x1D << 6) | OPC_ADDU_QB_DSP,
406 OPC_MULQ_S_PH = (0x1E << 6) | OPC_ADDU_QB_DSP,
409 #define OPC_ADDUH_QB_DSP OPC_MULT_G_2E
410 #define MASK_ADDUH_QB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
411 enum {
412 /* MIPS DSP Arithmetic Sub-class */
413 OPC_ADDUH_QB = (0x00 << 6) | OPC_ADDUH_QB_DSP,
414 OPC_ADDUH_R_QB = (0x02 << 6) | OPC_ADDUH_QB_DSP,
415 OPC_ADDQH_PH = (0x08 << 6) | OPC_ADDUH_QB_DSP,
416 OPC_ADDQH_R_PH = (0x0A << 6) | OPC_ADDUH_QB_DSP,
417 OPC_ADDQH_W = (0x10 << 6) | OPC_ADDUH_QB_DSP,
418 OPC_ADDQH_R_W = (0x12 << 6) | OPC_ADDUH_QB_DSP,
419 OPC_SUBUH_QB = (0x01 << 6) | OPC_ADDUH_QB_DSP,
420 OPC_SUBUH_R_QB = (0x03 << 6) | OPC_ADDUH_QB_DSP,
421 OPC_SUBQH_PH = (0x09 << 6) | OPC_ADDUH_QB_DSP,
422 OPC_SUBQH_R_PH = (0x0B << 6) | OPC_ADDUH_QB_DSP,
423 OPC_SUBQH_W = (0x11 << 6) | OPC_ADDUH_QB_DSP,
424 OPC_SUBQH_R_W = (0x13 << 6) | OPC_ADDUH_QB_DSP,
425 /* MIPS DSP Multiply Sub-class insns */
426 OPC_MUL_PH = (0x0C << 6) | OPC_ADDUH_QB_DSP,
427 OPC_MUL_S_PH = (0x0E << 6) | OPC_ADDUH_QB_DSP,
428 OPC_MULQ_S_W = (0x16 << 6) | OPC_ADDUH_QB_DSP,
429 OPC_MULQ_RS_W = (0x17 << 6) | OPC_ADDUH_QB_DSP,
432 #define MASK_ABSQ_S_PH(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
433 enum {
434 /* MIPS DSP Arithmetic Sub-class */
435 OPC_ABSQ_S_QB = (0x01 << 6) | OPC_ABSQ_S_PH_DSP,
436 OPC_ABSQ_S_PH = (0x09 << 6) | OPC_ABSQ_S_PH_DSP,
437 OPC_ABSQ_S_W = (0x11 << 6) | OPC_ABSQ_S_PH_DSP,
438 OPC_PRECEQ_W_PHL = (0x0C << 6) | OPC_ABSQ_S_PH_DSP,
439 OPC_PRECEQ_W_PHR = (0x0D << 6) | OPC_ABSQ_S_PH_DSP,
440 OPC_PRECEQU_PH_QBL = (0x04 << 6) | OPC_ABSQ_S_PH_DSP,
441 OPC_PRECEQU_PH_QBR = (0x05 << 6) | OPC_ABSQ_S_PH_DSP,
442 OPC_PRECEQU_PH_QBLA = (0x06 << 6) | OPC_ABSQ_S_PH_DSP,
443 OPC_PRECEQU_PH_QBRA = (0x07 << 6) | OPC_ABSQ_S_PH_DSP,
444 OPC_PRECEU_PH_QBL = (0x1C << 6) | OPC_ABSQ_S_PH_DSP,
445 OPC_PRECEU_PH_QBR = (0x1D << 6) | OPC_ABSQ_S_PH_DSP,
446 OPC_PRECEU_PH_QBLA = (0x1E << 6) | OPC_ABSQ_S_PH_DSP,
447 OPC_PRECEU_PH_QBRA = (0x1F << 6) | OPC_ABSQ_S_PH_DSP,
448 /* DSP Bit/Manipulation Sub-class */
449 OPC_BITREV = (0x1B << 6) | OPC_ABSQ_S_PH_DSP,
450 OPC_REPL_QB = (0x02 << 6) | OPC_ABSQ_S_PH_DSP,
451 OPC_REPLV_QB = (0x03 << 6) | OPC_ABSQ_S_PH_DSP,
452 OPC_REPL_PH = (0x0A << 6) | OPC_ABSQ_S_PH_DSP,
453 OPC_REPLV_PH = (0x0B << 6) | OPC_ABSQ_S_PH_DSP,
456 #define MASK_CMPU_EQ_QB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
457 enum {
458 /* MIPS DSP Arithmetic Sub-class */
459 OPC_PRECR_QB_PH = (0x0D << 6) | OPC_CMPU_EQ_QB_DSP,
460 OPC_PRECRQ_QB_PH = (0x0C << 6) | OPC_CMPU_EQ_QB_DSP,
461 OPC_PRECR_SRA_PH_W = (0x1E << 6) | OPC_CMPU_EQ_QB_DSP,
462 OPC_PRECR_SRA_R_PH_W = (0x1F << 6) | OPC_CMPU_EQ_QB_DSP,
463 OPC_PRECRQ_PH_W = (0x14 << 6) | OPC_CMPU_EQ_QB_DSP,
464 OPC_PRECRQ_RS_PH_W = (0x15 << 6) | OPC_CMPU_EQ_QB_DSP,
465 OPC_PRECRQU_S_QB_PH = (0x0F << 6) | OPC_CMPU_EQ_QB_DSP,
466 /* DSP Compare-Pick Sub-class */
467 OPC_CMPU_EQ_QB = (0x00 << 6) | OPC_CMPU_EQ_QB_DSP,
468 OPC_CMPU_LT_QB = (0x01 << 6) | OPC_CMPU_EQ_QB_DSP,
469 OPC_CMPU_LE_QB = (0x02 << 6) | OPC_CMPU_EQ_QB_DSP,
470 OPC_CMPGU_EQ_QB = (0x04 << 6) | OPC_CMPU_EQ_QB_DSP,
471 OPC_CMPGU_LT_QB = (0x05 << 6) | OPC_CMPU_EQ_QB_DSP,
472 OPC_CMPGU_LE_QB = (0x06 << 6) | OPC_CMPU_EQ_QB_DSP,
473 OPC_CMPGDU_EQ_QB = (0x18 << 6) | OPC_CMPU_EQ_QB_DSP,
474 OPC_CMPGDU_LT_QB = (0x19 << 6) | OPC_CMPU_EQ_QB_DSP,
475 OPC_CMPGDU_LE_QB = (0x1A << 6) | OPC_CMPU_EQ_QB_DSP,
476 OPC_CMP_EQ_PH = (0x08 << 6) | OPC_CMPU_EQ_QB_DSP,
477 OPC_CMP_LT_PH = (0x09 << 6) | OPC_CMPU_EQ_QB_DSP,
478 OPC_CMP_LE_PH = (0x0A << 6) | OPC_CMPU_EQ_QB_DSP,
479 OPC_PICK_QB = (0x03 << 6) | OPC_CMPU_EQ_QB_DSP,
480 OPC_PICK_PH = (0x0B << 6) | OPC_CMPU_EQ_QB_DSP,
481 OPC_PACKRL_PH = (0x0E << 6) | OPC_CMPU_EQ_QB_DSP,
484 #define MASK_SHLL_QB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
485 enum {
486 /* MIPS DSP GPR-Based Shift Sub-class */
487 OPC_SHLL_QB = (0x00 << 6) | OPC_SHLL_QB_DSP,
488 OPC_SHLLV_QB = (0x02 << 6) | OPC_SHLL_QB_DSP,
489 OPC_SHLL_PH = (0x08 << 6) | OPC_SHLL_QB_DSP,
490 OPC_SHLLV_PH = (0x0A << 6) | OPC_SHLL_QB_DSP,
491 OPC_SHLL_S_PH = (0x0C << 6) | OPC_SHLL_QB_DSP,
492 OPC_SHLLV_S_PH = (0x0E << 6) | OPC_SHLL_QB_DSP,
493 OPC_SHLL_S_W = (0x14 << 6) | OPC_SHLL_QB_DSP,
494 OPC_SHLLV_S_W = (0x16 << 6) | OPC_SHLL_QB_DSP,
495 OPC_SHRL_QB = (0x01 << 6) | OPC_SHLL_QB_DSP,
496 OPC_SHRLV_QB = (0x03 << 6) | OPC_SHLL_QB_DSP,
497 OPC_SHRL_PH = (0x19 << 6) | OPC_SHLL_QB_DSP,
498 OPC_SHRLV_PH = (0x1B << 6) | OPC_SHLL_QB_DSP,
499 OPC_SHRA_QB = (0x04 << 6) | OPC_SHLL_QB_DSP,
500 OPC_SHRA_R_QB = (0x05 << 6) | OPC_SHLL_QB_DSP,
501 OPC_SHRAV_QB = (0x06 << 6) | OPC_SHLL_QB_DSP,
502 OPC_SHRAV_R_QB = (0x07 << 6) | OPC_SHLL_QB_DSP,
503 OPC_SHRA_PH = (0x09 << 6) | OPC_SHLL_QB_DSP,
504 OPC_SHRAV_PH = (0x0B << 6) | OPC_SHLL_QB_DSP,
505 OPC_SHRA_R_PH = (0x0D << 6) | OPC_SHLL_QB_DSP,
506 OPC_SHRAV_R_PH = (0x0F << 6) | OPC_SHLL_QB_DSP,
507 OPC_SHRA_R_W = (0x15 << 6) | OPC_SHLL_QB_DSP,
508 OPC_SHRAV_R_W = (0x17 << 6) | OPC_SHLL_QB_DSP,
511 #define MASK_DPA_W_PH(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
512 enum {
513 /* MIPS DSP Multiply Sub-class insns */
514 OPC_DPAU_H_QBL = (0x03 << 6) | OPC_DPA_W_PH_DSP,
515 OPC_DPAU_H_QBR = (0x07 << 6) | OPC_DPA_W_PH_DSP,
516 OPC_DPSU_H_QBL = (0x0B << 6) | OPC_DPA_W_PH_DSP,
517 OPC_DPSU_H_QBR = (0x0F << 6) | OPC_DPA_W_PH_DSP,
518 OPC_DPA_W_PH = (0x00 << 6) | OPC_DPA_W_PH_DSP,
519 OPC_DPAX_W_PH = (0x08 << 6) | OPC_DPA_W_PH_DSP,
520 OPC_DPAQ_S_W_PH = (0x04 << 6) | OPC_DPA_W_PH_DSP,
521 OPC_DPAQX_S_W_PH = (0x18 << 6) | OPC_DPA_W_PH_DSP,
522 OPC_DPAQX_SA_W_PH = (0x1A << 6) | OPC_DPA_W_PH_DSP,
523 OPC_DPS_W_PH = (0x01 << 6) | OPC_DPA_W_PH_DSP,
524 OPC_DPSX_W_PH = (0x09 << 6) | OPC_DPA_W_PH_DSP,
525 OPC_DPSQ_S_W_PH = (0x05 << 6) | OPC_DPA_W_PH_DSP,
526 OPC_DPSQX_S_W_PH = (0x19 << 6) | OPC_DPA_W_PH_DSP,
527 OPC_DPSQX_SA_W_PH = (0x1B << 6) | OPC_DPA_W_PH_DSP,
528 OPC_MULSAQ_S_W_PH = (0x06 << 6) | OPC_DPA_W_PH_DSP,
529 OPC_DPAQ_SA_L_W = (0x0C << 6) | OPC_DPA_W_PH_DSP,
530 OPC_DPSQ_SA_L_W = (0x0D << 6) | OPC_DPA_W_PH_DSP,
531 OPC_MAQ_S_W_PHL = (0x14 << 6) | OPC_DPA_W_PH_DSP,
532 OPC_MAQ_S_W_PHR = (0x16 << 6) | OPC_DPA_W_PH_DSP,
533 OPC_MAQ_SA_W_PHL = (0x10 << 6) | OPC_DPA_W_PH_DSP,
534 OPC_MAQ_SA_W_PHR = (0x12 << 6) | OPC_DPA_W_PH_DSP,
535 OPC_MULSA_W_PH = (0x02 << 6) | OPC_DPA_W_PH_DSP,
538 #define MASK_INSV(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
539 enum {
540 /* DSP Bit/Manipulation Sub-class */
541 OPC_INSV = (0x00 << 6) | OPC_INSV_DSP,
544 #define MASK_APPEND(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
545 enum {
546 /* MIPS DSP Append Sub-class */
547 OPC_APPEND = (0x00 << 6) | OPC_APPEND_DSP,
548 OPC_PREPEND = (0x01 << 6) | OPC_APPEND_DSP,
549 OPC_BALIGN = (0x10 << 6) | OPC_APPEND_DSP,
552 #define MASK_EXTR_W(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
553 enum {
554 /* MIPS DSP Accumulator and DSPControl Access Sub-class */
555 OPC_EXTR_W = (0x00 << 6) | OPC_EXTR_W_DSP,
556 OPC_EXTR_R_W = (0x04 << 6) | OPC_EXTR_W_DSP,
557 OPC_EXTR_RS_W = (0x06 << 6) | OPC_EXTR_W_DSP,
558 OPC_EXTR_S_H = (0x0E << 6) | OPC_EXTR_W_DSP,
559 OPC_EXTRV_S_H = (0x0F << 6) | OPC_EXTR_W_DSP,
560 OPC_EXTRV_W = (0x01 << 6) | OPC_EXTR_W_DSP,
561 OPC_EXTRV_R_W = (0x05 << 6) | OPC_EXTR_W_DSP,
562 OPC_EXTRV_RS_W = (0x07 << 6) | OPC_EXTR_W_DSP,
563 OPC_EXTP = (0x02 << 6) | OPC_EXTR_W_DSP,
564 OPC_EXTPV = (0x03 << 6) | OPC_EXTR_W_DSP,
565 OPC_EXTPDP = (0x0A << 6) | OPC_EXTR_W_DSP,
566 OPC_EXTPDPV = (0x0B << 6) | OPC_EXTR_W_DSP,
567 OPC_SHILO = (0x1A << 6) | OPC_EXTR_W_DSP,
568 OPC_SHILOV = (0x1B << 6) | OPC_EXTR_W_DSP,
569 OPC_MTHLIP = (0x1F << 6) | OPC_EXTR_W_DSP,
570 OPC_WRDSP = (0x13 << 6) | OPC_EXTR_W_DSP,
571 OPC_RDDSP = (0x12 << 6) | OPC_EXTR_W_DSP,
574 #define MASK_ABSQ_S_QH(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
575 enum {
576 /* MIPS DSP Arithmetic Sub-class */
577 OPC_PRECEQ_L_PWL = (0x14 << 6) | OPC_ABSQ_S_QH_DSP,
578 OPC_PRECEQ_L_PWR = (0x15 << 6) | OPC_ABSQ_S_QH_DSP,
579 OPC_PRECEQ_PW_QHL = (0x0C << 6) | OPC_ABSQ_S_QH_DSP,
580 OPC_PRECEQ_PW_QHR = (0x0D << 6) | OPC_ABSQ_S_QH_DSP,
581 OPC_PRECEQ_PW_QHLA = (0x0E << 6) | OPC_ABSQ_S_QH_DSP,
582 OPC_PRECEQ_PW_QHRA = (0x0F << 6) | OPC_ABSQ_S_QH_DSP,
583 OPC_PRECEQU_QH_OBL = (0x04 << 6) | OPC_ABSQ_S_QH_DSP,
584 OPC_PRECEQU_QH_OBR = (0x05 << 6) | OPC_ABSQ_S_QH_DSP,
585 OPC_PRECEQU_QH_OBLA = (0x06 << 6) | OPC_ABSQ_S_QH_DSP,
586 OPC_PRECEQU_QH_OBRA = (0x07 << 6) | OPC_ABSQ_S_QH_DSP,
587 OPC_PRECEU_QH_OBL = (0x1C << 6) | OPC_ABSQ_S_QH_DSP,
588 OPC_PRECEU_QH_OBR = (0x1D << 6) | OPC_ABSQ_S_QH_DSP,
589 OPC_PRECEU_QH_OBLA = (0x1E << 6) | OPC_ABSQ_S_QH_DSP,
590 OPC_PRECEU_QH_OBRA = (0x1F << 6) | OPC_ABSQ_S_QH_DSP,
591 OPC_ABSQ_S_OB = (0x01 << 6) | OPC_ABSQ_S_QH_DSP,
592 OPC_ABSQ_S_PW = (0x11 << 6) | OPC_ABSQ_S_QH_DSP,
593 OPC_ABSQ_S_QH = (0x09 << 6) | OPC_ABSQ_S_QH_DSP,
594 /* DSP Bit/Manipulation Sub-class */
595 OPC_REPL_OB = (0x02 << 6) | OPC_ABSQ_S_QH_DSP,
596 OPC_REPL_PW = (0x12 << 6) | OPC_ABSQ_S_QH_DSP,
597 OPC_REPL_QH = (0x0A << 6) | OPC_ABSQ_S_QH_DSP,
598 OPC_REPLV_OB = (0x03 << 6) | OPC_ABSQ_S_QH_DSP,
599 OPC_REPLV_PW = (0x13 << 6) | OPC_ABSQ_S_QH_DSP,
600 OPC_REPLV_QH = (0x0B << 6) | OPC_ABSQ_S_QH_DSP,
603 #define MASK_ADDU_OB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
604 enum {
605 /* MIPS DSP Multiply Sub-class insns */
606 OPC_MULEQ_S_PW_QHL = (0x1C << 6) | OPC_ADDU_OB_DSP,
607 OPC_MULEQ_S_PW_QHR = (0x1D << 6) | OPC_ADDU_OB_DSP,
608 OPC_MULEU_S_QH_OBL = (0x06 << 6) | OPC_ADDU_OB_DSP,
609 OPC_MULEU_S_QH_OBR = (0x07 << 6) | OPC_ADDU_OB_DSP,
610 OPC_MULQ_RS_QH = (0x1F << 6) | OPC_ADDU_OB_DSP,
611 /* MIPS DSP Arithmetic Sub-class */
612 OPC_RADDU_L_OB = (0x14 << 6) | OPC_ADDU_OB_DSP,
613 OPC_SUBQ_PW = (0x13 << 6) | OPC_ADDU_OB_DSP,
614 OPC_SUBQ_S_PW = (0x17 << 6) | OPC_ADDU_OB_DSP,
615 OPC_SUBQ_QH = (0x0B << 6) | OPC_ADDU_OB_DSP,
616 OPC_SUBQ_S_QH = (0x0F << 6) | OPC_ADDU_OB_DSP,
617 OPC_SUBU_OB = (0x01 << 6) | OPC_ADDU_OB_DSP,
618 OPC_SUBU_S_OB = (0x05 << 6) | OPC_ADDU_OB_DSP,
619 OPC_SUBU_QH = (0x09 << 6) | OPC_ADDU_OB_DSP,
620 OPC_SUBU_S_QH = (0x0D << 6) | OPC_ADDU_OB_DSP,
621 OPC_SUBUH_OB = (0x19 << 6) | OPC_ADDU_OB_DSP,
622 OPC_SUBUH_R_OB = (0x1B << 6) | OPC_ADDU_OB_DSP,
623 OPC_ADDQ_PW = (0x12 << 6) | OPC_ADDU_OB_DSP,
624 OPC_ADDQ_S_PW = (0x16 << 6) | OPC_ADDU_OB_DSP,
625 OPC_ADDQ_QH = (0x0A << 6) | OPC_ADDU_OB_DSP,
626 OPC_ADDQ_S_QH = (0x0E << 6) | OPC_ADDU_OB_DSP,
627 OPC_ADDU_OB = (0x00 << 6) | OPC_ADDU_OB_DSP,
628 OPC_ADDU_S_OB = (0x04 << 6) | OPC_ADDU_OB_DSP,
629 OPC_ADDU_QH = (0x08 << 6) | OPC_ADDU_OB_DSP,
630 OPC_ADDU_S_QH = (0x0C << 6) | OPC_ADDU_OB_DSP,
631 OPC_ADDUH_OB = (0x18 << 6) | OPC_ADDU_OB_DSP,
632 OPC_ADDUH_R_OB = (0x1A << 6) | OPC_ADDU_OB_DSP,
635 #define MASK_CMPU_EQ_OB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
636 enum {
637 /* DSP Compare-Pick Sub-class */
638 OPC_CMP_EQ_PW = (0x10 << 6) | OPC_CMPU_EQ_OB_DSP,
639 OPC_CMP_LT_PW = (0x11 << 6) | OPC_CMPU_EQ_OB_DSP,
640 OPC_CMP_LE_PW = (0x12 << 6) | OPC_CMPU_EQ_OB_DSP,
641 OPC_CMP_EQ_QH = (0x08 << 6) | OPC_CMPU_EQ_OB_DSP,
642 OPC_CMP_LT_QH = (0x09 << 6) | OPC_CMPU_EQ_OB_DSP,
643 OPC_CMP_LE_QH = (0x0A << 6) | OPC_CMPU_EQ_OB_DSP,
644 OPC_CMPGDU_EQ_OB = (0x18 << 6) | OPC_CMPU_EQ_OB_DSP,
645 OPC_CMPGDU_LT_OB = (0x19 << 6) | OPC_CMPU_EQ_OB_DSP,
646 OPC_CMPGDU_LE_OB = (0x1A << 6) | OPC_CMPU_EQ_OB_DSP,
647 OPC_CMPGU_EQ_OB = (0x04 << 6) | OPC_CMPU_EQ_OB_DSP,
648 OPC_CMPGU_LT_OB = (0x05 << 6) | OPC_CMPU_EQ_OB_DSP,
649 OPC_CMPGU_LE_OB = (0x06 << 6) | OPC_CMPU_EQ_OB_DSP,
650 OPC_CMPU_EQ_OB = (0x00 << 6) | OPC_CMPU_EQ_OB_DSP,
651 OPC_CMPU_LT_OB = (0x01 << 6) | OPC_CMPU_EQ_OB_DSP,
652 OPC_CMPU_LE_OB = (0x02 << 6) | OPC_CMPU_EQ_OB_DSP,
653 OPC_PACKRL_PW = (0x0E << 6) | OPC_CMPU_EQ_OB_DSP,
654 OPC_PICK_OB = (0x03 << 6) | OPC_CMPU_EQ_OB_DSP,
655 OPC_PICK_PW = (0x13 << 6) | OPC_CMPU_EQ_OB_DSP,
656 OPC_PICK_QH = (0x0B << 6) | OPC_CMPU_EQ_OB_DSP,
657 /* MIPS DSP Arithmetic Sub-class */
658 OPC_PRECR_OB_QH = (0x0D << 6) | OPC_CMPU_EQ_OB_DSP,
659 OPC_PRECR_SRA_QH_PW = (0x1E << 6) | OPC_CMPU_EQ_OB_DSP,
660 OPC_PRECR_SRA_R_QH_PW = (0x1F << 6) | OPC_CMPU_EQ_OB_DSP,
661 OPC_PRECRQ_OB_QH = (0x0C << 6) | OPC_CMPU_EQ_OB_DSP,
662 OPC_PRECRQ_PW_L = (0x1C << 6) | OPC_CMPU_EQ_OB_DSP,
663 OPC_PRECRQ_QH_PW = (0x14 << 6) | OPC_CMPU_EQ_OB_DSP,
664 OPC_PRECRQ_RS_QH_PW = (0x15 << 6) | OPC_CMPU_EQ_OB_DSP,
665 OPC_PRECRQU_S_OB_QH = (0x0F << 6) | OPC_CMPU_EQ_OB_DSP,
668 #define MASK_DAPPEND(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
669 enum {
670 /* DSP Append Sub-class */
671 OPC_DAPPEND = (0x00 << 6) | OPC_DAPPEND_DSP,
672 OPC_PREPENDD = (0x03 << 6) | OPC_DAPPEND_DSP,
673 OPC_PREPENDW = (0x01 << 6) | OPC_DAPPEND_DSP,
674 OPC_DBALIGN = (0x10 << 6) | OPC_DAPPEND_DSP,
677 #define MASK_DEXTR_W(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
678 enum {
679 /* MIPS DSP Accumulator and DSPControl Access Sub-class */
680 OPC_DMTHLIP = (0x1F << 6) | OPC_DEXTR_W_DSP,
681 OPC_DSHILO = (0x1A << 6) | OPC_DEXTR_W_DSP,
682 OPC_DEXTP = (0x02 << 6) | OPC_DEXTR_W_DSP,
683 OPC_DEXTPDP = (0x0A << 6) | OPC_DEXTR_W_DSP,
684 OPC_DEXTPDPV = (0x0B << 6) | OPC_DEXTR_W_DSP,
685 OPC_DEXTPV = (0x03 << 6) | OPC_DEXTR_W_DSP,
686 OPC_DEXTR_L = (0x10 << 6) | OPC_DEXTR_W_DSP,
687 OPC_DEXTR_R_L = (0x14 << 6) | OPC_DEXTR_W_DSP,
688 OPC_DEXTR_RS_L = (0x16 << 6) | OPC_DEXTR_W_DSP,
689 OPC_DEXTR_W = (0x00 << 6) | OPC_DEXTR_W_DSP,
690 OPC_DEXTR_R_W = (0x04 << 6) | OPC_DEXTR_W_DSP,
691 OPC_DEXTR_RS_W = (0x06 << 6) | OPC_DEXTR_W_DSP,
692 OPC_DEXTR_S_H = (0x0E << 6) | OPC_DEXTR_W_DSP,
693 OPC_DEXTRV_L = (0x11 << 6) | OPC_DEXTR_W_DSP,
694 OPC_DEXTRV_R_L = (0x15 << 6) | OPC_DEXTR_W_DSP,
695 OPC_DEXTRV_RS_L = (0x17 << 6) | OPC_DEXTR_W_DSP,
696 OPC_DEXTRV_S_H = (0x0F << 6) | OPC_DEXTR_W_DSP,
697 OPC_DEXTRV_W = (0x01 << 6) | OPC_DEXTR_W_DSP,
698 OPC_DEXTRV_R_W = (0x05 << 6) | OPC_DEXTR_W_DSP,
699 OPC_DEXTRV_RS_W = (0x07 << 6) | OPC_DEXTR_W_DSP,
700 OPC_DSHILOV = (0x1B << 6) | OPC_DEXTR_W_DSP,
703 #define MASK_DINSV(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
704 enum {
705 /* DSP Bit/Manipulation Sub-class */
706 OPC_DINSV = (0x00 << 6) | OPC_DINSV_DSP,
709 #define MASK_DPAQ_W_QH(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
710 enum {
711 /* MIPS DSP Multiply Sub-class insns */
712 OPC_DMADD = (0x19 << 6) | OPC_DPAQ_W_QH_DSP,
713 OPC_DMADDU = (0x1D << 6) | OPC_DPAQ_W_QH_DSP,
714 OPC_DMSUB = (0x1B << 6) | OPC_DPAQ_W_QH_DSP,
715 OPC_DMSUBU = (0x1F << 6) | OPC_DPAQ_W_QH_DSP,
716 OPC_DPA_W_QH = (0x00 << 6) | OPC_DPAQ_W_QH_DSP,
717 OPC_DPAQ_S_W_QH = (0x04 << 6) | OPC_DPAQ_W_QH_DSP,
718 OPC_DPAQ_SA_L_PW = (0x0C << 6) | OPC_DPAQ_W_QH_DSP,
719 OPC_DPAU_H_OBL = (0x03 << 6) | OPC_DPAQ_W_QH_DSP,
720 OPC_DPAU_H_OBR = (0x07 << 6) | OPC_DPAQ_W_QH_DSP,
721 OPC_DPS_W_QH = (0x01 << 6) | OPC_DPAQ_W_QH_DSP,
722 OPC_DPSQ_S_W_QH = (0x05 << 6) | OPC_DPAQ_W_QH_DSP,
723 OPC_DPSQ_SA_L_PW = (0x0D << 6) | OPC_DPAQ_W_QH_DSP,
724 OPC_DPSU_H_OBL = (0x0B << 6) | OPC_DPAQ_W_QH_DSP,
725 OPC_DPSU_H_OBR = (0x0F << 6) | OPC_DPAQ_W_QH_DSP,
726 OPC_MAQ_S_L_PWL = (0x1C << 6) | OPC_DPAQ_W_QH_DSP,
727 OPC_MAQ_S_L_PWR = (0x1E << 6) | OPC_DPAQ_W_QH_DSP,
728 OPC_MAQ_S_W_QHLL = (0x14 << 6) | OPC_DPAQ_W_QH_DSP,
729 OPC_MAQ_SA_W_QHLL = (0x10 << 6) | OPC_DPAQ_W_QH_DSP,
730 OPC_MAQ_S_W_QHLR = (0x15 << 6) | OPC_DPAQ_W_QH_DSP,
731 OPC_MAQ_SA_W_QHLR = (0x11 << 6) | OPC_DPAQ_W_QH_DSP,
732 OPC_MAQ_S_W_QHRL = (0x16 << 6) | OPC_DPAQ_W_QH_DSP,
733 OPC_MAQ_SA_W_QHRL = (0x12 << 6) | OPC_DPAQ_W_QH_DSP,
734 OPC_MAQ_S_W_QHRR = (0x17 << 6) | OPC_DPAQ_W_QH_DSP,
735 OPC_MAQ_SA_W_QHRR = (0x13 << 6) | OPC_DPAQ_W_QH_DSP,
736 OPC_MULSAQ_S_L_PW = (0x0E << 6) | OPC_DPAQ_W_QH_DSP,
737 OPC_MULSAQ_S_W_QH = (0x06 << 6) | OPC_DPAQ_W_QH_DSP,
740 #define MASK_SHLL_OB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
741 enum {
742 /* MIPS DSP GPR-Based Shift Sub-class */
743 OPC_SHLL_PW = (0x10 << 6) | OPC_SHLL_OB_DSP,
744 OPC_SHLL_S_PW = (0x14 << 6) | OPC_SHLL_OB_DSP,
745 OPC_SHLLV_OB = (0x02 << 6) | OPC_SHLL_OB_DSP,
746 OPC_SHLLV_PW = (0x12 << 6) | OPC_SHLL_OB_DSP,
747 OPC_SHLLV_S_PW = (0x16 << 6) | OPC_SHLL_OB_DSP,
748 OPC_SHLLV_QH = (0x0A << 6) | OPC_SHLL_OB_DSP,
749 OPC_SHLLV_S_QH = (0x0E << 6) | OPC_SHLL_OB_DSP,
750 OPC_SHRA_PW = (0x11 << 6) | OPC_SHLL_OB_DSP,
751 OPC_SHRA_R_PW = (0x15 << 6) | OPC_SHLL_OB_DSP,
752 OPC_SHRAV_OB = (0x06 << 6) | OPC_SHLL_OB_DSP,
753 OPC_SHRAV_R_OB = (0x07 << 6) | OPC_SHLL_OB_DSP,
754 OPC_SHRAV_PW = (0x13 << 6) | OPC_SHLL_OB_DSP,
755 OPC_SHRAV_R_PW = (0x17 << 6) | OPC_SHLL_OB_DSP,
756 OPC_SHRAV_QH = (0x0B << 6) | OPC_SHLL_OB_DSP,
757 OPC_SHRAV_R_QH = (0x0F << 6) | OPC_SHLL_OB_DSP,
758 OPC_SHRLV_OB = (0x03 << 6) | OPC_SHLL_OB_DSP,
759 OPC_SHRLV_QH = (0x1B << 6) | OPC_SHLL_OB_DSP,
760 OPC_SHLL_OB = (0x00 << 6) | OPC_SHLL_OB_DSP,
761 OPC_SHLL_QH = (0x08 << 6) | OPC_SHLL_OB_DSP,
762 OPC_SHLL_S_QH = (0x0C << 6) | OPC_SHLL_OB_DSP,
763 OPC_SHRA_OB = (0x04 << 6) | OPC_SHLL_OB_DSP,
764 OPC_SHRA_R_OB = (0x05 << 6) | OPC_SHLL_OB_DSP,
765 OPC_SHRA_QH = (0x09 << 6) | OPC_SHLL_OB_DSP,
766 OPC_SHRA_R_QH = (0x0D << 6) | OPC_SHLL_OB_DSP,
767 OPC_SHRL_OB = (0x01 << 6) | OPC_SHLL_OB_DSP,
768 OPC_SHRL_QH = (0x19 << 6) | OPC_SHLL_OB_DSP,
771 /* Coprocessor 0 (rs field) */
772 #define MASK_CP0(op) MASK_OP_MAJOR(op) | (op & (0x1F << 21))
774 enum {
775 OPC_MFC0 = (0x00 << 21) | OPC_CP0,
776 OPC_DMFC0 = (0x01 << 21) | OPC_CP0,
777 OPC_MTC0 = (0x04 << 21) | OPC_CP0,
778 OPC_DMTC0 = (0x05 << 21) | OPC_CP0,
779 OPC_MFTR = (0x08 << 21) | OPC_CP0,
780 OPC_RDPGPR = (0x0A << 21) | OPC_CP0,
781 OPC_MFMC0 = (0x0B << 21) | OPC_CP0,
782 OPC_MTTR = (0x0C << 21) | OPC_CP0,
783 OPC_WRPGPR = (0x0E << 21) | OPC_CP0,
784 OPC_C0 = (0x10 << 21) | OPC_CP0,
785 OPC_C0_FIRST = (0x10 << 21) | OPC_CP0,
786 OPC_C0_LAST = (0x1F << 21) | OPC_CP0,
789 /* MFMC0 opcodes */
790 #define MASK_MFMC0(op) MASK_CP0(op) | (op & 0xFFFF)
792 enum {
793 OPC_DMT = 0x01 | (0 << 5) | (0x0F << 6) | (0x01 << 11) | OPC_MFMC0,
794 OPC_EMT = 0x01 | (1 << 5) | (0x0F << 6) | (0x01 << 11) | OPC_MFMC0,
795 OPC_DVPE = 0x01 | (0 << 5) | OPC_MFMC0,
796 OPC_EVPE = 0x01 | (1 << 5) | OPC_MFMC0,
797 OPC_DI = (0 << 5) | (0x0C << 11) | OPC_MFMC0,
798 OPC_EI = (1 << 5) | (0x0C << 11) | OPC_MFMC0,
801 /* Coprocessor 0 (with rs == C0) */
802 #define MASK_C0(op) MASK_CP0(op) | (op & 0x3F)
804 enum {
805 OPC_TLBR = 0x01 | OPC_C0,
806 OPC_TLBWI = 0x02 | OPC_C0,
807 OPC_TLBWR = 0x06 | OPC_C0,
808 OPC_TLBP = 0x08 | OPC_C0,
809 OPC_RFE = 0x10 | OPC_C0,
810 OPC_ERET = 0x18 | OPC_C0,
811 OPC_DERET = 0x1F | OPC_C0,
812 OPC_WAIT = 0x20 | OPC_C0,
815 /* Coprocessor 1 (rs field) */
816 #define MASK_CP1(op) MASK_OP_MAJOR(op) | (op & (0x1F << 21))
818 /* Values for the fmt field in FP instructions */
819 enum {
820 /* 0 - 15 are reserved */
821 FMT_S = 16, /* single fp */
822 FMT_D = 17, /* double fp */
823 FMT_E = 18, /* extended fp */
824 FMT_Q = 19, /* quad fp */
825 FMT_W = 20, /* 32-bit fixed */
826 FMT_L = 21, /* 64-bit fixed */
827 FMT_PS = 22, /* paired single fp */
828 /* 23 - 31 are reserved */
831 enum {
832 OPC_MFC1 = (0x00 << 21) | OPC_CP1,
833 OPC_DMFC1 = (0x01 << 21) | OPC_CP1,
834 OPC_CFC1 = (0x02 << 21) | OPC_CP1,
835 OPC_MFHC1 = (0x03 << 21) | OPC_CP1,
836 OPC_MTC1 = (0x04 << 21) | OPC_CP1,
837 OPC_DMTC1 = (0x05 << 21) | OPC_CP1,
838 OPC_CTC1 = (0x06 << 21) | OPC_CP1,
839 OPC_MTHC1 = (0x07 << 21) | OPC_CP1,
840 OPC_BC1 = (0x08 << 21) | OPC_CP1, /* bc */
841 OPC_BC1ANY2 = (0x09 << 21) | OPC_CP1,
842 OPC_BC1ANY4 = (0x0A << 21) | OPC_CP1,
843 OPC_S_FMT = (FMT_S << 21) | OPC_CP1,
844 OPC_D_FMT = (FMT_D << 21) | OPC_CP1,
845 OPC_E_FMT = (FMT_E << 21) | OPC_CP1,
846 OPC_Q_FMT = (FMT_Q << 21) | OPC_CP1,
847 OPC_W_FMT = (FMT_W << 21) | OPC_CP1,
848 OPC_L_FMT = (FMT_L << 21) | OPC_CP1,
849 OPC_PS_FMT = (FMT_PS << 21) | OPC_CP1,
852 #define MASK_CP1_FUNC(op) MASK_CP1(op) | (op & 0x3F)
853 #define MASK_BC1(op) MASK_CP1(op) | (op & (0x3 << 16))
855 enum {
856 OPC_BC1F = (0x00 << 16) | OPC_BC1,
857 OPC_BC1T = (0x01 << 16) | OPC_BC1,
858 OPC_BC1FL = (0x02 << 16) | OPC_BC1,
859 OPC_BC1TL = (0x03 << 16) | OPC_BC1,
862 enum {
863 OPC_BC1FANY2 = (0x00 << 16) | OPC_BC1ANY2,
864 OPC_BC1TANY2 = (0x01 << 16) | OPC_BC1ANY2,
867 enum {
868 OPC_BC1FANY4 = (0x00 << 16) | OPC_BC1ANY4,
869 OPC_BC1TANY4 = (0x01 << 16) | OPC_BC1ANY4,
872 #define MASK_CP2(op) MASK_OP_MAJOR(op) | (op & (0x1F << 21))
874 enum {
875 OPC_MFC2 = (0x00 << 21) | OPC_CP2,
876 OPC_DMFC2 = (0x01 << 21) | OPC_CP2,
877 OPC_CFC2 = (0x02 << 21) | OPC_CP2,
878 OPC_MFHC2 = (0x03 << 21) | OPC_CP2,
879 OPC_MTC2 = (0x04 << 21) | OPC_CP2,
880 OPC_DMTC2 = (0x05 << 21) | OPC_CP2,
881 OPC_CTC2 = (0x06 << 21) | OPC_CP2,
882 OPC_MTHC2 = (0x07 << 21) | OPC_CP2,
883 OPC_BC2 = (0x08 << 21) | OPC_CP2,
886 #define MASK_LMI(op) (MASK_OP_MAJOR(op) | (op & (0x1F << 21)) | (op & 0x1F))
888 enum {
889 OPC_PADDSH = (24 << 21) | (0x00) | OPC_CP2,
890 OPC_PADDUSH = (25 << 21) | (0x00) | OPC_CP2,
891 OPC_PADDH = (26 << 21) | (0x00) | OPC_CP2,
892 OPC_PADDW = (27 << 21) | (0x00) | OPC_CP2,
893 OPC_PADDSB = (28 << 21) | (0x00) | OPC_CP2,
894 OPC_PADDUSB = (29 << 21) | (0x00) | OPC_CP2,
895 OPC_PADDB = (30 << 21) | (0x00) | OPC_CP2,
896 OPC_PADDD = (31 << 21) | (0x00) | OPC_CP2,
898 OPC_PSUBSH = (24 << 21) | (0x01) | OPC_CP2,
899 OPC_PSUBUSH = (25 << 21) | (0x01) | OPC_CP2,
900 OPC_PSUBH = (26 << 21) | (0x01) | OPC_CP2,
901 OPC_PSUBW = (27 << 21) | (0x01) | OPC_CP2,
902 OPC_PSUBSB = (28 << 21) | (0x01) | OPC_CP2,
903 OPC_PSUBUSB = (29 << 21) | (0x01) | OPC_CP2,
904 OPC_PSUBB = (30 << 21) | (0x01) | OPC_CP2,
905 OPC_PSUBD = (31 << 21) | (0x01) | OPC_CP2,
907 OPC_PSHUFH = (24 << 21) | (0x02) | OPC_CP2,
908 OPC_PACKSSWH = (25 << 21) | (0x02) | OPC_CP2,
909 OPC_PACKSSHB = (26 << 21) | (0x02) | OPC_CP2,
910 OPC_PACKUSHB = (27 << 21) | (0x02) | OPC_CP2,
911 OPC_XOR_CP2 = (28 << 21) | (0x02) | OPC_CP2,
912 OPC_NOR_CP2 = (29 << 21) | (0x02) | OPC_CP2,
913 OPC_AND_CP2 = (30 << 21) | (0x02) | OPC_CP2,
914 OPC_PANDN = (31 << 21) | (0x02) | OPC_CP2,
916 OPC_PUNPCKLHW = (24 << 21) | (0x03) | OPC_CP2,
917 OPC_PUNPCKHHW = (25 << 21) | (0x03) | OPC_CP2,
918 OPC_PUNPCKLBH = (26 << 21) | (0x03) | OPC_CP2,
919 OPC_PUNPCKHBH = (27 << 21) | (0x03) | OPC_CP2,
920 OPC_PINSRH_0 = (28 << 21) | (0x03) | OPC_CP2,
921 OPC_PINSRH_1 = (29 << 21) | (0x03) | OPC_CP2,
922 OPC_PINSRH_2 = (30 << 21) | (0x03) | OPC_CP2,
923 OPC_PINSRH_3 = (31 << 21) | (0x03) | OPC_CP2,
925 OPC_PAVGH = (24 << 21) | (0x08) | OPC_CP2,
926 OPC_PAVGB = (25 << 21) | (0x08) | OPC_CP2,
927 OPC_PMAXSH = (26 << 21) | (0x08) | OPC_CP2,
928 OPC_PMINSH = (27 << 21) | (0x08) | OPC_CP2,
929 OPC_PMAXUB = (28 << 21) | (0x08) | OPC_CP2,
930 OPC_PMINUB = (29 << 21) | (0x08) | OPC_CP2,
932 OPC_PCMPEQW = (24 << 21) | (0x09) | OPC_CP2,
933 OPC_PCMPGTW = (25 << 21) | (0x09) | OPC_CP2,
934 OPC_PCMPEQH = (26 << 21) | (0x09) | OPC_CP2,
935 OPC_PCMPGTH = (27 << 21) | (0x09) | OPC_CP2,
936 OPC_PCMPEQB = (28 << 21) | (0x09) | OPC_CP2,
937 OPC_PCMPGTB = (29 << 21) | (0x09) | OPC_CP2,
939 OPC_PSLLW = (24 << 21) | (0x0A) | OPC_CP2,
940 OPC_PSLLH = (25 << 21) | (0x0A) | OPC_CP2,
941 OPC_PMULLH = (26 << 21) | (0x0A) | OPC_CP2,
942 OPC_PMULHH = (27 << 21) | (0x0A) | OPC_CP2,
943 OPC_PMULUW = (28 << 21) | (0x0A) | OPC_CP2,
944 OPC_PMULHUH = (29 << 21) | (0x0A) | OPC_CP2,
946 OPC_PSRLW = (24 << 21) | (0x0B) | OPC_CP2,
947 OPC_PSRLH = (25 << 21) | (0x0B) | OPC_CP2,
948 OPC_PSRAW = (26 << 21) | (0x0B) | OPC_CP2,
949 OPC_PSRAH = (27 << 21) | (0x0B) | OPC_CP2,
950 OPC_PUNPCKLWD = (28 << 21) | (0x0B) | OPC_CP2,
951 OPC_PUNPCKHWD = (29 << 21) | (0x0B) | OPC_CP2,
953 OPC_ADDU_CP2 = (24 << 21) | (0x0C) | OPC_CP2,
954 OPC_OR_CP2 = (25 << 21) | (0x0C) | OPC_CP2,
955 OPC_ADD_CP2 = (26 << 21) | (0x0C) | OPC_CP2,
956 OPC_DADD_CP2 = (27 << 21) | (0x0C) | OPC_CP2,
957 OPC_SEQU_CP2 = (28 << 21) | (0x0C) | OPC_CP2,
958 OPC_SEQ_CP2 = (29 << 21) | (0x0C) | OPC_CP2,
960 OPC_SUBU_CP2 = (24 << 21) | (0x0D) | OPC_CP2,
961 OPC_PASUBUB = (25 << 21) | (0x0D) | OPC_CP2,
962 OPC_SUB_CP2 = (26 << 21) | (0x0D) | OPC_CP2,
963 OPC_DSUB_CP2 = (27 << 21) | (0x0D) | OPC_CP2,
964 OPC_SLTU_CP2 = (28 << 21) | (0x0D) | OPC_CP2,
965 OPC_SLT_CP2 = (29 << 21) | (0x0D) | OPC_CP2,
967 OPC_SLL_CP2 = (24 << 21) | (0x0E) | OPC_CP2,
968 OPC_DSLL_CP2 = (25 << 21) | (0x0E) | OPC_CP2,
969 OPC_PEXTRH = (26 << 21) | (0x0E) | OPC_CP2,
970 OPC_PMADDHW = (27 << 21) | (0x0E) | OPC_CP2,
971 OPC_SLEU_CP2 = (28 << 21) | (0x0E) | OPC_CP2,
972 OPC_SLE_CP2 = (29 << 21) | (0x0E) | OPC_CP2,
974 OPC_SRL_CP2 = (24 << 21) | (0x0F) | OPC_CP2,
975 OPC_DSRL_CP2 = (25 << 21) | (0x0F) | OPC_CP2,
976 OPC_SRA_CP2 = (26 << 21) | (0x0F) | OPC_CP2,
977 OPC_DSRA_CP2 = (27 << 21) | (0x0F) | OPC_CP2,
978 OPC_BIADD = (28 << 21) | (0x0F) | OPC_CP2,
979 OPC_PMOVMSKB = (29 << 21) | (0x0F) | OPC_CP2,
983 #define MASK_CP3(op) MASK_OP_MAJOR(op) | (op & 0x3F)
985 enum {
986 OPC_LWXC1 = 0x00 | OPC_CP3,
987 OPC_LDXC1 = 0x01 | OPC_CP3,
988 OPC_LUXC1 = 0x05 | OPC_CP3,
989 OPC_SWXC1 = 0x08 | OPC_CP3,
990 OPC_SDXC1 = 0x09 | OPC_CP3,
991 OPC_SUXC1 = 0x0D | OPC_CP3,
992 OPC_PREFX = 0x0F | OPC_CP3,
993 OPC_ALNV_PS = 0x1E | OPC_CP3,
994 OPC_MADD_S = 0x20 | OPC_CP3,
995 OPC_MADD_D = 0x21 | OPC_CP3,
996 OPC_MADD_PS = 0x26 | OPC_CP3,
997 OPC_MSUB_S = 0x28 | OPC_CP3,
998 OPC_MSUB_D = 0x29 | OPC_CP3,
999 OPC_MSUB_PS = 0x2E | OPC_CP3,
1000 OPC_NMADD_S = 0x30 | OPC_CP3,
1001 OPC_NMADD_D = 0x31 | OPC_CP3,
1002 OPC_NMADD_PS= 0x36 | OPC_CP3,
1003 OPC_NMSUB_S = 0x38 | OPC_CP3,
1004 OPC_NMSUB_D = 0x39 | OPC_CP3,
1005 OPC_NMSUB_PS= 0x3E | OPC_CP3,
1008 /* global register indices */
1009 static TCGv_ptr cpu_env;
1010 static TCGv cpu_gpr[32], cpu_PC;
1011 static TCGv cpu_HI[MIPS_DSP_ACC], cpu_LO[MIPS_DSP_ACC], cpu_ACX[MIPS_DSP_ACC];
1012 static TCGv cpu_dspctrl, btarget, bcond;
1013 static TCGv_i32 hflags;
1014 static TCGv_i32 fpu_fcr0, fpu_fcr31;
1015 static TCGv_i64 fpu_f64[32];
1017 static uint32_t gen_opc_hflags[OPC_BUF_SIZE];
1018 static target_ulong gen_opc_btarget[OPC_BUF_SIZE];
1020 #include "exec/gen-icount.h"
1022 #define gen_helper_0e0i(name, arg) do { \
1023 TCGv_i32 helper_tmp = tcg_const_i32(arg); \
1024 gen_helper_##name(cpu_env, helper_tmp); \
1025 tcg_temp_free_i32(helper_tmp); \
1026 } while(0)
1028 #define gen_helper_0e1i(name, arg1, arg2) do { \
1029 TCGv_i32 helper_tmp = tcg_const_i32(arg2); \
1030 gen_helper_##name(cpu_env, arg1, helper_tmp); \
1031 tcg_temp_free_i32(helper_tmp); \
1032 } while(0)
1034 #define gen_helper_1e0i(name, ret, arg1) do { \
1035 TCGv_i32 helper_tmp = tcg_const_i32(arg1); \
1036 gen_helper_##name(ret, cpu_env, helper_tmp); \
1037 tcg_temp_free_i32(helper_tmp); \
1038 } while(0)
1040 #define gen_helper_1e1i(name, ret, arg1, arg2) do { \
1041 TCGv_i32 helper_tmp = tcg_const_i32(arg2); \
1042 gen_helper_##name(ret, cpu_env, arg1, helper_tmp); \
1043 tcg_temp_free_i32(helper_tmp); \
1044 } while(0)
1046 #define gen_helper_0e2i(name, arg1, arg2, arg3) do { \
1047 TCGv_i32 helper_tmp = tcg_const_i32(arg3); \
1048 gen_helper_##name(cpu_env, arg1, arg2, helper_tmp); \
1049 tcg_temp_free_i32(helper_tmp); \
1050 } while(0)
1052 #define gen_helper_1e2i(name, ret, arg1, arg2, arg3) do { \
1053 TCGv_i32 helper_tmp = tcg_const_i32(arg3); \
1054 gen_helper_##name(ret, cpu_env, arg1, arg2, helper_tmp); \
1055 tcg_temp_free_i32(helper_tmp); \
1056 } while(0)
1058 #define gen_helper_0e3i(name, arg1, arg2, arg3, arg4) do { \
1059 TCGv_i32 helper_tmp = tcg_const_i32(arg4); \
1060 gen_helper_##name(cpu_env, arg1, arg2, arg3, helper_tmp); \
1061 tcg_temp_free_i32(helper_tmp); \
1062 } while(0)
1064 typedef struct DisasContext {
1065 struct TranslationBlock *tb;
1066 target_ulong pc, saved_pc;
1067 uint32_t opcode;
1068 int singlestep_enabled;
1069 int insn_flags;
1070 /* Routine used to access memory */
1071 int mem_idx;
1072 uint32_t hflags, saved_hflags;
1073 int bstate;
1074 target_ulong btarget;
1075 } DisasContext;
1077 enum {
1078 BS_NONE = 0, /* We go out of the TB without reaching a branch or an
1079 * exception condition */
1080 BS_STOP = 1, /* We want to stop translation for any reason */
1081 BS_BRANCH = 2, /* We reached a branch condition */
1082 BS_EXCP = 3, /* We reached an exception condition */
1085 static const char * const regnames[] = {
1086 "r0", "at", "v0", "v1", "a0", "a1", "a2", "a3",
1087 "t0", "t1", "t2", "t3", "t4", "t5", "t6", "t7",
1088 "s0", "s1", "s2", "s3", "s4", "s5", "s6", "s7",
1089 "t8", "t9", "k0", "k1", "gp", "sp", "s8", "ra",
1092 static const char * const regnames_HI[] = {
1093 "HI0", "HI1", "HI2", "HI3",
1096 static const char * const regnames_LO[] = {
1097 "LO0", "LO1", "LO2", "LO3",
1100 static const char * const regnames_ACX[] = {
1101 "ACX0", "ACX1", "ACX2", "ACX3",
1104 static const char * const fregnames[] = {
1105 "f0", "f1", "f2", "f3", "f4", "f5", "f6", "f7",
1106 "f8", "f9", "f10", "f11", "f12", "f13", "f14", "f15",
1107 "f16", "f17", "f18", "f19", "f20", "f21", "f22", "f23",
1108 "f24", "f25", "f26", "f27", "f28", "f29", "f30", "f31",
1111 #define MIPS_DEBUG(fmt, ...) \
1112 do { \
1113 if (MIPS_DEBUG_DISAS) { \
1114 qemu_log_mask(CPU_LOG_TB_IN_ASM, \
1115 TARGET_FMT_lx ": %08x " fmt "\n", \
1116 ctx->pc, ctx->opcode , ## __VA_ARGS__); \
1118 } while (0)
1120 #define LOG_DISAS(...) \
1121 do { \
1122 if (MIPS_DEBUG_DISAS) { \
1123 qemu_log_mask(CPU_LOG_TB_IN_ASM, ## __VA_ARGS__); \
1125 } while (0)
1127 #define MIPS_INVAL(op) \
1128 MIPS_DEBUG("Invalid %s %03x %03x %03x", op, ctx->opcode >> 26, \
1129 ctx->opcode & 0x3F, ((ctx->opcode >> 16) & 0x1F))
1131 /* General purpose registers moves. */
1132 static inline void gen_load_gpr (TCGv t, int reg)
1134 if (reg == 0)
1135 tcg_gen_movi_tl(t, 0);
1136 else
1137 tcg_gen_mov_tl(t, cpu_gpr[reg]);
1140 static inline void gen_store_gpr (TCGv t, int reg)
1142 if (reg != 0)
1143 tcg_gen_mov_tl(cpu_gpr[reg], t);
1146 /* Moves to/from ACX register. */
1147 static inline void gen_load_ACX (TCGv t, int reg)
1149 tcg_gen_mov_tl(t, cpu_ACX[reg]);
1152 static inline void gen_store_ACX (TCGv t, int reg)
1154 tcg_gen_mov_tl(cpu_ACX[reg], t);
1157 /* Moves to/from shadow registers. */
1158 static inline void gen_load_srsgpr (int from, int to)
1160 TCGv t0 = tcg_temp_new();
1162 if (from == 0)
1163 tcg_gen_movi_tl(t0, 0);
1164 else {
1165 TCGv_i32 t2 = tcg_temp_new_i32();
1166 TCGv_ptr addr = tcg_temp_new_ptr();
1168 tcg_gen_ld_i32(t2, cpu_env, offsetof(CPUMIPSState, CP0_SRSCtl));
1169 tcg_gen_shri_i32(t2, t2, CP0SRSCtl_PSS);
1170 tcg_gen_andi_i32(t2, t2, 0xf);
1171 tcg_gen_muli_i32(t2, t2, sizeof(target_ulong) * 32);
1172 tcg_gen_ext_i32_ptr(addr, t2);
1173 tcg_gen_add_ptr(addr, cpu_env, addr);
1175 tcg_gen_ld_tl(t0, addr, sizeof(target_ulong) * from);
1176 tcg_temp_free_ptr(addr);
1177 tcg_temp_free_i32(t2);
1179 gen_store_gpr(t0, to);
1180 tcg_temp_free(t0);
1183 static inline void gen_store_srsgpr (int from, int to)
1185 if (to != 0) {
1186 TCGv t0 = tcg_temp_new();
1187 TCGv_i32 t2 = tcg_temp_new_i32();
1188 TCGv_ptr addr = tcg_temp_new_ptr();
1190 gen_load_gpr(t0, from);
1191 tcg_gen_ld_i32(t2, cpu_env, offsetof(CPUMIPSState, CP0_SRSCtl));
1192 tcg_gen_shri_i32(t2, t2, CP0SRSCtl_PSS);
1193 tcg_gen_andi_i32(t2, t2, 0xf);
1194 tcg_gen_muli_i32(t2, t2, sizeof(target_ulong) * 32);
1195 tcg_gen_ext_i32_ptr(addr, t2);
1196 tcg_gen_add_ptr(addr, cpu_env, addr);
1198 tcg_gen_st_tl(t0, addr, sizeof(target_ulong) * to);
1199 tcg_temp_free_ptr(addr);
1200 tcg_temp_free_i32(t2);
1201 tcg_temp_free(t0);
1205 /* Floating point register moves. */
1206 static void gen_load_fpr32(TCGv_i32 t, int reg)
1208 tcg_gen_trunc_i64_i32(t, fpu_f64[reg]);
1211 static void gen_store_fpr32(TCGv_i32 t, int reg)
1213 TCGv_i64 t64 = tcg_temp_new_i64();
1214 tcg_gen_extu_i32_i64(t64, t);
1215 tcg_gen_deposit_i64(fpu_f64[reg], fpu_f64[reg], t64, 0, 32);
1216 tcg_temp_free_i64(t64);
1219 static void gen_load_fpr32h(TCGv_i32 t, int reg)
1221 TCGv_i64 t64 = tcg_temp_new_i64();
1222 tcg_gen_shri_i64(t64, fpu_f64[reg], 32);
1223 tcg_gen_trunc_i64_i32(t, t64);
1224 tcg_temp_free_i64(t64);
1227 static void gen_store_fpr32h(TCGv_i32 t, int reg)
1229 TCGv_i64 t64 = tcg_temp_new_i64();
1230 tcg_gen_extu_i32_i64(t64, t);
1231 tcg_gen_deposit_i64(fpu_f64[reg], fpu_f64[reg], t64, 32, 32);
1232 tcg_temp_free_i64(t64);
1235 static void gen_load_fpr64(DisasContext *ctx, TCGv_i64 t, int reg)
1237 if (ctx->hflags & MIPS_HFLAG_F64) {
1238 tcg_gen_mov_i64(t, fpu_f64[reg]);
1239 } else {
1240 tcg_gen_concat32_i64(t, fpu_f64[reg & ~1], fpu_f64[reg | 1]);
1244 static void gen_store_fpr64(DisasContext *ctx, TCGv_i64 t, int reg)
1246 if (ctx->hflags & MIPS_HFLAG_F64) {
1247 tcg_gen_mov_i64(fpu_f64[reg], t);
1248 } else {
1249 TCGv_i64 t0;
1250 tcg_gen_deposit_i64(fpu_f64[reg & ~1], fpu_f64[reg & ~1], t, 0, 32);
1251 t0 = tcg_temp_new_i64();
1252 tcg_gen_shri_i64(t0, t, 32);
1253 tcg_gen_deposit_i64(fpu_f64[reg | 1], fpu_f64[reg | 1], t0, 0, 32);
1254 tcg_temp_free_i64(t0);
1258 static inline int get_fp_bit (int cc)
1260 if (cc)
1261 return 24 + cc;
1262 else
1263 return 23;
1266 /* Tests */
1267 static inline void gen_save_pc(target_ulong pc)
1269 tcg_gen_movi_tl(cpu_PC, pc);
1272 static inline void save_cpu_state (DisasContext *ctx, int do_save_pc)
1274 LOG_DISAS("hflags %08x saved %08x\n", ctx->hflags, ctx->saved_hflags);
1275 if (do_save_pc && ctx->pc != ctx->saved_pc) {
1276 gen_save_pc(ctx->pc);
1277 ctx->saved_pc = ctx->pc;
1279 if (ctx->hflags != ctx->saved_hflags) {
1280 tcg_gen_movi_i32(hflags, ctx->hflags);
1281 ctx->saved_hflags = ctx->hflags;
1282 switch (ctx->hflags & MIPS_HFLAG_BMASK_BASE) {
1283 case MIPS_HFLAG_BR:
1284 break;
1285 case MIPS_HFLAG_BC:
1286 case MIPS_HFLAG_BL:
1287 case MIPS_HFLAG_B:
1288 tcg_gen_movi_tl(btarget, ctx->btarget);
1289 break;
1294 static inline void restore_cpu_state (CPUMIPSState *env, DisasContext *ctx)
1296 ctx->saved_hflags = ctx->hflags;
1297 switch (ctx->hflags & MIPS_HFLAG_BMASK_BASE) {
1298 case MIPS_HFLAG_BR:
1299 break;
1300 case MIPS_HFLAG_BC:
1301 case MIPS_HFLAG_BL:
1302 case MIPS_HFLAG_B:
1303 ctx->btarget = env->btarget;
1304 break;
1308 static inline void
1309 generate_exception_err (DisasContext *ctx, int excp, int err)
1311 TCGv_i32 texcp = tcg_const_i32(excp);
1312 TCGv_i32 terr = tcg_const_i32(err);
1313 save_cpu_state(ctx, 1);
1314 gen_helper_raise_exception_err(cpu_env, texcp, terr);
1315 tcg_temp_free_i32(terr);
1316 tcg_temp_free_i32(texcp);
1319 static inline void
1320 generate_exception (DisasContext *ctx, int excp)
1322 save_cpu_state(ctx, 1);
1323 gen_helper_0e0i(raise_exception, excp);
1326 /* Addresses computation */
1327 static inline void gen_op_addr_add (DisasContext *ctx, TCGv ret, TCGv arg0, TCGv arg1)
1329 tcg_gen_add_tl(ret, arg0, arg1);
1331 #if defined(TARGET_MIPS64)
1332 /* For compatibility with 32-bit code, data reference in user mode
1333 with Status_UX = 0 should be casted to 32-bit and sign extended.
1334 See the MIPS64 PRA manual, section 4.10. */
1335 if (((ctx->hflags & MIPS_HFLAG_KSU) == MIPS_HFLAG_UM) &&
1336 !(ctx->hflags & MIPS_HFLAG_UX)) {
1337 tcg_gen_ext32s_i64(ret, ret);
1339 #endif
1342 static inline void check_cp0_enabled(DisasContext *ctx)
1344 if (unlikely(!(ctx->hflags & MIPS_HFLAG_CP0)))
1345 generate_exception_err(ctx, EXCP_CpU, 0);
1348 static inline void check_cp1_enabled(DisasContext *ctx)
1350 if (unlikely(!(ctx->hflags & MIPS_HFLAG_FPU)))
1351 generate_exception_err(ctx, EXCP_CpU, 1);
1354 /* Verify that the processor is running with COP1X instructions enabled.
1355 This is associated with the nabla symbol in the MIPS32 and MIPS64
1356 opcode tables. */
1358 static inline void check_cop1x(DisasContext *ctx)
1360 if (unlikely(!(ctx->hflags & MIPS_HFLAG_COP1X)))
1361 generate_exception(ctx, EXCP_RI);
1364 /* Verify that the processor is running with 64-bit floating-point
1365 operations enabled. */
1367 static inline void check_cp1_64bitmode(DisasContext *ctx)
1369 if (unlikely(~ctx->hflags & (MIPS_HFLAG_F64 | MIPS_HFLAG_COP1X)))
1370 generate_exception(ctx, EXCP_RI);
1374 * Verify if floating point register is valid; an operation is not defined
1375 * if bit 0 of any register specification is set and the FR bit in the
1376 * Status register equals zero, since the register numbers specify an
1377 * even-odd pair of adjacent coprocessor general registers. When the FR bit
1378 * in the Status register equals one, both even and odd register numbers
1379 * are valid. This limitation exists only for 64 bit wide (d,l,ps) registers.
1381 * Multiple 64 bit wide registers can be checked by calling
1382 * gen_op_cp1_registers(freg1 | freg2 | ... | fregN);
1384 static inline void check_cp1_registers(DisasContext *ctx, int regs)
1386 if (unlikely(!(ctx->hflags & MIPS_HFLAG_F64) && (regs & 1)))
1387 generate_exception(ctx, EXCP_RI);
1390 /* Verify that the processor is running with DSP instructions enabled.
1391 This is enabled by CP0 Status register MX(24) bit.
1394 static inline void check_dsp(DisasContext *ctx)
1396 if (unlikely(!(ctx->hflags & MIPS_HFLAG_DSP))) {
1397 if (ctx->insn_flags & ASE_DSP) {
1398 generate_exception(ctx, EXCP_DSPDIS);
1399 } else {
1400 generate_exception(ctx, EXCP_RI);
1405 static inline void check_dspr2(DisasContext *ctx)
1407 if (unlikely(!(ctx->hflags & MIPS_HFLAG_DSPR2))) {
1408 if (ctx->insn_flags & ASE_DSP) {
1409 generate_exception(ctx, EXCP_DSPDIS);
1410 } else {
1411 generate_exception(ctx, EXCP_RI);
1416 /* This code generates a "reserved instruction" exception if the
1417 CPU does not support the instruction set corresponding to flags. */
1418 static inline void check_insn(DisasContext *ctx, int flags)
1420 if (unlikely(!(ctx->insn_flags & flags))) {
1421 generate_exception(ctx, EXCP_RI);
1425 /* This code generates a "reserved instruction" exception if 64-bit
1426 instructions are not enabled. */
1427 static inline void check_mips_64(DisasContext *ctx)
1429 if (unlikely(!(ctx->hflags & MIPS_HFLAG_64)))
1430 generate_exception(ctx, EXCP_RI);
1433 /* Define small wrappers for gen_load_fpr* so that we have a uniform
1434 calling interface for 32 and 64-bit FPRs. No sense in changing
1435 all callers for gen_load_fpr32 when we need the CTX parameter for
1436 this one use. */
1437 #define gen_ldcmp_fpr32(ctx, x, y) gen_load_fpr32(x, y)
1438 #define gen_ldcmp_fpr64(ctx, x, y) gen_load_fpr64(ctx, x, y)
1439 #define FOP_CONDS(type, abs, fmt, ifmt, bits) \
1440 static inline void gen_cmp ## type ## _ ## fmt(DisasContext *ctx, int n, \
1441 int ft, int fs, int cc) \
1443 TCGv_i##bits fp0 = tcg_temp_new_i##bits (); \
1444 TCGv_i##bits fp1 = tcg_temp_new_i##bits (); \
1445 switch (ifmt) { \
1446 case FMT_PS: \
1447 check_cp1_64bitmode(ctx); \
1448 break; \
1449 case FMT_D: \
1450 if (abs) { \
1451 check_cop1x(ctx); \
1453 check_cp1_registers(ctx, fs | ft); \
1454 break; \
1455 case FMT_S: \
1456 if (abs) { \
1457 check_cop1x(ctx); \
1459 break; \
1461 gen_ldcmp_fpr##bits (ctx, fp0, fs); \
1462 gen_ldcmp_fpr##bits (ctx, fp1, ft); \
1463 switch (n) { \
1464 case 0: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _f, fp0, fp1, cc); break;\
1465 case 1: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _un, fp0, fp1, cc); break;\
1466 case 2: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _eq, fp0, fp1, cc); break;\
1467 case 3: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ueq, fp0, fp1, cc); break;\
1468 case 4: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _olt, fp0, fp1, cc); break;\
1469 case 5: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ult, fp0, fp1, cc); break;\
1470 case 6: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ole, fp0, fp1, cc); break;\
1471 case 7: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ule, fp0, fp1, cc); break;\
1472 case 8: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _sf, fp0, fp1, cc); break;\
1473 case 9: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ngle, fp0, fp1, cc); break;\
1474 case 10: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _seq, fp0, fp1, cc); break;\
1475 case 11: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ngl, fp0, fp1, cc); break;\
1476 case 12: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _lt, fp0, fp1, cc); break;\
1477 case 13: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _nge, fp0, fp1, cc); break;\
1478 case 14: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _le, fp0, fp1, cc); break;\
1479 case 15: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ngt, fp0, fp1, cc); break;\
1480 default: abort(); \
1482 tcg_temp_free_i##bits (fp0); \
1483 tcg_temp_free_i##bits (fp1); \
1486 FOP_CONDS(, 0, d, FMT_D, 64)
1487 FOP_CONDS(abs, 1, d, FMT_D, 64)
1488 FOP_CONDS(, 0, s, FMT_S, 32)
1489 FOP_CONDS(abs, 1, s, FMT_S, 32)
1490 FOP_CONDS(, 0, ps, FMT_PS, 64)
1491 FOP_CONDS(abs, 1, ps, FMT_PS, 64)
1492 #undef FOP_CONDS
1493 #undef gen_ldcmp_fpr32
1494 #undef gen_ldcmp_fpr64
1496 /* load/store instructions. */
1497 #ifdef CONFIG_USER_ONLY
1498 #define OP_LD_ATOMIC(insn,fname) \
1499 static inline void op_ld_##insn(TCGv ret, TCGv arg1, DisasContext *ctx) \
1501 TCGv t0 = tcg_temp_new(); \
1502 tcg_gen_mov_tl(t0, arg1); \
1503 tcg_gen_qemu_##fname(ret, arg1, ctx->mem_idx); \
1504 tcg_gen_st_tl(t0, cpu_env, offsetof(CPUMIPSState, lladdr)); \
1505 tcg_gen_st_tl(ret, cpu_env, offsetof(CPUMIPSState, llval)); \
1506 tcg_temp_free(t0); \
1508 #else
1509 #define OP_LD_ATOMIC(insn,fname) \
1510 static inline void op_ld_##insn(TCGv ret, TCGv arg1, DisasContext *ctx) \
1512 gen_helper_1e1i(insn, ret, arg1, ctx->mem_idx); \
1514 #endif
1515 OP_LD_ATOMIC(ll,ld32s);
1516 #if defined(TARGET_MIPS64)
1517 OP_LD_ATOMIC(lld,ld64);
1518 #endif
1519 #undef OP_LD_ATOMIC
1521 #ifdef CONFIG_USER_ONLY
1522 #define OP_ST_ATOMIC(insn,fname,ldname,almask) \
1523 static inline void op_st_##insn(TCGv arg1, TCGv arg2, int rt, DisasContext *ctx) \
1525 TCGv t0 = tcg_temp_new(); \
1526 int l1 = gen_new_label(); \
1527 int l2 = gen_new_label(); \
1529 tcg_gen_andi_tl(t0, arg2, almask); \
1530 tcg_gen_brcondi_tl(TCG_COND_EQ, t0, 0, l1); \
1531 tcg_gen_st_tl(arg2, cpu_env, offsetof(CPUMIPSState, CP0_BadVAddr)); \
1532 generate_exception(ctx, EXCP_AdES); \
1533 gen_set_label(l1); \
1534 tcg_gen_ld_tl(t0, cpu_env, offsetof(CPUMIPSState, lladdr)); \
1535 tcg_gen_brcond_tl(TCG_COND_NE, arg2, t0, l2); \
1536 tcg_gen_movi_tl(t0, rt | ((almask << 3) & 0x20)); \
1537 tcg_gen_st_tl(t0, cpu_env, offsetof(CPUMIPSState, llreg)); \
1538 tcg_gen_st_tl(arg1, cpu_env, offsetof(CPUMIPSState, llnewval)); \
1539 gen_helper_0e0i(raise_exception, EXCP_SC); \
1540 gen_set_label(l2); \
1541 tcg_gen_movi_tl(t0, 0); \
1542 gen_store_gpr(t0, rt); \
1543 tcg_temp_free(t0); \
1545 #else
1546 #define OP_ST_ATOMIC(insn,fname,ldname,almask) \
1547 static inline void op_st_##insn(TCGv arg1, TCGv arg2, int rt, DisasContext *ctx) \
1549 TCGv t0 = tcg_temp_new(); \
1550 gen_helper_1e2i(insn, t0, arg1, arg2, ctx->mem_idx); \
1551 gen_store_gpr(t0, rt); \
1552 tcg_temp_free(t0); \
1554 #endif
1555 OP_ST_ATOMIC(sc,st32,ld32s,0x3);
1556 #if defined(TARGET_MIPS64)
1557 OP_ST_ATOMIC(scd,st64,ld64,0x7);
1558 #endif
1559 #undef OP_ST_ATOMIC
1561 static void gen_base_offset_addr (DisasContext *ctx, TCGv addr,
1562 int base, int16_t offset)
1564 if (base == 0) {
1565 tcg_gen_movi_tl(addr, offset);
1566 } else if (offset == 0) {
1567 gen_load_gpr(addr, base);
1568 } else {
1569 tcg_gen_movi_tl(addr, offset);
1570 gen_op_addr_add(ctx, addr, cpu_gpr[base], addr);
1574 static target_ulong pc_relative_pc (DisasContext *ctx)
1576 target_ulong pc = ctx->pc;
1578 if (ctx->hflags & MIPS_HFLAG_BMASK) {
1579 int branch_bytes = ctx->hflags & MIPS_HFLAG_BDS16 ? 2 : 4;
1581 pc -= branch_bytes;
1584 pc &= ~(target_ulong)3;
1585 return pc;
1588 /* Load */
1589 static void gen_ld(DisasContext *ctx, uint32_t opc,
1590 int rt, int base, int16_t offset)
1592 const char *opn = "ld";
1593 TCGv t0, t1, t2;
1595 if (rt == 0 && ctx->insn_flags & (INSN_LOONGSON2E | INSN_LOONGSON2F)) {
1596 /* Loongson CPU uses a load to zero register for prefetch.
1597 We emulate it as a NOP. On other CPU we must perform the
1598 actual memory access. */
1599 MIPS_DEBUG("NOP");
1600 return;
1603 t0 = tcg_temp_new();
1604 gen_base_offset_addr(ctx, t0, base, offset);
1606 switch (opc) {
1607 #if defined(TARGET_MIPS64)
1608 case OPC_LWU:
1609 tcg_gen_qemu_ld32u(t0, t0, ctx->mem_idx);
1610 gen_store_gpr(t0, rt);
1611 opn = "lwu";
1612 break;
1613 case OPC_LD:
1614 tcg_gen_qemu_ld64(t0, t0, ctx->mem_idx);
1615 gen_store_gpr(t0, rt);
1616 opn = "ld";
1617 break;
1618 case OPC_LLD:
1619 save_cpu_state(ctx, 1);
1620 op_ld_lld(t0, t0, ctx);
1621 gen_store_gpr(t0, rt);
1622 opn = "lld";
1623 break;
1624 case OPC_LDL:
1625 t1 = tcg_temp_new();
1626 tcg_gen_andi_tl(t1, t0, 7);
1627 #ifndef TARGET_WORDS_BIGENDIAN
1628 tcg_gen_xori_tl(t1, t1, 7);
1629 #endif
1630 tcg_gen_shli_tl(t1, t1, 3);
1631 tcg_gen_andi_tl(t0, t0, ~7);
1632 tcg_gen_qemu_ld64(t0, t0, ctx->mem_idx);
1633 tcg_gen_shl_tl(t0, t0, t1);
1634 tcg_gen_xori_tl(t1, t1, 63);
1635 t2 = tcg_const_tl(0x7fffffffffffffffull);
1636 tcg_gen_shr_tl(t2, t2, t1);
1637 gen_load_gpr(t1, rt);
1638 tcg_gen_and_tl(t1, t1, t2);
1639 tcg_temp_free(t2);
1640 tcg_gen_or_tl(t0, t0, t1);
1641 tcg_temp_free(t1);
1642 gen_store_gpr(t0, rt);
1643 opn = "ldl";
1644 break;
1645 case OPC_LDR:
1646 t1 = tcg_temp_new();
1647 tcg_gen_andi_tl(t1, t0, 7);
1648 #ifdef TARGET_WORDS_BIGENDIAN
1649 tcg_gen_xori_tl(t1, t1, 7);
1650 #endif
1651 tcg_gen_shli_tl(t1, t1, 3);
1652 tcg_gen_andi_tl(t0, t0, ~7);
1653 tcg_gen_qemu_ld64(t0, t0, ctx->mem_idx);
1654 tcg_gen_shr_tl(t0, t0, t1);
1655 tcg_gen_xori_tl(t1, t1, 63);
1656 t2 = tcg_const_tl(0xfffffffffffffffeull);
1657 tcg_gen_shl_tl(t2, t2, t1);
1658 gen_load_gpr(t1, rt);
1659 tcg_gen_and_tl(t1, t1, t2);
1660 tcg_temp_free(t2);
1661 tcg_gen_or_tl(t0, t0, t1);
1662 tcg_temp_free(t1);
1663 gen_store_gpr(t0, rt);
1664 opn = "ldr";
1665 break;
1666 case OPC_LDPC:
1667 t1 = tcg_const_tl(pc_relative_pc(ctx));
1668 gen_op_addr_add(ctx, t0, t0, t1);
1669 tcg_temp_free(t1);
1670 tcg_gen_qemu_ld64(t0, t0, ctx->mem_idx);
1671 gen_store_gpr(t0, rt);
1672 opn = "ldpc";
1673 break;
1674 #endif
1675 case OPC_LWPC:
1676 t1 = tcg_const_tl(pc_relative_pc(ctx));
1677 gen_op_addr_add(ctx, t0, t0, t1);
1678 tcg_temp_free(t1);
1679 tcg_gen_qemu_ld32s(t0, t0, ctx->mem_idx);
1680 gen_store_gpr(t0, rt);
1681 opn = "lwpc";
1682 break;
1683 case OPC_LW:
1684 tcg_gen_qemu_ld32s(t0, t0, ctx->mem_idx);
1685 gen_store_gpr(t0, rt);
1686 opn = "lw";
1687 break;
1688 case OPC_LH:
1689 tcg_gen_qemu_ld16s(t0, t0, ctx->mem_idx);
1690 gen_store_gpr(t0, rt);
1691 opn = "lh";
1692 break;
1693 case OPC_LHU:
1694 tcg_gen_qemu_ld16u(t0, t0, ctx->mem_idx);
1695 gen_store_gpr(t0, rt);
1696 opn = "lhu";
1697 break;
1698 case OPC_LB:
1699 tcg_gen_qemu_ld8s(t0, t0, ctx->mem_idx);
1700 gen_store_gpr(t0, rt);
1701 opn = "lb";
1702 break;
1703 case OPC_LBU:
1704 tcg_gen_qemu_ld8u(t0, t0, ctx->mem_idx);
1705 gen_store_gpr(t0, rt);
1706 opn = "lbu";
1707 break;
1708 case OPC_LWL:
1709 t1 = tcg_temp_new();
1710 tcg_gen_andi_tl(t1, t0, 3);
1711 #ifndef TARGET_WORDS_BIGENDIAN
1712 tcg_gen_xori_tl(t1, t1, 3);
1713 #endif
1714 tcg_gen_shli_tl(t1, t1, 3);
1715 tcg_gen_andi_tl(t0, t0, ~3);
1716 tcg_gen_qemu_ld32u(t0, t0, ctx->mem_idx);
1717 tcg_gen_shl_tl(t0, t0, t1);
1718 tcg_gen_xori_tl(t1, t1, 31);
1719 t2 = tcg_const_tl(0x7fffffffull);
1720 tcg_gen_shr_tl(t2, t2, t1);
1721 gen_load_gpr(t1, rt);
1722 tcg_gen_and_tl(t1, t1, t2);
1723 tcg_temp_free(t2);
1724 tcg_gen_or_tl(t0, t0, t1);
1725 tcg_temp_free(t1);
1726 tcg_gen_ext32s_tl(t0, t0);
1727 gen_store_gpr(t0, rt);
1728 opn = "lwl";
1729 break;
1730 case OPC_LWR:
1731 t1 = tcg_temp_new();
1732 tcg_gen_andi_tl(t1, t0, 3);
1733 #ifdef TARGET_WORDS_BIGENDIAN
1734 tcg_gen_xori_tl(t1, t1, 3);
1735 #endif
1736 tcg_gen_shli_tl(t1, t1, 3);
1737 tcg_gen_andi_tl(t0, t0, ~3);
1738 tcg_gen_qemu_ld32u(t0, t0, ctx->mem_idx);
1739 tcg_gen_shr_tl(t0, t0, t1);
1740 tcg_gen_xori_tl(t1, t1, 31);
1741 t2 = tcg_const_tl(0xfffffffeull);
1742 tcg_gen_shl_tl(t2, t2, t1);
1743 gen_load_gpr(t1, rt);
1744 tcg_gen_and_tl(t1, t1, t2);
1745 tcg_temp_free(t2);
1746 tcg_gen_or_tl(t0, t0, t1);
1747 tcg_temp_free(t1);
1748 tcg_gen_ext32s_tl(t0, t0);
1749 gen_store_gpr(t0, rt);
1750 opn = "lwr";
1751 break;
1752 case OPC_LL:
1753 save_cpu_state(ctx, 1);
1754 op_ld_ll(t0, t0, ctx);
1755 gen_store_gpr(t0, rt);
1756 opn = "ll";
1757 break;
1759 (void)opn; /* avoid a compiler warning */
1760 MIPS_DEBUG("%s %s, %d(%s)", opn, regnames[rt], offset, regnames[base]);
1761 tcg_temp_free(t0);
1764 /* Store */
1765 static void gen_st (DisasContext *ctx, uint32_t opc, int rt,
1766 int base, int16_t offset)
1768 const char *opn = "st";
1769 TCGv t0 = tcg_temp_new();
1770 TCGv t1 = tcg_temp_new();
1772 gen_base_offset_addr(ctx, t0, base, offset);
1773 gen_load_gpr(t1, rt);
1774 switch (opc) {
1775 #if defined(TARGET_MIPS64)
1776 case OPC_SD:
1777 tcg_gen_qemu_st64(t1, t0, ctx->mem_idx);
1778 opn = "sd";
1779 break;
1780 case OPC_SDL:
1781 save_cpu_state(ctx, 1);
1782 gen_helper_0e2i(sdl, t1, t0, ctx->mem_idx);
1783 opn = "sdl";
1784 break;
1785 case OPC_SDR:
1786 save_cpu_state(ctx, 1);
1787 gen_helper_0e2i(sdr, t1, t0, ctx->mem_idx);
1788 opn = "sdr";
1789 break;
1790 #endif
1791 case OPC_SW:
1792 tcg_gen_qemu_st32(t1, t0, ctx->mem_idx);
1793 opn = "sw";
1794 break;
1795 case OPC_SH:
1796 tcg_gen_qemu_st16(t1, t0, ctx->mem_idx);
1797 opn = "sh";
1798 break;
1799 case OPC_SB:
1800 tcg_gen_qemu_st8(t1, t0, ctx->mem_idx);
1801 opn = "sb";
1802 break;
1803 case OPC_SWL:
1804 save_cpu_state(ctx, 1);
1805 gen_helper_0e2i(swl, t1, t0, ctx->mem_idx);
1806 opn = "swl";
1807 break;
1808 case OPC_SWR:
1809 save_cpu_state(ctx, 1);
1810 gen_helper_0e2i(swr, t1, t0, ctx->mem_idx);
1811 opn = "swr";
1812 break;
1814 (void)opn; /* avoid a compiler warning */
1815 MIPS_DEBUG("%s %s, %d(%s)", opn, regnames[rt], offset, regnames[base]);
1816 tcg_temp_free(t0);
1817 tcg_temp_free(t1);
1821 /* Store conditional */
1822 static void gen_st_cond (DisasContext *ctx, uint32_t opc, int rt,
1823 int base, int16_t offset)
1825 const char *opn = "st_cond";
1826 TCGv t0, t1;
1828 #ifdef CONFIG_USER_ONLY
1829 t0 = tcg_temp_local_new();
1830 t1 = tcg_temp_local_new();
1831 #else
1832 t0 = tcg_temp_new();
1833 t1 = tcg_temp_new();
1834 #endif
1835 gen_base_offset_addr(ctx, t0, base, offset);
1836 gen_load_gpr(t1, rt);
1837 switch (opc) {
1838 #if defined(TARGET_MIPS64)
1839 case OPC_SCD:
1840 save_cpu_state(ctx, 1);
1841 op_st_scd(t1, t0, rt, ctx);
1842 opn = "scd";
1843 break;
1844 #endif
1845 case OPC_SC:
1846 save_cpu_state(ctx, 1);
1847 op_st_sc(t1, t0, rt, ctx);
1848 opn = "sc";
1849 break;
1851 (void)opn; /* avoid a compiler warning */
1852 MIPS_DEBUG("%s %s, %d(%s)", opn, regnames[rt], offset, regnames[base]);
1853 tcg_temp_free(t1);
1854 tcg_temp_free(t0);
1857 /* Load and store */
1858 static void gen_flt_ldst (DisasContext *ctx, uint32_t opc, int ft,
1859 int base, int16_t offset)
1861 const char *opn = "flt_ldst";
1862 TCGv t0 = tcg_temp_new();
1864 gen_base_offset_addr(ctx, t0, base, offset);
1865 /* Don't do NOP if destination is zero: we must perform the actual
1866 memory access. */
1867 switch (opc) {
1868 case OPC_LWC1:
1870 TCGv_i32 fp0 = tcg_temp_new_i32();
1872 tcg_gen_qemu_ld32s(t0, t0, ctx->mem_idx);
1873 tcg_gen_trunc_tl_i32(fp0, t0);
1874 gen_store_fpr32(fp0, ft);
1875 tcg_temp_free_i32(fp0);
1877 opn = "lwc1";
1878 break;
1879 case OPC_SWC1:
1881 TCGv_i32 fp0 = tcg_temp_new_i32();
1882 TCGv t1 = tcg_temp_new();
1884 gen_load_fpr32(fp0, ft);
1885 tcg_gen_extu_i32_tl(t1, fp0);
1886 tcg_gen_qemu_st32(t1, t0, ctx->mem_idx);
1887 tcg_temp_free(t1);
1888 tcg_temp_free_i32(fp0);
1890 opn = "swc1";
1891 break;
1892 case OPC_LDC1:
1894 TCGv_i64 fp0 = tcg_temp_new_i64();
1896 tcg_gen_qemu_ld64(fp0, t0, ctx->mem_idx);
1897 gen_store_fpr64(ctx, fp0, ft);
1898 tcg_temp_free_i64(fp0);
1900 opn = "ldc1";
1901 break;
1902 case OPC_SDC1:
1904 TCGv_i64 fp0 = tcg_temp_new_i64();
1906 gen_load_fpr64(ctx, fp0, ft);
1907 tcg_gen_qemu_st64(fp0, t0, ctx->mem_idx);
1908 tcg_temp_free_i64(fp0);
1910 opn = "sdc1";
1911 break;
1912 default:
1913 MIPS_INVAL(opn);
1914 generate_exception(ctx, EXCP_RI);
1915 goto out;
1917 (void)opn; /* avoid a compiler warning */
1918 MIPS_DEBUG("%s %s, %d(%s)", opn, fregnames[ft], offset, regnames[base]);
1919 out:
1920 tcg_temp_free(t0);
1923 static void gen_cop1_ldst(CPUMIPSState *env, DisasContext *ctx,
1924 uint32_t op, int rt, int rs, int16_t imm)
1926 if (env->CP0_Config1 & (1 << CP0C1_FP)) {
1927 check_cp1_enabled(ctx);
1928 gen_flt_ldst(ctx, op, rt, rs, imm);
1929 } else {
1930 generate_exception_err(ctx, EXCP_CpU, 1);
1934 /* Arithmetic with immediate operand */
1935 static void gen_arith_imm(DisasContext *ctx, uint32_t opc,
1936 int rt, int rs, int16_t imm)
1938 target_ulong uimm = (target_long)imm; /* Sign extend to 32/64 bits */
1939 const char *opn = "imm arith";
1941 if (rt == 0 && opc != OPC_ADDI && opc != OPC_DADDI) {
1942 /* If no destination, treat it as a NOP.
1943 For addi, we must generate the overflow exception when needed. */
1944 MIPS_DEBUG("NOP");
1945 return;
1947 switch (opc) {
1948 case OPC_ADDI:
1950 TCGv t0 = tcg_temp_local_new();
1951 TCGv t1 = tcg_temp_new();
1952 TCGv t2 = tcg_temp_new();
1953 int l1 = gen_new_label();
1955 gen_load_gpr(t1, rs);
1956 tcg_gen_addi_tl(t0, t1, uimm);
1957 tcg_gen_ext32s_tl(t0, t0);
1959 tcg_gen_xori_tl(t1, t1, ~uimm);
1960 tcg_gen_xori_tl(t2, t0, uimm);
1961 tcg_gen_and_tl(t1, t1, t2);
1962 tcg_temp_free(t2);
1963 tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
1964 tcg_temp_free(t1);
1965 /* operands of same sign, result different sign */
1966 generate_exception(ctx, EXCP_OVERFLOW);
1967 gen_set_label(l1);
1968 tcg_gen_ext32s_tl(t0, t0);
1969 gen_store_gpr(t0, rt);
1970 tcg_temp_free(t0);
1972 opn = "addi";
1973 break;
1974 case OPC_ADDIU:
1975 if (rs != 0) {
1976 tcg_gen_addi_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
1977 tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]);
1978 } else {
1979 tcg_gen_movi_tl(cpu_gpr[rt], uimm);
1981 opn = "addiu";
1982 break;
1983 #if defined(TARGET_MIPS64)
1984 case OPC_DADDI:
1986 TCGv t0 = tcg_temp_local_new();
1987 TCGv t1 = tcg_temp_new();
1988 TCGv t2 = tcg_temp_new();
1989 int l1 = gen_new_label();
1991 gen_load_gpr(t1, rs);
1992 tcg_gen_addi_tl(t0, t1, uimm);
1994 tcg_gen_xori_tl(t1, t1, ~uimm);
1995 tcg_gen_xori_tl(t2, t0, uimm);
1996 tcg_gen_and_tl(t1, t1, t2);
1997 tcg_temp_free(t2);
1998 tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
1999 tcg_temp_free(t1);
2000 /* operands of same sign, result different sign */
2001 generate_exception(ctx, EXCP_OVERFLOW);
2002 gen_set_label(l1);
2003 gen_store_gpr(t0, rt);
2004 tcg_temp_free(t0);
2006 opn = "daddi";
2007 break;
2008 case OPC_DADDIU:
2009 if (rs != 0) {
2010 tcg_gen_addi_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
2011 } else {
2012 tcg_gen_movi_tl(cpu_gpr[rt], uimm);
2014 opn = "daddiu";
2015 break;
2016 #endif
2018 (void)opn; /* avoid a compiler warning */
2019 MIPS_DEBUG("%s %s, %s, " TARGET_FMT_lx, opn, regnames[rt], regnames[rs], uimm);
2022 /* Logic with immediate operand */
2023 static void gen_logic_imm(DisasContext *ctx, uint32_t opc,
2024 int rt, int rs, int16_t imm)
2026 target_ulong uimm;
2028 if (rt == 0) {
2029 /* If no destination, treat it as a NOP. */
2030 MIPS_DEBUG("NOP");
2031 return;
2033 uimm = (uint16_t)imm;
2034 switch (opc) {
2035 case OPC_ANDI:
2036 if (likely(rs != 0))
2037 tcg_gen_andi_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
2038 else
2039 tcg_gen_movi_tl(cpu_gpr[rt], 0);
2040 MIPS_DEBUG("andi %s, %s, " TARGET_FMT_lx, regnames[rt],
2041 regnames[rs], uimm);
2042 break;
2043 case OPC_ORI:
2044 if (rs != 0)
2045 tcg_gen_ori_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
2046 else
2047 tcg_gen_movi_tl(cpu_gpr[rt], uimm);
2048 MIPS_DEBUG("ori %s, %s, " TARGET_FMT_lx, regnames[rt],
2049 regnames[rs], uimm);
2050 break;
2051 case OPC_XORI:
2052 if (likely(rs != 0))
2053 tcg_gen_xori_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
2054 else
2055 tcg_gen_movi_tl(cpu_gpr[rt], uimm);
2056 MIPS_DEBUG("xori %s, %s, " TARGET_FMT_lx, regnames[rt],
2057 regnames[rs], uimm);
2058 break;
2059 case OPC_LUI:
2060 tcg_gen_movi_tl(cpu_gpr[rt], imm << 16);
2061 MIPS_DEBUG("lui %s, " TARGET_FMT_lx, regnames[rt], uimm);
2062 break;
2064 default:
2065 MIPS_DEBUG("Unknown logical immediate opcode %08x", opc);
2066 break;
2070 /* Set on less than with immediate operand */
2071 static void gen_slt_imm(DisasContext *ctx, uint32_t opc,
2072 int rt, int rs, int16_t imm)
2074 target_ulong uimm = (target_long)imm; /* Sign extend to 32/64 bits */
2075 const char *opn = "imm arith";
2076 TCGv t0;
2078 if (rt == 0) {
2079 /* If no destination, treat it as a NOP. */
2080 MIPS_DEBUG("NOP");
2081 return;
2083 t0 = tcg_temp_new();
2084 gen_load_gpr(t0, rs);
2085 switch (opc) {
2086 case OPC_SLTI:
2087 tcg_gen_setcondi_tl(TCG_COND_LT, cpu_gpr[rt], t0, uimm);
2088 opn = "slti";
2089 break;
2090 case OPC_SLTIU:
2091 tcg_gen_setcondi_tl(TCG_COND_LTU, cpu_gpr[rt], t0, uimm);
2092 opn = "sltiu";
2093 break;
2095 (void)opn; /* avoid a compiler warning */
2096 MIPS_DEBUG("%s %s, %s, " TARGET_FMT_lx, opn, regnames[rt], regnames[rs], uimm);
2097 tcg_temp_free(t0);
2100 /* Shifts with immediate operand */
2101 static void gen_shift_imm(DisasContext *ctx, uint32_t opc,
2102 int rt, int rs, int16_t imm)
2104 target_ulong uimm = ((uint16_t)imm) & 0x1f;
2105 const char *opn = "imm shift";
2106 TCGv t0;
2108 if (rt == 0) {
2109 /* If no destination, treat it as a NOP. */
2110 MIPS_DEBUG("NOP");
2111 return;
2114 t0 = tcg_temp_new();
2115 gen_load_gpr(t0, rs);
2116 switch (opc) {
2117 case OPC_SLL:
2118 tcg_gen_shli_tl(t0, t0, uimm);
2119 tcg_gen_ext32s_tl(cpu_gpr[rt], t0);
2120 opn = "sll";
2121 break;
2122 case OPC_SRA:
2123 tcg_gen_sari_tl(cpu_gpr[rt], t0, uimm);
2124 opn = "sra";
2125 break;
2126 case OPC_SRL:
2127 if (uimm != 0) {
2128 tcg_gen_ext32u_tl(t0, t0);
2129 tcg_gen_shri_tl(cpu_gpr[rt], t0, uimm);
2130 } else {
2131 tcg_gen_ext32s_tl(cpu_gpr[rt], t0);
2133 opn = "srl";
2134 break;
2135 case OPC_ROTR:
2136 if (uimm != 0) {
2137 TCGv_i32 t1 = tcg_temp_new_i32();
2139 tcg_gen_trunc_tl_i32(t1, t0);
2140 tcg_gen_rotri_i32(t1, t1, uimm);
2141 tcg_gen_ext_i32_tl(cpu_gpr[rt], t1);
2142 tcg_temp_free_i32(t1);
2143 } else {
2144 tcg_gen_ext32s_tl(cpu_gpr[rt], t0);
2146 opn = "rotr";
2147 break;
2148 #if defined(TARGET_MIPS64)
2149 case OPC_DSLL:
2150 tcg_gen_shli_tl(cpu_gpr[rt], t0, uimm);
2151 opn = "dsll";
2152 break;
2153 case OPC_DSRA:
2154 tcg_gen_sari_tl(cpu_gpr[rt], t0, uimm);
2155 opn = "dsra";
2156 break;
2157 case OPC_DSRL:
2158 tcg_gen_shri_tl(cpu_gpr[rt], t0, uimm);
2159 opn = "dsrl";
2160 break;
2161 case OPC_DROTR:
2162 if (uimm != 0) {
2163 tcg_gen_rotri_tl(cpu_gpr[rt], t0, uimm);
2164 } else {
2165 tcg_gen_mov_tl(cpu_gpr[rt], t0);
2167 opn = "drotr";
2168 break;
2169 case OPC_DSLL32:
2170 tcg_gen_shli_tl(cpu_gpr[rt], t0, uimm + 32);
2171 opn = "dsll32";
2172 break;
2173 case OPC_DSRA32:
2174 tcg_gen_sari_tl(cpu_gpr[rt], t0, uimm + 32);
2175 opn = "dsra32";
2176 break;
2177 case OPC_DSRL32:
2178 tcg_gen_shri_tl(cpu_gpr[rt], t0, uimm + 32);
2179 opn = "dsrl32";
2180 break;
2181 case OPC_DROTR32:
2182 tcg_gen_rotri_tl(cpu_gpr[rt], t0, uimm + 32);
2183 opn = "drotr32";
2184 break;
2185 #endif
2187 (void)opn; /* avoid a compiler warning */
2188 MIPS_DEBUG("%s %s, %s, " TARGET_FMT_lx, opn, regnames[rt], regnames[rs], uimm);
2189 tcg_temp_free(t0);
2192 /* Arithmetic */
2193 static void gen_arith(DisasContext *ctx, uint32_t opc,
2194 int rd, int rs, int rt)
2196 const char *opn = "arith";
2198 if (rd == 0 && opc != OPC_ADD && opc != OPC_SUB
2199 && opc != OPC_DADD && opc != OPC_DSUB) {
2200 /* If no destination, treat it as a NOP.
2201 For add & sub, we must generate the overflow exception when needed. */
2202 MIPS_DEBUG("NOP");
2203 return;
2206 switch (opc) {
2207 case OPC_ADD:
2209 TCGv t0 = tcg_temp_local_new();
2210 TCGv t1 = tcg_temp_new();
2211 TCGv t2 = tcg_temp_new();
2212 int l1 = gen_new_label();
2214 gen_load_gpr(t1, rs);
2215 gen_load_gpr(t2, rt);
2216 tcg_gen_add_tl(t0, t1, t2);
2217 tcg_gen_ext32s_tl(t0, t0);
2218 tcg_gen_xor_tl(t1, t1, t2);
2219 tcg_gen_xor_tl(t2, t0, t2);
2220 tcg_gen_andc_tl(t1, t2, t1);
2221 tcg_temp_free(t2);
2222 tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
2223 tcg_temp_free(t1);
2224 /* operands of same sign, result different sign */
2225 generate_exception(ctx, EXCP_OVERFLOW);
2226 gen_set_label(l1);
2227 gen_store_gpr(t0, rd);
2228 tcg_temp_free(t0);
2230 opn = "add";
2231 break;
2232 case OPC_ADDU:
2233 if (rs != 0 && rt != 0) {
2234 tcg_gen_add_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2235 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
2236 } else if (rs == 0 && rt != 0) {
2237 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rt]);
2238 } else if (rs != 0 && rt == 0) {
2239 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
2240 } else {
2241 tcg_gen_movi_tl(cpu_gpr[rd], 0);
2243 opn = "addu";
2244 break;
2245 case OPC_SUB:
2247 TCGv t0 = tcg_temp_local_new();
2248 TCGv t1 = tcg_temp_new();
2249 TCGv t2 = tcg_temp_new();
2250 int l1 = gen_new_label();
2252 gen_load_gpr(t1, rs);
2253 gen_load_gpr(t2, rt);
2254 tcg_gen_sub_tl(t0, t1, t2);
2255 tcg_gen_ext32s_tl(t0, t0);
2256 tcg_gen_xor_tl(t2, t1, t2);
2257 tcg_gen_xor_tl(t1, t0, t1);
2258 tcg_gen_and_tl(t1, t1, t2);
2259 tcg_temp_free(t2);
2260 tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
2261 tcg_temp_free(t1);
2262 /* operands of different sign, first operand and result different sign */
2263 generate_exception(ctx, EXCP_OVERFLOW);
2264 gen_set_label(l1);
2265 gen_store_gpr(t0, rd);
2266 tcg_temp_free(t0);
2268 opn = "sub";
2269 break;
2270 case OPC_SUBU:
2271 if (rs != 0 && rt != 0) {
2272 tcg_gen_sub_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2273 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
2274 } else if (rs == 0 && rt != 0) {
2275 tcg_gen_neg_tl(cpu_gpr[rd], cpu_gpr[rt]);
2276 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
2277 } else if (rs != 0 && rt == 0) {
2278 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
2279 } else {
2280 tcg_gen_movi_tl(cpu_gpr[rd], 0);
2282 opn = "subu";
2283 break;
2284 #if defined(TARGET_MIPS64)
2285 case OPC_DADD:
2287 TCGv t0 = tcg_temp_local_new();
2288 TCGv t1 = tcg_temp_new();
2289 TCGv t2 = tcg_temp_new();
2290 int l1 = gen_new_label();
2292 gen_load_gpr(t1, rs);
2293 gen_load_gpr(t2, rt);
2294 tcg_gen_add_tl(t0, t1, t2);
2295 tcg_gen_xor_tl(t1, t1, t2);
2296 tcg_gen_xor_tl(t2, t0, t2);
2297 tcg_gen_andc_tl(t1, t2, t1);
2298 tcg_temp_free(t2);
2299 tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
2300 tcg_temp_free(t1);
2301 /* operands of same sign, result different sign */
2302 generate_exception(ctx, EXCP_OVERFLOW);
2303 gen_set_label(l1);
2304 gen_store_gpr(t0, rd);
2305 tcg_temp_free(t0);
2307 opn = "dadd";
2308 break;
2309 case OPC_DADDU:
2310 if (rs != 0 && rt != 0) {
2311 tcg_gen_add_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2312 } else if (rs == 0 && rt != 0) {
2313 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rt]);
2314 } else if (rs != 0 && rt == 0) {
2315 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
2316 } else {
2317 tcg_gen_movi_tl(cpu_gpr[rd], 0);
2319 opn = "daddu";
2320 break;
2321 case OPC_DSUB:
2323 TCGv t0 = tcg_temp_local_new();
2324 TCGv t1 = tcg_temp_new();
2325 TCGv t2 = tcg_temp_new();
2326 int l1 = gen_new_label();
2328 gen_load_gpr(t1, rs);
2329 gen_load_gpr(t2, rt);
2330 tcg_gen_sub_tl(t0, t1, t2);
2331 tcg_gen_xor_tl(t2, t1, t2);
2332 tcg_gen_xor_tl(t1, t0, t1);
2333 tcg_gen_and_tl(t1, t1, t2);
2334 tcg_temp_free(t2);
2335 tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
2336 tcg_temp_free(t1);
2337 /* operands of different sign, first operand and result different sign */
2338 generate_exception(ctx, EXCP_OVERFLOW);
2339 gen_set_label(l1);
2340 gen_store_gpr(t0, rd);
2341 tcg_temp_free(t0);
2343 opn = "dsub";
2344 break;
2345 case OPC_DSUBU:
2346 if (rs != 0 && rt != 0) {
2347 tcg_gen_sub_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2348 } else if (rs == 0 && rt != 0) {
2349 tcg_gen_neg_tl(cpu_gpr[rd], cpu_gpr[rt]);
2350 } else if (rs != 0 && rt == 0) {
2351 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
2352 } else {
2353 tcg_gen_movi_tl(cpu_gpr[rd], 0);
2355 opn = "dsubu";
2356 break;
2357 #endif
2358 case OPC_MUL:
2359 if (likely(rs != 0 && rt != 0)) {
2360 tcg_gen_mul_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2361 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
2362 } else {
2363 tcg_gen_movi_tl(cpu_gpr[rd], 0);
2365 opn = "mul";
2366 break;
2368 (void)opn; /* avoid a compiler warning */
2369 MIPS_DEBUG("%s %s, %s, %s", opn, regnames[rd], regnames[rs], regnames[rt]);
2372 /* Conditional move */
2373 static void gen_cond_move(DisasContext *ctx, uint32_t opc,
2374 int rd, int rs, int rt)
2376 const char *opn = "cond move";
2377 TCGv t0, t1, t2;
2379 if (rd == 0) {
2380 /* If no destination, treat it as a NOP. */
2381 MIPS_DEBUG("NOP");
2382 return;
2385 t0 = tcg_temp_new();
2386 gen_load_gpr(t0, rt);
2387 t1 = tcg_const_tl(0);
2388 t2 = tcg_temp_new();
2389 gen_load_gpr(t2, rs);
2390 switch (opc) {
2391 case OPC_MOVN:
2392 tcg_gen_movcond_tl(TCG_COND_NE, cpu_gpr[rd], t0, t1, t2, cpu_gpr[rd]);
2393 opn = "movn";
2394 break;
2395 case OPC_MOVZ:
2396 tcg_gen_movcond_tl(TCG_COND_EQ, cpu_gpr[rd], t0, t1, t2, cpu_gpr[rd]);
2397 opn = "movz";
2398 break;
2400 tcg_temp_free(t2);
2401 tcg_temp_free(t1);
2402 tcg_temp_free(t0);
2404 (void)opn; /* avoid a compiler warning */
2405 MIPS_DEBUG("%s %s, %s, %s", opn, regnames[rd], regnames[rs], regnames[rt]);
2408 /* Logic */
2409 static void gen_logic(DisasContext *ctx, uint32_t opc,
2410 int rd, int rs, int rt)
2412 const char *opn = "logic";
2414 if (rd == 0) {
2415 /* If no destination, treat it as a NOP. */
2416 MIPS_DEBUG("NOP");
2417 return;
2420 switch (opc) {
2421 case OPC_AND:
2422 if (likely(rs != 0 && rt != 0)) {
2423 tcg_gen_and_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2424 } else {
2425 tcg_gen_movi_tl(cpu_gpr[rd], 0);
2427 opn = "and";
2428 break;
2429 case OPC_NOR:
2430 if (rs != 0 && rt != 0) {
2431 tcg_gen_nor_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2432 } else if (rs == 0 && rt != 0) {
2433 tcg_gen_not_tl(cpu_gpr[rd], cpu_gpr[rt]);
2434 } else if (rs != 0 && rt == 0) {
2435 tcg_gen_not_tl(cpu_gpr[rd], cpu_gpr[rs]);
2436 } else {
2437 tcg_gen_movi_tl(cpu_gpr[rd], ~((target_ulong)0));
2439 opn = "nor";
2440 break;
2441 case OPC_OR:
2442 if (likely(rs != 0 && rt != 0)) {
2443 tcg_gen_or_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2444 } else if (rs == 0 && rt != 0) {
2445 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rt]);
2446 } else if (rs != 0 && rt == 0) {
2447 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
2448 } else {
2449 tcg_gen_movi_tl(cpu_gpr[rd], 0);
2451 opn = "or";
2452 break;
2453 case OPC_XOR:
2454 if (likely(rs != 0 && rt != 0)) {
2455 tcg_gen_xor_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2456 } else if (rs == 0 && rt != 0) {
2457 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rt]);
2458 } else if (rs != 0 && rt == 0) {
2459 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
2460 } else {
2461 tcg_gen_movi_tl(cpu_gpr[rd], 0);
2463 opn = "xor";
2464 break;
2466 (void)opn; /* avoid a compiler warning */
2467 MIPS_DEBUG("%s %s, %s, %s", opn, regnames[rd], regnames[rs], regnames[rt]);
2470 /* Set on lower than */
2471 static void gen_slt(DisasContext *ctx, uint32_t opc,
2472 int rd, int rs, int rt)
2474 const char *opn = "slt";
2475 TCGv t0, t1;
2477 if (rd == 0) {
2478 /* If no destination, treat it as a NOP. */
2479 MIPS_DEBUG("NOP");
2480 return;
2483 t0 = tcg_temp_new();
2484 t1 = tcg_temp_new();
2485 gen_load_gpr(t0, rs);
2486 gen_load_gpr(t1, rt);
2487 switch (opc) {
2488 case OPC_SLT:
2489 tcg_gen_setcond_tl(TCG_COND_LT, cpu_gpr[rd], t0, t1);
2490 opn = "slt";
2491 break;
2492 case OPC_SLTU:
2493 tcg_gen_setcond_tl(TCG_COND_LTU, cpu_gpr[rd], t0, t1);
2494 opn = "sltu";
2495 break;
2497 (void)opn; /* avoid a compiler warning */
2498 MIPS_DEBUG("%s %s, %s, %s", opn, regnames[rd], regnames[rs], regnames[rt]);
2499 tcg_temp_free(t0);
2500 tcg_temp_free(t1);
2503 /* Shifts */
2504 static void gen_shift(DisasContext *ctx, uint32_t opc,
2505 int rd, int rs, int rt)
2507 const char *opn = "shifts";
2508 TCGv t0, t1;
2510 if (rd == 0) {
2511 /* If no destination, treat it as a NOP.
2512 For add & sub, we must generate the overflow exception when needed. */
2513 MIPS_DEBUG("NOP");
2514 return;
2517 t0 = tcg_temp_new();
2518 t1 = tcg_temp_new();
2519 gen_load_gpr(t0, rs);
2520 gen_load_gpr(t1, rt);
2521 switch (opc) {
2522 case OPC_SLLV:
2523 tcg_gen_andi_tl(t0, t0, 0x1f);
2524 tcg_gen_shl_tl(t0, t1, t0);
2525 tcg_gen_ext32s_tl(cpu_gpr[rd], t0);
2526 opn = "sllv";
2527 break;
2528 case OPC_SRAV:
2529 tcg_gen_andi_tl(t0, t0, 0x1f);
2530 tcg_gen_sar_tl(cpu_gpr[rd], t1, t0);
2531 opn = "srav";
2532 break;
2533 case OPC_SRLV:
2534 tcg_gen_ext32u_tl(t1, t1);
2535 tcg_gen_andi_tl(t0, t0, 0x1f);
2536 tcg_gen_shr_tl(t0, t1, t0);
2537 tcg_gen_ext32s_tl(cpu_gpr[rd], t0);
2538 opn = "srlv";
2539 break;
2540 case OPC_ROTRV:
2542 TCGv_i32 t2 = tcg_temp_new_i32();
2543 TCGv_i32 t3 = tcg_temp_new_i32();
2545 tcg_gen_trunc_tl_i32(t2, t0);
2546 tcg_gen_trunc_tl_i32(t3, t1);
2547 tcg_gen_andi_i32(t2, t2, 0x1f);
2548 tcg_gen_rotr_i32(t2, t3, t2);
2549 tcg_gen_ext_i32_tl(cpu_gpr[rd], t2);
2550 tcg_temp_free_i32(t2);
2551 tcg_temp_free_i32(t3);
2552 opn = "rotrv";
2554 break;
2555 #if defined(TARGET_MIPS64)
2556 case OPC_DSLLV:
2557 tcg_gen_andi_tl(t0, t0, 0x3f);
2558 tcg_gen_shl_tl(cpu_gpr[rd], t1, t0);
2559 opn = "dsllv";
2560 break;
2561 case OPC_DSRAV:
2562 tcg_gen_andi_tl(t0, t0, 0x3f);
2563 tcg_gen_sar_tl(cpu_gpr[rd], t1, t0);
2564 opn = "dsrav";
2565 break;
2566 case OPC_DSRLV:
2567 tcg_gen_andi_tl(t0, t0, 0x3f);
2568 tcg_gen_shr_tl(cpu_gpr[rd], t1, t0);
2569 opn = "dsrlv";
2570 break;
2571 case OPC_DROTRV:
2572 tcg_gen_andi_tl(t0, t0, 0x3f);
2573 tcg_gen_rotr_tl(cpu_gpr[rd], t1, t0);
2574 opn = "drotrv";
2575 break;
2576 #endif
2578 (void)opn; /* avoid a compiler warning */
2579 MIPS_DEBUG("%s %s, %s, %s", opn, regnames[rd], regnames[rs], regnames[rt]);
2580 tcg_temp_free(t0);
2581 tcg_temp_free(t1);
2584 /* Arithmetic on HI/LO registers */
2585 static void gen_HILO(DisasContext *ctx, uint32_t opc, int acc, int reg)
2587 const char *opn = "hilo";
2589 if (reg == 0 && (opc == OPC_MFHI || opc == OPC_MFLO)) {
2590 /* Treat as NOP. */
2591 MIPS_DEBUG("NOP");
2592 return;
2595 if (acc != 0) {
2596 check_dsp(ctx);
2599 switch (opc) {
2600 case OPC_MFHI:
2601 #if defined(TARGET_MIPS64)
2602 if (acc != 0) {
2603 tcg_gen_ext32s_tl(cpu_gpr[reg], cpu_HI[acc]);
2604 } else
2605 #endif
2607 tcg_gen_mov_tl(cpu_gpr[reg], cpu_HI[acc]);
2609 opn = "mfhi";
2610 break;
2611 case OPC_MFLO:
2612 #if defined(TARGET_MIPS64)
2613 if (acc != 0) {
2614 tcg_gen_ext32s_tl(cpu_gpr[reg], cpu_LO[acc]);
2615 } else
2616 #endif
2618 tcg_gen_mov_tl(cpu_gpr[reg], cpu_LO[acc]);
2620 opn = "mflo";
2621 break;
2622 case OPC_MTHI:
2623 if (reg != 0) {
2624 #if defined(TARGET_MIPS64)
2625 if (acc != 0) {
2626 tcg_gen_ext32s_tl(cpu_HI[acc], cpu_gpr[reg]);
2627 } else
2628 #endif
2630 tcg_gen_mov_tl(cpu_HI[acc], cpu_gpr[reg]);
2632 } else {
2633 tcg_gen_movi_tl(cpu_HI[acc], 0);
2635 opn = "mthi";
2636 break;
2637 case OPC_MTLO:
2638 if (reg != 0) {
2639 #if defined(TARGET_MIPS64)
2640 if (acc != 0) {
2641 tcg_gen_ext32s_tl(cpu_LO[acc], cpu_gpr[reg]);
2642 } else
2643 #endif
2645 tcg_gen_mov_tl(cpu_LO[acc], cpu_gpr[reg]);
2647 } else {
2648 tcg_gen_movi_tl(cpu_LO[acc], 0);
2650 opn = "mtlo";
2651 break;
2653 (void)opn; /* avoid a compiler warning */
2654 MIPS_DEBUG("%s %s", opn, regnames[reg]);
2657 static void gen_muldiv(DisasContext *ctx, uint32_t opc,
2658 int acc, int rs, int rt)
2660 const char *opn = "mul/div";
2661 TCGv t0, t1;
2663 t0 = tcg_temp_new();
2664 t1 = tcg_temp_new();
2666 gen_load_gpr(t0, rs);
2667 gen_load_gpr(t1, rt);
2669 if (acc != 0) {
2670 check_dsp(ctx);
2673 switch (opc) {
2674 case OPC_DIV:
2676 TCGv t2 = tcg_temp_new();
2677 TCGv t3 = tcg_temp_new();
2678 tcg_gen_ext32s_tl(t0, t0);
2679 tcg_gen_ext32s_tl(t1, t1);
2680 tcg_gen_setcondi_tl(TCG_COND_EQ, t2, t0, INT_MIN);
2681 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, -1);
2682 tcg_gen_and_tl(t2, t2, t3);
2683 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, 0);
2684 tcg_gen_or_tl(t2, t2, t3);
2685 tcg_gen_movi_tl(t3, 0);
2686 tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, t3, t2, t1);
2687 tcg_gen_div_tl(cpu_LO[acc], t0, t1);
2688 tcg_gen_rem_tl(cpu_HI[acc], t0, t1);
2689 tcg_gen_ext32s_tl(cpu_LO[acc], cpu_LO[acc]);
2690 tcg_gen_ext32s_tl(cpu_HI[acc], cpu_HI[acc]);
2691 tcg_temp_free(t3);
2692 tcg_temp_free(t2);
2694 opn = "div";
2695 break;
2696 case OPC_DIVU:
2698 TCGv t2 = tcg_const_tl(0);
2699 TCGv t3 = tcg_const_tl(1);
2700 tcg_gen_ext32u_tl(t0, t0);
2701 tcg_gen_ext32u_tl(t1, t1);
2702 tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1, t2, t3, t1);
2703 tcg_gen_divu_tl(cpu_LO[acc], t0, t1);
2704 tcg_gen_remu_tl(cpu_HI[acc], t0, t1);
2705 tcg_gen_ext32s_tl(cpu_LO[acc], cpu_LO[acc]);
2706 tcg_gen_ext32s_tl(cpu_HI[acc], cpu_HI[acc]);
2707 tcg_temp_free(t3);
2708 tcg_temp_free(t2);
2710 opn = "divu";
2711 break;
2712 case OPC_MULT:
2714 TCGv_i32 t2 = tcg_temp_new_i32();
2715 TCGv_i32 t3 = tcg_temp_new_i32();
2716 tcg_gen_trunc_tl_i32(t2, t0);
2717 tcg_gen_trunc_tl_i32(t3, t1);
2718 tcg_gen_muls2_i32(t2, t3, t2, t3);
2719 tcg_gen_ext_i32_tl(cpu_LO[acc], t2);
2720 tcg_gen_ext_i32_tl(cpu_HI[acc], t3);
2721 tcg_temp_free_i32(t2);
2722 tcg_temp_free_i32(t3);
2724 opn = "mult";
2725 break;
2726 case OPC_MULTU:
2728 TCGv_i32 t2 = tcg_temp_new_i32();
2729 TCGv_i32 t3 = tcg_temp_new_i32();
2730 tcg_gen_trunc_tl_i32(t2, t0);
2731 tcg_gen_trunc_tl_i32(t3, t1);
2732 tcg_gen_mulu2_i32(t2, t3, t2, t3);
2733 tcg_gen_ext_i32_tl(cpu_LO[acc], t2);
2734 tcg_gen_ext_i32_tl(cpu_HI[acc], t3);
2735 tcg_temp_free_i32(t2);
2736 tcg_temp_free_i32(t3);
2738 opn = "multu";
2739 break;
2740 #if defined(TARGET_MIPS64)
2741 case OPC_DDIV:
2743 TCGv t2 = tcg_temp_new();
2744 TCGv t3 = tcg_temp_new();
2745 tcg_gen_setcondi_tl(TCG_COND_EQ, t2, t0, -1LL << 63);
2746 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, -1LL);
2747 tcg_gen_and_tl(t2, t2, t3);
2748 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, 0);
2749 tcg_gen_or_tl(t2, t2, t3);
2750 tcg_gen_movi_tl(t3, 0);
2751 tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, t3, t2, t1);
2752 tcg_gen_div_tl(cpu_LO[acc], t0, t1);
2753 tcg_gen_rem_tl(cpu_HI[acc], t0, t1);
2754 tcg_temp_free(t3);
2755 tcg_temp_free(t2);
2757 opn = "ddiv";
2758 break;
2759 case OPC_DDIVU:
2761 TCGv t2 = tcg_const_tl(0);
2762 TCGv t3 = tcg_const_tl(1);
2763 tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1, t2, t3, t1);
2764 tcg_gen_divu_i64(cpu_LO[acc], t0, t1);
2765 tcg_gen_remu_i64(cpu_HI[acc], t0, t1);
2766 tcg_temp_free(t3);
2767 tcg_temp_free(t2);
2769 opn = "ddivu";
2770 break;
2771 case OPC_DMULT:
2772 tcg_gen_muls2_i64(cpu_LO[acc], cpu_HI[acc], t0, t1);
2773 opn = "dmult";
2774 break;
2775 case OPC_DMULTU:
2776 tcg_gen_mulu2_i64(cpu_LO[acc], cpu_HI[acc], t0, t1);
2777 opn = "dmultu";
2778 break;
2779 #endif
2780 case OPC_MADD:
2782 TCGv_i64 t2 = tcg_temp_new_i64();
2783 TCGv_i64 t3 = tcg_temp_new_i64();
2785 tcg_gen_ext_tl_i64(t2, t0);
2786 tcg_gen_ext_tl_i64(t3, t1);
2787 tcg_gen_mul_i64(t2, t2, t3);
2788 tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]);
2789 tcg_gen_add_i64(t2, t2, t3);
2790 tcg_temp_free_i64(t3);
2791 tcg_gen_trunc_i64_tl(t0, t2);
2792 tcg_gen_shri_i64(t2, t2, 32);
2793 tcg_gen_trunc_i64_tl(t1, t2);
2794 tcg_temp_free_i64(t2);
2795 tcg_gen_ext32s_tl(cpu_LO[acc], t0);
2796 tcg_gen_ext32s_tl(cpu_HI[acc], t1);
2798 opn = "madd";
2799 break;
2800 case OPC_MADDU:
2802 TCGv_i64 t2 = tcg_temp_new_i64();
2803 TCGv_i64 t3 = tcg_temp_new_i64();
2805 tcg_gen_ext32u_tl(t0, t0);
2806 tcg_gen_ext32u_tl(t1, t1);
2807 tcg_gen_extu_tl_i64(t2, t0);
2808 tcg_gen_extu_tl_i64(t3, t1);
2809 tcg_gen_mul_i64(t2, t2, t3);
2810 tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]);
2811 tcg_gen_add_i64(t2, t2, t3);
2812 tcg_temp_free_i64(t3);
2813 tcg_gen_trunc_i64_tl(t0, t2);
2814 tcg_gen_shri_i64(t2, t2, 32);
2815 tcg_gen_trunc_i64_tl(t1, t2);
2816 tcg_temp_free_i64(t2);
2817 tcg_gen_ext32s_tl(cpu_LO[acc], t0);
2818 tcg_gen_ext32s_tl(cpu_HI[acc], t1);
2820 opn = "maddu";
2821 break;
2822 case OPC_MSUB:
2824 TCGv_i64 t2 = tcg_temp_new_i64();
2825 TCGv_i64 t3 = tcg_temp_new_i64();
2827 tcg_gen_ext_tl_i64(t2, t0);
2828 tcg_gen_ext_tl_i64(t3, t1);
2829 tcg_gen_mul_i64(t2, t2, t3);
2830 tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]);
2831 tcg_gen_sub_i64(t2, t3, t2);
2832 tcg_temp_free_i64(t3);
2833 tcg_gen_trunc_i64_tl(t0, t2);
2834 tcg_gen_shri_i64(t2, t2, 32);
2835 tcg_gen_trunc_i64_tl(t1, t2);
2836 tcg_temp_free_i64(t2);
2837 tcg_gen_ext32s_tl(cpu_LO[acc], t0);
2838 tcg_gen_ext32s_tl(cpu_HI[acc], t1);
2840 opn = "msub";
2841 break;
2842 case OPC_MSUBU:
2844 TCGv_i64 t2 = tcg_temp_new_i64();
2845 TCGv_i64 t3 = tcg_temp_new_i64();
2847 tcg_gen_ext32u_tl(t0, t0);
2848 tcg_gen_ext32u_tl(t1, t1);
2849 tcg_gen_extu_tl_i64(t2, t0);
2850 tcg_gen_extu_tl_i64(t3, t1);
2851 tcg_gen_mul_i64(t2, t2, t3);
2852 tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]);
2853 tcg_gen_sub_i64(t2, t3, t2);
2854 tcg_temp_free_i64(t3);
2855 tcg_gen_trunc_i64_tl(t0, t2);
2856 tcg_gen_shri_i64(t2, t2, 32);
2857 tcg_gen_trunc_i64_tl(t1, t2);
2858 tcg_temp_free_i64(t2);
2859 tcg_gen_ext32s_tl(cpu_LO[acc], t0);
2860 tcg_gen_ext32s_tl(cpu_HI[acc], t1);
2862 opn = "msubu";
2863 break;
2864 default:
2865 MIPS_INVAL(opn);
2866 generate_exception(ctx, EXCP_RI);
2867 goto out;
2869 (void)opn; /* avoid a compiler warning */
2870 MIPS_DEBUG("%s %s %s", opn, regnames[rs], regnames[rt]);
2871 out:
2872 tcg_temp_free(t0);
2873 tcg_temp_free(t1);
2876 static void gen_mul_vr54xx (DisasContext *ctx, uint32_t opc,
2877 int rd, int rs, int rt)
2879 const char *opn = "mul vr54xx";
2880 TCGv t0 = tcg_temp_new();
2881 TCGv t1 = tcg_temp_new();
2883 gen_load_gpr(t0, rs);
2884 gen_load_gpr(t1, rt);
2886 switch (opc) {
2887 case OPC_VR54XX_MULS:
2888 gen_helper_muls(t0, cpu_env, t0, t1);
2889 opn = "muls";
2890 break;
2891 case OPC_VR54XX_MULSU:
2892 gen_helper_mulsu(t0, cpu_env, t0, t1);
2893 opn = "mulsu";
2894 break;
2895 case OPC_VR54XX_MACC:
2896 gen_helper_macc(t0, cpu_env, t0, t1);
2897 opn = "macc";
2898 break;
2899 case OPC_VR54XX_MACCU:
2900 gen_helper_maccu(t0, cpu_env, t0, t1);
2901 opn = "maccu";
2902 break;
2903 case OPC_VR54XX_MSAC:
2904 gen_helper_msac(t0, cpu_env, t0, t1);
2905 opn = "msac";
2906 break;
2907 case OPC_VR54XX_MSACU:
2908 gen_helper_msacu(t0, cpu_env, t0, t1);
2909 opn = "msacu";
2910 break;
2911 case OPC_VR54XX_MULHI:
2912 gen_helper_mulhi(t0, cpu_env, t0, t1);
2913 opn = "mulhi";
2914 break;
2915 case OPC_VR54XX_MULHIU:
2916 gen_helper_mulhiu(t0, cpu_env, t0, t1);
2917 opn = "mulhiu";
2918 break;
2919 case OPC_VR54XX_MULSHI:
2920 gen_helper_mulshi(t0, cpu_env, t0, t1);
2921 opn = "mulshi";
2922 break;
2923 case OPC_VR54XX_MULSHIU:
2924 gen_helper_mulshiu(t0, cpu_env, t0, t1);
2925 opn = "mulshiu";
2926 break;
2927 case OPC_VR54XX_MACCHI:
2928 gen_helper_macchi(t0, cpu_env, t0, t1);
2929 opn = "macchi";
2930 break;
2931 case OPC_VR54XX_MACCHIU:
2932 gen_helper_macchiu(t0, cpu_env, t0, t1);
2933 opn = "macchiu";
2934 break;
2935 case OPC_VR54XX_MSACHI:
2936 gen_helper_msachi(t0, cpu_env, t0, t1);
2937 opn = "msachi";
2938 break;
2939 case OPC_VR54XX_MSACHIU:
2940 gen_helper_msachiu(t0, cpu_env, t0, t1);
2941 opn = "msachiu";
2942 break;
2943 default:
2944 MIPS_INVAL("mul vr54xx");
2945 generate_exception(ctx, EXCP_RI);
2946 goto out;
2948 gen_store_gpr(t0, rd);
2949 (void)opn; /* avoid a compiler warning */
2950 MIPS_DEBUG("%s %s, %s, %s", opn, regnames[rd], regnames[rs], regnames[rt]);
2952 out:
2953 tcg_temp_free(t0);
2954 tcg_temp_free(t1);
2957 static void gen_cl (DisasContext *ctx, uint32_t opc,
2958 int rd, int rs)
2960 const char *opn = "CLx";
2961 TCGv t0;
2963 if (rd == 0) {
2964 /* Treat as NOP. */
2965 MIPS_DEBUG("NOP");
2966 return;
2968 t0 = tcg_temp_new();
2969 gen_load_gpr(t0, rs);
2970 switch (opc) {
2971 case OPC_CLO:
2972 gen_helper_clo(cpu_gpr[rd], t0);
2973 opn = "clo";
2974 break;
2975 case OPC_CLZ:
2976 gen_helper_clz(cpu_gpr[rd], t0);
2977 opn = "clz";
2978 break;
2979 #if defined(TARGET_MIPS64)
2980 case OPC_DCLO:
2981 gen_helper_dclo(cpu_gpr[rd], t0);
2982 opn = "dclo";
2983 break;
2984 case OPC_DCLZ:
2985 gen_helper_dclz(cpu_gpr[rd], t0);
2986 opn = "dclz";
2987 break;
2988 #endif
2990 (void)opn; /* avoid a compiler warning */
2991 MIPS_DEBUG("%s %s, %s", opn, regnames[rd], regnames[rs]);
2992 tcg_temp_free(t0);
2995 /* Godson integer instructions */
2996 static void gen_loongson_integer(DisasContext *ctx, uint32_t opc,
2997 int rd, int rs, int rt)
2999 const char *opn = "loongson";
3000 TCGv t0, t1;
3002 if (rd == 0) {
3003 /* Treat as NOP. */
3004 MIPS_DEBUG("NOP");
3005 return;
3008 switch (opc) {
3009 case OPC_MULT_G_2E:
3010 case OPC_MULT_G_2F:
3011 case OPC_MULTU_G_2E:
3012 case OPC_MULTU_G_2F:
3013 #if defined(TARGET_MIPS64)
3014 case OPC_DMULT_G_2E:
3015 case OPC_DMULT_G_2F:
3016 case OPC_DMULTU_G_2E:
3017 case OPC_DMULTU_G_2F:
3018 #endif
3019 t0 = tcg_temp_new();
3020 t1 = tcg_temp_new();
3021 break;
3022 default:
3023 t0 = tcg_temp_local_new();
3024 t1 = tcg_temp_local_new();
3025 break;
3028 gen_load_gpr(t0, rs);
3029 gen_load_gpr(t1, rt);
3031 switch (opc) {
3032 case OPC_MULT_G_2E:
3033 case OPC_MULT_G_2F:
3034 tcg_gen_mul_tl(cpu_gpr[rd], t0, t1);
3035 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3036 opn = "mult.g";
3037 break;
3038 case OPC_MULTU_G_2E:
3039 case OPC_MULTU_G_2F:
3040 tcg_gen_ext32u_tl(t0, t0);
3041 tcg_gen_ext32u_tl(t1, t1);
3042 tcg_gen_mul_tl(cpu_gpr[rd], t0, t1);
3043 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3044 opn = "multu.g";
3045 break;
3046 case OPC_DIV_G_2E:
3047 case OPC_DIV_G_2F:
3049 int l1 = gen_new_label();
3050 int l2 = gen_new_label();
3051 int l3 = gen_new_label();
3052 tcg_gen_ext32s_tl(t0, t0);
3053 tcg_gen_ext32s_tl(t1, t1);
3054 tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
3055 tcg_gen_movi_tl(cpu_gpr[rd], 0);
3056 tcg_gen_br(l3);
3057 gen_set_label(l1);
3058 tcg_gen_brcondi_tl(TCG_COND_NE, t0, INT_MIN, l2);
3059 tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1, l2);
3060 tcg_gen_mov_tl(cpu_gpr[rd], t0);
3061 tcg_gen_br(l3);
3062 gen_set_label(l2);
3063 tcg_gen_div_tl(cpu_gpr[rd], t0, t1);
3064 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3065 gen_set_label(l3);
3067 opn = "div.g";
3068 break;
3069 case OPC_DIVU_G_2E:
3070 case OPC_DIVU_G_2F:
3072 int l1 = gen_new_label();
3073 int l2 = gen_new_label();
3074 tcg_gen_ext32u_tl(t0, t0);
3075 tcg_gen_ext32u_tl(t1, t1);
3076 tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
3077 tcg_gen_movi_tl(cpu_gpr[rd], 0);
3078 tcg_gen_br(l2);
3079 gen_set_label(l1);
3080 tcg_gen_divu_tl(cpu_gpr[rd], t0, t1);
3081 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3082 gen_set_label(l2);
3084 opn = "divu.g";
3085 break;
3086 case OPC_MOD_G_2E:
3087 case OPC_MOD_G_2F:
3089 int l1 = gen_new_label();
3090 int l2 = gen_new_label();
3091 int l3 = gen_new_label();
3092 tcg_gen_ext32u_tl(t0, t0);
3093 tcg_gen_ext32u_tl(t1, t1);
3094 tcg_gen_brcondi_tl(TCG_COND_EQ, t1, 0, l1);
3095 tcg_gen_brcondi_tl(TCG_COND_NE, t0, INT_MIN, l2);
3096 tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1, l2);
3097 gen_set_label(l1);
3098 tcg_gen_movi_tl(cpu_gpr[rd], 0);
3099 tcg_gen_br(l3);
3100 gen_set_label(l2);
3101 tcg_gen_rem_tl(cpu_gpr[rd], t0, t1);
3102 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3103 gen_set_label(l3);
3105 opn = "mod.g";
3106 break;
3107 case OPC_MODU_G_2E:
3108 case OPC_MODU_G_2F:
3110 int l1 = gen_new_label();
3111 int l2 = gen_new_label();
3112 tcg_gen_ext32u_tl(t0, t0);
3113 tcg_gen_ext32u_tl(t1, t1);
3114 tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
3115 tcg_gen_movi_tl(cpu_gpr[rd], 0);
3116 tcg_gen_br(l2);
3117 gen_set_label(l1);
3118 tcg_gen_remu_tl(cpu_gpr[rd], t0, t1);
3119 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3120 gen_set_label(l2);
3122 opn = "modu.g";
3123 break;
3124 #if defined(TARGET_MIPS64)
3125 case OPC_DMULT_G_2E:
3126 case OPC_DMULT_G_2F:
3127 tcg_gen_mul_tl(cpu_gpr[rd], t0, t1);
3128 opn = "dmult.g";
3129 break;
3130 case OPC_DMULTU_G_2E:
3131 case OPC_DMULTU_G_2F:
3132 tcg_gen_mul_tl(cpu_gpr[rd], t0, t1);
3133 opn = "dmultu.g";
3134 break;
3135 case OPC_DDIV_G_2E:
3136 case OPC_DDIV_G_2F:
3138 int l1 = gen_new_label();
3139 int l2 = gen_new_label();
3140 int l3 = gen_new_label();
3141 tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
3142 tcg_gen_movi_tl(cpu_gpr[rd], 0);
3143 tcg_gen_br(l3);
3144 gen_set_label(l1);
3145 tcg_gen_brcondi_tl(TCG_COND_NE, t0, -1LL << 63, l2);
3146 tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1LL, l2);
3147 tcg_gen_mov_tl(cpu_gpr[rd], t0);
3148 tcg_gen_br(l3);
3149 gen_set_label(l2);
3150 tcg_gen_div_tl(cpu_gpr[rd], t0, t1);
3151 gen_set_label(l3);
3153 opn = "ddiv.g";
3154 break;
3155 case OPC_DDIVU_G_2E:
3156 case OPC_DDIVU_G_2F:
3158 int l1 = gen_new_label();
3159 int l2 = gen_new_label();
3160 tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
3161 tcg_gen_movi_tl(cpu_gpr[rd], 0);
3162 tcg_gen_br(l2);
3163 gen_set_label(l1);
3164 tcg_gen_divu_tl(cpu_gpr[rd], t0, t1);
3165 gen_set_label(l2);
3167 opn = "ddivu.g";
3168 break;
3169 case OPC_DMOD_G_2E:
3170 case OPC_DMOD_G_2F:
3172 int l1 = gen_new_label();
3173 int l2 = gen_new_label();
3174 int l3 = gen_new_label();
3175 tcg_gen_brcondi_tl(TCG_COND_EQ, t1, 0, l1);
3176 tcg_gen_brcondi_tl(TCG_COND_NE, t0, -1LL << 63, l2);
3177 tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1LL, l2);
3178 gen_set_label(l1);
3179 tcg_gen_movi_tl(cpu_gpr[rd], 0);
3180 tcg_gen_br(l3);
3181 gen_set_label(l2);
3182 tcg_gen_rem_tl(cpu_gpr[rd], t0, t1);
3183 gen_set_label(l3);
3185 opn = "dmod.g";
3186 break;
3187 case OPC_DMODU_G_2E:
3188 case OPC_DMODU_G_2F:
3190 int l1 = gen_new_label();
3191 int l2 = gen_new_label();
3192 tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
3193 tcg_gen_movi_tl(cpu_gpr[rd], 0);
3194 tcg_gen_br(l2);
3195 gen_set_label(l1);
3196 tcg_gen_remu_tl(cpu_gpr[rd], t0, t1);
3197 gen_set_label(l2);
3199 opn = "dmodu.g";
3200 break;
3201 #endif
3204 (void)opn; /* avoid a compiler warning */
3205 MIPS_DEBUG("%s %s, %s", opn, regnames[rd], regnames[rs]);
3206 tcg_temp_free(t0);
3207 tcg_temp_free(t1);
3210 /* Loongson multimedia instructions */
3211 static void gen_loongson_multimedia(DisasContext *ctx, int rd, int rs, int rt)
3213 const char *opn = "loongson_cp2";
3214 uint32_t opc, shift_max;
3215 TCGv_i64 t0, t1;
3217 opc = MASK_LMI(ctx->opcode);
3218 switch (opc) {
3219 case OPC_ADD_CP2:
3220 case OPC_SUB_CP2:
3221 case OPC_DADD_CP2:
3222 case OPC_DSUB_CP2:
3223 t0 = tcg_temp_local_new_i64();
3224 t1 = tcg_temp_local_new_i64();
3225 break;
3226 default:
3227 t0 = tcg_temp_new_i64();
3228 t1 = tcg_temp_new_i64();
3229 break;
3232 gen_load_fpr64(ctx, t0, rs);
3233 gen_load_fpr64(ctx, t1, rt);
3235 #define LMI_HELPER(UP, LO) \
3236 case OPC_##UP: gen_helper_##LO(t0, t0, t1); opn = #LO; break
3237 #define LMI_HELPER_1(UP, LO) \
3238 case OPC_##UP: gen_helper_##LO(t0, t0); opn = #LO; break
3239 #define LMI_DIRECT(UP, LO, OP) \
3240 case OPC_##UP: tcg_gen_##OP##_i64(t0, t0, t1); opn = #LO; break
3242 switch (opc) {
3243 LMI_HELPER(PADDSH, paddsh);
3244 LMI_HELPER(PADDUSH, paddush);
3245 LMI_HELPER(PADDH, paddh);
3246 LMI_HELPER(PADDW, paddw);
3247 LMI_HELPER(PADDSB, paddsb);
3248 LMI_HELPER(PADDUSB, paddusb);
3249 LMI_HELPER(PADDB, paddb);
3251 LMI_HELPER(PSUBSH, psubsh);
3252 LMI_HELPER(PSUBUSH, psubush);
3253 LMI_HELPER(PSUBH, psubh);
3254 LMI_HELPER(PSUBW, psubw);
3255 LMI_HELPER(PSUBSB, psubsb);
3256 LMI_HELPER(PSUBUSB, psubusb);
3257 LMI_HELPER(PSUBB, psubb);
3259 LMI_HELPER(PSHUFH, pshufh);
3260 LMI_HELPER(PACKSSWH, packsswh);
3261 LMI_HELPER(PACKSSHB, packsshb);
3262 LMI_HELPER(PACKUSHB, packushb);
3264 LMI_HELPER(PUNPCKLHW, punpcklhw);
3265 LMI_HELPER(PUNPCKHHW, punpckhhw);
3266 LMI_HELPER(PUNPCKLBH, punpcklbh);
3267 LMI_HELPER(PUNPCKHBH, punpckhbh);
3268 LMI_HELPER(PUNPCKLWD, punpcklwd);
3269 LMI_HELPER(PUNPCKHWD, punpckhwd);
3271 LMI_HELPER(PAVGH, pavgh);
3272 LMI_HELPER(PAVGB, pavgb);
3273 LMI_HELPER(PMAXSH, pmaxsh);
3274 LMI_HELPER(PMINSH, pminsh);
3275 LMI_HELPER(PMAXUB, pmaxub);
3276 LMI_HELPER(PMINUB, pminub);
3278 LMI_HELPER(PCMPEQW, pcmpeqw);
3279 LMI_HELPER(PCMPGTW, pcmpgtw);
3280 LMI_HELPER(PCMPEQH, pcmpeqh);
3281 LMI_HELPER(PCMPGTH, pcmpgth);
3282 LMI_HELPER(PCMPEQB, pcmpeqb);
3283 LMI_HELPER(PCMPGTB, pcmpgtb);
3285 LMI_HELPER(PSLLW, psllw);
3286 LMI_HELPER(PSLLH, psllh);
3287 LMI_HELPER(PSRLW, psrlw);
3288 LMI_HELPER(PSRLH, psrlh);
3289 LMI_HELPER(PSRAW, psraw);
3290 LMI_HELPER(PSRAH, psrah);
3292 LMI_HELPER(PMULLH, pmullh);
3293 LMI_HELPER(PMULHH, pmulhh);
3294 LMI_HELPER(PMULHUH, pmulhuh);
3295 LMI_HELPER(PMADDHW, pmaddhw);
3297 LMI_HELPER(PASUBUB, pasubub);
3298 LMI_HELPER_1(BIADD, biadd);
3299 LMI_HELPER_1(PMOVMSKB, pmovmskb);
3301 LMI_DIRECT(PADDD, paddd, add);
3302 LMI_DIRECT(PSUBD, psubd, sub);
3303 LMI_DIRECT(XOR_CP2, xor, xor);
3304 LMI_DIRECT(NOR_CP2, nor, nor);
3305 LMI_DIRECT(AND_CP2, and, and);
3306 LMI_DIRECT(PANDN, pandn, andc);
3307 LMI_DIRECT(OR, or, or);
3309 case OPC_PINSRH_0:
3310 tcg_gen_deposit_i64(t0, t0, t1, 0, 16);
3311 opn = "pinsrh_0";
3312 break;
3313 case OPC_PINSRH_1:
3314 tcg_gen_deposit_i64(t0, t0, t1, 16, 16);
3315 opn = "pinsrh_1";
3316 break;
3317 case OPC_PINSRH_2:
3318 tcg_gen_deposit_i64(t0, t0, t1, 32, 16);
3319 opn = "pinsrh_2";
3320 break;
3321 case OPC_PINSRH_3:
3322 tcg_gen_deposit_i64(t0, t0, t1, 48, 16);
3323 opn = "pinsrh_3";
3324 break;
3326 case OPC_PEXTRH:
3327 tcg_gen_andi_i64(t1, t1, 3);
3328 tcg_gen_shli_i64(t1, t1, 4);
3329 tcg_gen_shr_i64(t0, t0, t1);
3330 tcg_gen_ext16u_i64(t0, t0);
3331 opn = "pextrh";
3332 break;
3334 case OPC_ADDU_CP2:
3335 tcg_gen_add_i64(t0, t0, t1);
3336 tcg_gen_ext32s_i64(t0, t0);
3337 opn = "addu";
3338 break;
3339 case OPC_SUBU_CP2:
3340 tcg_gen_sub_i64(t0, t0, t1);
3341 tcg_gen_ext32s_i64(t0, t0);
3342 opn = "addu";
3343 break;
3345 case OPC_SLL_CP2:
3346 opn = "sll";
3347 shift_max = 32;
3348 goto do_shift;
3349 case OPC_SRL_CP2:
3350 opn = "srl";
3351 shift_max = 32;
3352 goto do_shift;
3353 case OPC_SRA_CP2:
3354 opn = "sra";
3355 shift_max = 32;
3356 goto do_shift;
3357 case OPC_DSLL_CP2:
3358 opn = "dsll";
3359 shift_max = 64;
3360 goto do_shift;
3361 case OPC_DSRL_CP2:
3362 opn = "dsrl";
3363 shift_max = 64;
3364 goto do_shift;
3365 case OPC_DSRA_CP2:
3366 opn = "dsra";
3367 shift_max = 64;
3368 goto do_shift;
3369 do_shift:
3370 /* Make sure shift count isn't TCG undefined behaviour. */
3371 tcg_gen_andi_i64(t1, t1, shift_max - 1);
3373 switch (opc) {
3374 case OPC_SLL_CP2:
3375 case OPC_DSLL_CP2:
3376 tcg_gen_shl_i64(t0, t0, t1);
3377 break;
3378 case OPC_SRA_CP2:
3379 case OPC_DSRA_CP2:
3380 /* Since SRA is UndefinedResult without sign-extended inputs,
3381 we can treat SRA and DSRA the same. */
3382 tcg_gen_sar_i64(t0, t0, t1);
3383 break;
3384 case OPC_SRL_CP2:
3385 /* We want to shift in zeros for SRL; zero-extend first. */
3386 tcg_gen_ext32u_i64(t0, t0);
3387 /* FALLTHRU */
3388 case OPC_DSRL_CP2:
3389 tcg_gen_shr_i64(t0, t0, t1);
3390 break;
3393 if (shift_max == 32) {
3394 tcg_gen_ext32s_i64(t0, t0);
3397 /* Shifts larger than MAX produce zero. */
3398 tcg_gen_setcondi_i64(TCG_COND_LTU, t1, t1, shift_max);
3399 tcg_gen_neg_i64(t1, t1);
3400 tcg_gen_and_i64(t0, t0, t1);
3401 break;
3403 case OPC_ADD_CP2:
3404 case OPC_DADD_CP2:
3406 TCGv_i64 t2 = tcg_temp_new_i64();
3407 int lab = gen_new_label();
3409 tcg_gen_mov_i64(t2, t0);
3410 tcg_gen_add_i64(t0, t1, t2);
3411 if (opc == OPC_ADD_CP2) {
3412 tcg_gen_ext32s_i64(t0, t0);
3414 tcg_gen_xor_i64(t1, t1, t2);
3415 tcg_gen_xor_i64(t2, t2, t0);
3416 tcg_gen_andc_i64(t1, t2, t1);
3417 tcg_temp_free_i64(t2);
3418 tcg_gen_brcondi_i64(TCG_COND_GE, t1, 0, lab);
3419 generate_exception(ctx, EXCP_OVERFLOW);
3420 gen_set_label(lab);
3422 opn = (opc == OPC_ADD_CP2 ? "add" : "dadd");
3423 break;
3426 case OPC_SUB_CP2:
3427 case OPC_DSUB_CP2:
3429 TCGv_i64 t2 = tcg_temp_new_i64();
3430 int lab = gen_new_label();
3432 tcg_gen_mov_i64(t2, t0);
3433 tcg_gen_sub_i64(t0, t1, t2);
3434 if (opc == OPC_SUB_CP2) {
3435 tcg_gen_ext32s_i64(t0, t0);
3437 tcg_gen_xor_i64(t1, t1, t2);
3438 tcg_gen_xor_i64(t2, t2, t0);
3439 tcg_gen_and_i64(t1, t1, t2);
3440 tcg_temp_free_i64(t2);
3441 tcg_gen_brcondi_i64(TCG_COND_GE, t1, 0, lab);
3442 generate_exception(ctx, EXCP_OVERFLOW);
3443 gen_set_label(lab);
3445 opn = (opc == OPC_SUB_CP2 ? "sub" : "dsub");
3446 break;
3449 case OPC_PMULUW:
3450 tcg_gen_ext32u_i64(t0, t0);
3451 tcg_gen_ext32u_i64(t1, t1);
3452 tcg_gen_mul_i64(t0, t0, t1);
3453 opn = "pmuluw";
3454 break;
3456 case OPC_SEQU_CP2:
3457 case OPC_SEQ_CP2:
3458 case OPC_SLTU_CP2:
3459 case OPC_SLT_CP2:
3460 case OPC_SLEU_CP2:
3461 case OPC_SLE_CP2:
3462 /* ??? Document is unclear: Set FCC[CC]. Does that mean the
3463 FD field is the CC field? */
3464 default:
3465 MIPS_INVAL(opn);
3466 generate_exception(ctx, EXCP_RI);
3467 return;
3470 #undef LMI_HELPER
3471 #undef LMI_DIRECT
3473 gen_store_fpr64(ctx, t0, rd);
3475 (void)opn; /* avoid a compiler warning */
3476 MIPS_DEBUG("%s %s, %s, %s", opn,
3477 fregnames[rd], fregnames[rs], fregnames[rt]);
3478 tcg_temp_free_i64(t0);
3479 tcg_temp_free_i64(t1);
3482 /* Traps */
3483 static void gen_trap (DisasContext *ctx, uint32_t opc,
3484 int rs, int rt, int16_t imm)
3486 int cond;
3487 TCGv t0 = tcg_temp_new();
3488 TCGv t1 = tcg_temp_new();
3490 cond = 0;
3491 /* Load needed operands */
3492 switch (opc) {
3493 case OPC_TEQ:
3494 case OPC_TGE:
3495 case OPC_TGEU:
3496 case OPC_TLT:
3497 case OPC_TLTU:
3498 case OPC_TNE:
3499 /* Compare two registers */
3500 if (rs != rt) {
3501 gen_load_gpr(t0, rs);
3502 gen_load_gpr(t1, rt);
3503 cond = 1;
3505 break;
3506 case OPC_TEQI:
3507 case OPC_TGEI:
3508 case OPC_TGEIU:
3509 case OPC_TLTI:
3510 case OPC_TLTIU:
3511 case OPC_TNEI:
3512 /* Compare register to immediate */
3513 if (rs != 0 || imm != 0) {
3514 gen_load_gpr(t0, rs);
3515 tcg_gen_movi_tl(t1, (int32_t)imm);
3516 cond = 1;
3518 break;
3520 if (cond == 0) {
3521 switch (opc) {
3522 case OPC_TEQ: /* rs == rs */
3523 case OPC_TEQI: /* r0 == 0 */
3524 case OPC_TGE: /* rs >= rs */
3525 case OPC_TGEI: /* r0 >= 0 */
3526 case OPC_TGEU: /* rs >= rs unsigned */
3527 case OPC_TGEIU: /* r0 >= 0 unsigned */
3528 /* Always trap */
3529 generate_exception(ctx, EXCP_TRAP);
3530 break;
3531 case OPC_TLT: /* rs < rs */
3532 case OPC_TLTI: /* r0 < 0 */
3533 case OPC_TLTU: /* rs < rs unsigned */
3534 case OPC_TLTIU: /* r0 < 0 unsigned */
3535 case OPC_TNE: /* rs != rs */
3536 case OPC_TNEI: /* r0 != 0 */
3537 /* Never trap: treat as NOP. */
3538 break;
3540 } else {
3541 int l1 = gen_new_label();
3543 switch (opc) {
3544 case OPC_TEQ:
3545 case OPC_TEQI:
3546 tcg_gen_brcond_tl(TCG_COND_NE, t0, t1, l1);
3547 break;
3548 case OPC_TGE:
3549 case OPC_TGEI:
3550 tcg_gen_brcond_tl(TCG_COND_LT, t0, t1, l1);
3551 break;
3552 case OPC_TGEU:
3553 case OPC_TGEIU:
3554 tcg_gen_brcond_tl(TCG_COND_LTU, t0, t1, l1);
3555 break;
3556 case OPC_TLT:
3557 case OPC_TLTI:
3558 tcg_gen_brcond_tl(TCG_COND_GE, t0, t1, l1);
3559 break;
3560 case OPC_TLTU:
3561 case OPC_TLTIU:
3562 tcg_gen_brcond_tl(TCG_COND_GEU, t0, t1, l1);
3563 break;
3564 case OPC_TNE:
3565 case OPC_TNEI:
3566 tcg_gen_brcond_tl(TCG_COND_EQ, t0, t1, l1);
3567 break;
3569 generate_exception(ctx, EXCP_TRAP);
3570 gen_set_label(l1);
3572 tcg_temp_free(t0);
3573 tcg_temp_free(t1);
3576 static inline void gen_goto_tb(DisasContext *ctx, int n, target_ulong dest)
3578 TranslationBlock *tb;
3579 tb = ctx->tb;
3580 if ((tb->pc & TARGET_PAGE_MASK) == (dest & TARGET_PAGE_MASK) &&
3581 likely(!ctx->singlestep_enabled)) {
3582 tcg_gen_goto_tb(n);
3583 gen_save_pc(dest);
3584 tcg_gen_exit_tb((uintptr_t)tb + n);
3585 } else {
3586 gen_save_pc(dest);
3587 if (ctx->singlestep_enabled) {
3588 save_cpu_state(ctx, 0);
3589 gen_helper_0e0i(raise_exception, EXCP_DEBUG);
3591 tcg_gen_exit_tb(0);
3595 /* Branches (before delay slot) */
3596 static void gen_compute_branch (DisasContext *ctx, uint32_t opc,
3597 int insn_bytes,
3598 int rs, int rt, int32_t offset)
3600 target_ulong btgt = -1;
3601 int blink = 0;
3602 int bcond_compute = 0;
3603 TCGv t0 = tcg_temp_new();
3604 TCGv t1 = tcg_temp_new();
3606 if (ctx->hflags & MIPS_HFLAG_BMASK) {
3607 #ifdef MIPS_DEBUG_DISAS
3608 LOG_DISAS("Branch in delay slot at PC 0x" TARGET_FMT_lx "\n", ctx->pc);
3609 #endif
3610 generate_exception(ctx, EXCP_RI);
3611 goto out;
3614 /* Load needed operands */
3615 switch (opc) {
3616 case OPC_BEQ:
3617 case OPC_BEQL:
3618 case OPC_BNE:
3619 case OPC_BNEL:
3620 /* Compare two registers */
3621 if (rs != rt) {
3622 gen_load_gpr(t0, rs);
3623 gen_load_gpr(t1, rt);
3624 bcond_compute = 1;
3626 btgt = ctx->pc + insn_bytes + offset;
3627 break;
3628 case OPC_BGEZ:
3629 case OPC_BGEZAL:
3630 case OPC_BGEZALS:
3631 case OPC_BGEZALL:
3632 case OPC_BGEZL:
3633 case OPC_BGTZ:
3634 case OPC_BGTZL:
3635 case OPC_BLEZ:
3636 case OPC_BLEZL:
3637 case OPC_BLTZ:
3638 case OPC_BLTZAL:
3639 case OPC_BLTZALS:
3640 case OPC_BLTZALL:
3641 case OPC_BLTZL:
3642 /* Compare to zero */
3643 if (rs != 0) {
3644 gen_load_gpr(t0, rs);
3645 bcond_compute = 1;
3647 btgt = ctx->pc + insn_bytes + offset;
3648 break;
3649 case OPC_BPOSGE32:
3650 #if defined(TARGET_MIPS64)
3651 case OPC_BPOSGE64:
3652 tcg_gen_andi_tl(t0, cpu_dspctrl, 0x7F);
3653 #else
3654 tcg_gen_andi_tl(t0, cpu_dspctrl, 0x3F);
3655 #endif
3656 bcond_compute = 1;
3657 btgt = ctx->pc + insn_bytes + offset;
3658 break;
3659 case OPC_J:
3660 case OPC_JAL:
3661 case OPC_JALX:
3662 case OPC_JALS:
3663 case OPC_JALXS:
3664 /* Jump to immediate */
3665 btgt = ((ctx->pc + insn_bytes) & (int32_t)0xF0000000) | (uint32_t)offset;
3666 break;
3667 case OPC_JR:
3668 case OPC_JALR:
3669 case OPC_JALRC:
3670 case OPC_JALRS:
3671 /* Jump to register */
3672 if (offset != 0 && offset != 16) {
3673 /* Hint = 0 is JR/JALR, hint 16 is JR.HB/JALR.HB, the
3674 others are reserved. */
3675 MIPS_INVAL("jump hint");
3676 generate_exception(ctx, EXCP_RI);
3677 goto out;
3679 gen_load_gpr(btarget, rs);
3680 break;
3681 default:
3682 MIPS_INVAL("branch/jump");
3683 generate_exception(ctx, EXCP_RI);
3684 goto out;
3686 if (bcond_compute == 0) {
3687 /* No condition to be computed */
3688 switch (opc) {
3689 case OPC_BEQ: /* rx == rx */
3690 case OPC_BEQL: /* rx == rx likely */
3691 case OPC_BGEZ: /* 0 >= 0 */
3692 case OPC_BGEZL: /* 0 >= 0 likely */
3693 case OPC_BLEZ: /* 0 <= 0 */
3694 case OPC_BLEZL: /* 0 <= 0 likely */
3695 /* Always take */
3696 ctx->hflags |= MIPS_HFLAG_B;
3697 MIPS_DEBUG("balways");
3698 break;
3699 case OPC_BGEZALS:
3700 case OPC_BGEZAL: /* 0 >= 0 */
3701 case OPC_BGEZALL: /* 0 >= 0 likely */
3702 ctx->hflags |= (opc == OPC_BGEZALS
3703 ? MIPS_HFLAG_BDS16
3704 : MIPS_HFLAG_BDS32);
3705 /* Always take and link */
3706 blink = 31;
3707 ctx->hflags |= MIPS_HFLAG_B;
3708 MIPS_DEBUG("balways and link");
3709 break;
3710 case OPC_BNE: /* rx != rx */
3711 case OPC_BGTZ: /* 0 > 0 */
3712 case OPC_BLTZ: /* 0 < 0 */
3713 /* Treat as NOP. */
3714 MIPS_DEBUG("bnever (NOP)");
3715 goto out;
3716 case OPC_BLTZALS:
3717 case OPC_BLTZAL: /* 0 < 0 */
3718 ctx->hflags |= (opc == OPC_BLTZALS
3719 ? MIPS_HFLAG_BDS16
3720 : MIPS_HFLAG_BDS32);
3721 /* Handle as an unconditional branch to get correct delay
3722 slot checking. */
3723 blink = 31;
3724 btgt = ctx->pc + (opc == OPC_BLTZALS ? 6 : 8);
3725 ctx->hflags |= MIPS_HFLAG_B;
3726 MIPS_DEBUG("bnever and link");
3727 break;
3728 case OPC_BLTZALL: /* 0 < 0 likely */
3729 tcg_gen_movi_tl(cpu_gpr[31], ctx->pc + 8);
3730 /* Skip the instruction in the delay slot */
3731 MIPS_DEBUG("bnever, link and skip");
3732 ctx->pc += 4;
3733 goto out;
3734 case OPC_BNEL: /* rx != rx likely */
3735 case OPC_BGTZL: /* 0 > 0 likely */
3736 case OPC_BLTZL: /* 0 < 0 likely */
3737 /* Skip the instruction in the delay slot */
3738 MIPS_DEBUG("bnever and skip");
3739 ctx->pc += 4;
3740 goto out;
3741 case OPC_J:
3742 ctx->hflags |= MIPS_HFLAG_B;
3743 MIPS_DEBUG("j " TARGET_FMT_lx, btgt);
3744 break;
3745 case OPC_JALXS:
3746 case OPC_JALX:
3747 ctx->hflags |= MIPS_HFLAG_BX;
3748 /* Fallthrough */
3749 case OPC_JALS:
3750 case OPC_JAL:
3751 blink = 31;
3752 ctx->hflags |= MIPS_HFLAG_B;
3753 ctx->hflags |= ((opc == OPC_JALS || opc == OPC_JALXS)
3754 ? MIPS_HFLAG_BDS16
3755 : MIPS_HFLAG_BDS32);
3756 MIPS_DEBUG("jal " TARGET_FMT_lx, btgt);
3757 break;
3758 case OPC_JR:
3759 ctx->hflags |= MIPS_HFLAG_BR;
3760 if (insn_bytes == 4)
3761 ctx->hflags |= MIPS_HFLAG_BDS32;
3762 MIPS_DEBUG("jr %s", regnames[rs]);
3763 break;
3764 case OPC_JALRS:
3765 case OPC_JALR:
3766 case OPC_JALRC:
3767 blink = rt;
3768 ctx->hflags |= MIPS_HFLAG_BR;
3769 ctx->hflags |= (opc == OPC_JALRS
3770 ? MIPS_HFLAG_BDS16
3771 : MIPS_HFLAG_BDS32);
3772 MIPS_DEBUG("jalr %s, %s", regnames[rt], regnames[rs]);
3773 break;
3774 default:
3775 MIPS_INVAL("branch/jump");
3776 generate_exception(ctx, EXCP_RI);
3777 goto out;
3779 } else {
3780 switch (opc) {
3781 case OPC_BEQ:
3782 tcg_gen_setcond_tl(TCG_COND_EQ, bcond, t0, t1);
3783 MIPS_DEBUG("beq %s, %s, " TARGET_FMT_lx,
3784 regnames[rs], regnames[rt], btgt);
3785 goto not_likely;
3786 case OPC_BEQL:
3787 tcg_gen_setcond_tl(TCG_COND_EQ, bcond, t0, t1);
3788 MIPS_DEBUG("beql %s, %s, " TARGET_FMT_lx,
3789 regnames[rs], regnames[rt], btgt);
3790 goto likely;
3791 case OPC_BNE:
3792 tcg_gen_setcond_tl(TCG_COND_NE, bcond, t0, t1);
3793 MIPS_DEBUG("bne %s, %s, " TARGET_FMT_lx,
3794 regnames[rs], regnames[rt], btgt);
3795 goto not_likely;
3796 case OPC_BNEL:
3797 tcg_gen_setcond_tl(TCG_COND_NE, bcond, t0, t1);
3798 MIPS_DEBUG("bnel %s, %s, " TARGET_FMT_lx,
3799 regnames[rs], regnames[rt], btgt);
3800 goto likely;
3801 case OPC_BGEZ:
3802 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 0);
3803 MIPS_DEBUG("bgez %s, " TARGET_FMT_lx, regnames[rs], btgt);
3804 goto not_likely;
3805 case OPC_BGEZL:
3806 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 0);
3807 MIPS_DEBUG("bgezl %s, " TARGET_FMT_lx, regnames[rs], btgt);
3808 goto likely;
3809 case OPC_BGEZALS:
3810 case OPC_BGEZAL:
3811 ctx->hflags |= (opc == OPC_BGEZALS
3812 ? MIPS_HFLAG_BDS16
3813 : MIPS_HFLAG_BDS32);
3814 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 0);
3815 MIPS_DEBUG("bgezal %s, " TARGET_FMT_lx, regnames[rs], btgt);
3816 blink = 31;
3817 goto not_likely;
3818 case OPC_BGEZALL:
3819 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 0);
3820 blink = 31;
3821 MIPS_DEBUG("bgezall %s, " TARGET_FMT_lx, regnames[rs], btgt);
3822 goto likely;
3823 case OPC_BGTZ:
3824 tcg_gen_setcondi_tl(TCG_COND_GT, bcond, t0, 0);
3825 MIPS_DEBUG("bgtz %s, " TARGET_FMT_lx, regnames[rs], btgt);
3826 goto not_likely;
3827 case OPC_BGTZL:
3828 tcg_gen_setcondi_tl(TCG_COND_GT, bcond, t0, 0);
3829 MIPS_DEBUG("bgtzl %s, " TARGET_FMT_lx, regnames[rs], btgt);
3830 goto likely;
3831 case OPC_BLEZ:
3832 tcg_gen_setcondi_tl(TCG_COND_LE, bcond, t0, 0);
3833 MIPS_DEBUG("blez %s, " TARGET_FMT_lx, regnames[rs], btgt);
3834 goto not_likely;
3835 case OPC_BLEZL:
3836 tcg_gen_setcondi_tl(TCG_COND_LE, bcond, t0, 0);
3837 MIPS_DEBUG("blezl %s, " TARGET_FMT_lx, regnames[rs], btgt);
3838 goto likely;
3839 case OPC_BLTZ:
3840 tcg_gen_setcondi_tl(TCG_COND_LT, bcond, t0, 0);
3841 MIPS_DEBUG("bltz %s, " TARGET_FMT_lx, regnames[rs], btgt);
3842 goto not_likely;
3843 case OPC_BLTZL:
3844 tcg_gen_setcondi_tl(TCG_COND_LT, bcond, t0, 0);
3845 MIPS_DEBUG("bltzl %s, " TARGET_FMT_lx, regnames[rs], btgt);
3846 goto likely;
3847 case OPC_BPOSGE32:
3848 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 32);
3849 MIPS_DEBUG("bposge32 " TARGET_FMT_lx, btgt);
3850 goto not_likely;
3851 #if defined(TARGET_MIPS64)
3852 case OPC_BPOSGE64:
3853 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 64);
3854 MIPS_DEBUG("bposge64 " TARGET_FMT_lx, btgt);
3855 goto not_likely;
3856 #endif
3857 case OPC_BLTZALS:
3858 case OPC_BLTZAL:
3859 ctx->hflags |= (opc == OPC_BLTZALS
3860 ? MIPS_HFLAG_BDS16
3861 : MIPS_HFLAG_BDS32);
3862 tcg_gen_setcondi_tl(TCG_COND_LT, bcond, t0, 0);
3863 blink = 31;
3864 MIPS_DEBUG("bltzal %s, " TARGET_FMT_lx, regnames[rs], btgt);
3865 not_likely:
3866 ctx->hflags |= MIPS_HFLAG_BC;
3867 break;
3868 case OPC_BLTZALL:
3869 tcg_gen_setcondi_tl(TCG_COND_LT, bcond, t0, 0);
3870 blink = 31;
3871 MIPS_DEBUG("bltzall %s, " TARGET_FMT_lx, regnames[rs], btgt);
3872 likely:
3873 ctx->hflags |= MIPS_HFLAG_BL;
3874 break;
3875 default:
3876 MIPS_INVAL("conditional branch/jump");
3877 generate_exception(ctx, EXCP_RI);
3878 goto out;
3881 MIPS_DEBUG("enter ds: link %d cond %02x target " TARGET_FMT_lx,
3882 blink, ctx->hflags, btgt);
3884 ctx->btarget = btgt;
3885 if (blink > 0) {
3886 int post_delay = insn_bytes;
3887 int lowbit = !!(ctx->hflags & MIPS_HFLAG_M16);
3889 if (opc != OPC_JALRC)
3890 post_delay += ((ctx->hflags & MIPS_HFLAG_BDS16) ? 2 : 4);
3892 tcg_gen_movi_tl(cpu_gpr[blink], ctx->pc + post_delay + lowbit);
3895 out:
3896 if (insn_bytes == 2)
3897 ctx->hflags |= MIPS_HFLAG_B16;
3898 tcg_temp_free(t0);
3899 tcg_temp_free(t1);
3902 /* special3 bitfield operations */
3903 static void gen_bitops (DisasContext *ctx, uint32_t opc, int rt,
3904 int rs, int lsb, int msb)
3906 TCGv t0 = tcg_temp_new();
3907 TCGv t1 = tcg_temp_new();
3909 gen_load_gpr(t1, rs);
3910 switch (opc) {
3911 case OPC_EXT:
3912 if (lsb + msb > 31)
3913 goto fail;
3914 tcg_gen_shri_tl(t0, t1, lsb);
3915 if (msb != 31) {
3916 tcg_gen_andi_tl(t0, t0, (1 << (msb + 1)) - 1);
3917 } else {
3918 tcg_gen_ext32s_tl(t0, t0);
3920 break;
3921 #if defined(TARGET_MIPS64)
3922 case OPC_DEXTM:
3923 tcg_gen_shri_tl(t0, t1, lsb);
3924 if (msb != 31) {
3925 tcg_gen_andi_tl(t0, t0, (1ULL << (msb + 1 + 32)) - 1);
3927 break;
3928 case OPC_DEXTU:
3929 tcg_gen_shri_tl(t0, t1, lsb + 32);
3930 tcg_gen_andi_tl(t0, t0, (1ULL << (msb + 1)) - 1);
3931 break;
3932 case OPC_DEXT:
3933 tcg_gen_shri_tl(t0, t1, lsb);
3934 tcg_gen_andi_tl(t0, t0, (1ULL << (msb + 1)) - 1);
3935 break;
3936 #endif
3937 case OPC_INS:
3938 if (lsb > msb)
3939 goto fail;
3940 gen_load_gpr(t0, rt);
3941 tcg_gen_deposit_tl(t0, t0, t1, lsb, msb - lsb + 1);
3942 tcg_gen_ext32s_tl(t0, t0);
3943 break;
3944 #if defined(TARGET_MIPS64)
3945 case OPC_DINSM:
3946 gen_load_gpr(t0, rt);
3947 tcg_gen_deposit_tl(t0, t0, t1, lsb, msb + 32 - lsb + 1);
3948 break;
3949 case OPC_DINSU:
3950 gen_load_gpr(t0, rt);
3951 tcg_gen_deposit_tl(t0, t0, t1, lsb + 32, msb - lsb + 1);
3952 break;
3953 case OPC_DINS:
3954 gen_load_gpr(t0, rt);
3955 tcg_gen_deposit_tl(t0, t0, t1, lsb, msb - lsb + 1);
3956 break;
3957 #endif
3958 default:
3959 fail:
3960 MIPS_INVAL("bitops");
3961 generate_exception(ctx, EXCP_RI);
3962 tcg_temp_free(t0);
3963 tcg_temp_free(t1);
3964 return;
3966 gen_store_gpr(t0, rt);
3967 tcg_temp_free(t0);
3968 tcg_temp_free(t1);
3971 static void gen_bshfl (DisasContext *ctx, uint32_t op2, int rt, int rd)
3973 TCGv t0;
3975 if (rd == 0) {
3976 /* If no destination, treat it as a NOP. */
3977 MIPS_DEBUG("NOP");
3978 return;
3981 t0 = tcg_temp_new();
3982 gen_load_gpr(t0, rt);
3983 switch (op2) {
3984 case OPC_WSBH:
3986 TCGv t1 = tcg_temp_new();
3988 tcg_gen_shri_tl(t1, t0, 8);
3989 tcg_gen_andi_tl(t1, t1, 0x00FF00FF);
3990 tcg_gen_shli_tl(t0, t0, 8);
3991 tcg_gen_andi_tl(t0, t0, ~0x00FF00FF);
3992 tcg_gen_or_tl(t0, t0, t1);
3993 tcg_temp_free(t1);
3994 tcg_gen_ext32s_tl(cpu_gpr[rd], t0);
3996 break;
3997 case OPC_SEB:
3998 tcg_gen_ext8s_tl(cpu_gpr[rd], t0);
3999 break;
4000 case OPC_SEH:
4001 tcg_gen_ext16s_tl(cpu_gpr[rd], t0);
4002 break;
4003 #if defined(TARGET_MIPS64)
4004 case OPC_DSBH:
4006 TCGv t1 = tcg_temp_new();
4008 tcg_gen_shri_tl(t1, t0, 8);
4009 tcg_gen_andi_tl(t1, t1, 0x00FF00FF00FF00FFULL);
4010 tcg_gen_shli_tl(t0, t0, 8);
4011 tcg_gen_andi_tl(t0, t0, ~0x00FF00FF00FF00FFULL);
4012 tcg_gen_or_tl(cpu_gpr[rd], t0, t1);
4013 tcg_temp_free(t1);
4015 break;
4016 case OPC_DSHD:
4018 TCGv t1 = tcg_temp_new();
4020 tcg_gen_shri_tl(t1, t0, 16);
4021 tcg_gen_andi_tl(t1, t1, 0x0000FFFF0000FFFFULL);
4022 tcg_gen_shli_tl(t0, t0, 16);
4023 tcg_gen_andi_tl(t0, t0, ~0x0000FFFF0000FFFFULL);
4024 tcg_gen_or_tl(t0, t0, t1);
4025 tcg_gen_shri_tl(t1, t0, 32);
4026 tcg_gen_shli_tl(t0, t0, 32);
4027 tcg_gen_or_tl(cpu_gpr[rd], t0, t1);
4028 tcg_temp_free(t1);
4030 break;
4031 #endif
4032 default:
4033 MIPS_INVAL("bsfhl");
4034 generate_exception(ctx, EXCP_RI);
4035 tcg_temp_free(t0);
4036 return;
4038 tcg_temp_free(t0);
4041 #ifndef CONFIG_USER_ONLY
4042 /* CP0 (MMU and control) */
4043 static inline void gen_mfc0_load32 (TCGv arg, target_ulong off)
4045 TCGv_i32 t0 = tcg_temp_new_i32();
4047 tcg_gen_ld_i32(t0, cpu_env, off);
4048 tcg_gen_ext_i32_tl(arg, t0);
4049 tcg_temp_free_i32(t0);
4052 static inline void gen_mfc0_load64 (TCGv arg, target_ulong off)
4054 tcg_gen_ld_tl(arg, cpu_env, off);
4055 tcg_gen_ext32s_tl(arg, arg);
4058 static inline void gen_mtc0_store32 (TCGv arg, target_ulong off)
4060 TCGv_i32 t0 = tcg_temp_new_i32();
4062 tcg_gen_trunc_tl_i32(t0, arg);
4063 tcg_gen_st_i32(t0, cpu_env, off);
4064 tcg_temp_free_i32(t0);
4067 static inline void gen_mtc0_store64 (TCGv arg, target_ulong off)
4069 tcg_gen_ext32s_tl(arg, arg);
4070 tcg_gen_st_tl(arg, cpu_env, off);
4073 static void gen_mfc0(DisasContext *ctx, TCGv arg, int reg, int sel)
4075 const char *rn = "invalid";
4077 if (sel != 0)
4078 check_insn(ctx, ISA_MIPS32);
4080 switch (reg) {
4081 case 0:
4082 switch (sel) {
4083 case 0:
4084 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Index));
4085 rn = "Index";
4086 break;
4087 case 1:
4088 check_insn(ctx, ASE_MT);
4089 gen_helper_mfc0_mvpcontrol(arg, cpu_env);
4090 rn = "MVPControl";
4091 break;
4092 case 2:
4093 check_insn(ctx, ASE_MT);
4094 gen_helper_mfc0_mvpconf0(arg, cpu_env);
4095 rn = "MVPConf0";
4096 break;
4097 case 3:
4098 check_insn(ctx, ASE_MT);
4099 gen_helper_mfc0_mvpconf1(arg, cpu_env);
4100 rn = "MVPConf1";
4101 break;
4102 default:
4103 goto die;
4105 break;
4106 case 1:
4107 switch (sel) {
4108 case 0:
4109 gen_helper_mfc0_random(arg, cpu_env);
4110 rn = "Random";
4111 break;
4112 case 1:
4113 check_insn(ctx, ASE_MT);
4114 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEControl));
4115 rn = "VPEControl";
4116 break;
4117 case 2:
4118 check_insn(ctx, ASE_MT);
4119 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEConf0));
4120 rn = "VPEConf0";
4121 break;
4122 case 3:
4123 check_insn(ctx, ASE_MT);
4124 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEConf1));
4125 rn = "VPEConf1";
4126 break;
4127 case 4:
4128 check_insn(ctx, ASE_MT);
4129 gen_mfc0_load64(arg, offsetof(CPUMIPSState, CP0_YQMask));
4130 rn = "YQMask";
4131 break;
4132 case 5:
4133 check_insn(ctx, ASE_MT);
4134 gen_mfc0_load64(arg, offsetof(CPUMIPSState, CP0_VPESchedule));
4135 rn = "VPESchedule";
4136 break;
4137 case 6:
4138 check_insn(ctx, ASE_MT);
4139 gen_mfc0_load64(arg, offsetof(CPUMIPSState, CP0_VPEScheFBack));
4140 rn = "VPEScheFBack";
4141 break;
4142 case 7:
4143 check_insn(ctx, ASE_MT);
4144 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEOpt));
4145 rn = "VPEOpt";
4146 break;
4147 default:
4148 goto die;
4150 break;
4151 case 2:
4152 switch (sel) {
4153 case 0:
4154 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EntryLo0));
4155 tcg_gen_ext32s_tl(arg, arg);
4156 rn = "EntryLo0";
4157 break;
4158 case 1:
4159 check_insn(ctx, ASE_MT);
4160 gen_helper_mfc0_tcstatus(arg, cpu_env);
4161 rn = "TCStatus";
4162 break;
4163 case 2:
4164 check_insn(ctx, ASE_MT);
4165 gen_helper_mfc0_tcbind(arg, cpu_env);
4166 rn = "TCBind";
4167 break;
4168 case 3:
4169 check_insn(ctx, ASE_MT);
4170 gen_helper_mfc0_tcrestart(arg, cpu_env);
4171 rn = "TCRestart";
4172 break;
4173 case 4:
4174 check_insn(ctx, ASE_MT);
4175 gen_helper_mfc0_tchalt(arg, cpu_env);
4176 rn = "TCHalt";
4177 break;
4178 case 5:
4179 check_insn(ctx, ASE_MT);
4180 gen_helper_mfc0_tccontext(arg, cpu_env);
4181 rn = "TCContext";
4182 break;
4183 case 6:
4184 check_insn(ctx, ASE_MT);
4185 gen_helper_mfc0_tcschedule(arg, cpu_env);
4186 rn = "TCSchedule";
4187 break;
4188 case 7:
4189 check_insn(ctx, ASE_MT);
4190 gen_helper_mfc0_tcschefback(arg, cpu_env);
4191 rn = "TCScheFBack";
4192 break;
4193 default:
4194 goto die;
4196 break;
4197 case 3:
4198 switch (sel) {
4199 case 0:
4200 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EntryLo1));
4201 tcg_gen_ext32s_tl(arg, arg);
4202 rn = "EntryLo1";
4203 break;
4204 default:
4205 goto die;
4207 break;
4208 case 4:
4209 switch (sel) {
4210 case 0:
4211 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_Context));
4212 tcg_gen_ext32s_tl(arg, arg);
4213 rn = "Context";
4214 break;
4215 case 1:
4216 // gen_helper_mfc0_contextconfig(arg); /* SmartMIPS ASE */
4217 rn = "ContextConfig";
4218 // break;
4219 default:
4220 goto die;
4222 break;
4223 case 5:
4224 switch (sel) {
4225 case 0:
4226 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PageMask));
4227 rn = "PageMask";
4228 break;
4229 case 1:
4230 check_insn(ctx, ISA_MIPS32R2);
4231 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PageGrain));
4232 rn = "PageGrain";
4233 break;
4234 default:
4235 goto die;
4237 break;
4238 case 6:
4239 switch (sel) {
4240 case 0:
4241 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Wired));
4242 rn = "Wired";
4243 break;
4244 case 1:
4245 check_insn(ctx, ISA_MIPS32R2);
4246 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf0));
4247 rn = "SRSConf0";
4248 break;
4249 case 2:
4250 check_insn(ctx, ISA_MIPS32R2);
4251 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf1));
4252 rn = "SRSConf1";
4253 break;
4254 case 3:
4255 check_insn(ctx, ISA_MIPS32R2);
4256 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf2));
4257 rn = "SRSConf2";
4258 break;
4259 case 4:
4260 check_insn(ctx, ISA_MIPS32R2);
4261 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf3));
4262 rn = "SRSConf3";
4263 break;
4264 case 5:
4265 check_insn(ctx, ISA_MIPS32R2);
4266 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf4));
4267 rn = "SRSConf4";
4268 break;
4269 default:
4270 goto die;
4272 break;
4273 case 7:
4274 switch (sel) {
4275 case 0:
4276 check_insn(ctx, ISA_MIPS32R2);
4277 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_HWREna));
4278 rn = "HWREna";
4279 break;
4280 default:
4281 goto die;
4283 break;
4284 case 8:
4285 switch (sel) {
4286 case 0:
4287 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_BadVAddr));
4288 tcg_gen_ext32s_tl(arg, arg);
4289 rn = "BadVAddr";
4290 break;
4291 default:
4292 goto die;
4294 break;
4295 case 9:
4296 switch (sel) {
4297 case 0:
4298 /* Mark as an IO operation because we read the time. */
4299 if (use_icount)
4300 gen_io_start();
4301 gen_helper_mfc0_count(arg, cpu_env);
4302 if (use_icount) {
4303 gen_io_end();
4305 /* Break the TB to be able to take timer interrupts immediately
4306 after reading count. */
4307 ctx->bstate = BS_STOP;
4308 rn = "Count";
4309 break;
4310 /* 6,7 are implementation dependent */
4311 default:
4312 goto die;
4314 break;
4315 case 10:
4316 switch (sel) {
4317 case 0:
4318 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EntryHi));
4319 tcg_gen_ext32s_tl(arg, arg);
4320 rn = "EntryHi";
4321 break;
4322 default:
4323 goto die;
4325 break;
4326 case 11:
4327 switch (sel) {
4328 case 0:
4329 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Compare));
4330 rn = "Compare";
4331 break;
4332 /* 6,7 are implementation dependent */
4333 default:
4334 goto die;
4336 break;
4337 case 12:
4338 switch (sel) {
4339 case 0:
4340 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Status));
4341 rn = "Status";
4342 break;
4343 case 1:
4344 check_insn(ctx, ISA_MIPS32R2);
4345 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_IntCtl));
4346 rn = "IntCtl";
4347 break;
4348 case 2:
4349 check_insn(ctx, ISA_MIPS32R2);
4350 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSCtl));
4351 rn = "SRSCtl";
4352 break;
4353 case 3:
4354 check_insn(ctx, ISA_MIPS32R2);
4355 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSMap));
4356 rn = "SRSMap";
4357 break;
4358 default:
4359 goto die;
4361 break;
4362 case 13:
4363 switch (sel) {
4364 case 0:
4365 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Cause));
4366 rn = "Cause";
4367 break;
4368 default:
4369 goto die;
4371 break;
4372 case 14:
4373 switch (sel) {
4374 case 0:
4375 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EPC));
4376 tcg_gen_ext32s_tl(arg, arg);
4377 rn = "EPC";
4378 break;
4379 default:
4380 goto die;
4382 break;
4383 case 15:
4384 switch (sel) {
4385 case 0:
4386 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PRid));
4387 rn = "PRid";
4388 break;
4389 case 1:
4390 check_insn(ctx, ISA_MIPS32R2);
4391 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_EBase));
4392 rn = "EBase";
4393 break;
4394 default:
4395 goto die;
4397 break;
4398 case 16:
4399 switch (sel) {
4400 case 0:
4401 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config0));
4402 rn = "Config";
4403 break;
4404 case 1:
4405 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config1));
4406 rn = "Config1";
4407 break;
4408 case 2:
4409 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config2));
4410 rn = "Config2";
4411 break;
4412 case 3:
4413 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config3));
4414 rn = "Config3";
4415 break;
4416 /* 4,5 are reserved */
4417 /* 6,7 are implementation dependent */
4418 case 6:
4419 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config6));
4420 rn = "Config6";
4421 break;
4422 case 7:
4423 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config7));
4424 rn = "Config7";
4425 break;
4426 default:
4427 goto die;
4429 break;
4430 case 17:
4431 switch (sel) {
4432 case 0:
4433 gen_helper_mfc0_lladdr(arg, cpu_env);
4434 rn = "LLAddr";
4435 break;
4436 default:
4437 goto die;
4439 break;
4440 case 18:
4441 switch (sel) {
4442 case 0 ... 7:
4443 gen_helper_1e0i(mfc0_watchlo, arg, sel);
4444 rn = "WatchLo";
4445 break;
4446 default:
4447 goto die;
4449 break;
4450 case 19:
4451 switch (sel) {
4452 case 0 ...7:
4453 gen_helper_1e0i(mfc0_watchhi, arg, sel);
4454 rn = "WatchHi";
4455 break;
4456 default:
4457 goto die;
4459 break;
4460 case 20:
4461 switch (sel) {
4462 case 0:
4463 #if defined(TARGET_MIPS64)
4464 check_insn(ctx, ISA_MIPS3);
4465 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_XContext));
4466 tcg_gen_ext32s_tl(arg, arg);
4467 rn = "XContext";
4468 break;
4469 #endif
4470 default:
4471 goto die;
4473 break;
4474 case 21:
4475 /* Officially reserved, but sel 0 is used for R1x000 framemask */
4476 switch (sel) {
4477 case 0:
4478 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Framemask));
4479 rn = "Framemask";
4480 break;
4481 default:
4482 goto die;
4484 break;
4485 case 22:
4486 tcg_gen_movi_tl(arg, 0); /* unimplemented */
4487 rn = "'Diagnostic"; /* implementation dependent */
4488 break;
4489 case 23:
4490 switch (sel) {
4491 case 0:
4492 gen_helper_mfc0_debug(arg, cpu_env); /* EJTAG support */
4493 rn = "Debug";
4494 break;
4495 case 1:
4496 // gen_helper_mfc0_tracecontrol(arg); /* PDtrace support */
4497 rn = "TraceControl";
4498 // break;
4499 case 2:
4500 // gen_helper_mfc0_tracecontrol2(arg); /* PDtrace support */
4501 rn = "TraceControl2";
4502 // break;
4503 case 3:
4504 // gen_helper_mfc0_usertracedata(arg); /* PDtrace support */
4505 rn = "UserTraceData";
4506 // break;
4507 case 4:
4508 // gen_helper_mfc0_tracebpc(arg); /* PDtrace support */
4509 rn = "TraceBPC";
4510 // break;
4511 default:
4512 goto die;
4514 break;
4515 case 24:
4516 switch (sel) {
4517 case 0:
4518 /* EJTAG support */
4519 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_DEPC));
4520 tcg_gen_ext32s_tl(arg, arg);
4521 rn = "DEPC";
4522 break;
4523 default:
4524 goto die;
4526 break;
4527 case 25:
4528 switch (sel) {
4529 case 0:
4530 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Performance0));
4531 rn = "Performance0";
4532 break;
4533 case 1:
4534 // gen_helper_mfc0_performance1(arg);
4535 rn = "Performance1";
4536 // break;
4537 case 2:
4538 // gen_helper_mfc0_performance2(arg);
4539 rn = "Performance2";
4540 // break;
4541 case 3:
4542 // gen_helper_mfc0_performance3(arg);
4543 rn = "Performance3";
4544 // break;
4545 case 4:
4546 // gen_helper_mfc0_performance4(arg);
4547 rn = "Performance4";
4548 // break;
4549 case 5:
4550 // gen_helper_mfc0_performance5(arg);
4551 rn = "Performance5";
4552 // break;
4553 case 6:
4554 // gen_helper_mfc0_performance6(arg);
4555 rn = "Performance6";
4556 // break;
4557 case 7:
4558 // gen_helper_mfc0_performance7(arg);
4559 rn = "Performance7";
4560 // break;
4561 default:
4562 goto die;
4564 break;
4565 case 26:
4566 tcg_gen_movi_tl(arg, 0); /* unimplemented */
4567 rn = "ECC";
4568 break;
4569 case 27:
4570 switch (sel) {
4571 case 0 ... 3:
4572 tcg_gen_movi_tl(arg, 0); /* unimplemented */
4573 rn = "CacheErr";
4574 break;
4575 default:
4576 goto die;
4578 break;
4579 case 28:
4580 switch (sel) {
4581 case 0:
4582 case 2:
4583 case 4:
4584 case 6:
4585 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_TagLo));
4586 rn = "TagLo";
4587 break;
4588 case 1:
4589 case 3:
4590 case 5:
4591 case 7:
4592 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DataLo));
4593 rn = "DataLo";
4594 break;
4595 default:
4596 goto die;
4598 break;
4599 case 29:
4600 switch (sel) {
4601 case 0:
4602 case 2:
4603 case 4:
4604 case 6:
4605 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_TagHi));
4606 rn = "TagHi";
4607 break;
4608 case 1:
4609 case 3:
4610 case 5:
4611 case 7:
4612 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DataHi));
4613 rn = "DataHi";
4614 break;
4615 default:
4616 goto die;
4618 break;
4619 case 30:
4620 switch (sel) {
4621 case 0:
4622 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_ErrorEPC));
4623 tcg_gen_ext32s_tl(arg, arg);
4624 rn = "ErrorEPC";
4625 break;
4626 default:
4627 goto die;
4629 break;
4630 case 31:
4631 switch (sel) {
4632 case 0:
4633 /* EJTAG support */
4634 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DESAVE));
4635 rn = "DESAVE";
4636 break;
4637 default:
4638 goto die;
4640 break;
4641 default:
4642 goto die;
4644 (void)rn; /* avoid a compiler warning */
4645 LOG_DISAS("mfc0 %s (reg %d sel %d)\n", rn, reg, sel);
4646 return;
4648 die:
4649 LOG_DISAS("mfc0 %s (reg %d sel %d)\n", rn, reg, sel);
4650 generate_exception(ctx, EXCP_RI);
4653 static void gen_mtc0(DisasContext *ctx, TCGv arg, int reg, int sel)
4655 const char *rn = "invalid";
4657 if (sel != 0)
4658 check_insn(ctx, ISA_MIPS32);
4660 if (use_icount)
4661 gen_io_start();
4663 switch (reg) {
4664 case 0:
4665 switch (sel) {
4666 case 0:
4667 gen_helper_mtc0_index(cpu_env, arg);
4668 rn = "Index";
4669 break;
4670 case 1:
4671 check_insn(ctx, ASE_MT);
4672 gen_helper_mtc0_mvpcontrol(cpu_env, arg);
4673 rn = "MVPControl";
4674 break;
4675 case 2:
4676 check_insn(ctx, ASE_MT);
4677 /* ignored */
4678 rn = "MVPConf0";
4679 break;
4680 case 3:
4681 check_insn(ctx, ASE_MT);
4682 /* ignored */
4683 rn = "MVPConf1";
4684 break;
4685 default:
4686 goto die;
4688 break;
4689 case 1:
4690 switch (sel) {
4691 case 0:
4692 /* ignored */
4693 rn = "Random";
4694 break;
4695 case 1:
4696 check_insn(ctx, ASE_MT);
4697 gen_helper_mtc0_vpecontrol(cpu_env, arg);
4698 rn = "VPEControl";
4699 break;
4700 case 2:
4701 check_insn(ctx, ASE_MT);
4702 gen_helper_mtc0_vpeconf0(cpu_env, arg);
4703 rn = "VPEConf0";
4704 break;
4705 case 3:
4706 check_insn(ctx, ASE_MT);
4707 gen_helper_mtc0_vpeconf1(cpu_env, arg);
4708 rn = "VPEConf1";
4709 break;
4710 case 4:
4711 check_insn(ctx, ASE_MT);
4712 gen_helper_mtc0_yqmask(cpu_env, arg);
4713 rn = "YQMask";
4714 break;
4715 case 5:
4716 check_insn(ctx, ASE_MT);
4717 gen_mtc0_store64(arg, offsetof(CPUMIPSState, CP0_VPESchedule));
4718 rn = "VPESchedule";
4719 break;
4720 case 6:
4721 check_insn(ctx, ASE_MT);
4722 gen_mtc0_store64(arg, offsetof(CPUMIPSState, CP0_VPEScheFBack));
4723 rn = "VPEScheFBack";
4724 break;
4725 case 7:
4726 check_insn(ctx, ASE_MT);
4727 gen_helper_mtc0_vpeopt(cpu_env, arg);
4728 rn = "VPEOpt";
4729 break;
4730 default:
4731 goto die;
4733 break;
4734 case 2:
4735 switch (sel) {
4736 case 0:
4737 gen_helper_mtc0_entrylo0(cpu_env, arg);
4738 rn = "EntryLo0";
4739 break;
4740 case 1:
4741 check_insn(ctx, ASE_MT);
4742 gen_helper_mtc0_tcstatus(cpu_env, arg);
4743 rn = "TCStatus";
4744 break;
4745 case 2:
4746 check_insn(ctx, ASE_MT);
4747 gen_helper_mtc0_tcbind(cpu_env, arg);
4748 rn = "TCBind";
4749 break;
4750 case 3:
4751 check_insn(ctx, ASE_MT);
4752 gen_helper_mtc0_tcrestart(cpu_env, arg);
4753 rn = "TCRestart";
4754 break;
4755 case 4:
4756 check_insn(ctx, ASE_MT);
4757 gen_helper_mtc0_tchalt(cpu_env, arg);
4758 rn = "TCHalt";
4759 break;
4760 case 5:
4761 check_insn(ctx, ASE_MT);
4762 gen_helper_mtc0_tccontext(cpu_env, arg);
4763 rn = "TCContext";
4764 break;
4765 case 6:
4766 check_insn(ctx, ASE_MT);
4767 gen_helper_mtc0_tcschedule(cpu_env, arg);
4768 rn = "TCSchedule";
4769 break;
4770 case 7:
4771 check_insn(ctx, ASE_MT);
4772 gen_helper_mtc0_tcschefback(cpu_env, arg);
4773 rn = "TCScheFBack";
4774 break;
4775 default:
4776 goto die;
4778 break;
4779 case 3:
4780 switch (sel) {
4781 case 0:
4782 gen_helper_mtc0_entrylo1(cpu_env, arg);
4783 rn = "EntryLo1";
4784 break;
4785 default:
4786 goto die;
4788 break;
4789 case 4:
4790 switch (sel) {
4791 case 0:
4792 gen_helper_mtc0_context(cpu_env, arg);
4793 rn = "Context";
4794 break;
4795 case 1:
4796 // gen_helper_mtc0_contextconfig(cpu_env, arg); /* SmartMIPS ASE */
4797 rn = "ContextConfig";
4798 // break;
4799 default:
4800 goto die;
4802 break;
4803 case 5:
4804 switch (sel) {
4805 case 0:
4806 gen_helper_mtc0_pagemask(cpu_env, arg);
4807 rn = "PageMask";
4808 break;
4809 case 1:
4810 check_insn(ctx, ISA_MIPS32R2);
4811 gen_helper_mtc0_pagegrain(cpu_env, arg);
4812 rn = "PageGrain";
4813 break;
4814 default:
4815 goto die;
4817 break;
4818 case 6:
4819 switch (sel) {
4820 case 0:
4821 gen_helper_mtc0_wired(cpu_env, arg);
4822 rn = "Wired";
4823 break;
4824 case 1:
4825 check_insn(ctx, ISA_MIPS32R2);
4826 gen_helper_mtc0_srsconf0(cpu_env, arg);
4827 rn = "SRSConf0";
4828 break;
4829 case 2:
4830 check_insn(ctx, ISA_MIPS32R2);
4831 gen_helper_mtc0_srsconf1(cpu_env, arg);
4832 rn = "SRSConf1";
4833 break;
4834 case 3:
4835 check_insn(ctx, ISA_MIPS32R2);
4836 gen_helper_mtc0_srsconf2(cpu_env, arg);
4837 rn = "SRSConf2";
4838 break;
4839 case 4:
4840 check_insn(ctx, ISA_MIPS32R2);
4841 gen_helper_mtc0_srsconf3(cpu_env, arg);
4842 rn = "SRSConf3";
4843 break;
4844 case 5:
4845 check_insn(ctx, ISA_MIPS32R2);
4846 gen_helper_mtc0_srsconf4(cpu_env, arg);
4847 rn = "SRSConf4";
4848 break;
4849 default:
4850 goto die;
4852 break;
4853 case 7:
4854 switch (sel) {
4855 case 0:
4856 check_insn(ctx, ISA_MIPS32R2);
4857 gen_helper_mtc0_hwrena(cpu_env, arg);
4858 rn = "HWREna";
4859 break;
4860 default:
4861 goto die;
4863 break;
4864 case 8:
4865 /* ignored */
4866 rn = "BadVAddr";
4867 break;
4868 case 9:
4869 switch (sel) {
4870 case 0:
4871 gen_helper_mtc0_count(cpu_env, arg);
4872 rn = "Count";
4873 break;
4874 /* 6,7 are implementation dependent */
4875 default:
4876 goto die;
4878 break;
4879 case 10:
4880 switch (sel) {
4881 case 0:
4882 gen_helper_mtc0_entryhi(cpu_env, arg);
4883 rn = "EntryHi";
4884 break;
4885 default:
4886 goto die;
4888 break;
4889 case 11:
4890 switch (sel) {
4891 case 0:
4892 gen_helper_mtc0_compare(cpu_env, arg);
4893 rn = "Compare";
4894 break;
4895 /* 6,7 are implementation dependent */
4896 default:
4897 goto die;
4899 break;
4900 case 12:
4901 switch (sel) {
4902 case 0:
4903 save_cpu_state(ctx, 1);
4904 gen_helper_mtc0_status(cpu_env, arg);
4905 /* BS_STOP isn't good enough here, hflags may have changed. */
4906 gen_save_pc(ctx->pc + 4);
4907 ctx->bstate = BS_EXCP;
4908 rn = "Status";
4909 break;
4910 case 1:
4911 check_insn(ctx, ISA_MIPS32R2);
4912 gen_helper_mtc0_intctl(cpu_env, arg);
4913 /* Stop translation as we may have switched the execution mode */
4914 ctx->bstate = BS_STOP;
4915 rn = "IntCtl";
4916 break;
4917 case 2:
4918 check_insn(ctx, ISA_MIPS32R2);
4919 gen_helper_mtc0_srsctl(cpu_env, arg);
4920 /* Stop translation as we may have switched the execution mode */
4921 ctx->bstate = BS_STOP;
4922 rn = "SRSCtl";
4923 break;
4924 case 3:
4925 check_insn(ctx, ISA_MIPS32R2);
4926 gen_mtc0_store32(arg, offsetof(CPUMIPSState, CP0_SRSMap));
4927 /* Stop translation as we may have switched the execution mode */
4928 ctx->bstate = BS_STOP;
4929 rn = "SRSMap";
4930 break;
4931 default:
4932 goto die;
4934 break;
4935 case 13:
4936 switch (sel) {
4937 case 0:
4938 save_cpu_state(ctx, 1);
4939 gen_helper_mtc0_cause(cpu_env, arg);
4940 rn = "Cause";
4941 break;
4942 default:
4943 goto die;
4945 break;
4946 case 14:
4947 switch (sel) {
4948 case 0:
4949 gen_mtc0_store64(arg, offsetof(CPUMIPSState, CP0_EPC));
4950 rn = "EPC";
4951 break;
4952 default:
4953 goto die;
4955 break;
4956 case 15:
4957 switch (sel) {
4958 case 0:
4959 /* ignored */
4960 rn = "PRid";
4961 break;
4962 case 1:
4963 check_insn(ctx, ISA_MIPS32R2);
4964 gen_helper_mtc0_ebase(cpu_env, arg);
4965 rn = "EBase";
4966 break;
4967 default:
4968 goto die;
4970 break;
4971 case 16:
4972 switch (sel) {
4973 case 0:
4974 gen_helper_mtc0_config0(cpu_env, arg);
4975 rn = "Config";
4976 /* Stop translation as we may have switched the execution mode */
4977 ctx->bstate = BS_STOP;
4978 break;
4979 case 1:
4980 /* ignored, read only */
4981 rn = "Config1";
4982 break;
4983 case 2:
4984 gen_helper_mtc0_config2(cpu_env, arg);
4985 rn = "Config2";
4986 /* Stop translation as we may have switched the execution mode */
4987 ctx->bstate = BS_STOP;
4988 break;
4989 case 3:
4990 /* ignored, read only */
4991 rn = "Config3";
4992 break;
4993 /* 4,5 are reserved */
4994 /* 6,7 are implementation dependent */
4995 case 6:
4996 /* ignored */
4997 rn = "Config6";
4998 break;
4999 case 7:
5000 /* ignored */
5001 rn = "Config7";
5002 break;
5003 default:
5004 rn = "Invalid config selector";
5005 goto die;
5007 break;
5008 case 17:
5009 switch (sel) {
5010 case 0:
5011 gen_helper_mtc0_lladdr(cpu_env, arg);
5012 rn = "LLAddr";
5013 break;
5014 default:
5015 goto die;
5017 break;
5018 case 18:
5019 switch (sel) {
5020 case 0 ... 7:
5021 gen_helper_0e1i(mtc0_watchlo, arg, sel);
5022 rn = "WatchLo";
5023 break;
5024 default:
5025 goto die;
5027 break;
5028 case 19:
5029 switch (sel) {
5030 case 0 ... 7:
5031 gen_helper_0e1i(mtc0_watchhi, arg, sel);
5032 rn = "WatchHi";
5033 break;
5034 default:
5035 goto die;
5037 break;
5038 case 20:
5039 switch (sel) {
5040 case 0:
5041 #if defined(TARGET_MIPS64)
5042 check_insn(ctx, ISA_MIPS3);
5043 gen_helper_mtc0_xcontext(cpu_env, arg);
5044 rn = "XContext";
5045 break;
5046 #endif
5047 default:
5048 goto die;
5050 break;
5051 case 21:
5052 /* Officially reserved, but sel 0 is used for R1x000 framemask */
5053 switch (sel) {
5054 case 0:
5055 gen_helper_mtc0_framemask(cpu_env, arg);
5056 rn = "Framemask";
5057 break;
5058 default:
5059 goto die;
5061 break;
5062 case 22:
5063 /* ignored */
5064 rn = "Diagnostic"; /* implementation dependent */
5065 break;
5066 case 23:
5067 switch (sel) {
5068 case 0:
5069 gen_helper_mtc0_debug(cpu_env, arg); /* EJTAG support */
5070 /* BS_STOP isn't good enough here, hflags may have changed. */
5071 gen_save_pc(ctx->pc + 4);
5072 ctx->bstate = BS_EXCP;
5073 rn = "Debug";
5074 break;
5075 case 1:
5076 // gen_helper_mtc0_tracecontrol(cpu_env, arg); /* PDtrace support */
5077 rn = "TraceControl";
5078 /* Stop translation as we may have switched the execution mode */
5079 ctx->bstate = BS_STOP;
5080 // break;
5081 case 2:
5082 // gen_helper_mtc0_tracecontrol2(cpu_env, arg); /* PDtrace support */
5083 rn = "TraceControl2";
5084 /* Stop translation as we may have switched the execution mode */
5085 ctx->bstate = BS_STOP;
5086 // break;
5087 case 3:
5088 /* Stop translation as we may have switched the execution mode */
5089 ctx->bstate = BS_STOP;
5090 // gen_helper_mtc0_usertracedata(cpu_env, arg); /* PDtrace support */
5091 rn = "UserTraceData";
5092 /* Stop translation as we may have switched the execution mode */
5093 ctx->bstate = BS_STOP;
5094 // break;
5095 case 4:
5096 // gen_helper_mtc0_tracebpc(cpu_env, arg); /* PDtrace support */
5097 /* Stop translation as we may have switched the execution mode */
5098 ctx->bstate = BS_STOP;
5099 rn = "TraceBPC";
5100 // break;
5101 default:
5102 goto die;
5104 break;
5105 case 24:
5106 switch (sel) {
5107 case 0:
5108 /* EJTAG support */
5109 gen_mtc0_store64(arg, offsetof(CPUMIPSState, CP0_DEPC));
5110 rn = "DEPC";
5111 break;
5112 default:
5113 goto die;
5115 break;
5116 case 25:
5117 switch (sel) {
5118 case 0:
5119 gen_helper_mtc0_performance0(cpu_env, arg);
5120 rn = "Performance0";
5121 break;
5122 case 1:
5123 // gen_helper_mtc0_performance1(arg);
5124 rn = "Performance1";
5125 // break;
5126 case 2:
5127 // gen_helper_mtc0_performance2(arg);
5128 rn = "Performance2";
5129 // break;
5130 case 3:
5131 // gen_helper_mtc0_performance3(arg);
5132 rn = "Performance3";
5133 // break;
5134 case 4:
5135 // gen_helper_mtc0_performance4(arg);
5136 rn = "Performance4";
5137 // break;
5138 case 5:
5139 // gen_helper_mtc0_performance5(arg);
5140 rn = "Performance5";
5141 // break;
5142 case 6:
5143 // gen_helper_mtc0_performance6(arg);
5144 rn = "Performance6";
5145 // break;
5146 case 7:
5147 // gen_helper_mtc0_performance7(arg);
5148 rn = "Performance7";
5149 // break;
5150 default:
5151 goto die;
5153 break;
5154 case 26:
5155 /* ignored */
5156 rn = "ECC";
5157 break;
5158 case 27:
5159 switch (sel) {
5160 case 0 ... 3:
5161 /* ignored */
5162 rn = "CacheErr";
5163 break;
5164 default:
5165 goto die;
5167 break;
5168 case 28:
5169 switch (sel) {
5170 case 0:
5171 case 2:
5172 case 4:
5173 case 6:
5174 gen_helper_mtc0_taglo(cpu_env, arg);
5175 rn = "TagLo";
5176 break;
5177 case 1:
5178 case 3:
5179 case 5:
5180 case 7:
5181 gen_helper_mtc0_datalo(cpu_env, arg);
5182 rn = "DataLo";
5183 break;
5184 default:
5185 goto die;
5187 break;
5188 case 29:
5189 switch (sel) {
5190 case 0:
5191 case 2:
5192 case 4:
5193 case 6:
5194 gen_helper_mtc0_taghi(cpu_env, arg);
5195 rn = "TagHi";
5196 break;
5197 case 1:
5198 case 3:
5199 case 5:
5200 case 7:
5201 gen_helper_mtc0_datahi(cpu_env, arg);
5202 rn = "DataHi";
5203 break;
5204 default:
5205 rn = "invalid sel";
5206 goto die;
5208 break;
5209 case 30:
5210 switch (sel) {
5211 case 0:
5212 gen_mtc0_store64(arg, offsetof(CPUMIPSState, CP0_ErrorEPC));
5213 rn = "ErrorEPC";
5214 break;
5215 default:
5216 goto die;
5218 break;
5219 case 31:
5220 switch (sel) {
5221 case 0:
5222 /* EJTAG support */
5223 gen_mtc0_store32(arg, offsetof(CPUMIPSState, CP0_DESAVE));
5224 rn = "DESAVE";
5225 break;
5226 default:
5227 goto die;
5229 /* Stop translation as we may have switched the execution mode */
5230 ctx->bstate = BS_STOP;
5231 break;
5232 default:
5233 goto die;
5235 (void)rn; /* avoid a compiler warning */
5236 LOG_DISAS("mtc0 %s (reg %d sel %d)\n", rn, reg, sel);
5237 /* For simplicity assume that all writes can cause interrupts. */
5238 if (use_icount) {
5239 gen_io_end();
5240 ctx->bstate = BS_STOP;
5242 return;
5244 die:
5245 LOG_DISAS("mtc0 %s (reg %d sel %d)\n", rn, reg, sel);
5246 generate_exception(ctx, EXCP_RI);
5249 #if defined(TARGET_MIPS64)
5250 static void gen_dmfc0(DisasContext *ctx, TCGv arg, int reg, int sel)
5252 const char *rn = "invalid";
5254 if (sel != 0)
5255 check_insn(ctx, ISA_MIPS64);
5257 switch (reg) {
5258 case 0:
5259 switch (sel) {
5260 case 0:
5261 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Index));
5262 rn = "Index";
5263 break;
5264 case 1:
5265 check_insn(ctx, ASE_MT);
5266 gen_helper_mfc0_mvpcontrol(arg, cpu_env);
5267 rn = "MVPControl";
5268 break;
5269 case 2:
5270 check_insn(ctx, ASE_MT);
5271 gen_helper_mfc0_mvpconf0(arg, cpu_env);
5272 rn = "MVPConf0";
5273 break;
5274 case 3:
5275 check_insn(ctx, ASE_MT);
5276 gen_helper_mfc0_mvpconf1(arg, cpu_env);
5277 rn = "MVPConf1";
5278 break;
5279 default:
5280 goto die;
5282 break;
5283 case 1:
5284 switch (sel) {
5285 case 0:
5286 gen_helper_mfc0_random(arg, cpu_env);
5287 rn = "Random";
5288 break;
5289 case 1:
5290 check_insn(ctx, ASE_MT);
5291 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEControl));
5292 rn = "VPEControl";
5293 break;
5294 case 2:
5295 check_insn(ctx, ASE_MT);
5296 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEConf0));
5297 rn = "VPEConf0";
5298 break;
5299 case 3:
5300 check_insn(ctx, ASE_MT);
5301 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEConf1));
5302 rn = "VPEConf1";
5303 break;
5304 case 4:
5305 check_insn(ctx, ASE_MT);
5306 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_YQMask));
5307 rn = "YQMask";
5308 break;
5309 case 5:
5310 check_insn(ctx, ASE_MT);
5311 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_VPESchedule));
5312 rn = "VPESchedule";
5313 break;
5314 case 6:
5315 check_insn(ctx, ASE_MT);
5316 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_VPEScheFBack));
5317 rn = "VPEScheFBack";
5318 break;
5319 case 7:
5320 check_insn(ctx, ASE_MT);
5321 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEOpt));
5322 rn = "VPEOpt";
5323 break;
5324 default:
5325 goto die;
5327 break;
5328 case 2:
5329 switch (sel) {
5330 case 0:
5331 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EntryLo0));
5332 rn = "EntryLo0";
5333 break;
5334 case 1:
5335 check_insn(ctx, ASE_MT);
5336 gen_helper_mfc0_tcstatus(arg, cpu_env);
5337 rn = "TCStatus";
5338 break;
5339 case 2:
5340 check_insn(ctx, ASE_MT);
5341 gen_helper_mfc0_tcbind(arg, cpu_env);
5342 rn = "TCBind";
5343 break;
5344 case 3:
5345 check_insn(ctx, ASE_MT);
5346 gen_helper_dmfc0_tcrestart(arg, cpu_env);
5347 rn = "TCRestart";
5348 break;
5349 case 4:
5350 check_insn(ctx, ASE_MT);
5351 gen_helper_dmfc0_tchalt(arg, cpu_env);
5352 rn = "TCHalt";
5353 break;
5354 case 5:
5355 check_insn(ctx, ASE_MT);
5356 gen_helper_dmfc0_tccontext(arg, cpu_env);
5357 rn = "TCContext";
5358 break;
5359 case 6:
5360 check_insn(ctx, ASE_MT);
5361 gen_helper_dmfc0_tcschedule(arg, cpu_env);
5362 rn = "TCSchedule";
5363 break;
5364 case 7:
5365 check_insn(ctx, ASE_MT);
5366 gen_helper_dmfc0_tcschefback(arg, cpu_env);
5367 rn = "TCScheFBack";
5368 break;
5369 default:
5370 goto die;
5372 break;
5373 case 3:
5374 switch (sel) {
5375 case 0:
5376 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EntryLo1));
5377 rn = "EntryLo1";
5378 break;
5379 default:
5380 goto die;
5382 break;
5383 case 4:
5384 switch (sel) {
5385 case 0:
5386 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_Context));
5387 rn = "Context";
5388 break;
5389 case 1:
5390 // gen_helper_dmfc0_contextconfig(arg); /* SmartMIPS ASE */
5391 rn = "ContextConfig";
5392 // break;
5393 default:
5394 goto die;
5396 break;
5397 case 5:
5398 switch (sel) {
5399 case 0:
5400 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PageMask));
5401 rn = "PageMask";
5402 break;
5403 case 1:
5404 check_insn(ctx, ISA_MIPS32R2);
5405 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PageGrain));
5406 rn = "PageGrain";
5407 break;
5408 default:
5409 goto die;
5411 break;
5412 case 6:
5413 switch (sel) {
5414 case 0:
5415 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Wired));
5416 rn = "Wired";
5417 break;
5418 case 1:
5419 check_insn(ctx, ISA_MIPS32R2);
5420 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf0));
5421 rn = "SRSConf0";
5422 break;
5423 case 2:
5424 check_insn(ctx, ISA_MIPS32R2);
5425 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf1));
5426 rn = "SRSConf1";
5427 break;
5428 case 3:
5429 check_insn(ctx, ISA_MIPS32R2);
5430 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf2));
5431 rn = "SRSConf2";
5432 break;
5433 case 4:
5434 check_insn(ctx, ISA_MIPS32R2);
5435 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf3));
5436 rn = "SRSConf3";
5437 break;
5438 case 5:
5439 check_insn(ctx, ISA_MIPS32R2);
5440 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf4));
5441 rn = "SRSConf4";
5442 break;
5443 default:
5444 goto die;
5446 break;
5447 case 7:
5448 switch (sel) {
5449 case 0:
5450 check_insn(ctx, ISA_MIPS32R2);
5451 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_HWREna));
5452 rn = "HWREna";
5453 break;
5454 default:
5455 goto die;
5457 break;
5458 case 8:
5459 switch (sel) {
5460 case 0:
5461 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_BadVAddr));
5462 rn = "BadVAddr";
5463 break;
5464 default:
5465 goto die;
5467 break;
5468 case 9:
5469 switch (sel) {
5470 case 0:
5471 /* Mark as an IO operation because we read the time. */
5472 if (use_icount)
5473 gen_io_start();
5474 gen_helper_mfc0_count(arg, cpu_env);
5475 if (use_icount) {
5476 gen_io_end();
5478 /* Break the TB to be able to take timer interrupts immediately
5479 after reading count. */
5480 ctx->bstate = BS_STOP;
5481 rn = "Count";
5482 break;
5483 /* 6,7 are implementation dependent */
5484 default:
5485 goto die;
5487 break;
5488 case 10:
5489 switch (sel) {
5490 case 0:
5491 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EntryHi));
5492 rn = "EntryHi";
5493 break;
5494 default:
5495 goto die;
5497 break;
5498 case 11:
5499 switch (sel) {
5500 case 0:
5501 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Compare));
5502 rn = "Compare";
5503 break;
5504 /* 6,7 are implementation dependent */
5505 default:
5506 goto die;
5508 break;
5509 case 12:
5510 switch (sel) {
5511 case 0:
5512 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Status));
5513 rn = "Status";
5514 break;
5515 case 1:
5516 check_insn(ctx, ISA_MIPS32R2);
5517 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_IntCtl));
5518 rn = "IntCtl";
5519 break;
5520 case 2:
5521 check_insn(ctx, ISA_MIPS32R2);
5522 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSCtl));
5523 rn = "SRSCtl";
5524 break;
5525 case 3:
5526 check_insn(ctx, ISA_MIPS32R2);
5527 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSMap));
5528 rn = "SRSMap";
5529 break;
5530 default:
5531 goto die;
5533 break;
5534 case 13:
5535 switch (sel) {
5536 case 0:
5537 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Cause));
5538 rn = "Cause";
5539 break;
5540 default:
5541 goto die;
5543 break;
5544 case 14:
5545 switch (sel) {
5546 case 0:
5547 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EPC));
5548 rn = "EPC";
5549 break;
5550 default:
5551 goto die;
5553 break;
5554 case 15:
5555 switch (sel) {
5556 case 0:
5557 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PRid));
5558 rn = "PRid";
5559 break;
5560 case 1:
5561 check_insn(ctx, ISA_MIPS32R2);
5562 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_EBase));
5563 rn = "EBase";
5564 break;
5565 default:
5566 goto die;
5568 break;
5569 case 16:
5570 switch (sel) {
5571 case 0:
5572 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config0));
5573 rn = "Config";
5574 break;
5575 case 1:
5576 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config1));
5577 rn = "Config1";
5578 break;
5579 case 2:
5580 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config2));
5581 rn = "Config2";
5582 break;
5583 case 3:
5584 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config3));
5585 rn = "Config3";
5586 break;
5587 /* 6,7 are implementation dependent */
5588 case 6:
5589 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config6));
5590 rn = "Config6";
5591 break;
5592 case 7:
5593 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config7));
5594 rn = "Config7";
5595 break;
5596 default:
5597 goto die;
5599 break;
5600 case 17:
5601 switch (sel) {
5602 case 0:
5603 gen_helper_dmfc0_lladdr(arg, cpu_env);
5604 rn = "LLAddr";
5605 break;
5606 default:
5607 goto die;
5609 break;
5610 case 18:
5611 switch (sel) {
5612 case 0 ... 7:
5613 gen_helper_1e0i(dmfc0_watchlo, arg, sel);
5614 rn = "WatchLo";
5615 break;
5616 default:
5617 goto die;
5619 break;
5620 case 19:
5621 switch (sel) {
5622 case 0 ... 7:
5623 gen_helper_1e0i(mfc0_watchhi, arg, sel);
5624 rn = "WatchHi";
5625 break;
5626 default:
5627 goto die;
5629 break;
5630 case 20:
5631 switch (sel) {
5632 case 0:
5633 check_insn(ctx, ISA_MIPS3);
5634 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_XContext));
5635 rn = "XContext";
5636 break;
5637 default:
5638 goto die;
5640 break;
5641 case 21:
5642 /* Officially reserved, but sel 0 is used for R1x000 framemask */
5643 switch (sel) {
5644 case 0:
5645 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Framemask));
5646 rn = "Framemask";
5647 break;
5648 default:
5649 goto die;
5651 break;
5652 case 22:
5653 tcg_gen_movi_tl(arg, 0); /* unimplemented */
5654 rn = "'Diagnostic"; /* implementation dependent */
5655 break;
5656 case 23:
5657 switch (sel) {
5658 case 0:
5659 gen_helper_mfc0_debug(arg, cpu_env); /* EJTAG support */
5660 rn = "Debug";
5661 break;
5662 case 1:
5663 // gen_helper_dmfc0_tracecontrol(arg, cpu_env); /* PDtrace support */
5664 rn = "TraceControl";
5665 // break;
5666 case 2:
5667 // gen_helper_dmfc0_tracecontrol2(arg, cpu_env); /* PDtrace support */
5668 rn = "TraceControl2";
5669 // break;
5670 case 3:
5671 // gen_helper_dmfc0_usertracedata(arg, cpu_env); /* PDtrace support */
5672 rn = "UserTraceData";
5673 // break;
5674 case 4:
5675 // gen_helper_dmfc0_tracebpc(arg, cpu_env); /* PDtrace support */
5676 rn = "TraceBPC";
5677 // break;
5678 default:
5679 goto die;
5681 break;
5682 case 24:
5683 switch (sel) {
5684 case 0:
5685 /* EJTAG support */
5686 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_DEPC));
5687 rn = "DEPC";
5688 break;
5689 default:
5690 goto die;
5692 break;
5693 case 25:
5694 switch (sel) {
5695 case 0:
5696 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Performance0));
5697 rn = "Performance0";
5698 break;
5699 case 1:
5700 // gen_helper_dmfc0_performance1(arg);
5701 rn = "Performance1";
5702 // break;
5703 case 2:
5704 // gen_helper_dmfc0_performance2(arg);
5705 rn = "Performance2";
5706 // break;
5707 case 3:
5708 // gen_helper_dmfc0_performance3(arg);
5709 rn = "Performance3";
5710 // break;
5711 case 4:
5712 // gen_helper_dmfc0_performance4(arg);
5713 rn = "Performance4";
5714 // break;
5715 case 5:
5716 // gen_helper_dmfc0_performance5(arg);
5717 rn = "Performance5";
5718 // break;
5719 case 6:
5720 // gen_helper_dmfc0_performance6(arg);
5721 rn = "Performance6";
5722 // break;
5723 case 7:
5724 // gen_helper_dmfc0_performance7(arg);
5725 rn = "Performance7";
5726 // break;
5727 default:
5728 goto die;
5730 break;
5731 case 26:
5732 tcg_gen_movi_tl(arg, 0); /* unimplemented */
5733 rn = "ECC";
5734 break;
5735 case 27:
5736 switch (sel) {
5737 /* ignored */
5738 case 0 ... 3:
5739 tcg_gen_movi_tl(arg, 0); /* unimplemented */
5740 rn = "CacheErr";
5741 break;
5742 default:
5743 goto die;
5745 break;
5746 case 28:
5747 switch (sel) {
5748 case 0:
5749 case 2:
5750 case 4:
5751 case 6:
5752 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_TagLo));
5753 rn = "TagLo";
5754 break;
5755 case 1:
5756 case 3:
5757 case 5:
5758 case 7:
5759 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DataLo));
5760 rn = "DataLo";
5761 break;
5762 default:
5763 goto die;
5765 break;
5766 case 29:
5767 switch (sel) {
5768 case 0:
5769 case 2:
5770 case 4:
5771 case 6:
5772 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_TagHi));
5773 rn = "TagHi";
5774 break;
5775 case 1:
5776 case 3:
5777 case 5:
5778 case 7:
5779 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DataHi));
5780 rn = "DataHi";
5781 break;
5782 default:
5783 goto die;
5785 break;
5786 case 30:
5787 switch (sel) {
5788 case 0:
5789 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_ErrorEPC));
5790 rn = "ErrorEPC";
5791 break;
5792 default:
5793 goto die;
5795 break;
5796 case 31:
5797 switch (sel) {
5798 case 0:
5799 /* EJTAG support */
5800 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DESAVE));
5801 rn = "DESAVE";
5802 break;
5803 default:
5804 goto die;
5806 break;
5807 default:
5808 goto die;
5810 (void)rn; /* avoid a compiler warning */
5811 LOG_DISAS("dmfc0 %s (reg %d sel %d)\n", rn, reg, sel);
5812 return;
5814 die:
5815 LOG_DISAS("dmfc0 %s (reg %d sel %d)\n", rn, reg, sel);
5816 generate_exception(ctx, EXCP_RI);
5819 static void gen_dmtc0(DisasContext *ctx, TCGv arg, int reg, int sel)
5821 const char *rn = "invalid";
5823 if (sel != 0)
5824 check_insn(ctx, ISA_MIPS64);
5826 if (use_icount)
5827 gen_io_start();
5829 switch (reg) {
5830 case 0:
5831 switch (sel) {
5832 case 0:
5833 gen_helper_mtc0_index(cpu_env, arg);
5834 rn = "Index";
5835 break;
5836 case 1:
5837 check_insn(ctx, ASE_MT);
5838 gen_helper_mtc0_mvpcontrol(cpu_env, arg);
5839 rn = "MVPControl";
5840 break;
5841 case 2:
5842 check_insn(ctx, ASE_MT);
5843 /* ignored */
5844 rn = "MVPConf0";
5845 break;
5846 case 3:
5847 check_insn(ctx, ASE_MT);
5848 /* ignored */
5849 rn = "MVPConf1";
5850 break;
5851 default:
5852 goto die;
5854 break;
5855 case 1:
5856 switch (sel) {
5857 case 0:
5858 /* ignored */
5859 rn = "Random";
5860 break;
5861 case 1:
5862 check_insn(ctx, ASE_MT);
5863 gen_helper_mtc0_vpecontrol(cpu_env, arg);
5864 rn = "VPEControl";
5865 break;
5866 case 2:
5867 check_insn(ctx, ASE_MT);
5868 gen_helper_mtc0_vpeconf0(cpu_env, arg);
5869 rn = "VPEConf0";
5870 break;
5871 case 3:
5872 check_insn(ctx, ASE_MT);
5873 gen_helper_mtc0_vpeconf1(cpu_env, arg);
5874 rn = "VPEConf1";
5875 break;
5876 case 4:
5877 check_insn(ctx, ASE_MT);
5878 gen_helper_mtc0_yqmask(cpu_env, arg);
5879 rn = "YQMask";
5880 break;
5881 case 5:
5882 check_insn(ctx, ASE_MT);
5883 tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_VPESchedule));
5884 rn = "VPESchedule";
5885 break;
5886 case 6:
5887 check_insn(ctx, ASE_MT);
5888 tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_VPEScheFBack));
5889 rn = "VPEScheFBack";
5890 break;
5891 case 7:
5892 check_insn(ctx, ASE_MT);
5893 gen_helper_mtc0_vpeopt(cpu_env, arg);
5894 rn = "VPEOpt";
5895 break;
5896 default:
5897 goto die;
5899 break;
5900 case 2:
5901 switch (sel) {
5902 case 0:
5903 gen_helper_mtc0_entrylo0(cpu_env, arg);
5904 rn = "EntryLo0";
5905 break;
5906 case 1:
5907 check_insn(ctx, ASE_MT);
5908 gen_helper_mtc0_tcstatus(cpu_env, arg);
5909 rn = "TCStatus";
5910 break;
5911 case 2:
5912 check_insn(ctx, ASE_MT);
5913 gen_helper_mtc0_tcbind(cpu_env, arg);
5914 rn = "TCBind";
5915 break;
5916 case 3:
5917 check_insn(ctx, ASE_MT);
5918 gen_helper_mtc0_tcrestart(cpu_env, arg);
5919 rn = "TCRestart";
5920 break;
5921 case 4:
5922 check_insn(ctx, ASE_MT);
5923 gen_helper_mtc0_tchalt(cpu_env, arg);
5924 rn = "TCHalt";
5925 break;
5926 case 5:
5927 check_insn(ctx, ASE_MT);
5928 gen_helper_mtc0_tccontext(cpu_env, arg);
5929 rn = "TCContext";
5930 break;
5931 case 6:
5932 check_insn(ctx, ASE_MT);
5933 gen_helper_mtc0_tcschedule(cpu_env, arg);
5934 rn = "TCSchedule";
5935 break;
5936 case 7:
5937 check_insn(ctx, ASE_MT);
5938 gen_helper_mtc0_tcschefback(cpu_env, arg);
5939 rn = "TCScheFBack";
5940 break;
5941 default:
5942 goto die;
5944 break;
5945 case 3:
5946 switch (sel) {
5947 case 0:
5948 gen_helper_mtc0_entrylo1(cpu_env, arg);
5949 rn = "EntryLo1";
5950 break;
5951 default:
5952 goto die;
5954 break;
5955 case 4:
5956 switch (sel) {
5957 case 0:
5958 gen_helper_mtc0_context(cpu_env, arg);
5959 rn = "Context";
5960 break;
5961 case 1:
5962 // gen_helper_mtc0_contextconfig(cpu_env, arg); /* SmartMIPS ASE */
5963 rn = "ContextConfig";
5964 // break;
5965 default:
5966 goto die;
5968 break;
5969 case 5:
5970 switch (sel) {
5971 case 0:
5972 gen_helper_mtc0_pagemask(cpu_env, arg);
5973 rn = "PageMask";
5974 break;
5975 case 1:
5976 check_insn(ctx, ISA_MIPS32R2);
5977 gen_helper_mtc0_pagegrain(cpu_env, arg);
5978 rn = "PageGrain";
5979 break;
5980 default:
5981 goto die;
5983 break;
5984 case 6:
5985 switch (sel) {
5986 case 0:
5987 gen_helper_mtc0_wired(cpu_env, arg);
5988 rn = "Wired";
5989 break;
5990 case 1:
5991 check_insn(ctx, ISA_MIPS32R2);
5992 gen_helper_mtc0_srsconf0(cpu_env, arg);
5993 rn = "SRSConf0";
5994 break;
5995 case 2:
5996 check_insn(ctx, ISA_MIPS32R2);
5997 gen_helper_mtc0_srsconf1(cpu_env, arg);
5998 rn = "SRSConf1";
5999 break;
6000 case 3:
6001 check_insn(ctx, ISA_MIPS32R2);
6002 gen_helper_mtc0_srsconf2(cpu_env, arg);
6003 rn = "SRSConf2";
6004 break;
6005 case 4:
6006 check_insn(ctx, ISA_MIPS32R2);
6007 gen_helper_mtc0_srsconf3(cpu_env, arg);
6008 rn = "SRSConf3";
6009 break;
6010 case 5:
6011 check_insn(ctx, ISA_MIPS32R2);
6012 gen_helper_mtc0_srsconf4(cpu_env, arg);
6013 rn = "SRSConf4";
6014 break;
6015 default:
6016 goto die;
6018 break;
6019 case 7:
6020 switch (sel) {
6021 case 0:
6022 check_insn(ctx, ISA_MIPS32R2);
6023 gen_helper_mtc0_hwrena(cpu_env, arg);
6024 rn = "HWREna";
6025 break;
6026 default:
6027 goto die;
6029 break;
6030 case 8:
6031 /* ignored */
6032 rn = "BadVAddr";
6033 break;
6034 case 9:
6035 switch (sel) {
6036 case 0:
6037 gen_helper_mtc0_count(cpu_env, arg);
6038 rn = "Count";
6039 break;
6040 /* 6,7 are implementation dependent */
6041 default:
6042 goto die;
6044 /* Stop translation as we may have switched the execution mode */
6045 ctx->bstate = BS_STOP;
6046 break;
6047 case 10:
6048 switch (sel) {
6049 case 0:
6050 gen_helper_mtc0_entryhi(cpu_env, arg);
6051 rn = "EntryHi";
6052 break;
6053 default:
6054 goto die;
6056 break;
6057 case 11:
6058 switch (sel) {
6059 case 0:
6060 gen_helper_mtc0_compare(cpu_env, arg);
6061 rn = "Compare";
6062 break;
6063 /* 6,7 are implementation dependent */
6064 default:
6065 goto die;
6067 /* Stop translation as we may have switched the execution mode */
6068 ctx->bstate = BS_STOP;
6069 break;
6070 case 12:
6071 switch (sel) {
6072 case 0:
6073 save_cpu_state(ctx, 1);
6074 gen_helper_mtc0_status(cpu_env, arg);
6075 /* BS_STOP isn't good enough here, hflags may have changed. */
6076 gen_save_pc(ctx->pc + 4);
6077 ctx->bstate = BS_EXCP;
6078 rn = "Status";
6079 break;
6080 case 1:
6081 check_insn(ctx, ISA_MIPS32R2);
6082 gen_helper_mtc0_intctl(cpu_env, arg);
6083 /* Stop translation as we may have switched the execution mode */
6084 ctx->bstate = BS_STOP;
6085 rn = "IntCtl";
6086 break;
6087 case 2:
6088 check_insn(ctx, ISA_MIPS32R2);
6089 gen_helper_mtc0_srsctl(cpu_env, arg);
6090 /* Stop translation as we may have switched the execution mode */
6091 ctx->bstate = BS_STOP;
6092 rn = "SRSCtl";
6093 break;
6094 case 3:
6095 check_insn(ctx, ISA_MIPS32R2);
6096 gen_mtc0_store32(arg, offsetof(CPUMIPSState, CP0_SRSMap));
6097 /* Stop translation as we may have switched the execution mode */
6098 ctx->bstate = BS_STOP;
6099 rn = "SRSMap";
6100 break;
6101 default:
6102 goto die;
6104 break;
6105 case 13:
6106 switch (sel) {
6107 case 0:
6108 save_cpu_state(ctx, 1);
6109 /* Mark as an IO operation because we may trigger a software
6110 interrupt. */
6111 if (use_icount) {
6112 gen_io_start();
6114 gen_helper_mtc0_cause(cpu_env, arg);
6115 if (use_icount) {
6116 gen_io_end();
6118 /* Stop translation as we may have triggered an intetrupt */
6119 ctx->bstate = BS_STOP;
6120 rn = "Cause";
6121 break;
6122 default:
6123 goto die;
6125 break;
6126 case 14:
6127 switch (sel) {
6128 case 0:
6129 tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EPC));
6130 rn = "EPC";
6131 break;
6132 default:
6133 goto die;
6135 break;
6136 case 15:
6137 switch (sel) {
6138 case 0:
6139 /* ignored */
6140 rn = "PRid";
6141 break;
6142 case 1:
6143 check_insn(ctx, ISA_MIPS32R2);
6144 gen_helper_mtc0_ebase(cpu_env, arg);
6145 rn = "EBase";
6146 break;
6147 default:
6148 goto die;
6150 break;
6151 case 16:
6152 switch (sel) {
6153 case 0:
6154 gen_helper_mtc0_config0(cpu_env, arg);
6155 rn = "Config";
6156 /* Stop translation as we may have switched the execution mode */
6157 ctx->bstate = BS_STOP;
6158 break;
6159 case 1:
6160 /* ignored, read only */
6161 rn = "Config1";
6162 break;
6163 case 2:
6164 gen_helper_mtc0_config2(cpu_env, arg);
6165 rn = "Config2";
6166 /* Stop translation as we may have switched the execution mode */
6167 ctx->bstate = BS_STOP;
6168 break;
6169 case 3:
6170 /* ignored */
6171 rn = "Config3";
6172 break;
6173 /* 6,7 are implementation dependent */
6174 default:
6175 rn = "Invalid config selector";
6176 goto die;
6178 break;
6179 case 17:
6180 switch (sel) {
6181 case 0:
6182 gen_helper_mtc0_lladdr(cpu_env, arg);
6183 rn = "LLAddr";
6184 break;
6185 default:
6186 goto die;
6188 break;
6189 case 18:
6190 switch (sel) {
6191 case 0 ... 7:
6192 gen_helper_0e1i(mtc0_watchlo, arg, sel);
6193 rn = "WatchLo";
6194 break;
6195 default:
6196 goto die;
6198 break;
6199 case 19:
6200 switch (sel) {
6201 case 0 ... 7:
6202 gen_helper_0e1i(mtc0_watchhi, arg, sel);
6203 rn = "WatchHi";
6204 break;
6205 default:
6206 goto die;
6208 break;
6209 case 20:
6210 switch (sel) {
6211 case 0:
6212 check_insn(ctx, ISA_MIPS3);
6213 gen_helper_mtc0_xcontext(cpu_env, arg);
6214 rn = "XContext";
6215 break;
6216 default:
6217 goto die;
6219 break;
6220 case 21:
6221 /* Officially reserved, but sel 0 is used for R1x000 framemask */
6222 switch (sel) {
6223 case 0:
6224 gen_helper_mtc0_framemask(cpu_env, arg);
6225 rn = "Framemask";
6226 break;
6227 default:
6228 goto die;
6230 break;
6231 case 22:
6232 /* ignored */
6233 rn = "Diagnostic"; /* implementation dependent */
6234 break;
6235 case 23:
6236 switch (sel) {
6237 case 0:
6238 gen_helper_mtc0_debug(cpu_env, arg); /* EJTAG support */
6239 /* BS_STOP isn't good enough here, hflags may have changed. */
6240 gen_save_pc(ctx->pc + 4);
6241 ctx->bstate = BS_EXCP;
6242 rn = "Debug";
6243 break;
6244 case 1:
6245 // gen_helper_mtc0_tracecontrol(cpu_env, arg); /* PDtrace support */
6246 /* Stop translation as we may have switched the execution mode */
6247 ctx->bstate = BS_STOP;
6248 rn = "TraceControl";
6249 // break;
6250 case 2:
6251 // gen_helper_mtc0_tracecontrol2(cpu_env, arg); /* PDtrace support */
6252 /* Stop translation as we may have switched the execution mode */
6253 ctx->bstate = BS_STOP;
6254 rn = "TraceControl2";
6255 // break;
6256 case 3:
6257 // gen_helper_mtc0_usertracedata(cpu_env, arg); /* PDtrace support */
6258 /* Stop translation as we may have switched the execution mode */
6259 ctx->bstate = BS_STOP;
6260 rn = "UserTraceData";
6261 // break;
6262 case 4:
6263 // gen_helper_mtc0_tracebpc(cpu_env, arg); /* PDtrace support */
6264 /* Stop translation as we may have switched the execution mode */
6265 ctx->bstate = BS_STOP;
6266 rn = "TraceBPC";
6267 // break;
6268 default:
6269 goto die;
6271 break;
6272 case 24:
6273 switch (sel) {
6274 case 0:
6275 /* EJTAG support */
6276 tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_DEPC));
6277 rn = "DEPC";
6278 break;
6279 default:
6280 goto die;
6282 break;
6283 case 25:
6284 switch (sel) {
6285 case 0:
6286 gen_helper_mtc0_performance0(cpu_env, arg);
6287 rn = "Performance0";
6288 break;
6289 case 1:
6290 // gen_helper_mtc0_performance1(cpu_env, arg);
6291 rn = "Performance1";
6292 // break;
6293 case 2:
6294 // gen_helper_mtc0_performance2(cpu_env, arg);
6295 rn = "Performance2";
6296 // break;
6297 case 3:
6298 // gen_helper_mtc0_performance3(cpu_env, arg);
6299 rn = "Performance3";
6300 // break;
6301 case 4:
6302 // gen_helper_mtc0_performance4(cpu_env, arg);
6303 rn = "Performance4";
6304 // break;
6305 case 5:
6306 // gen_helper_mtc0_performance5(cpu_env, arg);
6307 rn = "Performance5";
6308 // break;
6309 case 6:
6310 // gen_helper_mtc0_performance6(cpu_env, arg);
6311 rn = "Performance6";
6312 // break;
6313 case 7:
6314 // gen_helper_mtc0_performance7(cpu_env, arg);
6315 rn = "Performance7";
6316 // break;
6317 default:
6318 goto die;
6320 break;
6321 case 26:
6322 /* ignored */
6323 rn = "ECC";
6324 break;
6325 case 27:
6326 switch (sel) {
6327 case 0 ... 3:
6328 /* ignored */
6329 rn = "CacheErr";
6330 break;
6331 default:
6332 goto die;
6334 break;
6335 case 28:
6336 switch (sel) {
6337 case 0:
6338 case 2:
6339 case 4:
6340 case 6:
6341 gen_helper_mtc0_taglo(cpu_env, arg);
6342 rn = "TagLo";
6343 break;
6344 case 1:
6345 case 3:
6346 case 5:
6347 case 7:
6348 gen_helper_mtc0_datalo(cpu_env, arg);
6349 rn = "DataLo";
6350 break;
6351 default:
6352 goto die;
6354 break;
6355 case 29:
6356 switch (sel) {
6357 case 0:
6358 case 2:
6359 case 4:
6360 case 6:
6361 gen_helper_mtc0_taghi(cpu_env, arg);
6362 rn = "TagHi";
6363 break;
6364 case 1:
6365 case 3:
6366 case 5:
6367 case 7:
6368 gen_helper_mtc0_datahi(cpu_env, arg);
6369 rn = "DataHi";
6370 break;
6371 default:
6372 rn = "invalid sel";
6373 goto die;
6375 break;
6376 case 30:
6377 switch (sel) {
6378 case 0:
6379 tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_ErrorEPC));
6380 rn = "ErrorEPC";
6381 break;
6382 default:
6383 goto die;
6385 break;
6386 case 31:
6387 switch (sel) {
6388 case 0:
6389 /* EJTAG support */
6390 gen_mtc0_store32(arg, offsetof(CPUMIPSState, CP0_DESAVE));
6391 rn = "DESAVE";
6392 break;
6393 default:
6394 goto die;
6396 /* Stop translation as we may have switched the execution mode */
6397 ctx->bstate = BS_STOP;
6398 break;
6399 default:
6400 goto die;
6402 (void)rn; /* avoid a compiler warning */
6403 LOG_DISAS("dmtc0 %s (reg %d sel %d)\n", rn, reg, sel);
6404 /* For simplicity assume that all writes can cause interrupts. */
6405 if (use_icount) {
6406 gen_io_end();
6407 ctx->bstate = BS_STOP;
6409 return;
6411 die:
6412 LOG_DISAS("dmtc0 %s (reg %d sel %d)\n", rn, reg, sel);
6413 generate_exception(ctx, EXCP_RI);
6415 #endif /* TARGET_MIPS64 */
6417 static void gen_mftr(CPUMIPSState *env, DisasContext *ctx, int rt, int rd,
6418 int u, int sel, int h)
6420 int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
6421 TCGv t0 = tcg_temp_local_new();
6423 if ((env->CP0_VPEConf0 & (1 << CP0VPEC0_MVP)) == 0 &&
6424 ((env->tcs[other_tc].CP0_TCBind & (0xf << CP0TCBd_CurVPE)) !=
6425 (env->active_tc.CP0_TCBind & (0xf << CP0TCBd_CurVPE))))
6426 tcg_gen_movi_tl(t0, -1);
6427 else if ((env->CP0_VPEControl & (0xff << CP0VPECo_TargTC)) >
6428 (env->mvp->CP0_MVPConf0 & (0xff << CP0MVPC0_PTC)))
6429 tcg_gen_movi_tl(t0, -1);
6430 else if (u == 0) {
6431 switch (rt) {
6432 case 1:
6433 switch (sel) {
6434 case 1:
6435 gen_helper_mftc0_vpecontrol(t0, cpu_env);
6436 break;
6437 case 2:
6438 gen_helper_mftc0_vpeconf0(t0, cpu_env);
6439 break;
6440 default:
6441 goto die;
6442 break;
6444 break;
6445 case 2:
6446 switch (sel) {
6447 case 1:
6448 gen_helper_mftc0_tcstatus(t0, cpu_env);
6449 break;
6450 case 2:
6451 gen_helper_mftc0_tcbind(t0, cpu_env);
6452 break;
6453 case 3:
6454 gen_helper_mftc0_tcrestart(t0, cpu_env);
6455 break;
6456 case 4:
6457 gen_helper_mftc0_tchalt(t0, cpu_env);
6458 break;
6459 case 5:
6460 gen_helper_mftc0_tccontext(t0, cpu_env);
6461 break;
6462 case 6:
6463 gen_helper_mftc0_tcschedule(t0, cpu_env);
6464 break;
6465 case 7:
6466 gen_helper_mftc0_tcschefback(t0, cpu_env);
6467 break;
6468 default:
6469 gen_mfc0(ctx, t0, rt, sel);
6470 break;
6472 break;
6473 case 10:
6474 switch (sel) {
6475 case 0:
6476 gen_helper_mftc0_entryhi(t0, cpu_env);
6477 break;
6478 default:
6479 gen_mfc0(ctx, t0, rt, sel);
6480 break;
6482 case 12:
6483 switch (sel) {
6484 case 0:
6485 gen_helper_mftc0_status(t0, cpu_env);
6486 break;
6487 default:
6488 gen_mfc0(ctx, t0, rt, sel);
6489 break;
6491 case 13:
6492 switch (sel) {
6493 case 0:
6494 gen_helper_mftc0_cause(t0, cpu_env);
6495 break;
6496 default:
6497 goto die;
6498 break;
6500 break;
6501 case 14:
6502 switch (sel) {
6503 case 0:
6504 gen_helper_mftc0_epc(t0, cpu_env);
6505 break;
6506 default:
6507 goto die;
6508 break;
6510 break;
6511 case 15:
6512 switch (sel) {
6513 case 1:
6514 gen_helper_mftc0_ebase(t0, cpu_env);
6515 break;
6516 default:
6517 goto die;
6518 break;
6520 break;
6521 case 16:
6522 switch (sel) {
6523 case 0 ... 7:
6524 gen_helper_mftc0_configx(t0, cpu_env, tcg_const_tl(sel));
6525 break;
6526 default:
6527 goto die;
6528 break;
6530 break;
6531 case 23:
6532 switch (sel) {
6533 case 0:
6534 gen_helper_mftc0_debug(t0, cpu_env);
6535 break;
6536 default:
6537 gen_mfc0(ctx, t0, rt, sel);
6538 break;
6540 break;
6541 default:
6542 gen_mfc0(ctx, t0, rt, sel);
6544 } else switch (sel) {
6545 /* GPR registers. */
6546 case 0:
6547 gen_helper_1e0i(mftgpr, t0, rt);
6548 break;
6549 /* Auxiliary CPU registers */
6550 case 1:
6551 switch (rt) {
6552 case 0:
6553 gen_helper_1e0i(mftlo, t0, 0);
6554 break;
6555 case 1:
6556 gen_helper_1e0i(mfthi, t0, 0);
6557 break;
6558 case 2:
6559 gen_helper_1e0i(mftacx, t0, 0);
6560 break;
6561 case 4:
6562 gen_helper_1e0i(mftlo, t0, 1);
6563 break;
6564 case 5:
6565 gen_helper_1e0i(mfthi, t0, 1);
6566 break;
6567 case 6:
6568 gen_helper_1e0i(mftacx, t0, 1);
6569 break;
6570 case 8:
6571 gen_helper_1e0i(mftlo, t0, 2);
6572 break;
6573 case 9:
6574 gen_helper_1e0i(mfthi, t0, 2);
6575 break;
6576 case 10:
6577 gen_helper_1e0i(mftacx, t0, 2);
6578 break;
6579 case 12:
6580 gen_helper_1e0i(mftlo, t0, 3);
6581 break;
6582 case 13:
6583 gen_helper_1e0i(mfthi, t0, 3);
6584 break;
6585 case 14:
6586 gen_helper_1e0i(mftacx, t0, 3);
6587 break;
6588 case 16:
6589 gen_helper_mftdsp(t0, cpu_env);
6590 break;
6591 default:
6592 goto die;
6594 break;
6595 /* Floating point (COP1). */
6596 case 2:
6597 /* XXX: For now we support only a single FPU context. */
6598 if (h == 0) {
6599 TCGv_i32 fp0 = tcg_temp_new_i32();
6601 gen_load_fpr32(fp0, rt);
6602 tcg_gen_ext_i32_tl(t0, fp0);
6603 tcg_temp_free_i32(fp0);
6604 } else {
6605 TCGv_i32 fp0 = tcg_temp_new_i32();
6607 gen_load_fpr32h(fp0, rt);
6608 tcg_gen_ext_i32_tl(t0, fp0);
6609 tcg_temp_free_i32(fp0);
6611 break;
6612 case 3:
6613 /* XXX: For now we support only a single FPU context. */
6614 gen_helper_1e0i(cfc1, t0, rt);
6615 break;
6616 /* COP2: Not implemented. */
6617 case 4:
6618 case 5:
6619 /* fall through */
6620 default:
6621 goto die;
6623 LOG_DISAS("mftr (reg %d u %d sel %d h %d)\n", rt, u, sel, h);
6624 gen_store_gpr(t0, rd);
6625 tcg_temp_free(t0);
6626 return;
6628 die:
6629 tcg_temp_free(t0);
6630 LOG_DISAS("mftr (reg %d u %d sel %d h %d)\n", rt, u, sel, h);
6631 generate_exception(ctx, EXCP_RI);
6634 static void gen_mttr(CPUMIPSState *env, DisasContext *ctx, int rd, int rt,
6635 int u, int sel, int h)
6637 int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
6638 TCGv t0 = tcg_temp_local_new();
6640 gen_load_gpr(t0, rt);
6641 if ((env->CP0_VPEConf0 & (1 << CP0VPEC0_MVP)) == 0 &&
6642 ((env->tcs[other_tc].CP0_TCBind & (0xf << CP0TCBd_CurVPE)) !=
6643 (env->active_tc.CP0_TCBind & (0xf << CP0TCBd_CurVPE))))
6644 /* NOP */ ;
6645 else if ((env->CP0_VPEControl & (0xff << CP0VPECo_TargTC)) >
6646 (env->mvp->CP0_MVPConf0 & (0xff << CP0MVPC0_PTC)))
6647 /* NOP */ ;
6648 else if (u == 0) {
6649 switch (rd) {
6650 case 1:
6651 switch (sel) {
6652 case 1:
6653 gen_helper_mttc0_vpecontrol(cpu_env, t0);
6654 break;
6655 case 2:
6656 gen_helper_mttc0_vpeconf0(cpu_env, t0);
6657 break;
6658 default:
6659 goto die;
6660 break;
6662 break;
6663 case 2:
6664 switch (sel) {
6665 case 1:
6666 gen_helper_mttc0_tcstatus(cpu_env, t0);
6667 break;
6668 case 2:
6669 gen_helper_mttc0_tcbind(cpu_env, t0);
6670 break;
6671 case 3:
6672 gen_helper_mttc0_tcrestart(cpu_env, t0);
6673 break;
6674 case 4:
6675 gen_helper_mttc0_tchalt(cpu_env, t0);
6676 break;
6677 case 5:
6678 gen_helper_mttc0_tccontext(cpu_env, t0);
6679 break;
6680 case 6:
6681 gen_helper_mttc0_tcschedule(cpu_env, t0);
6682 break;
6683 case 7:
6684 gen_helper_mttc0_tcschefback(cpu_env, t0);
6685 break;
6686 default:
6687 gen_mtc0(ctx, t0, rd, sel);
6688 break;
6690 break;
6691 case 10:
6692 switch (sel) {
6693 case 0:
6694 gen_helper_mttc0_entryhi(cpu_env, t0);
6695 break;
6696 default:
6697 gen_mtc0(ctx, t0, rd, sel);
6698 break;
6700 case 12:
6701 switch (sel) {
6702 case 0:
6703 gen_helper_mttc0_status(cpu_env, t0);
6704 break;
6705 default:
6706 gen_mtc0(ctx, t0, rd, sel);
6707 break;
6709 case 13:
6710 switch (sel) {
6711 case 0:
6712 gen_helper_mttc0_cause(cpu_env, t0);
6713 break;
6714 default:
6715 goto die;
6716 break;
6718 break;
6719 case 15:
6720 switch (sel) {
6721 case 1:
6722 gen_helper_mttc0_ebase(cpu_env, t0);
6723 break;
6724 default:
6725 goto die;
6726 break;
6728 break;
6729 case 23:
6730 switch (sel) {
6731 case 0:
6732 gen_helper_mttc0_debug(cpu_env, t0);
6733 break;
6734 default:
6735 gen_mtc0(ctx, t0, rd, sel);
6736 break;
6738 break;
6739 default:
6740 gen_mtc0(ctx, t0, rd, sel);
6742 } else switch (sel) {
6743 /* GPR registers. */
6744 case 0:
6745 gen_helper_0e1i(mttgpr, t0, rd);
6746 break;
6747 /* Auxiliary CPU registers */
6748 case 1:
6749 switch (rd) {
6750 case 0:
6751 gen_helper_0e1i(mttlo, t0, 0);
6752 break;
6753 case 1:
6754 gen_helper_0e1i(mtthi, t0, 0);
6755 break;
6756 case 2:
6757 gen_helper_0e1i(mttacx, t0, 0);
6758 break;
6759 case 4:
6760 gen_helper_0e1i(mttlo, t0, 1);
6761 break;
6762 case 5:
6763 gen_helper_0e1i(mtthi, t0, 1);
6764 break;
6765 case 6:
6766 gen_helper_0e1i(mttacx, t0, 1);
6767 break;
6768 case 8:
6769 gen_helper_0e1i(mttlo, t0, 2);
6770 break;
6771 case 9:
6772 gen_helper_0e1i(mtthi, t0, 2);
6773 break;
6774 case 10:
6775 gen_helper_0e1i(mttacx, t0, 2);
6776 break;
6777 case 12:
6778 gen_helper_0e1i(mttlo, t0, 3);
6779 break;
6780 case 13:
6781 gen_helper_0e1i(mtthi, t0, 3);
6782 break;
6783 case 14:
6784 gen_helper_0e1i(mttacx, t0, 3);
6785 break;
6786 case 16:
6787 gen_helper_mttdsp(cpu_env, t0);
6788 break;
6789 default:
6790 goto die;
6792 break;
6793 /* Floating point (COP1). */
6794 case 2:
6795 /* XXX: For now we support only a single FPU context. */
6796 if (h == 0) {
6797 TCGv_i32 fp0 = tcg_temp_new_i32();
6799 tcg_gen_trunc_tl_i32(fp0, t0);
6800 gen_store_fpr32(fp0, rd);
6801 tcg_temp_free_i32(fp0);
6802 } else {
6803 TCGv_i32 fp0 = tcg_temp_new_i32();
6805 tcg_gen_trunc_tl_i32(fp0, t0);
6806 gen_store_fpr32h(fp0, rd);
6807 tcg_temp_free_i32(fp0);
6809 break;
6810 case 3:
6811 /* XXX: For now we support only a single FPU context. */
6812 gen_helper_0e1i(ctc1, t0, rd);
6813 break;
6814 /* COP2: Not implemented. */
6815 case 4:
6816 case 5:
6817 /* fall through */
6818 default:
6819 goto die;
6821 LOG_DISAS("mttr (reg %d u %d sel %d h %d)\n", rd, u, sel, h);
6822 tcg_temp_free(t0);
6823 return;
6825 die:
6826 tcg_temp_free(t0);
6827 LOG_DISAS("mttr (reg %d u %d sel %d h %d)\n", rd, u, sel, h);
6828 generate_exception(ctx, EXCP_RI);
6831 static void gen_cp0 (CPUMIPSState *env, DisasContext *ctx, uint32_t opc, int rt, int rd)
6833 const char *opn = "ldst";
6835 check_cp0_enabled(ctx);
6836 switch (opc) {
6837 case OPC_MFC0:
6838 if (rt == 0) {
6839 /* Treat as NOP. */
6840 return;
6842 gen_mfc0(ctx, cpu_gpr[rt], rd, ctx->opcode & 0x7);
6843 opn = "mfc0";
6844 break;
6845 case OPC_MTC0:
6847 TCGv t0 = tcg_temp_new();
6849 gen_load_gpr(t0, rt);
6850 gen_mtc0(ctx, t0, rd, ctx->opcode & 0x7);
6851 tcg_temp_free(t0);
6853 opn = "mtc0";
6854 break;
6855 #if defined(TARGET_MIPS64)
6856 case OPC_DMFC0:
6857 check_insn(ctx, ISA_MIPS3);
6858 if (rt == 0) {
6859 /* Treat as NOP. */
6860 return;
6862 gen_dmfc0(ctx, cpu_gpr[rt], rd, ctx->opcode & 0x7);
6863 opn = "dmfc0";
6864 break;
6865 case OPC_DMTC0:
6866 check_insn(ctx, ISA_MIPS3);
6868 TCGv t0 = tcg_temp_new();
6870 gen_load_gpr(t0, rt);
6871 gen_dmtc0(ctx, t0, rd, ctx->opcode & 0x7);
6872 tcg_temp_free(t0);
6874 opn = "dmtc0";
6875 break;
6876 #endif
6877 case OPC_MFTR:
6878 check_insn(ctx, ASE_MT);
6879 if (rd == 0) {
6880 /* Treat as NOP. */
6881 return;
6883 gen_mftr(env, ctx, rt, rd, (ctx->opcode >> 5) & 1,
6884 ctx->opcode & 0x7, (ctx->opcode >> 4) & 1);
6885 opn = "mftr";
6886 break;
6887 case OPC_MTTR:
6888 check_insn(ctx, ASE_MT);
6889 gen_mttr(env, ctx, rd, rt, (ctx->opcode >> 5) & 1,
6890 ctx->opcode & 0x7, (ctx->opcode >> 4) & 1);
6891 opn = "mttr";
6892 break;
6893 case OPC_TLBWI:
6894 opn = "tlbwi";
6895 if (!env->tlb->helper_tlbwi)
6896 goto die;
6897 gen_helper_tlbwi(cpu_env);
6898 break;
6899 case OPC_TLBWR:
6900 opn = "tlbwr";
6901 if (!env->tlb->helper_tlbwr)
6902 goto die;
6903 gen_helper_tlbwr(cpu_env);
6904 break;
6905 case OPC_TLBP:
6906 opn = "tlbp";
6907 if (!env->tlb->helper_tlbp)
6908 goto die;
6909 gen_helper_tlbp(cpu_env);
6910 break;
6911 case OPC_TLBR:
6912 opn = "tlbr";
6913 if (!env->tlb->helper_tlbr)
6914 goto die;
6915 gen_helper_tlbr(cpu_env);
6916 break;
6917 case OPC_ERET:
6918 opn = "eret";
6919 check_insn(ctx, ISA_MIPS2);
6920 gen_helper_eret(cpu_env);
6921 ctx->bstate = BS_EXCP;
6922 break;
6923 case OPC_DERET:
6924 opn = "deret";
6925 check_insn(ctx, ISA_MIPS32);
6926 if (!(ctx->hflags & MIPS_HFLAG_DM)) {
6927 MIPS_INVAL(opn);
6928 generate_exception(ctx, EXCP_RI);
6929 } else {
6930 gen_helper_deret(cpu_env);
6931 ctx->bstate = BS_EXCP;
6933 break;
6934 case OPC_WAIT:
6935 opn = "wait";
6936 check_insn(ctx, ISA_MIPS3 | ISA_MIPS32);
6937 /* If we get an exception, we want to restart at next instruction */
6938 ctx->pc += 4;
6939 save_cpu_state(ctx, 1);
6940 ctx->pc -= 4;
6941 gen_helper_wait(cpu_env);
6942 ctx->bstate = BS_EXCP;
6943 break;
6944 default:
6945 die:
6946 MIPS_INVAL(opn);
6947 generate_exception(ctx, EXCP_RI);
6948 return;
6950 (void)opn; /* avoid a compiler warning */
6951 MIPS_DEBUG("%s %s %d", opn, regnames[rt], rd);
6953 #endif /* !CONFIG_USER_ONLY */
6955 /* CP1 Branches (before delay slot) */
6956 static void gen_compute_branch1(DisasContext *ctx, uint32_t op,
6957 int32_t cc, int32_t offset)
6959 target_ulong btarget;
6960 const char *opn = "cp1 cond branch";
6961 TCGv_i32 t0 = tcg_temp_new_i32();
6963 if (cc != 0)
6964 check_insn(ctx, ISA_MIPS4 | ISA_MIPS32);
6966 btarget = ctx->pc + 4 + offset;
6968 switch (op) {
6969 case OPC_BC1F:
6970 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
6971 tcg_gen_not_i32(t0, t0);
6972 tcg_gen_andi_i32(t0, t0, 1);
6973 tcg_gen_extu_i32_tl(bcond, t0);
6974 opn = "bc1f";
6975 goto not_likely;
6976 case OPC_BC1FL:
6977 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
6978 tcg_gen_not_i32(t0, t0);
6979 tcg_gen_andi_i32(t0, t0, 1);
6980 tcg_gen_extu_i32_tl(bcond, t0);
6981 opn = "bc1fl";
6982 goto likely;
6983 case OPC_BC1T:
6984 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
6985 tcg_gen_andi_i32(t0, t0, 1);
6986 tcg_gen_extu_i32_tl(bcond, t0);
6987 opn = "bc1t";
6988 goto not_likely;
6989 case OPC_BC1TL:
6990 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
6991 tcg_gen_andi_i32(t0, t0, 1);
6992 tcg_gen_extu_i32_tl(bcond, t0);
6993 opn = "bc1tl";
6994 likely:
6995 ctx->hflags |= MIPS_HFLAG_BL;
6996 break;
6997 case OPC_BC1FANY2:
6999 TCGv_i32 t1 = tcg_temp_new_i32();
7000 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
7001 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+1));
7002 tcg_gen_nand_i32(t0, t0, t1);
7003 tcg_temp_free_i32(t1);
7004 tcg_gen_andi_i32(t0, t0, 1);
7005 tcg_gen_extu_i32_tl(bcond, t0);
7007 opn = "bc1any2f";
7008 goto not_likely;
7009 case OPC_BC1TANY2:
7011 TCGv_i32 t1 = tcg_temp_new_i32();
7012 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
7013 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+1));
7014 tcg_gen_or_i32(t0, t0, t1);
7015 tcg_temp_free_i32(t1);
7016 tcg_gen_andi_i32(t0, t0, 1);
7017 tcg_gen_extu_i32_tl(bcond, t0);
7019 opn = "bc1any2t";
7020 goto not_likely;
7021 case OPC_BC1FANY4:
7023 TCGv_i32 t1 = tcg_temp_new_i32();
7024 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
7025 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+1));
7026 tcg_gen_and_i32(t0, t0, t1);
7027 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+2));
7028 tcg_gen_and_i32(t0, t0, t1);
7029 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+3));
7030 tcg_gen_nand_i32(t0, t0, t1);
7031 tcg_temp_free_i32(t1);
7032 tcg_gen_andi_i32(t0, t0, 1);
7033 tcg_gen_extu_i32_tl(bcond, t0);
7035 opn = "bc1any4f";
7036 goto not_likely;
7037 case OPC_BC1TANY4:
7039 TCGv_i32 t1 = tcg_temp_new_i32();
7040 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
7041 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+1));
7042 tcg_gen_or_i32(t0, t0, t1);
7043 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+2));
7044 tcg_gen_or_i32(t0, t0, t1);
7045 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+3));
7046 tcg_gen_or_i32(t0, t0, t1);
7047 tcg_temp_free_i32(t1);
7048 tcg_gen_andi_i32(t0, t0, 1);
7049 tcg_gen_extu_i32_tl(bcond, t0);
7051 opn = "bc1any4t";
7052 not_likely:
7053 ctx->hflags |= MIPS_HFLAG_BC;
7054 break;
7055 default:
7056 MIPS_INVAL(opn);
7057 generate_exception (ctx, EXCP_RI);
7058 goto out;
7060 (void)opn; /* avoid a compiler warning */
7061 MIPS_DEBUG("%s: cond %02x target " TARGET_FMT_lx, opn,
7062 ctx->hflags, btarget);
7063 ctx->btarget = btarget;
7065 out:
7066 tcg_temp_free_i32(t0);
7069 /* Coprocessor 1 (FPU) */
7071 #define FOP(func, fmt) (((fmt) << 21) | (func))
7073 enum fopcode {
7074 OPC_ADD_S = FOP(0, FMT_S),
7075 OPC_SUB_S = FOP(1, FMT_S),
7076 OPC_MUL_S = FOP(2, FMT_S),
7077 OPC_DIV_S = FOP(3, FMT_S),
7078 OPC_SQRT_S = FOP(4, FMT_S),
7079 OPC_ABS_S = FOP(5, FMT_S),
7080 OPC_MOV_S = FOP(6, FMT_S),
7081 OPC_NEG_S = FOP(7, FMT_S),
7082 OPC_ROUND_L_S = FOP(8, FMT_S),
7083 OPC_TRUNC_L_S = FOP(9, FMT_S),
7084 OPC_CEIL_L_S = FOP(10, FMT_S),
7085 OPC_FLOOR_L_S = FOP(11, FMT_S),
7086 OPC_ROUND_W_S = FOP(12, FMT_S),
7087 OPC_TRUNC_W_S = FOP(13, FMT_S),
7088 OPC_CEIL_W_S = FOP(14, FMT_S),
7089 OPC_FLOOR_W_S = FOP(15, FMT_S),
7090 OPC_MOVCF_S = FOP(17, FMT_S),
7091 OPC_MOVZ_S = FOP(18, FMT_S),
7092 OPC_MOVN_S = FOP(19, FMT_S),
7093 OPC_RECIP_S = FOP(21, FMT_S),
7094 OPC_RSQRT_S = FOP(22, FMT_S),
7095 OPC_RECIP2_S = FOP(28, FMT_S),
7096 OPC_RECIP1_S = FOP(29, FMT_S),
7097 OPC_RSQRT1_S = FOP(30, FMT_S),
7098 OPC_RSQRT2_S = FOP(31, FMT_S),
7099 OPC_CVT_D_S = FOP(33, FMT_S),
7100 OPC_CVT_W_S = FOP(36, FMT_S),
7101 OPC_CVT_L_S = FOP(37, FMT_S),
7102 OPC_CVT_PS_S = FOP(38, FMT_S),
7103 OPC_CMP_F_S = FOP (48, FMT_S),
7104 OPC_CMP_UN_S = FOP (49, FMT_S),
7105 OPC_CMP_EQ_S = FOP (50, FMT_S),
7106 OPC_CMP_UEQ_S = FOP (51, FMT_S),
7107 OPC_CMP_OLT_S = FOP (52, FMT_S),
7108 OPC_CMP_ULT_S = FOP (53, FMT_S),
7109 OPC_CMP_OLE_S = FOP (54, FMT_S),
7110 OPC_CMP_ULE_S = FOP (55, FMT_S),
7111 OPC_CMP_SF_S = FOP (56, FMT_S),
7112 OPC_CMP_NGLE_S = FOP (57, FMT_S),
7113 OPC_CMP_SEQ_S = FOP (58, FMT_S),
7114 OPC_CMP_NGL_S = FOP (59, FMT_S),
7115 OPC_CMP_LT_S = FOP (60, FMT_S),
7116 OPC_CMP_NGE_S = FOP (61, FMT_S),
7117 OPC_CMP_LE_S = FOP (62, FMT_S),
7118 OPC_CMP_NGT_S = FOP (63, FMT_S),
7120 OPC_ADD_D = FOP(0, FMT_D),
7121 OPC_SUB_D = FOP(1, FMT_D),
7122 OPC_MUL_D = FOP(2, FMT_D),
7123 OPC_DIV_D = FOP(3, FMT_D),
7124 OPC_SQRT_D = FOP(4, FMT_D),
7125 OPC_ABS_D = FOP(5, FMT_D),
7126 OPC_MOV_D = FOP(6, FMT_D),
7127 OPC_NEG_D = FOP(7, FMT_D),
7128 OPC_ROUND_L_D = FOP(8, FMT_D),
7129 OPC_TRUNC_L_D = FOP(9, FMT_D),
7130 OPC_CEIL_L_D = FOP(10, FMT_D),
7131 OPC_FLOOR_L_D = FOP(11, FMT_D),
7132 OPC_ROUND_W_D = FOP(12, FMT_D),
7133 OPC_TRUNC_W_D = FOP(13, FMT_D),
7134 OPC_CEIL_W_D = FOP(14, FMT_D),
7135 OPC_FLOOR_W_D = FOP(15, FMT_D),
7136 OPC_MOVCF_D = FOP(17, FMT_D),
7137 OPC_MOVZ_D = FOP(18, FMT_D),
7138 OPC_MOVN_D = FOP(19, FMT_D),
7139 OPC_RECIP_D = FOP(21, FMT_D),
7140 OPC_RSQRT_D = FOP(22, FMT_D),
7141 OPC_RECIP2_D = FOP(28, FMT_D),
7142 OPC_RECIP1_D = FOP(29, FMT_D),
7143 OPC_RSQRT1_D = FOP(30, FMT_D),
7144 OPC_RSQRT2_D = FOP(31, FMT_D),
7145 OPC_CVT_S_D = FOP(32, FMT_D),
7146 OPC_CVT_W_D = FOP(36, FMT_D),
7147 OPC_CVT_L_D = FOP(37, FMT_D),
7148 OPC_CMP_F_D = FOP (48, FMT_D),
7149 OPC_CMP_UN_D = FOP (49, FMT_D),
7150 OPC_CMP_EQ_D = FOP (50, FMT_D),
7151 OPC_CMP_UEQ_D = FOP (51, FMT_D),
7152 OPC_CMP_OLT_D = FOP (52, FMT_D),
7153 OPC_CMP_ULT_D = FOP (53, FMT_D),
7154 OPC_CMP_OLE_D = FOP (54, FMT_D),
7155 OPC_CMP_ULE_D = FOP (55, FMT_D),
7156 OPC_CMP_SF_D = FOP (56, FMT_D),
7157 OPC_CMP_NGLE_D = FOP (57, FMT_D),
7158 OPC_CMP_SEQ_D = FOP (58, FMT_D),
7159 OPC_CMP_NGL_D = FOP (59, FMT_D),
7160 OPC_CMP_LT_D = FOP (60, FMT_D),
7161 OPC_CMP_NGE_D = FOP (61, FMT_D),
7162 OPC_CMP_LE_D = FOP (62, FMT_D),
7163 OPC_CMP_NGT_D = FOP (63, FMT_D),
7165 OPC_CVT_S_W = FOP(32, FMT_W),
7166 OPC_CVT_D_W = FOP(33, FMT_W),
7167 OPC_CVT_S_L = FOP(32, FMT_L),
7168 OPC_CVT_D_L = FOP(33, FMT_L),
7169 OPC_CVT_PS_PW = FOP(38, FMT_W),
7171 OPC_ADD_PS = FOP(0, FMT_PS),
7172 OPC_SUB_PS = FOP(1, FMT_PS),
7173 OPC_MUL_PS = FOP(2, FMT_PS),
7174 OPC_DIV_PS = FOP(3, FMT_PS),
7175 OPC_ABS_PS = FOP(5, FMT_PS),
7176 OPC_MOV_PS = FOP(6, FMT_PS),
7177 OPC_NEG_PS = FOP(7, FMT_PS),
7178 OPC_MOVCF_PS = FOP(17, FMT_PS),
7179 OPC_MOVZ_PS = FOP(18, FMT_PS),
7180 OPC_MOVN_PS = FOP(19, FMT_PS),
7181 OPC_ADDR_PS = FOP(24, FMT_PS),
7182 OPC_MULR_PS = FOP(26, FMT_PS),
7183 OPC_RECIP2_PS = FOP(28, FMT_PS),
7184 OPC_RECIP1_PS = FOP(29, FMT_PS),
7185 OPC_RSQRT1_PS = FOP(30, FMT_PS),
7186 OPC_RSQRT2_PS = FOP(31, FMT_PS),
7188 OPC_CVT_S_PU = FOP(32, FMT_PS),
7189 OPC_CVT_PW_PS = FOP(36, FMT_PS),
7190 OPC_CVT_S_PL = FOP(40, FMT_PS),
7191 OPC_PLL_PS = FOP(44, FMT_PS),
7192 OPC_PLU_PS = FOP(45, FMT_PS),
7193 OPC_PUL_PS = FOP(46, FMT_PS),
7194 OPC_PUU_PS = FOP(47, FMT_PS),
7195 OPC_CMP_F_PS = FOP (48, FMT_PS),
7196 OPC_CMP_UN_PS = FOP (49, FMT_PS),
7197 OPC_CMP_EQ_PS = FOP (50, FMT_PS),
7198 OPC_CMP_UEQ_PS = FOP (51, FMT_PS),
7199 OPC_CMP_OLT_PS = FOP (52, FMT_PS),
7200 OPC_CMP_ULT_PS = FOP (53, FMT_PS),
7201 OPC_CMP_OLE_PS = FOP (54, FMT_PS),
7202 OPC_CMP_ULE_PS = FOP (55, FMT_PS),
7203 OPC_CMP_SF_PS = FOP (56, FMT_PS),
7204 OPC_CMP_NGLE_PS = FOP (57, FMT_PS),
7205 OPC_CMP_SEQ_PS = FOP (58, FMT_PS),
7206 OPC_CMP_NGL_PS = FOP (59, FMT_PS),
7207 OPC_CMP_LT_PS = FOP (60, FMT_PS),
7208 OPC_CMP_NGE_PS = FOP (61, FMT_PS),
7209 OPC_CMP_LE_PS = FOP (62, FMT_PS),
7210 OPC_CMP_NGT_PS = FOP (63, FMT_PS),
7213 static void gen_cp1 (DisasContext *ctx, uint32_t opc, int rt, int fs)
7215 const char *opn = "cp1 move";
7216 TCGv t0 = tcg_temp_new();
7218 switch (opc) {
7219 case OPC_MFC1:
7221 TCGv_i32 fp0 = tcg_temp_new_i32();
7223 gen_load_fpr32(fp0, fs);
7224 tcg_gen_ext_i32_tl(t0, fp0);
7225 tcg_temp_free_i32(fp0);
7227 gen_store_gpr(t0, rt);
7228 opn = "mfc1";
7229 break;
7230 case OPC_MTC1:
7231 gen_load_gpr(t0, rt);
7233 TCGv_i32 fp0 = tcg_temp_new_i32();
7235 tcg_gen_trunc_tl_i32(fp0, t0);
7236 gen_store_fpr32(fp0, fs);
7237 tcg_temp_free_i32(fp0);
7239 opn = "mtc1";
7240 break;
7241 case OPC_CFC1:
7242 gen_helper_1e0i(cfc1, t0, fs);
7243 gen_store_gpr(t0, rt);
7244 opn = "cfc1";
7245 break;
7246 case OPC_CTC1:
7247 gen_load_gpr(t0, rt);
7248 gen_helper_0e1i(ctc1, t0, fs);
7249 opn = "ctc1";
7250 break;
7251 #if defined(TARGET_MIPS64)
7252 case OPC_DMFC1:
7253 gen_load_fpr64(ctx, t0, fs);
7254 gen_store_gpr(t0, rt);
7255 opn = "dmfc1";
7256 break;
7257 case OPC_DMTC1:
7258 gen_load_gpr(t0, rt);
7259 gen_store_fpr64(ctx, t0, fs);
7260 opn = "dmtc1";
7261 break;
7262 #endif
7263 case OPC_MFHC1:
7265 TCGv_i32 fp0 = tcg_temp_new_i32();
7267 gen_load_fpr32h(fp0, fs);
7268 tcg_gen_ext_i32_tl(t0, fp0);
7269 tcg_temp_free_i32(fp0);
7271 gen_store_gpr(t0, rt);
7272 opn = "mfhc1";
7273 break;
7274 case OPC_MTHC1:
7275 gen_load_gpr(t0, rt);
7277 TCGv_i32 fp0 = tcg_temp_new_i32();
7279 tcg_gen_trunc_tl_i32(fp0, t0);
7280 gen_store_fpr32h(fp0, fs);
7281 tcg_temp_free_i32(fp0);
7283 opn = "mthc1";
7284 break;
7285 default:
7286 MIPS_INVAL(opn);
7287 generate_exception (ctx, EXCP_RI);
7288 goto out;
7290 (void)opn; /* avoid a compiler warning */
7291 MIPS_DEBUG("%s %s %s", opn, regnames[rt], fregnames[fs]);
7293 out:
7294 tcg_temp_free(t0);
7297 static void gen_movci (DisasContext *ctx, int rd, int rs, int cc, int tf)
7299 int l1;
7300 TCGCond cond;
7301 TCGv_i32 t0;
7303 if (rd == 0) {
7304 /* Treat as NOP. */
7305 return;
7308 if (tf)
7309 cond = TCG_COND_EQ;
7310 else
7311 cond = TCG_COND_NE;
7313 l1 = gen_new_label();
7314 t0 = tcg_temp_new_i32();
7315 tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc));
7316 tcg_gen_brcondi_i32(cond, t0, 0, l1);
7317 tcg_temp_free_i32(t0);
7318 if (rs == 0) {
7319 tcg_gen_movi_tl(cpu_gpr[rd], 0);
7320 } else {
7321 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
7323 gen_set_label(l1);
7326 static inline void gen_movcf_s (int fs, int fd, int cc, int tf)
7328 int cond;
7329 TCGv_i32 t0 = tcg_temp_new_i32();
7330 int l1 = gen_new_label();
7332 if (tf)
7333 cond = TCG_COND_EQ;
7334 else
7335 cond = TCG_COND_NE;
7337 tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc));
7338 tcg_gen_brcondi_i32(cond, t0, 0, l1);
7339 gen_load_fpr32(t0, fs);
7340 gen_store_fpr32(t0, fd);
7341 gen_set_label(l1);
7342 tcg_temp_free_i32(t0);
7345 static inline void gen_movcf_d (DisasContext *ctx, int fs, int fd, int cc, int tf)
7347 int cond;
7348 TCGv_i32 t0 = tcg_temp_new_i32();
7349 TCGv_i64 fp0;
7350 int l1 = gen_new_label();
7352 if (tf)
7353 cond = TCG_COND_EQ;
7354 else
7355 cond = TCG_COND_NE;
7357 tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc));
7358 tcg_gen_brcondi_i32(cond, t0, 0, l1);
7359 tcg_temp_free_i32(t0);
7360 fp0 = tcg_temp_new_i64();
7361 gen_load_fpr64(ctx, fp0, fs);
7362 gen_store_fpr64(ctx, fp0, fd);
7363 tcg_temp_free_i64(fp0);
7364 gen_set_label(l1);
7367 static inline void gen_movcf_ps (int fs, int fd, int cc, int tf)
7369 int cond;
7370 TCGv_i32 t0 = tcg_temp_new_i32();
7371 int l1 = gen_new_label();
7372 int l2 = gen_new_label();
7374 if (tf)
7375 cond = TCG_COND_EQ;
7376 else
7377 cond = TCG_COND_NE;
7379 tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc));
7380 tcg_gen_brcondi_i32(cond, t0, 0, l1);
7381 gen_load_fpr32(t0, fs);
7382 gen_store_fpr32(t0, fd);
7383 gen_set_label(l1);
7385 tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc+1));
7386 tcg_gen_brcondi_i32(cond, t0, 0, l2);
7387 gen_load_fpr32h(t0, fs);
7388 gen_store_fpr32h(t0, fd);
7389 tcg_temp_free_i32(t0);
7390 gen_set_label(l2);
7394 static void gen_farith (DisasContext *ctx, enum fopcode op1,
7395 int ft, int fs, int fd, int cc)
7397 const char *opn = "farith";
7398 const char *condnames[] = {
7399 "c.f",
7400 "c.un",
7401 "c.eq",
7402 "c.ueq",
7403 "c.olt",
7404 "c.ult",
7405 "c.ole",
7406 "c.ule",
7407 "c.sf",
7408 "c.ngle",
7409 "c.seq",
7410 "c.ngl",
7411 "c.lt",
7412 "c.nge",
7413 "c.le",
7414 "c.ngt",
7416 const char *condnames_abs[] = {
7417 "cabs.f",
7418 "cabs.un",
7419 "cabs.eq",
7420 "cabs.ueq",
7421 "cabs.olt",
7422 "cabs.ult",
7423 "cabs.ole",
7424 "cabs.ule",
7425 "cabs.sf",
7426 "cabs.ngle",
7427 "cabs.seq",
7428 "cabs.ngl",
7429 "cabs.lt",
7430 "cabs.nge",
7431 "cabs.le",
7432 "cabs.ngt",
7434 enum { BINOP, CMPOP, OTHEROP } optype = OTHEROP;
7435 uint32_t func = ctx->opcode & 0x3f;
7437 switch (op1) {
7438 case OPC_ADD_S:
7440 TCGv_i32 fp0 = tcg_temp_new_i32();
7441 TCGv_i32 fp1 = tcg_temp_new_i32();
7443 gen_load_fpr32(fp0, fs);
7444 gen_load_fpr32(fp1, ft);
7445 gen_helper_float_add_s(fp0, cpu_env, fp0, fp1);
7446 tcg_temp_free_i32(fp1);
7447 gen_store_fpr32(fp0, fd);
7448 tcg_temp_free_i32(fp0);
7450 opn = "add.s";
7451 optype = BINOP;
7452 break;
7453 case OPC_SUB_S:
7455 TCGv_i32 fp0 = tcg_temp_new_i32();
7456 TCGv_i32 fp1 = tcg_temp_new_i32();
7458 gen_load_fpr32(fp0, fs);
7459 gen_load_fpr32(fp1, ft);
7460 gen_helper_float_sub_s(fp0, cpu_env, fp0, fp1);
7461 tcg_temp_free_i32(fp1);
7462 gen_store_fpr32(fp0, fd);
7463 tcg_temp_free_i32(fp0);
7465 opn = "sub.s";
7466 optype = BINOP;
7467 break;
7468 case OPC_MUL_S:
7470 TCGv_i32 fp0 = tcg_temp_new_i32();
7471 TCGv_i32 fp1 = tcg_temp_new_i32();
7473 gen_load_fpr32(fp0, fs);
7474 gen_load_fpr32(fp1, ft);
7475 gen_helper_float_mul_s(fp0, cpu_env, fp0, fp1);
7476 tcg_temp_free_i32(fp1);
7477 gen_store_fpr32(fp0, fd);
7478 tcg_temp_free_i32(fp0);
7480 opn = "mul.s";
7481 optype = BINOP;
7482 break;
7483 case OPC_DIV_S:
7485 TCGv_i32 fp0 = tcg_temp_new_i32();
7486 TCGv_i32 fp1 = tcg_temp_new_i32();
7488 gen_load_fpr32(fp0, fs);
7489 gen_load_fpr32(fp1, ft);
7490 gen_helper_float_div_s(fp0, cpu_env, fp0, fp1);
7491 tcg_temp_free_i32(fp1);
7492 gen_store_fpr32(fp0, fd);
7493 tcg_temp_free_i32(fp0);
7495 opn = "div.s";
7496 optype = BINOP;
7497 break;
7498 case OPC_SQRT_S:
7500 TCGv_i32 fp0 = tcg_temp_new_i32();
7502 gen_load_fpr32(fp0, fs);
7503 gen_helper_float_sqrt_s(fp0, cpu_env, fp0);
7504 gen_store_fpr32(fp0, fd);
7505 tcg_temp_free_i32(fp0);
7507 opn = "sqrt.s";
7508 break;
7509 case OPC_ABS_S:
7511 TCGv_i32 fp0 = tcg_temp_new_i32();
7513 gen_load_fpr32(fp0, fs);
7514 gen_helper_float_abs_s(fp0, fp0);
7515 gen_store_fpr32(fp0, fd);
7516 tcg_temp_free_i32(fp0);
7518 opn = "abs.s";
7519 break;
7520 case OPC_MOV_S:
7522 TCGv_i32 fp0 = tcg_temp_new_i32();
7524 gen_load_fpr32(fp0, fs);
7525 gen_store_fpr32(fp0, fd);
7526 tcg_temp_free_i32(fp0);
7528 opn = "mov.s";
7529 break;
7530 case OPC_NEG_S:
7532 TCGv_i32 fp0 = tcg_temp_new_i32();
7534 gen_load_fpr32(fp0, fs);
7535 gen_helper_float_chs_s(fp0, fp0);
7536 gen_store_fpr32(fp0, fd);
7537 tcg_temp_free_i32(fp0);
7539 opn = "neg.s";
7540 break;
7541 case OPC_ROUND_L_S:
7542 check_cp1_64bitmode(ctx);
7544 TCGv_i32 fp32 = tcg_temp_new_i32();
7545 TCGv_i64 fp64 = tcg_temp_new_i64();
7547 gen_load_fpr32(fp32, fs);
7548 gen_helper_float_roundl_s(fp64, cpu_env, fp32);
7549 tcg_temp_free_i32(fp32);
7550 gen_store_fpr64(ctx, fp64, fd);
7551 tcg_temp_free_i64(fp64);
7553 opn = "round.l.s";
7554 break;
7555 case OPC_TRUNC_L_S:
7556 check_cp1_64bitmode(ctx);
7558 TCGv_i32 fp32 = tcg_temp_new_i32();
7559 TCGv_i64 fp64 = tcg_temp_new_i64();
7561 gen_load_fpr32(fp32, fs);
7562 gen_helper_float_truncl_s(fp64, cpu_env, fp32);
7563 tcg_temp_free_i32(fp32);
7564 gen_store_fpr64(ctx, fp64, fd);
7565 tcg_temp_free_i64(fp64);
7567 opn = "trunc.l.s";
7568 break;
7569 case OPC_CEIL_L_S:
7570 check_cp1_64bitmode(ctx);
7572 TCGv_i32 fp32 = tcg_temp_new_i32();
7573 TCGv_i64 fp64 = tcg_temp_new_i64();
7575 gen_load_fpr32(fp32, fs);
7576 gen_helper_float_ceill_s(fp64, cpu_env, fp32);
7577 tcg_temp_free_i32(fp32);
7578 gen_store_fpr64(ctx, fp64, fd);
7579 tcg_temp_free_i64(fp64);
7581 opn = "ceil.l.s";
7582 break;
7583 case OPC_FLOOR_L_S:
7584 check_cp1_64bitmode(ctx);
7586 TCGv_i32 fp32 = tcg_temp_new_i32();
7587 TCGv_i64 fp64 = tcg_temp_new_i64();
7589 gen_load_fpr32(fp32, fs);
7590 gen_helper_float_floorl_s(fp64, cpu_env, fp32);
7591 tcg_temp_free_i32(fp32);
7592 gen_store_fpr64(ctx, fp64, fd);
7593 tcg_temp_free_i64(fp64);
7595 opn = "floor.l.s";
7596 break;
7597 case OPC_ROUND_W_S:
7599 TCGv_i32 fp0 = tcg_temp_new_i32();
7601 gen_load_fpr32(fp0, fs);
7602 gen_helper_float_roundw_s(fp0, cpu_env, fp0);
7603 gen_store_fpr32(fp0, fd);
7604 tcg_temp_free_i32(fp0);
7606 opn = "round.w.s";
7607 break;
7608 case OPC_TRUNC_W_S:
7610 TCGv_i32 fp0 = tcg_temp_new_i32();
7612 gen_load_fpr32(fp0, fs);
7613 gen_helper_float_truncw_s(fp0, cpu_env, fp0);
7614 gen_store_fpr32(fp0, fd);
7615 tcg_temp_free_i32(fp0);
7617 opn = "trunc.w.s";
7618 break;
7619 case OPC_CEIL_W_S:
7621 TCGv_i32 fp0 = tcg_temp_new_i32();
7623 gen_load_fpr32(fp0, fs);
7624 gen_helper_float_ceilw_s(fp0, cpu_env, fp0);
7625 gen_store_fpr32(fp0, fd);
7626 tcg_temp_free_i32(fp0);
7628 opn = "ceil.w.s";
7629 break;
7630 case OPC_FLOOR_W_S:
7632 TCGv_i32 fp0 = tcg_temp_new_i32();
7634 gen_load_fpr32(fp0, fs);
7635 gen_helper_float_floorw_s(fp0, cpu_env, fp0);
7636 gen_store_fpr32(fp0, fd);
7637 tcg_temp_free_i32(fp0);
7639 opn = "floor.w.s";
7640 break;
7641 case OPC_MOVCF_S:
7642 gen_movcf_s(fs, fd, (ft >> 2) & 0x7, ft & 0x1);
7643 opn = "movcf.s";
7644 break;
7645 case OPC_MOVZ_S:
7647 int l1 = gen_new_label();
7648 TCGv_i32 fp0;
7650 if (ft != 0) {
7651 tcg_gen_brcondi_tl(TCG_COND_NE, cpu_gpr[ft], 0, l1);
7653 fp0 = tcg_temp_new_i32();
7654 gen_load_fpr32(fp0, fs);
7655 gen_store_fpr32(fp0, fd);
7656 tcg_temp_free_i32(fp0);
7657 gen_set_label(l1);
7659 opn = "movz.s";
7660 break;
7661 case OPC_MOVN_S:
7663 int l1 = gen_new_label();
7664 TCGv_i32 fp0;
7666 if (ft != 0) {
7667 tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_gpr[ft], 0, l1);
7668 fp0 = tcg_temp_new_i32();
7669 gen_load_fpr32(fp0, fs);
7670 gen_store_fpr32(fp0, fd);
7671 tcg_temp_free_i32(fp0);
7672 gen_set_label(l1);
7675 opn = "movn.s";
7676 break;
7677 case OPC_RECIP_S:
7678 check_cop1x(ctx);
7680 TCGv_i32 fp0 = tcg_temp_new_i32();
7682 gen_load_fpr32(fp0, fs);
7683 gen_helper_float_recip_s(fp0, cpu_env, fp0);
7684 gen_store_fpr32(fp0, fd);
7685 tcg_temp_free_i32(fp0);
7687 opn = "recip.s";
7688 break;
7689 case OPC_RSQRT_S:
7690 check_cop1x(ctx);
7692 TCGv_i32 fp0 = tcg_temp_new_i32();
7694 gen_load_fpr32(fp0, fs);
7695 gen_helper_float_rsqrt_s(fp0, cpu_env, fp0);
7696 gen_store_fpr32(fp0, fd);
7697 tcg_temp_free_i32(fp0);
7699 opn = "rsqrt.s";
7700 break;
7701 case OPC_RECIP2_S:
7702 check_cp1_64bitmode(ctx);
7704 TCGv_i32 fp0 = tcg_temp_new_i32();
7705 TCGv_i32 fp1 = tcg_temp_new_i32();
7707 gen_load_fpr32(fp0, fs);
7708 gen_load_fpr32(fp1, ft);
7709 gen_helper_float_recip2_s(fp0, cpu_env, fp0, fp1);
7710 tcg_temp_free_i32(fp1);
7711 gen_store_fpr32(fp0, fd);
7712 tcg_temp_free_i32(fp0);
7714 opn = "recip2.s";
7715 break;
7716 case OPC_RECIP1_S:
7717 check_cp1_64bitmode(ctx);
7719 TCGv_i32 fp0 = tcg_temp_new_i32();
7721 gen_load_fpr32(fp0, fs);
7722 gen_helper_float_recip1_s(fp0, cpu_env, fp0);
7723 gen_store_fpr32(fp0, fd);
7724 tcg_temp_free_i32(fp0);
7726 opn = "recip1.s";
7727 break;
7728 case OPC_RSQRT1_S:
7729 check_cp1_64bitmode(ctx);
7731 TCGv_i32 fp0 = tcg_temp_new_i32();
7733 gen_load_fpr32(fp0, fs);
7734 gen_helper_float_rsqrt1_s(fp0, cpu_env, fp0);
7735 gen_store_fpr32(fp0, fd);
7736 tcg_temp_free_i32(fp0);
7738 opn = "rsqrt1.s";
7739 break;
7740 case OPC_RSQRT2_S:
7741 check_cp1_64bitmode(ctx);
7743 TCGv_i32 fp0 = tcg_temp_new_i32();
7744 TCGv_i32 fp1 = tcg_temp_new_i32();
7746 gen_load_fpr32(fp0, fs);
7747 gen_load_fpr32(fp1, ft);
7748 gen_helper_float_rsqrt2_s(fp0, cpu_env, fp0, fp1);
7749 tcg_temp_free_i32(fp1);
7750 gen_store_fpr32(fp0, fd);
7751 tcg_temp_free_i32(fp0);
7753 opn = "rsqrt2.s";
7754 break;
7755 case OPC_CVT_D_S:
7756 check_cp1_registers(ctx, fd);
7758 TCGv_i32 fp32 = tcg_temp_new_i32();
7759 TCGv_i64 fp64 = tcg_temp_new_i64();
7761 gen_load_fpr32(fp32, fs);
7762 gen_helper_float_cvtd_s(fp64, cpu_env, fp32);
7763 tcg_temp_free_i32(fp32);
7764 gen_store_fpr64(ctx, fp64, fd);
7765 tcg_temp_free_i64(fp64);
7767 opn = "cvt.d.s";
7768 break;
7769 case OPC_CVT_W_S:
7771 TCGv_i32 fp0 = tcg_temp_new_i32();
7773 gen_load_fpr32(fp0, fs);
7774 gen_helper_float_cvtw_s(fp0, cpu_env, fp0);
7775 gen_store_fpr32(fp0, fd);
7776 tcg_temp_free_i32(fp0);
7778 opn = "cvt.w.s";
7779 break;
7780 case OPC_CVT_L_S:
7781 check_cp1_64bitmode(ctx);
7783 TCGv_i32 fp32 = tcg_temp_new_i32();
7784 TCGv_i64 fp64 = tcg_temp_new_i64();
7786 gen_load_fpr32(fp32, fs);
7787 gen_helper_float_cvtl_s(fp64, cpu_env, fp32);
7788 tcg_temp_free_i32(fp32);
7789 gen_store_fpr64(ctx, fp64, fd);
7790 tcg_temp_free_i64(fp64);
7792 opn = "cvt.l.s";
7793 break;
7794 case OPC_CVT_PS_S:
7795 check_cp1_64bitmode(ctx);
7797 TCGv_i64 fp64 = tcg_temp_new_i64();
7798 TCGv_i32 fp32_0 = tcg_temp_new_i32();
7799 TCGv_i32 fp32_1 = tcg_temp_new_i32();
7801 gen_load_fpr32(fp32_0, fs);
7802 gen_load_fpr32(fp32_1, ft);
7803 tcg_gen_concat_i32_i64(fp64, fp32_1, fp32_0);
7804 tcg_temp_free_i32(fp32_1);
7805 tcg_temp_free_i32(fp32_0);
7806 gen_store_fpr64(ctx, fp64, fd);
7807 tcg_temp_free_i64(fp64);
7809 opn = "cvt.ps.s";
7810 break;
7811 case OPC_CMP_F_S:
7812 case OPC_CMP_UN_S:
7813 case OPC_CMP_EQ_S:
7814 case OPC_CMP_UEQ_S:
7815 case OPC_CMP_OLT_S:
7816 case OPC_CMP_ULT_S:
7817 case OPC_CMP_OLE_S:
7818 case OPC_CMP_ULE_S:
7819 case OPC_CMP_SF_S:
7820 case OPC_CMP_NGLE_S:
7821 case OPC_CMP_SEQ_S:
7822 case OPC_CMP_NGL_S:
7823 case OPC_CMP_LT_S:
7824 case OPC_CMP_NGE_S:
7825 case OPC_CMP_LE_S:
7826 case OPC_CMP_NGT_S:
7827 if (ctx->opcode & (1 << 6)) {
7828 gen_cmpabs_s(ctx, func-48, ft, fs, cc);
7829 opn = condnames_abs[func-48];
7830 } else {
7831 gen_cmp_s(ctx, func-48, ft, fs, cc);
7832 opn = condnames[func-48];
7834 break;
7835 case OPC_ADD_D:
7836 check_cp1_registers(ctx, fs | ft | fd);
7838 TCGv_i64 fp0 = tcg_temp_new_i64();
7839 TCGv_i64 fp1 = tcg_temp_new_i64();
7841 gen_load_fpr64(ctx, fp0, fs);
7842 gen_load_fpr64(ctx, fp1, ft);
7843 gen_helper_float_add_d(fp0, cpu_env, fp0, fp1);
7844 tcg_temp_free_i64(fp1);
7845 gen_store_fpr64(ctx, fp0, fd);
7846 tcg_temp_free_i64(fp0);
7848 opn = "add.d";
7849 optype = BINOP;
7850 break;
7851 case OPC_SUB_D:
7852 check_cp1_registers(ctx, fs | ft | fd);
7854 TCGv_i64 fp0 = tcg_temp_new_i64();
7855 TCGv_i64 fp1 = tcg_temp_new_i64();
7857 gen_load_fpr64(ctx, fp0, fs);
7858 gen_load_fpr64(ctx, fp1, ft);
7859 gen_helper_float_sub_d(fp0, cpu_env, fp0, fp1);
7860 tcg_temp_free_i64(fp1);
7861 gen_store_fpr64(ctx, fp0, fd);
7862 tcg_temp_free_i64(fp0);
7864 opn = "sub.d";
7865 optype = BINOP;
7866 break;
7867 case OPC_MUL_D:
7868 check_cp1_registers(ctx, fs | ft | fd);
7870 TCGv_i64 fp0 = tcg_temp_new_i64();
7871 TCGv_i64 fp1 = tcg_temp_new_i64();
7873 gen_load_fpr64(ctx, fp0, fs);
7874 gen_load_fpr64(ctx, fp1, ft);
7875 gen_helper_float_mul_d(fp0, cpu_env, fp0, fp1);
7876 tcg_temp_free_i64(fp1);
7877 gen_store_fpr64(ctx, fp0, fd);
7878 tcg_temp_free_i64(fp0);
7880 opn = "mul.d";
7881 optype = BINOP;
7882 break;
7883 case OPC_DIV_D:
7884 check_cp1_registers(ctx, fs | ft | fd);
7886 TCGv_i64 fp0 = tcg_temp_new_i64();
7887 TCGv_i64 fp1 = tcg_temp_new_i64();
7889 gen_load_fpr64(ctx, fp0, fs);
7890 gen_load_fpr64(ctx, fp1, ft);
7891 gen_helper_float_div_d(fp0, cpu_env, fp0, fp1);
7892 tcg_temp_free_i64(fp1);
7893 gen_store_fpr64(ctx, fp0, fd);
7894 tcg_temp_free_i64(fp0);
7896 opn = "div.d";
7897 optype = BINOP;
7898 break;
7899 case OPC_SQRT_D:
7900 check_cp1_registers(ctx, fs | fd);
7902 TCGv_i64 fp0 = tcg_temp_new_i64();
7904 gen_load_fpr64(ctx, fp0, fs);
7905 gen_helper_float_sqrt_d(fp0, cpu_env, fp0);
7906 gen_store_fpr64(ctx, fp0, fd);
7907 tcg_temp_free_i64(fp0);
7909 opn = "sqrt.d";
7910 break;
7911 case OPC_ABS_D:
7912 check_cp1_registers(ctx, fs | fd);
7914 TCGv_i64 fp0 = tcg_temp_new_i64();
7916 gen_load_fpr64(ctx, fp0, fs);
7917 gen_helper_float_abs_d(fp0, fp0);
7918 gen_store_fpr64(ctx, fp0, fd);
7919 tcg_temp_free_i64(fp0);
7921 opn = "abs.d";
7922 break;
7923 case OPC_MOV_D:
7924 check_cp1_registers(ctx, fs | fd);
7926 TCGv_i64 fp0 = tcg_temp_new_i64();
7928 gen_load_fpr64(ctx, fp0, fs);
7929 gen_store_fpr64(ctx, fp0, fd);
7930 tcg_temp_free_i64(fp0);
7932 opn = "mov.d";
7933 break;
7934 case OPC_NEG_D:
7935 check_cp1_registers(ctx, fs | fd);
7937 TCGv_i64 fp0 = tcg_temp_new_i64();
7939 gen_load_fpr64(ctx, fp0, fs);
7940 gen_helper_float_chs_d(fp0, fp0);
7941 gen_store_fpr64(ctx, fp0, fd);
7942 tcg_temp_free_i64(fp0);
7944 opn = "neg.d";
7945 break;
7946 case OPC_ROUND_L_D:
7947 check_cp1_64bitmode(ctx);
7949 TCGv_i64 fp0 = tcg_temp_new_i64();
7951 gen_load_fpr64(ctx, fp0, fs);
7952 gen_helper_float_roundl_d(fp0, cpu_env, fp0);
7953 gen_store_fpr64(ctx, fp0, fd);
7954 tcg_temp_free_i64(fp0);
7956 opn = "round.l.d";
7957 break;
7958 case OPC_TRUNC_L_D:
7959 check_cp1_64bitmode(ctx);
7961 TCGv_i64 fp0 = tcg_temp_new_i64();
7963 gen_load_fpr64(ctx, fp0, fs);
7964 gen_helper_float_truncl_d(fp0, cpu_env, fp0);
7965 gen_store_fpr64(ctx, fp0, fd);
7966 tcg_temp_free_i64(fp0);
7968 opn = "trunc.l.d";
7969 break;
7970 case OPC_CEIL_L_D:
7971 check_cp1_64bitmode(ctx);
7973 TCGv_i64 fp0 = tcg_temp_new_i64();
7975 gen_load_fpr64(ctx, fp0, fs);
7976 gen_helper_float_ceill_d(fp0, cpu_env, fp0);
7977 gen_store_fpr64(ctx, fp0, fd);
7978 tcg_temp_free_i64(fp0);
7980 opn = "ceil.l.d";
7981 break;
7982 case OPC_FLOOR_L_D:
7983 check_cp1_64bitmode(ctx);
7985 TCGv_i64 fp0 = tcg_temp_new_i64();
7987 gen_load_fpr64(ctx, fp0, fs);
7988 gen_helper_float_floorl_d(fp0, cpu_env, fp0);
7989 gen_store_fpr64(ctx, fp0, fd);
7990 tcg_temp_free_i64(fp0);
7992 opn = "floor.l.d";
7993 break;
7994 case OPC_ROUND_W_D:
7995 check_cp1_registers(ctx, fs);
7997 TCGv_i32 fp32 = tcg_temp_new_i32();
7998 TCGv_i64 fp64 = tcg_temp_new_i64();
8000 gen_load_fpr64(ctx, fp64, fs);
8001 gen_helper_float_roundw_d(fp32, cpu_env, fp64);
8002 tcg_temp_free_i64(fp64);
8003 gen_store_fpr32(fp32, fd);
8004 tcg_temp_free_i32(fp32);
8006 opn = "round.w.d";
8007 break;
8008 case OPC_TRUNC_W_D:
8009 check_cp1_registers(ctx, fs);
8011 TCGv_i32 fp32 = tcg_temp_new_i32();
8012 TCGv_i64 fp64 = tcg_temp_new_i64();
8014 gen_load_fpr64(ctx, fp64, fs);
8015 gen_helper_float_truncw_d(fp32, cpu_env, fp64);
8016 tcg_temp_free_i64(fp64);
8017 gen_store_fpr32(fp32, fd);
8018 tcg_temp_free_i32(fp32);
8020 opn = "trunc.w.d";
8021 break;
8022 case OPC_CEIL_W_D:
8023 check_cp1_registers(ctx, fs);
8025 TCGv_i32 fp32 = tcg_temp_new_i32();
8026 TCGv_i64 fp64 = tcg_temp_new_i64();
8028 gen_load_fpr64(ctx, fp64, fs);
8029 gen_helper_float_ceilw_d(fp32, cpu_env, fp64);
8030 tcg_temp_free_i64(fp64);
8031 gen_store_fpr32(fp32, fd);
8032 tcg_temp_free_i32(fp32);
8034 opn = "ceil.w.d";
8035 break;
8036 case OPC_FLOOR_W_D:
8037 check_cp1_registers(ctx, fs);
8039 TCGv_i32 fp32 = tcg_temp_new_i32();
8040 TCGv_i64 fp64 = tcg_temp_new_i64();
8042 gen_load_fpr64(ctx, fp64, fs);
8043 gen_helper_float_floorw_d(fp32, cpu_env, fp64);
8044 tcg_temp_free_i64(fp64);
8045 gen_store_fpr32(fp32, fd);
8046 tcg_temp_free_i32(fp32);
8048 opn = "floor.w.d";
8049 break;
8050 case OPC_MOVCF_D:
8051 gen_movcf_d(ctx, fs, fd, (ft >> 2) & 0x7, ft & 0x1);
8052 opn = "movcf.d";
8053 break;
8054 case OPC_MOVZ_D:
8056 int l1 = gen_new_label();
8057 TCGv_i64 fp0;
8059 if (ft != 0) {
8060 tcg_gen_brcondi_tl(TCG_COND_NE, cpu_gpr[ft], 0, l1);
8062 fp0 = tcg_temp_new_i64();
8063 gen_load_fpr64(ctx, fp0, fs);
8064 gen_store_fpr64(ctx, fp0, fd);
8065 tcg_temp_free_i64(fp0);
8066 gen_set_label(l1);
8068 opn = "movz.d";
8069 break;
8070 case OPC_MOVN_D:
8072 int l1 = gen_new_label();
8073 TCGv_i64 fp0;
8075 if (ft != 0) {
8076 tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_gpr[ft], 0, l1);
8077 fp0 = tcg_temp_new_i64();
8078 gen_load_fpr64(ctx, fp0, fs);
8079 gen_store_fpr64(ctx, fp0, fd);
8080 tcg_temp_free_i64(fp0);
8081 gen_set_label(l1);
8084 opn = "movn.d";
8085 break;
8086 case OPC_RECIP_D:
8087 check_cp1_64bitmode(ctx);
8089 TCGv_i64 fp0 = tcg_temp_new_i64();
8091 gen_load_fpr64(ctx, fp0, fs);
8092 gen_helper_float_recip_d(fp0, cpu_env, fp0);
8093 gen_store_fpr64(ctx, fp0, fd);
8094 tcg_temp_free_i64(fp0);
8096 opn = "recip.d";
8097 break;
8098 case OPC_RSQRT_D:
8099 check_cp1_64bitmode(ctx);
8101 TCGv_i64 fp0 = tcg_temp_new_i64();
8103 gen_load_fpr64(ctx, fp0, fs);
8104 gen_helper_float_rsqrt_d(fp0, cpu_env, fp0);
8105 gen_store_fpr64(ctx, fp0, fd);
8106 tcg_temp_free_i64(fp0);
8108 opn = "rsqrt.d";
8109 break;
8110 case OPC_RECIP2_D:
8111 check_cp1_64bitmode(ctx);
8113 TCGv_i64 fp0 = tcg_temp_new_i64();
8114 TCGv_i64 fp1 = tcg_temp_new_i64();
8116 gen_load_fpr64(ctx, fp0, fs);
8117 gen_load_fpr64(ctx, fp1, ft);
8118 gen_helper_float_recip2_d(fp0, cpu_env, fp0, fp1);
8119 tcg_temp_free_i64(fp1);
8120 gen_store_fpr64(ctx, fp0, fd);
8121 tcg_temp_free_i64(fp0);
8123 opn = "recip2.d";
8124 break;
8125 case OPC_RECIP1_D:
8126 check_cp1_64bitmode(ctx);
8128 TCGv_i64 fp0 = tcg_temp_new_i64();
8130 gen_load_fpr64(ctx, fp0, fs);
8131 gen_helper_float_recip1_d(fp0, cpu_env, fp0);
8132 gen_store_fpr64(ctx, fp0, fd);
8133 tcg_temp_free_i64(fp0);
8135 opn = "recip1.d";
8136 break;
8137 case OPC_RSQRT1_D:
8138 check_cp1_64bitmode(ctx);
8140 TCGv_i64 fp0 = tcg_temp_new_i64();
8142 gen_load_fpr64(ctx, fp0, fs);
8143 gen_helper_float_rsqrt1_d(fp0, cpu_env, fp0);
8144 gen_store_fpr64(ctx, fp0, fd);
8145 tcg_temp_free_i64(fp0);
8147 opn = "rsqrt1.d";
8148 break;
8149 case OPC_RSQRT2_D:
8150 check_cp1_64bitmode(ctx);
8152 TCGv_i64 fp0 = tcg_temp_new_i64();
8153 TCGv_i64 fp1 = tcg_temp_new_i64();
8155 gen_load_fpr64(ctx, fp0, fs);
8156 gen_load_fpr64(ctx, fp1, ft);
8157 gen_helper_float_rsqrt2_d(fp0, cpu_env, fp0, fp1);
8158 tcg_temp_free_i64(fp1);
8159 gen_store_fpr64(ctx, fp0, fd);
8160 tcg_temp_free_i64(fp0);
8162 opn = "rsqrt2.d";
8163 break;
8164 case OPC_CMP_F_D:
8165 case OPC_CMP_UN_D:
8166 case OPC_CMP_EQ_D:
8167 case OPC_CMP_UEQ_D:
8168 case OPC_CMP_OLT_D:
8169 case OPC_CMP_ULT_D:
8170 case OPC_CMP_OLE_D:
8171 case OPC_CMP_ULE_D:
8172 case OPC_CMP_SF_D:
8173 case OPC_CMP_NGLE_D:
8174 case OPC_CMP_SEQ_D:
8175 case OPC_CMP_NGL_D:
8176 case OPC_CMP_LT_D:
8177 case OPC_CMP_NGE_D:
8178 case OPC_CMP_LE_D:
8179 case OPC_CMP_NGT_D:
8180 if (ctx->opcode & (1 << 6)) {
8181 gen_cmpabs_d(ctx, func-48, ft, fs, cc);
8182 opn = condnames_abs[func-48];
8183 } else {
8184 gen_cmp_d(ctx, func-48, ft, fs, cc);
8185 opn = condnames[func-48];
8187 break;
8188 case OPC_CVT_S_D:
8189 check_cp1_registers(ctx, fs);
8191 TCGv_i32 fp32 = tcg_temp_new_i32();
8192 TCGv_i64 fp64 = tcg_temp_new_i64();
8194 gen_load_fpr64(ctx, fp64, fs);
8195 gen_helper_float_cvts_d(fp32, cpu_env, fp64);
8196 tcg_temp_free_i64(fp64);
8197 gen_store_fpr32(fp32, fd);
8198 tcg_temp_free_i32(fp32);
8200 opn = "cvt.s.d";
8201 break;
8202 case OPC_CVT_W_D:
8203 check_cp1_registers(ctx, fs);
8205 TCGv_i32 fp32 = tcg_temp_new_i32();
8206 TCGv_i64 fp64 = tcg_temp_new_i64();
8208 gen_load_fpr64(ctx, fp64, fs);
8209 gen_helper_float_cvtw_d(fp32, cpu_env, fp64);
8210 tcg_temp_free_i64(fp64);
8211 gen_store_fpr32(fp32, fd);
8212 tcg_temp_free_i32(fp32);
8214 opn = "cvt.w.d";
8215 break;
8216 case OPC_CVT_L_D:
8217 check_cp1_64bitmode(ctx);
8219 TCGv_i64 fp0 = tcg_temp_new_i64();
8221 gen_load_fpr64(ctx, fp0, fs);
8222 gen_helper_float_cvtl_d(fp0, cpu_env, fp0);
8223 gen_store_fpr64(ctx, fp0, fd);
8224 tcg_temp_free_i64(fp0);
8226 opn = "cvt.l.d";
8227 break;
8228 case OPC_CVT_S_W:
8230 TCGv_i32 fp0 = tcg_temp_new_i32();
8232 gen_load_fpr32(fp0, fs);
8233 gen_helper_float_cvts_w(fp0, cpu_env, fp0);
8234 gen_store_fpr32(fp0, fd);
8235 tcg_temp_free_i32(fp0);
8237 opn = "cvt.s.w";
8238 break;
8239 case OPC_CVT_D_W:
8240 check_cp1_registers(ctx, fd);
8242 TCGv_i32 fp32 = tcg_temp_new_i32();
8243 TCGv_i64 fp64 = tcg_temp_new_i64();
8245 gen_load_fpr32(fp32, fs);
8246 gen_helper_float_cvtd_w(fp64, cpu_env, fp32);
8247 tcg_temp_free_i32(fp32);
8248 gen_store_fpr64(ctx, fp64, fd);
8249 tcg_temp_free_i64(fp64);
8251 opn = "cvt.d.w";
8252 break;
8253 case OPC_CVT_S_L:
8254 check_cp1_64bitmode(ctx);
8256 TCGv_i32 fp32 = tcg_temp_new_i32();
8257 TCGv_i64 fp64 = tcg_temp_new_i64();
8259 gen_load_fpr64(ctx, fp64, fs);
8260 gen_helper_float_cvts_l(fp32, cpu_env, fp64);
8261 tcg_temp_free_i64(fp64);
8262 gen_store_fpr32(fp32, fd);
8263 tcg_temp_free_i32(fp32);
8265 opn = "cvt.s.l";
8266 break;
8267 case OPC_CVT_D_L:
8268 check_cp1_64bitmode(ctx);
8270 TCGv_i64 fp0 = tcg_temp_new_i64();
8272 gen_load_fpr64(ctx, fp0, fs);
8273 gen_helper_float_cvtd_l(fp0, cpu_env, fp0);
8274 gen_store_fpr64(ctx, fp0, fd);
8275 tcg_temp_free_i64(fp0);
8277 opn = "cvt.d.l";
8278 break;
8279 case OPC_CVT_PS_PW:
8280 check_cp1_64bitmode(ctx);
8282 TCGv_i64 fp0 = tcg_temp_new_i64();
8284 gen_load_fpr64(ctx, fp0, fs);
8285 gen_helper_float_cvtps_pw(fp0, cpu_env, fp0);
8286 gen_store_fpr64(ctx, fp0, fd);
8287 tcg_temp_free_i64(fp0);
8289 opn = "cvt.ps.pw";
8290 break;
8291 case OPC_ADD_PS:
8292 check_cp1_64bitmode(ctx);
8294 TCGv_i64 fp0 = tcg_temp_new_i64();
8295 TCGv_i64 fp1 = tcg_temp_new_i64();
8297 gen_load_fpr64(ctx, fp0, fs);
8298 gen_load_fpr64(ctx, fp1, ft);
8299 gen_helper_float_add_ps(fp0, cpu_env, fp0, fp1);
8300 tcg_temp_free_i64(fp1);
8301 gen_store_fpr64(ctx, fp0, fd);
8302 tcg_temp_free_i64(fp0);
8304 opn = "add.ps";
8305 break;
8306 case OPC_SUB_PS:
8307 check_cp1_64bitmode(ctx);
8309 TCGv_i64 fp0 = tcg_temp_new_i64();
8310 TCGv_i64 fp1 = tcg_temp_new_i64();
8312 gen_load_fpr64(ctx, fp0, fs);
8313 gen_load_fpr64(ctx, fp1, ft);
8314 gen_helper_float_sub_ps(fp0, cpu_env, fp0, fp1);
8315 tcg_temp_free_i64(fp1);
8316 gen_store_fpr64(ctx, fp0, fd);
8317 tcg_temp_free_i64(fp0);
8319 opn = "sub.ps";
8320 break;
8321 case OPC_MUL_PS:
8322 check_cp1_64bitmode(ctx);
8324 TCGv_i64 fp0 = tcg_temp_new_i64();
8325 TCGv_i64 fp1 = tcg_temp_new_i64();
8327 gen_load_fpr64(ctx, fp0, fs);
8328 gen_load_fpr64(ctx, fp1, ft);
8329 gen_helper_float_mul_ps(fp0, cpu_env, fp0, fp1);
8330 tcg_temp_free_i64(fp1);
8331 gen_store_fpr64(ctx, fp0, fd);
8332 tcg_temp_free_i64(fp0);
8334 opn = "mul.ps";
8335 break;
8336 case OPC_ABS_PS:
8337 check_cp1_64bitmode(ctx);
8339 TCGv_i64 fp0 = tcg_temp_new_i64();
8341 gen_load_fpr64(ctx, fp0, fs);
8342 gen_helper_float_abs_ps(fp0, fp0);
8343 gen_store_fpr64(ctx, fp0, fd);
8344 tcg_temp_free_i64(fp0);
8346 opn = "abs.ps";
8347 break;
8348 case OPC_MOV_PS:
8349 check_cp1_64bitmode(ctx);
8351 TCGv_i64 fp0 = tcg_temp_new_i64();
8353 gen_load_fpr64(ctx, fp0, fs);
8354 gen_store_fpr64(ctx, fp0, fd);
8355 tcg_temp_free_i64(fp0);
8357 opn = "mov.ps";
8358 break;
8359 case OPC_NEG_PS:
8360 check_cp1_64bitmode(ctx);
8362 TCGv_i64 fp0 = tcg_temp_new_i64();
8364 gen_load_fpr64(ctx, fp0, fs);
8365 gen_helper_float_chs_ps(fp0, fp0);
8366 gen_store_fpr64(ctx, fp0, fd);
8367 tcg_temp_free_i64(fp0);
8369 opn = "neg.ps";
8370 break;
8371 case OPC_MOVCF_PS:
8372 check_cp1_64bitmode(ctx);
8373 gen_movcf_ps(fs, fd, (ft >> 2) & 0x7, ft & 0x1);
8374 opn = "movcf.ps";
8375 break;
8376 case OPC_MOVZ_PS:
8377 check_cp1_64bitmode(ctx);
8379 int l1 = gen_new_label();
8380 TCGv_i64 fp0;
8382 if (ft != 0)
8383 tcg_gen_brcondi_tl(TCG_COND_NE, cpu_gpr[ft], 0, l1);
8384 fp0 = tcg_temp_new_i64();
8385 gen_load_fpr64(ctx, fp0, fs);
8386 gen_store_fpr64(ctx, fp0, fd);
8387 tcg_temp_free_i64(fp0);
8388 gen_set_label(l1);
8390 opn = "movz.ps";
8391 break;
8392 case OPC_MOVN_PS:
8393 check_cp1_64bitmode(ctx);
8395 int l1 = gen_new_label();
8396 TCGv_i64 fp0;
8398 if (ft != 0) {
8399 tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_gpr[ft], 0, l1);
8400 fp0 = tcg_temp_new_i64();
8401 gen_load_fpr64(ctx, fp0, fs);
8402 gen_store_fpr64(ctx, fp0, fd);
8403 tcg_temp_free_i64(fp0);
8404 gen_set_label(l1);
8407 opn = "movn.ps";
8408 break;
8409 case OPC_ADDR_PS:
8410 check_cp1_64bitmode(ctx);
8412 TCGv_i64 fp0 = tcg_temp_new_i64();
8413 TCGv_i64 fp1 = tcg_temp_new_i64();
8415 gen_load_fpr64(ctx, fp0, ft);
8416 gen_load_fpr64(ctx, fp1, fs);
8417 gen_helper_float_addr_ps(fp0, cpu_env, fp0, fp1);
8418 tcg_temp_free_i64(fp1);
8419 gen_store_fpr64(ctx, fp0, fd);
8420 tcg_temp_free_i64(fp0);
8422 opn = "addr.ps";
8423 break;
8424 case OPC_MULR_PS:
8425 check_cp1_64bitmode(ctx);
8427 TCGv_i64 fp0 = tcg_temp_new_i64();
8428 TCGv_i64 fp1 = tcg_temp_new_i64();
8430 gen_load_fpr64(ctx, fp0, ft);
8431 gen_load_fpr64(ctx, fp1, fs);
8432 gen_helper_float_mulr_ps(fp0, cpu_env, fp0, fp1);
8433 tcg_temp_free_i64(fp1);
8434 gen_store_fpr64(ctx, fp0, fd);
8435 tcg_temp_free_i64(fp0);
8437 opn = "mulr.ps";
8438 break;
8439 case OPC_RECIP2_PS:
8440 check_cp1_64bitmode(ctx);
8442 TCGv_i64 fp0 = tcg_temp_new_i64();
8443 TCGv_i64 fp1 = tcg_temp_new_i64();
8445 gen_load_fpr64(ctx, fp0, fs);
8446 gen_load_fpr64(ctx, fp1, ft);
8447 gen_helper_float_recip2_ps(fp0, cpu_env, fp0, fp1);
8448 tcg_temp_free_i64(fp1);
8449 gen_store_fpr64(ctx, fp0, fd);
8450 tcg_temp_free_i64(fp0);
8452 opn = "recip2.ps";
8453 break;
8454 case OPC_RECIP1_PS:
8455 check_cp1_64bitmode(ctx);
8457 TCGv_i64 fp0 = tcg_temp_new_i64();
8459 gen_load_fpr64(ctx, fp0, fs);
8460 gen_helper_float_recip1_ps(fp0, cpu_env, fp0);
8461 gen_store_fpr64(ctx, fp0, fd);
8462 tcg_temp_free_i64(fp0);
8464 opn = "recip1.ps";
8465 break;
8466 case OPC_RSQRT1_PS:
8467 check_cp1_64bitmode(ctx);
8469 TCGv_i64 fp0 = tcg_temp_new_i64();
8471 gen_load_fpr64(ctx, fp0, fs);
8472 gen_helper_float_rsqrt1_ps(fp0, cpu_env, fp0);
8473 gen_store_fpr64(ctx, fp0, fd);
8474 tcg_temp_free_i64(fp0);
8476 opn = "rsqrt1.ps";
8477 break;
8478 case OPC_RSQRT2_PS:
8479 check_cp1_64bitmode(ctx);
8481 TCGv_i64 fp0 = tcg_temp_new_i64();
8482 TCGv_i64 fp1 = tcg_temp_new_i64();
8484 gen_load_fpr64(ctx, fp0, fs);
8485 gen_load_fpr64(ctx, fp1, ft);
8486 gen_helper_float_rsqrt2_ps(fp0, cpu_env, fp0, fp1);
8487 tcg_temp_free_i64(fp1);
8488 gen_store_fpr64(ctx, fp0, fd);
8489 tcg_temp_free_i64(fp0);
8491 opn = "rsqrt2.ps";
8492 break;
8493 case OPC_CVT_S_PU:
8494 check_cp1_64bitmode(ctx);
8496 TCGv_i32 fp0 = tcg_temp_new_i32();
8498 gen_load_fpr32h(fp0, fs);
8499 gen_helper_float_cvts_pu(fp0, cpu_env, fp0);
8500 gen_store_fpr32(fp0, fd);
8501 tcg_temp_free_i32(fp0);
8503 opn = "cvt.s.pu";
8504 break;
8505 case OPC_CVT_PW_PS:
8506 check_cp1_64bitmode(ctx);
8508 TCGv_i64 fp0 = tcg_temp_new_i64();
8510 gen_load_fpr64(ctx, fp0, fs);
8511 gen_helper_float_cvtpw_ps(fp0, cpu_env, fp0);
8512 gen_store_fpr64(ctx, fp0, fd);
8513 tcg_temp_free_i64(fp0);
8515 opn = "cvt.pw.ps";
8516 break;
8517 case OPC_CVT_S_PL:
8518 check_cp1_64bitmode(ctx);
8520 TCGv_i32 fp0 = tcg_temp_new_i32();
8522 gen_load_fpr32(fp0, fs);
8523 gen_helper_float_cvts_pl(fp0, cpu_env, fp0);
8524 gen_store_fpr32(fp0, fd);
8525 tcg_temp_free_i32(fp0);
8527 opn = "cvt.s.pl";
8528 break;
8529 case OPC_PLL_PS:
8530 check_cp1_64bitmode(ctx);
8532 TCGv_i32 fp0 = tcg_temp_new_i32();
8533 TCGv_i32 fp1 = tcg_temp_new_i32();
8535 gen_load_fpr32(fp0, fs);
8536 gen_load_fpr32(fp1, ft);
8537 gen_store_fpr32h(fp0, fd);
8538 gen_store_fpr32(fp1, fd);
8539 tcg_temp_free_i32(fp0);
8540 tcg_temp_free_i32(fp1);
8542 opn = "pll.ps";
8543 break;
8544 case OPC_PLU_PS:
8545 check_cp1_64bitmode(ctx);
8547 TCGv_i32 fp0 = tcg_temp_new_i32();
8548 TCGv_i32 fp1 = tcg_temp_new_i32();
8550 gen_load_fpr32(fp0, fs);
8551 gen_load_fpr32h(fp1, ft);
8552 gen_store_fpr32(fp1, fd);
8553 gen_store_fpr32h(fp0, fd);
8554 tcg_temp_free_i32(fp0);
8555 tcg_temp_free_i32(fp1);
8557 opn = "plu.ps";
8558 break;
8559 case OPC_PUL_PS:
8560 check_cp1_64bitmode(ctx);
8562 TCGv_i32 fp0 = tcg_temp_new_i32();
8563 TCGv_i32 fp1 = tcg_temp_new_i32();
8565 gen_load_fpr32h(fp0, fs);
8566 gen_load_fpr32(fp1, ft);
8567 gen_store_fpr32(fp1, fd);
8568 gen_store_fpr32h(fp0, fd);
8569 tcg_temp_free_i32(fp0);
8570 tcg_temp_free_i32(fp1);
8572 opn = "pul.ps";
8573 break;
8574 case OPC_PUU_PS:
8575 check_cp1_64bitmode(ctx);
8577 TCGv_i32 fp0 = tcg_temp_new_i32();
8578 TCGv_i32 fp1 = tcg_temp_new_i32();
8580 gen_load_fpr32h(fp0, fs);
8581 gen_load_fpr32h(fp1, ft);
8582 gen_store_fpr32(fp1, fd);
8583 gen_store_fpr32h(fp0, fd);
8584 tcg_temp_free_i32(fp0);
8585 tcg_temp_free_i32(fp1);
8587 opn = "puu.ps";
8588 break;
8589 case OPC_CMP_F_PS:
8590 case OPC_CMP_UN_PS:
8591 case OPC_CMP_EQ_PS:
8592 case OPC_CMP_UEQ_PS:
8593 case OPC_CMP_OLT_PS:
8594 case OPC_CMP_ULT_PS:
8595 case OPC_CMP_OLE_PS:
8596 case OPC_CMP_ULE_PS:
8597 case OPC_CMP_SF_PS:
8598 case OPC_CMP_NGLE_PS:
8599 case OPC_CMP_SEQ_PS:
8600 case OPC_CMP_NGL_PS:
8601 case OPC_CMP_LT_PS:
8602 case OPC_CMP_NGE_PS:
8603 case OPC_CMP_LE_PS:
8604 case OPC_CMP_NGT_PS:
8605 if (ctx->opcode & (1 << 6)) {
8606 gen_cmpabs_ps(ctx, func-48, ft, fs, cc);
8607 opn = condnames_abs[func-48];
8608 } else {
8609 gen_cmp_ps(ctx, func-48, ft, fs, cc);
8610 opn = condnames[func-48];
8612 break;
8613 default:
8614 MIPS_INVAL(opn);
8615 generate_exception (ctx, EXCP_RI);
8616 return;
8618 (void)opn; /* avoid a compiler warning */
8619 switch (optype) {
8620 case BINOP:
8621 MIPS_DEBUG("%s %s, %s, %s", opn, fregnames[fd], fregnames[fs], fregnames[ft]);
8622 break;
8623 case CMPOP:
8624 MIPS_DEBUG("%s %s,%s", opn, fregnames[fs], fregnames[ft]);
8625 break;
8626 default:
8627 MIPS_DEBUG("%s %s,%s", opn, fregnames[fd], fregnames[fs]);
8628 break;
8632 /* Coprocessor 3 (FPU) */
8633 static void gen_flt3_ldst (DisasContext *ctx, uint32_t opc,
8634 int fd, int fs, int base, int index)
8636 const char *opn = "extended float load/store";
8637 int store = 0;
8638 TCGv t0 = tcg_temp_new();
8640 if (base == 0) {
8641 gen_load_gpr(t0, index);
8642 } else if (index == 0) {
8643 gen_load_gpr(t0, base);
8644 } else {
8645 gen_op_addr_add(ctx, t0, cpu_gpr[base], cpu_gpr[index]);
8647 /* Don't do NOP if destination is zero: we must perform the actual
8648 memory access. */
8649 switch (opc) {
8650 case OPC_LWXC1:
8651 check_cop1x(ctx);
8653 TCGv_i32 fp0 = tcg_temp_new_i32();
8655 tcg_gen_qemu_ld32s(t0, t0, ctx->mem_idx);
8656 tcg_gen_trunc_tl_i32(fp0, t0);
8657 gen_store_fpr32(fp0, fd);
8658 tcg_temp_free_i32(fp0);
8660 opn = "lwxc1";
8661 break;
8662 case OPC_LDXC1:
8663 check_cop1x(ctx);
8664 check_cp1_registers(ctx, fd);
8666 TCGv_i64 fp0 = tcg_temp_new_i64();
8668 tcg_gen_qemu_ld64(fp0, t0, ctx->mem_idx);
8669 gen_store_fpr64(ctx, fp0, fd);
8670 tcg_temp_free_i64(fp0);
8672 opn = "ldxc1";
8673 break;
8674 case OPC_LUXC1:
8675 check_cp1_64bitmode(ctx);
8676 tcg_gen_andi_tl(t0, t0, ~0x7);
8678 TCGv_i64 fp0 = tcg_temp_new_i64();
8680 tcg_gen_qemu_ld64(fp0, t0, ctx->mem_idx);
8681 gen_store_fpr64(ctx, fp0, fd);
8682 tcg_temp_free_i64(fp0);
8684 opn = "luxc1";
8685 break;
8686 case OPC_SWXC1:
8687 check_cop1x(ctx);
8689 TCGv_i32 fp0 = tcg_temp_new_i32();
8690 TCGv t1 = tcg_temp_new();
8692 gen_load_fpr32(fp0, fs);
8693 tcg_gen_extu_i32_tl(t1, fp0);
8694 tcg_gen_qemu_st32(t1, t0, ctx->mem_idx);
8695 tcg_temp_free_i32(fp0);
8696 tcg_temp_free(t1);
8698 opn = "swxc1";
8699 store = 1;
8700 break;
8701 case OPC_SDXC1:
8702 check_cop1x(ctx);
8703 check_cp1_registers(ctx, fs);
8705 TCGv_i64 fp0 = tcg_temp_new_i64();
8707 gen_load_fpr64(ctx, fp0, fs);
8708 tcg_gen_qemu_st64(fp0, t0, ctx->mem_idx);
8709 tcg_temp_free_i64(fp0);
8711 opn = "sdxc1";
8712 store = 1;
8713 break;
8714 case OPC_SUXC1:
8715 check_cp1_64bitmode(ctx);
8716 tcg_gen_andi_tl(t0, t0, ~0x7);
8718 TCGv_i64 fp0 = tcg_temp_new_i64();
8720 gen_load_fpr64(ctx, fp0, fs);
8721 tcg_gen_qemu_st64(fp0, t0, ctx->mem_idx);
8722 tcg_temp_free_i64(fp0);
8724 opn = "suxc1";
8725 store = 1;
8726 break;
8728 tcg_temp_free(t0);
8729 (void)opn; (void)store; /* avoid compiler warnings */
8730 MIPS_DEBUG("%s %s, %s(%s)", opn, fregnames[store ? fs : fd],
8731 regnames[index], regnames[base]);
8734 static void gen_flt3_arith (DisasContext *ctx, uint32_t opc,
8735 int fd, int fr, int fs, int ft)
8737 const char *opn = "flt3_arith";
8739 switch (opc) {
8740 case OPC_ALNV_PS:
8741 check_cp1_64bitmode(ctx);
8743 TCGv t0 = tcg_temp_local_new();
8744 TCGv_i32 fp = tcg_temp_new_i32();
8745 TCGv_i32 fph = tcg_temp_new_i32();
8746 int l1 = gen_new_label();
8747 int l2 = gen_new_label();
8749 gen_load_gpr(t0, fr);
8750 tcg_gen_andi_tl(t0, t0, 0x7);
8752 tcg_gen_brcondi_tl(TCG_COND_NE, t0, 0, l1);
8753 gen_load_fpr32(fp, fs);
8754 gen_load_fpr32h(fph, fs);
8755 gen_store_fpr32(fp, fd);
8756 gen_store_fpr32h(fph, fd);
8757 tcg_gen_br(l2);
8758 gen_set_label(l1);
8759 tcg_gen_brcondi_tl(TCG_COND_NE, t0, 4, l2);
8760 tcg_temp_free(t0);
8761 #ifdef TARGET_WORDS_BIGENDIAN
8762 gen_load_fpr32(fp, fs);
8763 gen_load_fpr32h(fph, ft);
8764 gen_store_fpr32h(fp, fd);
8765 gen_store_fpr32(fph, fd);
8766 #else
8767 gen_load_fpr32h(fph, fs);
8768 gen_load_fpr32(fp, ft);
8769 gen_store_fpr32(fph, fd);
8770 gen_store_fpr32h(fp, fd);
8771 #endif
8772 gen_set_label(l2);
8773 tcg_temp_free_i32(fp);
8774 tcg_temp_free_i32(fph);
8776 opn = "alnv.ps";
8777 break;
8778 case OPC_MADD_S:
8779 check_cop1x(ctx);
8781 TCGv_i32 fp0 = tcg_temp_new_i32();
8782 TCGv_i32 fp1 = tcg_temp_new_i32();
8783 TCGv_i32 fp2 = tcg_temp_new_i32();
8785 gen_load_fpr32(fp0, fs);
8786 gen_load_fpr32(fp1, ft);
8787 gen_load_fpr32(fp2, fr);
8788 gen_helper_float_madd_s(fp2, cpu_env, fp0, fp1, fp2);
8789 tcg_temp_free_i32(fp0);
8790 tcg_temp_free_i32(fp1);
8791 gen_store_fpr32(fp2, fd);
8792 tcg_temp_free_i32(fp2);
8794 opn = "madd.s";
8795 break;
8796 case OPC_MADD_D:
8797 check_cop1x(ctx);
8798 check_cp1_registers(ctx, fd | fs | ft | fr);
8800 TCGv_i64 fp0 = tcg_temp_new_i64();
8801 TCGv_i64 fp1 = tcg_temp_new_i64();
8802 TCGv_i64 fp2 = tcg_temp_new_i64();
8804 gen_load_fpr64(ctx, fp0, fs);
8805 gen_load_fpr64(ctx, fp1, ft);
8806 gen_load_fpr64(ctx, fp2, fr);
8807 gen_helper_float_madd_d(fp2, cpu_env, fp0, fp1, fp2);
8808 tcg_temp_free_i64(fp0);
8809 tcg_temp_free_i64(fp1);
8810 gen_store_fpr64(ctx, fp2, fd);
8811 tcg_temp_free_i64(fp2);
8813 opn = "madd.d";
8814 break;
8815 case OPC_MADD_PS:
8816 check_cp1_64bitmode(ctx);
8818 TCGv_i64 fp0 = tcg_temp_new_i64();
8819 TCGv_i64 fp1 = tcg_temp_new_i64();
8820 TCGv_i64 fp2 = tcg_temp_new_i64();
8822 gen_load_fpr64(ctx, fp0, fs);
8823 gen_load_fpr64(ctx, fp1, ft);
8824 gen_load_fpr64(ctx, fp2, fr);
8825 gen_helper_float_madd_ps(fp2, cpu_env, fp0, fp1, fp2);
8826 tcg_temp_free_i64(fp0);
8827 tcg_temp_free_i64(fp1);
8828 gen_store_fpr64(ctx, fp2, fd);
8829 tcg_temp_free_i64(fp2);
8831 opn = "madd.ps";
8832 break;
8833 case OPC_MSUB_S:
8834 check_cop1x(ctx);
8836 TCGv_i32 fp0 = tcg_temp_new_i32();
8837 TCGv_i32 fp1 = tcg_temp_new_i32();
8838 TCGv_i32 fp2 = tcg_temp_new_i32();
8840 gen_load_fpr32(fp0, fs);
8841 gen_load_fpr32(fp1, ft);
8842 gen_load_fpr32(fp2, fr);
8843 gen_helper_float_msub_s(fp2, cpu_env, fp0, fp1, fp2);
8844 tcg_temp_free_i32(fp0);
8845 tcg_temp_free_i32(fp1);
8846 gen_store_fpr32(fp2, fd);
8847 tcg_temp_free_i32(fp2);
8849 opn = "msub.s";
8850 break;
8851 case OPC_MSUB_D:
8852 check_cop1x(ctx);
8853 check_cp1_registers(ctx, fd | fs | ft | fr);
8855 TCGv_i64 fp0 = tcg_temp_new_i64();
8856 TCGv_i64 fp1 = tcg_temp_new_i64();
8857 TCGv_i64 fp2 = tcg_temp_new_i64();
8859 gen_load_fpr64(ctx, fp0, fs);
8860 gen_load_fpr64(ctx, fp1, ft);
8861 gen_load_fpr64(ctx, fp2, fr);
8862 gen_helper_float_msub_d(fp2, cpu_env, fp0, fp1, fp2);
8863 tcg_temp_free_i64(fp0);
8864 tcg_temp_free_i64(fp1);
8865 gen_store_fpr64(ctx, fp2, fd);
8866 tcg_temp_free_i64(fp2);
8868 opn = "msub.d";
8869 break;
8870 case OPC_MSUB_PS:
8871 check_cp1_64bitmode(ctx);
8873 TCGv_i64 fp0 = tcg_temp_new_i64();
8874 TCGv_i64 fp1 = tcg_temp_new_i64();
8875 TCGv_i64 fp2 = tcg_temp_new_i64();
8877 gen_load_fpr64(ctx, fp0, fs);
8878 gen_load_fpr64(ctx, fp1, ft);
8879 gen_load_fpr64(ctx, fp2, fr);
8880 gen_helper_float_msub_ps(fp2, cpu_env, fp0, fp1, fp2);
8881 tcg_temp_free_i64(fp0);
8882 tcg_temp_free_i64(fp1);
8883 gen_store_fpr64(ctx, fp2, fd);
8884 tcg_temp_free_i64(fp2);
8886 opn = "msub.ps";
8887 break;
8888 case OPC_NMADD_S:
8889 check_cop1x(ctx);
8891 TCGv_i32 fp0 = tcg_temp_new_i32();
8892 TCGv_i32 fp1 = tcg_temp_new_i32();
8893 TCGv_i32 fp2 = tcg_temp_new_i32();
8895 gen_load_fpr32(fp0, fs);
8896 gen_load_fpr32(fp1, ft);
8897 gen_load_fpr32(fp2, fr);
8898 gen_helper_float_nmadd_s(fp2, cpu_env, fp0, fp1, fp2);
8899 tcg_temp_free_i32(fp0);
8900 tcg_temp_free_i32(fp1);
8901 gen_store_fpr32(fp2, fd);
8902 tcg_temp_free_i32(fp2);
8904 opn = "nmadd.s";
8905 break;
8906 case OPC_NMADD_D:
8907 check_cop1x(ctx);
8908 check_cp1_registers(ctx, fd | fs | ft | fr);
8910 TCGv_i64 fp0 = tcg_temp_new_i64();
8911 TCGv_i64 fp1 = tcg_temp_new_i64();
8912 TCGv_i64 fp2 = tcg_temp_new_i64();
8914 gen_load_fpr64(ctx, fp0, fs);
8915 gen_load_fpr64(ctx, fp1, ft);
8916 gen_load_fpr64(ctx, fp2, fr);
8917 gen_helper_float_nmadd_d(fp2, cpu_env, fp0, fp1, fp2);
8918 tcg_temp_free_i64(fp0);
8919 tcg_temp_free_i64(fp1);
8920 gen_store_fpr64(ctx, fp2, fd);
8921 tcg_temp_free_i64(fp2);
8923 opn = "nmadd.d";
8924 break;
8925 case OPC_NMADD_PS:
8926 check_cp1_64bitmode(ctx);
8928 TCGv_i64 fp0 = tcg_temp_new_i64();
8929 TCGv_i64 fp1 = tcg_temp_new_i64();
8930 TCGv_i64 fp2 = tcg_temp_new_i64();
8932 gen_load_fpr64(ctx, fp0, fs);
8933 gen_load_fpr64(ctx, fp1, ft);
8934 gen_load_fpr64(ctx, fp2, fr);
8935 gen_helper_float_nmadd_ps(fp2, cpu_env, fp0, fp1, fp2);
8936 tcg_temp_free_i64(fp0);
8937 tcg_temp_free_i64(fp1);
8938 gen_store_fpr64(ctx, fp2, fd);
8939 tcg_temp_free_i64(fp2);
8941 opn = "nmadd.ps";
8942 break;
8943 case OPC_NMSUB_S:
8944 check_cop1x(ctx);
8946 TCGv_i32 fp0 = tcg_temp_new_i32();
8947 TCGv_i32 fp1 = tcg_temp_new_i32();
8948 TCGv_i32 fp2 = tcg_temp_new_i32();
8950 gen_load_fpr32(fp0, fs);
8951 gen_load_fpr32(fp1, ft);
8952 gen_load_fpr32(fp2, fr);
8953 gen_helper_float_nmsub_s(fp2, cpu_env, fp0, fp1, fp2);
8954 tcg_temp_free_i32(fp0);
8955 tcg_temp_free_i32(fp1);
8956 gen_store_fpr32(fp2, fd);
8957 tcg_temp_free_i32(fp2);
8959 opn = "nmsub.s";
8960 break;
8961 case OPC_NMSUB_D:
8962 check_cop1x(ctx);
8963 check_cp1_registers(ctx, fd | fs | ft | fr);
8965 TCGv_i64 fp0 = tcg_temp_new_i64();
8966 TCGv_i64 fp1 = tcg_temp_new_i64();
8967 TCGv_i64 fp2 = tcg_temp_new_i64();
8969 gen_load_fpr64(ctx, fp0, fs);
8970 gen_load_fpr64(ctx, fp1, ft);
8971 gen_load_fpr64(ctx, fp2, fr);
8972 gen_helper_float_nmsub_d(fp2, cpu_env, fp0, fp1, fp2);
8973 tcg_temp_free_i64(fp0);
8974 tcg_temp_free_i64(fp1);
8975 gen_store_fpr64(ctx, fp2, fd);
8976 tcg_temp_free_i64(fp2);
8978 opn = "nmsub.d";
8979 break;
8980 case OPC_NMSUB_PS:
8981 check_cp1_64bitmode(ctx);
8983 TCGv_i64 fp0 = tcg_temp_new_i64();
8984 TCGv_i64 fp1 = tcg_temp_new_i64();
8985 TCGv_i64 fp2 = tcg_temp_new_i64();
8987 gen_load_fpr64(ctx, fp0, fs);
8988 gen_load_fpr64(ctx, fp1, ft);
8989 gen_load_fpr64(ctx, fp2, fr);
8990 gen_helper_float_nmsub_ps(fp2, cpu_env, fp0, fp1, fp2);
8991 tcg_temp_free_i64(fp0);
8992 tcg_temp_free_i64(fp1);
8993 gen_store_fpr64(ctx, fp2, fd);
8994 tcg_temp_free_i64(fp2);
8996 opn = "nmsub.ps";
8997 break;
8998 default:
8999 MIPS_INVAL(opn);
9000 generate_exception (ctx, EXCP_RI);
9001 return;
9003 (void)opn; /* avoid a compiler warning */
9004 MIPS_DEBUG("%s %s, %s, %s, %s", opn, fregnames[fd], fregnames[fr],
9005 fregnames[fs], fregnames[ft]);
9008 static void gen_rdhwr(DisasContext *ctx, int rt, int rd)
9010 TCGv t0;
9012 #if !defined(CONFIG_USER_ONLY)
9013 /* The Linux kernel will emulate rdhwr if it's not supported natively.
9014 Therefore only check the ISA in system mode. */
9015 check_insn(ctx, ISA_MIPS32R2);
9016 #endif
9017 t0 = tcg_temp_new();
9019 switch (rd) {
9020 case 0:
9021 save_cpu_state(ctx, 1);
9022 gen_helper_rdhwr_cpunum(t0, cpu_env);
9023 gen_store_gpr(t0, rt);
9024 break;
9025 case 1:
9026 save_cpu_state(ctx, 1);
9027 gen_helper_rdhwr_synci_step(t0, cpu_env);
9028 gen_store_gpr(t0, rt);
9029 break;
9030 case 2:
9031 save_cpu_state(ctx, 1);
9032 gen_helper_rdhwr_cc(t0, cpu_env);
9033 gen_store_gpr(t0, rt);
9034 break;
9035 case 3:
9036 save_cpu_state(ctx, 1);
9037 gen_helper_rdhwr_ccres(t0, cpu_env);
9038 gen_store_gpr(t0, rt);
9039 break;
9040 case 29:
9041 #if defined(CONFIG_USER_ONLY)
9042 tcg_gen_ld_tl(t0, cpu_env, offsetof(CPUMIPSState, tls_value));
9043 gen_store_gpr(t0, rt);
9044 break;
9045 #else
9046 /* XXX: Some CPUs implement this in hardware.
9047 Not supported yet. */
9048 #endif
9049 default: /* Invalid */
9050 MIPS_INVAL("rdhwr");
9051 generate_exception(ctx, EXCP_RI);
9052 break;
9054 tcg_temp_free(t0);
9057 static void handle_delay_slot(DisasContext *ctx, int insn_bytes)
9059 if (ctx->hflags & MIPS_HFLAG_BMASK) {
9060 int proc_hflags = ctx->hflags & MIPS_HFLAG_BMASK;
9061 /* Branches completion */
9062 ctx->hflags &= ~MIPS_HFLAG_BMASK;
9063 ctx->bstate = BS_BRANCH;
9064 save_cpu_state(ctx, 0);
9065 /* FIXME: Need to clear can_do_io. */
9066 switch (proc_hflags & MIPS_HFLAG_BMASK_BASE) {
9067 case MIPS_HFLAG_B:
9068 /* unconditional branch */
9069 MIPS_DEBUG("unconditional branch");
9070 if (proc_hflags & MIPS_HFLAG_BX) {
9071 tcg_gen_xori_i32(hflags, hflags, MIPS_HFLAG_M16);
9073 gen_goto_tb(ctx, 0, ctx->btarget);
9074 break;
9075 case MIPS_HFLAG_BL:
9076 /* blikely taken case */
9077 MIPS_DEBUG("blikely branch taken");
9078 gen_goto_tb(ctx, 0, ctx->btarget);
9079 break;
9080 case MIPS_HFLAG_BC:
9081 /* Conditional branch */
9082 MIPS_DEBUG("conditional branch");
9084 int l1 = gen_new_label();
9086 tcg_gen_brcondi_tl(TCG_COND_NE, bcond, 0, l1);
9087 gen_goto_tb(ctx, 1, ctx->pc + insn_bytes);
9088 gen_set_label(l1);
9089 gen_goto_tb(ctx, 0, ctx->btarget);
9091 break;
9092 case MIPS_HFLAG_BR:
9093 /* unconditional branch to register */
9094 MIPS_DEBUG("branch to register");
9095 if (ctx->insn_flags & (ASE_MIPS16 | ASE_MICROMIPS)) {
9096 TCGv t0 = tcg_temp_new();
9097 TCGv_i32 t1 = tcg_temp_new_i32();
9099 tcg_gen_andi_tl(t0, btarget, 0x1);
9100 tcg_gen_trunc_tl_i32(t1, t0);
9101 tcg_temp_free(t0);
9102 tcg_gen_andi_i32(hflags, hflags, ~(uint32_t)MIPS_HFLAG_M16);
9103 tcg_gen_shli_i32(t1, t1, MIPS_HFLAG_M16_SHIFT);
9104 tcg_gen_or_i32(hflags, hflags, t1);
9105 tcg_temp_free_i32(t1);
9107 tcg_gen_andi_tl(cpu_PC, btarget, ~(target_ulong)0x1);
9108 } else {
9109 tcg_gen_mov_tl(cpu_PC, btarget);
9111 if (ctx->singlestep_enabled) {
9112 save_cpu_state(ctx, 0);
9113 gen_helper_0e0i(raise_exception, EXCP_DEBUG);
9115 tcg_gen_exit_tb(0);
9116 break;
9117 default:
9118 MIPS_DEBUG("unknown branch");
9119 break;
9124 /* ISA extensions (ASEs) */
9125 /* MIPS16 extension to MIPS32 */
9127 /* MIPS16 major opcodes */
9128 enum {
9129 M16_OPC_ADDIUSP = 0x00,
9130 M16_OPC_ADDIUPC = 0x01,
9131 M16_OPC_B = 0x02,
9132 M16_OPC_JAL = 0x03,
9133 M16_OPC_BEQZ = 0x04,
9134 M16_OPC_BNEQZ = 0x05,
9135 M16_OPC_SHIFT = 0x06,
9136 M16_OPC_LD = 0x07,
9137 M16_OPC_RRIA = 0x08,
9138 M16_OPC_ADDIU8 = 0x09,
9139 M16_OPC_SLTI = 0x0a,
9140 M16_OPC_SLTIU = 0x0b,
9141 M16_OPC_I8 = 0x0c,
9142 M16_OPC_LI = 0x0d,
9143 M16_OPC_CMPI = 0x0e,
9144 M16_OPC_SD = 0x0f,
9145 M16_OPC_LB = 0x10,
9146 M16_OPC_LH = 0x11,
9147 M16_OPC_LWSP = 0x12,
9148 M16_OPC_LW = 0x13,
9149 M16_OPC_LBU = 0x14,
9150 M16_OPC_LHU = 0x15,
9151 M16_OPC_LWPC = 0x16,
9152 M16_OPC_LWU = 0x17,
9153 M16_OPC_SB = 0x18,
9154 M16_OPC_SH = 0x19,
9155 M16_OPC_SWSP = 0x1a,
9156 M16_OPC_SW = 0x1b,
9157 M16_OPC_RRR = 0x1c,
9158 M16_OPC_RR = 0x1d,
9159 M16_OPC_EXTEND = 0x1e,
9160 M16_OPC_I64 = 0x1f
9163 /* I8 funct field */
9164 enum {
9165 I8_BTEQZ = 0x0,
9166 I8_BTNEZ = 0x1,
9167 I8_SWRASP = 0x2,
9168 I8_ADJSP = 0x3,
9169 I8_SVRS = 0x4,
9170 I8_MOV32R = 0x5,
9171 I8_MOVR32 = 0x7
9174 /* RRR f field */
9175 enum {
9176 RRR_DADDU = 0x0,
9177 RRR_ADDU = 0x1,
9178 RRR_DSUBU = 0x2,
9179 RRR_SUBU = 0x3
9182 /* RR funct field */
9183 enum {
9184 RR_JR = 0x00,
9185 RR_SDBBP = 0x01,
9186 RR_SLT = 0x02,
9187 RR_SLTU = 0x03,
9188 RR_SLLV = 0x04,
9189 RR_BREAK = 0x05,
9190 RR_SRLV = 0x06,
9191 RR_SRAV = 0x07,
9192 RR_DSRL = 0x08,
9193 RR_CMP = 0x0a,
9194 RR_NEG = 0x0b,
9195 RR_AND = 0x0c,
9196 RR_OR = 0x0d,
9197 RR_XOR = 0x0e,
9198 RR_NOT = 0x0f,
9199 RR_MFHI = 0x10,
9200 RR_CNVT = 0x11,
9201 RR_MFLO = 0x12,
9202 RR_DSRA = 0x13,
9203 RR_DSLLV = 0x14,
9204 RR_DSRLV = 0x16,
9205 RR_DSRAV = 0x17,
9206 RR_MULT = 0x18,
9207 RR_MULTU = 0x19,
9208 RR_DIV = 0x1a,
9209 RR_DIVU = 0x1b,
9210 RR_DMULT = 0x1c,
9211 RR_DMULTU = 0x1d,
9212 RR_DDIV = 0x1e,
9213 RR_DDIVU = 0x1f
9216 /* I64 funct field */
9217 enum {
9218 I64_LDSP = 0x0,
9219 I64_SDSP = 0x1,
9220 I64_SDRASP = 0x2,
9221 I64_DADJSP = 0x3,
9222 I64_LDPC = 0x4,
9223 I64_DADDIU5 = 0x5,
9224 I64_DADDIUPC = 0x6,
9225 I64_DADDIUSP = 0x7
9228 /* RR ry field for CNVT */
9229 enum {
9230 RR_RY_CNVT_ZEB = 0x0,
9231 RR_RY_CNVT_ZEH = 0x1,
9232 RR_RY_CNVT_ZEW = 0x2,
9233 RR_RY_CNVT_SEB = 0x4,
9234 RR_RY_CNVT_SEH = 0x5,
9235 RR_RY_CNVT_SEW = 0x6,
9238 static int xlat (int r)
9240 static int map[] = { 16, 17, 2, 3, 4, 5, 6, 7 };
9242 return map[r];
9245 static void gen_mips16_save (DisasContext *ctx,
9246 int xsregs, int aregs,
9247 int do_ra, int do_s0, int do_s1,
9248 int framesize)
9250 TCGv t0 = tcg_temp_new();
9251 TCGv t1 = tcg_temp_new();
9252 int args, astatic;
9254 switch (aregs) {
9255 case 0:
9256 case 1:
9257 case 2:
9258 case 3:
9259 case 11:
9260 args = 0;
9261 break;
9262 case 4:
9263 case 5:
9264 case 6:
9265 case 7:
9266 args = 1;
9267 break;
9268 case 8:
9269 case 9:
9270 case 10:
9271 args = 2;
9272 break;
9273 case 12:
9274 case 13:
9275 args = 3;
9276 break;
9277 case 14:
9278 args = 4;
9279 break;
9280 default:
9281 generate_exception(ctx, EXCP_RI);
9282 return;
9285 switch (args) {
9286 case 4:
9287 gen_base_offset_addr(ctx, t0, 29, 12);
9288 gen_load_gpr(t1, 7);
9289 tcg_gen_qemu_st32(t1, t0, ctx->mem_idx);
9290 /* Fall through */
9291 case 3:
9292 gen_base_offset_addr(ctx, t0, 29, 8);
9293 gen_load_gpr(t1, 6);
9294 tcg_gen_qemu_st32(t1, t0, ctx->mem_idx);
9295 /* Fall through */
9296 case 2:
9297 gen_base_offset_addr(ctx, t0, 29, 4);
9298 gen_load_gpr(t1, 5);
9299 tcg_gen_qemu_st32(t1, t0, ctx->mem_idx);
9300 /* Fall through */
9301 case 1:
9302 gen_base_offset_addr(ctx, t0, 29, 0);
9303 gen_load_gpr(t1, 4);
9304 tcg_gen_qemu_st32(t1, t0, ctx->mem_idx);
9307 gen_load_gpr(t0, 29);
9309 #define DECR_AND_STORE(reg) do { \
9310 tcg_gen_subi_tl(t0, t0, 4); \
9311 gen_load_gpr(t1, reg); \
9312 tcg_gen_qemu_st32(t1, t0, ctx->mem_idx); \
9313 } while (0)
9315 if (do_ra) {
9316 DECR_AND_STORE(31);
9319 switch (xsregs) {
9320 case 7:
9321 DECR_AND_STORE(30);
9322 /* Fall through */
9323 case 6:
9324 DECR_AND_STORE(23);
9325 /* Fall through */
9326 case 5:
9327 DECR_AND_STORE(22);
9328 /* Fall through */
9329 case 4:
9330 DECR_AND_STORE(21);
9331 /* Fall through */
9332 case 3:
9333 DECR_AND_STORE(20);
9334 /* Fall through */
9335 case 2:
9336 DECR_AND_STORE(19);
9337 /* Fall through */
9338 case 1:
9339 DECR_AND_STORE(18);
9342 if (do_s1) {
9343 DECR_AND_STORE(17);
9345 if (do_s0) {
9346 DECR_AND_STORE(16);
9349 switch (aregs) {
9350 case 0:
9351 case 4:
9352 case 8:
9353 case 12:
9354 case 14:
9355 astatic = 0;
9356 break;
9357 case 1:
9358 case 5:
9359 case 9:
9360 case 13:
9361 astatic = 1;
9362 break;
9363 case 2:
9364 case 6:
9365 case 10:
9366 astatic = 2;
9367 break;
9368 case 3:
9369 case 7:
9370 astatic = 3;
9371 break;
9372 case 11:
9373 astatic = 4;
9374 break;
9375 default:
9376 generate_exception(ctx, EXCP_RI);
9377 return;
9380 if (astatic > 0) {
9381 DECR_AND_STORE(7);
9382 if (astatic > 1) {
9383 DECR_AND_STORE(6);
9384 if (astatic > 2) {
9385 DECR_AND_STORE(5);
9386 if (astatic > 3) {
9387 DECR_AND_STORE(4);
9392 #undef DECR_AND_STORE
9394 tcg_gen_subi_tl(cpu_gpr[29], cpu_gpr[29], framesize);
9395 tcg_temp_free(t0);
9396 tcg_temp_free(t1);
9399 static void gen_mips16_restore (DisasContext *ctx,
9400 int xsregs, int aregs,
9401 int do_ra, int do_s0, int do_s1,
9402 int framesize)
9404 int astatic;
9405 TCGv t0 = tcg_temp_new();
9406 TCGv t1 = tcg_temp_new();
9408 tcg_gen_addi_tl(t0, cpu_gpr[29], framesize);
9410 #define DECR_AND_LOAD(reg) do { \
9411 tcg_gen_subi_tl(t0, t0, 4); \
9412 tcg_gen_qemu_ld32s(t1, t0, ctx->mem_idx); \
9413 gen_store_gpr(t1, reg); \
9414 } while (0)
9416 if (do_ra) {
9417 DECR_AND_LOAD(31);
9420 switch (xsregs) {
9421 case 7:
9422 DECR_AND_LOAD(30);
9423 /* Fall through */
9424 case 6:
9425 DECR_AND_LOAD(23);
9426 /* Fall through */
9427 case 5:
9428 DECR_AND_LOAD(22);
9429 /* Fall through */
9430 case 4:
9431 DECR_AND_LOAD(21);
9432 /* Fall through */
9433 case 3:
9434 DECR_AND_LOAD(20);
9435 /* Fall through */
9436 case 2:
9437 DECR_AND_LOAD(19);
9438 /* Fall through */
9439 case 1:
9440 DECR_AND_LOAD(18);
9443 if (do_s1) {
9444 DECR_AND_LOAD(17);
9446 if (do_s0) {
9447 DECR_AND_LOAD(16);
9450 switch (aregs) {
9451 case 0:
9452 case 4:
9453 case 8:
9454 case 12:
9455 case 14:
9456 astatic = 0;
9457 break;
9458 case 1:
9459 case 5:
9460 case 9:
9461 case 13:
9462 astatic = 1;
9463 break;
9464 case 2:
9465 case 6:
9466 case 10:
9467 astatic = 2;
9468 break;
9469 case 3:
9470 case 7:
9471 astatic = 3;
9472 break;
9473 case 11:
9474 astatic = 4;
9475 break;
9476 default:
9477 generate_exception(ctx, EXCP_RI);
9478 return;
9481 if (astatic > 0) {
9482 DECR_AND_LOAD(7);
9483 if (astatic > 1) {
9484 DECR_AND_LOAD(6);
9485 if (astatic > 2) {
9486 DECR_AND_LOAD(5);
9487 if (astatic > 3) {
9488 DECR_AND_LOAD(4);
9493 #undef DECR_AND_LOAD
9495 tcg_gen_addi_tl(cpu_gpr[29], cpu_gpr[29], framesize);
9496 tcg_temp_free(t0);
9497 tcg_temp_free(t1);
9500 static void gen_addiupc (DisasContext *ctx, int rx, int imm,
9501 int is_64_bit, int extended)
9503 TCGv t0;
9505 if (extended && (ctx->hflags & MIPS_HFLAG_BMASK)) {
9506 generate_exception(ctx, EXCP_RI);
9507 return;
9510 t0 = tcg_temp_new();
9512 tcg_gen_movi_tl(t0, pc_relative_pc(ctx));
9513 tcg_gen_addi_tl(cpu_gpr[rx], t0, imm);
9514 if (!is_64_bit) {
9515 tcg_gen_ext32s_tl(cpu_gpr[rx], cpu_gpr[rx]);
9518 tcg_temp_free(t0);
9521 #if defined(TARGET_MIPS64)
9522 static void decode_i64_mips16 (DisasContext *ctx,
9523 int ry, int funct, int16_t offset,
9524 int extended)
9526 switch (funct) {
9527 case I64_LDSP:
9528 check_mips_64(ctx);
9529 offset = extended ? offset : offset << 3;
9530 gen_ld(ctx, OPC_LD, ry, 29, offset);
9531 break;
9532 case I64_SDSP:
9533 check_mips_64(ctx);
9534 offset = extended ? offset : offset << 3;
9535 gen_st(ctx, OPC_SD, ry, 29, offset);
9536 break;
9537 case I64_SDRASP:
9538 check_mips_64(ctx);
9539 offset = extended ? offset : (ctx->opcode & 0xff) << 3;
9540 gen_st(ctx, OPC_SD, 31, 29, offset);
9541 break;
9542 case I64_DADJSP:
9543 check_mips_64(ctx);
9544 offset = extended ? offset : ((int8_t)ctx->opcode) << 3;
9545 gen_arith_imm(ctx, OPC_DADDIU, 29, 29, offset);
9546 break;
9547 case I64_LDPC:
9548 if (extended && (ctx->hflags & MIPS_HFLAG_BMASK)) {
9549 generate_exception(ctx, EXCP_RI);
9550 } else {
9551 offset = extended ? offset : offset << 3;
9552 gen_ld(ctx, OPC_LDPC, ry, 0, offset);
9554 break;
9555 case I64_DADDIU5:
9556 check_mips_64(ctx);
9557 offset = extended ? offset : ((int8_t)(offset << 3)) >> 3;
9558 gen_arith_imm(ctx, OPC_DADDIU, ry, ry, offset);
9559 break;
9560 case I64_DADDIUPC:
9561 check_mips_64(ctx);
9562 offset = extended ? offset : offset << 2;
9563 gen_addiupc(ctx, ry, offset, 1, extended);
9564 break;
9565 case I64_DADDIUSP:
9566 check_mips_64(ctx);
9567 offset = extended ? offset : offset << 2;
9568 gen_arith_imm(ctx, OPC_DADDIU, ry, 29, offset);
9569 break;
9572 #endif
9574 static int decode_extended_mips16_opc (CPUMIPSState *env, DisasContext *ctx)
9576 int extend = cpu_lduw_code(env, ctx->pc + 2);
9577 int op, rx, ry, funct, sa;
9578 int16_t imm, offset;
9580 ctx->opcode = (ctx->opcode << 16) | extend;
9581 op = (ctx->opcode >> 11) & 0x1f;
9582 sa = (ctx->opcode >> 22) & 0x1f;
9583 funct = (ctx->opcode >> 8) & 0x7;
9584 rx = xlat((ctx->opcode >> 8) & 0x7);
9585 ry = xlat((ctx->opcode >> 5) & 0x7);
9586 offset = imm = (int16_t) (((ctx->opcode >> 16) & 0x1f) << 11
9587 | ((ctx->opcode >> 21) & 0x3f) << 5
9588 | (ctx->opcode & 0x1f));
9590 /* The extended opcodes cleverly reuse the opcodes from their 16-bit
9591 counterparts. */
9592 switch (op) {
9593 case M16_OPC_ADDIUSP:
9594 gen_arith_imm(ctx, OPC_ADDIU, rx, 29, imm);
9595 break;
9596 case M16_OPC_ADDIUPC:
9597 gen_addiupc(ctx, rx, imm, 0, 1);
9598 break;
9599 case M16_OPC_B:
9600 gen_compute_branch(ctx, OPC_BEQ, 4, 0, 0, offset << 1);
9601 /* No delay slot, so just process as a normal instruction */
9602 break;
9603 case M16_OPC_BEQZ:
9604 gen_compute_branch(ctx, OPC_BEQ, 4, rx, 0, offset << 1);
9605 /* No delay slot, so just process as a normal instruction */
9606 break;
9607 case M16_OPC_BNEQZ:
9608 gen_compute_branch(ctx, OPC_BNE, 4, rx, 0, offset << 1);
9609 /* No delay slot, so just process as a normal instruction */
9610 break;
9611 case M16_OPC_SHIFT:
9612 switch (ctx->opcode & 0x3) {
9613 case 0x0:
9614 gen_shift_imm(ctx, OPC_SLL, rx, ry, sa);
9615 break;
9616 case 0x1:
9617 #if defined(TARGET_MIPS64)
9618 check_mips_64(ctx);
9619 gen_shift_imm(ctx, OPC_DSLL, rx, ry, sa);
9620 #else
9621 generate_exception(ctx, EXCP_RI);
9622 #endif
9623 break;
9624 case 0x2:
9625 gen_shift_imm(ctx, OPC_SRL, rx, ry, sa);
9626 break;
9627 case 0x3:
9628 gen_shift_imm(ctx, OPC_SRA, rx, ry, sa);
9629 break;
9631 break;
9632 #if defined(TARGET_MIPS64)
9633 case M16_OPC_LD:
9634 check_mips_64(ctx);
9635 gen_ld(ctx, OPC_LD, ry, rx, offset);
9636 break;
9637 #endif
9638 case M16_OPC_RRIA:
9639 imm = ctx->opcode & 0xf;
9640 imm = imm | ((ctx->opcode >> 20) & 0x7f) << 4;
9641 imm = imm | ((ctx->opcode >> 16) & 0xf) << 11;
9642 imm = (int16_t) (imm << 1) >> 1;
9643 if ((ctx->opcode >> 4) & 0x1) {
9644 #if defined(TARGET_MIPS64)
9645 check_mips_64(ctx);
9646 gen_arith_imm(ctx, OPC_DADDIU, ry, rx, imm);
9647 #else
9648 generate_exception(ctx, EXCP_RI);
9649 #endif
9650 } else {
9651 gen_arith_imm(ctx, OPC_ADDIU, ry, rx, imm);
9653 break;
9654 case M16_OPC_ADDIU8:
9655 gen_arith_imm(ctx, OPC_ADDIU, rx, rx, imm);
9656 break;
9657 case M16_OPC_SLTI:
9658 gen_slt_imm(ctx, OPC_SLTI, 24, rx, imm);
9659 break;
9660 case M16_OPC_SLTIU:
9661 gen_slt_imm(ctx, OPC_SLTIU, 24, rx, imm);
9662 break;
9663 case M16_OPC_I8:
9664 switch (funct) {
9665 case I8_BTEQZ:
9666 gen_compute_branch(ctx, OPC_BEQ, 4, 24, 0, offset << 1);
9667 break;
9668 case I8_BTNEZ:
9669 gen_compute_branch(ctx, OPC_BNE, 4, 24, 0, offset << 1);
9670 break;
9671 case I8_SWRASP:
9672 gen_st(ctx, OPC_SW, 31, 29, imm);
9673 break;
9674 case I8_ADJSP:
9675 gen_arith_imm(ctx, OPC_ADDIU, 29, 29, imm);
9676 break;
9677 case I8_SVRS:
9679 int xsregs = (ctx->opcode >> 24) & 0x7;
9680 int aregs = (ctx->opcode >> 16) & 0xf;
9681 int do_ra = (ctx->opcode >> 6) & 0x1;
9682 int do_s0 = (ctx->opcode >> 5) & 0x1;
9683 int do_s1 = (ctx->opcode >> 4) & 0x1;
9684 int framesize = (((ctx->opcode >> 20) & 0xf) << 4
9685 | (ctx->opcode & 0xf)) << 3;
9687 if (ctx->opcode & (1 << 7)) {
9688 gen_mips16_save(ctx, xsregs, aregs,
9689 do_ra, do_s0, do_s1,
9690 framesize);
9691 } else {
9692 gen_mips16_restore(ctx, xsregs, aregs,
9693 do_ra, do_s0, do_s1,
9694 framesize);
9697 break;
9698 default:
9699 generate_exception(ctx, EXCP_RI);
9700 break;
9702 break;
9703 case M16_OPC_LI:
9704 tcg_gen_movi_tl(cpu_gpr[rx], (uint16_t) imm);
9705 break;
9706 case M16_OPC_CMPI:
9707 tcg_gen_xori_tl(cpu_gpr[24], cpu_gpr[rx], (uint16_t) imm);
9708 break;
9709 #if defined(TARGET_MIPS64)
9710 case M16_OPC_SD:
9711 gen_st(ctx, OPC_SD, ry, rx, offset);
9712 break;
9713 #endif
9714 case M16_OPC_LB:
9715 gen_ld(ctx, OPC_LB, ry, rx, offset);
9716 break;
9717 case M16_OPC_LH:
9718 gen_ld(ctx, OPC_LH, ry, rx, offset);
9719 break;
9720 case M16_OPC_LWSP:
9721 gen_ld(ctx, OPC_LW, rx, 29, offset);
9722 break;
9723 case M16_OPC_LW:
9724 gen_ld(ctx, OPC_LW, ry, rx, offset);
9725 break;
9726 case M16_OPC_LBU:
9727 gen_ld(ctx, OPC_LBU, ry, rx, offset);
9728 break;
9729 case M16_OPC_LHU:
9730 gen_ld(ctx, OPC_LHU, ry, rx, offset);
9731 break;
9732 case M16_OPC_LWPC:
9733 gen_ld(ctx, OPC_LWPC, rx, 0, offset);
9734 break;
9735 #if defined(TARGET_MIPS64)
9736 case M16_OPC_LWU:
9737 gen_ld(ctx, OPC_LWU, ry, rx, offset);
9738 break;
9739 #endif
9740 case M16_OPC_SB:
9741 gen_st(ctx, OPC_SB, ry, rx, offset);
9742 break;
9743 case M16_OPC_SH:
9744 gen_st(ctx, OPC_SH, ry, rx, offset);
9745 break;
9746 case M16_OPC_SWSP:
9747 gen_st(ctx, OPC_SW, rx, 29, offset);
9748 break;
9749 case M16_OPC_SW:
9750 gen_st(ctx, OPC_SW, ry, rx, offset);
9751 break;
9752 #if defined(TARGET_MIPS64)
9753 case M16_OPC_I64:
9754 decode_i64_mips16(ctx, ry, funct, offset, 1);
9755 break;
9756 #endif
9757 default:
9758 generate_exception(ctx, EXCP_RI);
9759 break;
9762 return 4;
9765 static int decode_mips16_opc (CPUMIPSState *env, DisasContext *ctx)
9767 int rx, ry;
9768 int sa;
9769 int op, cnvt_op, op1, offset;
9770 int funct;
9771 int n_bytes;
9773 op = (ctx->opcode >> 11) & 0x1f;
9774 sa = (ctx->opcode >> 2) & 0x7;
9775 sa = sa == 0 ? 8 : sa;
9776 rx = xlat((ctx->opcode >> 8) & 0x7);
9777 cnvt_op = (ctx->opcode >> 5) & 0x7;
9778 ry = xlat((ctx->opcode >> 5) & 0x7);
9779 op1 = offset = ctx->opcode & 0x1f;
9781 n_bytes = 2;
9783 switch (op) {
9784 case M16_OPC_ADDIUSP:
9786 int16_t imm = ((uint8_t) ctx->opcode) << 2;
9788 gen_arith_imm(ctx, OPC_ADDIU, rx, 29, imm);
9790 break;
9791 case M16_OPC_ADDIUPC:
9792 gen_addiupc(ctx, rx, ((uint8_t) ctx->opcode) << 2, 0, 0);
9793 break;
9794 case M16_OPC_B:
9795 offset = (ctx->opcode & 0x7ff) << 1;
9796 offset = (int16_t)(offset << 4) >> 4;
9797 gen_compute_branch(ctx, OPC_BEQ, 2, 0, 0, offset);
9798 /* No delay slot, so just process as a normal instruction */
9799 break;
9800 case M16_OPC_JAL:
9801 offset = cpu_lduw_code(env, ctx->pc + 2);
9802 offset = (((ctx->opcode & 0x1f) << 21)
9803 | ((ctx->opcode >> 5) & 0x1f) << 16
9804 | offset) << 2;
9805 op = ((ctx->opcode >> 10) & 0x1) ? OPC_JALXS : OPC_JALS;
9806 gen_compute_branch(ctx, op, 4, rx, ry, offset);
9807 n_bytes = 4;
9808 break;
9809 case M16_OPC_BEQZ:
9810 gen_compute_branch(ctx, OPC_BEQ, 2, rx, 0, ((int8_t)ctx->opcode) << 1);
9811 /* No delay slot, so just process as a normal instruction */
9812 break;
9813 case M16_OPC_BNEQZ:
9814 gen_compute_branch(ctx, OPC_BNE, 2, rx, 0, ((int8_t)ctx->opcode) << 1);
9815 /* No delay slot, so just process as a normal instruction */
9816 break;
9817 case M16_OPC_SHIFT:
9818 switch (ctx->opcode & 0x3) {
9819 case 0x0:
9820 gen_shift_imm(ctx, OPC_SLL, rx, ry, sa);
9821 break;
9822 case 0x1:
9823 #if defined(TARGET_MIPS64)
9824 check_mips_64(ctx);
9825 gen_shift_imm(ctx, OPC_DSLL, rx, ry, sa);
9826 #else
9827 generate_exception(ctx, EXCP_RI);
9828 #endif
9829 break;
9830 case 0x2:
9831 gen_shift_imm(ctx, OPC_SRL, rx, ry, sa);
9832 break;
9833 case 0x3:
9834 gen_shift_imm(ctx, OPC_SRA, rx, ry, sa);
9835 break;
9837 break;
9838 #if defined(TARGET_MIPS64)
9839 case M16_OPC_LD:
9840 check_mips_64(ctx);
9841 gen_ld(ctx, OPC_LD, ry, rx, offset << 3);
9842 break;
9843 #endif
9844 case M16_OPC_RRIA:
9846 int16_t imm = (int8_t)((ctx->opcode & 0xf) << 4) >> 4;
9848 if ((ctx->opcode >> 4) & 1) {
9849 #if defined(TARGET_MIPS64)
9850 check_mips_64(ctx);
9851 gen_arith_imm(ctx, OPC_DADDIU, ry, rx, imm);
9852 #else
9853 generate_exception(ctx, EXCP_RI);
9854 #endif
9855 } else {
9856 gen_arith_imm(ctx, OPC_ADDIU, ry, rx, imm);
9859 break;
9860 case M16_OPC_ADDIU8:
9862 int16_t imm = (int8_t) ctx->opcode;
9864 gen_arith_imm(ctx, OPC_ADDIU, rx, rx, imm);
9866 break;
9867 case M16_OPC_SLTI:
9869 int16_t imm = (uint8_t) ctx->opcode;
9870 gen_slt_imm(ctx, OPC_SLTI, 24, rx, imm);
9872 break;
9873 case M16_OPC_SLTIU:
9875 int16_t imm = (uint8_t) ctx->opcode;
9876 gen_slt_imm(ctx, OPC_SLTIU, 24, rx, imm);
9878 break;
9879 case M16_OPC_I8:
9881 int reg32;
9883 funct = (ctx->opcode >> 8) & 0x7;
9884 switch (funct) {
9885 case I8_BTEQZ:
9886 gen_compute_branch(ctx, OPC_BEQ, 2, 24, 0,
9887 ((int8_t)ctx->opcode) << 1);
9888 break;
9889 case I8_BTNEZ:
9890 gen_compute_branch(ctx, OPC_BNE, 2, 24, 0,
9891 ((int8_t)ctx->opcode) << 1);
9892 break;
9893 case I8_SWRASP:
9894 gen_st(ctx, OPC_SW, 31, 29, (ctx->opcode & 0xff) << 2);
9895 break;
9896 case I8_ADJSP:
9897 gen_arith_imm(ctx, OPC_ADDIU, 29, 29,
9898 ((int8_t)ctx->opcode) << 3);
9899 break;
9900 case I8_SVRS:
9902 int do_ra = ctx->opcode & (1 << 6);
9903 int do_s0 = ctx->opcode & (1 << 5);
9904 int do_s1 = ctx->opcode & (1 << 4);
9905 int framesize = ctx->opcode & 0xf;
9907 if (framesize == 0) {
9908 framesize = 128;
9909 } else {
9910 framesize = framesize << 3;
9913 if (ctx->opcode & (1 << 7)) {
9914 gen_mips16_save(ctx, 0, 0,
9915 do_ra, do_s0, do_s1, framesize);
9916 } else {
9917 gen_mips16_restore(ctx, 0, 0,
9918 do_ra, do_s0, do_s1, framesize);
9921 break;
9922 case I8_MOV32R:
9924 int rz = xlat(ctx->opcode & 0x7);
9926 reg32 = (((ctx->opcode >> 3) & 0x3) << 3) |
9927 ((ctx->opcode >> 5) & 0x7);
9928 gen_arith(ctx, OPC_ADDU, reg32, rz, 0);
9930 break;
9931 case I8_MOVR32:
9932 reg32 = ctx->opcode & 0x1f;
9933 gen_arith(ctx, OPC_ADDU, ry, reg32, 0);
9934 break;
9935 default:
9936 generate_exception(ctx, EXCP_RI);
9937 break;
9940 break;
9941 case M16_OPC_LI:
9943 int16_t imm = (uint8_t) ctx->opcode;
9945 gen_arith_imm(ctx, OPC_ADDIU, rx, 0, imm);
9947 break;
9948 case M16_OPC_CMPI:
9950 int16_t imm = (uint8_t) ctx->opcode;
9951 gen_logic_imm(ctx, OPC_XORI, 24, rx, imm);
9953 break;
9954 #if defined(TARGET_MIPS64)
9955 case M16_OPC_SD:
9956 check_mips_64(ctx);
9957 gen_st(ctx, OPC_SD, ry, rx, offset << 3);
9958 break;
9959 #endif
9960 case M16_OPC_LB:
9961 gen_ld(ctx, OPC_LB, ry, rx, offset);
9962 break;
9963 case M16_OPC_LH:
9964 gen_ld(ctx, OPC_LH, ry, rx, offset << 1);
9965 break;
9966 case M16_OPC_LWSP:
9967 gen_ld(ctx, OPC_LW, rx, 29, ((uint8_t)ctx->opcode) << 2);
9968 break;
9969 case M16_OPC_LW:
9970 gen_ld(ctx, OPC_LW, ry, rx, offset << 2);
9971 break;
9972 case M16_OPC_LBU:
9973 gen_ld(ctx, OPC_LBU, ry, rx, offset);
9974 break;
9975 case M16_OPC_LHU:
9976 gen_ld(ctx, OPC_LHU, ry, rx, offset << 1);
9977 break;
9978 case M16_OPC_LWPC:
9979 gen_ld(ctx, OPC_LWPC, rx, 0, ((uint8_t)ctx->opcode) << 2);
9980 break;
9981 #if defined (TARGET_MIPS64)
9982 case M16_OPC_LWU:
9983 check_mips_64(ctx);
9984 gen_ld(ctx, OPC_LWU, ry, rx, offset << 2);
9985 break;
9986 #endif
9987 case M16_OPC_SB:
9988 gen_st(ctx, OPC_SB, ry, rx, offset);
9989 break;
9990 case M16_OPC_SH:
9991 gen_st(ctx, OPC_SH, ry, rx, offset << 1);
9992 break;
9993 case M16_OPC_SWSP:
9994 gen_st(ctx, OPC_SW, rx, 29, ((uint8_t)ctx->opcode) << 2);
9995 break;
9996 case M16_OPC_SW:
9997 gen_st(ctx, OPC_SW, ry, rx, offset << 2);
9998 break;
9999 case M16_OPC_RRR:
10001 int rz = xlat((ctx->opcode >> 2) & 0x7);
10002 int mips32_op;
10004 switch (ctx->opcode & 0x3) {
10005 case RRR_ADDU:
10006 mips32_op = OPC_ADDU;
10007 break;
10008 case RRR_SUBU:
10009 mips32_op = OPC_SUBU;
10010 break;
10011 #if defined(TARGET_MIPS64)
10012 case RRR_DADDU:
10013 mips32_op = OPC_DADDU;
10014 check_mips_64(ctx);
10015 break;
10016 case RRR_DSUBU:
10017 mips32_op = OPC_DSUBU;
10018 check_mips_64(ctx);
10019 break;
10020 #endif
10021 default:
10022 generate_exception(ctx, EXCP_RI);
10023 goto done;
10026 gen_arith(ctx, mips32_op, rz, rx, ry);
10027 done:
10030 break;
10031 case M16_OPC_RR:
10032 switch (op1) {
10033 case RR_JR:
10035 int nd = (ctx->opcode >> 7) & 0x1;
10036 int link = (ctx->opcode >> 6) & 0x1;
10037 int ra = (ctx->opcode >> 5) & 0x1;
10039 if (link) {
10040 op = nd ? OPC_JALRC : OPC_JALRS;
10041 } else {
10042 op = OPC_JR;
10045 gen_compute_branch(ctx, op, 2, ra ? 31 : rx, 31, 0);
10047 break;
10048 case RR_SDBBP:
10049 /* XXX: not clear which exception should be raised
10050 * when in debug mode...
10052 check_insn(ctx, ISA_MIPS32);
10053 if (!(ctx->hflags & MIPS_HFLAG_DM)) {
10054 generate_exception(ctx, EXCP_DBp);
10055 } else {
10056 generate_exception(ctx, EXCP_DBp);
10058 break;
10059 case RR_SLT:
10060 gen_slt(ctx, OPC_SLT, 24, rx, ry);
10061 break;
10062 case RR_SLTU:
10063 gen_slt(ctx, OPC_SLTU, 24, rx, ry);
10064 break;
10065 case RR_BREAK:
10066 generate_exception(ctx, EXCP_BREAK);
10067 break;
10068 case RR_SLLV:
10069 gen_shift(ctx, OPC_SLLV, ry, rx, ry);
10070 break;
10071 case RR_SRLV:
10072 gen_shift(ctx, OPC_SRLV, ry, rx, ry);
10073 break;
10074 case RR_SRAV:
10075 gen_shift(ctx, OPC_SRAV, ry, rx, ry);
10076 break;
10077 #if defined (TARGET_MIPS64)
10078 case RR_DSRL:
10079 check_mips_64(ctx);
10080 gen_shift_imm(ctx, OPC_DSRL, ry, ry, sa);
10081 break;
10082 #endif
10083 case RR_CMP:
10084 gen_logic(ctx, OPC_XOR, 24, rx, ry);
10085 break;
10086 case RR_NEG:
10087 gen_arith(ctx, OPC_SUBU, rx, 0, ry);
10088 break;
10089 case RR_AND:
10090 gen_logic(ctx, OPC_AND, rx, rx, ry);
10091 break;
10092 case RR_OR:
10093 gen_logic(ctx, OPC_OR, rx, rx, ry);
10094 break;
10095 case RR_XOR:
10096 gen_logic(ctx, OPC_XOR, rx, rx, ry);
10097 break;
10098 case RR_NOT:
10099 gen_logic(ctx, OPC_NOR, rx, ry, 0);
10100 break;
10101 case RR_MFHI:
10102 gen_HILO(ctx, OPC_MFHI, 0, rx);
10103 break;
10104 case RR_CNVT:
10105 switch (cnvt_op) {
10106 case RR_RY_CNVT_ZEB:
10107 tcg_gen_ext8u_tl(cpu_gpr[rx], cpu_gpr[rx]);
10108 break;
10109 case RR_RY_CNVT_ZEH:
10110 tcg_gen_ext16u_tl(cpu_gpr[rx], cpu_gpr[rx]);
10111 break;
10112 case RR_RY_CNVT_SEB:
10113 tcg_gen_ext8s_tl(cpu_gpr[rx], cpu_gpr[rx]);
10114 break;
10115 case RR_RY_CNVT_SEH:
10116 tcg_gen_ext16s_tl(cpu_gpr[rx], cpu_gpr[rx]);
10117 break;
10118 #if defined (TARGET_MIPS64)
10119 case RR_RY_CNVT_ZEW:
10120 check_mips_64(ctx);
10121 tcg_gen_ext32u_tl(cpu_gpr[rx], cpu_gpr[rx]);
10122 break;
10123 case RR_RY_CNVT_SEW:
10124 check_mips_64(ctx);
10125 tcg_gen_ext32s_tl(cpu_gpr[rx], cpu_gpr[rx]);
10126 break;
10127 #endif
10128 default:
10129 generate_exception(ctx, EXCP_RI);
10130 break;
10132 break;
10133 case RR_MFLO:
10134 gen_HILO(ctx, OPC_MFLO, 0, rx);
10135 break;
10136 #if defined (TARGET_MIPS64)
10137 case RR_DSRA:
10138 check_mips_64(ctx);
10139 gen_shift_imm(ctx, OPC_DSRA, ry, ry, sa);
10140 break;
10141 case RR_DSLLV:
10142 check_mips_64(ctx);
10143 gen_shift(ctx, OPC_DSLLV, ry, rx, ry);
10144 break;
10145 case RR_DSRLV:
10146 check_mips_64(ctx);
10147 gen_shift(ctx, OPC_DSRLV, ry, rx, ry);
10148 break;
10149 case RR_DSRAV:
10150 check_mips_64(ctx);
10151 gen_shift(ctx, OPC_DSRAV, ry, rx, ry);
10152 break;
10153 #endif
10154 case RR_MULT:
10155 gen_muldiv(ctx, OPC_MULT, 0, rx, ry);
10156 break;
10157 case RR_MULTU:
10158 gen_muldiv(ctx, OPC_MULTU, 0, rx, ry);
10159 break;
10160 case RR_DIV:
10161 gen_muldiv(ctx, OPC_DIV, 0, rx, ry);
10162 break;
10163 case RR_DIVU:
10164 gen_muldiv(ctx, OPC_DIVU, 0, rx, ry);
10165 break;
10166 #if defined (TARGET_MIPS64)
10167 case RR_DMULT:
10168 check_mips_64(ctx);
10169 gen_muldiv(ctx, OPC_DMULT, 0, rx, ry);
10170 break;
10171 case RR_DMULTU:
10172 check_mips_64(ctx);
10173 gen_muldiv(ctx, OPC_DMULTU, 0, rx, ry);
10174 break;
10175 case RR_DDIV:
10176 check_mips_64(ctx);
10177 gen_muldiv(ctx, OPC_DDIV, 0, rx, ry);
10178 break;
10179 case RR_DDIVU:
10180 check_mips_64(ctx);
10181 gen_muldiv(ctx, OPC_DDIVU, 0, rx, ry);
10182 break;
10183 #endif
10184 default:
10185 generate_exception(ctx, EXCP_RI);
10186 break;
10188 break;
10189 case M16_OPC_EXTEND:
10190 decode_extended_mips16_opc(env, ctx);
10191 n_bytes = 4;
10192 break;
10193 #if defined(TARGET_MIPS64)
10194 case M16_OPC_I64:
10195 funct = (ctx->opcode >> 8) & 0x7;
10196 decode_i64_mips16(ctx, ry, funct, offset, 0);
10197 break;
10198 #endif
10199 default:
10200 generate_exception(ctx, EXCP_RI);
10201 break;
10204 return n_bytes;
10207 /* microMIPS extension to MIPS32/MIPS64 */
10210 * microMIPS32/microMIPS64 major opcodes
10212 * 1. MIPS Architecture for Programmers Volume II-B:
10213 * The microMIPS32 Instruction Set (Revision 3.05)
10215 * Table 6.2 microMIPS32 Encoding of Major Opcode Field
10217 * 2. MIPS Architecture For Programmers Volume II-A:
10218 * The MIPS64 Instruction Set (Revision 3.51)
10221 enum {
10222 POOL32A = 0x00,
10223 POOL16A = 0x01,
10224 LBU16 = 0x02,
10225 MOVE16 = 0x03,
10226 ADDI32 = 0x04,
10227 LBU32 = 0x05,
10228 SB32 = 0x06,
10229 LB32 = 0x07,
10231 POOL32B = 0x08,
10232 POOL16B = 0x09,
10233 LHU16 = 0x0a,
10234 ANDI16 = 0x0b,
10235 ADDIU32 = 0x0c,
10236 LHU32 = 0x0d,
10237 SH32 = 0x0e,
10238 LH32 = 0x0f,
10240 POOL32I = 0x10,
10241 POOL16C = 0x11,
10242 LWSP16 = 0x12,
10243 POOL16D = 0x13,
10244 ORI32 = 0x14,
10245 POOL32F = 0x15,
10246 POOL32S = 0x16, /* MIPS64 */
10247 DADDIU32 = 0x17, /* MIPS64 */
10249 /* 0x1f is reserved */
10250 POOL32C = 0x18,
10251 LWGP16 = 0x19,
10252 LW16 = 0x1a,
10253 POOL16E = 0x1b,
10254 XORI32 = 0x1c,
10255 JALS32 = 0x1d,
10256 ADDIUPC = 0x1e,
10258 /* 0x20 is reserved */
10259 RES_20 = 0x20,
10260 POOL16F = 0x21,
10261 SB16 = 0x22,
10262 BEQZ16 = 0x23,
10263 SLTI32 = 0x24,
10264 BEQ32 = 0x25,
10265 SWC132 = 0x26,
10266 LWC132 = 0x27,
10268 /* 0x28 and 0x29 are reserved */
10269 RES_28 = 0x28,
10270 RES_29 = 0x29,
10271 SH16 = 0x2a,
10272 BNEZ16 = 0x2b,
10273 SLTIU32 = 0x2c,
10274 BNE32 = 0x2d,
10275 SDC132 = 0x2e,
10276 LDC132 = 0x2f,
10278 /* 0x30 and 0x31 are reserved */
10279 RES_30 = 0x30,
10280 RES_31 = 0x31,
10281 SWSP16 = 0x32,
10282 B16 = 0x33,
10283 ANDI32 = 0x34,
10284 J32 = 0x35,
10285 SD32 = 0x36, /* MIPS64 */
10286 LD32 = 0x37, /* MIPS64 */
10288 /* 0x38 and 0x39 are reserved */
10289 RES_38 = 0x38,
10290 RES_39 = 0x39,
10291 SW16 = 0x3a,
10292 LI16 = 0x3b,
10293 JALX32 = 0x3c,
10294 JAL32 = 0x3d,
10295 SW32 = 0x3e,
10296 LW32 = 0x3f
10299 /* POOL32A encoding of minor opcode field */
10301 enum {
10302 /* These opcodes are distinguished only by bits 9..6; those bits are
10303 * what are recorded below. */
10304 SLL32 = 0x0,
10305 SRL32 = 0x1,
10306 SRA = 0x2,
10307 ROTR = 0x3,
10309 SLLV = 0x0,
10310 SRLV = 0x1,
10311 SRAV = 0x2,
10312 ROTRV = 0x3,
10313 ADD = 0x4,
10314 ADDU32 = 0x5,
10315 SUB = 0x6,
10316 SUBU32 = 0x7,
10317 MUL = 0x8,
10318 AND = 0x9,
10319 OR32 = 0xa,
10320 NOR = 0xb,
10321 XOR32 = 0xc,
10322 SLT = 0xd,
10323 SLTU = 0xe,
10325 MOVN = 0x0,
10326 MOVZ = 0x1,
10327 LWXS = 0x4,
10329 /* The following can be distinguished by their lower 6 bits. */
10330 INS = 0x0c,
10331 EXT = 0x2c,
10332 POOL32AXF = 0x3c
10335 /* POOL32AXF encoding of minor opcode field extension */
10338 * 1. MIPS Architecture for Programmers Volume II-B:
10339 * The microMIPS32 Instruction Set (Revision 3.05)
10341 * Table 6.5 POOL32Axf Encoding of Minor Opcode Extension Field
10343 * 2. MIPS Architecture for Programmers VolumeIV-e:
10344 * The MIPS DSP Application-Specific Extension
10345 * to the microMIPS32 Architecture (Revision 2.34)
10347 * Table 5.5 POOL32Axf Encoding of Minor Opcode Extension Field
10350 enum {
10351 /* bits 11..6 */
10352 TEQ = 0x00,
10353 TGE = 0x08,
10354 TGEU = 0x10,
10355 TLT = 0x20,
10356 TLTU = 0x28,
10357 TNE = 0x30,
10359 MFC0 = 0x03,
10360 MTC0 = 0x0b,
10362 /* begin of microMIPS32 DSP */
10364 /* bits 13..12 for 0x01 */
10365 MFHI_ACC = 0x0,
10366 MFLO_ACC = 0x1,
10367 MTHI_ACC = 0x2,
10368 MTLO_ACC = 0x3,
10370 /* bits 13..12 for 0x2a */
10371 MADD_ACC = 0x0,
10372 MADDU_ACC = 0x1,
10373 MSUB_ACC = 0x2,
10374 MSUBU_ACC = 0x3,
10376 /* bits 13..12 for 0x32 */
10377 MULT_ACC = 0x0,
10378 MULTU_ACC = 0x1,
10380 /* end of microMIPS32 DSP */
10382 /* bits 15..12 for 0x2c */
10383 SEB = 0x2,
10384 SEH = 0x3,
10385 CLO = 0x4,
10386 CLZ = 0x5,
10387 RDHWR = 0x6,
10388 WSBH = 0x7,
10389 MULT = 0x8,
10390 MULTU = 0x9,
10391 DIV = 0xa,
10392 DIVU = 0xb,
10393 MADD = 0xc,
10394 MADDU = 0xd,
10395 MSUB = 0xe,
10396 MSUBU = 0xf,
10398 /* bits 15..12 for 0x34 */
10399 MFC2 = 0x4,
10400 MTC2 = 0x5,
10401 MFHC2 = 0x8,
10402 MTHC2 = 0x9,
10403 CFC2 = 0xc,
10404 CTC2 = 0xd,
10406 /* bits 15..12 for 0x3c */
10407 JALR = 0x0,
10408 JR = 0x0, /* alias */
10409 JALR_HB = 0x1,
10410 JALRS = 0x4,
10411 JALRS_HB = 0x5,
10413 /* bits 15..12 for 0x05 */
10414 RDPGPR = 0xe,
10415 WRPGPR = 0xf,
10417 /* bits 15..12 for 0x0d */
10418 TLBP = 0x0,
10419 TLBR = 0x1,
10420 TLBWI = 0x2,
10421 TLBWR = 0x3,
10422 WAIT = 0x9,
10423 IRET = 0xd,
10424 DERET = 0xe,
10425 ERET = 0xf,
10427 /* bits 15..12 for 0x15 */
10428 DMT = 0x0,
10429 DVPE = 0x1,
10430 EMT = 0x2,
10431 EVPE = 0x3,
10433 /* bits 15..12 for 0x1d */
10434 DI = 0x4,
10435 EI = 0x5,
10437 /* bits 15..12 for 0x2d */
10438 SYNC = 0x6,
10439 SYSCALL = 0x8,
10440 SDBBP = 0xd,
10442 /* bits 15..12 for 0x35 */
10443 MFHI32 = 0x0,
10444 MFLO32 = 0x1,
10445 MTHI32 = 0x2,
10446 MTLO32 = 0x3,
10449 /* POOL32B encoding of minor opcode field (bits 15..12) */
10451 enum {
10452 LWC2 = 0x0,
10453 LWP = 0x1,
10454 LDP = 0x4,
10455 LWM32 = 0x5,
10456 CACHE = 0x6,
10457 LDM = 0x7,
10458 SWC2 = 0x8,
10459 SWP = 0x9,
10460 SDP = 0xc,
10461 SWM32 = 0xd,
10462 SDM = 0xf
10465 /* POOL32C encoding of minor opcode field (bits 15..12) */
10467 enum {
10468 LWL = 0x0,
10469 SWL = 0x8,
10470 LWR = 0x1,
10471 SWR = 0x9,
10472 PREF = 0x2,
10473 /* 0xa is reserved */
10474 LL = 0x3,
10475 SC = 0xb,
10476 LDL = 0x4,
10477 SDL = 0xc,
10478 LDR = 0x5,
10479 SDR = 0xd,
10480 /* 0x6 is reserved */
10481 LWU = 0xe,
10482 LLD = 0x7,
10483 SCD = 0xf
10486 /* POOL32F encoding of minor opcode field (bits 5..0) */
10488 enum {
10489 /* These are the bit 7..6 values */
10490 ADD_FMT = 0x0,
10491 MOVN_FMT = 0x0,
10493 SUB_FMT = 0x1,
10494 MOVZ_FMT = 0x1,
10496 MUL_FMT = 0x2,
10498 DIV_FMT = 0x3,
10500 /* These are the bit 8..6 values */
10501 RSQRT2_FMT = 0x0,
10502 MOVF_FMT = 0x0,
10504 LWXC1 = 0x1,
10505 MOVT_FMT = 0x1,
10507 PLL_PS = 0x2,
10508 SWXC1 = 0x2,
10510 PLU_PS = 0x3,
10511 LDXC1 = 0x3,
10513 PUL_PS = 0x4,
10514 SDXC1 = 0x4,
10515 RECIP2_FMT = 0x4,
10517 PUU_PS = 0x5,
10518 LUXC1 = 0x5,
10520 CVT_PS_S = 0x6,
10521 SUXC1 = 0x6,
10522 ADDR_PS = 0x6,
10523 PREFX = 0x6,
10525 MULR_PS = 0x7,
10527 MADD_S = 0x01,
10528 MADD_D = 0x09,
10529 MADD_PS = 0x11,
10530 ALNV_PS = 0x19,
10531 MSUB_S = 0x21,
10532 MSUB_D = 0x29,
10533 MSUB_PS = 0x31,
10535 NMADD_S = 0x02,
10536 NMADD_D = 0x0a,
10537 NMADD_PS = 0x12,
10538 NMSUB_S = 0x22,
10539 NMSUB_D = 0x2a,
10540 NMSUB_PS = 0x32,
10542 POOL32FXF = 0x3b,
10544 CABS_COND_FMT = 0x1c, /* MIPS3D */
10545 C_COND_FMT = 0x3c
10548 /* POOL32Fxf encoding of minor opcode extension field */
10550 enum {
10551 CVT_L = 0x04,
10552 RSQRT_FMT = 0x08,
10553 FLOOR_L = 0x0c,
10554 CVT_PW_PS = 0x1c,
10555 CVT_W = 0x24,
10556 SQRT_FMT = 0x28,
10557 FLOOR_W = 0x2c,
10558 CVT_PS_PW = 0x3c,
10559 CFC1 = 0x40,
10560 RECIP_FMT = 0x48,
10561 CEIL_L = 0x4c,
10562 CTC1 = 0x60,
10563 CEIL_W = 0x6c,
10564 MFC1 = 0x80,
10565 CVT_S_PL = 0x84,
10566 TRUNC_L = 0x8c,
10567 MTC1 = 0xa0,
10568 CVT_S_PU = 0xa4,
10569 TRUNC_W = 0xac,
10570 MFHC1 = 0xc0,
10571 ROUND_L = 0xcc,
10572 MTHC1 = 0xe0,
10573 ROUND_W = 0xec,
10575 MOV_FMT = 0x01,
10576 MOVF = 0x05,
10577 ABS_FMT = 0x0d,
10578 RSQRT1_FMT = 0x1d,
10579 MOVT = 0x25,
10580 NEG_FMT = 0x2d,
10581 CVT_D = 0x4d,
10582 RECIP1_FMT = 0x5d,
10583 CVT_S = 0x6d
10586 /* POOL32I encoding of minor opcode field (bits 25..21) */
10588 enum {
10589 BLTZ = 0x00,
10590 BLTZAL = 0x01,
10591 BGEZ = 0x02,
10592 BGEZAL = 0x03,
10593 BLEZ = 0x04,
10594 BNEZC = 0x05,
10595 BGTZ = 0x06,
10596 BEQZC = 0x07,
10597 TLTI = 0x08,
10598 TGEI = 0x09,
10599 TLTIU = 0x0a,
10600 TGEIU = 0x0b,
10601 TNEI = 0x0c,
10602 LUI = 0x0d,
10603 TEQI = 0x0e,
10604 SYNCI = 0x10,
10605 BLTZALS = 0x11,
10606 BGEZALS = 0x13,
10607 BC2F = 0x14,
10608 BC2T = 0x15,
10609 BPOSGE64 = 0x1a,
10610 BPOSGE32 = 0x1b,
10611 /* These overlap and are distinguished by bit16 of the instruction */
10612 BC1F = 0x1c,
10613 BC1T = 0x1d,
10614 BC1ANY2F = 0x1c,
10615 BC1ANY2T = 0x1d,
10616 BC1ANY4F = 0x1e,
10617 BC1ANY4T = 0x1f
10620 /* POOL16A encoding of minor opcode field */
10622 enum {
10623 ADDU16 = 0x0,
10624 SUBU16 = 0x1
10627 /* POOL16B encoding of minor opcode field */
10629 enum {
10630 SLL16 = 0x0,
10631 SRL16 = 0x1
10634 /* POOL16C encoding of minor opcode field */
10636 enum {
10637 NOT16 = 0x00,
10638 XOR16 = 0x04,
10639 AND16 = 0x08,
10640 OR16 = 0x0c,
10641 LWM16 = 0x10,
10642 SWM16 = 0x14,
10643 JR16 = 0x18,
10644 JRC16 = 0x1a,
10645 JALR16 = 0x1c,
10646 JALR16S = 0x1e,
10647 MFHI16 = 0x20,
10648 MFLO16 = 0x24,
10649 BREAK16 = 0x28,
10650 SDBBP16 = 0x2c,
10651 JRADDIUSP = 0x30
10654 /* POOL16D encoding of minor opcode field */
10656 enum {
10657 ADDIUS5 = 0x0,
10658 ADDIUSP = 0x1
10661 /* POOL16E encoding of minor opcode field */
10663 enum {
10664 ADDIUR2 = 0x0,
10665 ADDIUR1SP = 0x1
10668 static int mmreg (int r)
10670 static const int map[] = { 16, 17, 2, 3, 4, 5, 6, 7 };
10672 return map[r];
10675 /* Used for 16-bit store instructions. */
10676 static int mmreg2 (int r)
10678 static const int map[] = { 0, 17, 2, 3, 4, 5, 6, 7 };
10680 return map[r];
10683 #define uMIPS_RD(op) ((op >> 7) & 0x7)
10684 #define uMIPS_RS(op) ((op >> 4) & 0x7)
10685 #define uMIPS_RS2(op) uMIPS_RS(op)
10686 #define uMIPS_RS1(op) ((op >> 1) & 0x7)
10687 #define uMIPS_RD5(op) ((op >> 5) & 0x1f)
10688 #define uMIPS_RS5(op) (op & 0x1f)
10690 /* Signed immediate */
10691 #define SIMM(op, start, width) \
10692 ((int32_t)(((op >> start) & ((~0U) >> (32-width))) \
10693 << (32-width)) \
10694 >> (32-width))
10695 /* Zero-extended immediate */
10696 #define ZIMM(op, start, width) ((op >> start) & ((~0U) >> (32-width)))
10698 static void gen_addiur1sp(DisasContext *ctx)
10700 int rd = mmreg(uMIPS_RD(ctx->opcode));
10702 gen_arith_imm(ctx, OPC_ADDIU, rd, 29, ((ctx->opcode >> 1) & 0x3f) << 2);
10705 static void gen_addiur2(DisasContext *ctx)
10707 static const int decoded_imm[] = { 1, 4, 8, 12, 16, 20, 24, -1 };
10708 int rd = mmreg(uMIPS_RD(ctx->opcode));
10709 int rs = mmreg(uMIPS_RS(ctx->opcode));
10711 gen_arith_imm(ctx, OPC_ADDIU, rd, rs, decoded_imm[ZIMM(ctx->opcode, 1, 3)]);
10714 static void gen_addiusp(DisasContext *ctx)
10716 int encoded = ZIMM(ctx->opcode, 1, 9);
10717 int decoded;
10719 if (encoded <= 1) {
10720 decoded = 256 + encoded;
10721 } else if (encoded <= 255) {
10722 decoded = encoded;
10723 } else if (encoded <= 509) {
10724 decoded = encoded - 512;
10725 } else {
10726 decoded = encoded - 768;
10729 gen_arith_imm(ctx, OPC_ADDIU, 29, 29, decoded << 2);
10732 static void gen_addius5(DisasContext *ctx)
10734 int imm = SIMM(ctx->opcode, 1, 4);
10735 int rd = (ctx->opcode >> 5) & 0x1f;
10737 gen_arith_imm(ctx, OPC_ADDIU, rd, rd, imm);
10740 static void gen_andi16(DisasContext *ctx)
10742 static const int decoded_imm[] = { 128, 1, 2, 3, 4, 7, 8, 15, 16,
10743 31, 32, 63, 64, 255, 32768, 65535 };
10744 int rd = mmreg(uMIPS_RD(ctx->opcode));
10745 int rs = mmreg(uMIPS_RS(ctx->opcode));
10746 int encoded = ZIMM(ctx->opcode, 0, 4);
10748 gen_logic_imm(ctx, OPC_ANDI, rd, rs, decoded_imm[encoded]);
10751 static void gen_ldst_multiple (DisasContext *ctx, uint32_t opc, int reglist,
10752 int base, int16_t offset)
10754 const char *opn = "ldst_multiple";
10755 TCGv t0, t1;
10756 TCGv_i32 t2;
10758 if (ctx->hflags & MIPS_HFLAG_BMASK) {
10759 generate_exception(ctx, EXCP_RI);
10760 return;
10763 t0 = tcg_temp_new();
10765 gen_base_offset_addr(ctx, t0, base, offset);
10767 t1 = tcg_const_tl(reglist);
10768 t2 = tcg_const_i32(ctx->mem_idx);
10770 save_cpu_state(ctx, 1);
10771 switch (opc) {
10772 case LWM32:
10773 gen_helper_lwm(cpu_env, t0, t1, t2);
10774 opn = "lwm";
10775 break;
10776 case SWM32:
10777 gen_helper_swm(cpu_env, t0, t1, t2);
10778 opn = "swm";
10779 break;
10780 #ifdef TARGET_MIPS64
10781 case LDM:
10782 gen_helper_ldm(cpu_env, t0, t1, t2);
10783 opn = "ldm";
10784 break;
10785 case SDM:
10786 gen_helper_sdm(cpu_env, t0, t1, t2);
10787 opn = "sdm";
10788 break;
10789 #endif
10791 (void)opn;
10792 MIPS_DEBUG("%s, %x, %d(%s)", opn, reglist, offset, regnames[base]);
10793 tcg_temp_free(t0);
10794 tcg_temp_free(t1);
10795 tcg_temp_free_i32(t2);
10799 static void gen_pool16c_insn(DisasContext *ctx)
10801 int rd = mmreg((ctx->opcode >> 3) & 0x7);
10802 int rs = mmreg(ctx->opcode & 0x7);
10803 int opc;
10805 switch (((ctx->opcode) >> 4) & 0x3f) {
10806 case NOT16 + 0:
10807 case NOT16 + 1:
10808 case NOT16 + 2:
10809 case NOT16 + 3:
10810 gen_logic(ctx, OPC_NOR, rd, rs, 0);
10811 break;
10812 case XOR16 + 0:
10813 case XOR16 + 1:
10814 case XOR16 + 2:
10815 case XOR16 + 3:
10816 gen_logic(ctx, OPC_XOR, rd, rd, rs);
10817 break;
10818 case AND16 + 0:
10819 case AND16 + 1:
10820 case AND16 + 2:
10821 case AND16 + 3:
10822 gen_logic(ctx, OPC_AND, rd, rd, rs);
10823 break;
10824 case OR16 + 0:
10825 case OR16 + 1:
10826 case OR16 + 2:
10827 case OR16 + 3:
10828 gen_logic(ctx, OPC_OR, rd, rd, rs);
10829 break;
10830 case LWM16 + 0:
10831 case LWM16 + 1:
10832 case LWM16 + 2:
10833 case LWM16 + 3:
10835 static const int lwm_convert[] = { 0x11, 0x12, 0x13, 0x14 };
10836 int offset = ZIMM(ctx->opcode, 0, 4);
10838 gen_ldst_multiple(ctx, LWM32, lwm_convert[(ctx->opcode >> 4) & 0x3],
10839 29, offset << 2);
10841 break;
10842 case SWM16 + 0:
10843 case SWM16 + 1:
10844 case SWM16 + 2:
10845 case SWM16 + 3:
10847 static const int swm_convert[] = { 0x11, 0x12, 0x13, 0x14 };
10848 int offset = ZIMM(ctx->opcode, 0, 4);
10850 gen_ldst_multiple(ctx, SWM32, swm_convert[(ctx->opcode >> 4) & 0x3],
10851 29, offset << 2);
10853 break;
10854 case JR16 + 0:
10855 case JR16 + 1:
10857 int reg = ctx->opcode & 0x1f;
10859 gen_compute_branch(ctx, OPC_JR, 2, reg, 0, 0);
10861 break;
10862 case JRC16 + 0:
10863 case JRC16 + 1:
10865 int reg = ctx->opcode & 0x1f;
10867 gen_compute_branch(ctx, OPC_JR, 2, reg, 0, 0);
10868 /* Let normal delay slot handling in our caller take us
10869 to the branch target. */
10871 break;
10872 case JALR16 + 0:
10873 case JALR16 + 1:
10874 opc = OPC_JALR;
10875 goto do_jalr;
10876 case JALR16S + 0:
10877 case JALR16S + 1:
10878 opc = OPC_JALRS;
10879 do_jalr:
10881 int reg = ctx->opcode & 0x1f;
10883 gen_compute_branch(ctx, opc, 2, reg, 31, 0);
10885 break;
10886 case MFHI16 + 0:
10887 case MFHI16 + 1:
10888 gen_HILO(ctx, OPC_MFHI, 0, uMIPS_RS5(ctx->opcode));
10889 break;
10890 case MFLO16 + 0:
10891 case MFLO16 + 1:
10892 gen_HILO(ctx, OPC_MFLO, 0, uMIPS_RS5(ctx->opcode));
10893 break;
10894 case BREAK16:
10895 generate_exception(ctx, EXCP_BREAK);
10896 break;
10897 case SDBBP16:
10898 /* XXX: not clear which exception should be raised
10899 * when in debug mode...
10901 check_insn(ctx, ISA_MIPS32);
10902 if (!(ctx->hflags & MIPS_HFLAG_DM)) {
10903 generate_exception(ctx, EXCP_DBp);
10904 } else {
10905 generate_exception(ctx, EXCP_DBp);
10907 break;
10908 case JRADDIUSP + 0:
10909 case JRADDIUSP + 1:
10911 int imm = ZIMM(ctx->opcode, 0, 5);
10913 gen_compute_branch(ctx, OPC_JR, 2, 31, 0, 0);
10914 gen_arith_imm(ctx, OPC_ADDIU, 29, 29, imm << 2);
10915 /* Let normal delay slot handling in our caller take us
10916 to the branch target. */
10918 break;
10919 default:
10920 generate_exception(ctx, EXCP_RI);
10921 break;
10925 static void gen_ldxs (DisasContext *ctx, int base, int index, int rd)
10927 TCGv t0 = tcg_temp_new();
10928 TCGv t1 = tcg_temp_new();
10930 gen_load_gpr(t0, base);
10932 if (index != 0) {
10933 gen_load_gpr(t1, index);
10934 tcg_gen_shli_tl(t1, t1, 2);
10935 gen_op_addr_add(ctx, t0, t1, t0);
10938 tcg_gen_qemu_ld32s(t1, t0, ctx->mem_idx);
10939 gen_store_gpr(t1, rd);
10941 tcg_temp_free(t0);
10942 tcg_temp_free(t1);
10945 static void gen_ldst_pair (DisasContext *ctx, uint32_t opc, int rd,
10946 int base, int16_t offset)
10948 const char *opn = "ldst_pair";
10949 TCGv t0, t1;
10951 if (ctx->hflags & MIPS_HFLAG_BMASK || rd == 31) {
10952 generate_exception(ctx, EXCP_RI);
10953 return;
10956 t0 = tcg_temp_new();
10957 t1 = tcg_temp_new();
10959 gen_base_offset_addr(ctx, t0, base, offset);
10961 switch (opc) {
10962 case LWP:
10963 if (rd == base) {
10964 generate_exception(ctx, EXCP_RI);
10965 return;
10967 tcg_gen_qemu_ld32s(t1, t0, ctx->mem_idx);
10968 gen_store_gpr(t1, rd);
10969 tcg_gen_movi_tl(t1, 4);
10970 gen_op_addr_add(ctx, t0, t0, t1);
10971 tcg_gen_qemu_ld32s(t1, t0, ctx->mem_idx);
10972 gen_store_gpr(t1, rd+1);
10973 opn = "lwp";
10974 break;
10975 case SWP:
10976 gen_load_gpr(t1, rd);
10977 tcg_gen_qemu_st32(t1, t0, ctx->mem_idx);
10978 tcg_gen_movi_tl(t1, 4);
10979 gen_op_addr_add(ctx, t0, t0, t1);
10980 gen_load_gpr(t1, rd+1);
10981 tcg_gen_qemu_st32(t1, t0, ctx->mem_idx);
10982 opn = "swp";
10983 break;
10984 #ifdef TARGET_MIPS64
10985 case LDP:
10986 if (rd == base) {
10987 generate_exception(ctx, EXCP_RI);
10988 return;
10990 tcg_gen_qemu_ld64(t1, t0, ctx->mem_idx);
10991 gen_store_gpr(t1, rd);
10992 tcg_gen_movi_tl(t1, 8);
10993 gen_op_addr_add(ctx, t0, t0, t1);
10994 tcg_gen_qemu_ld64(t1, t0, ctx->mem_idx);
10995 gen_store_gpr(t1, rd+1);
10996 opn = "ldp";
10997 break;
10998 case SDP:
10999 gen_load_gpr(t1, rd);
11000 tcg_gen_qemu_st64(t1, t0, ctx->mem_idx);
11001 tcg_gen_movi_tl(t1, 8);
11002 gen_op_addr_add(ctx, t0, t0, t1);
11003 gen_load_gpr(t1, rd+1);
11004 tcg_gen_qemu_st64(t1, t0, ctx->mem_idx);
11005 opn = "sdp";
11006 break;
11007 #endif
11009 (void)opn; /* avoid a compiler warning */
11010 MIPS_DEBUG("%s, %s, %d(%s)", opn, regnames[rd], offset, regnames[base]);
11011 tcg_temp_free(t0);
11012 tcg_temp_free(t1);
11015 static void gen_pool32axf (CPUMIPSState *env, DisasContext *ctx, int rt, int rs)
11017 int extension = (ctx->opcode >> 6) & 0x3f;
11018 int minor = (ctx->opcode >> 12) & 0xf;
11019 uint32_t mips32_op;
11021 switch (extension) {
11022 case TEQ:
11023 mips32_op = OPC_TEQ;
11024 goto do_trap;
11025 case TGE:
11026 mips32_op = OPC_TGE;
11027 goto do_trap;
11028 case TGEU:
11029 mips32_op = OPC_TGEU;
11030 goto do_trap;
11031 case TLT:
11032 mips32_op = OPC_TLT;
11033 goto do_trap;
11034 case TLTU:
11035 mips32_op = OPC_TLTU;
11036 goto do_trap;
11037 case TNE:
11038 mips32_op = OPC_TNE;
11039 do_trap:
11040 gen_trap(ctx, mips32_op, rs, rt, -1);
11041 break;
11042 #ifndef CONFIG_USER_ONLY
11043 case MFC0:
11044 case MFC0 + 32:
11045 check_cp0_enabled(ctx);
11046 if (rt == 0) {
11047 /* Treat as NOP. */
11048 break;
11050 gen_mfc0(ctx, cpu_gpr[rt], rs, (ctx->opcode >> 11) & 0x7);
11051 break;
11052 case MTC0:
11053 case MTC0 + 32:
11054 check_cp0_enabled(ctx);
11056 TCGv t0 = tcg_temp_new();
11058 gen_load_gpr(t0, rt);
11059 gen_mtc0(ctx, t0, rs, (ctx->opcode >> 11) & 0x7);
11060 tcg_temp_free(t0);
11062 break;
11063 #endif
11064 case 0x2a:
11065 switch (minor & 3) {
11066 case MADD_ACC:
11067 gen_muldiv(ctx, OPC_MADD, (ctx->opcode >> 14) & 3, rs, rt);
11068 break;
11069 case MADDU_ACC:
11070 gen_muldiv(ctx, OPC_MADDU, (ctx->opcode >> 14) & 3, rs, rt);
11071 break;
11072 case MSUB_ACC:
11073 gen_muldiv(ctx, OPC_MSUB, (ctx->opcode >> 14) & 3, rs, rt);
11074 break;
11075 case MSUBU_ACC:
11076 gen_muldiv(ctx, OPC_MSUBU, (ctx->opcode >> 14) & 3, rs, rt);
11077 break;
11078 default:
11079 goto pool32axf_invalid;
11081 break;
11082 case 0x32:
11083 switch (minor & 3) {
11084 case MULT_ACC:
11085 gen_muldiv(ctx, OPC_MULT, (ctx->opcode >> 14) & 3, rs, rt);
11086 break;
11087 case MULTU_ACC:
11088 gen_muldiv(ctx, OPC_MULTU, (ctx->opcode >> 14) & 3, rs, rt);
11089 break;
11090 default:
11091 goto pool32axf_invalid;
11093 break;
11094 case 0x2c:
11095 switch (minor) {
11096 case SEB:
11097 gen_bshfl(ctx, OPC_SEB, rs, rt);
11098 break;
11099 case SEH:
11100 gen_bshfl(ctx, OPC_SEH, rs, rt);
11101 break;
11102 case CLO:
11103 mips32_op = OPC_CLO;
11104 goto do_cl;
11105 case CLZ:
11106 mips32_op = OPC_CLZ;
11107 do_cl:
11108 check_insn(ctx, ISA_MIPS32);
11109 gen_cl(ctx, mips32_op, rt, rs);
11110 break;
11111 case RDHWR:
11112 gen_rdhwr(ctx, rt, rs);
11113 break;
11114 case WSBH:
11115 gen_bshfl(ctx, OPC_WSBH, rs, rt);
11116 break;
11117 case MULT:
11118 mips32_op = OPC_MULT;
11119 goto do_mul;
11120 case MULTU:
11121 mips32_op = OPC_MULTU;
11122 goto do_mul;
11123 case DIV:
11124 mips32_op = OPC_DIV;
11125 goto do_div;
11126 case DIVU:
11127 mips32_op = OPC_DIVU;
11128 goto do_div;
11129 do_div:
11130 check_insn(ctx, ISA_MIPS32);
11131 gen_muldiv(ctx, mips32_op, 0, rs, rt);
11132 break;
11133 case MADD:
11134 mips32_op = OPC_MADD;
11135 goto do_mul;
11136 case MADDU:
11137 mips32_op = OPC_MADDU;
11138 goto do_mul;
11139 case MSUB:
11140 mips32_op = OPC_MSUB;
11141 goto do_mul;
11142 case MSUBU:
11143 mips32_op = OPC_MSUBU;
11144 do_mul:
11145 check_insn(ctx, ISA_MIPS32);
11146 gen_muldiv(ctx, mips32_op, 0, rs, rt);
11147 break;
11148 default:
11149 goto pool32axf_invalid;
11151 break;
11152 case 0x34:
11153 switch (minor) {
11154 case MFC2:
11155 case MTC2:
11156 case MFHC2:
11157 case MTHC2:
11158 case CFC2:
11159 case CTC2:
11160 generate_exception_err(ctx, EXCP_CpU, 2);
11161 break;
11162 default:
11163 goto pool32axf_invalid;
11165 break;
11166 case 0x3c:
11167 switch (minor) {
11168 case JALR:
11169 case JALR_HB:
11170 gen_compute_branch (ctx, OPC_JALR, 4, rs, rt, 0);
11171 break;
11172 case JALRS:
11173 case JALRS_HB:
11174 gen_compute_branch (ctx, OPC_JALRS, 4, rs, rt, 0);
11175 break;
11176 default:
11177 goto pool32axf_invalid;
11179 break;
11180 case 0x05:
11181 switch (minor) {
11182 case RDPGPR:
11183 check_cp0_enabled(ctx);
11184 check_insn(ctx, ISA_MIPS32R2);
11185 gen_load_srsgpr(rt, rs);
11186 break;
11187 case WRPGPR:
11188 check_cp0_enabled(ctx);
11189 check_insn(ctx, ISA_MIPS32R2);
11190 gen_store_srsgpr(rt, rs);
11191 break;
11192 default:
11193 goto pool32axf_invalid;
11195 break;
11196 #ifndef CONFIG_USER_ONLY
11197 case 0x0d:
11198 switch (minor) {
11199 case TLBP:
11200 mips32_op = OPC_TLBP;
11201 goto do_cp0;
11202 case TLBR:
11203 mips32_op = OPC_TLBR;
11204 goto do_cp0;
11205 case TLBWI:
11206 mips32_op = OPC_TLBWI;
11207 goto do_cp0;
11208 case TLBWR:
11209 mips32_op = OPC_TLBWR;
11210 goto do_cp0;
11211 case WAIT:
11212 mips32_op = OPC_WAIT;
11213 goto do_cp0;
11214 case DERET:
11215 mips32_op = OPC_DERET;
11216 goto do_cp0;
11217 case ERET:
11218 mips32_op = OPC_ERET;
11219 do_cp0:
11220 gen_cp0(env, ctx, mips32_op, rt, rs);
11221 break;
11222 default:
11223 goto pool32axf_invalid;
11225 break;
11226 case 0x1d:
11227 switch (minor) {
11228 case DI:
11229 check_cp0_enabled(ctx);
11231 TCGv t0 = tcg_temp_new();
11233 save_cpu_state(ctx, 1);
11234 gen_helper_di(t0, cpu_env);
11235 gen_store_gpr(t0, rs);
11236 /* Stop translation as we may have switched the execution mode */
11237 ctx->bstate = BS_STOP;
11238 tcg_temp_free(t0);
11240 break;
11241 case EI:
11242 check_cp0_enabled(ctx);
11244 TCGv t0 = tcg_temp_new();
11246 save_cpu_state(ctx, 1);
11247 gen_helper_ei(t0, cpu_env);
11248 gen_store_gpr(t0, rs);
11249 /* Stop translation as we may have switched the execution mode */
11250 ctx->bstate = BS_STOP;
11251 tcg_temp_free(t0);
11253 break;
11254 default:
11255 goto pool32axf_invalid;
11257 break;
11258 #endif
11259 case 0x2d:
11260 switch (minor) {
11261 case SYNC:
11262 /* NOP */
11263 break;
11264 case SYSCALL:
11265 generate_exception(ctx, EXCP_SYSCALL);
11266 ctx->bstate = BS_STOP;
11267 break;
11268 case SDBBP:
11269 check_insn(ctx, ISA_MIPS32);
11270 if (!(ctx->hflags & MIPS_HFLAG_DM)) {
11271 generate_exception(ctx, EXCP_DBp);
11272 } else {
11273 generate_exception(ctx, EXCP_DBp);
11275 break;
11276 default:
11277 goto pool32axf_invalid;
11279 break;
11280 case 0x01:
11281 switch (minor & 3) {
11282 case MFHI_ACC:
11283 gen_HILO(ctx, OPC_MFHI, minor >> 2, rs);
11284 break;
11285 case MFLO_ACC:
11286 gen_HILO(ctx, OPC_MFLO, minor >> 2, rs);
11287 break;
11288 case MTHI_ACC:
11289 gen_HILO(ctx, OPC_MTHI, minor >> 2, rs);
11290 break;
11291 case MTLO_ACC:
11292 gen_HILO(ctx, OPC_MTLO, minor >> 2, rs);
11293 break;
11294 default:
11295 goto pool32axf_invalid;
11297 break;
11298 case 0x35:
11299 switch (minor) {
11300 case MFHI32:
11301 gen_HILO(ctx, OPC_MFHI, 0, rs);
11302 break;
11303 case MFLO32:
11304 gen_HILO(ctx, OPC_MFLO, 0, rs);
11305 break;
11306 case MTHI32:
11307 gen_HILO(ctx, OPC_MTHI, 0, rs);
11308 break;
11309 case MTLO32:
11310 gen_HILO(ctx, OPC_MTLO, 0, rs);
11311 break;
11312 default:
11313 goto pool32axf_invalid;
11315 break;
11316 default:
11317 pool32axf_invalid:
11318 MIPS_INVAL("pool32axf");
11319 generate_exception(ctx, EXCP_RI);
11320 break;
11324 /* Values for microMIPS fmt field. Variable-width, depending on which
11325 formats the instruction supports. */
11327 enum {
11328 FMT_SD_S = 0,
11329 FMT_SD_D = 1,
11331 FMT_SDPS_S = 0,
11332 FMT_SDPS_D = 1,
11333 FMT_SDPS_PS = 2,
11335 FMT_SWL_S = 0,
11336 FMT_SWL_W = 1,
11337 FMT_SWL_L = 2,
11339 FMT_DWL_D = 0,
11340 FMT_DWL_W = 1,
11341 FMT_DWL_L = 2
11344 static void gen_pool32fxf(DisasContext *ctx, int rt, int rs)
11346 int extension = (ctx->opcode >> 6) & 0x3ff;
11347 uint32_t mips32_op;
11349 #define FLOAT_1BIT_FMT(opc, fmt) (fmt << 8) | opc
11350 #define FLOAT_2BIT_FMT(opc, fmt) (fmt << 7) | opc
11351 #define COND_FLOAT_MOV(opc, cond) (cond << 7) | opc
11353 switch (extension) {
11354 case FLOAT_1BIT_FMT(CFC1, 0):
11355 mips32_op = OPC_CFC1;
11356 goto do_cp1;
11357 case FLOAT_1BIT_FMT(CTC1, 0):
11358 mips32_op = OPC_CTC1;
11359 goto do_cp1;
11360 case FLOAT_1BIT_FMT(MFC1, 0):
11361 mips32_op = OPC_MFC1;
11362 goto do_cp1;
11363 case FLOAT_1BIT_FMT(MTC1, 0):
11364 mips32_op = OPC_MTC1;
11365 goto do_cp1;
11366 case FLOAT_1BIT_FMT(MFHC1, 0):
11367 mips32_op = OPC_MFHC1;
11368 goto do_cp1;
11369 case FLOAT_1BIT_FMT(MTHC1, 0):
11370 mips32_op = OPC_MTHC1;
11371 do_cp1:
11372 gen_cp1(ctx, mips32_op, rt, rs);
11373 break;
11375 /* Reciprocal square root */
11376 case FLOAT_1BIT_FMT(RSQRT_FMT, FMT_SD_S):
11377 mips32_op = OPC_RSQRT_S;
11378 goto do_unaryfp;
11379 case FLOAT_1BIT_FMT(RSQRT_FMT, FMT_SD_D):
11380 mips32_op = OPC_RSQRT_D;
11381 goto do_unaryfp;
11383 /* Square root */
11384 case FLOAT_1BIT_FMT(SQRT_FMT, FMT_SD_S):
11385 mips32_op = OPC_SQRT_S;
11386 goto do_unaryfp;
11387 case FLOAT_1BIT_FMT(SQRT_FMT, FMT_SD_D):
11388 mips32_op = OPC_SQRT_D;
11389 goto do_unaryfp;
11391 /* Reciprocal */
11392 case FLOAT_1BIT_FMT(RECIP_FMT, FMT_SD_S):
11393 mips32_op = OPC_RECIP_S;
11394 goto do_unaryfp;
11395 case FLOAT_1BIT_FMT(RECIP_FMT, FMT_SD_D):
11396 mips32_op = OPC_RECIP_D;
11397 goto do_unaryfp;
11399 /* Floor */
11400 case FLOAT_1BIT_FMT(FLOOR_L, FMT_SD_S):
11401 mips32_op = OPC_FLOOR_L_S;
11402 goto do_unaryfp;
11403 case FLOAT_1BIT_FMT(FLOOR_L, FMT_SD_D):
11404 mips32_op = OPC_FLOOR_L_D;
11405 goto do_unaryfp;
11406 case FLOAT_1BIT_FMT(FLOOR_W, FMT_SD_S):
11407 mips32_op = OPC_FLOOR_W_S;
11408 goto do_unaryfp;
11409 case FLOAT_1BIT_FMT(FLOOR_W, FMT_SD_D):
11410 mips32_op = OPC_FLOOR_W_D;
11411 goto do_unaryfp;
11413 /* Ceiling */
11414 case FLOAT_1BIT_FMT(CEIL_L, FMT_SD_S):
11415 mips32_op = OPC_CEIL_L_S;
11416 goto do_unaryfp;
11417 case FLOAT_1BIT_FMT(CEIL_L, FMT_SD_D):
11418 mips32_op = OPC_CEIL_L_D;
11419 goto do_unaryfp;
11420 case FLOAT_1BIT_FMT(CEIL_W, FMT_SD_S):
11421 mips32_op = OPC_CEIL_W_S;
11422 goto do_unaryfp;
11423 case FLOAT_1BIT_FMT(CEIL_W, FMT_SD_D):
11424 mips32_op = OPC_CEIL_W_D;
11425 goto do_unaryfp;
11427 /* Truncation */
11428 case FLOAT_1BIT_FMT(TRUNC_L, FMT_SD_S):
11429 mips32_op = OPC_TRUNC_L_S;
11430 goto do_unaryfp;
11431 case FLOAT_1BIT_FMT(TRUNC_L, FMT_SD_D):
11432 mips32_op = OPC_TRUNC_L_D;
11433 goto do_unaryfp;
11434 case FLOAT_1BIT_FMT(TRUNC_W, FMT_SD_S):
11435 mips32_op = OPC_TRUNC_W_S;
11436 goto do_unaryfp;
11437 case FLOAT_1BIT_FMT(TRUNC_W, FMT_SD_D):
11438 mips32_op = OPC_TRUNC_W_D;
11439 goto do_unaryfp;
11441 /* Round */
11442 case FLOAT_1BIT_FMT(ROUND_L, FMT_SD_S):
11443 mips32_op = OPC_ROUND_L_S;
11444 goto do_unaryfp;
11445 case FLOAT_1BIT_FMT(ROUND_L, FMT_SD_D):
11446 mips32_op = OPC_ROUND_L_D;
11447 goto do_unaryfp;
11448 case FLOAT_1BIT_FMT(ROUND_W, FMT_SD_S):
11449 mips32_op = OPC_ROUND_W_S;
11450 goto do_unaryfp;
11451 case FLOAT_1BIT_FMT(ROUND_W, FMT_SD_D):
11452 mips32_op = OPC_ROUND_W_D;
11453 goto do_unaryfp;
11455 /* Integer to floating-point conversion */
11456 case FLOAT_1BIT_FMT(CVT_L, FMT_SD_S):
11457 mips32_op = OPC_CVT_L_S;
11458 goto do_unaryfp;
11459 case FLOAT_1BIT_FMT(CVT_L, FMT_SD_D):
11460 mips32_op = OPC_CVT_L_D;
11461 goto do_unaryfp;
11462 case FLOAT_1BIT_FMT(CVT_W, FMT_SD_S):
11463 mips32_op = OPC_CVT_W_S;
11464 goto do_unaryfp;
11465 case FLOAT_1BIT_FMT(CVT_W, FMT_SD_D):
11466 mips32_op = OPC_CVT_W_D;
11467 goto do_unaryfp;
11469 /* Paired-foo conversions */
11470 case FLOAT_1BIT_FMT(CVT_S_PL, 0):
11471 mips32_op = OPC_CVT_S_PL;
11472 goto do_unaryfp;
11473 case FLOAT_1BIT_FMT(CVT_S_PU, 0):
11474 mips32_op = OPC_CVT_S_PU;
11475 goto do_unaryfp;
11476 case FLOAT_1BIT_FMT(CVT_PW_PS, 0):
11477 mips32_op = OPC_CVT_PW_PS;
11478 goto do_unaryfp;
11479 case FLOAT_1BIT_FMT(CVT_PS_PW, 0):
11480 mips32_op = OPC_CVT_PS_PW;
11481 goto do_unaryfp;
11483 /* Floating-point moves */
11484 case FLOAT_2BIT_FMT(MOV_FMT, FMT_SDPS_S):
11485 mips32_op = OPC_MOV_S;
11486 goto do_unaryfp;
11487 case FLOAT_2BIT_FMT(MOV_FMT, FMT_SDPS_D):
11488 mips32_op = OPC_MOV_D;
11489 goto do_unaryfp;
11490 case FLOAT_2BIT_FMT(MOV_FMT, FMT_SDPS_PS):
11491 mips32_op = OPC_MOV_PS;
11492 goto do_unaryfp;
11494 /* Absolute value */
11495 case FLOAT_2BIT_FMT(ABS_FMT, FMT_SDPS_S):
11496 mips32_op = OPC_ABS_S;
11497 goto do_unaryfp;
11498 case FLOAT_2BIT_FMT(ABS_FMT, FMT_SDPS_D):
11499 mips32_op = OPC_ABS_D;
11500 goto do_unaryfp;
11501 case FLOAT_2BIT_FMT(ABS_FMT, FMT_SDPS_PS):
11502 mips32_op = OPC_ABS_PS;
11503 goto do_unaryfp;
11505 /* Negation */
11506 case FLOAT_2BIT_FMT(NEG_FMT, FMT_SDPS_S):
11507 mips32_op = OPC_NEG_S;
11508 goto do_unaryfp;
11509 case FLOAT_2BIT_FMT(NEG_FMT, FMT_SDPS_D):
11510 mips32_op = OPC_NEG_D;
11511 goto do_unaryfp;
11512 case FLOAT_2BIT_FMT(NEG_FMT, FMT_SDPS_PS):
11513 mips32_op = OPC_NEG_PS;
11514 goto do_unaryfp;
11516 /* Reciprocal square root step */
11517 case FLOAT_2BIT_FMT(RSQRT1_FMT, FMT_SDPS_S):
11518 mips32_op = OPC_RSQRT1_S;
11519 goto do_unaryfp;
11520 case FLOAT_2BIT_FMT(RSQRT1_FMT, FMT_SDPS_D):
11521 mips32_op = OPC_RSQRT1_D;
11522 goto do_unaryfp;
11523 case FLOAT_2BIT_FMT(RSQRT1_FMT, FMT_SDPS_PS):
11524 mips32_op = OPC_RSQRT1_PS;
11525 goto do_unaryfp;
11527 /* Reciprocal step */
11528 case FLOAT_2BIT_FMT(RECIP1_FMT, FMT_SDPS_S):
11529 mips32_op = OPC_RECIP1_S;
11530 goto do_unaryfp;
11531 case FLOAT_2BIT_FMT(RECIP1_FMT, FMT_SDPS_D):
11532 mips32_op = OPC_RECIP1_S;
11533 goto do_unaryfp;
11534 case FLOAT_2BIT_FMT(RECIP1_FMT, FMT_SDPS_PS):
11535 mips32_op = OPC_RECIP1_PS;
11536 goto do_unaryfp;
11538 /* Conversions from double */
11539 case FLOAT_2BIT_FMT(CVT_D, FMT_SWL_S):
11540 mips32_op = OPC_CVT_D_S;
11541 goto do_unaryfp;
11542 case FLOAT_2BIT_FMT(CVT_D, FMT_SWL_W):
11543 mips32_op = OPC_CVT_D_W;
11544 goto do_unaryfp;
11545 case FLOAT_2BIT_FMT(CVT_D, FMT_SWL_L):
11546 mips32_op = OPC_CVT_D_L;
11547 goto do_unaryfp;
11549 /* Conversions from single */
11550 case FLOAT_2BIT_FMT(CVT_S, FMT_DWL_D):
11551 mips32_op = OPC_CVT_S_D;
11552 goto do_unaryfp;
11553 case FLOAT_2BIT_FMT(CVT_S, FMT_DWL_W):
11554 mips32_op = OPC_CVT_S_W;
11555 goto do_unaryfp;
11556 case FLOAT_2BIT_FMT(CVT_S, FMT_DWL_L):
11557 mips32_op = OPC_CVT_S_L;
11558 do_unaryfp:
11559 gen_farith(ctx, mips32_op, -1, rs, rt, 0);
11560 break;
11562 /* Conditional moves on floating-point codes */
11563 case COND_FLOAT_MOV(MOVT, 0):
11564 case COND_FLOAT_MOV(MOVT, 1):
11565 case COND_FLOAT_MOV(MOVT, 2):
11566 case COND_FLOAT_MOV(MOVT, 3):
11567 case COND_FLOAT_MOV(MOVT, 4):
11568 case COND_FLOAT_MOV(MOVT, 5):
11569 case COND_FLOAT_MOV(MOVT, 6):
11570 case COND_FLOAT_MOV(MOVT, 7):
11571 gen_movci(ctx, rt, rs, (ctx->opcode >> 13) & 0x7, 1);
11572 break;
11573 case COND_FLOAT_MOV(MOVF, 0):
11574 case COND_FLOAT_MOV(MOVF, 1):
11575 case COND_FLOAT_MOV(MOVF, 2):
11576 case COND_FLOAT_MOV(MOVF, 3):
11577 case COND_FLOAT_MOV(MOVF, 4):
11578 case COND_FLOAT_MOV(MOVF, 5):
11579 case COND_FLOAT_MOV(MOVF, 6):
11580 case COND_FLOAT_MOV(MOVF, 7):
11581 gen_movci(ctx, rt, rs, (ctx->opcode >> 13) & 0x7, 0);
11582 break;
11583 default:
11584 MIPS_INVAL("pool32fxf");
11585 generate_exception(ctx, EXCP_RI);
11586 break;
11590 static void decode_micromips32_opc (CPUMIPSState *env, DisasContext *ctx,
11591 uint16_t insn_hw1)
11593 int32_t offset;
11594 uint16_t insn;
11595 int rt, rs, rd, rr;
11596 int16_t imm;
11597 uint32_t op, minor, mips32_op;
11598 uint32_t cond, fmt, cc;
11600 insn = cpu_lduw_code(env, ctx->pc + 2);
11601 ctx->opcode = (ctx->opcode << 16) | insn;
11603 rt = (ctx->opcode >> 21) & 0x1f;
11604 rs = (ctx->opcode >> 16) & 0x1f;
11605 rd = (ctx->opcode >> 11) & 0x1f;
11606 rr = (ctx->opcode >> 6) & 0x1f;
11607 imm = (int16_t) ctx->opcode;
11609 op = (ctx->opcode >> 26) & 0x3f;
11610 switch (op) {
11611 case POOL32A:
11612 minor = ctx->opcode & 0x3f;
11613 switch (minor) {
11614 case 0x00:
11615 minor = (ctx->opcode >> 6) & 0xf;
11616 switch (minor) {
11617 case SLL32:
11618 mips32_op = OPC_SLL;
11619 goto do_shifti;
11620 case SRA:
11621 mips32_op = OPC_SRA;
11622 goto do_shifti;
11623 case SRL32:
11624 mips32_op = OPC_SRL;
11625 goto do_shifti;
11626 case ROTR:
11627 mips32_op = OPC_ROTR;
11628 do_shifti:
11629 gen_shift_imm(ctx, mips32_op, rt, rs, rd);
11630 break;
11631 default:
11632 goto pool32a_invalid;
11634 break;
11635 case 0x10:
11636 minor = (ctx->opcode >> 6) & 0xf;
11637 switch (minor) {
11638 /* Arithmetic */
11639 case ADD:
11640 mips32_op = OPC_ADD;
11641 goto do_arith;
11642 case ADDU32:
11643 mips32_op = OPC_ADDU;
11644 goto do_arith;
11645 case SUB:
11646 mips32_op = OPC_SUB;
11647 goto do_arith;
11648 case SUBU32:
11649 mips32_op = OPC_SUBU;
11650 goto do_arith;
11651 case MUL:
11652 mips32_op = OPC_MUL;
11653 do_arith:
11654 gen_arith(ctx, mips32_op, rd, rs, rt);
11655 break;
11656 /* Shifts */
11657 case SLLV:
11658 mips32_op = OPC_SLLV;
11659 goto do_shift;
11660 case SRLV:
11661 mips32_op = OPC_SRLV;
11662 goto do_shift;
11663 case SRAV:
11664 mips32_op = OPC_SRAV;
11665 goto do_shift;
11666 case ROTRV:
11667 mips32_op = OPC_ROTRV;
11668 do_shift:
11669 gen_shift(ctx, mips32_op, rd, rs, rt);
11670 break;
11671 /* Logical operations */
11672 case AND:
11673 mips32_op = OPC_AND;
11674 goto do_logic;
11675 case OR32:
11676 mips32_op = OPC_OR;
11677 goto do_logic;
11678 case NOR:
11679 mips32_op = OPC_NOR;
11680 goto do_logic;
11681 case XOR32:
11682 mips32_op = OPC_XOR;
11683 do_logic:
11684 gen_logic(ctx, mips32_op, rd, rs, rt);
11685 break;
11686 /* Set less than */
11687 case SLT:
11688 mips32_op = OPC_SLT;
11689 goto do_slt;
11690 case SLTU:
11691 mips32_op = OPC_SLTU;
11692 do_slt:
11693 gen_slt(ctx, mips32_op, rd, rs, rt);
11694 break;
11695 default:
11696 goto pool32a_invalid;
11698 break;
11699 case 0x18:
11700 minor = (ctx->opcode >> 6) & 0xf;
11701 switch (minor) {
11702 /* Conditional moves */
11703 case MOVN:
11704 mips32_op = OPC_MOVN;
11705 goto do_cmov;
11706 case MOVZ:
11707 mips32_op = OPC_MOVZ;
11708 do_cmov:
11709 gen_cond_move(ctx, mips32_op, rd, rs, rt);
11710 break;
11711 case LWXS:
11712 gen_ldxs(ctx, rs, rt, rd);
11713 break;
11714 default:
11715 goto pool32a_invalid;
11717 break;
11718 case INS:
11719 gen_bitops(ctx, OPC_INS, rt, rs, rr, rd);
11720 return;
11721 case EXT:
11722 gen_bitops(ctx, OPC_EXT, rt, rs, rr, rd);
11723 return;
11724 case POOL32AXF:
11725 gen_pool32axf(env, ctx, rt, rs);
11726 break;
11727 case 0x07:
11728 generate_exception(ctx, EXCP_BREAK);
11729 break;
11730 default:
11731 pool32a_invalid:
11732 MIPS_INVAL("pool32a");
11733 generate_exception(ctx, EXCP_RI);
11734 break;
11736 break;
11737 case POOL32B:
11738 minor = (ctx->opcode >> 12) & 0xf;
11739 switch (minor) {
11740 case CACHE:
11741 check_cp0_enabled(ctx);
11742 /* Treat as no-op. */
11743 break;
11744 case LWC2:
11745 case SWC2:
11746 /* COP2: Not implemented. */
11747 generate_exception_err(ctx, EXCP_CpU, 2);
11748 break;
11749 case LWP:
11750 case SWP:
11751 #ifdef TARGET_MIPS64
11752 case LDP:
11753 case SDP:
11754 #endif
11755 gen_ldst_pair(ctx, minor, rt, rs, SIMM(ctx->opcode, 0, 12));
11756 break;
11757 case LWM32:
11758 case SWM32:
11759 #ifdef TARGET_MIPS64
11760 case LDM:
11761 case SDM:
11762 #endif
11763 gen_ldst_multiple(ctx, minor, rt, rs, SIMM(ctx->opcode, 0, 12));
11764 break;
11765 default:
11766 MIPS_INVAL("pool32b");
11767 generate_exception(ctx, EXCP_RI);
11768 break;
11770 break;
11771 case POOL32F:
11772 if (env->CP0_Config1 & (1 << CP0C1_FP)) {
11773 minor = ctx->opcode & 0x3f;
11774 check_cp1_enabled(ctx);
11775 switch (minor) {
11776 case ALNV_PS:
11777 mips32_op = OPC_ALNV_PS;
11778 goto do_madd;
11779 case MADD_S:
11780 mips32_op = OPC_MADD_S;
11781 goto do_madd;
11782 case MADD_D:
11783 mips32_op = OPC_MADD_D;
11784 goto do_madd;
11785 case MADD_PS:
11786 mips32_op = OPC_MADD_PS;
11787 goto do_madd;
11788 case MSUB_S:
11789 mips32_op = OPC_MSUB_S;
11790 goto do_madd;
11791 case MSUB_D:
11792 mips32_op = OPC_MSUB_D;
11793 goto do_madd;
11794 case MSUB_PS:
11795 mips32_op = OPC_MSUB_PS;
11796 goto do_madd;
11797 case NMADD_S:
11798 mips32_op = OPC_NMADD_S;
11799 goto do_madd;
11800 case NMADD_D:
11801 mips32_op = OPC_NMADD_D;
11802 goto do_madd;
11803 case NMADD_PS:
11804 mips32_op = OPC_NMADD_PS;
11805 goto do_madd;
11806 case NMSUB_S:
11807 mips32_op = OPC_NMSUB_S;
11808 goto do_madd;
11809 case NMSUB_D:
11810 mips32_op = OPC_NMSUB_D;
11811 goto do_madd;
11812 case NMSUB_PS:
11813 mips32_op = OPC_NMSUB_PS;
11814 do_madd:
11815 gen_flt3_arith(ctx, mips32_op, rd, rr, rs, rt);
11816 break;
11817 case CABS_COND_FMT:
11818 cond = (ctx->opcode >> 6) & 0xf;
11819 cc = (ctx->opcode >> 13) & 0x7;
11820 fmt = (ctx->opcode >> 10) & 0x3;
11821 switch (fmt) {
11822 case 0x0:
11823 gen_cmpabs_s(ctx, cond, rt, rs, cc);
11824 break;
11825 case 0x1:
11826 gen_cmpabs_d(ctx, cond, rt, rs, cc);
11827 break;
11828 case 0x2:
11829 gen_cmpabs_ps(ctx, cond, rt, rs, cc);
11830 break;
11831 default:
11832 goto pool32f_invalid;
11834 break;
11835 case C_COND_FMT:
11836 cond = (ctx->opcode >> 6) & 0xf;
11837 cc = (ctx->opcode >> 13) & 0x7;
11838 fmt = (ctx->opcode >> 10) & 0x3;
11839 switch (fmt) {
11840 case 0x0:
11841 gen_cmp_s(ctx, cond, rt, rs, cc);
11842 break;
11843 case 0x1:
11844 gen_cmp_d(ctx, cond, rt, rs, cc);
11845 break;
11846 case 0x2:
11847 gen_cmp_ps(ctx, cond, rt, rs, cc);
11848 break;
11849 default:
11850 goto pool32f_invalid;
11852 break;
11853 case POOL32FXF:
11854 gen_pool32fxf(ctx, rt, rs);
11855 break;
11856 case 0x00:
11857 /* PLL foo */
11858 switch ((ctx->opcode >> 6) & 0x7) {
11859 case PLL_PS:
11860 mips32_op = OPC_PLL_PS;
11861 goto do_ps;
11862 case PLU_PS:
11863 mips32_op = OPC_PLU_PS;
11864 goto do_ps;
11865 case PUL_PS:
11866 mips32_op = OPC_PUL_PS;
11867 goto do_ps;
11868 case PUU_PS:
11869 mips32_op = OPC_PUU_PS;
11870 goto do_ps;
11871 case CVT_PS_S:
11872 mips32_op = OPC_CVT_PS_S;
11873 do_ps:
11874 gen_farith(ctx, mips32_op, rt, rs, rd, 0);
11875 break;
11876 default:
11877 goto pool32f_invalid;
11879 break;
11880 case 0x08:
11881 /* [LS][WDU]XC1 */
11882 switch ((ctx->opcode >> 6) & 0x7) {
11883 case LWXC1:
11884 mips32_op = OPC_LWXC1;
11885 goto do_ldst_cp1;
11886 case SWXC1:
11887 mips32_op = OPC_SWXC1;
11888 goto do_ldst_cp1;
11889 case LDXC1:
11890 mips32_op = OPC_LDXC1;
11891 goto do_ldst_cp1;
11892 case SDXC1:
11893 mips32_op = OPC_SDXC1;
11894 goto do_ldst_cp1;
11895 case LUXC1:
11896 mips32_op = OPC_LUXC1;
11897 goto do_ldst_cp1;
11898 case SUXC1:
11899 mips32_op = OPC_SUXC1;
11900 do_ldst_cp1:
11901 gen_flt3_ldst(ctx, mips32_op, rd, rd, rt, rs);
11902 break;
11903 default:
11904 goto pool32f_invalid;
11906 break;
11907 case 0x18:
11908 /* 3D insns */
11909 fmt = (ctx->opcode >> 9) & 0x3;
11910 switch ((ctx->opcode >> 6) & 0x7) {
11911 case RSQRT2_FMT:
11912 switch (fmt) {
11913 case FMT_SDPS_S:
11914 mips32_op = OPC_RSQRT2_S;
11915 goto do_3d;
11916 case FMT_SDPS_D:
11917 mips32_op = OPC_RSQRT2_D;
11918 goto do_3d;
11919 case FMT_SDPS_PS:
11920 mips32_op = OPC_RSQRT2_PS;
11921 goto do_3d;
11922 default:
11923 goto pool32f_invalid;
11925 break;
11926 case RECIP2_FMT:
11927 switch (fmt) {
11928 case FMT_SDPS_S:
11929 mips32_op = OPC_RECIP2_S;
11930 goto do_3d;
11931 case FMT_SDPS_D:
11932 mips32_op = OPC_RECIP2_D;
11933 goto do_3d;
11934 case FMT_SDPS_PS:
11935 mips32_op = OPC_RECIP2_PS;
11936 goto do_3d;
11937 default:
11938 goto pool32f_invalid;
11940 break;
11941 case ADDR_PS:
11942 mips32_op = OPC_ADDR_PS;
11943 goto do_3d;
11944 case MULR_PS:
11945 mips32_op = OPC_MULR_PS;
11946 do_3d:
11947 gen_farith(ctx, mips32_op, rt, rs, rd, 0);
11948 break;
11949 default:
11950 goto pool32f_invalid;
11952 break;
11953 case 0x20:
11954 /* MOV[FT].fmt and PREFX */
11955 cc = (ctx->opcode >> 13) & 0x7;
11956 fmt = (ctx->opcode >> 9) & 0x3;
11957 switch ((ctx->opcode >> 6) & 0x7) {
11958 case MOVF_FMT:
11959 switch (fmt) {
11960 case FMT_SDPS_S:
11961 gen_movcf_s(rs, rt, cc, 0);
11962 break;
11963 case FMT_SDPS_D:
11964 gen_movcf_d(ctx, rs, rt, cc, 0);
11965 break;
11966 case FMT_SDPS_PS:
11967 gen_movcf_ps(rs, rt, cc, 0);
11968 break;
11969 default:
11970 goto pool32f_invalid;
11972 break;
11973 case MOVT_FMT:
11974 switch (fmt) {
11975 case FMT_SDPS_S:
11976 gen_movcf_s(rs, rt, cc, 1);
11977 break;
11978 case FMT_SDPS_D:
11979 gen_movcf_d(ctx, rs, rt, cc, 1);
11980 break;
11981 case FMT_SDPS_PS:
11982 gen_movcf_ps(rs, rt, cc, 1);
11983 break;
11984 default:
11985 goto pool32f_invalid;
11987 break;
11988 case PREFX:
11989 break;
11990 default:
11991 goto pool32f_invalid;
11993 break;
11994 #define FINSN_3ARG_SDPS(prfx) \
11995 switch ((ctx->opcode >> 8) & 0x3) { \
11996 case FMT_SDPS_S: \
11997 mips32_op = OPC_##prfx##_S; \
11998 goto do_fpop; \
11999 case FMT_SDPS_D: \
12000 mips32_op = OPC_##prfx##_D; \
12001 goto do_fpop; \
12002 case FMT_SDPS_PS: \
12003 mips32_op = OPC_##prfx##_PS; \
12004 goto do_fpop; \
12005 default: \
12006 goto pool32f_invalid; \
12008 case 0x30:
12009 /* regular FP ops */
12010 switch ((ctx->opcode >> 6) & 0x3) {
12011 case ADD_FMT:
12012 FINSN_3ARG_SDPS(ADD);
12013 break;
12014 case SUB_FMT:
12015 FINSN_3ARG_SDPS(SUB);
12016 break;
12017 case MUL_FMT:
12018 FINSN_3ARG_SDPS(MUL);
12019 break;
12020 case DIV_FMT:
12021 fmt = (ctx->opcode >> 8) & 0x3;
12022 if (fmt == 1) {
12023 mips32_op = OPC_DIV_D;
12024 } else if (fmt == 0) {
12025 mips32_op = OPC_DIV_S;
12026 } else {
12027 goto pool32f_invalid;
12029 goto do_fpop;
12030 default:
12031 goto pool32f_invalid;
12033 break;
12034 case 0x38:
12035 /* cmovs */
12036 switch ((ctx->opcode >> 6) & 0x3) {
12037 case MOVN_FMT:
12038 FINSN_3ARG_SDPS(MOVN);
12039 break;
12040 case MOVZ_FMT:
12041 FINSN_3ARG_SDPS(MOVZ);
12042 break;
12043 default:
12044 goto pool32f_invalid;
12046 break;
12047 do_fpop:
12048 gen_farith(ctx, mips32_op, rt, rs, rd, 0);
12049 break;
12050 default:
12051 pool32f_invalid:
12052 MIPS_INVAL("pool32f");
12053 generate_exception(ctx, EXCP_RI);
12054 break;
12056 } else {
12057 generate_exception_err(ctx, EXCP_CpU, 1);
12059 break;
12060 case POOL32I:
12061 minor = (ctx->opcode >> 21) & 0x1f;
12062 switch (minor) {
12063 case BLTZ:
12064 mips32_op = OPC_BLTZ;
12065 goto do_branch;
12066 case BLTZAL:
12067 mips32_op = OPC_BLTZAL;
12068 goto do_branch;
12069 case BLTZALS:
12070 mips32_op = OPC_BLTZALS;
12071 goto do_branch;
12072 case BGEZ:
12073 mips32_op = OPC_BGEZ;
12074 goto do_branch;
12075 case BGEZAL:
12076 mips32_op = OPC_BGEZAL;
12077 goto do_branch;
12078 case BGEZALS:
12079 mips32_op = OPC_BGEZALS;
12080 goto do_branch;
12081 case BLEZ:
12082 mips32_op = OPC_BLEZ;
12083 goto do_branch;
12084 case BGTZ:
12085 mips32_op = OPC_BGTZ;
12086 do_branch:
12087 gen_compute_branch(ctx, mips32_op, 4, rs, -1, imm << 1);
12088 break;
12090 /* Traps */
12091 case TLTI:
12092 mips32_op = OPC_TLTI;
12093 goto do_trapi;
12094 case TGEI:
12095 mips32_op = OPC_TGEI;
12096 goto do_trapi;
12097 case TLTIU:
12098 mips32_op = OPC_TLTIU;
12099 goto do_trapi;
12100 case TGEIU:
12101 mips32_op = OPC_TGEIU;
12102 goto do_trapi;
12103 case TNEI:
12104 mips32_op = OPC_TNEI;
12105 goto do_trapi;
12106 case TEQI:
12107 mips32_op = OPC_TEQI;
12108 do_trapi:
12109 gen_trap(ctx, mips32_op, rs, -1, imm);
12110 break;
12112 case BNEZC:
12113 case BEQZC:
12114 gen_compute_branch(ctx, minor == BNEZC ? OPC_BNE : OPC_BEQ,
12115 4, rs, 0, imm << 1);
12116 /* Compact branches don't have a delay slot, so just let
12117 the normal delay slot handling take us to the branch
12118 target. */
12119 break;
12120 case LUI:
12121 gen_logic_imm(ctx, OPC_LUI, rs, -1, imm);
12122 break;
12123 case SYNCI:
12124 break;
12125 case BC2F:
12126 case BC2T:
12127 /* COP2: Not implemented. */
12128 generate_exception_err(ctx, EXCP_CpU, 2);
12129 break;
12130 case BC1F:
12131 mips32_op = (ctx->opcode & (1 << 16)) ? OPC_BC1FANY2 : OPC_BC1F;
12132 goto do_cp1branch;
12133 case BC1T:
12134 mips32_op = (ctx->opcode & (1 << 16)) ? OPC_BC1TANY2 : OPC_BC1T;
12135 goto do_cp1branch;
12136 case BC1ANY4F:
12137 mips32_op = OPC_BC1FANY4;
12138 goto do_cp1mips3d;
12139 case BC1ANY4T:
12140 mips32_op = OPC_BC1TANY4;
12141 do_cp1mips3d:
12142 check_cop1x(ctx);
12143 check_insn(ctx, ASE_MIPS3D);
12144 /* Fall through */
12145 do_cp1branch:
12146 gen_compute_branch1(ctx, mips32_op,
12147 (ctx->opcode >> 18) & 0x7, imm << 1);
12148 break;
12149 case BPOSGE64:
12150 case BPOSGE32:
12151 /* MIPS DSP: not implemented */
12152 /* Fall through */
12153 default:
12154 MIPS_INVAL("pool32i");
12155 generate_exception(ctx, EXCP_RI);
12156 break;
12158 break;
12159 case POOL32C:
12160 minor = (ctx->opcode >> 12) & 0xf;
12161 switch (minor) {
12162 case LWL:
12163 mips32_op = OPC_LWL;
12164 goto do_ld_lr;
12165 case SWL:
12166 mips32_op = OPC_SWL;
12167 goto do_st_lr;
12168 case LWR:
12169 mips32_op = OPC_LWR;
12170 goto do_ld_lr;
12171 case SWR:
12172 mips32_op = OPC_SWR;
12173 goto do_st_lr;
12174 #if defined(TARGET_MIPS64)
12175 case LDL:
12176 mips32_op = OPC_LDL;
12177 goto do_ld_lr;
12178 case SDL:
12179 mips32_op = OPC_SDL;
12180 goto do_st_lr;
12181 case LDR:
12182 mips32_op = OPC_LDR;
12183 goto do_ld_lr;
12184 case SDR:
12185 mips32_op = OPC_SDR;
12186 goto do_st_lr;
12187 case LWU:
12188 mips32_op = OPC_LWU;
12189 goto do_ld_lr;
12190 case LLD:
12191 mips32_op = OPC_LLD;
12192 goto do_ld_lr;
12193 #endif
12194 case LL:
12195 mips32_op = OPC_LL;
12196 goto do_ld_lr;
12197 do_ld_lr:
12198 gen_ld(ctx, mips32_op, rt, rs, SIMM(ctx->opcode, 0, 12));
12199 break;
12200 do_st_lr:
12201 gen_st(ctx, mips32_op, rt, rs, SIMM(ctx->opcode, 0, 12));
12202 break;
12203 case SC:
12204 gen_st_cond(ctx, OPC_SC, rt, rs, SIMM(ctx->opcode, 0, 12));
12205 break;
12206 #if defined(TARGET_MIPS64)
12207 case SCD:
12208 gen_st_cond(ctx, OPC_SCD, rt, rs, SIMM(ctx->opcode, 0, 12));
12209 break;
12210 #endif
12211 case PREF:
12212 /* Treat as no-op */
12213 break;
12214 default:
12215 MIPS_INVAL("pool32c");
12216 generate_exception(ctx, EXCP_RI);
12217 break;
12219 break;
12220 case ADDI32:
12221 mips32_op = OPC_ADDI;
12222 goto do_addi;
12223 case ADDIU32:
12224 mips32_op = OPC_ADDIU;
12225 do_addi:
12226 gen_arith_imm(ctx, mips32_op, rt, rs, imm);
12227 break;
12229 /* Logical operations */
12230 case ORI32:
12231 mips32_op = OPC_ORI;
12232 goto do_logici;
12233 case XORI32:
12234 mips32_op = OPC_XORI;
12235 goto do_logici;
12236 case ANDI32:
12237 mips32_op = OPC_ANDI;
12238 do_logici:
12239 gen_logic_imm(ctx, mips32_op, rt, rs, imm);
12240 break;
12242 /* Set less than immediate */
12243 case SLTI32:
12244 mips32_op = OPC_SLTI;
12245 goto do_slti;
12246 case SLTIU32:
12247 mips32_op = OPC_SLTIU;
12248 do_slti:
12249 gen_slt_imm(ctx, mips32_op, rt, rs, imm);
12250 break;
12251 case JALX32:
12252 offset = (int32_t)(ctx->opcode & 0x3FFFFFF) << 2;
12253 gen_compute_branch(ctx, OPC_JALX, 4, rt, rs, offset);
12254 break;
12255 case JALS32:
12256 offset = (int32_t)(ctx->opcode & 0x3FFFFFF) << 1;
12257 gen_compute_branch(ctx, OPC_JALS, 4, rt, rs, offset);
12258 break;
12259 case BEQ32:
12260 gen_compute_branch(ctx, OPC_BEQ, 4, rt, rs, imm << 1);
12261 break;
12262 case BNE32:
12263 gen_compute_branch(ctx, OPC_BNE, 4, rt, rs, imm << 1);
12264 break;
12265 case J32:
12266 gen_compute_branch(ctx, OPC_J, 4, rt, rs,
12267 (int32_t)(ctx->opcode & 0x3FFFFFF) << 1);
12268 break;
12269 case JAL32:
12270 gen_compute_branch(ctx, OPC_JAL, 4, rt, rs,
12271 (int32_t)(ctx->opcode & 0x3FFFFFF) << 1);
12272 break;
12273 /* Floating point (COP1) */
12274 case LWC132:
12275 mips32_op = OPC_LWC1;
12276 goto do_cop1;
12277 case LDC132:
12278 mips32_op = OPC_LDC1;
12279 goto do_cop1;
12280 case SWC132:
12281 mips32_op = OPC_SWC1;
12282 goto do_cop1;
12283 case SDC132:
12284 mips32_op = OPC_SDC1;
12285 do_cop1:
12286 gen_cop1_ldst(env, ctx, mips32_op, rt, rs, imm);
12287 break;
12288 case ADDIUPC:
12290 int reg = mmreg(ZIMM(ctx->opcode, 23, 3));
12291 int offset = SIMM(ctx->opcode, 0, 23) << 2;
12293 gen_addiupc(ctx, reg, offset, 0, 0);
12295 break;
12296 /* Loads and stores */
12297 case LB32:
12298 mips32_op = OPC_LB;
12299 goto do_ld;
12300 case LBU32:
12301 mips32_op = OPC_LBU;
12302 goto do_ld;
12303 case LH32:
12304 mips32_op = OPC_LH;
12305 goto do_ld;
12306 case LHU32:
12307 mips32_op = OPC_LHU;
12308 goto do_ld;
12309 case LW32:
12310 mips32_op = OPC_LW;
12311 goto do_ld;
12312 #ifdef TARGET_MIPS64
12313 case LD32:
12314 mips32_op = OPC_LD;
12315 goto do_ld;
12316 case SD32:
12317 mips32_op = OPC_SD;
12318 goto do_st;
12319 #endif
12320 case SB32:
12321 mips32_op = OPC_SB;
12322 goto do_st;
12323 case SH32:
12324 mips32_op = OPC_SH;
12325 goto do_st;
12326 case SW32:
12327 mips32_op = OPC_SW;
12328 goto do_st;
12329 do_ld:
12330 gen_ld(ctx, mips32_op, rt, rs, imm);
12331 break;
12332 do_st:
12333 gen_st(ctx, mips32_op, rt, rs, imm);
12334 break;
12335 default:
12336 generate_exception(ctx, EXCP_RI);
12337 break;
12341 static int decode_micromips_opc (CPUMIPSState *env, DisasContext *ctx)
12343 uint32_t op;
12345 /* make sure instructions are on a halfword boundary */
12346 if (ctx->pc & 0x1) {
12347 env->CP0_BadVAddr = ctx->pc;
12348 generate_exception(ctx, EXCP_AdEL);
12349 ctx->bstate = BS_STOP;
12350 return 2;
12353 op = (ctx->opcode >> 10) & 0x3f;
12354 /* Enforce properly-sized instructions in a delay slot */
12355 if (ctx->hflags & MIPS_HFLAG_BMASK) {
12356 int bits = ctx->hflags & MIPS_HFLAG_BMASK_EXT;
12358 switch (op) {
12359 case POOL32A:
12360 case POOL32B:
12361 case POOL32I:
12362 case POOL32C:
12363 case ADDI32:
12364 case ADDIU32:
12365 case ORI32:
12366 case XORI32:
12367 case SLTI32:
12368 case SLTIU32:
12369 case ANDI32:
12370 case JALX32:
12371 case LBU32:
12372 case LHU32:
12373 case POOL32F:
12374 case JALS32:
12375 case BEQ32:
12376 case BNE32:
12377 case J32:
12378 case JAL32:
12379 case SB32:
12380 case SH32:
12381 case POOL32S:
12382 case ADDIUPC:
12383 case SWC132:
12384 case SDC132:
12385 case SD32:
12386 case SW32:
12387 case LB32:
12388 case LH32:
12389 case DADDIU32:
12390 case LWC132:
12391 case LDC132:
12392 case LD32:
12393 case LW32:
12394 if (bits & MIPS_HFLAG_BDS16) {
12395 generate_exception(ctx, EXCP_RI);
12396 /* Just stop translation; the user is confused. */
12397 ctx->bstate = BS_STOP;
12398 return 2;
12400 break;
12401 case POOL16A:
12402 case POOL16B:
12403 case POOL16C:
12404 case LWGP16:
12405 case POOL16F:
12406 case LBU16:
12407 case LHU16:
12408 case LWSP16:
12409 case LW16:
12410 case SB16:
12411 case SH16:
12412 case SWSP16:
12413 case SW16:
12414 case MOVE16:
12415 case ANDI16:
12416 case POOL16D:
12417 case POOL16E:
12418 case BEQZ16:
12419 case BNEZ16:
12420 case B16:
12421 case LI16:
12422 if (bits & MIPS_HFLAG_BDS32) {
12423 generate_exception(ctx, EXCP_RI);
12424 /* Just stop translation; the user is confused. */
12425 ctx->bstate = BS_STOP;
12426 return 2;
12428 break;
12429 default:
12430 break;
12433 switch (op) {
12434 case POOL16A:
12436 int rd = mmreg(uMIPS_RD(ctx->opcode));
12437 int rs1 = mmreg(uMIPS_RS1(ctx->opcode));
12438 int rs2 = mmreg(uMIPS_RS2(ctx->opcode));
12439 uint32_t opc = 0;
12441 switch (ctx->opcode & 0x1) {
12442 case ADDU16:
12443 opc = OPC_ADDU;
12444 break;
12445 case SUBU16:
12446 opc = OPC_SUBU;
12447 break;
12450 gen_arith(ctx, opc, rd, rs1, rs2);
12452 break;
12453 case POOL16B:
12455 int rd = mmreg(uMIPS_RD(ctx->opcode));
12456 int rs = mmreg(uMIPS_RS(ctx->opcode));
12457 int amount = (ctx->opcode >> 1) & 0x7;
12458 uint32_t opc = 0;
12459 amount = amount == 0 ? 8 : amount;
12461 switch (ctx->opcode & 0x1) {
12462 case SLL16:
12463 opc = OPC_SLL;
12464 break;
12465 case SRL16:
12466 opc = OPC_SRL;
12467 break;
12470 gen_shift_imm(ctx, opc, rd, rs, amount);
12472 break;
12473 case POOL16C:
12474 gen_pool16c_insn(ctx);
12475 break;
12476 case LWGP16:
12478 int rd = mmreg(uMIPS_RD(ctx->opcode));
12479 int rb = 28; /* GP */
12480 int16_t offset = SIMM(ctx->opcode, 0, 7) << 2;
12482 gen_ld(ctx, OPC_LW, rd, rb, offset);
12484 break;
12485 case POOL16F:
12486 if (ctx->opcode & 1) {
12487 generate_exception(ctx, EXCP_RI);
12488 } else {
12489 /* MOVEP */
12490 int enc_dest = uMIPS_RD(ctx->opcode);
12491 int enc_rt = uMIPS_RS2(ctx->opcode);
12492 int enc_rs = uMIPS_RS1(ctx->opcode);
12493 int rd, rs, re, rt;
12494 static const int rd_enc[] = { 5, 5, 6, 4, 4, 4, 4, 4 };
12495 static const int re_enc[] = { 6, 7, 7, 21, 22, 5, 6, 7 };
12496 static const int rs_rt_enc[] = { 0, 17, 2, 3, 16, 18, 19, 20 };
12498 rd = rd_enc[enc_dest];
12499 re = re_enc[enc_dest];
12500 rs = rs_rt_enc[enc_rs];
12501 rt = rs_rt_enc[enc_rt];
12503 gen_arith_imm(ctx, OPC_ADDIU, rd, rs, 0);
12504 gen_arith_imm(ctx, OPC_ADDIU, re, rt, 0);
12506 break;
12507 case LBU16:
12509 int rd = mmreg(uMIPS_RD(ctx->opcode));
12510 int rb = mmreg(uMIPS_RS(ctx->opcode));
12511 int16_t offset = ZIMM(ctx->opcode, 0, 4);
12512 offset = (offset == 0xf ? -1 : offset);
12514 gen_ld(ctx, OPC_LBU, rd, rb, offset);
12516 break;
12517 case LHU16:
12519 int rd = mmreg(uMIPS_RD(ctx->opcode));
12520 int rb = mmreg(uMIPS_RS(ctx->opcode));
12521 int16_t offset = ZIMM(ctx->opcode, 0, 4) << 1;
12523 gen_ld(ctx, OPC_LHU, rd, rb, offset);
12525 break;
12526 case LWSP16:
12528 int rd = (ctx->opcode >> 5) & 0x1f;
12529 int rb = 29; /* SP */
12530 int16_t offset = ZIMM(ctx->opcode, 0, 5) << 2;
12532 gen_ld(ctx, OPC_LW, rd, rb, offset);
12534 break;
12535 case LW16:
12537 int rd = mmreg(uMIPS_RD(ctx->opcode));
12538 int rb = mmreg(uMIPS_RS(ctx->opcode));
12539 int16_t offset = ZIMM(ctx->opcode, 0, 4) << 2;
12541 gen_ld(ctx, OPC_LW, rd, rb, offset);
12543 break;
12544 case SB16:
12546 int rd = mmreg2(uMIPS_RD(ctx->opcode));
12547 int rb = mmreg(uMIPS_RS(ctx->opcode));
12548 int16_t offset = ZIMM(ctx->opcode, 0, 4);
12550 gen_st(ctx, OPC_SB, rd, rb, offset);
12552 break;
12553 case SH16:
12555 int rd = mmreg2(uMIPS_RD(ctx->opcode));
12556 int rb = mmreg(uMIPS_RS(ctx->opcode));
12557 int16_t offset = ZIMM(ctx->opcode, 0, 4) << 1;
12559 gen_st(ctx, OPC_SH, rd, rb, offset);
12561 break;
12562 case SWSP16:
12564 int rd = (ctx->opcode >> 5) & 0x1f;
12565 int rb = 29; /* SP */
12566 int16_t offset = ZIMM(ctx->opcode, 0, 5) << 2;
12568 gen_st(ctx, OPC_SW, rd, rb, offset);
12570 break;
12571 case SW16:
12573 int rd = mmreg2(uMIPS_RD(ctx->opcode));
12574 int rb = mmreg(uMIPS_RS(ctx->opcode));
12575 int16_t offset = ZIMM(ctx->opcode, 0, 4) << 2;
12577 gen_st(ctx, OPC_SW, rd, rb, offset);
12579 break;
12580 case MOVE16:
12582 int rd = uMIPS_RD5(ctx->opcode);
12583 int rs = uMIPS_RS5(ctx->opcode);
12585 gen_arith_imm(ctx, OPC_ADDIU, rd, rs, 0);
12587 break;
12588 case ANDI16:
12589 gen_andi16(ctx);
12590 break;
12591 case POOL16D:
12592 switch (ctx->opcode & 0x1) {
12593 case ADDIUS5:
12594 gen_addius5(ctx);
12595 break;
12596 case ADDIUSP:
12597 gen_addiusp(ctx);
12598 break;
12600 break;
12601 case POOL16E:
12602 switch (ctx->opcode & 0x1) {
12603 case ADDIUR2:
12604 gen_addiur2(ctx);
12605 break;
12606 case ADDIUR1SP:
12607 gen_addiur1sp(ctx);
12608 break;
12610 break;
12611 case B16:
12612 gen_compute_branch(ctx, OPC_BEQ, 2, 0, 0,
12613 SIMM(ctx->opcode, 0, 10) << 1);
12614 break;
12615 case BNEZ16:
12616 case BEQZ16:
12617 gen_compute_branch(ctx, op == BNEZ16 ? OPC_BNE : OPC_BEQ, 2,
12618 mmreg(uMIPS_RD(ctx->opcode)),
12619 0, SIMM(ctx->opcode, 0, 7) << 1);
12620 break;
12621 case LI16:
12623 int reg = mmreg(uMIPS_RD(ctx->opcode));
12624 int imm = ZIMM(ctx->opcode, 0, 7);
12626 imm = (imm == 0x7f ? -1 : imm);
12627 tcg_gen_movi_tl(cpu_gpr[reg], imm);
12629 break;
12630 case RES_20:
12631 case RES_28:
12632 case RES_29:
12633 case RES_30:
12634 case RES_31:
12635 case RES_38:
12636 case RES_39:
12637 generate_exception(ctx, EXCP_RI);
12638 break;
12639 default:
12640 decode_micromips32_opc (env, ctx, op);
12641 return 4;
12644 return 2;
12647 /* SmartMIPS extension to MIPS32 */
12649 #if defined(TARGET_MIPS64)
12651 /* MDMX extension to MIPS64 */
12653 #endif
12655 /* MIPSDSP functions. */
12656 static void gen_mipsdsp_ld(DisasContext *ctx, uint32_t opc,
12657 int rd, int base, int offset)
12659 const char *opn = "ldx";
12660 TCGv t0;
12662 check_dsp(ctx);
12663 t0 = tcg_temp_new();
12665 if (base == 0) {
12666 gen_load_gpr(t0, offset);
12667 } else if (offset == 0) {
12668 gen_load_gpr(t0, base);
12669 } else {
12670 gen_op_addr_add(ctx, t0, cpu_gpr[base], cpu_gpr[offset]);
12673 switch (opc) {
12674 case OPC_LBUX:
12675 tcg_gen_qemu_ld8u(t0, t0, ctx->mem_idx);
12676 gen_store_gpr(t0, rd);
12677 opn = "lbux";
12678 break;
12679 case OPC_LHX:
12680 tcg_gen_qemu_ld16s(t0, t0, ctx->mem_idx);
12681 gen_store_gpr(t0, rd);
12682 opn = "lhx";
12683 break;
12684 case OPC_LWX:
12685 tcg_gen_qemu_ld32s(t0, t0, ctx->mem_idx);
12686 gen_store_gpr(t0, rd);
12687 opn = "lwx";
12688 break;
12689 #if defined(TARGET_MIPS64)
12690 case OPC_LDX:
12691 tcg_gen_qemu_ld64(t0, t0, ctx->mem_idx);
12692 gen_store_gpr(t0, rd);
12693 opn = "ldx";
12694 break;
12695 #endif
12697 (void)opn; /* avoid a compiler warning */
12698 MIPS_DEBUG("%s %s, %s(%s)", opn,
12699 regnames[rd], regnames[offset], regnames[base]);
12700 tcg_temp_free(t0);
12703 static void gen_mipsdsp_arith(DisasContext *ctx, uint32_t op1, uint32_t op2,
12704 int ret, int v1, int v2)
12706 const char *opn = "mipsdsp arith";
12707 TCGv v1_t;
12708 TCGv v2_t;
12710 if (ret == 0) {
12711 /* Treat as NOP. */
12712 MIPS_DEBUG("NOP");
12713 return;
12716 v1_t = tcg_temp_new();
12717 v2_t = tcg_temp_new();
12719 gen_load_gpr(v1_t, v1);
12720 gen_load_gpr(v2_t, v2);
12722 switch (op1) {
12723 /* OPC_MULT_G_2E is equal OPC_ADDUH_QB_DSP */
12724 case OPC_MULT_G_2E:
12725 check_dspr2(ctx);
12726 switch (op2) {
12727 case OPC_ADDUH_QB:
12728 gen_helper_adduh_qb(cpu_gpr[ret], v1_t, v2_t);
12729 break;
12730 case OPC_ADDUH_R_QB:
12731 gen_helper_adduh_r_qb(cpu_gpr[ret], v1_t, v2_t);
12732 break;
12733 case OPC_ADDQH_PH:
12734 gen_helper_addqh_ph(cpu_gpr[ret], v1_t, v2_t);
12735 break;
12736 case OPC_ADDQH_R_PH:
12737 gen_helper_addqh_r_ph(cpu_gpr[ret], v1_t, v2_t);
12738 break;
12739 case OPC_ADDQH_W:
12740 gen_helper_addqh_w(cpu_gpr[ret], v1_t, v2_t);
12741 break;
12742 case OPC_ADDQH_R_W:
12743 gen_helper_addqh_r_w(cpu_gpr[ret], v1_t, v2_t);
12744 break;
12745 case OPC_SUBUH_QB:
12746 gen_helper_subuh_qb(cpu_gpr[ret], v1_t, v2_t);
12747 break;
12748 case OPC_SUBUH_R_QB:
12749 gen_helper_subuh_r_qb(cpu_gpr[ret], v1_t, v2_t);
12750 break;
12751 case OPC_SUBQH_PH:
12752 gen_helper_subqh_ph(cpu_gpr[ret], v1_t, v2_t);
12753 break;
12754 case OPC_SUBQH_R_PH:
12755 gen_helper_subqh_r_ph(cpu_gpr[ret], v1_t, v2_t);
12756 break;
12757 case OPC_SUBQH_W:
12758 gen_helper_subqh_w(cpu_gpr[ret], v1_t, v2_t);
12759 break;
12760 case OPC_SUBQH_R_W:
12761 gen_helper_subqh_r_w(cpu_gpr[ret], v1_t, v2_t);
12762 break;
12764 break;
12765 case OPC_ABSQ_S_PH_DSP:
12766 switch (op2) {
12767 case OPC_ABSQ_S_QB:
12768 check_dspr2(ctx);
12769 gen_helper_absq_s_qb(cpu_gpr[ret], v2_t, cpu_env);
12770 break;
12771 case OPC_ABSQ_S_PH:
12772 check_dsp(ctx);
12773 gen_helper_absq_s_ph(cpu_gpr[ret], v2_t, cpu_env);
12774 break;
12775 case OPC_ABSQ_S_W:
12776 check_dsp(ctx);
12777 gen_helper_absq_s_w(cpu_gpr[ret], v2_t, cpu_env);
12778 break;
12779 case OPC_PRECEQ_W_PHL:
12780 check_dsp(ctx);
12781 tcg_gen_andi_tl(cpu_gpr[ret], v2_t, 0xFFFF0000);
12782 tcg_gen_ext32s_tl(cpu_gpr[ret], cpu_gpr[ret]);
12783 break;
12784 case OPC_PRECEQ_W_PHR:
12785 check_dsp(ctx);
12786 tcg_gen_andi_tl(cpu_gpr[ret], v2_t, 0x0000FFFF);
12787 tcg_gen_shli_tl(cpu_gpr[ret], cpu_gpr[ret], 16);
12788 tcg_gen_ext32s_tl(cpu_gpr[ret], cpu_gpr[ret]);
12789 break;
12790 case OPC_PRECEQU_PH_QBL:
12791 check_dsp(ctx);
12792 gen_helper_precequ_ph_qbl(cpu_gpr[ret], v2_t);
12793 break;
12794 case OPC_PRECEQU_PH_QBR:
12795 check_dsp(ctx);
12796 gen_helper_precequ_ph_qbr(cpu_gpr[ret], v2_t);
12797 break;
12798 case OPC_PRECEQU_PH_QBLA:
12799 check_dsp(ctx);
12800 gen_helper_precequ_ph_qbla(cpu_gpr[ret], v2_t);
12801 break;
12802 case OPC_PRECEQU_PH_QBRA:
12803 check_dsp(ctx);
12804 gen_helper_precequ_ph_qbra(cpu_gpr[ret], v2_t);
12805 break;
12806 case OPC_PRECEU_PH_QBL:
12807 check_dsp(ctx);
12808 gen_helper_preceu_ph_qbl(cpu_gpr[ret], v2_t);
12809 break;
12810 case OPC_PRECEU_PH_QBR:
12811 check_dsp(ctx);
12812 gen_helper_preceu_ph_qbr(cpu_gpr[ret], v2_t);
12813 break;
12814 case OPC_PRECEU_PH_QBLA:
12815 check_dsp(ctx);
12816 gen_helper_preceu_ph_qbla(cpu_gpr[ret], v2_t);
12817 break;
12818 case OPC_PRECEU_PH_QBRA:
12819 check_dsp(ctx);
12820 gen_helper_preceu_ph_qbra(cpu_gpr[ret], v2_t);
12821 break;
12823 break;
12824 case OPC_ADDU_QB_DSP:
12825 switch (op2) {
12826 case OPC_ADDQ_PH:
12827 check_dsp(ctx);
12828 gen_helper_addq_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12829 break;
12830 case OPC_ADDQ_S_PH:
12831 check_dsp(ctx);
12832 gen_helper_addq_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12833 break;
12834 case OPC_ADDQ_S_W:
12835 check_dsp(ctx);
12836 gen_helper_addq_s_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12837 break;
12838 case OPC_ADDU_QB:
12839 check_dsp(ctx);
12840 gen_helper_addu_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12841 break;
12842 case OPC_ADDU_S_QB:
12843 check_dsp(ctx);
12844 gen_helper_addu_s_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12845 break;
12846 case OPC_ADDU_PH:
12847 check_dspr2(ctx);
12848 gen_helper_addu_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12849 break;
12850 case OPC_ADDU_S_PH:
12851 check_dspr2(ctx);
12852 gen_helper_addu_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12853 break;
12854 case OPC_SUBQ_PH:
12855 check_dsp(ctx);
12856 gen_helper_subq_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12857 break;
12858 case OPC_SUBQ_S_PH:
12859 check_dsp(ctx);
12860 gen_helper_subq_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12861 break;
12862 case OPC_SUBQ_S_W:
12863 check_dsp(ctx);
12864 gen_helper_subq_s_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12865 break;
12866 case OPC_SUBU_QB:
12867 check_dsp(ctx);
12868 gen_helper_subu_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12869 break;
12870 case OPC_SUBU_S_QB:
12871 check_dsp(ctx);
12872 gen_helper_subu_s_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12873 break;
12874 case OPC_SUBU_PH:
12875 check_dspr2(ctx);
12876 gen_helper_subu_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12877 break;
12878 case OPC_SUBU_S_PH:
12879 check_dspr2(ctx);
12880 gen_helper_subu_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12881 break;
12882 case OPC_ADDSC:
12883 check_dsp(ctx);
12884 gen_helper_addsc(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12885 break;
12886 case OPC_ADDWC:
12887 check_dsp(ctx);
12888 gen_helper_addwc(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12889 break;
12890 case OPC_MODSUB:
12891 check_dsp(ctx);
12892 gen_helper_modsub(cpu_gpr[ret], v1_t, v2_t);
12893 break;
12894 case OPC_RADDU_W_QB:
12895 check_dsp(ctx);
12896 gen_helper_raddu_w_qb(cpu_gpr[ret], v1_t);
12897 break;
12899 break;
12900 case OPC_CMPU_EQ_QB_DSP:
12901 switch (op2) {
12902 case OPC_PRECR_QB_PH:
12903 check_dspr2(ctx);
12904 gen_helper_precr_qb_ph(cpu_gpr[ret], v1_t, v2_t);
12905 break;
12906 case OPC_PRECRQ_QB_PH:
12907 check_dsp(ctx);
12908 gen_helper_precrq_qb_ph(cpu_gpr[ret], v1_t, v2_t);
12909 break;
12910 case OPC_PRECR_SRA_PH_W:
12911 check_dspr2(ctx);
12913 TCGv_i32 sa_t = tcg_const_i32(v2);
12914 gen_helper_precr_sra_ph_w(cpu_gpr[ret], sa_t, v1_t,
12915 cpu_gpr[ret]);
12916 tcg_temp_free_i32(sa_t);
12917 break;
12919 case OPC_PRECR_SRA_R_PH_W:
12920 check_dspr2(ctx);
12922 TCGv_i32 sa_t = tcg_const_i32(v2);
12923 gen_helper_precr_sra_r_ph_w(cpu_gpr[ret], sa_t, v1_t,
12924 cpu_gpr[ret]);
12925 tcg_temp_free_i32(sa_t);
12926 break;
12928 case OPC_PRECRQ_PH_W:
12929 check_dsp(ctx);
12930 gen_helper_precrq_ph_w(cpu_gpr[ret], v1_t, v2_t);
12931 break;
12932 case OPC_PRECRQ_RS_PH_W:
12933 check_dsp(ctx);
12934 gen_helper_precrq_rs_ph_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12935 break;
12936 case OPC_PRECRQU_S_QB_PH:
12937 check_dsp(ctx);
12938 gen_helper_precrqu_s_qb_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12939 break;
12941 break;
12942 #ifdef TARGET_MIPS64
12943 case OPC_ABSQ_S_QH_DSP:
12944 switch (op2) {
12945 case OPC_PRECEQ_L_PWL:
12946 check_dsp(ctx);
12947 tcg_gen_andi_tl(cpu_gpr[ret], v2_t, 0xFFFFFFFF00000000ull);
12948 break;
12949 case OPC_PRECEQ_L_PWR:
12950 check_dsp(ctx);
12951 tcg_gen_shli_tl(cpu_gpr[ret], v2_t, 32);
12952 break;
12953 case OPC_PRECEQ_PW_QHL:
12954 check_dsp(ctx);
12955 gen_helper_preceq_pw_qhl(cpu_gpr[ret], v2_t);
12956 break;
12957 case OPC_PRECEQ_PW_QHR:
12958 check_dsp(ctx);
12959 gen_helper_preceq_pw_qhr(cpu_gpr[ret], v2_t);
12960 break;
12961 case OPC_PRECEQ_PW_QHLA:
12962 check_dsp(ctx);
12963 gen_helper_preceq_pw_qhla(cpu_gpr[ret], v2_t);
12964 break;
12965 case OPC_PRECEQ_PW_QHRA:
12966 check_dsp(ctx);
12967 gen_helper_preceq_pw_qhra(cpu_gpr[ret], v2_t);
12968 break;
12969 case OPC_PRECEQU_QH_OBL:
12970 check_dsp(ctx);
12971 gen_helper_precequ_qh_obl(cpu_gpr[ret], v2_t);
12972 break;
12973 case OPC_PRECEQU_QH_OBR:
12974 check_dsp(ctx);
12975 gen_helper_precequ_qh_obr(cpu_gpr[ret], v2_t);
12976 break;
12977 case OPC_PRECEQU_QH_OBLA:
12978 check_dsp(ctx);
12979 gen_helper_precequ_qh_obla(cpu_gpr[ret], v2_t);
12980 break;
12981 case OPC_PRECEQU_QH_OBRA:
12982 check_dsp(ctx);
12983 gen_helper_precequ_qh_obra(cpu_gpr[ret], v2_t);
12984 break;
12985 case OPC_PRECEU_QH_OBL:
12986 check_dsp(ctx);
12987 gen_helper_preceu_qh_obl(cpu_gpr[ret], v2_t);
12988 break;
12989 case OPC_PRECEU_QH_OBR:
12990 check_dsp(ctx);
12991 gen_helper_preceu_qh_obr(cpu_gpr[ret], v2_t);
12992 break;
12993 case OPC_PRECEU_QH_OBLA:
12994 check_dsp(ctx);
12995 gen_helper_preceu_qh_obla(cpu_gpr[ret], v2_t);
12996 break;
12997 case OPC_PRECEU_QH_OBRA:
12998 check_dsp(ctx);
12999 gen_helper_preceu_qh_obra(cpu_gpr[ret], v2_t);
13000 break;
13001 case OPC_ABSQ_S_OB:
13002 check_dspr2(ctx);
13003 gen_helper_absq_s_ob(cpu_gpr[ret], v2_t, cpu_env);
13004 break;
13005 case OPC_ABSQ_S_PW:
13006 check_dsp(ctx);
13007 gen_helper_absq_s_pw(cpu_gpr[ret], v2_t, cpu_env);
13008 break;
13009 case OPC_ABSQ_S_QH:
13010 check_dsp(ctx);
13011 gen_helper_absq_s_qh(cpu_gpr[ret], v2_t, cpu_env);
13012 break;
13014 break;
13015 case OPC_ADDU_OB_DSP:
13016 switch (op2) {
13017 case OPC_RADDU_L_OB:
13018 check_dsp(ctx);
13019 gen_helper_raddu_l_ob(cpu_gpr[ret], v1_t);
13020 break;
13021 case OPC_SUBQ_PW:
13022 check_dsp(ctx);
13023 gen_helper_subq_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13024 break;
13025 case OPC_SUBQ_S_PW:
13026 check_dsp(ctx);
13027 gen_helper_subq_s_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13028 break;
13029 case OPC_SUBQ_QH:
13030 check_dsp(ctx);
13031 gen_helper_subq_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13032 break;
13033 case OPC_SUBQ_S_QH:
13034 check_dsp(ctx);
13035 gen_helper_subq_s_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13036 break;
13037 case OPC_SUBU_OB:
13038 check_dsp(ctx);
13039 gen_helper_subu_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13040 break;
13041 case OPC_SUBU_S_OB:
13042 check_dsp(ctx);
13043 gen_helper_subu_s_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13044 break;
13045 case OPC_SUBU_QH:
13046 check_dspr2(ctx);
13047 gen_helper_subu_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13048 break;
13049 case OPC_SUBU_S_QH:
13050 check_dspr2(ctx);
13051 gen_helper_subu_s_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13052 break;
13053 case OPC_SUBUH_OB:
13054 check_dspr2(ctx);
13055 gen_helper_subuh_ob(cpu_gpr[ret], v1_t, v2_t);
13056 break;
13057 case OPC_SUBUH_R_OB:
13058 check_dspr2(ctx);
13059 gen_helper_subuh_r_ob(cpu_gpr[ret], v1_t, v2_t);
13060 break;
13061 case OPC_ADDQ_PW:
13062 check_dsp(ctx);
13063 gen_helper_addq_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13064 break;
13065 case OPC_ADDQ_S_PW:
13066 check_dsp(ctx);
13067 gen_helper_addq_s_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13068 break;
13069 case OPC_ADDQ_QH:
13070 check_dsp(ctx);
13071 gen_helper_addq_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13072 break;
13073 case OPC_ADDQ_S_QH:
13074 check_dsp(ctx);
13075 gen_helper_addq_s_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13076 break;
13077 case OPC_ADDU_OB:
13078 check_dsp(ctx);
13079 gen_helper_addu_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13080 break;
13081 case OPC_ADDU_S_OB:
13082 check_dsp(ctx);
13083 gen_helper_addu_s_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13084 break;
13085 case OPC_ADDU_QH:
13086 check_dspr2(ctx);
13087 gen_helper_addu_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13088 break;
13089 case OPC_ADDU_S_QH:
13090 check_dspr2(ctx);
13091 gen_helper_addu_s_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13092 break;
13093 case OPC_ADDUH_OB:
13094 check_dspr2(ctx);
13095 gen_helper_adduh_ob(cpu_gpr[ret], v1_t, v2_t);
13096 break;
13097 case OPC_ADDUH_R_OB:
13098 check_dspr2(ctx);
13099 gen_helper_adduh_r_ob(cpu_gpr[ret], v1_t, v2_t);
13100 break;
13102 break;
13103 case OPC_CMPU_EQ_OB_DSP:
13104 switch (op2) {
13105 case OPC_PRECR_OB_QH:
13106 check_dspr2(ctx);
13107 gen_helper_precr_ob_qh(cpu_gpr[ret], v1_t, v2_t);
13108 break;
13109 case OPC_PRECR_SRA_QH_PW:
13110 check_dspr2(ctx);
13112 TCGv_i32 ret_t = tcg_const_i32(ret);
13113 gen_helper_precr_sra_qh_pw(v2_t, v1_t, v2_t, ret_t);
13114 tcg_temp_free_i32(ret_t);
13115 break;
13117 case OPC_PRECR_SRA_R_QH_PW:
13118 check_dspr2(ctx);
13120 TCGv_i32 sa_v = tcg_const_i32(ret);
13121 gen_helper_precr_sra_r_qh_pw(v2_t, v1_t, v2_t, sa_v);
13122 tcg_temp_free_i32(sa_v);
13123 break;
13125 case OPC_PRECRQ_OB_QH:
13126 check_dsp(ctx);
13127 gen_helper_precrq_ob_qh(cpu_gpr[ret], v1_t, v2_t);
13128 break;
13129 case OPC_PRECRQ_PW_L:
13130 check_dsp(ctx);
13131 gen_helper_precrq_pw_l(cpu_gpr[ret], v1_t, v2_t);
13132 break;
13133 case OPC_PRECRQ_QH_PW:
13134 check_dsp(ctx);
13135 gen_helper_precrq_qh_pw(cpu_gpr[ret], v1_t, v2_t);
13136 break;
13137 case OPC_PRECRQ_RS_QH_PW:
13138 check_dsp(ctx);
13139 gen_helper_precrq_rs_qh_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13140 break;
13141 case OPC_PRECRQU_S_OB_QH:
13142 check_dsp(ctx);
13143 gen_helper_precrqu_s_ob_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13144 break;
13146 break;
13147 #endif
13150 tcg_temp_free(v1_t);
13151 tcg_temp_free(v2_t);
13153 (void)opn; /* avoid a compiler warning */
13154 MIPS_DEBUG("%s", opn);
13157 static void gen_mipsdsp_shift(DisasContext *ctx, uint32_t opc,
13158 int ret, int v1, int v2)
13160 uint32_t op2;
13161 const char *opn = "mipsdsp shift";
13162 TCGv t0;
13163 TCGv v1_t;
13164 TCGv v2_t;
13166 if (ret == 0) {
13167 /* Treat as NOP. */
13168 MIPS_DEBUG("NOP");
13169 return;
13172 t0 = tcg_temp_new();
13173 v1_t = tcg_temp_new();
13174 v2_t = tcg_temp_new();
13176 tcg_gen_movi_tl(t0, v1);
13177 gen_load_gpr(v1_t, v1);
13178 gen_load_gpr(v2_t, v2);
13180 switch (opc) {
13181 case OPC_SHLL_QB_DSP:
13183 op2 = MASK_SHLL_QB(ctx->opcode);
13184 switch (op2) {
13185 case OPC_SHLL_QB:
13186 check_dsp(ctx);
13187 gen_helper_shll_qb(cpu_gpr[ret], t0, v2_t, cpu_env);
13188 break;
13189 case OPC_SHLLV_QB:
13190 check_dsp(ctx);
13191 gen_helper_shll_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13192 break;
13193 case OPC_SHLL_PH:
13194 check_dsp(ctx);
13195 gen_helper_shll_ph(cpu_gpr[ret], t0, v2_t, cpu_env);
13196 break;
13197 case OPC_SHLLV_PH:
13198 check_dsp(ctx);
13199 gen_helper_shll_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13200 break;
13201 case OPC_SHLL_S_PH:
13202 check_dsp(ctx);
13203 gen_helper_shll_s_ph(cpu_gpr[ret], t0, v2_t, cpu_env);
13204 break;
13205 case OPC_SHLLV_S_PH:
13206 check_dsp(ctx);
13207 gen_helper_shll_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13208 break;
13209 case OPC_SHLL_S_W:
13210 check_dsp(ctx);
13211 gen_helper_shll_s_w(cpu_gpr[ret], t0, v2_t, cpu_env);
13212 break;
13213 case OPC_SHLLV_S_W:
13214 check_dsp(ctx);
13215 gen_helper_shll_s_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13216 break;
13217 case OPC_SHRL_QB:
13218 check_dsp(ctx);
13219 gen_helper_shrl_qb(cpu_gpr[ret], t0, v2_t);
13220 break;
13221 case OPC_SHRLV_QB:
13222 check_dsp(ctx);
13223 gen_helper_shrl_qb(cpu_gpr[ret], v1_t, v2_t);
13224 break;
13225 case OPC_SHRL_PH:
13226 check_dspr2(ctx);
13227 gen_helper_shrl_ph(cpu_gpr[ret], t0, v2_t);
13228 break;
13229 case OPC_SHRLV_PH:
13230 check_dspr2(ctx);
13231 gen_helper_shrl_ph(cpu_gpr[ret], v1_t, v2_t);
13232 break;
13233 case OPC_SHRA_QB:
13234 check_dspr2(ctx);
13235 gen_helper_shra_qb(cpu_gpr[ret], t0, v2_t);
13236 break;
13237 case OPC_SHRA_R_QB:
13238 check_dspr2(ctx);
13239 gen_helper_shra_r_qb(cpu_gpr[ret], t0, v2_t);
13240 break;
13241 case OPC_SHRAV_QB:
13242 check_dspr2(ctx);
13243 gen_helper_shra_qb(cpu_gpr[ret], v1_t, v2_t);
13244 break;
13245 case OPC_SHRAV_R_QB:
13246 check_dspr2(ctx);
13247 gen_helper_shra_r_qb(cpu_gpr[ret], v1_t, v2_t);
13248 break;
13249 case OPC_SHRA_PH:
13250 check_dsp(ctx);
13251 gen_helper_shra_ph(cpu_gpr[ret], t0, v2_t);
13252 break;
13253 case OPC_SHRA_R_PH:
13254 check_dsp(ctx);
13255 gen_helper_shra_r_ph(cpu_gpr[ret], t0, v2_t);
13256 break;
13257 case OPC_SHRAV_PH:
13258 check_dsp(ctx);
13259 gen_helper_shra_ph(cpu_gpr[ret], v1_t, v2_t);
13260 break;
13261 case OPC_SHRAV_R_PH:
13262 check_dsp(ctx);
13263 gen_helper_shra_r_ph(cpu_gpr[ret], v1_t, v2_t);
13264 break;
13265 case OPC_SHRA_R_W:
13266 check_dsp(ctx);
13267 gen_helper_shra_r_w(cpu_gpr[ret], t0, v2_t);
13268 break;
13269 case OPC_SHRAV_R_W:
13270 check_dsp(ctx);
13271 gen_helper_shra_r_w(cpu_gpr[ret], v1_t, v2_t);
13272 break;
13273 default: /* Invalid */
13274 MIPS_INVAL("MASK SHLL.QB");
13275 generate_exception(ctx, EXCP_RI);
13276 break;
13278 break;
13280 #ifdef TARGET_MIPS64
13281 case OPC_SHLL_OB_DSP:
13282 op2 = MASK_SHLL_OB(ctx->opcode);
13283 switch (op2) {
13284 case OPC_SHLL_PW:
13285 check_dsp(ctx);
13286 gen_helper_shll_pw(cpu_gpr[ret], v2_t, t0, cpu_env);
13287 break;
13288 case OPC_SHLLV_PW:
13289 check_dsp(ctx);
13290 gen_helper_shll_pw(cpu_gpr[ret], v2_t, v1_t, cpu_env);
13291 break;
13292 case OPC_SHLL_S_PW:
13293 check_dsp(ctx);
13294 gen_helper_shll_s_pw(cpu_gpr[ret], v2_t, t0, cpu_env);
13295 break;
13296 case OPC_SHLLV_S_PW:
13297 check_dsp(ctx);
13298 gen_helper_shll_s_pw(cpu_gpr[ret], v2_t, v1_t, cpu_env);
13299 break;
13300 case OPC_SHLL_OB:
13301 check_dsp(ctx);
13302 gen_helper_shll_ob(cpu_gpr[ret], v2_t, t0, cpu_env);
13303 break;
13304 case OPC_SHLLV_OB:
13305 check_dsp(ctx);
13306 gen_helper_shll_ob(cpu_gpr[ret], v2_t, v1_t, cpu_env);
13307 break;
13308 case OPC_SHLL_QH:
13309 check_dsp(ctx);
13310 gen_helper_shll_qh(cpu_gpr[ret], v2_t, t0, cpu_env);
13311 break;
13312 case OPC_SHLLV_QH:
13313 check_dsp(ctx);
13314 gen_helper_shll_qh(cpu_gpr[ret], v2_t, v1_t, cpu_env);
13315 break;
13316 case OPC_SHLL_S_QH:
13317 check_dsp(ctx);
13318 gen_helper_shll_s_qh(cpu_gpr[ret], v2_t, t0, cpu_env);
13319 break;
13320 case OPC_SHLLV_S_QH:
13321 check_dsp(ctx);
13322 gen_helper_shll_s_qh(cpu_gpr[ret], v2_t, v1_t, cpu_env);
13323 break;
13324 case OPC_SHRA_OB:
13325 check_dspr2(ctx);
13326 gen_helper_shra_ob(cpu_gpr[ret], v2_t, t0);
13327 break;
13328 case OPC_SHRAV_OB:
13329 check_dspr2(ctx);
13330 gen_helper_shra_ob(cpu_gpr[ret], v2_t, v1_t);
13331 break;
13332 case OPC_SHRA_R_OB:
13333 check_dspr2(ctx);
13334 gen_helper_shra_r_ob(cpu_gpr[ret], v2_t, t0);
13335 break;
13336 case OPC_SHRAV_R_OB:
13337 check_dspr2(ctx);
13338 gen_helper_shra_r_ob(cpu_gpr[ret], v2_t, v1_t);
13339 break;
13340 case OPC_SHRA_PW:
13341 check_dsp(ctx);
13342 gen_helper_shra_pw(cpu_gpr[ret], v2_t, t0);
13343 break;
13344 case OPC_SHRAV_PW:
13345 check_dsp(ctx);
13346 gen_helper_shra_pw(cpu_gpr[ret], v2_t, v1_t);
13347 break;
13348 case OPC_SHRA_R_PW:
13349 check_dsp(ctx);
13350 gen_helper_shra_r_pw(cpu_gpr[ret], v2_t, t0);
13351 break;
13352 case OPC_SHRAV_R_PW:
13353 check_dsp(ctx);
13354 gen_helper_shra_r_pw(cpu_gpr[ret], v2_t, v1_t);
13355 break;
13356 case OPC_SHRA_QH:
13357 check_dsp(ctx);
13358 gen_helper_shra_qh(cpu_gpr[ret], v2_t, t0);
13359 break;
13360 case OPC_SHRAV_QH:
13361 check_dsp(ctx);
13362 gen_helper_shra_qh(cpu_gpr[ret], v2_t, v1_t);
13363 break;
13364 case OPC_SHRA_R_QH:
13365 check_dsp(ctx);
13366 gen_helper_shra_r_qh(cpu_gpr[ret], v2_t, t0);
13367 break;
13368 case OPC_SHRAV_R_QH:
13369 check_dsp(ctx);
13370 gen_helper_shra_r_qh(cpu_gpr[ret], v2_t, v1_t);
13371 break;
13372 case OPC_SHRL_OB:
13373 check_dsp(ctx);
13374 gen_helper_shrl_ob(cpu_gpr[ret], v2_t, t0);
13375 break;
13376 case OPC_SHRLV_OB:
13377 check_dsp(ctx);
13378 gen_helper_shrl_ob(cpu_gpr[ret], v2_t, v1_t);
13379 break;
13380 case OPC_SHRL_QH:
13381 check_dspr2(ctx);
13382 gen_helper_shrl_qh(cpu_gpr[ret], v2_t, t0);
13383 break;
13384 case OPC_SHRLV_QH:
13385 check_dspr2(ctx);
13386 gen_helper_shrl_qh(cpu_gpr[ret], v2_t, v1_t);
13387 break;
13388 default: /* Invalid */
13389 MIPS_INVAL("MASK SHLL.OB");
13390 generate_exception(ctx, EXCP_RI);
13391 break;
13393 break;
13394 #endif
13397 tcg_temp_free(t0);
13398 tcg_temp_free(v1_t);
13399 tcg_temp_free(v2_t);
13400 (void)opn; /* avoid a compiler warning */
13401 MIPS_DEBUG("%s", opn);
13404 static void gen_mipsdsp_multiply(DisasContext *ctx, uint32_t op1, uint32_t op2,
13405 int ret, int v1, int v2, int check_ret)
13407 const char *opn = "mipsdsp multiply";
13408 TCGv_i32 t0;
13409 TCGv v1_t;
13410 TCGv v2_t;
13412 if ((ret == 0) && (check_ret == 1)) {
13413 /* Treat as NOP. */
13414 MIPS_DEBUG("NOP");
13415 return;
13418 t0 = tcg_temp_new_i32();
13419 v1_t = tcg_temp_new();
13420 v2_t = tcg_temp_new();
13422 tcg_gen_movi_i32(t0, ret);
13423 gen_load_gpr(v1_t, v1);
13424 gen_load_gpr(v2_t, v2);
13426 switch (op1) {
13427 /* OPC_MULT_G_2E, OPC_ADDUH_QB_DSP, OPC_MUL_PH_DSP have
13428 * the same mask and op1. */
13429 case OPC_MULT_G_2E:
13430 check_dspr2(ctx);
13431 switch (op2) {
13432 case OPC_MUL_PH:
13433 gen_helper_mul_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13434 break;
13435 case OPC_MUL_S_PH:
13436 gen_helper_mul_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13437 break;
13438 case OPC_MULQ_S_W:
13439 gen_helper_mulq_s_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13440 break;
13441 case OPC_MULQ_RS_W:
13442 gen_helper_mulq_rs_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13443 break;
13445 break;
13446 case OPC_DPA_W_PH_DSP:
13447 switch (op2) {
13448 case OPC_DPAU_H_QBL:
13449 check_dsp(ctx);
13450 gen_helper_dpau_h_qbl(t0, v1_t, v2_t, cpu_env);
13451 break;
13452 case OPC_DPAU_H_QBR:
13453 check_dsp(ctx);
13454 gen_helper_dpau_h_qbr(t0, v1_t, v2_t, cpu_env);
13455 break;
13456 case OPC_DPSU_H_QBL:
13457 check_dsp(ctx);
13458 gen_helper_dpsu_h_qbl(t0, v1_t, v2_t, cpu_env);
13459 break;
13460 case OPC_DPSU_H_QBR:
13461 check_dsp(ctx);
13462 gen_helper_dpsu_h_qbr(t0, v1_t, v2_t, cpu_env);
13463 break;
13464 case OPC_DPA_W_PH:
13465 check_dspr2(ctx);
13466 gen_helper_dpa_w_ph(t0, v1_t, v2_t, cpu_env);
13467 break;
13468 case OPC_DPAX_W_PH:
13469 check_dspr2(ctx);
13470 gen_helper_dpax_w_ph(t0, v1_t, v2_t, cpu_env);
13471 break;
13472 case OPC_DPAQ_S_W_PH:
13473 check_dsp(ctx);
13474 gen_helper_dpaq_s_w_ph(t0, v1_t, v2_t, cpu_env);
13475 break;
13476 case OPC_DPAQX_S_W_PH:
13477 check_dspr2(ctx);
13478 gen_helper_dpaqx_s_w_ph(t0, v1_t, v2_t, cpu_env);
13479 break;
13480 case OPC_DPAQX_SA_W_PH:
13481 check_dspr2(ctx);
13482 gen_helper_dpaqx_sa_w_ph(t0, v1_t, v2_t, cpu_env);
13483 break;
13484 case OPC_DPS_W_PH:
13485 check_dspr2(ctx);
13486 gen_helper_dps_w_ph(t0, v1_t, v2_t, cpu_env);
13487 break;
13488 case OPC_DPSX_W_PH:
13489 check_dspr2(ctx);
13490 gen_helper_dpsx_w_ph(t0, v1_t, v2_t, cpu_env);
13491 break;
13492 case OPC_DPSQ_S_W_PH:
13493 check_dsp(ctx);
13494 gen_helper_dpsq_s_w_ph(t0, v1_t, v2_t, cpu_env);
13495 break;
13496 case OPC_DPSQX_S_W_PH:
13497 check_dspr2(ctx);
13498 gen_helper_dpsqx_s_w_ph(t0, v1_t, v2_t, cpu_env);
13499 break;
13500 case OPC_DPSQX_SA_W_PH:
13501 check_dspr2(ctx);
13502 gen_helper_dpsqx_sa_w_ph(t0, v1_t, v2_t, cpu_env);
13503 break;
13504 case OPC_MULSAQ_S_W_PH:
13505 check_dsp(ctx);
13506 gen_helper_mulsaq_s_w_ph(t0, v1_t, v2_t, cpu_env);
13507 break;
13508 case OPC_DPAQ_SA_L_W:
13509 check_dsp(ctx);
13510 gen_helper_dpaq_sa_l_w(t0, v1_t, v2_t, cpu_env);
13511 break;
13512 case OPC_DPSQ_SA_L_W:
13513 check_dsp(ctx);
13514 gen_helper_dpsq_sa_l_w(t0, v1_t, v2_t, cpu_env);
13515 break;
13516 case OPC_MAQ_S_W_PHL:
13517 check_dsp(ctx);
13518 gen_helper_maq_s_w_phl(t0, v1_t, v2_t, cpu_env);
13519 break;
13520 case OPC_MAQ_S_W_PHR:
13521 check_dsp(ctx);
13522 gen_helper_maq_s_w_phr(t0, v1_t, v2_t, cpu_env);
13523 break;
13524 case OPC_MAQ_SA_W_PHL:
13525 check_dsp(ctx);
13526 gen_helper_maq_sa_w_phl(t0, v1_t, v2_t, cpu_env);
13527 break;
13528 case OPC_MAQ_SA_W_PHR:
13529 check_dsp(ctx);
13530 gen_helper_maq_sa_w_phr(t0, v1_t, v2_t, cpu_env);
13531 break;
13532 case OPC_MULSA_W_PH:
13533 check_dspr2(ctx);
13534 gen_helper_mulsa_w_ph(t0, v1_t, v2_t, cpu_env);
13535 break;
13537 break;
13538 #ifdef TARGET_MIPS64
13539 case OPC_DPAQ_W_QH_DSP:
13541 int ac = ret & 0x03;
13542 tcg_gen_movi_i32(t0, ac);
13544 switch (op2) {
13545 case OPC_DMADD:
13546 check_dsp(ctx);
13547 gen_helper_dmadd(v1_t, v2_t, t0, cpu_env);
13548 break;
13549 case OPC_DMADDU:
13550 check_dsp(ctx);
13551 gen_helper_dmaddu(v1_t, v2_t, t0, cpu_env);
13552 break;
13553 case OPC_DMSUB:
13554 check_dsp(ctx);
13555 gen_helper_dmsub(v1_t, v2_t, t0, cpu_env);
13556 break;
13557 case OPC_DMSUBU:
13558 check_dsp(ctx);
13559 gen_helper_dmsubu(v1_t, v2_t, t0, cpu_env);
13560 break;
13561 case OPC_DPA_W_QH:
13562 check_dspr2(ctx);
13563 gen_helper_dpa_w_qh(v1_t, v2_t, t0, cpu_env);
13564 break;
13565 case OPC_DPAQ_S_W_QH:
13566 check_dsp(ctx);
13567 gen_helper_dpaq_s_w_qh(v1_t, v2_t, t0, cpu_env);
13568 break;
13569 case OPC_DPAQ_SA_L_PW:
13570 check_dsp(ctx);
13571 gen_helper_dpaq_sa_l_pw(v1_t, v2_t, t0, cpu_env);
13572 break;
13573 case OPC_DPAU_H_OBL:
13574 check_dsp(ctx);
13575 gen_helper_dpau_h_obl(v1_t, v2_t, t0, cpu_env);
13576 break;
13577 case OPC_DPAU_H_OBR:
13578 check_dsp(ctx);
13579 gen_helper_dpau_h_obr(v1_t, v2_t, t0, cpu_env);
13580 break;
13581 case OPC_DPS_W_QH:
13582 check_dspr2(ctx);
13583 gen_helper_dps_w_qh(v1_t, v2_t, t0, cpu_env);
13584 break;
13585 case OPC_DPSQ_S_W_QH:
13586 check_dsp(ctx);
13587 gen_helper_dpsq_s_w_qh(v1_t, v2_t, t0, cpu_env);
13588 break;
13589 case OPC_DPSQ_SA_L_PW:
13590 check_dsp(ctx);
13591 gen_helper_dpsq_sa_l_pw(v1_t, v2_t, t0, cpu_env);
13592 break;
13593 case OPC_DPSU_H_OBL:
13594 check_dsp(ctx);
13595 gen_helper_dpsu_h_obl(v1_t, v2_t, t0, cpu_env);
13596 break;
13597 case OPC_DPSU_H_OBR:
13598 check_dsp(ctx);
13599 gen_helper_dpsu_h_obr(v1_t, v2_t, t0, cpu_env);
13600 break;
13601 case OPC_MAQ_S_L_PWL:
13602 check_dsp(ctx);
13603 gen_helper_maq_s_l_pwl(v1_t, v2_t, t0, cpu_env);
13604 break;
13605 case OPC_MAQ_S_L_PWR:
13606 check_dsp(ctx);
13607 gen_helper_maq_s_l_pwr(v1_t, v2_t, t0, cpu_env);
13608 break;
13609 case OPC_MAQ_S_W_QHLL:
13610 check_dsp(ctx);
13611 gen_helper_maq_s_w_qhll(v1_t, v2_t, t0, cpu_env);
13612 break;
13613 case OPC_MAQ_SA_W_QHLL:
13614 check_dsp(ctx);
13615 gen_helper_maq_sa_w_qhll(v1_t, v2_t, t0, cpu_env);
13616 break;
13617 case OPC_MAQ_S_W_QHLR:
13618 check_dsp(ctx);
13619 gen_helper_maq_s_w_qhlr(v1_t, v2_t, t0, cpu_env);
13620 break;
13621 case OPC_MAQ_SA_W_QHLR:
13622 check_dsp(ctx);
13623 gen_helper_maq_sa_w_qhlr(v1_t, v2_t, t0, cpu_env);
13624 break;
13625 case OPC_MAQ_S_W_QHRL:
13626 check_dsp(ctx);
13627 gen_helper_maq_s_w_qhrl(v1_t, v2_t, t0, cpu_env);
13628 break;
13629 case OPC_MAQ_SA_W_QHRL:
13630 check_dsp(ctx);
13631 gen_helper_maq_sa_w_qhrl(v1_t, v2_t, t0, cpu_env);
13632 break;
13633 case OPC_MAQ_S_W_QHRR:
13634 check_dsp(ctx);
13635 gen_helper_maq_s_w_qhrr(v1_t, v2_t, t0, cpu_env);
13636 break;
13637 case OPC_MAQ_SA_W_QHRR:
13638 check_dsp(ctx);
13639 gen_helper_maq_sa_w_qhrr(v1_t, v2_t, t0, cpu_env);
13640 break;
13641 case OPC_MULSAQ_S_L_PW:
13642 check_dsp(ctx);
13643 gen_helper_mulsaq_s_l_pw(v1_t, v2_t, t0, cpu_env);
13644 break;
13645 case OPC_MULSAQ_S_W_QH:
13646 check_dsp(ctx);
13647 gen_helper_mulsaq_s_w_qh(v1_t, v2_t, t0, cpu_env);
13648 break;
13651 break;
13652 #endif
13653 case OPC_ADDU_QB_DSP:
13654 switch (op2) {
13655 case OPC_MULEU_S_PH_QBL:
13656 check_dsp(ctx);
13657 gen_helper_muleu_s_ph_qbl(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13658 break;
13659 case OPC_MULEU_S_PH_QBR:
13660 check_dsp(ctx);
13661 gen_helper_muleu_s_ph_qbr(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13662 break;
13663 case OPC_MULQ_RS_PH:
13664 check_dsp(ctx);
13665 gen_helper_mulq_rs_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13666 break;
13667 case OPC_MULEQ_S_W_PHL:
13668 check_dsp(ctx);
13669 gen_helper_muleq_s_w_phl(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13670 break;
13671 case OPC_MULEQ_S_W_PHR:
13672 check_dsp(ctx);
13673 gen_helper_muleq_s_w_phr(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13674 break;
13675 case OPC_MULQ_S_PH:
13676 check_dspr2(ctx);
13677 gen_helper_mulq_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13678 break;
13680 break;
13681 #ifdef TARGET_MIPS64
13682 case OPC_ADDU_OB_DSP:
13683 switch (op2) {
13684 case OPC_MULEQ_S_PW_QHL:
13685 check_dsp(ctx);
13686 gen_helper_muleq_s_pw_qhl(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13687 break;
13688 case OPC_MULEQ_S_PW_QHR:
13689 check_dsp(ctx);
13690 gen_helper_muleq_s_pw_qhr(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13691 break;
13692 case OPC_MULEU_S_QH_OBL:
13693 check_dsp(ctx);
13694 gen_helper_muleu_s_qh_obl(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13695 break;
13696 case OPC_MULEU_S_QH_OBR:
13697 check_dsp(ctx);
13698 gen_helper_muleu_s_qh_obr(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13699 break;
13700 case OPC_MULQ_RS_QH:
13701 check_dsp(ctx);
13702 gen_helper_mulq_rs_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13703 break;
13705 break;
13706 #endif
13709 tcg_temp_free_i32(t0);
13710 tcg_temp_free(v1_t);
13711 tcg_temp_free(v2_t);
13713 (void)opn; /* avoid a compiler warning */
13714 MIPS_DEBUG("%s", opn);
13718 static void gen_mipsdsp_bitinsn(DisasContext *ctx, uint32_t op1, uint32_t op2,
13719 int ret, int val)
13721 const char *opn = "mipsdsp Bit/ Manipulation";
13722 int16_t imm;
13723 TCGv t0;
13724 TCGv val_t;
13726 if (ret == 0) {
13727 /* Treat as NOP. */
13728 MIPS_DEBUG("NOP");
13729 return;
13732 t0 = tcg_temp_new();
13733 val_t = tcg_temp_new();
13734 gen_load_gpr(val_t, val);
13736 switch (op1) {
13737 case OPC_ABSQ_S_PH_DSP:
13738 switch (op2) {
13739 case OPC_BITREV:
13740 check_dsp(ctx);
13741 gen_helper_bitrev(cpu_gpr[ret], val_t);
13742 break;
13743 case OPC_REPL_QB:
13744 check_dsp(ctx);
13746 target_long result;
13747 imm = (ctx->opcode >> 16) & 0xFF;
13748 result = (uint32_t)imm << 24 |
13749 (uint32_t)imm << 16 |
13750 (uint32_t)imm << 8 |
13751 (uint32_t)imm;
13752 result = (int32_t)result;
13753 tcg_gen_movi_tl(cpu_gpr[ret], result);
13755 break;
13756 case OPC_REPLV_QB:
13757 check_dsp(ctx);
13758 tcg_gen_ext8u_tl(cpu_gpr[ret], val_t);
13759 tcg_gen_shli_tl(t0, cpu_gpr[ret], 8);
13760 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
13761 tcg_gen_shli_tl(t0, cpu_gpr[ret], 16);
13762 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
13763 tcg_gen_ext32s_tl(cpu_gpr[ret], cpu_gpr[ret]);
13764 break;
13765 case OPC_REPL_PH:
13766 check_dsp(ctx);
13768 imm = (ctx->opcode >> 16) & 0x03FF;
13769 imm = (int16_t)(imm << 6) >> 6;
13770 tcg_gen_movi_tl(cpu_gpr[ret], \
13771 (target_long)((int32_t)imm << 16 | \
13772 (uint16_t)imm));
13774 break;
13775 case OPC_REPLV_PH:
13776 check_dsp(ctx);
13777 tcg_gen_ext16u_tl(cpu_gpr[ret], val_t);
13778 tcg_gen_shli_tl(t0, cpu_gpr[ret], 16);
13779 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
13780 tcg_gen_ext32s_tl(cpu_gpr[ret], cpu_gpr[ret]);
13781 break;
13783 break;
13784 #ifdef TARGET_MIPS64
13785 case OPC_ABSQ_S_QH_DSP:
13786 switch (op2) {
13787 case OPC_REPL_OB:
13788 check_dsp(ctx);
13790 target_long temp;
13792 imm = (ctx->opcode >> 16) & 0xFF;
13793 temp = ((uint64_t)imm << 8) | (uint64_t)imm;
13794 temp = (temp << 16) | temp;
13795 temp = (temp << 32) | temp;
13796 tcg_gen_movi_tl(cpu_gpr[ret], temp);
13797 break;
13799 case OPC_REPL_PW:
13800 check_dsp(ctx);
13802 target_long temp;
13804 imm = (ctx->opcode >> 16) & 0x03FF;
13805 imm = (int16_t)(imm << 6) >> 6;
13806 temp = ((target_long)imm << 32) \
13807 | ((target_long)imm & 0xFFFFFFFF);
13808 tcg_gen_movi_tl(cpu_gpr[ret], temp);
13809 break;
13811 case OPC_REPL_QH:
13812 check_dsp(ctx);
13814 target_long temp;
13816 imm = (ctx->opcode >> 16) & 0x03FF;
13817 imm = (int16_t)(imm << 6) >> 6;
13819 temp = ((uint64_t)(uint16_t)imm << 48) |
13820 ((uint64_t)(uint16_t)imm << 32) |
13821 ((uint64_t)(uint16_t)imm << 16) |
13822 (uint64_t)(uint16_t)imm;
13823 tcg_gen_movi_tl(cpu_gpr[ret], temp);
13824 break;
13826 case OPC_REPLV_OB:
13827 check_dsp(ctx);
13828 tcg_gen_ext8u_tl(cpu_gpr[ret], val_t);
13829 tcg_gen_shli_tl(t0, cpu_gpr[ret], 8);
13830 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
13831 tcg_gen_shli_tl(t0, cpu_gpr[ret], 16);
13832 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
13833 tcg_gen_shli_tl(t0, cpu_gpr[ret], 32);
13834 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
13835 break;
13836 case OPC_REPLV_PW:
13837 check_dsp(ctx);
13838 tcg_gen_ext32u_i64(cpu_gpr[ret], val_t);
13839 tcg_gen_shli_tl(t0, cpu_gpr[ret], 32);
13840 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
13841 break;
13842 case OPC_REPLV_QH:
13843 check_dsp(ctx);
13844 tcg_gen_ext16u_tl(cpu_gpr[ret], val_t);
13845 tcg_gen_shli_tl(t0, cpu_gpr[ret], 16);
13846 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
13847 tcg_gen_shli_tl(t0, cpu_gpr[ret], 32);
13848 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
13849 break;
13851 break;
13852 #endif
13854 tcg_temp_free(t0);
13855 tcg_temp_free(val_t);
13857 (void)opn; /* avoid a compiler warning */
13858 MIPS_DEBUG("%s", opn);
13861 static void gen_mipsdsp_add_cmp_pick(DisasContext *ctx,
13862 uint32_t op1, uint32_t op2,
13863 int ret, int v1, int v2, int check_ret)
13865 const char *opn = "mipsdsp add compare pick";
13866 TCGv t1;
13867 TCGv v1_t;
13868 TCGv v2_t;
13870 if ((ret == 0) && (check_ret == 1)) {
13871 /* Treat as NOP. */
13872 MIPS_DEBUG("NOP");
13873 return;
13876 t1 = tcg_temp_new();
13877 v1_t = tcg_temp_new();
13878 v2_t = tcg_temp_new();
13880 gen_load_gpr(v1_t, v1);
13881 gen_load_gpr(v2_t, v2);
13883 switch (op1) {
13884 case OPC_CMPU_EQ_QB_DSP:
13885 switch (op2) {
13886 case OPC_CMPU_EQ_QB:
13887 check_dsp(ctx);
13888 gen_helper_cmpu_eq_qb(v1_t, v2_t, cpu_env);
13889 break;
13890 case OPC_CMPU_LT_QB:
13891 check_dsp(ctx);
13892 gen_helper_cmpu_lt_qb(v1_t, v2_t, cpu_env);
13893 break;
13894 case OPC_CMPU_LE_QB:
13895 check_dsp(ctx);
13896 gen_helper_cmpu_le_qb(v1_t, v2_t, cpu_env);
13897 break;
13898 case OPC_CMPGU_EQ_QB:
13899 check_dsp(ctx);
13900 gen_helper_cmpgu_eq_qb(cpu_gpr[ret], v1_t, v2_t);
13901 break;
13902 case OPC_CMPGU_LT_QB:
13903 check_dsp(ctx);
13904 gen_helper_cmpgu_lt_qb(cpu_gpr[ret], v1_t, v2_t);
13905 break;
13906 case OPC_CMPGU_LE_QB:
13907 check_dsp(ctx);
13908 gen_helper_cmpgu_le_qb(cpu_gpr[ret], v1_t, v2_t);
13909 break;
13910 case OPC_CMPGDU_EQ_QB:
13911 check_dspr2(ctx);
13912 gen_helper_cmpgu_eq_qb(t1, v1_t, v2_t);
13913 tcg_gen_mov_tl(cpu_gpr[ret], t1);
13914 tcg_gen_andi_tl(cpu_dspctrl, cpu_dspctrl, 0xF0FFFFFF);
13915 tcg_gen_shli_tl(t1, t1, 24);
13916 tcg_gen_or_tl(cpu_dspctrl, cpu_dspctrl, t1);
13917 break;
13918 case OPC_CMPGDU_LT_QB:
13919 check_dspr2(ctx);
13920 gen_helper_cmpgu_lt_qb(t1, v1_t, v2_t);
13921 tcg_gen_mov_tl(cpu_gpr[ret], t1);
13922 tcg_gen_andi_tl(cpu_dspctrl, cpu_dspctrl, 0xF0FFFFFF);
13923 tcg_gen_shli_tl(t1, t1, 24);
13924 tcg_gen_or_tl(cpu_dspctrl, cpu_dspctrl, t1);
13925 break;
13926 case OPC_CMPGDU_LE_QB:
13927 check_dspr2(ctx);
13928 gen_helper_cmpgu_le_qb(t1, v1_t, v2_t);
13929 tcg_gen_mov_tl(cpu_gpr[ret], t1);
13930 tcg_gen_andi_tl(cpu_dspctrl, cpu_dspctrl, 0xF0FFFFFF);
13931 tcg_gen_shli_tl(t1, t1, 24);
13932 tcg_gen_or_tl(cpu_dspctrl, cpu_dspctrl, t1);
13933 break;
13934 case OPC_CMP_EQ_PH:
13935 check_dsp(ctx);
13936 gen_helper_cmp_eq_ph(v1_t, v2_t, cpu_env);
13937 break;
13938 case OPC_CMP_LT_PH:
13939 check_dsp(ctx);
13940 gen_helper_cmp_lt_ph(v1_t, v2_t, cpu_env);
13941 break;
13942 case OPC_CMP_LE_PH:
13943 check_dsp(ctx);
13944 gen_helper_cmp_le_ph(v1_t, v2_t, cpu_env);
13945 break;
13946 case OPC_PICK_QB:
13947 check_dsp(ctx);
13948 gen_helper_pick_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13949 break;
13950 case OPC_PICK_PH:
13951 check_dsp(ctx);
13952 gen_helper_pick_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13953 break;
13954 case OPC_PACKRL_PH:
13955 check_dsp(ctx);
13956 gen_helper_packrl_ph(cpu_gpr[ret], v1_t, v2_t);
13957 break;
13959 break;
13960 #ifdef TARGET_MIPS64
13961 case OPC_CMPU_EQ_OB_DSP:
13962 switch (op2) {
13963 case OPC_CMP_EQ_PW:
13964 check_dsp(ctx);
13965 gen_helper_cmp_eq_pw(v1_t, v2_t, cpu_env);
13966 break;
13967 case OPC_CMP_LT_PW:
13968 check_dsp(ctx);
13969 gen_helper_cmp_lt_pw(v1_t, v2_t, cpu_env);
13970 break;
13971 case OPC_CMP_LE_PW:
13972 check_dsp(ctx);
13973 gen_helper_cmp_le_pw(v1_t, v2_t, cpu_env);
13974 break;
13975 case OPC_CMP_EQ_QH:
13976 check_dsp(ctx);
13977 gen_helper_cmp_eq_qh(v1_t, v2_t, cpu_env);
13978 break;
13979 case OPC_CMP_LT_QH:
13980 check_dsp(ctx);
13981 gen_helper_cmp_lt_qh(v1_t, v2_t, cpu_env);
13982 break;
13983 case OPC_CMP_LE_QH:
13984 check_dsp(ctx);
13985 gen_helper_cmp_le_qh(v1_t, v2_t, cpu_env);
13986 break;
13987 case OPC_CMPGDU_EQ_OB:
13988 check_dspr2(ctx);
13989 gen_helper_cmpgdu_eq_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13990 break;
13991 case OPC_CMPGDU_LT_OB:
13992 check_dspr2(ctx);
13993 gen_helper_cmpgdu_lt_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13994 break;
13995 case OPC_CMPGDU_LE_OB:
13996 check_dspr2(ctx);
13997 gen_helper_cmpgdu_le_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13998 break;
13999 case OPC_CMPGU_EQ_OB:
14000 check_dsp(ctx);
14001 gen_helper_cmpgu_eq_ob(cpu_gpr[ret], v1_t, v2_t);
14002 break;
14003 case OPC_CMPGU_LT_OB:
14004 check_dsp(ctx);
14005 gen_helper_cmpgu_lt_ob(cpu_gpr[ret], v1_t, v2_t);
14006 break;
14007 case OPC_CMPGU_LE_OB:
14008 check_dsp(ctx);
14009 gen_helper_cmpgu_le_ob(cpu_gpr[ret], v1_t, v2_t);
14010 break;
14011 case OPC_CMPU_EQ_OB:
14012 check_dsp(ctx);
14013 gen_helper_cmpu_eq_ob(v1_t, v2_t, cpu_env);
14014 break;
14015 case OPC_CMPU_LT_OB:
14016 check_dsp(ctx);
14017 gen_helper_cmpu_lt_ob(v1_t, v2_t, cpu_env);
14018 break;
14019 case OPC_CMPU_LE_OB:
14020 check_dsp(ctx);
14021 gen_helper_cmpu_le_ob(v1_t, v2_t, cpu_env);
14022 break;
14023 case OPC_PACKRL_PW:
14024 check_dsp(ctx);
14025 gen_helper_packrl_pw(cpu_gpr[ret], v1_t, v2_t);
14026 break;
14027 case OPC_PICK_OB:
14028 check_dsp(ctx);
14029 gen_helper_pick_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
14030 break;
14031 case OPC_PICK_PW:
14032 check_dsp(ctx);
14033 gen_helper_pick_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
14034 break;
14035 case OPC_PICK_QH:
14036 check_dsp(ctx);
14037 gen_helper_pick_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
14038 break;
14040 break;
14041 #endif
14044 tcg_temp_free(t1);
14045 tcg_temp_free(v1_t);
14046 tcg_temp_free(v2_t);
14048 (void)opn; /* avoid a compiler warning */
14049 MIPS_DEBUG("%s", opn);
14052 static void gen_mipsdsp_append(CPUMIPSState *env, DisasContext *ctx,
14053 uint32_t op1, int rt, int rs, int sa)
14055 const char *opn = "mipsdsp append/dappend";
14056 TCGv t0;
14058 check_dspr2(ctx);
14060 if (rt == 0) {
14061 /* Treat as NOP. */
14062 MIPS_DEBUG("NOP");
14063 return;
14066 t0 = tcg_temp_new();
14067 gen_load_gpr(t0, rs);
14069 switch (op1) {
14070 case OPC_APPEND_DSP:
14071 switch (MASK_APPEND(ctx->opcode)) {
14072 case OPC_APPEND:
14073 if (sa != 0) {
14074 tcg_gen_deposit_tl(cpu_gpr[rt], t0, cpu_gpr[rt], sa, 32 - sa);
14076 tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]);
14077 break;
14078 case OPC_PREPEND:
14079 if (sa != 0) {
14080 tcg_gen_ext32u_tl(cpu_gpr[rt], cpu_gpr[rt]);
14081 tcg_gen_shri_tl(cpu_gpr[rt], cpu_gpr[rt], sa);
14082 tcg_gen_shli_tl(t0, t0, 32 - sa);
14083 tcg_gen_or_tl(cpu_gpr[rt], cpu_gpr[rt], t0);
14085 tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]);
14086 break;
14087 case OPC_BALIGN:
14088 sa &= 3;
14089 if (sa != 0 && sa != 2) {
14090 tcg_gen_shli_tl(cpu_gpr[rt], cpu_gpr[rt], 8 * sa);
14091 tcg_gen_ext32u_tl(t0, t0);
14092 tcg_gen_shri_tl(t0, t0, 8 * (4 - sa));
14093 tcg_gen_or_tl(cpu_gpr[rt], cpu_gpr[rt], t0);
14095 tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]);
14096 break;
14097 default: /* Invalid */
14098 MIPS_INVAL("MASK APPEND");
14099 generate_exception(ctx, EXCP_RI);
14100 break;
14102 break;
14103 #ifdef TARGET_MIPS64
14104 case OPC_DAPPEND_DSP:
14105 switch (MASK_DAPPEND(ctx->opcode)) {
14106 case OPC_DAPPEND:
14107 if (sa != 0) {
14108 tcg_gen_deposit_tl(cpu_gpr[rt], t0, cpu_gpr[rt], sa, 64 - sa);
14110 break;
14111 case OPC_PREPENDD:
14112 tcg_gen_shri_tl(cpu_gpr[rt], cpu_gpr[rt], 0x20 | sa);
14113 tcg_gen_shli_tl(t0, t0, 64 - (0x20 | sa));
14114 tcg_gen_or_tl(cpu_gpr[rt], t0, t0);
14115 break;
14116 case OPC_PREPENDW:
14117 if (sa != 0) {
14118 tcg_gen_shri_tl(cpu_gpr[rt], cpu_gpr[rt], sa);
14119 tcg_gen_shli_tl(t0, t0, 64 - sa);
14120 tcg_gen_or_tl(cpu_gpr[rt], cpu_gpr[rt], t0);
14122 break;
14123 case OPC_DBALIGN:
14124 sa &= 7;
14125 if (sa != 0 && sa != 2 && sa != 4) {
14126 tcg_gen_shli_tl(cpu_gpr[rt], cpu_gpr[rt], 8 * sa);
14127 tcg_gen_shri_tl(t0, t0, 8 * (8 - sa));
14128 tcg_gen_or_tl(cpu_gpr[rt], cpu_gpr[rt], t0);
14130 break;
14131 default: /* Invalid */
14132 MIPS_INVAL("MASK DAPPEND");
14133 generate_exception(ctx, EXCP_RI);
14134 break;
14136 break;
14137 #endif
14139 tcg_temp_free(t0);
14140 (void)opn; /* avoid a compiler warning */
14141 MIPS_DEBUG("%s", opn);
14144 static void gen_mipsdsp_accinsn(DisasContext *ctx, uint32_t op1, uint32_t op2,
14145 int ret, int v1, int v2, int check_ret)
14148 const char *opn = "mipsdsp accumulator";
14149 TCGv t0;
14150 TCGv t1;
14151 TCGv v1_t;
14152 TCGv v2_t;
14153 int16_t imm;
14155 if ((ret == 0) && (check_ret == 1)) {
14156 /* Treat as NOP. */
14157 MIPS_DEBUG("NOP");
14158 return;
14161 t0 = tcg_temp_new();
14162 t1 = tcg_temp_new();
14163 v1_t = tcg_temp_new();
14164 v2_t = tcg_temp_new();
14166 gen_load_gpr(v1_t, v1);
14167 gen_load_gpr(v2_t, v2);
14169 switch (op1) {
14170 case OPC_EXTR_W_DSP:
14171 check_dsp(ctx);
14172 switch (op2) {
14173 case OPC_EXTR_W:
14174 tcg_gen_movi_tl(t0, v2);
14175 tcg_gen_movi_tl(t1, v1);
14176 gen_helper_extr_w(cpu_gpr[ret], t0, t1, cpu_env);
14177 break;
14178 case OPC_EXTR_R_W:
14179 tcg_gen_movi_tl(t0, v2);
14180 tcg_gen_movi_tl(t1, v1);
14181 gen_helper_extr_r_w(cpu_gpr[ret], t0, t1, cpu_env);
14182 break;
14183 case OPC_EXTR_RS_W:
14184 tcg_gen_movi_tl(t0, v2);
14185 tcg_gen_movi_tl(t1, v1);
14186 gen_helper_extr_rs_w(cpu_gpr[ret], t0, t1, cpu_env);
14187 break;
14188 case OPC_EXTR_S_H:
14189 tcg_gen_movi_tl(t0, v2);
14190 tcg_gen_movi_tl(t1, v1);
14191 gen_helper_extr_s_h(cpu_gpr[ret], t0, t1, cpu_env);
14192 break;
14193 case OPC_EXTRV_S_H:
14194 tcg_gen_movi_tl(t0, v2);
14195 gen_helper_extr_s_h(cpu_gpr[ret], t0, v1_t, cpu_env);
14196 break;
14197 case OPC_EXTRV_W:
14198 tcg_gen_movi_tl(t0, v2);
14199 gen_helper_extr_w(cpu_gpr[ret], t0, v1_t, cpu_env);
14200 break;
14201 case OPC_EXTRV_R_W:
14202 tcg_gen_movi_tl(t0, v2);
14203 gen_helper_extr_r_w(cpu_gpr[ret], t0, v1_t, cpu_env);
14204 break;
14205 case OPC_EXTRV_RS_W:
14206 tcg_gen_movi_tl(t0, v2);
14207 gen_helper_extr_rs_w(cpu_gpr[ret], t0, v1_t, cpu_env);
14208 break;
14209 case OPC_EXTP:
14210 tcg_gen_movi_tl(t0, v2);
14211 tcg_gen_movi_tl(t1, v1);
14212 gen_helper_extp(cpu_gpr[ret], t0, t1, cpu_env);
14213 break;
14214 case OPC_EXTPV:
14215 tcg_gen_movi_tl(t0, v2);
14216 gen_helper_extp(cpu_gpr[ret], t0, v1_t, cpu_env);
14217 break;
14218 case OPC_EXTPDP:
14219 tcg_gen_movi_tl(t0, v2);
14220 tcg_gen_movi_tl(t1, v1);
14221 gen_helper_extpdp(cpu_gpr[ret], t0, t1, cpu_env);
14222 break;
14223 case OPC_EXTPDPV:
14224 tcg_gen_movi_tl(t0, v2);
14225 gen_helper_extpdp(cpu_gpr[ret], t0, v1_t, cpu_env);
14226 break;
14227 case OPC_SHILO:
14228 imm = (ctx->opcode >> 20) & 0x3F;
14229 tcg_gen_movi_tl(t0, ret);
14230 tcg_gen_movi_tl(t1, imm);
14231 gen_helper_shilo(t0, t1, cpu_env);
14232 break;
14233 case OPC_SHILOV:
14234 tcg_gen_movi_tl(t0, ret);
14235 gen_helper_shilo(t0, v1_t, cpu_env);
14236 break;
14237 case OPC_MTHLIP:
14238 tcg_gen_movi_tl(t0, ret);
14239 gen_helper_mthlip(t0, v1_t, cpu_env);
14240 break;
14241 case OPC_WRDSP:
14242 imm = (ctx->opcode >> 11) & 0x3FF;
14243 tcg_gen_movi_tl(t0, imm);
14244 gen_helper_wrdsp(v1_t, t0, cpu_env);
14245 break;
14246 case OPC_RDDSP:
14247 imm = (ctx->opcode >> 16) & 0x03FF;
14248 tcg_gen_movi_tl(t0, imm);
14249 gen_helper_rddsp(cpu_gpr[ret], t0, cpu_env);
14250 break;
14252 break;
14253 #ifdef TARGET_MIPS64
14254 case OPC_DEXTR_W_DSP:
14255 check_dsp(ctx);
14256 switch (op2) {
14257 case OPC_DMTHLIP:
14258 tcg_gen_movi_tl(t0, ret);
14259 gen_helper_dmthlip(v1_t, t0, cpu_env);
14260 break;
14261 case OPC_DSHILO:
14263 int shift = (ctx->opcode >> 19) & 0x7F;
14264 int ac = (ctx->opcode >> 11) & 0x03;
14265 tcg_gen_movi_tl(t0, shift);
14266 tcg_gen_movi_tl(t1, ac);
14267 gen_helper_dshilo(t0, t1, cpu_env);
14268 break;
14270 case OPC_DSHILOV:
14272 int ac = (ctx->opcode >> 11) & 0x03;
14273 tcg_gen_movi_tl(t0, ac);
14274 gen_helper_dshilo(v1_t, t0, cpu_env);
14275 break;
14277 case OPC_DEXTP:
14278 tcg_gen_movi_tl(t0, v2);
14279 tcg_gen_movi_tl(t1, v1);
14281 gen_helper_dextp(cpu_gpr[ret], t0, t1, cpu_env);
14282 break;
14283 case OPC_DEXTPV:
14284 tcg_gen_movi_tl(t0, v2);
14285 gen_helper_dextp(cpu_gpr[ret], t0, v1_t, cpu_env);
14286 break;
14287 case OPC_DEXTPDP:
14288 tcg_gen_movi_tl(t0, v2);
14289 tcg_gen_movi_tl(t1, v1);
14290 gen_helper_dextpdp(cpu_gpr[ret], t0, t1, cpu_env);
14291 break;
14292 case OPC_DEXTPDPV:
14293 tcg_gen_movi_tl(t0, v2);
14294 gen_helper_dextpdp(cpu_gpr[ret], t0, v1_t, cpu_env);
14295 break;
14296 case OPC_DEXTR_L:
14297 tcg_gen_movi_tl(t0, v2);
14298 tcg_gen_movi_tl(t1, v1);
14299 gen_helper_dextr_l(cpu_gpr[ret], t0, t1, cpu_env);
14300 break;
14301 case OPC_DEXTR_R_L:
14302 tcg_gen_movi_tl(t0, v2);
14303 tcg_gen_movi_tl(t1, v1);
14304 gen_helper_dextr_r_l(cpu_gpr[ret], t0, t1, cpu_env);
14305 break;
14306 case OPC_DEXTR_RS_L:
14307 tcg_gen_movi_tl(t0, v2);
14308 tcg_gen_movi_tl(t1, v1);
14309 gen_helper_dextr_rs_l(cpu_gpr[ret], t0, t1, cpu_env);
14310 break;
14311 case OPC_DEXTR_W:
14312 tcg_gen_movi_tl(t0, v2);
14313 tcg_gen_movi_tl(t1, v1);
14314 gen_helper_dextr_w(cpu_gpr[ret], t0, t1, cpu_env);
14315 break;
14316 case OPC_DEXTR_R_W:
14317 tcg_gen_movi_tl(t0, v2);
14318 tcg_gen_movi_tl(t1, v1);
14319 gen_helper_dextr_r_w(cpu_gpr[ret], t0, t1, cpu_env);
14320 break;
14321 case OPC_DEXTR_RS_W:
14322 tcg_gen_movi_tl(t0, v2);
14323 tcg_gen_movi_tl(t1, v1);
14324 gen_helper_dextr_rs_w(cpu_gpr[ret], t0, t1, cpu_env);
14325 break;
14326 case OPC_DEXTR_S_H:
14327 tcg_gen_movi_tl(t0, v2);
14328 tcg_gen_movi_tl(t1, v1);
14329 gen_helper_dextr_s_h(cpu_gpr[ret], t0, t1, cpu_env);
14330 break;
14331 case OPC_DEXTRV_S_H:
14332 tcg_gen_movi_tl(t0, v2);
14333 tcg_gen_movi_tl(t1, v1);
14334 gen_helper_dextr_s_h(cpu_gpr[ret], t0, t1, cpu_env);
14335 break;
14336 case OPC_DEXTRV_L:
14337 tcg_gen_movi_tl(t0, v2);
14338 gen_helper_dextr_l(cpu_gpr[ret], t0, v1_t, cpu_env);
14339 break;
14340 case OPC_DEXTRV_R_L:
14341 tcg_gen_movi_tl(t0, v2);
14342 gen_helper_dextr_r_l(cpu_gpr[ret], t0, v1_t, cpu_env);
14343 break;
14344 case OPC_DEXTRV_RS_L:
14345 tcg_gen_movi_tl(t0, v2);
14346 gen_helper_dextr_rs_l(cpu_gpr[ret], t0, v1_t, cpu_env);
14347 break;
14348 case OPC_DEXTRV_W:
14349 tcg_gen_movi_tl(t0, v2);
14350 gen_helper_dextr_w(cpu_gpr[ret], t0, v1_t, cpu_env);
14351 break;
14352 case OPC_DEXTRV_R_W:
14353 tcg_gen_movi_tl(t0, v2);
14354 gen_helper_dextr_r_w(cpu_gpr[ret], t0, v1_t, cpu_env);
14355 break;
14356 case OPC_DEXTRV_RS_W:
14357 tcg_gen_movi_tl(t0, v2);
14358 gen_helper_dextr_rs_w(cpu_gpr[ret], t0, v1_t, cpu_env);
14359 break;
14361 break;
14362 #endif
14365 tcg_temp_free(t0);
14366 tcg_temp_free(t1);
14367 tcg_temp_free(v1_t);
14368 tcg_temp_free(v2_t);
14370 (void)opn; /* avoid a compiler warning */
14371 MIPS_DEBUG("%s", opn);
14374 /* End MIPSDSP functions. */
14376 static void decode_opc (CPUMIPSState *env, DisasContext *ctx)
14378 int32_t offset;
14379 int rs, rt, rd, sa;
14380 uint32_t op, op1, op2;
14381 int16_t imm;
14383 /* make sure instructions are on a word boundary */
14384 if (ctx->pc & 0x3) {
14385 env->CP0_BadVAddr = ctx->pc;
14386 generate_exception(ctx, EXCP_AdEL);
14387 return;
14390 /* Handle blikely not taken case */
14391 if ((ctx->hflags & MIPS_HFLAG_BMASK_BASE) == MIPS_HFLAG_BL) {
14392 int l1 = gen_new_label();
14394 MIPS_DEBUG("blikely condition (" TARGET_FMT_lx ")", ctx->pc + 4);
14395 tcg_gen_brcondi_tl(TCG_COND_NE, bcond, 0, l1);
14396 tcg_gen_movi_i32(hflags, ctx->hflags & ~MIPS_HFLAG_BMASK);
14397 gen_goto_tb(ctx, 1, ctx->pc + 4);
14398 gen_set_label(l1);
14401 if (unlikely(qemu_loglevel_mask(CPU_LOG_TB_OP | CPU_LOG_TB_OP_OPT))) {
14402 tcg_gen_debug_insn_start(ctx->pc);
14405 op = MASK_OP_MAJOR(ctx->opcode);
14406 rs = (ctx->opcode >> 21) & 0x1f;
14407 rt = (ctx->opcode >> 16) & 0x1f;
14408 rd = (ctx->opcode >> 11) & 0x1f;
14409 sa = (ctx->opcode >> 6) & 0x1f;
14410 imm = (int16_t)ctx->opcode;
14411 switch (op) {
14412 case OPC_SPECIAL:
14413 op1 = MASK_SPECIAL(ctx->opcode);
14414 switch (op1) {
14415 case OPC_SLL: /* Shift with immediate */
14416 case OPC_SRA:
14417 gen_shift_imm(ctx, op1, rd, rt, sa);
14418 break;
14419 case OPC_SRL:
14420 switch ((ctx->opcode >> 21) & 0x1f) {
14421 case 1:
14422 /* rotr is decoded as srl on non-R2 CPUs */
14423 if (ctx->insn_flags & ISA_MIPS32R2) {
14424 op1 = OPC_ROTR;
14426 /* Fallthrough */
14427 case 0:
14428 gen_shift_imm(ctx, op1, rd, rt, sa);
14429 break;
14430 default:
14431 generate_exception(ctx, EXCP_RI);
14432 break;
14434 break;
14435 case OPC_MOVN: /* Conditional move */
14436 case OPC_MOVZ:
14437 check_insn(ctx, ISA_MIPS4 | ISA_MIPS32 |
14438 INSN_LOONGSON2E | INSN_LOONGSON2F);
14439 gen_cond_move(ctx, op1, rd, rs, rt);
14440 break;
14441 case OPC_ADD ... OPC_SUBU:
14442 gen_arith(ctx, op1, rd, rs, rt);
14443 break;
14444 case OPC_SLLV: /* Shifts */
14445 case OPC_SRAV:
14446 gen_shift(ctx, op1, rd, rs, rt);
14447 break;
14448 case OPC_SRLV:
14449 switch ((ctx->opcode >> 6) & 0x1f) {
14450 case 1:
14451 /* rotrv is decoded as srlv on non-R2 CPUs */
14452 if (ctx->insn_flags & ISA_MIPS32R2) {
14453 op1 = OPC_ROTRV;
14455 /* Fallthrough */
14456 case 0:
14457 gen_shift(ctx, op1, rd, rs, rt);
14458 break;
14459 default:
14460 generate_exception(ctx, EXCP_RI);
14461 break;
14463 break;
14464 case OPC_SLT: /* Set on less than */
14465 case OPC_SLTU:
14466 gen_slt(ctx, op1, rd, rs, rt);
14467 break;
14468 case OPC_AND: /* Logic*/
14469 case OPC_OR:
14470 case OPC_NOR:
14471 case OPC_XOR:
14472 gen_logic(ctx, op1, rd, rs, rt);
14473 break;
14474 case OPC_MULT:
14475 case OPC_MULTU:
14476 if (sa) {
14477 check_insn(ctx, INSN_VR54XX);
14478 op1 = MASK_MUL_VR54XX(ctx->opcode);
14479 gen_mul_vr54xx(ctx, op1, rd, rs, rt);
14480 } else {
14481 gen_muldiv(ctx, op1, rd & 3, rs, rt);
14483 break;
14484 case OPC_DIV:
14485 case OPC_DIVU:
14486 gen_muldiv(ctx, op1, 0, rs, rt);
14487 break;
14488 case OPC_JR ... OPC_JALR:
14489 gen_compute_branch(ctx, op1, 4, rs, rd, sa);
14490 break;
14491 case OPC_TGE ... OPC_TEQ: /* Traps */
14492 case OPC_TNE:
14493 gen_trap(ctx, op1, rs, rt, -1);
14494 break;
14495 case OPC_MFHI: /* Move from HI/LO */
14496 case OPC_MFLO:
14497 gen_HILO(ctx, op1, rs & 3, rd);
14498 break;
14499 case OPC_MTHI:
14500 case OPC_MTLO: /* Move to HI/LO */
14501 gen_HILO(ctx, op1, rd & 3, rs);
14502 break;
14503 case OPC_PMON: /* Pmon entry point, also R4010 selsl */
14504 #ifdef MIPS_STRICT_STANDARD
14505 MIPS_INVAL("PMON / selsl");
14506 generate_exception(ctx, EXCP_RI);
14507 #else
14508 gen_helper_0e0i(pmon, sa);
14509 #endif
14510 break;
14511 case OPC_SYSCALL:
14512 generate_exception(ctx, EXCP_SYSCALL);
14513 ctx->bstate = BS_STOP;
14514 break;
14515 case OPC_BREAK:
14516 generate_exception(ctx, EXCP_BREAK);
14517 break;
14518 case OPC_SPIM:
14519 #ifdef MIPS_STRICT_STANDARD
14520 MIPS_INVAL("SPIM");
14521 generate_exception(ctx, EXCP_RI);
14522 #else
14523 /* Implemented as RI exception for now. */
14524 MIPS_INVAL("spim (unofficial)");
14525 generate_exception(ctx, EXCP_RI);
14526 #endif
14527 break;
14528 case OPC_SYNC:
14529 /* Treat as NOP. */
14530 break;
14532 case OPC_MOVCI:
14533 check_insn(ctx, ISA_MIPS4 | ISA_MIPS32);
14534 if (env->CP0_Config1 & (1 << CP0C1_FP)) {
14535 check_cp1_enabled(ctx);
14536 gen_movci(ctx, rd, rs, (ctx->opcode >> 18) & 0x7,
14537 (ctx->opcode >> 16) & 1);
14538 } else {
14539 generate_exception_err(ctx, EXCP_CpU, 1);
14541 break;
14543 #if defined(TARGET_MIPS64)
14544 /* MIPS64 specific opcodes */
14545 case OPC_DSLL:
14546 case OPC_DSRA:
14547 case OPC_DSLL32:
14548 case OPC_DSRA32:
14549 check_insn(ctx, ISA_MIPS3);
14550 check_mips_64(ctx);
14551 gen_shift_imm(ctx, op1, rd, rt, sa);
14552 break;
14553 case OPC_DSRL:
14554 switch ((ctx->opcode >> 21) & 0x1f) {
14555 case 1:
14556 /* drotr is decoded as dsrl on non-R2 CPUs */
14557 if (ctx->insn_flags & ISA_MIPS32R2) {
14558 op1 = OPC_DROTR;
14560 /* Fallthrough */
14561 case 0:
14562 check_insn(ctx, ISA_MIPS3);
14563 check_mips_64(ctx);
14564 gen_shift_imm(ctx, op1, rd, rt, sa);
14565 break;
14566 default:
14567 generate_exception(ctx, EXCP_RI);
14568 break;
14570 break;
14571 case OPC_DSRL32:
14572 switch ((ctx->opcode >> 21) & 0x1f) {
14573 case 1:
14574 /* drotr32 is decoded as dsrl32 on non-R2 CPUs */
14575 if (ctx->insn_flags & ISA_MIPS32R2) {
14576 op1 = OPC_DROTR32;
14578 /* Fallthrough */
14579 case 0:
14580 check_insn(ctx, ISA_MIPS3);
14581 check_mips_64(ctx);
14582 gen_shift_imm(ctx, op1, rd, rt, sa);
14583 break;
14584 default:
14585 generate_exception(ctx, EXCP_RI);
14586 break;
14588 break;
14589 case OPC_DADD ... OPC_DSUBU:
14590 check_insn(ctx, ISA_MIPS3);
14591 check_mips_64(ctx);
14592 gen_arith(ctx, op1, rd, rs, rt);
14593 break;
14594 case OPC_DSLLV:
14595 case OPC_DSRAV:
14596 check_insn(ctx, ISA_MIPS3);
14597 check_mips_64(ctx);
14598 gen_shift(ctx, op1, rd, rs, rt);
14599 break;
14600 case OPC_DSRLV:
14601 switch ((ctx->opcode >> 6) & 0x1f) {
14602 case 1:
14603 /* drotrv is decoded as dsrlv on non-R2 CPUs */
14604 if (ctx->insn_flags & ISA_MIPS32R2) {
14605 op1 = OPC_DROTRV;
14607 /* Fallthrough */
14608 case 0:
14609 check_insn(ctx, ISA_MIPS3);
14610 check_mips_64(ctx);
14611 gen_shift(ctx, op1, rd, rs, rt);
14612 break;
14613 default:
14614 generate_exception(ctx, EXCP_RI);
14615 break;
14617 break;
14618 case OPC_DMULT ... OPC_DDIVU:
14619 check_insn(ctx, ISA_MIPS3);
14620 check_mips_64(ctx);
14621 gen_muldiv(ctx, op1, 0, rs, rt);
14622 break;
14623 #endif
14624 default: /* Invalid */
14625 MIPS_INVAL("special");
14626 generate_exception(ctx, EXCP_RI);
14627 break;
14629 break;
14630 case OPC_SPECIAL2:
14631 op1 = MASK_SPECIAL2(ctx->opcode);
14632 switch (op1) {
14633 case OPC_MADD ... OPC_MADDU: /* Multiply and add/sub */
14634 case OPC_MSUB ... OPC_MSUBU:
14635 check_insn(ctx, ISA_MIPS32);
14636 gen_muldiv(ctx, op1, rd & 3, rs, rt);
14637 break;
14638 case OPC_MUL:
14639 gen_arith(ctx, op1, rd, rs, rt);
14640 break;
14641 case OPC_CLO:
14642 case OPC_CLZ:
14643 check_insn(ctx, ISA_MIPS32);
14644 gen_cl(ctx, op1, rd, rs);
14645 break;
14646 case OPC_SDBBP:
14647 /* XXX: not clear which exception should be raised
14648 * when in debug mode...
14650 check_insn(ctx, ISA_MIPS32);
14651 if (!(ctx->hflags & MIPS_HFLAG_DM)) {
14652 generate_exception(ctx, EXCP_DBp);
14653 } else {
14654 generate_exception(ctx, EXCP_DBp);
14656 /* Treat as NOP. */
14657 break;
14658 case OPC_DIV_G_2F:
14659 case OPC_DIVU_G_2F:
14660 case OPC_MULT_G_2F:
14661 case OPC_MULTU_G_2F:
14662 case OPC_MOD_G_2F:
14663 case OPC_MODU_G_2F:
14664 check_insn(ctx, INSN_LOONGSON2F);
14665 gen_loongson_integer(ctx, op1, rd, rs, rt);
14666 break;
14667 #if defined(TARGET_MIPS64)
14668 case OPC_DCLO:
14669 case OPC_DCLZ:
14670 check_insn(ctx, ISA_MIPS64);
14671 check_mips_64(ctx);
14672 gen_cl(ctx, op1, rd, rs);
14673 break;
14674 case OPC_DMULT_G_2F:
14675 case OPC_DMULTU_G_2F:
14676 case OPC_DDIV_G_2F:
14677 case OPC_DDIVU_G_2F:
14678 case OPC_DMOD_G_2F:
14679 case OPC_DMODU_G_2F:
14680 check_insn(ctx, INSN_LOONGSON2F);
14681 gen_loongson_integer(ctx, op1, rd, rs, rt);
14682 break;
14683 #endif
14684 default: /* Invalid */
14685 MIPS_INVAL("special2");
14686 generate_exception(ctx, EXCP_RI);
14687 break;
14689 break;
14690 case OPC_SPECIAL3:
14691 op1 = MASK_SPECIAL3(ctx->opcode);
14692 switch (op1) {
14693 case OPC_EXT:
14694 case OPC_INS:
14695 check_insn(ctx, ISA_MIPS32R2);
14696 gen_bitops(ctx, op1, rt, rs, sa, rd);
14697 break;
14698 case OPC_BSHFL:
14699 check_insn(ctx, ISA_MIPS32R2);
14700 op2 = MASK_BSHFL(ctx->opcode);
14701 gen_bshfl(ctx, op2, rt, rd);
14702 break;
14703 case OPC_RDHWR:
14704 gen_rdhwr(ctx, rt, rd);
14705 break;
14706 case OPC_FORK:
14707 check_insn(ctx, ASE_MT);
14709 TCGv t0 = tcg_temp_new();
14710 TCGv t1 = tcg_temp_new();
14712 gen_load_gpr(t0, rt);
14713 gen_load_gpr(t1, rs);
14714 gen_helper_fork(t0, t1);
14715 tcg_temp_free(t0);
14716 tcg_temp_free(t1);
14718 break;
14719 case OPC_YIELD:
14720 check_insn(ctx, ASE_MT);
14722 TCGv t0 = tcg_temp_new();
14724 save_cpu_state(ctx, 1);
14725 gen_load_gpr(t0, rs);
14726 gen_helper_yield(t0, cpu_env, t0);
14727 gen_store_gpr(t0, rd);
14728 tcg_temp_free(t0);
14730 break;
14731 case OPC_DIV_G_2E ... OPC_DIVU_G_2E:
14732 case OPC_MOD_G_2E ... OPC_MODU_G_2E:
14733 case OPC_MULT_G_2E ... OPC_MULTU_G_2E:
14734 /* OPC_MULT_G_2E, OPC_ADDUH_QB_DSP, OPC_MUL_PH_DSP have
14735 * the same mask and op1. */
14736 if ((ctx->insn_flags & ASE_DSPR2) && (op1 == OPC_MULT_G_2E)) {
14737 op2 = MASK_ADDUH_QB(ctx->opcode);
14738 switch (op2) {
14739 case OPC_ADDUH_QB:
14740 case OPC_ADDUH_R_QB:
14741 case OPC_ADDQH_PH:
14742 case OPC_ADDQH_R_PH:
14743 case OPC_ADDQH_W:
14744 case OPC_ADDQH_R_W:
14745 case OPC_SUBUH_QB:
14746 case OPC_SUBUH_R_QB:
14747 case OPC_SUBQH_PH:
14748 case OPC_SUBQH_R_PH:
14749 case OPC_SUBQH_W:
14750 case OPC_SUBQH_R_W:
14751 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
14752 break;
14753 case OPC_MUL_PH:
14754 case OPC_MUL_S_PH:
14755 case OPC_MULQ_S_W:
14756 case OPC_MULQ_RS_W:
14757 gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 1);
14758 break;
14759 default:
14760 MIPS_INVAL("MASK ADDUH.QB");
14761 generate_exception(ctx, EXCP_RI);
14762 break;
14764 } else if (ctx->insn_flags & INSN_LOONGSON2E) {
14765 gen_loongson_integer(ctx, op1, rd, rs, rt);
14766 } else {
14767 generate_exception(ctx, EXCP_RI);
14769 break;
14770 case OPC_LX_DSP:
14771 op2 = MASK_LX(ctx->opcode);
14772 switch (op2) {
14773 #if defined(TARGET_MIPS64)
14774 case OPC_LDX:
14775 #endif
14776 case OPC_LBUX:
14777 case OPC_LHX:
14778 case OPC_LWX:
14779 gen_mipsdsp_ld(ctx, op2, rd, rs, rt);
14780 break;
14781 default: /* Invalid */
14782 MIPS_INVAL("MASK LX");
14783 generate_exception(ctx, EXCP_RI);
14784 break;
14786 break;
14787 case OPC_ABSQ_S_PH_DSP:
14788 op2 = MASK_ABSQ_S_PH(ctx->opcode);
14789 switch (op2) {
14790 case OPC_ABSQ_S_QB:
14791 case OPC_ABSQ_S_PH:
14792 case OPC_ABSQ_S_W:
14793 case OPC_PRECEQ_W_PHL:
14794 case OPC_PRECEQ_W_PHR:
14795 case OPC_PRECEQU_PH_QBL:
14796 case OPC_PRECEQU_PH_QBR:
14797 case OPC_PRECEQU_PH_QBLA:
14798 case OPC_PRECEQU_PH_QBRA:
14799 case OPC_PRECEU_PH_QBL:
14800 case OPC_PRECEU_PH_QBR:
14801 case OPC_PRECEU_PH_QBLA:
14802 case OPC_PRECEU_PH_QBRA:
14803 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
14804 break;
14805 case OPC_BITREV:
14806 case OPC_REPL_QB:
14807 case OPC_REPLV_QB:
14808 case OPC_REPL_PH:
14809 case OPC_REPLV_PH:
14810 gen_mipsdsp_bitinsn(ctx, op1, op2, rd, rt);
14811 break;
14812 default:
14813 MIPS_INVAL("MASK ABSQ_S.PH");
14814 generate_exception(ctx, EXCP_RI);
14815 break;
14817 break;
14818 case OPC_ADDU_QB_DSP:
14819 op2 = MASK_ADDU_QB(ctx->opcode);
14820 switch (op2) {
14821 case OPC_ADDQ_PH:
14822 case OPC_ADDQ_S_PH:
14823 case OPC_ADDQ_S_W:
14824 case OPC_ADDU_QB:
14825 case OPC_ADDU_S_QB:
14826 case OPC_ADDU_PH:
14827 case OPC_ADDU_S_PH:
14828 case OPC_SUBQ_PH:
14829 case OPC_SUBQ_S_PH:
14830 case OPC_SUBQ_S_W:
14831 case OPC_SUBU_QB:
14832 case OPC_SUBU_S_QB:
14833 case OPC_SUBU_PH:
14834 case OPC_SUBU_S_PH:
14835 case OPC_ADDSC:
14836 case OPC_ADDWC:
14837 case OPC_MODSUB:
14838 case OPC_RADDU_W_QB:
14839 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
14840 break;
14841 case OPC_MULEU_S_PH_QBL:
14842 case OPC_MULEU_S_PH_QBR:
14843 case OPC_MULQ_RS_PH:
14844 case OPC_MULEQ_S_W_PHL:
14845 case OPC_MULEQ_S_W_PHR:
14846 case OPC_MULQ_S_PH:
14847 gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 1);
14848 break;
14849 default: /* Invalid */
14850 MIPS_INVAL("MASK ADDU.QB");
14851 generate_exception(ctx, EXCP_RI);
14852 break;
14855 break;
14856 case OPC_CMPU_EQ_QB_DSP:
14857 op2 = MASK_CMPU_EQ_QB(ctx->opcode);
14858 switch (op2) {
14859 case OPC_PRECR_SRA_PH_W:
14860 case OPC_PRECR_SRA_R_PH_W:
14861 gen_mipsdsp_arith(ctx, op1, op2, rt, rs, rd);
14862 break;
14863 case OPC_PRECR_QB_PH:
14864 case OPC_PRECRQ_QB_PH:
14865 case OPC_PRECRQ_PH_W:
14866 case OPC_PRECRQ_RS_PH_W:
14867 case OPC_PRECRQU_S_QB_PH:
14868 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
14869 break;
14870 case OPC_CMPU_EQ_QB:
14871 case OPC_CMPU_LT_QB:
14872 case OPC_CMPU_LE_QB:
14873 case OPC_CMP_EQ_PH:
14874 case OPC_CMP_LT_PH:
14875 case OPC_CMP_LE_PH:
14876 gen_mipsdsp_add_cmp_pick(ctx, op1, op2, rd, rs, rt, 0);
14877 break;
14878 case OPC_CMPGU_EQ_QB:
14879 case OPC_CMPGU_LT_QB:
14880 case OPC_CMPGU_LE_QB:
14881 case OPC_CMPGDU_EQ_QB:
14882 case OPC_CMPGDU_LT_QB:
14883 case OPC_CMPGDU_LE_QB:
14884 case OPC_PICK_QB:
14885 case OPC_PICK_PH:
14886 case OPC_PACKRL_PH:
14887 gen_mipsdsp_add_cmp_pick(ctx, op1, op2, rd, rs, rt, 1);
14888 break;
14889 default: /* Invalid */
14890 MIPS_INVAL("MASK CMPU.EQ.QB");
14891 generate_exception(ctx, EXCP_RI);
14892 break;
14894 break;
14895 case OPC_SHLL_QB_DSP:
14896 gen_mipsdsp_shift(ctx, op1, rd, rs, rt);
14897 break;
14898 case OPC_DPA_W_PH_DSP:
14899 op2 = MASK_DPA_W_PH(ctx->opcode);
14900 switch (op2) {
14901 case OPC_DPAU_H_QBL:
14902 case OPC_DPAU_H_QBR:
14903 case OPC_DPSU_H_QBL:
14904 case OPC_DPSU_H_QBR:
14905 case OPC_DPA_W_PH:
14906 case OPC_DPAX_W_PH:
14907 case OPC_DPAQ_S_W_PH:
14908 case OPC_DPAQX_S_W_PH:
14909 case OPC_DPAQX_SA_W_PH:
14910 case OPC_DPS_W_PH:
14911 case OPC_DPSX_W_PH:
14912 case OPC_DPSQ_S_W_PH:
14913 case OPC_DPSQX_S_W_PH:
14914 case OPC_DPSQX_SA_W_PH:
14915 case OPC_MULSAQ_S_W_PH:
14916 case OPC_DPAQ_SA_L_W:
14917 case OPC_DPSQ_SA_L_W:
14918 case OPC_MAQ_S_W_PHL:
14919 case OPC_MAQ_S_W_PHR:
14920 case OPC_MAQ_SA_W_PHL:
14921 case OPC_MAQ_SA_W_PHR:
14922 case OPC_MULSA_W_PH:
14923 gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 0);
14924 break;
14925 default: /* Invalid */
14926 MIPS_INVAL("MASK DPAW.PH");
14927 generate_exception(ctx, EXCP_RI);
14928 break;
14930 break;
14931 case OPC_INSV_DSP:
14932 op2 = MASK_INSV(ctx->opcode);
14933 switch (op2) {
14934 case OPC_INSV:
14935 check_dsp(ctx);
14937 TCGv t0, t1;
14939 if (rt == 0) {
14940 MIPS_DEBUG("NOP");
14941 break;
14944 t0 = tcg_temp_new();
14945 t1 = tcg_temp_new();
14947 gen_load_gpr(t0, rt);
14948 gen_load_gpr(t1, rs);
14950 gen_helper_insv(cpu_gpr[rt], cpu_env, t1, t0);
14952 tcg_temp_free(t0);
14953 tcg_temp_free(t1);
14954 break;
14956 default: /* Invalid */
14957 MIPS_INVAL("MASK INSV");
14958 generate_exception(ctx, EXCP_RI);
14959 break;
14961 break;
14962 case OPC_APPEND_DSP:
14963 gen_mipsdsp_append(env, ctx, op1, rt, rs, rd);
14964 break;
14965 case OPC_EXTR_W_DSP:
14966 op2 = MASK_EXTR_W(ctx->opcode);
14967 switch (op2) {
14968 case OPC_EXTR_W:
14969 case OPC_EXTR_R_W:
14970 case OPC_EXTR_RS_W:
14971 case OPC_EXTR_S_H:
14972 case OPC_EXTRV_S_H:
14973 case OPC_EXTRV_W:
14974 case OPC_EXTRV_R_W:
14975 case OPC_EXTRV_RS_W:
14976 case OPC_EXTP:
14977 case OPC_EXTPV:
14978 case OPC_EXTPDP:
14979 case OPC_EXTPDPV:
14980 gen_mipsdsp_accinsn(ctx, op1, op2, rt, rs, rd, 1);
14981 break;
14982 case OPC_RDDSP:
14983 gen_mipsdsp_accinsn(ctx, op1, op2, rd, rs, rt, 1);
14984 break;
14985 case OPC_SHILO:
14986 case OPC_SHILOV:
14987 case OPC_MTHLIP:
14988 case OPC_WRDSP:
14989 gen_mipsdsp_accinsn(ctx, op1, op2, rd, rs, rt, 0);
14990 break;
14991 default: /* Invalid */
14992 MIPS_INVAL("MASK EXTR.W");
14993 generate_exception(ctx, EXCP_RI);
14994 break;
14996 break;
14997 #if defined(TARGET_MIPS64)
14998 case OPC_DEXTM ... OPC_DEXT:
14999 case OPC_DINSM ... OPC_DINS:
15000 check_insn(ctx, ISA_MIPS64R2);
15001 check_mips_64(ctx);
15002 gen_bitops(ctx, op1, rt, rs, sa, rd);
15003 break;
15004 case OPC_DBSHFL:
15005 check_insn(ctx, ISA_MIPS64R2);
15006 check_mips_64(ctx);
15007 op2 = MASK_DBSHFL(ctx->opcode);
15008 gen_bshfl(ctx, op2, rt, rd);
15009 break;
15010 case OPC_DDIV_G_2E ... OPC_DDIVU_G_2E:
15011 case OPC_DMULT_G_2E ... OPC_DMULTU_G_2E:
15012 case OPC_DMOD_G_2E ... OPC_DMODU_G_2E:
15013 check_insn(ctx, INSN_LOONGSON2E);
15014 gen_loongson_integer(ctx, op1, rd, rs, rt);
15015 break;
15016 case OPC_ABSQ_S_QH_DSP:
15017 op2 = MASK_ABSQ_S_QH(ctx->opcode);
15018 switch (op2) {
15019 case OPC_PRECEQ_L_PWL:
15020 case OPC_PRECEQ_L_PWR:
15021 case OPC_PRECEQ_PW_QHL:
15022 case OPC_PRECEQ_PW_QHR:
15023 case OPC_PRECEQ_PW_QHLA:
15024 case OPC_PRECEQ_PW_QHRA:
15025 case OPC_PRECEQU_QH_OBL:
15026 case OPC_PRECEQU_QH_OBR:
15027 case OPC_PRECEQU_QH_OBLA:
15028 case OPC_PRECEQU_QH_OBRA:
15029 case OPC_PRECEU_QH_OBL:
15030 case OPC_PRECEU_QH_OBR:
15031 case OPC_PRECEU_QH_OBLA:
15032 case OPC_PRECEU_QH_OBRA:
15033 case OPC_ABSQ_S_OB:
15034 case OPC_ABSQ_S_PW:
15035 case OPC_ABSQ_S_QH:
15036 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
15037 break;
15038 case OPC_REPL_OB:
15039 case OPC_REPL_PW:
15040 case OPC_REPL_QH:
15041 case OPC_REPLV_OB:
15042 case OPC_REPLV_PW:
15043 case OPC_REPLV_QH:
15044 gen_mipsdsp_bitinsn(ctx, op1, op2, rd, rt);
15045 break;
15046 default: /* Invalid */
15047 MIPS_INVAL("MASK ABSQ_S.QH");
15048 generate_exception(ctx, EXCP_RI);
15049 break;
15051 break;
15052 case OPC_ADDU_OB_DSP:
15053 op2 = MASK_ADDU_OB(ctx->opcode);
15054 switch (op2) {
15055 case OPC_RADDU_L_OB:
15056 case OPC_SUBQ_PW:
15057 case OPC_SUBQ_S_PW:
15058 case OPC_SUBQ_QH:
15059 case OPC_SUBQ_S_QH:
15060 case OPC_SUBU_OB:
15061 case OPC_SUBU_S_OB:
15062 case OPC_SUBU_QH:
15063 case OPC_SUBU_S_QH:
15064 case OPC_SUBUH_OB:
15065 case OPC_SUBUH_R_OB:
15066 case OPC_ADDQ_PW:
15067 case OPC_ADDQ_S_PW:
15068 case OPC_ADDQ_QH:
15069 case OPC_ADDQ_S_QH:
15070 case OPC_ADDU_OB:
15071 case OPC_ADDU_S_OB:
15072 case OPC_ADDU_QH:
15073 case OPC_ADDU_S_QH:
15074 case OPC_ADDUH_OB:
15075 case OPC_ADDUH_R_OB:
15076 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
15077 break;
15078 case OPC_MULEQ_S_PW_QHL:
15079 case OPC_MULEQ_S_PW_QHR:
15080 case OPC_MULEU_S_QH_OBL:
15081 case OPC_MULEU_S_QH_OBR:
15082 case OPC_MULQ_RS_QH:
15083 gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 1);
15084 break;
15085 default: /* Invalid */
15086 MIPS_INVAL("MASK ADDU.OB");
15087 generate_exception(ctx, EXCP_RI);
15088 break;
15090 break;
15091 case OPC_CMPU_EQ_OB_DSP:
15092 op2 = MASK_CMPU_EQ_OB(ctx->opcode);
15093 switch (op2) {
15094 case OPC_PRECR_SRA_QH_PW:
15095 case OPC_PRECR_SRA_R_QH_PW:
15096 /* Return value is rt. */
15097 gen_mipsdsp_arith(ctx, op1, op2, rt, rs, rd);
15098 break;
15099 case OPC_PRECR_OB_QH:
15100 case OPC_PRECRQ_OB_QH:
15101 case OPC_PRECRQ_PW_L:
15102 case OPC_PRECRQ_QH_PW:
15103 case OPC_PRECRQ_RS_QH_PW:
15104 case OPC_PRECRQU_S_OB_QH:
15105 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
15106 break;
15107 case OPC_CMPU_EQ_OB:
15108 case OPC_CMPU_LT_OB:
15109 case OPC_CMPU_LE_OB:
15110 case OPC_CMP_EQ_QH:
15111 case OPC_CMP_LT_QH:
15112 case OPC_CMP_LE_QH:
15113 case OPC_CMP_EQ_PW:
15114 case OPC_CMP_LT_PW:
15115 case OPC_CMP_LE_PW:
15116 gen_mipsdsp_add_cmp_pick(ctx, op1, op2, rd, rs, rt, 0);
15117 break;
15118 case OPC_CMPGDU_EQ_OB:
15119 case OPC_CMPGDU_LT_OB:
15120 case OPC_CMPGDU_LE_OB:
15121 case OPC_CMPGU_EQ_OB:
15122 case OPC_CMPGU_LT_OB:
15123 case OPC_CMPGU_LE_OB:
15124 case OPC_PACKRL_PW:
15125 case OPC_PICK_OB:
15126 case OPC_PICK_PW:
15127 case OPC_PICK_QH:
15128 gen_mipsdsp_add_cmp_pick(ctx, op1, op2, rd, rs, rt, 1);
15129 break;
15130 default: /* Invalid */
15131 MIPS_INVAL("MASK CMPU_EQ.OB");
15132 generate_exception(ctx, EXCP_RI);
15133 break;
15135 break;
15136 case OPC_DAPPEND_DSP:
15137 gen_mipsdsp_append(env, ctx, op1, rt, rs, rd);
15138 break;
15139 case OPC_DEXTR_W_DSP:
15140 op2 = MASK_DEXTR_W(ctx->opcode);
15141 switch (op2) {
15142 case OPC_DEXTP:
15143 case OPC_DEXTPDP:
15144 case OPC_DEXTPDPV:
15145 case OPC_DEXTPV:
15146 case OPC_DEXTR_L:
15147 case OPC_DEXTR_R_L:
15148 case OPC_DEXTR_RS_L:
15149 case OPC_DEXTR_W:
15150 case OPC_DEXTR_R_W:
15151 case OPC_DEXTR_RS_W:
15152 case OPC_DEXTR_S_H:
15153 case OPC_DEXTRV_L:
15154 case OPC_DEXTRV_R_L:
15155 case OPC_DEXTRV_RS_L:
15156 case OPC_DEXTRV_S_H:
15157 case OPC_DEXTRV_W:
15158 case OPC_DEXTRV_R_W:
15159 case OPC_DEXTRV_RS_W:
15160 gen_mipsdsp_accinsn(ctx, op1, op2, rt, rs, rd, 1);
15161 break;
15162 case OPC_DMTHLIP:
15163 case OPC_DSHILO:
15164 case OPC_DSHILOV:
15165 gen_mipsdsp_accinsn(ctx, op1, op2, rd, rs, rt, 0);
15166 break;
15167 default: /* Invalid */
15168 MIPS_INVAL("MASK EXTR.W");
15169 generate_exception(ctx, EXCP_RI);
15170 break;
15172 break;
15173 case OPC_DPAQ_W_QH_DSP:
15174 op2 = MASK_DPAQ_W_QH(ctx->opcode);
15175 switch (op2) {
15176 case OPC_DPAU_H_OBL:
15177 case OPC_DPAU_H_OBR:
15178 case OPC_DPSU_H_OBL:
15179 case OPC_DPSU_H_OBR:
15180 case OPC_DPA_W_QH:
15181 case OPC_DPAQ_S_W_QH:
15182 case OPC_DPS_W_QH:
15183 case OPC_DPSQ_S_W_QH:
15184 case OPC_MULSAQ_S_W_QH:
15185 case OPC_DPAQ_SA_L_PW:
15186 case OPC_DPSQ_SA_L_PW:
15187 case OPC_MULSAQ_S_L_PW:
15188 gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 0);
15189 break;
15190 case OPC_MAQ_S_W_QHLL:
15191 case OPC_MAQ_S_W_QHLR:
15192 case OPC_MAQ_S_W_QHRL:
15193 case OPC_MAQ_S_W_QHRR:
15194 case OPC_MAQ_SA_W_QHLL:
15195 case OPC_MAQ_SA_W_QHLR:
15196 case OPC_MAQ_SA_W_QHRL:
15197 case OPC_MAQ_SA_W_QHRR:
15198 case OPC_MAQ_S_L_PWL:
15199 case OPC_MAQ_S_L_PWR:
15200 case OPC_DMADD:
15201 case OPC_DMADDU:
15202 case OPC_DMSUB:
15203 case OPC_DMSUBU:
15204 gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 0);
15205 break;
15206 default: /* Invalid */
15207 MIPS_INVAL("MASK DPAQ.W.QH");
15208 generate_exception(ctx, EXCP_RI);
15209 break;
15211 break;
15212 case OPC_DINSV_DSP:
15213 op2 = MASK_INSV(ctx->opcode);
15214 switch (op2) {
15215 case OPC_DINSV:
15217 TCGv t0, t1;
15219 if (rt == 0) {
15220 MIPS_DEBUG("NOP");
15221 break;
15223 check_dsp(ctx);
15225 t0 = tcg_temp_new();
15226 t1 = tcg_temp_new();
15228 gen_load_gpr(t0, rt);
15229 gen_load_gpr(t1, rs);
15231 gen_helper_dinsv(cpu_gpr[rt], cpu_env, t1, t0);
15232 break;
15234 default: /* Invalid */
15235 MIPS_INVAL("MASK DINSV");
15236 generate_exception(ctx, EXCP_RI);
15237 break;
15239 break;
15240 case OPC_SHLL_OB_DSP:
15241 gen_mipsdsp_shift(ctx, op1, rd, rs, rt);
15242 break;
15243 #endif
15244 default: /* Invalid */
15245 MIPS_INVAL("special3");
15246 generate_exception(ctx, EXCP_RI);
15247 break;
15249 break;
15250 case OPC_REGIMM:
15251 op1 = MASK_REGIMM(ctx->opcode);
15252 switch (op1) {
15253 case OPC_BLTZ ... OPC_BGEZL: /* REGIMM branches */
15254 case OPC_BLTZAL ... OPC_BGEZALL:
15255 gen_compute_branch(ctx, op1, 4, rs, -1, imm << 2);
15256 break;
15257 case OPC_TGEI ... OPC_TEQI: /* REGIMM traps */
15258 case OPC_TNEI:
15259 gen_trap(ctx, op1, rs, -1, imm);
15260 break;
15261 case OPC_SYNCI:
15262 check_insn(ctx, ISA_MIPS32R2);
15263 /* Treat as NOP. */
15264 break;
15265 case OPC_BPOSGE32: /* MIPS DSP branch */
15266 #if defined(TARGET_MIPS64)
15267 case OPC_BPOSGE64:
15268 #endif
15269 check_dsp(ctx);
15270 gen_compute_branch(ctx, op1, 4, -1, -2, (int32_t)imm << 2);
15271 break;
15272 default: /* Invalid */
15273 MIPS_INVAL("regimm");
15274 generate_exception(ctx, EXCP_RI);
15275 break;
15277 break;
15278 case OPC_CP0:
15279 check_cp0_enabled(ctx);
15280 op1 = MASK_CP0(ctx->opcode);
15281 switch (op1) {
15282 case OPC_MFC0:
15283 case OPC_MTC0:
15284 case OPC_MFTR:
15285 case OPC_MTTR:
15286 #if defined(TARGET_MIPS64)
15287 case OPC_DMFC0:
15288 case OPC_DMTC0:
15289 #endif
15290 #ifndef CONFIG_USER_ONLY
15291 gen_cp0(env, ctx, op1, rt, rd);
15292 #endif /* !CONFIG_USER_ONLY */
15293 break;
15294 case OPC_C0_FIRST ... OPC_C0_LAST:
15295 #ifndef CONFIG_USER_ONLY
15296 gen_cp0(env, ctx, MASK_C0(ctx->opcode), rt, rd);
15297 #endif /* !CONFIG_USER_ONLY */
15298 break;
15299 case OPC_MFMC0:
15300 #ifndef CONFIG_USER_ONLY
15302 TCGv t0 = tcg_temp_new();
15304 op2 = MASK_MFMC0(ctx->opcode);
15305 switch (op2) {
15306 case OPC_DMT:
15307 check_insn(ctx, ASE_MT);
15308 gen_helper_dmt(t0);
15309 gen_store_gpr(t0, rt);
15310 break;
15311 case OPC_EMT:
15312 check_insn(ctx, ASE_MT);
15313 gen_helper_emt(t0);
15314 gen_store_gpr(t0, rt);
15315 break;
15316 case OPC_DVPE:
15317 check_insn(ctx, ASE_MT);
15318 gen_helper_dvpe(t0, cpu_env);
15319 gen_store_gpr(t0, rt);
15320 break;
15321 case OPC_EVPE:
15322 check_insn(ctx, ASE_MT);
15323 gen_helper_evpe(t0, cpu_env);
15324 gen_store_gpr(t0, rt);
15325 break;
15326 case OPC_DI:
15327 check_insn(ctx, ISA_MIPS32R2);
15328 save_cpu_state(ctx, 1);
15329 gen_helper_di(t0, cpu_env);
15330 gen_store_gpr(t0, rt);
15331 /* Stop translation as we may have switched the execution mode */
15332 ctx->bstate = BS_STOP;
15333 break;
15334 case OPC_EI:
15335 check_insn(ctx, ISA_MIPS32R2);
15336 save_cpu_state(ctx, 1);
15337 gen_helper_ei(t0, cpu_env);
15338 gen_store_gpr(t0, rt);
15339 /* Stop translation as we may have switched the execution mode */
15340 ctx->bstate = BS_STOP;
15341 break;
15342 default: /* Invalid */
15343 MIPS_INVAL("mfmc0");
15344 generate_exception(ctx, EXCP_RI);
15345 break;
15347 tcg_temp_free(t0);
15349 #endif /* !CONFIG_USER_ONLY */
15350 break;
15351 case OPC_RDPGPR:
15352 check_insn(ctx, ISA_MIPS32R2);
15353 gen_load_srsgpr(rt, rd);
15354 break;
15355 case OPC_WRPGPR:
15356 check_insn(ctx, ISA_MIPS32R2);
15357 gen_store_srsgpr(rt, rd);
15358 break;
15359 default:
15360 MIPS_INVAL("cp0");
15361 generate_exception(ctx, EXCP_RI);
15362 break;
15364 break;
15365 case OPC_ADDI: /* Arithmetic with immediate opcode */
15366 case OPC_ADDIU:
15367 gen_arith_imm(ctx, op, rt, rs, imm);
15368 break;
15369 case OPC_SLTI: /* Set on less than with immediate opcode */
15370 case OPC_SLTIU:
15371 gen_slt_imm(ctx, op, rt, rs, imm);
15372 break;
15373 case OPC_ANDI: /* Arithmetic with immediate opcode */
15374 case OPC_LUI:
15375 case OPC_ORI:
15376 case OPC_XORI:
15377 gen_logic_imm(ctx, op, rt, rs, imm);
15378 break;
15379 case OPC_J ... OPC_JAL: /* Jump */
15380 offset = (int32_t)(ctx->opcode & 0x3FFFFFF) << 2;
15381 gen_compute_branch(ctx, op, 4, rs, rt, offset);
15382 break;
15383 case OPC_BEQ ... OPC_BGTZ: /* Branch */
15384 case OPC_BEQL ... OPC_BGTZL:
15385 gen_compute_branch(ctx, op, 4, rs, rt, imm << 2);
15386 break;
15387 case OPC_LB ... OPC_LWR: /* Load and stores */
15388 case OPC_LL:
15389 gen_ld(ctx, op, rt, rs, imm);
15390 break;
15391 case OPC_SB ... OPC_SW:
15392 case OPC_SWR:
15393 gen_st(ctx, op, rt, rs, imm);
15394 break;
15395 case OPC_SC:
15396 gen_st_cond(ctx, op, rt, rs, imm);
15397 break;
15398 case OPC_CACHE:
15399 check_cp0_enabled(ctx);
15400 check_insn(ctx, ISA_MIPS3 | ISA_MIPS32);
15401 /* Treat as NOP. */
15402 break;
15403 case OPC_PREF:
15404 check_insn(ctx, ISA_MIPS4 | ISA_MIPS32);
15405 /* Treat as NOP. */
15406 break;
15408 /* Floating point (COP1). */
15409 case OPC_LWC1:
15410 case OPC_LDC1:
15411 case OPC_SWC1:
15412 case OPC_SDC1:
15413 gen_cop1_ldst(env, ctx, op, rt, rs, imm);
15414 break;
15416 case OPC_CP1:
15417 if (env->CP0_Config1 & (1 << CP0C1_FP)) {
15418 check_cp1_enabled(ctx);
15419 op1 = MASK_CP1(ctx->opcode);
15420 switch (op1) {
15421 case OPC_MFHC1:
15422 case OPC_MTHC1:
15423 check_insn(ctx, ISA_MIPS32R2);
15424 case OPC_MFC1:
15425 case OPC_CFC1:
15426 case OPC_MTC1:
15427 case OPC_CTC1:
15428 gen_cp1(ctx, op1, rt, rd);
15429 break;
15430 #if defined(TARGET_MIPS64)
15431 case OPC_DMFC1:
15432 case OPC_DMTC1:
15433 check_insn(ctx, ISA_MIPS3);
15434 gen_cp1(ctx, op1, rt, rd);
15435 break;
15436 #endif
15437 case OPC_BC1ANY2:
15438 case OPC_BC1ANY4:
15439 check_cop1x(ctx);
15440 check_insn(ctx, ASE_MIPS3D);
15441 /* fall through */
15442 case OPC_BC1:
15443 gen_compute_branch1(ctx, MASK_BC1(ctx->opcode),
15444 (rt >> 2) & 0x7, imm << 2);
15445 break;
15446 case OPC_S_FMT:
15447 case OPC_D_FMT:
15448 case OPC_W_FMT:
15449 case OPC_L_FMT:
15450 case OPC_PS_FMT:
15451 gen_farith(ctx, ctx->opcode & FOP(0x3f, 0x1f), rt, rd, sa,
15452 (imm >> 8) & 0x7);
15453 break;
15454 default:
15455 MIPS_INVAL("cp1");
15456 generate_exception (ctx, EXCP_RI);
15457 break;
15459 } else {
15460 generate_exception_err(ctx, EXCP_CpU, 1);
15462 break;
15464 /* COP2. */
15465 case OPC_LWC2:
15466 case OPC_LDC2:
15467 case OPC_SWC2:
15468 case OPC_SDC2:
15469 /* COP2: Not implemented. */
15470 generate_exception_err(ctx, EXCP_CpU, 2);
15471 break;
15472 case OPC_CP2:
15473 check_insn(ctx, INSN_LOONGSON2F);
15474 /* Note that these instructions use different fields. */
15475 gen_loongson_multimedia(ctx, sa, rd, rt);
15476 break;
15478 case OPC_CP3:
15479 if (env->CP0_Config1 & (1 << CP0C1_FP)) {
15480 check_cp1_enabled(ctx);
15481 op1 = MASK_CP3(ctx->opcode);
15482 switch (op1) {
15483 case OPC_LWXC1:
15484 case OPC_LDXC1:
15485 case OPC_LUXC1:
15486 case OPC_SWXC1:
15487 case OPC_SDXC1:
15488 case OPC_SUXC1:
15489 gen_flt3_ldst(ctx, op1, sa, rd, rs, rt);
15490 break;
15491 case OPC_PREFX:
15492 /* Treat as NOP. */
15493 break;
15494 case OPC_ALNV_PS:
15495 case OPC_MADD_S:
15496 case OPC_MADD_D:
15497 case OPC_MADD_PS:
15498 case OPC_MSUB_S:
15499 case OPC_MSUB_D:
15500 case OPC_MSUB_PS:
15501 case OPC_NMADD_S:
15502 case OPC_NMADD_D:
15503 case OPC_NMADD_PS:
15504 case OPC_NMSUB_S:
15505 case OPC_NMSUB_D:
15506 case OPC_NMSUB_PS:
15507 gen_flt3_arith(ctx, op1, sa, rs, rd, rt);
15508 break;
15509 default:
15510 MIPS_INVAL("cp3");
15511 generate_exception (ctx, EXCP_RI);
15512 break;
15514 } else {
15515 generate_exception_err(ctx, EXCP_CpU, 1);
15517 break;
15519 #if defined(TARGET_MIPS64)
15520 /* MIPS64 opcodes */
15521 case OPC_LWU:
15522 case OPC_LDL ... OPC_LDR:
15523 case OPC_LLD:
15524 case OPC_LD:
15525 check_insn(ctx, ISA_MIPS3);
15526 check_mips_64(ctx);
15527 gen_ld(ctx, op, rt, rs, imm);
15528 break;
15529 case OPC_SDL ... OPC_SDR:
15530 case OPC_SD:
15531 check_insn(ctx, ISA_MIPS3);
15532 check_mips_64(ctx);
15533 gen_st(ctx, op, rt, rs, imm);
15534 break;
15535 case OPC_SCD:
15536 check_insn(ctx, ISA_MIPS3);
15537 check_mips_64(ctx);
15538 gen_st_cond(ctx, op, rt, rs, imm);
15539 break;
15540 case OPC_DADDI:
15541 case OPC_DADDIU:
15542 check_insn(ctx, ISA_MIPS3);
15543 check_mips_64(ctx);
15544 gen_arith_imm(ctx, op, rt, rs, imm);
15545 break;
15546 #endif
15547 case OPC_JALX:
15548 check_insn(ctx, ASE_MIPS16 | ASE_MICROMIPS);
15549 offset = (int32_t)(ctx->opcode & 0x3FFFFFF) << 2;
15550 gen_compute_branch(ctx, op, 4, rs, rt, offset);
15551 break;
15552 case OPC_MDMX:
15553 check_insn(ctx, ASE_MDMX);
15554 /* MDMX: Not implemented. */
15555 default: /* Invalid */
15556 MIPS_INVAL("major opcode");
15557 generate_exception(ctx, EXCP_RI);
15558 break;
15562 static inline void
15563 gen_intermediate_code_internal(MIPSCPU *cpu, TranslationBlock *tb,
15564 bool search_pc)
15566 CPUState *cs = CPU(cpu);
15567 CPUMIPSState *env = &cpu->env;
15568 DisasContext ctx;
15569 target_ulong pc_start;
15570 uint16_t *gen_opc_end;
15571 CPUBreakpoint *bp;
15572 int j, lj = -1;
15573 int num_insns;
15574 int max_insns;
15575 int insn_bytes;
15576 int is_delay;
15578 if (search_pc)
15579 qemu_log("search pc %d\n", search_pc);
15581 pc_start = tb->pc;
15582 gen_opc_end = tcg_ctx.gen_opc_buf + OPC_MAX_SIZE;
15583 ctx.pc = pc_start;
15584 ctx.saved_pc = -1;
15585 ctx.singlestep_enabled = cs->singlestep_enabled;
15586 ctx.insn_flags = env->insn_flags;
15587 ctx.tb = tb;
15588 ctx.bstate = BS_NONE;
15589 /* Restore delay slot state from the tb context. */
15590 ctx.hflags = (uint32_t)tb->flags; /* FIXME: maybe use 64 bits here? */
15591 restore_cpu_state(env, &ctx);
15592 #ifdef CONFIG_USER_ONLY
15593 ctx.mem_idx = MIPS_HFLAG_UM;
15594 #else
15595 ctx.mem_idx = ctx.hflags & MIPS_HFLAG_KSU;
15596 #endif
15597 num_insns = 0;
15598 max_insns = tb->cflags & CF_COUNT_MASK;
15599 if (max_insns == 0)
15600 max_insns = CF_COUNT_MASK;
15601 LOG_DISAS("\ntb %p idx %d hflags %04x\n", tb, ctx.mem_idx, ctx.hflags);
15602 gen_tb_start();
15603 while (ctx.bstate == BS_NONE) {
15604 if (unlikely(!QTAILQ_EMPTY(&env->breakpoints))) {
15605 QTAILQ_FOREACH(bp, &env->breakpoints, entry) {
15606 if (bp->pc == ctx.pc) {
15607 save_cpu_state(&ctx, 1);
15608 ctx.bstate = BS_BRANCH;
15609 gen_helper_0e0i(raise_exception, EXCP_DEBUG);
15610 /* Include the breakpoint location or the tb won't
15611 * be flushed when it must be. */
15612 ctx.pc += 4;
15613 goto done_generating;
15618 if (search_pc) {
15619 j = tcg_ctx.gen_opc_ptr - tcg_ctx.gen_opc_buf;
15620 if (lj < j) {
15621 lj++;
15622 while (lj < j)
15623 tcg_ctx.gen_opc_instr_start[lj++] = 0;
15625 tcg_ctx.gen_opc_pc[lj] = ctx.pc;
15626 gen_opc_hflags[lj] = ctx.hflags & MIPS_HFLAG_BMASK;
15627 gen_opc_btarget[lj] = ctx.btarget;
15628 tcg_ctx.gen_opc_instr_start[lj] = 1;
15629 tcg_ctx.gen_opc_icount[lj] = num_insns;
15631 if (num_insns + 1 == max_insns && (tb->cflags & CF_LAST_IO))
15632 gen_io_start();
15634 is_delay = ctx.hflags & MIPS_HFLAG_BMASK;
15635 if (!(ctx.hflags & MIPS_HFLAG_M16)) {
15636 ctx.opcode = cpu_ldl_code(env, ctx.pc);
15637 insn_bytes = 4;
15638 decode_opc(env, &ctx);
15639 } else if (ctx.insn_flags & ASE_MICROMIPS) {
15640 ctx.opcode = cpu_lduw_code(env, ctx.pc);
15641 insn_bytes = decode_micromips_opc(env, &ctx);
15642 } else if (ctx.insn_flags & ASE_MIPS16) {
15643 ctx.opcode = cpu_lduw_code(env, ctx.pc);
15644 insn_bytes = decode_mips16_opc(env, &ctx);
15645 } else {
15646 generate_exception(&ctx, EXCP_RI);
15647 ctx.bstate = BS_STOP;
15648 break;
15650 if (is_delay) {
15651 handle_delay_slot(&ctx, insn_bytes);
15653 ctx.pc += insn_bytes;
15655 num_insns++;
15657 /* Execute a branch and its delay slot as a single instruction.
15658 This is what GDB expects and is consistent with what the
15659 hardware does (e.g. if a delay slot instruction faults, the
15660 reported PC is the PC of the branch). */
15661 if (cs->singlestep_enabled && (ctx.hflags & MIPS_HFLAG_BMASK) == 0) {
15662 break;
15665 if ((ctx.pc & (TARGET_PAGE_SIZE - 1)) == 0)
15666 break;
15668 if (tcg_ctx.gen_opc_ptr >= gen_opc_end) {
15669 break;
15672 if (num_insns >= max_insns)
15673 break;
15675 if (singlestep)
15676 break;
15678 if (tb->cflags & CF_LAST_IO) {
15679 gen_io_end();
15681 if (cs->singlestep_enabled && ctx.bstate != BS_BRANCH) {
15682 save_cpu_state(&ctx, ctx.bstate == BS_NONE);
15683 gen_helper_0e0i(raise_exception, EXCP_DEBUG);
15684 } else {
15685 switch (ctx.bstate) {
15686 case BS_STOP:
15687 gen_goto_tb(&ctx, 0, ctx.pc);
15688 break;
15689 case BS_NONE:
15690 save_cpu_state(&ctx, 0);
15691 gen_goto_tb(&ctx, 0, ctx.pc);
15692 break;
15693 case BS_EXCP:
15694 tcg_gen_exit_tb(0);
15695 break;
15696 case BS_BRANCH:
15697 default:
15698 break;
15701 done_generating:
15702 gen_tb_end(tb, num_insns);
15703 *tcg_ctx.gen_opc_ptr = INDEX_op_end;
15704 if (search_pc) {
15705 j = tcg_ctx.gen_opc_ptr - tcg_ctx.gen_opc_buf;
15706 lj++;
15707 while (lj <= j)
15708 tcg_ctx.gen_opc_instr_start[lj++] = 0;
15709 } else {
15710 tb->size = ctx.pc - pc_start;
15711 tb->icount = num_insns;
15713 #ifdef DEBUG_DISAS
15714 LOG_DISAS("\n");
15715 if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM)) {
15716 qemu_log("IN: %s\n", lookup_symbol(pc_start));
15717 log_target_disas(env, pc_start, ctx.pc - pc_start, 0);
15718 qemu_log("\n");
15720 #endif
15723 void gen_intermediate_code (CPUMIPSState *env, struct TranslationBlock *tb)
15725 gen_intermediate_code_internal(mips_env_get_cpu(env), tb, false);
15728 void gen_intermediate_code_pc (CPUMIPSState *env, struct TranslationBlock *tb)
15730 gen_intermediate_code_internal(mips_env_get_cpu(env), tb, true);
15733 static void fpu_dump_state(CPUMIPSState *env, FILE *f, fprintf_function fpu_fprintf,
15734 int flags)
15736 int i;
15737 int is_fpu64 = !!(env->hflags & MIPS_HFLAG_F64);
15739 #define printfpr(fp) \
15740 do { \
15741 if (is_fpu64) \
15742 fpu_fprintf(f, "w:%08x d:%016" PRIx64 \
15743 " fd:%13g fs:%13g psu: %13g\n", \
15744 (fp)->w[FP_ENDIAN_IDX], (fp)->d, \
15745 (double)(fp)->fd, \
15746 (double)(fp)->fs[FP_ENDIAN_IDX], \
15747 (double)(fp)->fs[!FP_ENDIAN_IDX]); \
15748 else { \
15749 fpr_t tmp; \
15750 tmp.w[FP_ENDIAN_IDX] = (fp)->w[FP_ENDIAN_IDX]; \
15751 tmp.w[!FP_ENDIAN_IDX] = ((fp) + 1)->w[FP_ENDIAN_IDX]; \
15752 fpu_fprintf(f, "w:%08x d:%016" PRIx64 \
15753 " fd:%13g fs:%13g psu:%13g\n", \
15754 tmp.w[FP_ENDIAN_IDX], tmp.d, \
15755 (double)tmp.fd, \
15756 (double)tmp.fs[FP_ENDIAN_IDX], \
15757 (double)tmp.fs[!FP_ENDIAN_IDX]); \
15759 } while(0)
15762 fpu_fprintf(f, "CP1 FCR0 0x%08x FCR31 0x%08x SR.FR %d fp_status 0x%02x\n",
15763 env->active_fpu.fcr0, env->active_fpu.fcr31, is_fpu64,
15764 get_float_exception_flags(&env->active_fpu.fp_status));
15765 for (i = 0; i < 32; (is_fpu64) ? i++ : (i += 2)) {
15766 fpu_fprintf(f, "%3s: ", fregnames[i]);
15767 printfpr(&env->active_fpu.fpr[i]);
15770 #undef printfpr
15773 #if defined(TARGET_MIPS64) && defined(MIPS_DEBUG_SIGN_EXTENSIONS)
15774 /* Debug help: The architecture requires 32bit code to maintain proper
15775 sign-extended values on 64bit machines. */
15777 #define SIGN_EXT_P(val) ((((val) & ~0x7fffffff) == 0) || (((val) & ~0x7fffffff) == ~0x7fffffff))
15779 static void
15780 cpu_mips_check_sign_extensions (CPUMIPSState *env, FILE *f,
15781 fprintf_function cpu_fprintf,
15782 int flags)
15784 int i;
15786 if (!SIGN_EXT_P(env->active_tc.PC))
15787 cpu_fprintf(f, "BROKEN: pc=0x" TARGET_FMT_lx "\n", env->active_tc.PC);
15788 if (!SIGN_EXT_P(env->active_tc.HI[0]))
15789 cpu_fprintf(f, "BROKEN: HI=0x" TARGET_FMT_lx "\n", env->active_tc.HI[0]);
15790 if (!SIGN_EXT_P(env->active_tc.LO[0]))
15791 cpu_fprintf(f, "BROKEN: LO=0x" TARGET_FMT_lx "\n", env->active_tc.LO[0]);
15792 if (!SIGN_EXT_P(env->btarget))
15793 cpu_fprintf(f, "BROKEN: btarget=0x" TARGET_FMT_lx "\n", env->btarget);
15795 for (i = 0; i < 32; i++) {
15796 if (!SIGN_EXT_P(env->active_tc.gpr[i]))
15797 cpu_fprintf(f, "BROKEN: %s=0x" TARGET_FMT_lx "\n", regnames[i], env->active_tc.gpr[i]);
15800 if (!SIGN_EXT_P(env->CP0_EPC))
15801 cpu_fprintf(f, "BROKEN: EPC=0x" TARGET_FMT_lx "\n", env->CP0_EPC);
15802 if (!SIGN_EXT_P(env->lladdr))
15803 cpu_fprintf(f, "BROKEN: LLAddr=0x" TARGET_FMT_lx "\n", env->lladdr);
15805 #endif
15807 void mips_cpu_dump_state(CPUState *cs, FILE *f, fprintf_function cpu_fprintf,
15808 int flags)
15810 MIPSCPU *cpu = MIPS_CPU(cs);
15811 CPUMIPSState *env = &cpu->env;
15812 int i;
15814 cpu_fprintf(f, "pc=0x" TARGET_FMT_lx " HI=0x" TARGET_FMT_lx
15815 " LO=0x" TARGET_FMT_lx " ds %04x "
15816 TARGET_FMT_lx " " TARGET_FMT_ld "\n",
15817 env->active_tc.PC, env->active_tc.HI[0], env->active_tc.LO[0],
15818 env->hflags, env->btarget, env->bcond);
15819 for (i = 0; i < 32; i++) {
15820 if ((i & 3) == 0)
15821 cpu_fprintf(f, "GPR%02d:", i);
15822 cpu_fprintf(f, " %s " TARGET_FMT_lx, regnames[i], env->active_tc.gpr[i]);
15823 if ((i & 3) == 3)
15824 cpu_fprintf(f, "\n");
15827 cpu_fprintf(f, "CP0 Status 0x%08x Cause 0x%08x EPC 0x" TARGET_FMT_lx "\n",
15828 env->CP0_Status, env->CP0_Cause, env->CP0_EPC);
15829 cpu_fprintf(f, " Config0 0x%08x Config1 0x%08x LLAddr 0x" TARGET_FMT_lx "\n",
15830 env->CP0_Config0, env->CP0_Config1, env->lladdr);
15831 if (env->hflags & MIPS_HFLAG_FPU)
15832 fpu_dump_state(env, f, cpu_fprintf, flags);
15833 #if defined(TARGET_MIPS64) && defined(MIPS_DEBUG_SIGN_EXTENSIONS)
15834 cpu_mips_check_sign_extensions(env, f, cpu_fprintf, flags);
15835 #endif
15838 void mips_tcg_init(void)
15840 int i;
15841 static int inited;
15843 /* Initialize various static tables. */
15844 if (inited)
15845 return;
15847 cpu_env = tcg_global_reg_new_ptr(TCG_AREG0, "env");
15848 TCGV_UNUSED(cpu_gpr[0]);
15849 for (i = 1; i < 32; i++)
15850 cpu_gpr[i] = tcg_global_mem_new(TCG_AREG0,
15851 offsetof(CPUMIPSState, active_tc.gpr[i]),
15852 regnames[i]);
15854 for (i = 0; i < 32; i++) {
15855 int off = offsetof(CPUMIPSState, active_fpu.fpr[i]);
15856 fpu_f64[i] = tcg_global_mem_new_i64(TCG_AREG0, off, fregnames[i]);
15859 cpu_PC = tcg_global_mem_new(TCG_AREG0,
15860 offsetof(CPUMIPSState, active_tc.PC), "PC");
15861 for (i = 0; i < MIPS_DSP_ACC; i++) {
15862 cpu_HI[i] = tcg_global_mem_new(TCG_AREG0,
15863 offsetof(CPUMIPSState, active_tc.HI[i]),
15864 regnames_HI[i]);
15865 cpu_LO[i] = tcg_global_mem_new(TCG_AREG0,
15866 offsetof(CPUMIPSState, active_tc.LO[i]),
15867 regnames_LO[i]);
15868 cpu_ACX[i] = tcg_global_mem_new(TCG_AREG0,
15869 offsetof(CPUMIPSState, active_tc.ACX[i]),
15870 regnames_ACX[i]);
15872 cpu_dspctrl = tcg_global_mem_new(TCG_AREG0,
15873 offsetof(CPUMIPSState, active_tc.DSPControl),
15874 "DSPControl");
15875 bcond = tcg_global_mem_new(TCG_AREG0,
15876 offsetof(CPUMIPSState, bcond), "bcond");
15877 btarget = tcg_global_mem_new(TCG_AREG0,
15878 offsetof(CPUMIPSState, btarget), "btarget");
15879 hflags = tcg_global_mem_new_i32(TCG_AREG0,
15880 offsetof(CPUMIPSState, hflags), "hflags");
15882 fpu_fcr0 = tcg_global_mem_new_i32(TCG_AREG0,
15883 offsetof(CPUMIPSState, active_fpu.fcr0),
15884 "fcr0");
15885 fpu_fcr31 = tcg_global_mem_new_i32(TCG_AREG0,
15886 offsetof(CPUMIPSState, active_fpu.fcr31),
15887 "fcr31");
15889 inited = 1;
15892 #include "translate_init.c"
15894 MIPSCPU *cpu_mips_init(const char *cpu_model)
15896 MIPSCPU *cpu;
15897 CPUMIPSState *env;
15898 const mips_def_t *def;
15900 def = cpu_mips_find_by_name(cpu_model);
15901 if (!def)
15902 return NULL;
15903 cpu = MIPS_CPU(object_new(TYPE_MIPS_CPU));
15904 env = &cpu->env;
15905 env->cpu_model = def;
15907 #ifndef CONFIG_USER_ONLY
15908 mmu_init(env, def);
15909 #endif
15910 fpu_init(env, def);
15911 mvp_init(env, def);
15913 object_property_set_bool(OBJECT(cpu), true, "realized", NULL);
15915 return cpu;
15918 void cpu_state_reset(CPUMIPSState *env)
15920 #ifndef CONFIG_USER_ONLY
15921 MIPSCPU *cpu = mips_env_get_cpu(env);
15922 CPUState *cs = CPU(cpu);
15923 #endif
15925 /* Reset registers to their default values */
15926 env->CP0_PRid = env->cpu_model->CP0_PRid;
15927 env->CP0_Config0 = env->cpu_model->CP0_Config0;
15928 #ifdef TARGET_WORDS_BIGENDIAN
15929 env->CP0_Config0 |= (1 << CP0C0_BE);
15930 #endif
15931 env->CP0_Config1 = env->cpu_model->CP0_Config1;
15932 env->CP0_Config2 = env->cpu_model->CP0_Config2;
15933 env->CP0_Config3 = env->cpu_model->CP0_Config3;
15934 env->CP0_Config6 = env->cpu_model->CP0_Config6;
15935 env->CP0_Config7 = env->cpu_model->CP0_Config7;
15936 env->CP0_LLAddr_rw_bitmask = env->cpu_model->CP0_LLAddr_rw_bitmask
15937 << env->cpu_model->CP0_LLAddr_shift;
15938 env->CP0_LLAddr_shift = env->cpu_model->CP0_LLAddr_shift;
15939 env->SYNCI_Step = env->cpu_model->SYNCI_Step;
15940 env->CCRes = env->cpu_model->CCRes;
15941 env->CP0_Status_rw_bitmask = env->cpu_model->CP0_Status_rw_bitmask;
15942 env->CP0_TCStatus_rw_bitmask = env->cpu_model->CP0_TCStatus_rw_bitmask;
15943 env->CP0_SRSCtl = env->cpu_model->CP0_SRSCtl;
15944 env->current_tc = 0;
15945 env->SEGBITS = env->cpu_model->SEGBITS;
15946 env->SEGMask = (target_ulong)((1ULL << env->cpu_model->SEGBITS) - 1);
15947 #if defined(TARGET_MIPS64)
15948 if (env->cpu_model->insn_flags & ISA_MIPS3) {
15949 env->SEGMask |= 3ULL << 62;
15951 #endif
15952 env->PABITS = env->cpu_model->PABITS;
15953 env->PAMask = (target_ulong)((1ULL << env->cpu_model->PABITS) - 1);
15954 env->CP0_SRSConf0_rw_bitmask = env->cpu_model->CP0_SRSConf0_rw_bitmask;
15955 env->CP0_SRSConf0 = env->cpu_model->CP0_SRSConf0;
15956 env->CP0_SRSConf1_rw_bitmask = env->cpu_model->CP0_SRSConf1_rw_bitmask;
15957 env->CP0_SRSConf1 = env->cpu_model->CP0_SRSConf1;
15958 env->CP0_SRSConf2_rw_bitmask = env->cpu_model->CP0_SRSConf2_rw_bitmask;
15959 env->CP0_SRSConf2 = env->cpu_model->CP0_SRSConf2;
15960 env->CP0_SRSConf3_rw_bitmask = env->cpu_model->CP0_SRSConf3_rw_bitmask;
15961 env->CP0_SRSConf3 = env->cpu_model->CP0_SRSConf3;
15962 env->CP0_SRSConf4_rw_bitmask = env->cpu_model->CP0_SRSConf4_rw_bitmask;
15963 env->CP0_SRSConf4 = env->cpu_model->CP0_SRSConf4;
15964 env->active_fpu.fcr0 = env->cpu_model->CP1_fcr0;
15965 env->insn_flags = env->cpu_model->insn_flags;
15967 #if defined(CONFIG_USER_ONLY)
15968 env->CP0_Status = (MIPS_HFLAG_UM << CP0St_KSU);
15969 # ifdef TARGET_MIPS64
15970 /* Enable 64-bit register mode. */
15971 env->CP0_Status |= (1 << CP0St_PX);
15972 # endif
15973 # ifdef TARGET_ABI_MIPSN64
15974 /* Enable 64-bit address mode. */
15975 env->CP0_Status |= (1 << CP0St_UX);
15976 # endif
15977 /* Enable access to the CPUNum, SYNCI_Step, CC, and CCRes RDHWR
15978 hardware registers. */
15979 env->CP0_HWREna |= 0x0000000F;
15980 if (env->CP0_Config1 & (1 << CP0C1_FP)) {
15981 env->CP0_Status |= (1 << CP0St_CU1);
15983 if (env->CP0_Config3 & (1 << CP0C3_DSPP)) {
15984 env->CP0_Status |= (1 << CP0St_MX);
15986 /* Enable 64-bit FPU if the target cpu supports it. */
15987 if (env->active_fpu.fcr0 & (1 << FCR0_F64)) {
15988 env->CP0_Status |= (1 << CP0St_FR);
15990 #else
15991 if (env->hflags & MIPS_HFLAG_BMASK) {
15992 /* If the exception was raised from a delay slot,
15993 come back to the jump. */
15994 env->CP0_ErrorEPC = env->active_tc.PC - 4;
15995 } else {
15996 env->CP0_ErrorEPC = env->active_tc.PC;
15998 env->active_tc.PC = (int32_t)0xBFC00000;
15999 env->CP0_Random = env->tlb->nb_tlb - 1;
16000 env->tlb->tlb_in_use = env->tlb->nb_tlb;
16001 env->CP0_Wired = 0;
16002 env->CP0_EBase = 0x80000000 | (cs->cpu_index & 0x3FF);
16003 env->CP0_Status = (1 << CP0St_BEV) | (1 << CP0St_ERL);
16004 /* vectored interrupts not implemented, timer on int 7,
16005 no performance counters. */
16006 env->CP0_IntCtl = 0xe0000000;
16008 int i;
16010 for (i = 0; i < 7; i++) {
16011 env->CP0_WatchLo[i] = 0;
16012 env->CP0_WatchHi[i] = 0x80000000;
16014 env->CP0_WatchLo[7] = 0;
16015 env->CP0_WatchHi[7] = 0;
16017 /* Count register increments in debug mode, EJTAG version 1 */
16018 env->CP0_Debug = (1 << CP0DB_CNT) | (0x1 << CP0DB_VER);
16020 if (env->CP0_Config3 & (1 << CP0C3_MT)) {
16021 int i;
16023 /* Only TC0 on VPE 0 starts as active. */
16024 for (i = 0; i < ARRAY_SIZE(env->tcs); i++) {
16025 env->tcs[i].CP0_TCBind = cs->cpu_index << CP0TCBd_CurVPE;
16026 env->tcs[i].CP0_TCHalt = 1;
16028 env->active_tc.CP0_TCHalt = 1;
16029 cs->halted = 1;
16031 if (cs->cpu_index == 0) {
16032 /* VPE0 starts up enabled. */
16033 env->mvp->CP0_MVPControl |= (1 << CP0MVPCo_EVP);
16034 env->CP0_VPEConf0 |= (1 << CP0VPEC0_MVP) | (1 << CP0VPEC0_VPA);
16036 /* TC0 starts up unhalted. */
16037 cs->halted = 0;
16038 env->active_tc.CP0_TCHalt = 0;
16039 env->tcs[0].CP0_TCHalt = 0;
16040 /* With thread 0 active. */
16041 env->active_tc.CP0_TCStatus = (1 << CP0TCSt_A);
16042 env->tcs[0].CP0_TCStatus = (1 << CP0TCSt_A);
16045 #endif
16046 compute_hflags(env);
16047 env->exception_index = EXCP_NONE;
16050 void restore_state_to_opc(CPUMIPSState *env, TranslationBlock *tb, int pc_pos)
16052 env->active_tc.PC = tcg_ctx.gen_opc_pc[pc_pos];
16053 env->hflags &= ~MIPS_HFLAG_BMASK;
16054 env->hflags |= gen_opc_hflags[pc_pos];
16055 switch (env->hflags & MIPS_HFLAG_BMASK_BASE) {
16056 case MIPS_HFLAG_BR:
16057 break;
16058 case MIPS_HFLAG_BC:
16059 case MIPS_HFLAG_BL:
16060 case MIPS_HFLAG_B:
16061 env->btarget = gen_opc_btarget[pc_pos];
16062 break;