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