target-i386: Use mulu2 and muls2
[qemu/pbrook.git] / target-mips / translate.c
blobf10a533e80b74b56bf3bb0044754a3bc239cbbbf
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 reg)
2587 const char *opn = "hilo";
2588 unsigned int acc;
2590 if (reg == 0 && (opc == OPC_MFHI || opc == OPC_MFLO)) {
2591 /* Treat as NOP. */
2592 MIPS_DEBUG("NOP");
2593 return;
2596 if (opc == OPC_MFHI || opc == OPC_MFLO) {
2597 acc = ((ctx->opcode) >> 21) & 0x03;
2598 } else {
2599 acc = ((ctx->opcode) >> 11) & 0x03;
2602 if (acc != 0) {
2603 check_dsp(ctx);
2606 switch (opc) {
2607 case OPC_MFHI:
2608 #if defined(TARGET_MIPS64)
2609 if (acc != 0) {
2610 tcg_gen_ext32s_tl(cpu_gpr[reg], cpu_HI[acc]);
2611 } else
2612 #endif
2614 tcg_gen_mov_tl(cpu_gpr[reg], cpu_HI[acc]);
2616 opn = "mfhi";
2617 break;
2618 case OPC_MFLO:
2619 #if defined(TARGET_MIPS64)
2620 if (acc != 0) {
2621 tcg_gen_ext32s_tl(cpu_gpr[reg], cpu_LO[acc]);
2622 } else
2623 #endif
2625 tcg_gen_mov_tl(cpu_gpr[reg], cpu_LO[acc]);
2627 opn = "mflo";
2628 break;
2629 case OPC_MTHI:
2630 if (reg != 0) {
2631 #if defined(TARGET_MIPS64)
2632 if (acc != 0) {
2633 tcg_gen_ext32s_tl(cpu_HI[acc], cpu_gpr[reg]);
2634 } else
2635 #endif
2637 tcg_gen_mov_tl(cpu_HI[acc], cpu_gpr[reg]);
2639 } else {
2640 tcg_gen_movi_tl(cpu_HI[acc], 0);
2642 opn = "mthi";
2643 break;
2644 case OPC_MTLO:
2645 if (reg != 0) {
2646 #if defined(TARGET_MIPS64)
2647 if (acc != 0) {
2648 tcg_gen_ext32s_tl(cpu_LO[acc], cpu_gpr[reg]);
2649 } else
2650 #endif
2652 tcg_gen_mov_tl(cpu_LO[acc], cpu_gpr[reg]);
2654 } else {
2655 tcg_gen_movi_tl(cpu_LO[acc], 0);
2657 opn = "mtlo";
2658 break;
2660 (void)opn; /* avoid a compiler warning */
2661 MIPS_DEBUG("%s %s", opn, regnames[reg]);
2664 static void gen_muldiv (DisasContext *ctx, uint32_t opc,
2665 int rs, int rt)
2667 const char *opn = "mul/div";
2668 TCGv t0, t1;
2669 unsigned int acc;
2671 t0 = tcg_temp_new();
2672 t1 = tcg_temp_new();
2674 gen_load_gpr(t0, rs);
2675 gen_load_gpr(t1, rt);
2677 switch (opc) {
2678 case OPC_DIV:
2680 TCGv t2 = tcg_temp_new();
2681 TCGv t3 = tcg_temp_new();
2682 tcg_gen_ext32s_tl(t0, t0);
2683 tcg_gen_ext32s_tl(t1, t1);
2684 tcg_gen_setcondi_tl(TCG_COND_EQ, t2, t0, INT_MIN);
2685 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, -1);
2686 tcg_gen_and_tl(t2, t2, t3);
2687 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, 0);
2688 tcg_gen_or_tl(t2, t2, t3);
2689 tcg_gen_movi_tl(t3, 0);
2690 tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, t3, t2, t1);
2691 tcg_gen_div_tl(cpu_LO[0], t0, t1);
2692 tcg_gen_rem_tl(cpu_HI[0], t0, t1);
2693 tcg_gen_ext32s_tl(cpu_LO[0], cpu_LO[0]);
2694 tcg_gen_ext32s_tl(cpu_HI[0], cpu_HI[0]);
2695 tcg_temp_free(t3);
2696 tcg_temp_free(t2);
2698 opn = "div";
2699 break;
2700 case OPC_DIVU:
2702 TCGv t2 = tcg_const_tl(0);
2703 TCGv t3 = tcg_const_tl(1);
2704 tcg_gen_ext32u_tl(t0, t0);
2705 tcg_gen_ext32u_tl(t1, t1);
2706 tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1, t2, t3, t1);
2707 tcg_gen_divu_tl(cpu_LO[0], t0, t1);
2708 tcg_gen_remu_tl(cpu_HI[0], t0, t1);
2709 tcg_gen_ext32s_tl(cpu_LO[0], cpu_LO[0]);
2710 tcg_gen_ext32s_tl(cpu_HI[0], cpu_HI[0]);
2711 tcg_temp_free(t3);
2712 tcg_temp_free(t2);
2714 opn = "divu";
2715 break;
2716 case OPC_MULT:
2718 TCGv_i32 t2 = tcg_temp_new_i32();
2719 TCGv_i32 t3 = tcg_temp_new_i32();
2720 acc = ((ctx->opcode) >> 11) & 0x03;
2721 if (acc != 0) {
2722 check_dsp(ctx);
2725 tcg_gen_trunc_tl_i32(t2, t0);
2726 tcg_gen_trunc_tl_i32(t3, t1);
2727 tcg_gen_muls2_i32(t2, t3, t2, t3);
2728 tcg_gen_ext_i32_tl(cpu_LO[acc], t2);
2729 tcg_gen_ext_i32_tl(cpu_HI[acc], t3);
2730 tcg_temp_free_i32(t2);
2731 tcg_temp_free_i32(t3);
2733 opn = "mult";
2734 break;
2735 case OPC_MULTU:
2737 TCGv_i32 t2 = tcg_temp_new_i32();
2738 TCGv_i32 t3 = tcg_temp_new_i32();
2739 acc = ((ctx->opcode) >> 11) & 0x03;
2740 if (acc != 0) {
2741 check_dsp(ctx);
2744 tcg_gen_trunc_tl_i32(t2, t0);
2745 tcg_gen_trunc_tl_i32(t3, t1);
2746 tcg_gen_mulu2_i32(t2, t3, t2, t3);
2747 tcg_gen_ext_i32_tl(cpu_LO[acc], t2);
2748 tcg_gen_ext_i32_tl(cpu_HI[acc], t3);
2749 tcg_temp_free_i32(t2);
2750 tcg_temp_free_i32(t3);
2752 opn = "multu";
2753 break;
2754 #if defined(TARGET_MIPS64)
2755 case OPC_DDIV:
2757 TCGv t2 = tcg_temp_new();
2758 TCGv t3 = tcg_temp_new();
2759 tcg_gen_setcondi_tl(TCG_COND_EQ, t2, t0, -1LL << 63);
2760 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, -1LL);
2761 tcg_gen_and_tl(t2, t2, t3);
2762 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, 0);
2763 tcg_gen_or_tl(t2, t2, t3);
2764 tcg_gen_movi_tl(t3, 0);
2765 tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, t3, t2, t1);
2766 tcg_gen_div_tl(cpu_LO[0], t0, t1);
2767 tcg_gen_rem_tl(cpu_HI[0], t0, t1);
2768 tcg_temp_free(t3);
2769 tcg_temp_free(t2);
2771 opn = "ddiv";
2772 break;
2773 case OPC_DDIVU:
2775 TCGv t2 = tcg_const_tl(0);
2776 TCGv t3 = tcg_const_tl(1);
2777 tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1, t2, t3, t1);
2778 tcg_gen_divu_i64(cpu_LO[0], t0, t1);
2779 tcg_gen_remu_i64(cpu_HI[0], t0, t1);
2780 tcg_temp_free(t3);
2781 tcg_temp_free(t2);
2783 opn = "ddivu";
2784 break;
2785 case OPC_DMULT:
2786 tcg_gen_muls2_i64(cpu_LO[0], cpu_HI[0], t0, t1);
2787 opn = "dmult";
2788 break;
2789 case OPC_DMULTU:
2790 tcg_gen_mulu2_i64(cpu_LO[0], cpu_HI[0], t0, t1);
2791 opn = "dmultu";
2792 break;
2793 #endif
2794 case OPC_MADD:
2796 TCGv_i64 t2 = tcg_temp_new_i64();
2797 TCGv_i64 t3 = tcg_temp_new_i64();
2798 acc = ((ctx->opcode) >> 11) & 0x03;
2799 if (acc != 0) {
2800 check_dsp(ctx);
2803 tcg_gen_ext_tl_i64(t2, t0);
2804 tcg_gen_ext_tl_i64(t3, t1);
2805 tcg_gen_mul_i64(t2, t2, t3);
2806 tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]);
2807 tcg_gen_add_i64(t2, t2, t3);
2808 tcg_temp_free_i64(t3);
2809 tcg_gen_trunc_i64_tl(t0, t2);
2810 tcg_gen_shri_i64(t2, t2, 32);
2811 tcg_gen_trunc_i64_tl(t1, t2);
2812 tcg_temp_free_i64(t2);
2813 tcg_gen_ext32s_tl(cpu_LO[acc], t0);
2814 tcg_gen_ext32s_tl(cpu_HI[acc], t1);
2816 opn = "madd";
2817 break;
2818 case OPC_MADDU:
2820 TCGv_i64 t2 = tcg_temp_new_i64();
2821 TCGv_i64 t3 = tcg_temp_new_i64();
2822 acc = ((ctx->opcode) >> 11) & 0x03;
2823 if (acc != 0) {
2824 check_dsp(ctx);
2827 tcg_gen_ext32u_tl(t0, t0);
2828 tcg_gen_ext32u_tl(t1, t1);
2829 tcg_gen_extu_tl_i64(t2, t0);
2830 tcg_gen_extu_tl_i64(t3, t1);
2831 tcg_gen_mul_i64(t2, t2, t3);
2832 tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]);
2833 tcg_gen_add_i64(t2, t2, t3);
2834 tcg_temp_free_i64(t3);
2835 tcg_gen_trunc_i64_tl(t0, t2);
2836 tcg_gen_shri_i64(t2, t2, 32);
2837 tcg_gen_trunc_i64_tl(t1, t2);
2838 tcg_temp_free_i64(t2);
2839 tcg_gen_ext32s_tl(cpu_LO[acc], t0);
2840 tcg_gen_ext32s_tl(cpu_HI[acc], t1);
2842 opn = "maddu";
2843 break;
2844 case OPC_MSUB:
2846 TCGv_i64 t2 = tcg_temp_new_i64();
2847 TCGv_i64 t3 = tcg_temp_new_i64();
2848 acc = ((ctx->opcode) >> 11) & 0x03;
2849 if (acc != 0) {
2850 check_dsp(ctx);
2853 tcg_gen_ext_tl_i64(t2, t0);
2854 tcg_gen_ext_tl_i64(t3, t1);
2855 tcg_gen_mul_i64(t2, t2, t3);
2856 tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]);
2857 tcg_gen_sub_i64(t2, t3, t2);
2858 tcg_temp_free_i64(t3);
2859 tcg_gen_trunc_i64_tl(t0, t2);
2860 tcg_gen_shri_i64(t2, t2, 32);
2861 tcg_gen_trunc_i64_tl(t1, t2);
2862 tcg_temp_free_i64(t2);
2863 tcg_gen_ext32s_tl(cpu_LO[acc], t0);
2864 tcg_gen_ext32s_tl(cpu_HI[acc], t1);
2866 opn = "msub";
2867 break;
2868 case OPC_MSUBU:
2870 TCGv_i64 t2 = tcg_temp_new_i64();
2871 TCGv_i64 t3 = tcg_temp_new_i64();
2872 acc = ((ctx->opcode) >> 11) & 0x03;
2873 if (acc != 0) {
2874 check_dsp(ctx);
2877 tcg_gen_ext32u_tl(t0, t0);
2878 tcg_gen_ext32u_tl(t1, t1);
2879 tcg_gen_extu_tl_i64(t2, t0);
2880 tcg_gen_extu_tl_i64(t3, t1);
2881 tcg_gen_mul_i64(t2, t2, t3);
2882 tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]);
2883 tcg_gen_sub_i64(t2, t3, t2);
2884 tcg_temp_free_i64(t3);
2885 tcg_gen_trunc_i64_tl(t0, t2);
2886 tcg_gen_shri_i64(t2, t2, 32);
2887 tcg_gen_trunc_i64_tl(t1, t2);
2888 tcg_temp_free_i64(t2);
2889 tcg_gen_ext32s_tl(cpu_LO[acc], t0);
2890 tcg_gen_ext32s_tl(cpu_HI[acc], t1);
2892 opn = "msubu";
2893 break;
2894 default:
2895 MIPS_INVAL(opn);
2896 generate_exception(ctx, EXCP_RI);
2897 goto out;
2899 (void)opn; /* avoid a compiler warning */
2900 MIPS_DEBUG("%s %s %s", opn, regnames[rs], regnames[rt]);
2901 out:
2902 tcg_temp_free(t0);
2903 tcg_temp_free(t1);
2906 static void gen_mul_vr54xx (DisasContext *ctx, uint32_t opc,
2907 int rd, int rs, int rt)
2909 const char *opn = "mul vr54xx";
2910 TCGv t0 = tcg_temp_new();
2911 TCGv t1 = tcg_temp_new();
2913 gen_load_gpr(t0, rs);
2914 gen_load_gpr(t1, rt);
2916 switch (opc) {
2917 case OPC_VR54XX_MULS:
2918 gen_helper_muls(t0, cpu_env, t0, t1);
2919 opn = "muls";
2920 break;
2921 case OPC_VR54XX_MULSU:
2922 gen_helper_mulsu(t0, cpu_env, t0, t1);
2923 opn = "mulsu";
2924 break;
2925 case OPC_VR54XX_MACC:
2926 gen_helper_macc(t0, cpu_env, t0, t1);
2927 opn = "macc";
2928 break;
2929 case OPC_VR54XX_MACCU:
2930 gen_helper_maccu(t0, cpu_env, t0, t1);
2931 opn = "maccu";
2932 break;
2933 case OPC_VR54XX_MSAC:
2934 gen_helper_msac(t0, cpu_env, t0, t1);
2935 opn = "msac";
2936 break;
2937 case OPC_VR54XX_MSACU:
2938 gen_helper_msacu(t0, cpu_env, t0, t1);
2939 opn = "msacu";
2940 break;
2941 case OPC_VR54XX_MULHI:
2942 gen_helper_mulhi(t0, cpu_env, t0, t1);
2943 opn = "mulhi";
2944 break;
2945 case OPC_VR54XX_MULHIU:
2946 gen_helper_mulhiu(t0, cpu_env, t0, t1);
2947 opn = "mulhiu";
2948 break;
2949 case OPC_VR54XX_MULSHI:
2950 gen_helper_mulshi(t0, cpu_env, t0, t1);
2951 opn = "mulshi";
2952 break;
2953 case OPC_VR54XX_MULSHIU:
2954 gen_helper_mulshiu(t0, cpu_env, t0, t1);
2955 opn = "mulshiu";
2956 break;
2957 case OPC_VR54XX_MACCHI:
2958 gen_helper_macchi(t0, cpu_env, t0, t1);
2959 opn = "macchi";
2960 break;
2961 case OPC_VR54XX_MACCHIU:
2962 gen_helper_macchiu(t0, cpu_env, t0, t1);
2963 opn = "macchiu";
2964 break;
2965 case OPC_VR54XX_MSACHI:
2966 gen_helper_msachi(t0, cpu_env, t0, t1);
2967 opn = "msachi";
2968 break;
2969 case OPC_VR54XX_MSACHIU:
2970 gen_helper_msachiu(t0, cpu_env, t0, t1);
2971 opn = "msachiu";
2972 break;
2973 default:
2974 MIPS_INVAL("mul vr54xx");
2975 generate_exception(ctx, EXCP_RI);
2976 goto out;
2978 gen_store_gpr(t0, rd);
2979 (void)opn; /* avoid a compiler warning */
2980 MIPS_DEBUG("%s %s, %s, %s", opn, regnames[rd], regnames[rs], regnames[rt]);
2982 out:
2983 tcg_temp_free(t0);
2984 tcg_temp_free(t1);
2987 static void gen_cl (DisasContext *ctx, uint32_t opc,
2988 int rd, int rs)
2990 const char *opn = "CLx";
2991 TCGv t0;
2993 if (rd == 0) {
2994 /* Treat as NOP. */
2995 MIPS_DEBUG("NOP");
2996 return;
2998 t0 = tcg_temp_new();
2999 gen_load_gpr(t0, rs);
3000 switch (opc) {
3001 case OPC_CLO:
3002 gen_helper_clo(cpu_gpr[rd], t0);
3003 opn = "clo";
3004 break;
3005 case OPC_CLZ:
3006 gen_helper_clz(cpu_gpr[rd], t0);
3007 opn = "clz";
3008 break;
3009 #if defined(TARGET_MIPS64)
3010 case OPC_DCLO:
3011 gen_helper_dclo(cpu_gpr[rd], t0);
3012 opn = "dclo";
3013 break;
3014 case OPC_DCLZ:
3015 gen_helper_dclz(cpu_gpr[rd], t0);
3016 opn = "dclz";
3017 break;
3018 #endif
3020 (void)opn; /* avoid a compiler warning */
3021 MIPS_DEBUG("%s %s, %s", opn, regnames[rd], regnames[rs]);
3022 tcg_temp_free(t0);
3025 /* Godson integer instructions */
3026 static void gen_loongson_integer(DisasContext *ctx, uint32_t opc,
3027 int rd, int rs, int rt)
3029 const char *opn = "loongson";
3030 TCGv t0, t1;
3032 if (rd == 0) {
3033 /* Treat as NOP. */
3034 MIPS_DEBUG("NOP");
3035 return;
3038 switch (opc) {
3039 case OPC_MULT_G_2E:
3040 case OPC_MULT_G_2F:
3041 case OPC_MULTU_G_2E:
3042 case OPC_MULTU_G_2F:
3043 #if defined(TARGET_MIPS64)
3044 case OPC_DMULT_G_2E:
3045 case OPC_DMULT_G_2F:
3046 case OPC_DMULTU_G_2E:
3047 case OPC_DMULTU_G_2F:
3048 #endif
3049 t0 = tcg_temp_new();
3050 t1 = tcg_temp_new();
3051 break;
3052 default:
3053 t0 = tcg_temp_local_new();
3054 t1 = tcg_temp_local_new();
3055 break;
3058 gen_load_gpr(t0, rs);
3059 gen_load_gpr(t1, rt);
3061 switch (opc) {
3062 case OPC_MULT_G_2E:
3063 case OPC_MULT_G_2F:
3064 tcg_gen_mul_tl(cpu_gpr[rd], t0, t1);
3065 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3066 opn = "mult.g";
3067 break;
3068 case OPC_MULTU_G_2E:
3069 case OPC_MULTU_G_2F:
3070 tcg_gen_ext32u_tl(t0, t0);
3071 tcg_gen_ext32u_tl(t1, t1);
3072 tcg_gen_mul_tl(cpu_gpr[rd], t0, t1);
3073 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3074 opn = "multu.g";
3075 break;
3076 case OPC_DIV_G_2E:
3077 case OPC_DIV_G_2F:
3079 int l1 = gen_new_label();
3080 int l2 = gen_new_label();
3081 int l3 = gen_new_label();
3082 tcg_gen_ext32s_tl(t0, t0);
3083 tcg_gen_ext32s_tl(t1, t1);
3084 tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
3085 tcg_gen_movi_tl(cpu_gpr[rd], 0);
3086 tcg_gen_br(l3);
3087 gen_set_label(l1);
3088 tcg_gen_brcondi_tl(TCG_COND_NE, t0, INT_MIN, l2);
3089 tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1, l2);
3090 tcg_gen_mov_tl(cpu_gpr[rd], t0);
3091 tcg_gen_br(l3);
3092 gen_set_label(l2);
3093 tcg_gen_div_tl(cpu_gpr[rd], t0, t1);
3094 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3095 gen_set_label(l3);
3097 opn = "div.g";
3098 break;
3099 case OPC_DIVU_G_2E:
3100 case OPC_DIVU_G_2F:
3102 int l1 = gen_new_label();
3103 int l2 = gen_new_label();
3104 tcg_gen_ext32u_tl(t0, t0);
3105 tcg_gen_ext32u_tl(t1, t1);
3106 tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
3107 tcg_gen_movi_tl(cpu_gpr[rd], 0);
3108 tcg_gen_br(l2);
3109 gen_set_label(l1);
3110 tcg_gen_divu_tl(cpu_gpr[rd], t0, t1);
3111 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3112 gen_set_label(l2);
3114 opn = "divu.g";
3115 break;
3116 case OPC_MOD_G_2E:
3117 case OPC_MOD_G_2F:
3119 int l1 = gen_new_label();
3120 int l2 = gen_new_label();
3121 int l3 = gen_new_label();
3122 tcg_gen_ext32u_tl(t0, t0);
3123 tcg_gen_ext32u_tl(t1, t1);
3124 tcg_gen_brcondi_tl(TCG_COND_EQ, t1, 0, l1);
3125 tcg_gen_brcondi_tl(TCG_COND_NE, t0, INT_MIN, l2);
3126 tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1, l2);
3127 gen_set_label(l1);
3128 tcg_gen_movi_tl(cpu_gpr[rd], 0);
3129 tcg_gen_br(l3);
3130 gen_set_label(l2);
3131 tcg_gen_rem_tl(cpu_gpr[rd], t0, t1);
3132 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3133 gen_set_label(l3);
3135 opn = "mod.g";
3136 break;
3137 case OPC_MODU_G_2E:
3138 case OPC_MODU_G_2F:
3140 int l1 = gen_new_label();
3141 int l2 = gen_new_label();
3142 tcg_gen_ext32u_tl(t0, t0);
3143 tcg_gen_ext32u_tl(t1, t1);
3144 tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
3145 tcg_gen_movi_tl(cpu_gpr[rd], 0);
3146 tcg_gen_br(l2);
3147 gen_set_label(l1);
3148 tcg_gen_remu_tl(cpu_gpr[rd], t0, t1);
3149 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3150 gen_set_label(l2);
3152 opn = "modu.g";
3153 break;
3154 #if defined(TARGET_MIPS64)
3155 case OPC_DMULT_G_2E:
3156 case OPC_DMULT_G_2F:
3157 tcg_gen_mul_tl(cpu_gpr[rd], t0, t1);
3158 opn = "dmult.g";
3159 break;
3160 case OPC_DMULTU_G_2E:
3161 case OPC_DMULTU_G_2F:
3162 tcg_gen_mul_tl(cpu_gpr[rd], t0, t1);
3163 opn = "dmultu.g";
3164 break;
3165 case OPC_DDIV_G_2E:
3166 case OPC_DDIV_G_2F:
3168 int l1 = gen_new_label();
3169 int l2 = gen_new_label();
3170 int l3 = gen_new_label();
3171 tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
3172 tcg_gen_movi_tl(cpu_gpr[rd], 0);
3173 tcg_gen_br(l3);
3174 gen_set_label(l1);
3175 tcg_gen_brcondi_tl(TCG_COND_NE, t0, -1LL << 63, l2);
3176 tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1LL, l2);
3177 tcg_gen_mov_tl(cpu_gpr[rd], t0);
3178 tcg_gen_br(l3);
3179 gen_set_label(l2);
3180 tcg_gen_div_tl(cpu_gpr[rd], t0, t1);
3181 gen_set_label(l3);
3183 opn = "ddiv.g";
3184 break;
3185 case OPC_DDIVU_G_2E:
3186 case OPC_DDIVU_G_2F:
3188 int l1 = gen_new_label();
3189 int l2 = gen_new_label();
3190 tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
3191 tcg_gen_movi_tl(cpu_gpr[rd], 0);
3192 tcg_gen_br(l2);
3193 gen_set_label(l1);
3194 tcg_gen_divu_tl(cpu_gpr[rd], t0, t1);
3195 gen_set_label(l2);
3197 opn = "ddivu.g";
3198 break;
3199 case OPC_DMOD_G_2E:
3200 case OPC_DMOD_G_2F:
3202 int l1 = gen_new_label();
3203 int l2 = gen_new_label();
3204 int l3 = gen_new_label();
3205 tcg_gen_brcondi_tl(TCG_COND_EQ, t1, 0, l1);
3206 tcg_gen_brcondi_tl(TCG_COND_NE, t0, -1LL << 63, l2);
3207 tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1LL, l2);
3208 gen_set_label(l1);
3209 tcg_gen_movi_tl(cpu_gpr[rd], 0);
3210 tcg_gen_br(l3);
3211 gen_set_label(l2);
3212 tcg_gen_rem_tl(cpu_gpr[rd], t0, t1);
3213 gen_set_label(l3);
3215 opn = "dmod.g";
3216 break;
3217 case OPC_DMODU_G_2E:
3218 case OPC_DMODU_G_2F:
3220 int l1 = gen_new_label();
3221 int l2 = gen_new_label();
3222 tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
3223 tcg_gen_movi_tl(cpu_gpr[rd], 0);
3224 tcg_gen_br(l2);
3225 gen_set_label(l1);
3226 tcg_gen_remu_tl(cpu_gpr[rd], t0, t1);
3227 gen_set_label(l2);
3229 opn = "dmodu.g";
3230 break;
3231 #endif
3234 (void)opn; /* avoid a compiler warning */
3235 MIPS_DEBUG("%s %s, %s", opn, regnames[rd], regnames[rs]);
3236 tcg_temp_free(t0);
3237 tcg_temp_free(t1);
3240 /* Loongson multimedia instructions */
3241 static void gen_loongson_multimedia(DisasContext *ctx, int rd, int rs, int rt)
3243 const char *opn = "loongson_cp2";
3244 uint32_t opc, shift_max;
3245 TCGv_i64 t0, t1;
3247 opc = MASK_LMI(ctx->opcode);
3248 switch (opc) {
3249 case OPC_ADD_CP2:
3250 case OPC_SUB_CP2:
3251 case OPC_DADD_CP2:
3252 case OPC_DSUB_CP2:
3253 t0 = tcg_temp_local_new_i64();
3254 t1 = tcg_temp_local_new_i64();
3255 break;
3256 default:
3257 t0 = tcg_temp_new_i64();
3258 t1 = tcg_temp_new_i64();
3259 break;
3262 gen_load_fpr64(ctx, t0, rs);
3263 gen_load_fpr64(ctx, t1, rt);
3265 #define LMI_HELPER(UP, LO) \
3266 case OPC_##UP: gen_helper_##LO(t0, t0, t1); opn = #LO; break
3267 #define LMI_HELPER_1(UP, LO) \
3268 case OPC_##UP: gen_helper_##LO(t0, t0); opn = #LO; break
3269 #define LMI_DIRECT(UP, LO, OP) \
3270 case OPC_##UP: tcg_gen_##OP##_i64(t0, t0, t1); opn = #LO; break
3272 switch (opc) {
3273 LMI_HELPER(PADDSH, paddsh);
3274 LMI_HELPER(PADDUSH, paddush);
3275 LMI_HELPER(PADDH, paddh);
3276 LMI_HELPER(PADDW, paddw);
3277 LMI_HELPER(PADDSB, paddsb);
3278 LMI_HELPER(PADDUSB, paddusb);
3279 LMI_HELPER(PADDB, paddb);
3281 LMI_HELPER(PSUBSH, psubsh);
3282 LMI_HELPER(PSUBUSH, psubush);
3283 LMI_HELPER(PSUBH, psubh);
3284 LMI_HELPER(PSUBW, psubw);
3285 LMI_HELPER(PSUBSB, psubsb);
3286 LMI_HELPER(PSUBUSB, psubusb);
3287 LMI_HELPER(PSUBB, psubb);
3289 LMI_HELPER(PSHUFH, pshufh);
3290 LMI_HELPER(PACKSSWH, packsswh);
3291 LMI_HELPER(PACKSSHB, packsshb);
3292 LMI_HELPER(PACKUSHB, packushb);
3294 LMI_HELPER(PUNPCKLHW, punpcklhw);
3295 LMI_HELPER(PUNPCKHHW, punpckhhw);
3296 LMI_HELPER(PUNPCKLBH, punpcklbh);
3297 LMI_HELPER(PUNPCKHBH, punpckhbh);
3298 LMI_HELPER(PUNPCKLWD, punpcklwd);
3299 LMI_HELPER(PUNPCKHWD, punpckhwd);
3301 LMI_HELPER(PAVGH, pavgh);
3302 LMI_HELPER(PAVGB, pavgb);
3303 LMI_HELPER(PMAXSH, pmaxsh);
3304 LMI_HELPER(PMINSH, pminsh);
3305 LMI_HELPER(PMAXUB, pmaxub);
3306 LMI_HELPER(PMINUB, pminub);
3308 LMI_HELPER(PCMPEQW, pcmpeqw);
3309 LMI_HELPER(PCMPGTW, pcmpgtw);
3310 LMI_HELPER(PCMPEQH, pcmpeqh);
3311 LMI_HELPER(PCMPGTH, pcmpgth);
3312 LMI_HELPER(PCMPEQB, pcmpeqb);
3313 LMI_HELPER(PCMPGTB, pcmpgtb);
3315 LMI_HELPER(PSLLW, psllw);
3316 LMI_HELPER(PSLLH, psllh);
3317 LMI_HELPER(PSRLW, psrlw);
3318 LMI_HELPER(PSRLH, psrlh);
3319 LMI_HELPER(PSRAW, psraw);
3320 LMI_HELPER(PSRAH, psrah);
3322 LMI_HELPER(PMULLH, pmullh);
3323 LMI_HELPER(PMULHH, pmulhh);
3324 LMI_HELPER(PMULHUH, pmulhuh);
3325 LMI_HELPER(PMADDHW, pmaddhw);
3327 LMI_HELPER(PASUBUB, pasubub);
3328 LMI_HELPER_1(BIADD, biadd);
3329 LMI_HELPER_1(PMOVMSKB, pmovmskb);
3331 LMI_DIRECT(PADDD, paddd, add);
3332 LMI_DIRECT(PSUBD, psubd, sub);
3333 LMI_DIRECT(XOR_CP2, xor, xor);
3334 LMI_DIRECT(NOR_CP2, nor, nor);
3335 LMI_DIRECT(AND_CP2, and, and);
3336 LMI_DIRECT(PANDN, pandn, andc);
3337 LMI_DIRECT(OR, or, or);
3339 case OPC_PINSRH_0:
3340 tcg_gen_deposit_i64(t0, t0, t1, 0, 16);
3341 opn = "pinsrh_0";
3342 break;
3343 case OPC_PINSRH_1:
3344 tcg_gen_deposit_i64(t0, t0, t1, 16, 16);
3345 opn = "pinsrh_1";
3346 break;
3347 case OPC_PINSRH_2:
3348 tcg_gen_deposit_i64(t0, t0, t1, 32, 16);
3349 opn = "pinsrh_2";
3350 break;
3351 case OPC_PINSRH_3:
3352 tcg_gen_deposit_i64(t0, t0, t1, 48, 16);
3353 opn = "pinsrh_3";
3354 break;
3356 case OPC_PEXTRH:
3357 tcg_gen_andi_i64(t1, t1, 3);
3358 tcg_gen_shli_i64(t1, t1, 4);
3359 tcg_gen_shr_i64(t0, t0, t1);
3360 tcg_gen_ext16u_i64(t0, t0);
3361 opn = "pextrh";
3362 break;
3364 case OPC_ADDU_CP2:
3365 tcg_gen_add_i64(t0, t0, t1);
3366 tcg_gen_ext32s_i64(t0, t0);
3367 opn = "addu";
3368 break;
3369 case OPC_SUBU_CP2:
3370 tcg_gen_sub_i64(t0, t0, t1);
3371 tcg_gen_ext32s_i64(t0, t0);
3372 opn = "addu";
3373 break;
3375 case OPC_SLL_CP2:
3376 opn = "sll";
3377 shift_max = 32;
3378 goto do_shift;
3379 case OPC_SRL_CP2:
3380 opn = "srl";
3381 shift_max = 32;
3382 goto do_shift;
3383 case OPC_SRA_CP2:
3384 opn = "sra";
3385 shift_max = 32;
3386 goto do_shift;
3387 case OPC_DSLL_CP2:
3388 opn = "dsll";
3389 shift_max = 64;
3390 goto do_shift;
3391 case OPC_DSRL_CP2:
3392 opn = "dsrl";
3393 shift_max = 64;
3394 goto do_shift;
3395 case OPC_DSRA_CP2:
3396 opn = "dsra";
3397 shift_max = 64;
3398 goto do_shift;
3399 do_shift:
3400 /* Make sure shift count isn't TCG undefined behaviour. */
3401 tcg_gen_andi_i64(t1, t1, shift_max - 1);
3403 switch (opc) {
3404 case OPC_SLL_CP2:
3405 case OPC_DSLL_CP2:
3406 tcg_gen_shl_i64(t0, t0, t1);
3407 break;
3408 case OPC_SRA_CP2:
3409 case OPC_DSRA_CP2:
3410 /* Since SRA is UndefinedResult without sign-extended inputs,
3411 we can treat SRA and DSRA the same. */
3412 tcg_gen_sar_i64(t0, t0, t1);
3413 break;
3414 case OPC_SRL_CP2:
3415 /* We want to shift in zeros for SRL; zero-extend first. */
3416 tcg_gen_ext32u_i64(t0, t0);
3417 /* FALLTHRU */
3418 case OPC_DSRL_CP2:
3419 tcg_gen_shr_i64(t0, t0, t1);
3420 break;
3423 if (shift_max == 32) {
3424 tcg_gen_ext32s_i64(t0, t0);
3427 /* Shifts larger than MAX produce zero. */
3428 tcg_gen_setcondi_i64(TCG_COND_LTU, t1, t1, shift_max);
3429 tcg_gen_neg_i64(t1, t1);
3430 tcg_gen_and_i64(t0, t0, t1);
3431 break;
3433 case OPC_ADD_CP2:
3434 case OPC_DADD_CP2:
3436 TCGv_i64 t2 = tcg_temp_new_i64();
3437 int lab = gen_new_label();
3439 tcg_gen_mov_i64(t2, t0);
3440 tcg_gen_add_i64(t0, t1, t2);
3441 if (opc == OPC_ADD_CP2) {
3442 tcg_gen_ext32s_i64(t0, t0);
3444 tcg_gen_xor_i64(t1, t1, t2);
3445 tcg_gen_xor_i64(t2, t2, t0);
3446 tcg_gen_andc_i64(t1, t2, t1);
3447 tcg_temp_free_i64(t2);
3448 tcg_gen_brcondi_i64(TCG_COND_GE, t1, 0, lab);
3449 generate_exception(ctx, EXCP_OVERFLOW);
3450 gen_set_label(lab);
3452 opn = (opc == OPC_ADD_CP2 ? "add" : "dadd");
3453 break;
3456 case OPC_SUB_CP2:
3457 case OPC_DSUB_CP2:
3459 TCGv_i64 t2 = tcg_temp_new_i64();
3460 int lab = gen_new_label();
3462 tcg_gen_mov_i64(t2, t0);
3463 tcg_gen_sub_i64(t0, t1, t2);
3464 if (opc == OPC_SUB_CP2) {
3465 tcg_gen_ext32s_i64(t0, t0);
3467 tcg_gen_xor_i64(t1, t1, t2);
3468 tcg_gen_xor_i64(t2, t2, t0);
3469 tcg_gen_and_i64(t1, t1, t2);
3470 tcg_temp_free_i64(t2);
3471 tcg_gen_brcondi_i64(TCG_COND_GE, t1, 0, lab);
3472 generate_exception(ctx, EXCP_OVERFLOW);
3473 gen_set_label(lab);
3475 opn = (opc == OPC_SUB_CP2 ? "sub" : "dsub");
3476 break;
3479 case OPC_PMULUW:
3480 tcg_gen_ext32u_i64(t0, t0);
3481 tcg_gen_ext32u_i64(t1, t1);
3482 tcg_gen_mul_i64(t0, t0, t1);
3483 opn = "pmuluw";
3484 break;
3486 case OPC_SEQU_CP2:
3487 case OPC_SEQ_CP2:
3488 case OPC_SLTU_CP2:
3489 case OPC_SLT_CP2:
3490 case OPC_SLEU_CP2:
3491 case OPC_SLE_CP2:
3492 /* ??? Document is unclear: Set FCC[CC]. Does that mean the
3493 FD field is the CC field? */
3494 default:
3495 MIPS_INVAL(opn);
3496 generate_exception(ctx, EXCP_RI);
3497 return;
3500 #undef LMI_HELPER
3501 #undef LMI_DIRECT
3503 gen_store_fpr64(ctx, t0, rd);
3505 (void)opn; /* avoid a compiler warning */
3506 MIPS_DEBUG("%s %s, %s, %s", opn,
3507 fregnames[rd], fregnames[rs], fregnames[rt]);
3508 tcg_temp_free_i64(t0);
3509 tcg_temp_free_i64(t1);
3512 /* Traps */
3513 static void gen_trap (DisasContext *ctx, uint32_t opc,
3514 int rs, int rt, int16_t imm)
3516 int cond;
3517 TCGv t0 = tcg_temp_new();
3518 TCGv t1 = tcg_temp_new();
3520 cond = 0;
3521 /* Load needed operands */
3522 switch (opc) {
3523 case OPC_TEQ:
3524 case OPC_TGE:
3525 case OPC_TGEU:
3526 case OPC_TLT:
3527 case OPC_TLTU:
3528 case OPC_TNE:
3529 /* Compare two registers */
3530 if (rs != rt) {
3531 gen_load_gpr(t0, rs);
3532 gen_load_gpr(t1, rt);
3533 cond = 1;
3535 break;
3536 case OPC_TEQI:
3537 case OPC_TGEI:
3538 case OPC_TGEIU:
3539 case OPC_TLTI:
3540 case OPC_TLTIU:
3541 case OPC_TNEI:
3542 /* Compare register to immediate */
3543 if (rs != 0 || imm != 0) {
3544 gen_load_gpr(t0, rs);
3545 tcg_gen_movi_tl(t1, (int32_t)imm);
3546 cond = 1;
3548 break;
3550 if (cond == 0) {
3551 switch (opc) {
3552 case OPC_TEQ: /* rs == rs */
3553 case OPC_TEQI: /* r0 == 0 */
3554 case OPC_TGE: /* rs >= rs */
3555 case OPC_TGEI: /* r0 >= 0 */
3556 case OPC_TGEU: /* rs >= rs unsigned */
3557 case OPC_TGEIU: /* r0 >= 0 unsigned */
3558 /* Always trap */
3559 generate_exception(ctx, EXCP_TRAP);
3560 break;
3561 case OPC_TLT: /* rs < rs */
3562 case OPC_TLTI: /* r0 < 0 */
3563 case OPC_TLTU: /* rs < rs unsigned */
3564 case OPC_TLTIU: /* r0 < 0 unsigned */
3565 case OPC_TNE: /* rs != rs */
3566 case OPC_TNEI: /* r0 != 0 */
3567 /* Never trap: treat as NOP. */
3568 break;
3570 } else {
3571 int l1 = gen_new_label();
3573 switch (opc) {
3574 case OPC_TEQ:
3575 case OPC_TEQI:
3576 tcg_gen_brcond_tl(TCG_COND_NE, t0, t1, l1);
3577 break;
3578 case OPC_TGE:
3579 case OPC_TGEI:
3580 tcg_gen_brcond_tl(TCG_COND_LT, t0, t1, l1);
3581 break;
3582 case OPC_TGEU:
3583 case OPC_TGEIU:
3584 tcg_gen_brcond_tl(TCG_COND_LTU, t0, t1, l1);
3585 break;
3586 case OPC_TLT:
3587 case OPC_TLTI:
3588 tcg_gen_brcond_tl(TCG_COND_GE, t0, t1, l1);
3589 break;
3590 case OPC_TLTU:
3591 case OPC_TLTIU:
3592 tcg_gen_brcond_tl(TCG_COND_GEU, t0, t1, l1);
3593 break;
3594 case OPC_TNE:
3595 case OPC_TNEI:
3596 tcg_gen_brcond_tl(TCG_COND_EQ, t0, t1, l1);
3597 break;
3599 generate_exception(ctx, EXCP_TRAP);
3600 gen_set_label(l1);
3602 tcg_temp_free(t0);
3603 tcg_temp_free(t1);
3606 static inline void gen_goto_tb(DisasContext *ctx, int n, target_ulong dest)
3608 TranslationBlock *tb;
3609 tb = ctx->tb;
3610 if ((tb->pc & TARGET_PAGE_MASK) == (dest & TARGET_PAGE_MASK) &&
3611 likely(!ctx->singlestep_enabled)) {
3612 tcg_gen_goto_tb(n);
3613 gen_save_pc(dest);
3614 tcg_gen_exit_tb((tcg_target_long)tb + n);
3615 } else {
3616 gen_save_pc(dest);
3617 if (ctx->singlestep_enabled) {
3618 save_cpu_state(ctx, 0);
3619 gen_helper_0e0i(raise_exception, EXCP_DEBUG);
3621 tcg_gen_exit_tb(0);
3625 /* Branches (before delay slot) */
3626 static void gen_compute_branch (DisasContext *ctx, uint32_t opc,
3627 int insn_bytes,
3628 int rs, int rt, int32_t offset)
3630 target_ulong btgt = -1;
3631 int blink = 0;
3632 int bcond_compute = 0;
3633 TCGv t0 = tcg_temp_new();
3634 TCGv t1 = tcg_temp_new();
3636 if (ctx->hflags & MIPS_HFLAG_BMASK) {
3637 #ifdef MIPS_DEBUG_DISAS
3638 LOG_DISAS("Branch in delay slot at PC 0x" TARGET_FMT_lx "\n", ctx->pc);
3639 #endif
3640 generate_exception(ctx, EXCP_RI);
3641 goto out;
3644 /* Load needed operands */
3645 switch (opc) {
3646 case OPC_BEQ:
3647 case OPC_BEQL:
3648 case OPC_BNE:
3649 case OPC_BNEL:
3650 /* Compare two registers */
3651 if (rs != rt) {
3652 gen_load_gpr(t0, rs);
3653 gen_load_gpr(t1, rt);
3654 bcond_compute = 1;
3656 btgt = ctx->pc + insn_bytes + offset;
3657 break;
3658 case OPC_BGEZ:
3659 case OPC_BGEZAL:
3660 case OPC_BGEZALS:
3661 case OPC_BGEZALL:
3662 case OPC_BGEZL:
3663 case OPC_BGTZ:
3664 case OPC_BGTZL:
3665 case OPC_BLEZ:
3666 case OPC_BLEZL:
3667 case OPC_BLTZ:
3668 case OPC_BLTZAL:
3669 case OPC_BLTZALS:
3670 case OPC_BLTZALL:
3671 case OPC_BLTZL:
3672 /* Compare to zero */
3673 if (rs != 0) {
3674 gen_load_gpr(t0, rs);
3675 bcond_compute = 1;
3677 btgt = ctx->pc + insn_bytes + offset;
3678 break;
3679 case OPC_BPOSGE32:
3680 #if defined(TARGET_MIPS64)
3681 case OPC_BPOSGE64:
3682 tcg_gen_andi_tl(t0, cpu_dspctrl, 0x7F);
3683 #else
3684 tcg_gen_andi_tl(t0, cpu_dspctrl, 0x3F);
3685 #endif
3686 bcond_compute = 1;
3687 btgt = ctx->pc + insn_bytes + offset;
3688 break;
3689 case OPC_J:
3690 case OPC_JAL:
3691 case OPC_JALX:
3692 case OPC_JALS:
3693 case OPC_JALXS:
3694 /* Jump to immediate */
3695 btgt = ((ctx->pc + insn_bytes) & (int32_t)0xF0000000) | (uint32_t)offset;
3696 break;
3697 case OPC_JR:
3698 case OPC_JALR:
3699 case OPC_JALRC:
3700 case OPC_JALRS:
3701 /* Jump to register */
3702 if (offset != 0 && offset != 16) {
3703 /* Hint = 0 is JR/JALR, hint 16 is JR.HB/JALR.HB, the
3704 others are reserved. */
3705 MIPS_INVAL("jump hint");
3706 generate_exception(ctx, EXCP_RI);
3707 goto out;
3709 gen_load_gpr(btarget, rs);
3710 break;
3711 default:
3712 MIPS_INVAL("branch/jump");
3713 generate_exception(ctx, EXCP_RI);
3714 goto out;
3716 if (bcond_compute == 0) {
3717 /* No condition to be computed */
3718 switch (opc) {
3719 case OPC_BEQ: /* rx == rx */
3720 case OPC_BEQL: /* rx == rx likely */
3721 case OPC_BGEZ: /* 0 >= 0 */
3722 case OPC_BGEZL: /* 0 >= 0 likely */
3723 case OPC_BLEZ: /* 0 <= 0 */
3724 case OPC_BLEZL: /* 0 <= 0 likely */
3725 /* Always take */
3726 ctx->hflags |= MIPS_HFLAG_B;
3727 MIPS_DEBUG("balways");
3728 break;
3729 case OPC_BGEZALS:
3730 case OPC_BGEZAL: /* 0 >= 0 */
3731 case OPC_BGEZALL: /* 0 >= 0 likely */
3732 ctx->hflags |= (opc == OPC_BGEZALS
3733 ? MIPS_HFLAG_BDS16
3734 : MIPS_HFLAG_BDS32);
3735 /* Always take and link */
3736 blink = 31;
3737 ctx->hflags |= MIPS_HFLAG_B;
3738 MIPS_DEBUG("balways and link");
3739 break;
3740 case OPC_BNE: /* rx != rx */
3741 case OPC_BGTZ: /* 0 > 0 */
3742 case OPC_BLTZ: /* 0 < 0 */
3743 /* Treat as NOP. */
3744 MIPS_DEBUG("bnever (NOP)");
3745 goto out;
3746 case OPC_BLTZALS:
3747 case OPC_BLTZAL: /* 0 < 0 */
3748 ctx->hflags |= (opc == OPC_BLTZALS
3749 ? MIPS_HFLAG_BDS16
3750 : MIPS_HFLAG_BDS32);
3751 /* Handle as an unconditional branch to get correct delay
3752 slot checking. */
3753 blink = 31;
3754 btgt = ctx->pc + (opc == OPC_BLTZALS ? 6 : 8);
3755 ctx->hflags |= MIPS_HFLAG_B;
3756 MIPS_DEBUG("bnever and link");
3757 break;
3758 case OPC_BLTZALL: /* 0 < 0 likely */
3759 tcg_gen_movi_tl(cpu_gpr[31], ctx->pc + 8);
3760 /* Skip the instruction in the delay slot */
3761 MIPS_DEBUG("bnever, link and skip");
3762 ctx->pc += 4;
3763 goto out;
3764 case OPC_BNEL: /* rx != rx likely */
3765 case OPC_BGTZL: /* 0 > 0 likely */
3766 case OPC_BLTZL: /* 0 < 0 likely */
3767 /* Skip the instruction in the delay slot */
3768 MIPS_DEBUG("bnever and skip");
3769 ctx->pc += 4;
3770 goto out;
3771 case OPC_J:
3772 ctx->hflags |= MIPS_HFLAG_B;
3773 MIPS_DEBUG("j " TARGET_FMT_lx, btgt);
3774 break;
3775 case OPC_JALXS:
3776 case OPC_JALX:
3777 ctx->hflags |= MIPS_HFLAG_BX;
3778 /* Fallthrough */
3779 case OPC_JALS:
3780 case OPC_JAL:
3781 blink = 31;
3782 ctx->hflags |= MIPS_HFLAG_B;
3783 ctx->hflags |= ((opc == OPC_JALS || opc == OPC_JALXS)
3784 ? MIPS_HFLAG_BDS16
3785 : MIPS_HFLAG_BDS32);
3786 MIPS_DEBUG("jal " TARGET_FMT_lx, btgt);
3787 break;
3788 case OPC_JR:
3789 ctx->hflags |= MIPS_HFLAG_BR;
3790 if (insn_bytes == 4)
3791 ctx->hflags |= MIPS_HFLAG_BDS32;
3792 MIPS_DEBUG("jr %s", regnames[rs]);
3793 break;
3794 case OPC_JALRS:
3795 case OPC_JALR:
3796 case OPC_JALRC:
3797 blink = rt;
3798 ctx->hflags |= MIPS_HFLAG_BR;
3799 ctx->hflags |= (opc == OPC_JALRS
3800 ? MIPS_HFLAG_BDS16
3801 : MIPS_HFLAG_BDS32);
3802 MIPS_DEBUG("jalr %s, %s", regnames[rt], regnames[rs]);
3803 break;
3804 default:
3805 MIPS_INVAL("branch/jump");
3806 generate_exception(ctx, EXCP_RI);
3807 goto out;
3809 } else {
3810 switch (opc) {
3811 case OPC_BEQ:
3812 tcg_gen_setcond_tl(TCG_COND_EQ, bcond, t0, t1);
3813 MIPS_DEBUG("beq %s, %s, " TARGET_FMT_lx,
3814 regnames[rs], regnames[rt], btgt);
3815 goto not_likely;
3816 case OPC_BEQL:
3817 tcg_gen_setcond_tl(TCG_COND_EQ, bcond, t0, t1);
3818 MIPS_DEBUG("beql %s, %s, " TARGET_FMT_lx,
3819 regnames[rs], regnames[rt], btgt);
3820 goto likely;
3821 case OPC_BNE:
3822 tcg_gen_setcond_tl(TCG_COND_NE, bcond, t0, t1);
3823 MIPS_DEBUG("bne %s, %s, " TARGET_FMT_lx,
3824 regnames[rs], regnames[rt], btgt);
3825 goto not_likely;
3826 case OPC_BNEL:
3827 tcg_gen_setcond_tl(TCG_COND_NE, bcond, t0, t1);
3828 MIPS_DEBUG("bnel %s, %s, " TARGET_FMT_lx,
3829 regnames[rs], regnames[rt], btgt);
3830 goto likely;
3831 case OPC_BGEZ:
3832 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 0);
3833 MIPS_DEBUG("bgez %s, " TARGET_FMT_lx, regnames[rs], btgt);
3834 goto not_likely;
3835 case OPC_BGEZL:
3836 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 0);
3837 MIPS_DEBUG("bgezl %s, " TARGET_FMT_lx, regnames[rs], btgt);
3838 goto likely;
3839 case OPC_BGEZALS:
3840 case OPC_BGEZAL:
3841 ctx->hflags |= (opc == OPC_BGEZALS
3842 ? MIPS_HFLAG_BDS16
3843 : MIPS_HFLAG_BDS32);
3844 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 0);
3845 MIPS_DEBUG("bgezal %s, " TARGET_FMT_lx, regnames[rs], btgt);
3846 blink = 31;
3847 goto not_likely;
3848 case OPC_BGEZALL:
3849 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 0);
3850 blink = 31;
3851 MIPS_DEBUG("bgezall %s, " TARGET_FMT_lx, regnames[rs], btgt);
3852 goto likely;
3853 case OPC_BGTZ:
3854 tcg_gen_setcondi_tl(TCG_COND_GT, bcond, t0, 0);
3855 MIPS_DEBUG("bgtz %s, " TARGET_FMT_lx, regnames[rs], btgt);
3856 goto not_likely;
3857 case OPC_BGTZL:
3858 tcg_gen_setcondi_tl(TCG_COND_GT, bcond, t0, 0);
3859 MIPS_DEBUG("bgtzl %s, " TARGET_FMT_lx, regnames[rs], btgt);
3860 goto likely;
3861 case OPC_BLEZ:
3862 tcg_gen_setcondi_tl(TCG_COND_LE, bcond, t0, 0);
3863 MIPS_DEBUG("blez %s, " TARGET_FMT_lx, regnames[rs], btgt);
3864 goto not_likely;
3865 case OPC_BLEZL:
3866 tcg_gen_setcondi_tl(TCG_COND_LE, bcond, t0, 0);
3867 MIPS_DEBUG("blezl %s, " TARGET_FMT_lx, regnames[rs], btgt);
3868 goto likely;
3869 case OPC_BLTZ:
3870 tcg_gen_setcondi_tl(TCG_COND_LT, bcond, t0, 0);
3871 MIPS_DEBUG("bltz %s, " TARGET_FMT_lx, regnames[rs], btgt);
3872 goto not_likely;
3873 case OPC_BLTZL:
3874 tcg_gen_setcondi_tl(TCG_COND_LT, bcond, t0, 0);
3875 MIPS_DEBUG("bltzl %s, " TARGET_FMT_lx, regnames[rs], btgt);
3876 goto likely;
3877 case OPC_BPOSGE32:
3878 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 32);
3879 MIPS_DEBUG("bposge32 " TARGET_FMT_lx, btgt);
3880 goto not_likely;
3881 #if defined(TARGET_MIPS64)
3882 case OPC_BPOSGE64:
3883 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 64);
3884 MIPS_DEBUG("bposge64 " TARGET_FMT_lx, btgt);
3885 goto not_likely;
3886 #endif
3887 case OPC_BLTZALS:
3888 case OPC_BLTZAL:
3889 ctx->hflags |= (opc == OPC_BLTZALS
3890 ? MIPS_HFLAG_BDS16
3891 : MIPS_HFLAG_BDS32);
3892 tcg_gen_setcondi_tl(TCG_COND_LT, bcond, t0, 0);
3893 blink = 31;
3894 MIPS_DEBUG("bltzal %s, " TARGET_FMT_lx, regnames[rs], btgt);
3895 not_likely:
3896 ctx->hflags |= MIPS_HFLAG_BC;
3897 break;
3898 case OPC_BLTZALL:
3899 tcg_gen_setcondi_tl(TCG_COND_LT, bcond, t0, 0);
3900 blink = 31;
3901 MIPS_DEBUG("bltzall %s, " TARGET_FMT_lx, regnames[rs], btgt);
3902 likely:
3903 ctx->hflags |= MIPS_HFLAG_BL;
3904 break;
3905 default:
3906 MIPS_INVAL("conditional branch/jump");
3907 generate_exception(ctx, EXCP_RI);
3908 goto out;
3911 MIPS_DEBUG("enter ds: link %d cond %02x target " TARGET_FMT_lx,
3912 blink, ctx->hflags, btgt);
3914 ctx->btarget = btgt;
3915 if (blink > 0) {
3916 int post_delay = insn_bytes;
3917 int lowbit = !!(ctx->hflags & MIPS_HFLAG_M16);
3919 if (opc != OPC_JALRC)
3920 post_delay += ((ctx->hflags & MIPS_HFLAG_BDS16) ? 2 : 4);
3922 tcg_gen_movi_tl(cpu_gpr[blink], ctx->pc + post_delay + lowbit);
3925 out:
3926 if (insn_bytes == 2)
3927 ctx->hflags |= MIPS_HFLAG_B16;
3928 tcg_temp_free(t0);
3929 tcg_temp_free(t1);
3932 /* special3 bitfield operations */
3933 static void gen_bitops (DisasContext *ctx, uint32_t opc, int rt,
3934 int rs, int lsb, int msb)
3936 TCGv t0 = tcg_temp_new();
3937 TCGv t1 = tcg_temp_new();
3939 gen_load_gpr(t1, rs);
3940 switch (opc) {
3941 case OPC_EXT:
3942 if (lsb + msb > 31)
3943 goto fail;
3944 tcg_gen_shri_tl(t0, t1, lsb);
3945 if (msb != 31) {
3946 tcg_gen_andi_tl(t0, t0, (1 << (msb + 1)) - 1);
3947 } else {
3948 tcg_gen_ext32s_tl(t0, t0);
3950 break;
3951 #if defined(TARGET_MIPS64)
3952 case OPC_DEXTM:
3953 tcg_gen_shri_tl(t0, t1, lsb);
3954 if (msb != 31) {
3955 tcg_gen_andi_tl(t0, t0, (1ULL << (msb + 1 + 32)) - 1);
3957 break;
3958 case OPC_DEXTU:
3959 tcg_gen_shri_tl(t0, t1, lsb + 32);
3960 tcg_gen_andi_tl(t0, t0, (1ULL << (msb + 1)) - 1);
3961 break;
3962 case OPC_DEXT:
3963 tcg_gen_shri_tl(t0, t1, lsb);
3964 tcg_gen_andi_tl(t0, t0, (1ULL << (msb + 1)) - 1);
3965 break;
3966 #endif
3967 case OPC_INS:
3968 if (lsb > msb)
3969 goto fail;
3970 gen_load_gpr(t0, rt);
3971 tcg_gen_deposit_tl(t0, t0, t1, lsb, msb - lsb + 1);
3972 tcg_gen_ext32s_tl(t0, t0);
3973 break;
3974 #if defined(TARGET_MIPS64)
3975 case OPC_DINSM:
3976 gen_load_gpr(t0, rt);
3977 tcg_gen_deposit_tl(t0, t0, t1, lsb, msb + 32 - lsb + 1);
3978 break;
3979 case OPC_DINSU:
3980 gen_load_gpr(t0, rt);
3981 tcg_gen_deposit_tl(t0, t0, t1, lsb + 32, msb - lsb + 1);
3982 break;
3983 case OPC_DINS:
3984 gen_load_gpr(t0, rt);
3985 tcg_gen_deposit_tl(t0, t0, t1, lsb, msb - lsb + 1);
3986 break;
3987 #endif
3988 default:
3989 fail:
3990 MIPS_INVAL("bitops");
3991 generate_exception(ctx, EXCP_RI);
3992 tcg_temp_free(t0);
3993 tcg_temp_free(t1);
3994 return;
3996 gen_store_gpr(t0, rt);
3997 tcg_temp_free(t0);
3998 tcg_temp_free(t1);
4001 static void gen_bshfl (DisasContext *ctx, uint32_t op2, int rt, int rd)
4003 TCGv t0;
4005 if (rd == 0) {
4006 /* If no destination, treat it as a NOP. */
4007 MIPS_DEBUG("NOP");
4008 return;
4011 t0 = tcg_temp_new();
4012 gen_load_gpr(t0, rt);
4013 switch (op2) {
4014 case OPC_WSBH:
4016 TCGv t1 = tcg_temp_new();
4018 tcg_gen_shri_tl(t1, t0, 8);
4019 tcg_gen_andi_tl(t1, t1, 0x00FF00FF);
4020 tcg_gen_shli_tl(t0, t0, 8);
4021 tcg_gen_andi_tl(t0, t0, ~0x00FF00FF);
4022 tcg_gen_or_tl(t0, t0, t1);
4023 tcg_temp_free(t1);
4024 tcg_gen_ext32s_tl(cpu_gpr[rd], t0);
4026 break;
4027 case OPC_SEB:
4028 tcg_gen_ext8s_tl(cpu_gpr[rd], t0);
4029 break;
4030 case OPC_SEH:
4031 tcg_gen_ext16s_tl(cpu_gpr[rd], t0);
4032 break;
4033 #if defined(TARGET_MIPS64)
4034 case OPC_DSBH:
4036 TCGv t1 = tcg_temp_new();
4038 tcg_gen_shri_tl(t1, t0, 8);
4039 tcg_gen_andi_tl(t1, t1, 0x00FF00FF00FF00FFULL);
4040 tcg_gen_shli_tl(t0, t0, 8);
4041 tcg_gen_andi_tl(t0, t0, ~0x00FF00FF00FF00FFULL);
4042 tcg_gen_or_tl(cpu_gpr[rd], t0, t1);
4043 tcg_temp_free(t1);
4045 break;
4046 case OPC_DSHD:
4048 TCGv t1 = tcg_temp_new();
4050 tcg_gen_shri_tl(t1, t0, 16);
4051 tcg_gen_andi_tl(t1, t1, 0x0000FFFF0000FFFFULL);
4052 tcg_gen_shli_tl(t0, t0, 16);
4053 tcg_gen_andi_tl(t0, t0, ~0x0000FFFF0000FFFFULL);
4054 tcg_gen_or_tl(t0, t0, t1);
4055 tcg_gen_shri_tl(t1, t0, 32);
4056 tcg_gen_shli_tl(t0, t0, 32);
4057 tcg_gen_or_tl(cpu_gpr[rd], t0, t1);
4058 tcg_temp_free(t1);
4060 break;
4061 #endif
4062 default:
4063 MIPS_INVAL("bsfhl");
4064 generate_exception(ctx, EXCP_RI);
4065 tcg_temp_free(t0);
4066 return;
4068 tcg_temp_free(t0);
4071 #ifndef CONFIG_USER_ONLY
4072 /* CP0 (MMU and control) */
4073 static inline void gen_mfc0_load32 (TCGv arg, target_ulong off)
4075 TCGv_i32 t0 = tcg_temp_new_i32();
4077 tcg_gen_ld_i32(t0, cpu_env, off);
4078 tcg_gen_ext_i32_tl(arg, t0);
4079 tcg_temp_free_i32(t0);
4082 static inline void gen_mfc0_load64 (TCGv arg, target_ulong off)
4084 tcg_gen_ld_tl(arg, cpu_env, off);
4085 tcg_gen_ext32s_tl(arg, arg);
4088 static inline void gen_mtc0_store32 (TCGv arg, target_ulong off)
4090 TCGv_i32 t0 = tcg_temp_new_i32();
4092 tcg_gen_trunc_tl_i32(t0, arg);
4093 tcg_gen_st_i32(t0, cpu_env, off);
4094 tcg_temp_free_i32(t0);
4097 static inline void gen_mtc0_store64 (TCGv arg, target_ulong off)
4099 tcg_gen_ext32s_tl(arg, arg);
4100 tcg_gen_st_tl(arg, cpu_env, off);
4103 static void gen_mfc0(DisasContext *ctx, TCGv arg, int reg, int sel)
4105 const char *rn = "invalid";
4107 if (sel != 0)
4108 check_insn(ctx, ISA_MIPS32);
4110 switch (reg) {
4111 case 0:
4112 switch (sel) {
4113 case 0:
4114 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Index));
4115 rn = "Index";
4116 break;
4117 case 1:
4118 check_insn(ctx, ASE_MT);
4119 gen_helper_mfc0_mvpcontrol(arg, cpu_env);
4120 rn = "MVPControl";
4121 break;
4122 case 2:
4123 check_insn(ctx, ASE_MT);
4124 gen_helper_mfc0_mvpconf0(arg, cpu_env);
4125 rn = "MVPConf0";
4126 break;
4127 case 3:
4128 check_insn(ctx, ASE_MT);
4129 gen_helper_mfc0_mvpconf1(arg, cpu_env);
4130 rn = "MVPConf1";
4131 break;
4132 default:
4133 goto die;
4135 break;
4136 case 1:
4137 switch (sel) {
4138 case 0:
4139 gen_helper_mfc0_random(arg, cpu_env);
4140 rn = "Random";
4141 break;
4142 case 1:
4143 check_insn(ctx, ASE_MT);
4144 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEControl));
4145 rn = "VPEControl";
4146 break;
4147 case 2:
4148 check_insn(ctx, ASE_MT);
4149 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEConf0));
4150 rn = "VPEConf0";
4151 break;
4152 case 3:
4153 check_insn(ctx, ASE_MT);
4154 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEConf1));
4155 rn = "VPEConf1";
4156 break;
4157 case 4:
4158 check_insn(ctx, ASE_MT);
4159 gen_mfc0_load64(arg, offsetof(CPUMIPSState, CP0_YQMask));
4160 rn = "YQMask";
4161 break;
4162 case 5:
4163 check_insn(ctx, ASE_MT);
4164 gen_mfc0_load64(arg, offsetof(CPUMIPSState, CP0_VPESchedule));
4165 rn = "VPESchedule";
4166 break;
4167 case 6:
4168 check_insn(ctx, ASE_MT);
4169 gen_mfc0_load64(arg, offsetof(CPUMIPSState, CP0_VPEScheFBack));
4170 rn = "VPEScheFBack";
4171 break;
4172 case 7:
4173 check_insn(ctx, ASE_MT);
4174 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEOpt));
4175 rn = "VPEOpt";
4176 break;
4177 default:
4178 goto die;
4180 break;
4181 case 2:
4182 switch (sel) {
4183 case 0:
4184 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EntryLo0));
4185 tcg_gen_ext32s_tl(arg, arg);
4186 rn = "EntryLo0";
4187 break;
4188 case 1:
4189 check_insn(ctx, ASE_MT);
4190 gen_helper_mfc0_tcstatus(arg, cpu_env);
4191 rn = "TCStatus";
4192 break;
4193 case 2:
4194 check_insn(ctx, ASE_MT);
4195 gen_helper_mfc0_tcbind(arg, cpu_env);
4196 rn = "TCBind";
4197 break;
4198 case 3:
4199 check_insn(ctx, ASE_MT);
4200 gen_helper_mfc0_tcrestart(arg, cpu_env);
4201 rn = "TCRestart";
4202 break;
4203 case 4:
4204 check_insn(ctx, ASE_MT);
4205 gen_helper_mfc0_tchalt(arg, cpu_env);
4206 rn = "TCHalt";
4207 break;
4208 case 5:
4209 check_insn(ctx, ASE_MT);
4210 gen_helper_mfc0_tccontext(arg, cpu_env);
4211 rn = "TCContext";
4212 break;
4213 case 6:
4214 check_insn(ctx, ASE_MT);
4215 gen_helper_mfc0_tcschedule(arg, cpu_env);
4216 rn = "TCSchedule";
4217 break;
4218 case 7:
4219 check_insn(ctx, ASE_MT);
4220 gen_helper_mfc0_tcschefback(arg, cpu_env);
4221 rn = "TCScheFBack";
4222 break;
4223 default:
4224 goto die;
4226 break;
4227 case 3:
4228 switch (sel) {
4229 case 0:
4230 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EntryLo1));
4231 tcg_gen_ext32s_tl(arg, arg);
4232 rn = "EntryLo1";
4233 break;
4234 default:
4235 goto die;
4237 break;
4238 case 4:
4239 switch (sel) {
4240 case 0:
4241 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_Context));
4242 tcg_gen_ext32s_tl(arg, arg);
4243 rn = "Context";
4244 break;
4245 case 1:
4246 // gen_helper_mfc0_contextconfig(arg); /* SmartMIPS ASE */
4247 rn = "ContextConfig";
4248 // break;
4249 default:
4250 goto die;
4252 break;
4253 case 5:
4254 switch (sel) {
4255 case 0:
4256 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PageMask));
4257 rn = "PageMask";
4258 break;
4259 case 1:
4260 check_insn(ctx, ISA_MIPS32R2);
4261 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PageGrain));
4262 rn = "PageGrain";
4263 break;
4264 default:
4265 goto die;
4267 break;
4268 case 6:
4269 switch (sel) {
4270 case 0:
4271 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Wired));
4272 rn = "Wired";
4273 break;
4274 case 1:
4275 check_insn(ctx, ISA_MIPS32R2);
4276 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf0));
4277 rn = "SRSConf0";
4278 break;
4279 case 2:
4280 check_insn(ctx, ISA_MIPS32R2);
4281 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf1));
4282 rn = "SRSConf1";
4283 break;
4284 case 3:
4285 check_insn(ctx, ISA_MIPS32R2);
4286 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf2));
4287 rn = "SRSConf2";
4288 break;
4289 case 4:
4290 check_insn(ctx, ISA_MIPS32R2);
4291 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf3));
4292 rn = "SRSConf3";
4293 break;
4294 case 5:
4295 check_insn(ctx, ISA_MIPS32R2);
4296 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf4));
4297 rn = "SRSConf4";
4298 break;
4299 default:
4300 goto die;
4302 break;
4303 case 7:
4304 switch (sel) {
4305 case 0:
4306 check_insn(ctx, ISA_MIPS32R2);
4307 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_HWREna));
4308 rn = "HWREna";
4309 break;
4310 default:
4311 goto die;
4313 break;
4314 case 8:
4315 switch (sel) {
4316 case 0:
4317 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_BadVAddr));
4318 tcg_gen_ext32s_tl(arg, arg);
4319 rn = "BadVAddr";
4320 break;
4321 default:
4322 goto die;
4324 break;
4325 case 9:
4326 switch (sel) {
4327 case 0:
4328 /* Mark as an IO operation because we read the time. */
4329 if (use_icount)
4330 gen_io_start();
4331 gen_helper_mfc0_count(arg, cpu_env);
4332 if (use_icount) {
4333 gen_io_end();
4335 /* Break the TB to be able to take timer interrupts immediately
4336 after reading count. */
4337 ctx->bstate = BS_STOP;
4338 rn = "Count";
4339 break;
4340 /* 6,7 are implementation dependent */
4341 default:
4342 goto die;
4344 break;
4345 case 10:
4346 switch (sel) {
4347 case 0:
4348 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EntryHi));
4349 tcg_gen_ext32s_tl(arg, arg);
4350 rn = "EntryHi";
4351 break;
4352 default:
4353 goto die;
4355 break;
4356 case 11:
4357 switch (sel) {
4358 case 0:
4359 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Compare));
4360 rn = "Compare";
4361 break;
4362 /* 6,7 are implementation dependent */
4363 default:
4364 goto die;
4366 break;
4367 case 12:
4368 switch (sel) {
4369 case 0:
4370 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Status));
4371 rn = "Status";
4372 break;
4373 case 1:
4374 check_insn(ctx, ISA_MIPS32R2);
4375 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_IntCtl));
4376 rn = "IntCtl";
4377 break;
4378 case 2:
4379 check_insn(ctx, ISA_MIPS32R2);
4380 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSCtl));
4381 rn = "SRSCtl";
4382 break;
4383 case 3:
4384 check_insn(ctx, ISA_MIPS32R2);
4385 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSMap));
4386 rn = "SRSMap";
4387 break;
4388 default:
4389 goto die;
4391 break;
4392 case 13:
4393 switch (sel) {
4394 case 0:
4395 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Cause));
4396 rn = "Cause";
4397 break;
4398 default:
4399 goto die;
4401 break;
4402 case 14:
4403 switch (sel) {
4404 case 0:
4405 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EPC));
4406 tcg_gen_ext32s_tl(arg, arg);
4407 rn = "EPC";
4408 break;
4409 default:
4410 goto die;
4412 break;
4413 case 15:
4414 switch (sel) {
4415 case 0:
4416 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PRid));
4417 rn = "PRid";
4418 break;
4419 case 1:
4420 check_insn(ctx, ISA_MIPS32R2);
4421 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_EBase));
4422 rn = "EBase";
4423 break;
4424 default:
4425 goto die;
4427 break;
4428 case 16:
4429 switch (sel) {
4430 case 0:
4431 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config0));
4432 rn = "Config";
4433 break;
4434 case 1:
4435 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config1));
4436 rn = "Config1";
4437 break;
4438 case 2:
4439 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config2));
4440 rn = "Config2";
4441 break;
4442 case 3:
4443 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config3));
4444 rn = "Config3";
4445 break;
4446 /* 4,5 are reserved */
4447 /* 6,7 are implementation dependent */
4448 case 6:
4449 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config6));
4450 rn = "Config6";
4451 break;
4452 case 7:
4453 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config7));
4454 rn = "Config7";
4455 break;
4456 default:
4457 goto die;
4459 break;
4460 case 17:
4461 switch (sel) {
4462 case 0:
4463 gen_helper_mfc0_lladdr(arg, cpu_env);
4464 rn = "LLAddr";
4465 break;
4466 default:
4467 goto die;
4469 break;
4470 case 18:
4471 switch (sel) {
4472 case 0 ... 7:
4473 gen_helper_1e0i(mfc0_watchlo, arg, sel);
4474 rn = "WatchLo";
4475 break;
4476 default:
4477 goto die;
4479 break;
4480 case 19:
4481 switch (sel) {
4482 case 0 ...7:
4483 gen_helper_1e0i(mfc0_watchhi, arg, sel);
4484 rn = "WatchHi";
4485 break;
4486 default:
4487 goto die;
4489 break;
4490 case 20:
4491 switch (sel) {
4492 case 0:
4493 #if defined(TARGET_MIPS64)
4494 check_insn(ctx, ISA_MIPS3);
4495 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_XContext));
4496 tcg_gen_ext32s_tl(arg, arg);
4497 rn = "XContext";
4498 break;
4499 #endif
4500 default:
4501 goto die;
4503 break;
4504 case 21:
4505 /* Officially reserved, but sel 0 is used for R1x000 framemask */
4506 switch (sel) {
4507 case 0:
4508 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Framemask));
4509 rn = "Framemask";
4510 break;
4511 default:
4512 goto die;
4514 break;
4515 case 22:
4516 tcg_gen_movi_tl(arg, 0); /* unimplemented */
4517 rn = "'Diagnostic"; /* implementation dependent */
4518 break;
4519 case 23:
4520 switch (sel) {
4521 case 0:
4522 gen_helper_mfc0_debug(arg, cpu_env); /* EJTAG support */
4523 rn = "Debug";
4524 break;
4525 case 1:
4526 // gen_helper_mfc0_tracecontrol(arg); /* PDtrace support */
4527 rn = "TraceControl";
4528 // break;
4529 case 2:
4530 // gen_helper_mfc0_tracecontrol2(arg); /* PDtrace support */
4531 rn = "TraceControl2";
4532 // break;
4533 case 3:
4534 // gen_helper_mfc0_usertracedata(arg); /* PDtrace support */
4535 rn = "UserTraceData";
4536 // break;
4537 case 4:
4538 // gen_helper_mfc0_tracebpc(arg); /* PDtrace support */
4539 rn = "TraceBPC";
4540 // break;
4541 default:
4542 goto die;
4544 break;
4545 case 24:
4546 switch (sel) {
4547 case 0:
4548 /* EJTAG support */
4549 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_DEPC));
4550 tcg_gen_ext32s_tl(arg, arg);
4551 rn = "DEPC";
4552 break;
4553 default:
4554 goto die;
4556 break;
4557 case 25:
4558 switch (sel) {
4559 case 0:
4560 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Performance0));
4561 rn = "Performance0";
4562 break;
4563 case 1:
4564 // gen_helper_mfc0_performance1(arg);
4565 rn = "Performance1";
4566 // break;
4567 case 2:
4568 // gen_helper_mfc0_performance2(arg);
4569 rn = "Performance2";
4570 // break;
4571 case 3:
4572 // gen_helper_mfc0_performance3(arg);
4573 rn = "Performance3";
4574 // break;
4575 case 4:
4576 // gen_helper_mfc0_performance4(arg);
4577 rn = "Performance4";
4578 // break;
4579 case 5:
4580 // gen_helper_mfc0_performance5(arg);
4581 rn = "Performance5";
4582 // break;
4583 case 6:
4584 // gen_helper_mfc0_performance6(arg);
4585 rn = "Performance6";
4586 // break;
4587 case 7:
4588 // gen_helper_mfc0_performance7(arg);
4589 rn = "Performance7";
4590 // break;
4591 default:
4592 goto die;
4594 break;
4595 case 26:
4596 tcg_gen_movi_tl(arg, 0); /* unimplemented */
4597 rn = "ECC";
4598 break;
4599 case 27:
4600 switch (sel) {
4601 case 0 ... 3:
4602 tcg_gen_movi_tl(arg, 0); /* unimplemented */
4603 rn = "CacheErr";
4604 break;
4605 default:
4606 goto die;
4608 break;
4609 case 28:
4610 switch (sel) {
4611 case 0:
4612 case 2:
4613 case 4:
4614 case 6:
4615 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_TagLo));
4616 rn = "TagLo";
4617 break;
4618 case 1:
4619 case 3:
4620 case 5:
4621 case 7:
4622 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DataLo));
4623 rn = "DataLo";
4624 break;
4625 default:
4626 goto die;
4628 break;
4629 case 29:
4630 switch (sel) {
4631 case 0:
4632 case 2:
4633 case 4:
4634 case 6:
4635 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_TagHi));
4636 rn = "TagHi";
4637 break;
4638 case 1:
4639 case 3:
4640 case 5:
4641 case 7:
4642 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DataHi));
4643 rn = "DataHi";
4644 break;
4645 default:
4646 goto die;
4648 break;
4649 case 30:
4650 switch (sel) {
4651 case 0:
4652 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_ErrorEPC));
4653 tcg_gen_ext32s_tl(arg, arg);
4654 rn = "ErrorEPC";
4655 break;
4656 default:
4657 goto die;
4659 break;
4660 case 31:
4661 switch (sel) {
4662 case 0:
4663 /* EJTAG support */
4664 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DESAVE));
4665 rn = "DESAVE";
4666 break;
4667 default:
4668 goto die;
4670 break;
4671 default:
4672 goto die;
4674 (void)rn; /* avoid a compiler warning */
4675 LOG_DISAS("mfc0 %s (reg %d sel %d)\n", rn, reg, sel);
4676 return;
4678 die:
4679 LOG_DISAS("mfc0 %s (reg %d sel %d)\n", rn, reg, sel);
4680 generate_exception(ctx, EXCP_RI);
4683 static void gen_mtc0(DisasContext *ctx, TCGv arg, int reg, int sel)
4685 const char *rn = "invalid";
4687 if (sel != 0)
4688 check_insn(ctx, ISA_MIPS32);
4690 if (use_icount)
4691 gen_io_start();
4693 switch (reg) {
4694 case 0:
4695 switch (sel) {
4696 case 0:
4697 gen_helper_mtc0_index(cpu_env, arg);
4698 rn = "Index";
4699 break;
4700 case 1:
4701 check_insn(ctx, ASE_MT);
4702 gen_helper_mtc0_mvpcontrol(cpu_env, arg);
4703 rn = "MVPControl";
4704 break;
4705 case 2:
4706 check_insn(ctx, ASE_MT);
4707 /* ignored */
4708 rn = "MVPConf0";
4709 break;
4710 case 3:
4711 check_insn(ctx, ASE_MT);
4712 /* ignored */
4713 rn = "MVPConf1";
4714 break;
4715 default:
4716 goto die;
4718 break;
4719 case 1:
4720 switch (sel) {
4721 case 0:
4722 /* ignored */
4723 rn = "Random";
4724 break;
4725 case 1:
4726 check_insn(ctx, ASE_MT);
4727 gen_helper_mtc0_vpecontrol(cpu_env, arg);
4728 rn = "VPEControl";
4729 break;
4730 case 2:
4731 check_insn(ctx, ASE_MT);
4732 gen_helper_mtc0_vpeconf0(cpu_env, arg);
4733 rn = "VPEConf0";
4734 break;
4735 case 3:
4736 check_insn(ctx, ASE_MT);
4737 gen_helper_mtc0_vpeconf1(cpu_env, arg);
4738 rn = "VPEConf1";
4739 break;
4740 case 4:
4741 check_insn(ctx, ASE_MT);
4742 gen_helper_mtc0_yqmask(cpu_env, arg);
4743 rn = "YQMask";
4744 break;
4745 case 5:
4746 check_insn(ctx, ASE_MT);
4747 gen_mtc0_store64(arg, offsetof(CPUMIPSState, CP0_VPESchedule));
4748 rn = "VPESchedule";
4749 break;
4750 case 6:
4751 check_insn(ctx, ASE_MT);
4752 gen_mtc0_store64(arg, offsetof(CPUMIPSState, CP0_VPEScheFBack));
4753 rn = "VPEScheFBack";
4754 break;
4755 case 7:
4756 check_insn(ctx, ASE_MT);
4757 gen_helper_mtc0_vpeopt(cpu_env, arg);
4758 rn = "VPEOpt";
4759 break;
4760 default:
4761 goto die;
4763 break;
4764 case 2:
4765 switch (sel) {
4766 case 0:
4767 gen_helper_mtc0_entrylo0(cpu_env, arg);
4768 rn = "EntryLo0";
4769 break;
4770 case 1:
4771 check_insn(ctx, ASE_MT);
4772 gen_helper_mtc0_tcstatus(cpu_env, arg);
4773 rn = "TCStatus";
4774 break;
4775 case 2:
4776 check_insn(ctx, ASE_MT);
4777 gen_helper_mtc0_tcbind(cpu_env, arg);
4778 rn = "TCBind";
4779 break;
4780 case 3:
4781 check_insn(ctx, ASE_MT);
4782 gen_helper_mtc0_tcrestart(cpu_env, arg);
4783 rn = "TCRestart";
4784 break;
4785 case 4:
4786 check_insn(ctx, ASE_MT);
4787 gen_helper_mtc0_tchalt(cpu_env, arg);
4788 rn = "TCHalt";
4789 break;
4790 case 5:
4791 check_insn(ctx, ASE_MT);
4792 gen_helper_mtc0_tccontext(cpu_env, arg);
4793 rn = "TCContext";
4794 break;
4795 case 6:
4796 check_insn(ctx, ASE_MT);
4797 gen_helper_mtc0_tcschedule(cpu_env, arg);
4798 rn = "TCSchedule";
4799 break;
4800 case 7:
4801 check_insn(ctx, ASE_MT);
4802 gen_helper_mtc0_tcschefback(cpu_env, arg);
4803 rn = "TCScheFBack";
4804 break;
4805 default:
4806 goto die;
4808 break;
4809 case 3:
4810 switch (sel) {
4811 case 0:
4812 gen_helper_mtc0_entrylo1(cpu_env, arg);
4813 rn = "EntryLo1";
4814 break;
4815 default:
4816 goto die;
4818 break;
4819 case 4:
4820 switch (sel) {
4821 case 0:
4822 gen_helper_mtc0_context(cpu_env, arg);
4823 rn = "Context";
4824 break;
4825 case 1:
4826 // gen_helper_mtc0_contextconfig(cpu_env, arg); /* SmartMIPS ASE */
4827 rn = "ContextConfig";
4828 // break;
4829 default:
4830 goto die;
4832 break;
4833 case 5:
4834 switch (sel) {
4835 case 0:
4836 gen_helper_mtc0_pagemask(cpu_env, arg);
4837 rn = "PageMask";
4838 break;
4839 case 1:
4840 check_insn(ctx, ISA_MIPS32R2);
4841 gen_helper_mtc0_pagegrain(cpu_env, arg);
4842 rn = "PageGrain";
4843 break;
4844 default:
4845 goto die;
4847 break;
4848 case 6:
4849 switch (sel) {
4850 case 0:
4851 gen_helper_mtc0_wired(cpu_env, arg);
4852 rn = "Wired";
4853 break;
4854 case 1:
4855 check_insn(ctx, ISA_MIPS32R2);
4856 gen_helper_mtc0_srsconf0(cpu_env, arg);
4857 rn = "SRSConf0";
4858 break;
4859 case 2:
4860 check_insn(ctx, ISA_MIPS32R2);
4861 gen_helper_mtc0_srsconf1(cpu_env, arg);
4862 rn = "SRSConf1";
4863 break;
4864 case 3:
4865 check_insn(ctx, ISA_MIPS32R2);
4866 gen_helper_mtc0_srsconf2(cpu_env, arg);
4867 rn = "SRSConf2";
4868 break;
4869 case 4:
4870 check_insn(ctx, ISA_MIPS32R2);
4871 gen_helper_mtc0_srsconf3(cpu_env, arg);
4872 rn = "SRSConf3";
4873 break;
4874 case 5:
4875 check_insn(ctx, ISA_MIPS32R2);
4876 gen_helper_mtc0_srsconf4(cpu_env, arg);
4877 rn = "SRSConf4";
4878 break;
4879 default:
4880 goto die;
4882 break;
4883 case 7:
4884 switch (sel) {
4885 case 0:
4886 check_insn(ctx, ISA_MIPS32R2);
4887 gen_helper_mtc0_hwrena(cpu_env, arg);
4888 rn = "HWREna";
4889 break;
4890 default:
4891 goto die;
4893 break;
4894 case 8:
4895 /* ignored */
4896 rn = "BadVAddr";
4897 break;
4898 case 9:
4899 switch (sel) {
4900 case 0:
4901 gen_helper_mtc0_count(cpu_env, arg);
4902 rn = "Count";
4903 break;
4904 /* 6,7 are implementation dependent */
4905 default:
4906 goto die;
4908 break;
4909 case 10:
4910 switch (sel) {
4911 case 0:
4912 gen_helper_mtc0_entryhi(cpu_env, arg);
4913 rn = "EntryHi";
4914 break;
4915 default:
4916 goto die;
4918 break;
4919 case 11:
4920 switch (sel) {
4921 case 0:
4922 gen_helper_mtc0_compare(cpu_env, arg);
4923 rn = "Compare";
4924 break;
4925 /* 6,7 are implementation dependent */
4926 default:
4927 goto die;
4929 break;
4930 case 12:
4931 switch (sel) {
4932 case 0:
4933 save_cpu_state(ctx, 1);
4934 gen_helper_mtc0_status(cpu_env, arg);
4935 /* BS_STOP isn't good enough here, hflags may have changed. */
4936 gen_save_pc(ctx->pc + 4);
4937 ctx->bstate = BS_EXCP;
4938 rn = "Status";
4939 break;
4940 case 1:
4941 check_insn(ctx, ISA_MIPS32R2);
4942 gen_helper_mtc0_intctl(cpu_env, arg);
4943 /* Stop translation as we may have switched the execution mode */
4944 ctx->bstate = BS_STOP;
4945 rn = "IntCtl";
4946 break;
4947 case 2:
4948 check_insn(ctx, ISA_MIPS32R2);
4949 gen_helper_mtc0_srsctl(cpu_env, arg);
4950 /* Stop translation as we may have switched the execution mode */
4951 ctx->bstate = BS_STOP;
4952 rn = "SRSCtl";
4953 break;
4954 case 3:
4955 check_insn(ctx, ISA_MIPS32R2);
4956 gen_mtc0_store32(arg, offsetof(CPUMIPSState, CP0_SRSMap));
4957 /* Stop translation as we may have switched the execution mode */
4958 ctx->bstate = BS_STOP;
4959 rn = "SRSMap";
4960 break;
4961 default:
4962 goto die;
4964 break;
4965 case 13:
4966 switch (sel) {
4967 case 0:
4968 save_cpu_state(ctx, 1);
4969 gen_helper_mtc0_cause(cpu_env, arg);
4970 rn = "Cause";
4971 break;
4972 default:
4973 goto die;
4975 break;
4976 case 14:
4977 switch (sel) {
4978 case 0:
4979 gen_mtc0_store64(arg, offsetof(CPUMIPSState, CP0_EPC));
4980 rn = "EPC";
4981 break;
4982 default:
4983 goto die;
4985 break;
4986 case 15:
4987 switch (sel) {
4988 case 0:
4989 /* ignored */
4990 rn = "PRid";
4991 break;
4992 case 1:
4993 check_insn(ctx, ISA_MIPS32R2);
4994 gen_helper_mtc0_ebase(cpu_env, arg);
4995 rn = "EBase";
4996 break;
4997 default:
4998 goto die;
5000 break;
5001 case 16:
5002 switch (sel) {
5003 case 0:
5004 gen_helper_mtc0_config0(cpu_env, arg);
5005 rn = "Config";
5006 /* Stop translation as we may have switched the execution mode */
5007 ctx->bstate = BS_STOP;
5008 break;
5009 case 1:
5010 /* ignored, read only */
5011 rn = "Config1";
5012 break;
5013 case 2:
5014 gen_helper_mtc0_config2(cpu_env, arg);
5015 rn = "Config2";
5016 /* Stop translation as we may have switched the execution mode */
5017 ctx->bstate = BS_STOP;
5018 break;
5019 case 3:
5020 /* ignored, read only */
5021 rn = "Config3";
5022 break;
5023 /* 4,5 are reserved */
5024 /* 6,7 are implementation dependent */
5025 case 6:
5026 /* ignored */
5027 rn = "Config6";
5028 break;
5029 case 7:
5030 /* ignored */
5031 rn = "Config7";
5032 break;
5033 default:
5034 rn = "Invalid config selector";
5035 goto die;
5037 break;
5038 case 17:
5039 switch (sel) {
5040 case 0:
5041 gen_helper_mtc0_lladdr(cpu_env, arg);
5042 rn = "LLAddr";
5043 break;
5044 default:
5045 goto die;
5047 break;
5048 case 18:
5049 switch (sel) {
5050 case 0 ... 7:
5051 gen_helper_0e1i(mtc0_watchlo, arg, sel);
5052 rn = "WatchLo";
5053 break;
5054 default:
5055 goto die;
5057 break;
5058 case 19:
5059 switch (sel) {
5060 case 0 ... 7:
5061 gen_helper_0e1i(mtc0_watchhi, arg, sel);
5062 rn = "WatchHi";
5063 break;
5064 default:
5065 goto die;
5067 break;
5068 case 20:
5069 switch (sel) {
5070 case 0:
5071 #if defined(TARGET_MIPS64)
5072 check_insn(ctx, ISA_MIPS3);
5073 gen_helper_mtc0_xcontext(cpu_env, arg);
5074 rn = "XContext";
5075 break;
5076 #endif
5077 default:
5078 goto die;
5080 break;
5081 case 21:
5082 /* Officially reserved, but sel 0 is used for R1x000 framemask */
5083 switch (sel) {
5084 case 0:
5085 gen_helper_mtc0_framemask(cpu_env, arg);
5086 rn = "Framemask";
5087 break;
5088 default:
5089 goto die;
5091 break;
5092 case 22:
5093 /* ignored */
5094 rn = "Diagnostic"; /* implementation dependent */
5095 break;
5096 case 23:
5097 switch (sel) {
5098 case 0:
5099 gen_helper_mtc0_debug(cpu_env, arg); /* EJTAG support */
5100 /* BS_STOP isn't good enough here, hflags may have changed. */
5101 gen_save_pc(ctx->pc + 4);
5102 ctx->bstate = BS_EXCP;
5103 rn = "Debug";
5104 break;
5105 case 1:
5106 // gen_helper_mtc0_tracecontrol(cpu_env, arg); /* PDtrace support */
5107 rn = "TraceControl";
5108 /* Stop translation as we may have switched the execution mode */
5109 ctx->bstate = BS_STOP;
5110 // break;
5111 case 2:
5112 // gen_helper_mtc0_tracecontrol2(cpu_env, arg); /* PDtrace support */
5113 rn = "TraceControl2";
5114 /* Stop translation as we may have switched the execution mode */
5115 ctx->bstate = BS_STOP;
5116 // break;
5117 case 3:
5118 /* Stop translation as we may have switched the execution mode */
5119 ctx->bstate = BS_STOP;
5120 // gen_helper_mtc0_usertracedata(cpu_env, arg); /* PDtrace support */
5121 rn = "UserTraceData";
5122 /* Stop translation as we may have switched the execution mode */
5123 ctx->bstate = BS_STOP;
5124 // break;
5125 case 4:
5126 // gen_helper_mtc0_tracebpc(cpu_env, arg); /* PDtrace support */
5127 /* Stop translation as we may have switched the execution mode */
5128 ctx->bstate = BS_STOP;
5129 rn = "TraceBPC";
5130 // break;
5131 default:
5132 goto die;
5134 break;
5135 case 24:
5136 switch (sel) {
5137 case 0:
5138 /* EJTAG support */
5139 gen_mtc0_store64(arg, offsetof(CPUMIPSState, CP0_DEPC));
5140 rn = "DEPC";
5141 break;
5142 default:
5143 goto die;
5145 break;
5146 case 25:
5147 switch (sel) {
5148 case 0:
5149 gen_helper_mtc0_performance0(cpu_env, arg);
5150 rn = "Performance0";
5151 break;
5152 case 1:
5153 // gen_helper_mtc0_performance1(arg);
5154 rn = "Performance1";
5155 // break;
5156 case 2:
5157 // gen_helper_mtc0_performance2(arg);
5158 rn = "Performance2";
5159 // break;
5160 case 3:
5161 // gen_helper_mtc0_performance3(arg);
5162 rn = "Performance3";
5163 // break;
5164 case 4:
5165 // gen_helper_mtc0_performance4(arg);
5166 rn = "Performance4";
5167 // break;
5168 case 5:
5169 // gen_helper_mtc0_performance5(arg);
5170 rn = "Performance5";
5171 // break;
5172 case 6:
5173 // gen_helper_mtc0_performance6(arg);
5174 rn = "Performance6";
5175 // break;
5176 case 7:
5177 // gen_helper_mtc0_performance7(arg);
5178 rn = "Performance7";
5179 // break;
5180 default:
5181 goto die;
5183 break;
5184 case 26:
5185 /* ignored */
5186 rn = "ECC";
5187 break;
5188 case 27:
5189 switch (sel) {
5190 case 0 ... 3:
5191 /* ignored */
5192 rn = "CacheErr";
5193 break;
5194 default:
5195 goto die;
5197 break;
5198 case 28:
5199 switch (sel) {
5200 case 0:
5201 case 2:
5202 case 4:
5203 case 6:
5204 gen_helper_mtc0_taglo(cpu_env, arg);
5205 rn = "TagLo";
5206 break;
5207 case 1:
5208 case 3:
5209 case 5:
5210 case 7:
5211 gen_helper_mtc0_datalo(cpu_env, arg);
5212 rn = "DataLo";
5213 break;
5214 default:
5215 goto die;
5217 break;
5218 case 29:
5219 switch (sel) {
5220 case 0:
5221 case 2:
5222 case 4:
5223 case 6:
5224 gen_helper_mtc0_taghi(cpu_env, arg);
5225 rn = "TagHi";
5226 break;
5227 case 1:
5228 case 3:
5229 case 5:
5230 case 7:
5231 gen_helper_mtc0_datahi(cpu_env, arg);
5232 rn = "DataHi";
5233 break;
5234 default:
5235 rn = "invalid sel";
5236 goto die;
5238 break;
5239 case 30:
5240 switch (sel) {
5241 case 0:
5242 gen_mtc0_store64(arg, offsetof(CPUMIPSState, CP0_ErrorEPC));
5243 rn = "ErrorEPC";
5244 break;
5245 default:
5246 goto die;
5248 break;
5249 case 31:
5250 switch (sel) {
5251 case 0:
5252 /* EJTAG support */
5253 gen_mtc0_store32(arg, offsetof(CPUMIPSState, CP0_DESAVE));
5254 rn = "DESAVE";
5255 break;
5256 default:
5257 goto die;
5259 /* Stop translation as we may have switched the execution mode */
5260 ctx->bstate = BS_STOP;
5261 break;
5262 default:
5263 goto die;
5265 (void)rn; /* avoid a compiler warning */
5266 LOG_DISAS("mtc0 %s (reg %d sel %d)\n", rn, reg, sel);
5267 /* For simplicity assume that all writes can cause interrupts. */
5268 if (use_icount) {
5269 gen_io_end();
5270 ctx->bstate = BS_STOP;
5272 return;
5274 die:
5275 LOG_DISAS("mtc0 %s (reg %d sel %d)\n", rn, reg, sel);
5276 generate_exception(ctx, EXCP_RI);
5279 #if defined(TARGET_MIPS64)
5280 static void gen_dmfc0(DisasContext *ctx, TCGv arg, int reg, int sel)
5282 const char *rn = "invalid";
5284 if (sel != 0)
5285 check_insn(ctx, ISA_MIPS64);
5287 switch (reg) {
5288 case 0:
5289 switch (sel) {
5290 case 0:
5291 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Index));
5292 rn = "Index";
5293 break;
5294 case 1:
5295 check_insn(ctx, ASE_MT);
5296 gen_helper_mfc0_mvpcontrol(arg, cpu_env);
5297 rn = "MVPControl";
5298 break;
5299 case 2:
5300 check_insn(ctx, ASE_MT);
5301 gen_helper_mfc0_mvpconf0(arg, cpu_env);
5302 rn = "MVPConf0";
5303 break;
5304 case 3:
5305 check_insn(ctx, ASE_MT);
5306 gen_helper_mfc0_mvpconf1(arg, cpu_env);
5307 rn = "MVPConf1";
5308 break;
5309 default:
5310 goto die;
5312 break;
5313 case 1:
5314 switch (sel) {
5315 case 0:
5316 gen_helper_mfc0_random(arg, cpu_env);
5317 rn = "Random";
5318 break;
5319 case 1:
5320 check_insn(ctx, ASE_MT);
5321 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEControl));
5322 rn = "VPEControl";
5323 break;
5324 case 2:
5325 check_insn(ctx, ASE_MT);
5326 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEConf0));
5327 rn = "VPEConf0";
5328 break;
5329 case 3:
5330 check_insn(ctx, ASE_MT);
5331 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEConf1));
5332 rn = "VPEConf1";
5333 break;
5334 case 4:
5335 check_insn(ctx, ASE_MT);
5336 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_YQMask));
5337 rn = "YQMask";
5338 break;
5339 case 5:
5340 check_insn(ctx, ASE_MT);
5341 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_VPESchedule));
5342 rn = "VPESchedule";
5343 break;
5344 case 6:
5345 check_insn(ctx, ASE_MT);
5346 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_VPEScheFBack));
5347 rn = "VPEScheFBack";
5348 break;
5349 case 7:
5350 check_insn(ctx, ASE_MT);
5351 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEOpt));
5352 rn = "VPEOpt";
5353 break;
5354 default:
5355 goto die;
5357 break;
5358 case 2:
5359 switch (sel) {
5360 case 0:
5361 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EntryLo0));
5362 rn = "EntryLo0";
5363 break;
5364 case 1:
5365 check_insn(ctx, ASE_MT);
5366 gen_helper_mfc0_tcstatus(arg, cpu_env);
5367 rn = "TCStatus";
5368 break;
5369 case 2:
5370 check_insn(ctx, ASE_MT);
5371 gen_helper_mfc0_tcbind(arg, cpu_env);
5372 rn = "TCBind";
5373 break;
5374 case 3:
5375 check_insn(ctx, ASE_MT);
5376 gen_helper_dmfc0_tcrestart(arg, cpu_env);
5377 rn = "TCRestart";
5378 break;
5379 case 4:
5380 check_insn(ctx, ASE_MT);
5381 gen_helper_dmfc0_tchalt(arg, cpu_env);
5382 rn = "TCHalt";
5383 break;
5384 case 5:
5385 check_insn(ctx, ASE_MT);
5386 gen_helper_dmfc0_tccontext(arg, cpu_env);
5387 rn = "TCContext";
5388 break;
5389 case 6:
5390 check_insn(ctx, ASE_MT);
5391 gen_helper_dmfc0_tcschedule(arg, cpu_env);
5392 rn = "TCSchedule";
5393 break;
5394 case 7:
5395 check_insn(ctx, ASE_MT);
5396 gen_helper_dmfc0_tcschefback(arg, cpu_env);
5397 rn = "TCScheFBack";
5398 break;
5399 default:
5400 goto die;
5402 break;
5403 case 3:
5404 switch (sel) {
5405 case 0:
5406 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EntryLo1));
5407 rn = "EntryLo1";
5408 break;
5409 default:
5410 goto die;
5412 break;
5413 case 4:
5414 switch (sel) {
5415 case 0:
5416 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_Context));
5417 rn = "Context";
5418 break;
5419 case 1:
5420 // gen_helper_dmfc0_contextconfig(arg); /* SmartMIPS ASE */
5421 rn = "ContextConfig";
5422 // break;
5423 default:
5424 goto die;
5426 break;
5427 case 5:
5428 switch (sel) {
5429 case 0:
5430 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PageMask));
5431 rn = "PageMask";
5432 break;
5433 case 1:
5434 check_insn(ctx, ISA_MIPS32R2);
5435 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PageGrain));
5436 rn = "PageGrain";
5437 break;
5438 default:
5439 goto die;
5441 break;
5442 case 6:
5443 switch (sel) {
5444 case 0:
5445 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Wired));
5446 rn = "Wired";
5447 break;
5448 case 1:
5449 check_insn(ctx, ISA_MIPS32R2);
5450 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf0));
5451 rn = "SRSConf0";
5452 break;
5453 case 2:
5454 check_insn(ctx, ISA_MIPS32R2);
5455 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf1));
5456 rn = "SRSConf1";
5457 break;
5458 case 3:
5459 check_insn(ctx, ISA_MIPS32R2);
5460 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf2));
5461 rn = "SRSConf2";
5462 break;
5463 case 4:
5464 check_insn(ctx, ISA_MIPS32R2);
5465 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf3));
5466 rn = "SRSConf3";
5467 break;
5468 case 5:
5469 check_insn(ctx, ISA_MIPS32R2);
5470 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf4));
5471 rn = "SRSConf4";
5472 break;
5473 default:
5474 goto die;
5476 break;
5477 case 7:
5478 switch (sel) {
5479 case 0:
5480 check_insn(ctx, ISA_MIPS32R2);
5481 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_HWREna));
5482 rn = "HWREna";
5483 break;
5484 default:
5485 goto die;
5487 break;
5488 case 8:
5489 switch (sel) {
5490 case 0:
5491 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_BadVAddr));
5492 rn = "BadVAddr";
5493 break;
5494 default:
5495 goto die;
5497 break;
5498 case 9:
5499 switch (sel) {
5500 case 0:
5501 /* Mark as an IO operation because we read the time. */
5502 if (use_icount)
5503 gen_io_start();
5504 gen_helper_mfc0_count(arg, cpu_env);
5505 if (use_icount) {
5506 gen_io_end();
5508 /* Break the TB to be able to take timer interrupts immediately
5509 after reading count. */
5510 ctx->bstate = BS_STOP;
5511 rn = "Count";
5512 break;
5513 /* 6,7 are implementation dependent */
5514 default:
5515 goto die;
5517 break;
5518 case 10:
5519 switch (sel) {
5520 case 0:
5521 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EntryHi));
5522 rn = "EntryHi";
5523 break;
5524 default:
5525 goto die;
5527 break;
5528 case 11:
5529 switch (sel) {
5530 case 0:
5531 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Compare));
5532 rn = "Compare";
5533 break;
5534 /* 6,7 are implementation dependent */
5535 default:
5536 goto die;
5538 break;
5539 case 12:
5540 switch (sel) {
5541 case 0:
5542 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Status));
5543 rn = "Status";
5544 break;
5545 case 1:
5546 check_insn(ctx, ISA_MIPS32R2);
5547 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_IntCtl));
5548 rn = "IntCtl";
5549 break;
5550 case 2:
5551 check_insn(ctx, ISA_MIPS32R2);
5552 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSCtl));
5553 rn = "SRSCtl";
5554 break;
5555 case 3:
5556 check_insn(ctx, ISA_MIPS32R2);
5557 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSMap));
5558 rn = "SRSMap";
5559 break;
5560 default:
5561 goto die;
5563 break;
5564 case 13:
5565 switch (sel) {
5566 case 0:
5567 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Cause));
5568 rn = "Cause";
5569 break;
5570 default:
5571 goto die;
5573 break;
5574 case 14:
5575 switch (sel) {
5576 case 0:
5577 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EPC));
5578 rn = "EPC";
5579 break;
5580 default:
5581 goto die;
5583 break;
5584 case 15:
5585 switch (sel) {
5586 case 0:
5587 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PRid));
5588 rn = "PRid";
5589 break;
5590 case 1:
5591 check_insn(ctx, ISA_MIPS32R2);
5592 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_EBase));
5593 rn = "EBase";
5594 break;
5595 default:
5596 goto die;
5598 break;
5599 case 16:
5600 switch (sel) {
5601 case 0:
5602 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config0));
5603 rn = "Config";
5604 break;
5605 case 1:
5606 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config1));
5607 rn = "Config1";
5608 break;
5609 case 2:
5610 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config2));
5611 rn = "Config2";
5612 break;
5613 case 3:
5614 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config3));
5615 rn = "Config3";
5616 break;
5617 /* 6,7 are implementation dependent */
5618 case 6:
5619 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config6));
5620 rn = "Config6";
5621 break;
5622 case 7:
5623 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config7));
5624 rn = "Config7";
5625 break;
5626 default:
5627 goto die;
5629 break;
5630 case 17:
5631 switch (sel) {
5632 case 0:
5633 gen_helper_dmfc0_lladdr(arg, cpu_env);
5634 rn = "LLAddr";
5635 break;
5636 default:
5637 goto die;
5639 break;
5640 case 18:
5641 switch (sel) {
5642 case 0 ... 7:
5643 gen_helper_1e0i(dmfc0_watchlo, arg, sel);
5644 rn = "WatchLo";
5645 break;
5646 default:
5647 goto die;
5649 break;
5650 case 19:
5651 switch (sel) {
5652 case 0 ... 7:
5653 gen_helper_1e0i(mfc0_watchhi, arg, sel);
5654 rn = "WatchHi";
5655 break;
5656 default:
5657 goto die;
5659 break;
5660 case 20:
5661 switch (sel) {
5662 case 0:
5663 check_insn(ctx, ISA_MIPS3);
5664 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_XContext));
5665 rn = "XContext";
5666 break;
5667 default:
5668 goto die;
5670 break;
5671 case 21:
5672 /* Officially reserved, but sel 0 is used for R1x000 framemask */
5673 switch (sel) {
5674 case 0:
5675 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Framemask));
5676 rn = "Framemask";
5677 break;
5678 default:
5679 goto die;
5681 break;
5682 case 22:
5683 tcg_gen_movi_tl(arg, 0); /* unimplemented */
5684 rn = "'Diagnostic"; /* implementation dependent */
5685 break;
5686 case 23:
5687 switch (sel) {
5688 case 0:
5689 gen_helper_mfc0_debug(arg, cpu_env); /* EJTAG support */
5690 rn = "Debug";
5691 break;
5692 case 1:
5693 // gen_helper_dmfc0_tracecontrol(arg, cpu_env); /* PDtrace support */
5694 rn = "TraceControl";
5695 // break;
5696 case 2:
5697 // gen_helper_dmfc0_tracecontrol2(arg, cpu_env); /* PDtrace support */
5698 rn = "TraceControl2";
5699 // break;
5700 case 3:
5701 // gen_helper_dmfc0_usertracedata(arg, cpu_env); /* PDtrace support */
5702 rn = "UserTraceData";
5703 // break;
5704 case 4:
5705 // gen_helper_dmfc0_tracebpc(arg, cpu_env); /* PDtrace support */
5706 rn = "TraceBPC";
5707 // break;
5708 default:
5709 goto die;
5711 break;
5712 case 24:
5713 switch (sel) {
5714 case 0:
5715 /* EJTAG support */
5716 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_DEPC));
5717 rn = "DEPC";
5718 break;
5719 default:
5720 goto die;
5722 break;
5723 case 25:
5724 switch (sel) {
5725 case 0:
5726 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Performance0));
5727 rn = "Performance0";
5728 break;
5729 case 1:
5730 // gen_helper_dmfc0_performance1(arg);
5731 rn = "Performance1";
5732 // break;
5733 case 2:
5734 // gen_helper_dmfc0_performance2(arg);
5735 rn = "Performance2";
5736 // break;
5737 case 3:
5738 // gen_helper_dmfc0_performance3(arg);
5739 rn = "Performance3";
5740 // break;
5741 case 4:
5742 // gen_helper_dmfc0_performance4(arg);
5743 rn = "Performance4";
5744 // break;
5745 case 5:
5746 // gen_helper_dmfc0_performance5(arg);
5747 rn = "Performance5";
5748 // break;
5749 case 6:
5750 // gen_helper_dmfc0_performance6(arg);
5751 rn = "Performance6";
5752 // break;
5753 case 7:
5754 // gen_helper_dmfc0_performance7(arg);
5755 rn = "Performance7";
5756 // break;
5757 default:
5758 goto die;
5760 break;
5761 case 26:
5762 tcg_gen_movi_tl(arg, 0); /* unimplemented */
5763 rn = "ECC";
5764 break;
5765 case 27:
5766 switch (sel) {
5767 /* ignored */
5768 case 0 ... 3:
5769 tcg_gen_movi_tl(arg, 0); /* unimplemented */
5770 rn = "CacheErr";
5771 break;
5772 default:
5773 goto die;
5775 break;
5776 case 28:
5777 switch (sel) {
5778 case 0:
5779 case 2:
5780 case 4:
5781 case 6:
5782 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_TagLo));
5783 rn = "TagLo";
5784 break;
5785 case 1:
5786 case 3:
5787 case 5:
5788 case 7:
5789 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DataLo));
5790 rn = "DataLo";
5791 break;
5792 default:
5793 goto die;
5795 break;
5796 case 29:
5797 switch (sel) {
5798 case 0:
5799 case 2:
5800 case 4:
5801 case 6:
5802 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_TagHi));
5803 rn = "TagHi";
5804 break;
5805 case 1:
5806 case 3:
5807 case 5:
5808 case 7:
5809 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DataHi));
5810 rn = "DataHi";
5811 break;
5812 default:
5813 goto die;
5815 break;
5816 case 30:
5817 switch (sel) {
5818 case 0:
5819 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_ErrorEPC));
5820 rn = "ErrorEPC";
5821 break;
5822 default:
5823 goto die;
5825 break;
5826 case 31:
5827 switch (sel) {
5828 case 0:
5829 /* EJTAG support */
5830 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DESAVE));
5831 rn = "DESAVE";
5832 break;
5833 default:
5834 goto die;
5836 break;
5837 default:
5838 goto die;
5840 (void)rn; /* avoid a compiler warning */
5841 LOG_DISAS("dmfc0 %s (reg %d sel %d)\n", rn, reg, sel);
5842 return;
5844 die:
5845 LOG_DISAS("dmfc0 %s (reg %d sel %d)\n", rn, reg, sel);
5846 generate_exception(ctx, EXCP_RI);
5849 static void gen_dmtc0(DisasContext *ctx, TCGv arg, int reg, int sel)
5851 const char *rn = "invalid";
5853 if (sel != 0)
5854 check_insn(ctx, ISA_MIPS64);
5856 if (use_icount)
5857 gen_io_start();
5859 switch (reg) {
5860 case 0:
5861 switch (sel) {
5862 case 0:
5863 gen_helper_mtc0_index(cpu_env, arg);
5864 rn = "Index";
5865 break;
5866 case 1:
5867 check_insn(ctx, ASE_MT);
5868 gen_helper_mtc0_mvpcontrol(cpu_env, arg);
5869 rn = "MVPControl";
5870 break;
5871 case 2:
5872 check_insn(ctx, ASE_MT);
5873 /* ignored */
5874 rn = "MVPConf0";
5875 break;
5876 case 3:
5877 check_insn(ctx, ASE_MT);
5878 /* ignored */
5879 rn = "MVPConf1";
5880 break;
5881 default:
5882 goto die;
5884 break;
5885 case 1:
5886 switch (sel) {
5887 case 0:
5888 /* ignored */
5889 rn = "Random";
5890 break;
5891 case 1:
5892 check_insn(ctx, ASE_MT);
5893 gen_helper_mtc0_vpecontrol(cpu_env, arg);
5894 rn = "VPEControl";
5895 break;
5896 case 2:
5897 check_insn(ctx, ASE_MT);
5898 gen_helper_mtc0_vpeconf0(cpu_env, arg);
5899 rn = "VPEConf0";
5900 break;
5901 case 3:
5902 check_insn(ctx, ASE_MT);
5903 gen_helper_mtc0_vpeconf1(cpu_env, arg);
5904 rn = "VPEConf1";
5905 break;
5906 case 4:
5907 check_insn(ctx, ASE_MT);
5908 gen_helper_mtc0_yqmask(cpu_env, arg);
5909 rn = "YQMask";
5910 break;
5911 case 5:
5912 check_insn(ctx, ASE_MT);
5913 tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_VPESchedule));
5914 rn = "VPESchedule";
5915 break;
5916 case 6:
5917 check_insn(ctx, ASE_MT);
5918 tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_VPEScheFBack));
5919 rn = "VPEScheFBack";
5920 break;
5921 case 7:
5922 check_insn(ctx, ASE_MT);
5923 gen_helper_mtc0_vpeopt(cpu_env, arg);
5924 rn = "VPEOpt";
5925 break;
5926 default:
5927 goto die;
5929 break;
5930 case 2:
5931 switch (sel) {
5932 case 0:
5933 gen_helper_mtc0_entrylo0(cpu_env, arg);
5934 rn = "EntryLo0";
5935 break;
5936 case 1:
5937 check_insn(ctx, ASE_MT);
5938 gen_helper_mtc0_tcstatus(cpu_env, arg);
5939 rn = "TCStatus";
5940 break;
5941 case 2:
5942 check_insn(ctx, ASE_MT);
5943 gen_helper_mtc0_tcbind(cpu_env, arg);
5944 rn = "TCBind";
5945 break;
5946 case 3:
5947 check_insn(ctx, ASE_MT);
5948 gen_helper_mtc0_tcrestart(cpu_env, arg);
5949 rn = "TCRestart";
5950 break;
5951 case 4:
5952 check_insn(ctx, ASE_MT);
5953 gen_helper_mtc0_tchalt(cpu_env, arg);
5954 rn = "TCHalt";
5955 break;
5956 case 5:
5957 check_insn(ctx, ASE_MT);
5958 gen_helper_mtc0_tccontext(cpu_env, arg);
5959 rn = "TCContext";
5960 break;
5961 case 6:
5962 check_insn(ctx, ASE_MT);
5963 gen_helper_mtc0_tcschedule(cpu_env, arg);
5964 rn = "TCSchedule";
5965 break;
5966 case 7:
5967 check_insn(ctx, ASE_MT);
5968 gen_helper_mtc0_tcschefback(cpu_env, arg);
5969 rn = "TCScheFBack";
5970 break;
5971 default:
5972 goto die;
5974 break;
5975 case 3:
5976 switch (sel) {
5977 case 0:
5978 gen_helper_mtc0_entrylo1(cpu_env, arg);
5979 rn = "EntryLo1";
5980 break;
5981 default:
5982 goto die;
5984 break;
5985 case 4:
5986 switch (sel) {
5987 case 0:
5988 gen_helper_mtc0_context(cpu_env, arg);
5989 rn = "Context";
5990 break;
5991 case 1:
5992 // gen_helper_mtc0_contextconfig(cpu_env, arg); /* SmartMIPS ASE */
5993 rn = "ContextConfig";
5994 // break;
5995 default:
5996 goto die;
5998 break;
5999 case 5:
6000 switch (sel) {
6001 case 0:
6002 gen_helper_mtc0_pagemask(cpu_env, arg);
6003 rn = "PageMask";
6004 break;
6005 case 1:
6006 check_insn(ctx, ISA_MIPS32R2);
6007 gen_helper_mtc0_pagegrain(cpu_env, arg);
6008 rn = "PageGrain";
6009 break;
6010 default:
6011 goto die;
6013 break;
6014 case 6:
6015 switch (sel) {
6016 case 0:
6017 gen_helper_mtc0_wired(cpu_env, arg);
6018 rn = "Wired";
6019 break;
6020 case 1:
6021 check_insn(ctx, ISA_MIPS32R2);
6022 gen_helper_mtc0_srsconf0(cpu_env, arg);
6023 rn = "SRSConf0";
6024 break;
6025 case 2:
6026 check_insn(ctx, ISA_MIPS32R2);
6027 gen_helper_mtc0_srsconf1(cpu_env, arg);
6028 rn = "SRSConf1";
6029 break;
6030 case 3:
6031 check_insn(ctx, ISA_MIPS32R2);
6032 gen_helper_mtc0_srsconf2(cpu_env, arg);
6033 rn = "SRSConf2";
6034 break;
6035 case 4:
6036 check_insn(ctx, ISA_MIPS32R2);
6037 gen_helper_mtc0_srsconf3(cpu_env, arg);
6038 rn = "SRSConf3";
6039 break;
6040 case 5:
6041 check_insn(ctx, ISA_MIPS32R2);
6042 gen_helper_mtc0_srsconf4(cpu_env, arg);
6043 rn = "SRSConf4";
6044 break;
6045 default:
6046 goto die;
6048 break;
6049 case 7:
6050 switch (sel) {
6051 case 0:
6052 check_insn(ctx, ISA_MIPS32R2);
6053 gen_helper_mtc0_hwrena(cpu_env, arg);
6054 rn = "HWREna";
6055 break;
6056 default:
6057 goto die;
6059 break;
6060 case 8:
6061 /* ignored */
6062 rn = "BadVAddr";
6063 break;
6064 case 9:
6065 switch (sel) {
6066 case 0:
6067 gen_helper_mtc0_count(cpu_env, arg);
6068 rn = "Count";
6069 break;
6070 /* 6,7 are implementation dependent */
6071 default:
6072 goto die;
6074 /* Stop translation as we may have switched the execution mode */
6075 ctx->bstate = BS_STOP;
6076 break;
6077 case 10:
6078 switch (sel) {
6079 case 0:
6080 gen_helper_mtc0_entryhi(cpu_env, arg);
6081 rn = "EntryHi";
6082 break;
6083 default:
6084 goto die;
6086 break;
6087 case 11:
6088 switch (sel) {
6089 case 0:
6090 gen_helper_mtc0_compare(cpu_env, arg);
6091 rn = "Compare";
6092 break;
6093 /* 6,7 are implementation dependent */
6094 default:
6095 goto die;
6097 /* Stop translation as we may have switched the execution mode */
6098 ctx->bstate = BS_STOP;
6099 break;
6100 case 12:
6101 switch (sel) {
6102 case 0:
6103 save_cpu_state(ctx, 1);
6104 gen_helper_mtc0_status(cpu_env, arg);
6105 /* BS_STOP isn't good enough here, hflags may have changed. */
6106 gen_save_pc(ctx->pc + 4);
6107 ctx->bstate = BS_EXCP;
6108 rn = "Status";
6109 break;
6110 case 1:
6111 check_insn(ctx, ISA_MIPS32R2);
6112 gen_helper_mtc0_intctl(cpu_env, arg);
6113 /* Stop translation as we may have switched the execution mode */
6114 ctx->bstate = BS_STOP;
6115 rn = "IntCtl";
6116 break;
6117 case 2:
6118 check_insn(ctx, ISA_MIPS32R2);
6119 gen_helper_mtc0_srsctl(cpu_env, arg);
6120 /* Stop translation as we may have switched the execution mode */
6121 ctx->bstate = BS_STOP;
6122 rn = "SRSCtl";
6123 break;
6124 case 3:
6125 check_insn(ctx, ISA_MIPS32R2);
6126 gen_mtc0_store32(arg, offsetof(CPUMIPSState, CP0_SRSMap));
6127 /* Stop translation as we may have switched the execution mode */
6128 ctx->bstate = BS_STOP;
6129 rn = "SRSMap";
6130 break;
6131 default:
6132 goto die;
6134 break;
6135 case 13:
6136 switch (sel) {
6137 case 0:
6138 save_cpu_state(ctx, 1);
6139 /* Mark as an IO operation because we may trigger a software
6140 interrupt. */
6141 if (use_icount) {
6142 gen_io_start();
6144 gen_helper_mtc0_cause(cpu_env, arg);
6145 if (use_icount) {
6146 gen_io_end();
6148 /* Stop translation as we may have triggered an intetrupt */
6149 ctx->bstate = BS_STOP;
6150 rn = "Cause";
6151 break;
6152 default:
6153 goto die;
6155 break;
6156 case 14:
6157 switch (sel) {
6158 case 0:
6159 tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EPC));
6160 rn = "EPC";
6161 break;
6162 default:
6163 goto die;
6165 break;
6166 case 15:
6167 switch (sel) {
6168 case 0:
6169 /* ignored */
6170 rn = "PRid";
6171 break;
6172 case 1:
6173 check_insn(ctx, ISA_MIPS32R2);
6174 gen_helper_mtc0_ebase(cpu_env, arg);
6175 rn = "EBase";
6176 break;
6177 default:
6178 goto die;
6180 break;
6181 case 16:
6182 switch (sel) {
6183 case 0:
6184 gen_helper_mtc0_config0(cpu_env, arg);
6185 rn = "Config";
6186 /* Stop translation as we may have switched the execution mode */
6187 ctx->bstate = BS_STOP;
6188 break;
6189 case 1:
6190 /* ignored, read only */
6191 rn = "Config1";
6192 break;
6193 case 2:
6194 gen_helper_mtc0_config2(cpu_env, arg);
6195 rn = "Config2";
6196 /* Stop translation as we may have switched the execution mode */
6197 ctx->bstate = BS_STOP;
6198 break;
6199 case 3:
6200 /* ignored */
6201 rn = "Config3";
6202 break;
6203 /* 6,7 are implementation dependent */
6204 default:
6205 rn = "Invalid config selector";
6206 goto die;
6208 break;
6209 case 17:
6210 switch (sel) {
6211 case 0:
6212 gen_helper_mtc0_lladdr(cpu_env, arg);
6213 rn = "LLAddr";
6214 break;
6215 default:
6216 goto die;
6218 break;
6219 case 18:
6220 switch (sel) {
6221 case 0 ... 7:
6222 gen_helper_0e1i(mtc0_watchlo, arg, sel);
6223 rn = "WatchLo";
6224 break;
6225 default:
6226 goto die;
6228 break;
6229 case 19:
6230 switch (sel) {
6231 case 0 ... 7:
6232 gen_helper_0e1i(mtc0_watchhi, arg, sel);
6233 rn = "WatchHi";
6234 break;
6235 default:
6236 goto die;
6238 break;
6239 case 20:
6240 switch (sel) {
6241 case 0:
6242 check_insn(ctx, ISA_MIPS3);
6243 gen_helper_mtc0_xcontext(cpu_env, arg);
6244 rn = "XContext";
6245 break;
6246 default:
6247 goto die;
6249 break;
6250 case 21:
6251 /* Officially reserved, but sel 0 is used for R1x000 framemask */
6252 switch (sel) {
6253 case 0:
6254 gen_helper_mtc0_framemask(cpu_env, arg);
6255 rn = "Framemask";
6256 break;
6257 default:
6258 goto die;
6260 break;
6261 case 22:
6262 /* ignored */
6263 rn = "Diagnostic"; /* implementation dependent */
6264 break;
6265 case 23:
6266 switch (sel) {
6267 case 0:
6268 gen_helper_mtc0_debug(cpu_env, arg); /* EJTAG support */
6269 /* BS_STOP isn't good enough here, hflags may have changed. */
6270 gen_save_pc(ctx->pc + 4);
6271 ctx->bstate = BS_EXCP;
6272 rn = "Debug";
6273 break;
6274 case 1:
6275 // gen_helper_mtc0_tracecontrol(cpu_env, arg); /* PDtrace support */
6276 /* Stop translation as we may have switched the execution mode */
6277 ctx->bstate = BS_STOP;
6278 rn = "TraceControl";
6279 // break;
6280 case 2:
6281 // gen_helper_mtc0_tracecontrol2(cpu_env, arg); /* PDtrace support */
6282 /* Stop translation as we may have switched the execution mode */
6283 ctx->bstate = BS_STOP;
6284 rn = "TraceControl2";
6285 // break;
6286 case 3:
6287 // gen_helper_mtc0_usertracedata(cpu_env, arg); /* PDtrace support */
6288 /* Stop translation as we may have switched the execution mode */
6289 ctx->bstate = BS_STOP;
6290 rn = "UserTraceData";
6291 // break;
6292 case 4:
6293 // gen_helper_mtc0_tracebpc(cpu_env, arg); /* PDtrace support */
6294 /* Stop translation as we may have switched the execution mode */
6295 ctx->bstate = BS_STOP;
6296 rn = "TraceBPC";
6297 // break;
6298 default:
6299 goto die;
6301 break;
6302 case 24:
6303 switch (sel) {
6304 case 0:
6305 /* EJTAG support */
6306 tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_DEPC));
6307 rn = "DEPC";
6308 break;
6309 default:
6310 goto die;
6312 break;
6313 case 25:
6314 switch (sel) {
6315 case 0:
6316 gen_helper_mtc0_performance0(cpu_env, arg);
6317 rn = "Performance0";
6318 break;
6319 case 1:
6320 // gen_helper_mtc0_performance1(cpu_env, arg);
6321 rn = "Performance1";
6322 // break;
6323 case 2:
6324 // gen_helper_mtc0_performance2(cpu_env, arg);
6325 rn = "Performance2";
6326 // break;
6327 case 3:
6328 // gen_helper_mtc0_performance3(cpu_env, arg);
6329 rn = "Performance3";
6330 // break;
6331 case 4:
6332 // gen_helper_mtc0_performance4(cpu_env, arg);
6333 rn = "Performance4";
6334 // break;
6335 case 5:
6336 // gen_helper_mtc0_performance5(cpu_env, arg);
6337 rn = "Performance5";
6338 // break;
6339 case 6:
6340 // gen_helper_mtc0_performance6(cpu_env, arg);
6341 rn = "Performance6";
6342 // break;
6343 case 7:
6344 // gen_helper_mtc0_performance7(cpu_env, arg);
6345 rn = "Performance7";
6346 // break;
6347 default:
6348 goto die;
6350 break;
6351 case 26:
6352 /* ignored */
6353 rn = "ECC";
6354 break;
6355 case 27:
6356 switch (sel) {
6357 case 0 ... 3:
6358 /* ignored */
6359 rn = "CacheErr";
6360 break;
6361 default:
6362 goto die;
6364 break;
6365 case 28:
6366 switch (sel) {
6367 case 0:
6368 case 2:
6369 case 4:
6370 case 6:
6371 gen_helper_mtc0_taglo(cpu_env, arg);
6372 rn = "TagLo";
6373 break;
6374 case 1:
6375 case 3:
6376 case 5:
6377 case 7:
6378 gen_helper_mtc0_datalo(cpu_env, arg);
6379 rn = "DataLo";
6380 break;
6381 default:
6382 goto die;
6384 break;
6385 case 29:
6386 switch (sel) {
6387 case 0:
6388 case 2:
6389 case 4:
6390 case 6:
6391 gen_helper_mtc0_taghi(cpu_env, arg);
6392 rn = "TagHi";
6393 break;
6394 case 1:
6395 case 3:
6396 case 5:
6397 case 7:
6398 gen_helper_mtc0_datahi(cpu_env, arg);
6399 rn = "DataHi";
6400 break;
6401 default:
6402 rn = "invalid sel";
6403 goto die;
6405 break;
6406 case 30:
6407 switch (sel) {
6408 case 0:
6409 tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_ErrorEPC));
6410 rn = "ErrorEPC";
6411 break;
6412 default:
6413 goto die;
6415 break;
6416 case 31:
6417 switch (sel) {
6418 case 0:
6419 /* EJTAG support */
6420 gen_mtc0_store32(arg, offsetof(CPUMIPSState, CP0_DESAVE));
6421 rn = "DESAVE";
6422 break;
6423 default:
6424 goto die;
6426 /* Stop translation as we may have switched the execution mode */
6427 ctx->bstate = BS_STOP;
6428 break;
6429 default:
6430 goto die;
6432 (void)rn; /* avoid a compiler warning */
6433 LOG_DISAS("dmtc0 %s (reg %d sel %d)\n", rn, reg, sel);
6434 /* For simplicity assume that all writes can cause interrupts. */
6435 if (use_icount) {
6436 gen_io_end();
6437 ctx->bstate = BS_STOP;
6439 return;
6441 die:
6442 LOG_DISAS("dmtc0 %s (reg %d sel %d)\n", rn, reg, sel);
6443 generate_exception(ctx, EXCP_RI);
6445 #endif /* TARGET_MIPS64 */
6447 static void gen_mftr(CPUMIPSState *env, DisasContext *ctx, int rt, int rd,
6448 int u, int sel, int h)
6450 int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
6451 TCGv t0 = tcg_temp_local_new();
6453 if ((env->CP0_VPEConf0 & (1 << CP0VPEC0_MVP)) == 0 &&
6454 ((env->tcs[other_tc].CP0_TCBind & (0xf << CP0TCBd_CurVPE)) !=
6455 (env->active_tc.CP0_TCBind & (0xf << CP0TCBd_CurVPE))))
6456 tcg_gen_movi_tl(t0, -1);
6457 else if ((env->CP0_VPEControl & (0xff << CP0VPECo_TargTC)) >
6458 (env->mvp->CP0_MVPConf0 & (0xff << CP0MVPC0_PTC)))
6459 tcg_gen_movi_tl(t0, -1);
6460 else if (u == 0) {
6461 switch (rt) {
6462 case 1:
6463 switch (sel) {
6464 case 1:
6465 gen_helper_mftc0_vpecontrol(t0, cpu_env);
6466 break;
6467 case 2:
6468 gen_helper_mftc0_vpeconf0(t0, cpu_env);
6469 break;
6470 default:
6471 goto die;
6472 break;
6474 break;
6475 case 2:
6476 switch (sel) {
6477 case 1:
6478 gen_helper_mftc0_tcstatus(t0, cpu_env);
6479 break;
6480 case 2:
6481 gen_helper_mftc0_tcbind(t0, cpu_env);
6482 break;
6483 case 3:
6484 gen_helper_mftc0_tcrestart(t0, cpu_env);
6485 break;
6486 case 4:
6487 gen_helper_mftc0_tchalt(t0, cpu_env);
6488 break;
6489 case 5:
6490 gen_helper_mftc0_tccontext(t0, cpu_env);
6491 break;
6492 case 6:
6493 gen_helper_mftc0_tcschedule(t0, cpu_env);
6494 break;
6495 case 7:
6496 gen_helper_mftc0_tcschefback(t0, cpu_env);
6497 break;
6498 default:
6499 gen_mfc0(ctx, t0, rt, sel);
6500 break;
6502 break;
6503 case 10:
6504 switch (sel) {
6505 case 0:
6506 gen_helper_mftc0_entryhi(t0, cpu_env);
6507 break;
6508 default:
6509 gen_mfc0(ctx, t0, rt, sel);
6510 break;
6512 case 12:
6513 switch (sel) {
6514 case 0:
6515 gen_helper_mftc0_status(t0, cpu_env);
6516 break;
6517 default:
6518 gen_mfc0(ctx, t0, rt, sel);
6519 break;
6521 case 13:
6522 switch (sel) {
6523 case 0:
6524 gen_helper_mftc0_cause(t0, cpu_env);
6525 break;
6526 default:
6527 goto die;
6528 break;
6530 break;
6531 case 14:
6532 switch (sel) {
6533 case 0:
6534 gen_helper_mftc0_epc(t0, cpu_env);
6535 break;
6536 default:
6537 goto die;
6538 break;
6540 break;
6541 case 15:
6542 switch (sel) {
6543 case 1:
6544 gen_helper_mftc0_ebase(t0, cpu_env);
6545 break;
6546 default:
6547 goto die;
6548 break;
6550 break;
6551 case 16:
6552 switch (sel) {
6553 case 0 ... 7:
6554 gen_helper_mftc0_configx(t0, cpu_env, tcg_const_tl(sel));
6555 break;
6556 default:
6557 goto die;
6558 break;
6560 break;
6561 case 23:
6562 switch (sel) {
6563 case 0:
6564 gen_helper_mftc0_debug(t0, cpu_env);
6565 break;
6566 default:
6567 gen_mfc0(ctx, t0, rt, sel);
6568 break;
6570 break;
6571 default:
6572 gen_mfc0(ctx, t0, rt, sel);
6574 } else switch (sel) {
6575 /* GPR registers. */
6576 case 0:
6577 gen_helper_1e0i(mftgpr, t0, rt);
6578 break;
6579 /* Auxiliary CPU registers */
6580 case 1:
6581 switch (rt) {
6582 case 0:
6583 gen_helper_1e0i(mftlo, t0, 0);
6584 break;
6585 case 1:
6586 gen_helper_1e0i(mfthi, t0, 0);
6587 break;
6588 case 2:
6589 gen_helper_1e0i(mftacx, t0, 0);
6590 break;
6591 case 4:
6592 gen_helper_1e0i(mftlo, t0, 1);
6593 break;
6594 case 5:
6595 gen_helper_1e0i(mfthi, t0, 1);
6596 break;
6597 case 6:
6598 gen_helper_1e0i(mftacx, t0, 1);
6599 break;
6600 case 8:
6601 gen_helper_1e0i(mftlo, t0, 2);
6602 break;
6603 case 9:
6604 gen_helper_1e0i(mfthi, t0, 2);
6605 break;
6606 case 10:
6607 gen_helper_1e0i(mftacx, t0, 2);
6608 break;
6609 case 12:
6610 gen_helper_1e0i(mftlo, t0, 3);
6611 break;
6612 case 13:
6613 gen_helper_1e0i(mfthi, t0, 3);
6614 break;
6615 case 14:
6616 gen_helper_1e0i(mftacx, t0, 3);
6617 break;
6618 case 16:
6619 gen_helper_mftdsp(t0, cpu_env);
6620 break;
6621 default:
6622 goto die;
6624 break;
6625 /* Floating point (COP1). */
6626 case 2:
6627 /* XXX: For now we support only a single FPU context. */
6628 if (h == 0) {
6629 TCGv_i32 fp0 = tcg_temp_new_i32();
6631 gen_load_fpr32(fp0, rt);
6632 tcg_gen_ext_i32_tl(t0, fp0);
6633 tcg_temp_free_i32(fp0);
6634 } else {
6635 TCGv_i32 fp0 = tcg_temp_new_i32();
6637 gen_load_fpr32h(fp0, rt);
6638 tcg_gen_ext_i32_tl(t0, fp0);
6639 tcg_temp_free_i32(fp0);
6641 break;
6642 case 3:
6643 /* XXX: For now we support only a single FPU context. */
6644 gen_helper_1e0i(cfc1, t0, rt);
6645 break;
6646 /* COP2: Not implemented. */
6647 case 4:
6648 case 5:
6649 /* fall through */
6650 default:
6651 goto die;
6653 LOG_DISAS("mftr (reg %d u %d sel %d h %d)\n", rt, u, sel, h);
6654 gen_store_gpr(t0, rd);
6655 tcg_temp_free(t0);
6656 return;
6658 die:
6659 tcg_temp_free(t0);
6660 LOG_DISAS("mftr (reg %d u %d sel %d h %d)\n", rt, u, sel, h);
6661 generate_exception(ctx, EXCP_RI);
6664 static void gen_mttr(CPUMIPSState *env, DisasContext *ctx, int rd, int rt,
6665 int u, int sel, int h)
6667 int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
6668 TCGv t0 = tcg_temp_local_new();
6670 gen_load_gpr(t0, rt);
6671 if ((env->CP0_VPEConf0 & (1 << CP0VPEC0_MVP)) == 0 &&
6672 ((env->tcs[other_tc].CP0_TCBind & (0xf << CP0TCBd_CurVPE)) !=
6673 (env->active_tc.CP0_TCBind & (0xf << CP0TCBd_CurVPE))))
6674 /* NOP */ ;
6675 else if ((env->CP0_VPEControl & (0xff << CP0VPECo_TargTC)) >
6676 (env->mvp->CP0_MVPConf0 & (0xff << CP0MVPC0_PTC)))
6677 /* NOP */ ;
6678 else if (u == 0) {
6679 switch (rd) {
6680 case 1:
6681 switch (sel) {
6682 case 1:
6683 gen_helper_mttc0_vpecontrol(cpu_env, t0);
6684 break;
6685 case 2:
6686 gen_helper_mttc0_vpeconf0(cpu_env, t0);
6687 break;
6688 default:
6689 goto die;
6690 break;
6692 break;
6693 case 2:
6694 switch (sel) {
6695 case 1:
6696 gen_helper_mttc0_tcstatus(cpu_env, t0);
6697 break;
6698 case 2:
6699 gen_helper_mttc0_tcbind(cpu_env, t0);
6700 break;
6701 case 3:
6702 gen_helper_mttc0_tcrestart(cpu_env, t0);
6703 break;
6704 case 4:
6705 gen_helper_mttc0_tchalt(cpu_env, t0);
6706 break;
6707 case 5:
6708 gen_helper_mttc0_tccontext(cpu_env, t0);
6709 break;
6710 case 6:
6711 gen_helper_mttc0_tcschedule(cpu_env, t0);
6712 break;
6713 case 7:
6714 gen_helper_mttc0_tcschefback(cpu_env, t0);
6715 break;
6716 default:
6717 gen_mtc0(ctx, t0, rd, sel);
6718 break;
6720 break;
6721 case 10:
6722 switch (sel) {
6723 case 0:
6724 gen_helper_mttc0_entryhi(cpu_env, t0);
6725 break;
6726 default:
6727 gen_mtc0(ctx, t0, rd, sel);
6728 break;
6730 case 12:
6731 switch (sel) {
6732 case 0:
6733 gen_helper_mttc0_status(cpu_env, t0);
6734 break;
6735 default:
6736 gen_mtc0(ctx, t0, rd, sel);
6737 break;
6739 case 13:
6740 switch (sel) {
6741 case 0:
6742 gen_helper_mttc0_cause(cpu_env, t0);
6743 break;
6744 default:
6745 goto die;
6746 break;
6748 break;
6749 case 15:
6750 switch (sel) {
6751 case 1:
6752 gen_helper_mttc0_ebase(cpu_env, t0);
6753 break;
6754 default:
6755 goto die;
6756 break;
6758 break;
6759 case 23:
6760 switch (sel) {
6761 case 0:
6762 gen_helper_mttc0_debug(cpu_env, t0);
6763 break;
6764 default:
6765 gen_mtc0(ctx, t0, rd, sel);
6766 break;
6768 break;
6769 default:
6770 gen_mtc0(ctx, t0, rd, sel);
6772 } else switch (sel) {
6773 /* GPR registers. */
6774 case 0:
6775 gen_helper_0e1i(mttgpr, t0, rd);
6776 break;
6777 /* Auxiliary CPU registers */
6778 case 1:
6779 switch (rd) {
6780 case 0:
6781 gen_helper_0e1i(mttlo, t0, 0);
6782 break;
6783 case 1:
6784 gen_helper_0e1i(mtthi, t0, 0);
6785 break;
6786 case 2:
6787 gen_helper_0e1i(mttacx, t0, 0);
6788 break;
6789 case 4:
6790 gen_helper_0e1i(mttlo, t0, 1);
6791 break;
6792 case 5:
6793 gen_helper_0e1i(mtthi, t0, 1);
6794 break;
6795 case 6:
6796 gen_helper_0e1i(mttacx, t0, 1);
6797 break;
6798 case 8:
6799 gen_helper_0e1i(mttlo, t0, 2);
6800 break;
6801 case 9:
6802 gen_helper_0e1i(mtthi, t0, 2);
6803 break;
6804 case 10:
6805 gen_helper_0e1i(mttacx, t0, 2);
6806 break;
6807 case 12:
6808 gen_helper_0e1i(mttlo, t0, 3);
6809 break;
6810 case 13:
6811 gen_helper_0e1i(mtthi, t0, 3);
6812 break;
6813 case 14:
6814 gen_helper_0e1i(mttacx, t0, 3);
6815 break;
6816 case 16:
6817 gen_helper_mttdsp(cpu_env, t0);
6818 break;
6819 default:
6820 goto die;
6822 break;
6823 /* Floating point (COP1). */
6824 case 2:
6825 /* XXX: For now we support only a single FPU context. */
6826 if (h == 0) {
6827 TCGv_i32 fp0 = tcg_temp_new_i32();
6829 tcg_gen_trunc_tl_i32(fp0, t0);
6830 gen_store_fpr32(fp0, rd);
6831 tcg_temp_free_i32(fp0);
6832 } else {
6833 TCGv_i32 fp0 = tcg_temp_new_i32();
6835 tcg_gen_trunc_tl_i32(fp0, t0);
6836 gen_store_fpr32h(fp0, rd);
6837 tcg_temp_free_i32(fp0);
6839 break;
6840 case 3:
6841 /* XXX: For now we support only a single FPU context. */
6842 gen_helper_0e1i(ctc1, t0, rd);
6843 break;
6844 /* COP2: Not implemented. */
6845 case 4:
6846 case 5:
6847 /* fall through */
6848 default:
6849 goto die;
6851 LOG_DISAS("mttr (reg %d u %d sel %d h %d)\n", rd, u, sel, h);
6852 tcg_temp_free(t0);
6853 return;
6855 die:
6856 tcg_temp_free(t0);
6857 LOG_DISAS("mttr (reg %d u %d sel %d h %d)\n", rd, u, sel, h);
6858 generate_exception(ctx, EXCP_RI);
6861 static void gen_cp0 (CPUMIPSState *env, DisasContext *ctx, uint32_t opc, int rt, int rd)
6863 const char *opn = "ldst";
6865 check_cp0_enabled(ctx);
6866 switch (opc) {
6867 case OPC_MFC0:
6868 if (rt == 0) {
6869 /* Treat as NOP. */
6870 return;
6872 gen_mfc0(ctx, cpu_gpr[rt], rd, ctx->opcode & 0x7);
6873 opn = "mfc0";
6874 break;
6875 case OPC_MTC0:
6877 TCGv t0 = tcg_temp_new();
6879 gen_load_gpr(t0, rt);
6880 gen_mtc0(ctx, t0, rd, ctx->opcode & 0x7);
6881 tcg_temp_free(t0);
6883 opn = "mtc0";
6884 break;
6885 #if defined(TARGET_MIPS64)
6886 case OPC_DMFC0:
6887 check_insn(ctx, ISA_MIPS3);
6888 if (rt == 0) {
6889 /* Treat as NOP. */
6890 return;
6892 gen_dmfc0(ctx, cpu_gpr[rt], rd, ctx->opcode & 0x7);
6893 opn = "dmfc0";
6894 break;
6895 case OPC_DMTC0:
6896 check_insn(ctx, ISA_MIPS3);
6898 TCGv t0 = tcg_temp_new();
6900 gen_load_gpr(t0, rt);
6901 gen_dmtc0(ctx, t0, rd, ctx->opcode & 0x7);
6902 tcg_temp_free(t0);
6904 opn = "dmtc0";
6905 break;
6906 #endif
6907 case OPC_MFTR:
6908 check_insn(ctx, ASE_MT);
6909 if (rd == 0) {
6910 /* Treat as NOP. */
6911 return;
6913 gen_mftr(env, ctx, rt, rd, (ctx->opcode >> 5) & 1,
6914 ctx->opcode & 0x7, (ctx->opcode >> 4) & 1);
6915 opn = "mftr";
6916 break;
6917 case OPC_MTTR:
6918 check_insn(ctx, ASE_MT);
6919 gen_mttr(env, ctx, rd, rt, (ctx->opcode >> 5) & 1,
6920 ctx->opcode & 0x7, (ctx->opcode >> 4) & 1);
6921 opn = "mttr";
6922 break;
6923 case OPC_TLBWI:
6924 opn = "tlbwi";
6925 if (!env->tlb->helper_tlbwi)
6926 goto die;
6927 gen_helper_tlbwi(cpu_env);
6928 break;
6929 case OPC_TLBWR:
6930 opn = "tlbwr";
6931 if (!env->tlb->helper_tlbwr)
6932 goto die;
6933 gen_helper_tlbwr(cpu_env);
6934 break;
6935 case OPC_TLBP:
6936 opn = "tlbp";
6937 if (!env->tlb->helper_tlbp)
6938 goto die;
6939 gen_helper_tlbp(cpu_env);
6940 break;
6941 case OPC_TLBR:
6942 opn = "tlbr";
6943 if (!env->tlb->helper_tlbr)
6944 goto die;
6945 gen_helper_tlbr(cpu_env);
6946 break;
6947 case OPC_ERET:
6948 opn = "eret";
6949 check_insn(ctx, ISA_MIPS2);
6950 gen_helper_eret(cpu_env);
6951 ctx->bstate = BS_EXCP;
6952 break;
6953 case OPC_DERET:
6954 opn = "deret";
6955 check_insn(ctx, ISA_MIPS32);
6956 if (!(ctx->hflags & MIPS_HFLAG_DM)) {
6957 MIPS_INVAL(opn);
6958 generate_exception(ctx, EXCP_RI);
6959 } else {
6960 gen_helper_deret(cpu_env);
6961 ctx->bstate = BS_EXCP;
6963 break;
6964 case OPC_WAIT:
6965 opn = "wait";
6966 check_insn(ctx, ISA_MIPS3 | ISA_MIPS32);
6967 /* If we get an exception, we want to restart at next instruction */
6968 ctx->pc += 4;
6969 save_cpu_state(ctx, 1);
6970 ctx->pc -= 4;
6971 gen_helper_wait(cpu_env);
6972 ctx->bstate = BS_EXCP;
6973 break;
6974 default:
6975 die:
6976 MIPS_INVAL(opn);
6977 generate_exception(ctx, EXCP_RI);
6978 return;
6980 (void)opn; /* avoid a compiler warning */
6981 MIPS_DEBUG("%s %s %d", opn, regnames[rt], rd);
6983 #endif /* !CONFIG_USER_ONLY */
6985 /* CP1 Branches (before delay slot) */
6986 static void gen_compute_branch1(DisasContext *ctx, uint32_t op,
6987 int32_t cc, int32_t offset)
6989 target_ulong btarget;
6990 const char *opn = "cp1 cond branch";
6991 TCGv_i32 t0 = tcg_temp_new_i32();
6993 if (cc != 0)
6994 check_insn(ctx, ISA_MIPS4 | ISA_MIPS32);
6996 btarget = ctx->pc + 4 + offset;
6998 switch (op) {
6999 case OPC_BC1F:
7000 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
7001 tcg_gen_not_i32(t0, t0);
7002 tcg_gen_andi_i32(t0, t0, 1);
7003 tcg_gen_extu_i32_tl(bcond, t0);
7004 opn = "bc1f";
7005 goto not_likely;
7006 case OPC_BC1FL:
7007 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
7008 tcg_gen_not_i32(t0, t0);
7009 tcg_gen_andi_i32(t0, t0, 1);
7010 tcg_gen_extu_i32_tl(bcond, t0);
7011 opn = "bc1fl";
7012 goto likely;
7013 case OPC_BC1T:
7014 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
7015 tcg_gen_andi_i32(t0, t0, 1);
7016 tcg_gen_extu_i32_tl(bcond, t0);
7017 opn = "bc1t";
7018 goto not_likely;
7019 case OPC_BC1TL:
7020 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
7021 tcg_gen_andi_i32(t0, t0, 1);
7022 tcg_gen_extu_i32_tl(bcond, t0);
7023 opn = "bc1tl";
7024 likely:
7025 ctx->hflags |= MIPS_HFLAG_BL;
7026 break;
7027 case OPC_BC1FANY2:
7029 TCGv_i32 t1 = tcg_temp_new_i32();
7030 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
7031 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+1));
7032 tcg_gen_nand_i32(t0, t0, t1);
7033 tcg_temp_free_i32(t1);
7034 tcg_gen_andi_i32(t0, t0, 1);
7035 tcg_gen_extu_i32_tl(bcond, t0);
7037 opn = "bc1any2f";
7038 goto not_likely;
7039 case OPC_BC1TANY2:
7041 TCGv_i32 t1 = tcg_temp_new_i32();
7042 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
7043 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+1));
7044 tcg_gen_or_i32(t0, t0, t1);
7045 tcg_temp_free_i32(t1);
7046 tcg_gen_andi_i32(t0, t0, 1);
7047 tcg_gen_extu_i32_tl(bcond, t0);
7049 opn = "bc1any2t";
7050 goto not_likely;
7051 case OPC_BC1FANY4:
7053 TCGv_i32 t1 = tcg_temp_new_i32();
7054 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
7055 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+1));
7056 tcg_gen_and_i32(t0, t0, t1);
7057 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+2));
7058 tcg_gen_and_i32(t0, t0, t1);
7059 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+3));
7060 tcg_gen_nand_i32(t0, t0, t1);
7061 tcg_temp_free_i32(t1);
7062 tcg_gen_andi_i32(t0, t0, 1);
7063 tcg_gen_extu_i32_tl(bcond, t0);
7065 opn = "bc1any4f";
7066 goto not_likely;
7067 case OPC_BC1TANY4:
7069 TCGv_i32 t1 = tcg_temp_new_i32();
7070 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
7071 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+1));
7072 tcg_gen_or_i32(t0, t0, t1);
7073 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+2));
7074 tcg_gen_or_i32(t0, t0, t1);
7075 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+3));
7076 tcg_gen_or_i32(t0, t0, t1);
7077 tcg_temp_free_i32(t1);
7078 tcg_gen_andi_i32(t0, t0, 1);
7079 tcg_gen_extu_i32_tl(bcond, t0);
7081 opn = "bc1any4t";
7082 not_likely:
7083 ctx->hflags |= MIPS_HFLAG_BC;
7084 break;
7085 default:
7086 MIPS_INVAL(opn);
7087 generate_exception (ctx, EXCP_RI);
7088 goto out;
7090 (void)opn; /* avoid a compiler warning */
7091 MIPS_DEBUG("%s: cond %02x target " TARGET_FMT_lx, opn,
7092 ctx->hflags, btarget);
7093 ctx->btarget = btarget;
7095 out:
7096 tcg_temp_free_i32(t0);
7099 /* Coprocessor 1 (FPU) */
7101 #define FOP(func, fmt) (((fmt) << 21) | (func))
7103 enum fopcode {
7104 OPC_ADD_S = FOP(0, FMT_S),
7105 OPC_SUB_S = FOP(1, FMT_S),
7106 OPC_MUL_S = FOP(2, FMT_S),
7107 OPC_DIV_S = FOP(3, FMT_S),
7108 OPC_SQRT_S = FOP(4, FMT_S),
7109 OPC_ABS_S = FOP(5, FMT_S),
7110 OPC_MOV_S = FOP(6, FMT_S),
7111 OPC_NEG_S = FOP(7, FMT_S),
7112 OPC_ROUND_L_S = FOP(8, FMT_S),
7113 OPC_TRUNC_L_S = FOP(9, FMT_S),
7114 OPC_CEIL_L_S = FOP(10, FMT_S),
7115 OPC_FLOOR_L_S = FOP(11, FMT_S),
7116 OPC_ROUND_W_S = FOP(12, FMT_S),
7117 OPC_TRUNC_W_S = FOP(13, FMT_S),
7118 OPC_CEIL_W_S = FOP(14, FMT_S),
7119 OPC_FLOOR_W_S = FOP(15, FMT_S),
7120 OPC_MOVCF_S = FOP(17, FMT_S),
7121 OPC_MOVZ_S = FOP(18, FMT_S),
7122 OPC_MOVN_S = FOP(19, FMT_S),
7123 OPC_RECIP_S = FOP(21, FMT_S),
7124 OPC_RSQRT_S = FOP(22, FMT_S),
7125 OPC_RECIP2_S = FOP(28, FMT_S),
7126 OPC_RECIP1_S = FOP(29, FMT_S),
7127 OPC_RSQRT1_S = FOP(30, FMT_S),
7128 OPC_RSQRT2_S = FOP(31, FMT_S),
7129 OPC_CVT_D_S = FOP(33, FMT_S),
7130 OPC_CVT_W_S = FOP(36, FMT_S),
7131 OPC_CVT_L_S = FOP(37, FMT_S),
7132 OPC_CVT_PS_S = FOP(38, FMT_S),
7133 OPC_CMP_F_S = FOP (48, FMT_S),
7134 OPC_CMP_UN_S = FOP (49, FMT_S),
7135 OPC_CMP_EQ_S = FOP (50, FMT_S),
7136 OPC_CMP_UEQ_S = FOP (51, FMT_S),
7137 OPC_CMP_OLT_S = FOP (52, FMT_S),
7138 OPC_CMP_ULT_S = FOP (53, FMT_S),
7139 OPC_CMP_OLE_S = FOP (54, FMT_S),
7140 OPC_CMP_ULE_S = FOP (55, FMT_S),
7141 OPC_CMP_SF_S = FOP (56, FMT_S),
7142 OPC_CMP_NGLE_S = FOP (57, FMT_S),
7143 OPC_CMP_SEQ_S = FOP (58, FMT_S),
7144 OPC_CMP_NGL_S = FOP (59, FMT_S),
7145 OPC_CMP_LT_S = FOP (60, FMT_S),
7146 OPC_CMP_NGE_S = FOP (61, FMT_S),
7147 OPC_CMP_LE_S = FOP (62, FMT_S),
7148 OPC_CMP_NGT_S = FOP (63, FMT_S),
7150 OPC_ADD_D = FOP(0, FMT_D),
7151 OPC_SUB_D = FOP(1, FMT_D),
7152 OPC_MUL_D = FOP(2, FMT_D),
7153 OPC_DIV_D = FOP(3, FMT_D),
7154 OPC_SQRT_D = FOP(4, FMT_D),
7155 OPC_ABS_D = FOP(5, FMT_D),
7156 OPC_MOV_D = FOP(6, FMT_D),
7157 OPC_NEG_D = FOP(7, FMT_D),
7158 OPC_ROUND_L_D = FOP(8, FMT_D),
7159 OPC_TRUNC_L_D = FOP(9, FMT_D),
7160 OPC_CEIL_L_D = FOP(10, FMT_D),
7161 OPC_FLOOR_L_D = FOP(11, FMT_D),
7162 OPC_ROUND_W_D = FOP(12, FMT_D),
7163 OPC_TRUNC_W_D = FOP(13, FMT_D),
7164 OPC_CEIL_W_D = FOP(14, FMT_D),
7165 OPC_FLOOR_W_D = FOP(15, FMT_D),
7166 OPC_MOVCF_D = FOP(17, FMT_D),
7167 OPC_MOVZ_D = FOP(18, FMT_D),
7168 OPC_MOVN_D = FOP(19, FMT_D),
7169 OPC_RECIP_D = FOP(21, FMT_D),
7170 OPC_RSQRT_D = FOP(22, FMT_D),
7171 OPC_RECIP2_D = FOP(28, FMT_D),
7172 OPC_RECIP1_D = FOP(29, FMT_D),
7173 OPC_RSQRT1_D = FOP(30, FMT_D),
7174 OPC_RSQRT2_D = FOP(31, FMT_D),
7175 OPC_CVT_S_D = FOP(32, FMT_D),
7176 OPC_CVT_W_D = FOP(36, FMT_D),
7177 OPC_CVT_L_D = FOP(37, FMT_D),
7178 OPC_CMP_F_D = FOP (48, FMT_D),
7179 OPC_CMP_UN_D = FOP (49, FMT_D),
7180 OPC_CMP_EQ_D = FOP (50, FMT_D),
7181 OPC_CMP_UEQ_D = FOP (51, FMT_D),
7182 OPC_CMP_OLT_D = FOP (52, FMT_D),
7183 OPC_CMP_ULT_D = FOP (53, FMT_D),
7184 OPC_CMP_OLE_D = FOP (54, FMT_D),
7185 OPC_CMP_ULE_D = FOP (55, FMT_D),
7186 OPC_CMP_SF_D = FOP (56, FMT_D),
7187 OPC_CMP_NGLE_D = FOP (57, FMT_D),
7188 OPC_CMP_SEQ_D = FOP (58, FMT_D),
7189 OPC_CMP_NGL_D = FOP (59, FMT_D),
7190 OPC_CMP_LT_D = FOP (60, FMT_D),
7191 OPC_CMP_NGE_D = FOP (61, FMT_D),
7192 OPC_CMP_LE_D = FOP (62, FMT_D),
7193 OPC_CMP_NGT_D = FOP (63, FMT_D),
7195 OPC_CVT_S_W = FOP(32, FMT_W),
7196 OPC_CVT_D_W = FOP(33, FMT_W),
7197 OPC_CVT_S_L = FOP(32, FMT_L),
7198 OPC_CVT_D_L = FOP(33, FMT_L),
7199 OPC_CVT_PS_PW = FOP(38, FMT_W),
7201 OPC_ADD_PS = FOP(0, FMT_PS),
7202 OPC_SUB_PS = FOP(1, FMT_PS),
7203 OPC_MUL_PS = FOP(2, FMT_PS),
7204 OPC_DIV_PS = FOP(3, FMT_PS),
7205 OPC_ABS_PS = FOP(5, FMT_PS),
7206 OPC_MOV_PS = FOP(6, FMT_PS),
7207 OPC_NEG_PS = FOP(7, FMT_PS),
7208 OPC_MOVCF_PS = FOP(17, FMT_PS),
7209 OPC_MOVZ_PS = FOP(18, FMT_PS),
7210 OPC_MOVN_PS = FOP(19, FMT_PS),
7211 OPC_ADDR_PS = FOP(24, FMT_PS),
7212 OPC_MULR_PS = FOP(26, FMT_PS),
7213 OPC_RECIP2_PS = FOP(28, FMT_PS),
7214 OPC_RECIP1_PS = FOP(29, FMT_PS),
7215 OPC_RSQRT1_PS = FOP(30, FMT_PS),
7216 OPC_RSQRT2_PS = FOP(31, FMT_PS),
7218 OPC_CVT_S_PU = FOP(32, FMT_PS),
7219 OPC_CVT_PW_PS = FOP(36, FMT_PS),
7220 OPC_CVT_S_PL = FOP(40, FMT_PS),
7221 OPC_PLL_PS = FOP(44, FMT_PS),
7222 OPC_PLU_PS = FOP(45, FMT_PS),
7223 OPC_PUL_PS = FOP(46, FMT_PS),
7224 OPC_PUU_PS = FOP(47, FMT_PS),
7225 OPC_CMP_F_PS = FOP (48, FMT_PS),
7226 OPC_CMP_UN_PS = FOP (49, FMT_PS),
7227 OPC_CMP_EQ_PS = FOP (50, FMT_PS),
7228 OPC_CMP_UEQ_PS = FOP (51, FMT_PS),
7229 OPC_CMP_OLT_PS = FOP (52, FMT_PS),
7230 OPC_CMP_ULT_PS = FOP (53, FMT_PS),
7231 OPC_CMP_OLE_PS = FOP (54, FMT_PS),
7232 OPC_CMP_ULE_PS = FOP (55, FMT_PS),
7233 OPC_CMP_SF_PS = FOP (56, FMT_PS),
7234 OPC_CMP_NGLE_PS = FOP (57, FMT_PS),
7235 OPC_CMP_SEQ_PS = FOP (58, FMT_PS),
7236 OPC_CMP_NGL_PS = FOP (59, FMT_PS),
7237 OPC_CMP_LT_PS = FOP (60, FMT_PS),
7238 OPC_CMP_NGE_PS = FOP (61, FMT_PS),
7239 OPC_CMP_LE_PS = FOP (62, FMT_PS),
7240 OPC_CMP_NGT_PS = FOP (63, FMT_PS),
7243 static void gen_cp1 (DisasContext *ctx, uint32_t opc, int rt, int fs)
7245 const char *opn = "cp1 move";
7246 TCGv t0 = tcg_temp_new();
7248 switch (opc) {
7249 case OPC_MFC1:
7251 TCGv_i32 fp0 = tcg_temp_new_i32();
7253 gen_load_fpr32(fp0, fs);
7254 tcg_gen_ext_i32_tl(t0, fp0);
7255 tcg_temp_free_i32(fp0);
7257 gen_store_gpr(t0, rt);
7258 opn = "mfc1";
7259 break;
7260 case OPC_MTC1:
7261 gen_load_gpr(t0, rt);
7263 TCGv_i32 fp0 = tcg_temp_new_i32();
7265 tcg_gen_trunc_tl_i32(fp0, t0);
7266 gen_store_fpr32(fp0, fs);
7267 tcg_temp_free_i32(fp0);
7269 opn = "mtc1";
7270 break;
7271 case OPC_CFC1:
7272 gen_helper_1e0i(cfc1, t0, fs);
7273 gen_store_gpr(t0, rt);
7274 opn = "cfc1";
7275 break;
7276 case OPC_CTC1:
7277 gen_load_gpr(t0, rt);
7278 gen_helper_0e1i(ctc1, t0, fs);
7279 opn = "ctc1";
7280 break;
7281 #if defined(TARGET_MIPS64)
7282 case OPC_DMFC1:
7283 gen_load_fpr64(ctx, t0, fs);
7284 gen_store_gpr(t0, rt);
7285 opn = "dmfc1";
7286 break;
7287 case OPC_DMTC1:
7288 gen_load_gpr(t0, rt);
7289 gen_store_fpr64(ctx, t0, fs);
7290 opn = "dmtc1";
7291 break;
7292 #endif
7293 case OPC_MFHC1:
7295 TCGv_i32 fp0 = tcg_temp_new_i32();
7297 gen_load_fpr32h(fp0, fs);
7298 tcg_gen_ext_i32_tl(t0, fp0);
7299 tcg_temp_free_i32(fp0);
7301 gen_store_gpr(t0, rt);
7302 opn = "mfhc1";
7303 break;
7304 case OPC_MTHC1:
7305 gen_load_gpr(t0, rt);
7307 TCGv_i32 fp0 = tcg_temp_new_i32();
7309 tcg_gen_trunc_tl_i32(fp0, t0);
7310 gen_store_fpr32h(fp0, fs);
7311 tcg_temp_free_i32(fp0);
7313 opn = "mthc1";
7314 break;
7315 default:
7316 MIPS_INVAL(opn);
7317 generate_exception (ctx, EXCP_RI);
7318 goto out;
7320 (void)opn; /* avoid a compiler warning */
7321 MIPS_DEBUG("%s %s %s", opn, regnames[rt], fregnames[fs]);
7323 out:
7324 tcg_temp_free(t0);
7327 static void gen_movci (DisasContext *ctx, int rd, int rs, int cc, int tf)
7329 int l1;
7330 TCGCond cond;
7331 TCGv_i32 t0;
7333 if (rd == 0) {
7334 /* Treat as NOP. */
7335 return;
7338 if (tf)
7339 cond = TCG_COND_EQ;
7340 else
7341 cond = TCG_COND_NE;
7343 l1 = gen_new_label();
7344 t0 = tcg_temp_new_i32();
7345 tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc));
7346 tcg_gen_brcondi_i32(cond, t0, 0, l1);
7347 tcg_temp_free_i32(t0);
7348 if (rs == 0) {
7349 tcg_gen_movi_tl(cpu_gpr[rd], 0);
7350 } else {
7351 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
7353 gen_set_label(l1);
7356 static inline void gen_movcf_s (int fs, int fd, int cc, int tf)
7358 int cond;
7359 TCGv_i32 t0 = tcg_temp_new_i32();
7360 int l1 = gen_new_label();
7362 if (tf)
7363 cond = TCG_COND_EQ;
7364 else
7365 cond = TCG_COND_NE;
7367 tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc));
7368 tcg_gen_brcondi_i32(cond, t0, 0, l1);
7369 gen_load_fpr32(t0, fs);
7370 gen_store_fpr32(t0, fd);
7371 gen_set_label(l1);
7372 tcg_temp_free_i32(t0);
7375 static inline void gen_movcf_d (DisasContext *ctx, int fs, int fd, int cc, int tf)
7377 int cond;
7378 TCGv_i32 t0 = tcg_temp_new_i32();
7379 TCGv_i64 fp0;
7380 int l1 = gen_new_label();
7382 if (tf)
7383 cond = TCG_COND_EQ;
7384 else
7385 cond = TCG_COND_NE;
7387 tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc));
7388 tcg_gen_brcondi_i32(cond, t0, 0, l1);
7389 tcg_temp_free_i32(t0);
7390 fp0 = tcg_temp_new_i64();
7391 gen_load_fpr64(ctx, fp0, fs);
7392 gen_store_fpr64(ctx, fp0, fd);
7393 tcg_temp_free_i64(fp0);
7394 gen_set_label(l1);
7397 static inline void gen_movcf_ps (int fs, int fd, int cc, int tf)
7399 int cond;
7400 TCGv_i32 t0 = tcg_temp_new_i32();
7401 int l1 = gen_new_label();
7402 int l2 = gen_new_label();
7404 if (tf)
7405 cond = TCG_COND_EQ;
7406 else
7407 cond = TCG_COND_NE;
7409 tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc));
7410 tcg_gen_brcondi_i32(cond, t0, 0, l1);
7411 gen_load_fpr32(t0, fs);
7412 gen_store_fpr32(t0, fd);
7413 gen_set_label(l1);
7415 tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc+1));
7416 tcg_gen_brcondi_i32(cond, t0, 0, l2);
7417 gen_load_fpr32h(t0, fs);
7418 gen_store_fpr32h(t0, fd);
7419 tcg_temp_free_i32(t0);
7420 gen_set_label(l2);
7424 static void gen_farith (DisasContext *ctx, enum fopcode op1,
7425 int ft, int fs, int fd, int cc)
7427 const char *opn = "farith";
7428 const char *condnames[] = {
7429 "c.f",
7430 "c.un",
7431 "c.eq",
7432 "c.ueq",
7433 "c.olt",
7434 "c.ult",
7435 "c.ole",
7436 "c.ule",
7437 "c.sf",
7438 "c.ngle",
7439 "c.seq",
7440 "c.ngl",
7441 "c.lt",
7442 "c.nge",
7443 "c.le",
7444 "c.ngt",
7446 const char *condnames_abs[] = {
7447 "cabs.f",
7448 "cabs.un",
7449 "cabs.eq",
7450 "cabs.ueq",
7451 "cabs.olt",
7452 "cabs.ult",
7453 "cabs.ole",
7454 "cabs.ule",
7455 "cabs.sf",
7456 "cabs.ngle",
7457 "cabs.seq",
7458 "cabs.ngl",
7459 "cabs.lt",
7460 "cabs.nge",
7461 "cabs.le",
7462 "cabs.ngt",
7464 enum { BINOP, CMPOP, OTHEROP } optype = OTHEROP;
7465 uint32_t func = ctx->opcode & 0x3f;
7467 switch (op1) {
7468 case OPC_ADD_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_add_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 = "add.s";
7481 optype = BINOP;
7482 break;
7483 case OPC_SUB_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_sub_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 = "sub.s";
7496 optype = BINOP;
7497 break;
7498 case OPC_MUL_S:
7500 TCGv_i32 fp0 = tcg_temp_new_i32();
7501 TCGv_i32 fp1 = tcg_temp_new_i32();
7503 gen_load_fpr32(fp0, fs);
7504 gen_load_fpr32(fp1, ft);
7505 gen_helper_float_mul_s(fp0, cpu_env, fp0, fp1);
7506 tcg_temp_free_i32(fp1);
7507 gen_store_fpr32(fp0, fd);
7508 tcg_temp_free_i32(fp0);
7510 opn = "mul.s";
7511 optype = BINOP;
7512 break;
7513 case OPC_DIV_S:
7515 TCGv_i32 fp0 = tcg_temp_new_i32();
7516 TCGv_i32 fp1 = tcg_temp_new_i32();
7518 gen_load_fpr32(fp0, fs);
7519 gen_load_fpr32(fp1, ft);
7520 gen_helper_float_div_s(fp0, cpu_env, fp0, fp1);
7521 tcg_temp_free_i32(fp1);
7522 gen_store_fpr32(fp0, fd);
7523 tcg_temp_free_i32(fp0);
7525 opn = "div.s";
7526 optype = BINOP;
7527 break;
7528 case OPC_SQRT_S:
7530 TCGv_i32 fp0 = tcg_temp_new_i32();
7532 gen_load_fpr32(fp0, fs);
7533 gen_helper_float_sqrt_s(fp0, cpu_env, fp0);
7534 gen_store_fpr32(fp0, fd);
7535 tcg_temp_free_i32(fp0);
7537 opn = "sqrt.s";
7538 break;
7539 case OPC_ABS_S:
7541 TCGv_i32 fp0 = tcg_temp_new_i32();
7543 gen_load_fpr32(fp0, fs);
7544 gen_helper_float_abs_s(fp0, fp0);
7545 gen_store_fpr32(fp0, fd);
7546 tcg_temp_free_i32(fp0);
7548 opn = "abs.s";
7549 break;
7550 case OPC_MOV_S:
7552 TCGv_i32 fp0 = tcg_temp_new_i32();
7554 gen_load_fpr32(fp0, fs);
7555 gen_store_fpr32(fp0, fd);
7556 tcg_temp_free_i32(fp0);
7558 opn = "mov.s";
7559 break;
7560 case OPC_NEG_S:
7562 TCGv_i32 fp0 = tcg_temp_new_i32();
7564 gen_load_fpr32(fp0, fs);
7565 gen_helper_float_chs_s(fp0, fp0);
7566 gen_store_fpr32(fp0, fd);
7567 tcg_temp_free_i32(fp0);
7569 opn = "neg.s";
7570 break;
7571 case OPC_ROUND_L_S:
7572 check_cp1_64bitmode(ctx);
7574 TCGv_i32 fp32 = tcg_temp_new_i32();
7575 TCGv_i64 fp64 = tcg_temp_new_i64();
7577 gen_load_fpr32(fp32, fs);
7578 gen_helper_float_roundl_s(fp64, cpu_env, fp32);
7579 tcg_temp_free_i32(fp32);
7580 gen_store_fpr64(ctx, fp64, fd);
7581 tcg_temp_free_i64(fp64);
7583 opn = "round.l.s";
7584 break;
7585 case OPC_TRUNC_L_S:
7586 check_cp1_64bitmode(ctx);
7588 TCGv_i32 fp32 = tcg_temp_new_i32();
7589 TCGv_i64 fp64 = tcg_temp_new_i64();
7591 gen_load_fpr32(fp32, fs);
7592 gen_helper_float_truncl_s(fp64, cpu_env, fp32);
7593 tcg_temp_free_i32(fp32);
7594 gen_store_fpr64(ctx, fp64, fd);
7595 tcg_temp_free_i64(fp64);
7597 opn = "trunc.l.s";
7598 break;
7599 case OPC_CEIL_L_S:
7600 check_cp1_64bitmode(ctx);
7602 TCGv_i32 fp32 = tcg_temp_new_i32();
7603 TCGv_i64 fp64 = tcg_temp_new_i64();
7605 gen_load_fpr32(fp32, fs);
7606 gen_helper_float_ceill_s(fp64, cpu_env, fp32);
7607 tcg_temp_free_i32(fp32);
7608 gen_store_fpr64(ctx, fp64, fd);
7609 tcg_temp_free_i64(fp64);
7611 opn = "ceil.l.s";
7612 break;
7613 case OPC_FLOOR_L_S:
7614 check_cp1_64bitmode(ctx);
7616 TCGv_i32 fp32 = tcg_temp_new_i32();
7617 TCGv_i64 fp64 = tcg_temp_new_i64();
7619 gen_load_fpr32(fp32, fs);
7620 gen_helper_float_floorl_s(fp64, cpu_env, fp32);
7621 tcg_temp_free_i32(fp32);
7622 gen_store_fpr64(ctx, fp64, fd);
7623 tcg_temp_free_i64(fp64);
7625 opn = "floor.l.s";
7626 break;
7627 case OPC_ROUND_W_S:
7629 TCGv_i32 fp0 = tcg_temp_new_i32();
7631 gen_load_fpr32(fp0, fs);
7632 gen_helper_float_roundw_s(fp0, cpu_env, fp0);
7633 gen_store_fpr32(fp0, fd);
7634 tcg_temp_free_i32(fp0);
7636 opn = "round.w.s";
7637 break;
7638 case OPC_TRUNC_W_S:
7640 TCGv_i32 fp0 = tcg_temp_new_i32();
7642 gen_load_fpr32(fp0, fs);
7643 gen_helper_float_truncw_s(fp0, cpu_env, fp0);
7644 gen_store_fpr32(fp0, fd);
7645 tcg_temp_free_i32(fp0);
7647 opn = "trunc.w.s";
7648 break;
7649 case OPC_CEIL_W_S:
7651 TCGv_i32 fp0 = tcg_temp_new_i32();
7653 gen_load_fpr32(fp0, fs);
7654 gen_helper_float_ceilw_s(fp0, cpu_env, fp0);
7655 gen_store_fpr32(fp0, fd);
7656 tcg_temp_free_i32(fp0);
7658 opn = "ceil.w.s";
7659 break;
7660 case OPC_FLOOR_W_S:
7662 TCGv_i32 fp0 = tcg_temp_new_i32();
7664 gen_load_fpr32(fp0, fs);
7665 gen_helper_float_floorw_s(fp0, cpu_env, fp0);
7666 gen_store_fpr32(fp0, fd);
7667 tcg_temp_free_i32(fp0);
7669 opn = "floor.w.s";
7670 break;
7671 case OPC_MOVCF_S:
7672 gen_movcf_s(fs, fd, (ft >> 2) & 0x7, ft & 0x1);
7673 opn = "movcf.s";
7674 break;
7675 case OPC_MOVZ_S:
7677 int l1 = gen_new_label();
7678 TCGv_i32 fp0;
7680 if (ft != 0) {
7681 tcg_gen_brcondi_tl(TCG_COND_NE, cpu_gpr[ft], 0, l1);
7683 fp0 = tcg_temp_new_i32();
7684 gen_load_fpr32(fp0, fs);
7685 gen_store_fpr32(fp0, fd);
7686 tcg_temp_free_i32(fp0);
7687 gen_set_label(l1);
7689 opn = "movz.s";
7690 break;
7691 case OPC_MOVN_S:
7693 int l1 = gen_new_label();
7694 TCGv_i32 fp0;
7696 if (ft != 0) {
7697 tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_gpr[ft], 0, l1);
7698 fp0 = tcg_temp_new_i32();
7699 gen_load_fpr32(fp0, fs);
7700 gen_store_fpr32(fp0, fd);
7701 tcg_temp_free_i32(fp0);
7702 gen_set_label(l1);
7705 opn = "movn.s";
7706 break;
7707 case OPC_RECIP_S:
7708 check_cop1x(ctx);
7710 TCGv_i32 fp0 = tcg_temp_new_i32();
7712 gen_load_fpr32(fp0, fs);
7713 gen_helper_float_recip_s(fp0, cpu_env, fp0);
7714 gen_store_fpr32(fp0, fd);
7715 tcg_temp_free_i32(fp0);
7717 opn = "recip.s";
7718 break;
7719 case OPC_RSQRT_S:
7720 check_cop1x(ctx);
7722 TCGv_i32 fp0 = tcg_temp_new_i32();
7724 gen_load_fpr32(fp0, fs);
7725 gen_helper_float_rsqrt_s(fp0, cpu_env, fp0);
7726 gen_store_fpr32(fp0, fd);
7727 tcg_temp_free_i32(fp0);
7729 opn = "rsqrt.s";
7730 break;
7731 case OPC_RECIP2_S:
7732 check_cp1_64bitmode(ctx);
7734 TCGv_i32 fp0 = tcg_temp_new_i32();
7735 TCGv_i32 fp1 = tcg_temp_new_i32();
7737 gen_load_fpr32(fp0, fs);
7738 gen_load_fpr32(fp1, ft);
7739 gen_helper_float_recip2_s(fp0, cpu_env, fp0, fp1);
7740 tcg_temp_free_i32(fp1);
7741 gen_store_fpr32(fp0, fd);
7742 tcg_temp_free_i32(fp0);
7744 opn = "recip2.s";
7745 break;
7746 case OPC_RECIP1_S:
7747 check_cp1_64bitmode(ctx);
7749 TCGv_i32 fp0 = tcg_temp_new_i32();
7751 gen_load_fpr32(fp0, fs);
7752 gen_helper_float_recip1_s(fp0, cpu_env, fp0);
7753 gen_store_fpr32(fp0, fd);
7754 tcg_temp_free_i32(fp0);
7756 opn = "recip1.s";
7757 break;
7758 case OPC_RSQRT1_S:
7759 check_cp1_64bitmode(ctx);
7761 TCGv_i32 fp0 = tcg_temp_new_i32();
7763 gen_load_fpr32(fp0, fs);
7764 gen_helper_float_rsqrt1_s(fp0, cpu_env, fp0);
7765 gen_store_fpr32(fp0, fd);
7766 tcg_temp_free_i32(fp0);
7768 opn = "rsqrt1.s";
7769 break;
7770 case OPC_RSQRT2_S:
7771 check_cp1_64bitmode(ctx);
7773 TCGv_i32 fp0 = tcg_temp_new_i32();
7774 TCGv_i32 fp1 = tcg_temp_new_i32();
7776 gen_load_fpr32(fp0, fs);
7777 gen_load_fpr32(fp1, ft);
7778 gen_helper_float_rsqrt2_s(fp0, cpu_env, fp0, fp1);
7779 tcg_temp_free_i32(fp1);
7780 gen_store_fpr32(fp0, fd);
7781 tcg_temp_free_i32(fp0);
7783 opn = "rsqrt2.s";
7784 break;
7785 case OPC_CVT_D_S:
7786 check_cp1_registers(ctx, fd);
7788 TCGv_i32 fp32 = tcg_temp_new_i32();
7789 TCGv_i64 fp64 = tcg_temp_new_i64();
7791 gen_load_fpr32(fp32, fs);
7792 gen_helper_float_cvtd_s(fp64, cpu_env, fp32);
7793 tcg_temp_free_i32(fp32);
7794 gen_store_fpr64(ctx, fp64, fd);
7795 tcg_temp_free_i64(fp64);
7797 opn = "cvt.d.s";
7798 break;
7799 case OPC_CVT_W_S:
7801 TCGv_i32 fp0 = tcg_temp_new_i32();
7803 gen_load_fpr32(fp0, fs);
7804 gen_helper_float_cvtw_s(fp0, cpu_env, fp0);
7805 gen_store_fpr32(fp0, fd);
7806 tcg_temp_free_i32(fp0);
7808 opn = "cvt.w.s";
7809 break;
7810 case OPC_CVT_L_S:
7811 check_cp1_64bitmode(ctx);
7813 TCGv_i32 fp32 = tcg_temp_new_i32();
7814 TCGv_i64 fp64 = tcg_temp_new_i64();
7816 gen_load_fpr32(fp32, fs);
7817 gen_helper_float_cvtl_s(fp64, cpu_env, fp32);
7818 tcg_temp_free_i32(fp32);
7819 gen_store_fpr64(ctx, fp64, fd);
7820 tcg_temp_free_i64(fp64);
7822 opn = "cvt.l.s";
7823 break;
7824 case OPC_CVT_PS_S:
7825 check_cp1_64bitmode(ctx);
7827 TCGv_i64 fp64 = tcg_temp_new_i64();
7828 TCGv_i32 fp32_0 = tcg_temp_new_i32();
7829 TCGv_i32 fp32_1 = tcg_temp_new_i32();
7831 gen_load_fpr32(fp32_0, fs);
7832 gen_load_fpr32(fp32_1, ft);
7833 tcg_gen_concat_i32_i64(fp64, fp32_1, fp32_0);
7834 tcg_temp_free_i32(fp32_1);
7835 tcg_temp_free_i32(fp32_0);
7836 gen_store_fpr64(ctx, fp64, fd);
7837 tcg_temp_free_i64(fp64);
7839 opn = "cvt.ps.s";
7840 break;
7841 case OPC_CMP_F_S:
7842 case OPC_CMP_UN_S:
7843 case OPC_CMP_EQ_S:
7844 case OPC_CMP_UEQ_S:
7845 case OPC_CMP_OLT_S:
7846 case OPC_CMP_ULT_S:
7847 case OPC_CMP_OLE_S:
7848 case OPC_CMP_ULE_S:
7849 case OPC_CMP_SF_S:
7850 case OPC_CMP_NGLE_S:
7851 case OPC_CMP_SEQ_S:
7852 case OPC_CMP_NGL_S:
7853 case OPC_CMP_LT_S:
7854 case OPC_CMP_NGE_S:
7855 case OPC_CMP_LE_S:
7856 case OPC_CMP_NGT_S:
7857 if (ctx->opcode & (1 << 6)) {
7858 gen_cmpabs_s(ctx, func-48, ft, fs, cc);
7859 opn = condnames_abs[func-48];
7860 } else {
7861 gen_cmp_s(ctx, func-48, ft, fs, cc);
7862 opn = condnames[func-48];
7864 break;
7865 case OPC_ADD_D:
7866 check_cp1_registers(ctx, fs | ft | fd);
7868 TCGv_i64 fp0 = tcg_temp_new_i64();
7869 TCGv_i64 fp1 = tcg_temp_new_i64();
7871 gen_load_fpr64(ctx, fp0, fs);
7872 gen_load_fpr64(ctx, fp1, ft);
7873 gen_helper_float_add_d(fp0, cpu_env, fp0, fp1);
7874 tcg_temp_free_i64(fp1);
7875 gen_store_fpr64(ctx, fp0, fd);
7876 tcg_temp_free_i64(fp0);
7878 opn = "add.d";
7879 optype = BINOP;
7880 break;
7881 case OPC_SUB_D:
7882 check_cp1_registers(ctx, fs | ft | fd);
7884 TCGv_i64 fp0 = tcg_temp_new_i64();
7885 TCGv_i64 fp1 = tcg_temp_new_i64();
7887 gen_load_fpr64(ctx, fp0, fs);
7888 gen_load_fpr64(ctx, fp1, ft);
7889 gen_helper_float_sub_d(fp0, cpu_env, fp0, fp1);
7890 tcg_temp_free_i64(fp1);
7891 gen_store_fpr64(ctx, fp0, fd);
7892 tcg_temp_free_i64(fp0);
7894 opn = "sub.d";
7895 optype = BINOP;
7896 break;
7897 case OPC_MUL_D:
7898 check_cp1_registers(ctx, fs | ft | fd);
7900 TCGv_i64 fp0 = tcg_temp_new_i64();
7901 TCGv_i64 fp1 = tcg_temp_new_i64();
7903 gen_load_fpr64(ctx, fp0, fs);
7904 gen_load_fpr64(ctx, fp1, ft);
7905 gen_helper_float_mul_d(fp0, cpu_env, fp0, fp1);
7906 tcg_temp_free_i64(fp1);
7907 gen_store_fpr64(ctx, fp0, fd);
7908 tcg_temp_free_i64(fp0);
7910 opn = "mul.d";
7911 optype = BINOP;
7912 break;
7913 case OPC_DIV_D:
7914 check_cp1_registers(ctx, fs | ft | fd);
7916 TCGv_i64 fp0 = tcg_temp_new_i64();
7917 TCGv_i64 fp1 = tcg_temp_new_i64();
7919 gen_load_fpr64(ctx, fp0, fs);
7920 gen_load_fpr64(ctx, fp1, ft);
7921 gen_helper_float_div_d(fp0, cpu_env, fp0, fp1);
7922 tcg_temp_free_i64(fp1);
7923 gen_store_fpr64(ctx, fp0, fd);
7924 tcg_temp_free_i64(fp0);
7926 opn = "div.d";
7927 optype = BINOP;
7928 break;
7929 case OPC_SQRT_D:
7930 check_cp1_registers(ctx, fs | fd);
7932 TCGv_i64 fp0 = tcg_temp_new_i64();
7934 gen_load_fpr64(ctx, fp0, fs);
7935 gen_helper_float_sqrt_d(fp0, cpu_env, fp0);
7936 gen_store_fpr64(ctx, fp0, fd);
7937 tcg_temp_free_i64(fp0);
7939 opn = "sqrt.d";
7940 break;
7941 case OPC_ABS_D:
7942 check_cp1_registers(ctx, fs | fd);
7944 TCGv_i64 fp0 = tcg_temp_new_i64();
7946 gen_load_fpr64(ctx, fp0, fs);
7947 gen_helper_float_abs_d(fp0, fp0);
7948 gen_store_fpr64(ctx, fp0, fd);
7949 tcg_temp_free_i64(fp0);
7951 opn = "abs.d";
7952 break;
7953 case OPC_MOV_D:
7954 check_cp1_registers(ctx, fs | fd);
7956 TCGv_i64 fp0 = tcg_temp_new_i64();
7958 gen_load_fpr64(ctx, fp0, fs);
7959 gen_store_fpr64(ctx, fp0, fd);
7960 tcg_temp_free_i64(fp0);
7962 opn = "mov.d";
7963 break;
7964 case OPC_NEG_D:
7965 check_cp1_registers(ctx, fs | fd);
7967 TCGv_i64 fp0 = tcg_temp_new_i64();
7969 gen_load_fpr64(ctx, fp0, fs);
7970 gen_helper_float_chs_d(fp0, fp0);
7971 gen_store_fpr64(ctx, fp0, fd);
7972 tcg_temp_free_i64(fp0);
7974 opn = "neg.d";
7975 break;
7976 case OPC_ROUND_L_D:
7977 check_cp1_64bitmode(ctx);
7979 TCGv_i64 fp0 = tcg_temp_new_i64();
7981 gen_load_fpr64(ctx, fp0, fs);
7982 gen_helper_float_roundl_d(fp0, cpu_env, fp0);
7983 gen_store_fpr64(ctx, fp0, fd);
7984 tcg_temp_free_i64(fp0);
7986 opn = "round.l.d";
7987 break;
7988 case OPC_TRUNC_L_D:
7989 check_cp1_64bitmode(ctx);
7991 TCGv_i64 fp0 = tcg_temp_new_i64();
7993 gen_load_fpr64(ctx, fp0, fs);
7994 gen_helper_float_truncl_d(fp0, cpu_env, fp0);
7995 gen_store_fpr64(ctx, fp0, fd);
7996 tcg_temp_free_i64(fp0);
7998 opn = "trunc.l.d";
7999 break;
8000 case OPC_CEIL_L_D:
8001 check_cp1_64bitmode(ctx);
8003 TCGv_i64 fp0 = tcg_temp_new_i64();
8005 gen_load_fpr64(ctx, fp0, fs);
8006 gen_helper_float_ceill_d(fp0, cpu_env, fp0);
8007 gen_store_fpr64(ctx, fp0, fd);
8008 tcg_temp_free_i64(fp0);
8010 opn = "ceil.l.d";
8011 break;
8012 case OPC_FLOOR_L_D:
8013 check_cp1_64bitmode(ctx);
8015 TCGv_i64 fp0 = tcg_temp_new_i64();
8017 gen_load_fpr64(ctx, fp0, fs);
8018 gen_helper_float_floorl_d(fp0, cpu_env, fp0);
8019 gen_store_fpr64(ctx, fp0, fd);
8020 tcg_temp_free_i64(fp0);
8022 opn = "floor.l.d";
8023 break;
8024 case OPC_ROUND_W_D:
8025 check_cp1_registers(ctx, fs);
8027 TCGv_i32 fp32 = tcg_temp_new_i32();
8028 TCGv_i64 fp64 = tcg_temp_new_i64();
8030 gen_load_fpr64(ctx, fp64, fs);
8031 gen_helper_float_roundw_d(fp32, cpu_env, fp64);
8032 tcg_temp_free_i64(fp64);
8033 gen_store_fpr32(fp32, fd);
8034 tcg_temp_free_i32(fp32);
8036 opn = "round.w.d";
8037 break;
8038 case OPC_TRUNC_W_D:
8039 check_cp1_registers(ctx, fs);
8041 TCGv_i32 fp32 = tcg_temp_new_i32();
8042 TCGv_i64 fp64 = tcg_temp_new_i64();
8044 gen_load_fpr64(ctx, fp64, fs);
8045 gen_helper_float_truncw_d(fp32, cpu_env, fp64);
8046 tcg_temp_free_i64(fp64);
8047 gen_store_fpr32(fp32, fd);
8048 tcg_temp_free_i32(fp32);
8050 opn = "trunc.w.d";
8051 break;
8052 case OPC_CEIL_W_D:
8053 check_cp1_registers(ctx, fs);
8055 TCGv_i32 fp32 = tcg_temp_new_i32();
8056 TCGv_i64 fp64 = tcg_temp_new_i64();
8058 gen_load_fpr64(ctx, fp64, fs);
8059 gen_helper_float_ceilw_d(fp32, cpu_env, fp64);
8060 tcg_temp_free_i64(fp64);
8061 gen_store_fpr32(fp32, fd);
8062 tcg_temp_free_i32(fp32);
8064 opn = "ceil.w.d";
8065 break;
8066 case OPC_FLOOR_W_D:
8067 check_cp1_registers(ctx, fs);
8069 TCGv_i32 fp32 = tcg_temp_new_i32();
8070 TCGv_i64 fp64 = tcg_temp_new_i64();
8072 gen_load_fpr64(ctx, fp64, fs);
8073 gen_helper_float_floorw_d(fp32, cpu_env, fp64);
8074 tcg_temp_free_i64(fp64);
8075 gen_store_fpr32(fp32, fd);
8076 tcg_temp_free_i32(fp32);
8078 opn = "floor.w.d";
8079 break;
8080 case OPC_MOVCF_D:
8081 gen_movcf_d(ctx, fs, fd, (ft >> 2) & 0x7, ft & 0x1);
8082 opn = "movcf.d";
8083 break;
8084 case OPC_MOVZ_D:
8086 int l1 = gen_new_label();
8087 TCGv_i64 fp0;
8089 if (ft != 0) {
8090 tcg_gen_brcondi_tl(TCG_COND_NE, cpu_gpr[ft], 0, l1);
8092 fp0 = tcg_temp_new_i64();
8093 gen_load_fpr64(ctx, fp0, fs);
8094 gen_store_fpr64(ctx, fp0, fd);
8095 tcg_temp_free_i64(fp0);
8096 gen_set_label(l1);
8098 opn = "movz.d";
8099 break;
8100 case OPC_MOVN_D:
8102 int l1 = gen_new_label();
8103 TCGv_i64 fp0;
8105 if (ft != 0) {
8106 tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_gpr[ft], 0, l1);
8107 fp0 = tcg_temp_new_i64();
8108 gen_load_fpr64(ctx, fp0, fs);
8109 gen_store_fpr64(ctx, fp0, fd);
8110 tcg_temp_free_i64(fp0);
8111 gen_set_label(l1);
8114 opn = "movn.d";
8115 break;
8116 case OPC_RECIP_D:
8117 check_cp1_64bitmode(ctx);
8119 TCGv_i64 fp0 = tcg_temp_new_i64();
8121 gen_load_fpr64(ctx, fp0, fs);
8122 gen_helper_float_recip_d(fp0, cpu_env, fp0);
8123 gen_store_fpr64(ctx, fp0, fd);
8124 tcg_temp_free_i64(fp0);
8126 opn = "recip.d";
8127 break;
8128 case OPC_RSQRT_D:
8129 check_cp1_64bitmode(ctx);
8131 TCGv_i64 fp0 = tcg_temp_new_i64();
8133 gen_load_fpr64(ctx, fp0, fs);
8134 gen_helper_float_rsqrt_d(fp0, cpu_env, fp0);
8135 gen_store_fpr64(ctx, fp0, fd);
8136 tcg_temp_free_i64(fp0);
8138 opn = "rsqrt.d";
8139 break;
8140 case OPC_RECIP2_D:
8141 check_cp1_64bitmode(ctx);
8143 TCGv_i64 fp0 = tcg_temp_new_i64();
8144 TCGv_i64 fp1 = tcg_temp_new_i64();
8146 gen_load_fpr64(ctx, fp0, fs);
8147 gen_load_fpr64(ctx, fp1, ft);
8148 gen_helper_float_recip2_d(fp0, cpu_env, fp0, fp1);
8149 tcg_temp_free_i64(fp1);
8150 gen_store_fpr64(ctx, fp0, fd);
8151 tcg_temp_free_i64(fp0);
8153 opn = "recip2.d";
8154 break;
8155 case OPC_RECIP1_D:
8156 check_cp1_64bitmode(ctx);
8158 TCGv_i64 fp0 = tcg_temp_new_i64();
8160 gen_load_fpr64(ctx, fp0, fs);
8161 gen_helper_float_recip1_d(fp0, cpu_env, fp0);
8162 gen_store_fpr64(ctx, fp0, fd);
8163 tcg_temp_free_i64(fp0);
8165 opn = "recip1.d";
8166 break;
8167 case OPC_RSQRT1_D:
8168 check_cp1_64bitmode(ctx);
8170 TCGv_i64 fp0 = tcg_temp_new_i64();
8172 gen_load_fpr64(ctx, fp0, fs);
8173 gen_helper_float_rsqrt1_d(fp0, cpu_env, fp0);
8174 gen_store_fpr64(ctx, fp0, fd);
8175 tcg_temp_free_i64(fp0);
8177 opn = "rsqrt1.d";
8178 break;
8179 case OPC_RSQRT2_D:
8180 check_cp1_64bitmode(ctx);
8182 TCGv_i64 fp0 = tcg_temp_new_i64();
8183 TCGv_i64 fp1 = tcg_temp_new_i64();
8185 gen_load_fpr64(ctx, fp0, fs);
8186 gen_load_fpr64(ctx, fp1, ft);
8187 gen_helper_float_rsqrt2_d(fp0, cpu_env, fp0, fp1);
8188 tcg_temp_free_i64(fp1);
8189 gen_store_fpr64(ctx, fp0, fd);
8190 tcg_temp_free_i64(fp0);
8192 opn = "rsqrt2.d";
8193 break;
8194 case OPC_CMP_F_D:
8195 case OPC_CMP_UN_D:
8196 case OPC_CMP_EQ_D:
8197 case OPC_CMP_UEQ_D:
8198 case OPC_CMP_OLT_D:
8199 case OPC_CMP_ULT_D:
8200 case OPC_CMP_OLE_D:
8201 case OPC_CMP_ULE_D:
8202 case OPC_CMP_SF_D:
8203 case OPC_CMP_NGLE_D:
8204 case OPC_CMP_SEQ_D:
8205 case OPC_CMP_NGL_D:
8206 case OPC_CMP_LT_D:
8207 case OPC_CMP_NGE_D:
8208 case OPC_CMP_LE_D:
8209 case OPC_CMP_NGT_D:
8210 if (ctx->opcode & (1 << 6)) {
8211 gen_cmpabs_d(ctx, func-48, ft, fs, cc);
8212 opn = condnames_abs[func-48];
8213 } else {
8214 gen_cmp_d(ctx, func-48, ft, fs, cc);
8215 opn = condnames[func-48];
8217 break;
8218 case OPC_CVT_S_D:
8219 check_cp1_registers(ctx, fs);
8221 TCGv_i32 fp32 = tcg_temp_new_i32();
8222 TCGv_i64 fp64 = tcg_temp_new_i64();
8224 gen_load_fpr64(ctx, fp64, fs);
8225 gen_helper_float_cvts_d(fp32, cpu_env, fp64);
8226 tcg_temp_free_i64(fp64);
8227 gen_store_fpr32(fp32, fd);
8228 tcg_temp_free_i32(fp32);
8230 opn = "cvt.s.d";
8231 break;
8232 case OPC_CVT_W_D:
8233 check_cp1_registers(ctx, fs);
8235 TCGv_i32 fp32 = tcg_temp_new_i32();
8236 TCGv_i64 fp64 = tcg_temp_new_i64();
8238 gen_load_fpr64(ctx, fp64, fs);
8239 gen_helper_float_cvtw_d(fp32, cpu_env, fp64);
8240 tcg_temp_free_i64(fp64);
8241 gen_store_fpr32(fp32, fd);
8242 tcg_temp_free_i32(fp32);
8244 opn = "cvt.w.d";
8245 break;
8246 case OPC_CVT_L_D:
8247 check_cp1_64bitmode(ctx);
8249 TCGv_i64 fp0 = tcg_temp_new_i64();
8251 gen_load_fpr64(ctx, fp0, fs);
8252 gen_helper_float_cvtl_d(fp0, cpu_env, fp0);
8253 gen_store_fpr64(ctx, fp0, fd);
8254 tcg_temp_free_i64(fp0);
8256 opn = "cvt.l.d";
8257 break;
8258 case OPC_CVT_S_W:
8260 TCGv_i32 fp0 = tcg_temp_new_i32();
8262 gen_load_fpr32(fp0, fs);
8263 gen_helper_float_cvts_w(fp0, cpu_env, fp0);
8264 gen_store_fpr32(fp0, fd);
8265 tcg_temp_free_i32(fp0);
8267 opn = "cvt.s.w";
8268 break;
8269 case OPC_CVT_D_W:
8270 check_cp1_registers(ctx, fd);
8272 TCGv_i32 fp32 = tcg_temp_new_i32();
8273 TCGv_i64 fp64 = tcg_temp_new_i64();
8275 gen_load_fpr32(fp32, fs);
8276 gen_helper_float_cvtd_w(fp64, cpu_env, fp32);
8277 tcg_temp_free_i32(fp32);
8278 gen_store_fpr64(ctx, fp64, fd);
8279 tcg_temp_free_i64(fp64);
8281 opn = "cvt.d.w";
8282 break;
8283 case OPC_CVT_S_L:
8284 check_cp1_64bitmode(ctx);
8286 TCGv_i32 fp32 = tcg_temp_new_i32();
8287 TCGv_i64 fp64 = tcg_temp_new_i64();
8289 gen_load_fpr64(ctx, fp64, fs);
8290 gen_helper_float_cvts_l(fp32, cpu_env, fp64);
8291 tcg_temp_free_i64(fp64);
8292 gen_store_fpr32(fp32, fd);
8293 tcg_temp_free_i32(fp32);
8295 opn = "cvt.s.l";
8296 break;
8297 case OPC_CVT_D_L:
8298 check_cp1_64bitmode(ctx);
8300 TCGv_i64 fp0 = tcg_temp_new_i64();
8302 gen_load_fpr64(ctx, fp0, fs);
8303 gen_helper_float_cvtd_l(fp0, cpu_env, fp0);
8304 gen_store_fpr64(ctx, fp0, fd);
8305 tcg_temp_free_i64(fp0);
8307 opn = "cvt.d.l";
8308 break;
8309 case OPC_CVT_PS_PW:
8310 check_cp1_64bitmode(ctx);
8312 TCGv_i64 fp0 = tcg_temp_new_i64();
8314 gen_load_fpr64(ctx, fp0, fs);
8315 gen_helper_float_cvtps_pw(fp0, cpu_env, fp0);
8316 gen_store_fpr64(ctx, fp0, fd);
8317 tcg_temp_free_i64(fp0);
8319 opn = "cvt.ps.pw";
8320 break;
8321 case OPC_ADD_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_add_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 = "add.ps";
8335 break;
8336 case OPC_SUB_PS:
8337 check_cp1_64bitmode(ctx);
8339 TCGv_i64 fp0 = tcg_temp_new_i64();
8340 TCGv_i64 fp1 = tcg_temp_new_i64();
8342 gen_load_fpr64(ctx, fp0, fs);
8343 gen_load_fpr64(ctx, fp1, ft);
8344 gen_helper_float_sub_ps(fp0, cpu_env, fp0, fp1);
8345 tcg_temp_free_i64(fp1);
8346 gen_store_fpr64(ctx, fp0, fd);
8347 tcg_temp_free_i64(fp0);
8349 opn = "sub.ps";
8350 break;
8351 case OPC_MUL_PS:
8352 check_cp1_64bitmode(ctx);
8354 TCGv_i64 fp0 = tcg_temp_new_i64();
8355 TCGv_i64 fp1 = tcg_temp_new_i64();
8357 gen_load_fpr64(ctx, fp0, fs);
8358 gen_load_fpr64(ctx, fp1, ft);
8359 gen_helper_float_mul_ps(fp0, cpu_env, fp0, fp1);
8360 tcg_temp_free_i64(fp1);
8361 gen_store_fpr64(ctx, fp0, fd);
8362 tcg_temp_free_i64(fp0);
8364 opn = "mul.ps";
8365 break;
8366 case OPC_ABS_PS:
8367 check_cp1_64bitmode(ctx);
8369 TCGv_i64 fp0 = tcg_temp_new_i64();
8371 gen_load_fpr64(ctx, fp0, fs);
8372 gen_helper_float_abs_ps(fp0, fp0);
8373 gen_store_fpr64(ctx, fp0, fd);
8374 tcg_temp_free_i64(fp0);
8376 opn = "abs.ps";
8377 break;
8378 case OPC_MOV_PS:
8379 check_cp1_64bitmode(ctx);
8381 TCGv_i64 fp0 = tcg_temp_new_i64();
8383 gen_load_fpr64(ctx, fp0, fs);
8384 gen_store_fpr64(ctx, fp0, fd);
8385 tcg_temp_free_i64(fp0);
8387 opn = "mov.ps";
8388 break;
8389 case OPC_NEG_PS:
8390 check_cp1_64bitmode(ctx);
8392 TCGv_i64 fp0 = tcg_temp_new_i64();
8394 gen_load_fpr64(ctx, fp0, fs);
8395 gen_helper_float_chs_ps(fp0, fp0);
8396 gen_store_fpr64(ctx, fp0, fd);
8397 tcg_temp_free_i64(fp0);
8399 opn = "neg.ps";
8400 break;
8401 case OPC_MOVCF_PS:
8402 check_cp1_64bitmode(ctx);
8403 gen_movcf_ps(fs, fd, (ft >> 2) & 0x7, ft & 0x1);
8404 opn = "movcf.ps";
8405 break;
8406 case OPC_MOVZ_PS:
8407 check_cp1_64bitmode(ctx);
8409 int l1 = gen_new_label();
8410 TCGv_i64 fp0;
8412 if (ft != 0)
8413 tcg_gen_brcondi_tl(TCG_COND_NE, cpu_gpr[ft], 0, l1);
8414 fp0 = tcg_temp_new_i64();
8415 gen_load_fpr64(ctx, fp0, fs);
8416 gen_store_fpr64(ctx, fp0, fd);
8417 tcg_temp_free_i64(fp0);
8418 gen_set_label(l1);
8420 opn = "movz.ps";
8421 break;
8422 case OPC_MOVN_PS:
8423 check_cp1_64bitmode(ctx);
8425 int l1 = gen_new_label();
8426 TCGv_i64 fp0;
8428 if (ft != 0) {
8429 tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_gpr[ft], 0, l1);
8430 fp0 = tcg_temp_new_i64();
8431 gen_load_fpr64(ctx, fp0, fs);
8432 gen_store_fpr64(ctx, fp0, fd);
8433 tcg_temp_free_i64(fp0);
8434 gen_set_label(l1);
8437 opn = "movn.ps";
8438 break;
8439 case OPC_ADDR_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, ft);
8446 gen_load_fpr64(ctx, fp1, fs);
8447 gen_helper_float_addr_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 = "addr.ps";
8453 break;
8454 case OPC_MULR_PS:
8455 check_cp1_64bitmode(ctx);
8457 TCGv_i64 fp0 = tcg_temp_new_i64();
8458 TCGv_i64 fp1 = tcg_temp_new_i64();
8460 gen_load_fpr64(ctx, fp0, ft);
8461 gen_load_fpr64(ctx, fp1, fs);
8462 gen_helper_float_mulr_ps(fp0, cpu_env, fp0, fp1);
8463 tcg_temp_free_i64(fp1);
8464 gen_store_fpr64(ctx, fp0, fd);
8465 tcg_temp_free_i64(fp0);
8467 opn = "mulr.ps";
8468 break;
8469 case OPC_RECIP2_PS:
8470 check_cp1_64bitmode(ctx);
8472 TCGv_i64 fp0 = tcg_temp_new_i64();
8473 TCGv_i64 fp1 = tcg_temp_new_i64();
8475 gen_load_fpr64(ctx, fp0, fs);
8476 gen_load_fpr64(ctx, fp1, ft);
8477 gen_helper_float_recip2_ps(fp0, cpu_env, fp0, fp1);
8478 tcg_temp_free_i64(fp1);
8479 gen_store_fpr64(ctx, fp0, fd);
8480 tcg_temp_free_i64(fp0);
8482 opn = "recip2.ps";
8483 break;
8484 case OPC_RECIP1_PS:
8485 check_cp1_64bitmode(ctx);
8487 TCGv_i64 fp0 = tcg_temp_new_i64();
8489 gen_load_fpr64(ctx, fp0, fs);
8490 gen_helper_float_recip1_ps(fp0, cpu_env, fp0);
8491 gen_store_fpr64(ctx, fp0, fd);
8492 tcg_temp_free_i64(fp0);
8494 opn = "recip1.ps";
8495 break;
8496 case OPC_RSQRT1_PS:
8497 check_cp1_64bitmode(ctx);
8499 TCGv_i64 fp0 = tcg_temp_new_i64();
8501 gen_load_fpr64(ctx, fp0, fs);
8502 gen_helper_float_rsqrt1_ps(fp0, cpu_env, fp0);
8503 gen_store_fpr64(ctx, fp0, fd);
8504 tcg_temp_free_i64(fp0);
8506 opn = "rsqrt1.ps";
8507 break;
8508 case OPC_RSQRT2_PS:
8509 check_cp1_64bitmode(ctx);
8511 TCGv_i64 fp0 = tcg_temp_new_i64();
8512 TCGv_i64 fp1 = tcg_temp_new_i64();
8514 gen_load_fpr64(ctx, fp0, fs);
8515 gen_load_fpr64(ctx, fp1, ft);
8516 gen_helper_float_rsqrt2_ps(fp0, cpu_env, fp0, fp1);
8517 tcg_temp_free_i64(fp1);
8518 gen_store_fpr64(ctx, fp0, fd);
8519 tcg_temp_free_i64(fp0);
8521 opn = "rsqrt2.ps";
8522 break;
8523 case OPC_CVT_S_PU:
8524 check_cp1_64bitmode(ctx);
8526 TCGv_i32 fp0 = tcg_temp_new_i32();
8528 gen_load_fpr32h(fp0, fs);
8529 gen_helper_float_cvts_pu(fp0, cpu_env, fp0);
8530 gen_store_fpr32(fp0, fd);
8531 tcg_temp_free_i32(fp0);
8533 opn = "cvt.s.pu";
8534 break;
8535 case OPC_CVT_PW_PS:
8536 check_cp1_64bitmode(ctx);
8538 TCGv_i64 fp0 = tcg_temp_new_i64();
8540 gen_load_fpr64(ctx, fp0, fs);
8541 gen_helper_float_cvtpw_ps(fp0, cpu_env, fp0);
8542 gen_store_fpr64(ctx, fp0, fd);
8543 tcg_temp_free_i64(fp0);
8545 opn = "cvt.pw.ps";
8546 break;
8547 case OPC_CVT_S_PL:
8548 check_cp1_64bitmode(ctx);
8550 TCGv_i32 fp0 = tcg_temp_new_i32();
8552 gen_load_fpr32(fp0, fs);
8553 gen_helper_float_cvts_pl(fp0, cpu_env, fp0);
8554 gen_store_fpr32(fp0, fd);
8555 tcg_temp_free_i32(fp0);
8557 opn = "cvt.s.pl";
8558 break;
8559 case OPC_PLL_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_fpr32(fp0, fs);
8566 gen_load_fpr32(fp1, ft);
8567 gen_store_fpr32h(fp0, fd);
8568 gen_store_fpr32(fp1, fd);
8569 tcg_temp_free_i32(fp0);
8570 tcg_temp_free_i32(fp1);
8572 opn = "pll.ps";
8573 break;
8574 case OPC_PLU_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_fpr32(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 = "plu.ps";
8588 break;
8589 case OPC_PUL_PS:
8590 check_cp1_64bitmode(ctx);
8592 TCGv_i32 fp0 = tcg_temp_new_i32();
8593 TCGv_i32 fp1 = tcg_temp_new_i32();
8595 gen_load_fpr32h(fp0, fs);
8596 gen_load_fpr32(fp1, ft);
8597 gen_store_fpr32(fp1, fd);
8598 gen_store_fpr32h(fp0, fd);
8599 tcg_temp_free_i32(fp0);
8600 tcg_temp_free_i32(fp1);
8602 opn = "pul.ps";
8603 break;
8604 case OPC_PUU_PS:
8605 check_cp1_64bitmode(ctx);
8607 TCGv_i32 fp0 = tcg_temp_new_i32();
8608 TCGv_i32 fp1 = tcg_temp_new_i32();
8610 gen_load_fpr32h(fp0, fs);
8611 gen_load_fpr32h(fp1, ft);
8612 gen_store_fpr32(fp1, fd);
8613 gen_store_fpr32h(fp0, fd);
8614 tcg_temp_free_i32(fp0);
8615 tcg_temp_free_i32(fp1);
8617 opn = "puu.ps";
8618 break;
8619 case OPC_CMP_F_PS:
8620 case OPC_CMP_UN_PS:
8621 case OPC_CMP_EQ_PS:
8622 case OPC_CMP_UEQ_PS:
8623 case OPC_CMP_OLT_PS:
8624 case OPC_CMP_ULT_PS:
8625 case OPC_CMP_OLE_PS:
8626 case OPC_CMP_ULE_PS:
8627 case OPC_CMP_SF_PS:
8628 case OPC_CMP_NGLE_PS:
8629 case OPC_CMP_SEQ_PS:
8630 case OPC_CMP_NGL_PS:
8631 case OPC_CMP_LT_PS:
8632 case OPC_CMP_NGE_PS:
8633 case OPC_CMP_LE_PS:
8634 case OPC_CMP_NGT_PS:
8635 if (ctx->opcode & (1 << 6)) {
8636 gen_cmpabs_ps(ctx, func-48, ft, fs, cc);
8637 opn = condnames_abs[func-48];
8638 } else {
8639 gen_cmp_ps(ctx, func-48, ft, fs, cc);
8640 opn = condnames[func-48];
8642 break;
8643 default:
8644 MIPS_INVAL(opn);
8645 generate_exception (ctx, EXCP_RI);
8646 return;
8648 (void)opn; /* avoid a compiler warning */
8649 switch (optype) {
8650 case BINOP:
8651 MIPS_DEBUG("%s %s, %s, %s", opn, fregnames[fd], fregnames[fs], fregnames[ft]);
8652 break;
8653 case CMPOP:
8654 MIPS_DEBUG("%s %s,%s", opn, fregnames[fs], fregnames[ft]);
8655 break;
8656 default:
8657 MIPS_DEBUG("%s %s,%s", opn, fregnames[fd], fregnames[fs]);
8658 break;
8662 /* Coprocessor 3 (FPU) */
8663 static void gen_flt3_ldst (DisasContext *ctx, uint32_t opc,
8664 int fd, int fs, int base, int index)
8666 const char *opn = "extended float load/store";
8667 int store = 0;
8668 TCGv t0 = tcg_temp_new();
8670 if (base == 0) {
8671 gen_load_gpr(t0, index);
8672 } else if (index == 0) {
8673 gen_load_gpr(t0, base);
8674 } else {
8675 gen_op_addr_add(ctx, t0, cpu_gpr[base], cpu_gpr[index]);
8677 /* Don't do NOP if destination is zero: we must perform the actual
8678 memory access. */
8679 switch (opc) {
8680 case OPC_LWXC1:
8681 check_cop1x(ctx);
8683 TCGv_i32 fp0 = tcg_temp_new_i32();
8685 tcg_gen_qemu_ld32s(t0, t0, ctx->mem_idx);
8686 tcg_gen_trunc_tl_i32(fp0, t0);
8687 gen_store_fpr32(fp0, fd);
8688 tcg_temp_free_i32(fp0);
8690 opn = "lwxc1";
8691 break;
8692 case OPC_LDXC1:
8693 check_cop1x(ctx);
8694 check_cp1_registers(ctx, fd);
8696 TCGv_i64 fp0 = tcg_temp_new_i64();
8698 tcg_gen_qemu_ld64(fp0, t0, ctx->mem_idx);
8699 gen_store_fpr64(ctx, fp0, fd);
8700 tcg_temp_free_i64(fp0);
8702 opn = "ldxc1";
8703 break;
8704 case OPC_LUXC1:
8705 check_cp1_64bitmode(ctx);
8706 tcg_gen_andi_tl(t0, t0, ~0x7);
8708 TCGv_i64 fp0 = tcg_temp_new_i64();
8710 tcg_gen_qemu_ld64(fp0, t0, ctx->mem_idx);
8711 gen_store_fpr64(ctx, fp0, fd);
8712 tcg_temp_free_i64(fp0);
8714 opn = "luxc1";
8715 break;
8716 case OPC_SWXC1:
8717 check_cop1x(ctx);
8719 TCGv_i32 fp0 = tcg_temp_new_i32();
8720 TCGv t1 = tcg_temp_new();
8722 gen_load_fpr32(fp0, fs);
8723 tcg_gen_extu_i32_tl(t1, fp0);
8724 tcg_gen_qemu_st32(t1, t0, ctx->mem_idx);
8725 tcg_temp_free_i32(fp0);
8726 tcg_temp_free(t1);
8728 opn = "swxc1";
8729 store = 1;
8730 break;
8731 case OPC_SDXC1:
8732 check_cop1x(ctx);
8733 check_cp1_registers(ctx, fs);
8735 TCGv_i64 fp0 = tcg_temp_new_i64();
8737 gen_load_fpr64(ctx, fp0, fs);
8738 tcg_gen_qemu_st64(fp0, t0, ctx->mem_idx);
8739 tcg_temp_free_i64(fp0);
8741 opn = "sdxc1";
8742 store = 1;
8743 break;
8744 case OPC_SUXC1:
8745 check_cp1_64bitmode(ctx);
8746 tcg_gen_andi_tl(t0, t0, ~0x7);
8748 TCGv_i64 fp0 = tcg_temp_new_i64();
8750 gen_load_fpr64(ctx, fp0, fs);
8751 tcg_gen_qemu_st64(fp0, t0, ctx->mem_idx);
8752 tcg_temp_free_i64(fp0);
8754 opn = "suxc1";
8755 store = 1;
8756 break;
8758 tcg_temp_free(t0);
8759 (void)opn; (void)store; /* avoid compiler warnings */
8760 MIPS_DEBUG("%s %s, %s(%s)", opn, fregnames[store ? fs : fd],
8761 regnames[index], regnames[base]);
8764 static void gen_flt3_arith (DisasContext *ctx, uint32_t opc,
8765 int fd, int fr, int fs, int ft)
8767 const char *opn = "flt3_arith";
8769 switch (opc) {
8770 case OPC_ALNV_PS:
8771 check_cp1_64bitmode(ctx);
8773 TCGv t0 = tcg_temp_local_new();
8774 TCGv_i32 fp = tcg_temp_new_i32();
8775 TCGv_i32 fph = tcg_temp_new_i32();
8776 int l1 = gen_new_label();
8777 int l2 = gen_new_label();
8779 gen_load_gpr(t0, fr);
8780 tcg_gen_andi_tl(t0, t0, 0x7);
8782 tcg_gen_brcondi_tl(TCG_COND_NE, t0, 0, l1);
8783 gen_load_fpr32(fp, fs);
8784 gen_load_fpr32h(fph, fs);
8785 gen_store_fpr32(fp, fd);
8786 gen_store_fpr32h(fph, fd);
8787 tcg_gen_br(l2);
8788 gen_set_label(l1);
8789 tcg_gen_brcondi_tl(TCG_COND_NE, t0, 4, l2);
8790 tcg_temp_free(t0);
8791 #ifdef TARGET_WORDS_BIGENDIAN
8792 gen_load_fpr32(fp, fs);
8793 gen_load_fpr32h(fph, ft);
8794 gen_store_fpr32h(fp, fd);
8795 gen_store_fpr32(fph, fd);
8796 #else
8797 gen_load_fpr32h(fph, fs);
8798 gen_load_fpr32(fp, ft);
8799 gen_store_fpr32(fph, fd);
8800 gen_store_fpr32h(fp, fd);
8801 #endif
8802 gen_set_label(l2);
8803 tcg_temp_free_i32(fp);
8804 tcg_temp_free_i32(fph);
8806 opn = "alnv.ps";
8807 break;
8808 case OPC_MADD_S:
8809 check_cop1x(ctx);
8811 TCGv_i32 fp0 = tcg_temp_new_i32();
8812 TCGv_i32 fp1 = tcg_temp_new_i32();
8813 TCGv_i32 fp2 = tcg_temp_new_i32();
8815 gen_load_fpr32(fp0, fs);
8816 gen_load_fpr32(fp1, ft);
8817 gen_load_fpr32(fp2, fr);
8818 gen_helper_float_madd_s(fp2, cpu_env, fp0, fp1, fp2);
8819 tcg_temp_free_i32(fp0);
8820 tcg_temp_free_i32(fp1);
8821 gen_store_fpr32(fp2, fd);
8822 tcg_temp_free_i32(fp2);
8824 opn = "madd.s";
8825 break;
8826 case OPC_MADD_D:
8827 check_cop1x(ctx);
8828 check_cp1_registers(ctx, fd | fs | ft | fr);
8830 TCGv_i64 fp0 = tcg_temp_new_i64();
8831 TCGv_i64 fp1 = tcg_temp_new_i64();
8832 TCGv_i64 fp2 = tcg_temp_new_i64();
8834 gen_load_fpr64(ctx, fp0, fs);
8835 gen_load_fpr64(ctx, fp1, ft);
8836 gen_load_fpr64(ctx, fp2, fr);
8837 gen_helper_float_madd_d(fp2, cpu_env, fp0, fp1, fp2);
8838 tcg_temp_free_i64(fp0);
8839 tcg_temp_free_i64(fp1);
8840 gen_store_fpr64(ctx, fp2, fd);
8841 tcg_temp_free_i64(fp2);
8843 opn = "madd.d";
8844 break;
8845 case OPC_MADD_PS:
8846 check_cp1_64bitmode(ctx);
8848 TCGv_i64 fp0 = tcg_temp_new_i64();
8849 TCGv_i64 fp1 = tcg_temp_new_i64();
8850 TCGv_i64 fp2 = tcg_temp_new_i64();
8852 gen_load_fpr64(ctx, fp0, fs);
8853 gen_load_fpr64(ctx, fp1, ft);
8854 gen_load_fpr64(ctx, fp2, fr);
8855 gen_helper_float_madd_ps(fp2, cpu_env, fp0, fp1, fp2);
8856 tcg_temp_free_i64(fp0);
8857 tcg_temp_free_i64(fp1);
8858 gen_store_fpr64(ctx, fp2, fd);
8859 tcg_temp_free_i64(fp2);
8861 opn = "madd.ps";
8862 break;
8863 case OPC_MSUB_S:
8864 check_cop1x(ctx);
8866 TCGv_i32 fp0 = tcg_temp_new_i32();
8867 TCGv_i32 fp1 = tcg_temp_new_i32();
8868 TCGv_i32 fp2 = tcg_temp_new_i32();
8870 gen_load_fpr32(fp0, fs);
8871 gen_load_fpr32(fp1, ft);
8872 gen_load_fpr32(fp2, fr);
8873 gen_helper_float_msub_s(fp2, cpu_env, fp0, fp1, fp2);
8874 tcg_temp_free_i32(fp0);
8875 tcg_temp_free_i32(fp1);
8876 gen_store_fpr32(fp2, fd);
8877 tcg_temp_free_i32(fp2);
8879 opn = "msub.s";
8880 break;
8881 case OPC_MSUB_D:
8882 check_cop1x(ctx);
8883 check_cp1_registers(ctx, fd | fs | ft | fr);
8885 TCGv_i64 fp0 = tcg_temp_new_i64();
8886 TCGv_i64 fp1 = tcg_temp_new_i64();
8887 TCGv_i64 fp2 = tcg_temp_new_i64();
8889 gen_load_fpr64(ctx, fp0, fs);
8890 gen_load_fpr64(ctx, fp1, ft);
8891 gen_load_fpr64(ctx, fp2, fr);
8892 gen_helper_float_msub_d(fp2, cpu_env, fp0, fp1, fp2);
8893 tcg_temp_free_i64(fp0);
8894 tcg_temp_free_i64(fp1);
8895 gen_store_fpr64(ctx, fp2, fd);
8896 tcg_temp_free_i64(fp2);
8898 opn = "msub.d";
8899 break;
8900 case OPC_MSUB_PS:
8901 check_cp1_64bitmode(ctx);
8903 TCGv_i64 fp0 = tcg_temp_new_i64();
8904 TCGv_i64 fp1 = tcg_temp_new_i64();
8905 TCGv_i64 fp2 = tcg_temp_new_i64();
8907 gen_load_fpr64(ctx, fp0, fs);
8908 gen_load_fpr64(ctx, fp1, ft);
8909 gen_load_fpr64(ctx, fp2, fr);
8910 gen_helper_float_msub_ps(fp2, cpu_env, fp0, fp1, fp2);
8911 tcg_temp_free_i64(fp0);
8912 tcg_temp_free_i64(fp1);
8913 gen_store_fpr64(ctx, fp2, fd);
8914 tcg_temp_free_i64(fp2);
8916 opn = "msub.ps";
8917 break;
8918 case OPC_NMADD_S:
8919 check_cop1x(ctx);
8921 TCGv_i32 fp0 = tcg_temp_new_i32();
8922 TCGv_i32 fp1 = tcg_temp_new_i32();
8923 TCGv_i32 fp2 = tcg_temp_new_i32();
8925 gen_load_fpr32(fp0, fs);
8926 gen_load_fpr32(fp1, ft);
8927 gen_load_fpr32(fp2, fr);
8928 gen_helper_float_nmadd_s(fp2, cpu_env, fp0, fp1, fp2);
8929 tcg_temp_free_i32(fp0);
8930 tcg_temp_free_i32(fp1);
8931 gen_store_fpr32(fp2, fd);
8932 tcg_temp_free_i32(fp2);
8934 opn = "nmadd.s";
8935 break;
8936 case OPC_NMADD_D:
8937 check_cop1x(ctx);
8938 check_cp1_registers(ctx, fd | fs | ft | fr);
8940 TCGv_i64 fp0 = tcg_temp_new_i64();
8941 TCGv_i64 fp1 = tcg_temp_new_i64();
8942 TCGv_i64 fp2 = tcg_temp_new_i64();
8944 gen_load_fpr64(ctx, fp0, fs);
8945 gen_load_fpr64(ctx, fp1, ft);
8946 gen_load_fpr64(ctx, fp2, fr);
8947 gen_helper_float_nmadd_d(fp2, cpu_env, fp0, fp1, fp2);
8948 tcg_temp_free_i64(fp0);
8949 tcg_temp_free_i64(fp1);
8950 gen_store_fpr64(ctx, fp2, fd);
8951 tcg_temp_free_i64(fp2);
8953 opn = "nmadd.d";
8954 break;
8955 case OPC_NMADD_PS:
8956 check_cp1_64bitmode(ctx);
8958 TCGv_i64 fp0 = tcg_temp_new_i64();
8959 TCGv_i64 fp1 = tcg_temp_new_i64();
8960 TCGv_i64 fp2 = tcg_temp_new_i64();
8962 gen_load_fpr64(ctx, fp0, fs);
8963 gen_load_fpr64(ctx, fp1, ft);
8964 gen_load_fpr64(ctx, fp2, fr);
8965 gen_helper_float_nmadd_ps(fp2, cpu_env, fp0, fp1, fp2);
8966 tcg_temp_free_i64(fp0);
8967 tcg_temp_free_i64(fp1);
8968 gen_store_fpr64(ctx, fp2, fd);
8969 tcg_temp_free_i64(fp2);
8971 opn = "nmadd.ps";
8972 break;
8973 case OPC_NMSUB_S:
8974 check_cop1x(ctx);
8976 TCGv_i32 fp0 = tcg_temp_new_i32();
8977 TCGv_i32 fp1 = tcg_temp_new_i32();
8978 TCGv_i32 fp2 = tcg_temp_new_i32();
8980 gen_load_fpr32(fp0, fs);
8981 gen_load_fpr32(fp1, ft);
8982 gen_load_fpr32(fp2, fr);
8983 gen_helper_float_nmsub_s(fp2, cpu_env, fp0, fp1, fp2);
8984 tcg_temp_free_i32(fp0);
8985 tcg_temp_free_i32(fp1);
8986 gen_store_fpr32(fp2, fd);
8987 tcg_temp_free_i32(fp2);
8989 opn = "nmsub.s";
8990 break;
8991 case OPC_NMSUB_D:
8992 check_cop1x(ctx);
8993 check_cp1_registers(ctx, fd | fs | ft | fr);
8995 TCGv_i64 fp0 = tcg_temp_new_i64();
8996 TCGv_i64 fp1 = tcg_temp_new_i64();
8997 TCGv_i64 fp2 = tcg_temp_new_i64();
8999 gen_load_fpr64(ctx, fp0, fs);
9000 gen_load_fpr64(ctx, fp1, ft);
9001 gen_load_fpr64(ctx, fp2, fr);
9002 gen_helper_float_nmsub_d(fp2, cpu_env, fp0, fp1, fp2);
9003 tcg_temp_free_i64(fp0);
9004 tcg_temp_free_i64(fp1);
9005 gen_store_fpr64(ctx, fp2, fd);
9006 tcg_temp_free_i64(fp2);
9008 opn = "nmsub.d";
9009 break;
9010 case OPC_NMSUB_PS:
9011 check_cp1_64bitmode(ctx);
9013 TCGv_i64 fp0 = tcg_temp_new_i64();
9014 TCGv_i64 fp1 = tcg_temp_new_i64();
9015 TCGv_i64 fp2 = tcg_temp_new_i64();
9017 gen_load_fpr64(ctx, fp0, fs);
9018 gen_load_fpr64(ctx, fp1, ft);
9019 gen_load_fpr64(ctx, fp2, fr);
9020 gen_helper_float_nmsub_ps(fp2, cpu_env, fp0, fp1, fp2);
9021 tcg_temp_free_i64(fp0);
9022 tcg_temp_free_i64(fp1);
9023 gen_store_fpr64(ctx, fp2, fd);
9024 tcg_temp_free_i64(fp2);
9026 opn = "nmsub.ps";
9027 break;
9028 default:
9029 MIPS_INVAL(opn);
9030 generate_exception (ctx, EXCP_RI);
9031 return;
9033 (void)opn; /* avoid a compiler warning */
9034 MIPS_DEBUG("%s %s, %s, %s, %s", opn, fregnames[fd], fregnames[fr],
9035 fregnames[fs], fregnames[ft]);
9038 static void gen_rdhwr(DisasContext *ctx, int rt, int rd)
9040 TCGv t0;
9042 #if !defined(CONFIG_USER_ONLY)
9043 /* The Linux kernel will emulate rdhwr if it's not supported natively.
9044 Therefore only check the ISA in system mode. */
9045 check_insn(ctx, ISA_MIPS32R2);
9046 #endif
9047 t0 = tcg_temp_new();
9049 switch (rd) {
9050 case 0:
9051 save_cpu_state(ctx, 1);
9052 gen_helper_rdhwr_cpunum(t0, cpu_env);
9053 gen_store_gpr(t0, rt);
9054 break;
9055 case 1:
9056 save_cpu_state(ctx, 1);
9057 gen_helper_rdhwr_synci_step(t0, cpu_env);
9058 gen_store_gpr(t0, rt);
9059 break;
9060 case 2:
9061 save_cpu_state(ctx, 1);
9062 gen_helper_rdhwr_cc(t0, cpu_env);
9063 gen_store_gpr(t0, rt);
9064 break;
9065 case 3:
9066 save_cpu_state(ctx, 1);
9067 gen_helper_rdhwr_ccres(t0, cpu_env);
9068 gen_store_gpr(t0, rt);
9069 break;
9070 case 29:
9071 #if defined(CONFIG_USER_ONLY)
9072 tcg_gen_ld_tl(t0, cpu_env, offsetof(CPUMIPSState, tls_value));
9073 gen_store_gpr(t0, rt);
9074 break;
9075 #else
9076 /* XXX: Some CPUs implement this in hardware.
9077 Not supported yet. */
9078 #endif
9079 default: /* Invalid */
9080 MIPS_INVAL("rdhwr");
9081 generate_exception(ctx, EXCP_RI);
9082 break;
9084 tcg_temp_free(t0);
9087 static void handle_delay_slot(DisasContext *ctx, int insn_bytes)
9089 if (ctx->hflags & MIPS_HFLAG_BMASK) {
9090 int proc_hflags = ctx->hflags & MIPS_HFLAG_BMASK;
9091 /* Branches completion */
9092 ctx->hflags &= ~MIPS_HFLAG_BMASK;
9093 ctx->bstate = BS_BRANCH;
9094 save_cpu_state(ctx, 0);
9095 /* FIXME: Need to clear can_do_io. */
9096 switch (proc_hflags & MIPS_HFLAG_BMASK_BASE) {
9097 case MIPS_HFLAG_B:
9098 /* unconditional branch */
9099 MIPS_DEBUG("unconditional branch");
9100 if (proc_hflags & MIPS_HFLAG_BX) {
9101 tcg_gen_xori_i32(hflags, hflags, MIPS_HFLAG_M16);
9103 gen_goto_tb(ctx, 0, ctx->btarget);
9104 break;
9105 case MIPS_HFLAG_BL:
9106 /* blikely taken case */
9107 MIPS_DEBUG("blikely branch taken");
9108 gen_goto_tb(ctx, 0, ctx->btarget);
9109 break;
9110 case MIPS_HFLAG_BC:
9111 /* Conditional branch */
9112 MIPS_DEBUG("conditional branch");
9114 int l1 = gen_new_label();
9116 tcg_gen_brcondi_tl(TCG_COND_NE, bcond, 0, l1);
9117 gen_goto_tb(ctx, 1, ctx->pc + insn_bytes);
9118 gen_set_label(l1);
9119 gen_goto_tb(ctx, 0, ctx->btarget);
9121 break;
9122 case MIPS_HFLAG_BR:
9123 /* unconditional branch to register */
9124 MIPS_DEBUG("branch to register");
9125 if (ctx->insn_flags & (ASE_MIPS16 | ASE_MICROMIPS)) {
9126 TCGv t0 = tcg_temp_new();
9127 TCGv_i32 t1 = tcg_temp_new_i32();
9129 tcg_gen_andi_tl(t0, btarget, 0x1);
9130 tcg_gen_trunc_tl_i32(t1, t0);
9131 tcg_temp_free(t0);
9132 tcg_gen_andi_i32(hflags, hflags, ~(uint32_t)MIPS_HFLAG_M16);
9133 tcg_gen_shli_i32(t1, t1, MIPS_HFLAG_M16_SHIFT);
9134 tcg_gen_or_i32(hflags, hflags, t1);
9135 tcg_temp_free_i32(t1);
9137 tcg_gen_andi_tl(cpu_PC, btarget, ~(target_ulong)0x1);
9138 } else {
9139 tcg_gen_mov_tl(cpu_PC, btarget);
9141 if (ctx->singlestep_enabled) {
9142 save_cpu_state(ctx, 0);
9143 gen_helper_0e0i(raise_exception, EXCP_DEBUG);
9145 tcg_gen_exit_tb(0);
9146 break;
9147 default:
9148 MIPS_DEBUG("unknown branch");
9149 break;
9154 /* ISA extensions (ASEs) */
9155 /* MIPS16 extension to MIPS32 */
9157 /* MIPS16 major opcodes */
9158 enum {
9159 M16_OPC_ADDIUSP = 0x00,
9160 M16_OPC_ADDIUPC = 0x01,
9161 M16_OPC_B = 0x02,
9162 M16_OPC_JAL = 0x03,
9163 M16_OPC_BEQZ = 0x04,
9164 M16_OPC_BNEQZ = 0x05,
9165 M16_OPC_SHIFT = 0x06,
9166 M16_OPC_LD = 0x07,
9167 M16_OPC_RRIA = 0x08,
9168 M16_OPC_ADDIU8 = 0x09,
9169 M16_OPC_SLTI = 0x0a,
9170 M16_OPC_SLTIU = 0x0b,
9171 M16_OPC_I8 = 0x0c,
9172 M16_OPC_LI = 0x0d,
9173 M16_OPC_CMPI = 0x0e,
9174 M16_OPC_SD = 0x0f,
9175 M16_OPC_LB = 0x10,
9176 M16_OPC_LH = 0x11,
9177 M16_OPC_LWSP = 0x12,
9178 M16_OPC_LW = 0x13,
9179 M16_OPC_LBU = 0x14,
9180 M16_OPC_LHU = 0x15,
9181 M16_OPC_LWPC = 0x16,
9182 M16_OPC_LWU = 0x17,
9183 M16_OPC_SB = 0x18,
9184 M16_OPC_SH = 0x19,
9185 M16_OPC_SWSP = 0x1a,
9186 M16_OPC_SW = 0x1b,
9187 M16_OPC_RRR = 0x1c,
9188 M16_OPC_RR = 0x1d,
9189 M16_OPC_EXTEND = 0x1e,
9190 M16_OPC_I64 = 0x1f
9193 /* I8 funct field */
9194 enum {
9195 I8_BTEQZ = 0x0,
9196 I8_BTNEZ = 0x1,
9197 I8_SWRASP = 0x2,
9198 I8_ADJSP = 0x3,
9199 I8_SVRS = 0x4,
9200 I8_MOV32R = 0x5,
9201 I8_MOVR32 = 0x7
9204 /* RRR f field */
9205 enum {
9206 RRR_DADDU = 0x0,
9207 RRR_ADDU = 0x1,
9208 RRR_DSUBU = 0x2,
9209 RRR_SUBU = 0x3
9212 /* RR funct field */
9213 enum {
9214 RR_JR = 0x00,
9215 RR_SDBBP = 0x01,
9216 RR_SLT = 0x02,
9217 RR_SLTU = 0x03,
9218 RR_SLLV = 0x04,
9219 RR_BREAK = 0x05,
9220 RR_SRLV = 0x06,
9221 RR_SRAV = 0x07,
9222 RR_DSRL = 0x08,
9223 RR_CMP = 0x0a,
9224 RR_NEG = 0x0b,
9225 RR_AND = 0x0c,
9226 RR_OR = 0x0d,
9227 RR_XOR = 0x0e,
9228 RR_NOT = 0x0f,
9229 RR_MFHI = 0x10,
9230 RR_CNVT = 0x11,
9231 RR_MFLO = 0x12,
9232 RR_DSRA = 0x13,
9233 RR_DSLLV = 0x14,
9234 RR_DSRLV = 0x16,
9235 RR_DSRAV = 0x17,
9236 RR_MULT = 0x18,
9237 RR_MULTU = 0x19,
9238 RR_DIV = 0x1a,
9239 RR_DIVU = 0x1b,
9240 RR_DMULT = 0x1c,
9241 RR_DMULTU = 0x1d,
9242 RR_DDIV = 0x1e,
9243 RR_DDIVU = 0x1f
9246 /* I64 funct field */
9247 enum {
9248 I64_LDSP = 0x0,
9249 I64_SDSP = 0x1,
9250 I64_SDRASP = 0x2,
9251 I64_DADJSP = 0x3,
9252 I64_LDPC = 0x4,
9253 I64_DADDIU5 = 0x5,
9254 I64_DADDIUPC = 0x6,
9255 I64_DADDIUSP = 0x7
9258 /* RR ry field for CNVT */
9259 enum {
9260 RR_RY_CNVT_ZEB = 0x0,
9261 RR_RY_CNVT_ZEH = 0x1,
9262 RR_RY_CNVT_ZEW = 0x2,
9263 RR_RY_CNVT_SEB = 0x4,
9264 RR_RY_CNVT_SEH = 0x5,
9265 RR_RY_CNVT_SEW = 0x6,
9268 static int xlat (int r)
9270 static int map[] = { 16, 17, 2, 3, 4, 5, 6, 7 };
9272 return map[r];
9275 static void gen_mips16_save (DisasContext *ctx,
9276 int xsregs, int aregs,
9277 int do_ra, int do_s0, int do_s1,
9278 int framesize)
9280 TCGv t0 = tcg_temp_new();
9281 TCGv t1 = tcg_temp_new();
9282 int args, astatic;
9284 switch (aregs) {
9285 case 0:
9286 case 1:
9287 case 2:
9288 case 3:
9289 case 11:
9290 args = 0;
9291 break;
9292 case 4:
9293 case 5:
9294 case 6:
9295 case 7:
9296 args = 1;
9297 break;
9298 case 8:
9299 case 9:
9300 case 10:
9301 args = 2;
9302 break;
9303 case 12:
9304 case 13:
9305 args = 3;
9306 break;
9307 case 14:
9308 args = 4;
9309 break;
9310 default:
9311 generate_exception(ctx, EXCP_RI);
9312 return;
9315 switch (args) {
9316 case 4:
9317 gen_base_offset_addr(ctx, t0, 29, 12);
9318 gen_load_gpr(t1, 7);
9319 tcg_gen_qemu_st32(t1, t0, ctx->mem_idx);
9320 /* Fall through */
9321 case 3:
9322 gen_base_offset_addr(ctx, t0, 29, 8);
9323 gen_load_gpr(t1, 6);
9324 tcg_gen_qemu_st32(t1, t0, ctx->mem_idx);
9325 /* Fall through */
9326 case 2:
9327 gen_base_offset_addr(ctx, t0, 29, 4);
9328 gen_load_gpr(t1, 5);
9329 tcg_gen_qemu_st32(t1, t0, ctx->mem_idx);
9330 /* Fall through */
9331 case 1:
9332 gen_base_offset_addr(ctx, t0, 29, 0);
9333 gen_load_gpr(t1, 4);
9334 tcg_gen_qemu_st32(t1, t0, ctx->mem_idx);
9337 gen_load_gpr(t0, 29);
9339 #define DECR_AND_STORE(reg) do { \
9340 tcg_gen_subi_tl(t0, t0, 4); \
9341 gen_load_gpr(t1, reg); \
9342 tcg_gen_qemu_st32(t1, t0, ctx->mem_idx); \
9343 } while (0)
9345 if (do_ra) {
9346 DECR_AND_STORE(31);
9349 switch (xsregs) {
9350 case 7:
9351 DECR_AND_STORE(30);
9352 /* Fall through */
9353 case 6:
9354 DECR_AND_STORE(23);
9355 /* Fall through */
9356 case 5:
9357 DECR_AND_STORE(22);
9358 /* Fall through */
9359 case 4:
9360 DECR_AND_STORE(21);
9361 /* Fall through */
9362 case 3:
9363 DECR_AND_STORE(20);
9364 /* Fall through */
9365 case 2:
9366 DECR_AND_STORE(19);
9367 /* Fall through */
9368 case 1:
9369 DECR_AND_STORE(18);
9372 if (do_s1) {
9373 DECR_AND_STORE(17);
9375 if (do_s0) {
9376 DECR_AND_STORE(16);
9379 switch (aregs) {
9380 case 0:
9381 case 4:
9382 case 8:
9383 case 12:
9384 case 14:
9385 astatic = 0;
9386 break;
9387 case 1:
9388 case 5:
9389 case 9:
9390 case 13:
9391 astatic = 1;
9392 break;
9393 case 2:
9394 case 6:
9395 case 10:
9396 astatic = 2;
9397 break;
9398 case 3:
9399 case 7:
9400 astatic = 3;
9401 break;
9402 case 11:
9403 astatic = 4;
9404 break;
9405 default:
9406 generate_exception(ctx, EXCP_RI);
9407 return;
9410 if (astatic > 0) {
9411 DECR_AND_STORE(7);
9412 if (astatic > 1) {
9413 DECR_AND_STORE(6);
9414 if (astatic > 2) {
9415 DECR_AND_STORE(5);
9416 if (astatic > 3) {
9417 DECR_AND_STORE(4);
9422 #undef DECR_AND_STORE
9424 tcg_gen_subi_tl(cpu_gpr[29], cpu_gpr[29], framesize);
9425 tcg_temp_free(t0);
9426 tcg_temp_free(t1);
9429 static void gen_mips16_restore (DisasContext *ctx,
9430 int xsregs, int aregs,
9431 int do_ra, int do_s0, int do_s1,
9432 int framesize)
9434 int astatic;
9435 TCGv t0 = tcg_temp_new();
9436 TCGv t1 = tcg_temp_new();
9438 tcg_gen_addi_tl(t0, cpu_gpr[29], framesize);
9440 #define DECR_AND_LOAD(reg) do { \
9441 tcg_gen_subi_tl(t0, t0, 4); \
9442 tcg_gen_qemu_ld32s(t1, t0, ctx->mem_idx); \
9443 gen_store_gpr(t1, reg); \
9444 } while (0)
9446 if (do_ra) {
9447 DECR_AND_LOAD(31);
9450 switch (xsregs) {
9451 case 7:
9452 DECR_AND_LOAD(30);
9453 /* Fall through */
9454 case 6:
9455 DECR_AND_LOAD(23);
9456 /* Fall through */
9457 case 5:
9458 DECR_AND_LOAD(22);
9459 /* Fall through */
9460 case 4:
9461 DECR_AND_LOAD(21);
9462 /* Fall through */
9463 case 3:
9464 DECR_AND_LOAD(20);
9465 /* Fall through */
9466 case 2:
9467 DECR_AND_LOAD(19);
9468 /* Fall through */
9469 case 1:
9470 DECR_AND_LOAD(18);
9473 if (do_s1) {
9474 DECR_AND_LOAD(17);
9476 if (do_s0) {
9477 DECR_AND_LOAD(16);
9480 switch (aregs) {
9481 case 0:
9482 case 4:
9483 case 8:
9484 case 12:
9485 case 14:
9486 astatic = 0;
9487 break;
9488 case 1:
9489 case 5:
9490 case 9:
9491 case 13:
9492 astatic = 1;
9493 break;
9494 case 2:
9495 case 6:
9496 case 10:
9497 astatic = 2;
9498 break;
9499 case 3:
9500 case 7:
9501 astatic = 3;
9502 break;
9503 case 11:
9504 astatic = 4;
9505 break;
9506 default:
9507 generate_exception(ctx, EXCP_RI);
9508 return;
9511 if (astatic > 0) {
9512 DECR_AND_LOAD(7);
9513 if (astatic > 1) {
9514 DECR_AND_LOAD(6);
9515 if (astatic > 2) {
9516 DECR_AND_LOAD(5);
9517 if (astatic > 3) {
9518 DECR_AND_LOAD(4);
9523 #undef DECR_AND_LOAD
9525 tcg_gen_addi_tl(cpu_gpr[29], cpu_gpr[29], framesize);
9526 tcg_temp_free(t0);
9527 tcg_temp_free(t1);
9530 static void gen_addiupc (DisasContext *ctx, int rx, int imm,
9531 int is_64_bit, int extended)
9533 TCGv t0;
9535 if (extended && (ctx->hflags & MIPS_HFLAG_BMASK)) {
9536 generate_exception(ctx, EXCP_RI);
9537 return;
9540 t0 = tcg_temp_new();
9542 tcg_gen_movi_tl(t0, pc_relative_pc(ctx));
9543 tcg_gen_addi_tl(cpu_gpr[rx], t0, imm);
9544 if (!is_64_bit) {
9545 tcg_gen_ext32s_tl(cpu_gpr[rx], cpu_gpr[rx]);
9548 tcg_temp_free(t0);
9551 #if defined(TARGET_MIPS64)
9552 static void decode_i64_mips16 (DisasContext *ctx,
9553 int ry, int funct, int16_t offset,
9554 int extended)
9556 switch (funct) {
9557 case I64_LDSP:
9558 check_mips_64(ctx);
9559 offset = extended ? offset : offset << 3;
9560 gen_ld(ctx, OPC_LD, ry, 29, offset);
9561 break;
9562 case I64_SDSP:
9563 check_mips_64(ctx);
9564 offset = extended ? offset : offset << 3;
9565 gen_st(ctx, OPC_SD, ry, 29, offset);
9566 break;
9567 case I64_SDRASP:
9568 check_mips_64(ctx);
9569 offset = extended ? offset : (ctx->opcode & 0xff) << 3;
9570 gen_st(ctx, OPC_SD, 31, 29, offset);
9571 break;
9572 case I64_DADJSP:
9573 check_mips_64(ctx);
9574 offset = extended ? offset : ((int8_t)ctx->opcode) << 3;
9575 gen_arith_imm(ctx, OPC_DADDIU, 29, 29, offset);
9576 break;
9577 case I64_LDPC:
9578 if (extended && (ctx->hflags & MIPS_HFLAG_BMASK)) {
9579 generate_exception(ctx, EXCP_RI);
9580 } else {
9581 offset = extended ? offset : offset << 3;
9582 gen_ld(ctx, OPC_LDPC, ry, 0, offset);
9584 break;
9585 case I64_DADDIU5:
9586 check_mips_64(ctx);
9587 offset = extended ? offset : ((int8_t)(offset << 3)) >> 3;
9588 gen_arith_imm(ctx, OPC_DADDIU, ry, ry, offset);
9589 break;
9590 case I64_DADDIUPC:
9591 check_mips_64(ctx);
9592 offset = extended ? offset : offset << 2;
9593 gen_addiupc(ctx, ry, offset, 1, extended);
9594 break;
9595 case I64_DADDIUSP:
9596 check_mips_64(ctx);
9597 offset = extended ? offset : offset << 2;
9598 gen_arith_imm(ctx, OPC_DADDIU, ry, 29, offset);
9599 break;
9602 #endif
9604 static int decode_extended_mips16_opc (CPUMIPSState *env, DisasContext *ctx,
9605 int *is_branch)
9607 int extend = cpu_lduw_code(env, ctx->pc + 2);
9608 int op, rx, ry, funct, sa;
9609 int16_t imm, offset;
9611 ctx->opcode = (ctx->opcode << 16) | extend;
9612 op = (ctx->opcode >> 11) & 0x1f;
9613 sa = (ctx->opcode >> 22) & 0x1f;
9614 funct = (ctx->opcode >> 8) & 0x7;
9615 rx = xlat((ctx->opcode >> 8) & 0x7);
9616 ry = xlat((ctx->opcode >> 5) & 0x7);
9617 offset = imm = (int16_t) (((ctx->opcode >> 16) & 0x1f) << 11
9618 | ((ctx->opcode >> 21) & 0x3f) << 5
9619 | (ctx->opcode & 0x1f));
9621 /* The extended opcodes cleverly reuse the opcodes from their 16-bit
9622 counterparts. */
9623 switch (op) {
9624 case M16_OPC_ADDIUSP:
9625 gen_arith_imm(ctx, OPC_ADDIU, rx, 29, imm);
9626 break;
9627 case M16_OPC_ADDIUPC:
9628 gen_addiupc(ctx, rx, imm, 0, 1);
9629 break;
9630 case M16_OPC_B:
9631 gen_compute_branch(ctx, OPC_BEQ, 4, 0, 0, offset << 1);
9632 /* No delay slot, so just process as a normal instruction */
9633 break;
9634 case M16_OPC_BEQZ:
9635 gen_compute_branch(ctx, OPC_BEQ, 4, rx, 0, offset << 1);
9636 /* No delay slot, so just process as a normal instruction */
9637 break;
9638 case M16_OPC_BNEQZ:
9639 gen_compute_branch(ctx, OPC_BNE, 4, rx, 0, offset << 1);
9640 /* No delay slot, so just process as a normal instruction */
9641 break;
9642 case M16_OPC_SHIFT:
9643 switch (ctx->opcode & 0x3) {
9644 case 0x0:
9645 gen_shift_imm(ctx, OPC_SLL, rx, ry, sa);
9646 break;
9647 case 0x1:
9648 #if defined(TARGET_MIPS64)
9649 check_mips_64(ctx);
9650 gen_shift_imm(ctx, OPC_DSLL, rx, ry, sa);
9651 #else
9652 generate_exception(ctx, EXCP_RI);
9653 #endif
9654 break;
9655 case 0x2:
9656 gen_shift_imm(ctx, OPC_SRL, rx, ry, sa);
9657 break;
9658 case 0x3:
9659 gen_shift_imm(ctx, OPC_SRA, rx, ry, sa);
9660 break;
9662 break;
9663 #if defined(TARGET_MIPS64)
9664 case M16_OPC_LD:
9665 check_mips_64(ctx);
9666 gen_ld(ctx, OPC_LD, ry, rx, offset);
9667 break;
9668 #endif
9669 case M16_OPC_RRIA:
9670 imm = ctx->opcode & 0xf;
9671 imm = imm | ((ctx->opcode >> 20) & 0x7f) << 4;
9672 imm = imm | ((ctx->opcode >> 16) & 0xf) << 11;
9673 imm = (int16_t) (imm << 1) >> 1;
9674 if ((ctx->opcode >> 4) & 0x1) {
9675 #if defined(TARGET_MIPS64)
9676 check_mips_64(ctx);
9677 gen_arith_imm(ctx, OPC_DADDIU, ry, rx, imm);
9678 #else
9679 generate_exception(ctx, EXCP_RI);
9680 #endif
9681 } else {
9682 gen_arith_imm(ctx, OPC_ADDIU, ry, rx, imm);
9684 break;
9685 case M16_OPC_ADDIU8:
9686 gen_arith_imm(ctx, OPC_ADDIU, rx, rx, imm);
9687 break;
9688 case M16_OPC_SLTI:
9689 gen_slt_imm(ctx, OPC_SLTI, 24, rx, imm);
9690 break;
9691 case M16_OPC_SLTIU:
9692 gen_slt_imm(ctx, OPC_SLTIU, 24, rx, imm);
9693 break;
9694 case M16_OPC_I8:
9695 switch (funct) {
9696 case I8_BTEQZ:
9697 gen_compute_branch(ctx, OPC_BEQ, 4, 24, 0, offset << 1);
9698 break;
9699 case I8_BTNEZ:
9700 gen_compute_branch(ctx, OPC_BNE, 4, 24, 0, offset << 1);
9701 break;
9702 case I8_SWRASP:
9703 gen_st(ctx, OPC_SW, 31, 29, imm);
9704 break;
9705 case I8_ADJSP:
9706 gen_arith_imm(ctx, OPC_ADDIU, 29, 29, imm);
9707 break;
9708 case I8_SVRS:
9710 int xsregs = (ctx->opcode >> 24) & 0x7;
9711 int aregs = (ctx->opcode >> 16) & 0xf;
9712 int do_ra = (ctx->opcode >> 6) & 0x1;
9713 int do_s0 = (ctx->opcode >> 5) & 0x1;
9714 int do_s1 = (ctx->opcode >> 4) & 0x1;
9715 int framesize = (((ctx->opcode >> 20) & 0xf) << 4
9716 | (ctx->opcode & 0xf)) << 3;
9718 if (ctx->opcode & (1 << 7)) {
9719 gen_mips16_save(ctx, xsregs, aregs,
9720 do_ra, do_s0, do_s1,
9721 framesize);
9722 } else {
9723 gen_mips16_restore(ctx, xsregs, aregs,
9724 do_ra, do_s0, do_s1,
9725 framesize);
9728 break;
9729 default:
9730 generate_exception(ctx, EXCP_RI);
9731 break;
9733 break;
9734 case M16_OPC_LI:
9735 tcg_gen_movi_tl(cpu_gpr[rx], (uint16_t) imm);
9736 break;
9737 case M16_OPC_CMPI:
9738 tcg_gen_xori_tl(cpu_gpr[24], cpu_gpr[rx], (uint16_t) imm);
9739 break;
9740 #if defined(TARGET_MIPS64)
9741 case M16_OPC_SD:
9742 gen_st(ctx, OPC_SD, ry, rx, offset);
9743 break;
9744 #endif
9745 case M16_OPC_LB:
9746 gen_ld(ctx, OPC_LB, ry, rx, offset);
9747 break;
9748 case M16_OPC_LH:
9749 gen_ld(ctx, OPC_LH, ry, rx, offset);
9750 break;
9751 case M16_OPC_LWSP:
9752 gen_ld(ctx, OPC_LW, rx, 29, offset);
9753 break;
9754 case M16_OPC_LW:
9755 gen_ld(ctx, OPC_LW, ry, rx, offset);
9756 break;
9757 case M16_OPC_LBU:
9758 gen_ld(ctx, OPC_LBU, ry, rx, offset);
9759 break;
9760 case M16_OPC_LHU:
9761 gen_ld(ctx, OPC_LHU, ry, rx, offset);
9762 break;
9763 case M16_OPC_LWPC:
9764 gen_ld(ctx, OPC_LWPC, rx, 0, offset);
9765 break;
9766 #if defined(TARGET_MIPS64)
9767 case M16_OPC_LWU:
9768 gen_ld(ctx, OPC_LWU, ry, rx, offset);
9769 break;
9770 #endif
9771 case M16_OPC_SB:
9772 gen_st(ctx, OPC_SB, ry, rx, offset);
9773 break;
9774 case M16_OPC_SH:
9775 gen_st(ctx, OPC_SH, ry, rx, offset);
9776 break;
9777 case M16_OPC_SWSP:
9778 gen_st(ctx, OPC_SW, rx, 29, offset);
9779 break;
9780 case M16_OPC_SW:
9781 gen_st(ctx, OPC_SW, ry, rx, offset);
9782 break;
9783 #if defined(TARGET_MIPS64)
9784 case M16_OPC_I64:
9785 decode_i64_mips16(ctx, ry, funct, offset, 1);
9786 break;
9787 #endif
9788 default:
9789 generate_exception(ctx, EXCP_RI);
9790 break;
9793 return 4;
9796 static int decode_mips16_opc (CPUMIPSState *env, DisasContext *ctx,
9797 int *is_branch)
9799 int rx, ry;
9800 int sa;
9801 int op, cnvt_op, op1, offset;
9802 int funct;
9803 int n_bytes;
9805 op = (ctx->opcode >> 11) & 0x1f;
9806 sa = (ctx->opcode >> 2) & 0x7;
9807 sa = sa == 0 ? 8 : sa;
9808 rx = xlat((ctx->opcode >> 8) & 0x7);
9809 cnvt_op = (ctx->opcode >> 5) & 0x7;
9810 ry = xlat((ctx->opcode >> 5) & 0x7);
9811 op1 = offset = ctx->opcode & 0x1f;
9813 n_bytes = 2;
9815 switch (op) {
9816 case M16_OPC_ADDIUSP:
9818 int16_t imm = ((uint8_t) ctx->opcode) << 2;
9820 gen_arith_imm(ctx, OPC_ADDIU, rx, 29, imm);
9822 break;
9823 case M16_OPC_ADDIUPC:
9824 gen_addiupc(ctx, rx, ((uint8_t) ctx->opcode) << 2, 0, 0);
9825 break;
9826 case M16_OPC_B:
9827 offset = (ctx->opcode & 0x7ff) << 1;
9828 offset = (int16_t)(offset << 4) >> 4;
9829 gen_compute_branch(ctx, OPC_BEQ, 2, 0, 0, offset);
9830 /* No delay slot, so just process as a normal instruction */
9831 break;
9832 case M16_OPC_JAL:
9833 offset = cpu_lduw_code(env, ctx->pc + 2);
9834 offset = (((ctx->opcode & 0x1f) << 21)
9835 | ((ctx->opcode >> 5) & 0x1f) << 16
9836 | offset) << 2;
9837 op = ((ctx->opcode >> 10) & 0x1) ? OPC_JALXS : OPC_JALS;
9838 gen_compute_branch(ctx, op, 4, rx, ry, offset);
9839 n_bytes = 4;
9840 *is_branch = 1;
9841 break;
9842 case M16_OPC_BEQZ:
9843 gen_compute_branch(ctx, OPC_BEQ, 2, rx, 0, ((int8_t)ctx->opcode) << 1);
9844 /* No delay slot, so just process as a normal instruction */
9845 break;
9846 case M16_OPC_BNEQZ:
9847 gen_compute_branch(ctx, OPC_BNE, 2, rx, 0, ((int8_t)ctx->opcode) << 1);
9848 /* No delay slot, so just process as a normal instruction */
9849 break;
9850 case M16_OPC_SHIFT:
9851 switch (ctx->opcode & 0x3) {
9852 case 0x0:
9853 gen_shift_imm(ctx, OPC_SLL, rx, ry, sa);
9854 break;
9855 case 0x1:
9856 #if defined(TARGET_MIPS64)
9857 check_mips_64(ctx);
9858 gen_shift_imm(ctx, OPC_DSLL, rx, ry, sa);
9859 #else
9860 generate_exception(ctx, EXCP_RI);
9861 #endif
9862 break;
9863 case 0x2:
9864 gen_shift_imm(ctx, OPC_SRL, rx, ry, sa);
9865 break;
9866 case 0x3:
9867 gen_shift_imm(ctx, OPC_SRA, rx, ry, sa);
9868 break;
9870 break;
9871 #if defined(TARGET_MIPS64)
9872 case M16_OPC_LD:
9873 check_mips_64(ctx);
9874 gen_ld(ctx, OPC_LD, ry, rx, offset << 3);
9875 break;
9876 #endif
9877 case M16_OPC_RRIA:
9879 int16_t imm = (int8_t)((ctx->opcode & 0xf) << 4) >> 4;
9881 if ((ctx->opcode >> 4) & 1) {
9882 #if defined(TARGET_MIPS64)
9883 check_mips_64(ctx);
9884 gen_arith_imm(ctx, OPC_DADDIU, ry, rx, imm);
9885 #else
9886 generate_exception(ctx, EXCP_RI);
9887 #endif
9888 } else {
9889 gen_arith_imm(ctx, OPC_ADDIU, ry, rx, imm);
9892 break;
9893 case M16_OPC_ADDIU8:
9895 int16_t imm = (int8_t) ctx->opcode;
9897 gen_arith_imm(ctx, OPC_ADDIU, rx, rx, imm);
9899 break;
9900 case M16_OPC_SLTI:
9902 int16_t imm = (uint8_t) ctx->opcode;
9903 gen_slt_imm(ctx, OPC_SLTI, 24, rx, imm);
9905 break;
9906 case M16_OPC_SLTIU:
9908 int16_t imm = (uint8_t) ctx->opcode;
9909 gen_slt_imm(ctx, OPC_SLTIU, 24, rx, imm);
9911 break;
9912 case M16_OPC_I8:
9914 int reg32;
9916 funct = (ctx->opcode >> 8) & 0x7;
9917 switch (funct) {
9918 case I8_BTEQZ:
9919 gen_compute_branch(ctx, OPC_BEQ, 2, 24, 0,
9920 ((int8_t)ctx->opcode) << 1);
9921 break;
9922 case I8_BTNEZ:
9923 gen_compute_branch(ctx, OPC_BNE, 2, 24, 0,
9924 ((int8_t)ctx->opcode) << 1);
9925 break;
9926 case I8_SWRASP:
9927 gen_st(ctx, OPC_SW, 31, 29, (ctx->opcode & 0xff) << 2);
9928 break;
9929 case I8_ADJSP:
9930 gen_arith_imm(ctx, OPC_ADDIU, 29, 29,
9931 ((int8_t)ctx->opcode) << 3);
9932 break;
9933 case I8_SVRS:
9935 int do_ra = ctx->opcode & (1 << 6);
9936 int do_s0 = ctx->opcode & (1 << 5);
9937 int do_s1 = ctx->opcode & (1 << 4);
9938 int framesize = ctx->opcode & 0xf;
9940 if (framesize == 0) {
9941 framesize = 128;
9942 } else {
9943 framesize = framesize << 3;
9946 if (ctx->opcode & (1 << 7)) {
9947 gen_mips16_save(ctx, 0, 0,
9948 do_ra, do_s0, do_s1, framesize);
9949 } else {
9950 gen_mips16_restore(ctx, 0, 0,
9951 do_ra, do_s0, do_s1, framesize);
9954 break;
9955 case I8_MOV32R:
9957 int rz = xlat(ctx->opcode & 0x7);
9959 reg32 = (((ctx->opcode >> 3) & 0x3) << 3) |
9960 ((ctx->opcode >> 5) & 0x7);
9961 gen_arith(ctx, OPC_ADDU, reg32, rz, 0);
9963 break;
9964 case I8_MOVR32:
9965 reg32 = ctx->opcode & 0x1f;
9966 gen_arith(ctx, OPC_ADDU, ry, reg32, 0);
9967 break;
9968 default:
9969 generate_exception(ctx, EXCP_RI);
9970 break;
9973 break;
9974 case M16_OPC_LI:
9976 int16_t imm = (uint8_t) ctx->opcode;
9978 gen_arith_imm(ctx, OPC_ADDIU, rx, 0, imm);
9980 break;
9981 case M16_OPC_CMPI:
9983 int16_t imm = (uint8_t) ctx->opcode;
9984 gen_logic_imm(ctx, OPC_XORI, 24, rx, imm);
9986 break;
9987 #if defined(TARGET_MIPS64)
9988 case M16_OPC_SD:
9989 check_mips_64(ctx);
9990 gen_st(ctx, OPC_SD, ry, rx, offset << 3);
9991 break;
9992 #endif
9993 case M16_OPC_LB:
9994 gen_ld(ctx, OPC_LB, ry, rx, offset);
9995 break;
9996 case M16_OPC_LH:
9997 gen_ld(ctx, OPC_LH, ry, rx, offset << 1);
9998 break;
9999 case M16_OPC_LWSP:
10000 gen_ld(ctx, OPC_LW, rx, 29, ((uint8_t)ctx->opcode) << 2);
10001 break;
10002 case M16_OPC_LW:
10003 gen_ld(ctx, OPC_LW, ry, rx, offset << 2);
10004 break;
10005 case M16_OPC_LBU:
10006 gen_ld(ctx, OPC_LBU, ry, rx, offset);
10007 break;
10008 case M16_OPC_LHU:
10009 gen_ld(ctx, OPC_LHU, ry, rx, offset << 1);
10010 break;
10011 case M16_OPC_LWPC:
10012 gen_ld(ctx, OPC_LWPC, rx, 0, ((uint8_t)ctx->opcode) << 2);
10013 break;
10014 #if defined (TARGET_MIPS64)
10015 case M16_OPC_LWU:
10016 check_mips_64(ctx);
10017 gen_ld(ctx, OPC_LWU, ry, rx, offset << 2);
10018 break;
10019 #endif
10020 case M16_OPC_SB:
10021 gen_st(ctx, OPC_SB, ry, rx, offset);
10022 break;
10023 case M16_OPC_SH:
10024 gen_st(ctx, OPC_SH, ry, rx, offset << 1);
10025 break;
10026 case M16_OPC_SWSP:
10027 gen_st(ctx, OPC_SW, rx, 29, ((uint8_t)ctx->opcode) << 2);
10028 break;
10029 case M16_OPC_SW:
10030 gen_st(ctx, OPC_SW, ry, rx, offset << 2);
10031 break;
10032 case M16_OPC_RRR:
10034 int rz = xlat((ctx->opcode >> 2) & 0x7);
10035 int mips32_op;
10037 switch (ctx->opcode & 0x3) {
10038 case RRR_ADDU:
10039 mips32_op = OPC_ADDU;
10040 break;
10041 case RRR_SUBU:
10042 mips32_op = OPC_SUBU;
10043 break;
10044 #if defined(TARGET_MIPS64)
10045 case RRR_DADDU:
10046 mips32_op = OPC_DADDU;
10047 check_mips_64(ctx);
10048 break;
10049 case RRR_DSUBU:
10050 mips32_op = OPC_DSUBU;
10051 check_mips_64(ctx);
10052 break;
10053 #endif
10054 default:
10055 generate_exception(ctx, EXCP_RI);
10056 goto done;
10059 gen_arith(ctx, mips32_op, rz, rx, ry);
10060 done:
10063 break;
10064 case M16_OPC_RR:
10065 switch (op1) {
10066 case RR_JR:
10068 int nd = (ctx->opcode >> 7) & 0x1;
10069 int link = (ctx->opcode >> 6) & 0x1;
10070 int ra = (ctx->opcode >> 5) & 0x1;
10072 if (link) {
10073 op = nd ? OPC_JALRC : OPC_JALRS;
10074 } else {
10075 op = OPC_JR;
10078 gen_compute_branch(ctx, op, 2, ra ? 31 : rx, 31, 0);
10079 if (!nd) {
10080 *is_branch = 1;
10083 break;
10084 case RR_SDBBP:
10085 /* XXX: not clear which exception should be raised
10086 * when in debug mode...
10088 check_insn(ctx, ISA_MIPS32);
10089 if (!(ctx->hflags & MIPS_HFLAG_DM)) {
10090 generate_exception(ctx, EXCP_DBp);
10091 } else {
10092 generate_exception(ctx, EXCP_DBp);
10094 break;
10095 case RR_SLT:
10096 gen_slt(ctx, OPC_SLT, 24, rx, ry);
10097 break;
10098 case RR_SLTU:
10099 gen_slt(ctx, OPC_SLTU, 24, rx, ry);
10100 break;
10101 case RR_BREAK:
10102 generate_exception(ctx, EXCP_BREAK);
10103 break;
10104 case RR_SLLV:
10105 gen_shift(ctx, OPC_SLLV, ry, rx, ry);
10106 break;
10107 case RR_SRLV:
10108 gen_shift(ctx, OPC_SRLV, ry, rx, ry);
10109 break;
10110 case RR_SRAV:
10111 gen_shift(ctx, OPC_SRAV, ry, rx, ry);
10112 break;
10113 #if defined (TARGET_MIPS64)
10114 case RR_DSRL:
10115 check_mips_64(ctx);
10116 gen_shift_imm(ctx, OPC_DSRL, ry, ry, sa);
10117 break;
10118 #endif
10119 case RR_CMP:
10120 gen_logic(ctx, OPC_XOR, 24, rx, ry);
10121 break;
10122 case RR_NEG:
10123 gen_arith(ctx, OPC_SUBU, rx, 0, ry);
10124 break;
10125 case RR_AND:
10126 gen_logic(ctx, OPC_AND, rx, rx, ry);
10127 break;
10128 case RR_OR:
10129 gen_logic(ctx, OPC_OR, rx, rx, ry);
10130 break;
10131 case RR_XOR:
10132 gen_logic(ctx, OPC_XOR, rx, rx, ry);
10133 break;
10134 case RR_NOT:
10135 gen_logic(ctx, OPC_NOR, rx, ry, 0);
10136 break;
10137 case RR_MFHI:
10138 gen_HILO(ctx, OPC_MFHI, rx);
10139 break;
10140 case RR_CNVT:
10141 switch (cnvt_op) {
10142 case RR_RY_CNVT_ZEB:
10143 tcg_gen_ext8u_tl(cpu_gpr[rx], cpu_gpr[rx]);
10144 break;
10145 case RR_RY_CNVT_ZEH:
10146 tcg_gen_ext16u_tl(cpu_gpr[rx], cpu_gpr[rx]);
10147 break;
10148 case RR_RY_CNVT_SEB:
10149 tcg_gen_ext8s_tl(cpu_gpr[rx], cpu_gpr[rx]);
10150 break;
10151 case RR_RY_CNVT_SEH:
10152 tcg_gen_ext16s_tl(cpu_gpr[rx], cpu_gpr[rx]);
10153 break;
10154 #if defined (TARGET_MIPS64)
10155 case RR_RY_CNVT_ZEW:
10156 check_mips_64(ctx);
10157 tcg_gen_ext32u_tl(cpu_gpr[rx], cpu_gpr[rx]);
10158 break;
10159 case RR_RY_CNVT_SEW:
10160 check_mips_64(ctx);
10161 tcg_gen_ext32s_tl(cpu_gpr[rx], cpu_gpr[rx]);
10162 break;
10163 #endif
10164 default:
10165 generate_exception(ctx, EXCP_RI);
10166 break;
10168 break;
10169 case RR_MFLO:
10170 gen_HILO(ctx, OPC_MFLO, rx);
10171 break;
10172 #if defined (TARGET_MIPS64)
10173 case RR_DSRA:
10174 check_mips_64(ctx);
10175 gen_shift_imm(ctx, OPC_DSRA, ry, ry, sa);
10176 break;
10177 case RR_DSLLV:
10178 check_mips_64(ctx);
10179 gen_shift(ctx, OPC_DSLLV, ry, rx, ry);
10180 break;
10181 case RR_DSRLV:
10182 check_mips_64(ctx);
10183 gen_shift(ctx, OPC_DSRLV, ry, rx, ry);
10184 break;
10185 case RR_DSRAV:
10186 check_mips_64(ctx);
10187 gen_shift(ctx, OPC_DSRAV, ry, rx, ry);
10188 break;
10189 #endif
10190 case RR_MULT:
10191 gen_muldiv(ctx, OPC_MULT, rx, ry);
10192 break;
10193 case RR_MULTU:
10194 gen_muldiv(ctx, OPC_MULTU, rx, ry);
10195 break;
10196 case RR_DIV:
10197 gen_muldiv(ctx, OPC_DIV, rx, ry);
10198 break;
10199 case RR_DIVU:
10200 gen_muldiv(ctx, OPC_DIVU, rx, ry);
10201 break;
10202 #if defined (TARGET_MIPS64)
10203 case RR_DMULT:
10204 check_mips_64(ctx);
10205 gen_muldiv(ctx, OPC_DMULT, rx, ry);
10206 break;
10207 case RR_DMULTU:
10208 check_mips_64(ctx);
10209 gen_muldiv(ctx, OPC_DMULTU, rx, ry);
10210 break;
10211 case RR_DDIV:
10212 check_mips_64(ctx);
10213 gen_muldiv(ctx, OPC_DDIV, rx, ry);
10214 break;
10215 case RR_DDIVU:
10216 check_mips_64(ctx);
10217 gen_muldiv(ctx, OPC_DDIVU, rx, ry);
10218 break;
10219 #endif
10220 default:
10221 generate_exception(ctx, EXCP_RI);
10222 break;
10224 break;
10225 case M16_OPC_EXTEND:
10226 decode_extended_mips16_opc(env, ctx, is_branch);
10227 n_bytes = 4;
10228 break;
10229 #if defined(TARGET_MIPS64)
10230 case M16_OPC_I64:
10231 funct = (ctx->opcode >> 8) & 0x7;
10232 decode_i64_mips16(ctx, ry, funct, offset, 0);
10233 break;
10234 #endif
10235 default:
10236 generate_exception(ctx, EXCP_RI);
10237 break;
10240 return n_bytes;
10243 /* microMIPS extension to MIPS32/MIPS64 */
10246 * microMIPS32/microMIPS64 major opcodes
10248 * 1. MIPS Architecture for Programmers Volume II-B:
10249 * The microMIPS32 Instruction Set (Revision 3.05)
10251 * Table 6.2 microMIPS32 Encoding of Major Opcode Field
10253 * 2. MIPS Architecture For Programmers Volume II-A:
10254 * The MIPS64 Instruction Set (Revision 3.51)
10257 enum {
10258 POOL32A = 0x00,
10259 POOL16A = 0x01,
10260 LBU16 = 0x02,
10261 MOVE16 = 0x03,
10262 ADDI32 = 0x04,
10263 LBU32 = 0x05,
10264 SB32 = 0x06,
10265 LB32 = 0x07,
10267 POOL32B = 0x08,
10268 POOL16B = 0x09,
10269 LHU16 = 0x0a,
10270 ANDI16 = 0x0b,
10271 ADDIU32 = 0x0c,
10272 LHU32 = 0x0d,
10273 SH32 = 0x0e,
10274 LH32 = 0x0f,
10276 POOL32I = 0x10,
10277 POOL16C = 0x11,
10278 LWSP16 = 0x12,
10279 POOL16D = 0x13,
10280 ORI32 = 0x14,
10281 POOL32F = 0x15,
10282 POOL32S = 0x16, /* MIPS64 */
10283 DADDIU32 = 0x17, /* MIPS64 */
10285 /* 0x1f is reserved */
10286 POOL32C = 0x18,
10287 LWGP16 = 0x19,
10288 LW16 = 0x1a,
10289 POOL16E = 0x1b,
10290 XORI32 = 0x1c,
10291 JALS32 = 0x1d,
10292 ADDIUPC = 0x1e,
10294 /* 0x20 is reserved */
10295 RES_20 = 0x20,
10296 POOL16F = 0x21,
10297 SB16 = 0x22,
10298 BEQZ16 = 0x23,
10299 SLTI32 = 0x24,
10300 BEQ32 = 0x25,
10301 SWC132 = 0x26,
10302 LWC132 = 0x27,
10304 /* 0x28 and 0x29 are reserved */
10305 RES_28 = 0x28,
10306 RES_29 = 0x29,
10307 SH16 = 0x2a,
10308 BNEZ16 = 0x2b,
10309 SLTIU32 = 0x2c,
10310 BNE32 = 0x2d,
10311 SDC132 = 0x2e,
10312 LDC132 = 0x2f,
10314 /* 0x30 and 0x31 are reserved */
10315 RES_30 = 0x30,
10316 RES_31 = 0x31,
10317 SWSP16 = 0x32,
10318 B16 = 0x33,
10319 ANDI32 = 0x34,
10320 J32 = 0x35,
10321 SD32 = 0x36, /* MIPS64 */
10322 LD32 = 0x37, /* MIPS64 */
10324 /* 0x38 and 0x39 are reserved */
10325 RES_38 = 0x38,
10326 RES_39 = 0x39,
10327 SW16 = 0x3a,
10328 LI16 = 0x3b,
10329 JALX32 = 0x3c,
10330 JAL32 = 0x3d,
10331 SW32 = 0x3e,
10332 LW32 = 0x3f
10335 /* POOL32A encoding of minor opcode field */
10337 enum {
10338 /* These opcodes are distinguished only by bits 9..6; those bits are
10339 * what are recorded below. */
10340 SLL32 = 0x0,
10341 SRL32 = 0x1,
10342 SRA = 0x2,
10343 ROTR = 0x3,
10345 SLLV = 0x0,
10346 SRLV = 0x1,
10347 SRAV = 0x2,
10348 ROTRV = 0x3,
10349 ADD = 0x4,
10350 ADDU32 = 0x5,
10351 SUB = 0x6,
10352 SUBU32 = 0x7,
10353 MUL = 0x8,
10354 AND = 0x9,
10355 OR32 = 0xa,
10356 NOR = 0xb,
10357 XOR32 = 0xc,
10358 SLT = 0xd,
10359 SLTU = 0xe,
10361 MOVN = 0x0,
10362 MOVZ = 0x1,
10363 LWXS = 0x4,
10365 /* The following can be distinguished by their lower 6 bits. */
10366 INS = 0x0c,
10367 EXT = 0x2c,
10368 POOL32AXF = 0x3c
10371 /* POOL32AXF encoding of minor opcode field extension */
10374 * 1. MIPS Architecture for Programmers Volume II-B:
10375 * The microMIPS32 Instruction Set (Revision 3.05)
10377 * Table 6.5 POOL32Axf Encoding of Minor Opcode Extension Field
10379 * 2. MIPS Architecture for Programmers VolumeIV-e:
10380 * The MIPS DSP Application-Specific Extension
10381 * to the microMIPS32 Architecture (Revision 2.34)
10383 * Table 5.5 POOL32Axf Encoding of Minor Opcode Extension Field
10386 enum {
10387 /* bits 11..6 */
10388 TEQ = 0x00,
10389 TGE = 0x08,
10390 TGEU = 0x10,
10391 TLT = 0x20,
10392 TLTU = 0x28,
10393 TNE = 0x30,
10395 MFC0 = 0x03,
10396 MTC0 = 0x0b,
10398 /* begin of microMIPS32 DSP */
10400 /* bits 13..12 for 0x01 */
10401 MFHI_ACC = 0x0,
10402 MFLO_ACC = 0x1,
10403 MTHI_ACC = 0x2,
10404 MTLO_ACC = 0x3,
10406 /* bits 13..12 for 0x2a */
10407 MADD_ACC = 0x0,
10408 MADDU_ACC = 0x1,
10409 MSUB_ACC = 0x2,
10410 MSUBU_ACC = 0x3,
10412 /* bits 13..12 for 0x32 */
10413 MULT_ACC = 0x0,
10414 MULTU_ACC = 0x1,
10416 /* end of microMIPS32 DSP */
10418 /* bits 15..12 for 0x2c */
10419 SEB = 0x2,
10420 SEH = 0x3,
10421 CLO = 0x4,
10422 CLZ = 0x5,
10423 RDHWR = 0x6,
10424 WSBH = 0x7,
10425 MULT = 0x8,
10426 MULTU = 0x9,
10427 DIV = 0xa,
10428 DIVU = 0xb,
10429 MADD = 0xc,
10430 MADDU = 0xd,
10431 MSUB = 0xe,
10432 MSUBU = 0xf,
10434 /* bits 15..12 for 0x34 */
10435 MFC2 = 0x4,
10436 MTC2 = 0x5,
10437 MFHC2 = 0x8,
10438 MTHC2 = 0x9,
10439 CFC2 = 0xc,
10440 CTC2 = 0xd,
10442 /* bits 15..12 for 0x3c */
10443 JALR = 0x0,
10444 JR = 0x0, /* alias */
10445 JALR_HB = 0x1,
10446 JALRS = 0x4,
10447 JALRS_HB = 0x5,
10449 /* bits 15..12 for 0x05 */
10450 RDPGPR = 0xe,
10451 WRPGPR = 0xf,
10453 /* bits 15..12 for 0x0d */
10454 TLBP = 0x0,
10455 TLBR = 0x1,
10456 TLBWI = 0x2,
10457 TLBWR = 0x3,
10458 WAIT = 0x9,
10459 IRET = 0xd,
10460 DERET = 0xe,
10461 ERET = 0xf,
10463 /* bits 15..12 for 0x15 */
10464 DMT = 0x0,
10465 DVPE = 0x1,
10466 EMT = 0x2,
10467 EVPE = 0x3,
10469 /* bits 15..12 for 0x1d */
10470 DI = 0x4,
10471 EI = 0x5,
10473 /* bits 15..12 for 0x2d */
10474 SYNC = 0x6,
10475 SYSCALL = 0x8,
10476 SDBBP = 0xd,
10478 /* bits 15..12 for 0x35 */
10479 MFHI32 = 0x0,
10480 MFLO32 = 0x1,
10481 MTHI32 = 0x2,
10482 MTLO32 = 0x3,
10485 /* POOL32B encoding of minor opcode field (bits 15..12) */
10487 enum {
10488 LWC2 = 0x0,
10489 LWP = 0x1,
10490 LDP = 0x4,
10491 LWM32 = 0x5,
10492 CACHE = 0x6,
10493 LDM = 0x7,
10494 SWC2 = 0x8,
10495 SWP = 0x9,
10496 SDP = 0xc,
10497 SWM32 = 0xd,
10498 SDM = 0xf
10501 /* POOL32C encoding of minor opcode field (bits 15..12) */
10503 enum {
10504 LWL = 0x0,
10505 SWL = 0x8,
10506 LWR = 0x1,
10507 SWR = 0x9,
10508 PREF = 0x2,
10509 /* 0xa is reserved */
10510 LL = 0x3,
10511 SC = 0xb,
10512 LDL = 0x4,
10513 SDL = 0xc,
10514 LDR = 0x5,
10515 SDR = 0xd,
10516 /* 0x6 is reserved */
10517 LWU = 0xe,
10518 LLD = 0x7,
10519 SCD = 0xf
10522 /* POOL32F encoding of minor opcode field (bits 5..0) */
10524 enum {
10525 /* These are the bit 7..6 values */
10526 ADD_FMT = 0x0,
10527 MOVN_FMT = 0x0,
10529 SUB_FMT = 0x1,
10530 MOVZ_FMT = 0x1,
10532 MUL_FMT = 0x2,
10534 DIV_FMT = 0x3,
10536 /* These are the bit 8..6 values */
10537 RSQRT2_FMT = 0x0,
10538 MOVF_FMT = 0x0,
10540 LWXC1 = 0x1,
10541 MOVT_FMT = 0x1,
10543 PLL_PS = 0x2,
10544 SWXC1 = 0x2,
10546 PLU_PS = 0x3,
10547 LDXC1 = 0x3,
10549 PUL_PS = 0x4,
10550 SDXC1 = 0x4,
10551 RECIP2_FMT = 0x4,
10553 PUU_PS = 0x5,
10554 LUXC1 = 0x5,
10556 CVT_PS_S = 0x6,
10557 SUXC1 = 0x6,
10558 ADDR_PS = 0x6,
10559 PREFX = 0x6,
10561 MULR_PS = 0x7,
10563 MADD_S = 0x01,
10564 MADD_D = 0x09,
10565 MADD_PS = 0x11,
10566 ALNV_PS = 0x19,
10567 MSUB_S = 0x21,
10568 MSUB_D = 0x29,
10569 MSUB_PS = 0x31,
10571 NMADD_S = 0x02,
10572 NMADD_D = 0x0a,
10573 NMADD_PS = 0x12,
10574 NMSUB_S = 0x22,
10575 NMSUB_D = 0x2a,
10576 NMSUB_PS = 0x32,
10578 POOL32FXF = 0x3b,
10580 CABS_COND_FMT = 0x1c, /* MIPS3D */
10581 C_COND_FMT = 0x3c
10584 /* POOL32Fxf encoding of minor opcode extension field */
10586 enum {
10587 CVT_L = 0x04,
10588 RSQRT_FMT = 0x08,
10589 FLOOR_L = 0x0c,
10590 CVT_PW_PS = 0x1c,
10591 CVT_W = 0x24,
10592 SQRT_FMT = 0x28,
10593 FLOOR_W = 0x2c,
10594 CVT_PS_PW = 0x3c,
10595 CFC1 = 0x40,
10596 RECIP_FMT = 0x48,
10597 CEIL_L = 0x4c,
10598 CTC1 = 0x60,
10599 CEIL_W = 0x6c,
10600 MFC1 = 0x80,
10601 CVT_S_PL = 0x84,
10602 TRUNC_L = 0x8c,
10603 MTC1 = 0xa0,
10604 CVT_S_PU = 0xa4,
10605 TRUNC_W = 0xac,
10606 MFHC1 = 0xc0,
10607 ROUND_L = 0xcc,
10608 MTHC1 = 0xe0,
10609 ROUND_W = 0xec,
10611 MOV_FMT = 0x01,
10612 MOVF = 0x05,
10613 ABS_FMT = 0x0d,
10614 RSQRT1_FMT = 0x1d,
10615 MOVT = 0x25,
10616 NEG_FMT = 0x2d,
10617 CVT_D = 0x4d,
10618 RECIP1_FMT = 0x5d,
10619 CVT_S = 0x6d
10622 /* POOL32I encoding of minor opcode field (bits 25..21) */
10624 enum {
10625 BLTZ = 0x00,
10626 BLTZAL = 0x01,
10627 BGEZ = 0x02,
10628 BGEZAL = 0x03,
10629 BLEZ = 0x04,
10630 BNEZC = 0x05,
10631 BGTZ = 0x06,
10632 BEQZC = 0x07,
10633 TLTI = 0x08,
10634 TGEI = 0x09,
10635 TLTIU = 0x0a,
10636 TGEIU = 0x0b,
10637 TNEI = 0x0c,
10638 LUI = 0x0d,
10639 TEQI = 0x0e,
10640 SYNCI = 0x10,
10641 BLTZALS = 0x11,
10642 BGEZALS = 0x13,
10643 BC2F = 0x14,
10644 BC2T = 0x15,
10645 BPOSGE64 = 0x1a,
10646 BPOSGE32 = 0x1b,
10647 /* These overlap and are distinguished by bit16 of the instruction */
10648 BC1F = 0x1c,
10649 BC1T = 0x1d,
10650 BC1ANY2F = 0x1c,
10651 BC1ANY2T = 0x1d,
10652 BC1ANY4F = 0x1e,
10653 BC1ANY4T = 0x1f
10656 /* POOL16A encoding of minor opcode field */
10658 enum {
10659 ADDU16 = 0x0,
10660 SUBU16 = 0x1
10663 /* POOL16B encoding of minor opcode field */
10665 enum {
10666 SLL16 = 0x0,
10667 SRL16 = 0x1
10670 /* POOL16C encoding of minor opcode field */
10672 enum {
10673 NOT16 = 0x00,
10674 XOR16 = 0x04,
10675 AND16 = 0x08,
10676 OR16 = 0x0c,
10677 LWM16 = 0x10,
10678 SWM16 = 0x14,
10679 JR16 = 0x18,
10680 JRC16 = 0x1a,
10681 JALR16 = 0x1c,
10682 JALR16S = 0x1e,
10683 MFHI16 = 0x20,
10684 MFLO16 = 0x24,
10685 BREAK16 = 0x28,
10686 SDBBP16 = 0x2c,
10687 JRADDIUSP = 0x30
10690 /* POOL16D encoding of minor opcode field */
10692 enum {
10693 ADDIUS5 = 0x0,
10694 ADDIUSP = 0x1
10697 /* POOL16E encoding of minor opcode field */
10699 enum {
10700 ADDIUR2 = 0x0,
10701 ADDIUR1SP = 0x1
10704 static int mmreg (int r)
10706 static const int map[] = { 16, 17, 2, 3, 4, 5, 6, 7 };
10708 return map[r];
10711 /* Used for 16-bit store instructions. */
10712 static int mmreg2 (int r)
10714 static const int map[] = { 0, 17, 2, 3, 4, 5, 6, 7 };
10716 return map[r];
10719 #define uMIPS_RD(op) ((op >> 7) & 0x7)
10720 #define uMIPS_RS(op) ((op >> 4) & 0x7)
10721 #define uMIPS_RS2(op) uMIPS_RS(op)
10722 #define uMIPS_RS1(op) ((op >> 1) & 0x7)
10723 #define uMIPS_RD5(op) ((op >> 5) & 0x1f)
10724 #define uMIPS_RS5(op) (op & 0x1f)
10726 /* Signed immediate */
10727 #define SIMM(op, start, width) \
10728 ((int32_t)(((op >> start) & ((~0U) >> (32-width))) \
10729 << (32-width)) \
10730 >> (32-width))
10731 /* Zero-extended immediate */
10732 #define ZIMM(op, start, width) ((op >> start) & ((~0U) >> (32-width)))
10734 static void gen_addiur1sp(DisasContext *ctx)
10736 int rd = mmreg(uMIPS_RD(ctx->opcode));
10738 gen_arith_imm(ctx, OPC_ADDIU, rd, 29, ((ctx->opcode >> 1) & 0x3f) << 2);
10741 static void gen_addiur2(DisasContext *ctx)
10743 static const int decoded_imm[] = { 1, 4, 8, 12, 16, 20, 24, -1 };
10744 int rd = mmreg(uMIPS_RD(ctx->opcode));
10745 int rs = mmreg(uMIPS_RS(ctx->opcode));
10747 gen_arith_imm(ctx, OPC_ADDIU, rd, rs, decoded_imm[ZIMM(ctx->opcode, 1, 3)]);
10750 static void gen_addiusp(DisasContext *ctx)
10752 int encoded = ZIMM(ctx->opcode, 1, 9);
10753 int decoded;
10755 if (encoded <= 1) {
10756 decoded = 256 + encoded;
10757 } else if (encoded <= 255) {
10758 decoded = encoded;
10759 } else if (encoded <= 509) {
10760 decoded = encoded - 512;
10761 } else {
10762 decoded = encoded - 768;
10765 gen_arith_imm(ctx, OPC_ADDIU, 29, 29, decoded << 2);
10768 static void gen_addius5(DisasContext *ctx)
10770 int imm = SIMM(ctx->opcode, 1, 4);
10771 int rd = (ctx->opcode >> 5) & 0x1f;
10773 gen_arith_imm(ctx, OPC_ADDIU, rd, rd, imm);
10776 static void gen_andi16(DisasContext *ctx)
10778 static const int decoded_imm[] = { 128, 1, 2, 3, 4, 7, 8, 15, 16,
10779 31, 32, 63, 64, 255, 32768, 65535 };
10780 int rd = mmreg(uMIPS_RD(ctx->opcode));
10781 int rs = mmreg(uMIPS_RS(ctx->opcode));
10782 int encoded = ZIMM(ctx->opcode, 0, 4);
10784 gen_logic_imm(ctx, OPC_ANDI, rd, rs, decoded_imm[encoded]);
10787 static void gen_ldst_multiple (DisasContext *ctx, uint32_t opc, int reglist,
10788 int base, int16_t offset)
10790 const char *opn = "ldst_multiple";
10791 TCGv t0, t1;
10792 TCGv_i32 t2;
10794 if (ctx->hflags & MIPS_HFLAG_BMASK) {
10795 generate_exception(ctx, EXCP_RI);
10796 return;
10799 t0 = tcg_temp_new();
10801 gen_base_offset_addr(ctx, t0, base, offset);
10803 t1 = tcg_const_tl(reglist);
10804 t2 = tcg_const_i32(ctx->mem_idx);
10806 save_cpu_state(ctx, 1);
10807 switch (opc) {
10808 case LWM32:
10809 gen_helper_lwm(cpu_env, t0, t1, t2);
10810 opn = "lwm";
10811 break;
10812 case SWM32:
10813 gen_helper_swm(cpu_env, t0, t1, t2);
10814 opn = "swm";
10815 break;
10816 #ifdef TARGET_MIPS64
10817 case LDM:
10818 gen_helper_ldm(cpu_env, t0, t1, t2);
10819 opn = "ldm";
10820 break;
10821 case SDM:
10822 gen_helper_sdm(cpu_env, t0, t1, t2);
10823 opn = "sdm";
10824 break;
10825 #endif
10827 (void)opn;
10828 MIPS_DEBUG("%s, %x, %d(%s)", opn, reglist, offset, regnames[base]);
10829 tcg_temp_free(t0);
10830 tcg_temp_free(t1);
10831 tcg_temp_free_i32(t2);
10835 static void gen_pool16c_insn(DisasContext *ctx, int *is_branch)
10837 int rd = mmreg((ctx->opcode >> 3) & 0x7);
10838 int rs = mmreg(ctx->opcode & 0x7);
10839 int opc;
10841 switch (((ctx->opcode) >> 4) & 0x3f) {
10842 case NOT16 + 0:
10843 case NOT16 + 1:
10844 case NOT16 + 2:
10845 case NOT16 + 3:
10846 gen_logic(ctx, OPC_NOR, rd, rs, 0);
10847 break;
10848 case XOR16 + 0:
10849 case XOR16 + 1:
10850 case XOR16 + 2:
10851 case XOR16 + 3:
10852 gen_logic(ctx, OPC_XOR, rd, rd, rs);
10853 break;
10854 case AND16 + 0:
10855 case AND16 + 1:
10856 case AND16 + 2:
10857 case AND16 + 3:
10858 gen_logic(ctx, OPC_AND, rd, rd, rs);
10859 break;
10860 case OR16 + 0:
10861 case OR16 + 1:
10862 case OR16 + 2:
10863 case OR16 + 3:
10864 gen_logic(ctx, OPC_OR, rd, rd, rs);
10865 break;
10866 case LWM16 + 0:
10867 case LWM16 + 1:
10868 case LWM16 + 2:
10869 case LWM16 + 3:
10871 static const int lwm_convert[] = { 0x11, 0x12, 0x13, 0x14 };
10872 int offset = ZIMM(ctx->opcode, 0, 4);
10874 gen_ldst_multiple(ctx, LWM32, lwm_convert[(ctx->opcode >> 4) & 0x3],
10875 29, offset << 2);
10877 break;
10878 case SWM16 + 0:
10879 case SWM16 + 1:
10880 case SWM16 + 2:
10881 case SWM16 + 3:
10883 static const int swm_convert[] = { 0x11, 0x12, 0x13, 0x14 };
10884 int offset = ZIMM(ctx->opcode, 0, 4);
10886 gen_ldst_multiple(ctx, SWM32, swm_convert[(ctx->opcode >> 4) & 0x3],
10887 29, offset << 2);
10889 break;
10890 case JR16 + 0:
10891 case JR16 + 1:
10893 int reg = ctx->opcode & 0x1f;
10895 gen_compute_branch(ctx, OPC_JR, 2, reg, 0, 0);
10897 *is_branch = 1;
10898 break;
10899 case JRC16 + 0:
10900 case JRC16 + 1:
10902 int reg = ctx->opcode & 0x1f;
10904 gen_compute_branch(ctx, OPC_JR, 2, reg, 0, 0);
10905 /* Let normal delay slot handling in our caller take us
10906 to the branch target. */
10908 break;
10909 case JALR16 + 0:
10910 case JALR16 + 1:
10911 opc = OPC_JALR;
10912 goto do_jalr;
10913 case JALR16S + 0:
10914 case JALR16S + 1:
10915 opc = OPC_JALRS;
10916 do_jalr:
10918 int reg = ctx->opcode & 0x1f;
10920 gen_compute_branch(ctx, opc, 2, reg, 31, 0);
10922 *is_branch = 1;
10923 break;
10924 case MFHI16 + 0:
10925 case MFHI16 + 1:
10926 gen_HILO(ctx, OPC_MFHI, uMIPS_RS5(ctx->opcode));
10927 break;
10928 case MFLO16 + 0:
10929 case MFLO16 + 1:
10930 gen_HILO(ctx, OPC_MFLO, uMIPS_RS5(ctx->opcode));
10931 break;
10932 case BREAK16:
10933 generate_exception(ctx, EXCP_BREAK);
10934 break;
10935 case SDBBP16:
10936 /* XXX: not clear which exception should be raised
10937 * when in debug mode...
10939 check_insn(ctx, ISA_MIPS32);
10940 if (!(ctx->hflags & MIPS_HFLAG_DM)) {
10941 generate_exception(ctx, EXCP_DBp);
10942 } else {
10943 generate_exception(ctx, EXCP_DBp);
10945 break;
10946 case JRADDIUSP + 0:
10947 case JRADDIUSP + 1:
10949 int imm = ZIMM(ctx->opcode, 0, 5);
10951 gen_compute_branch(ctx, OPC_JR, 2, 31, 0, 0);
10952 gen_arith_imm(ctx, OPC_ADDIU, 29, 29, imm << 2);
10953 /* Let normal delay slot handling in our caller take us
10954 to the branch target. */
10956 break;
10957 default:
10958 generate_exception(ctx, EXCP_RI);
10959 break;
10963 static void gen_ldxs (DisasContext *ctx, int base, int index, int rd)
10965 TCGv t0 = tcg_temp_new();
10966 TCGv t1 = tcg_temp_new();
10968 gen_load_gpr(t0, base);
10970 if (index != 0) {
10971 gen_load_gpr(t1, index);
10972 tcg_gen_shli_tl(t1, t1, 2);
10973 gen_op_addr_add(ctx, t0, t1, t0);
10976 tcg_gen_qemu_ld32s(t1, t0, ctx->mem_idx);
10977 gen_store_gpr(t1, rd);
10979 tcg_temp_free(t0);
10980 tcg_temp_free(t1);
10983 static void gen_ldst_pair (DisasContext *ctx, uint32_t opc, int rd,
10984 int base, int16_t offset)
10986 const char *opn = "ldst_pair";
10987 TCGv t0, t1;
10989 if (ctx->hflags & MIPS_HFLAG_BMASK || rd == 31) {
10990 generate_exception(ctx, EXCP_RI);
10991 return;
10994 t0 = tcg_temp_new();
10995 t1 = tcg_temp_new();
10997 gen_base_offset_addr(ctx, t0, base, offset);
10999 switch (opc) {
11000 case LWP:
11001 if (rd == base) {
11002 generate_exception(ctx, EXCP_RI);
11003 return;
11005 tcg_gen_qemu_ld32s(t1, t0, ctx->mem_idx);
11006 gen_store_gpr(t1, rd);
11007 tcg_gen_movi_tl(t1, 4);
11008 gen_op_addr_add(ctx, t0, t0, t1);
11009 tcg_gen_qemu_ld32s(t1, t0, ctx->mem_idx);
11010 gen_store_gpr(t1, rd+1);
11011 opn = "lwp";
11012 break;
11013 case SWP:
11014 gen_load_gpr(t1, rd);
11015 tcg_gen_qemu_st32(t1, t0, ctx->mem_idx);
11016 tcg_gen_movi_tl(t1, 4);
11017 gen_op_addr_add(ctx, t0, t0, t1);
11018 gen_load_gpr(t1, rd+1);
11019 tcg_gen_qemu_st32(t1, t0, ctx->mem_idx);
11020 opn = "swp";
11021 break;
11022 #ifdef TARGET_MIPS64
11023 case LDP:
11024 if (rd == base) {
11025 generate_exception(ctx, EXCP_RI);
11026 return;
11028 tcg_gen_qemu_ld64(t1, t0, ctx->mem_idx);
11029 gen_store_gpr(t1, rd);
11030 tcg_gen_movi_tl(t1, 8);
11031 gen_op_addr_add(ctx, t0, t0, t1);
11032 tcg_gen_qemu_ld64(t1, t0, ctx->mem_idx);
11033 gen_store_gpr(t1, rd+1);
11034 opn = "ldp";
11035 break;
11036 case SDP:
11037 gen_load_gpr(t1, rd);
11038 tcg_gen_qemu_st64(t1, t0, ctx->mem_idx);
11039 tcg_gen_movi_tl(t1, 8);
11040 gen_op_addr_add(ctx, t0, t0, t1);
11041 gen_load_gpr(t1, rd+1);
11042 tcg_gen_qemu_st64(t1, t0, ctx->mem_idx);
11043 opn = "sdp";
11044 break;
11045 #endif
11047 (void)opn; /* avoid a compiler warning */
11048 MIPS_DEBUG("%s, %s, %d(%s)", opn, regnames[rd], offset, regnames[base]);
11049 tcg_temp_free(t0);
11050 tcg_temp_free(t1);
11053 static void gen_pool32axf (CPUMIPSState *env, DisasContext *ctx, int rt, int rs,
11054 int *is_branch)
11056 int extension = (ctx->opcode >> 6) & 0x3f;
11057 int minor = (ctx->opcode >> 12) & 0xf;
11058 uint32_t mips32_op;
11060 switch (extension) {
11061 case TEQ:
11062 mips32_op = OPC_TEQ;
11063 goto do_trap;
11064 case TGE:
11065 mips32_op = OPC_TGE;
11066 goto do_trap;
11067 case TGEU:
11068 mips32_op = OPC_TGEU;
11069 goto do_trap;
11070 case TLT:
11071 mips32_op = OPC_TLT;
11072 goto do_trap;
11073 case TLTU:
11074 mips32_op = OPC_TLTU;
11075 goto do_trap;
11076 case TNE:
11077 mips32_op = OPC_TNE;
11078 do_trap:
11079 gen_trap(ctx, mips32_op, rs, rt, -1);
11080 break;
11081 #ifndef CONFIG_USER_ONLY
11082 case MFC0:
11083 case MFC0 + 32:
11084 check_cp0_enabled(ctx);
11085 if (rt == 0) {
11086 /* Treat as NOP. */
11087 break;
11089 gen_mfc0(ctx, cpu_gpr[rt], rs, (ctx->opcode >> 11) & 0x7);
11090 break;
11091 case MTC0:
11092 case MTC0 + 32:
11093 check_cp0_enabled(ctx);
11095 TCGv t0 = tcg_temp_new();
11097 gen_load_gpr(t0, rt);
11098 gen_mtc0(ctx, t0, rs, (ctx->opcode >> 11) & 0x7);
11099 tcg_temp_free(t0);
11101 break;
11102 #endif
11103 case 0x2c:
11104 switch (minor) {
11105 case SEB:
11106 gen_bshfl(ctx, OPC_SEB, rs, rt);
11107 break;
11108 case SEH:
11109 gen_bshfl(ctx, OPC_SEH, rs, rt);
11110 break;
11111 case CLO:
11112 mips32_op = OPC_CLO;
11113 goto do_cl;
11114 case CLZ:
11115 mips32_op = OPC_CLZ;
11116 do_cl:
11117 check_insn(ctx, ISA_MIPS32);
11118 gen_cl(ctx, mips32_op, rt, rs);
11119 break;
11120 case RDHWR:
11121 gen_rdhwr(ctx, rt, rs);
11122 break;
11123 case WSBH:
11124 gen_bshfl(ctx, OPC_WSBH, rs, rt);
11125 break;
11126 case MULT:
11127 mips32_op = OPC_MULT;
11128 goto do_muldiv;
11129 case MULTU:
11130 mips32_op = OPC_MULTU;
11131 goto do_muldiv;
11132 case DIV:
11133 mips32_op = OPC_DIV;
11134 goto do_muldiv;
11135 case DIVU:
11136 mips32_op = OPC_DIVU;
11137 goto do_muldiv;
11138 case MADD:
11139 mips32_op = OPC_MADD;
11140 goto do_muldiv;
11141 case MADDU:
11142 mips32_op = OPC_MADDU;
11143 goto do_muldiv;
11144 case MSUB:
11145 mips32_op = OPC_MSUB;
11146 goto do_muldiv;
11147 case MSUBU:
11148 mips32_op = OPC_MSUBU;
11149 do_muldiv:
11150 check_insn(ctx, ISA_MIPS32);
11151 gen_muldiv(ctx, mips32_op, rs, rt);
11152 break;
11153 default:
11154 goto pool32axf_invalid;
11156 break;
11157 case 0x34:
11158 switch (minor) {
11159 case MFC2:
11160 case MTC2:
11161 case MFHC2:
11162 case MTHC2:
11163 case CFC2:
11164 case CTC2:
11165 generate_exception_err(ctx, EXCP_CpU, 2);
11166 break;
11167 default:
11168 goto pool32axf_invalid;
11170 break;
11171 case 0x3c:
11172 switch (minor) {
11173 case JALR:
11174 case JALR_HB:
11175 gen_compute_branch (ctx, OPC_JALR, 4, rs, rt, 0);
11176 *is_branch = 1;
11177 break;
11178 case JALRS:
11179 case JALRS_HB:
11180 gen_compute_branch (ctx, OPC_JALRS, 4, rs, rt, 0);
11181 *is_branch = 1;
11182 break;
11183 default:
11184 goto pool32axf_invalid;
11186 break;
11187 case 0x05:
11188 switch (minor) {
11189 case RDPGPR:
11190 check_cp0_enabled(ctx);
11191 check_insn(ctx, ISA_MIPS32R2);
11192 gen_load_srsgpr(rt, rs);
11193 break;
11194 case WRPGPR:
11195 check_cp0_enabled(ctx);
11196 check_insn(ctx, ISA_MIPS32R2);
11197 gen_store_srsgpr(rt, rs);
11198 break;
11199 default:
11200 goto pool32axf_invalid;
11202 break;
11203 #ifndef CONFIG_USER_ONLY
11204 case 0x0d:
11205 switch (minor) {
11206 case TLBP:
11207 mips32_op = OPC_TLBP;
11208 goto do_cp0;
11209 case TLBR:
11210 mips32_op = OPC_TLBR;
11211 goto do_cp0;
11212 case TLBWI:
11213 mips32_op = OPC_TLBWI;
11214 goto do_cp0;
11215 case TLBWR:
11216 mips32_op = OPC_TLBWR;
11217 goto do_cp0;
11218 case WAIT:
11219 mips32_op = OPC_WAIT;
11220 goto do_cp0;
11221 case DERET:
11222 mips32_op = OPC_DERET;
11223 goto do_cp0;
11224 case ERET:
11225 mips32_op = OPC_ERET;
11226 do_cp0:
11227 gen_cp0(env, ctx, mips32_op, rt, rs);
11228 break;
11229 default:
11230 goto pool32axf_invalid;
11232 break;
11233 case 0x1d:
11234 switch (minor) {
11235 case DI:
11236 check_cp0_enabled(ctx);
11238 TCGv t0 = tcg_temp_new();
11240 save_cpu_state(ctx, 1);
11241 gen_helper_di(t0, cpu_env);
11242 gen_store_gpr(t0, rs);
11243 /* Stop translation as we may have switched the execution mode */
11244 ctx->bstate = BS_STOP;
11245 tcg_temp_free(t0);
11247 break;
11248 case EI:
11249 check_cp0_enabled(ctx);
11251 TCGv t0 = tcg_temp_new();
11253 save_cpu_state(ctx, 1);
11254 gen_helper_ei(t0, cpu_env);
11255 gen_store_gpr(t0, rs);
11256 /* Stop translation as we may have switched the execution mode */
11257 ctx->bstate = BS_STOP;
11258 tcg_temp_free(t0);
11260 break;
11261 default:
11262 goto pool32axf_invalid;
11264 break;
11265 #endif
11266 case 0x2d:
11267 switch (minor) {
11268 case SYNC:
11269 /* NOP */
11270 break;
11271 case SYSCALL:
11272 generate_exception(ctx, EXCP_SYSCALL);
11273 ctx->bstate = BS_STOP;
11274 break;
11275 case SDBBP:
11276 check_insn(ctx, ISA_MIPS32);
11277 if (!(ctx->hflags & MIPS_HFLAG_DM)) {
11278 generate_exception(ctx, EXCP_DBp);
11279 } else {
11280 generate_exception(ctx, EXCP_DBp);
11282 break;
11283 default:
11284 goto pool32axf_invalid;
11286 break;
11287 case 0x35:
11288 switch (minor) {
11289 case MFHI32:
11290 gen_HILO(ctx, OPC_MFHI, rs);
11291 break;
11292 case MFLO32:
11293 gen_HILO(ctx, OPC_MFLO, rs);
11294 break;
11295 case MTHI32:
11296 gen_HILO(ctx, OPC_MTHI, rs);
11297 break;
11298 case MTLO32:
11299 gen_HILO(ctx, OPC_MTLO, rs);
11300 break;
11301 default:
11302 goto pool32axf_invalid;
11304 break;
11305 default:
11306 pool32axf_invalid:
11307 MIPS_INVAL("pool32axf");
11308 generate_exception(ctx, EXCP_RI);
11309 break;
11313 /* Values for microMIPS fmt field. Variable-width, depending on which
11314 formats the instruction supports. */
11316 enum {
11317 FMT_SD_S = 0,
11318 FMT_SD_D = 1,
11320 FMT_SDPS_S = 0,
11321 FMT_SDPS_D = 1,
11322 FMT_SDPS_PS = 2,
11324 FMT_SWL_S = 0,
11325 FMT_SWL_W = 1,
11326 FMT_SWL_L = 2,
11328 FMT_DWL_D = 0,
11329 FMT_DWL_W = 1,
11330 FMT_DWL_L = 2
11333 static void gen_pool32fxf(DisasContext *ctx, int rt, int rs)
11335 int extension = (ctx->opcode >> 6) & 0x3ff;
11336 uint32_t mips32_op;
11338 #define FLOAT_1BIT_FMT(opc, fmt) (fmt << 8) | opc
11339 #define FLOAT_2BIT_FMT(opc, fmt) (fmt << 7) | opc
11340 #define COND_FLOAT_MOV(opc, cond) (cond << 7) | opc
11342 switch (extension) {
11343 case FLOAT_1BIT_FMT(CFC1, 0):
11344 mips32_op = OPC_CFC1;
11345 goto do_cp1;
11346 case FLOAT_1BIT_FMT(CTC1, 0):
11347 mips32_op = OPC_CTC1;
11348 goto do_cp1;
11349 case FLOAT_1BIT_FMT(MFC1, 0):
11350 mips32_op = OPC_MFC1;
11351 goto do_cp1;
11352 case FLOAT_1BIT_FMT(MTC1, 0):
11353 mips32_op = OPC_MTC1;
11354 goto do_cp1;
11355 case FLOAT_1BIT_FMT(MFHC1, 0):
11356 mips32_op = OPC_MFHC1;
11357 goto do_cp1;
11358 case FLOAT_1BIT_FMT(MTHC1, 0):
11359 mips32_op = OPC_MTHC1;
11360 do_cp1:
11361 gen_cp1(ctx, mips32_op, rt, rs);
11362 break;
11364 /* Reciprocal square root */
11365 case FLOAT_1BIT_FMT(RSQRT_FMT, FMT_SD_S):
11366 mips32_op = OPC_RSQRT_S;
11367 goto do_unaryfp;
11368 case FLOAT_1BIT_FMT(RSQRT_FMT, FMT_SD_D):
11369 mips32_op = OPC_RSQRT_D;
11370 goto do_unaryfp;
11372 /* Square root */
11373 case FLOAT_1BIT_FMT(SQRT_FMT, FMT_SD_S):
11374 mips32_op = OPC_SQRT_S;
11375 goto do_unaryfp;
11376 case FLOAT_1BIT_FMT(SQRT_FMT, FMT_SD_D):
11377 mips32_op = OPC_SQRT_D;
11378 goto do_unaryfp;
11380 /* Reciprocal */
11381 case FLOAT_1BIT_FMT(RECIP_FMT, FMT_SD_S):
11382 mips32_op = OPC_RECIP_S;
11383 goto do_unaryfp;
11384 case FLOAT_1BIT_FMT(RECIP_FMT, FMT_SD_D):
11385 mips32_op = OPC_RECIP_D;
11386 goto do_unaryfp;
11388 /* Floor */
11389 case FLOAT_1BIT_FMT(FLOOR_L, FMT_SD_S):
11390 mips32_op = OPC_FLOOR_L_S;
11391 goto do_unaryfp;
11392 case FLOAT_1BIT_FMT(FLOOR_L, FMT_SD_D):
11393 mips32_op = OPC_FLOOR_L_D;
11394 goto do_unaryfp;
11395 case FLOAT_1BIT_FMT(FLOOR_W, FMT_SD_S):
11396 mips32_op = OPC_FLOOR_W_S;
11397 goto do_unaryfp;
11398 case FLOAT_1BIT_FMT(FLOOR_W, FMT_SD_D):
11399 mips32_op = OPC_FLOOR_W_D;
11400 goto do_unaryfp;
11402 /* Ceiling */
11403 case FLOAT_1BIT_FMT(CEIL_L, FMT_SD_S):
11404 mips32_op = OPC_CEIL_L_S;
11405 goto do_unaryfp;
11406 case FLOAT_1BIT_FMT(CEIL_L, FMT_SD_D):
11407 mips32_op = OPC_CEIL_L_D;
11408 goto do_unaryfp;
11409 case FLOAT_1BIT_FMT(CEIL_W, FMT_SD_S):
11410 mips32_op = OPC_CEIL_W_S;
11411 goto do_unaryfp;
11412 case FLOAT_1BIT_FMT(CEIL_W, FMT_SD_D):
11413 mips32_op = OPC_CEIL_W_D;
11414 goto do_unaryfp;
11416 /* Truncation */
11417 case FLOAT_1BIT_FMT(TRUNC_L, FMT_SD_S):
11418 mips32_op = OPC_TRUNC_L_S;
11419 goto do_unaryfp;
11420 case FLOAT_1BIT_FMT(TRUNC_L, FMT_SD_D):
11421 mips32_op = OPC_TRUNC_L_D;
11422 goto do_unaryfp;
11423 case FLOAT_1BIT_FMT(TRUNC_W, FMT_SD_S):
11424 mips32_op = OPC_TRUNC_W_S;
11425 goto do_unaryfp;
11426 case FLOAT_1BIT_FMT(TRUNC_W, FMT_SD_D):
11427 mips32_op = OPC_TRUNC_W_D;
11428 goto do_unaryfp;
11430 /* Round */
11431 case FLOAT_1BIT_FMT(ROUND_L, FMT_SD_S):
11432 mips32_op = OPC_ROUND_L_S;
11433 goto do_unaryfp;
11434 case FLOAT_1BIT_FMT(ROUND_L, FMT_SD_D):
11435 mips32_op = OPC_ROUND_L_D;
11436 goto do_unaryfp;
11437 case FLOAT_1BIT_FMT(ROUND_W, FMT_SD_S):
11438 mips32_op = OPC_ROUND_W_S;
11439 goto do_unaryfp;
11440 case FLOAT_1BIT_FMT(ROUND_W, FMT_SD_D):
11441 mips32_op = OPC_ROUND_W_D;
11442 goto do_unaryfp;
11444 /* Integer to floating-point conversion */
11445 case FLOAT_1BIT_FMT(CVT_L, FMT_SD_S):
11446 mips32_op = OPC_CVT_L_S;
11447 goto do_unaryfp;
11448 case FLOAT_1BIT_FMT(CVT_L, FMT_SD_D):
11449 mips32_op = OPC_CVT_L_D;
11450 goto do_unaryfp;
11451 case FLOAT_1BIT_FMT(CVT_W, FMT_SD_S):
11452 mips32_op = OPC_CVT_W_S;
11453 goto do_unaryfp;
11454 case FLOAT_1BIT_FMT(CVT_W, FMT_SD_D):
11455 mips32_op = OPC_CVT_W_D;
11456 goto do_unaryfp;
11458 /* Paired-foo conversions */
11459 case FLOAT_1BIT_FMT(CVT_S_PL, 0):
11460 mips32_op = OPC_CVT_S_PL;
11461 goto do_unaryfp;
11462 case FLOAT_1BIT_FMT(CVT_S_PU, 0):
11463 mips32_op = OPC_CVT_S_PU;
11464 goto do_unaryfp;
11465 case FLOAT_1BIT_FMT(CVT_PW_PS, 0):
11466 mips32_op = OPC_CVT_PW_PS;
11467 goto do_unaryfp;
11468 case FLOAT_1BIT_FMT(CVT_PS_PW, 0):
11469 mips32_op = OPC_CVT_PS_PW;
11470 goto do_unaryfp;
11472 /* Floating-point moves */
11473 case FLOAT_2BIT_FMT(MOV_FMT, FMT_SDPS_S):
11474 mips32_op = OPC_MOV_S;
11475 goto do_unaryfp;
11476 case FLOAT_2BIT_FMT(MOV_FMT, FMT_SDPS_D):
11477 mips32_op = OPC_MOV_D;
11478 goto do_unaryfp;
11479 case FLOAT_2BIT_FMT(MOV_FMT, FMT_SDPS_PS):
11480 mips32_op = OPC_MOV_PS;
11481 goto do_unaryfp;
11483 /* Absolute value */
11484 case FLOAT_2BIT_FMT(ABS_FMT, FMT_SDPS_S):
11485 mips32_op = OPC_ABS_S;
11486 goto do_unaryfp;
11487 case FLOAT_2BIT_FMT(ABS_FMT, FMT_SDPS_D):
11488 mips32_op = OPC_ABS_D;
11489 goto do_unaryfp;
11490 case FLOAT_2BIT_FMT(ABS_FMT, FMT_SDPS_PS):
11491 mips32_op = OPC_ABS_PS;
11492 goto do_unaryfp;
11494 /* Negation */
11495 case FLOAT_2BIT_FMT(NEG_FMT, FMT_SDPS_S):
11496 mips32_op = OPC_NEG_S;
11497 goto do_unaryfp;
11498 case FLOAT_2BIT_FMT(NEG_FMT, FMT_SDPS_D):
11499 mips32_op = OPC_NEG_D;
11500 goto do_unaryfp;
11501 case FLOAT_2BIT_FMT(NEG_FMT, FMT_SDPS_PS):
11502 mips32_op = OPC_NEG_PS;
11503 goto do_unaryfp;
11505 /* Reciprocal square root step */
11506 case FLOAT_2BIT_FMT(RSQRT1_FMT, FMT_SDPS_S):
11507 mips32_op = OPC_RSQRT1_S;
11508 goto do_unaryfp;
11509 case FLOAT_2BIT_FMT(RSQRT1_FMT, FMT_SDPS_D):
11510 mips32_op = OPC_RSQRT1_D;
11511 goto do_unaryfp;
11512 case FLOAT_2BIT_FMT(RSQRT1_FMT, FMT_SDPS_PS):
11513 mips32_op = OPC_RSQRT1_PS;
11514 goto do_unaryfp;
11516 /* Reciprocal step */
11517 case FLOAT_2BIT_FMT(RECIP1_FMT, FMT_SDPS_S):
11518 mips32_op = OPC_RECIP1_S;
11519 goto do_unaryfp;
11520 case FLOAT_2BIT_FMT(RECIP1_FMT, FMT_SDPS_D):
11521 mips32_op = OPC_RECIP1_S;
11522 goto do_unaryfp;
11523 case FLOAT_2BIT_FMT(RECIP1_FMT, FMT_SDPS_PS):
11524 mips32_op = OPC_RECIP1_PS;
11525 goto do_unaryfp;
11527 /* Conversions from double */
11528 case FLOAT_2BIT_FMT(CVT_D, FMT_SWL_S):
11529 mips32_op = OPC_CVT_D_S;
11530 goto do_unaryfp;
11531 case FLOAT_2BIT_FMT(CVT_D, FMT_SWL_W):
11532 mips32_op = OPC_CVT_D_W;
11533 goto do_unaryfp;
11534 case FLOAT_2BIT_FMT(CVT_D, FMT_SWL_L):
11535 mips32_op = OPC_CVT_D_L;
11536 goto do_unaryfp;
11538 /* Conversions from single */
11539 case FLOAT_2BIT_FMT(CVT_S, FMT_DWL_D):
11540 mips32_op = OPC_CVT_S_D;
11541 goto do_unaryfp;
11542 case FLOAT_2BIT_FMT(CVT_S, FMT_DWL_W):
11543 mips32_op = OPC_CVT_S_W;
11544 goto do_unaryfp;
11545 case FLOAT_2BIT_FMT(CVT_S, FMT_DWL_L):
11546 mips32_op = OPC_CVT_S_L;
11547 do_unaryfp:
11548 gen_farith(ctx, mips32_op, -1, rs, rt, 0);
11549 break;
11551 /* Conditional moves on floating-point codes */
11552 case COND_FLOAT_MOV(MOVT, 0):
11553 case COND_FLOAT_MOV(MOVT, 1):
11554 case COND_FLOAT_MOV(MOVT, 2):
11555 case COND_FLOAT_MOV(MOVT, 3):
11556 case COND_FLOAT_MOV(MOVT, 4):
11557 case COND_FLOAT_MOV(MOVT, 5):
11558 case COND_FLOAT_MOV(MOVT, 6):
11559 case COND_FLOAT_MOV(MOVT, 7):
11560 gen_movci(ctx, rt, rs, (ctx->opcode >> 13) & 0x7, 1);
11561 break;
11562 case COND_FLOAT_MOV(MOVF, 0):
11563 case COND_FLOAT_MOV(MOVF, 1):
11564 case COND_FLOAT_MOV(MOVF, 2):
11565 case COND_FLOAT_MOV(MOVF, 3):
11566 case COND_FLOAT_MOV(MOVF, 4):
11567 case COND_FLOAT_MOV(MOVF, 5):
11568 case COND_FLOAT_MOV(MOVF, 6):
11569 case COND_FLOAT_MOV(MOVF, 7):
11570 gen_movci(ctx, rt, rs, (ctx->opcode >> 13) & 0x7, 0);
11571 break;
11572 default:
11573 MIPS_INVAL("pool32fxf");
11574 generate_exception(ctx, EXCP_RI);
11575 break;
11579 static void decode_micromips32_opc (CPUMIPSState *env, DisasContext *ctx,
11580 uint16_t insn_hw1, int *is_branch)
11582 int32_t offset;
11583 uint16_t insn;
11584 int rt, rs, rd, rr;
11585 int16_t imm;
11586 uint32_t op, minor, mips32_op;
11587 uint32_t cond, fmt, cc;
11589 insn = cpu_lduw_code(env, ctx->pc + 2);
11590 ctx->opcode = (ctx->opcode << 16) | insn;
11592 rt = (ctx->opcode >> 21) & 0x1f;
11593 rs = (ctx->opcode >> 16) & 0x1f;
11594 rd = (ctx->opcode >> 11) & 0x1f;
11595 rr = (ctx->opcode >> 6) & 0x1f;
11596 imm = (int16_t) ctx->opcode;
11598 op = (ctx->opcode >> 26) & 0x3f;
11599 switch (op) {
11600 case POOL32A:
11601 minor = ctx->opcode & 0x3f;
11602 switch (minor) {
11603 case 0x00:
11604 minor = (ctx->opcode >> 6) & 0xf;
11605 switch (minor) {
11606 case SLL32:
11607 mips32_op = OPC_SLL;
11608 goto do_shifti;
11609 case SRA:
11610 mips32_op = OPC_SRA;
11611 goto do_shifti;
11612 case SRL32:
11613 mips32_op = OPC_SRL;
11614 goto do_shifti;
11615 case ROTR:
11616 mips32_op = OPC_ROTR;
11617 do_shifti:
11618 gen_shift_imm(ctx, mips32_op, rt, rs, rd);
11619 break;
11620 default:
11621 goto pool32a_invalid;
11623 break;
11624 case 0x10:
11625 minor = (ctx->opcode >> 6) & 0xf;
11626 switch (minor) {
11627 /* Arithmetic */
11628 case ADD:
11629 mips32_op = OPC_ADD;
11630 goto do_arith;
11631 case ADDU32:
11632 mips32_op = OPC_ADDU;
11633 goto do_arith;
11634 case SUB:
11635 mips32_op = OPC_SUB;
11636 goto do_arith;
11637 case SUBU32:
11638 mips32_op = OPC_SUBU;
11639 goto do_arith;
11640 case MUL:
11641 mips32_op = OPC_MUL;
11642 do_arith:
11643 gen_arith(ctx, mips32_op, rd, rs, rt);
11644 break;
11645 /* Shifts */
11646 case SLLV:
11647 mips32_op = OPC_SLLV;
11648 goto do_shift;
11649 case SRLV:
11650 mips32_op = OPC_SRLV;
11651 goto do_shift;
11652 case SRAV:
11653 mips32_op = OPC_SRAV;
11654 goto do_shift;
11655 case ROTRV:
11656 mips32_op = OPC_ROTRV;
11657 do_shift:
11658 gen_shift(ctx, mips32_op, rd, rs, rt);
11659 break;
11660 /* Logical operations */
11661 case AND:
11662 mips32_op = OPC_AND;
11663 goto do_logic;
11664 case OR32:
11665 mips32_op = OPC_OR;
11666 goto do_logic;
11667 case NOR:
11668 mips32_op = OPC_NOR;
11669 goto do_logic;
11670 case XOR32:
11671 mips32_op = OPC_XOR;
11672 do_logic:
11673 gen_logic(ctx, mips32_op, rd, rs, rt);
11674 break;
11675 /* Set less than */
11676 case SLT:
11677 mips32_op = OPC_SLT;
11678 goto do_slt;
11679 case SLTU:
11680 mips32_op = OPC_SLTU;
11681 do_slt:
11682 gen_slt(ctx, mips32_op, rd, rs, rt);
11683 break;
11684 default:
11685 goto pool32a_invalid;
11687 break;
11688 case 0x18:
11689 minor = (ctx->opcode >> 6) & 0xf;
11690 switch (minor) {
11691 /* Conditional moves */
11692 case MOVN:
11693 mips32_op = OPC_MOVN;
11694 goto do_cmov;
11695 case MOVZ:
11696 mips32_op = OPC_MOVZ;
11697 do_cmov:
11698 gen_cond_move(ctx, mips32_op, rd, rs, rt);
11699 break;
11700 case LWXS:
11701 gen_ldxs(ctx, rs, rt, rd);
11702 break;
11703 default:
11704 goto pool32a_invalid;
11706 break;
11707 case INS:
11708 gen_bitops(ctx, OPC_INS, rt, rs, rr, rd);
11709 return;
11710 case EXT:
11711 gen_bitops(ctx, OPC_EXT, rt, rs, rr, rd);
11712 return;
11713 case POOL32AXF:
11714 gen_pool32axf(env, ctx, rt, rs, is_branch);
11715 break;
11716 case 0x07:
11717 generate_exception(ctx, EXCP_BREAK);
11718 break;
11719 default:
11720 pool32a_invalid:
11721 MIPS_INVAL("pool32a");
11722 generate_exception(ctx, EXCP_RI);
11723 break;
11725 break;
11726 case POOL32B:
11727 minor = (ctx->opcode >> 12) & 0xf;
11728 switch (minor) {
11729 case CACHE:
11730 check_cp0_enabled(ctx);
11731 /* Treat as no-op. */
11732 break;
11733 case LWC2:
11734 case SWC2:
11735 /* COP2: Not implemented. */
11736 generate_exception_err(ctx, EXCP_CpU, 2);
11737 break;
11738 case LWP:
11739 case SWP:
11740 #ifdef TARGET_MIPS64
11741 case LDP:
11742 case SDP:
11743 #endif
11744 gen_ldst_pair(ctx, minor, rt, rs, SIMM(ctx->opcode, 0, 12));
11745 break;
11746 case LWM32:
11747 case SWM32:
11748 #ifdef TARGET_MIPS64
11749 case LDM:
11750 case SDM:
11751 #endif
11752 gen_ldst_multiple(ctx, minor, rt, rs, SIMM(ctx->opcode, 0, 12));
11753 break;
11754 default:
11755 MIPS_INVAL("pool32b");
11756 generate_exception(ctx, EXCP_RI);
11757 break;
11759 break;
11760 case POOL32F:
11761 if (env->CP0_Config1 & (1 << CP0C1_FP)) {
11762 minor = ctx->opcode & 0x3f;
11763 check_cp1_enabled(ctx);
11764 switch (minor) {
11765 case ALNV_PS:
11766 mips32_op = OPC_ALNV_PS;
11767 goto do_madd;
11768 case MADD_S:
11769 mips32_op = OPC_MADD_S;
11770 goto do_madd;
11771 case MADD_D:
11772 mips32_op = OPC_MADD_D;
11773 goto do_madd;
11774 case MADD_PS:
11775 mips32_op = OPC_MADD_PS;
11776 goto do_madd;
11777 case MSUB_S:
11778 mips32_op = OPC_MSUB_S;
11779 goto do_madd;
11780 case MSUB_D:
11781 mips32_op = OPC_MSUB_D;
11782 goto do_madd;
11783 case MSUB_PS:
11784 mips32_op = OPC_MSUB_PS;
11785 goto do_madd;
11786 case NMADD_S:
11787 mips32_op = OPC_NMADD_S;
11788 goto do_madd;
11789 case NMADD_D:
11790 mips32_op = OPC_NMADD_D;
11791 goto do_madd;
11792 case NMADD_PS:
11793 mips32_op = OPC_NMADD_PS;
11794 goto do_madd;
11795 case NMSUB_S:
11796 mips32_op = OPC_NMSUB_S;
11797 goto do_madd;
11798 case NMSUB_D:
11799 mips32_op = OPC_NMSUB_D;
11800 goto do_madd;
11801 case NMSUB_PS:
11802 mips32_op = OPC_NMSUB_PS;
11803 do_madd:
11804 gen_flt3_arith(ctx, mips32_op, rd, rr, rs, rt);
11805 break;
11806 case CABS_COND_FMT:
11807 cond = (ctx->opcode >> 6) & 0xf;
11808 cc = (ctx->opcode >> 13) & 0x7;
11809 fmt = (ctx->opcode >> 10) & 0x3;
11810 switch (fmt) {
11811 case 0x0:
11812 gen_cmpabs_s(ctx, cond, rt, rs, cc);
11813 break;
11814 case 0x1:
11815 gen_cmpabs_d(ctx, cond, rt, rs, cc);
11816 break;
11817 case 0x2:
11818 gen_cmpabs_ps(ctx, cond, rt, rs, cc);
11819 break;
11820 default:
11821 goto pool32f_invalid;
11823 break;
11824 case C_COND_FMT:
11825 cond = (ctx->opcode >> 6) & 0xf;
11826 cc = (ctx->opcode >> 13) & 0x7;
11827 fmt = (ctx->opcode >> 10) & 0x3;
11828 switch (fmt) {
11829 case 0x0:
11830 gen_cmp_s(ctx, cond, rt, rs, cc);
11831 break;
11832 case 0x1:
11833 gen_cmp_d(ctx, cond, rt, rs, cc);
11834 break;
11835 case 0x2:
11836 gen_cmp_ps(ctx, cond, rt, rs, cc);
11837 break;
11838 default:
11839 goto pool32f_invalid;
11841 break;
11842 case POOL32FXF:
11843 gen_pool32fxf(ctx, rt, rs);
11844 break;
11845 case 0x00:
11846 /* PLL foo */
11847 switch ((ctx->opcode >> 6) & 0x7) {
11848 case PLL_PS:
11849 mips32_op = OPC_PLL_PS;
11850 goto do_ps;
11851 case PLU_PS:
11852 mips32_op = OPC_PLU_PS;
11853 goto do_ps;
11854 case PUL_PS:
11855 mips32_op = OPC_PUL_PS;
11856 goto do_ps;
11857 case PUU_PS:
11858 mips32_op = OPC_PUU_PS;
11859 goto do_ps;
11860 case CVT_PS_S:
11861 mips32_op = OPC_CVT_PS_S;
11862 do_ps:
11863 gen_farith(ctx, mips32_op, rt, rs, rd, 0);
11864 break;
11865 default:
11866 goto pool32f_invalid;
11868 break;
11869 case 0x08:
11870 /* [LS][WDU]XC1 */
11871 switch ((ctx->opcode >> 6) & 0x7) {
11872 case LWXC1:
11873 mips32_op = OPC_LWXC1;
11874 goto do_ldst_cp1;
11875 case SWXC1:
11876 mips32_op = OPC_SWXC1;
11877 goto do_ldst_cp1;
11878 case LDXC1:
11879 mips32_op = OPC_LDXC1;
11880 goto do_ldst_cp1;
11881 case SDXC1:
11882 mips32_op = OPC_SDXC1;
11883 goto do_ldst_cp1;
11884 case LUXC1:
11885 mips32_op = OPC_LUXC1;
11886 goto do_ldst_cp1;
11887 case SUXC1:
11888 mips32_op = OPC_SUXC1;
11889 do_ldst_cp1:
11890 gen_flt3_ldst(ctx, mips32_op, rd, rd, rt, rs);
11891 break;
11892 default:
11893 goto pool32f_invalid;
11895 break;
11896 case 0x18:
11897 /* 3D insns */
11898 fmt = (ctx->opcode >> 9) & 0x3;
11899 switch ((ctx->opcode >> 6) & 0x7) {
11900 case RSQRT2_FMT:
11901 switch (fmt) {
11902 case FMT_SDPS_S:
11903 mips32_op = OPC_RSQRT2_S;
11904 goto do_3d;
11905 case FMT_SDPS_D:
11906 mips32_op = OPC_RSQRT2_D;
11907 goto do_3d;
11908 case FMT_SDPS_PS:
11909 mips32_op = OPC_RSQRT2_PS;
11910 goto do_3d;
11911 default:
11912 goto pool32f_invalid;
11914 break;
11915 case RECIP2_FMT:
11916 switch (fmt) {
11917 case FMT_SDPS_S:
11918 mips32_op = OPC_RECIP2_S;
11919 goto do_3d;
11920 case FMT_SDPS_D:
11921 mips32_op = OPC_RECIP2_D;
11922 goto do_3d;
11923 case FMT_SDPS_PS:
11924 mips32_op = OPC_RECIP2_PS;
11925 goto do_3d;
11926 default:
11927 goto pool32f_invalid;
11929 break;
11930 case ADDR_PS:
11931 mips32_op = OPC_ADDR_PS;
11932 goto do_3d;
11933 case MULR_PS:
11934 mips32_op = OPC_MULR_PS;
11935 do_3d:
11936 gen_farith(ctx, mips32_op, rt, rs, rd, 0);
11937 break;
11938 default:
11939 goto pool32f_invalid;
11941 break;
11942 case 0x20:
11943 /* MOV[FT].fmt and PREFX */
11944 cc = (ctx->opcode >> 13) & 0x7;
11945 fmt = (ctx->opcode >> 9) & 0x3;
11946 switch ((ctx->opcode >> 6) & 0x7) {
11947 case MOVF_FMT:
11948 switch (fmt) {
11949 case FMT_SDPS_S:
11950 gen_movcf_s(rs, rt, cc, 0);
11951 break;
11952 case FMT_SDPS_D:
11953 gen_movcf_d(ctx, rs, rt, cc, 0);
11954 break;
11955 case FMT_SDPS_PS:
11956 gen_movcf_ps(rs, rt, cc, 0);
11957 break;
11958 default:
11959 goto pool32f_invalid;
11961 break;
11962 case MOVT_FMT:
11963 switch (fmt) {
11964 case FMT_SDPS_S:
11965 gen_movcf_s(rs, rt, cc, 1);
11966 break;
11967 case FMT_SDPS_D:
11968 gen_movcf_d(ctx, rs, rt, cc, 1);
11969 break;
11970 case FMT_SDPS_PS:
11971 gen_movcf_ps(rs, rt, cc, 1);
11972 break;
11973 default:
11974 goto pool32f_invalid;
11976 break;
11977 case PREFX:
11978 break;
11979 default:
11980 goto pool32f_invalid;
11982 break;
11983 #define FINSN_3ARG_SDPS(prfx) \
11984 switch ((ctx->opcode >> 8) & 0x3) { \
11985 case FMT_SDPS_S: \
11986 mips32_op = OPC_##prfx##_S; \
11987 goto do_fpop; \
11988 case FMT_SDPS_D: \
11989 mips32_op = OPC_##prfx##_D; \
11990 goto do_fpop; \
11991 case FMT_SDPS_PS: \
11992 mips32_op = OPC_##prfx##_PS; \
11993 goto do_fpop; \
11994 default: \
11995 goto pool32f_invalid; \
11997 case 0x30:
11998 /* regular FP ops */
11999 switch ((ctx->opcode >> 6) & 0x3) {
12000 case ADD_FMT:
12001 FINSN_3ARG_SDPS(ADD);
12002 break;
12003 case SUB_FMT:
12004 FINSN_3ARG_SDPS(SUB);
12005 break;
12006 case MUL_FMT:
12007 FINSN_3ARG_SDPS(MUL);
12008 break;
12009 case DIV_FMT:
12010 fmt = (ctx->opcode >> 8) & 0x3;
12011 if (fmt == 1) {
12012 mips32_op = OPC_DIV_D;
12013 } else if (fmt == 0) {
12014 mips32_op = OPC_DIV_S;
12015 } else {
12016 goto pool32f_invalid;
12018 goto do_fpop;
12019 default:
12020 goto pool32f_invalid;
12022 break;
12023 case 0x38:
12024 /* cmovs */
12025 switch ((ctx->opcode >> 6) & 0x3) {
12026 case MOVN_FMT:
12027 FINSN_3ARG_SDPS(MOVN);
12028 break;
12029 case MOVZ_FMT:
12030 FINSN_3ARG_SDPS(MOVZ);
12031 break;
12032 default:
12033 goto pool32f_invalid;
12035 break;
12036 do_fpop:
12037 gen_farith(ctx, mips32_op, rt, rs, rd, 0);
12038 break;
12039 default:
12040 pool32f_invalid:
12041 MIPS_INVAL("pool32f");
12042 generate_exception(ctx, EXCP_RI);
12043 break;
12045 } else {
12046 generate_exception_err(ctx, EXCP_CpU, 1);
12048 break;
12049 case POOL32I:
12050 minor = (ctx->opcode >> 21) & 0x1f;
12051 switch (minor) {
12052 case BLTZ:
12053 mips32_op = OPC_BLTZ;
12054 goto do_branch;
12055 case BLTZAL:
12056 mips32_op = OPC_BLTZAL;
12057 goto do_branch;
12058 case BLTZALS:
12059 mips32_op = OPC_BLTZALS;
12060 goto do_branch;
12061 case BGEZ:
12062 mips32_op = OPC_BGEZ;
12063 goto do_branch;
12064 case BGEZAL:
12065 mips32_op = OPC_BGEZAL;
12066 goto do_branch;
12067 case BGEZALS:
12068 mips32_op = OPC_BGEZALS;
12069 goto do_branch;
12070 case BLEZ:
12071 mips32_op = OPC_BLEZ;
12072 goto do_branch;
12073 case BGTZ:
12074 mips32_op = OPC_BGTZ;
12075 do_branch:
12076 gen_compute_branch(ctx, mips32_op, 4, rs, -1, imm << 1);
12077 *is_branch = 1;
12078 break;
12080 /* Traps */
12081 case TLTI:
12082 mips32_op = OPC_TLTI;
12083 goto do_trapi;
12084 case TGEI:
12085 mips32_op = OPC_TGEI;
12086 goto do_trapi;
12087 case TLTIU:
12088 mips32_op = OPC_TLTIU;
12089 goto do_trapi;
12090 case TGEIU:
12091 mips32_op = OPC_TGEIU;
12092 goto do_trapi;
12093 case TNEI:
12094 mips32_op = OPC_TNEI;
12095 goto do_trapi;
12096 case TEQI:
12097 mips32_op = OPC_TEQI;
12098 do_trapi:
12099 gen_trap(ctx, mips32_op, rs, -1, imm);
12100 break;
12102 case BNEZC:
12103 case BEQZC:
12104 gen_compute_branch(ctx, minor == BNEZC ? OPC_BNE : OPC_BEQ,
12105 4, rs, 0, imm << 1);
12106 /* Compact branches don't have a delay slot, so just let
12107 the normal delay slot handling take us to the branch
12108 target. */
12109 break;
12110 case LUI:
12111 gen_logic_imm(ctx, OPC_LUI, rs, -1, imm);
12112 break;
12113 case SYNCI:
12114 break;
12115 case BC2F:
12116 case BC2T:
12117 /* COP2: Not implemented. */
12118 generate_exception_err(ctx, EXCP_CpU, 2);
12119 break;
12120 case BC1F:
12121 mips32_op = (ctx->opcode & (1 << 16)) ? OPC_BC1FANY2 : OPC_BC1F;
12122 goto do_cp1branch;
12123 case BC1T:
12124 mips32_op = (ctx->opcode & (1 << 16)) ? OPC_BC1TANY2 : OPC_BC1T;
12125 goto do_cp1branch;
12126 case BC1ANY4F:
12127 mips32_op = OPC_BC1FANY4;
12128 goto do_cp1mips3d;
12129 case BC1ANY4T:
12130 mips32_op = OPC_BC1TANY4;
12131 do_cp1mips3d:
12132 check_cop1x(ctx);
12133 check_insn(ctx, ASE_MIPS3D);
12134 /* Fall through */
12135 do_cp1branch:
12136 gen_compute_branch1(ctx, mips32_op,
12137 (ctx->opcode >> 18) & 0x7, imm << 1);
12138 *is_branch = 1;
12139 break;
12140 case BPOSGE64:
12141 case BPOSGE32:
12142 /* MIPS DSP: not implemented */
12143 /* Fall through */
12144 default:
12145 MIPS_INVAL("pool32i");
12146 generate_exception(ctx, EXCP_RI);
12147 break;
12149 break;
12150 case POOL32C:
12151 minor = (ctx->opcode >> 12) & 0xf;
12152 switch (minor) {
12153 case LWL:
12154 mips32_op = OPC_LWL;
12155 goto do_ld_lr;
12156 case SWL:
12157 mips32_op = OPC_SWL;
12158 goto do_st_lr;
12159 case LWR:
12160 mips32_op = OPC_LWR;
12161 goto do_ld_lr;
12162 case SWR:
12163 mips32_op = OPC_SWR;
12164 goto do_st_lr;
12165 #if defined(TARGET_MIPS64)
12166 case LDL:
12167 mips32_op = OPC_LDL;
12168 goto do_ld_lr;
12169 case SDL:
12170 mips32_op = OPC_SDL;
12171 goto do_st_lr;
12172 case LDR:
12173 mips32_op = OPC_LDR;
12174 goto do_ld_lr;
12175 case SDR:
12176 mips32_op = OPC_SDR;
12177 goto do_st_lr;
12178 case LWU:
12179 mips32_op = OPC_LWU;
12180 goto do_ld_lr;
12181 case LLD:
12182 mips32_op = OPC_LLD;
12183 goto do_ld_lr;
12184 #endif
12185 case LL:
12186 mips32_op = OPC_LL;
12187 goto do_ld_lr;
12188 do_ld_lr:
12189 gen_ld(ctx, mips32_op, rt, rs, SIMM(ctx->opcode, 0, 12));
12190 break;
12191 do_st_lr:
12192 gen_st(ctx, mips32_op, rt, rs, SIMM(ctx->opcode, 0, 12));
12193 break;
12194 case SC:
12195 gen_st_cond(ctx, OPC_SC, rt, rs, SIMM(ctx->opcode, 0, 12));
12196 break;
12197 #if defined(TARGET_MIPS64)
12198 case SCD:
12199 gen_st_cond(ctx, OPC_SCD, rt, rs, SIMM(ctx->opcode, 0, 12));
12200 break;
12201 #endif
12202 case PREF:
12203 /* Treat as no-op */
12204 break;
12205 default:
12206 MIPS_INVAL("pool32c");
12207 generate_exception(ctx, EXCP_RI);
12208 break;
12210 break;
12211 case ADDI32:
12212 mips32_op = OPC_ADDI;
12213 goto do_addi;
12214 case ADDIU32:
12215 mips32_op = OPC_ADDIU;
12216 do_addi:
12217 gen_arith_imm(ctx, mips32_op, rt, rs, imm);
12218 break;
12220 /* Logical operations */
12221 case ORI32:
12222 mips32_op = OPC_ORI;
12223 goto do_logici;
12224 case XORI32:
12225 mips32_op = OPC_XORI;
12226 goto do_logici;
12227 case ANDI32:
12228 mips32_op = OPC_ANDI;
12229 do_logici:
12230 gen_logic_imm(ctx, mips32_op, rt, rs, imm);
12231 break;
12233 /* Set less than immediate */
12234 case SLTI32:
12235 mips32_op = OPC_SLTI;
12236 goto do_slti;
12237 case SLTIU32:
12238 mips32_op = OPC_SLTIU;
12239 do_slti:
12240 gen_slt_imm(ctx, mips32_op, rt, rs, imm);
12241 break;
12242 case JALX32:
12243 offset = (int32_t)(ctx->opcode & 0x3FFFFFF) << 2;
12244 gen_compute_branch(ctx, OPC_JALX, 4, rt, rs, offset);
12245 *is_branch = 1;
12246 break;
12247 case JALS32:
12248 offset = (int32_t)(ctx->opcode & 0x3FFFFFF) << 1;
12249 gen_compute_branch(ctx, OPC_JALS, 4, rt, rs, offset);
12250 *is_branch = 1;
12251 break;
12252 case BEQ32:
12253 gen_compute_branch(ctx, OPC_BEQ, 4, rt, rs, imm << 1);
12254 *is_branch = 1;
12255 break;
12256 case BNE32:
12257 gen_compute_branch(ctx, OPC_BNE, 4, rt, rs, imm << 1);
12258 *is_branch = 1;
12259 break;
12260 case J32:
12261 gen_compute_branch(ctx, OPC_J, 4, rt, rs,
12262 (int32_t)(ctx->opcode & 0x3FFFFFF) << 1);
12263 *is_branch = 1;
12264 break;
12265 case JAL32:
12266 gen_compute_branch(ctx, OPC_JAL, 4, rt, rs,
12267 (int32_t)(ctx->opcode & 0x3FFFFFF) << 1);
12268 *is_branch = 1;
12269 break;
12270 /* Floating point (COP1) */
12271 case LWC132:
12272 mips32_op = OPC_LWC1;
12273 goto do_cop1;
12274 case LDC132:
12275 mips32_op = OPC_LDC1;
12276 goto do_cop1;
12277 case SWC132:
12278 mips32_op = OPC_SWC1;
12279 goto do_cop1;
12280 case SDC132:
12281 mips32_op = OPC_SDC1;
12282 do_cop1:
12283 gen_cop1_ldst(env, ctx, mips32_op, rt, rs, imm);
12284 break;
12285 case ADDIUPC:
12287 int reg = mmreg(ZIMM(ctx->opcode, 23, 3));
12288 int offset = SIMM(ctx->opcode, 0, 23) << 2;
12290 gen_addiupc(ctx, reg, offset, 0, 0);
12292 break;
12293 /* Loads and stores */
12294 case LB32:
12295 mips32_op = OPC_LB;
12296 goto do_ld;
12297 case LBU32:
12298 mips32_op = OPC_LBU;
12299 goto do_ld;
12300 case LH32:
12301 mips32_op = OPC_LH;
12302 goto do_ld;
12303 case LHU32:
12304 mips32_op = OPC_LHU;
12305 goto do_ld;
12306 case LW32:
12307 mips32_op = OPC_LW;
12308 goto do_ld;
12309 #ifdef TARGET_MIPS64
12310 case LD32:
12311 mips32_op = OPC_LD;
12312 goto do_ld;
12313 case SD32:
12314 mips32_op = OPC_SD;
12315 goto do_st;
12316 #endif
12317 case SB32:
12318 mips32_op = OPC_SB;
12319 goto do_st;
12320 case SH32:
12321 mips32_op = OPC_SH;
12322 goto do_st;
12323 case SW32:
12324 mips32_op = OPC_SW;
12325 goto do_st;
12326 do_ld:
12327 gen_ld(ctx, mips32_op, rt, rs, imm);
12328 break;
12329 do_st:
12330 gen_st(ctx, mips32_op, rt, rs, imm);
12331 break;
12332 default:
12333 generate_exception(ctx, EXCP_RI);
12334 break;
12338 static int decode_micromips_opc (CPUMIPSState *env, DisasContext *ctx, int *is_branch)
12340 uint32_t op;
12342 /* make sure instructions are on a halfword boundary */
12343 if (ctx->pc & 0x1) {
12344 env->CP0_BadVAddr = ctx->pc;
12345 generate_exception(ctx, EXCP_AdEL);
12346 ctx->bstate = BS_STOP;
12347 return 2;
12350 op = (ctx->opcode >> 10) & 0x3f;
12351 /* Enforce properly-sized instructions in a delay slot */
12352 if (ctx->hflags & MIPS_HFLAG_BMASK) {
12353 int bits = ctx->hflags & MIPS_HFLAG_BMASK_EXT;
12355 switch (op) {
12356 case POOL32A:
12357 case POOL32B:
12358 case POOL32I:
12359 case POOL32C:
12360 case ADDI32:
12361 case ADDIU32:
12362 case ORI32:
12363 case XORI32:
12364 case SLTI32:
12365 case SLTIU32:
12366 case ANDI32:
12367 case JALX32:
12368 case LBU32:
12369 case LHU32:
12370 case POOL32F:
12371 case JALS32:
12372 case BEQ32:
12373 case BNE32:
12374 case J32:
12375 case JAL32:
12376 case SB32:
12377 case SH32:
12378 case POOL32S:
12379 case ADDIUPC:
12380 case SWC132:
12381 case SDC132:
12382 case SD32:
12383 case SW32:
12384 case LB32:
12385 case LH32:
12386 case DADDIU32:
12387 case LWC132:
12388 case LDC132:
12389 case LD32:
12390 case LW32:
12391 if (bits & MIPS_HFLAG_BDS16) {
12392 generate_exception(ctx, EXCP_RI);
12393 /* Just stop translation; the user is confused. */
12394 ctx->bstate = BS_STOP;
12395 return 2;
12397 break;
12398 case POOL16A:
12399 case POOL16B:
12400 case POOL16C:
12401 case LWGP16:
12402 case POOL16F:
12403 case LBU16:
12404 case LHU16:
12405 case LWSP16:
12406 case LW16:
12407 case SB16:
12408 case SH16:
12409 case SWSP16:
12410 case SW16:
12411 case MOVE16:
12412 case ANDI16:
12413 case POOL16D:
12414 case POOL16E:
12415 case BEQZ16:
12416 case BNEZ16:
12417 case B16:
12418 case LI16:
12419 if (bits & MIPS_HFLAG_BDS32) {
12420 generate_exception(ctx, EXCP_RI);
12421 /* Just stop translation; the user is confused. */
12422 ctx->bstate = BS_STOP;
12423 return 2;
12425 break;
12426 default:
12427 break;
12430 switch (op) {
12431 case POOL16A:
12433 int rd = mmreg(uMIPS_RD(ctx->opcode));
12434 int rs1 = mmreg(uMIPS_RS1(ctx->opcode));
12435 int rs2 = mmreg(uMIPS_RS2(ctx->opcode));
12436 uint32_t opc = 0;
12438 switch (ctx->opcode & 0x1) {
12439 case ADDU16:
12440 opc = OPC_ADDU;
12441 break;
12442 case SUBU16:
12443 opc = OPC_SUBU;
12444 break;
12447 gen_arith(ctx, opc, rd, rs1, rs2);
12449 break;
12450 case POOL16B:
12452 int rd = mmreg(uMIPS_RD(ctx->opcode));
12453 int rs = mmreg(uMIPS_RS(ctx->opcode));
12454 int amount = (ctx->opcode >> 1) & 0x7;
12455 uint32_t opc = 0;
12456 amount = amount == 0 ? 8 : amount;
12458 switch (ctx->opcode & 0x1) {
12459 case SLL16:
12460 opc = OPC_SLL;
12461 break;
12462 case SRL16:
12463 opc = OPC_SRL;
12464 break;
12467 gen_shift_imm(ctx, opc, rd, rs, amount);
12469 break;
12470 case POOL16C:
12471 gen_pool16c_insn(ctx, is_branch);
12472 break;
12473 case LWGP16:
12475 int rd = mmreg(uMIPS_RD(ctx->opcode));
12476 int rb = 28; /* GP */
12477 int16_t offset = SIMM(ctx->opcode, 0, 7) << 2;
12479 gen_ld(ctx, OPC_LW, rd, rb, offset);
12481 break;
12482 case POOL16F:
12483 if (ctx->opcode & 1) {
12484 generate_exception(ctx, EXCP_RI);
12485 } else {
12486 /* MOVEP */
12487 int enc_dest = uMIPS_RD(ctx->opcode);
12488 int enc_rt = uMIPS_RS2(ctx->opcode);
12489 int enc_rs = uMIPS_RS1(ctx->opcode);
12490 int rd, rs, re, rt;
12491 static const int rd_enc[] = { 5, 5, 6, 4, 4, 4, 4, 4 };
12492 static const int re_enc[] = { 6, 7, 7, 21, 22, 5, 6, 7 };
12493 static const int rs_rt_enc[] = { 0, 17, 2, 3, 16, 18, 19, 20 };
12495 rd = rd_enc[enc_dest];
12496 re = re_enc[enc_dest];
12497 rs = rs_rt_enc[enc_rs];
12498 rt = rs_rt_enc[enc_rt];
12500 gen_arith_imm(ctx, OPC_ADDIU, rd, rs, 0);
12501 gen_arith_imm(ctx, OPC_ADDIU, re, rt, 0);
12503 break;
12504 case LBU16:
12506 int rd = mmreg(uMIPS_RD(ctx->opcode));
12507 int rb = mmreg(uMIPS_RS(ctx->opcode));
12508 int16_t offset = ZIMM(ctx->opcode, 0, 4);
12509 offset = (offset == 0xf ? -1 : offset);
12511 gen_ld(ctx, OPC_LBU, rd, rb, offset);
12513 break;
12514 case LHU16:
12516 int rd = mmreg(uMIPS_RD(ctx->opcode));
12517 int rb = mmreg(uMIPS_RS(ctx->opcode));
12518 int16_t offset = ZIMM(ctx->opcode, 0, 4) << 1;
12520 gen_ld(ctx, OPC_LHU, rd, rb, offset);
12522 break;
12523 case LWSP16:
12525 int rd = (ctx->opcode >> 5) & 0x1f;
12526 int rb = 29; /* SP */
12527 int16_t offset = ZIMM(ctx->opcode, 0, 5) << 2;
12529 gen_ld(ctx, OPC_LW, rd, rb, offset);
12531 break;
12532 case LW16:
12534 int rd = mmreg(uMIPS_RD(ctx->opcode));
12535 int rb = mmreg(uMIPS_RS(ctx->opcode));
12536 int16_t offset = ZIMM(ctx->opcode, 0, 4) << 2;
12538 gen_ld(ctx, OPC_LW, rd, rb, offset);
12540 break;
12541 case SB16:
12543 int rd = mmreg2(uMIPS_RD(ctx->opcode));
12544 int rb = mmreg(uMIPS_RS(ctx->opcode));
12545 int16_t offset = ZIMM(ctx->opcode, 0, 4);
12547 gen_st(ctx, OPC_SB, rd, rb, offset);
12549 break;
12550 case SH16:
12552 int rd = mmreg2(uMIPS_RD(ctx->opcode));
12553 int rb = mmreg(uMIPS_RS(ctx->opcode));
12554 int16_t offset = ZIMM(ctx->opcode, 0, 4) << 1;
12556 gen_st(ctx, OPC_SH, rd, rb, offset);
12558 break;
12559 case SWSP16:
12561 int rd = (ctx->opcode >> 5) & 0x1f;
12562 int rb = 29; /* SP */
12563 int16_t offset = ZIMM(ctx->opcode, 0, 5) << 2;
12565 gen_st(ctx, OPC_SW, rd, rb, offset);
12567 break;
12568 case SW16:
12570 int rd = mmreg2(uMIPS_RD(ctx->opcode));
12571 int rb = mmreg(uMIPS_RS(ctx->opcode));
12572 int16_t offset = ZIMM(ctx->opcode, 0, 4) << 2;
12574 gen_st(ctx, OPC_SW, rd, rb, offset);
12576 break;
12577 case MOVE16:
12579 int rd = uMIPS_RD5(ctx->opcode);
12580 int rs = uMIPS_RS5(ctx->opcode);
12582 gen_arith_imm(ctx, OPC_ADDIU, rd, rs, 0);
12584 break;
12585 case ANDI16:
12586 gen_andi16(ctx);
12587 break;
12588 case POOL16D:
12589 switch (ctx->opcode & 0x1) {
12590 case ADDIUS5:
12591 gen_addius5(ctx);
12592 break;
12593 case ADDIUSP:
12594 gen_addiusp(ctx);
12595 break;
12597 break;
12598 case POOL16E:
12599 switch (ctx->opcode & 0x1) {
12600 case ADDIUR2:
12601 gen_addiur2(ctx);
12602 break;
12603 case ADDIUR1SP:
12604 gen_addiur1sp(ctx);
12605 break;
12607 break;
12608 case B16:
12609 gen_compute_branch(ctx, OPC_BEQ, 2, 0, 0,
12610 SIMM(ctx->opcode, 0, 10) << 1);
12611 *is_branch = 1;
12612 break;
12613 case BNEZ16:
12614 case BEQZ16:
12615 gen_compute_branch(ctx, op == BNEZ16 ? OPC_BNE : OPC_BEQ, 2,
12616 mmreg(uMIPS_RD(ctx->opcode)),
12617 0, SIMM(ctx->opcode, 0, 7) << 1);
12618 *is_branch = 1;
12619 break;
12620 case LI16:
12622 int reg = mmreg(uMIPS_RD(ctx->opcode));
12623 int imm = ZIMM(ctx->opcode, 0, 7);
12625 imm = (imm == 0x7f ? -1 : imm);
12626 tcg_gen_movi_tl(cpu_gpr[reg], imm);
12628 break;
12629 case RES_20:
12630 case RES_28:
12631 case RES_29:
12632 case RES_30:
12633 case RES_31:
12634 case RES_38:
12635 case RES_39:
12636 generate_exception(ctx, EXCP_RI);
12637 break;
12638 default:
12639 decode_micromips32_opc (env, ctx, op, is_branch);
12640 return 4;
12643 return 2;
12646 /* SmartMIPS extension to MIPS32 */
12648 #if defined(TARGET_MIPS64)
12650 /* MDMX extension to MIPS64 */
12652 #endif
12654 /* MIPSDSP functions. */
12655 static void gen_mipsdsp_ld(DisasContext *ctx, uint32_t opc,
12656 int rd, int base, int offset)
12658 const char *opn = "ldx";
12659 TCGv t0;
12661 check_dsp(ctx);
12662 t0 = tcg_temp_new();
12664 if (base == 0) {
12665 gen_load_gpr(t0, offset);
12666 } else if (offset == 0) {
12667 gen_load_gpr(t0, base);
12668 } else {
12669 gen_op_addr_add(ctx, t0, cpu_gpr[base], cpu_gpr[offset]);
12672 switch (opc) {
12673 case OPC_LBUX:
12674 tcg_gen_qemu_ld8u(t0, t0, ctx->mem_idx);
12675 gen_store_gpr(t0, rd);
12676 opn = "lbux";
12677 break;
12678 case OPC_LHX:
12679 tcg_gen_qemu_ld16s(t0, t0, ctx->mem_idx);
12680 gen_store_gpr(t0, rd);
12681 opn = "lhx";
12682 break;
12683 case OPC_LWX:
12684 tcg_gen_qemu_ld32s(t0, t0, ctx->mem_idx);
12685 gen_store_gpr(t0, rd);
12686 opn = "lwx";
12687 break;
12688 #if defined(TARGET_MIPS64)
12689 case OPC_LDX:
12690 tcg_gen_qemu_ld64(t0, t0, ctx->mem_idx);
12691 gen_store_gpr(t0, rd);
12692 opn = "ldx";
12693 break;
12694 #endif
12696 (void)opn; /* avoid a compiler warning */
12697 MIPS_DEBUG("%s %s, %s(%s)", opn,
12698 regnames[rd], regnames[offset], regnames[base]);
12699 tcg_temp_free(t0);
12702 static void gen_mipsdsp_arith(DisasContext *ctx, uint32_t op1, uint32_t op2,
12703 int ret, int v1, int v2)
12705 const char *opn = "mipsdsp arith";
12706 TCGv v1_t;
12707 TCGv v2_t;
12709 if (ret == 0) {
12710 /* Treat as NOP. */
12711 MIPS_DEBUG("NOP");
12712 return;
12715 v1_t = tcg_temp_new();
12716 v2_t = tcg_temp_new();
12718 gen_load_gpr(v1_t, v1);
12719 gen_load_gpr(v2_t, v2);
12721 switch (op1) {
12722 /* OPC_MULT_G_2E is equal OPC_ADDUH_QB_DSP */
12723 case OPC_MULT_G_2E:
12724 check_dspr2(ctx);
12725 switch (op2) {
12726 case OPC_ADDUH_QB:
12727 gen_helper_adduh_qb(cpu_gpr[ret], v1_t, v2_t);
12728 break;
12729 case OPC_ADDUH_R_QB:
12730 gen_helper_adduh_r_qb(cpu_gpr[ret], v1_t, v2_t);
12731 break;
12732 case OPC_ADDQH_PH:
12733 gen_helper_addqh_ph(cpu_gpr[ret], v1_t, v2_t);
12734 break;
12735 case OPC_ADDQH_R_PH:
12736 gen_helper_addqh_r_ph(cpu_gpr[ret], v1_t, v2_t);
12737 break;
12738 case OPC_ADDQH_W:
12739 gen_helper_addqh_w(cpu_gpr[ret], v1_t, v2_t);
12740 break;
12741 case OPC_ADDQH_R_W:
12742 gen_helper_addqh_r_w(cpu_gpr[ret], v1_t, v2_t);
12743 break;
12744 case OPC_SUBUH_QB:
12745 gen_helper_subuh_qb(cpu_gpr[ret], v1_t, v2_t);
12746 break;
12747 case OPC_SUBUH_R_QB:
12748 gen_helper_subuh_r_qb(cpu_gpr[ret], v1_t, v2_t);
12749 break;
12750 case OPC_SUBQH_PH:
12751 gen_helper_subqh_ph(cpu_gpr[ret], v1_t, v2_t);
12752 break;
12753 case OPC_SUBQH_R_PH:
12754 gen_helper_subqh_r_ph(cpu_gpr[ret], v1_t, v2_t);
12755 break;
12756 case OPC_SUBQH_W:
12757 gen_helper_subqh_w(cpu_gpr[ret], v1_t, v2_t);
12758 break;
12759 case OPC_SUBQH_R_W:
12760 gen_helper_subqh_r_w(cpu_gpr[ret], v1_t, v2_t);
12761 break;
12763 break;
12764 case OPC_ABSQ_S_PH_DSP:
12765 switch (op2) {
12766 case OPC_ABSQ_S_QB:
12767 check_dspr2(ctx);
12768 gen_helper_absq_s_qb(cpu_gpr[ret], v2_t, cpu_env);
12769 break;
12770 case OPC_ABSQ_S_PH:
12771 check_dsp(ctx);
12772 gen_helper_absq_s_ph(cpu_gpr[ret], v2_t, cpu_env);
12773 break;
12774 case OPC_ABSQ_S_W:
12775 check_dsp(ctx);
12776 gen_helper_absq_s_w(cpu_gpr[ret], v2_t, cpu_env);
12777 break;
12778 case OPC_PRECEQ_W_PHL:
12779 check_dsp(ctx);
12780 tcg_gen_andi_tl(cpu_gpr[ret], v2_t, 0xFFFF0000);
12781 tcg_gen_ext32s_tl(cpu_gpr[ret], cpu_gpr[ret]);
12782 break;
12783 case OPC_PRECEQ_W_PHR:
12784 check_dsp(ctx);
12785 tcg_gen_andi_tl(cpu_gpr[ret], v2_t, 0x0000FFFF);
12786 tcg_gen_shli_tl(cpu_gpr[ret], cpu_gpr[ret], 16);
12787 tcg_gen_ext32s_tl(cpu_gpr[ret], cpu_gpr[ret]);
12788 break;
12789 case OPC_PRECEQU_PH_QBL:
12790 check_dsp(ctx);
12791 gen_helper_precequ_ph_qbl(cpu_gpr[ret], v2_t);
12792 break;
12793 case OPC_PRECEQU_PH_QBR:
12794 check_dsp(ctx);
12795 gen_helper_precequ_ph_qbr(cpu_gpr[ret], v2_t);
12796 break;
12797 case OPC_PRECEQU_PH_QBLA:
12798 check_dsp(ctx);
12799 gen_helper_precequ_ph_qbla(cpu_gpr[ret], v2_t);
12800 break;
12801 case OPC_PRECEQU_PH_QBRA:
12802 check_dsp(ctx);
12803 gen_helper_precequ_ph_qbra(cpu_gpr[ret], v2_t);
12804 break;
12805 case OPC_PRECEU_PH_QBL:
12806 check_dsp(ctx);
12807 gen_helper_preceu_ph_qbl(cpu_gpr[ret], v2_t);
12808 break;
12809 case OPC_PRECEU_PH_QBR:
12810 check_dsp(ctx);
12811 gen_helper_preceu_ph_qbr(cpu_gpr[ret], v2_t);
12812 break;
12813 case OPC_PRECEU_PH_QBLA:
12814 check_dsp(ctx);
12815 gen_helper_preceu_ph_qbla(cpu_gpr[ret], v2_t);
12816 break;
12817 case OPC_PRECEU_PH_QBRA:
12818 check_dsp(ctx);
12819 gen_helper_preceu_ph_qbra(cpu_gpr[ret], v2_t);
12820 break;
12822 break;
12823 case OPC_ADDU_QB_DSP:
12824 switch (op2) {
12825 case OPC_ADDQ_PH:
12826 check_dsp(ctx);
12827 gen_helper_addq_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12828 break;
12829 case OPC_ADDQ_S_PH:
12830 check_dsp(ctx);
12831 gen_helper_addq_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12832 break;
12833 case OPC_ADDQ_S_W:
12834 check_dsp(ctx);
12835 gen_helper_addq_s_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12836 break;
12837 case OPC_ADDU_QB:
12838 check_dsp(ctx);
12839 gen_helper_addu_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12840 break;
12841 case OPC_ADDU_S_QB:
12842 check_dsp(ctx);
12843 gen_helper_addu_s_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12844 break;
12845 case OPC_ADDU_PH:
12846 check_dspr2(ctx);
12847 gen_helper_addu_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12848 break;
12849 case OPC_ADDU_S_PH:
12850 check_dspr2(ctx);
12851 gen_helper_addu_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12852 break;
12853 case OPC_SUBQ_PH:
12854 check_dsp(ctx);
12855 gen_helper_subq_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12856 break;
12857 case OPC_SUBQ_S_PH:
12858 check_dsp(ctx);
12859 gen_helper_subq_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12860 break;
12861 case OPC_SUBQ_S_W:
12862 check_dsp(ctx);
12863 gen_helper_subq_s_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12864 break;
12865 case OPC_SUBU_QB:
12866 check_dsp(ctx);
12867 gen_helper_subu_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12868 break;
12869 case OPC_SUBU_S_QB:
12870 check_dsp(ctx);
12871 gen_helper_subu_s_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12872 break;
12873 case OPC_SUBU_PH:
12874 check_dspr2(ctx);
12875 gen_helper_subu_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12876 break;
12877 case OPC_SUBU_S_PH:
12878 check_dspr2(ctx);
12879 gen_helper_subu_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12880 break;
12881 case OPC_ADDSC:
12882 check_dsp(ctx);
12883 gen_helper_addsc(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12884 break;
12885 case OPC_ADDWC:
12886 check_dsp(ctx);
12887 gen_helper_addwc(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12888 break;
12889 case OPC_MODSUB:
12890 check_dsp(ctx);
12891 gen_helper_modsub(cpu_gpr[ret], v1_t, v2_t);
12892 break;
12893 case OPC_RADDU_W_QB:
12894 check_dsp(ctx);
12895 gen_helper_raddu_w_qb(cpu_gpr[ret], v1_t);
12896 break;
12898 break;
12899 case OPC_CMPU_EQ_QB_DSP:
12900 switch (op2) {
12901 case OPC_PRECR_QB_PH:
12902 check_dspr2(ctx);
12903 gen_helper_precr_qb_ph(cpu_gpr[ret], v1_t, v2_t);
12904 break;
12905 case OPC_PRECRQ_QB_PH:
12906 check_dsp(ctx);
12907 gen_helper_precrq_qb_ph(cpu_gpr[ret], v1_t, v2_t);
12908 break;
12909 case OPC_PRECR_SRA_PH_W:
12910 check_dspr2(ctx);
12912 TCGv_i32 sa_t = tcg_const_i32(v2);
12913 gen_helper_precr_sra_ph_w(cpu_gpr[ret], sa_t, v1_t,
12914 cpu_gpr[ret]);
12915 tcg_temp_free_i32(sa_t);
12916 break;
12918 case OPC_PRECR_SRA_R_PH_W:
12919 check_dspr2(ctx);
12921 TCGv_i32 sa_t = tcg_const_i32(v2);
12922 gen_helper_precr_sra_r_ph_w(cpu_gpr[ret], sa_t, v1_t,
12923 cpu_gpr[ret]);
12924 tcg_temp_free_i32(sa_t);
12925 break;
12927 case OPC_PRECRQ_PH_W:
12928 check_dsp(ctx);
12929 gen_helper_precrq_ph_w(cpu_gpr[ret], v1_t, v2_t);
12930 break;
12931 case OPC_PRECRQ_RS_PH_W:
12932 check_dsp(ctx);
12933 gen_helper_precrq_rs_ph_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12934 break;
12935 case OPC_PRECRQU_S_QB_PH:
12936 check_dsp(ctx);
12937 gen_helper_precrqu_s_qb_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12938 break;
12940 break;
12941 #ifdef TARGET_MIPS64
12942 case OPC_ABSQ_S_QH_DSP:
12943 switch (op2) {
12944 case OPC_PRECEQ_L_PWL:
12945 check_dsp(ctx);
12946 tcg_gen_andi_tl(cpu_gpr[ret], v2_t, 0xFFFFFFFF00000000ull);
12947 break;
12948 case OPC_PRECEQ_L_PWR:
12949 check_dsp(ctx);
12950 tcg_gen_shli_tl(cpu_gpr[ret], v2_t, 32);
12951 break;
12952 case OPC_PRECEQ_PW_QHL:
12953 check_dsp(ctx);
12954 gen_helper_preceq_pw_qhl(cpu_gpr[ret], v2_t);
12955 break;
12956 case OPC_PRECEQ_PW_QHR:
12957 check_dsp(ctx);
12958 gen_helper_preceq_pw_qhr(cpu_gpr[ret], v2_t);
12959 break;
12960 case OPC_PRECEQ_PW_QHLA:
12961 check_dsp(ctx);
12962 gen_helper_preceq_pw_qhla(cpu_gpr[ret], v2_t);
12963 break;
12964 case OPC_PRECEQ_PW_QHRA:
12965 check_dsp(ctx);
12966 gen_helper_preceq_pw_qhra(cpu_gpr[ret], v2_t);
12967 break;
12968 case OPC_PRECEQU_QH_OBL:
12969 check_dsp(ctx);
12970 gen_helper_precequ_qh_obl(cpu_gpr[ret], v2_t);
12971 break;
12972 case OPC_PRECEQU_QH_OBR:
12973 check_dsp(ctx);
12974 gen_helper_precequ_qh_obr(cpu_gpr[ret], v2_t);
12975 break;
12976 case OPC_PRECEQU_QH_OBLA:
12977 check_dsp(ctx);
12978 gen_helper_precequ_qh_obla(cpu_gpr[ret], v2_t);
12979 break;
12980 case OPC_PRECEQU_QH_OBRA:
12981 check_dsp(ctx);
12982 gen_helper_precequ_qh_obra(cpu_gpr[ret], v2_t);
12983 break;
12984 case OPC_PRECEU_QH_OBL:
12985 check_dsp(ctx);
12986 gen_helper_preceu_qh_obl(cpu_gpr[ret], v2_t);
12987 break;
12988 case OPC_PRECEU_QH_OBR:
12989 check_dsp(ctx);
12990 gen_helper_preceu_qh_obr(cpu_gpr[ret], v2_t);
12991 break;
12992 case OPC_PRECEU_QH_OBLA:
12993 check_dsp(ctx);
12994 gen_helper_preceu_qh_obla(cpu_gpr[ret], v2_t);
12995 break;
12996 case OPC_PRECEU_QH_OBRA:
12997 check_dsp(ctx);
12998 gen_helper_preceu_qh_obra(cpu_gpr[ret], v2_t);
12999 break;
13000 case OPC_ABSQ_S_OB:
13001 check_dspr2(ctx);
13002 gen_helper_absq_s_ob(cpu_gpr[ret], v2_t, cpu_env);
13003 break;
13004 case OPC_ABSQ_S_PW:
13005 check_dsp(ctx);
13006 gen_helper_absq_s_pw(cpu_gpr[ret], v2_t, cpu_env);
13007 break;
13008 case OPC_ABSQ_S_QH:
13009 check_dsp(ctx);
13010 gen_helper_absq_s_qh(cpu_gpr[ret], v2_t, cpu_env);
13011 break;
13013 break;
13014 case OPC_ADDU_OB_DSP:
13015 switch (op2) {
13016 case OPC_RADDU_L_OB:
13017 check_dsp(ctx);
13018 gen_helper_raddu_l_ob(cpu_gpr[ret], v1_t);
13019 break;
13020 case OPC_SUBQ_PW:
13021 check_dsp(ctx);
13022 gen_helper_subq_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13023 break;
13024 case OPC_SUBQ_S_PW:
13025 check_dsp(ctx);
13026 gen_helper_subq_s_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13027 break;
13028 case OPC_SUBQ_QH:
13029 check_dsp(ctx);
13030 gen_helper_subq_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13031 break;
13032 case OPC_SUBQ_S_QH:
13033 check_dsp(ctx);
13034 gen_helper_subq_s_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13035 break;
13036 case OPC_SUBU_OB:
13037 check_dsp(ctx);
13038 gen_helper_subu_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13039 break;
13040 case OPC_SUBU_S_OB:
13041 check_dsp(ctx);
13042 gen_helper_subu_s_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13043 break;
13044 case OPC_SUBU_QH:
13045 check_dspr2(ctx);
13046 gen_helper_subu_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13047 break;
13048 case OPC_SUBU_S_QH:
13049 check_dspr2(ctx);
13050 gen_helper_subu_s_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13051 break;
13052 case OPC_SUBUH_OB:
13053 check_dspr2(ctx);
13054 gen_helper_subuh_ob(cpu_gpr[ret], v1_t, v2_t);
13055 break;
13056 case OPC_SUBUH_R_OB:
13057 check_dspr2(ctx);
13058 gen_helper_subuh_r_ob(cpu_gpr[ret], v1_t, v2_t);
13059 break;
13060 case OPC_ADDQ_PW:
13061 check_dsp(ctx);
13062 gen_helper_addq_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13063 break;
13064 case OPC_ADDQ_S_PW:
13065 check_dsp(ctx);
13066 gen_helper_addq_s_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13067 break;
13068 case OPC_ADDQ_QH:
13069 check_dsp(ctx);
13070 gen_helper_addq_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13071 break;
13072 case OPC_ADDQ_S_QH:
13073 check_dsp(ctx);
13074 gen_helper_addq_s_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13075 break;
13076 case OPC_ADDU_OB:
13077 check_dsp(ctx);
13078 gen_helper_addu_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13079 break;
13080 case OPC_ADDU_S_OB:
13081 check_dsp(ctx);
13082 gen_helper_addu_s_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13083 break;
13084 case OPC_ADDU_QH:
13085 check_dspr2(ctx);
13086 gen_helper_addu_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13087 break;
13088 case OPC_ADDU_S_QH:
13089 check_dspr2(ctx);
13090 gen_helper_addu_s_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13091 break;
13092 case OPC_ADDUH_OB:
13093 check_dspr2(ctx);
13094 gen_helper_adduh_ob(cpu_gpr[ret], v1_t, v2_t);
13095 break;
13096 case OPC_ADDUH_R_OB:
13097 check_dspr2(ctx);
13098 gen_helper_adduh_r_ob(cpu_gpr[ret], v1_t, v2_t);
13099 break;
13101 break;
13102 case OPC_CMPU_EQ_OB_DSP:
13103 switch (op2) {
13104 case OPC_PRECR_OB_QH:
13105 check_dspr2(ctx);
13106 gen_helper_precr_ob_qh(cpu_gpr[ret], v1_t, v2_t);
13107 break;
13108 case OPC_PRECR_SRA_QH_PW:
13109 check_dspr2(ctx);
13111 TCGv_i32 ret_t = tcg_const_i32(ret);
13112 gen_helper_precr_sra_qh_pw(v2_t, v1_t, v2_t, ret_t);
13113 tcg_temp_free_i32(ret_t);
13114 break;
13116 case OPC_PRECR_SRA_R_QH_PW:
13117 check_dspr2(ctx);
13119 TCGv_i32 sa_v = tcg_const_i32(ret);
13120 gen_helper_precr_sra_r_qh_pw(v2_t, v1_t, v2_t, sa_v);
13121 tcg_temp_free_i32(sa_v);
13122 break;
13124 case OPC_PRECRQ_OB_QH:
13125 check_dsp(ctx);
13126 gen_helper_precrq_ob_qh(cpu_gpr[ret], v1_t, v2_t);
13127 break;
13128 case OPC_PRECRQ_PW_L:
13129 check_dsp(ctx);
13130 gen_helper_precrq_pw_l(cpu_gpr[ret], v1_t, v2_t);
13131 break;
13132 case OPC_PRECRQ_QH_PW:
13133 check_dsp(ctx);
13134 gen_helper_precrq_qh_pw(cpu_gpr[ret], v1_t, v2_t);
13135 break;
13136 case OPC_PRECRQ_RS_QH_PW:
13137 check_dsp(ctx);
13138 gen_helper_precrq_rs_qh_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13139 break;
13140 case OPC_PRECRQU_S_OB_QH:
13141 check_dsp(ctx);
13142 gen_helper_precrqu_s_ob_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13143 break;
13145 break;
13146 #endif
13149 tcg_temp_free(v1_t);
13150 tcg_temp_free(v2_t);
13152 (void)opn; /* avoid a compiler warning */
13153 MIPS_DEBUG("%s", opn);
13156 static void gen_mipsdsp_shift(DisasContext *ctx, uint32_t opc,
13157 int ret, int v1, int v2)
13159 uint32_t op2;
13160 const char *opn = "mipsdsp shift";
13161 TCGv t0;
13162 TCGv v1_t;
13163 TCGv v2_t;
13165 if (ret == 0) {
13166 /* Treat as NOP. */
13167 MIPS_DEBUG("NOP");
13168 return;
13171 t0 = tcg_temp_new();
13172 v1_t = tcg_temp_new();
13173 v2_t = tcg_temp_new();
13175 tcg_gen_movi_tl(t0, v1);
13176 gen_load_gpr(v1_t, v1);
13177 gen_load_gpr(v2_t, v2);
13179 switch (opc) {
13180 case OPC_SHLL_QB_DSP:
13182 op2 = MASK_SHLL_QB(ctx->opcode);
13183 switch (op2) {
13184 case OPC_SHLL_QB:
13185 check_dsp(ctx);
13186 gen_helper_shll_qb(cpu_gpr[ret], t0, v2_t, cpu_env);
13187 break;
13188 case OPC_SHLLV_QB:
13189 check_dsp(ctx);
13190 gen_helper_shll_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13191 break;
13192 case OPC_SHLL_PH:
13193 check_dsp(ctx);
13194 gen_helper_shll_ph(cpu_gpr[ret], t0, v2_t, cpu_env);
13195 break;
13196 case OPC_SHLLV_PH:
13197 check_dsp(ctx);
13198 gen_helper_shll_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13199 break;
13200 case OPC_SHLL_S_PH:
13201 check_dsp(ctx);
13202 gen_helper_shll_s_ph(cpu_gpr[ret], t0, v2_t, cpu_env);
13203 break;
13204 case OPC_SHLLV_S_PH:
13205 check_dsp(ctx);
13206 gen_helper_shll_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13207 break;
13208 case OPC_SHLL_S_W:
13209 check_dsp(ctx);
13210 gen_helper_shll_s_w(cpu_gpr[ret], t0, v2_t, cpu_env);
13211 break;
13212 case OPC_SHLLV_S_W:
13213 check_dsp(ctx);
13214 gen_helper_shll_s_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13215 break;
13216 case OPC_SHRL_QB:
13217 check_dsp(ctx);
13218 gen_helper_shrl_qb(cpu_gpr[ret], t0, v2_t);
13219 break;
13220 case OPC_SHRLV_QB:
13221 check_dsp(ctx);
13222 gen_helper_shrl_qb(cpu_gpr[ret], v1_t, v2_t);
13223 break;
13224 case OPC_SHRL_PH:
13225 check_dspr2(ctx);
13226 gen_helper_shrl_ph(cpu_gpr[ret], t0, v2_t);
13227 break;
13228 case OPC_SHRLV_PH:
13229 check_dspr2(ctx);
13230 gen_helper_shrl_ph(cpu_gpr[ret], v1_t, v2_t);
13231 break;
13232 case OPC_SHRA_QB:
13233 check_dspr2(ctx);
13234 gen_helper_shra_qb(cpu_gpr[ret], t0, v2_t);
13235 break;
13236 case OPC_SHRA_R_QB:
13237 check_dspr2(ctx);
13238 gen_helper_shra_r_qb(cpu_gpr[ret], t0, v2_t);
13239 break;
13240 case OPC_SHRAV_QB:
13241 check_dspr2(ctx);
13242 gen_helper_shra_qb(cpu_gpr[ret], v1_t, v2_t);
13243 break;
13244 case OPC_SHRAV_R_QB:
13245 check_dspr2(ctx);
13246 gen_helper_shra_r_qb(cpu_gpr[ret], v1_t, v2_t);
13247 break;
13248 case OPC_SHRA_PH:
13249 check_dsp(ctx);
13250 gen_helper_shra_ph(cpu_gpr[ret], t0, v2_t);
13251 break;
13252 case OPC_SHRA_R_PH:
13253 check_dsp(ctx);
13254 gen_helper_shra_r_ph(cpu_gpr[ret], t0, v2_t);
13255 break;
13256 case OPC_SHRAV_PH:
13257 check_dsp(ctx);
13258 gen_helper_shra_ph(cpu_gpr[ret], v1_t, v2_t);
13259 break;
13260 case OPC_SHRAV_R_PH:
13261 check_dsp(ctx);
13262 gen_helper_shra_r_ph(cpu_gpr[ret], v1_t, v2_t);
13263 break;
13264 case OPC_SHRA_R_W:
13265 check_dsp(ctx);
13266 gen_helper_shra_r_w(cpu_gpr[ret], t0, v2_t);
13267 break;
13268 case OPC_SHRAV_R_W:
13269 check_dsp(ctx);
13270 gen_helper_shra_r_w(cpu_gpr[ret], v1_t, v2_t);
13271 break;
13272 default: /* Invalid */
13273 MIPS_INVAL("MASK SHLL.QB");
13274 generate_exception(ctx, EXCP_RI);
13275 break;
13277 break;
13279 #ifdef TARGET_MIPS64
13280 case OPC_SHLL_OB_DSP:
13281 op2 = MASK_SHLL_OB(ctx->opcode);
13282 switch (op2) {
13283 case OPC_SHLL_PW:
13284 check_dsp(ctx);
13285 gen_helper_shll_pw(cpu_gpr[ret], v2_t, t0, cpu_env);
13286 break;
13287 case OPC_SHLLV_PW:
13288 check_dsp(ctx);
13289 gen_helper_shll_pw(cpu_gpr[ret], v2_t, v1_t, cpu_env);
13290 break;
13291 case OPC_SHLL_S_PW:
13292 check_dsp(ctx);
13293 gen_helper_shll_s_pw(cpu_gpr[ret], v2_t, t0, cpu_env);
13294 break;
13295 case OPC_SHLLV_S_PW:
13296 check_dsp(ctx);
13297 gen_helper_shll_s_pw(cpu_gpr[ret], v2_t, v1_t, cpu_env);
13298 break;
13299 case OPC_SHLL_OB:
13300 check_dsp(ctx);
13301 gen_helper_shll_ob(cpu_gpr[ret], v2_t, t0, cpu_env);
13302 break;
13303 case OPC_SHLLV_OB:
13304 check_dsp(ctx);
13305 gen_helper_shll_ob(cpu_gpr[ret], v2_t, v1_t, cpu_env);
13306 break;
13307 case OPC_SHLL_QH:
13308 check_dsp(ctx);
13309 gen_helper_shll_qh(cpu_gpr[ret], v2_t, t0, cpu_env);
13310 break;
13311 case OPC_SHLLV_QH:
13312 check_dsp(ctx);
13313 gen_helper_shll_qh(cpu_gpr[ret], v2_t, v1_t, cpu_env);
13314 break;
13315 case OPC_SHLL_S_QH:
13316 check_dsp(ctx);
13317 gen_helper_shll_s_qh(cpu_gpr[ret], v2_t, t0, cpu_env);
13318 break;
13319 case OPC_SHLLV_S_QH:
13320 check_dsp(ctx);
13321 gen_helper_shll_s_qh(cpu_gpr[ret], v2_t, v1_t, cpu_env);
13322 break;
13323 case OPC_SHRA_OB:
13324 check_dspr2(ctx);
13325 gen_helper_shra_ob(cpu_gpr[ret], v2_t, t0);
13326 break;
13327 case OPC_SHRAV_OB:
13328 check_dspr2(ctx);
13329 gen_helper_shra_ob(cpu_gpr[ret], v2_t, v1_t);
13330 break;
13331 case OPC_SHRA_R_OB:
13332 check_dspr2(ctx);
13333 gen_helper_shra_r_ob(cpu_gpr[ret], v2_t, t0);
13334 break;
13335 case OPC_SHRAV_R_OB:
13336 check_dspr2(ctx);
13337 gen_helper_shra_r_ob(cpu_gpr[ret], v2_t, v1_t);
13338 break;
13339 case OPC_SHRA_PW:
13340 check_dsp(ctx);
13341 gen_helper_shra_pw(cpu_gpr[ret], v2_t, t0);
13342 break;
13343 case OPC_SHRAV_PW:
13344 check_dsp(ctx);
13345 gen_helper_shra_pw(cpu_gpr[ret], v2_t, v1_t);
13346 break;
13347 case OPC_SHRA_R_PW:
13348 check_dsp(ctx);
13349 gen_helper_shra_r_pw(cpu_gpr[ret], v2_t, t0);
13350 break;
13351 case OPC_SHRAV_R_PW:
13352 check_dsp(ctx);
13353 gen_helper_shra_r_pw(cpu_gpr[ret], v2_t, v1_t);
13354 break;
13355 case OPC_SHRA_QH:
13356 check_dsp(ctx);
13357 gen_helper_shra_qh(cpu_gpr[ret], v2_t, t0);
13358 break;
13359 case OPC_SHRAV_QH:
13360 check_dsp(ctx);
13361 gen_helper_shra_qh(cpu_gpr[ret], v2_t, v1_t);
13362 break;
13363 case OPC_SHRA_R_QH:
13364 check_dsp(ctx);
13365 gen_helper_shra_r_qh(cpu_gpr[ret], v2_t, t0);
13366 break;
13367 case OPC_SHRAV_R_QH:
13368 check_dsp(ctx);
13369 gen_helper_shra_r_qh(cpu_gpr[ret], v2_t, v1_t);
13370 break;
13371 case OPC_SHRL_OB:
13372 check_dsp(ctx);
13373 gen_helper_shrl_ob(cpu_gpr[ret], v2_t, t0);
13374 break;
13375 case OPC_SHRLV_OB:
13376 check_dsp(ctx);
13377 gen_helper_shrl_ob(cpu_gpr[ret], v2_t, v1_t);
13378 break;
13379 case OPC_SHRL_QH:
13380 check_dspr2(ctx);
13381 gen_helper_shrl_qh(cpu_gpr[ret], v2_t, t0);
13382 break;
13383 case OPC_SHRLV_QH:
13384 check_dspr2(ctx);
13385 gen_helper_shrl_qh(cpu_gpr[ret], v2_t, v1_t);
13386 break;
13387 default: /* Invalid */
13388 MIPS_INVAL("MASK SHLL.OB");
13389 generate_exception(ctx, EXCP_RI);
13390 break;
13392 break;
13393 #endif
13396 tcg_temp_free(t0);
13397 tcg_temp_free(v1_t);
13398 tcg_temp_free(v2_t);
13399 (void)opn; /* avoid a compiler warning */
13400 MIPS_DEBUG("%s", opn);
13403 static void gen_mipsdsp_multiply(DisasContext *ctx, uint32_t op1, uint32_t op2,
13404 int ret, int v1, int v2, int check_ret)
13406 const char *opn = "mipsdsp multiply";
13407 TCGv_i32 t0;
13408 TCGv v1_t;
13409 TCGv v2_t;
13411 if ((ret == 0) && (check_ret == 1)) {
13412 /* Treat as NOP. */
13413 MIPS_DEBUG("NOP");
13414 return;
13417 t0 = tcg_temp_new_i32();
13418 v1_t = tcg_temp_new();
13419 v2_t = tcg_temp_new();
13421 tcg_gen_movi_i32(t0, ret);
13422 gen_load_gpr(v1_t, v1);
13423 gen_load_gpr(v2_t, v2);
13425 switch (op1) {
13426 /* OPC_MULT_G_2E, OPC_ADDUH_QB_DSP, OPC_MUL_PH_DSP have
13427 * the same mask and op1. */
13428 case OPC_MULT_G_2E:
13429 switch (op2) {
13430 case OPC_MUL_PH:
13431 gen_helper_mul_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13432 break;
13433 case OPC_MUL_S_PH:
13434 gen_helper_mul_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13435 break;
13436 case OPC_MULQ_S_W:
13437 gen_helper_mulq_s_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13438 break;
13439 case OPC_MULQ_RS_W:
13440 gen_helper_mulq_rs_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13441 break;
13443 break;
13444 case OPC_DPA_W_PH_DSP:
13445 switch (op2) {
13446 case OPC_DPAU_H_QBL:
13447 check_dsp(ctx);
13448 gen_helper_dpau_h_qbl(t0, v1_t, v2_t, cpu_env);
13449 break;
13450 case OPC_DPAU_H_QBR:
13451 check_dsp(ctx);
13452 gen_helper_dpau_h_qbr(t0, v1_t, v2_t, cpu_env);
13453 break;
13454 case OPC_DPSU_H_QBL:
13455 check_dsp(ctx);
13456 gen_helper_dpsu_h_qbl(t0, v1_t, v2_t, cpu_env);
13457 break;
13458 case OPC_DPSU_H_QBR:
13459 check_dsp(ctx);
13460 gen_helper_dpsu_h_qbr(t0, v1_t, v2_t, cpu_env);
13461 break;
13462 case OPC_DPA_W_PH:
13463 check_dspr2(ctx);
13464 gen_helper_dpa_w_ph(t0, v1_t, v2_t, cpu_env);
13465 break;
13466 case OPC_DPAX_W_PH:
13467 check_dspr2(ctx);
13468 gen_helper_dpax_w_ph(t0, v1_t, v2_t, cpu_env);
13469 break;
13470 case OPC_DPAQ_S_W_PH:
13471 check_dsp(ctx);
13472 gen_helper_dpaq_s_w_ph(t0, v1_t, v2_t, cpu_env);
13473 break;
13474 case OPC_DPAQX_S_W_PH:
13475 check_dspr2(ctx);
13476 gen_helper_dpaqx_s_w_ph(t0, v1_t, v2_t, cpu_env);
13477 break;
13478 case OPC_DPAQX_SA_W_PH:
13479 check_dspr2(ctx);
13480 gen_helper_dpaqx_sa_w_ph(t0, v1_t, v2_t, cpu_env);
13481 break;
13482 case OPC_DPS_W_PH:
13483 check_dspr2(ctx);
13484 gen_helper_dps_w_ph(t0, v1_t, v2_t, cpu_env);
13485 break;
13486 case OPC_DPSX_W_PH:
13487 check_dspr2(ctx);
13488 gen_helper_dpsx_w_ph(t0, v1_t, v2_t, cpu_env);
13489 break;
13490 case OPC_DPSQ_S_W_PH:
13491 check_dsp(ctx);
13492 gen_helper_dpsq_s_w_ph(t0, v1_t, v2_t, cpu_env);
13493 break;
13494 case OPC_DPSQX_S_W_PH:
13495 check_dspr2(ctx);
13496 gen_helper_dpsqx_s_w_ph(t0, v1_t, v2_t, cpu_env);
13497 break;
13498 case OPC_DPSQX_SA_W_PH:
13499 check_dspr2(ctx);
13500 gen_helper_dpsqx_sa_w_ph(t0, v1_t, v2_t, cpu_env);
13501 break;
13502 case OPC_MULSAQ_S_W_PH:
13503 check_dsp(ctx);
13504 gen_helper_mulsaq_s_w_ph(t0, v1_t, v2_t, cpu_env);
13505 break;
13506 case OPC_DPAQ_SA_L_W:
13507 check_dsp(ctx);
13508 gen_helper_dpaq_sa_l_w(t0, v1_t, v2_t, cpu_env);
13509 break;
13510 case OPC_DPSQ_SA_L_W:
13511 check_dsp(ctx);
13512 gen_helper_dpsq_sa_l_w(t0, v1_t, v2_t, cpu_env);
13513 break;
13514 case OPC_MAQ_S_W_PHL:
13515 check_dsp(ctx);
13516 gen_helper_maq_s_w_phl(t0, v1_t, v2_t, cpu_env);
13517 break;
13518 case OPC_MAQ_S_W_PHR:
13519 check_dsp(ctx);
13520 gen_helper_maq_s_w_phr(t0, v1_t, v2_t, cpu_env);
13521 break;
13522 case OPC_MAQ_SA_W_PHL:
13523 check_dsp(ctx);
13524 gen_helper_maq_sa_w_phl(t0, v1_t, v2_t, cpu_env);
13525 break;
13526 case OPC_MAQ_SA_W_PHR:
13527 check_dsp(ctx);
13528 gen_helper_maq_sa_w_phr(t0, v1_t, v2_t, cpu_env);
13529 break;
13530 case OPC_MULSA_W_PH:
13531 check_dspr2(ctx);
13532 gen_helper_mulsa_w_ph(t0, v1_t, v2_t, cpu_env);
13533 break;
13535 break;
13536 #ifdef TARGET_MIPS64
13537 case OPC_DPAQ_W_QH_DSP:
13539 int ac = ret & 0x03;
13540 tcg_gen_movi_i32(t0, ac);
13542 switch (op2) {
13543 case OPC_DMADD:
13544 check_dsp(ctx);
13545 gen_helper_dmadd(v1_t, v2_t, t0, cpu_env);
13546 break;
13547 case OPC_DMADDU:
13548 check_dsp(ctx);
13549 gen_helper_dmaddu(v1_t, v2_t, t0, cpu_env);
13550 break;
13551 case OPC_DMSUB:
13552 check_dsp(ctx);
13553 gen_helper_dmsub(v1_t, v2_t, t0, cpu_env);
13554 break;
13555 case OPC_DMSUBU:
13556 check_dsp(ctx);
13557 gen_helper_dmsubu(v1_t, v2_t, t0, cpu_env);
13558 break;
13559 case OPC_DPA_W_QH:
13560 check_dspr2(ctx);
13561 gen_helper_dpa_w_qh(v1_t, v2_t, t0, cpu_env);
13562 break;
13563 case OPC_DPAQ_S_W_QH:
13564 check_dsp(ctx);
13565 gen_helper_dpaq_s_w_qh(v1_t, v2_t, t0, cpu_env);
13566 break;
13567 case OPC_DPAQ_SA_L_PW:
13568 check_dsp(ctx);
13569 gen_helper_dpaq_sa_l_pw(v1_t, v2_t, t0, cpu_env);
13570 break;
13571 case OPC_DPAU_H_OBL:
13572 check_dsp(ctx);
13573 gen_helper_dpau_h_obl(v1_t, v2_t, t0, cpu_env);
13574 break;
13575 case OPC_DPAU_H_OBR:
13576 check_dsp(ctx);
13577 gen_helper_dpau_h_obr(v1_t, v2_t, t0, cpu_env);
13578 break;
13579 case OPC_DPS_W_QH:
13580 check_dspr2(ctx);
13581 gen_helper_dps_w_qh(v1_t, v2_t, t0, cpu_env);
13582 break;
13583 case OPC_DPSQ_S_W_QH:
13584 check_dsp(ctx);
13585 gen_helper_dpsq_s_w_qh(v1_t, v2_t, t0, cpu_env);
13586 break;
13587 case OPC_DPSQ_SA_L_PW:
13588 check_dsp(ctx);
13589 gen_helper_dpsq_sa_l_pw(v1_t, v2_t, t0, cpu_env);
13590 break;
13591 case OPC_DPSU_H_OBL:
13592 check_dsp(ctx);
13593 gen_helper_dpsu_h_obl(v1_t, v2_t, t0, cpu_env);
13594 break;
13595 case OPC_DPSU_H_OBR:
13596 check_dsp(ctx);
13597 gen_helper_dpsu_h_obr(v1_t, v2_t, t0, cpu_env);
13598 break;
13599 case OPC_MAQ_S_L_PWL:
13600 check_dsp(ctx);
13601 gen_helper_maq_s_l_pwl(v1_t, v2_t, t0, cpu_env);
13602 break;
13603 case OPC_MAQ_S_L_PWR:
13604 check_dsp(ctx);
13605 gen_helper_maq_s_l_pwr(v1_t, v2_t, t0, cpu_env);
13606 break;
13607 case OPC_MAQ_S_W_QHLL:
13608 check_dsp(ctx);
13609 gen_helper_maq_s_w_qhll(v1_t, v2_t, t0, cpu_env);
13610 break;
13611 case OPC_MAQ_SA_W_QHLL:
13612 check_dsp(ctx);
13613 gen_helper_maq_sa_w_qhll(v1_t, v2_t, t0, cpu_env);
13614 break;
13615 case OPC_MAQ_S_W_QHLR:
13616 check_dsp(ctx);
13617 gen_helper_maq_s_w_qhlr(v1_t, v2_t, t0, cpu_env);
13618 break;
13619 case OPC_MAQ_SA_W_QHLR:
13620 check_dsp(ctx);
13621 gen_helper_maq_sa_w_qhlr(v1_t, v2_t, t0, cpu_env);
13622 break;
13623 case OPC_MAQ_S_W_QHRL:
13624 check_dsp(ctx);
13625 gen_helper_maq_s_w_qhrl(v1_t, v2_t, t0, cpu_env);
13626 break;
13627 case OPC_MAQ_SA_W_QHRL:
13628 check_dsp(ctx);
13629 gen_helper_maq_sa_w_qhrl(v1_t, v2_t, t0, cpu_env);
13630 break;
13631 case OPC_MAQ_S_W_QHRR:
13632 check_dsp(ctx);
13633 gen_helper_maq_s_w_qhrr(v1_t, v2_t, t0, cpu_env);
13634 break;
13635 case OPC_MAQ_SA_W_QHRR:
13636 check_dsp(ctx);
13637 gen_helper_maq_sa_w_qhrr(v1_t, v2_t, t0, cpu_env);
13638 break;
13639 case OPC_MULSAQ_S_L_PW:
13640 check_dsp(ctx);
13641 gen_helper_mulsaq_s_l_pw(v1_t, v2_t, t0, cpu_env);
13642 break;
13643 case OPC_MULSAQ_S_W_QH:
13644 check_dsp(ctx);
13645 gen_helper_mulsaq_s_w_qh(v1_t, v2_t, t0, cpu_env);
13646 break;
13649 break;
13650 #endif
13651 case OPC_ADDU_QB_DSP:
13652 switch (op2) {
13653 case OPC_MULEU_S_PH_QBL:
13654 check_dsp(ctx);
13655 gen_helper_muleu_s_ph_qbl(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13656 break;
13657 case OPC_MULEU_S_PH_QBR:
13658 check_dsp(ctx);
13659 gen_helper_muleu_s_ph_qbr(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13660 break;
13661 case OPC_MULQ_RS_PH:
13662 check_dsp(ctx);
13663 gen_helper_mulq_rs_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13664 break;
13665 case OPC_MULEQ_S_W_PHL:
13666 check_dsp(ctx);
13667 gen_helper_muleq_s_w_phl(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13668 break;
13669 case OPC_MULEQ_S_W_PHR:
13670 check_dsp(ctx);
13671 gen_helper_muleq_s_w_phr(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13672 break;
13673 case OPC_MULQ_S_PH:
13674 check_dspr2(ctx);
13675 gen_helper_mulq_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13676 break;
13678 break;
13679 #ifdef TARGET_MIPS64
13680 case OPC_ADDU_OB_DSP:
13681 switch (op2) {
13682 case OPC_MULEQ_S_PW_QHL:
13683 check_dsp(ctx);
13684 gen_helper_muleq_s_pw_qhl(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13685 break;
13686 case OPC_MULEQ_S_PW_QHR:
13687 check_dsp(ctx);
13688 gen_helper_muleq_s_pw_qhr(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13689 break;
13690 case OPC_MULEU_S_QH_OBL:
13691 check_dsp(ctx);
13692 gen_helper_muleu_s_qh_obl(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13693 break;
13694 case OPC_MULEU_S_QH_OBR:
13695 check_dsp(ctx);
13696 gen_helper_muleu_s_qh_obr(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13697 break;
13698 case OPC_MULQ_RS_QH:
13699 check_dsp(ctx);
13700 gen_helper_mulq_rs_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13701 break;
13703 break;
13704 #endif
13707 tcg_temp_free_i32(t0);
13708 tcg_temp_free(v1_t);
13709 tcg_temp_free(v2_t);
13711 (void)opn; /* avoid a compiler warning */
13712 MIPS_DEBUG("%s", opn);
13716 static void gen_mipsdsp_bitinsn(DisasContext *ctx, uint32_t op1, uint32_t op2,
13717 int ret, int val)
13719 const char *opn = "mipsdsp Bit/ Manipulation";
13720 int16_t imm;
13721 TCGv t0;
13722 TCGv val_t;
13724 if (ret == 0) {
13725 /* Treat as NOP. */
13726 MIPS_DEBUG("NOP");
13727 return;
13730 t0 = tcg_temp_new();
13731 val_t = tcg_temp_new();
13732 gen_load_gpr(val_t, val);
13734 switch (op1) {
13735 case OPC_ABSQ_S_PH_DSP:
13736 switch (op2) {
13737 case OPC_BITREV:
13738 check_dsp(ctx);
13739 gen_helper_bitrev(cpu_gpr[ret], val_t);
13740 break;
13741 case OPC_REPL_QB:
13742 check_dsp(ctx);
13744 target_long result;
13745 imm = (ctx->opcode >> 16) & 0xFF;
13746 result = (uint32_t)imm << 24 |
13747 (uint32_t)imm << 16 |
13748 (uint32_t)imm << 8 |
13749 (uint32_t)imm;
13750 result = (int32_t)result;
13751 tcg_gen_movi_tl(cpu_gpr[ret], result);
13753 break;
13754 case OPC_REPLV_QB:
13755 check_dsp(ctx);
13756 tcg_gen_ext8u_tl(cpu_gpr[ret], val_t);
13757 tcg_gen_shli_tl(t0, cpu_gpr[ret], 8);
13758 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
13759 tcg_gen_shli_tl(t0, cpu_gpr[ret], 16);
13760 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
13761 tcg_gen_ext32s_tl(cpu_gpr[ret], cpu_gpr[ret]);
13762 break;
13763 case OPC_REPL_PH:
13764 check_dsp(ctx);
13766 imm = (ctx->opcode >> 16) & 0x03FF;
13767 imm = (int16_t)(imm << 6) >> 6;
13768 tcg_gen_movi_tl(cpu_gpr[ret], \
13769 (target_long)((int32_t)imm << 16 | \
13770 (uint16_t)imm));
13772 break;
13773 case OPC_REPLV_PH:
13774 check_dsp(ctx);
13775 tcg_gen_ext16u_tl(cpu_gpr[ret], val_t);
13776 tcg_gen_shli_tl(t0, cpu_gpr[ret], 16);
13777 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
13778 tcg_gen_ext32s_tl(cpu_gpr[ret], cpu_gpr[ret]);
13779 break;
13781 break;
13782 #ifdef TARGET_MIPS64
13783 case OPC_ABSQ_S_QH_DSP:
13784 switch (op2) {
13785 case OPC_REPL_OB:
13786 check_dsp(ctx);
13788 target_long temp;
13790 imm = (ctx->opcode >> 16) & 0xFF;
13791 temp = ((uint64_t)imm << 8) | (uint64_t)imm;
13792 temp = (temp << 16) | temp;
13793 temp = (temp << 32) | temp;
13794 tcg_gen_movi_tl(cpu_gpr[ret], temp);
13795 break;
13797 case OPC_REPL_PW:
13798 check_dsp(ctx);
13800 target_long temp;
13802 imm = (ctx->opcode >> 16) & 0x03FF;
13803 imm = (int16_t)(imm << 6) >> 6;
13804 temp = ((target_long)imm << 32) \
13805 | ((target_long)imm & 0xFFFFFFFF);
13806 tcg_gen_movi_tl(cpu_gpr[ret], temp);
13807 break;
13809 case OPC_REPL_QH:
13810 check_dsp(ctx);
13812 target_long temp;
13814 imm = (ctx->opcode >> 16) & 0x03FF;
13815 imm = (int16_t)(imm << 6) >> 6;
13817 temp = ((uint64_t)(uint16_t)imm << 48) |
13818 ((uint64_t)(uint16_t)imm << 32) |
13819 ((uint64_t)(uint16_t)imm << 16) |
13820 (uint64_t)(uint16_t)imm;
13821 tcg_gen_movi_tl(cpu_gpr[ret], temp);
13822 break;
13824 case OPC_REPLV_OB:
13825 check_dsp(ctx);
13826 tcg_gen_ext8u_tl(cpu_gpr[ret], val_t);
13827 tcg_gen_shli_tl(t0, cpu_gpr[ret], 8);
13828 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
13829 tcg_gen_shli_tl(t0, cpu_gpr[ret], 16);
13830 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
13831 tcg_gen_shli_tl(t0, cpu_gpr[ret], 32);
13832 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
13833 break;
13834 case OPC_REPLV_PW:
13835 check_dsp(ctx);
13836 tcg_gen_ext32u_i64(cpu_gpr[ret], val_t);
13837 tcg_gen_shli_tl(t0, cpu_gpr[ret], 32);
13838 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
13839 break;
13840 case OPC_REPLV_QH:
13841 check_dsp(ctx);
13842 tcg_gen_ext16u_tl(cpu_gpr[ret], val_t);
13843 tcg_gen_shli_tl(t0, cpu_gpr[ret], 16);
13844 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
13845 tcg_gen_shli_tl(t0, cpu_gpr[ret], 32);
13846 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
13847 break;
13849 break;
13850 #endif
13852 tcg_temp_free(t0);
13853 tcg_temp_free(val_t);
13855 (void)opn; /* avoid a compiler warning */
13856 MIPS_DEBUG("%s", opn);
13859 static void gen_mipsdsp_add_cmp_pick(DisasContext *ctx,
13860 uint32_t op1, uint32_t op2,
13861 int ret, int v1, int v2, int check_ret)
13863 const char *opn = "mipsdsp add compare pick";
13864 TCGv t1;
13865 TCGv v1_t;
13866 TCGv v2_t;
13868 if ((ret == 0) && (check_ret == 1)) {
13869 /* Treat as NOP. */
13870 MIPS_DEBUG("NOP");
13871 return;
13874 t1 = tcg_temp_new();
13875 v1_t = tcg_temp_new();
13876 v2_t = tcg_temp_new();
13878 gen_load_gpr(v1_t, v1);
13879 gen_load_gpr(v2_t, v2);
13881 switch (op1) {
13882 case OPC_CMPU_EQ_QB_DSP:
13883 switch (op2) {
13884 case OPC_CMPU_EQ_QB:
13885 check_dsp(ctx);
13886 gen_helper_cmpu_eq_qb(v1_t, v2_t, cpu_env);
13887 break;
13888 case OPC_CMPU_LT_QB:
13889 check_dsp(ctx);
13890 gen_helper_cmpu_lt_qb(v1_t, v2_t, cpu_env);
13891 break;
13892 case OPC_CMPU_LE_QB:
13893 check_dsp(ctx);
13894 gen_helper_cmpu_le_qb(v1_t, v2_t, cpu_env);
13895 break;
13896 case OPC_CMPGU_EQ_QB:
13897 check_dsp(ctx);
13898 gen_helper_cmpgu_eq_qb(cpu_gpr[ret], v1_t, v2_t);
13899 break;
13900 case OPC_CMPGU_LT_QB:
13901 check_dsp(ctx);
13902 gen_helper_cmpgu_lt_qb(cpu_gpr[ret], v1_t, v2_t);
13903 break;
13904 case OPC_CMPGU_LE_QB:
13905 check_dsp(ctx);
13906 gen_helper_cmpgu_le_qb(cpu_gpr[ret], v1_t, v2_t);
13907 break;
13908 case OPC_CMPGDU_EQ_QB:
13909 check_dspr2(ctx);
13910 gen_helper_cmpgu_eq_qb(t1, v1_t, v2_t);
13911 tcg_gen_mov_tl(cpu_gpr[ret], t1);
13912 tcg_gen_andi_tl(cpu_dspctrl, cpu_dspctrl, 0xF0FFFFFF);
13913 tcg_gen_shli_tl(t1, t1, 24);
13914 tcg_gen_or_tl(cpu_dspctrl, cpu_dspctrl, t1);
13915 break;
13916 case OPC_CMPGDU_LT_QB:
13917 check_dspr2(ctx);
13918 gen_helper_cmpgu_lt_qb(t1, v1_t, v2_t);
13919 tcg_gen_mov_tl(cpu_gpr[ret], t1);
13920 tcg_gen_andi_tl(cpu_dspctrl, cpu_dspctrl, 0xF0FFFFFF);
13921 tcg_gen_shli_tl(t1, t1, 24);
13922 tcg_gen_or_tl(cpu_dspctrl, cpu_dspctrl, t1);
13923 break;
13924 case OPC_CMPGDU_LE_QB:
13925 check_dspr2(ctx);
13926 gen_helper_cmpgu_le_qb(t1, v1_t, v2_t);
13927 tcg_gen_mov_tl(cpu_gpr[ret], t1);
13928 tcg_gen_andi_tl(cpu_dspctrl, cpu_dspctrl, 0xF0FFFFFF);
13929 tcg_gen_shli_tl(t1, t1, 24);
13930 tcg_gen_or_tl(cpu_dspctrl, cpu_dspctrl, t1);
13931 break;
13932 case OPC_CMP_EQ_PH:
13933 check_dsp(ctx);
13934 gen_helper_cmp_eq_ph(v1_t, v2_t, cpu_env);
13935 break;
13936 case OPC_CMP_LT_PH:
13937 check_dsp(ctx);
13938 gen_helper_cmp_lt_ph(v1_t, v2_t, cpu_env);
13939 break;
13940 case OPC_CMP_LE_PH:
13941 check_dsp(ctx);
13942 gen_helper_cmp_le_ph(v1_t, v2_t, cpu_env);
13943 break;
13944 case OPC_PICK_QB:
13945 check_dsp(ctx);
13946 gen_helper_pick_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13947 break;
13948 case OPC_PICK_PH:
13949 check_dsp(ctx);
13950 gen_helper_pick_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13951 break;
13952 case OPC_PACKRL_PH:
13953 check_dsp(ctx);
13954 gen_helper_packrl_ph(cpu_gpr[ret], v1_t, v2_t);
13955 break;
13957 break;
13958 #ifdef TARGET_MIPS64
13959 case OPC_CMPU_EQ_OB_DSP:
13960 switch (op2) {
13961 case OPC_CMP_EQ_PW:
13962 check_dsp(ctx);
13963 gen_helper_cmp_eq_pw(v1_t, v2_t, cpu_env);
13964 break;
13965 case OPC_CMP_LT_PW:
13966 check_dsp(ctx);
13967 gen_helper_cmp_lt_pw(v1_t, v2_t, cpu_env);
13968 break;
13969 case OPC_CMP_LE_PW:
13970 check_dsp(ctx);
13971 gen_helper_cmp_le_pw(v1_t, v2_t, cpu_env);
13972 break;
13973 case OPC_CMP_EQ_QH:
13974 check_dsp(ctx);
13975 gen_helper_cmp_eq_qh(v1_t, v2_t, cpu_env);
13976 break;
13977 case OPC_CMP_LT_QH:
13978 check_dsp(ctx);
13979 gen_helper_cmp_lt_qh(v1_t, v2_t, cpu_env);
13980 break;
13981 case OPC_CMP_LE_QH:
13982 check_dsp(ctx);
13983 gen_helper_cmp_le_qh(v1_t, v2_t, cpu_env);
13984 break;
13985 case OPC_CMPGDU_EQ_OB:
13986 check_dspr2(ctx);
13987 gen_helper_cmpgdu_eq_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13988 break;
13989 case OPC_CMPGDU_LT_OB:
13990 check_dspr2(ctx);
13991 gen_helper_cmpgdu_lt_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13992 break;
13993 case OPC_CMPGDU_LE_OB:
13994 check_dspr2(ctx);
13995 gen_helper_cmpgdu_le_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13996 break;
13997 case OPC_CMPGU_EQ_OB:
13998 check_dsp(ctx);
13999 gen_helper_cmpgu_eq_ob(cpu_gpr[ret], v1_t, v2_t);
14000 break;
14001 case OPC_CMPGU_LT_OB:
14002 check_dsp(ctx);
14003 gen_helper_cmpgu_lt_ob(cpu_gpr[ret], v1_t, v2_t);
14004 break;
14005 case OPC_CMPGU_LE_OB:
14006 check_dsp(ctx);
14007 gen_helper_cmpgu_le_ob(cpu_gpr[ret], v1_t, v2_t);
14008 break;
14009 case OPC_CMPU_EQ_OB:
14010 check_dsp(ctx);
14011 gen_helper_cmpu_eq_ob(v1_t, v2_t, cpu_env);
14012 break;
14013 case OPC_CMPU_LT_OB:
14014 check_dsp(ctx);
14015 gen_helper_cmpu_lt_ob(v1_t, v2_t, cpu_env);
14016 break;
14017 case OPC_CMPU_LE_OB:
14018 check_dsp(ctx);
14019 gen_helper_cmpu_le_ob(v1_t, v2_t, cpu_env);
14020 break;
14021 case OPC_PACKRL_PW:
14022 check_dsp(ctx);
14023 gen_helper_packrl_pw(cpu_gpr[ret], v1_t, v2_t);
14024 break;
14025 case OPC_PICK_OB:
14026 check_dsp(ctx);
14027 gen_helper_pick_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
14028 break;
14029 case OPC_PICK_PW:
14030 check_dsp(ctx);
14031 gen_helper_pick_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
14032 break;
14033 case OPC_PICK_QH:
14034 check_dsp(ctx);
14035 gen_helper_pick_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
14036 break;
14038 break;
14039 #endif
14042 tcg_temp_free(t1);
14043 tcg_temp_free(v1_t);
14044 tcg_temp_free(v2_t);
14046 (void)opn; /* avoid a compiler warning */
14047 MIPS_DEBUG("%s", opn);
14050 static void gen_mipsdsp_append(CPUMIPSState *env, DisasContext *ctx,
14051 uint32_t op1, int rt, int rs, int sa)
14053 const char *opn = "mipsdsp append/dappend";
14054 TCGv t0;
14056 check_dspr2(ctx);
14058 if (rt == 0) {
14059 /* Treat as NOP. */
14060 MIPS_DEBUG("NOP");
14061 return;
14064 t0 = tcg_temp_new();
14065 gen_load_gpr(t0, rs);
14067 switch (op1) {
14068 case OPC_APPEND_DSP:
14069 switch (MASK_APPEND(ctx->opcode)) {
14070 case OPC_APPEND:
14071 if (sa != 0) {
14072 tcg_gen_deposit_tl(cpu_gpr[rt], t0, cpu_gpr[rt], sa, 32 - sa);
14074 tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]);
14075 break;
14076 case OPC_PREPEND:
14077 if (sa != 0) {
14078 tcg_gen_ext32u_tl(cpu_gpr[rt], cpu_gpr[rt]);
14079 tcg_gen_shri_tl(cpu_gpr[rt], cpu_gpr[rt], sa);
14080 tcg_gen_shli_tl(t0, t0, 32 - sa);
14081 tcg_gen_or_tl(cpu_gpr[rt], cpu_gpr[rt], t0);
14083 tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]);
14084 break;
14085 case OPC_BALIGN:
14086 sa &= 3;
14087 if (sa != 0 && sa != 2) {
14088 tcg_gen_shli_tl(cpu_gpr[rt], cpu_gpr[rt], 8 * sa);
14089 tcg_gen_ext32u_tl(t0, t0);
14090 tcg_gen_shri_tl(t0, t0, 8 * (4 - sa));
14091 tcg_gen_or_tl(cpu_gpr[rt], cpu_gpr[rt], t0);
14093 tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]);
14094 break;
14095 default: /* Invalid */
14096 MIPS_INVAL("MASK APPEND");
14097 generate_exception(ctx, EXCP_RI);
14098 break;
14100 break;
14101 #ifdef TARGET_MIPS64
14102 case OPC_DAPPEND_DSP:
14103 switch (MASK_DAPPEND(ctx->opcode)) {
14104 case OPC_DAPPEND:
14105 if (sa != 0) {
14106 tcg_gen_deposit_tl(cpu_gpr[rt], t0, cpu_gpr[rt], sa, 64 - sa);
14108 break;
14109 case OPC_PREPENDD:
14110 tcg_gen_shri_tl(cpu_gpr[rt], cpu_gpr[rt], 0x20 | sa);
14111 tcg_gen_shli_tl(t0, t0, 64 - (0x20 | sa));
14112 tcg_gen_or_tl(cpu_gpr[rt], t0, t0);
14113 break;
14114 case OPC_PREPENDW:
14115 if (sa != 0) {
14116 tcg_gen_shri_tl(cpu_gpr[rt], cpu_gpr[rt], sa);
14117 tcg_gen_shli_tl(t0, t0, 64 - sa);
14118 tcg_gen_or_tl(cpu_gpr[rt], cpu_gpr[rt], t0);
14120 break;
14121 case OPC_DBALIGN:
14122 sa &= 7;
14123 if (sa != 0 && sa != 2 && sa != 4) {
14124 tcg_gen_shli_tl(cpu_gpr[rt], cpu_gpr[rt], 8 * sa);
14125 tcg_gen_shri_tl(t0, t0, 8 * (8 - sa));
14126 tcg_gen_or_tl(cpu_gpr[rt], cpu_gpr[rt], t0);
14128 break;
14129 default: /* Invalid */
14130 MIPS_INVAL("MASK DAPPEND");
14131 generate_exception(ctx, EXCP_RI);
14132 break;
14134 break;
14135 #endif
14137 tcg_temp_free(t0);
14138 (void)opn; /* avoid a compiler warning */
14139 MIPS_DEBUG("%s", opn);
14142 static void gen_mipsdsp_accinsn(DisasContext *ctx, uint32_t op1, uint32_t op2,
14143 int ret, int v1, int v2, int check_ret)
14146 const char *opn = "mipsdsp accumulator";
14147 TCGv t0;
14148 TCGv t1;
14149 TCGv v1_t;
14150 TCGv v2_t;
14151 int16_t imm;
14153 if ((ret == 0) && (check_ret == 1)) {
14154 /* Treat as NOP. */
14155 MIPS_DEBUG("NOP");
14156 return;
14159 t0 = tcg_temp_new();
14160 t1 = tcg_temp_new();
14161 v1_t = tcg_temp_new();
14162 v2_t = tcg_temp_new();
14164 gen_load_gpr(v1_t, v1);
14165 gen_load_gpr(v2_t, v2);
14167 switch (op1) {
14168 case OPC_EXTR_W_DSP:
14169 check_dsp(ctx);
14170 switch (op2) {
14171 case OPC_EXTR_W:
14172 tcg_gen_movi_tl(t0, v2);
14173 tcg_gen_movi_tl(t1, v1);
14174 gen_helper_extr_w(cpu_gpr[ret], t0, t1, cpu_env);
14175 break;
14176 case OPC_EXTR_R_W:
14177 tcg_gen_movi_tl(t0, v2);
14178 tcg_gen_movi_tl(t1, v1);
14179 gen_helper_extr_r_w(cpu_gpr[ret], t0, t1, cpu_env);
14180 break;
14181 case OPC_EXTR_RS_W:
14182 tcg_gen_movi_tl(t0, v2);
14183 tcg_gen_movi_tl(t1, v1);
14184 gen_helper_extr_rs_w(cpu_gpr[ret], t0, t1, cpu_env);
14185 break;
14186 case OPC_EXTR_S_H:
14187 tcg_gen_movi_tl(t0, v2);
14188 tcg_gen_movi_tl(t1, v1);
14189 gen_helper_extr_s_h(cpu_gpr[ret], t0, t1, cpu_env);
14190 break;
14191 case OPC_EXTRV_S_H:
14192 tcg_gen_movi_tl(t0, v2);
14193 gen_helper_extr_s_h(cpu_gpr[ret], t0, v1_t, cpu_env);
14194 break;
14195 case OPC_EXTRV_W:
14196 tcg_gen_movi_tl(t0, v2);
14197 gen_helper_extr_w(cpu_gpr[ret], t0, v1_t, cpu_env);
14198 break;
14199 case OPC_EXTRV_R_W:
14200 tcg_gen_movi_tl(t0, v2);
14201 gen_helper_extr_r_w(cpu_gpr[ret], t0, v1_t, cpu_env);
14202 break;
14203 case OPC_EXTRV_RS_W:
14204 tcg_gen_movi_tl(t0, v2);
14205 gen_helper_extr_rs_w(cpu_gpr[ret], t0, v1_t, cpu_env);
14206 break;
14207 case OPC_EXTP:
14208 tcg_gen_movi_tl(t0, v2);
14209 tcg_gen_movi_tl(t1, v1);
14210 gen_helper_extp(cpu_gpr[ret], t0, t1, cpu_env);
14211 break;
14212 case OPC_EXTPV:
14213 tcg_gen_movi_tl(t0, v2);
14214 gen_helper_extp(cpu_gpr[ret], t0, v1_t, cpu_env);
14215 break;
14216 case OPC_EXTPDP:
14217 tcg_gen_movi_tl(t0, v2);
14218 tcg_gen_movi_tl(t1, v1);
14219 gen_helper_extpdp(cpu_gpr[ret], t0, t1, cpu_env);
14220 break;
14221 case OPC_EXTPDPV:
14222 tcg_gen_movi_tl(t0, v2);
14223 gen_helper_extpdp(cpu_gpr[ret], t0, v1_t, cpu_env);
14224 break;
14225 case OPC_SHILO:
14226 imm = (ctx->opcode >> 20) & 0x3F;
14227 tcg_gen_movi_tl(t0, ret);
14228 tcg_gen_movi_tl(t1, imm);
14229 gen_helper_shilo(t0, t1, cpu_env);
14230 break;
14231 case OPC_SHILOV:
14232 tcg_gen_movi_tl(t0, ret);
14233 gen_helper_shilo(t0, v1_t, cpu_env);
14234 break;
14235 case OPC_MTHLIP:
14236 tcg_gen_movi_tl(t0, ret);
14237 gen_helper_mthlip(t0, v1_t, cpu_env);
14238 break;
14239 case OPC_WRDSP:
14240 imm = (ctx->opcode >> 11) & 0x3FF;
14241 tcg_gen_movi_tl(t0, imm);
14242 gen_helper_wrdsp(v1_t, t0, cpu_env);
14243 break;
14244 case OPC_RDDSP:
14245 imm = (ctx->opcode >> 16) & 0x03FF;
14246 tcg_gen_movi_tl(t0, imm);
14247 gen_helper_rddsp(cpu_gpr[ret], t0, cpu_env);
14248 break;
14250 break;
14251 #ifdef TARGET_MIPS64
14252 case OPC_DEXTR_W_DSP:
14253 check_dsp(ctx);
14254 switch (op2) {
14255 case OPC_DMTHLIP:
14256 tcg_gen_movi_tl(t0, ret);
14257 gen_helper_dmthlip(v1_t, t0, cpu_env);
14258 break;
14259 case OPC_DSHILO:
14261 int shift = (ctx->opcode >> 19) & 0x7F;
14262 int ac = (ctx->opcode >> 11) & 0x03;
14263 tcg_gen_movi_tl(t0, shift);
14264 tcg_gen_movi_tl(t1, ac);
14265 gen_helper_dshilo(t0, t1, cpu_env);
14266 break;
14268 case OPC_DSHILOV:
14270 int ac = (ctx->opcode >> 11) & 0x03;
14271 tcg_gen_movi_tl(t0, ac);
14272 gen_helper_dshilo(v1_t, t0, cpu_env);
14273 break;
14275 case OPC_DEXTP:
14276 tcg_gen_movi_tl(t0, v2);
14277 tcg_gen_movi_tl(t1, v1);
14279 gen_helper_dextp(cpu_gpr[ret], t0, t1, cpu_env);
14280 break;
14281 case OPC_DEXTPV:
14282 tcg_gen_movi_tl(t0, v2);
14283 gen_helper_dextp(cpu_gpr[ret], t0, v1_t, cpu_env);
14284 break;
14285 case OPC_DEXTPDP:
14286 tcg_gen_movi_tl(t0, v2);
14287 tcg_gen_movi_tl(t1, v1);
14288 gen_helper_dextpdp(cpu_gpr[ret], t0, t1, cpu_env);
14289 break;
14290 case OPC_DEXTPDPV:
14291 tcg_gen_movi_tl(t0, v2);
14292 gen_helper_dextpdp(cpu_gpr[ret], t0, v1_t, cpu_env);
14293 break;
14294 case OPC_DEXTR_L:
14295 tcg_gen_movi_tl(t0, v2);
14296 tcg_gen_movi_tl(t1, v1);
14297 gen_helper_dextr_l(cpu_gpr[ret], t0, t1, cpu_env);
14298 break;
14299 case OPC_DEXTR_R_L:
14300 tcg_gen_movi_tl(t0, v2);
14301 tcg_gen_movi_tl(t1, v1);
14302 gen_helper_dextr_r_l(cpu_gpr[ret], t0, t1, cpu_env);
14303 break;
14304 case OPC_DEXTR_RS_L:
14305 tcg_gen_movi_tl(t0, v2);
14306 tcg_gen_movi_tl(t1, v1);
14307 gen_helper_dextr_rs_l(cpu_gpr[ret], t0, t1, cpu_env);
14308 break;
14309 case OPC_DEXTR_W:
14310 tcg_gen_movi_tl(t0, v2);
14311 tcg_gen_movi_tl(t1, v1);
14312 gen_helper_dextr_w(cpu_gpr[ret], t0, t1, cpu_env);
14313 break;
14314 case OPC_DEXTR_R_W:
14315 tcg_gen_movi_tl(t0, v2);
14316 tcg_gen_movi_tl(t1, v1);
14317 gen_helper_dextr_r_w(cpu_gpr[ret], t0, t1, cpu_env);
14318 break;
14319 case OPC_DEXTR_RS_W:
14320 tcg_gen_movi_tl(t0, v2);
14321 tcg_gen_movi_tl(t1, v1);
14322 gen_helper_dextr_rs_w(cpu_gpr[ret], t0, t1, cpu_env);
14323 break;
14324 case OPC_DEXTR_S_H:
14325 tcg_gen_movi_tl(t0, v2);
14326 tcg_gen_movi_tl(t1, v1);
14327 gen_helper_dextr_s_h(cpu_gpr[ret], t0, t1, cpu_env);
14328 break;
14329 case OPC_DEXTRV_S_H:
14330 tcg_gen_movi_tl(t0, v2);
14331 tcg_gen_movi_tl(t1, v1);
14332 gen_helper_dextr_s_h(cpu_gpr[ret], t0, t1, cpu_env);
14333 break;
14334 case OPC_DEXTRV_L:
14335 tcg_gen_movi_tl(t0, v2);
14336 gen_helper_dextr_l(cpu_gpr[ret], t0, v1_t, cpu_env);
14337 break;
14338 case OPC_DEXTRV_R_L:
14339 tcg_gen_movi_tl(t0, v2);
14340 gen_helper_dextr_r_l(cpu_gpr[ret], t0, v1_t, cpu_env);
14341 break;
14342 case OPC_DEXTRV_RS_L:
14343 tcg_gen_movi_tl(t0, v2);
14344 gen_helper_dextr_rs_l(cpu_gpr[ret], t0, v1_t, cpu_env);
14345 break;
14346 case OPC_DEXTRV_W:
14347 tcg_gen_movi_tl(t0, v2);
14348 gen_helper_dextr_w(cpu_gpr[ret], t0, v1_t, cpu_env);
14349 break;
14350 case OPC_DEXTRV_R_W:
14351 tcg_gen_movi_tl(t0, v2);
14352 gen_helper_dextr_r_w(cpu_gpr[ret], t0, v1_t, cpu_env);
14353 break;
14354 case OPC_DEXTRV_RS_W:
14355 tcg_gen_movi_tl(t0, v2);
14356 gen_helper_dextr_rs_w(cpu_gpr[ret], t0, v1_t, cpu_env);
14357 break;
14359 break;
14360 #endif
14363 tcg_temp_free(t0);
14364 tcg_temp_free(t1);
14365 tcg_temp_free(v1_t);
14366 tcg_temp_free(v2_t);
14368 (void)opn; /* avoid a compiler warning */
14369 MIPS_DEBUG("%s", opn);
14372 /* End MIPSDSP functions. */
14374 static void decode_opc (CPUMIPSState *env, DisasContext *ctx, int *is_branch)
14376 int32_t offset;
14377 int rs, rt, rd, sa;
14378 uint32_t op, op1, op2;
14379 int16_t imm;
14381 /* make sure instructions are on a word boundary */
14382 if (ctx->pc & 0x3) {
14383 env->CP0_BadVAddr = ctx->pc;
14384 generate_exception(ctx, EXCP_AdEL);
14385 return;
14388 /* Handle blikely not taken case */
14389 if ((ctx->hflags & MIPS_HFLAG_BMASK_BASE) == MIPS_HFLAG_BL) {
14390 int l1 = gen_new_label();
14392 MIPS_DEBUG("blikely condition (" TARGET_FMT_lx ")", ctx->pc + 4);
14393 tcg_gen_brcondi_tl(TCG_COND_NE, bcond, 0, l1);
14394 tcg_gen_movi_i32(hflags, ctx->hflags & ~MIPS_HFLAG_BMASK);
14395 gen_goto_tb(ctx, 1, ctx->pc + 4);
14396 gen_set_label(l1);
14399 if (unlikely(qemu_loglevel_mask(CPU_LOG_TB_OP | CPU_LOG_TB_OP_OPT))) {
14400 tcg_gen_debug_insn_start(ctx->pc);
14403 op = MASK_OP_MAJOR(ctx->opcode);
14404 rs = (ctx->opcode >> 21) & 0x1f;
14405 rt = (ctx->opcode >> 16) & 0x1f;
14406 rd = (ctx->opcode >> 11) & 0x1f;
14407 sa = (ctx->opcode >> 6) & 0x1f;
14408 imm = (int16_t)ctx->opcode;
14409 switch (op) {
14410 case OPC_SPECIAL:
14411 op1 = MASK_SPECIAL(ctx->opcode);
14412 switch (op1) {
14413 case OPC_SLL: /* Shift with immediate */
14414 case OPC_SRA:
14415 gen_shift_imm(ctx, op1, rd, rt, sa);
14416 break;
14417 case OPC_SRL:
14418 switch ((ctx->opcode >> 21) & 0x1f) {
14419 case 1:
14420 /* rotr is decoded as srl on non-R2 CPUs */
14421 if (ctx->insn_flags & ISA_MIPS32R2) {
14422 op1 = OPC_ROTR;
14424 /* Fallthrough */
14425 case 0:
14426 gen_shift_imm(ctx, op1, rd, rt, sa);
14427 break;
14428 default:
14429 generate_exception(ctx, EXCP_RI);
14430 break;
14432 break;
14433 case OPC_MOVN: /* Conditional move */
14434 case OPC_MOVZ:
14435 check_insn(ctx, ISA_MIPS4 | ISA_MIPS32 |
14436 INSN_LOONGSON2E | INSN_LOONGSON2F);
14437 gen_cond_move(ctx, op1, rd, rs, rt);
14438 break;
14439 case OPC_ADD ... OPC_SUBU:
14440 gen_arith(ctx, op1, rd, rs, rt);
14441 break;
14442 case OPC_SLLV: /* Shifts */
14443 case OPC_SRAV:
14444 gen_shift(ctx, op1, rd, rs, rt);
14445 break;
14446 case OPC_SRLV:
14447 switch ((ctx->opcode >> 6) & 0x1f) {
14448 case 1:
14449 /* rotrv is decoded as srlv on non-R2 CPUs */
14450 if (ctx->insn_flags & ISA_MIPS32R2) {
14451 op1 = OPC_ROTRV;
14453 /* Fallthrough */
14454 case 0:
14455 gen_shift(ctx, op1, rd, rs, rt);
14456 break;
14457 default:
14458 generate_exception(ctx, EXCP_RI);
14459 break;
14461 break;
14462 case OPC_SLT: /* Set on less than */
14463 case OPC_SLTU:
14464 gen_slt(ctx, op1, rd, rs, rt);
14465 break;
14466 case OPC_AND: /* Logic*/
14467 case OPC_OR:
14468 case OPC_NOR:
14469 case OPC_XOR:
14470 gen_logic(ctx, op1, rd, rs, rt);
14471 break;
14472 case OPC_MULT ... OPC_DIVU:
14473 if (sa) {
14474 check_insn(ctx, INSN_VR54XX);
14475 op1 = MASK_MUL_VR54XX(ctx->opcode);
14476 gen_mul_vr54xx(ctx, op1, rd, rs, rt);
14477 } else
14478 gen_muldiv(ctx, op1, rs, rt);
14479 break;
14480 case OPC_JR ... OPC_JALR:
14481 gen_compute_branch(ctx, op1, 4, rs, rd, sa);
14482 *is_branch = 1;
14483 break;
14484 case OPC_TGE ... OPC_TEQ: /* Traps */
14485 case OPC_TNE:
14486 gen_trap(ctx, op1, rs, rt, -1);
14487 break;
14488 case OPC_MFHI: /* Move from HI/LO */
14489 case OPC_MFLO:
14490 gen_HILO(ctx, op1, rd);
14491 break;
14492 case OPC_MTHI:
14493 case OPC_MTLO: /* Move to HI/LO */
14494 gen_HILO(ctx, op1, rs);
14495 break;
14496 case OPC_PMON: /* Pmon entry point, also R4010 selsl */
14497 #ifdef MIPS_STRICT_STANDARD
14498 MIPS_INVAL("PMON / selsl");
14499 generate_exception(ctx, EXCP_RI);
14500 #else
14501 gen_helper_0e0i(pmon, sa);
14502 #endif
14503 break;
14504 case OPC_SYSCALL:
14505 generate_exception(ctx, EXCP_SYSCALL);
14506 ctx->bstate = BS_STOP;
14507 break;
14508 case OPC_BREAK:
14509 generate_exception(ctx, EXCP_BREAK);
14510 break;
14511 case OPC_SPIM:
14512 #ifdef MIPS_STRICT_STANDARD
14513 MIPS_INVAL("SPIM");
14514 generate_exception(ctx, EXCP_RI);
14515 #else
14516 /* Implemented as RI exception for now. */
14517 MIPS_INVAL("spim (unofficial)");
14518 generate_exception(ctx, EXCP_RI);
14519 #endif
14520 break;
14521 case OPC_SYNC:
14522 /* Treat as NOP. */
14523 break;
14525 case OPC_MOVCI:
14526 check_insn(ctx, ISA_MIPS4 | ISA_MIPS32);
14527 if (env->CP0_Config1 & (1 << CP0C1_FP)) {
14528 check_cp1_enabled(ctx);
14529 gen_movci(ctx, rd, rs, (ctx->opcode >> 18) & 0x7,
14530 (ctx->opcode >> 16) & 1);
14531 } else {
14532 generate_exception_err(ctx, EXCP_CpU, 1);
14534 break;
14536 #if defined(TARGET_MIPS64)
14537 /* MIPS64 specific opcodes */
14538 case OPC_DSLL:
14539 case OPC_DSRA:
14540 case OPC_DSLL32:
14541 case OPC_DSRA32:
14542 check_insn(ctx, ISA_MIPS3);
14543 check_mips_64(ctx);
14544 gen_shift_imm(ctx, op1, rd, rt, sa);
14545 break;
14546 case OPC_DSRL:
14547 switch ((ctx->opcode >> 21) & 0x1f) {
14548 case 1:
14549 /* drotr is decoded as dsrl on non-R2 CPUs */
14550 if (ctx->insn_flags & ISA_MIPS32R2) {
14551 op1 = OPC_DROTR;
14553 /* Fallthrough */
14554 case 0:
14555 check_insn(ctx, ISA_MIPS3);
14556 check_mips_64(ctx);
14557 gen_shift_imm(ctx, op1, rd, rt, sa);
14558 break;
14559 default:
14560 generate_exception(ctx, EXCP_RI);
14561 break;
14563 break;
14564 case OPC_DSRL32:
14565 switch ((ctx->opcode >> 21) & 0x1f) {
14566 case 1:
14567 /* drotr32 is decoded as dsrl32 on non-R2 CPUs */
14568 if (ctx->insn_flags & ISA_MIPS32R2) {
14569 op1 = OPC_DROTR32;
14571 /* Fallthrough */
14572 case 0:
14573 check_insn(ctx, ISA_MIPS3);
14574 check_mips_64(ctx);
14575 gen_shift_imm(ctx, op1, rd, rt, sa);
14576 break;
14577 default:
14578 generate_exception(ctx, EXCP_RI);
14579 break;
14581 break;
14582 case OPC_DADD ... OPC_DSUBU:
14583 check_insn(ctx, ISA_MIPS3);
14584 check_mips_64(ctx);
14585 gen_arith(ctx, op1, rd, rs, rt);
14586 break;
14587 case OPC_DSLLV:
14588 case OPC_DSRAV:
14589 check_insn(ctx, ISA_MIPS3);
14590 check_mips_64(ctx);
14591 gen_shift(ctx, op1, rd, rs, rt);
14592 break;
14593 case OPC_DSRLV:
14594 switch ((ctx->opcode >> 6) & 0x1f) {
14595 case 1:
14596 /* drotrv is decoded as dsrlv on non-R2 CPUs */
14597 if (ctx->insn_flags & ISA_MIPS32R2) {
14598 op1 = OPC_DROTRV;
14600 /* Fallthrough */
14601 case 0:
14602 check_insn(ctx, ISA_MIPS3);
14603 check_mips_64(ctx);
14604 gen_shift(ctx, op1, rd, rs, rt);
14605 break;
14606 default:
14607 generate_exception(ctx, EXCP_RI);
14608 break;
14610 break;
14611 case OPC_DMULT ... OPC_DDIVU:
14612 check_insn(ctx, ISA_MIPS3);
14613 check_mips_64(ctx);
14614 gen_muldiv(ctx, op1, rs, rt);
14615 break;
14616 #endif
14617 default: /* Invalid */
14618 MIPS_INVAL("special");
14619 generate_exception(ctx, EXCP_RI);
14620 break;
14622 break;
14623 case OPC_SPECIAL2:
14624 op1 = MASK_SPECIAL2(ctx->opcode);
14625 switch (op1) {
14626 case OPC_MADD ... OPC_MADDU: /* Multiply and add/sub */
14627 case OPC_MSUB ... OPC_MSUBU:
14628 check_insn(ctx, ISA_MIPS32);
14629 gen_muldiv(ctx, op1, rs, rt);
14630 break;
14631 case OPC_MUL:
14632 gen_arith(ctx, op1, rd, rs, rt);
14633 break;
14634 case OPC_CLO:
14635 case OPC_CLZ:
14636 check_insn(ctx, ISA_MIPS32);
14637 gen_cl(ctx, op1, rd, rs);
14638 break;
14639 case OPC_SDBBP:
14640 /* XXX: not clear which exception should be raised
14641 * when in debug mode...
14643 check_insn(ctx, ISA_MIPS32);
14644 if (!(ctx->hflags & MIPS_HFLAG_DM)) {
14645 generate_exception(ctx, EXCP_DBp);
14646 } else {
14647 generate_exception(ctx, EXCP_DBp);
14649 /* Treat as NOP. */
14650 break;
14651 case OPC_DIV_G_2F:
14652 case OPC_DIVU_G_2F:
14653 case OPC_MULT_G_2F:
14654 case OPC_MULTU_G_2F:
14655 case OPC_MOD_G_2F:
14656 case OPC_MODU_G_2F:
14657 check_insn(ctx, INSN_LOONGSON2F);
14658 gen_loongson_integer(ctx, op1, rd, rs, rt);
14659 break;
14660 #if defined(TARGET_MIPS64)
14661 case OPC_DCLO:
14662 case OPC_DCLZ:
14663 check_insn(ctx, ISA_MIPS64);
14664 check_mips_64(ctx);
14665 gen_cl(ctx, op1, rd, rs);
14666 break;
14667 case OPC_DMULT_G_2F:
14668 case OPC_DMULTU_G_2F:
14669 case OPC_DDIV_G_2F:
14670 case OPC_DDIVU_G_2F:
14671 case OPC_DMOD_G_2F:
14672 case OPC_DMODU_G_2F:
14673 check_insn(ctx, INSN_LOONGSON2F);
14674 gen_loongson_integer(ctx, op1, rd, rs, rt);
14675 break;
14676 #endif
14677 default: /* Invalid */
14678 MIPS_INVAL("special2");
14679 generate_exception(ctx, EXCP_RI);
14680 break;
14682 break;
14683 case OPC_SPECIAL3:
14684 op1 = MASK_SPECIAL3(ctx->opcode);
14685 switch (op1) {
14686 case OPC_EXT:
14687 case OPC_INS:
14688 check_insn(ctx, ISA_MIPS32R2);
14689 gen_bitops(ctx, op1, rt, rs, sa, rd);
14690 break;
14691 case OPC_BSHFL:
14692 check_insn(ctx, ISA_MIPS32R2);
14693 op2 = MASK_BSHFL(ctx->opcode);
14694 gen_bshfl(ctx, op2, rt, rd);
14695 break;
14696 case OPC_RDHWR:
14697 gen_rdhwr(ctx, rt, rd);
14698 break;
14699 case OPC_FORK:
14700 check_insn(ctx, ASE_MT);
14702 TCGv t0 = tcg_temp_new();
14703 TCGv t1 = tcg_temp_new();
14705 gen_load_gpr(t0, rt);
14706 gen_load_gpr(t1, rs);
14707 gen_helper_fork(t0, t1);
14708 tcg_temp_free(t0);
14709 tcg_temp_free(t1);
14711 break;
14712 case OPC_YIELD:
14713 check_insn(ctx, ASE_MT);
14715 TCGv t0 = tcg_temp_new();
14717 save_cpu_state(ctx, 1);
14718 gen_load_gpr(t0, rs);
14719 gen_helper_yield(t0, cpu_env, t0);
14720 gen_store_gpr(t0, rd);
14721 tcg_temp_free(t0);
14723 break;
14724 case OPC_DIV_G_2E ... OPC_DIVU_G_2E:
14725 case OPC_MOD_G_2E ... OPC_MODU_G_2E:
14726 case OPC_MULT_G_2E ... OPC_MULTU_G_2E:
14727 /* OPC_MULT_G_2E, OPC_ADDUH_QB_DSP, OPC_MUL_PH_DSP have
14728 * the same mask and op1. */
14729 if ((ctx->insn_flags & ASE_DSPR2) && (op1 == OPC_MULT_G_2E)) {
14730 op2 = MASK_ADDUH_QB(ctx->opcode);
14731 switch (op2) {
14732 case OPC_ADDUH_QB:
14733 case OPC_ADDUH_R_QB:
14734 case OPC_ADDQH_PH:
14735 case OPC_ADDQH_R_PH:
14736 case OPC_ADDQH_W:
14737 case OPC_ADDQH_R_W:
14738 case OPC_SUBUH_QB:
14739 case OPC_SUBUH_R_QB:
14740 case OPC_SUBQH_PH:
14741 case OPC_SUBQH_R_PH:
14742 case OPC_SUBQH_W:
14743 case OPC_SUBQH_R_W:
14744 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
14745 break;
14746 case OPC_MUL_PH:
14747 case OPC_MUL_S_PH:
14748 case OPC_MULQ_S_W:
14749 case OPC_MULQ_RS_W:
14750 gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 1);
14751 break;
14752 default:
14753 MIPS_INVAL("MASK ADDUH.QB");
14754 generate_exception(ctx, EXCP_RI);
14755 break;
14757 } else if (ctx->insn_flags & INSN_LOONGSON2E) {
14758 gen_loongson_integer(ctx, op1, rd, rs, rt);
14759 } else {
14760 generate_exception(ctx, EXCP_RI);
14762 break;
14763 case OPC_LX_DSP:
14764 op2 = MASK_LX(ctx->opcode);
14765 switch (op2) {
14766 #if defined(TARGET_MIPS64)
14767 case OPC_LDX:
14768 #endif
14769 case OPC_LBUX:
14770 case OPC_LHX:
14771 case OPC_LWX:
14772 gen_mipsdsp_ld(ctx, op2, rd, rs, rt);
14773 break;
14774 default: /* Invalid */
14775 MIPS_INVAL("MASK LX");
14776 generate_exception(ctx, EXCP_RI);
14777 break;
14779 break;
14780 case OPC_ABSQ_S_PH_DSP:
14781 op2 = MASK_ABSQ_S_PH(ctx->opcode);
14782 switch (op2) {
14783 case OPC_ABSQ_S_QB:
14784 case OPC_ABSQ_S_PH:
14785 case OPC_ABSQ_S_W:
14786 case OPC_PRECEQ_W_PHL:
14787 case OPC_PRECEQ_W_PHR:
14788 case OPC_PRECEQU_PH_QBL:
14789 case OPC_PRECEQU_PH_QBR:
14790 case OPC_PRECEQU_PH_QBLA:
14791 case OPC_PRECEQU_PH_QBRA:
14792 case OPC_PRECEU_PH_QBL:
14793 case OPC_PRECEU_PH_QBR:
14794 case OPC_PRECEU_PH_QBLA:
14795 case OPC_PRECEU_PH_QBRA:
14796 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
14797 break;
14798 case OPC_BITREV:
14799 case OPC_REPL_QB:
14800 case OPC_REPLV_QB:
14801 case OPC_REPL_PH:
14802 case OPC_REPLV_PH:
14803 gen_mipsdsp_bitinsn(ctx, op1, op2, rd, rt);
14804 break;
14805 default:
14806 MIPS_INVAL("MASK ABSQ_S.PH");
14807 generate_exception(ctx, EXCP_RI);
14808 break;
14810 break;
14811 case OPC_ADDU_QB_DSP:
14812 op2 = MASK_ADDU_QB(ctx->opcode);
14813 switch (op2) {
14814 case OPC_ADDQ_PH:
14815 case OPC_ADDQ_S_PH:
14816 case OPC_ADDQ_S_W:
14817 case OPC_ADDU_QB:
14818 case OPC_ADDU_S_QB:
14819 case OPC_ADDU_PH:
14820 case OPC_ADDU_S_PH:
14821 case OPC_SUBQ_PH:
14822 case OPC_SUBQ_S_PH:
14823 case OPC_SUBQ_S_W:
14824 case OPC_SUBU_QB:
14825 case OPC_SUBU_S_QB:
14826 case OPC_SUBU_PH:
14827 case OPC_SUBU_S_PH:
14828 case OPC_ADDSC:
14829 case OPC_ADDWC:
14830 case OPC_MODSUB:
14831 case OPC_RADDU_W_QB:
14832 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
14833 break;
14834 case OPC_MULEU_S_PH_QBL:
14835 case OPC_MULEU_S_PH_QBR:
14836 case OPC_MULQ_RS_PH:
14837 case OPC_MULEQ_S_W_PHL:
14838 case OPC_MULEQ_S_W_PHR:
14839 case OPC_MULQ_S_PH:
14840 gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 1);
14841 break;
14842 default: /* Invalid */
14843 MIPS_INVAL("MASK ADDU.QB");
14844 generate_exception(ctx, EXCP_RI);
14845 break;
14848 break;
14849 case OPC_CMPU_EQ_QB_DSP:
14850 op2 = MASK_CMPU_EQ_QB(ctx->opcode);
14851 switch (op2) {
14852 case OPC_PRECR_SRA_PH_W:
14853 case OPC_PRECR_SRA_R_PH_W:
14854 gen_mipsdsp_arith(ctx, op1, op2, rt, rs, rd);
14855 break;
14856 case OPC_PRECR_QB_PH:
14857 case OPC_PRECRQ_QB_PH:
14858 case OPC_PRECRQ_PH_W:
14859 case OPC_PRECRQ_RS_PH_W:
14860 case OPC_PRECRQU_S_QB_PH:
14861 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
14862 break;
14863 case OPC_CMPU_EQ_QB:
14864 case OPC_CMPU_LT_QB:
14865 case OPC_CMPU_LE_QB:
14866 case OPC_CMP_EQ_PH:
14867 case OPC_CMP_LT_PH:
14868 case OPC_CMP_LE_PH:
14869 gen_mipsdsp_add_cmp_pick(ctx, op1, op2, rd, rs, rt, 0);
14870 break;
14871 case OPC_CMPGU_EQ_QB:
14872 case OPC_CMPGU_LT_QB:
14873 case OPC_CMPGU_LE_QB:
14874 case OPC_CMPGDU_EQ_QB:
14875 case OPC_CMPGDU_LT_QB:
14876 case OPC_CMPGDU_LE_QB:
14877 case OPC_PICK_QB:
14878 case OPC_PICK_PH:
14879 case OPC_PACKRL_PH:
14880 gen_mipsdsp_add_cmp_pick(ctx, op1, op2, rd, rs, rt, 1);
14881 break;
14882 default: /* Invalid */
14883 MIPS_INVAL("MASK CMPU.EQ.QB");
14884 generate_exception(ctx, EXCP_RI);
14885 break;
14887 break;
14888 case OPC_SHLL_QB_DSP:
14889 gen_mipsdsp_shift(ctx, op1, rd, rs, rt);
14890 break;
14891 case OPC_DPA_W_PH_DSP:
14892 op2 = MASK_DPA_W_PH(ctx->opcode);
14893 switch (op2) {
14894 case OPC_DPAU_H_QBL:
14895 case OPC_DPAU_H_QBR:
14896 case OPC_DPSU_H_QBL:
14897 case OPC_DPSU_H_QBR:
14898 case OPC_DPA_W_PH:
14899 case OPC_DPAX_W_PH:
14900 case OPC_DPAQ_S_W_PH:
14901 case OPC_DPAQX_S_W_PH:
14902 case OPC_DPAQX_SA_W_PH:
14903 case OPC_DPS_W_PH:
14904 case OPC_DPSX_W_PH:
14905 case OPC_DPSQ_S_W_PH:
14906 case OPC_DPSQX_S_W_PH:
14907 case OPC_DPSQX_SA_W_PH:
14908 case OPC_MULSAQ_S_W_PH:
14909 case OPC_DPAQ_SA_L_W:
14910 case OPC_DPSQ_SA_L_W:
14911 case OPC_MAQ_S_W_PHL:
14912 case OPC_MAQ_S_W_PHR:
14913 case OPC_MAQ_SA_W_PHL:
14914 case OPC_MAQ_SA_W_PHR:
14915 case OPC_MULSA_W_PH:
14916 gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 0);
14917 break;
14918 default: /* Invalid */
14919 MIPS_INVAL("MASK DPAW.PH");
14920 generate_exception(ctx, EXCP_RI);
14921 break;
14923 break;
14924 case OPC_INSV_DSP:
14925 op2 = MASK_INSV(ctx->opcode);
14926 switch (op2) {
14927 case OPC_INSV:
14928 check_dsp(ctx);
14930 TCGv t0, t1;
14932 if (rt == 0) {
14933 MIPS_DEBUG("NOP");
14934 break;
14937 t0 = tcg_temp_new();
14938 t1 = tcg_temp_new();
14940 gen_load_gpr(t0, rt);
14941 gen_load_gpr(t1, rs);
14943 gen_helper_insv(cpu_gpr[rt], cpu_env, t1, t0);
14945 tcg_temp_free(t0);
14946 tcg_temp_free(t1);
14947 break;
14949 default: /* Invalid */
14950 MIPS_INVAL("MASK INSV");
14951 generate_exception(ctx, EXCP_RI);
14952 break;
14954 break;
14955 case OPC_APPEND_DSP:
14956 gen_mipsdsp_append(env, ctx, op1, rt, rs, rd);
14957 break;
14958 case OPC_EXTR_W_DSP:
14959 op2 = MASK_EXTR_W(ctx->opcode);
14960 switch (op2) {
14961 case OPC_EXTR_W:
14962 case OPC_EXTR_R_W:
14963 case OPC_EXTR_RS_W:
14964 case OPC_EXTR_S_H:
14965 case OPC_EXTRV_S_H:
14966 case OPC_EXTRV_W:
14967 case OPC_EXTRV_R_W:
14968 case OPC_EXTRV_RS_W:
14969 case OPC_EXTP:
14970 case OPC_EXTPV:
14971 case OPC_EXTPDP:
14972 case OPC_EXTPDPV:
14973 gen_mipsdsp_accinsn(ctx, op1, op2, rt, rs, rd, 1);
14974 break;
14975 case OPC_RDDSP:
14976 gen_mipsdsp_accinsn(ctx, op1, op2, rd, rs, rt, 1);
14977 break;
14978 case OPC_SHILO:
14979 case OPC_SHILOV:
14980 case OPC_MTHLIP:
14981 case OPC_WRDSP:
14982 gen_mipsdsp_accinsn(ctx, op1, op2, rd, rs, rt, 0);
14983 break;
14984 default: /* Invalid */
14985 MIPS_INVAL("MASK EXTR.W");
14986 generate_exception(ctx, EXCP_RI);
14987 break;
14989 break;
14990 #if defined(TARGET_MIPS64)
14991 case OPC_DEXTM ... OPC_DEXT:
14992 case OPC_DINSM ... OPC_DINS:
14993 check_insn(ctx, ISA_MIPS64R2);
14994 check_mips_64(ctx);
14995 gen_bitops(ctx, op1, rt, rs, sa, rd);
14996 break;
14997 case OPC_DBSHFL:
14998 check_insn(ctx, ISA_MIPS64R2);
14999 check_mips_64(ctx);
15000 op2 = MASK_DBSHFL(ctx->opcode);
15001 gen_bshfl(ctx, op2, rt, rd);
15002 break;
15003 case OPC_DDIV_G_2E ... OPC_DDIVU_G_2E:
15004 case OPC_DMULT_G_2E ... OPC_DMULTU_G_2E:
15005 case OPC_DMOD_G_2E ... OPC_DMODU_G_2E:
15006 check_insn(ctx, INSN_LOONGSON2E);
15007 gen_loongson_integer(ctx, op1, rd, rs, rt);
15008 break;
15009 case OPC_ABSQ_S_QH_DSP:
15010 op2 = MASK_ABSQ_S_QH(ctx->opcode);
15011 switch (op2) {
15012 case OPC_PRECEQ_L_PWL:
15013 case OPC_PRECEQ_L_PWR:
15014 case OPC_PRECEQ_PW_QHL:
15015 case OPC_PRECEQ_PW_QHR:
15016 case OPC_PRECEQ_PW_QHLA:
15017 case OPC_PRECEQ_PW_QHRA:
15018 case OPC_PRECEQU_QH_OBL:
15019 case OPC_PRECEQU_QH_OBR:
15020 case OPC_PRECEQU_QH_OBLA:
15021 case OPC_PRECEQU_QH_OBRA:
15022 case OPC_PRECEU_QH_OBL:
15023 case OPC_PRECEU_QH_OBR:
15024 case OPC_PRECEU_QH_OBLA:
15025 case OPC_PRECEU_QH_OBRA:
15026 case OPC_ABSQ_S_OB:
15027 case OPC_ABSQ_S_PW:
15028 case OPC_ABSQ_S_QH:
15029 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
15030 break;
15031 case OPC_REPL_OB:
15032 case OPC_REPL_PW:
15033 case OPC_REPL_QH:
15034 case OPC_REPLV_OB:
15035 case OPC_REPLV_PW:
15036 case OPC_REPLV_QH:
15037 gen_mipsdsp_bitinsn(ctx, op1, op2, rd, rt);
15038 break;
15039 default: /* Invalid */
15040 MIPS_INVAL("MASK ABSQ_S.QH");
15041 generate_exception(ctx, EXCP_RI);
15042 break;
15044 break;
15045 case OPC_ADDU_OB_DSP:
15046 op2 = MASK_ADDU_OB(ctx->opcode);
15047 switch (op2) {
15048 case OPC_RADDU_L_OB:
15049 case OPC_SUBQ_PW:
15050 case OPC_SUBQ_S_PW:
15051 case OPC_SUBQ_QH:
15052 case OPC_SUBQ_S_QH:
15053 case OPC_SUBU_OB:
15054 case OPC_SUBU_S_OB:
15055 case OPC_SUBU_QH:
15056 case OPC_SUBU_S_QH:
15057 case OPC_SUBUH_OB:
15058 case OPC_SUBUH_R_OB:
15059 case OPC_ADDQ_PW:
15060 case OPC_ADDQ_S_PW:
15061 case OPC_ADDQ_QH:
15062 case OPC_ADDQ_S_QH:
15063 case OPC_ADDU_OB:
15064 case OPC_ADDU_S_OB:
15065 case OPC_ADDU_QH:
15066 case OPC_ADDU_S_QH:
15067 case OPC_ADDUH_OB:
15068 case OPC_ADDUH_R_OB:
15069 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
15070 break;
15071 case OPC_MULEQ_S_PW_QHL:
15072 case OPC_MULEQ_S_PW_QHR:
15073 case OPC_MULEU_S_QH_OBL:
15074 case OPC_MULEU_S_QH_OBR:
15075 case OPC_MULQ_RS_QH:
15076 gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 1);
15077 break;
15078 default: /* Invalid */
15079 MIPS_INVAL("MASK ADDU.OB");
15080 generate_exception(ctx, EXCP_RI);
15081 break;
15083 break;
15084 case OPC_CMPU_EQ_OB_DSP:
15085 op2 = MASK_CMPU_EQ_OB(ctx->opcode);
15086 switch (op2) {
15087 case OPC_PRECR_SRA_QH_PW:
15088 case OPC_PRECR_SRA_R_QH_PW:
15089 /* Return value is rt. */
15090 gen_mipsdsp_arith(ctx, op1, op2, rt, rs, rd);
15091 break;
15092 case OPC_PRECR_OB_QH:
15093 case OPC_PRECRQ_OB_QH:
15094 case OPC_PRECRQ_PW_L:
15095 case OPC_PRECRQ_QH_PW:
15096 case OPC_PRECRQ_RS_QH_PW:
15097 case OPC_PRECRQU_S_OB_QH:
15098 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
15099 break;
15100 case OPC_CMPU_EQ_OB:
15101 case OPC_CMPU_LT_OB:
15102 case OPC_CMPU_LE_OB:
15103 case OPC_CMP_EQ_QH:
15104 case OPC_CMP_LT_QH:
15105 case OPC_CMP_LE_QH:
15106 case OPC_CMP_EQ_PW:
15107 case OPC_CMP_LT_PW:
15108 case OPC_CMP_LE_PW:
15109 gen_mipsdsp_add_cmp_pick(ctx, op1, op2, rd, rs, rt, 0);
15110 break;
15111 case OPC_CMPGDU_EQ_OB:
15112 case OPC_CMPGDU_LT_OB:
15113 case OPC_CMPGDU_LE_OB:
15114 case OPC_CMPGU_EQ_OB:
15115 case OPC_CMPGU_LT_OB:
15116 case OPC_CMPGU_LE_OB:
15117 case OPC_PACKRL_PW:
15118 case OPC_PICK_OB:
15119 case OPC_PICK_PW:
15120 case OPC_PICK_QH:
15121 gen_mipsdsp_add_cmp_pick(ctx, op1, op2, rd, rs, rt, 1);
15122 break;
15123 default: /* Invalid */
15124 MIPS_INVAL("MASK CMPU_EQ.OB");
15125 generate_exception(ctx, EXCP_RI);
15126 break;
15128 break;
15129 case OPC_DAPPEND_DSP:
15130 gen_mipsdsp_append(env, ctx, op1, rt, rs, rd);
15131 break;
15132 case OPC_DEXTR_W_DSP:
15133 op2 = MASK_DEXTR_W(ctx->opcode);
15134 switch (op2) {
15135 case OPC_DEXTP:
15136 case OPC_DEXTPDP:
15137 case OPC_DEXTPDPV:
15138 case OPC_DEXTPV:
15139 case OPC_DEXTR_L:
15140 case OPC_DEXTR_R_L:
15141 case OPC_DEXTR_RS_L:
15142 case OPC_DEXTR_W:
15143 case OPC_DEXTR_R_W:
15144 case OPC_DEXTR_RS_W:
15145 case OPC_DEXTR_S_H:
15146 case OPC_DEXTRV_L:
15147 case OPC_DEXTRV_R_L:
15148 case OPC_DEXTRV_RS_L:
15149 case OPC_DEXTRV_S_H:
15150 case OPC_DEXTRV_W:
15151 case OPC_DEXTRV_R_W:
15152 case OPC_DEXTRV_RS_W:
15153 gen_mipsdsp_accinsn(ctx, op1, op2, rt, rs, rd, 1);
15154 break;
15155 case OPC_DMTHLIP:
15156 case OPC_DSHILO:
15157 case OPC_DSHILOV:
15158 gen_mipsdsp_accinsn(ctx, op1, op2, rd, rs, rt, 0);
15159 break;
15160 default: /* Invalid */
15161 MIPS_INVAL("MASK EXTR.W");
15162 generate_exception(ctx, EXCP_RI);
15163 break;
15165 break;
15166 case OPC_DPAQ_W_QH_DSP:
15167 op2 = MASK_DPAQ_W_QH(ctx->opcode);
15168 switch (op2) {
15169 case OPC_DPAU_H_OBL:
15170 case OPC_DPAU_H_OBR:
15171 case OPC_DPSU_H_OBL:
15172 case OPC_DPSU_H_OBR:
15173 case OPC_DPA_W_QH:
15174 case OPC_DPAQ_S_W_QH:
15175 case OPC_DPS_W_QH:
15176 case OPC_DPSQ_S_W_QH:
15177 case OPC_MULSAQ_S_W_QH:
15178 case OPC_DPAQ_SA_L_PW:
15179 case OPC_DPSQ_SA_L_PW:
15180 case OPC_MULSAQ_S_L_PW:
15181 gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 0);
15182 break;
15183 case OPC_MAQ_S_W_QHLL:
15184 case OPC_MAQ_S_W_QHLR:
15185 case OPC_MAQ_S_W_QHRL:
15186 case OPC_MAQ_S_W_QHRR:
15187 case OPC_MAQ_SA_W_QHLL:
15188 case OPC_MAQ_SA_W_QHLR:
15189 case OPC_MAQ_SA_W_QHRL:
15190 case OPC_MAQ_SA_W_QHRR:
15191 case OPC_MAQ_S_L_PWL:
15192 case OPC_MAQ_S_L_PWR:
15193 case OPC_DMADD:
15194 case OPC_DMADDU:
15195 case OPC_DMSUB:
15196 case OPC_DMSUBU:
15197 gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 0);
15198 break;
15199 default: /* Invalid */
15200 MIPS_INVAL("MASK DPAQ.W.QH");
15201 generate_exception(ctx, EXCP_RI);
15202 break;
15204 break;
15205 case OPC_DINSV_DSP:
15206 op2 = MASK_INSV(ctx->opcode);
15207 switch (op2) {
15208 case OPC_DINSV:
15210 TCGv t0, t1;
15212 if (rt == 0) {
15213 MIPS_DEBUG("NOP");
15214 break;
15216 check_dsp(ctx);
15218 t0 = tcg_temp_new();
15219 t1 = tcg_temp_new();
15221 gen_load_gpr(t0, rt);
15222 gen_load_gpr(t1, rs);
15224 gen_helper_dinsv(cpu_gpr[rt], cpu_env, t1, t0);
15225 break;
15227 default: /* Invalid */
15228 MIPS_INVAL("MASK DINSV");
15229 generate_exception(ctx, EXCP_RI);
15230 break;
15232 break;
15233 case OPC_SHLL_OB_DSP:
15234 gen_mipsdsp_shift(ctx, op1, rd, rs, rt);
15235 break;
15236 #endif
15237 default: /* Invalid */
15238 MIPS_INVAL("special3");
15239 generate_exception(ctx, EXCP_RI);
15240 break;
15242 break;
15243 case OPC_REGIMM:
15244 op1 = MASK_REGIMM(ctx->opcode);
15245 switch (op1) {
15246 case OPC_BLTZ ... OPC_BGEZL: /* REGIMM branches */
15247 case OPC_BLTZAL ... OPC_BGEZALL:
15248 gen_compute_branch(ctx, op1, 4, rs, -1, imm << 2);
15249 *is_branch = 1;
15250 break;
15251 case OPC_TGEI ... OPC_TEQI: /* REGIMM traps */
15252 case OPC_TNEI:
15253 gen_trap(ctx, op1, rs, -1, imm);
15254 break;
15255 case OPC_SYNCI:
15256 check_insn(ctx, ISA_MIPS32R2);
15257 /* Treat as NOP. */
15258 break;
15259 case OPC_BPOSGE32: /* MIPS DSP branch */
15260 #if defined(TARGET_MIPS64)
15261 case OPC_BPOSGE64:
15262 #endif
15263 check_dsp(ctx);
15264 gen_compute_branch(ctx, op1, 4, -1, -2, (int32_t)imm << 2);
15265 *is_branch = 1;
15266 break;
15267 default: /* Invalid */
15268 MIPS_INVAL("regimm");
15269 generate_exception(ctx, EXCP_RI);
15270 break;
15272 break;
15273 case OPC_CP0:
15274 check_cp0_enabled(ctx);
15275 op1 = MASK_CP0(ctx->opcode);
15276 switch (op1) {
15277 case OPC_MFC0:
15278 case OPC_MTC0:
15279 case OPC_MFTR:
15280 case OPC_MTTR:
15281 #if defined(TARGET_MIPS64)
15282 case OPC_DMFC0:
15283 case OPC_DMTC0:
15284 #endif
15285 #ifndef CONFIG_USER_ONLY
15286 gen_cp0(env, ctx, op1, rt, rd);
15287 #endif /* !CONFIG_USER_ONLY */
15288 break;
15289 case OPC_C0_FIRST ... OPC_C0_LAST:
15290 #ifndef CONFIG_USER_ONLY
15291 gen_cp0(env, ctx, MASK_C0(ctx->opcode), rt, rd);
15292 #endif /* !CONFIG_USER_ONLY */
15293 break;
15294 case OPC_MFMC0:
15295 #ifndef CONFIG_USER_ONLY
15297 TCGv t0 = tcg_temp_new();
15299 op2 = MASK_MFMC0(ctx->opcode);
15300 switch (op2) {
15301 case OPC_DMT:
15302 check_insn(ctx, ASE_MT);
15303 gen_helper_dmt(t0);
15304 gen_store_gpr(t0, rt);
15305 break;
15306 case OPC_EMT:
15307 check_insn(ctx, ASE_MT);
15308 gen_helper_emt(t0);
15309 gen_store_gpr(t0, rt);
15310 break;
15311 case OPC_DVPE:
15312 check_insn(ctx, ASE_MT);
15313 gen_helper_dvpe(t0, cpu_env);
15314 gen_store_gpr(t0, rt);
15315 break;
15316 case OPC_EVPE:
15317 check_insn(ctx, ASE_MT);
15318 gen_helper_evpe(t0, cpu_env);
15319 gen_store_gpr(t0, rt);
15320 break;
15321 case OPC_DI:
15322 check_insn(ctx, ISA_MIPS32R2);
15323 save_cpu_state(ctx, 1);
15324 gen_helper_di(t0, cpu_env);
15325 gen_store_gpr(t0, rt);
15326 /* Stop translation as we may have switched the execution mode */
15327 ctx->bstate = BS_STOP;
15328 break;
15329 case OPC_EI:
15330 check_insn(ctx, ISA_MIPS32R2);
15331 save_cpu_state(ctx, 1);
15332 gen_helper_ei(t0, cpu_env);
15333 gen_store_gpr(t0, rt);
15334 /* Stop translation as we may have switched the execution mode */
15335 ctx->bstate = BS_STOP;
15336 break;
15337 default: /* Invalid */
15338 MIPS_INVAL("mfmc0");
15339 generate_exception(ctx, EXCP_RI);
15340 break;
15342 tcg_temp_free(t0);
15344 #endif /* !CONFIG_USER_ONLY */
15345 break;
15346 case OPC_RDPGPR:
15347 check_insn(ctx, ISA_MIPS32R2);
15348 gen_load_srsgpr(rt, rd);
15349 break;
15350 case OPC_WRPGPR:
15351 check_insn(ctx, ISA_MIPS32R2);
15352 gen_store_srsgpr(rt, rd);
15353 break;
15354 default:
15355 MIPS_INVAL("cp0");
15356 generate_exception(ctx, EXCP_RI);
15357 break;
15359 break;
15360 case OPC_ADDI: /* Arithmetic with immediate opcode */
15361 case OPC_ADDIU:
15362 gen_arith_imm(ctx, op, rt, rs, imm);
15363 break;
15364 case OPC_SLTI: /* Set on less than with immediate opcode */
15365 case OPC_SLTIU:
15366 gen_slt_imm(ctx, op, rt, rs, imm);
15367 break;
15368 case OPC_ANDI: /* Arithmetic with immediate opcode */
15369 case OPC_LUI:
15370 case OPC_ORI:
15371 case OPC_XORI:
15372 gen_logic_imm(ctx, op, rt, rs, imm);
15373 break;
15374 case OPC_J ... OPC_JAL: /* Jump */
15375 offset = (int32_t)(ctx->opcode & 0x3FFFFFF) << 2;
15376 gen_compute_branch(ctx, op, 4, rs, rt, offset);
15377 *is_branch = 1;
15378 break;
15379 case OPC_BEQ ... OPC_BGTZ: /* Branch */
15380 case OPC_BEQL ... OPC_BGTZL:
15381 gen_compute_branch(ctx, op, 4, rs, rt, imm << 2);
15382 *is_branch = 1;
15383 break;
15384 case OPC_LB ... OPC_LWR: /* Load and stores */
15385 case OPC_LL:
15386 gen_ld(ctx, op, rt, rs, imm);
15387 break;
15388 case OPC_SB ... OPC_SW:
15389 case OPC_SWR:
15390 gen_st(ctx, op, rt, rs, imm);
15391 break;
15392 case OPC_SC:
15393 gen_st_cond(ctx, op, rt, rs, imm);
15394 break;
15395 case OPC_CACHE:
15396 check_cp0_enabled(ctx);
15397 check_insn(ctx, ISA_MIPS3 | ISA_MIPS32);
15398 /* Treat as NOP. */
15399 break;
15400 case OPC_PREF:
15401 check_insn(ctx, ISA_MIPS4 | ISA_MIPS32);
15402 /* Treat as NOP. */
15403 break;
15405 /* Floating point (COP1). */
15406 case OPC_LWC1:
15407 case OPC_LDC1:
15408 case OPC_SWC1:
15409 case OPC_SDC1:
15410 gen_cop1_ldst(env, ctx, op, rt, rs, imm);
15411 break;
15413 case OPC_CP1:
15414 if (env->CP0_Config1 & (1 << CP0C1_FP)) {
15415 check_cp1_enabled(ctx);
15416 op1 = MASK_CP1(ctx->opcode);
15417 switch (op1) {
15418 case OPC_MFHC1:
15419 case OPC_MTHC1:
15420 check_insn(ctx, ISA_MIPS32R2);
15421 case OPC_MFC1:
15422 case OPC_CFC1:
15423 case OPC_MTC1:
15424 case OPC_CTC1:
15425 gen_cp1(ctx, op1, rt, rd);
15426 break;
15427 #if defined(TARGET_MIPS64)
15428 case OPC_DMFC1:
15429 case OPC_DMTC1:
15430 check_insn(ctx, ISA_MIPS3);
15431 gen_cp1(ctx, op1, rt, rd);
15432 break;
15433 #endif
15434 case OPC_BC1ANY2:
15435 case OPC_BC1ANY4:
15436 check_cop1x(ctx);
15437 check_insn(ctx, ASE_MIPS3D);
15438 /* fall through */
15439 case OPC_BC1:
15440 gen_compute_branch1(ctx, MASK_BC1(ctx->opcode),
15441 (rt >> 2) & 0x7, imm << 2);
15442 *is_branch = 1;
15443 break;
15444 case OPC_S_FMT:
15445 case OPC_D_FMT:
15446 case OPC_W_FMT:
15447 case OPC_L_FMT:
15448 case OPC_PS_FMT:
15449 gen_farith(ctx, ctx->opcode & FOP(0x3f, 0x1f), rt, rd, sa,
15450 (imm >> 8) & 0x7);
15451 break;
15452 default:
15453 MIPS_INVAL("cp1");
15454 generate_exception (ctx, EXCP_RI);
15455 break;
15457 } else {
15458 generate_exception_err(ctx, EXCP_CpU, 1);
15460 break;
15462 /* COP2. */
15463 case OPC_LWC2:
15464 case OPC_LDC2:
15465 case OPC_SWC2:
15466 case OPC_SDC2:
15467 /* COP2: Not implemented. */
15468 generate_exception_err(ctx, EXCP_CpU, 2);
15469 break;
15470 case OPC_CP2:
15471 check_insn(ctx, INSN_LOONGSON2F);
15472 /* Note that these instructions use different fields. */
15473 gen_loongson_multimedia(ctx, sa, rd, rt);
15474 break;
15476 case OPC_CP3:
15477 if (env->CP0_Config1 & (1 << CP0C1_FP)) {
15478 check_cp1_enabled(ctx);
15479 op1 = MASK_CP3(ctx->opcode);
15480 switch (op1) {
15481 case OPC_LWXC1:
15482 case OPC_LDXC1:
15483 case OPC_LUXC1:
15484 case OPC_SWXC1:
15485 case OPC_SDXC1:
15486 case OPC_SUXC1:
15487 gen_flt3_ldst(ctx, op1, sa, rd, rs, rt);
15488 break;
15489 case OPC_PREFX:
15490 /* Treat as NOP. */
15491 break;
15492 case OPC_ALNV_PS:
15493 case OPC_MADD_S:
15494 case OPC_MADD_D:
15495 case OPC_MADD_PS:
15496 case OPC_MSUB_S:
15497 case OPC_MSUB_D:
15498 case OPC_MSUB_PS:
15499 case OPC_NMADD_S:
15500 case OPC_NMADD_D:
15501 case OPC_NMADD_PS:
15502 case OPC_NMSUB_S:
15503 case OPC_NMSUB_D:
15504 case OPC_NMSUB_PS:
15505 gen_flt3_arith(ctx, op1, sa, rs, rd, rt);
15506 break;
15507 default:
15508 MIPS_INVAL("cp3");
15509 generate_exception (ctx, EXCP_RI);
15510 break;
15512 } else {
15513 generate_exception_err(ctx, EXCP_CpU, 1);
15515 break;
15517 #if defined(TARGET_MIPS64)
15518 /* MIPS64 opcodes */
15519 case OPC_LWU:
15520 case OPC_LDL ... OPC_LDR:
15521 case OPC_LLD:
15522 case OPC_LD:
15523 check_insn(ctx, ISA_MIPS3);
15524 check_mips_64(ctx);
15525 gen_ld(ctx, op, rt, rs, imm);
15526 break;
15527 case OPC_SDL ... OPC_SDR:
15528 case OPC_SD:
15529 check_insn(ctx, ISA_MIPS3);
15530 check_mips_64(ctx);
15531 gen_st(ctx, op, rt, rs, imm);
15532 break;
15533 case OPC_SCD:
15534 check_insn(ctx, ISA_MIPS3);
15535 check_mips_64(ctx);
15536 gen_st_cond(ctx, op, rt, rs, imm);
15537 break;
15538 case OPC_DADDI:
15539 case OPC_DADDIU:
15540 check_insn(ctx, ISA_MIPS3);
15541 check_mips_64(ctx);
15542 gen_arith_imm(ctx, op, rt, rs, imm);
15543 break;
15544 #endif
15545 case OPC_JALX:
15546 check_insn(ctx, ASE_MIPS16 | ASE_MICROMIPS);
15547 offset = (int32_t)(ctx->opcode & 0x3FFFFFF) << 2;
15548 gen_compute_branch(ctx, op, 4, rs, rt, offset);
15549 *is_branch = 1;
15550 break;
15551 case OPC_MDMX:
15552 check_insn(ctx, ASE_MDMX);
15553 /* MDMX: Not implemented. */
15554 default: /* Invalid */
15555 MIPS_INVAL("major opcode");
15556 generate_exception(ctx, EXCP_RI);
15557 break;
15561 static inline void
15562 gen_intermediate_code_internal (CPUMIPSState *env, TranslationBlock *tb,
15563 int search_pc)
15565 DisasContext ctx;
15566 target_ulong pc_start;
15567 uint16_t *gen_opc_end;
15568 CPUBreakpoint *bp;
15569 int j, lj = -1;
15570 int num_insns;
15571 int max_insns;
15572 int insn_bytes;
15573 int is_branch;
15575 if (search_pc)
15576 qemu_log("search pc %d\n", search_pc);
15578 pc_start = tb->pc;
15579 gen_opc_end = tcg_ctx.gen_opc_buf + OPC_MAX_SIZE;
15580 ctx.pc = pc_start;
15581 ctx.saved_pc = -1;
15582 ctx.singlestep_enabled = env->singlestep_enabled;
15583 ctx.insn_flags = env->insn_flags;
15584 ctx.tb = tb;
15585 ctx.bstate = BS_NONE;
15586 /* Restore delay slot state from the tb context. */
15587 ctx.hflags = (uint32_t)tb->flags; /* FIXME: maybe use 64 bits here? */
15588 restore_cpu_state(env, &ctx);
15589 #ifdef CONFIG_USER_ONLY
15590 ctx.mem_idx = MIPS_HFLAG_UM;
15591 #else
15592 ctx.mem_idx = ctx.hflags & MIPS_HFLAG_KSU;
15593 #endif
15594 num_insns = 0;
15595 max_insns = tb->cflags & CF_COUNT_MASK;
15596 if (max_insns == 0)
15597 max_insns = CF_COUNT_MASK;
15598 LOG_DISAS("\ntb %p idx %d hflags %04x\n", tb, ctx.mem_idx, ctx.hflags);
15599 gen_icount_start();
15600 while (ctx.bstate == BS_NONE) {
15601 if (unlikely(!QTAILQ_EMPTY(&env->breakpoints))) {
15602 QTAILQ_FOREACH(bp, &env->breakpoints, entry) {
15603 if (bp->pc == ctx.pc) {
15604 save_cpu_state(&ctx, 1);
15605 ctx.bstate = BS_BRANCH;
15606 gen_helper_0e0i(raise_exception, EXCP_DEBUG);
15607 /* Include the breakpoint location or the tb won't
15608 * be flushed when it must be. */
15609 ctx.pc += 4;
15610 goto done_generating;
15615 if (search_pc) {
15616 j = tcg_ctx.gen_opc_ptr - tcg_ctx.gen_opc_buf;
15617 if (lj < j) {
15618 lj++;
15619 while (lj < j)
15620 tcg_ctx.gen_opc_instr_start[lj++] = 0;
15622 tcg_ctx.gen_opc_pc[lj] = ctx.pc;
15623 gen_opc_hflags[lj] = ctx.hflags & MIPS_HFLAG_BMASK;
15624 gen_opc_btarget[lj] = ctx.btarget;
15625 tcg_ctx.gen_opc_instr_start[lj] = 1;
15626 tcg_ctx.gen_opc_icount[lj] = num_insns;
15628 if (num_insns + 1 == max_insns && (tb->cflags & CF_LAST_IO))
15629 gen_io_start();
15631 is_branch = 0;
15632 if (!(ctx.hflags & MIPS_HFLAG_M16)) {
15633 ctx.opcode = cpu_ldl_code(env, ctx.pc);
15634 insn_bytes = 4;
15635 decode_opc(env, &ctx, &is_branch);
15636 } else if (ctx.insn_flags & ASE_MICROMIPS) {
15637 ctx.opcode = cpu_lduw_code(env, ctx.pc);
15638 insn_bytes = decode_micromips_opc(env, &ctx, &is_branch);
15639 } else if (ctx.insn_flags & ASE_MIPS16) {
15640 ctx.opcode = cpu_lduw_code(env, ctx.pc);
15641 insn_bytes = decode_mips16_opc(env, &ctx, &is_branch);
15642 } else {
15643 generate_exception(&ctx, EXCP_RI);
15644 ctx.bstate = BS_STOP;
15645 break;
15647 if (!is_branch) {
15648 handle_delay_slot(&ctx, insn_bytes);
15650 ctx.pc += insn_bytes;
15652 num_insns++;
15654 /* Execute a branch and its delay slot as a single instruction.
15655 This is what GDB expects and is consistent with what the
15656 hardware does (e.g. if a delay slot instruction faults, the
15657 reported PC is the PC of the branch). */
15658 if (env->singlestep_enabled && (ctx.hflags & MIPS_HFLAG_BMASK) == 0)
15659 break;
15661 if ((ctx.pc & (TARGET_PAGE_SIZE - 1)) == 0)
15662 break;
15664 if (tcg_ctx.gen_opc_ptr >= gen_opc_end) {
15665 break;
15668 if (num_insns >= max_insns)
15669 break;
15671 if (singlestep)
15672 break;
15674 if (tb->cflags & CF_LAST_IO)
15675 gen_io_end();
15676 if (env->singlestep_enabled && ctx.bstate != BS_BRANCH) {
15677 save_cpu_state(&ctx, ctx.bstate == BS_NONE);
15678 gen_helper_0e0i(raise_exception, EXCP_DEBUG);
15679 } else {
15680 switch (ctx.bstate) {
15681 case BS_STOP:
15682 gen_goto_tb(&ctx, 0, ctx.pc);
15683 break;
15684 case BS_NONE:
15685 save_cpu_state(&ctx, 0);
15686 gen_goto_tb(&ctx, 0, ctx.pc);
15687 break;
15688 case BS_EXCP:
15689 tcg_gen_exit_tb(0);
15690 break;
15691 case BS_BRANCH:
15692 default:
15693 break;
15696 done_generating:
15697 gen_icount_end(tb, num_insns);
15698 *tcg_ctx.gen_opc_ptr = INDEX_op_end;
15699 if (search_pc) {
15700 j = tcg_ctx.gen_opc_ptr - tcg_ctx.gen_opc_buf;
15701 lj++;
15702 while (lj <= j)
15703 tcg_ctx.gen_opc_instr_start[lj++] = 0;
15704 } else {
15705 tb->size = ctx.pc - pc_start;
15706 tb->icount = num_insns;
15708 #ifdef DEBUG_DISAS
15709 LOG_DISAS("\n");
15710 if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM)) {
15711 qemu_log("IN: %s\n", lookup_symbol(pc_start));
15712 log_target_disas(env, pc_start, ctx.pc - pc_start, 0);
15713 qemu_log("\n");
15715 #endif
15718 void gen_intermediate_code (CPUMIPSState *env, struct TranslationBlock *tb)
15720 gen_intermediate_code_internal(env, tb, 0);
15723 void gen_intermediate_code_pc (CPUMIPSState *env, struct TranslationBlock *tb)
15725 gen_intermediate_code_internal(env, tb, 1);
15728 static void fpu_dump_state(CPUMIPSState *env, FILE *f, fprintf_function fpu_fprintf,
15729 int flags)
15731 int i;
15732 int is_fpu64 = !!(env->hflags & MIPS_HFLAG_F64);
15734 #define printfpr(fp) \
15735 do { \
15736 if (is_fpu64) \
15737 fpu_fprintf(f, "w:%08x d:%016" PRIx64 \
15738 " fd:%13g fs:%13g psu: %13g\n", \
15739 (fp)->w[FP_ENDIAN_IDX], (fp)->d, \
15740 (double)(fp)->fd, \
15741 (double)(fp)->fs[FP_ENDIAN_IDX], \
15742 (double)(fp)->fs[!FP_ENDIAN_IDX]); \
15743 else { \
15744 fpr_t tmp; \
15745 tmp.w[FP_ENDIAN_IDX] = (fp)->w[FP_ENDIAN_IDX]; \
15746 tmp.w[!FP_ENDIAN_IDX] = ((fp) + 1)->w[FP_ENDIAN_IDX]; \
15747 fpu_fprintf(f, "w:%08x d:%016" PRIx64 \
15748 " fd:%13g fs:%13g psu:%13g\n", \
15749 tmp.w[FP_ENDIAN_IDX], tmp.d, \
15750 (double)tmp.fd, \
15751 (double)tmp.fs[FP_ENDIAN_IDX], \
15752 (double)tmp.fs[!FP_ENDIAN_IDX]); \
15754 } while(0)
15757 fpu_fprintf(f, "CP1 FCR0 0x%08x FCR31 0x%08x SR.FR %d fp_status 0x%02x\n",
15758 env->active_fpu.fcr0, env->active_fpu.fcr31, is_fpu64,
15759 get_float_exception_flags(&env->active_fpu.fp_status));
15760 for (i = 0; i < 32; (is_fpu64) ? i++ : (i += 2)) {
15761 fpu_fprintf(f, "%3s: ", fregnames[i]);
15762 printfpr(&env->active_fpu.fpr[i]);
15765 #undef printfpr
15768 #if defined(TARGET_MIPS64) && defined(MIPS_DEBUG_SIGN_EXTENSIONS)
15769 /* Debug help: The architecture requires 32bit code to maintain proper
15770 sign-extended values on 64bit machines. */
15772 #define SIGN_EXT_P(val) ((((val) & ~0x7fffffff) == 0) || (((val) & ~0x7fffffff) == ~0x7fffffff))
15774 static void
15775 cpu_mips_check_sign_extensions (CPUMIPSState *env, FILE *f,
15776 fprintf_function cpu_fprintf,
15777 int flags)
15779 int i;
15781 if (!SIGN_EXT_P(env->active_tc.PC))
15782 cpu_fprintf(f, "BROKEN: pc=0x" TARGET_FMT_lx "\n", env->active_tc.PC);
15783 if (!SIGN_EXT_P(env->active_tc.HI[0]))
15784 cpu_fprintf(f, "BROKEN: HI=0x" TARGET_FMT_lx "\n", env->active_tc.HI[0]);
15785 if (!SIGN_EXT_P(env->active_tc.LO[0]))
15786 cpu_fprintf(f, "BROKEN: LO=0x" TARGET_FMT_lx "\n", env->active_tc.LO[0]);
15787 if (!SIGN_EXT_P(env->btarget))
15788 cpu_fprintf(f, "BROKEN: btarget=0x" TARGET_FMT_lx "\n", env->btarget);
15790 for (i = 0; i < 32; i++) {
15791 if (!SIGN_EXT_P(env->active_tc.gpr[i]))
15792 cpu_fprintf(f, "BROKEN: %s=0x" TARGET_FMT_lx "\n", regnames[i], env->active_tc.gpr[i]);
15795 if (!SIGN_EXT_P(env->CP0_EPC))
15796 cpu_fprintf(f, "BROKEN: EPC=0x" TARGET_FMT_lx "\n", env->CP0_EPC);
15797 if (!SIGN_EXT_P(env->lladdr))
15798 cpu_fprintf(f, "BROKEN: LLAddr=0x" TARGET_FMT_lx "\n", env->lladdr);
15800 #endif
15802 void cpu_dump_state (CPUMIPSState *env, FILE *f, fprintf_function cpu_fprintf,
15803 int flags)
15805 int i;
15807 cpu_fprintf(f, "pc=0x" TARGET_FMT_lx " HI=0x" TARGET_FMT_lx
15808 " LO=0x" TARGET_FMT_lx " ds %04x "
15809 TARGET_FMT_lx " " TARGET_FMT_ld "\n",
15810 env->active_tc.PC, env->active_tc.HI[0], env->active_tc.LO[0],
15811 env->hflags, env->btarget, env->bcond);
15812 for (i = 0; i < 32; i++) {
15813 if ((i & 3) == 0)
15814 cpu_fprintf(f, "GPR%02d:", i);
15815 cpu_fprintf(f, " %s " TARGET_FMT_lx, regnames[i], env->active_tc.gpr[i]);
15816 if ((i & 3) == 3)
15817 cpu_fprintf(f, "\n");
15820 cpu_fprintf(f, "CP0 Status 0x%08x Cause 0x%08x EPC 0x" TARGET_FMT_lx "\n",
15821 env->CP0_Status, env->CP0_Cause, env->CP0_EPC);
15822 cpu_fprintf(f, " Config0 0x%08x Config1 0x%08x LLAddr 0x" TARGET_FMT_lx "\n",
15823 env->CP0_Config0, env->CP0_Config1, env->lladdr);
15824 if (env->hflags & MIPS_HFLAG_FPU)
15825 fpu_dump_state(env, f, cpu_fprintf, flags);
15826 #if defined(TARGET_MIPS64) && defined(MIPS_DEBUG_SIGN_EXTENSIONS)
15827 cpu_mips_check_sign_extensions(env, f, cpu_fprintf, flags);
15828 #endif
15831 void mips_tcg_init(void)
15833 int i;
15834 static int inited;
15836 /* Initialize various static tables. */
15837 if (inited)
15838 return;
15840 cpu_env = tcg_global_reg_new_ptr(TCG_AREG0, "env");
15841 TCGV_UNUSED(cpu_gpr[0]);
15842 for (i = 1; i < 32; i++)
15843 cpu_gpr[i] = tcg_global_mem_new(TCG_AREG0,
15844 offsetof(CPUMIPSState, active_tc.gpr[i]),
15845 regnames[i]);
15847 for (i = 0; i < 32; i++) {
15848 int off = offsetof(CPUMIPSState, active_fpu.fpr[i]);
15849 fpu_f64[i] = tcg_global_mem_new_i64(TCG_AREG0, off, fregnames[i]);
15852 cpu_PC = tcg_global_mem_new(TCG_AREG0,
15853 offsetof(CPUMIPSState, active_tc.PC), "PC");
15854 for (i = 0; i < MIPS_DSP_ACC; i++) {
15855 cpu_HI[i] = tcg_global_mem_new(TCG_AREG0,
15856 offsetof(CPUMIPSState, active_tc.HI[i]),
15857 regnames_HI[i]);
15858 cpu_LO[i] = tcg_global_mem_new(TCG_AREG0,
15859 offsetof(CPUMIPSState, active_tc.LO[i]),
15860 regnames_LO[i]);
15861 cpu_ACX[i] = tcg_global_mem_new(TCG_AREG0,
15862 offsetof(CPUMIPSState, active_tc.ACX[i]),
15863 regnames_ACX[i]);
15865 cpu_dspctrl = tcg_global_mem_new(TCG_AREG0,
15866 offsetof(CPUMIPSState, active_tc.DSPControl),
15867 "DSPControl");
15868 bcond = tcg_global_mem_new(TCG_AREG0,
15869 offsetof(CPUMIPSState, bcond), "bcond");
15870 btarget = tcg_global_mem_new(TCG_AREG0,
15871 offsetof(CPUMIPSState, btarget), "btarget");
15872 hflags = tcg_global_mem_new_i32(TCG_AREG0,
15873 offsetof(CPUMIPSState, hflags), "hflags");
15875 fpu_fcr0 = tcg_global_mem_new_i32(TCG_AREG0,
15876 offsetof(CPUMIPSState, active_fpu.fcr0),
15877 "fcr0");
15878 fpu_fcr31 = tcg_global_mem_new_i32(TCG_AREG0,
15879 offsetof(CPUMIPSState, active_fpu.fcr31),
15880 "fcr31");
15882 /* register helpers */
15883 #define GEN_HELPER 2
15884 #include "helper.h"
15886 inited = 1;
15889 #include "translate_init.c"
15891 MIPSCPU *cpu_mips_init(const char *cpu_model)
15893 MIPSCPU *cpu;
15894 CPUMIPSState *env;
15895 const mips_def_t *def;
15897 def = cpu_mips_find_by_name(cpu_model);
15898 if (!def)
15899 return NULL;
15900 cpu = MIPS_CPU(object_new(TYPE_MIPS_CPU));
15901 env = &cpu->env;
15902 env->cpu_model = def;
15903 env->cpu_model_str = cpu_model;
15905 #ifndef CONFIG_USER_ONLY
15906 mmu_init(env, def);
15907 #endif
15908 fpu_init(env, def);
15909 mvp_init(env, def);
15911 object_property_set_bool(OBJECT(cpu), true, "realized", NULL);
15913 return cpu;
15916 void cpu_state_reset(CPUMIPSState *env)
15918 #ifndef CONFIG_USER_ONLY
15919 MIPSCPU *cpu = mips_env_get_cpu(env);
15920 CPUState *cs = CPU(cpu);
15921 #endif
15923 /* Reset registers to their default values */
15924 env->CP0_PRid = env->cpu_model->CP0_PRid;
15925 env->CP0_Config0 = env->cpu_model->CP0_Config0;
15926 #ifdef TARGET_WORDS_BIGENDIAN
15927 env->CP0_Config0 |= (1 << CP0C0_BE);
15928 #endif
15929 env->CP0_Config1 = env->cpu_model->CP0_Config1;
15930 env->CP0_Config2 = env->cpu_model->CP0_Config2;
15931 env->CP0_Config3 = env->cpu_model->CP0_Config3;
15932 env->CP0_Config6 = env->cpu_model->CP0_Config6;
15933 env->CP0_Config7 = env->cpu_model->CP0_Config7;
15934 env->CP0_LLAddr_rw_bitmask = env->cpu_model->CP0_LLAddr_rw_bitmask
15935 << env->cpu_model->CP0_LLAddr_shift;
15936 env->CP0_LLAddr_shift = env->cpu_model->CP0_LLAddr_shift;
15937 env->SYNCI_Step = env->cpu_model->SYNCI_Step;
15938 env->CCRes = env->cpu_model->CCRes;
15939 env->CP0_Status_rw_bitmask = env->cpu_model->CP0_Status_rw_bitmask;
15940 env->CP0_TCStatus_rw_bitmask = env->cpu_model->CP0_TCStatus_rw_bitmask;
15941 env->CP0_SRSCtl = env->cpu_model->CP0_SRSCtl;
15942 env->current_tc = 0;
15943 env->SEGBITS = env->cpu_model->SEGBITS;
15944 env->SEGMask = (target_ulong)((1ULL << env->cpu_model->SEGBITS) - 1);
15945 #if defined(TARGET_MIPS64)
15946 if (env->cpu_model->insn_flags & ISA_MIPS3) {
15947 env->SEGMask |= 3ULL << 62;
15949 #endif
15950 env->PABITS = env->cpu_model->PABITS;
15951 env->PAMask = (target_ulong)((1ULL << env->cpu_model->PABITS) - 1);
15952 env->CP0_SRSConf0_rw_bitmask = env->cpu_model->CP0_SRSConf0_rw_bitmask;
15953 env->CP0_SRSConf0 = env->cpu_model->CP0_SRSConf0;
15954 env->CP0_SRSConf1_rw_bitmask = env->cpu_model->CP0_SRSConf1_rw_bitmask;
15955 env->CP0_SRSConf1 = env->cpu_model->CP0_SRSConf1;
15956 env->CP0_SRSConf2_rw_bitmask = env->cpu_model->CP0_SRSConf2_rw_bitmask;
15957 env->CP0_SRSConf2 = env->cpu_model->CP0_SRSConf2;
15958 env->CP0_SRSConf3_rw_bitmask = env->cpu_model->CP0_SRSConf3_rw_bitmask;
15959 env->CP0_SRSConf3 = env->cpu_model->CP0_SRSConf3;
15960 env->CP0_SRSConf4_rw_bitmask = env->cpu_model->CP0_SRSConf4_rw_bitmask;
15961 env->CP0_SRSConf4 = env->cpu_model->CP0_SRSConf4;
15962 env->active_fpu.fcr0 = env->cpu_model->CP1_fcr0;
15963 env->insn_flags = env->cpu_model->insn_flags;
15965 #if defined(CONFIG_USER_ONLY)
15966 env->CP0_Status = (MIPS_HFLAG_UM << CP0St_KSU);
15967 /* Enable access to the CPUNum, SYNCI_Step, CC, and CCRes RDHWR
15968 hardware registers. */
15969 env->CP0_HWREna |= 0x0000000F;
15970 if (env->CP0_Config1 & (1 << CP0C1_FP)) {
15971 env->CP0_Status |= (1 << CP0St_CU1);
15973 if (env->CP0_Config3 & (1 << CP0C3_DSPP)) {
15974 env->CP0_Status |= (1 << CP0St_MX);
15976 #else
15977 if (env->hflags & MIPS_HFLAG_BMASK) {
15978 /* If the exception was raised from a delay slot,
15979 come back to the jump. */
15980 env->CP0_ErrorEPC = env->active_tc.PC - 4;
15981 } else {
15982 env->CP0_ErrorEPC = env->active_tc.PC;
15984 env->active_tc.PC = (int32_t)0xBFC00000;
15985 env->CP0_Random = env->tlb->nb_tlb - 1;
15986 env->tlb->tlb_in_use = env->tlb->nb_tlb;
15987 env->CP0_Wired = 0;
15988 env->CP0_EBase = 0x80000000 | (cs->cpu_index & 0x3FF);
15989 env->CP0_Status = (1 << CP0St_BEV) | (1 << CP0St_ERL);
15990 /* vectored interrupts not implemented, timer on int 7,
15991 no performance counters. */
15992 env->CP0_IntCtl = 0xe0000000;
15994 int i;
15996 for (i = 0; i < 7; i++) {
15997 env->CP0_WatchLo[i] = 0;
15998 env->CP0_WatchHi[i] = 0x80000000;
16000 env->CP0_WatchLo[7] = 0;
16001 env->CP0_WatchHi[7] = 0;
16003 /* Count register increments in debug mode, EJTAG version 1 */
16004 env->CP0_Debug = (1 << CP0DB_CNT) | (0x1 << CP0DB_VER);
16006 if (env->CP0_Config3 & (1 << CP0C3_MT)) {
16007 int i;
16009 /* Only TC0 on VPE 0 starts as active. */
16010 for (i = 0; i < ARRAY_SIZE(env->tcs); i++) {
16011 env->tcs[i].CP0_TCBind = cs->cpu_index << CP0TCBd_CurVPE;
16012 env->tcs[i].CP0_TCHalt = 1;
16014 env->active_tc.CP0_TCHalt = 1;
16015 env->halted = 1;
16017 if (cs->cpu_index == 0) {
16018 /* VPE0 starts up enabled. */
16019 env->mvp->CP0_MVPControl |= (1 << CP0MVPCo_EVP);
16020 env->CP0_VPEConf0 |= (1 << CP0VPEC0_MVP) | (1 << CP0VPEC0_VPA);
16022 /* TC0 starts up unhalted. */
16023 env->halted = 0;
16024 env->active_tc.CP0_TCHalt = 0;
16025 env->tcs[0].CP0_TCHalt = 0;
16026 /* With thread 0 active. */
16027 env->active_tc.CP0_TCStatus = (1 << CP0TCSt_A);
16028 env->tcs[0].CP0_TCStatus = (1 << CP0TCSt_A);
16031 #endif
16032 compute_hflags(env);
16033 env->exception_index = EXCP_NONE;
16036 void restore_state_to_opc(CPUMIPSState *env, TranslationBlock *tb, int pc_pos)
16038 env->active_tc.PC = tcg_ctx.gen_opc_pc[pc_pos];
16039 env->hflags &= ~MIPS_HFLAG_BMASK;
16040 env->hflags |= gen_opc_hflags[pc_pos];
16041 switch (env->hflags & MIPS_HFLAG_BMASK_BASE) {
16042 case MIPS_HFLAG_BR:
16043 break;
16044 case MIPS_HFLAG_BC:
16045 case MIPS_HFLAG_BL:
16046 case MIPS_HFLAG_B:
16047 env->btarget = gen_opc_btarget[pc_pos];
16048 break;