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/>.
25 #include "disas/disas.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))
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 */
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,
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)
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,
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),
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,
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))
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))
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)
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,
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,
277 OPC_CLZ = 0x20 | OPC_SPECIAL2,
278 OPC_CLO = 0x21 | OPC_SPECIAL2,
279 OPC_DCLZ = 0x24 | OPC_SPECIAL2,
280 OPC_DCLO = 0x25 | OPC_SPECIAL2,
282 OPC_SDBBP = 0x3F | OPC_SPECIAL2,
285 /* Special3 opcodes */
286 #define MASK_SPECIAL3(op) MASK_OP_MAJOR(op) | (op & 0x3F)
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,
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,
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,
348 #define MASK_BSHFL(op) MASK_SPECIAL3(op) | (op & (0x1F << 6))
351 OPC_WSBH = (0x02 << 6) | OPC_BSHFL,
352 OPC_SEB = (0x10 << 6) | OPC_BSHFL,
353 OPC_SEH = (0x18 << 6) | OPC_BSHFL,
357 #define MASK_DBSHFL(op) MASK_SPECIAL3(op) | (op & (0x1F << 6))
360 OPC_DSBH = (0x02 << 6) | OPC_DBSHFL,
361 OPC_DSHD = (0x05 << 6) | OPC_DBSHFL,
364 /* MIPS DSP REGIMM opcodes */
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)))
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)))
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)))
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)))
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)))
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)))
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)))
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)))
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)))
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)))
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)))
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)))
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)))
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)))
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)))
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)))
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)))
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)))
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))
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,
790 #define MASK_MFMC0(op) MASK_CP0(op) | (op & 0xFFFF)
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)
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 */
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 */
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))
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,
863 OPC_BC1FANY2 = (0x00 << 16) | OPC_BC1ANY2,
864 OPC_BC1TANY2 = (0x01 << 16) | OPC_BC1ANY2,
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))
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))
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)
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); \
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); \
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); \
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); \
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); \
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); \
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); \
1064 typedef struct DisasContext {
1065 struct TranslationBlock *tb;
1066 target_ulong pc, saved_pc;
1068 int singlestep_enabled;
1070 /* Routine used to access memory */
1072 uint32_t hflags, saved_hflags;
1074 target_ulong btarget;
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, ...) \
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__); \
1120 #define LOG_DISAS(...) \
1122 if (MIPS_DEBUG_DISAS) { \
1123 qemu_log_mask(CPU_LOG_TB_IN_ASM, ## __VA_ARGS__); \
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)
1135 tcg_gen_movi_tl(t, 0);
1137 tcg_gen_mov_tl(t, cpu_gpr[reg]);
1140 static inline void gen_store_gpr (TCGv t, int reg)
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();
1163 tcg_gen_movi_tl(t0, 0);
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);
1183 static inline void gen_store_srsgpr (int from, int to)
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);
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]);
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);
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)
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) {
1288 tcg_gen_movi_tl(btarget, ctx->btarget);
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) {
1303 ctx->btarget = env->btarget;
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);
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);
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
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);
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);
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
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 (); \
1447 check_cp1_64bitmode(ctx); \
1453 check_cp1_registers(ctx, fs | ft); \
1461 gen_ldcmp_fpr##bits (ctx, fp0, fs); \
1462 gen_ldcmp_fpr##bits (ctx, fp1, ft); \
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;\
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)
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); \
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); \
1515 OP_LD_ATOMIC(ll,ld32s);
1516 #if defined(TARGET_MIPS64)
1517 OP_LD_ATOMIC(lld,ld64);
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); \
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); \
1555 OP_ST_ATOMIC(sc,st32,ld32s,0x3);
1556 #if defined(TARGET_MIPS64)
1557 OP_ST_ATOMIC(scd,st64,ld64,0x7);
1561 static void gen_base_offset_addr (DisasContext *ctx, TCGv addr,
1562 int base, int16_t offset)
1565 tcg_gen_movi_tl(addr, offset);
1566 } else if (offset == 0) {
1567 gen_load_gpr(addr, base);
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;
1584 pc &= ~(target_ulong)3;
1589 static void gen_ld(DisasContext *ctx, uint32_t opc,
1590 int rt, int base, int16_t offset)
1592 const char *opn = "ld";
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. */
1603 t0 = tcg_temp_new();
1604 gen_base_offset_addr(ctx, t0, base, offset);
1607 #if defined(TARGET_MIPS64)
1609 tcg_gen_qemu_ld32u(t0, t0, ctx->mem_idx);
1610 gen_store_gpr(t0, rt);
1614 tcg_gen_qemu_ld64(t0, t0, ctx->mem_idx);
1615 gen_store_gpr(t0, rt);
1619 save_cpu_state(ctx, 1);
1620 op_ld_lld(t0, t0, ctx);
1621 gen_store_gpr(t0, rt);
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);
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);
1640 tcg_gen_or_tl(t0, t0, t1);
1642 gen_store_gpr(t0, rt);
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);
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);
1661 tcg_gen_or_tl(t0, t0, t1);
1663 gen_store_gpr(t0, rt);
1667 t1 = tcg_const_tl(pc_relative_pc(ctx));
1668 gen_op_addr_add(ctx, t0, t0, t1);
1670 tcg_gen_qemu_ld64(t0, t0, ctx->mem_idx);
1671 gen_store_gpr(t0, rt);
1676 t1 = tcg_const_tl(pc_relative_pc(ctx));
1677 gen_op_addr_add(ctx, t0, t0, t1);
1679 tcg_gen_qemu_ld32s(t0, t0, ctx->mem_idx);
1680 gen_store_gpr(t0, rt);
1684 tcg_gen_qemu_ld32s(t0, t0, ctx->mem_idx);
1685 gen_store_gpr(t0, rt);
1689 tcg_gen_qemu_ld16s(t0, t0, ctx->mem_idx);
1690 gen_store_gpr(t0, rt);
1694 tcg_gen_qemu_ld16u(t0, t0, ctx->mem_idx);
1695 gen_store_gpr(t0, rt);
1699 tcg_gen_qemu_ld8s(t0, t0, ctx->mem_idx);
1700 gen_store_gpr(t0, rt);
1704 tcg_gen_qemu_ld8u(t0, t0, ctx->mem_idx);
1705 gen_store_gpr(t0, rt);
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);
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);
1724 tcg_gen_or_tl(t0, t0, t1);
1726 tcg_gen_ext32s_tl(t0, t0);
1727 gen_store_gpr(t0, rt);
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);
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);
1746 tcg_gen_or_tl(t0, t0, t1);
1748 gen_store_gpr(t0, rt);
1752 save_cpu_state(ctx, 1);
1753 op_ld_ll(t0, t0, ctx);
1754 gen_store_gpr(t0, rt);
1758 (void)opn; /* avoid a compiler warning */
1759 MIPS_DEBUG("%s %s, %d(%s)", opn, regnames[rt], offset, regnames[base]);
1764 static void gen_st (DisasContext *ctx, uint32_t opc, int rt,
1765 int base, int16_t offset)
1767 const char *opn = "st";
1768 TCGv t0 = tcg_temp_new();
1769 TCGv t1 = tcg_temp_new();
1771 gen_base_offset_addr(ctx, t0, base, offset);
1772 gen_load_gpr(t1, rt);
1774 #if defined(TARGET_MIPS64)
1776 tcg_gen_qemu_st64(t1, t0, ctx->mem_idx);
1780 save_cpu_state(ctx, 1);
1781 gen_helper_0e2i(sdl, t1, t0, ctx->mem_idx);
1785 save_cpu_state(ctx, 1);
1786 gen_helper_0e2i(sdr, t1, t0, ctx->mem_idx);
1791 tcg_gen_qemu_st32(t1, t0, ctx->mem_idx);
1795 tcg_gen_qemu_st16(t1, t0, ctx->mem_idx);
1799 tcg_gen_qemu_st8(t1, t0, ctx->mem_idx);
1803 save_cpu_state(ctx, 1);
1804 gen_helper_0e2i(swl, t1, t0, ctx->mem_idx);
1808 save_cpu_state(ctx, 1);
1809 gen_helper_0e2i(swr, t1, t0, ctx->mem_idx);
1813 (void)opn; /* avoid a compiler warning */
1814 MIPS_DEBUG("%s %s, %d(%s)", opn, regnames[rt], offset, regnames[base]);
1820 /* Store conditional */
1821 static void gen_st_cond (DisasContext *ctx, uint32_t opc, int rt,
1822 int base, int16_t offset)
1824 const char *opn = "st_cond";
1827 #ifdef CONFIG_USER_ONLY
1828 t0 = tcg_temp_local_new();
1829 t1 = tcg_temp_local_new();
1831 t0 = tcg_temp_new();
1832 t1 = tcg_temp_new();
1834 gen_base_offset_addr(ctx, t0, base, offset);
1835 gen_load_gpr(t1, rt);
1837 #if defined(TARGET_MIPS64)
1839 save_cpu_state(ctx, 1);
1840 op_st_scd(t1, t0, rt, ctx);
1845 save_cpu_state(ctx, 1);
1846 op_st_sc(t1, t0, rt, ctx);
1850 (void)opn; /* avoid a compiler warning */
1851 MIPS_DEBUG("%s %s, %d(%s)", opn, regnames[rt], offset, regnames[base]);
1856 /* Load and store */
1857 static void gen_flt_ldst (DisasContext *ctx, uint32_t opc, int ft,
1858 int base, int16_t offset)
1860 const char *opn = "flt_ldst";
1861 TCGv t0 = tcg_temp_new();
1863 gen_base_offset_addr(ctx, t0, base, offset);
1864 /* Don't do NOP if destination is zero: we must perform the actual
1869 TCGv_i32 fp0 = tcg_temp_new_i32();
1871 tcg_gen_qemu_ld32s(t0, t0, ctx->mem_idx);
1872 tcg_gen_trunc_tl_i32(fp0, t0);
1873 gen_store_fpr32(fp0, ft);
1874 tcg_temp_free_i32(fp0);
1880 TCGv_i32 fp0 = tcg_temp_new_i32();
1881 TCGv t1 = tcg_temp_new();
1883 gen_load_fpr32(fp0, ft);
1884 tcg_gen_extu_i32_tl(t1, fp0);
1885 tcg_gen_qemu_st32(t1, t0, ctx->mem_idx);
1887 tcg_temp_free_i32(fp0);
1893 TCGv_i64 fp0 = tcg_temp_new_i64();
1895 tcg_gen_qemu_ld64(fp0, t0, ctx->mem_idx);
1896 gen_store_fpr64(ctx, fp0, ft);
1897 tcg_temp_free_i64(fp0);
1903 TCGv_i64 fp0 = tcg_temp_new_i64();
1905 gen_load_fpr64(ctx, fp0, ft);
1906 tcg_gen_qemu_st64(fp0, t0, ctx->mem_idx);
1907 tcg_temp_free_i64(fp0);
1913 generate_exception(ctx, EXCP_RI);
1916 (void)opn; /* avoid a compiler warning */
1917 MIPS_DEBUG("%s %s, %d(%s)", opn, fregnames[ft], offset, regnames[base]);
1922 static void gen_cop1_ldst(CPUMIPSState *env, DisasContext *ctx,
1923 uint32_t op, int rt, int rs, int16_t imm)
1925 if (env->CP0_Config1 & (1 << CP0C1_FP)) {
1926 check_cp1_enabled(ctx);
1927 gen_flt_ldst(ctx, op, rt, rs, imm);
1929 generate_exception_err(ctx, EXCP_CpU, 1);
1933 /* Arithmetic with immediate operand */
1934 static void gen_arith_imm(DisasContext *ctx, uint32_t opc,
1935 int rt, int rs, int16_t imm)
1937 target_ulong uimm = (target_long)imm; /* Sign extend to 32/64 bits */
1938 const char *opn = "imm arith";
1940 if (rt == 0 && opc != OPC_ADDI && opc != OPC_DADDI) {
1941 /* If no destination, treat it as a NOP.
1942 For addi, we must generate the overflow exception when needed. */
1949 TCGv t0 = tcg_temp_local_new();
1950 TCGv t1 = tcg_temp_new();
1951 TCGv t2 = tcg_temp_new();
1952 int l1 = gen_new_label();
1954 gen_load_gpr(t1, rs);
1955 tcg_gen_addi_tl(t0, t1, uimm);
1956 tcg_gen_ext32s_tl(t0, t0);
1958 tcg_gen_xori_tl(t1, t1, ~uimm);
1959 tcg_gen_xori_tl(t2, t0, uimm);
1960 tcg_gen_and_tl(t1, t1, t2);
1962 tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
1964 /* operands of same sign, result different sign */
1965 generate_exception(ctx, EXCP_OVERFLOW);
1967 tcg_gen_ext32s_tl(t0, t0);
1968 gen_store_gpr(t0, rt);
1975 tcg_gen_addi_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
1976 tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]);
1978 tcg_gen_movi_tl(cpu_gpr[rt], uimm);
1982 #if defined(TARGET_MIPS64)
1985 TCGv t0 = tcg_temp_local_new();
1986 TCGv t1 = tcg_temp_new();
1987 TCGv t2 = tcg_temp_new();
1988 int l1 = gen_new_label();
1990 gen_load_gpr(t1, rs);
1991 tcg_gen_addi_tl(t0, t1, uimm);
1993 tcg_gen_xori_tl(t1, t1, ~uimm);
1994 tcg_gen_xori_tl(t2, t0, uimm);
1995 tcg_gen_and_tl(t1, t1, t2);
1997 tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
1999 /* operands of same sign, result different sign */
2000 generate_exception(ctx, EXCP_OVERFLOW);
2002 gen_store_gpr(t0, rt);
2009 tcg_gen_addi_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
2011 tcg_gen_movi_tl(cpu_gpr[rt], uimm);
2017 (void)opn; /* avoid a compiler warning */
2018 MIPS_DEBUG("%s %s, %s, " TARGET_FMT_lx, opn, regnames[rt], regnames[rs], uimm);
2021 /* Logic with immediate operand */
2022 static void gen_logic_imm(DisasContext *ctx, uint32_t opc,
2023 int rt, int rs, int16_t imm)
2028 /* If no destination, treat it as a NOP. */
2032 uimm = (uint16_t)imm;
2035 if (likely(rs != 0))
2036 tcg_gen_andi_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
2038 tcg_gen_movi_tl(cpu_gpr[rt], 0);
2039 MIPS_DEBUG("andi %s, %s, " TARGET_FMT_lx, regnames[rt],
2040 regnames[rs], uimm);
2044 tcg_gen_ori_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
2046 tcg_gen_movi_tl(cpu_gpr[rt], uimm);
2047 MIPS_DEBUG("ori %s, %s, " TARGET_FMT_lx, regnames[rt],
2048 regnames[rs], uimm);
2051 if (likely(rs != 0))
2052 tcg_gen_xori_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
2054 tcg_gen_movi_tl(cpu_gpr[rt], uimm);
2055 MIPS_DEBUG("xori %s, %s, " TARGET_FMT_lx, regnames[rt],
2056 regnames[rs], uimm);
2059 tcg_gen_movi_tl(cpu_gpr[rt], imm << 16);
2060 MIPS_DEBUG("lui %s, " TARGET_FMT_lx, regnames[rt], uimm);
2064 MIPS_DEBUG("Unknown logical immediate opcode %08x", opc);
2069 /* Set on less than with immediate operand */
2070 static void gen_slt_imm(DisasContext *ctx, uint32_t opc,
2071 int rt, int rs, int16_t imm)
2073 target_ulong uimm = (target_long)imm; /* Sign extend to 32/64 bits */
2074 const char *opn = "imm arith";
2078 /* If no destination, treat it as a NOP. */
2082 t0 = tcg_temp_new();
2083 gen_load_gpr(t0, rs);
2086 tcg_gen_setcondi_tl(TCG_COND_LT, cpu_gpr[rt], t0, uimm);
2090 tcg_gen_setcondi_tl(TCG_COND_LTU, cpu_gpr[rt], t0, uimm);
2094 (void)opn; /* avoid a compiler warning */
2095 MIPS_DEBUG("%s %s, %s, " TARGET_FMT_lx, opn, regnames[rt], regnames[rs], uimm);
2099 /* Shifts with immediate operand */
2100 static void gen_shift_imm(DisasContext *ctx, uint32_t opc,
2101 int rt, int rs, int16_t imm)
2103 target_ulong uimm = ((uint16_t)imm) & 0x1f;
2104 const char *opn = "imm shift";
2108 /* If no destination, treat it as a NOP. */
2113 t0 = tcg_temp_new();
2114 gen_load_gpr(t0, rs);
2117 tcg_gen_shli_tl(t0, t0, uimm);
2118 tcg_gen_ext32s_tl(cpu_gpr[rt], t0);
2122 tcg_gen_sari_tl(cpu_gpr[rt], t0, uimm);
2127 tcg_gen_ext32u_tl(t0, t0);
2128 tcg_gen_shri_tl(cpu_gpr[rt], t0, uimm);
2130 tcg_gen_ext32s_tl(cpu_gpr[rt], t0);
2136 TCGv_i32 t1 = tcg_temp_new_i32();
2138 tcg_gen_trunc_tl_i32(t1, t0);
2139 tcg_gen_rotri_i32(t1, t1, uimm);
2140 tcg_gen_ext_i32_tl(cpu_gpr[rt], t1);
2141 tcg_temp_free_i32(t1);
2143 tcg_gen_ext32s_tl(cpu_gpr[rt], t0);
2147 #if defined(TARGET_MIPS64)
2149 tcg_gen_shli_tl(cpu_gpr[rt], t0, uimm);
2153 tcg_gen_sari_tl(cpu_gpr[rt], t0, uimm);
2157 tcg_gen_shri_tl(cpu_gpr[rt], t0, uimm);
2162 tcg_gen_rotri_tl(cpu_gpr[rt], t0, uimm);
2164 tcg_gen_mov_tl(cpu_gpr[rt], t0);
2169 tcg_gen_shli_tl(cpu_gpr[rt], t0, uimm + 32);
2173 tcg_gen_sari_tl(cpu_gpr[rt], t0, uimm + 32);
2177 tcg_gen_shri_tl(cpu_gpr[rt], t0, uimm + 32);
2181 tcg_gen_rotri_tl(cpu_gpr[rt], t0, uimm + 32);
2186 (void)opn; /* avoid a compiler warning */
2187 MIPS_DEBUG("%s %s, %s, " TARGET_FMT_lx, opn, regnames[rt], regnames[rs], uimm);
2192 static void gen_arith(DisasContext *ctx, uint32_t opc,
2193 int rd, int rs, int rt)
2195 const char *opn = "arith";
2197 if (rd == 0 && opc != OPC_ADD && opc != OPC_SUB
2198 && opc != OPC_DADD && opc != OPC_DSUB) {
2199 /* If no destination, treat it as a NOP.
2200 For add & sub, we must generate the overflow exception when needed. */
2208 TCGv t0 = tcg_temp_local_new();
2209 TCGv t1 = tcg_temp_new();
2210 TCGv t2 = tcg_temp_new();
2211 int l1 = gen_new_label();
2213 gen_load_gpr(t1, rs);
2214 gen_load_gpr(t2, rt);
2215 tcg_gen_add_tl(t0, t1, t2);
2216 tcg_gen_ext32s_tl(t0, t0);
2217 tcg_gen_xor_tl(t1, t1, t2);
2218 tcg_gen_xor_tl(t2, t0, t2);
2219 tcg_gen_andc_tl(t1, t2, t1);
2221 tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
2223 /* operands of same sign, result different sign */
2224 generate_exception(ctx, EXCP_OVERFLOW);
2226 gen_store_gpr(t0, rd);
2232 if (rs != 0 && rt != 0) {
2233 tcg_gen_add_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2234 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
2235 } else if (rs == 0 && rt != 0) {
2236 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rt]);
2237 } else if (rs != 0 && rt == 0) {
2238 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
2240 tcg_gen_movi_tl(cpu_gpr[rd], 0);
2246 TCGv t0 = tcg_temp_local_new();
2247 TCGv t1 = tcg_temp_new();
2248 TCGv t2 = tcg_temp_new();
2249 int l1 = gen_new_label();
2251 gen_load_gpr(t1, rs);
2252 gen_load_gpr(t2, rt);
2253 tcg_gen_sub_tl(t0, t1, t2);
2254 tcg_gen_ext32s_tl(t0, t0);
2255 tcg_gen_xor_tl(t2, t1, t2);
2256 tcg_gen_xor_tl(t1, t0, t1);
2257 tcg_gen_and_tl(t1, t1, t2);
2259 tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
2261 /* operands of different sign, first operand and result different sign */
2262 generate_exception(ctx, EXCP_OVERFLOW);
2264 gen_store_gpr(t0, rd);
2270 if (rs != 0 && rt != 0) {
2271 tcg_gen_sub_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2272 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
2273 } else if (rs == 0 && rt != 0) {
2274 tcg_gen_neg_tl(cpu_gpr[rd], cpu_gpr[rt]);
2275 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
2276 } else if (rs != 0 && rt == 0) {
2277 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
2279 tcg_gen_movi_tl(cpu_gpr[rd], 0);
2283 #if defined(TARGET_MIPS64)
2286 TCGv t0 = tcg_temp_local_new();
2287 TCGv t1 = tcg_temp_new();
2288 TCGv t2 = tcg_temp_new();
2289 int l1 = gen_new_label();
2291 gen_load_gpr(t1, rs);
2292 gen_load_gpr(t2, rt);
2293 tcg_gen_add_tl(t0, t1, t2);
2294 tcg_gen_xor_tl(t1, t1, t2);
2295 tcg_gen_xor_tl(t2, t0, t2);
2296 tcg_gen_andc_tl(t1, t2, t1);
2298 tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
2300 /* operands of same sign, result different sign */
2301 generate_exception(ctx, EXCP_OVERFLOW);
2303 gen_store_gpr(t0, rd);
2309 if (rs != 0 && rt != 0) {
2310 tcg_gen_add_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2311 } else if (rs == 0 && rt != 0) {
2312 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rt]);
2313 } else if (rs != 0 && rt == 0) {
2314 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
2316 tcg_gen_movi_tl(cpu_gpr[rd], 0);
2322 TCGv t0 = tcg_temp_local_new();
2323 TCGv t1 = tcg_temp_new();
2324 TCGv t2 = tcg_temp_new();
2325 int l1 = gen_new_label();
2327 gen_load_gpr(t1, rs);
2328 gen_load_gpr(t2, rt);
2329 tcg_gen_sub_tl(t0, t1, t2);
2330 tcg_gen_xor_tl(t2, t1, t2);
2331 tcg_gen_xor_tl(t1, t0, t1);
2332 tcg_gen_and_tl(t1, t1, t2);
2334 tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
2336 /* operands of different sign, first operand and result different sign */
2337 generate_exception(ctx, EXCP_OVERFLOW);
2339 gen_store_gpr(t0, rd);
2345 if (rs != 0 && rt != 0) {
2346 tcg_gen_sub_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2347 } else if (rs == 0 && rt != 0) {
2348 tcg_gen_neg_tl(cpu_gpr[rd], cpu_gpr[rt]);
2349 } else if (rs != 0 && rt == 0) {
2350 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
2352 tcg_gen_movi_tl(cpu_gpr[rd], 0);
2358 if (likely(rs != 0 && rt != 0)) {
2359 tcg_gen_mul_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2360 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
2362 tcg_gen_movi_tl(cpu_gpr[rd], 0);
2367 (void)opn; /* avoid a compiler warning */
2368 MIPS_DEBUG("%s %s, %s, %s", opn, regnames[rd], regnames[rs], regnames[rt]);
2371 /* Conditional move */
2372 static void gen_cond_move(DisasContext *ctx, uint32_t opc,
2373 int rd, int rs, int rt)
2375 const char *opn = "cond move";
2379 /* If no destination, treat it as a NOP. */
2384 t0 = tcg_temp_new();
2385 gen_load_gpr(t0, rt);
2386 t1 = tcg_const_tl(0);
2387 t2 = tcg_temp_new();
2388 gen_load_gpr(t2, rs);
2391 tcg_gen_movcond_tl(TCG_COND_NE, cpu_gpr[rd], t0, t1, t2, cpu_gpr[rd]);
2395 tcg_gen_movcond_tl(TCG_COND_EQ, cpu_gpr[rd], t0, t1, t2, cpu_gpr[rd]);
2403 (void)opn; /* avoid a compiler warning */
2404 MIPS_DEBUG("%s %s, %s, %s", opn, regnames[rd], regnames[rs], regnames[rt]);
2408 static void gen_logic(DisasContext *ctx, uint32_t opc,
2409 int rd, int rs, int rt)
2411 const char *opn = "logic";
2414 /* If no destination, treat it as a NOP. */
2421 if (likely(rs != 0 && rt != 0)) {
2422 tcg_gen_and_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2424 tcg_gen_movi_tl(cpu_gpr[rd], 0);
2429 if (rs != 0 && rt != 0) {
2430 tcg_gen_nor_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2431 } else if (rs == 0 && rt != 0) {
2432 tcg_gen_not_tl(cpu_gpr[rd], cpu_gpr[rt]);
2433 } else if (rs != 0 && rt == 0) {
2434 tcg_gen_not_tl(cpu_gpr[rd], cpu_gpr[rs]);
2436 tcg_gen_movi_tl(cpu_gpr[rd], ~((target_ulong)0));
2441 if (likely(rs != 0 && rt != 0)) {
2442 tcg_gen_or_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2443 } else if (rs == 0 && rt != 0) {
2444 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rt]);
2445 } else if (rs != 0 && rt == 0) {
2446 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
2448 tcg_gen_movi_tl(cpu_gpr[rd], 0);
2453 if (likely(rs != 0 && rt != 0)) {
2454 tcg_gen_xor_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2455 } else if (rs == 0 && rt != 0) {
2456 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rt]);
2457 } else if (rs != 0 && rt == 0) {
2458 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
2460 tcg_gen_movi_tl(cpu_gpr[rd], 0);
2465 (void)opn; /* avoid a compiler warning */
2466 MIPS_DEBUG("%s %s, %s, %s", opn, regnames[rd], regnames[rs], regnames[rt]);
2469 /* Set on lower than */
2470 static void gen_slt(DisasContext *ctx, uint32_t opc,
2471 int rd, int rs, int rt)
2473 const char *opn = "slt";
2477 /* If no destination, treat it as a NOP. */
2482 t0 = tcg_temp_new();
2483 t1 = tcg_temp_new();
2484 gen_load_gpr(t0, rs);
2485 gen_load_gpr(t1, rt);
2488 tcg_gen_setcond_tl(TCG_COND_LT, cpu_gpr[rd], t0, t1);
2492 tcg_gen_setcond_tl(TCG_COND_LTU, cpu_gpr[rd], t0, t1);
2496 (void)opn; /* avoid a compiler warning */
2497 MIPS_DEBUG("%s %s, %s, %s", opn, regnames[rd], regnames[rs], regnames[rt]);
2503 static void gen_shift(DisasContext *ctx, uint32_t opc,
2504 int rd, int rs, int rt)
2506 const char *opn = "shifts";
2510 /* If no destination, treat it as a NOP.
2511 For add & sub, we must generate the overflow exception when needed. */
2516 t0 = tcg_temp_new();
2517 t1 = tcg_temp_new();
2518 gen_load_gpr(t0, rs);
2519 gen_load_gpr(t1, rt);
2522 tcg_gen_andi_tl(t0, t0, 0x1f);
2523 tcg_gen_shl_tl(t0, t1, t0);
2524 tcg_gen_ext32s_tl(cpu_gpr[rd], t0);
2528 tcg_gen_andi_tl(t0, t0, 0x1f);
2529 tcg_gen_sar_tl(cpu_gpr[rd], t1, t0);
2533 tcg_gen_ext32u_tl(t1, t1);
2534 tcg_gen_andi_tl(t0, t0, 0x1f);
2535 tcg_gen_shr_tl(t0, t1, t0);
2536 tcg_gen_ext32s_tl(cpu_gpr[rd], t0);
2541 TCGv_i32 t2 = tcg_temp_new_i32();
2542 TCGv_i32 t3 = tcg_temp_new_i32();
2544 tcg_gen_trunc_tl_i32(t2, t0);
2545 tcg_gen_trunc_tl_i32(t3, t1);
2546 tcg_gen_andi_i32(t2, t2, 0x1f);
2547 tcg_gen_rotr_i32(t2, t3, t2);
2548 tcg_gen_ext_i32_tl(cpu_gpr[rd], t2);
2549 tcg_temp_free_i32(t2);
2550 tcg_temp_free_i32(t3);
2554 #if defined(TARGET_MIPS64)
2556 tcg_gen_andi_tl(t0, t0, 0x3f);
2557 tcg_gen_shl_tl(cpu_gpr[rd], t1, t0);
2561 tcg_gen_andi_tl(t0, t0, 0x3f);
2562 tcg_gen_sar_tl(cpu_gpr[rd], t1, t0);
2566 tcg_gen_andi_tl(t0, t0, 0x3f);
2567 tcg_gen_shr_tl(cpu_gpr[rd], t1, t0);
2571 tcg_gen_andi_tl(t0, t0, 0x3f);
2572 tcg_gen_rotr_tl(cpu_gpr[rd], t1, t0);
2577 (void)opn; /* avoid a compiler warning */
2578 MIPS_DEBUG("%s %s, %s, %s", opn, regnames[rd], regnames[rs], regnames[rt]);
2583 /* Arithmetic on HI/LO registers */
2584 static void gen_HILO (DisasContext *ctx, uint32_t opc, int reg)
2586 const char *opn = "hilo";
2589 if (reg == 0 && (opc == OPC_MFHI || opc == OPC_MFLO)) {
2595 if (opc == OPC_MFHI || opc == OPC_MFLO) {
2596 acc = ((ctx->opcode) >> 21) & 0x03;
2598 acc = ((ctx->opcode) >> 11) & 0x03;
2607 #if defined(TARGET_MIPS64)
2609 tcg_gen_ext32s_tl(cpu_gpr[reg], cpu_HI[acc]);
2613 tcg_gen_mov_tl(cpu_gpr[reg], cpu_HI[acc]);
2618 #if defined(TARGET_MIPS64)
2620 tcg_gen_ext32s_tl(cpu_gpr[reg], cpu_LO[acc]);
2624 tcg_gen_mov_tl(cpu_gpr[reg], cpu_LO[acc]);
2630 #if defined(TARGET_MIPS64)
2632 tcg_gen_ext32s_tl(cpu_HI[acc], cpu_gpr[reg]);
2636 tcg_gen_mov_tl(cpu_HI[acc], cpu_gpr[reg]);
2639 tcg_gen_movi_tl(cpu_HI[acc], 0);
2645 #if defined(TARGET_MIPS64)
2647 tcg_gen_ext32s_tl(cpu_LO[acc], cpu_gpr[reg]);
2651 tcg_gen_mov_tl(cpu_LO[acc], cpu_gpr[reg]);
2654 tcg_gen_movi_tl(cpu_LO[acc], 0);
2659 (void)opn; /* avoid a compiler warning */
2660 MIPS_DEBUG("%s %s", opn, regnames[reg]);
2663 static void gen_muldiv (DisasContext *ctx, uint32_t opc,
2666 const char *opn = "mul/div";
2670 t0 = tcg_temp_new();
2671 t1 = tcg_temp_new();
2673 gen_load_gpr(t0, rs);
2674 gen_load_gpr(t1, rt);
2679 TCGv t2 = tcg_temp_new();
2680 TCGv t3 = tcg_temp_new();
2681 tcg_gen_ext32s_tl(t0, t0);
2682 tcg_gen_ext32s_tl(t1, t1);
2683 tcg_gen_setcondi_tl(TCG_COND_EQ, t2, t0, INT_MIN);
2684 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, -1);
2685 tcg_gen_and_tl(t2, t2, t3);
2686 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, 0);
2687 tcg_gen_or_tl(t2, t2, t3);
2688 tcg_gen_movi_tl(t3, 0);
2689 tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, t3, t2, t1);
2690 tcg_gen_div_tl(cpu_LO[0], t0, t1);
2691 tcg_gen_rem_tl(cpu_HI[0], t0, t1);
2692 tcg_gen_ext32s_tl(cpu_LO[0], cpu_LO[0]);
2693 tcg_gen_ext32s_tl(cpu_HI[0], cpu_HI[0]);
2701 TCGv t2 = tcg_const_tl(0);
2702 TCGv t3 = tcg_const_tl(1);
2703 tcg_gen_ext32u_tl(t0, t0);
2704 tcg_gen_ext32u_tl(t1, t1);
2705 tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1, t2, t3, t1);
2706 tcg_gen_divu_tl(cpu_LO[0], t0, t1);
2707 tcg_gen_remu_tl(cpu_HI[0], t0, t1);
2708 tcg_gen_ext32s_tl(cpu_LO[0], cpu_LO[0]);
2709 tcg_gen_ext32s_tl(cpu_HI[0], cpu_HI[0]);
2717 TCGv_i64 t2 = tcg_temp_new_i64();
2718 TCGv_i64 t3 = tcg_temp_new_i64();
2719 acc = ((ctx->opcode) >> 11) & 0x03;
2724 tcg_gen_ext_tl_i64(t2, t0);
2725 tcg_gen_ext_tl_i64(t3, t1);
2726 tcg_gen_mul_i64(t2, t2, t3);
2727 tcg_temp_free_i64(t3);
2728 tcg_gen_trunc_i64_tl(t0, t2);
2729 tcg_gen_shri_i64(t2, t2, 32);
2730 tcg_gen_trunc_i64_tl(t1, t2);
2731 tcg_temp_free_i64(t2);
2732 tcg_gen_ext32s_tl(cpu_LO[acc], t0);
2733 tcg_gen_ext32s_tl(cpu_HI[acc], t1);
2739 TCGv_i64 t2 = tcg_temp_new_i64();
2740 TCGv_i64 t3 = tcg_temp_new_i64();
2741 acc = ((ctx->opcode) >> 11) & 0x03;
2746 tcg_gen_ext32u_tl(t0, t0);
2747 tcg_gen_ext32u_tl(t1, t1);
2748 tcg_gen_extu_tl_i64(t2, t0);
2749 tcg_gen_extu_tl_i64(t3, t1);
2750 tcg_gen_mul_i64(t2, t2, t3);
2751 tcg_temp_free_i64(t3);
2752 tcg_gen_trunc_i64_tl(t0, t2);
2753 tcg_gen_shri_i64(t2, t2, 32);
2754 tcg_gen_trunc_i64_tl(t1, t2);
2755 tcg_temp_free_i64(t2);
2756 tcg_gen_ext32s_tl(cpu_LO[acc], t0);
2757 tcg_gen_ext32s_tl(cpu_HI[acc], t1);
2761 #if defined(TARGET_MIPS64)
2764 TCGv t2 = tcg_temp_new();
2765 TCGv t3 = tcg_temp_new();
2766 tcg_gen_setcondi_tl(TCG_COND_EQ, t2, t0, -1LL << 63);
2767 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, -1LL);
2768 tcg_gen_and_tl(t2, t2, t3);
2769 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, 0);
2770 tcg_gen_or_tl(t2, t2, t3);
2771 tcg_gen_movi_tl(t3, 0);
2772 tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, t3, t2, t1);
2773 tcg_gen_div_tl(cpu_LO[0], t0, t1);
2774 tcg_gen_rem_tl(cpu_HI[0], t0, t1);
2782 TCGv t2 = tcg_const_tl(0);
2783 TCGv t3 = tcg_const_tl(1);
2784 tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1, t2, t3, t1);
2785 tcg_gen_divu_i64(cpu_LO[0], t0, t1);
2786 tcg_gen_remu_i64(cpu_HI[0], t0, t1);
2793 gen_helper_dmult(cpu_env, t0, t1);
2797 gen_helper_dmultu(cpu_env, t0, t1);
2803 TCGv_i64 t2 = tcg_temp_new_i64();
2804 TCGv_i64 t3 = tcg_temp_new_i64();
2805 acc = ((ctx->opcode) >> 11) & 0x03;
2810 tcg_gen_ext_tl_i64(t2, t0);
2811 tcg_gen_ext_tl_i64(t3, t1);
2812 tcg_gen_mul_i64(t2, t2, t3);
2813 tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]);
2814 tcg_gen_add_i64(t2, t2, t3);
2815 tcg_temp_free_i64(t3);
2816 tcg_gen_trunc_i64_tl(t0, t2);
2817 tcg_gen_shri_i64(t2, t2, 32);
2818 tcg_gen_trunc_i64_tl(t1, t2);
2819 tcg_temp_free_i64(t2);
2820 tcg_gen_ext32s_tl(cpu_LO[acc], t0);
2821 tcg_gen_ext32s_tl(cpu_HI[acc], t1);
2827 TCGv_i64 t2 = tcg_temp_new_i64();
2828 TCGv_i64 t3 = tcg_temp_new_i64();
2829 acc = ((ctx->opcode) >> 11) & 0x03;
2834 tcg_gen_ext32u_tl(t0, t0);
2835 tcg_gen_ext32u_tl(t1, t1);
2836 tcg_gen_extu_tl_i64(t2, t0);
2837 tcg_gen_extu_tl_i64(t3, t1);
2838 tcg_gen_mul_i64(t2, t2, t3);
2839 tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]);
2840 tcg_gen_add_i64(t2, t2, t3);
2841 tcg_temp_free_i64(t3);
2842 tcg_gen_trunc_i64_tl(t0, t2);
2843 tcg_gen_shri_i64(t2, t2, 32);
2844 tcg_gen_trunc_i64_tl(t1, t2);
2845 tcg_temp_free_i64(t2);
2846 tcg_gen_ext32s_tl(cpu_LO[acc], t0);
2847 tcg_gen_ext32s_tl(cpu_HI[acc], t1);
2853 TCGv_i64 t2 = tcg_temp_new_i64();
2854 TCGv_i64 t3 = tcg_temp_new_i64();
2855 acc = ((ctx->opcode) >> 11) & 0x03;
2860 tcg_gen_ext_tl_i64(t2, t0);
2861 tcg_gen_ext_tl_i64(t3, t1);
2862 tcg_gen_mul_i64(t2, t2, t3);
2863 tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]);
2864 tcg_gen_sub_i64(t2, t3, t2);
2865 tcg_temp_free_i64(t3);
2866 tcg_gen_trunc_i64_tl(t0, t2);
2867 tcg_gen_shri_i64(t2, t2, 32);
2868 tcg_gen_trunc_i64_tl(t1, t2);
2869 tcg_temp_free_i64(t2);
2870 tcg_gen_ext32s_tl(cpu_LO[acc], t0);
2871 tcg_gen_ext32s_tl(cpu_HI[acc], t1);
2877 TCGv_i64 t2 = tcg_temp_new_i64();
2878 TCGv_i64 t3 = tcg_temp_new_i64();
2879 acc = ((ctx->opcode) >> 11) & 0x03;
2884 tcg_gen_ext32u_tl(t0, t0);
2885 tcg_gen_ext32u_tl(t1, t1);
2886 tcg_gen_extu_tl_i64(t2, t0);
2887 tcg_gen_extu_tl_i64(t3, t1);
2888 tcg_gen_mul_i64(t2, t2, t3);
2889 tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]);
2890 tcg_gen_sub_i64(t2, t3, t2);
2891 tcg_temp_free_i64(t3);
2892 tcg_gen_trunc_i64_tl(t0, t2);
2893 tcg_gen_shri_i64(t2, t2, 32);
2894 tcg_gen_trunc_i64_tl(t1, t2);
2895 tcg_temp_free_i64(t2);
2896 tcg_gen_ext32s_tl(cpu_LO[acc], t0);
2897 tcg_gen_ext32s_tl(cpu_HI[acc], t1);
2903 generate_exception(ctx, EXCP_RI);
2906 (void)opn; /* avoid a compiler warning */
2907 MIPS_DEBUG("%s %s %s", opn, regnames[rs], regnames[rt]);
2913 static void gen_mul_vr54xx (DisasContext *ctx, uint32_t opc,
2914 int rd, int rs, int rt)
2916 const char *opn = "mul vr54xx";
2917 TCGv t0 = tcg_temp_new();
2918 TCGv t1 = tcg_temp_new();
2920 gen_load_gpr(t0, rs);
2921 gen_load_gpr(t1, rt);
2924 case OPC_VR54XX_MULS:
2925 gen_helper_muls(t0, cpu_env, t0, t1);
2928 case OPC_VR54XX_MULSU:
2929 gen_helper_mulsu(t0, cpu_env, t0, t1);
2932 case OPC_VR54XX_MACC:
2933 gen_helper_macc(t0, cpu_env, t0, t1);
2936 case OPC_VR54XX_MACCU:
2937 gen_helper_maccu(t0, cpu_env, t0, t1);
2940 case OPC_VR54XX_MSAC:
2941 gen_helper_msac(t0, cpu_env, t0, t1);
2944 case OPC_VR54XX_MSACU:
2945 gen_helper_msacu(t0, cpu_env, t0, t1);
2948 case OPC_VR54XX_MULHI:
2949 gen_helper_mulhi(t0, cpu_env, t0, t1);
2952 case OPC_VR54XX_MULHIU:
2953 gen_helper_mulhiu(t0, cpu_env, t0, t1);
2956 case OPC_VR54XX_MULSHI:
2957 gen_helper_mulshi(t0, cpu_env, t0, t1);
2960 case OPC_VR54XX_MULSHIU:
2961 gen_helper_mulshiu(t0, cpu_env, t0, t1);
2964 case OPC_VR54XX_MACCHI:
2965 gen_helper_macchi(t0, cpu_env, t0, t1);
2968 case OPC_VR54XX_MACCHIU:
2969 gen_helper_macchiu(t0, cpu_env, t0, t1);
2972 case OPC_VR54XX_MSACHI:
2973 gen_helper_msachi(t0, cpu_env, t0, t1);
2976 case OPC_VR54XX_MSACHIU:
2977 gen_helper_msachiu(t0, cpu_env, t0, t1);
2981 MIPS_INVAL("mul vr54xx");
2982 generate_exception(ctx, EXCP_RI);
2985 gen_store_gpr(t0, rd);
2986 (void)opn; /* avoid a compiler warning */
2987 MIPS_DEBUG("%s %s, %s, %s", opn, regnames[rd], regnames[rs], regnames[rt]);
2994 static void gen_cl (DisasContext *ctx, uint32_t opc,
2997 const char *opn = "CLx";
3005 t0 = tcg_temp_new();
3006 gen_load_gpr(t0, rs);
3009 gen_helper_clo(cpu_gpr[rd], t0);
3013 gen_helper_clz(cpu_gpr[rd], t0);
3016 #if defined(TARGET_MIPS64)
3018 gen_helper_dclo(cpu_gpr[rd], t0);
3022 gen_helper_dclz(cpu_gpr[rd], t0);
3027 (void)opn; /* avoid a compiler warning */
3028 MIPS_DEBUG("%s %s, %s", opn, regnames[rd], regnames[rs]);
3032 /* Godson integer instructions */
3033 static void gen_loongson_integer(DisasContext *ctx, uint32_t opc,
3034 int rd, int rs, int rt)
3036 const char *opn = "loongson";
3048 case OPC_MULTU_G_2E:
3049 case OPC_MULTU_G_2F:
3050 #if defined(TARGET_MIPS64)
3051 case OPC_DMULT_G_2E:
3052 case OPC_DMULT_G_2F:
3053 case OPC_DMULTU_G_2E:
3054 case OPC_DMULTU_G_2F:
3056 t0 = tcg_temp_new();
3057 t1 = tcg_temp_new();
3060 t0 = tcg_temp_local_new();
3061 t1 = tcg_temp_local_new();
3065 gen_load_gpr(t0, rs);
3066 gen_load_gpr(t1, rt);
3071 tcg_gen_mul_tl(cpu_gpr[rd], t0, t1);
3072 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3075 case OPC_MULTU_G_2E:
3076 case OPC_MULTU_G_2F:
3077 tcg_gen_ext32u_tl(t0, t0);
3078 tcg_gen_ext32u_tl(t1, t1);
3079 tcg_gen_mul_tl(cpu_gpr[rd], t0, t1);
3080 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3086 int l1 = gen_new_label();
3087 int l2 = gen_new_label();
3088 int l3 = gen_new_label();
3089 tcg_gen_ext32s_tl(t0, t0);
3090 tcg_gen_ext32s_tl(t1, t1);
3091 tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
3092 tcg_gen_movi_tl(cpu_gpr[rd], 0);
3095 tcg_gen_brcondi_tl(TCG_COND_NE, t0, INT_MIN, l2);
3096 tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1, l2);
3097 tcg_gen_mov_tl(cpu_gpr[rd], t0);
3100 tcg_gen_div_tl(cpu_gpr[rd], t0, t1);
3101 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3109 int l1 = gen_new_label();
3110 int l2 = gen_new_label();
3111 tcg_gen_ext32u_tl(t0, t0);
3112 tcg_gen_ext32u_tl(t1, t1);
3113 tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
3114 tcg_gen_movi_tl(cpu_gpr[rd], 0);
3117 tcg_gen_divu_tl(cpu_gpr[rd], t0, t1);
3118 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3126 int l1 = gen_new_label();
3127 int l2 = gen_new_label();
3128 int l3 = gen_new_label();
3129 tcg_gen_ext32u_tl(t0, t0);
3130 tcg_gen_ext32u_tl(t1, t1);
3131 tcg_gen_brcondi_tl(TCG_COND_EQ, t1, 0, l1);
3132 tcg_gen_brcondi_tl(TCG_COND_NE, t0, INT_MIN, l2);
3133 tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1, l2);
3135 tcg_gen_movi_tl(cpu_gpr[rd], 0);
3138 tcg_gen_rem_tl(cpu_gpr[rd], t0, t1);
3139 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3147 int l1 = gen_new_label();
3148 int l2 = gen_new_label();
3149 tcg_gen_ext32u_tl(t0, t0);
3150 tcg_gen_ext32u_tl(t1, t1);
3151 tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
3152 tcg_gen_movi_tl(cpu_gpr[rd], 0);
3155 tcg_gen_remu_tl(cpu_gpr[rd], t0, t1);
3156 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3161 #if defined(TARGET_MIPS64)
3162 case OPC_DMULT_G_2E:
3163 case OPC_DMULT_G_2F:
3164 tcg_gen_mul_tl(cpu_gpr[rd], t0, t1);
3167 case OPC_DMULTU_G_2E:
3168 case OPC_DMULTU_G_2F:
3169 tcg_gen_mul_tl(cpu_gpr[rd], t0, t1);
3175 int l1 = gen_new_label();
3176 int l2 = gen_new_label();
3177 int l3 = gen_new_label();
3178 tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
3179 tcg_gen_movi_tl(cpu_gpr[rd], 0);
3182 tcg_gen_brcondi_tl(TCG_COND_NE, t0, -1LL << 63, l2);
3183 tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1LL, l2);
3184 tcg_gen_mov_tl(cpu_gpr[rd], t0);
3187 tcg_gen_div_tl(cpu_gpr[rd], t0, t1);
3192 case OPC_DDIVU_G_2E:
3193 case OPC_DDIVU_G_2F:
3195 int l1 = gen_new_label();
3196 int l2 = gen_new_label();
3197 tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
3198 tcg_gen_movi_tl(cpu_gpr[rd], 0);
3201 tcg_gen_divu_tl(cpu_gpr[rd], t0, t1);
3209 int l1 = gen_new_label();
3210 int l2 = gen_new_label();
3211 int l3 = gen_new_label();
3212 tcg_gen_brcondi_tl(TCG_COND_EQ, t1, 0, l1);
3213 tcg_gen_brcondi_tl(TCG_COND_NE, t0, -1LL << 63, l2);
3214 tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1LL, l2);
3216 tcg_gen_movi_tl(cpu_gpr[rd], 0);
3219 tcg_gen_rem_tl(cpu_gpr[rd], t0, t1);
3224 case OPC_DMODU_G_2E:
3225 case OPC_DMODU_G_2F:
3227 int l1 = gen_new_label();
3228 int l2 = gen_new_label();
3229 tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
3230 tcg_gen_movi_tl(cpu_gpr[rd], 0);
3233 tcg_gen_remu_tl(cpu_gpr[rd], t0, t1);
3241 (void)opn; /* avoid a compiler warning */
3242 MIPS_DEBUG("%s %s, %s", opn, regnames[rd], regnames[rs]);
3247 /* Loongson multimedia instructions */
3248 static void gen_loongson_multimedia(DisasContext *ctx, int rd, int rs, int rt)
3250 const char *opn = "loongson_cp2";
3251 uint32_t opc, shift_max;
3254 opc = MASK_LMI(ctx->opcode);
3260 t0 = tcg_temp_local_new_i64();
3261 t1 = tcg_temp_local_new_i64();
3264 t0 = tcg_temp_new_i64();
3265 t1 = tcg_temp_new_i64();
3269 gen_load_fpr64(ctx, t0, rs);
3270 gen_load_fpr64(ctx, t1, rt);
3272 #define LMI_HELPER(UP, LO) \
3273 case OPC_##UP: gen_helper_##LO(t0, t0, t1); opn = #LO; break
3274 #define LMI_HELPER_1(UP, LO) \
3275 case OPC_##UP: gen_helper_##LO(t0, t0); opn = #LO; break
3276 #define LMI_DIRECT(UP, LO, OP) \
3277 case OPC_##UP: tcg_gen_##OP##_i64(t0, t0, t1); opn = #LO; break
3280 LMI_HELPER(PADDSH, paddsh);
3281 LMI_HELPER(PADDUSH, paddush);
3282 LMI_HELPER(PADDH, paddh);
3283 LMI_HELPER(PADDW, paddw);
3284 LMI_HELPER(PADDSB, paddsb);
3285 LMI_HELPER(PADDUSB, paddusb);
3286 LMI_HELPER(PADDB, paddb);
3288 LMI_HELPER(PSUBSH, psubsh);
3289 LMI_HELPER(PSUBUSH, psubush);
3290 LMI_HELPER(PSUBH, psubh);
3291 LMI_HELPER(PSUBW, psubw);
3292 LMI_HELPER(PSUBSB, psubsb);
3293 LMI_HELPER(PSUBUSB, psubusb);
3294 LMI_HELPER(PSUBB, psubb);
3296 LMI_HELPER(PSHUFH, pshufh);
3297 LMI_HELPER(PACKSSWH, packsswh);
3298 LMI_HELPER(PACKSSHB, packsshb);
3299 LMI_HELPER(PACKUSHB, packushb);
3301 LMI_HELPER(PUNPCKLHW, punpcklhw);
3302 LMI_HELPER(PUNPCKHHW, punpckhhw);
3303 LMI_HELPER(PUNPCKLBH, punpcklbh);
3304 LMI_HELPER(PUNPCKHBH, punpckhbh);
3305 LMI_HELPER(PUNPCKLWD, punpcklwd);
3306 LMI_HELPER(PUNPCKHWD, punpckhwd);
3308 LMI_HELPER(PAVGH, pavgh);
3309 LMI_HELPER(PAVGB, pavgb);
3310 LMI_HELPER(PMAXSH, pmaxsh);
3311 LMI_HELPER(PMINSH, pminsh);
3312 LMI_HELPER(PMAXUB, pmaxub);
3313 LMI_HELPER(PMINUB, pminub);
3315 LMI_HELPER(PCMPEQW, pcmpeqw);
3316 LMI_HELPER(PCMPGTW, pcmpgtw);
3317 LMI_HELPER(PCMPEQH, pcmpeqh);
3318 LMI_HELPER(PCMPGTH, pcmpgth);
3319 LMI_HELPER(PCMPEQB, pcmpeqb);
3320 LMI_HELPER(PCMPGTB, pcmpgtb);
3322 LMI_HELPER(PSLLW, psllw);
3323 LMI_HELPER(PSLLH, psllh);
3324 LMI_HELPER(PSRLW, psrlw);
3325 LMI_HELPER(PSRLH, psrlh);
3326 LMI_HELPER(PSRAW, psraw);
3327 LMI_HELPER(PSRAH, psrah);
3329 LMI_HELPER(PMULLH, pmullh);
3330 LMI_HELPER(PMULHH, pmulhh);
3331 LMI_HELPER(PMULHUH, pmulhuh);
3332 LMI_HELPER(PMADDHW, pmaddhw);
3334 LMI_HELPER(PASUBUB, pasubub);
3335 LMI_HELPER_1(BIADD, biadd);
3336 LMI_HELPER_1(PMOVMSKB, pmovmskb);
3338 LMI_DIRECT(PADDD, paddd, add);
3339 LMI_DIRECT(PSUBD, psubd, sub);
3340 LMI_DIRECT(XOR_CP2, xor, xor);
3341 LMI_DIRECT(NOR_CP2, nor, nor);
3342 LMI_DIRECT(AND_CP2, and, and);
3343 LMI_DIRECT(PANDN, pandn, andc);
3344 LMI_DIRECT(OR, or, or);
3347 tcg_gen_deposit_i64(t0, t0, t1, 0, 16);
3351 tcg_gen_deposit_i64(t0, t0, t1, 16, 16);
3355 tcg_gen_deposit_i64(t0, t0, t1, 32, 16);
3359 tcg_gen_deposit_i64(t0, t0, t1, 48, 16);
3364 tcg_gen_andi_i64(t1, t1, 3);
3365 tcg_gen_shli_i64(t1, t1, 4);
3366 tcg_gen_shr_i64(t0, t0, t1);
3367 tcg_gen_ext16u_i64(t0, t0);
3372 tcg_gen_add_i64(t0, t0, t1);
3373 tcg_gen_ext32s_i64(t0, t0);
3377 tcg_gen_sub_i64(t0, t0, t1);
3378 tcg_gen_ext32s_i64(t0, t0);
3407 /* Make sure shift count isn't TCG undefined behaviour. */
3408 tcg_gen_andi_i64(t1, t1, shift_max - 1);
3413 tcg_gen_shl_i64(t0, t0, t1);
3417 /* Since SRA is UndefinedResult without sign-extended inputs,
3418 we can treat SRA and DSRA the same. */
3419 tcg_gen_sar_i64(t0, t0, t1);
3422 /* We want to shift in zeros for SRL; zero-extend first. */
3423 tcg_gen_ext32u_i64(t0, t0);
3426 tcg_gen_shr_i64(t0, t0, t1);
3430 if (shift_max == 32) {
3431 tcg_gen_ext32s_i64(t0, t0);
3434 /* Shifts larger than MAX produce zero. */
3435 tcg_gen_setcondi_i64(TCG_COND_LTU, t1, t1, shift_max);
3436 tcg_gen_neg_i64(t1, t1);
3437 tcg_gen_and_i64(t0, t0, t1);
3443 TCGv_i64 t2 = tcg_temp_new_i64();
3444 int lab = gen_new_label();
3446 tcg_gen_mov_i64(t2, t0);
3447 tcg_gen_add_i64(t0, t1, t2);
3448 if (opc == OPC_ADD_CP2) {
3449 tcg_gen_ext32s_i64(t0, t0);
3451 tcg_gen_xor_i64(t1, t1, t2);
3452 tcg_gen_xor_i64(t2, t2, t0);
3453 tcg_gen_andc_i64(t1, t2, t1);
3454 tcg_temp_free_i64(t2);
3455 tcg_gen_brcondi_i64(TCG_COND_GE, t1, 0, lab);
3456 generate_exception(ctx, EXCP_OVERFLOW);
3459 opn = (opc == OPC_ADD_CP2 ? "add" : "dadd");
3466 TCGv_i64 t2 = tcg_temp_new_i64();
3467 int lab = gen_new_label();
3469 tcg_gen_mov_i64(t2, t0);
3470 tcg_gen_sub_i64(t0, t1, t2);
3471 if (opc == OPC_SUB_CP2) {
3472 tcg_gen_ext32s_i64(t0, t0);
3474 tcg_gen_xor_i64(t1, t1, t2);
3475 tcg_gen_xor_i64(t2, t2, t0);
3476 tcg_gen_and_i64(t1, t1, t2);
3477 tcg_temp_free_i64(t2);
3478 tcg_gen_brcondi_i64(TCG_COND_GE, t1, 0, lab);
3479 generate_exception(ctx, EXCP_OVERFLOW);
3482 opn = (opc == OPC_SUB_CP2 ? "sub" : "dsub");
3487 tcg_gen_ext32u_i64(t0, t0);
3488 tcg_gen_ext32u_i64(t1, t1);
3489 tcg_gen_mul_i64(t0, t0, t1);
3499 /* ??? Document is unclear: Set FCC[CC]. Does that mean the
3500 FD field is the CC field? */
3503 generate_exception(ctx, EXCP_RI);
3510 gen_store_fpr64(ctx, t0, rd);
3512 (void)opn; /* avoid a compiler warning */
3513 MIPS_DEBUG("%s %s, %s, %s", opn,
3514 fregnames[rd], fregnames[rs], fregnames[rt]);
3515 tcg_temp_free_i64(t0);
3516 tcg_temp_free_i64(t1);
3520 static void gen_trap (DisasContext *ctx, uint32_t opc,
3521 int rs, int rt, int16_t imm)
3524 TCGv t0 = tcg_temp_new();
3525 TCGv t1 = tcg_temp_new();
3528 /* Load needed operands */
3536 /* Compare two registers */
3538 gen_load_gpr(t0, rs);
3539 gen_load_gpr(t1, rt);
3549 /* Compare register to immediate */
3550 if (rs != 0 || imm != 0) {
3551 gen_load_gpr(t0, rs);
3552 tcg_gen_movi_tl(t1, (int32_t)imm);
3559 case OPC_TEQ: /* rs == rs */
3560 case OPC_TEQI: /* r0 == 0 */
3561 case OPC_TGE: /* rs >= rs */
3562 case OPC_TGEI: /* r0 >= 0 */
3563 case OPC_TGEU: /* rs >= rs unsigned */
3564 case OPC_TGEIU: /* r0 >= 0 unsigned */
3566 generate_exception(ctx, EXCP_TRAP);
3568 case OPC_TLT: /* rs < rs */
3569 case OPC_TLTI: /* r0 < 0 */
3570 case OPC_TLTU: /* rs < rs unsigned */
3571 case OPC_TLTIU: /* r0 < 0 unsigned */
3572 case OPC_TNE: /* rs != rs */
3573 case OPC_TNEI: /* r0 != 0 */
3574 /* Never trap: treat as NOP. */
3578 int l1 = gen_new_label();
3583 tcg_gen_brcond_tl(TCG_COND_NE, t0, t1, l1);
3587 tcg_gen_brcond_tl(TCG_COND_LT, t0, t1, l1);
3591 tcg_gen_brcond_tl(TCG_COND_LTU, t0, t1, l1);
3595 tcg_gen_brcond_tl(TCG_COND_GE, t0, t1, l1);
3599 tcg_gen_brcond_tl(TCG_COND_GEU, t0, t1, l1);
3603 tcg_gen_brcond_tl(TCG_COND_EQ, t0, t1, l1);
3606 generate_exception(ctx, EXCP_TRAP);
3613 static inline void gen_goto_tb(DisasContext *ctx, int n, target_ulong dest)
3615 TranslationBlock *tb;
3617 if ((tb->pc & TARGET_PAGE_MASK) == (dest & TARGET_PAGE_MASK) &&
3618 likely(!ctx->singlestep_enabled)) {
3621 tcg_gen_exit_tb((tcg_target_long)tb + n);
3624 if (ctx->singlestep_enabled) {
3625 save_cpu_state(ctx, 0);
3626 gen_helper_0e0i(raise_exception, EXCP_DEBUG);
3632 /* Branches (before delay slot) */
3633 static void gen_compute_branch (DisasContext *ctx, uint32_t opc,
3635 int rs, int rt, int32_t offset)
3637 target_ulong btgt = -1;
3639 int bcond_compute = 0;
3640 TCGv t0 = tcg_temp_new();
3641 TCGv t1 = tcg_temp_new();
3643 if (ctx->hflags & MIPS_HFLAG_BMASK) {
3644 #ifdef MIPS_DEBUG_DISAS
3645 LOG_DISAS("Branch in delay slot at PC 0x" TARGET_FMT_lx "\n", ctx->pc);
3647 generate_exception(ctx, EXCP_RI);
3651 /* Load needed operands */
3657 /* Compare two registers */
3659 gen_load_gpr(t0, rs);
3660 gen_load_gpr(t1, rt);
3663 btgt = ctx->pc + insn_bytes + offset;
3679 /* Compare to zero */
3681 gen_load_gpr(t0, rs);
3684 btgt = ctx->pc + insn_bytes + offset;
3687 #if defined(TARGET_MIPS64)
3689 tcg_gen_andi_tl(t0, cpu_dspctrl, 0x7F);
3691 tcg_gen_andi_tl(t0, cpu_dspctrl, 0x3F);
3694 btgt = ctx->pc + insn_bytes + offset;
3701 /* Jump to immediate */
3702 btgt = ((ctx->pc + insn_bytes) & (int32_t)0xF0000000) | (uint32_t)offset;
3708 /* Jump to register */
3709 if (offset != 0 && offset != 16) {
3710 /* Hint = 0 is JR/JALR, hint 16 is JR.HB/JALR.HB, the
3711 others are reserved. */
3712 MIPS_INVAL("jump hint");
3713 generate_exception(ctx, EXCP_RI);
3716 gen_load_gpr(btarget, rs);
3719 MIPS_INVAL("branch/jump");
3720 generate_exception(ctx, EXCP_RI);
3723 if (bcond_compute == 0) {
3724 /* No condition to be computed */
3726 case OPC_BEQ: /* rx == rx */
3727 case OPC_BEQL: /* rx == rx likely */
3728 case OPC_BGEZ: /* 0 >= 0 */
3729 case OPC_BGEZL: /* 0 >= 0 likely */
3730 case OPC_BLEZ: /* 0 <= 0 */
3731 case OPC_BLEZL: /* 0 <= 0 likely */
3733 ctx->hflags |= MIPS_HFLAG_B;
3734 MIPS_DEBUG("balways");
3737 case OPC_BGEZAL: /* 0 >= 0 */
3738 case OPC_BGEZALL: /* 0 >= 0 likely */
3739 ctx->hflags |= (opc == OPC_BGEZALS
3741 : MIPS_HFLAG_BDS32);
3742 /* Always take and link */
3744 ctx->hflags |= MIPS_HFLAG_B;
3745 MIPS_DEBUG("balways and link");
3747 case OPC_BNE: /* rx != rx */
3748 case OPC_BGTZ: /* 0 > 0 */
3749 case OPC_BLTZ: /* 0 < 0 */
3751 MIPS_DEBUG("bnever (NOP)");
3754 case OPC_BLTZAL: /* 0 < 0 */
3755 ctx->hflags |= (opc == OPC_BLTZALS
3757 : MIPS_HFLAG_BDS32);
3758 /* Handle as an unconditional branch to get correct delay
3761 btgt = ctx->pc + (opc == OPC_BLTZALS ? 6 : 8);
3762 ctx->hflags |= MIPS_HFLAG_B;
3763 MIPS_DEBUG("bnever and link");
3765 case OPC_BLTZALL: /* 0 < 0 likely */
3766 tcg_gen_movi_tl(cpu_gpr[31], ctx->pc + 8);
3767 /* Skip the instruction in the delay slot */
3768 MIPS_DEBUG("bnever, link and skip");
3771 case OPC_BNEL: /* rx != rx likely */
3772 case OPC_BGTZL: /* 0 > 0 likely */
3773 case OPC_BLTZL: /* 0 < 0 likely */
3774 /* Skip the instruction in the delay slot */
3775 MIPS_DEBUG("bnever and skip");
3779 ctx->hflags |= MIPS_HFLAG_B;
3780 MIPS_DEBUG("j " TARGET_FMT_lx, btgt);
3784 ctx->hflags |= MIPS_HFLAG_BX;
3789 ctx->hflags |= MIPS_HFLAG_B;
3790 ctx->hflags |= ((opc == OPC_JALS || opc == OPC_JALXS)
3792 : MIPS_HFLAG_BDS32);
3793 MIPS_DEBUG("jal " TARGET_FMT_lx, btgt);
3796 ctx->hflags |= MIPS_HFLAG_BR;
3797 if (insn_bytes == 4)
3798 ctx->hflags |= MIPS_HFLAG_BDS32;
3799 MIPS_DEBUG("jr %s", regnames[rs]);
3805 ctx->hflags |= MIPS_HFLAG_BR;
3806 ctx->hflags |= (opc == OPC_JALRS
3808 : MIPS_HFLAG_BDS32);
3809 MIPS_DEBUG("jalr %s, %s", regnames[rt], regnames[rs]);
3812 MIPS_INVAL("branch/jump");
3813 generate_exception(ctx, EXCP_RI);
3819 tcg_gen_setcond_tl(TCG_COND_EQ, bcond, t0, t1);
3820 MIPS_DEBUG("beq %s, %s, " TARGET_FMT_lx,
3821 regnames[rs], regnames[rt], btgt);
3824 tcg_gen_setcond_tl(TCG_COND_EQ, bcond, t0, t1);
3825 MIPS_DEBUG("beql %s, %s, " TARGET_FMT_lx,
3826 regnames[rs], regnames[rt], btgt);
3829 tcg_gen_setcond_tl(TCG_COND_NE, bcond, t0, t1);
3830 MIPS_DEBUG("bne %s, %s, " TARGET_FMT_lx,
3831 regnames[rs], regnames[rt], btgt);
3834 tcg_gen_setcond_tl(TCG_COND_NE, bcond, t0, t1);
3835 MIPS_DEBUG("bnel %s, %s, " TARGET_FMT_lx,
3836 regnames[rs], regnames[rt], btgt);
3839 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 0);
3840 MIPS_DEBUG("bgez %s, " TARGET_FMT_lx, regnames[rs], btgt);
3843 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 0);
3844 MIPS_DEBUG("bgezl %s, " TARGET_FMT_lx, regnames[rs], btgt);
3848 ctx->hflags |= (opc == OPC_BGEZALS
3850 : MIPS_HFLAG_BDS32);
3851 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 0);
3852 MIPS_DEBUG("bgezal %s, " TARGET_FMT_lx, regnames[rs], btgt);
3856 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 0);
3858 MIPS_DEBUG("bgezall %s, " TARGET_FMT_lx, regnames[rs], btgt);
3861 tcg_gen_setcondi_tl(TCG_COND_GT, bcond, t0, 0);
3862 MIPS_DEBUG("bgtz %s, " TARGET_FMT_lx, regnames[rs], btgt);
3865 tcg_gen_setcondi_tl(TCG_COND_GT, bcond, t0, 0);
3866 MIPS_DEBUG("bgtzl %s, " TARGET_FMT_lx, regnames[rs], btgt);
3869 tcg_gen_setcondi_tl(TCG_COND_LE, bcond, t0, 0);
3870 MIPS_DEBUG("blez %s, " TARGET_FMT_lx, regnames[rs], btgt);
3873 tcg_gen_setcondi_tl(TCG_COND_LE, bcond, t0, 0);
3874 MIPS_DEBUG("blezl %s, " TARGET_FMT_lx, regnames[rs], btgt);
3877 tcg_gen_setcondi_tl(TCG_COND_LT, bcond, t0, 0);
3878 MIPS_DEBUG("bltz %s, " TARGET_FMT_lx, regnames[rs], btgt);
3881 tcg_gen_setcondi_tl(TCG_COND_LT, bcond, t0, 0);
3882 MIPS_DEBUG("bltzl %s, " TARGET_FMT_lx, regnames[rs], btgt);
3885 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 32);
3886 MIPS_DEBUG("bposge32 " TARGET_FMT_lx, btgt);
3888 #if defined(TARGET_MIPS64)
3890 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 64);
3891 MIPS_DEBUG("bposge64 " TARGET_FMT_lx, btgt);
3896 ctx->hflags |= (opc == OPC_BLTZALS
3898 : MIPS_HFLAG_BDS32);
3899 tcg_gen_setcondi_tl(TCG_COND_LT, bcond, t0, 0);
3901 MIPS_DEBUG("bltzal %s, " TARGET_FMT_lx, regnames[rs], btgt);
3903 ctx->hflags |= MIPS_HFLAG_BC;
3906 tcg_gen_setcondi_tl(TCG_COND_LT, bcond, t0, 0);
3908 MIPS_DEBUG("bltzall %s, " TARGET_FMT_lx, regnames[rs], btgt);
3910 ctx->hflags |= MIPS_HFLAG_BL;
3913 MIPS_INVAL("conditional branch/jump");
3914 generate_exception(ctx, EXCP_RI);
3918 MIPS_DEBUG("enter ds: link %d cond %02x target " TARGET_FMT_lx,
3919 blink, ctx->hflags, btgt);
3921 ctx->btarget = btgt;
3923 int post_delay = insn_bytes;
3924 int lowbit = !!(ctx->hflags & MIPS_HFLAG_M16);
3926 if (opc != OPC_JALRC)
3927 post_delay += ((ctx->hflags & MIPS_HFLAG_BDS16) ? 2 : 4);
3929 tcg_gen_movi_tl(cpu_gpr[blink], ctx->pc + post_delay + lowbit);
3933 if (insn_bytes == 2)
3934 ctx->hflags |= MIPS_HFLAG_B16;
3939 /* special3 bitfield operations */
3940 static void gen_bitops (DisasContext *ctx, uint32_t opc, int rt,
3941 int rs, int lsb, int msb)
3943 TCGv t0 = tcg_temp_new();
3944 TCGv t1 = tcg_temp_new();
3946 gen_load_gpr(t1, rs);
3951 tcg_gen_shri_tl(t0, t1, lsb);
3953 tcg_gen_andi_tl(t0, t0, (1 << (msb + 1)) - 1);
3955 tcg_gen_ext32s_tl(t0, t0);
3958 #if defined(TARGET_MIPS64)
3960 tcg_gen_shri_tl(t0, t1, lsb);
3962 tcg_gen_andi_tl(t0, t0, (1ULL << (msb + 1 + 32)) - 1);
3966 tcg_gen_shri_tl(t0, t1, lsb + 32);
3967 tcg_gen_andi_tl(t0, t0, (1ULL << (msb + 1)) - 1);
3970 tcg_gen_shri_tl(t0, t1, lsb);
3971 tcg_gen_andi_tl(t0, t0, (1ULL << (msb + 1)) - 1);
3977 gen_load_gpr(t0, rt);
3978 tcg_gen_deposit_tl(t0, t0, t1, lsb, msb - lsb + 1);
3979 tcg_gen_ext32s_tl(t0, t0);
3981 #if defined(TARGET_MIPS64)
3983 gen_load_gpr(t0, rt);
3984 tcg_gen_deposit_tl(t0, t0, t1, lsb, msb + 32 - lsb + 1);
3987 gen_load_gpr(t0, rt);
3988 tcg_gen_deposit_tl(t0, t0, t1, lsb + 32, msb - lsb + 1);
3991 gen_load_gpr(t0, rt);
3992 tcg_gen_deposit_tl(t0, t0, t1, lsb, msb - lsb + 1);
3997 MIPS_INVAL("bitops");
3998 generate_exception(ctx, EXCP_RI);
4003 gen_store_gpr(t0, rt);
4008 static void gen_bshfl (DisasContext *ctx, uint32_t op2, int rt, int rd)
4013 /* If no destination, treat it as a NOP. */
4018 t0 = tcg_temp_new();
4019 gen_load_gpr(t0, rt);
4023 TCGv t1 = tcg_temp_new();
4025 tcg_gen_shri_tl(t1, t0, 8);
4026 tcg_gen_andi_tl(t1, t1, 0x00FF00FF);
4027 tcg_gen_shli_tl(t0, t0, 8);
4028 tcg_gen_andi_tl(t0, t0, ~0x00FF00FF);
4029 tcg_gen_or_tl(t0, t0, t1);
4031 tcg_gen_ext32s_tl(cpu_gpr[rd], t0);
4035 tcg_gen_ext8s_tl(cpu_gpr[rd], t0);
4038 tcg_gen_ext16s_tl(cpu_gpr[rd], t0);
4040 #if defined(TARGET_MIPS64)
4043 TCGv t1 = tcg_temp_new();
4045 tcg_gen_shri_tl(t1, t0, 8);
4046 tcg_gen_andi_tl(t1, t1, 0x00FF00FF00FF00FFULL);
4047 tcg_gen_shli_tl(t0, t0, 8);
4048 tcg_gen_andi_tl(t0, t0, ~0x00FF00FF00FF00FFULL);
4049 tcg_gen_or_tl(cpu_gpr[rd], t0, t1);
4055 TCGv t1 = tcg_temp_new();
4057 tcg_gen_shri_tl(t1, t0, 16);
4058 tcg_gen_andi_tl(t1, t1, 0x0000FFFF0000FFFFULL);
4059 tcg_gen_shli_tl(t0, t0, 16);
4060 tcg_gen_andi_tl(t0, t0, ~0x0000FFFF0000FFFFULL);
4061 tcg_gen_or_tl(t0, t0, t1);
4062 tcg_gen_shri_tl(t1, t0, 32);
4063 tcg_gen_shli_tl(t0, t0, 32);
4064 tcg_gen_or_tl(cpu_gpr[rd], t0, t1);
4070 MIPS_INVAL("bsfhl");
4071 generate_exception(ctx, EXCP_RI);
4078 #ifndef CONFIG_USER_ONLY
4079 /* CP0 (MMU and control) */
4080 static inline void gen_mfc0_load32 (TCGv arg, target_ulong off)
4082 TCGv_i32 t0 = tcg_temp_new_i32();
4084 tcg_gen_ld_i32(t0, cpu_env, off);
4085 tcg_gen_ext_i32_tl(arg, t0);
4086 tcg_temp_free_i32(t0);
4089 static inline void gen_mfc0_load64 (TCGv arg, target_ulong off)
4091 tcg_gen_ld_tl(arg, cpu_env, off);
4092 tcg_gen_ext32s_tl(arg, arg);
4095 static inline void gen_mtc0_store32 (TCGv arg, target_ulong off)
4097 TCGv_i32 t0 = tcg_temp_new_i32();
4099 tcg_gen_trunc_tl_i32(t0, arg);
4100 tcg_gen_st_i32(t0, cpu_env, off);
4101 tcg_temp_free_i32(t0);
4104 static inline void gen_mtc0_store64 (TCGv arg, target_ulong off)
4106 tcg_gen_ext32s_tl(arg, arg);
4107 tcg_gen_st_tl(arg, cpu_env, off);
4110 static void gen_mfc0(DisasContext *ctx, TCGv arg, int reg, int sel)
4112 const char *rn = "invalid";
4115 check_insn(ctx, ISA_MIPS32);
4121 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Index));
4125 check_insn(ctx, ASE_MT);
4126 gen_helper_mfc0_mvpcontrol(arg, cpu_env);
4130 check_insn(ctx, ASE_MT);
4131 gen_helper_mfc0_mvpconf0(arg, cpu_env);
4135 check_insn(ctx, ASE_MT);
4136 gen_helper_mfc0_mvpconf1(arg, cpu_env);
4146 gen_helper_mfc0_random(arg, cpu_env);
4150 check_insn(ctx, ASE_MT);
4151 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEControl));
4155 check_insn(ctx, ASE_MT);
4156 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEConf0));
4160 check_insn(ctx, ASE_MT);
4161 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEConf1));
4165 check_insn(ctx, ASE_MT);
4166 gen_mfc0_load64(arg, offsetof(CPUMIPSState, CP0_YQMask));
4170 check_insn(ctx, ASE_MT);
4171 gen_mfc0_load64(arg, offsetof(CPUMIPSState, CP0_VPESchedule));
4175 check_insn(ctx, ASE_MT);
4176 gen_mfc0_load64(arg, offsetof(CPUMIPSState, CP0_VPEScheFBack));
4177 rn = "VPEScheFBack";
4180 check_insn(ctx, ASE_MT);
4181 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEOpt));
4191 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EntryLo0));
4192 tcg_gen_ext32s_tl(arg, arg);
4196 check_insn(ctx, ASE_MT);
4197 gen_helper_mfc0_tcstatus(arg, cpu_env);
4201 check_insn(ctx, ASE_MT);
4202 gen_helper_mfc0_tcbind(arg, cpu_env);
4206 check_insn(ctx, ASE_MT);
4207 gen_helper_mfc0_tcrestart(arg, cpu_env);
4211 check_insn(ctx, ASE_MT);
4212 gen_helper_mfc0_tchalt(arg, cpu_env);
4216 check_insn(ctx, ASE_MT);
4217 gen_helper_mfc0_tccontext(arg, cpu_env);
4221 check_insn(ctx, ASE_MT);
4222 gen_helper_mfc0_tcschedule(arg, cpu_env);
4226 check_insn(ctx, ASE_MT);
4227 gen_helper_mfc0_tcschefback(arg, cpu_env);
4237 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EntryLo1));
4238 tcg_gen_ext32s_tl(arg, arg);
4248 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_Context));
4249 tcg_gen_ext32s_tl(arg, arg);
4253 // gen_helper_mfc0_contextconfig(arg); /* SmartMIPS ASE */
4254 rn = "ContextConfig";
4263 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PageMask));
4267 check_insn(ctx, ISA_MIPS32R2);
4268 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PageGrain));
4278 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Wired));
4282 check_insn(ctx, ISA_MIPS32R2);
4283 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf0));
4287 check_insn(ctx, ISA_MIPS32R2);
4288 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf1));
4292 check_insn(ctx, ISA_MIPS32R2);
4293 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf2));
4297 check_insn(ctx, ISA_MIPS32R2);
4298 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf3));
4302 check_insn(ctx, ISA_MIPS32R2);
4303 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf4));
4313 check_insn(ctx, ISA_MIPS32R2);
4314 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_HWREna));
4324 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_BadVAddr));
4325 tcg_gen_ext32s_tl(arg, arg);
4335 /* Mark as an IO operation because we read the time. */
4338 gen_helper_mfc0_count(arg, cpu_env);
4342 /* Break the TB to be able to take timer interrupts immediately
4343 after reading count. */
4344 ctx->bstate = BS_STOP;
4347 /* 6,7 are implementation dependent */
4355 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EntryHi));
4356 tcg_gen_ext32s_tl(arg, arg);
4366 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Compare));
4369 /* 6,7 are implementation dependent */
4377 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Status));
4381 check_insn(ctx, ISA_MIPS32R2);
4382 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_IntCtl));
4386 check_insn(ctx, ISA_MIPS32R2);
4387 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSCtl));
4391 check_insn(ctx, ISA_MIPS32R2);
4392 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSMap));
4402 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Cause));
4412 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EPC));
4413 tcg_gen_ext32s_tl(arg, arg);
4423 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PRid));
4427 check_insn(ctx, ISA_MIPS32R2);
4428 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_EBase));
4438 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config0));
4442 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config1));
4446 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config2));
4450 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config3));
4453 /* 4,5 are reserved */
4454 /* 6,7 are implementation dependent */
4456 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config6));
4460 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config7));
4470 gen_helper_mfc0_lladdr(arg, cpu_env);
4480 gen_helper_1e0i(mfc0_watchlo, arg, sel);
4490 gen_helper_1e0i(mfc0_watchhi, arg, sel);
4500 #if defined(TARGET_MIPS64)
4501 check_insn(ctx, ISA_MIPS3);
4502 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_XContext));
4503 tcg_gen_ext32s_tl(arg, arg);
4512 /* Officially reserved, but sel 0 is used for R1x000 framemask */
4515 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Framemask));
4523 tcg_gen_movi_tl(arg, 0); /* unimplemented */
4524 rn = "'Diagnostic"; /* implementation dependent */
4529 gen_helper_mfc0_debug(arg, cpu_env); /* EJTAG support */
4533 // gen_helper_mfc0_tracecontrol(arg); /* PDtrace support */
4534 rn = "TraceControl";
4537 // gen_helper_mfc0_tracecontrol2(arg); /* PDtrace support */
4538 rn = "TraceControl2";
4541 // gen_helper_mfc0_usertracedata(arg); /* PDtrace support */
4542 rn = "UserTraceData";
4545 // gen_helper_mfc0_tracebpc(arg); /* PDtrace support */
4556 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_DEPC));
4557 tcg_gen_ext32s_tl(arg, arg);
4567 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Performance0));
4568 rn = "Performance0";
4571 // gen_helper_mfc0_performance1(arg);
4572 rn = "Performance1";
4575 // gen_helper_mfc0_performance2(arg);
4576 rn = "Performance2";
4579 // gen_helper_mfc0_performance3(arg);
4580 rn = "Performance3";
4583 // gen_helper_mfc0_performance4(arg);
4584 rn = "Performance4";
4587 // gen_helper_mfc0_performance5(arg);
4588 rn = "Performance5";
4591 // gen_helper_mfc0_performance6(arg);
4592 rn = "Performance6";
4595 // gen_helper_mfc0_performance7(arg);
4596 rn = "Performance7";
4603 tcg_gen_movi_tl(arg, 0); /* unimplemented */
4609 tcg_gen_movi_tl(arg, 0); /* unimplemented */
4622 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_TagLo));
4629 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DataLo));
4642 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_TagHi));
4649 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DataHi));
4659 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_ErrorEPC));
4660 tcg_gen_ext32s_tl(arg, arg);
4671 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DESAVE));
4681 (void)rn; /* avoid a compiler warning */
4682 LOG_DISAS("mfc0 %s (reg %d sel %d)\n", rn, reg, sel);
4686 LOG_DISAS("mfc0 %s (reg %d sel %d)\n", rn, reg, sel);
4687 generate_exception(ctx, EXCP_RI);
4690 static void gen_mtc0(DisasContext *ctx, TCGv arg, int reg, int sel)
4692 const char *rn = "invalid";
4695 check_insn(ctx, ISA_MIPS32);
4704 gen_helper_mtc0_index(cpu_env, arg);
4708 check_insn(ctx, ASE_MT);
4709 gen_helper_mtc0_mvpcontrol(cpu_env, arg);
4713 check_insn(ctx, ASE_MT);
4718 check_insn(ctx, ASE_MT);
4733 check_insn(ctx, ASE_MT);
4734 gen_helper_mtc0_vpecontrol(cpu_env, arg);
4738 check_insn(ctx, ASE_MT);
4739 gen_helper_mtc0_vpeconf0(cpu_env, arg);
4743 check_insn(ctx, ASE_MT);
4744 gen_helper_mtc0_vpeconf1(cpu_env, arg);
4748 check_insn(ctx, ASE_MT);
4749 gen_helper_mtc0_yqmask(cpu_env, arg);
4753 check_insn(ctx, ASE_MT);
4754 gen_mtc0_store64(arg, offsetof(CPUMIPSState, CP0_VPESchedule));
4758 check_insn(ctx, ASE_MT);
4759 gen_mtc0_store64(arg, offsetof(CPUMIPSState, CP0_VPEScheFBack));
4760 rn = "VPEScheFBack";
4763 check_insn(ctx, ASE_MT);
4764 gen_helper_mtc0_vpeopt(cpu_env, arg);
4774 gen_helper_mtc0_entrylo0(cpu_env, arg);
4778 check_insn(ctx, ASE_MT);
4779 gen_helper_mtc0_tcstatus(cpu_env, arg);
4783 check_insn(ctx, ASE_MT);
4784 gen_helper_mtc0_tcbind(cpu_env, arg);
4788 check_insn(ctx, ASE_MT);
4789 gen_helper_mtc0_tcrestart(cpu_env, arg);
4793 check_insn(ctx, ASE_MT);
4794 gen_helper_mtc0_tchalt(cpu_env, arg);
4798 check_insn(ctx, ASE_MT);
4799 gen_helper_mtc0_tccontext(cpu_env, arg);
4803 check_insn(ctx, ASE_MT);
4804 gen_helper_mtc0_tcschedule(cpu_env, arg);
4808 check_insn(ctx, ASE_MT);
4809 gen_helper_mtc0_tcschefback(cpu_env, arg);
4819 gen_helper_mtc0_entrylo1(cpu_env, arg);
4829 gen_helper_mtc0_context(cpu_env, arg);
4833 // gen_helper_mtc0_contextconfig(cpu_env, arg); /* SmartMIPS ASE */
4834 rn = "ContextConfig";
4843 gen_helper_mtc0_pagemask(cpu_env, arg);
4847 check_insn(ctx, ISA_MIPS32R2);
4848 gen_helper_mtc0_pagegrain(cpu_env, arg);
4858 gen_helper_mtc0_wired(cpu_env, arg);
4862 check_insn(ctx, ISA_MIPS32R2);
4863 gen_helper_mtc0_srsconf0(cpu_env, arg);
4867 check_insn(ctx, ISA_MIPS32R2);
4868 gen_helper_mtc0_srsconf1(cpu_env, arg);
4872 check_insn(ctx, ISA_MIPS32R2);
4873 gen_helper_mtc0_srsconf2(cpu_env, arg);
4877 check_insn(ctx, ISA_MIPS32R2);
4878 gen_helper_mtc0_srsconf3(cpu_env, arg);
4882 check_insn(ctx, ISA_MIPS32R2);
4883 gen_helper_mtc0_srsconf4(cpu_env, arg);
4893 check_insn(ctx, ISA_MIPS32R2);
4894 gen_helper_mtc0_hwrena(cpu_env, arg);
4908 gen_helper_mtc0_count(cpu_env, arg);
4911 /* 6,7 are implementation dependent */
4919 gen_helper_mtc0_entryhi(cpu_env, arg);
4929 gen_helper_mtc0_compare(cpu_env, arg);
4932 /* 6,7 are implementation dependent */
4940 save_cpu_state(ctx, 1);
4941 gen_helper_mtc0_status(cpu_env, arg);
4942 /* BS_STOP isn't good enough here, hflags may have changed. */
4943 gen_save_pc(ctx->pc + 4);
4944 ctx->bstate = BS_EXCP;
4948 check_insn(ctx, ISA_MIPS32R2);
4949 gen_helper_mtc0_intctl(cpu_env, arg);
4950 /* Stop translation as we may have switched the execution mode */
4951 ctx->bstate = BS_STOP;
4955 check_insn(ctx, ISA_MIPS32R2);
4956 gen_helper_mtc0_srsctl(cpu_env, arg);
4957 /* Stop translation as we may have switched the execution mode */
4958 ctx->bstate = BS_STOP;
4962 check_insn(ctx, ISA_MIPS32R2);
4963 gen_mtc0_store32(arg, offsetof(CPUMIPSState, CP0_SRSMap));
4964 /* Stop translation as we may have switched the execution mode */
4965 ctx->bstate = BS_STOP;
4975 save_cpu_state(ctx, 1);
4976 gen_helper_mtc0_cause(cpu_env, arg);
4986 gen_mtc0_store64(arg, offsetof(CPUMIPSState, CP0_EPC));
5000 check_insn(ctx, ISA_MIPS32R2);
5001 gen_helper_mtc0_ebase(cpu_env, arg);
5011 gen_helper_mtc0_config0(cpu_env, arg);
5013 /* Stop translation as we may have switched the execution mode */
5014 ctx->bstate = BS_STOP;
5017 /* ignored, read only */
5021 gen_helper_mtc0_config2(cpu_env, arg);
5023 /* Stop translation as we may have switched the execution mode */
5024 ctx->bstate = BS_STOP;
5027 /* ignored, read only */
5030 /* 4,5 are reserved */
5031 /* 6,7 are implementation dependent */
5041 rn = "Invalid config selector";
5048 gen_helper_mtc0_lladdr(cpu_env, arg);
5058 gen_helper_0e1i(mtc0_watchlo, arg, sel);
5068 gen_helper_0e1i(mtc0_watchhi, arg, sel);
5078 #if defined(TARGET_MIPS64)
5079 check_insn(ctx, ISA_MIPS3);
5080 gen_helper_mtc0_xcontext(cpu_env, arg);
5089 /* Officially reserved, but sel 0 is used for R1x000 framemask */
5092 gen_helper_mtc0_framemask(cpu_env, arg);
5101 rn = "Diagnostic"; /* implementation dependent */
5106 gen_helper_mtc0_debug(cpu_env, arg); /* EJTAG support */
5107 /* BS_STOP isn't good enough here, hflags may have changed. */
5108 gen_save_pc(ctx->pc + 4);
5109 ctx->bstate = BS_EXCP;
5113 // gen_helper_mtc0_tracecontrol(cpu_env, arg); /* PDtrace support */
5114 rn = "TraceControl";
5115 /* Stop translation as we may have switched the execution mode */
5116 ctx->bstate = BS_STOP;
5119 // gen_helper_mtc0_tracecontrol2(cpu_env, arg); /* PDtrace support */
5120 rn = "TraceControl2";
5121 /* Stop translation as we may have switched the execution mode */
5122 ctx->bstate = BS_STOP;
5125 /* Stop translation as we may have switched the execution mode */
5126 ctx->bstate = BS_STOP;
5127 // gen_helper_mtc0_usertracedata(cpu_env, arg); /* PDtrace support */
5128 rn = "UserTraceData";
5129 /* Stop translation as we may have switched the execution mode */
5130 ctx->bstate = BS_STOP;
5133 // gen_helper_mtc0_tracebpc(cpu_env, arg); /* PDtrace support */
5134 /* Stop translation as we may have switched the execution mode */
5135 ctx->bstate = BS_STOP;
5146 gen_mtc0_store64(arg, offsetof(CPUMIPSState, CP0_DEPC));
5156 gen_helper_mtc0_performance0(cpu_env, arg);
5157 rn = "Performance0";
5160 // gen_helper_mtc0_performance1(arg);
5161 rn = "Performance1";
5164 // gen_helper_mtc0_performance2(arg);
5165 rn = "Performance2";
5168 // gen_helper_mtc0_performance3(arg);
5169 rn = "Performance3";
5172 // gen_helper_mtc0_performance4(arg);
5173 rn = "Performance4";
5176 // gen_helper_mtc0_performance5(arg);
5177 rn = "Performance5";
5180 // gen_helper_mtc0_performance6(arg);
5181 rn = "Performance6";
5184 // gen_helper_mtc0_performance7(arg);
5185 rn = "Performance7";
5211 gen_helper_mtc0_taglo(cpu_env, arg);
5218 gen_helper_mtc0_datalo(cpu_env, arg);
5231 gen_helper_mtc0_taghi(cpu_env, arg);
5238 gen_helper_mtc0_datahi(cpu_env, arg);
5249 gen_mtc0_store64(arg, offsetof(CPUMIPSState, CP0_ErrorEPC));
5260 gen_mtc0_store32(arg, offsetof(CPUMIPSState, CP0_DESAVE));
5266 /* Stop translation as we may have switched the execution mode */
5267 ctx->bstate = BS_STOP;
5272 (void)rn; /* avoid a compiler warning */
5273 LOG_DISAS("mtc0 %s (reg %d sel %d)\n", rn, reg, sel);
5274 /* For simplicity assume that all writes can cause interrupts. */
5277 ctx->bstate = BS_STOP;
5282 LOG_DISAS("mtc0 %s (reg %d sel %d)\n", rn, reg, sel);
5283 generate_exception(ctx, EXCP_RI);
5286 #if defined(TARGET_MIPS64)
5287 static void gen_dmfc0(DisasContext *ctx, TCGv arg, int reg, int sel)
5289 const char *rn = "invalid";
5292 check_insn(ctx, ISA_MIPS64);
5298 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Index));
5302 check_insn(ctx, ASE_MT);
5303 gen_helper_mfc0_mvpcontrol(arg, cpu_env);
5307 check_insn(ctx, ASE_MT);
5308 gen_helper_mfc0_mvpconf0(arg, cpu_env);
5312 check_insn(ctx, ASE_MT);
5313 gen_helper_mfc0_mvpconf1(arg, cpu_env);
5323 gen_helper_mfc0_random(arg, cpu_env);
5327 check_insn(ctx, ASE_MT);
5328 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEControl));
5332 check_insn(ctx, ASE_MT);
5333 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEConf0));
5337 check_insn(ctx, ASE_MT);
5338 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEConf1));
5342 check_insn(ctx, ASE_MT);
5343 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_YQMask));
5347 check_insn(ctx, ASE_MT);
5348 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_VPESchedule));
5352 check_insn(ctx, ASE_MT);
5353 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_VPEScheFBack));
5354 rn = "VPEScheFBack";
5357 check_insn(ctx, ASE_MT);
5358 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEOpt));
5368 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EntryLo0));
5372 check_insn(ctx, ASE_MT);
5373 gen_helper_mfc0_tcstatus(arg, cpu_env);
5377 check_insn(ctx, ASE_MT);
5378 gen_helper_mfc0_tcbind(arg, cpu_env);
5382 check_insn(ctx, ASE_MT);
5383 gen_helper_dmfc0_tcrestart(arg, cpu_env);
5387 check_insn(ctx, ASE_MT);
5388 gen_helper_dmfc0_tchalt(arg, cpu_env);
5392 check_insn(ctx, ASE_MT);
5393 gen_helper_dmfc0_tccontext(arg, cpu_env);
5397 check_insn(ctx, ASE_MT);
5398 gen_helper_dmfc0_tcschedule(arg, cpu_env);
5402 check_insn(ctx, ASE_MT);
5403 gen_helper_dmfc0_tcschefback(arg, cpu_env);
5413 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EntryLo1));
5423 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_Context));
5427 // gen_helper_dmfc0_contextconfig(arg); /* SmartMIPS ASE */
5428 rn = "ContextConfig";
5437 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PageMask));
5441 check_insn(ctx, ISA_MIPS32R2);
5442 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PageGrain));
5452 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Wired));
5456 check_insn(ctx, ISA_MIPS32R2);
5457 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf0));
5461 check_insn(ctx, ISA_MIPS32R2);
5462 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf1));
5466 check_insn(ctx, ISA_MIPS32R2);
5467 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf2));
5471 check_insn(ctx, ISA_MIPS32R2);
5472 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf3));
5476 check_insn(ctx, ISA_MIPS32R2);
5477 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf4));
5487 check_insn(ctx, ISA_MIPS32R2);
5488 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_HWREna));
5498 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_BadVAddr));
5508 /* Mark as an IO operation because we read the time. */
5511 gen_helper_mfc0_count(arg, cpu_env);
5515 /* Break the TB to be able to take timer interrupts immediately
5516 after reading count. */
5517 ctx->bstate = BS_STOP;
5520 /* 6,7 are implementation dependent */
5528 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EntryHi));
5538 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Compare));
5541 /* 6,7 are implementation dependent */
5549 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Status));
5553 check_insn(ctx, ISA_MIPS32R2);
5554 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_IntCtl));
5558 check_insn(ctx, ISA_MIPS32R2);
5559 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSCtl));
5563 check_insn(ctx, ISA_MIPS32R2);
5564 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSMap));
5574 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Cause));
5584 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EPC));
5594 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PRid));
5598 check_insn(ctx, ISA_MIPS32R2);
5599 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_EBase));
5609 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config0));
5613 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config1));
5617 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config2));
5621 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config3));
5624 /* 6,7 are implementation dependent */
5626 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config6));
5630 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config7));
5640 gen_helper_dmfc0_lladdr(arg, cpu_env);
5650 gen_helper_1e0i(dmfc0_watchlo, arg, sel);
5660 gen_helper_1e0i(mfc0_watchhi, arg, sel);
5670 check_insn(ctx, ISA_MIPS3);
5671 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_XContext));
5679 /* Officially reserved, but sel 0 is used for R1x000 framemask */
5682 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Framemask));
5690 tcg_gen_movi_tl(arg, 0); /* unimplemented */
5691 rn = "'Diagnostic"; /* implementation dependent */
5696 gen_helper_mfc0_debug(arg, cpu_env); /* EJTAG support */
5700 // gen_helper_dmfc0_tracecontrol(arg, cpu_env); /* PDtrace support */
5701 rn = "TraceControl";
5704 // gen_helper_dmfc0_tracecontrol2(arg, cpu_env); /* PDtrace support */
5705 rn = "TraceControl2";
5708 // gen_helper_dmfc0_usertracedata(arg, cpu_env); /* PDtrace support */
5709 rn = "UserTraceData";
5712 // gen_helper_dmfc0_tracebpc(arg, cpu_env); /* PDtrace support */
5723 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_DEPC));
5733 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Performance0));
5734 rn = "Performance0";
5737 // gen_helper_dmfc0_performance1(arg);
5738 rn = "Performance1";
5741 // gen_helper_dmfc0_performance2(arg);
5742 rn = "Performance2";
5745 // gen_helper_dmfc0_performance3(arg);
5746 rn = "Performance3";
5749 // gen_helper_dmfc0_performance4(arg);
5750 rn = "Performance4";
5753 // gen_helper_dmfc0_performance5(arg);
5754 rn = "Performance5";
5757 // gen_helper_dmfc0_performance6(arg);
5758 rn = "Performance6";
5761 // gen_helper_dmfc0_performance7(arg);
5762 rn = "Performance7";
5769 tcg_gen_movi_tl(arg, 0); /* unimplemented */
5776 tcg_gen_movi_tl(arg, 0); /* unimplemented */
5789 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_TagLo));
5796 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DataLo));
5809 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_TagHi));
5816 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DataHi));
5826 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_ErrorEPC));
5837 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DESAVE));
5847 (void)rn; /* avoid a compiler warning */
5848 LOG_DISAS("dmfc0 %s (reg %d sel %d)\n", rn, reg, sel);
5852 LOG_DISAS("dmfc0 %s (reg %d sel %d)\n", rn, reg, sel);
5853 generate_exception(ctx, EXCP_RI);
5856 static void gen_dmtc0(DisasContext *ctx, TCGv arg, int reg, int sel)
5858 const char *rn = "invalid";
5861 check_insn(ctx, ISA_MIPS64);
5870 gen_helper_mtc0_index(cpu_env, arg);
5874 check_insn(ctx, ASE_MT);
5875 gen_helper_mtc0_mvpcontrol(cpu_env, arg);
5879 check_insn(ctx, ASE_MT);
5884 check_insn(ctx, ASE_MT);
5899 check_insn(ctx, ASE_MT);
5900 gen_helper_mtc0_vpecontrol(cpu_env, arg);
5904 check_insn(ctx, ASE_MT);
5905 gen_helper_mtc0_vpeconf0(cpu_env, arg);
5909 check_insn(ctx, ASE_MT);
5910 gen_helper_mtc0_vpeconf1(cpu_env, arg);
5914 check_insn(ctx, ASE_MT);
5915 gen_helper_mtc0_yqmask(cpu_env, arg);
5919 check_insn(ctx, ASE_MT);
5920 tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_VPESchedule));
5924 check_insn(ctx, ASE_MT);
5925 tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_VPEScheFBack));
5926 rn = "VPEScheFBack";
5929 check_insn(ctx, ASE_MT);
5930 gen_helper_mtc0_vpeopt(cpu_env, arg);
5940 gen_helper_mtc0_entrylo0(cpu_env, arg);
5944 check_insn(ctx, ASE_MT);
5945 gen_helper_mtc0_tcstatus(cpu_env, arg);
5949 check_insn(ctx, ASE_MT);
5950 gen_helper_mtc0_tcbind(cpu_env, arg);
5954 check_insn(ctx, ASE_MT);
5955 gen_helper_mtc0_tcrestart(cpu_env, arg);
5959 check_insn(ctx, ASE_MT);
5960 gen_helper_mtc0_tchalt(cpu_env, arg);
5964 check_insn(ctx, ASE_MT);
5965 gen_helper_mtc0_tccontext(cpu_env, arg);
5969 check_insn(ctx, ASE_MT);
5970 gen_helper_mtc0_tcschedule(cpu_env, arg);
5974 check_insn(ctx, ASE_MT);
5975 gen_helper_mtc0_tcschefback(cpu_env, arg);
5985 gen_helper_mtc0_entrylo1(cpu_env, arg);
5995 gen_helper_mtc0_context(cpu_env, arg);
5999 // gen_helper_mtc0_contextconfig(cpu_env, arg); /* SmartMIPS ASE */
6000 rn = "ContextConfig";
6009 gen_helper_mtc0_pagemask(cpu_env, arg);
6013 check_insn(ctx, ISA_MIPS32R2);
6014 gen_helper_mtc0_pagegrain(cpu_env, arg);
6024 gen_helper_mtc0_wired(cpu_env, arg);
6028 check_insn(ctx, ISA_MIPS32R2);
6029 gen_helper_mtc0_srsconf0(cpu_env, arg);
6033 check_insn(ctx, ISA_MIPS32R2);
6034 gen_helper_mtc0_srsconf1(cpu_env, arg);
6038 check_insn(ctx, ISA_MIPS32R2);
6039 gen_helper_mtc0_srsconf2(cpu_env, arg);
6043 check_insn(ctx, ISA_MIPS32R2);
6044 gen_helper_mtc0_srsconf3(cpu_env, arg);
6048 check_insn(ctx, ISA_MIPS32R2);
6049 gen_helper_mtc0_srsconf4(cpu_env, arg);
6059 check_insn(ctx, ISA_MIPS32R2);
6060 gen_helper_mtc0_hwrena(cpu_env, arg);
6074 gen_helper_mtc0_count(cpu_env, arg);
6077 /* 6,7 are implementation dependent */
6081 /* Stop translation as we may have switched the execution mode */
6082 ctx->bstate = BS_STOP;
6087 gen_helper_mtc0_entryhi(cpu_env, arg);
6097 gen_helper_mtc0_compare(cpu_env, arg);
6100 /* 6,7 are implementation dependent */
6104 /* Stop translation as we may have switched the execution mode */
6105 ctx->bstate = BS_STOP;
6110 save_cpu_state(ctx, 1);
6111 gen_helper_mtc0_status(cpu_env, arg);
6112 /* BS_STOP isn't good enough here, hflags may have changed. */
6113 gen_save_pc(ctx->pc + 4);
6114 ctx->bstate = BS_EXCP;
6118 check_insn(ctx, ISA_MIPS32R2);
6119 gen_helper_mtc0_intctl(cpu_env, arg);
6120 /* Stop translation as we may have switched the execution mode */
6121 ctx->bstate = BS_STOP;
6125 check_insn(ctx, ISA_MIPS32R2);
6126 gen_helper_mtc0_srsctl(cpu_env, arg);
6127 /* Stop translation as we may have switched the execution mode */
6128 ctx->bstate = BS_STOP;
6132 check_insn(ctx, ISA_MIPS32R2);
6133 gen_mtc0_store32(arg, offsetof(CPUMIPSState, CP0_SRSMap));
6134 /* Stop translation as we may have switched the execution mode */
6135 ctx->bstate = BS_STOP;
6145 save_cpu_state(ctx, 1);
6146 /* Mark as an IO operation because we may trigger a software
6151 gen_helper_mtc0_cause(cpu_env, arg);
6155 /* Stop translation as we may have triggered an intetrupt */
6156 ctx->bstate = BS_STOP;
6166 tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EPC));
6180 check_insn(ctx, ISA_MIPS32R2);
6181 gen_helper_mtc0_ebase(cpu_env, arg);
6191 gen_helper_mtc0_config0(cpu_env, arg);
6193 /* Stop translation as we may have switched the execution mode */
6194 ctx->bstate = BS_STOP;
6197 /* ignored, read only */
6201 gen_helper_mtc0_config2(cpu_env, arg);
6203 /* Stop translation as we may have switched the execution mode */
6204 ctx->bstate = BS_STOP;
6210 /* 6,7 are implementation dependent */
6212 rn = "Invalid config selector";
6219 gen_helper_mtc0_lladdr(cpu_env, arg);
6229 gen_helper_0e1i(mtc0_watchlo, arg, sel);
6239 gen_helper_0e1i(mtc0_watchhi, arg, sel);
6249 check_insn(ctx, ISA_MIPS3);
6250 gen_helper_mtc0_xcontext(cpu_env, arg);
6258 /* Officially reserved, but sel 0 is used for R1x000 framemask */
6261 gen_helper_mtc0_framemask(cpu_env, arg);
6270 rn = "Diagnostic"; /* implementation dependent */
6275 gen_helper_mtc0_debug(cpu_env, arg); /* EJTAG support */
6276 /* BS_STOP isn't good enough here, hflags may have changed. */
6277 gen_save_pc(ctx->pc + 4);
6278 ctx->bstate = BS_EXCP;
6282 // gen_helper_mtc0_tracecontrol(cpu_env, arg); /* PDtrace support */
6283 /* Stop translation as we may have switched the execution mode */
6284 ctx->bstate = BS_STOP;
6285 rn = "TraceControl";
6288 // gen_helper_mtc0_tracecontrol2(cpu_env, arg); /* PDtrace support */
6289 /* Stop translation as we may have switched the execution mode */
6290 ctx->bstate = BS_STOP;
6291 rn = "TraceControl2";
6294 // gen_helper_mtc0_usertracedata(cpu_env, arg); /* PDtrace support */
6295 /* Stop translation as we may have switched the execution mode */
6296 ctx->bstate = BS_STOP;
6297 rn = "UserTraceData";
6300 // gen_helper_mtc0_tracebpc(cpu_env, arg); /* PDtrace support */
6301 /* Stop translation as we may have switched the execution mode */
6302 ctx->bstate = BS_STOP;
6313 tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_DEPC));
6323 gen_helper_mtc0_performance0(cpu_env, arg);
6324 rn = "Performance0";
6327 // gen_helper_mtc0_performance1(cpu_env, arg);
6328 rn = "Performance1";
6331 // gen_helper_mtc0_performance2(cpu_env, arg);
6332 rn = "Performance2";
6335 // gen_helper_mtc0_performance3(cpu_env, arg);
6336 rn = "Performance3";
6339 // gen_helper_mtc0_performance4(cpu_env, arg);
6340 rn = "Performance4";
6343 // gen_helper_mtc0_performance5(cpu_env, arg);
6344 rn = "Performance5";
6347 // gen_helper_mtc0_performance6(cpu_env, arg);
6348 rn = "Performance6";
6351 // gen_helper_mtc0_performance7(cpu_env, arg);
6352 rn = "Performance7";
6378 gen_helper_mtc0_taglo(cpu_env, arg);
6385 gen_helper_mtc0_datalo(cpu_env, arg);
6398 gen_helper_mtc0_taghi(cpu_env, arg);
6405 gen_helper_mtc0_datahi(cpu_env, arg);
6416 tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_ErrorEPC));
6427 gen_mtc0_store32(arg, offsetof(CPUMIPSState, CP0_DESAVE));
6433 /* Stop translation as we may have switched the execution mode */
6434 ctx->bstate = BS_STOP;
6439 (void)rn; /* avoid a compiler warning */
6440 LOG_DISAS("dmtc0 %s (reg %d sel %d)\n", rn, reg, sel);
6441 /* For simplicity assume that all writes can cause interrupts. */
6444 ctx->bstate = BS_STOP;
6449 LOG_DISAS("dmtc0 %s (reg %d sel %d)\n", rn, reg, sel);
6450 generate_exception(ctx, EXCP_RI);
6452 #endif /* TARGET_MIPS64 */
6454 static void gen_mftr(CPUMIPSState *env, DisasContext *ctx, int rt, int rd,
6455 int u, int sel, int h)
6457 int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
6458 TCGv t0 = tcg_temp_local_new();
6460 if ((env->CP0_VPEConf0 & (1 << CP0VPEC0_MVP)) == 0 &&
6461 ((env->tcs[other_tc].CP0_TCBind & (0xf << CP0TCBd_CurVPE)) !=
6462 (env->active_tc.CP0_TCBind & (0xf << CP0TCBd_CurVPE))))
6463 tcg_gen_movi_tl(t0, -1);
6464 else if ((env->CP0_VPEControl & (0xff << CP0VPECo_TargTC)) >
6465 (env->mvp->CP0_MVPConf0 & (0xff << CP0MVPC0_PTC)))
6466 tcg_gen_movi_tl(t0, -1);
6472 gen_helper_mftc0_vpecontrol(t0, cpu_env);
6475 gen_helper_mftc0_vpeconf0(t0, cpu_env);
6485 gen_helper_mftc0_tcstatus(t0, cpu_env);
6488 gen_helper_mftc0_tcbind(t0, cpu_env);
6491 gen_helper_mftc0_tcrestart(t0, cpu_env);
6494 gen_helper_mftc0_tchalt(t0, cpu_env);
6497 gen_helper_mftc0_tccontext(t0, cpu_env);
6500 gen_helper_mftc0_tcschedule(t0, cpu_env);
6503 gen_helper_mftc0_tcschefback(t0, cpu_env);
6506 gen_mfc0(ctx, t0, rt, sel);
6513 gen_helper_mftc0_entryhi(t0, cpu_env);
6516 gen_mfc0(ctx, t0, rt, sel);
6522 gen_helper_mftc0_status(t0, cpu_env);
6525 gen_mfc0(ctx, t0, rt, sel);
6531 gen_helper_mftc0_cause(t0, cpu_env);
6541 gen_helper_mftc0_epc(t0, cpu_env);
6551 gen_helper_mftc0_ebase(t0, cpu_env);
6561 gen_helper_mftc0_configx(t0, cpu_env, tcg_const_tl(sel));
6571 gen_helper_mftc0_debug(t0, cpu_env);
6574 gen_mfc0(ctx, t0, rt, sel);
6579 gen_mfc0(ctx, t0, rt, sel);
6581 } else switch (sel) {
6582 /* GPR registers. */
6584 gen_helper_1e0i(mftgpr, t0, rt);
6586 /* Auxiliary CPU registers */
6590 gen_helper_1e0i(mftlo, t0, 0);
6593 gen_helper_1e0i(mfthi, t0, 0);
6596 gen_helper_1e0i(mftacx, t0, 0);
6599 gen_helper_1e0i(mftlo, t0, 1);
6602 gen_helper_1e0i(mfthi, t0, 1);
6605 gen_helper_1e0i(mftacx, t0, 1);
6608 gen_helper_1e0i(mftlo, t0, 2);
6611 gen_helper_1e0i(mfthi, t0, 2);
6614 gen_helper_1e0i(mftacx, t0, 2);
6617 gen_helper_1e0i(mftlo, t0, 3);
6620 gen_helper_1e0i(mfthi, t0, 3);
6623 gen_helper_1e0i(mftacx, t0, 3);
6626 gen_helper_mftdsp(t0, cpu_env);
6632 /* Floating point (COP1). */
6634 /* XXX: For now we support only a single FPU context. */
6636 TCGv_i32 fp0 = tcg_temp_new_i32();
6638 gen_load_fpr32(fp0, rt);
6639 tcg_gen_ext_i32_tl(t0, fp0);
6640 tcg_temp_free_i32(fp0);
6642 TCGv_i32 fp0 = tcg_temp_new_i32();
6644 gen_load_fpr32h(fp0, rt);
6645 tcg_gen_ext_i32_tl(t0, fp0);
6646 tcg_temp_free_i32(fp0);
6650 /* XXX: For now we support only a single FPU context. */
6651 gen_helper_1e0i(cfc1, t0, rt);
6653 /* COP2: Not implemented. */
6660 LOG_DISAS("mftr (reg %d u %d sel %d h %d)\n", rt, u, sel, h);
6661 gen_store_gpr(t0, rd);
6667 LOG_DISAS("mftr (reg %d u %d sel %d h %d)\n", rt, u, sel, h);
6668 generate_exception(ctx, EXCP_RI);
6671 static void gen_mttr(CPUMIPSState *env, DisasContext *ctx, int rd, int rt,
6672 int u, int sel, int h)
6674 int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
6675 TCGv t0 = tcg_temp_local_new();
6677 gen_load_gpr(t0, rt);
6678 if ((env->CP0_VPEConf0 & (1 << CP0VPEC0_MVP)) == 0 &&
6679 ((env->tcs[other_tc].CP0_TCBind & (0xf << CP0TCBd_CurVPE)) !=
6680 (env->active_tc.CP0_TCBind & (0xf << CP0TCBd_CurVPE))))
6682 else if ((env->CP0_VPEControl & (0xff << CP0VPECo_TargTC)) >
6683 (env->mvp->CP0_MVPConf0 & (0xff << CP0MVPC0_PTC)))
6690 gen_helper_mttc0_vpecontrol(cpu_env, t0);
6693 gen_helper_mttc0_vpeconf0(cpu_env, t0);
6703 gen_helper_mttc0_tcstatus(cpu_env, t0);
6706 gen_helper_mttc0_tcbind(cpu_env, t0);
6709 gen_helper_mttc0_tcrestart(cpu_env, t0);
6712 gen_helper_mttc0_tchalt(cpu_env, t0);
6715 gen_helper_mttc0_tccontext(cpu_env, t0);
6718 gen_helper_mttc0_tcschedule(cpu_env, t0);
6721 gen_helper_mttc0_tcschefback(cpu_env, t0);
6724 gen_mtc0(ctx, t0, rd, sel);
6731 gen_helper_mttc0_entryhi(cpu_env, t0);
6734 gen_mtc0(ctx, t0, rd, sel);
6740 gen_helper_mttc0_status(cpu_env, t0);
6743 gen_mtc0(ctx, t0, rd, sel);
6749 gen_helper_mttc0_cause(cpu_env, t0);
6759 gen_helper_mttc0_ebase(cpu_env, t0);
6769 gen_helper_mttc0_debug(cpu_env, t0);
6772 gen_mtc0(ctx, t0, rd, sel);
6777 gen_mtc0(ctx, t0, rd, sel);
6779 } else switch (sel) {
6780 /* GPR registers. */
6782 gen_helper_0e1i(mttgpr, t0, rd);
6784 /* Auxiliary CPU registers */
6788 gen_helper_0e1i(mttlo, t0, 0);
6791 gen_helper_0e1i(mtthi, t0, 0);
6794 gen_helper_0e1i(mttacx, t0, 0);
6797 gen_helper_0e1i(mttlo, t0, 1);
6800 gen_helper_0e1i(mtthi, t0, 1);
6803 gen_helper_0e1i(mttacx, t0, 1);
6806 gen_helper_0e1i(mttlo, t0, 2);
6809 gen_helper_0e1i(mtthi, t0, 2);
6812 gen_helper_0e1i(mttacx, t0, 2);
6815 gen_helper_0e1i(mttlo, t0, 3);
6818 gen_helper_0e1i(mtthi, t0, 3);
6821 gen_helper_0e1i(mttacx, t0, 3);
6824 gen_helper_mttdsp(cpu_env, t0);
6830 /* Floating point (COP1). */
6832 /* XXX: For now we support only a single FPU context. */
6834 TCGv_i32 fp0 = tcg_temp_new_i32();
6836 tcg_gen_trunc_tl_i32(fp0, t0);
6837 gen_store_fpr32(fp0, rd);
6838 tcg_temp_free_i32(fp0);
6840 TCGv_i32 fp0 = tcg_temp_new_i32();
6842 tcg_gen_trunc_tl_i32(fp0, t0);
6843 gen_store_fpr32h(fp0, rd);
6844 tcg_temp_free_i32(fp0);
6848 /* XXX: For now we support only a single FPU context. */
6849 gen_helper_0e1i(ctc1, t0, rd);
6851 /* COP2: Not implemented. */
6858 LOG_DISAS("mttr (reg %d u %d sel %d h %d)\n", rd, u, sel, h);
6864 LOG_DISAS("mttr (reg %d u %d sel %d h %d)\n", rd, u, sel, h);
6865 generate_exception(ctx, EXCP_RI);
6868 static void gen_cp0 (CPUMIPSState *env, DisasContext *ctx, uint32_t opc, int rt, int rd)
6870 const char *opn = "ldst";
6872 check_cp0_enabled(ctx);
6879 gen_mfc0(ctx, cpu_gpr[rt], rd, ctx->opcode & 0x7);
6884 TCGv t0 = tcg_temp_new();
6886 gen_load_gpr(t0, rt);
6887 gen_mtc0(ctx, t0, rd, ctx->opcode & 0x7);
6892 #if defined(TARGET_MIPS64)
6894 check_insn(ctx, ISA_MIPS3);
6899 gen_dmfc0(ctx, cpu_gpr[rt], rd, ctx->opcode & 0x7);
6903 check_insn(ctx, ISA_MIPS3);
6905 TCGv t0 = tcg_temp_new();
6907 gen_load_gpr(t0, rt);
6908 gen_dmtc0(ctx, t0, rd, ctx->opcode & 0x7);
6915 check_insn(ctx, ASE_MT);
6920 gen_mftr(env, ctx, rt, rd, (ctx->opcode >> 5) & 1,
6921 ctx->opcode & 0x7, (ctx->opcode >> 4) & 1);
6925 check_insn(ctx, ASE_MT);
6926 gen_mttr(env, ctx, rd, rt, (ctx->opcode >> 5) & 1,
6927 ctx->opcode & 0x7, (ctx->opcode >> 4) & 1);
6932 if (!env->tlb->helper_tlbwi)
6934 gen_helper_tlbwi(cpu_env);
6938 if (!env->tlb->helper_tlbwr)
6940 gen_helper_tlbwr(cpu_env);
6944 if (!env->tlb->helper_tlbp)
6946 gen_helper_tlbp(cpu_env);
6950 if (!env->tlb->helper_tlbr)
6952 gen_helper_tlbr(cpu_env);
6956 check_insn(ctx, ISA_MIPS2);
6957 gen_helper_eret(cpu_env);
6958 ctx->bstate = BS_EXCP;
6962 check_insn(ctx, ISA_MIPS32);
6963 if (!(ctx->hflags & MIPS_HFLAG_DM)) {
6965 generate_exception(ctx, EXCP_RI);
6967 gen_helper_deret(cpu_env);
6968 ctx->bstate = BS_EXCP;
6973 check_insn(ctx, ISA_MIPS3 | ISA_MIPS32);
6974 /* If we get an exception, we want to restart at next instruction */
6976 save_cpu_state(ctx, 1);
6978 gen_helper_wait(cpu_env);
6979 ctx->bstate = BS_EXCP;
6984 generate_exception(ctx, EXCP_RI);
6987 (void)opn; /* avoid a compiler warning */
6988 MIPS_DEBUG("%s %s %d", opn, regnames[rt], rd);
6990 #endif /* !CONFIG_USER_ONLY */
6992 /* CP1 Branches (before delay slot) */
6993 static void gen_compute_branch1(DisasContext *ctx, uint32_t op,
6994 int32_t cc, int32_t offset)
6996 target_ulong btarget;
6997 const char *opn = "cp1 cond branch";
6998 TCGv_i32 t0 = tcg_temp_new_i32();
7001 check_insn(ctx, ISA_MIPS4 | ISA_MIPS32);
7003 btarget = ctx->pc + 4 + offset;
7007 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
7008 tcg_gen_not_i32(t0, t0);
7009 tcg_gen_andi_i32(t0, t0, 1);
7010 tcg_gen_extu_i32_tl(bcond, t0);
7014 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
7015 tcg_gen_not_i32(t0, t0);
7016 tcg_gen_andi_i32(t0, t0, 1);
7017 tcg_gen_extu_i32_tl(bcond, t0);
7021 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
7022 tcg_gen_andi_i32(t0, t0, 1);
7023 tcg_gen_extu_i32_tl(bcond, t0);
7027 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
7028 tcg_gen_andi_i32(t0, t0, 1);
7029 tcg_gen_extu_i32_tl(bcond, t0);
7032 ctx->hflags |= MIPS_HFLAG_BL;
7036 TCGv_i32 t1 = tcg_temp_new_i32();
7037 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
7038 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+1));
7039 tcg_gen_nand_i32(t0, t0, t1);
7040 tcg_temp_free_i32(t1);
7041 tcg_gen_andi_i32(t0, t0, 1);
7042 tcg_gen_extu_i32_tl(bcond, t0);
7048 TCGv_i32 t1 = tcg_temp_new_i32();
7049 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
7050 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+1));
7051 tcg_gen_or_i32(t0, t0, t1);
7052 tcg_temp_free_i32(t1);
7053 tcg_gen_andi_i32(t0, t0, 1);
7054 tcg_gen_extu_i32_tl(bcond, t0);
7060 TCGv_i32 t1 = tcg_temp_new_i32();
7061 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
7062 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+1));
7063 tcg_gen_and_i32(t0, t0, t1);
7064 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+2));
7065 tcg_gen_and_i32(t0, t0, t1);
7066 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+3));
7067 tcg_gen_nand_i32(t0, t0, t1);
7068 tcg_temp_free_i32(t1);
7069 tcg_gen_andi_i32(t0, t0, 1);
7070 tcg_gen_extu_i32_tl(bcond, t0);
7076 TCGv_i32 t1 = tcg_temp_new_i32();
7077 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
7078 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+1));
7079 tcg_gen_or_i32(t0, t0, t1);
7080 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+2));
7081 tcg_gen_or_i32(t0, t0, t1);
7082 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+3));
7083 tcg_gen_or_i32(t0, t0, t1);
7084 tcg_temp_free_i32(t1);
7085 tcg_gen_andi_i32(t0, t0, 1);
7086 tcg_gen_extu_i32_tl(bcond, t0);
7090 ctx->hflags |= MIPS_HFLAG_BC;
7094 generate_exception (ctx, EXCP_RI);
7097 (void)opn; /* avoid a compiler warning */
7098 MIPS_DEBUG("%s: cond %02x target " TARGET_FMT_lx, opn,
7099 ctx->hflags, btarget);
7100 ctx->btarget = btarget;
7103 tcg_temp_free_i32(t0);
7106 /* Coprocessor 1 (FPU) */
7108 #define FOP(func, fmt) (((fmt) << 21) | (func))
7111 OPC_ADD_S = FOP(0, FMT_S),
7112 OPC_SUB_S = FOP(1, FMT_S),
7113 OPC_MUL_S = FOP(2, FMT_S),
7114 OPC_DIV_S = FOP(3, FMT_S),
7115 OPC_SQRT_S = FOP(4, FMT_S),
7116 OPC_ABS_S = FOP(5, FMT_S),
7117 OPC_MOV_S = FOP(6, FMT_S),
7118 OPC_NEG_S = FOP(7, FMT_S),
7119 OPC_ROUND_L_S = FOP(8, FMT_S),
7120 OPC_TRUNC_L_S = FOP(9, FMT_S),
7121 OPC_CEIL_L_S = FOP(10, FMT_S),
7122 OPC_FLOOR_L_S = FOP(11, FMT_S),
7123 OPC_ROUND_W_S = FOP(12, FMT_S),
7124 OPC_TRUNC_W_S = FOP(13, FMT_S),
7125 OPC_CEIL_W_S = FOP(14, FMT_S),
7126 OPC_FLOOR_W_S = FOP(15, FMT_S),
7127 OPC_MOVCF_S = FOP(17, FMT_S),
7128 OPC_MOVZ_S = FOP(18, FMT_S),
7129 OPC_MOVN_S = FOP(19, FMT_S),
7130 OPC_RECIP_S = FOP(21, FMT_S),
7131 OPC_RSQRT_S = FOP(22, FMT_S),
7132 OPC_RECIP2_S = FOP(28, FMT_S),
7133 OPC_RECIP1_S = FOP(29, FMT_S),
7134 OPC_RSQRT1_S = FOP(30, FMT_S),
7135 OPC_RSQRT2_S = FOP(31, FMT_S),
7136 OPC_CVT_D_S = FOP(33, FMT_S),
7137 OPC_CVT_W_S = FOP(36, FMT_S),
7138 OPC_CVT_L_S = FOP(37, FMT_S),
7139 OPC_CVT_PS_S = FOP(38, FMT_S),
7140 OPC_CMP_F_S = FOP (48, FMT_S),
7141 OPC_CMP_UN_S = FOP (49, FMT_S),
7142 OPC_CMP_EQ_S = FOP (50, FMT_S),
7143 OPC_CMP_UEQ_S = FOP (51, FMT_S),
7144 OPC_CMP_OLT_S = FOP (52, FMT_S),
7145 OPC_CMP_ULT_S = FOP (53, FMT_S),
7146 OPC_CMP_OLE_S = FOP (54, FMT_S),
7147 OPC_CMP_ULE_S = FOP (55, FMT_S),
7148 OPC_CMP_SF_S = FOP (56, FMT_S),
7149 OPC_CMP_NGLE_S = FOP (57, FMT_S),
7150 OPC_CMP_SEQ_S = FOP (58, FMT_S),
7151 OPC_CMP_NGL_S = FOP (59, FMT_S),
7152 OPC_CMP_LT_S = FOP (60, FMT_S),
7153 OPC_CMP_NGE_S = FOP (61, FMT_S),
7154 OPC_CMP_LE_S = FOP (62, FMT_S),
7155 OPC_CMP_NGT_S = FOP (63, FMT_S),
7157 OPC_ADD_D = FOP(0, FMT_D),
7158 OPC_SUB_D = FOP(1, FMT_D),
7159 OPC_MUL_D = FOP(2, FMT_D),
7160 OPC_DIV_D = FOP(3, FMT_D),
7161 OPC_SQRT_D = FOP(4, FMT_D),
7162 OPC_ABS_D = FOP(5, FMT_D),
7163 OPC_MOV_D = FOP(6, FMT_D),
7164 OPC_NEG_D = FOP(7, FMT_D),
7165 OPC_ROUND_L_D = FOP(8, FMT_D),
7166 OPC_TRUNC_L_D = FOP(9, FMT_D),
7167 OPC_CEIL_L_D = FOP(10, FMT_D),
7168 OPC_FLOOR_L_D = FOP(11, FMT_D),
7169 OPC_ROUND_W_D = FOP(12, FMT_D),
7170 OPC_TRUNC_W_D = FOP(13, FMT_D),
7171 OPC_CEIL_W_D = FOP(14, FMT_D),
7172 OPC_FLOOR_W_D = FOP(15, FMT_D),
7173 OPC_MOVCF_D = FOP(17, FMT_D),
7174 OPC_MOVZ_D = FOP(18, FMT_D),
7175 OPC_MOVN_D = FOP(19, FMT_D),
7176 OPC_RECIP_D = FOP(21, FMT_D),
7177 OPC_RSQRT_D = FOP(22, FMT_D),
7178 OPC_RECIP2_D = FOP(28, FMT_D),
7179 OPC_RECIP1_D = FOP(29, FMT_D),
7180 OPC_RSQRT1_D = FOP(30, FMT_D),
7181 OPC_RSQRT2_D = FOP(31, FMT_D),
7182 OPC_CVT_S_D = FOP(32, FMT_D),
7183 OPC_CVT_W_D = FOP(36, FMT_D),
7184 OPC_CVT_L_D = FOP(37, FMT_D),
7185 OPC_CMP_F_D = FOP (48, FMT_D),
7186 OPC_CMP_UN_D = FOP (49, FMT_D),
7187 OPC_CMP_EQ_D = FOP (50, FMT_D),
7188 OPC_CMP_UEQ_D = FOP (51, FMT_D),
7189 OPC_CMP_OLT_D = FOP (52, FMT_D),
7190 OPC_CMP_ULT_D = FOP (53, FMT_D),
7191 OPC_CMP_OLE_D = FOP (54, FMT_D),
7192 OPC_CMP_ULE_D = FOP (55, FMT_D),
7193 OPC_CMP_SF_D = FOP (56, FMT_D),
7194 OPC_CMP_NGLE_D = FOP (57, FMT_D),
7195 OPC_CMP_SEQ_D = FOP (58, FMT_D),
7196 OPC_CMP_NGL_D = FOP (59, FMT_D),
7197 OPC_CMP_LT_D = FOP (60, FMT_D),
7198 OPC_CMP_NGE_D = FOP (61, FMT_D),
7199 OPC_CMP_LE_D = FOP (62, FMT_D),
7200 OPC_CMP_NGT_D = FOP (63, FMT_D),
7202 OPC_CVT_S_W = FOP(32, FMT_W),
7203 OPC_CVT_D_W = FOP(33, FMT_W),
7204 OPC_CVT_S_L = FOP(32, FMT_L),
7205 OPC_CVT_D_L = FOP(33, FMT_L),
7206 OPC_CVT_PS_PW = FOP(38, FMT_W),
7208 OPC_ADD_PS = FOP(0, FMT_PS),
7209 OPC_SUB_PS = FOP(1, FMT_PS),
7210 OPC_MUL_PS = FOP(2, FMT_PS),
7211 OPC_DIV_PS = FOP(3, FMT_PS),
7212 OPC_ABS_PS = FOP(5, FMT_PS),
7213 OPC_MOV_PS = FOP(6, FMT_PS),
7214 OPC_NEG_PS = FOP(7, FMT_PS),
7215 OPC_MOVCF_PS = FOP(17, FMT_PS),
7216 OPC_MOVZ_PS = FOP(18, FMT_PS),
7217 OPC_MOVN_PS = FOP(19, FMT_PS),
7218 OPC_ADDR_PS = FOP(24, FMT_PS),
7219 OPC_MULR_PS = FOP(26, FMT_PS),
7220 OPC_RECIP2_PS = FOP(28, FMT_PS),
7221 OPC_RECIP1_PS = FOP(29, FMT_PS),
7222 OPC_RSQRT1_PS = FOP(30, FMT_PS),
7223 OPC_RSQRT2_PS = FOP(31, FMT_PS),
7225 OPC_CVT_S_PU = FOP(32, FMT_PS),
7226 OPC_CVT_PW_PS = FOP(36, FMT_PS),
7227 OPC_CVT_S_PL = FOP(40, FMT_PS),
7228 OPC_PLL_PS = FOP(44, FMT_PS),
7229 OPC_PLU_PS = FOP(45, FMT_PS),
7230 OPC_PUL_PS = FOP(46, FMT_PS),
7231 OPC_PUU_PS = FOP(47, FMT_PS),
7232 OPC_CMP_F_PS = FOP (48, FMT_PS),
7233 OPC_CMP_UN_PS = FOP (49, FMT_PS),
7234 OPC_CMP_EQ_PS = FOP (50, FMT_PS),
7235 OPC_CMP_UEQ_PS = FOP (51, FMT_PS),
7236 OPC_CMP_OLT_PS = FOP (52, FMT_PS),
7237 OPC_CMP_ULT_PS = FOP (53, FMT_PS),
7238 OPC_CMP_OLE_PS = FOP (54, FMT_PS),
7239 OPC_CMP_ULE_PS = FOP (55, FMT_PS),
7240 OPC_CMP_SF_PS = FOP (56, FMT_PS),
7241 OPC_CMP_NGLE_PS = FOP (57, FMT_PS),
7242 OPC_CMP_SEQ_PS = FOP (58, FMT_PS),
7243 OPC_CMP_NGL_PS = FOP (59, FMT_PS),
7244 OPC_CMP_LT_PS = FOP (60, FMT_PS),
7245 OPC_CMP_NGE_PS = FOP (61, FMT_PS),
7246 OPC_CMP_LE_PS = FOP (62, FMT_PS),
7247 OPC_CMP_NGT_PS = FOP (63, FMT_PS),
7250 static void gen_cp1 (DisasContext *ctx, uint32_t opc, int rt, int fs)
7252 const char *opn = "cp1 move";
7253 TCGv t0 = tcg_temp_new();
7258 TCGv_i32 fp0 = tcg_temp_new_i32();
7260 gen_load_fpr32(fp0, fs);
7261 tcg_gen_ext_i32_tl(t0, fp0);
7262 tcg_temp_free_i32(fp0);
7264 gen_store_gpr(t0, rt);
7268 gen_load_gpr(t0, rt);
7270 TCGv_i32 fp0 = tcg_temp_new_i32();
7272 tcg_gen_trunc_tl_i32(fp0, t0);
7273 gen_store_fpr32(fp0, fs);
7274 tcg_temp_free_i32(fp0);
7279 gen_helper_1e0i(cfc1, t0, fs);
7280 gen_store_gpr(t0, rt);
7284 gen_load_gpr(t0, rt);
7285 gen_helper_0e1i(ctc1, t0, fs);
7288 #if defined(TARGET_MIPS64)
7290 gen_load_fpr64(ctx, t0, fs);
7291 gen_store_gpr(t0, rt);
7295 gen_load_gpr(t0, rt);
7296 gen_store_fpr64(ctx, t0, fs);
7302 TCGv_i32 fp0 = tcg_temp_new_i32();
7304 gen_load_fpr32h(fp0, fs);
7305 tcg_gen_ext_i32_tl(t0, fp0);
7306 tcg_temp_free_i32(fp0);
7308 gen_store_gpr(t0, rt);
7312 gen_load_gpr(t0, rt);
7314 TCGv_i32 fp0 = tcg_temp_new_i32();
7316 tcg_gen_trunc_tl_i32(fp0, t0);
7317 gen_store_fpr32h(fp0, fs);
7318 tcg_temp_free_i32(fp0);
7324 generate_exception (ctx, EXCP_RI);
7327 (void)opn; /* avoid a compiler warning */
7328 MIPS_DEBUG("%s %s %s", opn, regnames[rt], fregnames[fs]);
7334 static void gen_movci (DisasContext *ctx, int rd, int rs, int cc, int tf)
7350 l1 = gen_new_label();
7351 t0 = tcg_temp_new_i32();
7352 tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc));
7353 tcg_gen_brcondi_i32(cond, t0, 0, l1);
7354 tcg_temp_free_i32(t0);
7356 tcg_gen_movi_tl(cpu_gpr[rd], 0);
7358 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
7363 static inline void gen_movcf_s (int fs, int fd, int cc, int tf)
7366 TCGv_i32 t0 = tcg_temp_new_i32();
7367 int l1 = gen_new_label();
7374 tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc));
7375 tcg_gen_brcondi_i32(cond, t0, 0, l1);
7376 gen_load_fpr32(t0, fs);
7377 gen_store_fpr32(t0, fd);
7379 tcg_temp_free_i32(t0);
7382 static inline void gen_movcf_d (DisasContext *ctx, int fs, int fd, int cc, int tf)
7385 TCGv_i32 t0 = tcg_temp_new_i32();
7387 int l1 = gen_new_label();
7394 tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc));
7395 tcg_gen_brcondi_i32(cond, t0, 0, l1);
7396 tcg_temp_free_i32(t0);
7397 fp0 = tcg_temp_new_i64();
7398 gen_load_fpr64(ctx, fp0, fs);
7399 gen_store_fpr64(ctx, fp0, fd);
7400 tcg_temp_free_i64(fp0);
7404 static inline void gen_movcf_ps (int fs, int fd, int cc, int tf)
7407 TCGv_i32 t0 = tcg_temp_new_i32();
7408 int l1 = gen_new_label();
7409 int l2 = gen_new_label();
7416 tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc));
7417 tcg_gen_brcondi_i32(cond, t0, 0, l1);
7418 gen_load_fpr32(t0, fs);
7419 gen_store_fpr32(t0, fd);
7422 tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc+1));
7423 tcg_gen_brcondi_i32(cond, t0, 0, l2);
7424 gen_load_fpr32h(t0, fs);
7425 gen_store_fpr32h(t0, fd);
7426 tcg_temp_free_i32(t0);
7431 static void gen_farith (DisasContext *ctx, enum fopcode op1,
7432 int ft, int fs, int fd, int cc)
7434 const char *opn = "farith";
7435 const char *condnames[] = {
7453 const char *condnames_abs[] = {
7471 enum { BINOP, CMPOP, OTHEROP } optype = OTHEROP;
7472 uint32_t func = ctx->opcode & 0x3f;
7477 TCGv_i32 fp0 = tcg_temp_new_i32();
7478 TCGv_i32 fp1 = tcg_temp_new_i32();
7480 gen_load_fpr32(fp0, fs);
7481 gen_load_fpr32(fp1, ft);
7482 gen_helper_float_add_s(fp0, cpu_env, fp0, fp1);
7483 tcg_temp_free_i32(fp1);
7484 gen_store_fpr32(fp0, fd);
7485 tcg_temp_free_i32(fp0);
7492 TCGv_i32 fp0 = tcg_temp_new_i32();
7493 TCGv_i32 fp1 = tcg_temp_new_i32();
7495 gen_load_fpr32(fp0, fs);
7496 gen_load_fpr32(fp1, ft);
7497 gen_helper_float_sub_s(fp0, cpu_env, fp0, fp1);
7498 tcg_temp_free_i32(fp1);
7499 gen_store_fpr32(fp0, fd);
7500 tcg_temp_free_i32(fp0);
7507 TCGv_i32 fp0 = tcg_temp_new_i32();
7508 TCGv_i32 fp1 = tcg_temp_new_i32();
7510 gen_load_fpr32(fp0, fs);
7511 gen_load_fpr32(fp1, ft);
7512 gen_helper_float_mul_s(fp0, cpu_env, fp0, fp1);
7513 tcg_temp_free_i32(fp1);
7514 gen_store_fpr32(fp0, fd);
7515 tcg_temp_free_i32(fp0);
7522 TCGv_i32 fp0 = tcg_temp_new_i32();
7523 TCGv_i32 fp1 = tcg_temp_new_i32();
7525 gen_load_fpr32(fp0, fs);
7526 gen_load_fpr32(fp1, ft);
7527 gen_helper_float_div_s(fp0, cpu_env, fp0, fp1);
7528 tcg_temp_free_i32(fp1);
7529 gen_store_fpr32(fp0, fd);
7530 tcg_temp_free_i32(fp0);
7537 TCGv_i32 fp0 = tcg_temp_new_i32();
7539 gen_load_fpr32(fp0, fs);
7540 gen_helper_float_sqrt_s(fp0, cpu_env, fp0);
7541 gen_store_fpr32(fp0, fd);
7542 tcg_temp_free_i32(fp0);
7548 TCGv_i32 fp0 = tcg_temp_new_i32();
7550 gen_load_fpr32(fp0, fs);
7551 gen_helper_float_abs_s(fp0, fp0);
7552 gen_store_fpr32(fp0, fd);
7553 tcg_temp_free_i32(fp0);
7559 TCGv_i32 fp0 = tcg_temp_new_i32();
7561 gen_load_fpr32(fp0, fs);
7562 gen_store_fpr32(fp0, fd);
7563 tcg_temp_free_i32(fp0);
7569 TCGv_i32 fp0 = tcg_temp_new_i32();
7571 gen_load_fpr32(fp0, fs);
7572 gen_helper_float_chs_s(fp0, fp0);
7573 gen_store_fpr32(fp0, fd);
7574 tcg_temp_free_i32(fp0);
7579 check_cp1_64bitmode(ctx);
7581 TCGv_i32 fp32 = tcg_temp_new_i32();
7582 TCGv_i64 fp64 = tcg_temp_new_i64();
7584 gen_load_fpr32(fp32, fs);
7585 gen_helper_float_roundl_s(fp64, cpu_env, fp32);
7586 tcg_temp_free_i32(fp32);
7587 gen_store_fpr64(ctx, fp64, fd);
7588 tcg_temp_free_i64(fp64);
7593 check_cp1_64bitmode(ctx);
7595 TCGv_i32 fp32 = tcg_temp_new_i32();
7596 TCGv_i64 fp64 = tcg_temp_new_i64();
7598 gen_load_fpr32(fp32, fs);
7599 gen_helper_float_truncl_s(fp64, cpu_env, fp32);
7600 tcg_temp_free_i32(fp32);
7601 gen_store_fpr64(ctx, fp64, fd);
7602 tcg_temp_free_i64(fp64);
7607 check_cp1_64bitmode(ctx);
7609 TCGv_i32 fp32 = tcg_temp_new_i32();
7610 TCGv_i64 fp64 = tcg_temp_new_i64();
7612 gen_load_fpr32(fp32, fs);
7613 gen_helper_float_ceill_s(fp64, cpu_env, fp32);
7614 tcg_temp_free_i32(fp32);
7615 gen_store_fpr64(ctx, fp64, fd);
7616 tcg_temp_free_i64(fp64);
7621 check_cp1_64bitmode(ctx);
7623 TCGv_i32 fp32 = tcg_temp_new_i32();
7624 TCGv_i64 fp64 = tcg_temp_new_i64();
7626 gen_load_fpr32(fp32, fs);
7627 gen_helper_float_floorl_s(fp64, cpu_env, fp32);
7628 tcg_temp_free_i32(fp32);
7629 gen_store_fpr64(ctx, fp64, fd);
7630 tcg_temp_free_i64(fp64);
7636 TCGv_i32 fp0 = tcg_temp_new_i32();
7638 gen_load_fpr32(fp0, fs);
7639 gen_helper_float_roundw_s(fp0, cpu_env, fp0);
7640 gen_store_fpr32(fp0, fd);
7641 tcg_temp_free_i32(fp0);
7647 TCGv_i32 fp0 = tcg_temp_new_i32();
7649 gen_load_fpr32(fp0, fs);
7650 gen_helper_float_truncw_s(fp0, cpu_env, fp0);
7651 gen_store_fpr32(fp0, fd);
7652 tcg_temp_free_i32(fp0);
7658 TCGv_i32 fp0 = tcg_temp_new_i32();
7660 gen_load_fpr32(fp0, fs);
7661 gen_helper_float_ceilw_s(fp0, cpu_env, fp0);
7662 gen_store_fpr32(fp0, fd);
7663 tcg_temp_free_i32(fp0);
7669 TCGv_i32 fp0 = tcg_temp_new_i32();
7671 gen_load_fpr32(fp0, fs);
7672 gen_helper_float_floorw_s(fp0, cpu_env, fp0);
7673 gen_store_fpr32(fp0, fd);
7674 tcg_temp_free_i32(fp0);
7679 gen_movcf_s(fs, fd, (ft >> 2) & 0x7, ft & 0x1);
7684 int l1 = gen_new_label();
7688 tcg_gen_brcondi_tl(TCG_COND_NE, cpu_gpr[ft], 0, l1);
7690 fp0 = tcg_temp_new_i32();
7691 gen_load_fpr32(fp0, fs);
7692 gen_store_fpr32(fp0, fd);
7693 tcg_temp_free_i32(fp0);
7700 int l1 = gen_new_label();
7704 tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_gpr[ft], 0, l1);
7705 fp0 = tcg_temp_new_i32();
7706 gen_load_fpr32(fp0, fs);
7707 gen_store_fpr32(fp0, fd);
7708 tcg_temp_free_i32(fp0);
7717 TCGv_i32 fp0 = tcg_temp_new_i32();
7719 gen_load_fpr32(fp0, fs);
7720 gen_helper_float_recip_s(fp0, cpu_env, fp0);
7721 gen_store_fpr32(fp0, fd);
7722 tcg_temp_free_i32(fp0);
7729 TCGv_i32 fp0 = tcg_temp_new_i32();
7731 gen_load_fpr32(fp0, fs);
7732 gen_helper_float_rsqrt_s(fp0, cpu_env, fp0);
7733 gen_store_fpr32(fp0, fd);
7734 tcg_temp_free_i32(fp0);
7739 check_cp1_64bitmode(ctx);
7741 TCGv_i32 fp0 = tcg_temp_new_i32();
7742 TCGv_i32 fp1 = tcg_temp_new_i32();
7744 gen_load_fpr32(fp0, fs);
7745 gen_load_fpr32(fp1, ft);
7746 gen_helper_float_recip2_s(fp0, cpu_env, fp0, fp1);
7747 tcg_temp_free_i32(fp1);
7748 gen_store_fpr32(fp0, fd);
7749 tcg_temp_free_i32(fp0);
7754 check_cp1_64bitmode(ctx);
7756 TCGv_i32 fp0 = tcg_temp_new_i32();
7758 gen_load_fpr32(fp0, fs);
7759 gen_helper_float_recip1_s(fp0, cpu_env, fp0);
7760 gen_store_fpr32(fp0, fd);
7761 tcg_temp_free_i32(fp0);
7766 check_cp1_64bitmode(ctx);
7768 TCGv_i32 fp0 = tcg_temp_new_i32();
7770 gen_load_fpr32(fp0, fs);
7771 gen_helper_float_rsqrt1_s(fp0, cpu_env, fp0);
7772 gen_store_fpr32(fp0, fd);
7773 tcg_temp_free_i32(fp0);
7778 check_cp1_64bitmode(ctx);
7780 TCGv_i32 fp0 = tcg_temp_new_i32();
7781 TCGv_i32 fp1 = tcg_temp_new_i32();
7783 gen_load_fpr32(fp0, fs);
7784 gen_load_fpr32(fp1, ft);
7785 gen_helper_float_rsqrt2_s(fp0, cpu_env, fp0, fp1);
7786 tcg_temp_free_i32(fp1);
7787 gen_store_fpr32(fp0, fd);
7788 tcg_temp_free_i32(fp0);
7793 check_cp1_registers(ctx, fd);
7795 TCGv_i32 fp32 = tcg_temp_new_i32();
7796 TCGv_i64 fp64 = tcg_temp_new_i64();
7798 gen_load_fpr32(fp32, fs);
7799 gen_helper_float_cvtd_s(fp64, cpu_env, fp32);
7800 tcg_temp_free_i32(fp32);
7801 gen_store_fpr64(ctx, fp64, fd);
7802 tcg_temp_free_i64(fp64);
7808 TCGv_i32 fp0 = tcg_temp_new_i32();
7810 gen_load_fpr32(fp0, fs);
7811 gen_helper_float_cvtw_s(fp0, cpu_env, fp0);
7812 gen_store_fpr32(fp0, fd);
7813 tcg_temp_free_i32(fp0);
7818 check_cp1_64bitmode(ctx);
7820 TCGv_i32 fp32 = tcg_temp_new_i32();
7821 TCGv_i64 fp64 = tcg_temp_new_i64();
7823 gen_load_fpr32(fp32, fs);
7824 gen_helper_float_cvtl_s(fp64, cpu_env, fp32);
7825 tcg_temp_free_i32(fp32);
7826 gen_store_fpr64(ctx, fp64, fd);
7827 tcg_temp_free_i64(fp64);
7832 check_cp1_64bitmode(ctx);
7834 TCGv_i64 fp64 = tcg_temp_new_i64();
7835 TCGv_i32 fp32_0 = tcg_temp_new_i32();
7836 TCGv_i32 fp32_1 = tcg_temp_new_i32();
7838 gen_load_fpr32(fp32_0, fs);
7839 gen_load_fpr32(fp32_1, ft);
7840 tcg_gen_concat_i32_i64(fp64, fp32_1, fp32_0);
7841 tcg_temp_free_i32(fp32_1);
7842 tcg_temp_free_i32(fp32_0);
7843 gen_store_fpr64(ctx, fp64, fd);
7844 tcg_temp_free_i64(fp64);
7857 case OPC_CMP_NGLE_S:
7864 if (ctx->opcode & (1 << 6)) {
7865 gen_cmpabs_s(ctx, func-48, ft, fs, cc);
7866 opn = condnames_abs[func-48];
7868 gen_cmp_s(ctx, func-48, ft, fs, cc);
7869 opn = condnames[func-48];
7873 check_cp1_registers(ctx, fs | ft | fd);
7875 TCGv_i64 fp0 = tcg_temp_new_i64();
7876 TCGv_i64 fp1 = tcg_temp_new_i64();
7878 gen_load_fpr64(ctx, fp0, fs);
7879 gen_load_fpr64(ctx, fp1, ft);
7880 gen_helper_float_add_d(fp0, cpu_env, fp0, fp1);
7881 tcg_temp_free_i64(fp1);
7882 gen_store_fpr64(ctx, fp0, fd);
7883 tcg_temp_free_i64(fp0);
7889 check_cp1_registers(ctx, fs | ft | fd);
7891 TCGv_i64 fp0 = tcg_temp_new_i64();
7892 TCGv_i64 fp1 = tcg_temp_new_i64();
7894 gen_load_fpr64(ctx, fp0, fs);
7895 gen_load_fpr64(ctx, fp1, ft);
7896 gen_helper_float_sub_d(fp0, cpu_env, fp0, fp1);
7897 tcg_temp_free_i64(fp1);
7898 gen_store_fpr64(ctx, fp0, fd);
7899 tcg_temp_free_i64(fp0);
7905 check_cp1_registers(ctx, fs | ft | fd);
7907 TCGv_i64 fp0 = tcg_temp_new_i64();
7908 TCGv_i64 fp1 = tcg_temp_new_i64();
7910 gen_load_fpr64(ctx, fp0, fs);
7911 gen_load_fpr64(ctx, fp1, ft);
7912 gen_helper_float_mul_d(fp0, cpu_env, fp0, fp1);
7913 tcg_temp_free_i64(fp1);
7914 gen_store_fpr64(ctx, fp0, fd);
7915 tcg_temp_free_i64(fp0);
7921 check_cp1_registers(ctx, fs | ft | fd);
7923 TCGv_i64 fp0 = tcg_temp_new_i64();
7924 TCGv_i64 fp1 = tcg_temp_new_i64();
7926 gen_load_fpr64(ctx, fp0, fs);
7927 gen_load_fpr64(ctx, fp1, ft);
7928 gen_helper_float_div_d(fp0, cpu_env, fp0, fp1);
7929 tcg_temp_free_i64(fp1);
7930 gen_store_fpr64(ctx, fp0, fd);
7931 tcg_temp_free_i64(fp0);
7937 check_cp1_registers(ctx, fs | fd);
7939 TCGv_i64 fp0 = tcg_temp_new_i64();
7941 gen_load_fpr64(ctx, fp0, fs);
7942 gen_helper_float_sqrt_d(fp0, cpu_env, fp0);
7943 gen_store_fpr64(ctx, fp0, fd);
7944 tcg_temp_free_i64(fp0);
7949 check_cp1_registers(ctx, fs | fd);
7951 TCGv_i64 fp0 = tcg_temp_new_i64();
7953 gen_load_fpr64(ctx, fp0, fs);
7954 gen_helper_float_abs_d(fp0, fp0);
7955 gen_store_fpr64(ctx, fp0, fd);
7956 tcg_temp_free_i64(fp0);
7961 check_cp1_registers(ctx, fs | fd);
7963 TCGv_i64 fp0 = tcg_temp_new_i64();
7965 gen_load_fpr64(ctx, fp0, fs);
7966 gen_store_fpr64(ctx, fp0, fd);
7967 tcg_temp_free_i64(fp0);
7972 check_cp1_registers(ctx, fs | fd);
7974 TCGv_i64 fp0 = tcg_temp_new_i64();
7976 gen_load_fpr64(ctx, fp0, fs);
7977 gen_helper_float_chs_d(fp0, fp0);
7978 gen_store_fpr64(ctx, fp0, fd);
7979 tcg_temp_free_i64(fp0);
7984 check_cp1_64bitmode(ctx);
7986 TCGv_i64 fp0 = tcg_temp_new_i64();
7988 gen_load_fpr64(ctx, fp0, fs);
7989 gen_helper_float_roundl_d(fp0, cpu_env, fp0);
7990 gen_store_fpr64(ctx, fp0, fd);
7991 tcg_temp_free_i64(fp0);
7996 check_cp1_64bitmode(ctx);
7998 TCGv_i64 fp0 = tcg_temp_new_i64();
8000 gen_load_fpr64(ctx, fp0, fs);
8001 gen_helper_float_truncl_d(fp0, cpu_env, fp0);
8002 gen_store_fpr64(ctx, fp0, fd);
8003 tcg_temp_free_i64(fp0);
8008 check_cp1_64bitmode(ctx);
8010 TCGv_i64 fp0 = tcg_temp_new_i64();
8012 gen_load_fpr64(ctx, fp0, fs);
8013 gen_helper_float_ceill_d(fp0, cpu_env, fp0);
8014 gen_store_fpr64(ctx, fp0, fd);
8015 tcg_temp_free_i64(fp0);
8020 check_cp1_64bitmode(ctx);
8022 TCGv_i64 fp0 = tcg_temp_new_i64();
8024 gen_load_fpr64(ctx, fp0, fs);
8025 gen_helper_float_floorl_d(fp0, cpu_env, fp0);
8026 gen_store_fpr64(ctx, fp0, fd);
8027 tcg_temp_free_i64(fp0);
8032 check_cp1_registers(ctx, fs);
8034 TCGv_i32 fp32 = tcg_temp_new_i32();
8035 TCGv_i64 fp64 = tcg_temp_new_i64();
8037 gen_load_fpr64(ctx, fp64, fs);
8038 gen_helper_float_roundw_d(fp32, cpu_env, fp64);
8039 tcg_temp_free_i64(fp64);
8040 gen_store_fpr32(fp32, fd);
8041 tcg_temp_free_i32(fp32);
8046 check_cp1_registers(ctx, fs);
8048 TCGv_i32 fp32 = tcg_temp_new_i32();
8049 TCGv_i64 fp64 = tcg_temp_new_i64();
8051 gen_load_fpr64(ctx, fp64, fs);
8052 gen_helper_float_truncw_d(fp32, cpu_env, fp64);
8053 tcg_temp_free_i64(fp64);
8054 gen_store_fpr32(fp32, fd);
8055 tcg_temp_free_i32(fp32);
8060 check_cp1_registers(ctx, fs);
8062 TCGv_i32 fp32 = tcg_temp_new_i32();
8063 TCGv_i64 fp64 = tcg_temp_new_i64();
8065 gen_load_fpr64(ctx, fp64, fs);
8066 gen_helper_float_ceilw_d(fp32, cpu_env, fp64);
8067 tcg_temp_free_i64(fp64);
8068 gen_store_fpr32(fp32, fd);
8069 tcg_temp_free_i32(fp32);
8074 check_cp1_registers(ctx, fs);
8076 TCGv_i32 fp32 = tcg_temp_new_i32();
8077 TCGv_i64 fp64 = tcg_temp_new_i64();
8079 gen_load_fpr64(ctx, fp64, fs);
8080 gen_helper_float_floorw_d(fp32, cpu_env, fp64);
8081 tcg_temp_free_i64(fp64);
8082 gen_store_fpr32(fp32, fd);
8083 tcg_temp_free_i32(fp32);
8088 gen_movcf_d(ctx, fs, fd, (ft >> 2) & 0x7, ft & 0x1);
8093 int l1 = gen_new_label();
8097 tcg_gen_brcondi_tl(TCG_COND_NE, cpu_gpr[ft], 0, l1);
8099 fp0 = tcg_temp_new_i64();
8100 gen_load_fpr64(ctx, fp0, fs);
8101 gen_store_fpr64(ctx, fp0, fd);
8102 tcg_temp_free_i64(fp0);
8109 int l1 = gen_new_label();
8113 tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_gpr[ft], 0, l1);
8114 fp0 = tcg_temp_new_i64();
8115 gen_load_fpr64(ctx, fp0, fs);
8116 gen_store_fpr64(ctx, fp0, fd);
8117 tcg_temp_free_i64(fp0);
8124 check_cp1_64bitmode(ctx);
8126 TCGv_i64 fp0 = tcg_temp_new_i64();
8128 gen_load_fpr64(ctx, fp0, fs);
8129 gen_helper_float_recip_d(fp0, cpu_env, fp0);
8130 gen_store_fpr64(ctx, fp0, fd);
8131 tcg_temp_free_i64(fp0);
8136 check_cp1_64bitmode(ctx);
8138 TCGv_i64 fp0 = tcg_temp_new_i64();
8140 gen_load_fpr64(ctx, fp0, fs);
8141 gen_helper_float_rsqrt_d(fp0, cpu_env, fp0);
8142 gen_store_fpr64(ctx, fp0, fd);
8143 tcg_temp_free_i64(fp0);
8148 check_cp1_64bitmode(ctx);
8150 TCGv_i64 fp0 = tcg_temp_new_i64();
8151 TCGv_i64 fp1 = tcg_temp_new_i64();
8153 gen_load_fpr64(ctx, fp0, fs);
8154 gen_load_fpr64(ctx, fp1, ft);
8155 gen_helper_float_recip2_d(fp0, cpu_env, fp0, fp1);
8156 tcg_temp_free_i64(fp1);
8157 gen_store_fpr64(ctx, fp0, fd);
8158 tcg_temp_free_i64(fp0);
8163 check_cp1_64bitmode(ctx);
8165 TCGv_i64 fp0 = tcg_temp_new_i64();
8167 gen_load_fpr64(ctx, fp0, fs);
8168 gen_helper_float_recip1_d(fp0, cpu_env, fp0);
8169 gen_store_fpr64(ctx, fp0, fd);
8170 tcg_temp_free_i64(fp0);
8175 check_cp1_64bitmode(ctx);
8177 TCGv_i64 fp0 = tcg_temp_new_i64();
8179 gen_load_fpr64(ctx, fp0, fs);
8180 gen_helper_float_rsqrt1_d(fp0, cpu_env, fp0);
8181 gen_store_fpr64(ctx, fp0, fd);
8182 tcg_temp_free_i64(fp0);
8187 check_cp1_64bitmode(ctx);
8189 TCGv_i64 fp0 = tcg_temp_new_i64();
8190 TCGv_i64 fp1 = tcg_temp_new_i64();
8192 gen_load_fpr64(ctx, fp0, fs);
8193 gen_load_fpr64(ctx, fp1, ft);
8194 gen_helper_float_rsqrt2_d(fp0, cpu_env, fp0, fp1);
8195 tcg_temp_free_i64(fp1);
8196 gen_store_fpr64(ctx, fp0, fd);
8197 tcg_temp_free_i64(fp0);
8210 case OPC_CMP_NGLE_D:
8217 if (ctx->opcode & (1 << 6)) {
8218 gen_cmpabs_d(ctx, func-48, ft, fs, cc);
8219 opn = condnames_abs[func-48];
8221 gen_cmp_d(ctx, func-48, ft, fs, cc);
8222 opn = condnames[func-48];
8226 check_cp1_registers(ctx, fs);
8228 TCGv_i32 fp32 = tcg_temp_new_i32();
8229 TCGv_i64 fp64 = tcg_temp_new_i64();
8231 gen_load_fpr64(ctx, fp64, fs);
8232 gen_helper_float_cvts_d(fp32, cpu_env, fp64);
8233 tcg_temp_free_i64(fp64);
8234 gen_store_fpr32(fp32, fd);
8235 tcg_temp_free_i32(fp32);
8240 check_cp1_registers(ctx, fs);
8242 TCGv_i32 fp32 = tcg_temp_new_i32();
8243 TCGv_i64 fp64 = tcg_temp_new_i64();
8245 gen_load_fpr64(ctx, fp64, fs);
8246 gen_helper_float_cvtw_d(fp32, cpu_env, fp64);
8247 tcg_temp_free_i64(fp64);
8248 gen_store_fpr32(fp32, fd);
8249 tcg_temp_free_i32(fp32);
8254 check_cp1_64bitmode(ctx);
8256 TCGv_i64 fp0 = tcg_temp_new_i64();
8258 gen_load_fpr64(ctx, fp0, fs);
8259 gen_helper_float_cvtl_d(fp0, cpu_env, fp0);
8260 gen_store_fpr64(ctx, fp0, fd);
8261 tcg_temp_free_i64(fp0);
8267 TCGv_i32 fp0 = tcg_temp_new_i32();
8269 gen_load_fpr32(fp0, fs);
8270 gen_helper_float_cvts_w(fp0, cpu_env, fp0);
8271 gen_store_fpr32(fp0, fd);
8272 tcg_temp_free_i32(fp0);
8277 check_cp1_registers(ctx, fd);
8279 TCGv_i32 fp32 = tcg_temp_new_i32();
8280 TCGv_i64 fp64 = tcg_temp_new_i64();
8282 gen_load_fpr32(fp32, fs);
8283 gen_helper_float_cvtd_w(fp64, cpu_env, fp32);
8284 tcg_temp_free_i32(fp32);
8285 gen_store_fpr64(ctx, fp64, fd);
8286 tcg_temp_free_i64(fp64);
8291 check_cp1_64bitmode(ctx);
8293 TCGv_i32 fp32 = tcg_temp_new_i32();
8294 TCGv_i64 fp64 = tcg_temp_new_i64();
8296 gen_load_fpr64(ctx, fp64, fs);
8297 gen_helper_float_cvts_l(fp32, cpu_env, fp64);
8298 tcg_temp_free_i64(fp64);
8299 gen_store_fpr32(fp32, fd);
8300 tcg_temp_free_i32(fp32);
8305 check_cp1_64bitmode(ctx);
8307 TCGv_i64 fp0 = tcg_temp_new_i64();
8309 gen_load_fpr64(ctx, fp0, fs);
8310 gen_helper_float_cvtd_l(fp0, cpu_env, fp0);
8311 gen_store_fpr64(ctx, fp0, fd);
8312 tcg_temp_free_i64(fp0);
8317 check_cp1_64bitmode(ctx);
8319 TCGv_i64 fp0 = tcg_temp_new_i64();
8321 gen_load_fpr64(ctx, fp0, fs);
8322 gen_helper_float_cvtps_pw(fp0, cpu_env, fp0);
8323 gen_store_fpr64(ctx, fp0, fd);
8324 tcg_temp_free_i64(fp0);
8329 check_cp1_64bitmode(ctx);
8331 TCGv_i64 fp0 = tcg_temp_new_i64();
8332 TCGv_i64 fp1 = tcg_temp_new_i64();
8334 gen_load_fpr64(ctx, fp0, fs);
8335 gen_load_fpr64(ctx, fp1, ft);
8336 gen_helper_float_add_ps(fp0, cpu_env, fp0, fp1);
8337 tcg_temp_free_i64(fp1);
8338 gen_store_fpr64(ctx, fp0, fd);
8339 tcg_temp_free_i64(fp0);
8344 check_cp1_64bitmode(ctx);
8346 TCGv_i64 fp0 = tcg_temp_new_i64();
8347 TCGv_i64 fp1 = tcg_temp_new_i64();
8349 gen_load_fpr64(ctx, fp0, fs);
8350 gen_load_fpr64(ctx, fp1, ft);
8351 gen_helper_float_sub_ps(fp0, cpu_env, fp0, fp1);
8352 tcg_temp_free_i64(fp1);
8353 gen_store_fpr64(ctx, fp0, fd);
8354 tcg_temp_free_i64(fp0);
8359 check_cp1_64bitmode(ctx);
8361 TCGv_i64 fp0 = tcg_temp_new_i64();
8362 TCGv_i64 fp1 = tcg_temp_new_i64();
8364 gen_load_fpr64(ctx, fp0, fs);
8365 gen_load_fpr64(ctx, fp1, ft);
8366 gen_helper_float_mul_ps(fp0, cpu_env, fp0, fp1);
8367 tcg_temp_free_i64(fp1);
8368 gen_store_fpr64(ctx, fp0, fd);
8369 tcg_temp_free_i64(fp0);
8374 check_cp1_64bitmode(ctx);
8376 TCGv_i64 fp0 = tcg_temp_new_i64();
8378 gen_load_fpr64(ctx, fp0, fs);
8379 gen_helper_float_abs_ps(fp0, fp0);
8380 gen_store_fpr64(ctx, fp0, fd);
8381 tcg_temp_free_i64(fp0);
8386 check_cp1_64bitmode(ctx);
8388 TCGv_i64 fp0 = tcg_temp_new_i64();
8390 gen_load_fpr64(ctx, fp0, fs);
8391 gen_store_fpr64(ctx, fp0, fd);
8392 tcg_temp_free_i64(fp0);
8397 check_cp1_64bitmode(ctx);
8399 TCGv_i64 fp0 = tcg_temp_new_i64();
8401 gen_load_fpr64(ctx, fp0, fs);
8402 gen_helper_float_chs_ps(fp0, fp0);
8403 gen_store_fpr64(ctx, fp0, fd);
8404 tcg_temp_free_i64(fp0);
8409 check_cp1_64bitmode(ctx);
8410 gen_movcf_ps(fs, fd, (ft >> 2) & 0x7, ft & 0x1);
8414 check_cp1_64bitmode(ctx);
8416 int l1 = gen_new_label();
8420 tcg_gen_brcondi_tl(TCG_COND_NE, cpu_gpr[ft], 0, l1);
8421 fp0 = tcg_temp_new_i64();
8422 gen_load_fpr64(ctx, fp0, fs);
8423 gen_store_fpr64(ctx, fp0, fd);
8424 tcg_temp_free_i64(fp0);
8430 check_cp1_64bitmode(ctx);
8432 int l1 = gen_new_label();
8436 tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_gpr[ft], 0, l1);
8437 fp0 = tcg_temp_new_i64();
8438 gen_load_fpr64(ctx, fp0, fs);
8439 gen_store_fpr64(ctx, fp0, fd);
8440 tcg_temp_free_i64(fp0);
8447 check_cp1_64bitmode(ctx);
8449 TCGv_i64 fp0 = tcg_temp_new_i64();
8450 TCGv_i64 fp1 = tcg_temp_new_i64();
8452 gen_load_fpr64(ctx, fp0, ft);
8453 gen_load_fpr64(ctx, fp1, fs);
8454 gen_helper_float_addr_ps(fp0, cpu_env, fp0, fp1);
8455 tcg_temp_free_i64(fp1);
8456 gen_store_fpr64(ctx, fp0, fd);
8457 tcg_temp_free_i64(fp0);
8462 check_cp1_64bitmode(ctx);
8464 TCGv_i64 fp0 = tcg_temp_new_i64();
8465 TCGv_i64 fp1 = tcg_temp_new_i64();
8467 gen_load_fpr64(ctx, fp0, ft);
8468 gen_load_fpr64(ctx, fp1, fs);
8469 gen_helper_float_mulr_ps(fp0, cpu_env, fp0, fp1);
8470 tcg_temp_free_i64(fp1);
8471 gen_store_fpr64(ctx, fp0, fd);
8472 tcg_temp_free_i64(fp0);
8477 check_cp1_64bitmode(ctx);
8479 TCGv_i64 fp0 = tcg_temp_new_i64();
8480 TCGv_i64 fp1 = tcg_temp_new_i64();
8482 gen_load_fpr64(ctx, fp0, fs);
8483 gen_load_fpr64(ctx, fp1, ft);
8484 gen_helper_float_recip2_ps(fp0, cpu_env, fp0, fp1);
8485 tcg_temp_free_i64(fp1);
8486 gen_store_fpr64(ctx, fp0, fd);
8487 tcg_temp_free_i64(fp0);
8492 check_cp1_64bitmode(ctx);
8494 TCGv_i64 fp0 = tcg_temp_new_i64();
8496 gen_load_fpr64(ctx, fp0, fs);
8497 gen_helper_float_recip1_ps(fp0, cpu_env, fp0);
8498 gen_store_fpr64(ctx, fp0, fd);
8499 tcg_temp_free_i64(fp0);
8504 check_cp1_64bitmode(ctx);
8506 TCGv_i64 fp0 = tcg_temp_new_i64();
8508 gen_load_fpr64(ctx, fp0, fs);
8509 gen_helper_float_rsqrt1_ps(fp0, cpu_env, fp0);
8510 gen_store_fpr64(ctx, fp0, fd);
8511 tcg_temp_free_i64(fp0);
8516 check_cp1_64bitmode(ctx);
8518 TCGv_i64 fp0 = tcg_temp_new_i64();
8519 TCGv_i64 fp1 = tcg_temp_new_i64();
8521 gen_load_fpr64(ctx, fp0, fs);
8522 gen_load_fpr64(ctx, fp1, ft);
8523 gen_helper_float_rsqrt2_ps(fp0, cpu_env, fp0, fp1);
8524 tcg_temp_free_i64(fp1);
8525 gen_store_fpr64(ctx, fp0, fd);
8526 tcg_temp_free_i64(fp0);
8531 check_cp1_64bitmode(ctx);
8533 TCGv_i32 fp0 = tcg_temp_new_i32();
8535 gen_load_fpr32h(fp0, fs);
8536 gen_helper_float_cvts_pu(fp0, cpu_env, fp0);
8537 gen_store_fpr32(fp0, fd);
8538 tcg_temp_free_i32(fp0);
8543 check_cp1_64bitmode(ctx);
8545 TCGv_i64 fp0 = tcg_temp_new_i64();
8547 gen_load_fpr64(ctx, fp0, fs);
8548 gen_helper_float_cvtpw_ps(fp0, cpu_env, fp0);
8549 gen_store_fpr64(ctx, fp0, fd);
8550 tcg_temp_free_i64(fp0);
8555 check_cp1_64bitmode(ctx);
8557 TCGv_i32 fp0 = tcg_temp_new_i32();
8559 gen_load_fpr32(fp0, fs);
8560 gen_helper_float_cvts_pl(fp0, cpu_env, fp0);
8561 gen_store_fpr32(fp0, fd);
8562 tcg_temp_free_i32(fp0);
8567 check_cp1_64bitmode(ctx);
8569 TCGv_i32 fp0 = tcg_temp_new_i32();
8570 TCGv_i32 fp1 = tcg_temp_new_i32();
8572 gen_load_fpr32(fp0, fs);
8573 gen_load_fpr32(fp1, ft);
8574 gen_store_fpr32h(fp0, fd);
8575 gen_store_fpr32(fp1, fd);
8576 tcg_temp_free_i32(fp0);
8577 tcg_temp_free_i32(fp1);
8582 check_cp1_64bitmode(ctx);
8584 TCGv_i32 fp0 = tcg_temp_new_i32();
8585 TCGv_i32 fp1 = tcg_temp_new_i32();
8587 gen_load_fpr32(fp0, fs);
8588 gen_load_fpr32h(fp1, ft);
8589 gen_store_fpr32(fp1, fd);
8590 gen_store_fpr32h(fp0, fd);
8591 tcg_temp_free_i32(fp0);
8592 tcg_temp_free_i32(fp1);
8597 check_cp1_64bitmode(ctx);
8599 TCGv_i32 fp0 = tcg_temp_new_i32();
8600 TCGv_i32 fp1 = tcg_temp_new_i32();
8602 gen_load_fpr32h(fp0, fs);
8603 gen_load_fpr32(fp1, ft);
8604 gen_store_fpr32(fp1, fd);
8605 gen_store_fpr32h(fp0, fd);
8606 tcg_temp_free_i32(fp0);
8607 tcg_temp_free_i32(fp1);
8612 check_cp1_64bitmode(ctx);
8614 TCGv_i32 fp0 = tcg_temp_new_i32();
8615 TCGv_i32 fp1 = tcg_temp_new_i32();
8617 gen_load_fpr32h(fp0, fs);
8618 gen_load_fpr32h(fp1, ft);
8619 gen_store_fpr32(fp1, fd);
8620 gen_store_fpr32h(fp0, fd);
8621 tcg_temp_free_i32(fp0);
8622 tcg_temp_free_i32(fp1);
8629 case OPC_CMP_UEQ_PS:
8630 case OPC_CMP_OLT_PS:
8631 case OPC_CMP_ULT_PS:
8632 case OPC_CMP_OLE_PS:
8633 case OPC_CMP_ULE_PS:
8635 case OPC_CMP_NGLE_PS:
8636 case OPC_CMP_SEQ_PS:
8637 case OPC_CMP_NGL_PS:
8639 case OPC_CMP_NGE_PS:
8641 case OPC_CMP_NGT_PS:
8642 if (ctx->opcode & (1 << 6)) {
8643 gen_cmpabs_ps(ctx, func-48, ft, fs, cc);
8644 opn = condnames_abs[func-48];
8646 gen_cmp_ps(ctx, func-48, ft, fs, cc);
8647 opn = condnames[func-48];
8652 generate_exception (ctx, EXCP_RI);
8655 (void)opn; /* avoid a compiler warning */
8658 MIPS_DEBUG("%s %s, %s, %s", opn, fregnames[fd], fregnames[fs], fregnames[ft]);
8661 MIPS_DEBUG("%s %s,%s", opn, fregnames[fs], fregnames[ft]);
8664 MIPS_DEBUG("%s %s,%s", opn, fregnames[fd], fregnames[fs]);
8669 /* Coprocessor 3 (FPU) */
8670 static void gen_flt3_ldst (DisasContext *ctx, uint32_t opc,
8671 int fd, int fs, int base, int index)
8673 const char *opn = "extended float load/store";
8675 TCGv t0 = tcg_temp_new();
8678 gen_load_gpr(t0, index);
8679 } else if (index == 0) {
8680 gen_load_gpr(t0, base);
8682 gen_op_addr_add(ctx, t0, cpu_gpr[base], cpu_gpr[index]);
8684 /* Don't do NOP if destination is zero: we must perform the actual
8690 TCGv_i32 fp0 = tcg_temp_new_i32();
8692 tcg_gen_qemu_ld32s(t0, t0, ctx->mem_idx);
8693 tcg_gen_trunc_tl_i32(fp0, t0);
8694 gen_store_fpr32(fp0, fd);
8695 tcg_temp_free_i32(fp0);
8701 check_cp1_registers(ctx, fd);
8703 TCGv_i64 fp0 = tcg_temp_new_i64();
8705 tcg_gen_qemu_ld64(fp0, t0, ctx->mem_idx);
8706 gen_store_fpr64(ctx, fp0, fd);
8707 tcg_temp_free_i64(fp0);
8712 check_cp1_64bitmode(ctx);
8713 tcg_gen_andi_tl(t0, t0, ~0x7);
8715 TCGv_i64 fp0 = tcg_temp_new_i64();
8717 tcg_gen_qemu_ld64(fp0, t0, ctx->mem_idx);
8718 gen_store_fpr64(ctx, fp0, fd);
8719 tcg_temp_free_i64(fp0);
8726 TCGv_i32 fp0 = tcg_temp_new_i32();
8727 TCGv t1 = tcg_temp_new();
8729 gen_load_fpr32(fp0, fs);
8730 tcg_gen_extu_i32_tl(t1, fp0);
8731 tcg_gen_qemu_st32(t1, t0, ctx->mem_idx);
8732 tcg_temp_free_i32(fp0);
8740 check_cp1_registers(ctx, fs);
8742 TCGv_i64 fp0 = tcg_temp_new_i64();
8744 gen_load_fpr64(ctx, fp0, fs);
8745 tcg_gen_qemu_st64(fp0, t0, ctx->mem_idx);
8746 tcg_temp_free_i64(fp0);
8752 check_cp1_64bitmode(ctx);
8753 tcg_gen_andi_tl(t0, t0, ~0x7);
8755 TCGv_i64 fp0 = tcg_temp_new_i64();
8757 gen_load_fpr64(ctx, fp0, fs);
8758 tcg_gen_qemu_st64(fp0, t0, ctx->mem_idx);
8759 tcg_temp_free_i64(fp0);
8766 (void)opn; (void)store; /* avoid compiler warnings */
8767 MIPS_DEBUG("%s %s, %s(%s)", opn, fregnames[store ? fs : fd],
8768 regnames[index], regnames[base]);
8771 static void gen_flt3_arith (DisasContext *ctx, uint32_t opc,
8772 int fd, int fr, int fs, int ft)
8774 const char *opn = "flt3_arith";
8778 check_cp1_64bitmode(ctx);
8780 TCGv t0 = tcg_temp_local_new();
8781 TCGv_i32 fp = tcg_temp_new_i32();
8782 TCGv_i32 fph = tcg_temp_new_i32();
8783 int l1 = gen_new_label();
8784 int l2 = gen_new_label();
8786 gen_load_gpr(t0, fr);
8787 tcg_gen_andi_tl(t0, t0, 0x7);
8789 tcg_gen_brcondi_tl(TCG_COND_NE, t0, 0, l1);
8790 gen_load_fpr32(fp, fs);
8791 gen_load_fpr32h(fph, fs);
8792 gen_store_fpr32(fp, fd);
8793 gen_store_fpr32h(fph, fd);
8796 tcg_gen_brcondi_tl(TCG_COND_NE, t0, 4, l2);
8798 #ifdef TARGET_WORDS_BIGENDIAN
8799 gen_load_fpr32(fp, fs);
8800 gen_load_fpr32h(fph, ft);
8801 gen_store_fpr32h(fp, fd);
8802 gen_store_fpr32(fph, fd);
8804 gen_load_fpr32h(fph, fs);
8805 gen_load_fpr32(fp, ft);
8806 gen_store_fpr32(fph, fd);
8807 gen_store_fpr32h(fp, fd);
8810 tcg_temp_free_i32(fp);
8811 tcg_temp_free_i32(fph);
8818 TCGv_i32 fp0 = tcg_temp_new_i32();
8819 TCGv_i32 fp1 = tcg_temp_new_i32();
8820 TCGv_i32 fp2 = tcg_temp_new_i32();
8822 gen_load_fpr32(fp0, fs);
8823 gen_load_fpr32(fp1, ft);
8824 gen_load_fpr32(fp2, fr);
8825 gen_helper_float_madd_s(fp2, cpu_env, fp0, fp1, fp2);
8826 tcg_temp_free_i32(fp0);
8827 tcg_temp_free_i32(fp1);
8828 gen_store_fpr32(fp2, fd);
8829 tcg_temp_free_i32(fp2);
8835 check_cp1_registers(ctx, fd | fs | ft | fr);
8837 TCGv_i64 fp0 = tcg_temp_new_i64();
8838 TCGv_i64 fp1 = tcg_temp_new_i64();
8839 TCGv_i64 fp2 = tcg_temp_new_i64();
8841 gen_load_fpr64(ctx, fp0, fs);
8842 gen_load_fpr64(ctx, fp1, ft);
8843 gen_load_fpr64(ctx, fp2, fr);
8844 gen_helper_float_madd_d(fp2, cpu_env, fp0, fp1, fp2);
8845 tcg_temp_free_i64(fp0);
8846 tcg_temp_free_i64(fp1);
8847 gen_store_fpr64(ctx, fp2, fd);
8848 tcg_temp_free_i64(fp2);
8853 check_cp1_64bitmode(ctx);
8855 TCGv_i64 fp0 = tcg_temp_new_i64();
8856 TCGv_i64 fp1 = tcg_temp_new_i64();
8857 TCGv_i64 fp2 = tcg_temp_new_i64();
8859 gen_load_fpr64(ctx, fp0, fs);
8860 gen_load_fpr64(ctx, fp1, ft);
8861 gen_load_fpr64(ctx, fp2, fr);
8862 gen_helper_float_madd_ps(fp2, cpu_env, fp0, fp1, fp2);
8863 tcg_temp_free_i64(fp0);
8864 tcg_temp_free_i64(fp1);
8865 gen_store_fpr64(ctx, fp2, fd);
8866 tcg_temp_free_i64(fp2);
8873 TCGv_i32 fp0 = tcg_temp_new_i32();
8874 TCGv_i32 fp1 = tcg_temp_new_i32();
8875 TCGv_i32 fp2 = tcg_temp_new_i32();
8877 gen_load_fpr32(fp0, fs);
8878 gen_load_fpr32(fp1, ft);
8879 gen_load_fpr32(fp2, fr);
8880 gen_helper_float_msub_s(fp2, cpu_env, fp0, fp1, fp2);
8881 tcg_temp_free_i32(fp0);
8882 tcg_temp_free_i32(fp1);
8883 gen_store_fpr32(fp2, fd);
8884 tcg_temp_free_i32(fp2);
8890 check_cp1_registers(ctx, fd | fs | ft | fr);
8892 TCGv_i64 fp0 = tcg_temp_new_i64();
8893 TCGv_i64 fp1 = tcg_temp_new_i64();
8894 TCGv_i64 fp2 = tcg_temp_new_i64();
8896 gen_load_fpr64(ctx, fp0, fs);
8897 gen_load_fpr64(ctx, fp1, ft);
8898 gen_load_fpr64(ctx, fp2, fr);
8899 gen_helper_float_msub_d(fp2, cpu_env, fp0, fp1, fp2);
8900 tcg_temp_free_i64(fp0);
8901 tcg_temp_free_i64(fp1);
8902 gen_store_fpr64(ctx, fp2, fd);
8903 tcg_temp_free_i64(fp2);
8908 check_cp1_64bitmode(ctx);
8910 TCGv_i64 fp0 = tcg_temp_new_i64();
8911 TCGv_i64 fp1 = tcg_temp_new_i64();
8912 TCGv_i64 fp2 = tcg_temp_new_i64();
8914 gen_load_fpr64(ctx, fp0, fs);
8915 gen_load_fpr64(ctx, fp1, ft);
8916 gen_load_fpr64(ctx, fp2, fr);
8917 gen_helper_float_msub_ps(fp2, cpu_env, fp0, fp1, fp2);
8918 tcg_temp_free_i64(fp0);
8919 tcg_temp_free_i64(fp1);
8920 gen_store_fpr64(ctx, fp2, fd);
8921 tcg_temp_free_i64(fp2);
8928 TCGv_i32 fp0 = tcg_temp_new_i32();
8929 TCGv_i32 fp1 = tcg_temp_new_i32();
8930 TCGv_i32 fp2 = tcg_temp_new_i32();
8932 gen_load_fpr32(fp0, fs);
8933 gen_load_fpr32(fp1, ft);
8934 gen_load_fpr32(fp2, fr);
8935 gen_helper_float_nmadd_s(fp2, cpu_env, fp0, fp1, fp2);
8936 tcg_temp_free_i32(fp0);
8937 tcg_temp_free_i32(fp1);
8938 gen_store_fpr32(fp2, fd);
8939 tcg_temp_free_i32(fp2);
8945 check_cp1_registers(ctx, fd | fs | ft | fr);
8947 TCGv_i64 fp0 = tcg_temp_new_i64();
8948 TCGv_i64 fp1 = tcg_temp_new_i64();
8949 TCGv_i64 fp2 = tcg_temp_new_i64();
8951 gen_load_fpr64(ctx, fp0, fs);
8952 gen_load_fpr64(ctx, fp1, ft);
8953 gen_load_fpr64(ctx, fp2, fr);
8954 gen_helper_float_nmadd_d(fp2, cpu_env, fp0, fp1, fp2);
8955 tcg_temp_free_i64(fp0);
8956 tcg_temp_free_i64(fp1);
8957 gen_store_fpr64(ctx, fp2, fd);
8958 tcg_temp_free_i64(fp2);
8963 check_cp1_64bitmode(ctx);
8965 TCGv_i64 fp0 = tcg_temp_new_i64();
8966 TCGv_i64 fp1 = tcg_temp_new_i64();
8967 TCGv_i64 fp2 = tcg_temp_new_i64();
8969 gen_load_fpr64(ctx, fp0, fs);
8970 gen_load_fpr64(ctx, fp1, ft);
8971 gen_load_fpr64(ctx, fp2, fr);
8972 gen_helper_float_nmadd_ps(fp2, cpu_env, fp0, fp1, fp2);
8973 tcg_temp_free_i64(fp0);
8974 tcg_temp_free_i64(fp1);
8975 gen_store_fpr64(ctx, fp2, fd);
8976 tcg_temp_free_i64(fp2);
8983 TCGv_i32 fp0 = tcg_temp_new_i32();
8984 TCGv_i32 fp1 = tcg_temp_new_i32();
8985 TCGv_i32 fp2 = tcg_temp_new_i32();
8987 gen_load_fpr32(fp0, fs);
8988 gen_load_fpr32(fp1, ft);
8989 gen_load_fpr32(fp2, fr);
8990 gen_helper_float_nmsub_s(fp2, cpu_env, fp0, fp1, fp2);
8991 tcg_temp_free_i32(fp0);
8992 tcg_temp_free_i32(fp1);
8993 gen_store_fpr32(fp2, fd);
8994 tcg_temp_free_i32(fp2);
9000 check_cp1_registers(ctx, fd | fs | ft | fr);
9002 TCGv_i64 fp0 = tcg_temp_new_i64();
9003 TCGv_i64 fp1 = tcg_temp_new_i64();
9004 TCGv_i64 fp2 = tcg_temp_new_i64();
9006 gen_load_fpr64(ctx, fp0, fs);
9007 gen_load_fpr64(ctx, fp1, ft);
9008 gen_load_fpr64(ctx, fp2, fr);
9009 gen_helper_float_nmsub_d(fp2, cpu_env, fp0, fp1, fp2);
9010 tcg_temp_free_i64(fp0);
9011 tcg_temp_free_i64(fp1);
9012 gen_store_fpr64(ctx, fp2, fd);
9013 tcg_temp_free_i64(fp2);
9018 check_cp1_64bitmode(ctx);
9020 TCGv_i64 fp0 = tcg_temp_new_i64();
9021 TCGv_i64 fp1 = tcg_temp_new_i64();
9022 TCGv_i64 fp2 = tcg_temp_new_i64();
9024 gen_load_fpr64(ctx, fp0, fs);
9025 gen_load_fpr64(ctx, fp1, ft);
9026 gen_load_fpr64(ctx, fp2, fr);
9027 gen_helper_float_nmsub_ps(fp2, cpu_env, fp0, fp1, fp2);
9028 tcg_temp_free_i64(fp0);
9029 tcg_temp_free_i64(fp1);
9030 gen_store_fpr64(ctx, fp2, fd);
9031 tcg_temp_free_i64(fp2);
9037 generate_exception (ctx, EXCP_RI);
9040 (void)opn; /* avoid a compiler warning */
9041 MIPS_DEBUG("%s %s, %s, %s, %s", opn, fregnames[fd], fregnames[fr],
9042 fregnames[fs], fregnames[ft]);
9045 static void gen_rdhwr(DisasContext *ctx, int rt, int rd)
9049 #if !defined(CONFIG_USER_ONLY)
9050 /* The Linux kernel will emulate rdhwr if it's not supported natively.
9051 Therefore only check the ISA in system mode. */
9052 check_insn(ctx, ISA_MIPS32R2);
9054 t0 = tcg_temp_new();
9058 save_cpu_state(ctx, 1);
9059 gen_helper_rdhwr_cpunum(t0, cpu_env);
9060 gen_store_gpr(t0, rt);
9063 save_cpu_state(ctx, 1);
9064 gen_helper_rdhwr_synci_step(t0, cpu_env);
9065 gen_store_gpr(t0, rt);
9068 save_cpu_state(ctx, 1);
9069 gen_helper_rdhwr_cc(t0, cpu_env);
9070 gen_store_gpr(t0, rt);
9073 save_cpu_state(ctx, 1);
9074 gen_helper_rdhwr_ccres(t0, cpu_env);
9075 gen_store_gpr(t0, rt);
9078 #if defined(CONFIG_USER_ONLY)
9079 tcg_gen_ld_tl(t0, cpu_env, offsetof(CPUMIPSState, tls_value));
9080 gen_store_gpr(t0, rt);
9083 /* XXX: Some CPUs implement this in hardware.
9084 Not supported yet. */
9086 default: /* Invalid */
9087 MIPS_INVAL("rdhwr");
9088 generate_exception(ctx, EXCP_RI);
9094 static void handle_delay_slot(DisasContext *ctx, int insn_bytes)
9096 if (ctx->hflags & MIPS_HFLAG_BMASK) {
9097 int proc_hflags = ctx->hflags & MIPS_HFLAG_BMASK;
9098 /* Branches completion */
9099 ctx->hflags &= ~MIPS_HFLAG_BMASK;
9100 ctx->bstate = BS_BRANCH;
9101 save_cpu_state(ctx, 0);
9102 /* FIXME: Need to clear can_do_io. */
9103 switch (proc_hflags & MIPS_HFLAG_BMASK_BASE) {
9105 /* unconditional branch */
9106 MIPS_DEBUG("unconditional branch");
9107 if (proc_hflags & MIPS_HFLAG_BX) {
9108 tcg_gen_xori_i32(hflags, hflags, MIPS_HFLAG_M16);
9110 gen_goto_tb(ctx, 0, ctx->btarget);
9113 /* blikely taken case */
9114 MIPS_DEBUG("blikely branch taken");
9115 gen_goto_tb(ctx, 0, ctx->btarget);
9118 /* Conditional branch */
9119 MIPS_DEBUG("conditional branch");
9121 int l1 = gen_new_label();
9123 tcg_gen_brcondi_tl(TCG_COND_NE, bcond, 0, l1);
9124 gen_goto_tb(ctx, 1, ctx->pc + insn_bytes);
9126 gen_goto_tb(ctx, 0, ctx->btarget);
9130 /* unconditional branch to register */
9131 MIPS_DEBUG("branch to register");
9132 if (ctx->insn_flags & (ASE_MIPS16 | ASE_MICROMIPS)) {
9133 TCGv t0 = tcg_temp_new();
9134 TCGv_i32 t1 = tcg_temp_new_i32();
9136 tcg_gen_andi_tl(t0, btarget, 0x1);
9137 tcg_gen_trunc_tl_i32(t1, t0);
9139 tcg_gen_andi_i32(hflags, hflags, ~(uint32_t)MIPS_HFLAG_M16);
9140 tcg_gen_shli_i32(t1, t1, MIPS_HFLAG_M16_SHIFT);
9141 tcg_gen_or_i32(hflags, hflags, t1);
9142 tcg_temp_free_i32(t1);
9144 tcg_gen_andi_tl(cpu_PC, btarget, ~(target_ulong)0x1);
9146 tcg_gen_mov_tl(cpu_PC, btarget);
9148 if (ctx->singlestep_enabled) {
9149 save_cpu_state(ctx, 0);
9150 gen_helper_0e0i(raise_exception, EXCP_DEBUG);
9155 MIPS_DEBUG("unknown branch");
9161 /* ISA extensions (ASEs) */
9162 /* MIPS16 extension to MIPS32 */
9164 /* MIPS16 major opcodes */
9166 M16_OPC_ADDIUSP = 0x00,
9167 M16_OPC_ADDIUPC = 0x01,
9170 M16_OPC_BEQZ = 0x04,
9171 M16_OPC_BNEQZ = 0x05,
9172 M16_OPC_SHIFT = 0x06,
9174 M16_OPC_RRIA = 0x08,
9175 M16_OPC_ADDIU8 = 0x09,
9176 M16_OPC_SLTI = 0x0a,
9177 M16_OPC_SLTIU = 0x0b,
9180 M16_OPC_CMPI = 0x0e,
9184 M16_OPC_LWSP = 0x12,
9188 M16_OPC_LWPC = 0x16,
9192 M16_OPC_SWSP = 0x1a,
9196 M16_OPC_EXTEND = 0x1e,
9200 /* I8 funct field */
9219 /* RR funct field */
9253 /* I64 funct field */
9265 /* RR ry field for CNVT */
9267 RR_RY_CNVT_ZEB = 0x0,
9268 RR_RY_CNVT_ZEH = 0x1,
9269 RR_RY_CNVT_ZEW = 0x2,
9270 RR_RY_CNVT_SEB = 0x4,
9271 RR_RY_CNVT_SEH = 0x5,
9272 RR_RY_CNVT_SEW = 0x6,
9275 static int xlat (int r)
9277 static int map[] = { 16, 17, 2, 3, 4, 5, 6, 7 };
9282 static void gen_mips16_save (DisasContext *ctx,
9283 int xsregs, int aregs,
9284 int do_ra, int do_s0, int do_s1,
9287 TCGv t0 = tcg_temp_new();
9288 TCGv t1 = tcg_temp_new();
9318 generate_exception(ctx, EXCP_RI);
9324 gen_base_offset_addr(ctx, t0, 29, 12);
9325 gen_load_gpr(t1, 7);
9326 tcg_gen_qemu_st32(t1, t0, ctx->mem_idx);
9329 gen_base_offset_addr(ctx, t0, 29, 8);
9330 gen_load_gpr(t1, 6);
9331 tcg_gen_qemu_st32(t1, t0, ctx->mem_idx);
9334 gen_base_offset_addr(ctx, t0, 29, 4);
9335 gen_load_gpr(t1, 5);
9336 tcg_gen_qemu_st32(t1, t0, ctx->mem_idx);
9339 gen_base_offset_addr(ctx, t0, 29, 0);
9340 gen_load_gpr(t1, 4);
9341 tcg_gen_qemu_st32(t1, t0, ctx->mem_idx);
9344 gen_load_gpr(t0, 29);
9346 #define DECR_AND_STORE(reg) do { \
9347 tcg_gen_subi_tl(t0, t0, 4); \
9348 gen_load_gpr(t1, reg); \
9349 tcg_gen_qemu_st32(t1, t0, ctx->mem_idx); \
9413 generate_exception(ctx, EXCP_RI);
9429 #undef DECR_AND_STORE
9431 tcg_gen_subi_tl(cpu_gpr[29], cpu_gpr[29], framesize);
9436 static void gen_mips16_restore (DisasContext *ctx,
9437 int xsregs, int aregs,
9438 int do_ra, int do_s0, int do_s1,
9442 TCGv t0 = tcg_temp_new();
9443 TCGv t1 = tcg_temp_new();
9445 tcg_gen_addi_tl(t0, cpu_gpr[29], framesize);
9447 #define DECR_AND_LOAD(reg) do { \
9448 tcg_gen_subi_tl(t0, t0, 4); \
9449 tcg_gen_qemu_ld32u(t1, t0, ctx->mem_idx); \
9450 gen_store_gpr(t1, reg); \
9514 generate_exception(ctx, EXCP_RI);
9530 #undef DECR_AND_LOAD
9532 tcg_gen_addi_tl(cpu_gpr[29], cpu_gpr[29], framesize);
9537 static void gen_addiupc (DisasContext *ctx, int rx, int imm,
9538 int is_64_bit, int extended)
9542 if (extended && (ctx->hflags & MIPS_HFLAG_BMASK)) {
9543 generate_exception(ctx, EXCP_RI);
9547 t0 = tcg_temp_new();
9549 tcg_gen_movi_tl(t0, pc_relative_pc(ctx));
9550 tcg_gen_addi_tl(cpu_gpr[rx], t0, imm);
9552 tcg_gen_ext32s_tl(cpu_gpr[rx], cpu_gpr[rx]);
9558 #if defined(TARGET_MIPS64)
9559 static void decode_i64_mips16 (DisasContext *ctx,
9560 int ry, int funct, int16_t offset,
9566 offset = extended ? offset : offset << 3;
9567 gen_ld(ctx, OPC_LD, ry, 29, offset);
9571 offset = extended ? offset : offset << 3;
9572 gen_st(ctx, OPC_SD, ry, 29, offset);
9576 offset = extended ? offset : (ctx->opcode & 0xff) << 3;
9577 gen_st(ctx, OPC_SD, 31, 29, offset);
9581 offset = extended ? offset : ((int8_t)ctx->opcode) << 3;
9582 gen_arith_imm(ctx, OPC_DADDIU, 29, 29, offset);
9585 if (extended && (ctx->hflags & MIPS_HFLAG_BMASK)) {
9586 generate_exception(ctx, EXCP_RI);
9588 offset = extended ? offset : offset << 3;
9589 gen_ld(ctx, OPC_LDPC, ry, 0, offset);
9594 offset = extended ? offset : ((int8_t)(offset << 3)) >> 3;
9595 gen_arith_imm(ctx, OPC_DADDIU, ry, ry, offset);
9599 offset = extended ? offset : offset << 2;
9600 gen_addiupc(ctx, ry, offset, 1, extended);
9604 offset = extended ? offset : offset << 2;
9605 gen_arith_imm(ctx, OPC_DADDIU, ry, 29, offset);
9611 static int decode_extended_mips16_opc (CPUMIPSState *env, DisasContext *ctx,
9614 int extend = cpu_lduw_code(env, ctx->pc + 2);
9615 int op, rx, ry, funct, sa;
9616 int16_t imm, offset;
9618 ctx->opcode = (ctx->opcode << 16) | extend;
9619 op = (ctx->opcode >> 11) & 0x1f;
9620 sa = (ctx->opcode >> 22) & 0x1f;
9621 funct = (ctx->opcode >> 8) & 0x7;
9622 rx = xlat((ctx->opcode >> 8) & 0x7);
9623 ry = xlat((ctx->opcode >> 5) & 0x7);
9624 offset = imm = (int16_t) (((ctx->opcode >> 16) & 0x1f) << 11
9625 | ((ctx->opcode >> 21) & 0x3f) << 5
9626 | (ctx->opcode & 0x1f));
9628 /* The extended opcodes cleverly reuse the opcodes from their 16-bit
9631 case M16_OPC_ADDIUSP:
9632 gen_arith_imm(ctx, OPC_ADDIU, rx, 29, imm);
9634 case M16_OPC_ADDIUPC:
9635 gen_addiupc(ctx, rx, imm, 0, 1);
9638 gen_compute_branch(ctx, OPC_BEQ, 4, 0, 0, offset << 1);
9639 /* No delay slot, so just process as a normal instruction */
9642 gen_compute_branch(ctx, OPC_BEQ, 4, rx, 0, offset << 1);
9643 /* No delay slot, so just process as a normal instruction */
9646 gen_compute_branch(ctx, OPC_BNE, 4, rx, 0, offset << 1);
9647 /* No delay slot, so just process as a normal instruction */
9650 switch (ctx->opcode & 0x3) {
9652 gen_shift_imm(ctx, OPC_SLL, rx, ry, sa);
9655 #if defined(TARGET_MIPS64)
9657 gen_shift_imm(ctx, OPC_DSLL, rx, ry, sa);
9659 generate_exception(ctx, EXCP_RI);
9663 gen_shift_imm(ctx, OPC_SRL, rx, ry, sa);
9666 gen_shift_imm(ctx, OPC_SRA, rx, ry, sa);
9670 #if defined(TARGET_MIPS64)
9673 gen_ld(ctx, OPC_LD, ry, rx, offset);
9677 imm = ctx->opcode & 0xf;
9678 imm = imm | ((ctx->opcode >> 20) & 0x7f) << 4;
9679 imm = imm | ((ctx->opcode >> 16) & 0xf) << 11;
9680 imm = (int16_t) (imm << 1) >> 1;
9681 if ((ctx->opcode >> 4) & 0x1) {
9682 #if defined(TARGET_MIPS64)
9684 gen_arith_imm(ctx, OPC_DADDIU, ry, rx, imm);
9686 generate_exception(ctx, EXCP_RI);
9689 gen_arith_imm(ctx, OPC_ADDIU, ry, rx, imm);
9692 case M16_OPC_ADDIU8:
9693 gen_arith_imm(ctx, OPC_ADDIU, rx, rx, imm);
9696 gen_slt_imm(ctx, OPC_SLTI, 24, rx, imm);
9699 gen_slt_imm(ctx, OPC_SLTIU, 24, rx, imm);
9704 gen_compute_branch(ctx, OPC_BEQ, 4, 24, 0, offset << 1);
9707 gen_compute_branch(ctx, OPC_BNE, 4, 24, 0, offset << 1);
9710 gen_st(ctx, OPC_SW, 31, 29, imm);
9713 gen_arith_imm(ctx, OPC_ADDIU, 29, 29, imm);
9717 int xsregs = (ctx->opcode >> 24) & 0x7;
9718 int aregs = (ctx->opcode >> 16) & 0xf;
9719 int do_ra = (ctx->opcode >> 6) & 0x1;
9720 int do_s0 = (ctx->opcode >> 5) & 0x1;
9721 int do_s1 = (ctx->opcode >> 4) & 0x1;
9722 int framesize = (((ctx->opcode >> 20) & 0xf) << 4
9723 | (ctx->opcode & 0xf)) << 3;
9725 if (ctx->opcode & (1 << 7)) {
9726 gen_mips16_save(ctx, xsregs, aregs,
9727 do_ra, do_s0, do_s1,
9730 gen_mips16_restore(ctx, xsregs, aregs,
9731 do_ra, do_s0, do_s1,
9737 generate_exception(ctx, EXCP_RI);
9742 tcg_gen_movi_tl(cpu_gpr[rx], (uint16_t) imm);
9745 tcg_gen_xori_tl(cpu_gpr[24], cpu_gpr[rx], (uint16_t) imm);
9747 #if defined(TARGET_MIPS64)
9749 gen_st(ctx, OPC_SD, ry, rx, offset);
9753 gen_ld(ctx, OPC_LB, ry, rx, offset);
9756 gen_ld(ctx, OPC_LH, ry, rx, offset);
9759 gen_ld(ctx, OPC_LW, rx, 29, offset);
9762 gen_ld(ctx, OPC_LW, ry, rx, offset);
9765 gen_ld(ctx, OPC_LBU, ry, rx, offset);
9768 gen_ld(ctx, OPC_LHU, ry, rx, offset);
9771 gen_ld(ctx, OPC_LWPC, rx, 0, offset);
9773 #if defined(TARGET_MIPS64)
9775 gen_ld(ctx, OPC_LWU, ry, rx, offset);
9779 gen_st(ctx, OPC_SB, ry, rx, offset);
9782 gen_st(ctx, OPC_SH, ry, rx, offset);
9785 gen_st(ctx, OPC_SW, rx, 29, offset);
9788 gen_st(ctx, OPC_SW, ry, rx, offset);
9790 #if defined(TARGET_MIPS64)
9792 decode_i64_mips16(ctx, ry, funct, offset, 1);
9796 generate_exception(ctx, EXCP_RI);
9803 static int decode_mips16_opc (CPUMIPSState *env, DisasContext *ctx,
9808 int op, cnvt_op, op1, offset;
9812 op = (ctx->opcode >> 11) & 0x1f;
9813 sa = (ctx->opcode >> 2) & 0x7;
9814 sa = sa == 0 ? 8 : sa;
9815 rx = xlat((ctx->opcode >> 8) & 0x7);
9816 cnvt_op = (ctx->opcode >> 5) & 0x7;
9817 ry = xlat((ctx->opcode >> 5) & 0x7);
9818 op1 = offset = ctx->opcode & 0x1f;
9823 case M16_OPC_ADDIUSP:
9825 int16_t imm = ((uint8_t) ctx->opcode) << 2;
9827 gen_arith_imm(ctx, OPC_ADDIU, rx, 29, imm);
9830 case M16_OPC_ADDIUPC:
9831 gen_addiupc(ctx, rx, ((uint8_t) ctx->opcode) << 2, 0, 0);
9834 offset = (ctx->opcode & 0x7ff) << 1;
9835 offset = (int16_t)(offset << 4) >> 4;
9836 gen_compute_branch(ctx, OPC_BEQ, 2, 0, 0, offset);
9837 /* No delay slot, so just process as a normal instruction */
9840 offset = cpu_lduw_code(env, ctx->pc + 2);
9841 offset = (((ctx->opcode & 0x1f) << 21)
9842 | ((ctx->opcode >> 5) & 0x1f) << 16
9844 op = ((ctx->opcode >> 10) & 0x1) ? OPC_JALXS : OPC_JALS;
9845 gen_compute_branch(ctx, op, 4, rx, ry, offset);
9850 gen_compute_branch(ctx, OPC_BEQ, 2, rx, 0, ((int8_t)ctx->opcode) << 1);
9851 /* No delay slot, so just process as a normal instruction */
9854 gen_compute_branch(ctx, OPC_BNE, 2, rx, 0, ((int8_t)ctx->opcode) << 1);
9855 /* No delay slot, so just process as a normal instruction */
9858 switch (ctx->opcode & 0x3) {
9860 gen_shift_imm(ctx, OPC_SLL, rx, ry, sa);
9863 #if defined(TARGET_MIPS64)
9865 gen_shift_imm(ctx, OPC_DSLL, rx, ry, sa);
9867 generate_exception(ctx, EXCP_RI);
9871 gen_shift_imm(ctx, OPC_SRL, rx, ry, sa);
9874 gen_shift_imm(ctx, OPC_SRA, rx, ry, sa);
9878 #if defined(TARGET_MIPS64)
9881 gen_ld(ctx, OPC_LD, ry, rx, offset << 3);
9886 int16_t imm = (int8_t)((ctx->opcode & 0xf) << 4) >> 4;
9888 if ((ctx->opcode >> 4) & 1) {
9889 #if defined(TARGET_MIPS64)
9891 gen_arith_imm(ctx, OPC_DADDIU, ry, rx, imm);
9893 generate_exception(ctx, EXCP_RI);
9896 gen_arith_imm(ctx, OPC_ADDIU, ry, rx, imm);
9900 case M16_OPC_ADDIU8:
9902 int16_t imm = (int8_t) ctx->opcode;
9904 gen_arith_imm(ctx, OPC_ADDIU, rx, rx, imm);
9909 int16_t imm = (uint8_t) ctx->opcode;
9910 gen_slt_imm(ctx, OPC_SLTI, 24, rx, imm);
9915 int16_t imm = (uint8_t) ctx->opcode;
9916 gen_slt_imm(ctx, OPC_SLTIU, 24, rx, imm);
9923 funct = (ctx->opcode >> 8) & 0x7;
9926 gen_compute_branch(ctx, OPC_BEQ, 2, 24, 0,
9927 ((int8_t)ctx->opcode) << 1);
9930 gen_compute_branch(ctx, OPC_BNE, 2, 24, 0,
9931 ((int8_t)ctx->opcode) << 1);
9934 gen_st(ctx, OPC_SW, 31, 29, (ctx->opcode & 0xff) << 2);
9937 gen_arith_imm(ctx, OPC_ADDIU, 29, 29,
9938 ((int8_t)ctx->opcode) << 3);
9942 int do_ra = ctx->opcode & (1 << 6);
9943 int do_s0 = ctx->opcode & (1 << 5);
9944 int do_s1 = ctx->opcode & (1 << 4);
9945 int framesize = ctx->opcode & 0xf;
9947 if (framesize == 0) {
9950 framesize = framesize << 3;
9953 if (ctx->opcode & (1 << 7)) {
9954 gen_mips16_save(ctx, 0, 0,
9955 do_ra, do_s0, do_s1, framesize);
9957 gen_mips16_restore(ctx, 0, 0,
9958 do_ra, do_s0, do_s1, framesize);
9964 int rz = xlat(ctx->opcode & 0x7);
9966 reg32 = (((ctx->opcode >> 3) & 0x3) << 3) |
9967 ((ctx->opcode >> 5) & 0x7);
9968 gen_arith(ctx, OPC_ADDU, reg32, rz, 0);
9972 reg32 = ctx->opcode & 0x1f;
9973 gen_arith(ctx, OPC_ADDU, ry, reg32, 0);
9976 generate_exception(ctx, EXCP_RI);
9983 int16_t imm = (uint8_t) ctx->opcode;
9985 gen_arith_imm(ctx, OPC_ADDIU, rx, 0, imm);
9990 int16_t imm = (uint8_t) ctx->opcode;
9991 gen_logic_imm(ctx, OPC_XORI, 24, rx, imm);
9994 #if defined(TARGET_MIPS64)
9997 gen_st(ctx, OPC_SD, ry, rx, offset << 3);
10001 gen_ld(ctx, OPC_LB, ry, rx, offset);
10004 gen_ld(ctx, OPC_LH, ry, rx, offset << 1);
10007 gen_ld(ctx, OPC_LW, rx, 29, ((uint8_t)ctx->opcode) << 2);
10010 gen_ld(ctx, OPC_LW, ry, rx, offset << 2);
10013 gen_ld(ctx, OPC_LBU, ry, rx, offset);
10016 gen_ld(ctx, OPC_LHU, ry, rx, offset << 1);
10019 gen_ld(ctx, OPC_LWPC, rx, 0, ((uint8_t)ctx->opcode) << 2);
10021 #if defined (TARGET_MIPS64)
10023 check_mips_64(ctx);
10024 gen_ld(ctx, OPC_LWU, ry, rx, offset << 2);
10028 gen_st(ctx, OPC_SB, ry, rx, offset);
10031 gen_st(ctx, OPC_SH, ry, rx, offset << 1);
10034 gen_st(ctx, OPC_SW, rx, 29, ((uint8_t)ctx->opcode) << 2);
10037 gen_st(ctx, OPC_SW, ry, rx, offset << 2);
10041 int rz = xlat((ctx->opcode >> 2) & 0x7);
10044 switch (ctx->opcode & 0x3) {
10046 mips32_op = OPC_ADDU;
10049 mips32_op = OPC_SUBU;
10051 #if defined(TARGET_MIPS64)
10053 mips32_op = OPC_DADDU;
10054 check_mips_64(ctx);
10057 mips32_op = OPC_DSUBU;
10058 check_mips_64(ctx);
10062 generate_exception(ctx, EXCP_RI);
10066 gen_arith(ctx, mips32_op, rz, rx, ry);
10075 int nd = (ctx->opcode >> 7) & 0x1;
10076 int link = (ctx->opcode >> 6) & 0x1;
10077 int ra = (ctx->opcode >> 5) & 0x1;
10080 op = nd ? OPC_JALRC : OPC_JALRS;
10085 gen_compute_branch(ctx, op, 2, ra ? 31 : rx, 31, 0);
10092 /* XXX: not clear which exception should be raised
10093 * when in debug mode...
10095 check_insn(ctx, ISA_MIPS32);
10096 if (!(ctx->hflags & MIPS_HFLAG_DM)) {
10097 generate_exception(ctx, EXCP_DBp);
10099 generate_exception(ctx, EXCP_DBp);
10103 gen_slt(ctx, OPC_SLT, 24, rx, ry);
10106 gen_slt(ctx, OPC_SLTU, 24, rx, ry);
10109 generate_exception(ctx, EXCP_BREAK);
10112 gen_shift(ctx, OPC_SLLV, ry, rx, ry);
10115 gen_shift(ctx, OPC_SRLV, ry, rx, ry);
10118 gen_shift(ctx, OPC_SRAV, ry, rx, ry);
10120 #if defined (TARGET_MIPS64)
10122 check_mips_64(ctx);
10123 gen_shift_imm(ctx, OPC_DSRL, ry, ry, sa);
10127 gen_logic(ctx, OPC_XOR, 24, rx, ry);
10130 gen_arith(ctx, OPC_SUBU, rx, 0, ry);
10133 gen_logic(ctx, OPC_AND, rx, rx, ry);
10136 gen_logic(ctx, OPC_OR, rx, rx, ry);
10139 gen_logic(ctx, OPC_XOR, rx, rx, ry);
10142 gen_logic(ctx, OPC_NOR, rx, ry, 0);
10145 gen_HILO(ctx, OPC_MFHI, rx);
10149 case RR_RY_CNVT_ZEB:
10150 tcg_gen_ext8u_tl(cpu_gpr[rx], cpu_gpr[rx]);
10152 case RR_RY_CNVT_ZEH:
10153 tcg_gen_ext16u_tl(cpu_gpr[rx], cpu_gpr[rx]);
10155 case RR_RY_CNVT_SEB:
10156 tcg_gen_ext8s_tl(cpu_gpr[rx], cpu_gpr[rx]);
10158 case RR_RY_CNVT_SEH:
10159 tcg_gen_ext16s_tl(cpu_gpr[rx], cpu_gpr[rx]);
10161 #if defined (TARGET_MIPS64)
10162 case RR_RY_CNVT_ZEW:
10163 check_mips_64(ctx);
10164 tcg_gen_ext32u_tl(cpu_gpr[rx], cpu_gpr[rx]);
10166 case RR_RY_CNVT_SEW:
10167 check_mips_64(ctx);
10168 tcg_gen_ext32s_tl(cpu_gpr[rx], cpu_gpr[rx]);
10172 generate_exception(ctx, EXCP_RI);
10177 gen_HILO(ctx, OPC_MFLO, rx);
10179 #if defined (TARGET_MIPS64)
10181 check_mips_64(ctx);
10182 gen_shift_imm(ctx, OPC_DSRA, ry, ry, sa);
10185 check_mips_64(ctx);
10186 gen_shift(ctx, OPC_DSLLV, ry, rx, ry);
10189 check_mips_64(ctx);
10190 gen_shift(ctx, OPC_DSRLV, ry, rx, ry);
10193 check_mips_64(ctx);
10194 gen_shift(ctx, OPC_DSRAV, ry, rx, ry);
10198 gen_muldiv(ctx, OPC_MULT, rx, ry);
10201 gen_muldiv(ctx, OPC_MULTU, rx, ry);
10204 gen_muldiv(ctx, OPC_DIV, rx, ry);
10207 gen_muldiv(ctx, OPC_DIVU, rx, ry);
10209 #if defined (TARGET_MIPS64)
10211 check_mips_64(ctx);
10212 gen_muldiv(ctx, OPC_DMULT, rx, ry);
10215 check_mips_64(ctx);
10216 gen_muldiv(ctx, OPC_DMULTU, rx, ry);
10219 check_mips_64(ctx);
10220 gen_muldiv(ctx, OPC_DDIV, rx, ry);
10223 check_mips_64(ctx);
10224 gen_muldiv(ctx, OPC_DDIVU, rx, ry);
10228 generate_exception(ctx, EXCP_RI);
10232 case M16_OPC_EXTEND:
10233 decode_extended_mips16_opc(env, ctx, is_branch);
10236 #if defined(TARGET_MIPS64)
10238 funct = (ctx->opcode >> 8) & 0x7;
10239 decode_i64_mips16(ctx, ry, funct, offset, 0);
10243 generate_exception(ctx, EXCP_RI);
10250 /* microMIPS extension to MIPS32/MIPS64 */
10253 * microMIPS32/microMIPS64 major opcodes
10255 * 1. MIPS Architecture for Programmers Volume II-B:
10256 * The microMIPS32 Instruction Set (Revision 3.05)
10258 * Table 6.2 microMIPS32 Encoding of Major Opcode Field
10260 * 2. MIPS Architecture For Programmers Volume II-A:
10261 * The MIPS64 Instruction Set (Revision 3.51)
10289 POOL32S = 0x16, /* MIPS64 */
10290 DADDIU32 = 0x17, /* MIPS64 */
10292 /* 0x1f is reserved */
10301 /* 0x20 is reserved */
10311 /* 0x28 and 0x29 are reserved */
10321 /* 0x30 and 0x31 are reserved */
10328 SD32 = 0x36, /* MIPS64 */
10329 LD32 = 0x37, /* MIPS64 */
10331 /* 0x38 and 0x39 are reserved */
10342 /* POOL32A encoding of minor opcode field */
10345 /* These opcodes are distinguished only by bits 9..6; those bits are
10346 * what are recorded below. */
10372 /* The following can be distinguished by their lower 6 bits. */
10378 /* POOL32AXF encoding of minor opcode field extension */
10381 * 1. MIPS Architecture for Programmers Volume II-B:
10382 * The microMIPS32 Instruction Set (Revision 3.05)
10384 * Table 6.5 POOL32Axf Encoding of Minor Opcode Extension Field
10386 * 2. MIPS Architecture for Programmers VolumeIV-e:
10387 * The MIPS DSP Application-Specific Extension
10388 * to the microMIPS32 Architecture (Revision 2.34)
10390 * Table 5.5 POOL32Axf Encoding of Minor Opcode Extension Field
10405 /* begin of microMIPS32 DSP */
10407 /* bits 13..12 for 0x01 */
10413 /* bits 13..12 for 0x2a */
10419 /* bits 13..12 for 0x32 */
10423 /* end of microMIPS32 DSP */
10425 /* bits 15..12 for 0x2c */
10441 /* bits 15..12 for 0x34 */
10449 /* bits 15..12 for 0x3c */
10451 JR = 0x0, /* alias */
10456 /* bits 15..12 for 0x05 */
10460 /* bits 15..12 for 0x0d */
10470 /* bits 15..12 for 0x15 */
10476 /* bits 15..12 for 0x1d */
10480 /* bits 15..12 for 0x2d */
10485 /* bits 15..12 for 0x35 */
10492 /* POOL32B encoding of minor opcode field (bits 15..12) */
10508 /* POOL32C encoding of minor opcode field (bits 15..12) */
10516 /* 0xa is reserved */
10523 /* 0x6 is reserved */
10529 /* POOL32F encoding of minor opcode field (bits 5..0) */
10532 /* These are the bit 7..6 values */
10543 /* These are the bit 8..6 values */
10587 CABS_COND_FMT = 0x1c, /* MIPS3D */
10591 /* POOL32Fxf encoding of minor opcode extension field */
10629 /* POOL32I encoding of minor opcode field (bits 25..21) */
10654 /* These overlap and are distinguished by bit16 of the instruction */
10663 /* POOL16A encoding of minor opcode field */
10670 /* POOL16B encoding of minor opcode field */
10677 /* POOL16C encoding of minor opcode field */
10697 /* POOL16D encoding of minor opcode field */
10704 /* POOL16E encoding of minor opcode field */
10711 static int mmreg (int r)
10713 static const int map[] = { 16, 17, 2, 3, 4, 5, 6, 7 };
10718 /* Used for 16-bit store instructions. */
10719 static int mmreg2 (int r)
10721 static const int map[] = { 0, 17, 2, 3, 4, 5, 6, 7 };
10726 #define uMIPS_RD(op) ((op >> 7) & 0x7)
10727 #define uMIPS_RS(op) ((op >> 4) & 0x7)
10728 #define uMIPS_RS2(op) uMIPS_RS(op)
10729 #define uMIPS_RS1(op) ((op >> 1) & 0x7)
10730 #define uMIPS_RD5(op) ((op >> 5) & 0x1f)
10731 #define uMIPS_RS5(op) (op & 0x1f)
10733 /* Signed immediate */
10734 #define SIMM(op, start, width) \
10735 ((int32_t)(((op >> start) & ((~0U) >> (32-width))) \
10738 /* Zero-extended immediate */
10739 #define ZIMM(op, start, width) ((op >> start) & ((~0U) >> (32-width)))
10741 static void gen_addiur1sp(DisasContext *ctx)
10743 int rd = mmreg(uMIPS_RD(ctx->opcode));
10745 gen_arith_imm(ctx, OPC_ADDIU, rd, 29, ((ctx->opcode >> 1) & 0x3f) << 2);
10748 static void gen_addiur2(DisasContext *ctx)
10750 static const int decoded_imm[] = { 1, 4, 8, 12, 16, 20, 24, -1 };
10751 int rd = mmreg(uMIPS_RD(ctx->opcode));
10752 int rs = mmreg(uMIPS_RS(ctx->opcode));
10754 gen_arith_imm(ctx, OPC_ADDIU, rd, rs, decoded_imm[ZIMM(ctx->opcode, 1, 3)]);
10757 static void gen_addiusp(DisasContext *ctx)
10759 int encoded = ZIMM(ctx->opcode, 1, 9);
10762 if (encoded <= 1) {
10763 decoded = 256 + encoded;
10764 } else if (encoded <= 255) {
10766 } else if (encoded <= 509) {
10767 decoded = encoded - 512;
10769 decoded = encoded - 768;
10772 gen_arith_imm(ctx, OPC_ADDIU, 29, 29, decoded << 2);
10775 static void gen_addius5(DisasContext *ctx)
10777 int imm = SIMM(ctx->opcode, 1, 4);
10778 int rd = (ctx->opcode >> 5) & 0x1f;
10780 gen_arith_imm(ctx, OPC_ADDIU, rd, rd, imm);
10783 static void gen_andi16(DisasContext *ctx)
10785 static const int decoded_imm[] = { 128, 1, 2, 3, 4, 7, 8, 15, 16,
10786 31, 32, 63, 64, 255, 32768, 65535 };
10787 int rd = mmreg(uMIPS_RD(ctx->opcode));
10788 int rs = mmreg(uMIPS_RS(ctx->opcode));
10789 int encoded = ZIMM(ctx->opcode, 0, 4);
10791 gen_logic_imm(ctx, OPC_ANDI, rd, rs, decoded_imm[encoded]);
10794 static void gen_ldst_multiple (DisasContext *ctx, uint32_t opc, int reglist,
10795 int base, int16_t offset)
10797 const char *opn = "ldst_multiple";
10801 if (ctx->hflags & MIPS_HFLAG_BMASK) {
10802 generate_exception(ctx, EXCP_RI);
10806 t0 = tcg_temp_new();
10808 gen_base_offset_addr(ctx, t0, base, offset);
10810 t1 = tcg_const_tl(reglist);
10811 t2 = tcg_const_i32(ctx->mem_idx);
10813 save_cpu_state(ctx, 1);
10816 gen_helper_lwm(cpu_env, t0, t1, t2);
10820 gen_helper_swm(cpu_env, t0, t1, t2);
10823 #ifdef TARGET_MIPS64
10825 gen_helper_ldm(cpu_env, t0, t1, t2);
10829 gen_helper_sdm(cpu_env, t0, t1, t2);
10835 MIPS_DEBUG("%s, %x, %d(%s)", opn, reglist, offset, regnames[base]);
10838 tcg_temp_free_i32(t2);
10842 static void gen_pool16c_insn(DisasContext *ctx, int *is_branch)
10844 int rd = mmreg((ctx->opcode >> 3) & 0x7);
10845 int rs = mmreg(ctx->opcode & 0x7);
10848 switch (((ctx->opcode) >> 4) & 0x3f) {
10853 gen_logic(ctx, OPC_NOR, rd, rs, 0);
10859 gen_logic(ctx, OPC_XOR, rd, rd, rs);
10865 gen_logic(ctx, OPC_AND, rd, rd, rs);
10871 gen_logic(ctx, OPC_OR, rd, rd, rs);
10878 static const int lwm_convert[] = { 0x11, 0x12, 0x13, 0x14 };
10879 int offset = ZIMM(ctx->opcode, 0, 4);
10881 gen_ldst_multiple(ctx, LWM32, lwm_convert[(ctx->opcode >> 4) & 0x3],
10890 static const int swm_convert[] = { 0x11, 0x12, 0x13, 0x14 };
10891 int offset = ZIMM(ctx->opcode, 0, 4);
10893 gen_ldst_multiple(ctx, SWM32, swm_convert[(ctx->opcode >> 4) & 0x3],
10900 int reg = ctx->opcode & 0x1f;
10902 gen_compute_branch(ctx, OPC_JR, 2, reg, 0, 0);
10909 int reg = ctx->opcode & 0x1f;
10911 gen_compute_branch(ctx, OPC_JR, 2, reg, 0, 0);
10912 /* Let normal delay slot handling in our caller take us
10913 to the branch target. */
10925 int reg = ctx->opcode & 0x1f;
10927 gen_compute_branch(ctx, opc, 2, reg, 31, 0);
10933 gen_HILO(ctx, OPC_MFHI, uMIPS_RS5(ctx->opcode));
10937 gen_HILO(ctx, OPC_MFLO, uMIPS_RS5(ctx->opcode));
10940 generate_exception(ctx, EXCP_BREAK);
10943 /* XXX: not clear which exception should be raised
10944 * when in debug mode...
10946 check_insn(ctx, ISA_MIPS32);
10947 if (!(ctx->hflags & MIPS_HFLAG_DM)) {
10948 generate_exception(ctx, EXCP_DBp);
10950 generate_exception(ctx, EXCP_DBp);
10953 case JRADDIUSP + 0:
10954 case JRADDIUSP + 1:
10956 int imm = ZIMM(ctx->opcode, 0, 5);
10958 gen_compute_branch(ctx, OPC_JR, 2, 31, 0, 0);
10959 gen_arith_imm(ctx, OPC_ADDIU, 29, 29, imm << 2);
10960 /* Let normal delay slot handling in our caller take us
10961 to the branch target. */
10965 generate_exception(ctx, EXCP_RI);
10970 static void gen_ldxs (DisasContext *ctx, int base, int index, int rd)
10972 TCGv t0 = tcg_temp_new();
10973 TCGv t1 = tcg_temp_new();
10975 gen_load_gpr(t0, base);
10978 gen_load_gpr(t1, index);
10979 tcg_gen_shli_tl(t1, t1, 2);
10980 gen_op_addr_add(ctx, t0, t1, t0);
10983 tcg_gen_qemu_ld32s(t1, t0, ctx->mem_idx);
10984 gen_store_gpr(t1, rd);
10990 static void gen_ldst_pair (DisasContext *ctx, uint32_t opc, int rd,
10991 int base, int16_t offset)
10993 const char *opn = "ldst_pair";
10996 if (ctx->hflags & MIPS_HFLAG_BMASK || rd == 31) {
10997 generate_exception(ctx, EXCP_RI);
11001 t0 = tcg_temp_new();
11002 t1 = tcg_temp_new();
11004 gen_base_offset_addr(ctx, t0, base, offset);
11009 generate_exception(ctx, EXCP_RI);
11012 tcg_gen_qemu_ld32s(t1, t0, ctx->mem_idx);
11013 gen_store_gpr(t1, rd);
11014 tcg_gen_movi_tl(t1, 4);
11015 gen_op_addr_add(ctx, t0, t0, t1);
11016 tcg_gen_qemu_ld32s(t1, t0, ctx->mem_idx);
11017 gen_store_gpr(t1, rd+1);
11021 gen_load_gpr(t1, rd);
11022 tcg_gen_qemu_st32(t1, t0, ctx->mem_idx);
11023 tcg_gen_movi_tl(t1, 4);
11024 gen_op_addr_add(ctx, t0, t0, t1);
11025 gen_load_gpr(t1, rd+1);
11026 tcg_gen_qemu_st32(t1, t0, ctx->mem_idx);
11029 #ifdef TARGET_MIPS64
11032 generate_exception(ctx, EXCP_RI);
11035 tcg_gen_qemu_ld64(t1, t0, ctx->mem_idx);
11036 gen_store_gpr(t1, rd);
11037 tcg_gen_movi_tl(t1, 8);
11038 gen_op_addr_add(ctx, t0, t0, t1);
11039 tcg_gen_qemu_ld64(t1, t0, ctx->mem_idx);
11040 gen_store_gpr(t1, rd+1);
11044 gen_load_gpr(t1, rd);
11045 tcg_gen_qemu_st64(t1, t0, ctx->mem_idx);
11046 tcg_gen_movi_tl(t1, 8);
11047 gen_op_addr_add(ctx, t0, t0, t1);
11048 gen_load_gpr(t1, rd+1);
11049 tcg_gen_qemu_st64(t1, t0, ctx->mem_idx);
11054 (void)opn; /* avoid a compiler warning */
11055 MIPS_DEBUG("%s, %s, %d(%s)", opn, regnames[rd], offset, regnames[base]);
11060 static void gen_pool32axf (CPUMIPSState *env, DisasContext *ctx, int rt, int rs,
11063 int extension = (ctx->opcode >> 6) & 0x3f;
11064 int minor = (ctx->opcode >> 12) & 0xf;
11065 uint32_t mips32_op;
11067 switch (extension) {
11069 mips32_op = OPC_TEQ;
11072 mips32_op = OPC_TGE;
11075 mips32_op = OPC_TGEU;
11078 mips32_op = OPC_TLT;
11081 mips32_op = OPC_TLTU;
11084 mips32_op = OPC_TNE;
11086 gen_trap(ctx, mips32_op, rs, rt, -1);
11088 #ifndef CONFIG_USER_ONLY
11091 check_cp0_enabled(ctx);
11093 /* Treat as NOP. */
11096 gen_mfc0(ctx, cpu_gpr[rt], rs, (ctx->opcode >> 11) & 0x7);
11100 check_cp0_enabled(ctx);
11102 TCGv t0 = tcg_temp_new();
11104 gen_load_gpr(t0, rt);
11105 gen_mtc0(ctx, t0, rs, (ctx->opcode >> 11) & 0x7);
11113 gen_bshfl(ctx, OPC_SEB, rs, rt);
11116 gen_bshfl(ctx, OPC_SEH, rs, rt);
11119 mips32_op = OPC_CLO;
11122 mips32_op = OPC_CLZ;
11124 check_insn(ctx, ISA_MIPS32);
11125 gen_cl(ctx, mips32_op, rt, rs);
11128 gen_rdhwr(ctx, rt, rs);
11131 gen_bshfl(ctx, OPC_WSBH, rs, rt);
11134 mips32_op = OPC_MULT;
11137 mips32_op = OPC_MULTU;
11140 mips32_op = OPC_DIV;
11143 mips32_op = OPC_DIVU;
11146 mips32_op = OPC_MADD;
11149 mips32_op = OPC_MADDU;
11152 mips32_op = OPC_MSUB;
11155 mips32_op = OPC_MSUBU;
11157 check_insn(ctx, ISA_MIPS32);
11158 gen_muldiv(ctx, mips32_op, rs, rt);
11161 goto pool32axf_invalid;
11172 generate_exception_err(ctx, EXCP_CpU, 2);
11175 goto pool32axf_invalid;
11182 gen_compute_branch (ctx, OPC_JALR, 4, rs, rt, 0);
11187 gen_compute_branch (ctx, OPC_JALRS, 4, rs, rt, 0);
11191 goto pool32axf_invalid;
11197 check_cp0_enabled(ctx);
11198 check_insn(ctx, ISA_MIPS32R2);
11199 gen_load_srsgpr(rt, rs);
11202 check_cp0_enabled(ctx);
11203 check_insn(ctx, ISA_MIPS32R2);
11204 gen_store_srsgpr(rt, rs);
11207 goto pool32axf_invalid;
11210 #ifndef CONFIG_USER_ONLY
11214 mips32_op = OPC_TLBP;
11217 mips32_op = OPC_TLBR;
11220 mips32_op = OPC_TLBWI;
11223 mips32_op = OPC_TLBWR;
11226 mips32_op = OPC_WAIT;
11229 mips32_op = OPC_DERET;
11232 mips32_op = OPC_ERET;
11234 gen_cp0(env, ctx, mips32_op, rt, rs);
11237 goto pool32axf_invalid;
11243 check_cp0_enabled(ctx);
11245 TCGv t0 = tcg_temp_new();
11247 save_cpu_state(ctx, 1);
11248 gen_helper_di(t0, cpu_env);
11249 gen_store_gpr(t0, rs);
11250 /* Stop translation as we may have switched the execution mode */
11251 ctx->bstate = BS_STOP;
11256 check_cp0_enabled(ctx);
11258 TCGv t0 = tcg_temp_new();
11260 save_cpu_state(ctx, 1);
11261 gen_helper_ei(t0, cpu_env);
11262 gen_store_gpr(t0, rs);
11263 /* Stop translation as we may have switched the execution mode */
11264 ctx->bstate = BS_STOP;
11269 goto pool32axf_invalid;
11279 generate_exception(ctx, EXCP_SYSCALL);
11280 ctx->bstate = BS_STOP;
11283 check_insn(ctx, ISA_MIPS32);
11284 if (!(ctx->hflags & MIPS_HFLAG_DM)) {
11285 generate_exception(ctx, EXCP_DBp);
11287 generate_exception(ctx, EXCP_DBp);
11291 goto pool32axf_invalid;
11297 gen_HILO(ctx, OPC_MFHI, rs);
11300 gen_HILO(ctx, OPC_MFLO, rs);
11303 gen_HILO(ctx, OPC_MTHI, rs);
11306 gen_HILO(ctx, OPC_MTLO, rs);
11309 goto pool32axf_invalid;
11314 MIPS_INVAL("pool32axf");
11315 generate_exception(ctx, EXCP_RI);
11320 /* Values for microMIPS fmt field. Variable-width, depending on which
11321 formats the instruction supports. */
11340 static void gen_pool32fxf(DisasContext *ctx, int rt, int rs)
11342 int extension = (ctx->opcode >> 6) & 0x3ff;
11343 uint32_t mips32_op;
11345 #define FLOAT_1BIT_FMT(opc, fmt) (fmt << 8) | opc
11346 #define FLOAT_2BIT_FMT(opc, fmt) (fmt << 7) | opc
11347 #define COND_FLOAT_MOV(opc, cond) (cond << 7) | opc
11349 switch (extension) {
11350 case FLOAT_1BIT_FMT(CFC1, 0):
11351 mips32_op = OPC_CFC1;
11353 case FLOAT_1BIT_FMT(CTC1, 0):
11354 mips32_op = OPC_CTC1;
11356 case FLOAT_1BIT_FMT(MFC1, 0):
11357 mips32_op = OPC_MFC1;
11359 case FLOAT_1BIT_FMT(MTC1, 0):
11360 mips32_op = OPC_MTC1;
11362 case FLOAT_1BIT_FMT(MFHC1, 0):
11363 mips32_op = OPC_MFHC1;
11365 case FLOAT_1BIT_FMT(MTHC1, 0):
11366 mips32_op = OPC_MTHC1;
11368 gen_cp1(ctx, mips32_op, rt, rs);
11371 /* Reciprocal square root */
11372 case FLOAT_1BIT_FMT(RSQRT_FMT, FMT_SD_S):
11373 mips32_op = OPC_RSQRT_S;
11375 case FLOAT_1BIT_FMT(RSQRT_FMT, FMT_SD_D):
11376 mips32_op = OPC_RSQRT_D;
11380 case FLOAT_1BIT_FMT(SQRT_FMT, FMT_SD_S):
11381 mips32_op = OPC_SQRT_S;
11383 case FLOAT_1BIT_FMT(SQRT_FMT, FMT_SD_D):
11384 mips32_op = OPC_SQRT_D;
11388 case FLOAT_1BIT_FMT(RECIP_FMT, FMT_SD_S):
11389 mips32_op = OPC_RECIP_S;
11391 case FLOAT_1BIT_FMT(RECIP_FMT, FMT_SD_D):
11392 mips32_op = OPC_RECIP_D;
11396 case FLOAT_1BIT_FMT(FLOOR_L, FMT_SD_S):
11397 mips32_op = OPC_FLOOR_L_S;
11399 case FLOAT_1BIT_FMT(FLOOR_L, FMT_SD_D):
11400 mips32_op = OPC_FLOOR_L_D;
11402 case FLOAT_1BIT_FMT(FLOOR_W, FMT_SD_S):
11403 mips32_op = OPC_FLOOR_W_S;
11405 case FLOAT_1BIT_FMT(FLOOR_W, FMT_SD_D):
11406 mips32_op = OPC_FLOOR_W_D;
11410 case FLOAT_1BIT_FMT(CEIL_L, FMT_SD_S):
11411 mips32_op = OPC_CEIL_L_S;
11413 case FLOAT_1BIT_FMT(CEIL_L, FMT_SD_D):
11414 mips32_op = OPC_CEIL_L_D;
11416 case FLOAT_1BIT_FMT(CEIL_W, FMT_SD_S):
11417 mips32_op = OPC_CEIL_W_S;
11419 case FLOAT_1BIT_FMT(CEIL_W, FMT_SD_D):
11420 mips32_op = OPC_CEIL_W_D;
11424 case FLOAT_1BIT_FMT(TRUNC_L, FMT_SD_S):
11425 mips32_op = OPC_TRUNC_L_S;
11427 case FLOAT_1BIT_FMT(TRUNC_L, FMT_SD_D):
11428 mips32_op = OPC_TRUNC_L_D;
11430 case FLOAT_1BIT_FMT(TRUNC_W, FMT_SD_S):
11431 mips32_op = OPC_TRUNC_W_S;
11433 case FLOAT_1BIT_FMT(TRUNC_W, FMT_SD_D):
11434 mips32_op = OPC_TRUNC_W_D;
11438 case FLOAT_1BIT_FMT(ROUND_L, FMT_SD_S):
11439 mips32_op = OPC_ROUND_L_S;
11441 case FLOAT_1BIT_FMT(ROUND_L, FMT_SD_D):
11442 mips32_op = OPC_ROUND_L_D;
11444 case FLOAT_1BIT_FMT(ROUND_W, FMT_SD_S):
11445 mips32_op = OPC_ROUND_W_S;
11447 case FLOAT_1BIT_FMT(ROUND_W, FMT_SD_D):
11448 mips32_op = OPC_ROUND_W_D;
11451 /* Integer to floating-point conversion */
11452 case FLOAT_1BIT_FMT(CVT_L, FMT_SD_S):
11453 mips32_op = OPC_CVT_L_S;
11455 case FLOAT_1BIT_FMT(CVT_L, FMT_SD_D):
11456 mips32_op = OPC_CVT_L_D;
11458 case FLOAT_1BIT_FMT(CVT_W, FMT_SD_S):
11459 mips32_op = OPC_CVT_W_S;
11461 case FLOAT_1BIT_FMT(CVT_W, FMT_SD_D):
11462 mips32_op = OPC_CVT_W_D;
11465 /* Paired-foo conversions */
11466 case FLOAT_1BIT_FMT(CVT_S_PL, 0):
11467 mips32_op = OPC_CVT_S_PL;
11469 case FLOAT_1BIT_FMT(CVT_S_PU, 0):
11470 mips32_op = OPC_CVT_S_PU;
11472 case FLOAT_1BIT_FMT(CVT_PW_PS, 0):
11473 mips32_op = OPC_CVT_PW_PS;
11475 case FLOAT_1BIT_FMT(CVT_PS_PW, 0):
11476 mips32_op = OPC_CVT_PS_PW;
11479 /* Floating-point moves */
11480 case FLOAT_2BIT_FMT(MOV_FMT, FMT_SDPS_S):
11481 mips32_op = OPC_MOV_S;
11483 case FLOAT_2BIT_FMT(MOV_FMT, FMT_SDPS_D):
11484 mips32_op = OPC_MOV_D;
11486 case FLOAT_2BIT_FMT(MOV_FMT, FMT_SDPS_PS):
11487 mips32_op = OPC_MOV_PS;
11490 /* Absolute value */
11491 case FLOAT_2BIT_FMT(ABS_FMT, FMT_SDPS_S):
11492 mips32_op = OPC_ABS_S;
11494 case FLOAT_2BIT_FMT(ABS_FMT, FMT_SDPS_D):
11495 mips32_op = OPC_ABS_D;
11497 case FLOAT_2BIT_FMT(ABS_FMT, FMT_SDPS_PS):
11498 mips32_op = OPC_ABS_PS;
11502 case FLOAT_2BIT_FMT(NEG_FMT, FMT_SDPS_S):
11503 mips32_op = OPC_NEG_S;
11505 case FLOAT_2BIT_FMT(NEG_FMT, FMT_SDPS_D):
11506 mips32_op = OPC_NEG_D;
11508 case FLOAT_2BIT_FMT(NEG_FMT, FMT_SDPS_PS):
11509 mips32_op = OPC_NEG_PS;
11512 /* Reciprocal square root step */
11513 case FLOAT_2BIT_FMT(RSQRT1_FMT, FMT_SDPS_S):
11514 mips32_op = OPC_RSQRT1_S;
11516 case FLOAT_2BIT_FMT(RSQRT1_FMT, FMT_SDPS_D):
11517 mips32_op = OPC_RSQRT1_D;
11519 case FLOAT_2BIT_FMT(RSQRT1_FMT, FMT_SDPS_PS):
11520 mips32_op = OPC_RSQRT1_PS;
11523 /* Reciprocal step */
11524 case FLOAT_2BIT_FMT(RECIP1_FMT, FMT_SDPS_S):
11525 mips32_op = OPC_RECIP1_S;
11527 case FLOAT_2BIT_FMT(RECIP1_FMT, FMT_SDPS_D):
11528 mips32_op = OPC_RECIP1_S;
11530 case FLOAT_2BIT_FMT(RECIP1_FMT, FMT_SDPS_PS):
11531 mips32_op = OPC_RECIP1_PS;
11534 /* Conversions from double */
11535 case FLOAT_2BIT_FMT(CVT_D, FMT_SWL_S):
11536 mips32_op = OPC_CVT_D_S;
11538 case FLOAT_2BIT_FMT(CVT_D, FMT_SWL_W):
11539 mips32_op = OPC_CVT_D_W;
11541 case FLOAT_2BIT_FMT(CVT_D, FMT_SWL_L):
11542 mips32_op = OPC_CVT_D_L;
11545 /* Conversions from single */
11546 case FLOAT_2BIT_FMT(CVT_S, FMT_DWL_D):
11547 mips32_op = OPC_CVT_S_D;
11549 case FLOAT_2BIT_FMT(CVT_S, FMT_DWL_W):
11550 mips32_op = OPC_CVT_S_W;
11552 case FLOAT_2BIT_FMT(CVT_S, FMT_DWL_L):
11553 mips32_op = OPC_CVT_S_L;
11555 gen_farith(ctx, mips32_op, -1, rs, rt, 0);
11558 /* Conditional moves on floating-point codes */
11559 case COND_FLOAT_MOV(MOVT, 0):
11560 case COND_FLOAT_MOV(MOVT, 1):
11561 case COND_FLOAT_MOV(MOVT, 2):
11562 case COND_FLOAT_MOV(MOVT, 3):
11563 case COND_FLOAT_MOV(MOVT, 4):
11564 case COND_FLOAT_MOV(MOVT, 5):
11565 case COND_FLOAT_MOV(MOVT, 6):
11566 case COND_FLOAT_MOV(MOVT, 7):
11567 gen_movci(ctx, rt, rs, (ctx->opcode >> 13) & 0x7, 1);
11569 case COND_FLOAT_MOV(MOVF, 0):
11570 case COND_FLOAT_MOV(MOVF, 1):
11571 case COND_FLOAT_MOV(MOVF, 2):
11572 case COND_FLOAT_MOV(MOVF, 3):
11573 case COND_FLOAT_MOV(MOVF, 4):
11574 case COND_FLOAT_MOV(MOVF, 5):
11575 case COND_FLOAT_MOV(MOVF, 6):
11576 case COND_FLOAT_MOV(MOVF, 7):
11577 gen_movci(ctx, rt, rs, (ctx->opcode >> 13) & 0x7, 0);
11580 MIPS_INVAL("pool32fxf");
11581 generate_exception(ctx, EXCP_RI);
11586 static void decode_micromips32_opc (CPUMIPSState *env, DisasContext *ctx,
11587 uint16_t insn_hw1, int *is_branch)
11591 int rt, rs, rd, rr;
11593 uint32_t op, minor, mips32_op;
11594 uint32_t cond, fmt, cc;
11596 insn = cpu_lduw_code(env, ctx->pc + 2);
11597 ctx->opcode = (ctx->opcode << 16) | insn;
11599 rt = (ctx->opcode >> 21) & 0x1f;
11600 rs = (ctx->opcode >> 16) & 0x1f;
11601 rd = (ctx->opcode >> 11) & 0x1f;
11602 rr = (ctx->opcode >> 6) & 0x1f;
11603 imm = (int16_t) ctx->opcode;
11605 op = (ctx->opcode >> 26) & 0x3f;
11608 minor = ctx->opcode & 0x3f;
11611 minor = (ctx->opcode >> 6) & 0xf;
11614 mips32_op = OPC_SLL;
11617 mips32_op = OPC_SRA;
11620 mips32_op = OPC_SRL;
11623 mips32_op = OPC_ROTR;
11625 gen_shift_imm(ctx, mips32_op, rt, rs, rd);
11628 goto pool32a_invalid;
11632 minor = (ctx->opcode >> 6) & 0xf;
11636 mips32_op = OPC_ADD;
11639 mips32_op = OPC_ADDU;
11642 mips32_op = OPC_SUB;
11645 mips32_op = OPC_SUBU;
11648 mips32_op = OPC_MUL;
11650 gen_arith(ctx, mips32_op, rd, rs, rt);
11654 mips32_op = OPC_SLLV;
11657 mips32_op = OPC_SRLV;
11660 mips32_op = OPC_SRAV;
11663 mips32_op = OPC_ROTRV;
11665 gen_shift(ctx, mips32_op, rd, rs, rt);
11667 /* Logical operations */
11669 mips32_op = OPC_AND;
11672 mips32_op = OPC_OR;
11675 mips32_op = OPC_NOR;
11678 mips32_op = OPC_XOR;
11680 gen_logic(ctx, mips32_op, rd, rs, rt);
11682 /* Set less than */
11684 mips32_op = OPC_SLT;
11687 mips32_op = OPC_SLTU;
11689 gen_slt(ctx, mips32_op, rd, rs, rt);
11692 goto pool32a_invalid;
11696 minor = (ctx->opcode >> 6) & 0xf;
11698 /* Conditional moves */
11700 mips32_op = OPC_MOVN;
11703 mips32_op = OPC_MOVZ;
11705 gen_cond_move(ctx, mips32_op, rd, rs, rt);
11708 gen_ldxs(ctx, rs, rt, rd);
11711 goto pool32a_invalid;
11715 gen_bitops(ctx, OPC_INS, rt, rs, rr, rd);
11718 gen_bitops(ctx, OPC_EXT, rt, rs, rr, rd);
11721 gen_pool32axf(env, ctx, rt, rs, is_branch);
11724 generate_exception(ctx, EXCP_BREAK);
11728 MIPS_INVAL("pool32a");
11729 generate_exception(ctx, EXCP_RI);
11734 minor = (ctx->opcode >> 12) & 0xf;
11737 check_cp0_enabled(ctx);
11738 /* Treat as no-op. */
11742 /* COP2: Not implemented. */
11743 generate_exception_err(ctx, EXCP_CpU, 2);
11747 #ifdef TARGET_MIPS64
11751 gen_ldst_pair(ctx, minor, rt, rs, SIMM(ctx->opcode, 0, 12));
11755 #ifdef TARGET_MIPS64
11759 gen_ldst_multiple(ctx, minor, rt, rs, SIMM(ctx->opcode, 0, 12));
11762 MIPS_INVAL("pool32b");
11763 generate_exception(ctx, EXCP_RI);
11768 if (env->CP0_Config1 & (1 << CP0C1_FP)) {
11769 minor = ctx->opcode & 0x3f;
11770 check_cp1_enabled(ctx);
11773 mips32_op = OPC_ALNV_PS;
11776 mips32_op = OPC_MADD_S;
11779 mips32_op = OPC_MADD_D;
11782 mips32_op = OPC_MADD_PS;
11785 mips32_op = OPC_MSUB_S;
11788 mips32_op = OPC_MSUB_D;
11791 mips32_op = OPC_MSUB_PS;
11794 mips32_op = OPC_NMADD_S;
11797 mips32_op = OPC_NMADD_D;
11800 mips32_op = OPC_NMADD_PS;
11803 mips32_op = OPC_NMSUB_S;
11806 mips32_op = OPC_NMSUB_D;
11809 mips32_op = OPC_NMSUB_PS;
11811 gen_flt3_arith(ctx, mips32_op, rd, rr, rs, rt);
11813 case CABS_COND_FMT:
11814 cond = (ctx->opcode >> 6) & 0xf;
11815 cc = (ctx->opcode >> 13) & 0x7;
11816 fmt = (ctx->opcode >> 10) & 0x3;
11819 gen_cmpabs_s(ctx, cond, rt, rs, cc);
11822 gen_cmpabs_d(ctx, cond, rt, rs, cc);
11825 gen_cmpabs_ps(ctx, cond, rt, rs, cc);
11828 goto pool32f_invalid;
11832 cond = (ctx->opcode >> 6) & 0xf;
11833 cc = (ctx->opcode >> 13) & 0x7;
11834 fmt = (ctx->opcode >> 10) & 0x3;
11837 gen_cmp_s(ctx, cond, rt, rs, cc);
11840 gen_cmp_d(ctx, cond, rt, rs, cc);
11843 gen_cmp_ps(ctx, cond, rt, rs, cc);
11846 goto pool32f_invalid;
11850 gen_pool32fxf(ctx, rt, rs);
11854 switch ((ctx->opcode >> 6) & 0x7) {
11856 mips32_op = OPC_PLL_PS;
11859 mips32_op = OPC_PLU_PS;
11862 mips32_op = OPC_PUL_PS;
11865 mips32_op = OPC_PUU_PS;
11868 mips32_op = OPC_CVT_PS_S;
11870 gen_farith(ctx, mips32_op, rt, rs, rd, 0);
11873 goto pool32f_invalid;
11878 switch ((ctx->opcode >> 6) & 0x7) {
11880 mips32_op = OPC_LWXC1;
11883 mips32_op = OPC_SWXC1;
11886 mips32_op = OPC_LDXC1;
11889 mips32_op = OPC_SDXC1;
11892 mips32_op = OPC_LUXC1;
11895 mips32_op = OPC_SUXC1;
11897 gen_flt3_ldst(ctx, mips32_op, rd, rd, rt, rs);
11900 goto pool32f_invalid;
11905 fmt = (ctx->opcode >> 9) & 0x3;
11906 switch ((ctx->opcode >> 6) & 0x7) {
11910 mips32_op = OPC_RSQRT2_S;
11913 mips32_op = OPC_RSQRT2_D;
11916 mips32_op = OPC_RSQRT2_PS;
11919 goto pool32f_invalid;
11925 mips32_op = OPC_RECIP2_S;
11928 mips32_op = OPC_RECIP2_D;
11931 mips32_op = OPC_RECIP2_PS;
11934 goto pool32f_invalid;
11938 mips32_op = OPC_ADDR_PS;
11941 mips32_op = OPC_MULR_PS;
11943 gen_farith(ctx, mips32_op, rt, rs, rd, 0);
11946 goto pool32f_invalid;
11950 /* MOV[FT].fmt and PREFX */
11951 cc = (ctx->opcode >> 13) & 0x7;
11952 fmt = (ctx->opcode >> 9) & 0x3;
11953 switch ((ctx->opcode >> 6) & 0x7) {
11957 gen_movcf_s(rs, rt, cc, 0);
11960 gen_movcf_d(ctx, rs, rt, cc, 0);
11963 gen_movcf_ps(rs, rt, cc, 0);
11966 goto pool32f_invalid;
11972 gen_movcf_s(rs, rt, cc, 1);
11975 gen_movcf_d(ctx, rs, rt, cc, 1);
11978 gen_movcf_ps(rs, rt, cc, 1);
11981 goto pool32f_invalid;
11987 goto pool32f_invalid;
11990 #define FINSN_3ARG_SDPS(prfx) \
11991 switch ((ctx->opcode >> 8) & 0x3) { \
11993 mips32_op = OPC_##prfx##_S; \
11996 mips32_op = OPC_##prfx##_D; \
11998 case FMT_SDPS_PS: \
11999 mips32_op = OPC_##prfx##_PS; \
12002 goto pool32f_invalid; \
12005 /* regular FP ops */
12006 switch ((ctx->opcode >> 6) & 0x3) {
12008 FINSN_3ARG_SDPS(ADD);
12011 FINSN_3ARG_SDPS(SUB);
12014 FINSN_3ARG_SDPS(MUL);
12017 fmt = (ctx->opcode >> 8) & 0x3;
12019 mips32_op = OPC_DIV_D;
12020 } else if (fmt == 0) {
12021 mips32_op = OPC_DIV_S;
12023 goto pool32f_invalid;
12027 goto pool32f_invalid;
12032 switch ((ctx->opcode >> 6) & 0x3) {
12034 FINSN_3ARG_SDPS(MOVN);
12037 FINSN_3ARG_SDPS(MOVZ);
12040 goto pool32f_invalid;
12044 gen_farith(ctx, mips32_op, rt, rs, rd, 0);
12048 MIPS_INVAL("pool32f");
12049 generate_exception(ctx, EXCP_RI);
12053 generate_exception_err(ctx, EXCP_CpU, 1);
12057 minor = (ctx->opcode >> 21) & 0x1f;
12060 mips32_op = OPC_BLTZ;
12063 mips32_op = OPC_BLTZAL;
12066 mips32_op = OPC_BLTZALS;
12069 mips32_op = OPC_BGEZ;
12072 mips32_op = OPC_BGEZAL;
12075 mips32_op = OPC_BGEZALS;
12078 mips32_op = OPC_BLEZ;
12081 mips32_op = OPC_BGTZ;
12083 gen_compute_branch(ctx, mips32_op, 4, rs, -1, imm << 1);
12089 mips32_op = OPC_TLTI;
12092 mips32_op = OPC_TGEI;
12095 mips32_op = OPC_TLTIU;
12098 mips32_op = OPC_TGEIU;
12101 mips32_op = OPC_TNEI;
12104 mips32_op = OPC_TEQI;
12106 gen_trap(ctx, mips32_op, rs, -1, imm);
12111 gen_compute_branch(ctx, minor == BNEZC ? OPC_BNE : OPC_BEQ,
12112 4, rs, 0, imm << 1);
12113 /* Compact branches don't have a delay slot, so just let
12114 the normal delay slot handling take us to the branch
12118 gen_logic_imm(ctx, OPC_LUI, rs, -1, imm);
12124 /* COP2: Not implemented. */
12125 generate_exception_err(ctx, EXCP_CpU, 2);
12128 mips32_op = (ctx->opcode & (1 << 16)) ? OPC_BC1FANY2 : OPC_BC1F;
12131 mips32_op = (ctx->opcode & (1 << 16)) ? OPC_BC1TANY2 : OPC_BC1T;
12134 mips32_op = OPC_BC1FANY4;
12137 mips32_op = OPC_BC1TANY4;
12140 check_insn(ctx, ASE_MIPS3D);
12143 gen_compute_branch1(ctx, mips32_op,
12144 (ctx->opcode >> 18) & 0x7, imm << 1);
12149 /* MIPS DSP: not implemented */
12152 MIPS_INVAL("pool32i");
12153 generate_exception(ctx, EXCP_RI);
12158 minor = (ctx->opcode >> 12) & 0xf;
12161 mips32_op = OPC_LWL;
12164 mips32_op = OPC_SWL;
12167 mips32_op = OPC_LWR;
12170 mips32_op = OPC_SWR;
12172 #if defined(TARGET_MIPS64)
12174 mips32_op = OPC_LDL;
12177 mips32_op = OPC_SDL;
12180 mips32_op = OPC_LDR;
12183 mips32_op = OPC_SDR;
12186 mips32_op = OPC_LWU;
12189 mips32_op = OPC_LLD;
12193 mips32_op = OPC_LL;
12196 gen_ld(ctx, mips32_op, rt, rs, SIMM(ctx->opcode, 0, 12));
12199 gen_st(ctx, mips32_op, rt, rs, SIMM(ctx->opcode, 0, 12));
12202 gen_st_cond(ctx, OPC_SC, rt, rs, SIMM(ctx->opcode, 0, 12));
12204 #if defined(TARGET_MIPS64)
12206 gen_st_cond(ctx, OPC_SCD, rt, rs, SIMM(ctx->opcode, 0, 12));
12210 /* Treat as no-op */
12213 MIPS_INVAL("pool32c");
12214 generate_exception(ctx, EXCP_RI);
12219 mips32_op = OPC_ADDI;
12222 mips32_op = OPC_ADDIU;
12224 gen_arith_imm(ctx, mips32_op, rt, rs, imm);
12227 /* Logical operations */
12229 mips32_op = OPC_ORI;
12232 mips32_op = OPC_XORI;
12235 mips32_op = OPC_ANDI;
12237 gen_logic_imm(ctx, mips32_op, rt, rs, imm);
12240 /* Set less than immediate */
12242 mips32_op = OPC_SLTI;
12245 mips32_op = OPC_SLTIU;
12247 gen_slt_imm(ctx, mips32_op, rt, rs, imm);
12250 offset = (int32_t)(ctx->opcode & 0x3FFFFFF) << 2;
12251 gen_compute_branch(ctx, OPC_JALX, 4, rt, rs, offset);
12255 offset = (int32_t)(ctx->opcode & 0x3FFFFFF) << 1;
12256 gen_compute_branch(ctx, OPC_JALS, 4, rt, rs, offset);
12260 gen_compute_branch(ctx, OPC_BEQ, 4, rt, rs, imm << 1);
12264 gen_compute_branch(ctx, OPC_BNE, 4, rt, rs, imm << 1);
12268 gen_compute_branch(ctx, OPC_J, 4, rt, rs,
12269 (int32_t)(ctx->opcode & 0x3FFFFFF) << 1);
12273 gen_compute_branch(ctx, OPC_JAL, 4, rt, rs,
12274 (int32_t)(ctx->opcode & 0x3FFFFFF) << 1);
12277 /* Floating point (COP1) */
12279 mips32_op = OPC_LWC1;
12282 mips32_op = OPC_LDC1;
12285 mips32_op = OPC_SWC1;
12288 mips32_op = OPC_SDC1;
12290 gen_cop1_ldst(env, ctx, mips32_op, rt, rs, imm);
12294 int reg = mmreg(ZIMM(ctx->opcode, 23, 3));
12295 int offset = SIMM(ctx->opcode, 0, 23) << 2;
12297 gen_addiupc(ctx, reg, offset, 0, 0);
12300 /* Loads and stores */
12302 mips32_op = OPC_LB;
12305 mips32_op = OPC_LBU;
12308 mips32_op = OPC_LH;
12311 mips32_op = OPC_LHU;
12314 mips32_op = OPC_LW;
12316 #ifdef TARGET_MIPS64
12318 mips32_op = OPC_LD;
12321 mips32_op = OPC_SD;
12325 mips32_op = OPC_SB;
12328 mips32_op = OPC_SH;
12331 mips32_op = OPC_SW;
12334 gen_ld(ctx, mips32_op, rt, rs, imm);
12337 gen_st(ctx, mips32_op, rt, rs, imm);
12340 generate_exception(ctx, EXCP_RI);
12345 static int decode_micromips_opc (CPUMIPSState *env, DisasContext *ctx, int *is_branch)
12349 /* make sure instructions are on a halfword boundary */
12350 if (ctx->pc & 0x1) {
12351 env->CP0_BadVAddr = ctx->pc;
12352 generate_exception(ctx, EXCP_AdEL);
12353 ctx->bstate = BS_STOP;
12357 op = (ctx->opcode >> 10) & 0x3f;
12358 /* Enforce properly-sized instructions in a delay slot */
12359 if (ctx->hflags & MIPS_HFLAG_BMASK) {
12360 int bits = ctx->hflags & MIPS_HFLAG_BMASK_EXT;
12398 if (bits & MIPS_HFLAG_BDS16) {
12399 generate_exception(ctx, EXCP_RI);
12400 /* Just stop translation; the user is confused. */
12401 ctx->bstate = BS_STOP;
12426 if (bits & MIPS_HFLAG_BDS32) {
12427 generate_exception(ctx, EXCP_RI);
12428 /* Just stop translation; the user is confused. */
12429 ctx->bstate = BS_STOP;
12440 int rd = mmreg(uMIPS_RD(ctx->opcode));
12441 int rs1 = mmreg(uMIPS_RS1(ctx->opcode));
12442 int rs2 = mmreg(uMIPS_RS2(ctx->opcode));
12445 switch (ctx->opcode & 0x1) {
12454 gen_arith(ctx, opc, rd, rs1, rs2);
12459 int rd = mmreg(uMIPS_RD(ctx->opcode));
12460 int rs = mmreg(uMIPS_RS(ctx->opcode));
12461 int amount = (ctx->opcode >> 1) & 0x7;
12463 amount = amount == 0 ? 8 : amount;
12465 switch (ctx->opcode & 0x1) {
12474 gen_shift_imm(ctx, opc, rd, rs, amount);
12478 gen_pool16c_insn(ctx, is_branch);
12482 int rd = mmreg(uMIPS_RD(ctx->opcode));
12483 int rb = 28; /* GP */
12484 int16_t offset = SIMM(ctx->opcode, 0, 7) << 2;
12486 gen_ld(ctx, OPC_LW, rd, rb, offset);
12490 if (ctx->opcode & 1) {
12491 generate_exception(ctx, EXCP_RI);
12494 int enc_dest = uMIPS_RD(ctx->opcode);
12495 int enc_rt = uMIPS_RS2(ctx->opcode);
12496 int enc_rs = uMIPS_RS1(ctx->opcode);
12497 int rd, rs, re, rt;
12498 static const int rd_enc[] = { 5, 5, 6, 4, 4, 4, 4, 4 };
12499 static const int re_enc[] = { 6, 7, 7, 21, 22, 5, 6, 7 };
12500 static const int rs_rt_enc[] = { 0, 17, 2, 3, 16, 18, 19, 20 };
12502 rd = rd_enc[enc_dest];
12503 re = re_enc[enc_dest];
12504 rs = rs_rt_enc[enc_rs];
12505 rt = rs_rt_enc[enc_rt];
12507 gen_arith_imm(ctx, OPC_ADDIU, rd, rs, 0);
12508 gen_arith_imm(ctx, OPC_ADDIU, re, rt, 0);
12513 int rd = mmreg(uMIPS_RD(ctx->opcode));
12514 int rb = mmreg(uMIPS_RS(ctx->opcode));
12515 int16_t offset = ZIMM(ctx->opcode, 0, 4);
12516 offset = (offset == 0xf ? -1 : offset);
12518 gen_ld(ctx, OPC_LBU, rd, rb, offset);
12523 int rd = mmreg(uMIPS_RD(ctx->opcode));
12524 int rb = mmreg(uMIPS_RS(ctx->opcode));
12525 int16_t offset = ZIMM(ctx->opcode, 0, 4) << 1;
12527 gen_ld(ctx, OPC_LHU, rd, rb, offset);
12532 int rd = (ctx->opcode >> 5) & 0x1f;
12533 int rb = 29; /* SP */
12534 int16_t offset = ZIMM(ctx->opcode, 0, 5) << 2;
12536 gen_ld(ctx, OPC_LW, rd, rb, offset);
12541 int rd = mmreg(uMIPS_RD(ctx->opcode));
12542 int rb = mmreg(uMIPS_RS(ctx->opcode));
12543 int16_t offset = ZIMM(ctx->opcode, 0, 4) << 2;
12545 gen_ld(ctx, OPC_LW, rd, rb, offset);
12550 int rd = mmreg2(uMIPS_RD(ctx->opcode));
12551 int rb = mmreg(uMIPS_RS(ctx->opcode));
12552 int16_t offset = ZIMM(ctx->opcode, 0, 4);
12554 gen_st(ctx, OPC_SB, rd, rb, offset);
12559 int rd = mmreg2(uMIPS_RD(ctx->opcode));
12560 int rb = mmreg(uMIPS_RS(ctx->opcode));
12561 int16_t offset = ZIMM(ctx->opcode, 0, 4) << 1;
12563 gen_st(ctx, OPC_SH, rd, rb, offset);
12568 int rd = (ctx->opcode >> 5) & 0x1f;
12569 int rb = 29; /* SP */
12570 int16_t offset = ZIMM(ctx->opcode, 0, 5) << 2;
12572 gen_st(ctx, OPC_SW, rd, rb, offset);
12577 int rd = mmreg2(uMIPS_RD(ctx->opcode));
12578 int rb = mmreg(uMIPS_RS(ctx->opcode));
12579 int16_t offset = ZIMM(ctx->opcode, 0, 4) << 2;
12581 gen_st(ctx, OPC_SW, rd, rb, offset);
12586 int rd = uMIPS_RD5(ctx->opcode);
12587 int rs = uMIPS_RS5(ctx->opcode);
12589 gen_arith_imm(ctx, OPC_ADDIU, rd, rs, 0);
12596 switch (ctx->opcode & 0x1) {
12606 switch (ctx->opcode & 0x1) {
12611 gen_addiur1sp(ctx);
12616 gen_compute_branch(ctx, OPC_BEQ, 2, 0, 0,
12617 SIMM(ctx->opcode, 0, 10) << 1);
12622 gen_compute_branch(ctx, op == BNEZ16 ? OPC_BNE : OPC_BEQ, 2,
12623 mmreg(uMIPS_RD(ctx->opcode)),
12624 0, SIMM(ctx->opcode, 0, 7) << 1);
12629 int reg = mmreg(uMIPS_RD(ctx->opcode));
12630 int imm = ZIMM(ctx->opcode, 0, 7);
12632 imm = (imm == 0x7f ? -1 : imm);
12633 tcg_gen_movi_tl(cpu_gpr[reg], imm);
12643 generate_exception(ctx, EXCP_RI);
12646 decode_micromips32_opc (env, ctx, op, is_branch);
12653 /* SmartMIPS extension to MIPS32 */
12655 #if defined(TARGET_MIPS64)
12657 /* MDMX extension to MIPS64 */
12661 /* MIPSDSP functions. */
12662 static void gen_mipsdsp_ld(DisasContext *ctx, uint32_t opc,
12663 int rd, int base, int offset)
12665 const char *opn = "ldx";
12669 t0 = tcg_temp_new();
12672 gen_load_gpr(t0, offset);
12673 } else if (offset == 0) {
12674 gen_load_gpr(t0, base);
12676 gen_op_addr_add(ctx, t0, cpu_gpr[base], cpu_gpr[offset]);
12681 tcg_gen_qemu_ld8u(t0, t0, ctx->mem_idx);
12682 gen_store_gpr(t0, rd);
12686 tcg_gen_qemu_ld16s(t0, t0, ctx->mem_idx);
12687 gen_store_gpr(t0, rd);
12691 tcg_gen_qemu_ld32s(t0, t0, ctx->mem_idx);
12692 gen_store_gpr(t0, rd);
12695 #if defined(TARGET_MIPS64)
12697 tcg_gen_qemu_ld64(t0, t0, ctx->mem_idx);
12698 gen_store_gpr(t0, rd);
12703 (void)opn; /* avoid a compiler warning */
12704 MIPS_DEBUG("%s %s, %s(%s)", opn,
12705 regnames[rd], regnames[offset], regnames[base]);
12709 static void gen_mipsdsp_arith(DisasContext *ctx, uint32_t op1, uint32_t op2,
12710 int ret, int v1, int v2)
12712 const char *opn = "mipsdsp arith";
12717 /* Treat as NOP. */
12722 v1_t = tcg_temp_new();
12723 v2_t = tcg_temp_new();
12725 gen_load_gpr(v1_t, v1);
12726 gen_load_gpr(v2_t, v2);
12729 /* OPC_MULT_G_2E is equal OPC_ADDUH_QB_DSP */
12730 case OPC_MULT_G_2E:
12734 gen_helper_adduh_qb(cpu_gpr[ret], v1_t, v2_t);
12736 case OPC_ADDUH_R_QB:
12737 gen_helper_adduh_r_qb(cpu_gpr[ret], v1_t, v2_t);
12740 gen_helper_addqh_ph(cpu_gpr[ret], v1_t, v2_t);
12742 case OPC_ADDQH_R_PH:
12743 gen_helper_addqh_r_ph(cpu_gpr[ret], v1_t, v2_t);
12746 gen_helper_addqh_w(cpu_gpr[ret], v1_t, v2_t);
12748 case OPC_ADDQH_R_W:
12749 gen_helper_addqh_r_w(cpu_gpr[ret], v1_t, v2_t);
12752 gen_helper_subuh_qb(cpu_gpr[ret], v1_t, v2_t);
12754 case OPC_SUBUH_R_QB:
12755 gen_helper_subuh_r_qb(cpu_gpr[ret], v1_t, v2_t);
12758 gen_helper_subqh_ph(cpu_gpr[ret], v1_t, v2_t);
12760 case OPC_SUBQH_R_PH:
12761 gen_helper_subqh_r_ph(cpu_gpr[ret], v1_t, v2_t);
12764 gen_helper_subqh_w(cpu_gpr[ret], v1_t, v2_t);
12766 case OPC_SUBQH_R_W:
12767 gen_helper_subqh_r_w(cpu_gpr[ret], v1_t, v2_t);
12771 case OPC_ABSQ_S_PH_DSP:
12773 case OPC_ABSQ_S_QB:
12775 gen_helper_absq_s_qb(cpu_gpr[ret], v2_t, cpu_env);
12777 case OPC_ABSQ_S_PH:
12779 gen_helper_absq_s_ph(cpu_gpr[ret], v2_t, cpu_env);
12783 gen_helper_absq_s_w(cpu_gpr[ret], v2_t, cpu_env);
12785 case OPC_PRECEQ_W_PHL:
12787 tcg_gen_andi_tl(cpu_gpr[ret], v2_t, 0xFFFF0000);
12788 tcg_gen_ext32s_tl(cpu_gpr[ret], cpu_gpr[ret]);
12790 case OPC_PRECEQ_W_PHR:
12792 tcg_gen_andi_tl(cpu_gpr[ret], v2_t, 0x0000FFFF);
12793 tcg_gen_shli_tl(cpu_gpr[ret], cpu_gpr[ret], 16);
12794 tcg_gen_ext32s_tl(cpu_gpr[ret], cpu_gpr[ret]);
12796 case OPC_PRECEQU_PH_QBL:
12798 gen_helper_precequ_ph_qbl(cpu_gpr[ret], v2_t);
12800 case OPC_PRECEQU_PH_QBR:
12802 gen_helper_precequ_ph_qbr(cpu_gpr[ret], v2_t);
12804 case OPC_PRECEQU_PH_QBLA:
12806 gen_helper_precequ_ph_qbla(cpu_gpr[ret], v2_t);
12808 case OPC_PRECEQU_PH_QBRA:
12810 gen_helper_precequ_ph_qbra(cpu_gpr[ret], v2_t);
12812 case OPC_PRECEU_PH_QBL:
12814 gen_helper_preceu_ph_qbl(cpu_gpr[ret], v2_t);
12816 case OPC_PRECEU_PH_QBR:
12818 gen_helper_preceu_ph_qbr(cpu_gpr[ret], v2_t);
12820 case OPC_PRECEU_PH_QBLA:
12822 gen_helper_preceu_ph_qbla(cpu_gpr[ret], v2_t);
12824 case OPC_PRECEU_PH_QBRA:
12826 gen_helper_preceu_ph_qbra(cpu_gpr[ret], v2_t);
12830 case OPC_ADDU_QB_DSP:
12834 gen_helper_addq_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12836 case OPC_ADDQ_S_PH:
12838 gen_helper_addq_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12842 gen_helper_addq_s_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12846 gen_helper_addu_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12848 case OPC_ADDU_S_QB:
12850 gen_helper_addu_s_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12854 gen_helper_addu_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12856 case OPC_ADDU_S_PH:
12858 gen_helper_addu_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12862 gen_helper_subq_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12864 case OPC_SUBQ_S_PH:
12866 gen_helper_subq_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12870 gen_helper_subq_s_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12874 gen_helper_subu_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12876 case OPC_SUBU_S_QB:
12878 gen_helper_subu_s_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12882 gen_helper_subu_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12884 case OPC_SUBU_S_PH:
12886 gen_helper_subu_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12890 gen_helper_addsc(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12894 gen_helper_addwc(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12898 gen_helper_modsub(cpu_gpr[ret], v1_t, v2_t);
12900 case OPC_RADDU_W_QB:
12902 gen_helper_raddu_w_qb(cpu_gpr[ret], v1_t);
12906 case OPC_CMPU_EQ_QB_DSP:
12908 case OPC_PRECR_QB_PH:
12910 gen_helper_precr_qb_ph(cpu_gpr[ret], v1_t, v2_t);
12912 case OPC_PRECRQ_QB_PH:
12914 gen_helper_precrq_qb_ph(cpu_gpr[ret], v1_t, v2_t);
12916 case OPC_PRECR_SRA_PH_W:
12919 TCGv_i32 sa_t = tcg_const_i32(v2);
12920 gen_helper_precr_sra_ph_w(cpu_gpr[ret], sa_t, v1_t,
12922 tcg_temp_free_i32(sa_t);
12925 case OPC_PRECR_SRA_R_PH_W:
12928 TCGv_i32 sa_t = tcg_const_i32(v2);
12929 gen_helper_precr_sra_r_ph_w(cpu_gpr[ret], sa_t, v1_t,
12931 tcg_temp_free_i32(sa_t);
12934 case OPC_PRECRQ_PH_W:
12936 gen_helper_precrq_ph_w(cpu_gpr[ret], v1_t, v2_t);
12938 case OPC_PRECRQ_RS_PH_W:
12940 gen_helper_precrq_rs_ph_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12942 case OPC_PRECRQU_S_QB_PH:
12944 gen_helper_precrqu_s_qb_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12948 #ifdef TARGET_MIPS64
12949 case OPC_ABSQ_S_QH_DSP:
12951 case OPC_PRECEQ_L_PWL:
12953 tcg_gen_andi_tl(cpu_gpr[ret], v2_t, 0xFFFFFFFF00000000ull);
12955 case OPC_PRECEQ_L_PWR:
12957 tcg_gen_shli_tl(cpu_gpr[ret], v2_t, 32);
12959 case OPC_PRECEQ_PW_QHL:
12961 gen_helper_preceq_pw_qhl(cpu_gpr[ret], v2_t);
12963 case OPC_PRECEQ_PW_QHR:
12965 gen_helper_preceq_pw_qhr(cpu_gpr[ret], v2_t);
12967 case OPC_PRECEQ_PW_QHLA:
12969 gen_helper_preceq_pw_qhla(cpu_gpr[ret], v2_t);
12971 case OPC_PRECEQ_PW_QHRA:
12973 gen_helper_preceq_pw_qhra(cpu_gpr[ret], v2_t);
12975 case OPC_PRECEQU_QH_OBL:
12977 gen_helper_precequ_qh_obl(cpu_gpr[ret], v2_t);
12979 case OPC_PRECEQU_QH_OBR:
12981 gen_helper_precequ_qh_obr(cpu_gpr[ret], v2_t);
12983 case OPC_PRECEQU_QH_OBLA:
12985 gen_helper_precequ_qh_obla(cpu_gpr[ret], v2_t);
12987 case OPC_PRECEQU_QH_OBRA:
12989 gen_helper_precequ_qh_obra(cpu_gpr[ret], v2_t);
12991 case OPC_PRECEU_QH_OBL:
12993 gen_helper_preceu_qh_obl(cpu_gpr[ret], v2_t);
12995 case OPC_PRECEU_QH_OBR:
12997 gen_helper_preceu_qh_obr(cpu_gpr[ret], v2_t);
12999 case OPC_PRECEU_QH_OBLA:
13001 gen_helper_preceu_qh_obla(cpu_gpr[ret], v2_t);
13003 case OPC_PRECEU_QH_OBRA:
13005 gen_helper_preceu_qh_obra(cpu_gpr[ret], v2_t);
13007 case OPC_ABSQ_S_OB:
13009 gen_helper_absq_s_ob(cpu_gpr[ret], v2_t, cpu_env);
13011 case OPC_ABSQ_S_PW:
13013 gen_helper_absq_s_pw(cpu_gpr[ret], v2_t, cpu_env);
13015 case OPC_ABSQ_S_QH:
13017 gen_helper_absq_s_qh(cpu_gpr[ret], v2_t, cpu_env);
13021 case OPC_ADDU_OB_DSP:
13023 case OPC_RADDU_L_OB:
13025 gen_helper_raddu_l_ob(cpu_gpr[ret], v1_t);
13029 gen_helper_subq_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13031 case OPC_SUBQ_S_PW:
13033 gen_helper_subq_s_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13037 gen_helper_subq_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13039 case OPC_SUBQ_S_QH:
13041 gen_helper_subq_s_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13045 gen_helper_subu_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13047 case OPC_SUBU_S_OB:
13049 gen_helper_subu_s_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13053 gen_helper_subu_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13055 case OPC_SUBU_S_QH:
13057 gen_helper_subu_s_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13061 gen_helper_subuh_ob(cpu_gpr[ret], v1_t, v2_t);
13063 case OPC_SUBUH_R_OB:
13065 gen_helper_subuh_r_ob(cpu_gpr[ret], v1_t, v2_t);
13069 gen_helper_addq_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13071 case OPC_ADDQ_S_PW:
13073 gen_helper_addq_s_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13077 gen_helper_addq_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13079 case OPC_ADDQ_S_QH:
13081 gen_helper_addq_s_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13085 gen_helper_addu_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13087 case OPC_ADDU_S_OB:
13089 gen_helper_addu_s_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13093 gen_helper_addu_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13095 case OPC_ADDU_S_QH:
13097 gen_helper_addu_s_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13101 gen_helper_adduh_ob(cpu_gpr[ret], v1_t, v2_t);
13103 case OPC_ADDUH_R_OB:
13105 gen_helper_adduh_r_ob(cpu_gpr[ret], v1_t, v2_t);
13109 case OPC_CMPU_EQ_OB_DSP:
13111 case OPC_PRECR_OB_QH:
13113 gen_helper_precr_ob_qh(cpu_gpr[ret], v1_t, v2_t);
13115 case OPC_PRECR_SRA_QH_PW:
13118 TCGv_i32 ret_t = tcg_const_i32(ret);
13119 gen_helper_precr_sra_qh_pw(v2_t, v1_t, v2_t, ret_t);
13120 tcg_temp_free_i32(ret_t);
13123 case OPC_PRECR_SRA_R_QH_PW:
13126 TCGv_i32 sa_v = tcg_const_i32(ret);
13127 gen_helper_precr_sra_r_qh_pw(v2_t, v1_t, v2_t, sa_v);
13128 tcg_temp_free_i32(sa_v);
13131 case OPC_PRECRQ_OB_QH:
13133 gen_helper_precrq_ob_qh(cpu_gpr[ret], v1_t, v2_t);
13135 case OPC_PRECRQ_PW_L:
13137 gen_helper_precrq_pw_l(cpu_gpr[ret], v1_t, v2_t);
13139 case OPC_PRECRQ_QH_PW:
13141 gen_helper_precrq_qh_pw(cpu_gpr[ret], v1_t, v2_t);
13143 case OPC_PRECRQ_RS_QH_PW:
13145 gen_helper_precrq_rs_qh_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13147 case OPC_PRECRQU_S_OB_QH:
13149 gen_helper_precrqu_s_ob_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13156 tcg_temp_free(v1_t);
13157 tcg_temp_free(v2_t);
13159 (void)opn; /* avoid a compiler warning */
13160 MIPS_DEBUG("%s", opn);
13163 static void gen_mipsdsp_shift(DisasContext *ctx, uint32_t opc,
13164 int ret, int v1, int v2)
13167 const char *opn = "mipsdsp shift";
13173 /* Treat as NOP. */
13178 t0 = tcg_temp_new();
13179 v1_t = tcg_temp_new();
13180 v2_t = tcg_temp_new();
13182 tcg_gen_movi_tl(t0, v1);
13183 gen_load_gpr(v1_t, v1);
13184 gen_load_gpr(v2_t, v2);
13187 case OPC_SHLL_QB_DSP:
13189 op2 = MASK_SHLL_QB(ctx->opcode);
13193 gen_helper_shll_qb(cpu_gpr[ret], t0, v2_t, cpu_env);
13197 gen_helper_shll_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13201 gen_helper_shll_ph(cpu_gpr[ret], t0, v2_t, cpu_env);
13205 gen_helper_shll_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13207 case OPC_SHLL_S_PH:
13209 gen_helper_shll_s_ph(cpu_gpr[ret], t0, v2_t, cpu_env);
13211 case OPC_SHLLV_S_PH:
13213 gen_helper_shll_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13217 gen_helper_shll_s_w(cpu_gpr[ret], t0, v2_t, cpu_env);
13219 case OPC_SHLLV_S_W:
13221 gen_helper_shll_s_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13225 gen_helper_shrl_qb(cpu_gpr[ret], t0, v2_t);
13229 gen_helper_shrl_qb(cpu_gpr[ret], v1_t, v2_t);
13233 gen_helper_shrl_ph(cpu_gpr[ret], t0, v2_t);
13237 gen_helper_shrl_ph(cpu_gpr[ret], v1_t, v2_t);
13241 gen_helper_shra_qb(cpu_gpr[ret], t0, v2_t);
13243 case OPC_SHRA_R_QB:
13245 gen_helper_shra_r_qb(cpu_gpr[ret], t0, v2_t);
13249 gen_helper_shra_qb(cpu_gpr[ret], v1_t, v2_t);
13251 case OPC_SHRAV_R_QB:
13253 gen_helper_shra_r_qb(cpu_gpr[ret], v1_t, v2_t);
13257 gen_helper_shra_ph(cpu_gpr[ret], t0, v2_t);
13259 case OPC_SHRA_R_PH:
13261 gen_helper_shra_r_ph(cpu_gpr[ret], t0, v2_t);
13265 gen_helper_shra_ph(cpu_gpr[ret], v1_t, v2_t);
13267 case OPC_SHRAV_R_PH:
13269 gen_helper_shra_r_ph(cpu_gpr[ret], v1_t, v2_t);
13273 gen_helper_shra_r_w(cpu_gpr[ret], t0, v2_t);
13275 case OPC_SHRAV_R_W:
13277 gen_helper_shra_r_w(cpu_gpr[ret], v1_t, v2_t);
13279 default: /* Invalid */
13280 MIPS_INVAL("MASK SHLL.QB");
13281 generate_exception(ctx, EXCP_RI);
13286 #ifdef TARGET_MIPS64
13287 case OPC_SHLL_OB_DSP:
13288 op2 = MASK_SHLL_OB(ctx->opcode);
13292 gen_helper_shll_pw(cpu_gpr[ret], v2_t, t0, cpu_env);
13296 gen_helper_shll_pw(cpu_gpr[ret], v2_t, v1_t, cpu_env);
13298 case OPC_SHLL_S_PW:
13300 gen_helper_shll_s_pw(cpu_gpr[ret], v2_t, t0, cpu_env);
13302 case OPC_SHLLV_S_PW:
13304 gen_helper_shll_s_pw(cpu_gpr[ret], v2_t, v1_t, cpu_env);
13308 gen_helper_shll_ob(cpu_gpr[ret], v2_t, t0, cpu_env);
13312 gen_helper_shll_ob(cpu_gpr[ret], v2_t, v1_t, cpu_env);
13316 gen_helper_shll_qh(cpu_gpr[ret], v2_t, t0, cpu_env);
13320 gen_helper_shll_qh(cpu_gpr[ret], v2_t, v1_t, cpu_env);
13322 case OPC_SHLL_S_QH:
13324 gen_helper_shll_s_qh(cpu_gpr[ret], v2_t, t0, cpu_env);
13326 case OPC_SHLLV_S_QH:
13328 gen_helper_shll_s_qh(cpu_gpr[ret], v2_t, v1_t, cpu_env);
13332 gen_helper_shra_ob(cpu_gpr[ret], v2_t, t0);
13336 gen_helper_shra_ob(cpu_gpr[ret], v2_t, v1_t);
13338 case OPC_SHRA_R_OB:
13340 gen_helper_shra_r_ob(cpu_gpr[ret], v2_t, t0);
13342 case OPC_SHRAV_R_OB:
13344 gen_helper_shra_r_ob(cpu_gpr[ret], v2_t, v1_t);
13348 gen_helper_shra_pw(cpu_gpr[ret], v2_t, t0);
13352 gen_helper_shra_pw(cpu_gpr[ret], v2_t, v1_t);
13354 case OPC_SHRA_R_PW:
13356 gen_helper_shra_r_pw(cpu_gpr[ret], v2_t, t0);
13358 case OPC_SHRAV_R_PW:
13360 gen_helper_shra_r_pw(cpu_gpr[ret], v2_t, v1_t);
13364 gen_helper_shra_qh(cpu_gpr[ret], v2_t, t0);
13368 gen_helper_shra_qh(cpu_gpr[ret], v2_t, v1_t);
13370 case OPC_SHRA_R_QH:
13372 gen_helper_shra_r_qh(cpu_gpr[ret], v2_t, t0);
13374 case OPC_SHRAV_R_QH:
13376 gen_helper_shra_r_qh(cpu_gpr[ret], v2_t, v1_t);
13380 gen_helper_shrl_ob(cpu_gpr[ret], v2_t, t0);
13384 gen_helper_shrl_ob(cpu_gpr[ret], v2_t, v1_t);
13388 gen_helper_shrl_qh(cpu_gpr[ret], v2_t, t0);
13392 gen_helper_shrl_qh(cpu_gpr[ret], v2_t, v1_t);
13394 default: /* Invalid */
13395 MIPS_INVAL("MASK SHLL.OB");
13396 generate_exception(ctx, EXCP_RI);
13404 tcg_temp_free(v1_t);
13405 tcg_temp_free(v2_t);
13406 (void)opn; /* avoid a compiler warning */
13407 MIPS_DEBUG("%s", opn);
13410 static void gen_mipsdsp_multiply(DisasContext *ctx, uint32_t op1, uint32_t op2,
13411 int ret, int v1, int v2, int check_ret)
13413 const char *opn = "mipsdsp multiply";
13418 if ((ret == 0) && (check_ret == 1)) {
13419 /* Treat as NOP. */
13424 t0 = tcg_temp_new_i32();
13425 v1_t = tcg_temp_new();
13426 v2_t = tcg_temp_new();
13428 tcg_gen_movi_i32(t0, ret);
13429 gen_load_gpr(v1_t, v1);
13430 gen_load_gpr(v2_t, v2);
13433 /* OPC_MULT_G_2E, OPC_ADDUH_QB_DSP, OPC_MUL_PH_DSP have
13434 * the same mask and op1. */
13435 case OPC_MULT_G_2E:
13438 gen_helper_mul_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13441 gen_helper_mul_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13444 gen_helper_mulq_s_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13446 case OPC_MULQ_RS_W:
13447 gen_helper_mulq_rs_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13451 case OPC_DPA_W_PH_DSP:
13453 case OPC_DPAU_H_QBL:
13455 gen_helper_dpau_h_qbl(t0, v1_t, v2_t, cpu_env);
13457 case OPC_DPAU_H_QBR:
13459 gen_helper_dpau_h_qbr(t0, v1_t, v2_t, cpu_env);
13461 case OPC_DPSU_H_QBL:
13463 gen_helper_dpsu_h_qbl(t0, v1_t, v2_t, cpu_env);
13465 case OPC_DPSU_H_QBR:
13467 gen_helper_dpsu_h_qbr(t0, v1_t, v2_t, cpu_env);
13471 gen_helper_dpa_w_ph(t0, v1_t, v2_t, cpu_env);
13473 case OPC_DPAX_W_PH:
13475 gen_helper_dpax_w_ph(t0, v1_t, v2_t, cpu_env);
13477 case OPC_DPAQ_S_W_PH:
13479 gen_helper_dpaq_s_w_ph(t0, v1_t, v2_t, cpu_env);
13481 case OPC_DPAQX_S_W_PH:
13483 gen_helper_dpaqx_s_w_ph(t0, v1_t, v2_t, cpu_env);
13485 case OPC_DPAQX_SA_W_PH:
13487 gen_helper_dpaqx_sa_w_ph(t0, v1_t, v2_t, cpu_env);
13491 gen_helper_dps_w_ph(t0, v1_t, v2_t, cpu_env);
13493 case OPC_DPSX_W_PH:
13495 gen_helper_dpsx_w_ph(t0, v1_t, v2_t, cpu_env);
13497 case OPC_DPSQ_S_W_PH:
13499 gen_helper_dpsq_s_w_ph(t0, v1_t, v2_t, cpu_env);
13501 case OPC_DPSQX_S_W_PH:
13503 gen_helper_dpsqx_s_w_ph(t0, v1_t, v2_t, cpu_env);
13505 case OPC_DPSQX_SA_W_PH:
13507 gen_helper_dpsqx_sa_w_ph(t0, v1_t, v2_t, cpu_env);
13509 case OPC_MULSAQ_S_W_PH:
13511 gen_helper_mulsaq_s_w_ph(t0, v1_t, v2_t, cpu_env);
13513 case OPC_DPAQ_SA_L_W:
13515 gen_helper_dpaq_sa_l_w(t0, v1_t, v2_t, cpu_env);
13517 case OPC_DPSQ_SA_L_W:
13519 gen_helper_dpsq_sa_l_w(t0, v1_t, v2_t, cpu_env);
13521 case OPC_MAQ_S_W_PHL:
13523 gen_helper_maq_s_w_phl(t0, v1_t, v2_t, cpu_env);
13525 case OPC_MAQ_S_W_PHR:
13527 gen_helper_maq_s_w_phr(t0, v1_t, v2_t, cpu_env);
13529 case OPC_MAQ_SA_W_PHL:
13531 gen_helper_maq_sa_w_phl(t0, v1_t, v2_t, cpu_env);
13533 case OPC_MAQ_SA_W_PHR:
13535 gen_helper_maq_sa_w_phr(t0, v1_t, v2_t, cpu_env);
13537 case OPC_MULSA_W_PH:
13539 gen_helper_mulsa_w_ph(t0, v1_t, v2_t, cpu_env);
13543 #ifdef TARGET_MIPS64
13544 case OPC_DPAQ_W_QH_DSP:
13546 int ac = ret & 0x03;
13547 tcg_gen_movi_i32(t0, ac);
13552 gen_helper_dmadd(v1_t, v2_t, t0, cpu_env);
13556 gen_helper_dmaddu(v1_t, v2_t, t0, cpu_env);
13560 gen_helper_dmsub(v1_t, v2_t, t0, cpu_env);
13564 gen_helper_dmsubu(v1_t, v2_t, t0, cpu_env);
13568 gen_helper_dpa_w_qh(v1_t, v2_t, t0, cpu_env);
13570 case OPC_DPAQ_S_W_QH:
13572 gen_helper_dpaq_s_w_qh(v1_t, v2_t, t0, cpu_env);
13574 case OPC_DPAQ_SA_L_PW:
13576 gen_helper_dpaq_sa_l_pw(v1_t, v2_t, t0, cpu_env);
13578 case OPC_DPAU_H_OBL:
13580 gen_helper_dpau_h_obl(v1_t, v2_t, t0, cpu_env);
13582 case OPC_DPAU_H_OBR:
13584 gen_helper_dpau_h_obr(v1_t, v2_t, t0, cpu_env);
13588 gen_helper_dps_w_qh(v1_t, v2_t, t0, cpu_env);
13590 case OPC_DPSQ_S_W_QH:
13592 gen_helper_dpsq_s_w_qh(v1_t, v2_t, t0, cpu_env);
13594 case OPC_DPSQ_SA_L_PW:
13596 gen_helper_dpsq_sa_l_pw(v1_t, v2_t, t0, cpu_env);
13598 case OPC_DPSU_H_OBL:
13600 gen_helper_dpsu_h_obl(v1_t, v2_t, t0, cpu_env);
13602 case OPC_DPSU_H_OBR:
13604 gen_helper_dpsu_h_obr(v1_t, v2_t, t0, cpu_env);
13606 case OPC_MAQ_S_L_PWL:
13608 gen_helper_maq_s_l_pwl(v1_t, v2_t, t0, cpu_env);
13610 case OPC_MAQ_S_L_PWR:
13612 gen_helper_maq_s_l_pwr(v1_t, v2_t, t0, cpu_env);
13614 case OPC_MAQ_S_W_QHLL:
13616 gen_helper_maq_s_w_qhll(v1_t, v2_t, t0, cpu_env);
13618 case OPC_MAQ_SA_W_QHLL:
13620 gen_helper_maq_sa_w_qhll(v1_t, v2_t, t0, cpu_env);
13622 case OPC_MAQ_S_W_QHLR:
13624 gen_helper_maq_s_w_qhlr(v1_t, v2_t, t0, cpu_env);
13626 case OPC_MAQ_SA_W_QHLR:
13628 gen_helper_maq_sa_w_qhlr(v1_t, v2_t, t0, cpu_env);
13630 case OPC_MAQ_S_W_QHRL:
13632 gen_helper_maq_s_w_qhrl(v1_t, v2_t, t0, cpu_env);
13634 case OPC_MAQ_SA_W_QHRL:
13636 gen_helper_maq_sa_w_qhrl(v1_t, v2_t, t0, cpu_env);
13638 case OPC_MAQ_S_W_QHRR:
13640 gen_helper_maq_s_w_qhrr(v1_t, v2_t, t0, cpu_env);
13642 case OPC_MAQ_SA_W_QHRR:
13644 gen_helper_maq_sa_w_qhrr(v1_t, v2_t, t0, cpu_env);
13646 case OPC_MULSAQ_S_L_PW:
13648 gen_helper_mulsaq_s_l_pw(v1_t, v2_t, t0, cpu_env);
13650 case OPC_MULSAQ_S_W_QH:
13652 gen_helper_mulsaq_s_w_qh(v1_t, v2_t, t0, cpu_env);
13658 case OPC_ADDU_QB_DSP:
13660 case OPC_MULEU_S_PH_QBL:
13662 gen_helper_muleu_s_ph_qbl(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13664 case OPC_MULEU_S_PH_QBR:
13666 gen_helper_muleu_s_ph_qbr(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13668 case OPC_MULQ_RS_PH:
13670 gen_helper_mulq_rs_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13672 case OPC_MULEQ_S_W_PHL:
13674 gen_helper_muleq_s_w_phl(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13676 case OPC_MULEQ_S_W_PHR:
13678 gen_helper_muleq_s_w_phr(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13680 case OPC_MULQ_S_PH:
13682 gen_helper_mulq_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13686 #ifdef TARGET_MIPS64
13687 case OPC_ADDU_OB_DSP:
13689 case OPC_MULEQ_S_PW_QHL:
13691 gen_helper_muleq_s_pw_qhl(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13693 case OPC_MULEQ_S_PW_QHR:
13695 gen_helper_muleq_s_pw_qhr(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13697 case OPC_MULEU_S_QH_OBL:
13699 gen_helper_muleu_s_qh_obl(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13701 case OPC_MULEU_S_QH_OBR:
13703 gen_helper_muleu_s_qh_obr(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13705 case OPC_MULQ_RS_QH:
13707 gen_helper_mulq_rs_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13714 tcg_temp_free_i32(t0);
13715 tcg_temp_free(v1_t);
13716 tcg_temp_free(v2_t);
13718 (void)opn; /* avoid a compiler warning */
13719 MIPS_DEBUG("%s", opn);
13723 static void gen_mipsdsp_bitinsn(DisasContext *ctx, uint32_t op1, uint32_t op2,
13726 const char *opn = "mipsdsp Bit/ Manipulation";
13732 /* Treat as NOP. */
13737 t0 = tcg_temp_new();
13738 val_t = tcg_temp_new();
13739 gen_load_gpr(val_t, val);
13742 case OPC_ABSQ_S_PH_DSP:
13746 gen_helper_bitrev(cpu_gpr[ret], val_t);
13751 target_long result;
13752 imm = (ctx->opcode >> 16) & 0xFF;
13753 result = (uint32_t)imm << 24 |
13754 (uint32_t)imm << 16 |
13755 (uint32_t)imm << 8 |
13757 result = (int32_t)result;
13758 tcg_gen_movi_tl(cpu_gpr[ret], result);
13763 tcg_gen_ext8u_tl(cpu_gpr[ret], val_t);
13764 tcg_gen_shli_tl(t0, cpu_gpr[ret], 8);
13765 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
13766 tcg_gen_shli_tl(t0, cpu_gpr[ret], 16);
13767 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
13768 tcg_gen_ext32s_tl(cpu_gpr[ret], cpu_gpr[ret]);
13773 imm = (ctx->opcode >> 16) & 0x03FF;
13774 imm = (int16_t)(imm << 6) >> 6;
13775 tcg_gen_movi_tl(cpu_gpr[ret], \
13776 (target_long)((int32_t)imm << 16 | \
13782 tcg_gen_ext16u_tl(cpu_gpr[ret], val_t);
13783 tcg_gen_shli_tl(t0, cpu_gpr[ret], 16);
13784 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
13785 tcg_gen_ext32s_tl(cpu_gpr[ret], cpu_gpr[ret]);
13789 #ifdef TARGET_MIPS64
13790 case OPC_ABSQ_S_QH_DSP:
13797 imm = (ctx->opcode >> 16) & 0xFF;
13798 temp = ((uint64_t)imm << 8) | (uint64_t)imm;
13799 temp = (temp << 16) | temp;
13800 temp = (temp << 32) | temp;
13801 tcg_gen_movi_tl(cpu_gpr[ret], temp);
13809 imm = (ctx->opcode >> 16) & 0x03FF;
13810 imm = (int16_t)(imm << 6) >> 6;
13811 temp = ((target_long)imm << 32) \
13812 | ((target_long)imm & 0xFFFFFFFF);
13813 tcg_gen_movi_tl(cpu_gpr[ret], temp);
13821 imm = (ctx->opcode >> 16) & 0x03FF;
13822 imm = (int16_t)(imm << 6) >> 6;
13824 temp = ((uint64_t)(uint16_t)imm << 48) |
13825 ((uint64_t)(uint16_t)imm << 32) |
13826 ((uint64_t)(uint16_t)imm << 16) |
13827 (uint64_t)(uint16_t)imm;
13828 tcg_gen_movi_tl(cpu_gpr[ret], temp);
13833 tcg_gen_ext8u_tl(cpu_gpr[ret], val_t);
13834 tcg_gen_shli_tl(t0, cpu_gpr[ret], 8);
13835 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
13836 tcg_gen_shli_tl(t0, cpu_gpr[ret], 16);
13837 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
13838 tcg_gen_shli_tl(t0, cpu_gpr[ret], 32);
13839 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
13843 tcg_gen_ext32u_i64(cpu_gpr[ret], val_t);
13844 tcg_gen_shli_tl(t0, cpu_gpr[ret], 32);
13845 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
13849 tcg_gen_ext16u_tl(cpu_gpr[ret], val_t);
13850 tcg_gen_shli_tl(t0, cpu_gpr[ret], 16);
13851 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
13852 tcg_gen_shli_tl(t0, cpu_gpr[ret], 32);
13853 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
13860 tcg_temp_free(val_t);
13862 (void)opn; /* avoid a compiler warning */
13863 MIPS_DEBUG("%s", opn);
13866 static void gen_mipsdsp_add_cmp_pick(DisasContext *ctx,
13867 uint32_t op1, uint32_t op2,
13868 int ret, int v1, int v2, int check_ret)
13870 const char *opn = "mipsdsp add compare pick";
13875 if ((ret == 0) && (check_ret == 1)) {
13876 /* Treat as NOP. */
13881 t1 = tcg_temp_new();
13882 v1_t = tcg_temp_new();
13883 v2_t = tcg_temp_new();
13885 gen_load_gpr(v1_t, v1);
13886 gen_load_gpr(v2_t, v2);
13889 case OPC_CMPU_EQ_QB_DSP:
13891 case OPC_CMPU_EQ_QB:
13893 gen_helper_cmpu_eq_qb(v1_t, v2_t, cpu_env);
13895 case OPC_CMPU_LT_QB:
13897 gen_helper_cmpu_lt_qb(v1_t, v2_t, cpu_env);
13899 case OPC_CMPU_LE_QB:
13901 gen_helper_cmpu_le_qb(v1_t, v2_t, cpu_env);
13903 case OPC_CMPGU_EQ_QB:
13905 gen_helper_cmpgu_eq_qb(cpu_gpr[ret], v1_t, v2_t);
13907 case OPC_CMPGU_LT_QB:
13909 gen_helper_cmpgu_lt_qb(cpu_gpr[ret], v1_t, v2_t);
13911 case OPC_CMPGU_LE_QB:
13913 gen_helper_cmpgu_le_qb(cpu_gpr[ret], v1_t, v2_t);
13915 case OPC_CMPGDU_EQ_QB:
13917 gen_helper_cmpgu_eq_qb(t1, v1_t, v2_t);
13918 tcg_gen_mov_tl(cpu_gpr[ret], t1);
13919 tcg_gen_andi_tl(cpu_dspctrl, cpu_dspctrl, 0xF0FFFFFF);
13920 tcg_gen_shli_tl(t1, t1, 24);
13921 tcg_gen_or_tl(cpu_dspctrl, cpu_dspctrl, t1);
13923 case OPC_CMPGDU_LT_QB:
13925 gen_helper_cmpgu_lt_qb(t1, v1_t, v2_t);
13926 tcg_gen_mov_tl(cpu_gpr[ret], t1);
13927 tcg_gen_andi_tl(cpu_dspctrl, cpu_dspctrl, 0xF0FFFFFF);
13928 tcg_gen_shli_tl(t1, t1, 24);
13929 tcg_gen_or_tl(cpu_dspctrl, cpu_dspctrl, t1);
13931 case OPC_CMPGDU_LE_QB:
13933 gen_helper_cmpgu_le_qb(t1, v1_t, v2_t);
13934 tcg_gen_mov_tl(cpu_gpr[ret], t1);
13935 tcg_gen_andi_tl(cpu_dspctrl, cpu_dspctrl, 0xF0FFFFFF);
13936 tcg_gen_shli_tl(t1, t1, 24);
13937 tcg_gen_or_tl(cpu_dspctrl, cpu_dspctrl, t1);
13939 case OPC_CMP_EQ_PH:
13941 gen_helper_cmp_eq_ph(v1_t, v2_t, cpu_env);
13943 case OPC_CMP_LT_PH:
13945 gen_helper_cmp_lt_ph(v1_t, v2_t, cpu_env);
13947 case OPC_CMP_LE_PH:
13949 gen_helper_cmp_le_ph(v1_t, v2_t, cpu_env);
13953 gen_helper_pick_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13957 gen_helper_pick_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13959 case OPC_PACKRL_PH:
13961 gen_helper_packrl_ph(cpu_gpr[ret], v1_t, v2_t);
13965 #ifdef TARGET_MIPS64
13966 case OPC_CMPU_EQ_OB_DSP:
13968 case OPC_CMP_EQ_PW:
13970 gen_helper_cmp_eq_pw(v1_t, v2_t, cpu_env);
13972 case OPC_CMP_LT_PW:
13974 gen_helper_cmp_lt_pw(v1_t, v2_t, cpu_env);
13976 case OPC_CMP_LE_PW:
13978 gen_helper_cmp_le_pw(v1_t, v2_t, cpu_env);
13980 case OPC_CMP_EQ_QH:
13982 gen_helper_cmp_eq_qh(v1_t, v2_t, cpu_env);
13984 case OPC_CMP_LT_QH:
13986 gen_helper_cmp_lt_qh(v1_t, v2_t, cpu_env);
13988 case OPC_CMP_LE_QH:
13990 gen_helper_cmp_le_qh(v1_t, v2_t, cpu_env);
13992 case OPC_CMPGDU_EQ_OB:
13994 gen_helper_cmpgdu_eq_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13996 case OPC_CMPGDU_LT_OB:
13998 gen_helper_cmpgdu_lt_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
14000 case OPC_CMPGDU_LE_OB:
14002 gen_helper_cmpgdu_le_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
14004 case OPC_CMPGU_EQ_OB:
14006 gen_helper_cmpgu_eq_ob(cpu_gpr[ret], v1_t, v2_t);
14008 case OPC_CMPGU_LT_OB:
14010 gen_helper_cmpgu_lt_ob(cpu_gpr[ret], v1_t, v2_t);
14012 case OPC_CMPGU_LE_OB:
14014 gen_helper_cmpgu_le_ob(cpu_gpr[ret], v1_t, v2_t);
14016 case OPC_CMPU_EQ_OB:
14018 gen_helper_cmpu_eq_ob(v1_t, v2_t, cpu_env);
14020 case OPC_CMPU_LT_OB:
14022 gen_helper_cmpu_lt_ob(v1_t, v2_t, cpu_env);
14024 case OPC_CMPU_LE_OB:
14026 gen_helper_cmpu_le_ob(v1_t, v2_t, cpu_env);
14028 case OPC_PACKRL_PW:
14030 gen_helper_packrl_pw(cpu_gpr[ret], v1_t, v2_t);
14034 gen_helper_pick_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
14038 gen_helper_pick_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
14042 gen_helper_pick_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
14050 tcg_temp_free(v1_t);
14051 tcg_temp_free(v2_t);
14053 (void)opn; /* avoid a compiler warning */
14054 MIPS_DEBUG("%s", opn);
14057 static void gen_mipsdsp_append(CPUMIPSState *env, DisasContext *ctx,
14058 uint32_t op1, int rt, int rs, int sa)
14060 const char *opn = "mipsdsp append/dappend";
14066 /* Treat as NOP. */
14071 t0 = tcg_temp_new();
14072 gen_load_gpr(t0, rs);
14075 case OPC_APPEND_DSP:
14076 switch (MASK_APPEND(ctx->opcode)) {
14079 tcg_gen_deposit_tl(cpu_gpr[rt], t0, cpu_gpr[rt], sa, 32 - sa);
14081 tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]);
14085 tcg_gen_ext32u_tl(cpu_gpr[rt], cpu_gpr[rt]);
14086 tcg_gen_shri_tl(cpu_gpr[rt], cpu_gpr[rt], sa);
14087 tcg_gen_shli_tl(t0, t0, 32 - sa);
14088 tcg_gen_or_tl(cpu_gpr[rt], cpu_gpr[rt], t0);
14090 tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]);
14094 if (sa != 0 && sa != 2) {
14095 tcg_gen_shli_tl(cpu_gpr[rt], cpu_gpr[rt], 8 * sa);
14096 tcg_gen_ext32u_tl(t0, t0);
14097 tcg_gen_shri_tl(t0, t0, 8 * (4 - sa));
14098 tcg_gen_or_tl(cpu_gpr[rt], cpu_gpr[rt], t0);
14100 tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]);
14102 default: /* Invalid */
14103 MIPS_INVAL("MASK APPEND");
14104 generate_exception(ctx, EXCP_RI);
14108 #ifdef TARGET_MIPS64
14109 case OPC_DAPPEND_DSP:
14110 switch (MASK_DAPPEND(ctx->opcode)) {
14113 tcg_gen_deposit_tl(cpu_gpr[rt], t0, cpu_gpr[rt], sa, 64 - sa);
14117 tcg_gen_shri_tl(cpu_gpr[rt], cpu_gpr[rt], 0x20 | sa);
14118 tcg_gen_shli_tl(t0, t0, 64 - (0x20 | sa));
14119 tcg_gen_or_tl(cpu_gpr[rt], t0, t0);
14123 tcg_gen_shri_tl(cpu_gpr[rt], cpu_gpr[rt], sa);
14124 tcg_gen_shli_tl(t0, t0, 64 - sa);
14125 tcg_gen_or_tl(cpu_gpr[rt], cpu_gpr[rt], t0);
14130 if (sa != 0 && sa != 2 && sa != 4) {
14131 tcg_gen_shli_tl(cpu_gpr[rt], cpu_gpr[rt], 8 * sa);
14132 tcg_gen_shri_tl(t0, t0, 8 * (8 - sa));
14133 tcg_gen_or_tl(cpu_gpr[rt], cpu_gpr[rt], t0);
14136 default: /* Invalid */
14137 MIPS_INVAL("MASK DAPPEND");
14138 generate_exception(ctx, EXCP_RI);
14145 (void)opn; /* avoid a compiler warning */
14146 MIPS_DEBUG("%s", opn);
14149 static void gen_mipsdsp_accinsn(DisasContext *ctx, uint32_t op1, uint32_t op2,
14150 int ret, int v1, int v2, int check_ret)
14153 const char *opn = "mipsdsp accumulator";
14160 if ((ret == 0) && (check_ret == 1)) {
14161 /* Treat as NOP. */
14166 t0 = tcg_temp_new();
14167 t1 = tcg_temp_new();
14168 v1_t = tcg_temp_new();
14169 v2_t = tcg_temp_new();
14171 gen_load_gpr(v1_t, v1);
14172 gen_load_gpr(v2_t, v2);
14175 case OPC_EXTR_W_DSP:
14179 tcg_gen_movi_tl(t0, v2);
14180 tcg_gen_movi_tl(t1, v1);
14181 gen_helper_extr_w(cpu_gpr[ret], t0, t1, cpu_env);
14184 tcg_gen_movi_tl(t0, v2);
14185 tcg_gen_movi_tl(t1, v1);
14186 gen_helper_extr_r_w(cpu_gpr[ret], t0, t1, cpu_env);
14188 case OPC_EXTR_RS_W:
14189 tcg_gen_movi_tl(t0, v2);
14190 tcg_gen_movi_tl(t1, v1);
14191 gen_helper_extr_rs_w(cpu_gpr[ret], t0, t1, cpu_env);
14194 tcg_gen_movi_tl(t0, v2);
14195 tcg_gen_movi_tl(t1, v1);
14196 gen_helper_extr_s_h(cpu_gpr[ret], t0, t1, cpu_env);
14198 case OPC_EXTRV_S_H:
14199 tcg_gen_movi_tl(t0, v2);
14200 gen_helper_extr_s_h(cpu_gpr[ret], t0, v1_t, cpu_env);
14203 tcg_gen_movi_tl(t0, v2);
14204 gen_helper_extr_w(cpu_gpr[ret], t0, v1_t, cpu_env);
14206 case OPC_EXTRV_R_W:
14207 tcg_gen_movi_tl(t0, v2);
14208 gen_helper_extr_r_w(cpu_gpr[ret], t0, v1_t, cpu_env);
14210 case OPC_EXTRV_RS_W:
14211 tcg_gen_movi_tl(t0, v2);
14212 gen_helper_extr_rs_w(cpu_gpr[ret], t0, v1_t, cpu_env);
14215 tcg_gen_movi_tl(t0, v2);
14216 tcg_gen_movi_tl(t1, v1);
14217 gen_helper_extp(cpu_gpr[ret], t0, t1, cpu_env);
14220 tcg_gen_movi_tl(t0, v2);
14221 gen_helper_extp(cpu_gpr[ret], t0, v1_t, cpu_env);
14224 tcg_gen_movi_tl(t0, v2);
14225 tcg_gen_movi_tl(t1, v1);
14226 gen_helper_extpdp(cpu_gpr[ret], t0, t1, cpu_env);
14229 tcg_gen_movi_tl(t0, v2);
14230 gen_helper_extpdp(cpu_gpr[ret], t0, v1_t, cpu_env);
14233 imm = (ctx->opcode >> 20) & 0x3F;
14234 tcg_gen_movi_tl(t0, ret);
14235 tcg_gen_movi_tl(t1, imm);
14236 gen_helper_shilo(t0, t1, cpu_env);
14239 tcg_gen_movi_tl(t0, ret);
14240 gen_helper_shilo(t0, v1_t, cpu_env);
14243 tcg_gen_movi_tl(t0, ret);
14244 gen_helper_mthlip(t0, v1_t, cpu_env);
14247 imm = (ctx->opcode >> 11) & 0x3FF;
14248 tcg_gen_movi_tl(t0, imm);
14249 gen_helper_wrdsp(v1_t, t0, cpu_env);
14252 imm = (ctx->opcode >> 16) & 0x03FF;
14253 tcg_gen_movi_tl(t0, imm);
14254 gen_helper_rddsp(cpu_gpr[ret], t0, cpu_env);
14258 #ifdef TARGET_MIPS64
14259 case OPC_DEXTR_W_DSP:
14263 tcg_gen_movi_tl(t0, ret);
14264 gen_helper_dmthlip(v1_t, t0, cpu_env);
14268 int shift = (ctx->opcode >> 19) & 0x7F;
14269 int ac = (ctx->opcode >> 11) & 0x03;
14270 tcg_gen_movi_tl(t0, shift);
14271 tcg_gen_movi_tl(t1, ac);
14272 gen_helper_dshilo(t0, t1, cpu_env);
14277 int ac = (ctx->opcode >> 11) & 0x03;
14278 tcg_gen_movi_tl(t0, ac);
14279 gen_helper_dshilo(v1_t, t0, cpu_env);
14283 tcg_gen_movi_tl(t0, v2);
14284 tcg_gen_movi_tl(t1, v1);
14286 gen_helper_dextp(cpu_gpr[ret], t0, t1, cpu_env);
14289 tcg_gen_movi_tl(t0, v2);
14290 gen_helper_dextp(cpu_gpr[ret], t0, v1_t, cpu_env);
14293 tcg_gen_movi_tl(t0, v2);
14294 tcg_gen_movi_tl(t1, v1);
14295 gen_helper_dextpdp(cpu_gpr[ret], t0, t1, cpu_env);
14298 tcg_gen_movi_tl(t0, v2);
14299 gen_helper_dextpdp(cpu_gpr[ret], t0, v1_t, cpu_env);
14302 tcg_gen_movi_tl(t0, v2);
14303 tcg_gen_movi_tl(t1, v1);
14304 gen_helper_dextr_l(cpu_gpr[ret], t0, t1, cpu_env);
14306 case OPC_DEXTR_R_L:
14307 tcg_gen_movi_tl(t0, v2);
14308 tcg_gen_movi_tl(t1, v1);
14309 gen_helper_dextr_r_l(cpu_gpr[ret], t0, t1, cpu_env);
14311 case OPC_DEXTR_RS_L:
14312 tcg_gen_movi_tl(t0, v2);
14313 tcg_gen_movi_tl(t1, v1);
14314 gen_helper_dextr_rs_l(cpu_gpr[ret], t0, t1, cpu_env);
14317 tcg_gen_movi_tl(t0, v2);
14318 tcg_gen_movi_tl(t1, v1);
14319 gen_helper_dextr_w(cpu_gpr[ret], t0, t1, cpu_env);
14321 case OPC_DEXTR_R_W:
14322 tcg_gen_movi_tl(t0, v2);
14323 tcg_gen_movi_tl(t1, v1);
14324 gen_helper_dextr_r_w(cpu_gpr[ret], t0, t1, cpu_env);
14326 case OPC_DEXTR_RS_W:
14327 tcg_gen_movi_tl(t0, v2);
14328 tcg_gen_movi_tl(t1, v1);
14329 gen_helper_dextr_rs_w(cpu_gpr[ret], t0, t1, cpu_env);
14331 case OPC_DEXTR_S_H:
14332 tcg_gen_movi_tl(t0, v2);
14333 tcg_gen_movi_tl(t1, v1);
14334 gen_helper_dextr_s_h(cpu_gpr[ret], t0, t1, cpu_env);
14336 case OPC_DEXTRV_S_H:
14337 tcg_gen_movi_tl(t0, v2);
14338 tcg_gen_movi_tl(t1, v1);
14339 gen_helper_dextr_s_h(cpu_gpr[ret], t0, t1, cpu_env);
14342 tcg_gen_movi_tl(t0, v2);
14343 gen_helper_dextr_l(cpu_gpr[ret], t0, v1_t, cpu_env);
14345 case OPC_DEXTRV_R_L:
14346 tcg_gen_movi_tl(t0, v2);
14347 gen_helper_dextr_r_l(cpu_gpr[ret], t0, v1_t, cpu_env);
14349 case OPC_DEXTRV_RS_L:
14350 tcg_gen_movi_tl(t0, v2);
14351 gen_helper_dextr_rs_l(cpu_gpr[ret], t0, v1_t, cpu_env);
14354 tcg_gen_movi_tl(t0, v2);
14355 gen_helper_dextr_w(cpu_gpr[ret], t0, v1_t, cpu_env);
14357 case OPC_DEXTRV_R_W:
14358 tcg_gen_movi_tl(t0, v2);
14359 gen_helper_dextr_r_w(cpu_gpr[ret], t0, v1_t, cpu_env);
14361 case OPC_DEXTRV_RS_W:
14362 tcg_gen_movi_tl(t0, v2);
14363 gen_helper_dextr_rs_w(cpu_gpr[ret], t0, v1_t, cpu_env);
14372 tcg_temp_free(v1_t);
14373 tcg_temp_free(v2_t);
14375 (void)opn; /* avoid a compiler warning */
14376 MIPS_DEBUG("%s", opn);
14379 /* End MIPSDSP functions. */
14381 static void decode_opc (CPUMIPSState *env, DisasContext *ctx, int *is_branch)
14384 int rs, rt, rd, sa;
14385 uint32_t op, op1, op2;
14388 /* make sure instructions are on a word boundary */
14389 if (ctx->pc & 0x3) {
14390 env->CP0_BadVAddr = ctx->pc;
14391 generate_exception(ctx, EXCP_AdEL);
14395 /* Handle blikely not taken case */
14396 if ((ctx->hflags & MIPS_HFLAG_BMASK_BASE) == MIPS_HFLAG_BL) {
14397 int l1 = gen_new_label();
14399 MIPS_DEBUG("blikely condition (" TARGET_FMT_lx ")", ctx->pc + 4);
14400 tcg_gen_brcondi_tl(TCG_COND_NE, bcond, 0, l1);
14401 tcg_gen_movi_i32(hflags, ctx->hflags & ~MIPS_HFLAG_BMASK);
14402 gen_goto_tb(ctx, 1, ctx->pc + 4);
14406 if (unlikely(qemu_loglevel_mask(CPU_LOG_TB_OP | CPU_LOG_TB_OP_OPT))) {
14407 tcg_gen_debug_insn_start(ctx->pc);
14410 op = MASK_OP_MAJOR(ctx->opcode);
14411 rs = (ctx->opcode >> 21) & 0x1f;
14412 rt = (ctx->opcode >> 16) & 0x1f;
14413 rd = (ctx->opcode >> 11) & 0x1f;
14414 sa = (ctx->opcode >> 6) & 0x1f;
14415 imm = (int16_t)ctx->opcode;
14418 op1 = MASK_SPECIAL(ctx->opcode);
14420 case OPC_SLL: /* Shift with immediate */
14422 gen_shift_imm(ctx, op1, rd, rt, sa);
14425 switch ((ctx->opcode >> 21) & 0x1f) {
14427 /* rotr is decoded as srl on non-R2 CPUs */
14428 if (ctx->insn_flags & ISA_MIPS32R2) {
14433 gen_shift_imm(ctx, op1, rd, rt, sa);
14436 generate_exception(ctx, EXCP_RI);
14440 case OPC_MOVN: /* Conditional move */
14442 check_insn(ctx, ISA_MIPS4 | ISA_MIPS32 |
14443 INSN_LOONGSON2E | INSN_LOONGSON2F);
14444 gen_cond_move(ctx, op1, rd, rs, rt);
14446 case OPC_ADD ... OPC_SUBU:
14447 gen_arith(ctx, op1, rd, rs, rt);
14449 case OPC_SLLV: /* Shifts */
14451 gen_shift(ctx, op1, rd, rs, rt);
14454 switch ((ctx->opcode >> 6) & 0x1f) {
14456 /* rotrv is decoded as srlv on non-R2 CPUs */
14457 if (ctx->insn_flags & ISA_MIPS32R2) {
14462 gen_shift(ctx, op1, rd, rs, rt);
14465 generate_exception(ctx, EXCP_RI);
14469 case OPC_SLT: /* Set on less than */
14471 gen_slt(ctx, op1, rd, rs, rt);
14473 case OPC_AND: /* Logic*/
14477 gen_logic(ctx, op1, rd, rs, rt);
14479 case OPC_MULT ... OPC_DIVU:
14481 check_insn(ctx, INSN_VR54XX);
14482 op1 = MASK_MUL_VR54XX(ctx->opcode);
14483 gen_mul_vr54xx(ctx, op1, rd, rs, rt);
14485 gen_muldiv(ctx, op1, rs, rt);
14487 case OPC_JR ... OPC_JALR:
14488 gen_compute_branch(ctx, op1, 4, rs, rd, sa);
14491 case OPC_TGE ... OPC_TEQ: /* Traps */
14493 gen_trap(ctx, op1, rs, rt, -1);
14495 case OPC_MFHI: /* Move from HI/LO */
14497 gen_HILO(ctx, op1, rd);
14500 case OPC_MTLO: /* Move to HI/LO */
14501 gen_HILO(ctx, op1, rs);
14503 case OPC_PMON: /* Pmon entry point, also R4010 selsl */
14504 #ifdef MIPS_STRICT_STANDARD
14505 MIPS_INVAL("PMON / selsl");
14506 generate_exception(ctx, EXCP_RI);
14508 gen_helper_0e0i(pmon, sa);
14512 generate_exception(ctx, EXCP_SYSCALL);
14513 ctx->bstate = BS_STOP;
14516 generate_exception(ctx, EXCP_BREAK);
14519 #ifdef MIPS_STRICT_STANDARD
14520 MIPS_INVAL("SPIM");
14521 generate_exception(ctx, EXCP_RI);
14523 /* Implemented as RI exception for now. */
14524 MIPS_INVAL("spim (unofficial)");
14525 generate_exception(ctx, EXCP_RI);
14529 /* Treat as NOP. */
14533 check_insn(ctx, ISA_MIPS4 | ISA_MIPS32);
14534 if (env->CP0_Config1 & (1 << CP0C1_FP)) {
14535 check_cp1_enabled(ctx);
14536 gen_movci(ctx, rd, rs, (ctx->opcode >> 18) & 0x7,
14537 (ctx->opcode >> 16) & 1);
14539 generate_exception_err(ctx, EXCP_CpU, 1);
14543 #if defined(TARGET_MIPS64)
14544 /* MIPS64 specific opcodes */
14549 check_insn(ctx, ISA_MIPS3);
14550 check_mips_64(ctx);
14551 gen_shift_imm(ctx, op1, rd, rt, sa);
14554 switch ((ctx->opcode >> 21) & 0x1f) {
14556 /* drotr is decoded as dsrl on non-R2 CPUs */
14557 if (ctx->insn_flags & ISA_MIPS32R2) {
14562 check_insn(ctx, ISA_MIPS3);
14563 check_mips_64(ctx);
14564 gen_shift_imm(ctx, op1, rd, rt, sa);
14567 generate_exception(ctx, EXCP_RI);
14572 switch ((ctx->opcode >> 21) & 0x1f) {
14574 /* drotr32 is decoded as dsrl32 on non-R2 CPUs */
14575 if (ctx->insn_flags & ISA_MIPS32R2) {
14580 check_insn(ctx, ISA_MIPS3);
14581 check_mips_64(ctx);
14582 gen_shift_imm(ctx, op1, rd, rt, sa);
14585 generate_exception(ctx, EXCP_RI);
14589 case OPC_DADD ... OPC_DSUBU:
14590 check_insn(ctx, ISA_MIPS3);
14591 check_mips_64(ctx);
14592 gen_arith(ctx, op1, rd, rs, rt);
14596 check_insn(ctx, ISA_MIPS3);
14597 check_mips_64(ctx);
14598 gen_shift(ctx, op1, rd, rs, rt);
14601 switch ((ctx->opcode >> 6) & 0x1f) {
14603 /* drotrv is decoded as dsrlv on non-R2 CPUs */
14604 if (ctx->insn_flags & ISA_MIPS32R2) {
14609 check_insn(ctx, ISA_MIPS3);
14610 check_mips_64(ctx);
14611 gen_shift(ctx, op1, rd, rs, rt);
14614 generate_exception(ctx, EXCP_RI);
14618 case OPC_DMULT ... OPC_DDIVU:
14619 check_insn(ctx, ISA_MIPS3);
14620 check_mips_64(ctx);
14621 gen_muldiv(ctx, op1, rs, rt);
14624 default: /* Invalid */
14625 MIPS_INVAL("special");
14626 generate_exception(ctx, EXCP_RI);
14631 op1 = MASK_SPECIAL2(ctx->opcode);
14633 case OPC_MADD ... OPC_MADDU: /* Multiply and add/sub */
14634 case OPC_MSUB ... OPC_MSUBU:
14635 check_insn(ctx, ISA_MIPS32);
14636 gen_muldiv(ctx, op1, rs, rt);
14639 gen_arith(ctx, op1, rd, rs, rt);
14643 check_insn(ctx, ISA_MIPS32);
14644 gen_cl(ctx, op1, rd, rs);
14647 /* XXX: not clear which exception should be raised
14648 * when in debug mode...
14650 check_insn(ctx, ISA_MIPS32);
14651 if (!(ctx->hflags & MIPS_HFLAG_DM)) {
14652 generate_exception(ctx, EXCP_DBp);
14654 generate_exception(ctx, EXCP_DBp);
14656 /* Treat as NOP. */
14659 case OPC_DIVU_G_2F:
14660 case OPC_MULT_G_2F:
14661 case OPC_MULTU_G_2F:
14663 case OPC_MODU_G_2F:
14664 check_insn(ctx, INSN_LOONGSON2F);
14665 gen_loongson_integer(ctx, op1, rd, rs, rt);
14667 #if defined(TARGET_MIPS64)
14670 check_insn(ctx, ISA_MIPS64);
14671 check_mips_64(ctx);
14672 gen_cl(ctx, op1, rd, rs);
14674 case OPC_DMULT_G_2F:
14675 case OPC_DMULTU_G_2F:
14676 case OPC_DDIV_G_2F:
14677 case OPC_DDIVU_G_2F:
14678 case OPC_DMOD_G_2F:
14679 case OPC_DMODU_G_2F:
14680 check_insn(ctx, INSN_LOONGSON2F);
14681 gen_loongson_integer(ctx, op1, rd, rs, rt);
14684 default: /* Invalid */
14685 MIPS_INVAL("special2");
14686 generate_exception(ctx, EXCP_RI);
14691 op1 = MASK_SPECIAL3(ctx->opcode);
14695 check_insn(ctx, ISA_MIPS32R2);
14696 gen_bitops(ctx, op1, rt, rs, sa, rd);
14699 check_insn(ctx, ISA_MIPS32R2);
14700 op2 = MASK_BSHFL(ctx->opcode);
14701 gen_bshfl(ctx, op2, rt, rd);
14704 gen_rdhwr(ctx, rt, rd);
14707 check_insn(ctx, ASE_MT);
14709 TCGv t0 = tcg_temp_new();
14710 TCGv t1 = tcg_temp_new();
14712 gen_load_gpr(t0, rt);
14713 gen_load_gpr(t1, rs);
14714 gen_helper_fork(t0, t1);
14720 check_insn(ctx, ASE_MT);
14722 TCGv t0 = tcg_temp_new();
14724 save_cpu_state(ctx, 1);
14725 gen_load_gpr(t0, rs);
14726 gen_helper_yield(t0, cpu_env, t0);
14727 gen_store_gpr(t0, rd);
14731 case OPC_DIV_G_2E ... OPC_DIVU_G_2E:
14732 case OPC_MOD_G_2E ... OPC_MODU_G_2E:
14733 case OPC_MULT_G_2E ... OPC_MULTU_G_2E:
14734 /* OPC_MULT_G_2E, OPC_ADDUH_QB_DSP, OPC_MUL_PH_DSP have
14735 * the same mask and op1. */
14736 if ((ctx->insn_flags & ASE_DSPR2) && (op1 == OPC_MULT_G_2E)) {
14737 op2 = MASK_ADDUH_QB(ctx->opcode);
14740 case OPC_ADDUH_R_QB:
14742 case OPC_ADDQH_R_PH:
14744 case OPC_ADDQH_R_W:
14746 case OPC_SUBUH_R_QB:
14748 case OPC_SUBQH_R_PH:
14750 case OPC_SUBQH_R_W:
14751 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
14756 case OPC_MULQ_RS_W:
14757 gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 1);
14760 MIPS_INVAL("MASK ADDUH.QB");
14761 generate_exception(ctx, EXCP_RI);
14764 } else if (ctx->insn_flags & INSN_LOONGSON2E) {
14765 gen_loongson_integer(ctx, op1, rd, rs, rt);
14767 generate_exception(ctx, EXCP_RI);
14771 op2 = MASK_LX(ctx->opcode);
14773 #if defined(TARGET_MIPS64)
14779 gen_mipsdsp_ld(ctx, op2, rd, rs, rt);
14781 default: /* Invalid */
14782 MIPS_INVAL("MASK LX");
14783 generate_exception(ctx, EXCP_RI);
14787 case OPC_ABSQ_S_PH_DSP:
14788 op2 = MASK_ABSQ_S_PH(ctx->opcode);
14790 case OPC_ABSQ_S_QB:
14791 case OPC_ABSQ_S_PH:
14793 case OPC_PRECEQ_W_PHL:
14794 case OPC_PRECEQ_W_PHR:
14795 case OPC_PRECEQU_PH_QBL:
14796 case OPC_PRECEQU_PH_QBR:
14797 case OPC_PRECEQU_PH_QBLA:
14798 case OPC_PRECEQU_PH_QBRA:
14799 case OPC_PRECEU_PH_QBL:
14800 case OPC_PRECEU_PH_QBR:
14801 case OPC_PRECEU_PH_QBLA:
14802 case OPC_PRECEU_PH_QBRA:
14803 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
14810 gen_mipsdsp_bitinsn(ctx, op1, op2, rd, rt);
14813 MIPS_INVAL("MASK ABSQ_S.PH");
14814 generate_exception(ctx, EXCP_RI);
14818 case OPC_ADDU_QB_DSP:
14819 op2 = MASK_ADDU_QB(ctx->opcode);
14822 case OPC_ADDQ_S_PH:
14825 case OPC_ADDU_S_QB:
14827 case OPC_ADDU_S_PH:
14829 case OPC_SUBQ_S_PH:
14832 case OPC_SUBU_S_QB:
14834 case OPC_SUBU_S_PH:
14838 case OPC_RADDU_W_QB:
14839 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
14841 case OPC_MULEU_S_PH_QBL:
14842 case OPC_MULEU_S_PH_QBR:
14843 case OPC_MULQ_RS_PH:
14844 case OPC_MULEQ_S_W_PHL:
14845 case OPC_MULEQ_S_W_PHR:
14846 case OPC_MULQ_S_PH:
14847 gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 1);
14849 default: /* Invalid */
14850 MIPS_INVAL("MASK ADDU.QB");
14851 generate_exception(ctx, EXCP_RI);
14856 case OPC_CMPU_EQ_QB_DSP:
14857 op2 = MASK_CMPU_EQ_QB(ctx->opcode);
14859 case OPC_PRECR_SRA_PH_W:
14860 case OPC_PRECR_SRA_R_PH_W:
14861 gen_mipsdsp_arith(ctx, op1, op2, rt, rs, rd);
14863 case OPC_PRECR_QB_PH:
14864 case OPC_PRECRQ_QB_PH:
14865 case OPC_PRECRQ_PH_W:
14866 case OPC_PRECRQ_RS_PH_W:
14867 case OPC_PRECRQU_S_QB_PH:
14868 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
14870 case OPC_CMPU_EQ_QB:
14871 case OPC_CMPU_LT_QB:
14872 case OPC_CMPU_LE_QB:
14873 case OPC_CMP_EQ_PH:
14874 case OPC_CMP_LT_PH:
14875 case OPC_CMP_LE_PH:
14876 gen_mipsdsp_add_cmp_pick(ctx, op1, op2, rd, rs, rt, 0);
14878 case OPC_CMPGU_EQ_QB:
14879 case OPC_CMPGU_LT_QB:
14880 case OPC_CMPGU_LE_QB:
14881 case OPC_CMPGDU_EQ_QB:
14882 case OPC_CMPGDU_LT_QB:
14883 case OPC_CMPGDU_LE_QB:
14886 case OPC_PACKRL_PH:
14887 gen_mipsdsp_add_cmp_pick(ctx, op1, op2, rd, rs, rt, 1);
14889 default: /* Invalid */
14890 MIPS_INVAL("MASK CMPU.EQ.QB");
14891 generate_exception(ctx, EXCP_RI);
14895 case OPC_SHLL_QB_DSP:
14896 gen_mipsdsp_shift(ctx, op1, rd, rs, rt);
14898 case OPC_DPA_W_PH_DSP:
14899 op2 = MASK_DPA_W_PH(ctx->opcode);
14901 case OPC_DPAU_H_QBL:
14902 case OPC_DPAU_H_QBR:
14903 case OPC_DPSU_H_QBL:
14904 case OPC_DPSU_H_QBR:
14906 case OPC_DPAX_W_PH:
14907 case OPC_DPAQ_S_W_PH:
14908 case OPC_DPAQX_S_W_PH:
14909 case OPC_DPAQX_SA_W_PH:
14911 case OPC_DPSX_W_PH:
14912 case OPC_DPSQ_S_W_PH:
14913 case OPC_DPSQX_S_W_PH:
14914 case OPC_DPSQX_SA_W_PH:
14915 case OPC_MULSAQ_S_W_PH:
14916 case OPC_DPAQ_SA_L_W:
14917 case OPC_DPSQ_SA_L_W:
14918 case OPC_MAQ_S_W_PHL:
14919 case OPC_MAQ_S_W_PHR:
14920 case OPC_MAQ_SA_W_PHL:
14921 case OPC_MAQ_SA_W_PHR:
14922 case OPC_MULSA_W_PH:
14923 gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 0);
14925 default: /* Invalid */
14926 MIPS_INVAL("MASK DPAW.PH");
14927 generate_exception(ctx, EXCP_RI);
14932 op2 = MASK_INSV(ctx->opcode);
14944 t0 = tcg_temp_new();
14945 t1 = tcg_temp_new();
14947 gen_load_gpr(t0, rt);
14948 gen_load_gpr(t1, rs);
14950 gen_helper_insv(cpu_gpr[rt], cpu_env, t1, t0);
14956 default: /* Invalid */
14957 MIPS_INVAL("MASK INSV");
14958 generate_exception(ctx, EXCP_RI);
14962 case OPC_APPEND_DSP:
14963 gen_mipsdsp_append(env, ctx, op1, rt, rs, rd);
14965 case OPC_EXTR_W_DSP:
14966 op2 = MASK_EXTR_W(ctx->opcode);
14970 case OPC_EXTR_RS_W:
14972 case OPC_EXTRV_S_H:
14974 case OPC_EXTRV_R_W:
14975 case OPC_EXTRV_RS_W:
14980 gen_mipsdsp_accinsn(ctx, op1, op2, rt, rs, rd, 1);
14983 gen_mipsdsp_accinsn(ctx, op1, op2, rd, rs, rt, 1);
14989 gen_mipsdsp_accinsn(ctx, op1, op2, rd, rs, rt, 0);
14991 default: /* Invalid */
14992 MIPS_INVAL("MASK EXTR.W");
14993 generate_exception(ctx, EXCP_RI);
14997 #if defined(TARGET_MIPS64)
14998 case OPC_DEXTM ... OPC_DEXT:
14999 case OPC_DINSM ... OPC_DINS:
15000 check_insn(ctx, ISA_MIPS64R2);
15001 check_mips_64(ctx);
15002 gen_bitops(ctx, op1, rt, rs, sa, rd);
15005 check_insn(ctx, ISA_MIPS64R2);
15006 check_mips_64(ctx);
15007 op2 = MASK_DBSHFL(ctx->opcode);
15008 gen_bshfl(ctx, op2, rt, rd);
15010 case OPC_DDIV_G_2E ... OPC_DDIVU_G_2E:
15011 case OPC_DMULT_G_2E ... OPC_DMULTU_G_2E:
15012 case OPC_DMOD_G_2E ... OPC_DMODU_G_2E:
15013 check_insn(ctx, INSN_LOONGSON2E);
15014 gen_loongson_integer(ctx, op1, rd, rs, rt);
15016 case OPC_ABSQ_S_QH_DSP:
15017 op2 = MASK_ABSQ_S_QH(ctx->opcode);
15019 case OPC_PRECEQ_L_PWL:
15020 case OPC_PRECEQ_L_PWR:
15021 case OPC_PRECEQ_PW_QHL:
15022 case OPC_PRECEQ_PW_QHR:
15023 case OPC_PRECEQ_PW_QHLA:
15024 case OPC_PRECEQ_PW_QHRA:
15025 case OPC_PRECEQU_QH_OBL:
15026 case OPC_PRECEQU_QH_OBR:
15027 case OPC_PRECEQU_QH_OBLA:
15028 case OPC_PRECEQU_QH_OBRA:
15029 case OPC_PRECEU_QH_OBL:
15030 case OPC_PRECEU_QH_OBR:
15031 case OPC_PRECEU_QH_OBLA:
15032 case OPC_PRECEU_QH_OBRA:
15033 case OPC_ABSQ_S_OB:
15034 case OPC_ABSQ_S_PW:
15035 case OPC_ABSQ_S_QH:
15036 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
15044 gen_mipsdsp_bitinsn(ctx, op1, op2, rd, rt);
15046 default: /* Invalid */
15047 MIPS_INVAL("MASK ABSQ_S.QH");
15048 generate_exception(ctx, EXCP_RI);
15052 case OPC_ADDU_OB_DSP:
15053 op2 = MASK_ADDU_OB(ctx->opcode);
15055 case OPC_RADDU_L_OB:
15057 case OPC_SUBQ_S_PW:
15059 case OPC_SUBQ_S_QH:
15061 case OPC_SUBU_S_OB:
15063 case OPC_SUBU_S_QH:
15065 case OPC_SUBUH_R_OB:
15067 case OPC_ADDQ_S_PW:
15069 case OPC_ADDQ_S_QH:
15071 case OPC_ADDU_S_OB:
15073 case OPC_ADDU_S_QH:
15075 case OPC_ADDUH_R_OB:
15076 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
15078 case OPC_MULEQ_S_PW_QHL:
15079 case OPC_MULEQ_S_PW_QHR:
15080 case OPC_MULEU_S_QH_OBL:
15081 case OPC_MULEU_S_QH_OBR:
15082 case OPC_MULQ_RS_QH:
15083 gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 1);
15085 default: /* Invalid */
15086 MIPS_INVAL("MASK ADDU.OB");
15087 generate_exception(ctx, EXCP_RI);
15091 case OPC_CMPU_EQ_OB_DSP:
15092 op2 = MASK_CMPU_EQ_OB(ctx->opcode);
15094 case OPC_PRECR_SRA_QH_PW:
15095 case OPC_PRECR_SRA_R_QH_PW:
15096 /* Return value is rt. */
15097 gen_mipsdsp_arith(ctx, op1, op2, rt, rs, rd);
15099 case OPC_PRECR_OB_QH:
15100 case OPC_PRECRQ_OB_QH:
15101 case OPC_PRECRQ_PW_L:
15102 case OPC_PRECRQ_QH_PW:
15103 case OPC_PRECRQ_RS_QH_PW:
15104 case OPC_PRECRQU_S_OB_QH:
15105 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
15107 case OPC_CMPU_EQ_OB:
15108 case OPC_CMPU_LT_OB:
15109 case OPC_CMPU_LE_OB:
15110 case OPC_CMP_EQ_QH:
15111 case OPC_CMP_LT_QH:
15112 case OPC_CMP_LE_QH:
15113 case OPC_CMP_EQ_PW:
15114 case OPC_CMP_LT_PW:
15115 case OPC_CMP_LE_PW:
15116 gen_mipsdsp_add_cmp_pick(ctx, op1, op2, rd, rs, rt, 0);
15118 case OPC_CMPGDU_EQ_OB:
15119 case OPC_CMPGDU_LT_OB:
15120 case OPC_CMPGDU_LE_OB:
15121 case OPC_CMPGU_EQ_OB:
15122 case OPC_CMPGU_LT_OB:
15123 case OPC_CMPGU_LE_OB:
15124 case OPC_PACKRL_PW:
15128 gen_mipsdsp_add_cmp_pick(ctx, op1, op2, rd, rs, rt, 1);
15130 default: /* Invalid */
15131 MIPS_INVAL("MASK CMPU_EQ.OB");
15132 generate_exception(ctx, EXCP_RI);
15136 case OPC_DAPPEND_DSP:
15137 gen_mipsdsp_append(env, ctx, op1, rt, rs, rd);
15139 case OPC_DEXTR_W_DSP:
15140 op2 = MASK_DEXTR_W(ctx->opcode);
15147 case OPC_DEXTR_R_L:
15148 case OPC_DEXTR_RS_L:
15150 case OPC_DEXTR_R_W:
15151 case OPC_DEXTR_RS_W:
15152 case OPC_DEXTR_S_H:
15154 case OPC_DEXTRV_R_L:
15155 case OPC_DEXTRV_RS_L:
15156 case OPC_DEXTRV_S_H:
15158 case OPC_DEXTRV_R_W:
15159 case OPC_DEXTRV_RS_W:
15160 gen_mipsdsp_accinsn(ctx, op1, op2, rt, rs, rd, 1);
15165 gen_mipsdsp_accinsn(ctx, op1, op2, rd, rs, rt, 0);
15167 default: /* Invalid */
15168 MIPS_INVAL("MASK EXTR.W");
15169 generate_exception(ctx, EXCP_RI);
15173 case OPC_DPAQ_W_QH_DSP:
15174 op2 = MASK_DPAQ_W_QH(ctx->opcode);
15176 case OPC_DPAU_H_OBL:
15177 case OPC_DPAU_H_OBR:
15178 case OPC_DPSU_H_OBL:
15179 case OPC_DPSU_H_OBR:
15181 case OPC_DPAQ_S_W_QH:
15183 case OPC_DPSQ_S_W_QH:
15184 case OPC_MULSAQ_S_W_QH:
15185 case OPC_DPAQ_SA_L_PW:
15186 case OPC_DPSQ_SA_L_PW:
15187 case OPC_MULSAQ_S_L_PW:
15188 gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 0);
15190 case OPC_MAQ_S_W_QHLL:
15191 case OPC_MAQ_S_W_QHLR:
15192 case OPC_MAQ_S_W_QHRL:
15193 case OPC_MAQ_S_W_QHRR:
15194 case OPC_MAQ_SA_W_QHLL:
15195 case OPC_MAQ_SA_W_QHLR:
15196 case OPC_MAQ_SA_W_QHRL:
15197 case OPC_MAQ_SA_W_QHRR:
15198 case OPC_MAQ_S_L_PWL:
15199 case OPC_MAQ_S_L_PWR:
15204 gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 0);
15206 default: /* Invalid */
15207 MIPS_INVAL("MASK DPAQ.W.QH");
15208 generate_exception(ctx, EXCP_RI);
15212 case OPC_DINSV_DSP:
15213 op2 = MASK_INSV(ctx->opcode);
15225 t0 = tcg_temp_new();
15226 t1 = tcg_temp_new();
15228 gen_load_gpr(t0, rt);
15229 gen_load_gpr(t1, rs);
15231 gen_helper_dinsv(cpu_gpr[rt], cpu_env, t1, t0);
15234 default: /* Invalid */
15235 MIPS_INVAL("MASK DINSV");
15236 generate_exception(ctx, EXCP_RI);
15240 case OPC_SHLL_OB_DSP:
15241 gen_mipsdsp_shift(ctx, op1, rd, rs, rt);
15244 default: /* Invalid */
15245 MIPS_INVAL("special3");
15246 generate_exception(ctx, EXCP_RI);
15251 op1 = MASK_REGIMM(ctx->opcode);
15253 case OPC_BLTZ ... OPC_BGEZL: /* REGIMM branches */
15254 case OPC_BLTZAL ... OPC_BGEZALL:
15255 gen_compute_branch(ctx, op1, 4, rs, -1, imm << 2);
15258 case OPC_TGEI ... OPC_TEQI: /* REGIMM traps */
15260 gen_trap(ctx, op1, rs, -1, imm);
15263 check_insn(ctx, ISA_MIPS32R2);
15264 /* Treat as NOP. */
15266 case OPC_BPOSGE32: /* MIPS DSP branch */
15267 #if defined(TARGET_MIPS64)
15271 gen_compute_branch(ctx, op1, 4, -1, -2, (int32_t)imm << 2);
15274 default: /* Invalid */
15275 MIPS_INVAL("regimm");
15276 generate_exception(ctx, EXCP_RI);
15281 check_cp0_enabled(ctx);
15282 op1 = MASK_CP0(ctx->opcode);
15288 #if defined(TARGET_MIPS64)
15292 #ifndef CONFIG_USER_ONLY
15293 gen_cp0(env, ctx, op1, rt, rd);
15294 #endif /* !CONFIG_USER_ONLY */
15296 case OPC_C0_FIRST ... OPC_C0_LAST:
15297 #ifndef CONFIG_USER_ONLY
15298 gen_cp0(env, ctx, MASK_C0(ctx->opcode), rt, rd);
15299 #endif /* !CONFIG_USER_ONLY */
15302 #ifndef CONFIG_USER_ONLY
15304 TCGv t0 = tcg_temp_new();
15306 op2 = MASK_MFMC0(ctx->opcode);
15309 check_insn(ctx, ASE_MT);
15310 gen_helper_dmt(t0);
15311 gen_store_gpr(t0, rt);
15314 check_insn(ctx, ASE_MT);
15315 gen_helper_emt(t0);
15316 gen_store_gpr(t0, rt);
15319 check_insn(ctx, ASE_MT);
15320 gen_helper_dvpe(t0, cpu_env);
15321 gen_store_gpr(t0, rt);
15324 check_insn(ctx, ASE_MT);
15325 gen_helper_evpe(t0, cpu_env);
15326 gen_store_gpr(t0, rt);
15329 check_insn(ctx, ISA_MIPS32R2);
15330 save_cpu_state(ctx, 1);
15331 gen_helper_di(t0, cpu_env);
15332 gen_store_gpr(t0, rt);
15333 /* Stop translation as we may have switched the execution mode */
15334 ctx->bstate = BS_STOP;
15337 check_insn(ctx, ISA_MIPS32R2);
15338 save_cpu_state(ctx, 1);
15339 gen_helper_ei(t0, cpu_env);
15340 gen_store_gpr(t0, rt);
15341 /* Stop translation as we may have switched the execution mode */
15342 ctx->bstate = BS_STOP;
15344 default: /* Invalid */
15345 MIPS_INVAL("mfmc0");
15346 generate_exception(ctx, EXCP_RI);
15351 #endif /* !CONFIG_USER_ONLY */
15354 check_insn(ctx, ISA_MIPS32R2);
15355 gen_load_srsgpr(rt, rd);
15358 check_insn(ctx, ISA_MIPS32R2);
15359 gen_store_srsgpr(rt, rd);
15363 generate_exception(ctx, EXCP_RI);
15367 case OPC_ADDI: /* Arithmetic with immediate opcode */
15369 gen_arith_imm(ctx, op, rt, rs, imm);
15371 case OPC_SLTI: /* Set on less than with immediate opcode */
15373 gen_slt_imm(ctx, op, rt, rs, imm);
15375 case OPC_ANDI: /* Arithmetic with immediate opcode */
15379 gen_logic_imm(ctx, op, rt, rs, imm);
15381 case OPC_J ... OPC_JAL: /* Jump */
15382 offset = (int32_t)(ctx->opcode & 0x3FFFFFF) << 2;
15383 gen_compute_branch(ctx, op, 4, rs, rt, offset);
15386 case OPC_BEQ ... OPC_BGTZ: /* Branch */
15387 case OPC_BEQL ... OPC_BGTZL:
15388 gen_compute_branch(ctx, op, 4, rs, rt, imm << 2);
15391 case OPC_LB ... OPC_LWR: /* Load and stores */
15393 gen_ld(ctx, op, rt, rs, imm);
15395 case OPC_SB ... OPC_SW:
15397 gen_st(ctx, op, rt, rs, imm);
15400 gen_st_cond(ctx, op, rt, rs, imm);
15403 check_cp0_enabled(ctx);
15404 check_insn(ctx, ISA_MIPS3 | ISA_MIPS32);
15405 /* Treat as NOP. */
15408 check_insn(ctx, ISA_MIPS4 | ISA_MIPS32);
15409 /* Treat as NOP. */
15412 /* Floating point (COP1). */
15417 gen_cop1_ldst(env, ctx, op, rt, rs, imm);
15421 if (env->CP0_Config1 & (1 << CP0C1_FP)) {
15422 check_cp1_enabled(ctx);
15423 op1 = MASK_CP1(ctx->opcode);
15427 check_insn(ctx, ISA_MIPS32R2);
15432 gen_cp1(ctx, op1, rt, rd);
15434 #if defined(TARGET_MIPS64)
15437 check_insn(ctx, ISA_MIPS3);
15438 gen_cp1(ctx, op1, rt, rd);
15444 check_insn(ctx, ASE_MIPS3D);
15447 gen_compute_branch1(ctx, MASK_BC1(ctx->opcode),
15448 (rt >> 2) & 0x7, imm << 2);
15456 gen_farith(ctx, ctx->opcode & FOP(0x3f, 0x1f), rt, rd, sa,
15461 generate_exception (ctx, EXCP_RI);
15465 generate_exception_err(ctx, EXCP_CpU, 1);
15474 /* COP2: Not implemented. */
15475 generate_exception_err(ctx, EXCP_CpU, 2);
15478 check_insn(ctx, INSN_LOONGSON2F);
15479 /* Note that these instructions use different fields. */
15480 gen_loongson_multimedia(ctx, sa, rd, rt);
15484 if (env->CP0_Config1 & (1 << CP0C1_FP)) {
15485 check_cp1_enabled(ctx);
15486 op1 = MASK_CP3(ctx->opcode);
15494 gen_flt3_ldst(ctx, op1, sa, rd, rs, rt);
15497 /* Treat as NOP. */
15512 gen_flt3_arith(ctx, op1, sa, rs, rd, rt);
15516 generate_exception (ctx, EXCP_RI);
15520 generate_exception_err(ctx, EXCP_CpU, 1);
15524 #if defined(TARGET_MIPS64)
15525 /* MIPS64 opcodes */
15527 case OPC_LDL ... OPC_LDR:
15530 check_insn(ctx, ISA_MIPS3);
15531 check_mips_64(ctx);
15532 gen_ld(ctx, op, rt, rs, imm);
15534 case OPC_SDL ... OPC_SDR:
15536 check_insn(ctx, ISA_MIPS3);
15537 check_mips_64(ctx);
15538 gen_st(ctx, op, rt, rs, imm);
15541 check_insn(ctx, ISA_MIPS3);
15542 check_mips_64(ctx);
15543 gen_st_cond(ctx, op, rt, rs, imm);
15547 check_insn(ctx, ISA_MIPS3);
15548 check_mips_64(ctx);
15549 gen_arith_imm(ctx, op, rt, rs, imm);
15553 check_insn(ctx, ASE_MIPS16 | ASE_MICROMIPS);
15554 offset = (int32_t)(ctx->opcode & 0x3FFFFFF) << 2;
15555 gen_compute_branch(ctx, op, 4, rs, rt, offset);
15559 check_insn(ctx, ASE_MDMX);
15560 /* MDMX: Not implemented. */
15561 default: /* Invalid */
15562 MIPS_INVAL("major opcode");
15563 generate_exception(ctx, EXCP_RI);
15569 gen_intermediate_code_internal (CPUMIPSState *env, TranslationBlock *tb,
15573 target_ulong pc_start;
15574 uint16_t *gen_opc_end;
15583 qemu_log("search pc %d\n", search_pc);
15586 gen_opc_end = tcg_ctx.gen_opc_buf + OPC_MAX_SIZE;
15589 ctx.singlestep_enabled = env->singlestep_enabled;
15590 ctx.insn_flags = env->insn_flags;
15592 ctx.bstate = BS_NONE;
15593 /* Restore delay slot state from the tb context. */
15594 ctx.hflags = (uint32_t)tb->flags; /* FIXME: maybe use 64 bits here? */
15595 restore_cpu_state(env, &ctx);
15596 #ifdef CONFIG_USER_ONLY
15597 ctx.mem_idx = MIPS_HFLAG_UM;
15599 ctx.mem_idx = ctx.hflags & MIPS_HFLAG_KSU;
15602 max_insns = tb->cflags & CF_COUNT_MASK;
15603 if (max_insns == 0)
15604 max_insns = CF_COUNT_MASK;
15605 LOG_DISAS("\ntb %p idx %d hflags %04x\n", tb, ctx.mem_idx, ctx.hflags);
15606 gen_icount_start();
15607 while (ctx.bstate == BS_NONE) {
15608 if (unlikely(!QTAILQ_EMPTY(&env->breakpoints))) {
15609 QTAILQ_FOREACH(bp, &env->breakpoints, entry) {
15610 if (bp->pc == ctx.pc) {
15611 save_cpu_state(&ctx, 1);
15612 ctx.bstate = BS_BRANCH;
15613 gen_helper_0e0i(raise_exception, EXCP_DEBUG);
15614 /* Include the breakpoint location or the tb won't
15615 * be flushed when it must be. */
15617 goto done_generating;
15623 j = tcg_ctx.gen_opc_ptr - tcg_ctx.gen_opc_buf;
15627 tcg_ctx.gen_opc_instr_start[lj++] = 0;
15629 tcg_ctx.gen_opc_pc[lj] = ctx.pc;
15630 gen_opc_hflags[lj] = ctx.hflags & MIPS_HFLAG_BMASK;
15631 gen_opc_btarget[lj] = ctx.btarget;
15632 tcg_ctx.gen_opc_instr_start[lj] = 1;
15633 tcg_ctx.gen_opc_icount[lj] = num_insns;
15635 if (num_insns + 1 == max_insns && (tb->cflags & CF_LAST_IO))
15639 if (!(ctx.hflags & MIPS_HFLAG_M16)) {
15640 ctx.opcode = cpu_ldl_code(env, ctx.pc);
15642 decode_opc(env, &ctx, &is_branch);
15643 } else if (ctx.insn_flags & ASE_MICROMIPS) {
15644 ctx.opcode = cpu_lduw_code(env, ctx.pc);
15645 insn_bytes = decode_micromips_opc(env, &ctx, &is_branch);
15646 } else if (ctx.insn_flags & ASE_MIPS16) {
15647 ctx.opcode = cpu_lduw_code(env, ctx.pc);
15648 insn_bytes = decode_mips16_opc(env, &ctx, &is_branch);
15650 generate_exception(&ctx, EXCP_RI);
15651 ctx.bstate = BS_STOP;
15655 handle_delay_slot(&ctx, insn_bytes);
15657 ctx.pc += insn_bytes;
15661 /* Execute a branch and its delay slot as a single instruction.
15662 This is what GDB expects and is consistent with what the
15663 hardware does (e.g. if a delay slot instruction faults, the
15664 reported PC is the PC of the branch). */
15665 if (env->singlestep_enabled && (ctx.hflags & MIPS_HFLAG_BMASK) == 0)
15668 if ((ctx.pc & (TARGET_PAGE_SIZE - 1)) == 0)
15671 if (tcg_ctx.gen_opc_ptr >= gen_opc_end) {
15675 if (num_insns >= max_insns)
15681 if (tb->cflags & CF_LAST_IO)
15683 if (env->singlestep_enabled && ctx.bstate != BS_BRANCH) {
15684 save_cpu_state(&ctx, ctx.bstate == BS_NONE);
15685 gen_helper_0e0i(raise_exception, EXCP_DEBUG);
15687 switch (ctx.bstate) {
15689 gen_goto_tb(&ctx, 0, ctx.pc);
15692 save_cpu_state(&ctx, 0);
15693 gen_goto_tb(&ctx, 0, ctx.pc);
15696 tcg_gen_exit_tb(0);
15704 gen_icount_end(tb, num_insns);
15705 *tcg_ctx.gen_opc_ptr = INDEX_op_end;
15707 j = tcg_ctx.gen_opc_ptr - tcg_ctx.gen_opc_buf;
15710 tcg_ctx.gen_opc_instr_start[lj++] = 0;
15712 tb->size = ctx.pc - pc_start;
15713 tb->icount = num_insns;
15717 if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM)) {
15718 qemu_log("IN: %s\n", lookup_symbol(pc_start));
15719 log_target_disas(env, pc_start, ctx.pc - pc_start, 0);
15725 void gen_intermediate_code (CPUMIPSState *env, struct TranslationBlock *tb)
15727 gen_intermediate_code_internal(env, tb, 0);
15730 void gen_intermediate_code_pc (CPUMIPSState *env, struct TranslationBlock *tb)
15732 gen_intermediate_code_internal(env, tb, 1);
15735 static void fpu_dump_state(CPUMIPSState *env, FILE *f, fprintf_function fpu_fprintf,
15739 int is_fpu64 = !!(env->hflags & MIPS_HFLAG_F64);
15741 #define printfpr(fp) \
15744 fpu_fprintf(f, "w:%08x d:%016" PRIx64 \
15745 " fd:%13g fs:%13g psu: %13g\n", \
15746 (fp)->w[FP_ENDIAN_IDX], (fp)->d, \
15747 (double)(fp)->fd, \
15748 (double)(fp)->fs[FP_ENDIAN_IDX], \
15749 (double)(fp)->fs[!FP_ENDIAN_IDX]); \
15752 tmp.w[FP_ENDIAN_IDX] = (fp)->w[FP_ENDIAN_IDX]; \
15753 tmp.w[!FP_ENDIAN_IDX] = ((fp) + 1)->w[FP_ENDIAN_IDX]; \
15754 fpu_fprintf(f, "w:%08x d:%016" PRIx64 \
15755 " fd:%13g fs:%13g psu:%13g\n", \
15756 tmp.w[FP_ENDIAN_IDX], tmp.d, \
15758 (double)tmp.fs[FP_ENDIAN_IDX], \
15759 (double)tmp.fs[!FP_ENDIAN_IDX]); \
15764 fpu_fprintf(f, "CP1 FCR0 0x%08x FCR31 0x%08x SR.FR %d fp_status 0x%02x\n",
15765 env->active_fpu.fcr0, env->active_fpu.fcr31, is_fpu64,
15766 get_float_exception_flags(&env->active_fpu.fp_status));
15767 for (i = 0; i < 32; (is_fpu64) ? i++ : (i += 2)) {
15768 fpu_fprintf(f, "%3s: ", fregnames[i]);
15769 printfpr(&env->active_fpu.fpr[i]);
15775 #if defined(TARGET_MIPS64) && defined(MIPS_DEBUG_SIGN_EXTENSIONS)
15776 /* Debug help: The architecture requires 32bit code to maintain proper
15777 sign-extended values on 64bit machines. */
15779 #define SIGN_EXT_P(val) ((((val) & ~0x7fffffff) == 0) || (((val) & ~0x7fffffff) == ~0x7fffffff))
15782 cpu_mips_check_sign_extensions (CPUMIPSState *env, FILE *f,
15783 fprintf_function cpu_fprintf,
15788 if (!SIGN_EXT_P(env->active_tc.PC))
15789 cpu_fprintf(f, "BROKEN: pc=0x" TARGET_FMT_lx "\n", env->active_tc.PC);
15790 if (!SIGN_EXT_P(env->active_tc.HI[0]))
15791 cpu_fprintf(f, "BROKEN: HI=0x" TARGET_FMT_lx "\n", env->active_tc.HI[0]);
15792 if (!SIGN_EXT_P(env->active_tc.LO[0]))
15793 cpu_fprintf(f, "BROKEN: LO=0x" TARGET_FMT_lx "\n", env->active_tc.LO[0]);
15794 if (!SIGN_EXT_P(env->btarget))
15795 cpu_fprintf(f, "BROKEN: btarget=0x" TARGET_FMT_lx "\n", env->btarget);
15797 for (i = 0; i < 32; i++) {
15798 if (!SIGN_EXT_P(env->active_tc.gpr[i]))
15799 cpu_fprintf(f, "BROKEN: %s=0x" TARGET_FMT_lx "\n", regnames[i], env->active_tc.gpr[i]);
15802 if (!SIGN_EXT_P(env->CP0_EPC))
15803 cpu_fprintf(f, "BROKEN: EPC=0x" TARGET_FMT_lx "\n", env->CP0_EPC);
15804 if (!SIGN_EXT_P(env->lladdr))
15805 cpu_fprintf(f, "BROKEN: LLAddr=0x" TARGET_FMT_lx "\n", env->lladdr);
15809 void cpu_dump_state (CPUMIPSState *env, FILE *f, fprintf_function cpu_fprintf,
15814 cpu_fprintf(f, "pc=0x" TARGET_FMT_lx " HI=0x" TARGET_FMT_lx
15815 " LO=0x" TARGET_FMT_lx " ds %04x "
15816 TARGET_FMT_lx " " TARGET_FMT_ld "\n",
15817 env->active_tc.PC, env->active_tc.HI[0], env->active_tc.LO[0],
15818 env->hflags, env->btarget, env->bcond);
15819 for (i = 0; i < 32; i++) {
15821 cpu_fprintf(f, "GPR%02d:", i);
15822 cpu_fprintf(f, " %s " TARGET_FMT_lx, regnames[i], env->active_tc.gpr[i]);
15824 cpu_fprintf(f, "\n");
15827 cpu_fprintf(f, "CP0 Status 0x%08x Cause 0x%08x EPC 0x" TARGET_FMT_lx "\n",
15828 env->CP0_Status, env->CP0_Cause, env->CP0_EPC);
15829 cpu_fprintf(f, " Config0 0x%08x Config1 0x%08x LLAddr 0x" TARGET_FMT_lx "\n",
15830 env->CP0_Config0, env->CP0_Config1, env->lladdr);
15831 if (env->hflags & MIPS_HFLAG_FPU)
15832 fpu_dump_state(env, f, cpu_fprintf, flags);
15833 #if defined(TARGET_MIPS64) && defined(MIPS_DEBUG_SIGN_EXTENSIONS)
15834 cpu_mips_check_sign_extensions(env, f, cpu_fprintf, flags);
15838 static void mips_tcg_init(void)
15843 /* Initialize various static tables. */
15847 cpu_env = tcg_global_reg_new_ptr(TCG_AREG0, "env");
15848 TCGV_UNUSED(cpu_gpr[0]);
15849 for (i = 1; i < 32; i++)
15850 cpu_gpr[i] = tcg_global_mem_new(TCG_AREG0,
15851 offsetof(CPUMIPSState, active_tc.gpr[i]),
15854 for (i = 0; i < 32; i++) {
15855 int off = offsetof(CPUMIPSState, active_fpu.fpr[i]);
15856 fpu_f64[i] = tcg_global_mem_new_i64(TCG_AREG0, off, fregnames[i]);
15859 cpu_PC = tcg_global_mem_new(TCG_AREG0,
15860 offsetof(CPUMIPSState, active_tc.PC), "PC");
15861 for (i = 0; i < MIPS_DSP_ACC; i++) {
15862 cpu_HI[i] = tcg_global_mem_new(TCG_AREG0,
15863 offsetof(CPUMIPSState, active_tc.HI[i]),
15865 cpu_LO[i] = tcg_global_mem_new(TCG_AREG0,
15866 offsetof(CPUMIPSState, active_tc.LO[i]),
15868 cpu_ACX[i] = tcg_global_mem_new(TCG_AREG0,
15869 offsetof(CPUMIPSState, active_tc.ACX[i]),
15872 cpu_dspctrl = tcg_global_mem_new(TCG_AREG0,
15873 offsetof(CPUMIPSState, active_tc.DSPControl),
15875 bcond = tcg_global_mem_new(TCG_AREG0,
15876 offsetof(CPUMIPSState, bcond), "bcond");
15877 btarget = tcg_global_mem_new(TCG_AREG0,
15878 offsetof(CPUMIPSState, btarget), "btarget");
15879 hflags = tcg_global_mem_new_i32(TCG_AREG0,
15880 offsetof(CPUMIPSState, hflags), "hflags");
15882 fpu_fcr0 = tcg_global_mem_new_i32(TCG_AREG0,
15883 offsetof(CPUMIPSState, active_fpu.fcr0),
15885 fpu_fcr31 = tcg_global_mem_new_i32(TCG_AREG0,
15886 offsetof(CPUMIPSState, active_fpu.fcr31),
15889 /* register helpers */
15890 #define GEN_HELPER 2
15891 #include "helper.h"
15896 #include "translate_init.c"
15898 MIPSCPU *cpu_mips_init(const char *cpu_model)
15902 const mips_def_t *def;
15904 def = cpu_mips_find_by_name(cpu_model);
15907 cpu = MIPS_CPU(object_new(TYPE_MIPS_CPU));
15909 env->cpu_model = def;
15910 env->cpu_model_str = cpu_model;
15912 #ifndef CONFIG_USER_ONLY
15913 mmu_init(env, def);
15915 fpu_init(env, def);
15916 mvp_init(env, def);
15918 cpu_reset(CPU(cpu));
15919 qemu_init_vcpu(env);
15923 void cpu_state_reset(CPUMIPSState *env)
15925 #ifndef CONFIG_USER_ONLY
15926 MIPSCPU *cpu = mips_env_get_cpu(env);
15927 CPUState *cs = CPU(cpu);
15930 /* Reset registers to their default values */
15931 env->CP0_PRid = env->cpu_model->CP0_PRid;
15932 env->CP0_Config0 = env->cpu_model->CP0_Config0;
15933 #ifdef TARGET_WORDS_BIGENDIAN
15934 env->CP0_Config0 |= (1 << CP0C0_BE);
15936 env->CP0_Config1 = env->cpu_model->CP0_Config1;
15937 env->CP0_Config2 = env->cpu_model->CP0_Config2;
15938 env->CP0_Config3 = env->cpu_model->CP0_Config3;
15939 env->CP0_Config6 = env->cpu_model->CP0_Config6;
15940 env->CP0_Config7 = env->cpu_model->CP0_Config7;
15941 env->CP0_LLAddr_rw_bitmask = env->cpu_model->CP0_LLAddr_rw_bitmask
15942 << env->cpu_model->CP0_LLAddr_shift;
15943 env->CP0_LLAddr_shift = env->cpu_model->CP0_LLAddr_shift;
15944 env->SYNCI_Step = env->cpu_model->SYNCI_Step;
15945 env->CCRes = env->cpu_model->CCRes;
15946 env->CP0_Status_rw_bitmask = env->cpu_model->CP0_Status_rw_bitmask;
15947 env->CP0_TCStatus_rw_bitmask = env->cpu_model->CP0_TCStatus_rw_bitmask;
15948 env->CP0_SRSCtl = env->cpu_model->CP0_SRSCtl;
15949 env->current_tc = 0;
15950 env->SEGBITS = env->cpu_model->SEGBITS;
15951 env->SEGMask = (target_ulong)((1ULL << env->cpu_model->SEGBITS) - 1);
15952 #if defined(TARGET_MIPS64)
15953 if (env->cpu_model->insn_flags & ISA_MIPS3) {
15954 env->SEGMask |= 3ULL << 62;
15957 env->PABITS = env->cpu_model->PABITS;
15958 env->PAMask = (target_ulong)((1ULL << env->cpu_model->PABITS) - 1);
15959 env->CP0_SRSConf0_rw_bitmask = env->cpu_model->CP0_SRSConf0_rw_bitmask;
15960 env->CP0_SRSConf0 = env->cpu_model->CP0_SRSConf0;
15961 env->CP0_SRSConf1_rw_bitmask = env->cpu_model->CP0_SRSConf1_rw_bitmask;
15962 env->CP0_SRSConf1 = env->cpu_model->CP0_SRSConf1;
15963 env->CP0_SRSConf2_rw_bitmask = env->cpu_model->CP0_SRSConf2_rw_bitmask;
15964 env->CP0_SRSConf2 = env->cpu_model->CP0_SRSConf2;
15965 env->CP0_SRSConf3_rw_bitmask = env->cpu_model->CP0_SRSConf3_rw_bitmask;
15966 env->CP0_SRSConf3 = env->cpu_model->CP0_SRSConf3;
15967 env->CP0_SRSConf4_rw_bitmask = env->cpu_model->CP0_SRSConf4_rw_bitmask;
15968 env->CP0_SRSConf4 = env->cpu_model->CP0_SRSConf4;
15969 env->active_fpu.fcr0 = env->cpu_model->CP1_fcr0;
15970 env->insn_flags = env->cpu_model->insn_flags;
15972 #if defined(CONFIG_USER_ONLY)
15973 env->CP0_Status = (MIPS_HFLAG_UM << CP0St_KSU);
15974 /* Enable access to the CPUNum, SYNCI_Step, CC, and CCRes RDHWR
15975 hardware registers. */
15976 env->CP0_HWREna |= 0x0000000F;
15977 if (env->CP0_Config1 & (1 << CP0C1_FP)) {
15978 env->CP0_Status |= (1 << CP0St_CU1);
15980 if (env->cpu_model->insn_flags & ASE_DSPR2) {
15981 env->hflags |= MIPS_HFLAG_DSP | MIPS_HFLAG_DSPR2;
15982 } else if (env->cpu_model->insn_flags & ASE_DSP) {
15983 env->hflags |= MIPS_HFLAG_DSP;
15986 if (env->hflags & MIPS_HFLAG_BMASK) {
15987 /* If the exception was raised from a delay slot,
15988 come back to the jump. */
15989 env->CP0_ErrorEPC = env->active_tc.PC - 4;
15991 env->CP0_ErrorEPC = env->active_tc.PC;
15993 env->active_tc.PC = (int32_t)0xBFC00000;
15994 env->CP0_Random = env->tlb->nb_tlb - 1;
15995 env->tlb->tlb_in_use = env->tlb->nb_tlb;
15996 env->CP0_Wired = 0;
15997 env->CP0_EBase = 0x80000000 | (cs->cpu_index & 0x3FF);
15998 env->CP0_Status = (1 << CP0St_BEV) | (1 << CP0St_ERL);
15999 /* vectored interrupts not implemented, timer on int 7,
16000 no performance counters. */
16001 env->CP0_IntCtl = 0xe0000000;
16005 for (i = 0; i < 7; i++) {
16006 env->CP0_WatchLo[i] = 0;
16007 env->CP0_WatchHi[i] = 0x80000000;
16009 env->CP0_WatchLo[7] = 0;
16010 env->CP0_WatchHi[7] = 0;
16012 /* Count register increments in debug mode, EJTAG version 1 */
16013 env->CP0_Debug = (1 << CP0DB_CNT) | (0x1 << CP0DB_VER);
16015 if (env->CP0_Config3 & (1 << CP0C3_MT)) {
16018 /* Only TC0 on VPE 0 starts as active. */
16019 for (i = 0; i < ARRAY_SIZE(env->tcs); i++) {
16020 env->tcs[i].CP0_TCBind = cs->cpu_index << CP0TCBd_CurVPE;
16021 env->tcs[i].CP0_TCHalt = 1;
16023 env->active_tc.CP0_TCHalt = 1;
16026 if (cs->cpu_index == 0) {
16027 /* VPE0 starts up enabled. */
16028 env->mvp->CP0_MVPControl |= (1 << CP0MVPCo_EVP);
16029 env->CP0_VPEConf0 |= (1 << CP0VPEC0_MVP) | (1 << CP0VPEC0_VPA);
16031 /* TC0 starts up unhalted. */
16033 env->active_tc.CP0_TCHalt = 0;
16034 env->tcs[0].CP0_TCHalt = 0;
16035 /* With thread 0 active. */
16036 env->active_tc.CP0_TCStatus = (1 << CP0TCSt_A);
16037 env->tcs[0].CP0_TCStatus = (1 << CP0TCSt_A);
16041 compute_hflags(env);
16042 env->exception_index = EXCP_NONE;
16045 void restore_state_to_opc(CPUMIPSState *env, TranslationBlock *tb, int pc_pos)
16047 env->active_tc.PC = tcg_ctx.gen_opc_pc[pc_pos];
16048 env->hflags &= ~MIPS_HFLAG_BMASK;
16049 env->hflags |= gen_opc_hflags[pc_pos];
16050 switch (env->hflags & MIPS_HFLAG_BMASK_BASE) {
16051 case MIPS_HFLAG_BR:
16053 case MIPS_HFLAG_BC:
16054 case MIPS_HFLAG_BL:
16056 env->btarget = gen_opc_btarget[pc_pos];