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 Compare-Pick 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 Compare-Pick 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 Compare-Pick 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 generate_exception(ctx, EXCP_DSPDIS);
1401 static inline void check_dspr2(DisasContext *ctx)
1403 if (unlikely(!(ctx->hflags & MIPS_HFLAG_DSPR2))) {
1404 generate_exception(ctx, EXCP_DSPDIS);
1408 /* This code generates a "reserved instruction" exception if the
1409 CPU does not support the instruction set corresponding to flags. */
1410 static inline void check_insn(DisasContext *ctx, int flags)
1412 if (unlikely(!(ctx->insn_flags & flags))) {
1413 generate_exception(ctx, EXCP_RI);
1417 /* This code generates a "reserved instruction" exception if 64-bit
1418 instructions are not enabled. */
1419 static inline void check_mips_64(DisasContext *ctx)
1421 if (unlikely(!(ctx->hflags & MIPS_HFLAG_64)))
1422 generate_exception(ctx, EXCP_RI);
1425 /* Define small wrappers for gen_load_fpr* so that we have a uniform
1426 calling interface for 32 and 64-bit FPRs. No sense in changing
1427 all callers for gen_load_fpr32 when we need the CTX parameter for
1429 #define gen_ldcmp_fpr32(ctx, x, y) gen_load_fpr32(x, y)
1430 #define gen_ldcmp_fpr64(ctx, x, y) gen_load_fpr64(ctx, x, y)
1431 #define FOP_CONDS(type, abs, fmt, ifmt, bits) \
1432 static inline void gen_cmp ## type ## _ ## fmt(DisasContext *ctx, int n, \
1433 int ft, int fs, int cc) \
1435 TCGv_i##bits fp0 = tcg_temp_new_i##bits (); \
1436 TCGv_i##bits fp1 = tcg_temp_new_i##bits (); \
1439 check_cp1_64bitmode(ctx); \
1445 check_cp1_registers(ctx, fs | ft); \
1453 gen_ldcmp_fpr##bits (ctx, fp0, fs); \
1454 gen_ldcmp_fpr##bits (ctx, fp1, ft); \
1456 case 0: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _f, fp0, fp1, cc); break;\
1457 case 1: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _un, fp0, fp1, cc); break;\
1458 case 2: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _eq, fp0, fp1, cc); break;\
1459 case 3: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ueq, fp0, fp1, cc); break;\
1460 case 4: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _olt, fp0, fp1, cc); break;\
1461 case 5: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ult, fp0, fp1, cc); break;\
1462 case 6: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ole, fp0, fp1, cc); break;\
1463 case 7: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ule, fp0, fp1, cc); break;\
1464 case 8: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _sf, fp0, fp1, cc); break;\
1465 case 9: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ngle, fp0, fp1, cc); break;\
1466 case 10: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _seq, fp0, fp1, cc); break;\
1467 case 11: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ngl, fp0, fp1, cc); break;\
1468 case 12: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _lt, fp0, fp1, cc); break;\
1469 case 13: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _nge, fp0, fp1, cc); break;\
1470 case 14: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _le, fp0, fp1, cc); break;\
1471 case 15: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ngt, fp0, fp1, cc); break;\
1474 tcg_temp_free_i##bits (fp0); \
1475 tcg_temp_free_i##bits (fp1); \
1478 FOP_CONDS(, 0, d, FMT_D, 64)
1479 FOP_CONDS(abs, 1, d, FMT_D, 64)
1480 FOP_CONDS(, 0, s, FMT_S, 32)
1481 FOP_CONDS(abs, 1, s, FMT_S, 32)
1482 FOP_CONDS(, 0, ps, FMT_PS, 64)
1483 FOP_CONDS(abs, 1, ps, FMT_PS, 64)
1485 #undef gen_ldcmp_fpr32
1486 #undef gen_ldcmp_fpr64
1488 /* load/store instructions. */
1489 #ifdef CONFIG_USER_ONLY
1490 #define OP_LD_ATOMIC(insn,fname) \
1491 static inline void op_ld_##insn(TCGv ret, TCGv arg1, DisasContext *ctx) \
1493 TCGv t0 = tcg_temp_new(); \
1494 tcg_gen_mov_tl(t0, arg1); \
1495 tcg_gen_qemu_##fname(ret, arg1, ctx->mem_idx); \
1496 tcg_gen_st_tl(t0, cpu_env, offsetof(CPUMIPSState, lladdr)); \
1497 tcg_gen_st_tl(ret, cpu_env, offsetof(CPUMIPSState, llval)); \
1498 tcg_temp_free(t0); \
1501 #define OP_LD_ATOMIC(insn,fname) \
1502 static inline void op_ld_##insn(TCGv ret, TCGv arg1, DisasContext *ctx) \
1504 gen_helper_1e1i(insn, ret, arg1, ctx->mem_idx); \
1507 OP_LD_ATOMIC(ll,ld32s);
1508 #if defined(TARGET_MIPS64)
1509 OP_LD_ATOMIC(lld,ld64);
1513 #ifdef CONFIG_USER_ONLY
1514 #define OP_ST_ATOMIC(insn,fname,ldname,almask) \
1515 static inline void op_st_##insn(TCGv arg1, TCGv arg2, int rt, DisasContext *ctx) \
1517 TCGv t0 = tcg_temp_new(); \
1518 int l1 = gen_new_label(); \
1519 int l2 = gen_new_label(); \
1521 tcg_gen_andi_tl(t0, arg2, almask); \
1522 tcg_gen_brcondi_tl(TCG_COND_EQ, t0, 0, l1); \
1523 tcg_gen_st_tl(arg2, cpu_env, offsetof(CPUMIPSState, CP0_BadVAddr)); \
1524 generate_exception(ctx, EXCP_AdES); \
1525 gen_set_label(l1); \
1526 tcg_gen_ld_tl(t0, cpu_env, offsetof(CPUMIPSState, lladdr)); \
1527 tcg_gen_brcond_tl(TCG_COND_NE, arg2, t0, l2); \
1528 tcg_gen_movi_tl(t0, rt | ((almask << 3) & 0x20)); \
1529 tcg_gen_st_tl(t0, cpu_env, offsetof(CPUMIPSState, llreg)); \
1530 tcg_gen_st_tl(arg1, cpu_env, offsetof(CPUMIPSState, llnewval)); \
1531 gen_helper_0e0i(raise_exception, EXCP_SC); \
1532 gen_set_label(l2); \
1533 tcg_gen_movi_tl(t0, 0); \
1534 gen_store_gpr(t0, rt); \
1535 tcg_temp_free(t0); \
1538 #define OP_ST_ATOMIC(insn,fname,ldname,almask) \
1539 static inline void op_st_##insn(TCGv arg1, TCGv arg2, int rt, DisasContext *ctx) \
1541 TCGv t0 = tcg_temp_new(); \
1542 gen_helper_1e2i(insn, t0, arg1, arg2, ctx->mem_idx); \
1543 gen_store_gpr(t0, rt); \
1544 tcg_temp_free(t0); \
1547 OP_ST_ATOMIC(sc,st32,ld32s,0x3);
1548 #if defined(TARGET_MIPS64)
1549 OP_ST_ATOMIC(scd,st64,ld64,0x7);
1553 static void gen_base_offset_addr (DisasContext *ctx, TCGv addr,
1554 int base, int16_t offset)
1557 tcg_gen_movi_tl(addr, offset);
1558 } else if (offset == 0) {
1559 gen_load_gpr(addr, base);
1561 tcg_gen_movi_tl(addr, offset);
1562 gen_op_addr_add(ctx, addr, cpu_gpr[base], addr);
1566 static target_ulong pc_relative_pc (DisasContext *ctx)
1568 target_ulong pc = ctx->pc;
1570 if (ctx->hflags & MIPS_HFLAG_BMASK) {
1571 int branch_bytes = ctx->hflags & MIPS_HFLAG_BDS16 ? 2 : 4;
1576 pc &= ~(target_ulong)3;
1581 static void gen_ld(DisasContext *ctx, uint32_t opc,
1582 int rt, int base, int16_t offset)
1584 const char *opn = "ld";
1587 if (rt == 0 && ctx->insn_flags & (INSN_LOONGSON2E | INSN_LOONGSON2F)) {
1588 /* Loongson CPU uses a load to zero register for prefetch.
1589 We emulate it as a NOP. On other CPU we must perform the
1590 actual memory access. */
1595 t0 = tcg_temp_new();
1596 gen_base_offset_addr(ctx, t0, base, offset);
1599 #if defined(TARGET_MIPS64)
1601 tcg_gen_qemu_ld32u(t0, t0, ctx->mem_idx);
1602 gen_store_gpr(t0, rt);
1606 tcg_gen_qemu_ld64(t0, t0, ctx->mem_idx);
1607 gen_store_gpr(t0, rt);
1611 save_cpu_state(ctx, 1);
1612 op_ld_lld(t0, t0, ctx);
1613 gen_store_gpr(t0, rt);
1617 t1 = tcg_temp_new();
1618 tcg_gen_andi_tl(t1, t0, 7);
1619 #ifndef TARGET_WORDS_BIGENDIAN
1620 tcg_gen_xori_tl(t1, t1, 7);
1622 tcg_gen_shli_tl(t1, t1, 3);
1623 tcg_gen_andi_tl(t0, t0, ~7);
1624 tcg_gen_qemu_ld64(t0, t0, ctx->mem_idx);
1625 tcg_gen_shl_tl(t0, t0, t1);
1626 tcg_gen_xori_tl(t1, t1, 63);
1627 t2 = tcg_const_tl(0x7fffffffffffffffull);
1628 tcg_gen_shr_tl(t2, t2, t1);
1629 gen_load_gpr(t1, rt);
1630 tcg_gen_and_tl(t1, t1, t2);
1632 tcg_gen_or_tl(t0, t0, t1);
1634 gen_store_gpr(t0, rt);
1638 t1 = tcg_temp_new();
1639 tcg_gen_andi_tl(t1, t0, 7);
1640 #ifdef TARGET_WORDS_BIGENDIAN
1641 tcg_gen_xori_tl(t1, t1, 7);
1643 tcg_gen_shli_tl(t1, t1, 3);
1644 tcg_gen_andi_tl(t0, t0, ~7);
1645 tcg_gen_qemu_ld64(t0, t0, ctx->mem_idx);
1646 tcg_gen_shr_tl(t0, t0, t1);
1647 tcg_gen_xori_tl(t1, t1, 63);
1648 t2 = tcg_const_tl(0xfffffffffffffffeull);
1649 tcg_gen_shl_tl(t2, t2, t1);
1650 gen_load_gpr(t1, rt);
1651 tcg_gen_and_tl(t1, t1, t2);
1653 tcg_gen_or_tl(t0, t0, t1);
1655 gen_store_gpr(t0, rt);
1659 t1 = tcg_const_tl(pc_relative_pc(ctx));
1660 gen_op_addr_add(ctx, t0, t0, t1);
1662 tcg_gen_qemu_ld64(t0, t0, ctx->mem_idx);
1663 gen_store_gpr(t0, rt);
1668 t1 = tcg_const_tl(pc_relative_pc(ctx));
1669 gen_op_addr_add(ctx, t0, t0, t1);
1671 tcg_gen_qemu_ld32s(t0, t0, ctx->mem_idx);
1672 gen_store_gpr(t0, rt);
1676 tcg_gen_qemu_ld32s(t0, t0, ctx->mem_idx);
1677 gen_store_gpr(t0, rt);
1681 tcg_gen_qemu_ld16s(t0, t0, ctx->mem_idx);
1682 gen_store_gpr(t0, rt);
1686 tcg_gen_qemu_ld16u(t0, t0, ctx->mem_idx);
1687 gen_store_gpr(t0, rt);
1691 tcg_gen_qemu_ld8s(t0, t0, ctx->mem_idx);
1692 gen_store_gpr(t0, rt);
1696 tcg_gen_qemu_ld8u(t0, t0, ctx->mem_idx);
1697 gen_store_gpr(t0, rt);
1701 t1 = tcg_temp_new();
1702 tcg_gen_andi_tl(t1, t0, 3);
1703 #ifndef TARGET_WORDS_BIGENDIAN
1704 tcg_gen_xori_tl(t1, t1, 3);
1706 tcg_gen_shli_tl(t1, t1, 3);
1707 tcg_gen_andi_tl(t0, t0, ~3);
1708 tcg_gen_qemu_ld32u(t0, t0, ctx->mem_idx);
1709 tcg_gen_shl_tl(t0, t0, t1);
1710 tcg_gen_xori_tl(t1, t1, 31);
1711 t2 = tcg_const_tl(0x7fffffffull);
1712 tcg_gen_shr_tl(t2, t2, t1);
1713 gen_load_gpr(t1, rt);
1714 tcg_gen_and_tl(t1, t1, t2);
1716 tcg_gen_or_tl(t0, t0, t1);
1718 tcg_gen_ext32s_tl(t0, t0);
1719 gen_store_gpr(t0, rt);
1723 t1 = tcg_temp_new();
1724 tcg_gen_andi_tl(t1, t0, 3);
1725 #ifdef TARGET_WORDS_BIGENDIAN
1726 tcg_gen_xori_tl(t1, t1, 3);
1728 tcg_gen_shli_tl(t1, t1, 3);
1729 tcg_gen_andi_tl(t0, t0, ~3);
1730 tcg_gen_qemu_ld32u(t0, t0, ctx->mem_idx);
1731 tcg_gen_shr_tl(t0, t0, t1);
1732 tcg_gen_xori_tl(t1, t1, 31);
1733 t2 = tcg_const_tl(0xfffffffeull);
1734 tcg_gen_shl_tl(t2, t2, t1);
1735 gen_load_gpr(t1, rt);
1736 tcg_gen_and_tl(t1, t1, t2);
1738 tcg_gen_or_tl(t0, t0, t1);
1740 gen_store_gpr(t0, rt);
1744 save_cpu_state(ctx, 1);
1745 op_ld_ll(t0, t0, ctx);
1746 gen_store_gpr(t0, rt);
1750 (void)opn; /* avoid a compiler warning */
1751 MIPS_DEBUG("%s %s, %d(%s)", opn, regnames[rt], offset, regnames[base]);
1756 static void gen_st (DisasContext *ctx, uint32_t opc, int rt,
1757 int base, int16_t offset)
1759 const char *opn = "st";
1760 TCGv t0 = tcg_temp_new();
1761 TCGv t1 = tcg_temp_new();
1763 gen_base_offset_addr(ctx, t0, base, offset);
1764 gen_load_gpr(t1, rt);
1766 #if defined(TARGET_MIPS64)
1768 tcg_gen_qemu_st64(t1, t0, ctx->mem_idx);
1772 save_cpu_state(ctx, 1);
1773 gen_helper_0e2i(sdl, t1, t0, ctx->mem_idx);
1777 save_cpu_state(ctx, 1);
1778 gen_helper_0e2i(sdr, t1, t0, ctx->mem_idx);
1783 tcg_gen_qemu_st32(t1, t0, ctx->mem_idx);
1787 tcg_gen_qemu_st16(t1, t0, ctx->mem_idx);
1791 tcg_gen_qemu_st8(t1, t0, ctx->mem_idx);
1795 save_cpu_state(ctx, 1);
1796 gen_helper_0e2i(swl, t1, t0, ctx->mem_idx);
1800 save_cpu_state(ctx, 1);
1801 gen_helper_0e2i(swr, t1, t0, ctx->mem_idx);
1805 (void)opn; /* avoid a compiler warning */
1806 MIPS_DEBUG("%s %s, %d(%s)", opn, regnames[rt], offset, regnames[base]);
1812 /* Store conditional */
1813 static void gen_st_cond (DisasContext *ctx, uint32_t opc, int rt,
1814 int base, int16_t offset)
1816 const char *opn = "st_cond";
1819 #ifdef CONFIG_USER_ONLY
1820 t0 = tcg_temp_local_new();
1821 t1 = tcg_temp_local_new();
1823 t0 = tcg_temp_new();
1824 t1 = tcg_temp_new();
1826 gen_base_offset_addr(ctx, t0, base, offset);
1827 gen_load_gpr(t1, rt);
1829 #if defined(TARGET_MIPS64)
1831 save_cpu_state(ctx, 1);
1832 op_st_scd(t1, t0, rt, ctx);
1837 save_cpu_state(ctx, 1);
1838 op_st_sc(t1, t0, rt, ctx);
1842 (void)opn; /* avoid a compiler warning */
1843 MIPS_DEBUG("%s %s, %d(%s)", opn, regnames[rt], offset, regnames[base]);
1848 /* Load and store */
1849 static void gen_flt_ldst (DisasContext *ctx, uint32_t opc, int ft,
1850 int base, int16_t offset)
1852 const char *opn = "flt_ldst";
1853 TCGv t0 = tcg_temp_new();
1855 gen_base_offset_addr(ctx, t0, base, offset);
1856 /* Don't do NOP if destination is zero: we must perform the actual
1861 TCGv_i32 fp0 = tcg_temp_new_i32();
1863 tcg_gen_qemu_ld32s(t0, t0, ctx->mem_idx);
1864 tcg_gen_trunc_tl_i32(fp0, t0);
1865 gen_store_fpr32(fp0, ft);
1866 tcg_temp_free_i32(fp0);
1872 TCGv_i32 fp0 = tcg_temp_new_i32();
1873 TCGv t1 = tcg_temp_new();
1875 gen_load_fpr32(fp0, ft);
1876 tcg_gen_extu_i32_tl(t1, fp0);
1877 tcg_gen_qemu_st32(t1, t0, ctx->mem_idx);
1879 tcg_temp_free_i32(fp0);
1885 TCGv_i64 fp0 = tcg_temp_new_i64();
1887 tcg_gen_qemu_ld64(fp0, t0, ctx->mem_idx);
1888 gen_store_fpr64(ctx, fp0, ft);
1889 tcg_temp_free_i64(fp0);
1895 TCGv_i64 fp0 = tcg_temp_new_i64();
1897 gen_load_fpr64(ctx, fp0, ft);
1898 tcg_gen_qemu_st64(fp0, t0, ctx->mem_idx);
1899 tcg_temp_free_i64(fp0);
1905 generate_exception(ctx, EXCP_RI);
1908 (void)opn; /* avoid a compiler warning */
1909 MIPS_DEBUG("%s %s, %d(%s)", opn, fregnames[ft], offset, regnames[base]);
1914 static void gen_cop1_ldst(CPUMIPSState *env, DisasContext *ctx,
1915 uint32_t op, int rt, int rs, int16_t imm)
1917 if (env->CP0_Config1 & (1 << CP0C1_FP)) {
1918 check_cp1_enabled(ctx);
1919 gen_flt_ldst(ctx, op, rt, rs, imm);
1921 generate_exception_err(ctx, EXCP_CpU, 1);
1925 /* Arithmetic with immediate operand */
1926 static void gen_arith_imm(DisasContext *ctx, uint32_t opc,
1927 int rt, int rs, int16_t imm)
1929 target_ulong uimm = (target_long)imm; /* Sign extend to 32/64 bits */
1930 const char *opn = "imm arith";
1932 if (rt == 0 && opc != OPC_ADDI && opc != OPC_DADDI) {
1933 /* If no destination, treat it as a NOP.
1934 For addi, we must generate the overflow exception when needed. */
1941 TCGv t0 = tcg_temp_local_new();
1942 TCGv t1 = tcg_temp_new();
1943 TCGv t2 = tcg_temp_new();
1944 int l1 = gen_new_label();
1946 gen_load_gpr(t1, rs);
1947 tcg_gen_addi_tl(t0, t1, uimm);
1948 tcg_gen_ext32s_tl(t0, t0);
1950 tcg_gen_xori_tl(t1, t1, ~uimm);
1951 tcg_gen_xori_tl(t2, t0, uimm);
1952 tcg_gen_and_tl(t1, t1, t2);
1954 tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
1956 /* operands of same sign, result different sign */
1957 generate_exception(ctx, EXCP_OVERFLOW);
1959 tcg_gen_ext32s_tl(t0, t0);
1960 gen_store_gpr(t0, rt);
1967 tcg_gen_addi_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
1968 tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]);
1970 tcg_gen_movi_tl(cpu_gpr[rt], uimm);
1974 #if defined(TARGET_MIPS64)
1977 TCGv t0 = tcg_temp_local_new();
1978 TCGv t1 = tcg_temp_new();
1979 TCGv t2 = tcg_temp_new();
1980 int l1 = gen_new_label();
1982 gen_load_gpr(t1, rs);
1983 tcg_gen_addi_tl(t0, t1, uimm);
1985 tcg_gen_xori_tl(t1, t1, ~uimm);
1986 tcg_gen_xori_tl(t2, t0, uimm);
1987 tcg_gen_and_tl(t1, t1, t2);
1989 tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
1991 /* operands of same sign, result different sign */
1992 generate_exception(ctx, EXCP_OVERFLOW);
1994 gen_store_gpr(t0, rt);
2001 tcg_gen_addi_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
2003 tcg_gen_movi_tl(cpu_gpr[rt], uimm);
2009 (void)opn; /* avoid a compiler warning */
2010 MIPS_DEBUG("%s %s, %s, " TARGET_FMT_lx, opn, regnames[rt], regnames[rs], uimm);
2013 /* Logic with immediate operand */
2014 static void gen_logic_imm(DisasContext *ctx, uint32_t opc,
2015 int rt, int rs, int16_t imm)
2020 /* If no destination, treat it as a NOP. */
2024 uimm = (uint16_t)imm;
2027 if (likely(rs != 0))
2028 tcg_gen_andi_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
2030 tcg_gen_movi_tl(cpu_gpr[rt], 0);
2031 MIPS_DEBUG("andi %s, %s, " TARGET_FMT_lx, regnames[rt],
2032 regnames[rs], uimm);
2036 tcg_gen_ori_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
2038 tcg_gen_movi_tl(cpu_gpr[rt], uimm);
2039 MIPS_DEBUG("ori %s, %s, " TARGET_FMT_lx, regnames[rt],
2040 regnames[rs], uimm);
2043 if (likely(rs != 0))
2044 tcg_gen_xori_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
2046 tcg_gen_movi_tl(cpu_gpr[rt], uimm);
2047 MIPS_DEBUG("xori %s, %s, " TARGET_FMT_lx, regnames[rt],
2048 regnames[rs], uimm);
2051 tcg_gen_movi_tl(cpu_gpr[rt], imm << 16);
2052 MIPS_DEBUG("lui %s, " TARGET_FMT_lx, regnames[rt], uimm);
2056 MIPS_DEBUG("Unknown logical immediate opcode %08x", opc);
2061 /* Set on less than with immediate operand */
2062 static void gen_slt_imm(DisasContext *ctx, uint32_t opc,
2063 int rt, int rs, int16_t imm)
2065 target_ulong uimm = (target_long)imm; /* Sign extend to 32/64 bits */
2066 const char *opn = "imm arith";
2070 /* If no destination, treat it as a NOP. */
2074 t0 = tcg_temp_new();
2075 gen_load_gpr(t0, rs);
2078 tcg_gen_setcondi_tl(TCG_COND_LT, cpu_gpr[rt], t0, uimm);
2082 tcg_gen_setcondi_tl(TCG_COND_LTU, cpu_gpr[rt], t0, uimm);
2086 (void)opn; /* avoid a compiler warning */
2087 MIPS_DEBUG("%s %s, %s, " TARGET_FMT_lx, opn, regnames[rt], regnames[rs], uimm);
2091 /* Shifts with immediate operand */
2092 static void gen_shift_imm(DisasContext *ctx, uint32_t opc,
2093 int rt, int rs, int16_t imm)
2095 target_ulong uimm = ((uint16_t)imm) & 0x1f;
2096 const char *opn = "imm shift";
2100 /* If no destination, treat it as a NOP. */
2105 t0 = tcg_temp_new();
2106 gen_load_gpr(t0, rs);
2109 tcg_gen_shli_tl(t0, t0, uimm);
2110 tcg_gen_ext32s_tl(cpu_gpr[rt], t0);
2114 tcg_gen_sari_tl(cpu_gpr[rt], t0, uimm);
2119 tcg_gen_ext32u_tl(t0, t0);
2120 tcg_gen_shri_tl(cpu_gpr[rt], t0, uimm);
2122 tcg_gen_ext32s_tl(cpu_gpr[rt], t0);
2128 TCGv_i32 t1 = tcg_temp_new_i32();
2130 tcg_gen_trunc_tl_i32(t1, t0);
2131 tcg_gen_rotri_i32(t1, t1, uimm);
2132 tcg_gen_ext_i32_tl(cpu_gpr[rt], t1);
2133 tcg_temp_free_i32(t1);
2135 tcg_gen_ext32s_tl(cpu_gpr[rt], t0);
2139 #if defined(TARGET_MIPS64)
2141 tcg_gen_shli_tl(cpu_gpr[rt], t0, uimm);
2145 tcg_gen_sari_tl(cpu_gpr[rt], t0, uimm);
2149 tcg_gen_shri_tl(cpu_gpr[rt], t0, uimm);
2154 tcg_gen_rotri_tl(cpu_gpr[rt], t0, uimm);
2156 tcg_gen_mov_tl(cpu_gpr[rt], t0);
2161 tcg_gen_shli_tl(cpu_gpr[rt], t0, uimm + 32);
2165 tcg_gen_sari_tl(cpu_gpr[rt], t0, uimm + 32);
2169 tcg_gen_shri_tl(cpu_gpr[rt], t0, uimm + 32);
2173 tcg_gen_rotri_tl(cpu_gpr[rt], t0, uimm + 32);
2178 (void)opn; /* avoid a compiler warning */
2179 MIPS_DEBUG("%s %s, %s, " TARGET_FMT_lx, opn, regnames[rt], regnames[rs], uimm);
2184 static void gen_arith(DisasContext *ctx, uint32_t opc,
2185 int rd, int rs, int rt)
2187 const char *opn = "arith";
2189 if (rd == 0 && opc != OPC_ADD && opc != OPC_SUB
2190 && opc != OPC_DADD && opc != OPC_DSUB) {
2191 /* If no destination, treat it as a NOP.
2192 For add & sub, we must generate the overflow exception when needed. */
2200 TCGv t0 = tcg_temp_local_new();
2201 TCGv t1 = tcg_temp_new();
2202 TCGv t2 = tcg_temp_new();
2203 int l1 = gen_new_label();
2205 gen_load_gpr(t1, rs);
2206 gen_load_gpr(t2, rt);
2207 tcg_gen_add_tl(t0, t1, t2);
2208 tcg_gen_ext32s_tl(t0, t0);
2209 tcg_gen_xor_tl(t1, t1, t2);
2210 tcg_gen_xor_tl(t2, t0, t2);
2211 tcg_gen_andc_tl(t1, t2, t1);
2213 tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
2215 /* operands of same sign, result different sign */
2216 generate_exception(ctx, EXCP_OVERFLOW);
2218 gen_store_gpr(t0, rd);
2224 if (rs != 0 && rt != 0) {
2225 tcg_gen_add_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2226 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
2227 } else if (rs == 0 && rt != 0) {
2228 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rt]);
2229 } else if (rs != 0 && rt == 0) {
2230 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
2232 tcg_gen_movi_tl(cpu_gpr[rd], 0);
2238 TCGv t0 = tcg_temp_local_new();
2239 TCGv t1 = tcg_temp_new();
2240 TCGv t2 = tcg_temp_new();
2241 int l1 = gen_new_label();
2243 gen_load_gpr(t1, rs);
2244 gen_load_gpr(t2, rt);
2245 tcg_gen_sub_tl(t0, t1, t2);
2246 tcg_gen_ext32s_tl(t0, t0);
2247 tcg_gen_xor_tl(t2, t1, t2);
2248 tcg_gen_xor_tl(t1, t0, t1);
2249 tcg_gen_and_tl(t1, t1, t2);
2251 tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
2253 /* operands of different sign, first operand and result different sign */
2254 generate_exception(ctx, EXCP_OVERFLOW);
2256 gen_store_gpr(t0, rd);
2262 if (rs != 0 && rt != 0) {
2263 tcg_gen_sub_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2264 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
2265 } else if (rs == 0 && rt != 0) {
2266 tcg_gen_neg_tl(cpu_gpr[rd], cpu_gpr[rt]);
2267 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
2268 } else if (rs != 0 && rt == 0) {
2269 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
2271 tcg_gen_movi_tl(cpu_gpr[rd], 0);
2275 #if defined(TARGET_MIPS64)
2278 TCGv t0 = tcg_temp_local_new();
2279 TCGv t1 = tcg_temp_new();
2280 TCGv t2 = tcg_temp_new();
2281 int l1 = gen_new_label();
2283 gen_load_gpr(t1, rs);
2284 gen_load_gpr(t2, rt);
2285 tcg_gen_add_tl(t0, t1, t2);
2286 tcg_gen_xor_tl(t1, t1, t2);
2287 tcg_gen_xor_tl(t2, t0, t2);
2288 tcg_gen_andc_tl(t1, t2, t1);
2290 tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
2292 /* operands of same sign, result different sign */
2293 generate_exception(ctx, EXCP_OVERFLOW);
2295 gen_store_gpr(t0, rd);
2301 if (rs != 0 && rt != 0) {
2302 tcg_gen_add_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2303 } else if (rs == 0 && rt != 0) {
2304 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rt]);
2305 } else if (rs != 0 && rt == 0) {
2306 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
2308 tcg_gen_movi_tl(cpu_gpr[rd], 0);
2314 TCGv t0 = tcg_temp_local_new();
2315 TCGv t1 = tcg_temp_new();
2316 TCGv t2 = tcg_temp_new();
2317 int l1 = gen_new_label();
2319 gen_load_gpr(t1, rs);
2320 gen_load_gpr(t2, rt);
2321 tcg_gen_sub_tl(t0, t1, t2);
2322 tcg_gen_xor_tl(t2, t1, t2);
2323 tcg_gen_xor_tl(t1, t0, t1);
2324 tcg_gen_and_tl(t1, t1, t2);
2326 tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
2328 /* operands of different sign, first operand and result different sign */
2329 generate_exception(ctx, EXCP_OVERFLOW);
2331 gen_store_gpr(t0, rd);
2337 if (rs != 0 && rt != 0) {
2338 tcg_gen_sub_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2339 } else if (rs == 0 && rt != 0) {
2340 tcg_gen_neg_tl(cpu_gpr[rd], cpu_gpr[rt]);
2341 } else if (rs != 0 && rt == 0) {
2342 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
2344 tcg_gen_movi_tl(cpu_gpr[rd], 0);
2350 if (likely(rs != 0 && rt != 0)) {
2351 tcg_gen_mul_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2352 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
2354 tcg_gen_movi_tl(cpu_gpr[rd], 0);
2359 (void)opn; /* avoid a compiler warning */
2360 MIPS_DEBUG("%s %s, %s, %s", opn, regnames[rd], regnames[rs], regnames[rt]);
2363 /* Conditional move */
2364 static void gen_cond_move(DisasContext *ctx, uint32_t opc,
2365 int rd, int rs, int rt)
2367 const char *opn = "cond move";
2371 /* If no destination, treat it as a NOP. */
2376 t0 = tcg_temp_new();
2377 gen_load_gpr(t0, rt);
2378 t1 = tcg_const_tl(0);
2379 t2 = tcg_temp_new();
2380 gen_load_gpr(t2, rs);
2383 tcg_gen_movcond_tl(TCG_COND_NE, cpu_gpr[rd], t0, t1, t2, cpu_gpr[rd]);
2387 tcg_gen_movcond_tl(TCG_COND_EQ, cpu_gpr[rd], t0, t1, t2, cpu_gpr[rd]);
2395 (void)opn; /* avoid a compiler warning */
2396 MIPS_DEBUG("%s %s, %s, %s", opn, regnames[rd], regnames[rs], regnames[rt]);
2400 static void gen_logic(DisasContext *ctx, uint32_t opc,
2401 int rd, int rs, int rt)
2403 const char *opn = "logic";
2406 /* If no destination, treat it as a NOP. */
2413 if (likely(rs != 0 && rt != 0)) {
2414 tcg_gen_and_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2416 tcg_gen_movi_tl(cpu_gpr[rd], 0);
2421 if (rs != 0 && rt != 0) {
2422 tcg_gen_nor_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2423 } else if (rs == 0 && rt != 0) {
2424 tcg_gen_not_tl(cpu_gpr[rd], cpu_gpr[rt]);
2425 } else if (rs != 0 && rt == 0) {
2426 tcg_gen_not_tl(cpu_gpr[rd], cpu_gpr[rs]);
2428 tcg_gen_movi_tl(cpu_gpr[rd], ~((target_ulong)0));
2433 if (likely(rs != 0 && rt != 0)) {
2434 tcg_gen_or_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2435 } else if (rs == 0 && rt != 0) {
2436 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rt]);
2437 } else if (rs != 0 && rt == 0) {
2438 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
2440 tcg_gen_movi_tl(cpu_gpr[rd], 0);
2445 if (likely(rs != 0 && rt != 0)) {
2446 tcg_gen_xor_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2447 } else if (rs == 0 && rt != 0) {
2448 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rt]);
2449 } else if (rs != 0 && rt == 0) {
2450 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
2452 tcg_gen_movi_tl(cpu_gpr[rd], 0);
2457 (void)opn; /* avoid a compiler warning */
2458 MIPS_DEBUG("%s %s, %s, %s", opn, regnames[rd], regnames[rs], regnames[rt]);
2461 /* Set on lower than */
2462 static void gen_slt(DisasContext *ctx, uint32_t opc,
2463 int rd, int rs, int rt)
2465 const char *opn = "slt";
2469 /* If no destination, treat it as a NOP. */
2474 t0 = tcg_temp_new();
2475 t1 = tcg_temp_new();
2476 gen_load_gpr(t0, rs);
2477 gen_load_gpr(t1, rt);
2480 tcg_gen_setcond_tl(TCG_COND_LT, cpu_gpr[rd], t0, t1);
2484 tcg_gen_setcond_tl(TCG_COND_LTU, cpu_gpr[rd], t0, t1);
2488 (void)opn; /* avoid a compiler warning */
2489 MIPS_DEBUG("%s %s, %s, %s", opn, regnames[rd], regnames[rs], regnames[rt]);
2495 static void gen_shift(DisasContext *ctx, uint32_t opc,
2496 int rd, int rs, int rt)
2498 const char *opn = "shifts";
2502 /* If no destination, treat it as a NOP.
2503 For add & sub, we must generate the overflow exception when needed. */
2508 t0 = tcg_temp_new();
2509 t1 = tcg_temp_new();
2510 gen_load_gpr(t0, rs);
2511 gen_load_gpr(t1, rt);
2514 tcg_gen_andi_tl(t0, t0, 0x1f);
2515 tcg_gen_shl_tl(t0, t1, t0);
2516 tcg_gen_ext32s_tl(cpu_gpr[rd], t0);
2520 tcg_gen_andi_tl(t0, t0, 0x1f);
2521 tcg_gen_sar_tl(cpu_gpr[rd], t1, t0);
2525 tcg_gen_ext32u_tl(t1, t1);
2526 tcg_gen_andi_tl(t0, t0, 0x1f);
2527 tcg_gen_shr_tl(t0, t1, t0);
2528 tcg_gen_ext32s_tl(cpu_gpr[rd], t0);
2533 TCGv_i32 t2 = tcg_temp_new_i32();
2534 TCGv_i32 t3 = tcg_temp_new_i32();
2536 tcg_gen_trunc_tl_i32(t2, t0);
2537 tcg_gen_trunc_tl_i32(t3, t1);
2538 tcg_gen_andi_i32(t2, t2, 0x1f);
2539 tcg_gen_rotr_i32(t2, t3, t2);
2540 tcg_gen_ext_i32_tl(cpu_gpr[rd], t2);
2541 tcg_temp_free_i32(t2);
2542 tcg_temp_free_i32(t3);
2546 #if defined(TARGET_MIPS64)
2548 tcg_gen_andi_tl(t0, t0, 0x3f);
2549 tcg_gen_shl_tl(cpu_gpr[rd], t1, t0);
2553 tcg_gen_andi_tl(t0, t0, 0x3f);
2554 tcg_gen_sar_tl(cpu_gpr[rd], t1, t0);
2558 tcg_gen_andi_tl(t0, t0, 0x3f);
2559 tcg_gen_shr_tl(cpu_gpr[rd], t1, t0);
2563 tcg_gen_andi_tl(t0, t0, 0x3f);
2564 tcg_gen_rotr_tl(cpu_gpr[rd], t1, t0);
2569 (void)opn; /* avoid a compiler warning */
2570 MIPS_DEBUG("%s %s, %s, %s", opn, regnames[rd], regnames[rs], regnames[rt]);
2575 /* Arithmetic on HI/LO registers */
2576 static void gen_HILO (DisasContext *ctx, uint32_t opc, int reg)
2578 const char *opn = "hilo";
2581 if (reg == 0 && (opc == OPC_MFHI || opc == OPC_MFLO)) {
2587 if (opc == OPC_MFHI || opc == OPC_MFLO) {
2588 acc = ((ctx->opcode) >> 21) & 0x03;
2590 acc = ((ctx->opcode) >> 11) & 0x03;
2599 #if defined(TARGET_MIPS64)
2601 tcg_gen_ext32s_tl(cpu_gpr[reg], cpu_HI[acc]);
2605 tcg_gen_mov_tl(cpu_gpr[reg], cpu_HI[acc]);
2610 #if defined(TARGET_MIPS64)
2612 tcg_gen_ext32s_tl(cpu_gpr[reg], cpu_LO[acc]);
2616 tcg_gen_mov_tl(cpu_gpr[reg], cpu_LO[acc]);
2622 #if defined(TARGET_MIPS64)
2624 tcg_gen_ext32s_tl(cpu_HI[acc], cpu_gpr[reg]);
2628 tcg_gen_mov_tl(cpu_HI[acc], cpu_gpr[reg]);
2631 tcg_gen_movi_tl(cpu_HI[acc], 0);
2637 #if defined(TARGET_MIPS64)
2639 tcg_gen_ext32s_tl(cpu_LO[acc], cpu_gpr[reg]);
2643 tcg_gen_mov_tl(cpu_LO[acc], cpu_gpr[reg]);
2646 tcg_gen_movi_tl(cpu_LO[acc], 0);
2651 (void)opn; /* avoid a compiler warning */
2652 MIPS_DEBUG("%s %s", opn, regnames[reg]);
2655 static void gen_muldiv (DisasContext *ctx, uint32_t opc,
2658 const char *opn = "mul/div";
2662 t0 = tcg_temp_new();
2663 t1 = tcg_temp_new();
2665 gen_load_gpr(t0, rs);
2666 gen_load_gpr(t1, rt);
2671 TCGv t2 = tcg_temp_new();
2672 TCGv t3 = tcg_temp_new();
2673 tcg_gen_ext32s_tl(t0, t0);
2674 tcg_gen_ext32s_tl(t1, t1);
2675 tcg_gen_setcondi_tl(TCG_COND_EQ, t2, t0, INT_MIN);
2676 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, -1);
2677 tcg_gen_and_tl(t2, t2, t3);
2678 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, 0);
2679 tcg_gen_or_tl(t2, t2, t3);
2680 tcg_gen_movi_tl(t3, 0);
2681 tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, t3, t2, t1);
2682 tcg_gen_div_tl(cpu_LO[0], t0, t1);
2683 tcg_gen_rem_tl(cpu_HI[0], t0, t1);
2684 tcg_gen_ext32s_tl(cpu_LO[0], cpu_LO[0]);
2685 tcg_gen_ext32s_tl(cpu_HI[0], cpu_HI[0]);
2693 TCGv t2 = tcg_const_tl(0);
2694 TCGv t3 = tcg_const_tl(1);
2695 tcg_gen_ext32u_tl(t0, t0);
2696 tcg_gen_ext32u_tl(t1, t1);
2697 tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1, t2, t3, t1);
2698 tcg_gen_divu_tl(cpu_LO[0], t0, t1);
2699 tcg_gen_remu_tl(cpu_HI[0], t0, t1);
2700 tcg_gen_ext32s_tl(cpu_LO[0], cpu_LO[0]);
2701 tcg_gen_ext32s_tl(cpu_HI[0], cpu_HI[0]);
2709 TCGv_i64 t2 = tcg_temp_new_i64();
2710 TCGv_i64 t3 = tcg_temp_new_i64();
2711 acc = ((ctx->opcode) >> 11) & 0x03;
2716 tcg_gen_ext_tl_i64(t2, t0);
2717 tcg_gen_ext_tl_i64(t3, t1);
2718 tcg_gen_mul_i64(t2, t2, t3);
2719 tcg_temp_free_i64(t3);
2720 tcg_gen_trunc_i64_tl(t0, t2);
2721 tcg_gen_shri_i64(t2, t2, 32);
2722 tcg_gen_trunc_i64_tl(t1, t2);
2723 tcg_temp_free_i64(t2);
2724 tcg_gen_ext32s_tl(cpu_LO[acc], t0);
2725 tcg_gen_ext32s_tl(cpu_HI[acc], t1);
2731 TCGv_i64 t2 = tcg_temp_new_i64();
2732 TCGv_i64 t3 = tcg_temp_new_i64();
2733 acc = ((ctx->opcode) >> 11) & 0x03;
2738 tcg_gen_ext32u_tl(t0, t0);
2739 tcg_gen_ext32u_tl(t1, t1);
2740 tcg_gen_extu_tl_i64(t2, t0);
2741 tcg_gen_extu_tl_i64(t3, t1);
2742 tcg_gen_mul_i64(t2, t2, t3);
2743 tcg_temp_free_i64(t3);
2744 tcg_gen_trunc_i64_tl(t0, t2);
2745 tcg_gen_shri_i64(t2, t2, 32);
2746 tcg_gen_trunc_i64_tl(t1, t2);
2747 tcg_temp_free_i64(t2);
2748 tcg_gen_ext32s_tl(cpu_LO[acc], t0);
2749 tcg_gen_ext32s_tl(cpu_HI[acc], t1);
2753 #if defined(TARGET_MIPS64)
2756 TCGv t2 = tcg_temp_new();
2757 TCGv t3 = tcg_temp_new();
2758 tcg_gen_setcondi_tl(TCG_COND_EQ, t2, t0, -1LL << 63);
2759 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, -1LL);
2760 tcg_gen_and_tl(t2, t2, t3);
2761 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, 0);
2762 tcg_gen_or_tl(t2, t2, t3);
2763 tcg_gen_movi_tl(t3, 0);
2764 tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, t3, t2, t1);
2765 tcg_gen_div_tl(cpu_LO[0], t0, t1);
2766 tcg_gen_rem_tl(cpu_HI[0], t0, t1);
2774 TCGv t2 = tcg_const_tl(0);
2775 TCGv t3 = tcg_const_tl(1);
2776 tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1, t2, t3, t1);
2777 tcg_gen_divu_i64(cpu_LO[0], t0, t1);
2778 tcg_gen_remu_i64(cpu_HI[0], t0, t1);
2785 gen_helper_dmult(cpu_env, t0, t1);
2789 gen_helper_dmultu(cpu_env, t0, t1);
2795 TCGv_i64 t2 = tcg_temp_new_i64();
2796 TCGv_i64 t3 = tcg_temp_new_i64();
2797 acc = ((ctx->opcode) >> 11) & 0x03;
2802 tcg_gen_ext_tl_i64(t2, t0);
2803 tcg_gen_ext_tl_i64(t3, t1);
2804 tcg_gen_mul_i64(t2, t2, t3);
2805 tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]);
2806 tcg_gen_add_i64(t2, t2, t3);
2807 tcg_temp_free_i64(t3);
2808 tcg_gen_trunc_i64_tl(t0, t2);
2809 tcg_gen_shri_i64(t2, t2, 32);
2810 tcg_gen_trunc_i64_tl(t1, t2);
2811 tcg_temp_free_i64(t2);
2812 tcg_gen_ext32s_tl(cpu_LO[acc], t0);
2813 tcg_gen_ext32s_tl(cpu_HI[acc], t1);
2819 TCGv_i64 t2 = tcg_temp_new_i64();
2820 TCGv_i64 t3 = tcg_temp_new_i64();
2821 acc = ((ctx->opcode) >> 11) & 0x03;
2826 tcg_gen_ext32u_tl(t0, t0);
2827 tcg_gen_ext32u_tl(t1, t1);
2828 tcg_gen_extu_tl_i64(t2, t0);
2829 tcg_gen_extu_tl_i64(t3, t1);
2830 tcg_gen_mul_i64(t2, t2, t3);
2831 tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]);
2832 tcg_gen_add_i64(t2, t2, t3);
2833 tcg_temp_free_i64(t3);
2834 tcg_gen_trunc_i64_tl(t0, t2);
2835 tcg_gen_shri_i64(t2, t2, 32);
2836 tcg_gen_trunc_i64_tl(t1, t2);
2837 tcg_temp_free_i64(t2);
2838 tcg_gen_ext32s_tl(cpu_LO[acc], t0);
2839 tcg_gen_ext32s_tl(cpu_HI[acc], t1);
2845 TCGv_i64 t2 = tcg_temp_new_i64();
2846 TCGv_i64 t3 = tcg_temp_new_i64();
2847 acc = ((ctx->opcode) >> 11) & 0x03;
2852 tcg_gen_ext_tl_i64(t2, t0);
2853 tcg_gen_ext_tl_i64(t3, t1);
2854 tcg_gen_mul_i64(t2, t2, t3);
2855 tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]);
2856 tcg_gen_sub_i64(t2, t3, t2);
2857 tcg_temp_free_i64(t3);
2858 tcg_gen_trunc_i64_tl(t0, t2);
2859 tcg_gen_shri_i64(t2, t2, 32);
2860 tcg_gen_trunc_i64_tl(t1, t2);
2861 tcg_temp_free_i64(t2);
2862 tcg_gen_ext32s_tl(cpu_LO[acc], t0);
2863 tcg_gen_ext32s_tl(cpu_HI[acc], t1);
2869 TCGv_i64 t2 = tcg_temp_new_i64();
2870 TCGv_i64 t3 = tcg_temp_new_i64();
2871 acc = ((ctx->opcode) >> 11) & 0x03;
2876 tcg_gen_ext32u_tl(t0, t0);
2877 tcg_gen_ext32u_tl(t1, t1);
2878 tcg_gen_extu_tl_i64(t2, t0);
2879 tcg_gen_extu_tl_i64(t3, t1);
2880 tcg_gen_mul_i64(t2, t2, t3);
2881 tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]);
2882 tcg_gen_sub_i64(t2, t3, t2);
2883 tcg_temp_free_i64(t3);
2884 tcg_gen_trunc_i64_tl(t0, t2);
2885 tcg_gen_shri_i64(t2, t2, 32);
2886 tcg_gen_trunc_i64_tl(t1, t2);
2887 tcg_temp_free_i64(t2);
2888 tcg_gen_ext32s_tl(cpu_LO[acc], t0);
2889 tcg_gen_ext32s_tl(cpu_HI[acc], t1);
2895 generate_exception(ctx, EXCP_RI);
2898 (void)opn; /* avoid a compiler warning */
2899 MIPS_DEBUG("%s %s %s", opn, regnames[rs], regnames[rt]);
2905 static void gen_mul_vr54xx (DisasContext *ctx, uint32_t opc,
2906 int rd, int rs, int rt)
2908 const char *opn = "mul vr54xx";
2909 TCGv t0 = tcg_temp_new();
2910 TCGv t1 = tcg_temp_new();
2912 gen_load_gpr(t0, rs);
2913 gen_load_gpr(t1, rt);
2916 case OPC_VR54XX_MULS:
2917 gen_helper_muls(t0, cpu_env, t0, t1);
2920 case OPC_VR54XX_MULSU:
2921 gen_helper_mulsu(t0, cpu_env, t0, t1);
2924 case OPC_VR54XX_MACC:
2925 gen_helper_macc(t0, cpu_env, t0, t1);
2928 case OPC_VR54XX_MACCU:
2929 gen_helper_maccu(t0, cpu_env, t0, t1);
2932 case OPC_VR54XX_MSAC:
2933 gen_helper_msac(t0, cpu_env, t0, t1);
2936 case OPC_VR54XX_MSACU:
2937 gen_helper_msacu(t0, cpu_env, t0, t1);
2940 case OPC_VR54XX_MULHI:
2941 gen_helper_mulhi(t0, cpu_env, t0, t1);
2944 case OPC_VR54XX_MULHIU:
2945 gen_helper_mulhiu(t0, cpu_env, t0, t1);
2948 case OPC_VR54XX_MULSHI:
2949 gen_helper_mulshi(t0, cpu_env, t0, t1);
2952 case OPC_VR54XX_MULSHIU:
2953 gen_helper_mulshiu(t0, cpu_env, t0, t1);
2956 case OPC_VR54XX_MACCHI:
2957 gen_helper_macchi(t0, cpu_env, t0, t1);
2960 case OPC_VR54XX_MACCHIU:
2961 gen_helper_macchiu(t0, cpu_env, t0, t1);
2964 case OPC_VR54XX_MSACHI:
2965 gen_helper_msachi(t0, cpu_env, t0, t1);
2968 case OPC_VR54XX_MSACHIU:
2969 gen_helper_msachiu(t0, cpu_env, t0, t1);
2973 MIPS_INVAL("mul vr54xx");
2974 generate_exception(ctx, EXCP_RI);
2977 gen_store_gpr(t0, rd);
2978 (void)opn; /* avoid a compiler warning */
2979 MIPS_DEBUG("%s %s, %s, %s", opn, regnames[rd], regnames[rs], regnames[rt]);
2986 static void gen_cl (DisasContext *ctx, uint32_t opc,
2989 const char *opn = "CLx";
2997 t0 = tcg_temp_new();
2998 gen_load_gpr(t0, rs);
3001 gen_helper_clo(cpu_gpr[rd], t0);
3005 gen_helper_clz(cpu_gpr[rd], t0);
3008 #if defined(TARGET_MIPS64)
3010 gen_helper_dclo(cpu_gpr[rd], t0);
3014 gen_helper_dclz(cpu_gpr[rd], t0);
3019 (void)opn; /* avoid a compiler warning */
3020 MIPS_DEBUG("%s %s, %s", opn, regnames[rd], regnames[rs]);
3024 /* Godson integer instructions */
3025 static void gen_loongson_integer(DisasContext *ctx, uint32_t opc,
3026 int rd, int rs, int rt)
3028 const char *opn = "loongson";
3040 case OPC_MULTU_G_2E:
3041 case OPC_MULTU_G_2F:
3042 #if defined(TARGET_MIPS64)
3043 case OPC_DMULT_G_2E:
3044 case OPC_DMULT_G_2F:
3045 case OPC_DMULTU_G_2E:
3046 case OPC_DMULTU_G_2F:
3048 t0 = tcg_temp_new();
3049 t1 = tcg_temp_new();
3052 t0 = tcg_temp_local_new();
3053 t1 = tcg_temp_local_new();
3057 gen_load_gpr(t0, rs);
3058 gen_load_gpr(t1, rt);
3063 tcg_gen_mul_tl(cpu_gpr[rd], t0, t1);
3064 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3067 case OPC_MULTU_G_2E:
3068 case OPC_MULTU_G_2F:
3069 tcg_gen_ext32u_tl(t0, t0);
3070 tcg_gen_ext32u_tl(t1, t1);
3071 tcg_gen_mul_tl(cpu_gpr[rd], t0, t1);
3072 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3078 int l1 = gen_new_label();
3079 int l2 = gen_new_label();
3080 int l3 = gen_new_label();
3081 tcg_gen_ext32s_tl(t0, t0);
3082 tcg_gen_ext32s_tl(t1, t1);
3083 tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
3084 tcg_gen_movi_tl(cpu_gpr[rd], 0);
3087 tcg_gen_brcondi_tl(TCG_COND_NE, t0, INT_MIN, l2);
3088 tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1, l2);
3089 tcg_gen_mov_tl(cpu_gpr[rd], t0);
3092 tcg_gen_div_tl(cpu_gpr[rd], t0, t1);
3093 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3101 int l1 = gen_new_label();
3102 int l2 = gen_new_label();
3103 tcg_gen_ext32u_tl(t0, t0);
3104 tcg_gen_ext32u_tl(t1, t1);
3105 tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
3106 tcg_gen_movi_tl(cpu_gpr[rd], 0);
3109 tcg_gen_divu_tl(cpu_gpr[rd], t0, t1);
3110 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3118 int l1 = gen_new_label();
3119 int l2 = gen_new_label();
3120 int l3 = gen_new_label();
3121 tcg_gen_ext32u_tl(t0, t0);
3122 tcg_gen_ext32u_tl(t1, t1);
3123 tcg_gen_brcondi_tl(TCG_COND_EQ, t1, 0, l1);
3124 tcg_gen_brcondi_tl(TCG_COND_NE, t0, INT_MIN, l2);
3125 tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1, l2);
3127 tcg_gen_movi_tl(cpu_gpr[rd], 0);
3130 tcg_gen_rem_tl(cpu_gpr[rd], t0, t1);
3131 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3139 int l1 = gen_new_label();
3140 int l2 = gen_new_label();
3141 tcg_gen_ext32u_tl(t0, t0);
3142 tcg_gen_ext32u_tl(t1, t1);
3143 tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
3144 tcg_gen_movi_tl(cpu_gpr[rd], 0);
3147 tcg_gen_remu_tl(cpu_gpr[rd], t0, t1);
3148 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3153 #if defined(TARGET_MIPS64)
3154 case OPC_DMULT_G_2E:
3155 case OPC_DMULT_G_2F:
3156 tcg_gen_mul_tl(cpu_gpr[rd], t0, t1);
3159 case OPC_DMULTU_G_2E:
3160 case OPC_DMULTU_G_2F:
3161 tcg_gen_mul_tl(cpu_gpr[rd], t0, t1);
3167 int l1 = gen_new_label();
3168 int l2 = gen_new_label();
3169 int l3 = gen_new_label();
3170 tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
3171 tcg_gen_movi_tl(cpu_gpr[rd], 0);
3174 tcg_gen_brcondi_tl(TCG_COND_NE, t0, -1LL << 63, l2);
3175 tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1LL, l2);
3176 tcg_gen_mov_tl(cpu_gpr[rd], t0);
3179 tcg_gen_div_tl(cpu_gpr[rd], t0, t1);
3184 case OPC_DDIVU_G_2E:
3185 case OPC_DDIVU_G_2F:
3187 int l1 = gen_new_label();
3188 int l2 = gen_new_label();
3189 tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
3190 tcg_gen_movi_tl(cpu_gpr[rd], 0);
3193 tcg_gen_divu_tl(cpu_gpr[rd], t0, t1);
3201 int l1 = gen_new_label();
3202 int l2 = gen_new_label();
3203 int l3 = gen_new_label();
3204 tcg_gen_brcondi_tl(TCG_COND_EQ, t1, 0, l1);
3205 tcg_gen_brcondi_tl(TCG_COND_NE, t0, -1LL << 63, l2);
3206 tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1LL, l2);
3208 tcg_gen_movi_tl(cpu_gpr[rd], 0);
3211 tcg_gen_rem_tl(cpu_gpr[rd], t0, t1);
3216 case OPC_DMODU_G_2E:
3217 case OPC_DMODU_G_2F:
3219 int l1 = gen_new_label();
3220 int l2 = gen_new_label();
3221 tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
3222 tcg_gen_movi_tl(cpu_gpr[rd], 0);
3225 tcg_gen_remu_tl(cpu_gpr[rd], t0, t1);
3233 (void)opn; /* avoid a compiler warning */
3234 MIPS_DEBUG("%s %s, %s", opn, regnames[rd], regnames[rs]);
3239 /* Loongson multimedia instructions */
3240 static void gen_loongson_multimedia(DisasContext *ctx, int rd, int rs, int rt)
3242 const char *opn = "loongson_cp2";
3243 uint32_t opc, shift_max;
3246 opc = MASK_LMI(ctx->opcode);
3252 t0 = tcg_temp_local_new_i64();
3253 t1 = tcg_temp_local_new_i64();
3256 t0 = tcg_temp_new_i64();
3257 t1 = tcg_temp_new_i64();
3261 gen_load_fpr64(ctx, t0, rs);
3262 gen_load_fpr64(ctx, t1, rt);
3264 #define LMI_HELPER(UP, LO) \
3265 case OPC_##UP: gen_helper_##LO(t0, t0, t1); opn = #LO; break
3266 #define LMI_HELPER_1(UP, LO) \
3267 case OPC_##UP: gen_helper_##LO(t0, t0); opn = #LO; break
3268 #define LMI_DIRECT(UP, LO, OP) \
3269 case OPC_##UP: tcg_gen_##OP##_i64(t0, t0, t1); opn = #LO; break
3272 LMI_HELPER(PADDSH, paddsh);
3273 LMI_HELPER(PADDUSH, paddush);
3274 LMI_HELPER(PADDH, paddh);
3275 LMI_HELPER(PADDW, paddw);
3276 LMI_HELPER(PADDSB, paddsb);
3277 LMI_HELPER(PADDUSB, paddusb);
3278 LMI_HELPER(PADDB, paddb);
3280 LMI_HELPER(PSUBSH, psubsh);
3281 LMI_HELPER(PSUBUSH, psubush);
3282 LMI_HELPER(PSUBH, psubh);
3283 LMI_HELPER(PSUBW, psubw);
3284 LMI_HELPER(PSUBSB, psubsb);
3285 LMI_HELPER(PSUBUSB, psubusb);
3286 LMI_HELPER(PSUBB, psubb);
3288 LMI_HELPER(PSHUFH, pshufh);
3289 LMI_HELPER(PACKSSWH, packsswh);
3290 LMI_HELPER(PACKSSHB, packsshb);
3291 LMI_HELPER(PACKUSHB, packushb);
3293 LMI_HELPER(PUNPCKLHW, punpcklhw);
3294 LMI_HELPER(PUNPCKHHW, punpckhhw);
3295 LMI_HELPER(PUNPCKLBH, punpcklbh);
3296 LMI_HELPER(PUNPCKHBH, punpckhbh);
3297 LMI_HELPER(PUNPCKLWD, punpcklwd);
3298 LMI_HELPER(PUNPCKHWD, punpckhwd);
3300 LMI_HELPER(PAVGH, pavgh);
3301 LMI_HELPER(PAVGB, pavgb);
3302 LMI_HELPER(PMAXSH, pmaxsh);
3303 LMI_HELPER(PMINSH, pminsh);
3304 LMI_HELPER(PMAXUB, pmaxub);
3305 LMI_HELPER(PMINUB, pminub);
3307 LMI_HELPER(PCMPEQW, pcmpeqw);
3308 LMI_HELPER(PCMPGTW, pcmpgtw);
3309 LMI_HELPER(PCMPEQH, pcmpeqh);
3310 LMI_HELPER(PCMPGTH, pcmpgth);
3311 LMI_HELPER(PCMPEQB, pcmpeqb);
3312 LMI_HELPER(PCMPGTB, pcmpgtb);
3314 LMI_HELPER(PSLLW, psllw);
3315 LMI_HELPER(PSLLH, psllh);
3316 LMI_HELPER(PSRLW, psrlw);
3317 LMI_HELPER(PSRLH, psrlh);
3318 LMI_HELPER(PSRAW, psraw);
3319 LMI_HELPER(PSRAH, psrah);
3321 LMI_HELPER(PMULLH, pmullh);
3322 LMI_HELPER(PMULHH, pmulhh);
3323 LMI_HELPER(PMULHUH, pmulhuh);
3324 LMI_HELPER(PMADDHW, pmaddhw);
3326 LMI_HELPER(PASUBUB, pasubub);
3327 LMI_HELPER_1(BIADD, biadd);
3328 LMI_HELPER_1(PMOVMSKB, pmovmskb);
3330 LMI_DIRECT(PADDD, paddd, add);
3331 LMI_DIRECT(PSUBD, psubd, sub);
3332 LMI_DIRECT(XOR_CP2, xor, xor);
3333 LMI_DIRECT(NOR_CP2, nor, nor);
3334 LMI_DIRECT(AND_CP2, and, and);
3335 LMI_DIRECT(PANDN, pandn, andc);
3336 LMI_DIRECT(OR, or, or);
3339 tcg_gen_deposit_i64(t0, t0, t1, 0, 16);
3343 tcg_gen_deposit_i64(t0, t0, t1, 16, 16);
3347 tcg_gen_deposit_i64(t0, t0, t1, 32, 16);
3351 tcg_gen_deposit_i64(t0, t0, t1, 48, 16);
3356 tcg_gen_andi_i64(t1, t1, 3);
3357 tcg_gen_shli_i64(t1, t1, 4);
3358 tcg_gen_shr_i64(t0, t0, t1);
3359 tcg_gen_ext16u_i64(t0, t0);
3364 tcg_gen_add_i64(t0, t0, t1);
3365 tcg_gen_ext32s_i64(t0, t0);
3369 tcg_gen_sub_i64(t0, t0, t1);
3370 tcg_gen_ext32s_i64(t0, t0);
3399 /* Make sure shift count isn't TCG undefined behaviour. */
3400 tcg_gen_andi_i64(t1, t1, shift_max - 1);
3405 tcg_gen_shl_i64(t0, t0, t1);
3409 /* Since SRA is UndefinedResult without sign-extended inputs,
3410 we can treat SRA and DSRA the same. */
3411 tcg_gen_sar_i64(t0, t0, t1);
3414 /* We want to shift in zeros for SRL; zero-extend first. */
3415 tcg_gen_ext32u_i64(t0, t0);
3418 tcg_gen_shr_i64(t0, t0, t1);
3422 if (shift_max == 32) {
3423 tcg_gen_ext32s_i64(t0, t0);
3426 /* Shifts larger than MAX produce zero. */
3427 tcg_gen_setcondi_i64(TCG_COND_LTU, t1, t1, shift_max);
3428 tcg_gen_neg_i64(t1, t1);
3429 tcg_gen_and_i64(t0, t0, t1);
3435 TCGv_i64 t2 = tcg_temp_new_i64();
3436 int lab = gen_new_label();
3438 tcg_gen_mov_i64(t2, t0);
3439 tcg_gen_add_i64(t0, t1, t2);
3440 if (opc == OPC_ADD_CP2) {
3441 tcg_gen_ext32s_i64(t0, t0);
3443 tcg_gen_xor_i64(t1, t1, t2);
3444 tcg_gen_xor_i64(t2, t2, t0);
3445 tcg_gen_andc_i64(t1, t2, t1);
3446 tcg_temp_free_i64(t2);
3447 tcg_gen_brcondi_i64(TCG_COND_GE, t1, 0, lab);
3448 generate_exception(ctx, EXCP_OVERFLOW);
3451 opn = (opc == OPC_ADD_CP2 ? "add" : "dadd");
3458 TCGv_i64 t2 = tcg_temp_new_i64();
3459 int lab = gen_new_label();
3461 tcg_gen_mov_i64(t2, t0);
3462 tcg_gen_sub_i64(t0, t1, t2);
3463 if (opc == OPC_SUB_CP2) {
3464 tcg_gen_ext32s_i64(t0, t0);
3466 tcg_gen_xor_i64(t1, t1, t2);
3467 tcg_gen_xor_i64(t2, t2, t0);
3468 tcg_gen_and_i64(t1, t1, t2);
3469 tcg_temp_free_i64(t2);
3470 tcg_gen_brcondi_i64(TCG_COND_GE, t1, 0, lab);
3471 generate_exception(ctx, EXCP_OVERFLOW);
3474 opn = (opc == OPC_SUB_CP2 ? "sub" : "dsub");
3479 tcg_gen_ext32u_i64(t0, t0);
3480 tcg_gen_ext32u_i64(t1, t1);
3481 tcg_gen_mul_i64(t0, t0, t1);
3491 /* ??? Document is unclear: Set FCC[CC]. Does that mean the
3492 FD field is the CC field? */
3495 generate_exception(ctx, EXCP_RI);
3502 gen_store_fpr64(ctx, t0, rd);
3504 (void)opn; /* avoid a compiler warning */
3505 MIPS_DEBUG("%s %s, %s, %s", opn,
3506 fregnames[rd], fregnames[rs], fregnames[rt]);
3507 tcg_temp_free_i64(t0);
3508 tcg_temp_free_i64(t1);
3512 static void gen_trap (DisasContext *ctx, uint32_t opc,
3513 int rs, int rt, int16_t imm)
3516 TCGv t0 = tcg_temp_new();
3517 TCGv t1 = tcg_temp_new();
3520 /* Load needed operands */
3528 /* Compare two registers */
3530 gen_load_gpr(t0, rs);
3531 gen_load_gpr(t1, rt);
3541 /* Compare register to immediate */
3542 if (rs != 0 || imm != 0) {
3543 gen_load_gpr(t0, rs);
3544 tcg_gen_movi_tl(t1, (int32_t)imm);
3551 case OPC_TEQ: /* rs == rs */
3552 case OPC_TEQI: /* r0 == 0 */
3553 case OPC_TGE: /* rs >= rs */
3554 case OPC_TGEI: /* r0 >= 0 */
3555 case OPC_TGEU: /* rs >= rs unsigned */
3556 case OPC_TGEIU: /* r0 >= 0 unsigned */
3558 generate_exception(ctx, EXCP_TRAP);
3560 case OPC_TLT: /* rs < rs */
3561 case OPC_TLTI: /* r0 < 0 */
3562 case OPC_TLTU: /* rs < rs unsigned */
3563 case OPC_TLTIU: /* r0 < 0 unsigned */
3564 case OPC_TNE: /* rs != rs */
3565 case OPC_TNEI: /* r0 != 0 */
3566 /* Never trap: treat as NOP. */
3570 int l1 = gen_new_label();
3575 tcg_gen_brcond_tl(TCG_COND_NE, t0, t1, l1);
3579 tcg_gen_brcond_tl(TCG_COND_LT, t0, t1, l1);
3583 tcg_gen_brcond_tl(TCG_COND_LTU, t0, t1, l1);
3587 tcg_gen_brcond_tl(TCG_COND_GE, t0, t1, l1);
3591 tcg_gen_brcond_tl(TCG_COND_GEU, t0, t1, l1);
3595 tcg_gen_brcond_tl(TCG_COND_EQ, t0, t1, l1);
3598 generate_exception(ctx, EXCP_TRAP);
3605 static inline void gen_goto_tb(DisasContext *ctx, int n, target_ulong dest)
3607 TranslationBlock *tb;
3609 if ((tb->pc & TARGET_PAGE_MASK) == (dest & TARGET_PAGE_MASK) &&
3610 likely(!ctx->singlestep_enabled)) {
3613 tcg_gen_exit_tb((tcg_target_long)tb + n);
3616 if (ctx->singlestep_enabled) {
3617 save_cpu_state(ctx, 0);
3618 gen_helper_0e0i(raise_exception, EXCP_DEBUG);
3624 /* Branches (before delay slot) */
3625 static void gen_compute_branch (DisasContext *ctx, uint32_t opc,
3627 int rs, int rt, int32_t offset)
3629 target_ulong btgt = -1;
3631 int bcond_compute = 0;
3632 TCGv t0 = tcg_temp_new();
3633 TCGv t1 = tcg_temp_new();
3635 if (ctx->hflags & MIPS_HFLAG_BMASK) {
3636 #ifdef MIPS_DEBUG_DISAS
3637 LOG_DISAS("Branch in delay slot at PC 0x" TARGET_FMT_lx "\n", ctx->pc);
3639 generate_exception(ctx, EXCP_RI);
3643 /* Load needed operands */
3649 /* Compare two registers */
3651 gen_load_gpr(t0, rs);
3652 gen_load_gpr(t1, rt);
3655 btgt = ctx->pc + insn_bytes + offset;
3671 /* Compare to zero */
3673 gen_load_gpr(t0, rs);
3676 btgt = ctx->pc + insn_bytes + offset;
3679 #if defined(TARGET_MIPS64)
3681 tcg_gen_andi_tl(t0, cpu_dspctrl, 0x7F);
3683 tcg_gen_andi_tl(t0, cpu_dspctrl, 0x3F);
3686 btgt = ctx->pc + insn_bytes + offset;
3693 /* Jump to immediate */
3694 btgt = ((ctx->pc + insn_bytes) & (int32_t)0xF0000000) | (uint32_t)offset;
3700 /* Jump to register */
3701 if (offset != 0 && offset != 16) {
3702 /* Hint = 0 is JR/JALR, hint 16 is JR.HB/JALR.HB, the
3703 others are reserved. */
3704 MIPS_INVAL("jump hint");
3705 generate_exception(ctx, EXCP_RI);
3708 gen_load_gpr(btarget, rs);
3711 MIPS_INVAL("branch/jump");
3712 generate_exception(ctx, EXCP_RI);
3715 if (bcond_compute == 0) {
3716 /* No condition to be computed */
3718 case OPC_BEQ: /* rx == rx */
3719 case OPC_BEQL: /* rx == rx likely */
3720 case OPC_BGEZ: /* 0 >= 0 */
3721 case OPC_BGEZL: /* 0 >= 0 likely */
3722 case OPC_BLEZ: /* 0 <= 0 */
3723 case OPC_BLEZL: /* 0 <= 0 likely */
3725 ctx->hflags |= MIPS_HFLAG_B;
3726 MIPS_DEBUG("balways");
3729 case OPC_BGEZAL: /* 0 >= 0 */
3730 case OPC_BGEZALL: /* 0 >= 0 likely */
3731 ctx->hflags |= (opc == OPC_BGEZALS
3733 : MIPS_HFLAG_BDS32);
3734 /* Always take and link */
3736 ctx->hflags |= MIPS_HFLAG_B;
3737 MIPS_DEBUG("balways and link");
3739 case OPC_BNE: /* rx != rx */
3740 case OPC_BGTZ: /* 0 > 0 */
3741 case OPC_BLTZ: /* 0 < 0 */
3743 MIPS_DEBUG("bnever (NOP)");
3746 case OPC_BLTZAL: /* 0 < 0 */
3747 ctx->hflags |= (opc == OPC_BLTZALS
3749 : MIPS_HFLAG_BDS32);
3750 /* Handle as an unconditional branch to get correct delay
3753 btgt = ctx->pc + (opc == OPC_BLTZALS ? 6 : 8);
3754 ctx->hflags |= MIPS_HFLAG_B;
3755 MIPS_DEBUG("bnever and link");
3757 case OPC_BLTZALL: /* 0 < 0 likely */
3758 tcg_gen_movi_tl(cpu_gpr[31], ctx->pc + 8);
3759 /* Skip the instruction in the delay slot */
3760 MIPS_DEBUG("bnever, link and skip");
3763 case OPC_BNEL: /* rx != rx likely */
3764 case OPC_BGTZL: /* 0 > 0 likely */
3765 case OPC_BLTZL: /* 0 < 0 likely */
3766 /* Skip the instruction in the delay slot */
3767 MIPS_DEBUG("bnever and skip");
3771 ctx->hflags |= MIPS_HFLAG_B;
3772 MIPS_DEBUG("j " TARGET_FMT_lx, btgt);
3776 ctx->hflags |= MIPS_HFLAG_BX;
3781 ctx->hflags |= MIPS_HFLAG_B;
3782 ctx->hflags |= ((opc == OPC_JALS || opc == OPC_JALXS)
3784 : MIPS_HFLAG_BDS32);
3785 MIPS_DEBUG("jal " TARGET_FMT_lx, btgt);
3788 ctx->hflags |= MIPS_HFLAG_BR;
3789 if (insn_bytes == 4)
3790 ctx->hflags |= MIPS_HFLAG_BDS32;
3791 MIPS_DEBUG("jr %s", regnames[rs]);
3797 ctx->hflags |= MIPS_HFLAG_BR;
3798 ctx->hflags |= (opc == OPC_JALRS
3800 : MIPS_HFLAG_BDS32);
3801 MIPS_DEBUG("jalr %s, %s", regnames[rt], regnames[rs]);
3804 MIPS_INVAL("branch/jump");
3805 generate_exception(ctx, EXCP_RI);
3811 tcg_gen_setcond_tl(TCG_COND_EQ, bcond, t0, t1);
3812 MIPS_DEBUG("beq %s, %s, " TARGET_FMT_lx,
3813 regnames[rs], regnames[rt], btgt);
3816 tcg_gen_setcond_tl(TCG_COND_EQ, bcond, t0, t1);
3817 MIPS_DEBUG("beql %s, %s, " TARGET_FMT_lx,
3818 regnames[rs], regnames[rt], btgt);
3821 tcg_gen_setcond_tl(TCG_COND_NE, bcond, t0, t1);
3822 MIPS_DEBUG("bne %s, %s, " TARGET_FMT_lx,
3823 regnames[rs], regnames[rt], btgt);
3826 tcg_gen_setcond_tl(TCG_COND_NE, bcond, t0, t1);
3827 MIPS_DEBUG("bnel %s, %s, " TARGET_FMT_lx,
3828 regnames[rs], regnames[rt], btgt);
3831 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 0);
3832 MIPS_DEBUG("bgez %s, " TARGET_FMT_lx, regnames[rs], btgt);
3835 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 0);
3836 MIPS_DEBUG("bgezl %s, " TARGET_FMT_lx, regnames[rs], btgt);
3840 ctx->hflags |= (opc == OPC_BGEZALS
3842 : MIPS_HFLAG_BDS32);
3843 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 0);
3844 MIPS_DEBUG("bgezal %s, " TARGET_FMT_lx, regnames[rs], btgt);
3848 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 0);
3850 MIPS_DEBUG("bgezall %s, " TARGET_FMT_lx, regnames[rs], btgt);
3853 tcg_gen_setcondi_tl(TCG_COND_GT, bcond, t0, 0);
3854 MIPS_DEBUG("bgtz %s, " TARGET_FMT_lx, regnames[rs], btgt);
3857 tcg_gen_setcondi_tl(TCG_COND_GT, bcond, t0, 0);
3858 MIPS_DEBUG("bgtzl %s, " TARGET_FMT_lx, regnames[rs], btgt);
3861 tcg_gen_setcondi_tl(TCG_COND_LE, bcond, t0, 0);
3862 MIPS_DEBUG("blez %s, " TARGET_FMT_lx, regnames[rs], btgt);
3865 tcg_gen_setcondi_tl(TCG_COND_LE, bcond, t0, 0);
3866 MIPS_DEBUG("blezl %s, " TARGET_FMT_lx, regnames[rs], btgt);
3869 tcg_gen_setcondi_tl(TCG_COND_LT, bcond, t0, 0);
3870 MIPS_DEBUG("bltz %s, " TARGET_FMT_lx, regnames[rs], btgt);
3873 tcg_gen_setcondi_tl(TCG_COND_LT, bcond, t0, 0);
3874 MIPS_DEBUG("bltzl %s, " TARGET_FMT_lx, regnames[rs], btgt);
3877 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 32);
3878 MIPS_DEBUG("bposge32 " TARGET_FMT_lx, btgt);
3880 #if defined(TARGET_MIPS64)
3882 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 64);
3883 MIPS_DEBUG("bposge64 " TARGET_FMT_lx, btgt);
3888 ctx->hflags |= (opc == OPC_BLTZALS
3890 : MIPS_HFLAG_BDS32);
3891 tcg_gen_setcondi_tl(TCG_COND_LT, bcond, t0, 0);
3893 MIPS_DEBUG("bltzal %s, " TARGET_FMT_lx, regnames[rs], btgt);
3895 ctx->hflags |= MIPS_HFLAG_BC;
3898 tcg_gen_setcondi_tl(TCG_COND_LT, bcond, t0, 0);
3900 MIPS_DEBUG("bltzall %s, " TARGET_FMT_lx, regnames[rs], btgt);
3902 ctx->hflags |= MIPS_HFLAG_BL;
3905 MIPS_INVAL("conditional branch/jump");
3906 generate_exception(ctx, EXCP_RI);
3910 MIPS_DEBUG("enter ds: link %d cond %02x target " TARGET_FMT_lx,
3911 blink, ctx->hflags, btgt);
3913 ctx->btarget = btgt;
3915 int post_delay = insn_bytes;
3916 int lowbit = !!(ctx->hflags & MIPS_HFLAG_M16);
3918 if (opc != OPC_JALRC)
3919 post_delay += ((ctx->hflags & MIPS_HFLAG_BDS16) ? 2 : 4);
3921 tcg_gen_movi_tl(cpu_gpr[blink], ctx->pc + post_delay + lowbit);
3925 if (insn_bytes == 2)
3926 ctx->hflags |= MIPS_HFLAG_B16;
3931 /* special3 bitfield operations */
3932 static void gen_bitops (DisasContext *ctx, uint32_t opc, int rt,
3933 int rs, int lsb, int msb)
3935 TCGv t0 = tcg_temp_new();
3936 TCGv t1 = tcg_temp_new();
3938 gen_load_gpr(t1, rs);
3943 tcg_gen_shri_tl(t0, t1, lsb);
3945 tcg_gen_andi_tl(t0, t0, (1 << (msb + 1)) - 1);
3947 tcg_gen_ext32s_tl(t0, t0);
3950 #if defined(TARGET_MIPS64)
3952 tcg_gen_shri_tl(t0, t1, lsb);
3954 tcg_gen_andi_tl(t0, t0, (1ULL << (msb + 1 + 32)) - 1);
3958 tcg_gen_shri_tl(t0, t1, lsb + 32);
3959 tcg_gen_andi_tl(t0, t0, (1ULL << (msb + 1)) - 1);
3962 tcg_gen_shri_tl(t0, t1, lsb);
3963 tcg_gen_andi_tl(t0, t0, (1ULL << (msb + 1)) - 1);
3969 gen_load_gpr(t0, rt);
3970 tcg_gen_deposit_tl(t0, t0, t1, lsb, msb - lsb + 1);
3971 tcg_gen_ext32s_tl(t0, t0);
3973 #if defined(TARGET_MIPS64)
3975 gen_load_gpr(t0, rt);
3976 tcg_gen_deposit_tl(t0, t0, t1, lsb, msb + 32 - lsb + 1);
3979 gen_load_gpr(t0, rt);
3980 tcg_gen_deposit_tl(t0, t0, t1, lsb + 32, msb - lsb + 1);
3983 gen_load_gpr(t0, rt);
3984 tcg_gen_deposit_tl(t0, t0, t1, lsb, msb - lsb + 1);
3989 MIPS_INVAL("bitops");
3990 generate_exception(ctx, EXCP_RI);
3995 gen_store_gpr(t0, rt);
4000 static void gen_bshfl (DisasContext *ctx, uint32_t op2, int rt, int rd)
4005 /* If no destination, treat it as a NOP. */
4010 t0 = tcg_temp_new();
4011 gen_load_gpr(t0, rt);
4015 TCGv t1 = tcg_temp_new();
4017 tcg_gen_shri_tl(t1, t0, 8);
4018 tcg_gen_andi_tl(t1, t1, 0x00FF00FF);
4019 tcg_gen_shli_tl(t0, t0, 8);
4020 tcg_gen_andi_tl(t0, t0, ~0x00FF00FF);
4021 tcg_gen_or_tl(t0, t0, t1);
4023 tcg_gen_ext32s_tl(cpu_gpr[rd], t0);
4027 tcg_gen_ext8s_tl(cpu_gpr[rd], t0);
4030 tcg_gen_ext16s_tl(cpu_gpr[rd], t0);
4032 #if defined(TARGET_MIPS64)
4035 TCGv t1 = tcg_temp_new();
4037 tcg_gen_shri_tl(t1, t0, 8);
4038 tcg_gen_andi_tl(t1, t1, 0x00FF00FF00FF00FFULL);
4039 tcg_gen_shli_tl(t0, t0, 8);
4040 tcg_gen_andi_tl(t0, t0, ~0x00FF00FF00FF00FFULL);
4041 tcg_gen_or_tl(cpu_gpr[rd], t0, t1);
4047 TCGv t1 = tcg_temp_new();
4049 tcg_gen_shri_tl(t1, t0, 16);
4050 tcg_gen_andi_tl(t1, t1, 0x0000FFFF0000FFFFULL);
4051 tcg_gen_shli_tl(t0, t0, 16);
4052 tcg_gen_andi_tl(t0, t0, ~0x0000FFFF0000FFFFULL);
4053 tcg_gen_or_tl(t0, t0, t1);
4054 tcg_gen_shri_tl(t1, t0, 32);
4055 tcg_gen_shli_tl(t0, t0, 32);
4056 tcg_gen_or_tl(cpu_gpr[rd], t0, t1);
4062 MIPS_INVAL("bsfhl");
4063 generate_exception(ctx, EXCP_RI);
4070 #ifndef CONFIG_USER_ONLY
4071 /* CP0 (MMU and control) */
4072 static inline void gen_mfc0_load32 (TCGv arg, target_ulong off)
4074 TCGv_i32 t0 = tcg_temp_new_i32();
4076 tcg_gen_ld_i32(t0, cpu_env, off);
4077 tcg_gen_ext_i32_tl(arg, t0);
4078 tcg_temp_free_i32(t0);
4081 static inline void gen_mfc0_load64 (TCGv arg, target_ulong off)
4083 tcg_gen_ld_tl(arg, cpu_env, off);
4084 tcg_gen_ext32s_tl(arg, arg);
4087 static inline void gen_mtc0_store32 (TCGv arg, target_ulong off)
4089 TCGv_i32 t0 = tcg_temp_new_i32();
4091 tcg_gen_trunc_tl_i32(t0, arg);
4092 tcg_gen_st_i32(t0, cpu_env, off);
4093 tcg_temp_free_i32(t0);
4096 static inline void gen_mtc0_store64 (TCGv arg, target_ulong off)
4098 tcg_gen_ext32s_tl(arg, arg);
4099 tcg_gen_st_tl(arg, cpu_env, off);
4102 static void gen_mfc0(DisasContext *ctx, TCGv arg, int reg, int sel)
4104 const char *rn = "invalid";
4107 check_insn(ctx, ISA_MIPS32);
4113 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Index));
4117 check_insn(ctx, ASE_MT);
4118 gen_helper_mfc0_mvpcontrol(arg, cpu_env);
4122 check_insn(ctx, ASE_MT);
4123 gen_helper_mfc0_mvpconf0(arg, cpu_env);
4127 check_insn(ctx, ASE_MT);
4128 gen_helper_mfc0_mvpconf1(arg, cpu_env);
4138 gen_helper_mfc0_random(arg, cpu_env);
4142 check_insn(ctx, ASE_MT);
4143 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEControl));
4147 check_insn(ctx, ASE_MT);
4148 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEConf0));
4152 check_insn(ctx, ASE_MT);
4153 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEConf1));
4157 check_insn(ctx, ASE_MT);
4158 gen_mfc0_load64(arg, offsetof(CPUMIPSState, CP0_YQMask));
4162 check_insn(ctx, ASE_MT);
4163 gen_mfc0_load64(arg, offsetof(CPUMIPSState, CP0_VPESchedule));
4167 check_insn(ctx, ASE_MT);
4168 gen_mfc0_load64(arg, offsetof(CPUMIPSState, CP0_VPEScheFBack));
4169 rn = "VPEScheFBack";
4172 check_insn(ctx, ASE_MT);
4173 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEOpt));
4183 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EntryLo0));
4184 tcg_gen_ext32s_tl(arg, arg);
4188 check_insn(ctx, ASE_MT);
4189 gen_helper_mfc0_tcstatus(arg, cpu_env);
4193 check_insn(ctx, ASE_MT);
4194 gen_helper_mfc0_tcbind(arg, cpu_env);
4198 check_insn(ctx, ASE_MT);
4199 gen_helper_mfc0_tcrestart(arg, cpu_env);
4203 check_insn(ctx, ASE_MT);
4204 gen_helper_mfc0_tchalt(arg, cpu_env);
4208 check_insn(ctx, ASE_MT);
4209 gen_helper_mfc0_tccontext(arg, cpu_env);
4213 check_insn(ctx, ASE_MT);
4214 gen_helper_mfc0_tcschedule(arg, cpu_env);
4218 check_insn(ctx, ASE_MT);
4219 gen_helper_mfc0_tcschefback(arg, cpu_env);
4229 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EntryLo1));
4230 tcg_gen_ext32s_tl(arg, arg);
4240 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_Context));
4241 tcg_gen_ext32s_tl(arg, arg);
4245 // gen_helper_mfc0_contextconfig(arg); /* SmartMIPS ASE */
4246 rn = "ContextConfig";
4255 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PageMask));
4259 check_insn(ctx, ISA_MIPS32R2);
4260 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PageGrain));
4270 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Wired));
4274 check_insn(ctx, ISA_MIPS32R2);
4275 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf0));
4279 check_insn(ctx, ISA_MIPS32R2);
4280 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf1));
4284 check_insn(ctx, ISA_MIPS32R2);
4285 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf2));
4289 check_insn(ctx, ISA_MIPS32R2);
4290 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf3));
4294 check_insn(ctx, ISA_MIPS32R2);
4295 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf4));
4305 check_insn(ctx, ISA_MIPS32R2);
4306 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_HWREna));
4316 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_BadVAddr));
4317 tcg_gen_ext32s_tl(arg, arg);
4327 /* Mark as an IO operation because we read the time. */
4330 gen_helper_mfc0_count(arg, cpu_env);
4334 /* Break the TB to be able to take timer interrupts immediately
4335 after reading count. */
4336 ctx->bstate = BS_STOP;
4339 /* 6,7 are implementation dependent */
4347 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EntryHi));
4348 tcg_gen_ext32s_tl(arg, arg);
4358 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Compare));
4361 /* 6,7 are implementation dependent */
4369 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Status));
4373 check_insn(ctx, ISA_MIPS32R2);
4374 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_IntCtl));
4378 check_insn(ctx, ISA_MIPS32R2);
4379 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSCtl));
4383 check_insn(ctx, ISA_MIPS32R2);
4384 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSMap));
4394 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Cause));
4404 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EPC));
4405 tcg_gen_ext32s_tl(arg, arg);
4415 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PRid));
4419 check_insn(ctx, ISA_MIPS32R2);
4420 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_EBase));
4430 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config0));
4434 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config1));
4438 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config2));
4442 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config3));
4445 /* 4,5 are reserved */
4446 /* 6,7 are implementation dependent */
4448 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config6));
4452 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config7));
4462 gen_helper_mfc0_lladdr(arg, cpu_env);
4472 gen_helper_1e0i(mfc0_watchlo, arg, sel);
4482 gen_helper_1e0i(mfc0_watchhi, arg, sel);
4492 #if defined(TARGET_MIPS64)
4493 check_insn(ctx, ISA_MIPS3);
4494 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_XContext));
4495 tcg_gen_ext32s_tl(arg, arg);
4504 /* Officially reserved, but sel 0 is used for R1x000 framemask */
4507 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Framemask));
4515 tcg_gen_movi_tl(arg, 0); /* unimplemented */
4516 rn = "'Diagnostic"; /* implementation dependent */
4521 gen_helper_mfc0_debug(arg, cpu_env); /* EJTAG support */
4525 // gen_helper_mfc0_tracecontrol(arg); /* PDtrace support */
4526 rn = "TraceControl";
4529 // gen_helper_mfc0_tracecontrol2(arg); /* PDtrace support */
4530 rn = "TraceControl2";
4533 // gen_helper_mfc0_usertracedata(arg); /* PDtrace support */
4534 rn = "UserTraceData";
4537 // gen_helper_mfc0_tracebpc(arg); /* PDtrace support */
4548 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_DEPC));
4549 tcg_gen_ext32s_tl(arg, arg);
4559 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Performance0));
4560 rn = "Performance0";
4563 // gen_helper_mfc0_performance1(arg);
4564 rn = "Performance1";
4567 // gen_helper_mfc0_performance2(arg);
4568 rn = "Performance2";
4571 // gen_helper_mfc0_performance3(arg);
4572 rn = "Performance3";
4575 // gen_helper_mfc0_performance4(arg);
4576 rn = "Performance4";
4579 // gen_helper_mfc0_performance5(arg);
4580 rn = "Performance5";
4583 // gen_helper_mfc0_performance6(arg);
4584 rn = "Performance6";
4587 // gen_helper_mfc0_performance7(arg);
4588 rn = "Performance7";
4595 tcg_gen_movi_tl(arg, 0); /* unimplemented */
4601 tcg_gen_movi_tl(arg, 0); /* unimplemented */
4614 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_TagLo));
4621 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DataLo));
4634 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_TagHi));
4641 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DataHi));
4651 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_ErrorEPC));
4652 tcg_gen_ext32s_tl(arg, arg);
4663 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DESAVE));
4673 (void)rn; /* avoid a compiler warning */
4674 LOG_DISAS("mfc0 %s (reg %d sel %d)\n", rn, reg, sel);
4678 LOG_DISAS("mfc0 %s (reg %d sel %d)\n", rn, reg, sel);
4679 generate_exception(ctx, EXCP_RI);
4682 static void gen_mtc0(DisasContext *ctx, TCGv arg, int reg, int sel)
4684 const char *rn = "invalid";
4687 check_insn(ctx, ISA_MIPS32);
4696 gen_helper_mtc0_index(cpu_env, arg);
4700 check_insn(ctx, ASE_MT);
4701 gen_helper_mtc0_mvpcontrol(cpu_env, arg);
4705 check_insn(ctx, ASE_MT);
4710 check_insn(ctx, ASE_MT);
4725 check_insn(ctx, ASE_MT);
4726 gen_helper_mtc0_vpecontrol(cpu_env, arg);
4730 check_insn(ctx, ASE_MT);
4731 gen_helper_mtc0_vpeconf0(cpu_env, arg);
4735 check_insn(ctx, ASE_MT);
4736 gen_helper_mtc0_vpeconf1(cpu_env, arg);
4740 check_insn(ctx, ASE_MT);
4741 gen_helper_mtc0_yqmask(cpu_env, arg);
4745 check_insn(ctx, ASE_MT);
4746 gen_mtc0_store64(arg, offsetof(CPUMIPSState, CP0_VPESchedule));
4750 check_insn(ctx, ASE_MT);
4751 gen_mtc0_store64(arg, offsetof(CPUMIPSState, CP0_VPEScheFBack));
4752 rn = "VPEScheFBack";
4755 check_insn(ctx, ASE_MT);
4756 gen_helper_mtc0_vpeopt(cpu_env, arg);
4766 gen_helper_mtc0_entrylo0(cpu_env, arg);
4770 check_insn(ctx, ASE_MT);
4771 gen_helper_mtc0_tcstatus(cpu_env, arg);
4775 check_insn(ctx, ASE_MT);
4776 gen_helper_mtc0_tcbind(cpu_env, arg);
4780 check_insn(ctx, ASE_MT);
4781 gen_helper_mtc0_tcrestart(cpu_env, arg);
4785 check_insn(ctx, ASE_MT);
4786 gen_helper_mtc0_tchalt(cpu_env, arg);
4790 check_insn(ctx, ASE_MT);
4791 gen_helper_mtc0_tccontext(cpu_env, arg);
4795 check_insn(ctx, ASE_MT);
4796 gen_helper_mtc0_tcschedule(cpu_env, arg);
4800 check_insn(ctx, ASE_MT);
4801 gen_helper_mtc0_tcschefback(cpu_env, arg);
4811 gen_helper_mtc0_entrylo1(cpu_env, arg);
4821 gen_helper_mtc0_context(cpu_env, arg);
4825 // gen_helper_mtc0_contextconfig(cpu_env, arg); /* SmartMIPS ASE */
4826 rn = "ContextConfig";
4835 gen_helper_mtc0_pagemask(cpu_env, arg);
4839 check_insn(ctx, ISA_MIPS32R2);
4840 gen_helper_mtc0_pagegrain(cpu_env, arg);
4850 gen_helper_mtc0_wired(cpu_env, arg);
4854 check_insn(ctx, ISA_MIPS32R2);
4855 gen_helper_mtc0_srsconf0(cpu_env, arg);
4859 check_insn(ctx, ISA_MIPS32R2);
4860 gen_helper_mtc0_srsconf1(cpu_env, arg);
4864 check_insn(ctx, ISA_MIPS32R2);
4865 gen_helper_mtc0_srsconf2(cpu_env, arg);
4869 check_insn(ctx, ISA_MIPS32R2);
4870 gen_helper_mtc0_srsconf3(cpu_env, arg);
4874 check_insn(ctx, ISA_MIPS32R2);
4875 gen_helper_mtc0_srsconf4(cpu_env, arg);
4885 check_insn(ctx, ISA_MIPS32R2);
4886 gen_helper_mtc0_hwrena(cpu_env, arg);
4900 gen_helper_mtc0_count(cpu_env, arg);
4903 /* 6,7 are implementation dependent */
4911 gen_helper_mtc0_entryhi(cpu_env, arg);
4921 gen_helper_mtc0_compare(cpu_env, arg);
4924 /* 6,7 are implementation dependent */
4932 save_cpu_state(ctx, 1);
4933 gen_helper_mtc0_status(cpu_env, arg);
4934 /* BS_STOP isn't good enough here, hflags may have changed. */
4935 gen_save_pc(ctx->pc + 4);
4936 ctx->bstate = BS_EXCP;
4940 check_insn(ctx, ISA_MIPS32R2);
4941 gen_helper_mtc0_intctl(cpu_env, arg);
4942 /* Stop translation as we may have switched the execution mode */
4943 ctx->bstate = BS_STOP;
4947 check_insn(ctx, ISA_MIPS32R2);
4948 gen_helper_mtc0_srsctl(cpu_env, arg);
4949 /* Stop translation as we may have switched the execution mode */
4950 ctx->bstate = BS_STOP;
4954 check_insn(ctx, ISA_MIPS32R2);
4955 gen_mtc0_store32(arg, offsetof(CPUMIPSState, CP0_SRSMap));
4956 /* Stop translation as we may have switched the execution mode */
4957 ctx->bstate = BS_STOP;
4967 save_cpu_state(ctx, 1);
4968 gen_helper_mtc0_cause(cpu_env, arg);
4978 gen_mtc0_store64(arg, offsetof(CPUMIPSState, CP0_EPC));
4992 check_insn(ctx, ISA_MIPS32R2);
4993 gen_helper_mtc0_ebase(cpu_env, arg);
5003 gen_helper_mtc0_config0(cpu_env, arg);
5005 /* Stop translation as we may have switched the execution mode */
5006 ctx->bstate = BS_STOP;
5009 /* ignored, read only */
5013 gen_helper_mtc0_config2(cpu_env, arg);
5015 /* Stop translation as we may have switched the execution mode */
5016 ctx->bstate = BS_STOP;
5019 /* ignored, read only */
5022 /* 4,5 are reserved */
5023 /* 6,7 are implementation dependent */
5033 rn = "Invalid config selector";
5040 gen_helper_mtc0_lladdr(cpu_env, arg);
5050 gen_helper_0e1i(mtc0_watchlo, arg, sel);
5060 gen_helper_0e1i(mtc0_watchhi, arg, sel);
5070 #if defined(TARGET_MIPS64)
5071 check_insn(ctx, ISA_MIPS3);
5072 gen_helper_mtc0_xcontext(cpu_env, arg);
5081 /* Officially reserved, but sel 0 is used for R1x000 framemask */
5084 gen_helper_mtc0_framemask(cpu_env, arg);
5093 rn = "Diagnostic"; /* implementation dependent */
5098 gen_helper_mtc0_debug(cpu_env, arg); /* EJTAG support */
5099 /* BS_STOP isn't good enough here, hflags may have changed. */
5100 gen_save_pc(ctx->pc + 4);
5101 ctx->bstate = BS_EXCP;
5105 // gen_helper_mtc0_tracecontrol(cpu_env, arg); /* PDtrace support */
5106 rn = "TraceControl";
5107 /* Stop translation as we may have switched the execution mode */
5108 ctx->bstate = BS_STOP;
5111 // gen_helper_mtc0_tracecontrol2(cpu_env, arg); /* PDtrace support */
5112 rn = "TraceControl2";
5113 /* Stop translation as we may have switched the execution mode */
5114 ctx->bstate = BS_STOP;
5117 /* Stop translation as we may have switched the execution mode */
5118 ctx->bstate = BS_STOP;
5119 // gen_helper_mtc0_usertracedata(cpu_env, arg); /* PDtrace support */
5120 rn = "UserTraceData";
5121 /* Stop translation as we may have switched the execution mode */
5122 ctx->bstate = BS_STOP;
5125 // gen_helper_mtc0_tracebpc(cpu_env, arg); /* PDtrace support */
5126 /* Stop translation as we may have switched the execution mode */
5127 ctx->bstate = BS_STOP;
5138 gen_mtc0_store64(arg, offsetof(CPUMIPSState, CP0_DEPC));
5148 gen_helper_mtc0_performance0(cpu_env, arg);
5149 rn = "Performance0";
5152 // gen_helper_mtc0_performance1(arg);
5153 rn = "Performance1";
5156 // gen_helper_mtc0_performance2(arg);
5157 rn = "Performance2";
5160 // gen_helper_mtc0_performance3(arg);
5161 rn = "Performance3";
5164 // gen_helper_mtc0_performance4(arg);
5165 rn = "Performance4";
5168 // gen_helper_mtc0_performance5(arg);
5169 rn = "Performance5";
5172 // gen_helper_mtc0_performance6(arg);
5173 rn = "Performance6";
5176 // gen_helper_mtc0_performance7(arg);
5177 rn = "Performance7";
5203 gen_helper_mtc0_taglo(cpu_env, arg);
5210 gen_helper_mtc0_datalo(cpu_env, arg);
5223 gen_helper_mtc0_taghi(cpu_env, arg);
5230 gen_helper_mtc0_datahi(cpu_env, arg);
5241 gen_mtc0_store64(arg, offsetof(CPUMIPSState, CP0_ErrorEPC));
5252 gen_mtc0_store32(arg, offsetof(CPUMIPSState, CP0_DESAVE));
5258 /* Stop translation as we may have switched the execution mode */
5259 ctx->bstate = BS_STOP;
5264 (void)rn; /* avoid a compiler warning */
5265 LOG_DISAS("mtc0 %s (reg %d sel %d)\n", rn, reg, sel);
5266 /* For simplicity assume that all writes can cause interrupts. */
5269 ctx->bstate = BS_STOP;
5274 LOG_DISAS("mtc0 %s (reg %d sel %d)\n", rn, reg, sel);
5275 generate_exception(ctx, EXCP_RI);
5278 #if defined(TARGET_MIPS64)
5279 static void gen_dmfc0(DisasContext *ctx, TCGv arg, int reg, int sel)
5281 const char *rn = "invalid";
5284 check_insn(ctx, ISA_MIPS64);
5290 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Index));
5294 check_insn(ctx, ASE_MT);
5295 gen_helper_mfc0_mvpcontrol(arg, cpu_env);
5299 check_insn(ctx, ASE_MT);
5300 gen_helper_mfc0_mvpconf0(arg, cpu_env);
5304 check_insn(ctx, ASE_MT);
5305 gen_helper_mfc0_mvpconf1(arg, cpu_env);
5315 gen_helper_mfc0_random(arg, cpu_env);
5319 check_insn(ctx, ASE_MT);
5320 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEControl));
5324 check_insn(ctx, ASE_MT);
5325 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEConf0));
5329 check_insn(ctx, ASE_MT);
5330 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEConf1));
5334 check_insn(ctx, ASE_MT);
5335 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_YQMask));
5339 check_insn(ctx, ASE_MT);
5340 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_VPESchedule));
5344 check_insn(ctx, ASE_MT);
5345 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_VPEScheFBack));
5346 rn = "VPEScheFBack";
5349 check_insn(ctx, ASE_MT);
5350 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEOpt));
5360 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EntryLo0));
5364 check_insn(ctx, ASE_MT);
5365 gen_helper_mfc0_tcstatus(arg, cpu_env);
5369 check_insn(ctx, ASE_MT);
5370 gen_helper_mfc0_tcbind(arg, cpu_env);
5374 check_insn(ctx, ASE_MT);
5375 gen_helper_dmfc0_tcrestart(arg, cpu_env);
5379 check_insn(ctx, ASE_MT);
5380 gen_helper_dmfc0_tchalt(arg, cpu_env);
5384 check_insn(ctx, ASE_MT);
5385 gen_helper_dmfc0_tccontext(arg, cpu_env);
5389 check_insn(ctx, ASE_MT);
5390 gen_helper_dmfc0_tcschedule(arg, cpu_env);
5394 check_insn(ctx, ASE_MT);
5395 gen_helper_dmfc0_tcschefback(arg, cpu_env);
5405 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EntryLo1));
5415 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_Context));
5419 // gen_helper_dmfc0_contextconfig(arg); /* SmartMIPS ASE */
5420 rn = "ContextConfig";
5429 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PageMask));
5433 check_insn(ctx, ISA_MIPS32R2);
5434 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PageGrain));
5444 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Wired));
5448 check_insn(ctx, ISA_MIPS32R2);
5449 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf0));
5453 check_insn(ctx, ISA_MIPS32R2);
5454 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf1));
5458 check_insn(ctx, ISA_MIPS32R2);
5459 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf2));
5463 check_insn(ctx, ISA_MIPS32R2);
5464 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf3));
5468 check_insn(ctx, ISA_MIPS32R2);
5469 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf4));
5479 check_insn(ctx, ISA_MIPS32R2);
5480 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_HWREna));
5490 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_BadVAddr));
5500 /* Mark as an IO operation because we read the time. */
5503 gen_helper_mfc0_count(arg, cpu_env);
5507 /* Break the TB to be able to take timer interrupts immediately
5508 after reading count. */
5509 ctx->bstate = BS_STOP;
5512 /* 6,7 are implementation dependent */
5520 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EntryHi));
5530 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Compare));
5533 /* 6,7 are implementation dependent */
5541 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Status));
5545 check_insn(ctx, ISA_MIPS32R2);
5546 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_IntCtl));
5550 check_insn(ctx, ISA_MIPS32R2);
5551 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSCtl));
5555 check_insn(ctx, ISA_MIPS32R2);
5556 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSMap));
5566 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Cause));
5576 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EPC));
5586 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PRid));
5590 check_insn(ctx, ISA_MIPS32R2);
5591 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_EBase));
5601 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config0));
5605 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config1));
5609 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config2));
5613 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config3));
5616 /* 6,7 are implementation dependent */
5618 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config6));
5622 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config7));
5632 gen_helper_dmfc0_lladdr(arg, cpu_env);
5642 gen_helper_1e0i(dmfc0_watchlo, arg, sel);
5652 gen_helper_1e0i(mfc0_watchhi, arg, sel);
5662 check_insn(ctx, ISA_MIPS3);
5663 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_XContext));
5671 /* Officially reserved, but sel 0 is used for R1x000 framemask */
5674 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Framemask));
5682 tcg_gen_movi_tl(arg, 0); /* unimplemented */
5683 rn = "'Diagnostic"; /* implementation dependent */
5688 gen_helper_mfc0_debug(arg, cpu_env); /* EJTAG support */
5692 // gen_helper_dmfc0_tracecontrol(arg, cpu_env); /* PDtrace support */
5693 rn = "TraceControl";
5696 // gen_helper_dmfc0_tracecontrol2(arg, cpu_env); /* PDtrace support */
5697 rn = "TraceControl2";
5700 // gen_helper_dmfc0_usertracedata(arg, cpu_env); /* PDtrace support */
5701 rn = "UserTraceData";
5704 // gen_helper_dmfc0_tracebpc(arg, cpu_env); /* PDtrace support */
5715 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_DEPC));
5725 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Performance0));
5726 rn = "Performance0";
5729 // gen_helper_dmfc0_performance1(arg);
5730 rn = "Performance1";
5733 // gen_helper_dmfc0_performance2(arg);
5734 rn = "Performance2";
5737 // gen_helper_dmfc0_performance3(arg);
5738 rn = "Performance3";
5741 // gen_helper_dmfc0_performance4(arg);
5742 rn = "Performance4";
5745 // gen_helper_dmfc0_performance5(arg);
5746 rn = "Performance5";
5749 // gen_helper_dmfc0_performance6(arg);
5750 rn = "Performance6";
5753 // gen_helper_dmfc0_performance7(arg);
5754 rn = "Performance7";
5761 tcg_gen_movi_tl(arg, 0); /* unimplemented */
5768 tcg_gen_movi_tl(arg, 0); /* unimplemented */
5781 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_TagLo));
5788 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DataLo));
5801 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_TagHi));
5808 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DataHi));
5818 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_ErrorEPC));
5829 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DESAVE));
5839 (void)rn; /* avoid a compiler warning */
5840 LOG_DISAS("dmfc0 %s (reg %d sel %d)\n", rn, reg, sel);
5844 LOG_DISAS("dmfc0 %s (reg %d sel %d)\n", rn, reg, sel);
5845 generate_exception(ctx, EXCP_RI);
5848 static void gen_dmtc0(DisasContext *ctx, TCGv arg, int reg, int sel)
5850 const char *rn = "invalid";
5853 check_insn(ctx, ISA_MIPS64);
5862 gen_helper_mtc0_index(cpu_env, arg);
5866 check_insn(ctx, ASE_MT);
5867 gen_helper_mtc0_mvpcontrol(cpu_env, arg);
5871 check_insn(ctx, ASE_MT);
5876 check_insn(ctx, ASE_MT);
5891 check_insn(ctx, ASE_MT);
5892 gen_helper_mtc0_vpecontrol(cpu_env, arg);
5896 check_insn(ctx, ASE_MT);
5897 gen_helper_mtc0_vpeconf0(cpu_env, arg);
5901 check_insn(ctx, ASE_MT);
5902 gen_helper_mtc0_vpeconf1(cpu_env, arg);
5906 check_insn(ctx, ASE_MT);
5907 gen_helper_mtc0_yqmask(cpu_env, arg);
5911 check_insn(ctx, ASE_MT);
5912 tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_VPESchedule));
5916 check_insn(ctx, ASE_MT);
5917 tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_VPEScheFBack));
5918 rn = "VPEScheFBack";
5921 check_insn(ctx, ASE_MT);
5922 gen_helper_mtc0_vpeopt(cpu_env, arg);
5932 gen_helper_mtc0_entrylo0(cpu_env, arg);
5936 check_insn(ctx, ASE_MT);
5937 gen_helper_mtc0_tcstatus(cpu_env, arg);
5941 check_insn(ctx, ASE_MT);
5942 gen_helper_mtc0_tcbind(cpu_env, arg);
5946 check_insn(ctx, ASE_MT);
5947 gen_helper_mtc0_tcrestart(cpu_env, arg);
5951 check_insn(ctx, ASE_MT);
5952 gen_helper_mtc0_tchalt(cpu_env, arg);
5956 check_insn(ctx, ASE_MT);
5957 gen_helper_mtc0_tccontext(cpu_env, arg);
5961 check_insn(ctx, ASE_MT);
5962 gen_helper_mtc0_tcschedule(cpu_env, arg);
5966 check_insn(ctx, ASE_MT);
5967 gen_helper_mtc0_tcschefback(cpu_env, arg);
5977 gen_helper_mtc0_entrylo1(cpu_env, arg);
5987 gen_helper_mtc0_context(cpu_env, arg);
5991 // gen_helper_mtc0_contextconfig(cpu_env, arg); /* SmartMIPS ASE */
5992 rn = "ContextConfig";
6001 gen_helper_mtc0_pagemask(cpu_env, arg);
6005 check_insn(ctx, ISA_MIPS32R2);
6006 gen_helper_mtc0_pagegrain(cpu_env, arg);
6016 gen_helper_mtc0_wired(cpu_env, arg);
6020 check_insn(ctx, ISA_MIPS32R2);
6021 gen_helper_mtc0_srsconf0(cpu_env, arg);
6025 check_insn(ctx, ISA_MIPS32R2);
6026 gen_helper_mtc0_srsconf1(cpu_env, arg);
6030 check_insn(ctx, ISA_MIPS32R2);
6031 gen_helper_mtc0_srsconf2(cpu_env, arg);
6035 check_insn(ctx, ISA_MIPS32R2);
6036 gen_helper_mtc0_srsconf3(cpu_env, arg);
6040 check_insn(ctx, ISA_MIPS32R2);
6041 gen_helper_mtc0_srsconf4(cpu_env, arg);
6051 check_insn(ctx, ISA_MIPS32R2);
6052 gen_helper_mtc0_hwrena(cpu_env, arg);
6066 gen_helper_mtc0_count(cpu_env, arg);
6069 /* 6,7 are implementation dependent */
6073 /* Stop translation as we may have switched the execution mode */
6074 ctx->bstate = BS_STOP;
6079 gen_helper_mtc0_entryhi(cpu_env, arg);
6089 gen_helper_mtc0_compare(cpu_env, arg);
6092 /* 6,7 are implementation dependent */
6096 /* Stop translation as we may have switched the execution mode */
6097 ctx->bstate = BS_STOP;
6102 save_cpu_state(ctx, 1);
6103 gen_helper_mtc0_status(cpu_env, arg);
6104 /* BS_STOP isn't good enough here, hflags may have changed. */
6105 gen_save_pc(ctx->pc + 4);
6106 ctx->bstate = BS_EXCP;
6110 check_insn(ctx, ISA_MIPS32R2);
6111 gen_helper_mtc0_intctl(cpu_env, arg);
6112 /* Stop translation as we may have switched the execution mode */
6113 ctx->bstate = BS_STOP;
6117 check_insn(ctx, ISA_MIPS32R2);
6118 gen_helper_mtc0_srsctl(cpu_env, arg);
6119 /* Stop translation as we may have switched the execution mode */
6120 ctx->bstate = BS_STOP;
6124 check_insn(ctx, ISA_MIPS32R2);
6125 gen_mtc0_store32(arg, offsetof(CPUMIPSState, CP0_SRSMap));
6126 /* Stop translation as we may have switched the execution mode */
6127 ctx->bstate = BS_STOP;
6137 save_cpu_state(ctx, 1);
6138 /* Mark as an IO operation because we may trigger a software
6143 gen_helper_mtc0_cause(cpu_env, arg);
6147 /* Stop translation as we may have triggered an intetrupt */
6148 ctx->bstate = BS_STOP;
6158 tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EPC));
6172 check_insn(ctx, ISA_MIPS32R2);
6173 gen_helper_mtc0_ebase(cpu_env, arg);
6183 gen_helper_mtc0_config0(cpu_env, arg);
6185 /* Stop translation as we may have switched the execution mode */
6186 ctx->bstate = BS_STOP;
6189 /* ignored, read only */
6193 gen_helper_mtc0_config2(cpu_env, arg);
6195 /* Stop translation as we may have switched the execution mode */
6196 ctx->bstate = BS_STOP;
6202 /* 6,7 are implementation dependent */
6204 rn = "Invalid config selector";
6211 gen_helper_mtc0_lladdr(cpu_env, arg);
6221 gen_helper_0e1i(mtc0_watchlo, arg, sel);
6231 gen_helper_0e1i(mtc0_watchhi, arg, sel);
6241 check_insn(ctx, ISA_MIPS3);
6242 gen_helper_mtc0_xcontext(cpu_env, arg);
6250 /* Officially reserved, but sel 0 is used for R1x000 framemask */
6253 gen_helper_mtc0_framemask(cpu_env, arg);
6262 rn = "Diagnostic"; /* implementation dependent */
6267 gen_helper_mtc0_debug(cpu_env, arg); /* EJTAG support */
6268 /* BS_STOP isn't good enough here, hflags may have changed. */
6269 gen_save_pc(ctx->pc + 4);
6270 ctx->bstate = BS_EXCP;
6274 // gen_helper_mtc0_tracecontrol(cpu_env, arg); /* PDtrace support */
6275 /* Stop translation as we may have switched the execution mode */
6276 ctx->bstate = BS_STOP;
6277 rn = "TraceControl";
6280 // gen_helper_mtc0_tracecontrol2(cpu_env, arg); /* PDtrace support */
6281 /* Stop translation as we may have switched the execution mode */
6282 ctx->bstate = BS_STOP;
6283 rn = "TraceControl2";
6286 // gen_helper_mtc0_usertracedata(cpu_env, arg); /* PDtrace support */
6287 /* Stop translation as we may have switched the execution mode */
6288 ctx->bstate = BS_STOP;
6289 rn = "UserTraceData";
6292 // gen_helper_mtc0_tracebpc(cpu_env, arg); /* PDtrace support */
6293 /* Stop translation as we may have switched the execution mode */
6294 ctx->bstate = BS_STOP;
6305 tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_DEPC));
6315 gen_helper_mtc0_performance0(cpu_env, arg);
6316 rn = "Performance0";
6319 // gen_helper_mtc0_performance1(cpu_env, arg);
6320 rn = "Performance1";
6323 // gen_helper_mtc0_performance2(cpu_env, arg);
6324 rn = "Performance2";
6327 // gen_helper_mtc0_performance3(cpu_env, arg);
6328 rn = "Performance3";
6331 // gen_helper_mtc0_performance4(cpu_env, arg);
6332 rn = "Performance4";
6335 // gen_helper_mtc0_performance5(cpu_env, arg);
6336 rn = "Performance5";
6339 // gen_helper_mtc0_performance6(cpu_env, arg);
6340 rn = "Performance6";
6343 // gen_helper_mtc0_performance7(cpu_env, arg);
6344 rn = "Performance7";
6370 gen_helper_mtc0_taglo(cpu_env, arg);
6377 gen_helper_mtc0_datalo(cpu_env, arg);
6390 gen_helper_mtc0_taghi(cpu_env, arg);
6397 gen_helper_mtc0_datahi(cpu_env, arg);
6408 tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_ErrorEPC));
6419 gen_mtc0_store32(arg, offsetof(CPUMIPSState, CP0_DESAVE));
6425 /* Stop translation as we may have switched the execution mode */
6426 ctx->bstate = BS_STOP;
6431 (void)rn; /* avoid a compiler warning */
6432 LOG_DISAS("dmtc0 %s (reg %d sel %d)\n", rn, reg, sel);
6433 /* For simplicity assume that all writes can cause interrupts. */
6436 ctx->bstate = BS_STOP;
6441 LOG_DISAS("dmtc0 %s (reg %d sel %d)\n", rn, reg, sel);
6442 generate_exception(ctx, EXCP_RI);
6444 #endif /* TARGET_MIPS64 */
6446 static void gen_mftr(CPUMIPSState *env, DisasContext *ctx, int rt, int rd,
6447 int u, int sel, int h)
6449 int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
6450 TCGv t0 = tcg_temp_local_new();
6452 if ((env->CP0_VPEConf0 & (1 << CP0VPEC0_MVP)) == 0 &&
6453 ((env->tcs[other_tc].CP0_TCBind & (0xf << CP0TCBd_CurVPE)) !=
6454 (env->active_tc.CP0_TCBind & (0xf << CP0TCBd_CurVPE))))
6455 tcg_gen_movi_tl(t0, -1);
6456 else if ((env->CP0_VPEControl & (0xff << CP0VPECo_TargTC)) >
6457 (env->mvp->CP0_MVPConf0 & (0xff << CP0MVPC0_PTC)))
6458 tcg_gen_movi_tl(t0, -1);
6464 gen_helper_mftc0_vpecontrol(t0, cpu_env);
6467 gen_helper_mftc0_vpeconf0(t0, cpu_env);
6477 gen_helper_mftc0_tcstatus(t0, cpu_env);
6480 gen_helper_mftc0_tcbind(t0, cpu_env);
6483 gen_helper_mftc0_tcrestart(t0, cpu_env);
6486 gen_helper_mftc0_tchalt(t0, cpu_env);
6489 gen_helper_mftc0_tccontext(t0, cpu_env);
6492 gen_helper_mftc0_tcschedule(t0, cpu_env);
6495 gen_helper_mftc0_tcschefback(t0, cpu_env);
6498 gen_mfc0(ctx, t0, rt, sel);
6505 gen_helper_mftc0_entryhi(t0, cpu_env);
6508 gen_mfc0(ctx, t0, rt, sel);
6514 gen_helper_mftc0_status(t0, cpu_env);
6517 gen_mfc0(ctx, t0, rt, sel);
6523 gen_helper_mftc0_cause(t0, cpu_env);
6533 gen_helper_mftc0_epc(t0, cpu_env);
6543 gen_helper_mftc0_ebase(t0, cpu_env);
6553 gen_helper_mftc0_configx(t0, cpu_env, tcg_const_tl(sel));
6563 gen_helper_mftc0_debug(t0, cpu_env);
6566 gen_mfc0(ctx, t0, rt, sel);
6571 gen_mfc0(ctx, t0, rt, sel);
6573 } else switch (sel) {
6574 /* GPR registers. */
6576 gen_helper_1e0i(mftgpr, t0, rt);
6578 /* Auxiliary CPU registers */
6582 gen_helper_1e0i(mftlo, t0, 0);
6585 gen_helper_1e0i(mfthi, t0, 0);
6588 gen_helper_1e0i(mftacx, t0, 0);
6591 gen_helper_1e0i(mftlo, t0, 1);
6594 gen_helper_1e0i(mfthi, t0, 1);
6597 gen_helper_1e0i(mftacx, t0, 1);
6600 gen_helper_1e0i(mftlo, t0, 2);
6603 gen_helper_1e0i(mfthi, t0, 2);
6606 gen_helper_1e0i(mftacx, t0, 2);
6609 gen_helper_1e0i(mftlo, t0, 3);
6612 gen_helper_1e0i(mfthi, t0, 3);
6615 gen_helper_1e0i(mftacx, t0, 3);
6618 gen_helper_mftdsp(t0, cpu_env);
6624 /* Floating point (COP1). */
6626 /* XXX: For now we support only a single FPU context. */
6628 TCGv_i32 fp0 = tcg_temp_new_i32();
6630 gen_load_fpr32(fp0, rt);
6631 tcg_gen_ext_i32_tl(t0, fp0);
6632 tcg_temp_free_i32(fp0);
6634 TCGv_i32 fp0 = tcg_temp_new_i32();
6636 gen_load_fpr32h(fp0, rt);
6637 tcg_gen_ext_i32_tl(t0, fp0);
6638 tcg_temp_free_i32(fp0);
6642 /* XXX: For now we support only a single FPU context. */
6643 gen_helper_1e0i(cfc1, t0, rt);
6645 /* COP2: Not implemented. */
6652 LOG_DISAS("mftr (reg %d u %d sel %d h %d)\n", rt, u, sel, h);
6653 gen_store_gpr(t0, rd);
6659 LOG_DISAS("mftr (reg %d u %d sel %d h %d)\n", rt, u, sel, h);
6660 generate_exception(ctx, EXCP_RI);
6663 static void gen_mttr(CPUMIPSState *env, DisasContext *ctx, int rd, int rt,
6664 int u, int sel, int h)
6666 int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
6667 TCGv t0 = tcg_temp_local_new();
6669 gen_load_gpr(t0, rt);
6670 if ((env->CP0_VPEConf0 & (1 << CP0VPEC0_MVP)) == 0 &&
6671 ((env->tcs[other_tc].CP0_TCBind & (0xf << CP0TCBd_CurVPE)) !=
6672 (env->active_tc.CP0_TCBind & (0xf << CP0TCBd_CurVPE))))
6674 else if ((env->CP0_VPEControl & (0xff << CP0VPECo_TargTC)) >
6675 (env->mvp->CP0_MVPConf0 & (0xff << CP0MVPC0_PTC)))
6682 gen_helper_mttc0_vpecontrol(cpu_env, t0);
6685 gen_helper_mttc0_vpeconf0(cpu_env, t0);
6695 gen_helper_mttc0_tcstatus(cpu_env, t0);
6698 gen_helper_mttc0_tcbind(cpu_env, t0);
6701 gen_helper_mttc0_tcrestart(cpu_env, t0);
6704 gen_helper_mttc0_tchalt(cpu_env, t0);
6707 gen_helper_mttc0_tccontext(cpu_env, t0);
6710 gen_helper_mttc0_tcschedule(cpu_env, t0);
6713 gen_helper_mttc0_tcschefback(cpu_env, t0);
6716 gen_mtc0(ctx, t0, rd, sel);
6723 gen_helper_mttc0_entryhi(cpu_env, t0);
6726 gen_mtc0(ctx, t0, rd, sel);
6732 gen_helper_mttc0_status(cpu_env, t0);
6735 gen_mtc0(ctx, t0, rd, sel);
6741 gen_helper_mttc0_cause(cpu_env, t0);
6751 gen_helper_mttc0_ebase(cpu_env, t0);
6761 gen_helper_mttc0_debug(cpu_env, t0);
6764 gen_mtc0(ctx, t0, rd, sel);
6769 gen_mtc0(ctx, t0, rd, sel);
6771 } else switch (sel) {
6772 /* GPR registers. */
6774 gen_helper_0e1i(mttgpr, t0, rd);
6776 /* Auxiliary CPU registers */
6780 gen_helper_0e1i(mttlo, t0, 0);
6783 gen_helper_0e1i(mtthi, t0, 0);
6786 gen_helper_0e1i(mttacx, t0, 0);
6789 gen_helper_0e1i(mttlo, t0, 1);
6792 gen_helper_0e1i(mtthi, t0, 1);
6795 gen_helper_0e1i(mttacx, t0, 1);
6798 gen_helper_0e1i(mttlo, t0, 2);
6801 gen_helper_0e1i(mtthi, t0, 2);
6804 gen_helper_0e1i(mttacx, t0, 2);
6807 gen_helper_0e1i(mttlo, t0, 3);
6810 gen_helper_0e1i(mtthi, t0, 3);
6813 gen_helper_0e1i(mttacx, t0, 3);
6816 gen_helper_mttdsp(cpu_env, t0);
6822 /* Floating point (COP1). */
6824 /* XXX: For now we support only a single FPU context. */
6826 TCGv_i32 fp0 = tcg_temp_new_i32();
6828 tcg_gen_trunc_tl_i32(fp0, t0);
6829 gen_store_fpr32(fp0, rd);
6830 tcg_temp_free_i32(fp0);
6832 TCGv_i32 fp0 = tcg_temp_new_i32();
6834 tcg_gen_trunc_tl_i32(fp0, t0);
6835 gen_store_fpr32h(fp0, rd);
6836 tcg_temp_free_i32(fp0);
6840 /* XXX: For now we support only a single FPU context. */
6841 gen_helper_0e1i(ctc1, t0, rd);
6843 /* COP2: Not implemented. */
6850 LOG_DISAS("mttr (reg %d u %d sel %d h %d)\n", rd, u, sel, h);
6856 LOG_DISAS("mttr (reg %d u %d sel %d h %d)\n", rd, u, sel, h);
6857 generate_exception(ctx, EXCP_RI);
6860 static void gen_cp0 (CPUMIPSState *env, DisasContext *ctx, uint32_t opc, int rt, int rd)
6862 const char *opn = "ldst";
6864 check_cp0_enabled(ctx);
6871 gen_mfc0(ctx, cpu_gpr[rt], rd, ctx->opcode & 0x7);
6876 TCGv t0 = tcg_temp_new();
6878 gen_load_gpr(t0, rt);
6879 gen_mtc0(ctx, t0, rd, ctx->opcode & 0x7);
6884 #if defined(TARGET_MIPS64)
6886 check_insn(ctx, ISA_MIPS3);
6891 gen_dmfc0(ctx, cpu_gpr[rt], rd, ctx->opcode & 0x7);
6895 check_insn(ctx, ISA_MIPS3);
6897 TCGv t0 = tcg_temp_new();
6899 gen_load_gpr(t0, rt);
6900 gen_dmtc0(ctx, t0, rd, ctx->opcode & 0x7);
6907 check_insn(ctx, ASE_MT);
6912 gen_mftr(env, ctx, rt, rd, (ctx->opcode >> 5) & 1,
6913 ctx->opcode & 0x7, (ctx->opcode >> 4) & 1);
6917 check_insn(ctx, ASE_MT);
6918 gen_mttr(env, ctx, rd, rt, (ctx->opcode >> 5) & 1,
6919 ctx->opcode & 0x7, (ctx->opcode >> 4) & 1);
6924 if (!env->tlb->helper_tlbwi)
6926 gen_helper_tlbwi(cpu_env);
6930 if (!env->tlb->helper_tlbwr)
6932 gen_helper_tlbwr(cpu_env);
6936 if (!env->tlb->helper_tlbp)
6938 gen_helper_tlbp(cpu_env);
6942 if (!env->tlb->helper_tlbr)
6944 gen_helper_tlbr(cpu_env);
6948 check_insn(ctx, ISA_MIPS2);
6949 gen_helper_eret(cpu_env);
6950 ctx->bstate = BS_EXCP;
6954 check_insn(ctx, ISA_MIPS32);
6955 if (!(ctx->hflags & MIPS_HFLAG_DM)) {
6957 generate_exception(ctx, EXCP_RI);
6959 gen_helper_deret(cpu_env);
6960 ctx->bstate = BS_EXCP;
6965 check_insn(ctx, ISA_MIPS3 | ISA_MIPS32);
6966 /* If we get an exception, we want to restart at next instruction */
6968 save_cpu_state(ctx, 1);
6970 gen_helper_wait(cpu_env);
6971 ctx->bstate = BS_EXCP;
6976 generate_exception(ctx, EXCP_RI);
6979 (void)opn; /* avoid a compiler warning */
6980 MIPS_DEBUG("%s %s %d", opn, regnames[rt], rd);
6982 #endif /* !CONFIG_USER_ONLY */
6984 /* CP1 Branches (before delay slot) */
6985 static void gen_compute_branch1(DisasContext *ctx, uint32_t op,
6986 int32_t cc, int32_t offset)
6988 target_ulong btarget;
6989 const char *opn = "cp1 cond branch";
6990 TCGv_i32 t0 = tcg_temp_new_i32();
6993 check_insn(ctx, ISA_MIPS4 | ISA_MIPS32);
6995 btarget = ctx->pc + 4 + offset;
6999 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
7000 tcg_gen_not_i32(t0, t0);
7001 tcg_gen_andi_i32(t0, t0, 1);
7002 tcg_gen_extu_i32_tl(bcond, t0);
7006 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
7007 tcg_gen_not_i32(t0, t0);
7008 tcg_gen_andi_i32(t0, t0, 1);
7009 tcg_gen_extu_i32_tl(bcond, t0);
7013 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
7014 tcg_gen_andi_i32(t0, t0, 1);
7015 tcg_gen_extu_i32_tl(bcond, t0);
7019 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
7020 tcg_gen_andi_i32(t0, t0, 1);
7021 tcg_gen_extu_i32_tl(bcond, t0);
7024 ctx->hflags |= MIPS_HFLAG_BL;
7028 TCGv_i32 t1 = tcg_temp_new_i32();
7029 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
7030 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+1));
7031 tcg_gen_nand_i32(t0, t0, t1);
7032 tcg_temp_free_i32(t1);
7033 tcg_gen_andi_i32(t0, t0, 1);
7034 tcg_gen_extu_i32_tl(bcond, t0);
7040 TCGv_i32 t1 = tcg_temp_new_i32();
7041 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
7042 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+1));
7043 tcg_gen_or_i32(t0, t0, t1);
7044 tcg_temp_free_i32(t1);
7045 tcg_gen_andi_i32(t0, t0, 1);
7046 tcg_gen_extu_i32_tl(bcond, t0);
7052 TCGv_i32 t1 = tcg_temp_new_i32();
7053 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
7054 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+1));
7055 tcg_gen_and_i32(t0, t0, t1);
7056 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+2));
7057 tcg_gen_and_i32(t0, t0, t1);
7058 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+3));
7059 tcg_gen_nand_i32(t0, t0, t1);
7060 tcg_temp_free_i32(t1);
7061 tcg_gen_andi_i32(t0, t0, 1);
7062 tcg_gen_extu_i32_tl(bcond, t0);
7068 TCGv_i32 t1 = tcg_temp_new_i32();
7069 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
7070 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+1));
7071 tcg_gen_or_i32(t0, t0, t1);
7072 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+2));
7073 tcg_gen_or_i32(t0, t0, t1);
7074 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+3));
7075 tcg_gen_or_i32(t0, t0, t1);
7076 tcg_temp_free_i32(t1);
7077 tcg_gen_andi_i32(t0, t0, 1);
7078 tcg_gen_extu_i32_tl(bcond, t0);
7082 ctx->hflags |= MIPS_HFLAG_BC;
7086 generate_exception (ctx, EXCP_RI);
7089 (void)opn; /* avoid a compiler warning */
7090 MIPS_DEBUG("%s: cond %02x target " TARGET_FMT_lx, opn,
7091 ctx->hflags, btarget);
7092 ctx->btarget = btarget;
7095 tcg_temp_free_i32(t0);
7098 /* Coprocessor 1 (FPU) */
7100 #define FOP(func, fmt) (((fmt) << 21) | (func))
7103 OPC_ADD_S = FOP(0, FMT_S),
7104 OPC_SUB_S = FOP(1, FMT_S),
7105 OPC_MUL_S = FOP(2, FMT_S),
7106 OPC_DIV_S = FOP(3, FMT_S),
7107 OPC_SQRT_S = FOP(4, FMT_S),
7108 OPC_ABS_S = FOP(5, FMT_S),
7109 OPC_MOV_S = FOP(6, FMT_S),
7110 OPC_NEG_S = FOP(7, FMT_S),
7111 OPC_ROUND_L_S = FOP(8, FMT_S),
7112 OPC_TRUNC_L_S = FOP(9, FMT_S),
7113 OPC_CEIL_L_S = FOP(10, FMT_S),
7114 OPC_FLOOR_L_S = FOP(11, FMT_S),
7115 OPC_ROUND_W_S = FOP(12, FMT_S),
7116 OPC_TRUNC_W_S = FOP(13, FMT_S),
7117 OPC_CEIL_W_S = FOP(14, FMT_S),
7118 OPC_FLOOR_W_S = FOP(15, FMT_S),
7119 OPC_MOVCF_S = FOP(17, FMT_S),
7120 OPC_MOVZ_S = FOP(18, FMT_S),
7121 OPC_MOVN_S = FOP(19, FMT_S),
7122 OPC_RECIP_S = FOP(21, FMT_S),
7123 OPC_RSQRT_S = FOP(22, FMT_S),
7124 OPC_RECIP2_S = FOP(28, FMT_S),
7125 OPC_RECIP1_S = FOP(29, FMT_S),
7126 OPC_RSQRT1_S = FOP(30, FMT_S),
7127 OPC_RSQRT2_S = FOP(31, FMT_S),
7128 OPC_CVT_D_S = FOP(33, FMT_S),
7129 OPC_CVT_W_S = FOP(36, FMT_S),
7130 OPC_CVT_L_S = FOP(37, FMT_S),
7131 OPC_CVT_PS_S = FOP(38, FMT_S),
7132 OPC_CMP_F_S = FOP (48, FMT_S),
7133 OPC_CMP_UN_S = FOP (49, FMT_S),
7134 OPC_CMP_EQ_S = FOP (50, FMT_S),
7135 OPC_CMP_UEQ_S = FOP (51, FMT_S),
7136 OPC_CMP_OLT_S = FOP (52, FMT_S),
7137 OPC_CMP_ULT_S = FOP (53, FMT_S),
7138 OPC_CMP_OLE_S = FOP (54, FMT_S),
7139 OPC_CMP_ULE_S = FOP (55, FMT_S),
7140 OPC_CMP_SF_S = FOP (56, FMT_S),
7141 OPC_CMP_NGLE_S = FOP (57, FMT_S),
7142 OPC_CMP_SEQ_S = FOP (58, FMT_S),
7143 OPC_CMP_NGL_S = FOP (59, FMT_S),
7144 OPC_CMP_LT_S = FOP (60, FMT_S),
7145 OPC_CMP_NGE_S = FOP (61, FMT_S),
7146 OPC_CMP_LE_S = FOP (62, FMT_S),
7147 OPC_CMP_NGT_S = FOP (63, FMT_S),
7149 OPC_ADD_D = FOP(0, FMT_D),
7150 OPC_SUB_D = FOP(1, FMT_D),
7151 OPC_MUL_D = FOP(2, FMT_D),
7152 OPC_DIV_D = FOP(3, FMT_D),
7153 OPC_SQRT_D = FOP(4, FMT_D),
7154 OPC_ABS_D = FOP(5, FMT_D),
7155 OPC_MOV_D = FOP(6, FMT_D),
7156 OPC_NEG_D = FOP(7, FMT_D),
7157 OPC_ROUND_L_D = FOP(8, FMT_D),
7158 OPC_TRUNC_L_D = FOP(9, FMT_D),
7159 OPC_CEIL_L_D = FOP(10, FMT_D),
7160 OPC_FLOOR_L_D = FOP(11, FMT_D),
7161 OPC_ROUND_W_D = FOP(12, FMT_D),
7162 OPC_TRUNC_W_D = FOP(13, FMT_D),
7163 OPC_CEIL_W_D = FOP(14, FMT_D),
7164 OPC_FLOOR_W_D = FOP(15, FMT_D),
7165 OPC_MOVCF_D = FOP(17, FMT_D),
7166 OPC_MOVZ_D = FOP(18, FMT_D),
7167 OPC_MOVN_D = FOP(19, FMT_D),
7168 OPC_RECIP_D = FOP(21, FMT_D),
7169 OPC_RSQRT_D = FOP(22, FMT_D),
7170 OPC_RECIP2_D = FOP(28, FMT_D),
7171 OPC_RECIP1_D = FOP(29, FMT_D),
7172 OPC_RSQRT1_D = FOP(30, FMT_D),
7173 OPC_RSQRT2_D = FOP(31, FMT_D),
7174 OPC_CVT_S_D = FOP(32, FMT_D),
7175 OPC_CVT_W_D = FOP(36, FMT_D),
7176 OPC_CVT_L_D = FOP(37, FMT_D),
7177 OPC_CMP_F_D = FOP (48, FMT_D),
7178 OPC_CMP_UN_D = FOP (49, FMT_D),
7179 OPC_CMP_EQ_D = FOP (50, FMT_D),
7180 OPC_CMP_UEQ_D = FOP (51, FMT_D),
7181 OPC_CMP_OLT_D = FOP (52, FMT_D),
7182 OPC_CMP_ULT_D = FOP (53, FMT_D),
7183 OPC_CMP_OLE_D = FOP (54, FMT_D),
7184 OPC_CMP_ULE_D = FOP (55, FMT_D),
7185 OPC_CMP_SF_D = FOP (56, FMT_D),
7186 OPC_CMP_NGLE_D = FOP (57, FMT_D),
7187 OPC_CMP_SEQ_D = FOP (58, FMT_D),
7188 OPC_CMP_NGL_D = FOP (59, FMT_D),
7189 OPC_CMP_LT_D = FOP (60, FMT_D),
7190 OPC_CMP_NGE_D = FOP (61, FMT_D),
7191 OPC_CMP_LE_D = FOP (62, FMT_D),
7192 OPC_CMP_NGT_D = FOP (63, FMT_D),
7194 OPC_CVT_S_W = FOP(32, FMT_W),
7195 OPC_CVT_D_W = FOP(33, FMT_W),
7196 OPC_CVT_S_L = FOP(32, FMT_L),
7197 OPC_CVT_D_L = FOP(33, FMT_L),
7198 OPC_CVT_PS_PW = FOP(38, FMT_W),
7200 OPC_ADD_PS = FOP(0, FMT_PS),
7201 OPC_SUB_PS = FOP(1, FMT_PS),
7202 OPC_MUL_PS = FOP(2, FMT_PS),
7203 OPC_DIV_PS = FOP(3, FMT_PS),
7204 OPC_ABS_PS = FOP(5, FMT_PS),
7205 OPC_MOV_PS = FOP(6, FMT_PS),
7206 OPC_NEG_PS = FOP(7, FMT_PS),
7207 OPC_MOVCF_PS = FOP(17, FMT_PS),
7208 OPC_MOVZ_PS = FOP(18, FMT_PS),
7209 OPC_MOVN_PS = FOP(19, FMT_PS),
7210 OPC_ADDR_PS = FOP(24, FMT_PS),
7211 OPC_MULR_PS = FOP(26, FMT_PS),
7212 OPC_RECIP2_PS = FOP(28, FMT_PS),
7213 OPC_RECIP1_PS = FOP(29, FMT_PS),
7214 OPC_RSQRT1_PS = FOP(30, FMT_PS),
7215 OPC_RSQRT2_PS = FOP(31, FMT_PS),
7217 OPC_CVT_S_PU = FOP(32, FMT_PS),
7218 OPC_CVT_PW_PS = FOP(36, FMT_PS),
7219 OPC_CVT_S_PL = FOP(40, FMT_PS),
7220 OPC_PLL_PS = FOP(44, FMT_PS),
7221 OPC_PLU_PS = FOP(45, FMT_PS),
7222 OPC_PUL_PS = FOP(46, FMT_PS),
7223 OPC_PUU_PS = FOP(47, FMT_PS),
7224 OPC_CMP_F_PS = FOP (48, FMT_PS),
7225 OPC_CMP_UN_PS = FOP (49, FMT_PS),
7226 OPC_CMP_EQ_PS = FOP (50, FMT_PS),
7227 OPC_CMP_UEQ_PS = FOP (51, FMT_PS),
7228 OPC_CMP_OLT_PS = FOP (52, FMT_PS),
7229 OPC_CMP_ULT_PS = FOP (53, FMT_PS),
7230 OPC_CMP_OLE_PS = FOP (54, FMT_PS),
7231 OPC_CMP_ULE_PS = FOP (55, FMT_PS),
7232 OPC_CMP_SF_PS = FOP (56, FMT_PS),
7233 OPC_CMP_NGLE_PS = FOP (57, FMT_PS),
7234 OPC_CMP_SEQ_PS = FOP (58, FMT_PS),
7235 OPC_CMP_NGL_PS = FOP (59, FMT_PS),
7236 OPC_CMP_LT_PS = FOP (60, FMT_PS),
7237 OPC_CMP_NGE_PS = FOP (61, FMT_PS),
7238 OPC_CMP_LE_PS = FOP (62, FMT_PS),
7239 OPC_CMP_NGT_PS = FOP (63, FMT_PS),
7242 static void gen_cp1 (DisasContext *ctx, uint32_t opc, int rt, int fs)
7244 const char *opn = "cp1 move";
7245 TCGv t0 = tcg_temp_new();
7250 TCGv_i32 fp0 = tcg_temp_new_i32();
7252 gen_load_fpr32(fp0, fs);
7253 tcg_gen_ext_i32_tl(t0, fp0);
7254 tcg_temp_free_i32(fp0);
7256 gen_store_gpr(t0, rt);
7260 gen_load_gpr(t0, rt);
7262 TCGv_i32 fp0 = tcg_temp_new_i32();
7264 tcg_gen_trunc_tl_i32(fp0, t0);
7265 gen_store_fpr32(fp0, fs);
7266 tcg_temp_free_i32(fp0);
7271 gen_helper_1e0i(cfc1, t0, fs);
7272 gen_store_gpr(t0, rt);
7276 gen_load_gpr(t0, rt);
7277 gen_helper_0e1i(ctc1, t0, fs);
7280 #if defined(TARGET_MIPS64)
7282 gen_load_fpr64(ctx, t0, fs);
7283 gen_store_gpr(t0, rt);
7287 gen_load_gpr(t0, rt);
7288 gen_store_fpr64(ctx, t0, fs);
7294 TCGv_i32 fp0 = tcg_temp_new_i32();
7296 gen_load_fpr32h(fp0, fs);
7297 tcg_gen_ext_i32_tl(t0, fp0);
7298 tcg_temp_free_i32(fp0);
7300 gen_store_gpr(t0, rt);
7304 gen_load_gpr(t0, rt);
7306 TCGv_i32 fp0 = tcg_temp_new_i32();
7308 tcg_gen_trunc_tl_i32(fp0, t0);
7309 gen_store_fpr32h(fp0, fs);
7310 tcg_temp_free_i32(fp0);
7316 generate_exception (ctx, EXCP_RI);
7319 (void)opn; /* avoid a compiler warning */
7320 MIPS_DEBUG("%s %s %s", opn, regnames[rt], fregnames[fs]);
7326 static void gen_movci (DisasContext *ctx, int rd, int rs, int cc, int tf)
7342 l1 = gen_new_label();
7343 t0 = tcg_temp_new_i32();
7344 tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc));
7345 tcg_gen_brcondi_i32(cond, t0, 0, l1);
7346 tcg_temp_free_i32(t0);
7348 tcg_gen_movi_tl(cpu_gpr[rd], 0);
7350 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
7355 static inline void gen_movcf_s (int fs, int fd, int cc, int tf)
7358 TCGv_i32 t0 = tcg_temp_new_i32();
7359 int l1 = gen_new_label();
7366 tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc));
7367 tcg_gen_brcondi_i32(cond, t0, 0, l1);
7368 gen_load_fpr32(t0, fs);
7369 gen_store_fpr32(t0, fd);
7371 tcg_temp_free_i32(t0);
7374 static inline void gen_movcf_d (DisasContext *ctx, int fs, int fd, int cc, int tf)
7377 TCGv_i32 t0 = tcg_temp_new_i32();
7379 int l1 = gen_new_label();
7386 tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc));
7387 tcg_gen_brcondi_i32(cond, t0, 0, l1);
7388 tcg_temp_free_i32(t0);
7389 fp0 = tcg_temp_new_i64();
7390 gen_load_fpr64(ctx, fp0, fs);
7391 gen_store_fpr64(ctx, fp0, fd);
7392 tcg_temp_free_i64(fp0);
7396 static inline void gen_movcf_ps (int fs, int fd, int cc, int tf)
7399 TCGv_i32 t0 = tcg_temp_new_i32();
7400 int l1 = gen_new_label();
7401 int l2 = gen_new_label();
7408 tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc));
7409 tcg_gen_brcondi_i32(cond, t0, 0, l1);
7410 gen_load_fpr32(t0, fs);
7411 gen_store_fpr32(t0, fd);
7414 tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc+1));
7415 tcg_gen_brcondi_i32(cond, t0, 0, l2);
7416 gen_load_fpr32h(t0, fs);
7417 gen_store_fpr32h(t0, fd);
7418 tcg_temp_free_i32(t0);
7423 static void gen_farith (DisasContext *ctx, enum fopcode op1,
7424 int ft, int fs, int fd, int cc)
7426 const char *opn = "farith";
7427 const char *condnames[] = {
7445 const char *condnames_abs[] = {
7463 enum { BINOP, CMPOP, OTHEROP } optype = OTHEROP;
7464 uint32_t func = ctx->opcode & 0x3f;
7469 TCGv_i32 fp0 = tcg_temp_new_i32();
7470 TCGv_i32 fp1 = tcg_temp_new_i32();
7472 gen_load_fpr32(fp0, fs);
7473 gen_load_fpr32(fp1, ft);
7474 gen_helper_float_add_s(fp0, cpu_env, fp0, fp1);
7475 tcg_temp_free_i32(fp1);
7476 gen_store_fpr32(fp0, fd);
7477 tcg_temp_free_i32(fp0);
7484 TCGv_i32 fp0 = tcg_temp_new_i32();
7485 TCGv_i32 fp1 = tcg_temp_new_i32();
7487 gen_load_fpr32(fp0, fs);
7488 gen_load_fpr32(fp1, ft);
7489 gen_helper_float_sub_s(fp0, cpu_env, fp0, fp1);
7490 tcg_temp_free_i32(fp1);
7491 gen_store_fpr32(fp0, fd);
7492 tcg_temp_free_i32(fp0);
7499 TCGv_i32 fp0 = tcg_temp_new_i32();
7500 TCGv_i32 fp1 = tcg_temp_new_i32();
7502 gen_load_fpr32(fp0, fs);
7503 gen_load_fpr32(fp1, ft);
7504 gen_helper_float_mul_s(fp0, cpu_env, fp0, fp1);
7505 tcg_temp_free_i32(fp1);
7506 gen_store_fpr32(fp0, fd);
7507 tcg_temp_free_i32(fp0);
7514 TCGv_i32 fp0 = tcg_temp_new_i32();
7515 TCGv_i32 fp1 = tcg_temp_new_i32();
7517 gen_load_fpr32(fp0, fs);
7518 gen_load_fpr32(fp1, ft);
7519 gen_helper_float_div_s(fp0, cpu_env, fp0, fp1);
7520 tcg_temp_free_i32(fp1);
7521 gen_store_fpr32(fp0, fd);
7522 tcg_temp_free_i32(fp0);
7529 TCGv_i32 fp0 = tcg_temp_new_i32();
7531 gen_load_fpr32(fp0, fs);
7532 gen_helper_float_sqrt_s(fp0, cpu_env, fp0);
7533 gen_store_fpr32(fp0, fd);
7534 tcg_temp_free_i32(fp0);
7540 TCGv_i32 fp0 = tcg_temp_new_i32();
7542 gen_load_fpr32(fp0, fs);
7543 gen_helper_float_abs_s(fp0, fp0);
7544 gen_store_fpr32(fp0, fd);
7545 tcg_temp_free_i32(fp0);
7551 TCGv_i32 fp0 = tcg_temp_new_i32();
7553 gen_load_fpr32(fp0, fs);
7554 gen_store_fpr32(fp0, fd);
7555 tcg_temp_free_i32(fp0);
7561 TCGv_i32 fp0 = tcg_temp_new_i32();
7563 gen_load_fpr32(fp0, fs);
7564 gen_helper_float_chs_s(fp0, fp0);
7565 gen_store_fpr32(fp0, fd);
7566 tcg_temp_free_i32(fp0);
7571 check_cp1_64bitmode(ctx);
7573 TCGv_i32 fp32 = tcg_temp_new_i32();
7574 TCGv_i64 fp64 = tcg_temp_new_i64();
7576 gen_load_fpr32(fp32, fs);
7577 gen_helper_float_roundl_s(fp64, cpu_env, fp32);
7578 tcg_temp_free_i32(fp32);
7579 gen_store_fpr64(ctx, fp64, fd);
7580 tcg_temp_free_i64(fp64);
7585 check_cp1_64bitmode(ctx);
7587 TCGv_i32 fp32 = tcg_temp_new_i32();
7588 TCGv_i64 fp64 = tcg_temp_new_i64();
7590 gen_load_fpr32(fp32, fs);
7591 gen_helper_float_truncl_s(fp64, cpu_env, fp32);
7592 tcg_temp_free_i32(fp32);
7593 gen_store_fpr64(ctx, fp64, fd);
7594 tcg_temp_free_i64(fp64);
7599 check_cp1_64bitmode(ctx);
7601 TCGv_i32 fp32 = tcg_temp_new_i32();
7602 TCGv_i64 fp64 = tcg_temp_new_i64();
7604 gen_load_fpr32(fp32, fs);
7605 gen_helper_float_ceill_s(fp64, cpu_env, fp32);
7606 tcg_temp_free_i32(fp32);
7607 gen_store_fpr64(ctx, fp64, fd);
7608 tcg_temp_free_i64(fp64);
7613 check_cp1_64bitmode(ctx);
7615 TCGv_i32 fp32 = tcg_temp_new_i32();
7616 TCGv_i64 fp64 = tcg_temp_new_i64();
7618 gen_load_fpr32(fp32, fs);
7619 gen_helper_float_floorl_s(fp64, cpu_env, fp32);
7620 tcg_temp_free_i32(fp32);
7621 gen_store_fpr64(ctx, fp64, fd);
7622 tcg_temp_free_i64(fp64);
7628 TCGv_i32 fp0 = tcg_temp_new_i32();
7630 gen_load_fpr32(fp0, fs);
7631 gen_helper_float_roundw_s(fp0, cpu_env, fp0);
7632 gen_store_fpr32(fp0, fd);
7633 tcg_temp_free_i32(fp0);
7639 TCGv_i32 fp0 = tcg_temp_new_i32();
7641 gen_load_fpr32(fp0, fs);
7642 gen_helper_float_truncw_s(fp0, cpu_env, fp0);
7643 gen_store_fpr32(fp0, fd);
7644 tcg_temp_free_i32(fp0);
7650 TCGv_i32 fp0 = tcg_temp_new_i32();
7652 gen_load_fpr32(fp0, fs);
7653 gen_helper_float_ceilw_s(fp0, cpu_env, fp0);
7654 gen_store_fpr32(fp0, fd);
7655 tcg_temp_free_i32(fp0);
7661 TCGv_i32 fp0 = tcg_temp_new_i32();
7663 gen_load_fpr32(fp0, fs);
7664 gen_helper_float_floorw_s(fp0, cpu_env, fp0);
7665 gen_store_fpr32(fp0, fd);
7666 tcg_temp_free_i32(fp0);
7671 gen_movcf_s(fs, fd, (ft >> 2) & 0x7, ft & 0x1);
7676 int l1 = gen_new_label();
7680 tcg_gen_brcondi_tl(TCG_COND_NE, cpu_gpr[ft], 0, l1);
7682 fp0 = tcg_temp_new_i32();
7683 gen_load_fpr32(fp0, fs);
7684 gen_store_fpr32(fp0, fd);
7685 tcg_temp_free_i32(fp0);
7692 int l1 = gen_new_label();
7696 tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_gpr[ft], 0, l1);
7697 fp0 = tcg_temp_new_i32();
7698 gen_load_fpr32(fp0, fs);
7699 gen_store_fpr32(fp0, fd);
7700 tcg_temp_free_i32(fp0);
7709 TCGv_i32 fp0 = tcg_temp_new_i32();
7711 gen_load_fpr32(fp0, fs);
7712 gen_helper_float_recip_s(fp0, cpu_env, fp0);
7713 gen_store_fpr32(fp0, fd);
7714 tcg_temp_free_i32(fp0);
7721 TCGv_i32 fp0 = tcg_temp_new_i32();
7723 gen_load_fpr32(fp0, fs);
7724 gen_helper_float_rsqrt_s(fp0, cpu_env, fp0);
7725 gen_store_fpr32(fp0, fd);
7726 tcg_temp_free_i32(fp0);
7731 check_cp1_64bitmode(ctx);
7733 TCGv_i32 fp0 = tcg_temp_new_i32();
7734 TCGv_i32 fp1 = tcg_temp_new_i32();
7736 gen_load_fpr32(fp0, fs);
7737 gen_load_fpr32(fp1, ft);
7738 gen_helper_float_recip2_s(fp0, cpu_env, fp0, fp1);
7739 tcg_temp_free_i32(fp1);
7740 gen_store_fpr32(fp0, fd);
7741 tcg_temp_free_i32(fp0);
7746 check_cp1_64bitmode(ctx);
7748 TCGv_i32 fp0 = tcg_temp_new_i32();
7750 gen_load_fpr32(fp0, fs);
7751 gen_helper_float_recip1_s(fp0, cpu_env, fp0);
7752 gen_store_fpr32(fp0, fd);
7753 tcg_temp_free_i32(fp0);
7758 check_cp1_64bitmode(ctx);
7760 TCGv_i32 fp0 = tcg_temp_new_i32();
7762 gen_load_fpr32(fp0, fs);
7763 gen_helper_float_rsqrt1_s(fp0, cpu_env, fp0);
7764 gen_store_fpr32(fp0, fd);
7765 tcg_temp_free_i32(fp0);
7770 check_cp1_64bitmode(ctx);
7772 TCGv_i32 fp0 = tcg_temp_new_i32();
7773 TCGv_i32 fp1 = tcg_temp_new_i32();
7775 gen_load_fpr32(fp0, fs);
7776 gen_load_fpr32(fp1, ft);
7777 gen_helper_float_rsqrt2_s(fp0, cpu_env, fp0, fp1);
7778 tcg_temp_free_i32(fp1);
7779 gen_store_fpr32(fp0, fd);
7780 tcg_temp_free_i32(fp0);
7785 check_cp1_registers(ctx, fd);
7787 TCGv_i32 fp32 = tcg_temp_new_i32();
7788 TCGv_i64 fp64 = tcg_temp_new_i64();
7790 gen_load_fpr32(fp32, fs);
7791 gen_helper_float_cvtd_s(fp64, cpu_env, fp32);
7792 tcg_temp_free_i32(fp32);
7793 gen_store_fpr64(ctx, fp64, fd);
7794 tcg_temp_free_i64(fp64);
7800 TCGv_i32 fp0 = tcg_temp_new_i32();
7802 gen_load_fpr32(fp0, fs);
7803 gen_helper_float_cvtw_s(fp0, cpu_env, fp0);
7804 gen_store_fpr32(fp0, fd);
7805 tcg_temp_free_i32(fp0);
7810 check_cp1_64bitmode(ctx);
7812 TCGv_i32 fp32 = tcg_temp_new_i32();
7813 TCGv_i64 fp64 = tcg_temp_new_i64();
7815 gen_load_fpr32(fp32, fs);
7816 gen_helper_float_cvtl_s(fp64, cpu_env, fp32);
7817 tcg_temp_free_i32(fp32);
7818 gen_store_fpr64(ctx, fp64, fd);
7819 tcg_temp_free_i64(fp64);
7824 check_cp1_64bitmode(ctx);
7826 TCGv_i64 fp64 = tcg_temp_new_i64();
7827 TCGv_i32 fp32_0 = tcg_temp_new_i32();
7828 TCGv_i32 fp32_1 = tcg_temp_new_i32();
7830 gen_load_fpr32(fp32_0, fs);
7831 gen_load_fpr32(fp32_1, ft);
7832 tcg_gen_concat_i32_i64(fp64, fp32_1, fp32_0);
7833 tcg_temp_free_i32(fp32_1);
7834 tcg_temp_free_i32(fp32_0);
7835 gen_store_fpr64(ctx, fp64, fd);
7836 tcg_temp_free_i64(fp64);
7849 case OPC_CMP_NGLE_S:
7856 if (ctx->opcode & (1 << 6)) {
7857 gen_cmpabs_s(ctx, func-48, ft, fs, cc);
7858 opn = condnames_abs[func-48];
7860 gen_cmp_s(ctx, func-48, ft, fs, cc);
7861 opn = condnames[func-48];
7865 check_cp1_registers(ctx, fs | ft | fd);
7867 TCGv_i64 fp0 = tcg_temp_new_i64();
7868 TCGv_i64 fp1 = tcg_temp_new_i64();
7870 gen_load_fpr64(ctx, fp0, fs);
7871 gen_load_fpr64(ctx, fp1, ft);
7872 gen_helper_float_add_d(fp0, cpu_env, fp0, fp1);
7873 tcg_temp_free_i64(fp1);
7874 gen_store_fpr64(ctx, fp0, fd);
7875 tcg_temp_free_i64(fp0);
7881 check_cp1_registers(ctx, fs | ft | fd);
7883 TCGv_i64 fp0 = tcg_temp_new_i64();
7884 TCGv_i64 fp1 = tcg_temp_new_i64();
7886 gen_load_fpr64(ctx, fp0, fs);
7887 gen_load_fpr64(ctx, fp1, ft);
7888 gen_helper_float_sub_d(fp0, cpu_env, fp0, fp1);
7889 tcg_temp_free_i64(fp1);
7890 gen_store_fpr64(ctx, fp0, fd);
7891 tcg_temp_free_i64(fp0);
7897 check_cp1_registers(ctx, fs | ft | fd);
7899 TCGv_i64 fp0 = tcg_temp_new_i64();
7900 TCGv_i64 fp1 = tcg_temp_new_i64();
7902 gen_load_fpr64(ctx, fp0, fs);
7903 gen_load_fpr64(ctx, fp1, ft);
7904 gen_helper_float_mul_d(fp0, cpu_env, fp0, fp1);
7905 tcg_temp_free_i64(fp1);
7906 gen_store_fpr64(ctx, fp0, fd);
7907 tcg_temp_free_i64(fp0);
7913 check_cp1_registers(ctx, fs | ft | fd);
7915 TCGv_i64 fp0 = tcg_temp_new_i64();
7916 TCGv_i64 fp1 = tcg_temp_new_i64();
7918 gen_load_fpr64(ctx, fp0, fs);
7919 gen_load_fpr64(ctx, fp1, ft);
7920 gen_helper_float_div_d(fp0, cpu_env, fp0, fp1);
7921 tcg_temp_free_i64(fp1);
7922 gen_store_fpr64(ctx, fp0, fd);
7923 tcg_temp_free_i64(fp0);
7929 check_cp1_registers(ctx, fs | fd);
7931 TCGv_i64 fp0 = tcg_temp_new_i64();
7933 gen_load_fpr64(ctx, fp0, fs);
7934 gen_helper_float_sqrt_d(fp0, cpu_env, fp0);
7935 gen_store_fpr64(ctx, fp0, fd);
7936 tcg_temp_free_i64(fp0);
7941 check_cp1_registers(ctx, fs | fd);
7943 TCGv_i64 fp0 = tcg_temp_new_i64();
7945 gen_load_fpr64(ctx, fp0, fs);
7946 gen_helper_float_abs_d(fp0, fp0);
7947 gen_store_fpr64(ctx, fp0, fd);
7948 tcg_temp_free_i64(fp0);
7953 check_cp1_registers(ctx, fs | fd);
7955 TCGv_i64 fp0 = tcg_temp_new_i64();
7957 gen_load_fpr64(ctx, fp0, fs);
7958 gen_store_fpr64(ctx, fp0, fd);
7959 tcg_temp_free_i64(fp0);
7964 check_cp1_registers(ctx, fs | fd);
7966 TCGv_i64 fp0 = tcg_temp_new_i64();
7968 gen_load_fpr64(ctx, fp0, fs);
7969 gen_helper_float_chs_d(fp0, fp0);
7970 gen_store_fpr64(ctx, fp0, fd);
7971 tcg_temp_free_i64(fp0);
7976 check_cp1_64bitmode(ctx);
7978 TCGv_i64 fp0 = tcg_temp_new_i64();
7980 gen_load_fpr64(ctx, fp0, fs);
7981 gen_helper_float_roundl_d(fp0, cpu_env, fp0);
7982 gen_store_fpr64(ctx, fp0, fd);
7983 tcg_temp_free_i64(fp0);
7988 check_cp1_64bitmode(ctx);
7990 TCGv_i64 fp0 = tcg_temp_new_i64();
7992 gen_load_fpr64(ctx, fp0, fs);
7993 gen_helper_float_truncl_d(fp0, cpu_env, fp0);
7994 gen_store_fpr64(ctx, fp0, fd);
7995 tcg_temp_free_i64(fp0);
8000 check_cp1_64bitmode(ctx);
8002 TCGv_i64 fp0 = tcg_temp_new_i64();
8004 gen_load_fpr64(ctx, fp0, fs);
8005 gen_helper_float_ceill_d(fp0, cpu_env, fp0);
8006 gen_store_fpr64(ctx, fp0, fd);
8007 tcg_temp_free_i64(fp0);
8012 check_cp1_64bitmode(ctx);
8014 TCGv_i64 fp0 = tcg_temp_new_i64();
8016 gen_load_fpr64(ctx, fp0, fs);
8017 gen_helper_float_floorl_d(fp0, cpu_env, fp0);
8018 gen_store_fpr64(ctx, fp0, fd);
8019 tcg_temp_free_i64(fp0);
8024 check_cp1_registers(ctx, fs);
8026 TCGv_i32 fp32 = tcg_temp_new_i32();
8027 TCGv_i64 fp64 = tcg_temp_new_i64();
8029 gen_load_fpr64(ctx, fp64, fs);
8030 gen_helper_float_roundw_d(fp32, cpu_env, fp64);
8031 tcg_temp_free_i64(fp64);
8032 gen_store_fpr32(fp32, fd);
8033 tcg_temp_free_i32(fp32);
8038 check_cp1_registers(ctx, fs);
8040 TCGv_i32 fp32 = tcg_temp_new_i32();
8041 TCGv_i64 fp64 = tcg_temp_new_i64();
8043 gen_load_fpr64(ctx, fp64, fs);
8044 gen_helper_float_truncw_d(fp32, cpu_env, fp64);
8045 tcg_temp_free_i64(fp64);
8046 gen_store_fpr32(fp32, fd);
8047 tcg_temp_free_i32(fp32);
8052 check_cp1_registers(ctx, fs);
8054 TCGv_i32 fp32 = tcg_temp_new_i32();
8055 TCGv_i64 fp64 = tcg_temp_new_i64();
8057 gen_load_fpr64(ctx, fp64, fs);
8058 gen_helper_float_ceilw_d(fp32, cpu_env, fp64);
8059 tcg_temp_free_i64(fp64);
8060 gen_store_fpr32(fp32, fd);
8061 tcg_temp_free_i32(fp32);
8066 check_cp1_registers(ctx, fs);
8068 TCGv_i32 fp32 = tcg_temp_new_i32();
8069 TCGv_i64 fp64 = tcg_temp_new_i64();
8071 gen_load_fpr64(ctx, fp64, fs);
8072 gen_helper_float_floorw_d(fp32, cpu_env, fp64);
8073 tcg_temp_free_i64(fp64);
8074 gen_store_fpr32(fp32, fd);
8075 tcg_temp_free_i32(fp32);
8080 gen_movcf_d(ctx, fs, fd, (ft >> 2) & 0x7, ft & 0x1);
8085 int l1 = gen_new_label();
8089 tcg_gen_brcondi_tl(TCG_COND_NE, cpu_gpr[ft], 0, l1);
8091 fp0 = tcg_temp_new_i64();
8092 gen_load_fpr64(ctx, fp0, fs);
8093 gen_store_fpr64(ctx, fp0, fd);
8094 tcg_temp_free_i64(fp0);
8101 int l1 = gen_new_label();
8105 tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_gpr[ft], 0, l1);
8106 fp0 = tcg_temp_new_i64();
8107 gen_load_fpr64(ctx, fp0, fs);
8108 gen_store_fpr64(ctx, fp0, fd);
8109 tcg_temp_free_i64(fp0);
8116 check_cp1_64bitmode(ctx);
8118 TCGv_i64 fp0 = tcg_temp_new_i64();
8120 gen_load_fpr64(ctx, fp0, fs);
8121 gen_helper_float_recip_d(fp0, cpu_env, fp0);
8122 gen_store_fpr64(ctx, fp0, fd);
8123 tcg_temp_free_i64(fp0);
8128 check_cp1_64bitmode(ctx);
8130 TCGv_i64 fp0 = tcg_temp_new_i64();
8132 gen_load_fpr64(ctx, fp0, fs);
8133 gen_helper_float_rsqrt_d(fp0, cpu_env, fp0);
8134 gen_store_fpr64(ctx, fp0, fd);
8135 tcg_temp_free_i64(fp0);
8140 check_cp1_64bitmode(ctx);
8142 TCGv_i64 fp0 = tcg_temp_new_i64();
8143 TCGv_i64 fp1 = tcg_temp_new_i64();
8145 gen_load_fpr64(ctx, fp0, fs);
8146 gen_load_fpr64(ctx, fp1, ft);
8147 gen_helper_float_recip2_d(fp0, cpu_env, fp0, fp1);
8148 tcg_temp_free_i64(fp1);
8149 gen_store_fpr64(ctx, fp0, fd);
8150 tcg_temp_free_i64(fp0);
8155 check_cp1_64bitmode(ctx);
8157 TCGv_i64 fp0 = tcg_temp_new_i64();
8159 gen_load_fpr64(ctx, fp0, fs);
8160 gen_helper_float_recip1_d(fp0, cpu_env, fp0);
8161 gen_store_fpr64(ctx, fp0, fd);
8162 tcg_temp_free_i64(fp0);
8167 check_cp1_64bitmode(ctx);
8169 TCGv_i64 fp0 = tcg_temp_new_i64();
8171 gen_load_fpr64(ctx, fp0, fs);
8172 gen_helper_float_rsqrt1_d(fp0, cpu_env, fp0);
8173 gen_store_fpr64(ctx, fp0, fd);
8174 tcg_temp_free_i64(fp0);
8179 check_cp1_64bitmode(ctx);
8181 TCGv_i64 fp0 = tcg_temp_new_i64();
8182 TCGv_i64 fp1 = tcg_temp_new_i64();
8184 gen_load_fpr64(ctx, fp0, fs);
8185 gen_load_fpr64(ctx, fp1, ft);
8186 gen_helper_float_rsqrt2_d(fp0, cpu_env, fp0, fp1);
8187 tcg_temp_free_i64(fp1);
8188 gen_store_fpr64(ctx, fp0, fd);
8189 tcg_temp_free_i64(fp0);
8202 case OPC_CMP_NGLE_D:
8209 if (ctx->opcode & (1 << 6)) {
8210 gen_cmpabs_d(ctx, func-48, ft, fs, cc);
8211 opn = condnames_abs[func-48];
8213 gen_cmp_d(ctx, func-48, ft, fs, cc);
8214 opn = condnames[func-48];
8218 check_cp1_registers(ctx, fs);
8220 TCGv_i32 fp32 = tcg_temp_new_i32();
8221 TCGv_i64 fp64 = tcg_temp_new_i64();
8223 gen_load_fpr64(ctx, fp64, fs);
8224 gen_helper_float_cvts_d(fp32, cpu_env, fp64);
8225 tcg_temp_free_i64(fp64);
8226 gen_store_fpr32(fp32, fd);
8227 tcg_temp_free_i32(fp32);
8232 check_cp1_registers(ctx, fs);
8234 TCGv_i32 fp32 = tcg_temp_new_i32();
8235 TCGv_i64 fp64 = tcg_temp_new_i64();
8237 gen_load_fpr64(ctx, fp64, fs);
8238 gen_helper_float_cvtw_d(fp32, cpu_env, fp64);
8239 tcg_temp_free_i64(fp64);
8240 gen_store_fpr32(fp32, fd);
8241 tcg_temp_free_i32(fp32);
8246 check_cp1_64bitmode(ctx);
8248 TCGv_i64 fp0 = tcg_temp_new_i64();
8250 gen_load_fpr64(ctx, fp0, fs);
8251 gen_helper_float_cvtl_d(fp0, cpu_env, fp0);
8252 gen_store_fpr64(ctx, fp0, fd);
8253 tcg_temp_free_i64(fp0);
8259 TCGv_i32 fp0 = tcg_temp_new_i32();
8261 gen_load_fpr32(fp0, fs);
8262 gen_helper_float_cvts_w(fp0, cpu_env, fp0);
8263 gen_store_fpr32(fp0, fd);
8264 tcg_temp_free_i32(fp0);
8269 check_cp1_registers(ctx, fd);
8271 TCGv_i32 fp32 = tcg_temp_new_i32();
8272 TCGv_i64 fp64 = tcg_temp_new_i64();
8274 gen_load_fpr32(fp32, fs);
8275 gen_helper_float_cvtd_w(fp64, cpu_env, fp32);
8276 tcg_temp_free_i32(fp32);
8277 gen_store_fpr64(ctx, fp64, fd);
8278 tcg_temp_free_i64(fp64);
8283 check_cp1_64bitmode(ctx);
8285 TCGv_i32 fp32 = tcg_temp_new_i32();
8286 TCGv_i64 fp64 = tcg_temp_new_i64();
8288 gen_load_fpr64(ctx, fp64, fs);
8289 gen_helper_float_cvts_l(fp32, cpu_env, fp64);
8290 tcg_temp_free_i64(fp64);
8291 gen_store_fpr32(fp32, fd);
8292 tcg_temp_free_i32(fp32);
8297 check_cp1_64bitmode(ctx);
8299 TCGv_i64 fp0 = tcg_temp_new_i64();
8301 gen_load_fpr64(ctx, fp0, fs);
8302 gen_helper_float_cvtd_l(fp0, cpu_env, fp0);
8303 gen_store_fpr64(ctx, fp0, fd);
8304 tcg_temp_free_i64(fp0);
8309 check_cp1_64bitmode(ctx);
8311 TCGv_i64 fp0 = tcg_temp_new_i64();
8313 gen_load_fpr64(ctx, fp0, fs);
8314 gen_helper_float_cvtps_pw(fp0, cpu_env, fp0);
8315 gen_store_fpr64(ctx, fp0, fd);
8316 tcg_temp_free_i64(fp0);
8321 check_cp1_64bitmode(ctx);
8323 TCGv_i64 fp0 = tcg_temp_new_i64();
8324 TCGv_i64 fp1 = tcg_temp_new_i64();
8326 gen_load_fpr64(ctx, fp0, fs);
8327 gen_load_fpr64(ctx, fp1, ft);
8328 gen_helper_float_add_ps(fp0, cpu_env, fp0, fp1);
8329 tcg_temp_free_i64(fp1);
8330 gen_store_fpr64(ctx, fp0, fd);
8331 tcg_temp_free_i64(fp0);
8336 check_cp1_64bitmode(ctx);
8338 TCGv_i64 fp0 = tcg_temp_new_i64();
8339 TCGv_i64 fp1 = tcg_temp_new_i64();
8341 gen_load_fpr64(ctx, fp0, fs);
8342 gen_load_fpr64(ctx, fp1, ft);
8343 gen_helper_float_sub_ps(fp0, cpu_env, fp0, fp1);
8344 tcg_temp_free_i64(fp1);
8345 gen_store_fpr64(ctx, fp0, fd);
8346 tcg_temp_free_i64(fp0);
8351 check_cp1_64bitmode(ctx);
8353 TCGv_i64 fp0 = tcg_temp_new_i64();
8354 TCGv_i64 fp1 = tcg_temp_new_i64();
8356 gen_load_fpr64(ctx, fp0, fs);
8357 gen_load_fpr64(ctx, fp1, ft);
8358 gen_helper_float_mul_ps(fp0, cpu_env, fp0, fp1);
8359 tcg_temp_free_i64(fp1);
8360 gen_store_fpr64(ctx, fp0, fd);
8361 tcg_temp_free_i64(fp0);
8366 check_cp1_64bitmode(ctx);
8368 TCGv_i64 fp0 = tcg_temp_new_i64();
8370 gen_load_fpr64(ctx, fp0, fs);
8371 gen_helper_float_abs_ps(fp0, fp0);
8372 gen_store_fpr64(ctx, fp0, fd);
8373 tcg_temp_free_i64(fp0);
8378 check_cp1_64bitmode(ctx);
8380 TCGv_i64 fp0 = tcg_temp_new_i64();
8382 gen_load_fpr64(ctx, fp0, fs);
8383 gen_store_fpr64(ctx, fp0, fd);
8384 tcg_temp_free_i64(fp0);
8389 check_cp1_64bitmode(ctx);
8391 TCGv_i64 fp0 = tcg_temp_new_i64();
8393 gen_load_fpr64(ctx, fp0, fs);
8394 gen_helper_float_chs_ps(fp0, fp0);
8395 gen_store_fpr64(ctx, fp0, fd);
8396 tcg_temp_free_i64(fp0);
8401 check_cp1_64bitmode(ctx);
8402 gen_movcf_ps(fs, fd, (ft >> 2) & 0x7, ft & 0x1);
8406 check_cp1_64bitmode(ctx);
8408 int l1 = gen_new_label();
8412 tcg_gen_brcondi_tl(TCG_COND_NE, cpu_gpr[ft], 0, l1);
8413 fp0 = tcg_temp_new_i64();
8414 gen_load_fpr64(ctx, fp0, fs);
8415 gen_store_fpr64(ctx, fp0, fd);
8416 tcg_temp_free_i64(fp0);
8422 check_cp1_64bitmode(ctx);
8424 int l1 = gen_new_label();
8428 tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_gpr[ft], 0, l1);
8429 fp0 = tcg_temp_new_i64();
8430 gen_load_fpr64(ctx, fp0, fs);
8431 gen_store_fpr64(ctx, fp0, fd);
8432 tcg_temp_free_i64(fp0);
8439 check_cp1_64bitmode(ctx);
8441 TCGv_i64 fp0 = tcg_temp_new_i64();
8442 TCGv_i64 fp1 = tcg_temp_new_i64();
8444 gen_load_fpr64(ctx, fp0, ft);
8445 gen_load_fpr64(ctx, fp1, fs);
8446 gen_helper_float_addr_ps(fp0, cpu_env, fp0, fp1);
8447 tcg_temp_free_i64(fp1);
8448 gen_store_fpr64(ctx, fp0, fd);
8449 tcg_temp_free_i64(fp0);
8454 check_cp1_64bitmode(ctx);
8456 TCGv_i64 fp0 = tcg_temp_new_i64();
8457 TCGv_i64 fp1 = tcg_temp_new_i64();
8459 gen_load_fpr64(ctx, fp0, ft);
8460 gen_load_fpr64(ctx, fp1, fs);
8461 gen_helper_float_mulr_ps(fp0, cpu_env, fp0, fp1);
8462 tcg_temp_free_i64(fp1);
8463 gen_store_fpr64(ctx, fp0, fd);
8464 tcg_temp_free_i64(fp0);
8469 check_cp1_64bitmode(ctx);
8471 TCGv_i64 fp0 = tcg_temp_new_i64();
8472 TCGv_i64 fp1 = tcg_temp_new_i64();
8474 gen_load_fpr64(ctx, fp0, fs);
8475 gen_load_fpr64(ctx, fp1, ft);
8476 gen_helper_float_recip2_ps(fp0, cpu_env, fp0, fp1);
8477 tcg_temp_free_i64(fp1);
8478 gen_store_fpr64(ctx, fp0, fd);
8479 tcg_temp_free_i64(fp0);
8484 check_cp1_64bitmode(ctx);
8486 TCGv_i64 fp0 = tcg_temp_new_i64();
8488 gen_load_fpr64(ctx, fp0, fs);
8489 gen_helper_float_recip1_ps(fp0, cpu_env, fp0);
8490 gen_store_fpr64(ctx, fp0, fd);
8491 tcg_temp_free_i64(fp0);
8496 check_cp1_64bitmode(ctx);
8498 TCGv_i64 fp0 = tcg_temp_new_i64();
8500 gen_load_fpr64(ctx, fp0, fs);
8501 gen_helper_float_rsqrt1_ps(fp0, cpu_env, fp0);
8502 gen_store_fpr64(ctx, fp0, fd);
8503 tcg_temp_free_i64(fp0);
8508 check_cp1_64bitmode(ctx);
8510 TCGv_i64 fp0 = tcg_temp_new_i64();
8511 TCGv_i64 fp1 = tcg_temp_new_i64();
8513 gen_load_fpr64(ctx, fp0, fs);
8514 gen_load_fpr64(ctx, fp1, ft);
8515 gen_helper_float_rsqrt2_ps(fp0, cpu_env, fp0, fp1);
8516 tcg_temp_free_i64(fp1);
8517 gen_store_fpr64(ctx, fp0, fd);
8518 tcg_temp_free_i64(fp0);
8523 check_cp1_64bitmode(ctx);
8525 TCGv_i32 fp0 = tcg_temp_new_i32();
8527 gen_load_fpr32h(fp0, fs);
8528 gen_helper_float_cvts_pu(fp0, cpu_env, fp0);
8529 gen_store_fpr32(fp0, fd);
8530 tcg_temp_free_i32(fp0);
8535 check_cp1_64bitmode(ctx);
8537 TCGv_i64 fp0 = tcg_temp_new_i64();
8539 gen_load_fpr64(ctx, fp0, fs);
8540 gen_helper_float_cvtpw_ps(fp0, cpu_env, fp0);
8541 gen_store_fpr64(ctx, fp0, fd);
8542 tcg_temp_free_i64(fp0);
8547 check_cp1_64bitmode(ctx);
8549 TCGv_i32 fp0 = tcg_temp_new_i32();
8551 gen_load_fpr32(fp0, fs);
8552 gen_helper_float_cvts_pl(fp0, cpu_env, fp0);
8553 gen_store_fpr32(fp0, fd);
8554 tcg_temp_free_i32(fp0);
8559 check_cp1_64bitmode(ctx);
8561 TCGv_i32 fp0 = tcg_temp_new_i32();
8562 TCGv_i32 fp1 = tcg_temp_new_i32();
8564 gen_load_fpr32(fp0, fs);
8565 gen_load_fpr32(fp1, ft);
8566 gen_store_fpr32h(fp0, fd);
8567 gen_store_fpr32(fp1, fd);
8568 tcg_temp_free_i32(fp0);
8569 tcg_temp_free_i32(fp1);
8574 check_cp1_64bitmode(ctx);
8576 TCGv_i32 fp0 = tcg_temp_new_i32();
8577 TCGv_i32 fp1 = tcg_temp_new_i32();
8579 gen_load_fpr32(fp0, fs);
8580 gen_load_fpr32h(fp1, ft);
8581 gen_store_fpr32(fp1, fd);
8582 gen_store_fpr32h(fp0, fd);
8583 tcg_temp_free_i32(fp0);
8584 tcg_temp_free_i32(fp1);
8589 check_cp1_64bitmode(ctx);
8591 TCGv_i32 fp0 = tcg_temp_new_i32();
8592 TCGv_i32 fp1 = tcg_temp_new_i32();
8594 gen_load_fpr32h(fp0, fs);
8595 gen_load_fpr32(fp1, ft);
8596 gen_store_fpr32(fp1, fd);
8597 gen_store_fpr32h(fp0, fd);
8598 tcg_temp_free_i32(fp0);
8599 tcg_temp_free_i32(fp1);
8604 check_cp1_64bitmode(ctx);
8606 TCGv_i32 fp0 = tcg_temp_new_i32();
8607 TCGv_i32 fp1 = tcg_temp_new_i32();
8609 gen_load_fpr32h(fp0, fs);
8610 gen_load_fpr32h(fp1, ft);
8611 gen_store_fpr32(fp1, fd);
8612 gen_store_fpr32h(fp0, fd);
8613 tcg_temp_free_i32(fp0);
8614 tcg_temp_free_i32(fp1);
8621 case OPC_CMP_UEQ_PS:
8622 case OPC_CMP_OLT_PS:
8623 case OPC_CMP_ULT_PS:
8624 case OPC_CMP_OLE_PS:
8625 case OPC_CMP_ULE_PS:
8627 case OPC_CMP_NGLE_PS:
8628 case OPC_CMP_SEQ_PS:
8629 case OPC_CMP_NGL_PS:
8631 case OPC_CMP_NGE_PS:
8633 case OPC_CMP_NGT_PS:
8634 if (ctx->opcode & (1 << 6)) {
8635 gen_cmpabs_ps(ctx, func-48, ft, fs, cc);
8636 opn = condnames_abs[func-48];
8638 gen_cmp_ps(ctx, func-48, ft, fs, cc);
8639 opn = condnames[func-48];
8644 generate_exception (ctx, EXCP_RI);
8647 (void)opn; /* avoid a compiler warning */
8650 MIPS_DEBUG("%s %s, %s, %s", opn, fregnames[fd], fregnames[fs], fregnames[ft]);
8653 MIPS_DEBUG("%s %s,%s", opn, fregnames[fs], fregnames[ft]);
8656 MIPS_DEBUG("%s %s,%s", opn, fregnames[fd], fregnames[fs]);
8661 /* Coprocessor 3 (FPU) */
8662 static void gen_flt3_ldst (DisasContext *ctx, uint32_t opc,
8663 int fd, int fs, int base, int index)
8665 const char *opn = "extended float load/store";
8667 TCGv t0 = tcg_temp_new();
8670 gen_load_gpr(t0, index);
8671 } else if (index == 0) {
8672 gen_load_gpr(t0, base);
8674 gen_op_addr_add(ctx, t0, cpu_gpr[base], cpu_gpr[index]);
8676 /* Don't do NOP if destination is zero: we must perform the actual
8682 TCGv_i32 fp0 = tcg_temp_new_i32();
8684 tcg_gen_qemu_ld32s(t0, t0, ctx->mem_idx);
8685 tcg_gen_trunc_tl_i32(fp0, t0);
8686 gen_store_fpr32(fp0, fd);
8687 tcg_temp_free_i32(fp0);
8693 check_cp1_registers(ctx, fd);
8695 TCGv_i64 fp0 = tcg_temp_new_i64();
8697 tcg_gen_qemu_ld64(fp0, t0, ctx->mem_idx);
8698 gen_store_fpr64(ctx, fp0, fd);
8699 tcg_temp_free_i64(fp0);
8704 check_cp1_64bitmode(ctx);
8705 tcg_gen_andi_tl(t0, t0, ~0x7);
8707 TCGv_i64 fp0 = tcg_temp_new_i64();
8709 tcg_gen_qemu_ld64(fp0, t0, ctx->mem_idx);
8710 gen_store_fpr64(ctx, fp0, fd);
8711 tcg_temp_free_i64(fp0);
8718 TCGv_i32 fp0 = tcg_temp_new_i32();
8719 TCGv t1 = tcg_temp_new();
8721 gen_load_fpr32(fp0, fs);
8722 tcg_gen_extu_i32_tl(t1, fp0);
8723 tcg_gen_qemu_st32(t1, t0, ctx->mem_idx);
8724 tcg_temp_free_i32(fp0);
8732 check_cp1_registers(ctx, fs);
8734 TCGv_i64 fp0 = tcg_temp_new_i64();
8736 gen_load_fpr64(ctx, fp0, fs);
8737 tcg_gen_qemu_st64(fp0, t0, ctx->mem_idx);
8738 tcg_temp_free_i64(fp0);
8744 check_cp1_64bitmode(ctx);
8745 tcg_gen_andi_tl(t0, t0, ~0x7);
8747 TCGv_i64 fp0 = tcg_temp_new_i64();
8749 gen_load_fpr64(ctx, fp0, fs);
8750 tcg_gen_qemu_st64(fp0, t0, ctx->mem_idx);
8751 tcg_temp_free_i64(fp0);
8758 (void)opn; (void)store; /* avoid compiler warnings */
8759 MIPS_DEBUG("%s %s, %s(%s)", opn, fregnames[store ? fs : fd],
8760 regnames[index], regnames[base]);
8763 static void gen_flt3_arith (DisasContext *ctx, uint32_t opc,
8764 int fd, int fr, int fs, int ft)
8766 const char *opn = "flt3_arith";
8770 check_cp1_64bitmode(ctx);
8772 TCGv t0 = tcg_temp_local_new();
8773 TCGv_i32 fp = tcg_temp_new_i32();
8774 TCGv_i32 fph = tcg_temp_new_i32();
8775 int l1 = gen_new_label();
8776 int l2 = gen_new_label();
8778 gen_load_gpr(t0, fr);
8779 tcg_gen_andi_tl(t0, t0, 0x7);
8781 tcg_gen_brcondi_tl(TCG_COND_NE, t0, 0, l1);
8782 gen_load_fpr32(fp, fs);
8783 gen_load_fpr32h(fph, fs);
8784 gen_store_fpr32(fp, fd);
8785 gen_store_fpr32h(fph, fd);
8788 tcg_gen_brcondi_tl(TCG_COND_NE, t0, 4, l2);
8790 #ifdef TARGET_WORDS_BIGENDIAN
8791 gen_load_fpr32(fp, fs);
8792 gen_load_fpr32h(fph, ft);
8793 gen_store_fpr32h(fp, fd);
8794 gen_store_fpr32(fph, fd);
8796 gen_load_fpr32h(fph, fs);
8797 gen_load_fpr32(fp, ft);
8798 gen_store_fpr32(fph, fd);
8799 gen_store_fpr32h(fp, fd);
8802 tcg_temp_free_i32(fp);
8803 tcg_temp_free_i32(fph);
8810 TCGv_i32 fp0 = tcg_temp_new_i32();
8811 TCGv_i32 fp1 = tcg_temp_new_i32();
8812 TCGv_i32 fp2 = tcg_temp_new_i32();
8814 gen_load_fpr32(fp0, fs);
8815 gen_load_fpr32(fp1, ft);
8816 gen_load_fpr32(fp2, fr);
8817 gen_helper_float_madd_s(fp2, cpu_env, fp0, fp1, fp2);
8818 tcg_temp_free_i32(fp0);
8819 tcg_temp_free_i32(fp1);
8820 gen_store_fpr32(fp2, fd);
8821 tcg_temp_free_i32(fp2);
8827 check_cp1_registers(ctx, fd | fs | ft | fr);
8829 TCGv_i64 fp0 = tcg_temp_new_i64();
8830 TCGv_i64 fp1 = tcg_temp_new_i64();
8831 TCGv_i64 fp2 = tcg_temp_new_i64();
8833 gen_load_fpr64(ctx, fp0, fs);
8834 gen_load_fpr64(ctx, fp1, ft);
8835 gen_load_fpr64(ctx, fp2, fr);
8836 gen_helper_float_madd_d(fp2, cpu_env, fp0, fp1, fp2);
8837 tcg_temp_free_i64(fp0);
8838 tcg_temp_free_i64(fp1);
8839 gen_store_fpr64(ctx, fp2, fd);
8840 tcg_temp_free_i64(fp2);
8845 check_cp1_64bitmode(ctx);
8847 TCGv_i64 fp0 = tcg_temp_new_i64();
8848 TCGv_i64 fp1 = tcg_temp_new_i64();
8849 TCGv_i64 fp2 = tcg_temp_new_i64();
8851 gen_load_fpr64(ctx, fp0, fs);
8852 gen_load_fpr64(ctx, fp1, ft);
8853 gen_load_fpr64(ctx, fp2, fr);
8854 gen_helper_float_madd_ps(fp2, cpu_env, fp0, fp1, fp2);
8855 tcg_temp_free_i64(fp0);
8856 tcg_temp_free_i64(fp1);
8857 gen_store_fpr64(ctx, fp2, fd);
8858 tcg_temp_free_i64(fp2);
8865 TCGv_i32 fp0 = tcg_temp_new_i32();
8866 TCGv_i32 fp1 = tcg_temp_new_i32();
8867 TCGv_i32 fp2 = tcg_temp_new_i32();
8869 gen_load_fpr32(fp0, fs);
8870 gen_load_fpr32(fp1, ft);
8871 gen_load_fpr32(fp2, fr);
8872 gen_helper_float_msub_s(fp2, cpu_env, fp0, fp1, fp2);
8873 tcg_temp_free_i32(fp0);
8874 tcg_temp_free_i32(fp1);
8875 gen_store_fpr32(fp2, fd);
8876 tcg_temp_free_i32(fp2);
8882 check_cp1_registers(ctx, fd | fs | ft | fr);
8884 TCGv_i64 fp0 = tcg_temp_new_i64();
8885 TCGv_i64 fp1 = tcg_temp_new_i64();
8886 TCGv_i64 fp2 = tcg_temp_new_i64();
8888 gen_load_fpr64(ctx, fp0, fs);
8889 gen_load_fpr64(ctx, fp1, ft);
8890 gen_load_fpr64(ctx, fp2, fr);
8891 gen_helper_float_msub_d(fp2, cpu_env, fp0, fp1, fp2);
8892 tcg_temp_free_i64(fp0);
8893 tcg_temp_free_i64(fp1);
8894 gen_store_fpr64(ctx, fp2, fd);
8895 tcg_temp_free_i64(fp2);
8900 check_cp1_64bitmode(ctx);
8902 TCGv_i64 fp0 = tcg_temp_new_i64();
8903 TCGv_i64 fp1 = tcg_temp_new_i64();
8904 TCGv_i64 fp2 = tcg_temp_new_i64();
8906 gen_load_fpr64(ctx, fp0, fs);
8907 gen_load_fpr64(ctx, fp1, ft);
8908 gen_load_fpr64(ctx, fp2, fr);
8909 gen_helper_float_msub_ps(fp2, cpu_env, fp0, fp1, fp2);
8910 tcg_temp_free_i64(fp0);
8911 tcg_temp_free_i64(fp1);
8912 gen_store_fpr64(ctx, fp2, fd);
8913 tcg_temp_free_i64(fp2);
8920 TCGv_i32 fp0 = tcg_temp_new_i32();
8921 TCGv_i32 fp1 = tcg_temp_new_i32();
8922 TCGv_i32 fp2 = tcg_temp_new_i32();
8924 gen_load_fpr32(fp0, fs);
8925 gen_load_fpr32(fp1, ft);
8926 gen_load_fpr32(fp2, fr);
8927 gen_helper_float_nmadd_s(fp2, cpu_env, fp0, fp1, fp2);
8928 tcg_temp_free_i32(fp0);
8929 tcg_temp_free_i32(fp1);
8930 gen_store_fpr32(fp2, fd);
8931 tcg_temp_free_i32(fp2);
8937 check_cp1_registers(ctx, fd | fs | ft | fr);
8939 TCGv_i64 fp0 = tcg_temp_new_i64();
8940 TCGv_i64 fp1 = tcg_temp_new_i64();
8941 TCGv_i64 fp2 = tcg_temp_new_i64();
8943 gen_load_fpr64(ctx, fp0, fs);
8944 gen_load_fpr64(ctx, fp1, ft);
8945 gen_load_fpr64(ctx, fp2, fr);
8946 gen_helper_float_nmadd_d(fp2, cpu_env, fp0, fp1, fp2);
8947 tcg_temp_free_i64(fp0);
8948 tcg_temp_free_i64(fp1);
8949 gen_store_fpr64(ctx, fp2, fd);
8950 tcg_temp_free_i64(fp2);
8955 check_cp1_64bitmode(ctx);
8957 TCGv_i64 fp0 = tcg_temp_new_i64();
8958 TCGv_i64 fp1 = tcg_temp_new_i64();
8959 TCGv_i64 fp2 = tcg_temp_new_i64();
8961 gen_load_fpr64(ctx, fp0, fs);
8962 gen_load_fpr64(ctx, fp1, ft);
8963 gen_load_fpr64(ctx, fp2, fr);
8964 gen_helper_float_nmadd_ps(fp2, cpu_env, fp0, fp1, fp2);
8965 tcg_temp_free_i64(fp0);
8966 tcg_temp_free_i64(fp1);
8967 gen_store_fpr64(ctx, fp2, fd);
8968 tcg_temp_free_i64(fp2);
8975 TCGv_i32 fp0 = tcg_temp_new_i32();
8976 TCGv_i32 fp1 = tcg_temp_new_i32();
8977 TCGv_i32 fp2 = tcg_temp_new_i32();
8979 gen_load_fpr32(fp0, fs);
8980 gen_load_fpr32(fp1, ft);
8981 gen_load_fpr32(fp2, fr);
8982 gen_helper_float_nmsub_s(fp2, cpu_env, fp0, fp1, fp2);
8983 tcg_temp_free_i32(fp0);
8984 tcg_temp_free_i32(fp1);
8985 gen_store_fpr32(fp2, fd);
8986 tcg_temp_free_i32(fp2);
8992 check_cp1_registers(ctx, fd | fs | ft | fr);
8994 TCGv_i64 fp0 = tcg_temp_new_i64();
8995 TCGv_i64 fp1 = tcg_temp_new_i64();
8996 TCGv_i64 fp2 = tcg_temp_new_i64();
8998 gen_load_fpr64(ctx, fp0, fs);
8999 gen_load_fpr64(ctx, fp1, ft);
9000 gen_load_fpr64(ctx, fp2, fr);
9001 gen_helper_float_nmsub_d(fp2, cpu_env, fp0, fp1, fp2);
9002 tcg_temp_free_i64(fp0);
9003 tcg_temp_free_i64(fp1);
9004 gen_store_fpr64(ctx, fp2, fd);
9005 tcg_temp_free_i64(fp2);
9010 check_cp1_64bitmode(ctx);
9012 TCGv_i64 fp0 = tcg_temp_new_i64();
9013 TCGv_i64 fp1 = tcg_temp_new_i64();
9014 TCGv_i64 fp2 = tcg_temp_new_i64();
9016 gen_load_fpr64(ctx, fp0, fs);
9017 gen_load_fpr64(ctx, fp1, ft);
9018 gen_load_fpr64(ctx, fp2, fr);
9019 gen_helper_float_nmsub_ps(fp2, cpu_env, fp0, fp1, fp2);
9020 tcg_temp_free_i64(fp0);
9021 tcg_temp_free_i64(fp1);
9022 gen_store_fpr64(ctx, fp2, fd);
9023 tcg_temp_free_i64(fp2);
9029 generate_exception (ctx, EXCP_RI);
9032 (void)opn; /* avoid a compiler warning */
9033 MIPS_DEBUG("%s %s, %s, %s, %s", opn, fregnames[fd], fregnames[fr],
9034 fregnames[fs], fregnames[ft]);
9037 static void gen_rdhwr(DisasContext *ctx, int rt, int rd)
9041 #if !defined(CONFIG_USER_ONLY)
9042 /* The Linux kernel will emulate rdhwr if it's not supported natively.
9043 Therefore only check the ISA in system mode. */
9044 check_insn(ctx, ISA_MIPS32R2);
9046 t0 = tcg_temp_new();
9050 save_cpu_state(ctx, 1);
9051 gen_helper_rdhwr_cpunum(t0, cpu_env);
9052 gen_store_gpr(t0, rt);
9055 save_cpu_state(ctx, 1);
9056 gen_helper_rdhwr_synci_step(t0, cpu_env);
9057 gen_store_gpr(t0, rt);
9060 save_cpu_state(ctx, 1);
9061 gen_helper_rdhwr_cc(t0, cpu_env);
9062 gen_store_gpr(t0, rt);
9065 save_cpu_state(ctx, 1);
9066 gen_helper_rdhwr_ccres(t0, cpu_env);
9067 gen_store_gpr(t0, rt);
9070 #if defined(CONFIG_USER_ONLY)
9071 tcg_gen_ld_tl(t0, cpu_env, offsetof(CPUMIPSState, tls_value));
9072 gen_store_gpr(t0, rt);
9075 /* XXX: Some CPUs implement this in hardware.
9076 Not supported yet. */
9078 default: /* Invalid */
9079 MIPS_INVAL("rdhwr");
9080 generate_exception(ctx, EXCP_RI);
9086 static void handle_delay_slot(DisasContext *ctx, int insn_bytes)
9088 if (ctx->hflags & MIPS_HFLAG_BMASK) {
9089 int proc_hflags = ctx->hflags & MIPS_HFLAG_BMASK;
9090 /* Branches completion */
9091 ctx->hflags &= ~MIPS_HFLAG_BMASK;
9092 ctx->bstate = BS_BRANCH;
9093 save_cpu_state(ctx, 0);
9094 /* FIXME: Need to clear can_do_io. */
9095 switch (proc_hflags & MIPS_HFLAG_BMASK_BASE) {
9097 /* unconditional branch */
9098 MIPS_DEBUG("unconditional branch");
9099 if (proc_hflags & MIPS_HFLAG_BX) {
9100 tcg_gen_xori_i32(hflags, hflags, MIPS_HFLAG_M16);
9102 gen_goto_tb(ctx, 0, ctx->btarget);
9105 /* blikely taken case */
9106 MIPS_DEBUG("blikely branch taken");
9107 gen_goto_tb(ctx, 0, ctx->btarget);
9110 /* Conditional branch */
9111 MIPS_DEBUG("conditional branch");
9113 int l1 = gen_new_label();
9115 tcg_gen_brcondi_tl(TCG_COND_NE, bcond, 0, l1);
9116 gen_goto_tb(ctx, 1, ctx->pc + insn_bytes);
9118 gen_goto_tb(ctx, 0, ctx->btarget);
9122 /* unconditional branch to register */
9123 MIPS_DEBUG("branch to register");
9124 if (ctx->insn_flags & (ASE_MIPS16 | ASE_MICROMIPS)) {
9125 TCGv t0 = tcg_temp_new();
9126 TCGv_i32 t1 = tcg_temp_new_i32();
9128 tcg_gen_andi_tl(t0, btarget, 0x1);
9129 tcg_gen_trunc_tl_i32(t1, t0);
9131 tcg_gen_andi_i32(hflags, hflags, ~(uint32_t)MIPS_HFLAG_M16);
9132 tcg_gen_shli_i32(t1, t1, MIPS_HFLAG_M16_SHIFT);
9133 tcg_gen_or_i32(hflags, hflags, t1);
9134 tcg_temp_free_i32(t1);
9136 tcg_gen_andi_tl(cpu_PC, btarget, ~(target_ulong)0x1);
9138 tcg_gen_mov_tl(cpu_PC, btarget);
9140 if (ctx->singlestep_enabled) {
9141 save_cpu_state(ctx, 0);
9142 gen_helper_0e0i(raise_exception, EXCP_DEBUG);
9147 MIPS_DEBUG("unknown branch");
9153 /* ISA extensions (ASEs) */
9154 /* MIPS16 extension to MIPS32 */
9156 /* MIPS16 major opcodes */
9158 M16_OPC_ADDIUSP = 0x00,
9159 M16_OPC_ADDIUPC = 0x01,
9162 M16_OPC_BEQZ = 0x04,
9163 M16_OPC_BNEQZ = 0x05,
9164 M16_OPC_SHIFT = 0x06,
9166 M16_OPC_RRIA = 0x08,
9167 M16_OPC_ADDIU8 = 0x09,
9168 M16_OPC_SLTI = 0x0a,
9169 M16_OPC_SLTIU = 0x0b,
9172 M16_OPC_CMPI = 0x0e,
9176 M16_OPC_LWSP = 0x12,
9180 M16_OPC_LWPC = 0x16,
9184 M16_OPC_SWSP = 0x1a,
9188 M16_OPC_EXTEND = 0x1e,
9192 /* I8 funct field */
9211 /* RR funct field */
9245 /* I64 funct field */
9257 /* RR ry field for CNVT */
9259 RR_RY_CNVT_ZEB = 0x0,
9260 RR_RY_CNVT_ZEH = 0x1,
9261 RR_RY_CNVT_ZEW = 0x2,
9262 RR_RY_CNVT_SEB = 0x4,
9263 RR_RY_CNVT_SEH = 0x5,
9264 RR_RY_CNVT_SEW = 0x6,
9267 static int xlat (int r)
9269 static int map[] = { 16, 17, 2, 3, 4, 5, 6, 7 };
9274 static void gen_mips16_save (DisasContext *ctx,
9275 int xsregs, int aregs,
9276 int do_ra, int do_s0, int do_s1,
9279 TCGv t0 = tcg_temp_new();
9280 TCGv t1 = tcg_temp_new();
9310 generate_exception(ctx, EXCP_RI);
9316 gen_base_offset_addr(ctx, t0, 29, 12);
9317 gen_load_gpr(t1, 7);
9318 tcg_gen_qemu_st32(t1, t0, ctx->mem_idx);
9321 gen_base_offset_addr(ctx, t0, 29, 8);
9322 gen_load_gpr(t1, 6);
9323 tcg_gen_qemu_st32(t1, t0, ctx->mem_idx);
9326 gen_base_offset_addr(ctx, t0, 29, 4);
9327 gen_load_gpr(t1, 5);
9328 tcg_gen_qemu_st32(t1, t0, ctx->mem_idx);
9331 gen_base_offset_addr(ctx, t0, 29, 0);
9332 gen_load_gpr(t1, 4);
9333 tcg_gen_qemu_st32(t1, t0, ctx->mem_idx);
9336 gen_load_gpr(t0, 29);
9338 #define DECR_AND_STORE(reg) do { \
9339 tcg_gen_subi_tl(t0, t0, 4); \
9340 gen_load_gpr(t1, reg); \
9341 tcg_gen_qemu_st32(t1, t0, ctx->mem_idx); \
9405 generate_exception(ctx, EXCP_RI);
9421 #undef DECR_AND_STORE
9423 tcg_gen_subi_tl(cpu_gpr[29], cpu_gpr[29], framesize);
9428 static void gen_mips16_restore (DisasContext *ctx,
9429 int xsregs, int aregs,
9430 int do_ra, int do_s0, int do_s1,
9434 TCGv t0 = tcg_temp_new();
9435 TCGv t1 = tcg_temp_new();
9437 tcg_gen_addi_tl(t0, cpu_gpr[29], framesize);
9439 #define DECR_AND_LOAD(reg) do { \
9440 tcg_gen_subi_tl(t0, t0, 4); \
9441 tcg_gen_qemu_ld32u(t1, t0, ctx->mem_idx); \
9442 gen_store_gpr(t1, reg); \
9506 generate_exception(ctx, EXCP_RI);
9522 #undef DECR_AND_LOAD
9524 tcg_gen_addi_tl(cpu_gpr[29], cpu_gpr[29], framesize);
9529 static void gen_addiupc (DisasContext *ctx, int rx, int imm,
9530 int is_64_bit, int extended)
9534 if (extended && (ctx->hflags & MIPS_HFLAG_BMASK)) {
9535 generate_exception(ctx, EXCP_RI);
9539 t0 = tcg_temp_new();
9541 tcg_gen_movi_tl(t0, pc_relative_pc(ctx));
9542 tcg_gen_addi_tl(cpu_gpr[rx], t0, imm);
9544 tcg_gen_ext32s_tl(cpu_gpr[rx], cpu_gpr[rx]);
9550 #if defined(TARGET_MIPS64)
9551 static void decode_i64_mips16 (DisasContext *ctx,
9552 int ry, int funct, int16_t offset,
9558 offset = extended ? offset : offset << 3;
9559 gen_ld(ctx, OPC_LD, ry, 29, offset);
9563 offset = extended ? offset : offset << 3;
9564 gen_st(ctx, OPC_SD, ry, 29, offset);
9568 offset = extended ? offset : (ctx->opcode & 0xff) << 3;
9569 gen_st(ctx, OPC_SD, 31, 29, offset);
9573 offset = extended ? offset : ((int8_t)ctx->opcode) << 3;
9574 gen_arith_imm(ctx, OPC_DADDIU, 29, 29, offset);
9577 if (extended && (ctx->hflags & MIPS_HFLAG_BMASK)) {
9578 generate_exception(ctx, EXCP_RI);
9580 offset = extended ? offset : offset << 3;
9581 gen_ld(ctx, OPC_LDPC, ry, 0, offset);
9586 offset = extended ? offset : ((int8_t)(offset << 3)) >> 3;
9587 gen_arith_imm(ctx, OPC_DADDIU, ry, ry, offset);
9591 offset = extended ? offset : offset << 2;
9592 gen_addiupc(ctx, ry, offset, 1, extended);
9596 offset = extended ? offset : offset << 2;
9597 gen_arith_imm(ctx, OPC_DADDIU, ry, 29, offset);
9603 static int decode_extended_mips16_opc (CPUMIPSState *env, DisasContext *ctx,
9606 int extend = cpu_lduw_code(env, ctx->pc + 2);
9607 int op, rx, ry, funct, sa;
9608 int16_t imm, offset;
9610 ctx->opcode = (ctx->opcode << 16) | extend;
9611 op = (ctx->opcode >> 11) & 0x1f;
9612 sa = (ctx->opcode >> 22) & 0x1f;
9613 funct = (ctx->opcode >> 8) & 0x7;
9614 rx = xlat((ctx->opcode >> 8) & 0x7);
9615 ry = xlat((ctx->opcode >> 5) & 0x7);
9616 offset = imm = (int16_t) (((ctx->opcode >> 16) & 0x1f) << 11
9617 | ((ctx->opcode >> 21) & 0x3f) << 5
9618 | (ctx->opcode & 0x1f));
9620 /* The extended opcodes cleverly reuse the opcodes from their 16-bit
9623 case M16_OPC_ADDIUSP:
9624 gen_arith_imm(ctx, OPC_ADDIU, rx, 29, imm);
9626 case M16_OPC_ADDIUPC:
9627 gen_addiupc(ctx, rx, imm, 0, 1);
9630 gen_compute_branch(ctx, OPC_BEQ, 4, 0, 0, offset << 1);
9631 /* No delay slot, so just process as a normal instruction */
9634 gen_compute_branch(ctx, OPC_BEQ, 4, rx, 0, offset << 1);
9635 /* No delay slot, so just process as a normal instruction */
9638 gen_compute_branch(ctx, OPC_BNE, 4, rx, 0, offset << 1);
9639 /* No delay slot, so just process as a normal instruction */
9642 switch (ctx->opcode & 0x3) {
9644 gen_shift_imm(ctx, OPC_SLL, rx, ry, sa);
9647 #if defined(TARGET_MIPS64)
9649 gen_shift_imm(ctx, OPC_DSLL, rx, ry, sa);
9651 generate_exception(ctx, EXCP_RI);
9655 gen_shift_imm(ctx, OPC_SRL, rx, ry, sa);
9658 gen_shift_imm(ctx, OPC_SRA, rx, ry, sa);
9662 #if defined(TARGET_MIPS64)
9665 gen_ld(ctx, OPC_LD, ry, rx, offset);
9669 imm = ctx->opcode & 0xf;
9670 imm = imm | ((ctx->opcode >> 20) & 0x7f) << 4;
9671 imm = imm | ((ctx->opcode >> 16) & 0xf) << 11;
9672 imm = (int16_t) (imm << 1) >> 1;
9673 if ((ctx->opcode >> 4) & 0x1) {
9674 #if defined(TARGET_MIPS64)
9676 gen_arith_imm(ctx, OPC_DADDIU, ry, rx, imm);
9678 generate_exception(ctx, EXCP_RI);
9681 gen_arith_imm(ctx, OPC_ADDIU, ry, rx, imm);
9684 case M16_OPC_ADDIU8:
9685 gen_arith_imm(ctx, OPC_ADDIU, rx, rx, imm);
9688 gen_slt_imm(ctx, OPC_SLTI, 24, rx, imm);
9691 gen_slt_imm(ctx, OPC_SLTIU, 24, rx, imm);
9696 gen_compute_branch(ctx, OPC_BEQ, 4, 24, 0, offset << 1);
9699 gen_compute_branch(ctx, OPC_BNE, 4, 24, 0, offset << 1);
9702 gen_st(ctx, OPC_SW, 31, 29, imm);
9705 gen_arith_imm(ctx, OPC_ADDIU, 29, 29, imm);
9709 int xsregs = (ctx->opcode >> 24) & 0x7;
9710 int aregs = (ctx->opcode >> 16) & 0xf;
9711 int do_ra = (ctx->opcode >> 6) & 0x1;
9712 int do_s0 = (ctx->opcode >> 5) & 0x1;
9713 int do_s1 = (ctx->opcode >> 4) & 0x1;
9714 int framesize = (((ctx->opcode >> 20) & 0xf) << 4
9715 | (ctx->opcode & 0xf)) << 3;
9717 if (ctx->opcode & (1 << 7)) {
9718 gen_mips16_save(ctx, xsregs, aregs,
9719 do_ra, do_s0, do_s1,
9722 gen_mips16_restore(ctx, xsregs, aregs,
9723 do_ra, do_s0, do_s1,
9729 generate_exception(ctx, EXCP_RI);
9734 tcg_gen_movi_tl(cpu_gpr[rx], (uint16_t) imm);
9737 tcg_gen_xori_tl(cpu_gpr[24], cpu_gpr[rx], (uint16_t) imm);
9739 #if defined(TARGET_MIPS64)
9741 gen_st(ctx, OPC_SD, ry, rx, offset);
9745 gen_ld(ctx, OPC_LB, ry, rx, offset);
9748 gen_ld(ctx, OPC_LH, ry, rx, offset);
9751 gen_ld(ctx, OPC_LW, rx, 29, offset);
9754 gen_ld(ctx, OPC_LW, ry, rx, offset);
9757 gen_ld(ctx, OPC_LBU, ry, rx, offset);
9760 gen_ld(ctx, OPC_LHU, ry, rx, offset);
9763 gen_ld(ctx, OPC_LWPC, rx, 0, offset);
9765 #if defined(TARGET_MIPS64)
9767 gen_ld(ctx, OPC_LWU, ry, rx, offset);
9771 gen_st(ctx, OPC_SB, ry, rx, offset);
9774 gen_st(ctx, OPC_SH, ry, rx, offset);
9777 gen_st(ctx, OPC_SW, rx, 29, offset);
9780 gen_st(ctx, OPC_SW, ry, rx, offset);
9782 #if defined(TARGET_MIPS64)
9784 decode_i64_mips16(ctx, ry, funct, offset, 1);
9788 generate_exception(ctx, EXCP_RI);
9795 static int decode_mips16_opc (CPUMIPSState *env, DisasContext *ctx,
9800 int op, cnvt_op, op1, offset;
9804 op = (ctx->opcode >> 11) & 0x1f;
9805 sa = (ctx->opcode >> 2) & 0x7;
9806 sa = sa == 0 ? 8 : sa;
9807 rx = xlat((ctx->opcode >> 8) & 0x7);
9808 cnvt_op = (ctx->opcode >> 5) & 0x7;
9809 ry = xlat((ctx->opcode >> 5) & 0x7);
9810 op1 = offset = ctx->opcode & 0x1f;
9815 case M16_OPC_ADDIUSP:
9817 int16_t imm = ((uint8_t) ctx->opcode) << 2;
9819 gen_arith_imm(ctx, OPC_ADDIU, rx, 29, imm);
9822 case M16_OPC_ADDIUPC:
9823 gen_addiupc(ctx, rx, ((uint8_t) ctx->opcode) << 2, 0, 0);
9826 offset = (ctx->opcode & 0x7ff) << 1;
9827 offset = (int16_t)(offset << 4) >> 4;
9828 gen_compute_branch(ctx, OPC_BEQ, 2, 0, 0, offset);
9829 /* No delay slot, so just process as a normal instruction */
9832 offset = cpu_lduw_code(env, ctx->pc + 2);
9833 offset = (((ctx->opcode & 0x1f) << 21)
9834 | ((ctx->opcode >> 5) & 0x1f) << 16
9836 op = ((ctx->opcode >> 10) & 0x1) ? OPC_JALXS : OPC_JALS;
9837 gen_compute_branch(ctx, op, 4, rx, ry, offset);
9842 gen_compute_branch(ctx, OPC_BEQ, 2, rx, 0, ((int8_t)ctx->opcode) << 1);
9843 /* No delay slot, so just process as a normal instruction */
9846 gen_compute_branch(ctx, OPC_BNE, 2, rx, 0, ((int8_t)ctx->opcode) << 1);
9847 /* No delay slot, so just process as a normal instruction */
9850 switch (ctx->opcode & 0x3) {
9852 gen_shift_imm(ctx, OPC_SLL, rx, ry, sa);
9855 #if defined(TARGET_MIPS64)
9857 gen_shift_imm(ctx, OPC_DSLL, rx, ry, sa);
9859 generate_exception(ctx, EXCP_RI);
9863 gen_shift_imm(ctx, OPC_SRL, rx, ry, sa);
9866 gen_shift_imm(ctx, OPC_SRA, rx, ry, sa);
9870 #if defined(TARGET_MIPS64)
9873 gen_ld(ctx, OPC_LD, ry, rx, offset << 3);
9878 int16_t imm = (int8_t)((ctx->opcode & 0xf) << 4) >> 4;
9880 if ((ctx->opcode >> 4) & 1) {
9881 #if defined(TARGET_MIPS64)
9883 gen_arith_imm(ctx, OPC_DADDIU, ry, rx, imm);
9885 generate_exception(ctx, EXCP_RI);
9888 gen_arith_imm(ctx, OPC_ADDIU, ry, rx, imm);
9892 case M16_OPC_ADDIU8:
9894 int16_t imm = (int8_t) ctx->opcode;
9896 gen_arith_imm(ctx, OPC_ADDIU, rx, rx, imm);
9901 int16_t imm = (uint8_t) ctx->opcode;
9902 gen_slt_imm(ctx, OPC_SLTI, 24, rx, imm);
9907 int16_t imm = (uint8_t) ctx->opcode;
9908 gen_slt_imm(ctx, OPC_SLTIU, 24, rx, imm);
9915 funct = (ctx->opcode >> 8) & 0x7;
9918 gen_compute_branch(ctx, OPC_BEQ, 2, 24, 0,
9919 ((int8_t)ctx->opcode) << 1);
9922 gen_compute_branch(ctx, OPC_BNE, 2, 24, 0,
9923 ((int8_t)ctx->opcode) << 1);
9926 gen_st(ctx, OPC_SW, 31, 29, (ctx->opcode & 0xff) << 2);
9929 gen_arith_imm(ctx, OPC_ADDIU, 29, 29,
9930 ((int8_t)ctx->opcode) << 3);
9934 int do_ra = ctx->opcode & (1 << 6);
9935 int do_s0 = ctx->opcode & (1 << 5);
9936 int do_s1 = ctx->opcode & (1 << 4);
9937 int framesize = ctx->opcode & 0xf;
9939 if (framesize == 0) {
9942 framesize = framesize << 3;
9945 if (ctx->opcode & (1 << 7)) {
9946 gen_mips16_save(ctx, 0, 0,
9947 do_ra, do_s0, do_s1, framesize);
9949 gen_mips16_restore(ctx, 0, 0,
9950 do_ra, do_s0, do_s1, framesize);
9956 int rz = xlat(ctx->opcode & 0x7);
9958 reg32 = (((ctx->opcode >> 3) & 0x3) << 3) |
9959 ((ctx->opcode >> 5) & 0x7);
9960 gen_arith(ctx, OPC_ADDU, reg32, rz, 0);
9964 reg32 = ctx->opcode & 0x1f;
9965 gen_arith(ctx, OPC_ADDU, ry, reg32, 0);
9968 generate_exception(ctx, EXCP_RI);
9975 int16_t imm = (uint8_t) ctx->opcode;
9977 gen_arith_imm(ctx, OPC_ADDIU, rx, 0, imm);
9982 int16_t imm = (uint8_t) ctx->opcode;
9983 gen_logic_imm(ctx, OPC_XORI, 24, rx, imm);
9986 #if defined(TARGET_MIPS64)
9989 gen_st(ctx, OPC_SD, ry, rx, offset << 3);
9993 gen_ld(ctx, OPC_LB, ry, rx, offset);
9996 gen_ld(ctx, OPC_LH, ry, rx, offset << 1);
9999 gen_ld(ctx, OPC_LW, rx, 29, ((uint8_t)ctx->opcode) << 2);
10002 gen_ld(ctx, OPC_LW, ry, rx, offset << 2);
10005 gen_ld(ctx, OPC_LBU, ry, rx, offset);
10008 gen_ld(ctx, OPC_LHU, ry, rx, offset << 1);
10011 gen_ld(ctx, OPC_LWPC, rx, 0, ((uint8_t)ctx->opcode) << 2);
10013 #if defined (TARGET_MIPS64)
10015 check_mips_64(ctx);
10016 gen_ld(ctx, OPC_LWU, ry, rx, offset << 2);
10020 gen_st(ctx, OPC_SB, ry, rx, offset);
10023 gen_st(ctx, OPC_SH, ry, rx, offset << 1);
10026 gen_st(ctx, OPC_SW, rx, 29, ((uint8_t)ctx->opcode) << 2);
10029 gen_st(ctx, OPC_SW, ry, rx, offset << 2);
10033 int rz = xlat((ctx->opcode >> 2) & 0x7);
10036 switch (ctx->opcode & 0x3) {
10038 mips32_op = OPC_ADDU;
10041 mips32_op = OPC_SUBU;
10043 #if defined(TARGET_MIPS64)
10045 mips32_op = OPC_DADDU;
10046 check_mips_64(ctx);
10049 mips32_op = OPC_DSUBU;
10050 check_mips_64(ctx);
10054 generate_exception(ctx, EXCP_RI);
10058 gen_arith(ctx, mips32_op, rz, rx, ry);
10067 int nd = (ctx->opcode >> 7) & 0x1;
10068 int link = (ctx->opcode >> 6) & 0x1;
10069 int ra = (ctx->opcode >> 5) & 0x1;
10072 op = nd ? OPC_JALRC : OPC_JALRS;
10077 gen_compute_branch(ctx, op, 2, ra ? 31 : rx, 31, 0);
10084 /* XXX: not clear which exception should be raised
10085 * when in debug mode...
10087 check_insn(ctx, ISA_MIPS32);
10088 if (!(ctx->hflags & MIPS_HFLAG_DM)) {
10089 generate_exception(ctx, EXCP_DBp);
10091 generate_exception(ctx, EXCP_DBp);
10095 gen_slt(ctx, OPC_SLT, 24, rx, ry);
10098 gen_slt(ctx, OPC_SLTU, 24, rx, ry);
10101 generate_exception(ctx, EXCP_BREAK);
10104 gen_shift(ctx, OPC_SLLV, ry, rx, ry);
10107 gen_shift(ctx, OPC_SRLV, ry, rx, ry);
10110 gen_shift(ctx, OPC_SRAV, ry, rx, ry);
10112 #if defined (TARGET_MIPS64)
10114 check_mips_64(ctx);
10115 gen_shift_imm(ctx, OPC_DSRL, ry, ry, sa);
10119 gen_logic(ctx, OPC_XOR, 24, rx, ry);
10122 gen_arith(ctx, OPC_SUBU, rx, 0, ry);
10125 gen_logic(ctx, OPC_AND, rx, rx, ry);
10128 gen_logic(ctx, OPC_OR, rx, rx, ry);
10131 gen_logic(ctx, OPC_XOR, rx, rx, ry);
10134 gen_logic(ctx, OPC_NOR, rx, ry, 0);
10137 gen_HILO(ctx, OPC_MFHI, rx);
10141 case RR_RY_CNVT_ZEB:
10142 tcg_gen_ext8u_tl(cpu_gpr[rx], cpu_gpr[rx]);
10144 case RR_RY_CNVT_ZEH:
10145 tcg_gen_ext16u_tl(cpu_gpr[rx], cpu_gpr[rx]);
10147 case RR_RY_CNVT_SEB:
10148 tcg_gen_ext8s_tl(cpu_gpr[rx], cpu_gpr[rx]);
10150 case RR_RY_CNVT_SEH:
10151 tcg_gen_ext16s_tl(cpu_gpr[rx], cpu_gpr[rx]);
10153 #if defined (TARGET_MIPS64)
10154 case RR_RY_CNVT_ZEW:
10155 check_mips_64(ctx);
10156 tcg_gen_ext32u_tl(cpu_gpr[rx], cpu_gpr[rx]);
10158 case RR_RY_CNVT_SEW:
10159 check_mips_64(ctx);
10160 tcg_gen_ext32s_tl(cpu_gpr[rx], cpu_gpr[rx]);
10164 generate_exception(ctx, EXCP_RI);
10169 gen_HILO(ctx, OPC_MFLO, rx);
10171 #if defined (TARGET_MIPS64)
10173 check_mips_64(ctx);
10174 gen_shift_imm(ctx, OPC_DSRA, ry, ry, sa);
10177 check_mips_64(ctx);
10178 gen_shift(ctx, OPC_DSLLV, ry, rx, ry);
10181 check_mips_64(ctx);
10182 gen_shift(ctx, OPC_DSRLV, ry, rx, ry);
10185 check_mips_64(ctx);
10186 gen_shift(ctx, OPC_DSRAV, ry, rx, ry);
10190 gen_muldiv(ctx, OPC_MULT, rx, ry);
10193 gen_muldiv(ctx, OPC_MULTU, rx, ry);
10196 gen_muldiv(ctx, OPC_DIV, rx, ry);
10199 gen_muldiv(ctx, OPC_DIVU, rx, ry);
10201 #if defined (TARGET_MIPS64)
10203 check_mips_64(ctx);
10204 gen_muldiv(ctx, OPC_DMULT, rx, ry);
10207 check_mips_64(ctx);
10208 gen_muldiv(ctx, OPC_DMULTU, rx, ry);
10211 check_mips_64(ctx);
10212 gen_muldiv(ctx, OPC_DDIV, rx, ry);
10215 check_mips_64(ctx);
10216 gen_muldiv(ctx, OPC_DDIVU, rx, ry);
10220 generate_exception(ctx, EXCP_RI);
10224 case M16_OPC_EXTEND:
10225 decode_extended_mips16_opc(env, ctx, is_branch);
10228 #if defined(TARGET_MIPS64)
10230 funct = (ctx->opcode >> 8) & 0x7;
10231 decode_i64_mips16(ctx, ry, funct, offset, 0);
10235 generate_exception(ctx, EXCP_RI);
10242 /* microMIPS extension to MIPS32/MIPS64 */
10245 * microMIPS32/microMIPS64 major opcodes
10247 * 1. MIPS Architecture for Programmers Volume II-B:
10248 * The microMIPS32 Instruction Set (Revision 3.05)
10250 * Table 6.2 microMIPS32 Encoding of Major Opcode Field
10252 * 2. MIPS Architecture For Programmers Volume II-A:
10253 * The MIPS64 Instruction Set (Revision 3.51)
10281 POOL32S = 0x16, /* MIPS64 */
10282 DADDIU32 = 0x17, /* MIPS64 */
10284 /* 0x1f is reserved */
10293 /* 0x20 is reserved */
10303 /* 0x28 and 0x29 are reserved */
10313 /* 0x30 and 0x31 are reserved */
10320 SD32 = 0x36, /* MIPS64 */
10321 LD32 = 0x37, /* MIPS64 */
10323 /* 0x38 and 0x39 are reserved */
10334 /* POOL32A encoding of minor opcode field */
10337 /* These opcodes are distinguished only by bits 9..6; those bits are
10338 * what are recorded below. */
10364 /* The following can be distinguished by their lower 6 bits. */
10370 /* POOL32AXF encoding of minor opcode field extension */
10373 * 1. MIPS Architecture for Programmers Volume II-B:
10374 * The microMIPS32 Instruction Set (Revision 3.05)
10376 * Table 6.5 POOL32Axf Encoding of Minor Opcode Extension Field
10378 * 2. MIPS Architecture for Programmers VolumeIV-e:
10379 * The MIPS DSP Application-Specific Extension
10380 * to the microMIPS32 Architecture (Revision 2.34)
10382 * Table 5.5 POOL32Axf Encoding of Minor Opcode Extension Field
10397 /* begin of microMIPS32 DSP */
10399 /* bits 13..12 for 0x01 */
10405 /* bits 13..12 for 0x2a */
10411 /* bits 13..12 for 0x32 */
10415 /* end of microMIPS32 DSP */
10417 /* bits 15..12 for 0x2c */
10433 /* bits 15..12 for 0x34 */
10441 /* bits 15..12 for 0x3c */
10443 JR = 0x0, /* alias */
10448 /* bits 15..12 for 0x05 */
10452 /* bits 15..12 for 0x0d */
10462 /* bits 15..12 for 0x15 */
10468 /* bits 15..12 for 0x1d */
10472 /* bits 15..12 for 0x2d */
10477 /* bits 15..12 for 0x35 */
10484 /* POOL32B encoding of minor opcode field (bits 15..12) */
10500 /* POOL32C encoding of minor opcode field (bits 15..12) */
10508 /* 0xa is reserved */
10515 /* 0x6 is reserved */
10521 /* POOL32F encoding of minor opcode field (bits 5..0) */
10524 /* These are the bit 7..6 values */
10535 /* These are the bit 8..6 values */
10579 CABS_COND_FMT = 0x1c, /* MIPS3D */
10583 /* POOL32Fxf encoding of minor opcode extension field */
10621 /* POOL32I encoding of minor opcode field (bits 25..21) */
10646 /* These overlap and are distinguished by bit16 of the instruction */
10655 /* POOL16A encoding of minor opcode field */
10662 /* POOL16B encoding of minor opcode field */
10669 /* POOL16C encoding of minor opcode field */
10689 /* POOL16D encoding of minor opcode field */
10696 /* POOL16E encoding of minor opcode field */
10703 static int mmreg (int r)
10705 static const int map[] = { 16, 17, 2, 3, 4, 5, 6, 7 };
10710 /* Used for 16-bit store instructions. */
10711 static int mmreg2 (int r)
10713 static const int map[] = { 0, 17, 2, 3, 4, 5, 6, 7 };
10718 #define uMIPS_RD(op) ((op >> 7) & 0x7)
10719 #define uMIPS_RS(op) ((op >> 4) & 0x7)
10720 #define uMIPS_RS2(op) uMIPS_RS(op)
10721 #define uMIPS_RS1(op) ((op >> 1) & 0x7)
10722 #define uMIPS_RD5(op) ((op >> 5) & 0x1f)
10723 #define uMIPS_RS5(op) (op & 0x1f)
10725 /* Signed immediate */
10726 #define SIMM(op, start, width) \
10727 ((int32_t)(((op >> start) & ((~0U) >> (32-width))) \
10730 /* Zero-extended immediate */
10731 #define ZIMM(op, start, width) ((op >> start) & ((~0U) >> (32-width)))
10733 static void gen_addiur1sp(DisasContext *ctx)
10735 int rd = mmreg(uMIPS_RD(ctx->opcode));
10737 gen_arith_imm(ctx, OPC_ADDIU, rd, 29, ((ctx->opcode >> 1) & 0x3f) << 2);
10740 static void gen_addiur2(DisasContext *ctx)
10742 static const int decoded_imm[] = { 1, 4, 8, 12, 16, 20, 24, -1 };
10743 int rd = mmreg(uMIPS_RD(ctx->opcode));
10744 int rs = mmreg(uMIPS_RS(ctx->opcode));
10746 gen_arith_imm(ctx, OPC_ADDIU, rd, rs, decoded_imm[ZIMM(ctx->opcode, 1, 3)]);
10749 static void gen_addiusp(DisasContext *ctx)
10751 int encoded = ZIMM(ctx->opcode, 1, 9);
10754 if (encoded <= 1) {
10755 decoded = 256 + encoded;
10756 } else if (encoded <= 255) {
10758 } else if (encoded <= 509) {
10759 decoded = encoded - 512;
10761 decoded = encoded - 768;
10764 gen_arith_imm(ctx, OPC_ADDIU, 29, 29, decoded << 2);
10767 static void gen_addius5(DisasContext *ctx)
10769 int imm = SIMM(ctx->opcode, 1, 4);
10770 int rd = (ctx->opcode >> 5) & 0x1f;
10772 gen_arith_imm(ctx, OPC_ADDIU, rd, rd, imm);
10775 static void gen_andi16(DisasContext *ctx)
10777 static const int decoded_imm[] = { 128, 1, 2, 3, 4, 7, 8, 15, 16,
10778 31, 32, 63, 64, 255, 32768, 65535 };
10779 int rd = mmreg(uMIPS_RD(ctx->opcode));
10780 int rs = mmreg(uMIPS_RS(ctx->opcode));
10781 int encoded = ZIMM(ctx->opcode, 0, 4);
10783 gen_logic_imm(ctx, OPC_ANDI, rd, rs, decoded_imm[encoded]);
10786 static void gen_ldst_multiple (DisasContext *ctx, uint32_t opc, int reglist,
10787 int base, int16_t offset)
10789 const char *opn = "ldst_multiple";
10793 if (ctx->hflags & MIPS_HFLAG_BMASK) {
10794 generate_exception(ctx, EXCP_RI);
10798 t0 = tcg_temp_new();
10800 gen_base_offset_addr(ctx, t0, base, offset);
10802 t1 = tcg_const_tl(reglist);
10803 t2 = tcg_const_i32(ctx->mem_idx);
10805 save_cpu_state(ctx, 1);
10808 gen_helper_lwm(cpu_env, t0, t1, t2);
10812 gen_helper_swm(cpu_env, t0, t1, t2);
10815 #ifdef TARGET_MIPS64
10817 gen_helper_ldm(cpu_env, t0, t1, t2);
10821 gen_helper_sdm(cpu_env, t0, t1, t2);
10827 MIPS_DEBUG("%s, %x, %d(%s)", opn, reglist, offset, regnames[base]);
10830 tcg_temp_free_i32(t2);
10834 static void gen_pool16c_insn(DisasContext *ctx, int *is_branch)
10836 int rd = mmreg((ctx->opcode >> 3) & 0x7);
10837 int rs = mmreg(ctx->opcode & 0x7);
10840 switch (((ctx->opcode) >> 4) & 0x3f) {
10845 gen_logic(ctx, OPC_NOR, rd, rs, 0);
10851 gen_logic(ctx, OPC_XOR, rd, rd, rs);
10857 gen_logic(ctx, OPC_AND, rd, rd, rs);
10863 gen_logic(ctx, OPC_OR, rd, rd, rs);
10870 static const int lwm_convert[] = { 0x11, 0x12, 0x13, 0x14 };
10871 int offset = ZIMM(ctx->opcode, 0, 4);
10873 gen_ldst_multiple(ctx, LWM32, lwm_convert[(ctx->opcode >> 4) & 0x3],
10882 static const int swm_convert[] = { 0x11, 0x12, 0x13, 0x14 };
10883 int offset = ZIMM(ctx->opcode, 0, 4);
10885 gen_ldst_multiple(ctx, SWM32, swm_convert[(ctx->opcode >> 4) & 0x3],
10892 int reg = ctx->opcode & 0x1f;
10894 gen_compute_branch(ctx, OPC_JR, 2, reg, 0, 0);
10901 int reg = ctx->opcode & 0x1f;
10903 gen_compute_branch(ctx, OPC_JR, 2, reg, 0, 0);
10904 /* Let normal delay slot handling in our caller take us
10905 to the branch target. */
10917 int reg = ctx->opcode & 0x1f;
10919 gen_compute_branch(ctx, opc, 2, reg, 31, 0);
10925 gen_HILO(ctx, OPC_MFHI, uMIPS_RS5(ctx->opcode));
10929 gen_HILO(ctx, OPC_MFLO, uMIPS_RS5(ctx->opcode));
10932 generate_exception(ctx, EXCP_BREAK);
10935 /* XXX: not clear which exception should be raised
10936 * when in debug mode...
10938 check_insn(ctx, ISA_MIPS32);
10939 if (!(ctx->hflags & MIPS_HFLAG_DM)) {
10940 generate_exception(ctx, EXCP_DBp);
10942 generate_exception(ctx, EXCP_DBp);
10945 case JRADDIUSP + 0:
10946 case JRADDIUSP + 1:
10948 int imm = ZIMM(ctx->opcode, 0, 5);
10950 gen_compute_branch(ctx, OPC_JR, 2, 31, 0, 0);
10951 gen_arith_imm(ctx, OPC_ADDIU, 29, 29, imm << 2);
10952 /* Let normal delay slot handling in our caller take us
10953 to the branch target. */
10957 generate_exception(ctx, EXCP_RI);
10962 static void gen_ldxs (DisasContext *ctx, int base, int index, int rd)
10964 TCGv t0 = tcg_temp_new();
10965 TCGv t1 = tcg_temp_new();
10967 gen_load_gpr(t0, base);
10970 gen_load_gpr(t1, index);
10971 tcg_gen_shli_tl(t1, t1, 2);
10972 gen_op_addr_add(ctx, t0, t1, t0);
10975 tcg_gen_qemu_ld32s(t1, t0, ctx->mem_idx);
10976 gen_store_gpr(t1, rd);
10982 static void gen_ldst_pair (DisasContext *ctx, uint32_t opc, int rd,
10983 int base, int16_t offset)
10985 const char *opn = "ldst_pair";
10988 if (ctx->hflags & MIPS_HFLAG_BMASK || rd == 31) {
10989 generate_exception(ctx, EXCP_RI);
10993 t0 = tcg_temp_new();
10994 t1 = tcg_temp_new();
10996 gen_base_offset_addr(ctx, t0, base, offset);
11001 generate_exception(ctx, EXCP_RI);
11004 tcg_gen_qemu_ld32s(t1, t0, ctx->mem_idx);
11005 gen_store_gpr(t1, rd);
11006 tcg_gen_movi_tl(t1, 4);
11007 gen_op_addr_add(ctx, t0, t0, t1);
11008 tcg_gen_qemu_ld32s(t1, t0, ctx->mem_idx);
11009 gen_store_gpr(t1, rd+1);
11013 gen_load_gpr(t1, rd);
11014 tcg_gen_qemu_st32(t1, t0, ctx->mem_idx);
11015 tcg_gen_movi_tl(t1, 4);
11016 gen_op_addr_add(ctx, t0, t0, t1);
11017 gen_load_gpr(t1, rd+1);
11018 tcg_gen_qemu_st32(t1, t0, ctx->mem_idx);
11021 #ifdef TARGET_MIPS64
11024 generate_exception(ctx, EXCP_RI);
11027 tcg_gen_qemu_ld64(t1, t0, ctx->mem_idx);
11028 gen_store_gpr(t1, rd);
11029 tcg_gen_movi_tl(t1, 8);
11030 gen_op_addr_add(ctx, t0, t0, t1);
11031 tcg_gen_qemu_ld64(t1, t0, ctx->mem_idx);
11032 gen_store_gpr(t1, rd+1);
11036 gen_load_gpr(t1, rd);
11037 tcg_gen_qemu_st64(t1, t0, ctx->mem_idx);
11038 tcg_gen_movi_tl(t1, 8);
11039 gen_op_addr_add(ctx, t0, t0, t1);
11040 gen_load_gpr(t1, rd+1);
11041 tcg_gen_qemu_st64(t1, t0, ctx->mem_idx);
11046 (void)opn; /* avoid a compiler warning */
11047 MIPS_DEBUG("%s, %s, %d(%s)", opn, regnames[rd], offset, regnames[base]);
11052 static void gen_pool32axf (CPUMIPSState *env, DisasContext *ctx, int rt, int rs,
11055 int extension = (ctx->opcode >> 6) & 0x3f;
11056 int minor = (ctx->opcode >> 12) & 0xf;
11057 uint32_t mips32_op;
11059 switch (extension) {
11061 mips32_op = OPC_TEQ;
11064 mips32_op = OPC_TGE;
11067 mips32_op = OPC_TGEU;
11070 mips32_op = OPC_TLT;
11073 mips32_op = OPC_TLTU;
11076 mips32_op = OPC_TNE;
11078 gen_trap(ctx, mips32_op, rs, rt, -1);
11080 #ifndef CONFIG_USER_ONLY
11083 check_cp0_enabled(ctx);
11085 /* Treat as NOP. */
11088 gen_mfc0(ctx, cpu_gpr[rt], rs, (ctx->opcode >> 11) & 0x7);
11092 check_cp0_enabled(ctx);
11094 TCGv t0 = tcg_temp_new();
11096 gen_load_gpr(t0, rt);
11097 gen_mtc0(ctx, t0, rs, (ctx->opcode >> 11) & 0x7);
11105 gen_bshfl(ctx, OPC_SEB, rs, rt);
11108 gen_bshfl(ctx, OPC_SEH, rs, rt);
11111 mips32_op = OPC_CLO;
11114 mips32_op = OPC_CLZ;
11116 check_insn(ctx, ISA_MIPS32);
11117 gen_cl(ctx, mips32_op, rt, rs);
11120 gen_rdhwr(ctx, rt, rs);
11123 gen_bshfl(ctx, OPC_WSBH, rs, rt);
11126 mips32_op = OPC_MULT;
11129 mips32_op = OPC_MULTU;
11132 mips32_op = OPC_DIV;
11135 mips32_op = OPC_DIVU;
11138 mips32_op = OPC_MADD;
11141 mips32_op = OPC_MADDU;
11144 mips32_op = OPC_MSUB;
11147 mips32_op = OPC_MSUBU;
11149 check_insn(ctx, ISA_MIPS32);
11150 gen_muldiv(ctx, mips32_op, rs, rt);
11153 goto pool32axf_invalid;
11164 generate_exception_err(ctx, EXCP_CpU, 2);
11167 goto pool32axf_invalid;
11174 gen_compute_branch (ctx, OPC_JALR, 4, rs, rt, 0);
11179 gen_compute_branch (ctx, OPC_JALRS, 4, rs, rt, 0);
11183 goto pool32axf_invalid;
11189 check_cp0_enabled(ctx);
11190 check_insn(ctx, ISA_MIPS32R2);
11191 gen_load_srsgpr(rt, rs);
11194 check_cp0_enabled(ctx);
11195 check_insn(ctx, ISA_MIPS32R2);
11196 gen_store_srsgpr(rt, rs);
11199 goto pool32axf_invalid;
11202 #ifndef CONFIG_USER_ONLY
11206 mips32_op = OPC_TLBP;
11209 mips32_op = OPC_TLBR;
11212 mips32_op = OPC_TLBWI;
11215 mips32_op = OPC_TLBWR;
11218 mips32_op = OPC_WAIT;
11221 mips32_op = OPC_DERET;
11224 mips32_op = OPC_ERET;
11226 gen_cp0(env, ctx, mips32_op, rt, rs);
11229 goto pool32axf_invalid;
11235 check_cp0_enabled(ctx);
11237 TCGv t0 = tcg_temp_new();
11239 save_cpu_state(ctx, 1);
11240 gen_helper_di(t0, cpu_env);
11241 gen_store_gpr(t0, rs);
11242 /* Stop translation as we may have switched the execution mode */
11243 ctx->bstate = BS_STOP;
11248 check_cp0_enabled(ctx);
11250 TCGv t0 = tcg_temp_new();
11252 save_cpu_state(ctx, 1);
11253 gen_helper_ei(t0, cpu_env);
11254 gen_store_gpr(t0, rs);
11255 /* Stop translation as we may have switched the execution mode */
11256 ctx->bstate = BS_STOP;
11261 goto pool32axf_invalid;
11271 generate_exception(ctx, EXCP_SYSCALL);
11272 ctx->bstate = BS_STOP;
11275 check_insn(ctx, ISA_MIPS32);
11276 if (!(ctx->hflags & MIPS_HFLAG_DM)) {
11277 generate_exception(ctx, EXCP_DBp);
11279 generate_exception(ctx, EXCP_DBp);
11283 goto pool32axf_invalid;
11289 gen_HILO(ctx, OPC_MFHI, rs);
11292 gen_HILO(ctx, OPC_MFLO, rs);
11295 gen_HILO(ctx, OPC_MTHI, rs);
11298 gen_HILO(ctx, OPC_MTLO, rs);
11301 goto pool32axf_invalid;
11306 MIPS_INVAL("pool32axf");
11307 generate_exception(ctx, EXCP_RI);
11312 /* Values for microMIPS fmt field. Variable-width, depending on which
11313 formats the instruction supports. */
11332 static void gen_pool32fxf(DisasContext *ctx, int rt, int rs)
11334 int extension = (ctx->opcode >> 6) & 0x3ff;
11335 uint32_t mips32_op;
11337 #define FLOAT_1BIT_FMT(opc, fmt) (fmt << 8) | opc
11338 #define FLOAT_2BIT_FMT(opc, fmt) (fmt << 7) | opc
11339 #define COND_FLOAT_MOV(opc, cond) (cond << 7) | opc
11341 switch (extension) {
11342 case FLOAT_1BIT_FMT(CFC1, 0):
11343 mips32_op = OPC_CFC1;
11345 case FLOAT_1BIT_FMT(CTC1, 0):
11346 mips32_op = OPC_CTC1;
11348 case FLOAT_1BIT_FMT(MFC1, 0):
11349 mips32_op = OPC_MFC1;
11351 case FLOAT_1BIT_FMT(MTC1, 0):
11352 mips32_op = OPC_MTC1;
11354 case FLOAT_1BIT_FMT(MFHC1, 0):
11355 mips32_op = OPC_MFHC1;
11357 case FLOAT_1BIT_FMT(MTHC1, 0):
11358 mips32_op = OPC_MTHC1;
11360 gen_cp1(ctx, mips32_op, rt, rs);
11363 /* Reciprocal square root */
11364 case FLOAT_1BIT_FMT(RSQRT_FMT, FMT_SD_S):
11365 mips32_op = OPC_RSQRT_S;
11367 case FLOAT_1BIT_FMT(RSQRT_FMT, FMT_SD_D):
11368 mips32_op = OPC_RSQRT_D;
11372 case FLOAT_1BIT_FMT(SQRT_FMT, FMT_SD_S):
11373 mips32_op = OPC_SQRT_S;
11375 case FLOAT_1BIT_FMT(SQRT_FMT, FMT_SD_D):
11376 mips32_op = OPC_SQRT_D;
11380 case FLOAT_1BIT_FMT(RECIP_FMT, FMT_SD_S):
11381 mips32_op = OPC_RECIP_S;
11383 case FLOAT_1BIT_FMT(RECIP_FMT, FMT_SD_D):
11384 mips32_op = OPC_RECIP_D;
11388 case FLOAT_1BIT_FMT(FLOOR_L, FMT_SD_S):
11389 mips32_op = OPC_FLOOR_L_S;
11391 case FLOAT_1BIT_FMT(FLOOR_L, FMT_SD_D):
11392 mips32_op = OPC_FLOOR_L_D;
11394 case FLOAT_1BIT_FMT(FLOOR_W, FMT_SD_S):
11395 mips32_op = OPC_FLOOR_W_S;
11397 case FLOAT_1BIT_FMT(FLOOR_W, FMT_SD_D):
11398 mips32_op = OPC_FLOOR_W_D;
11402 case FLOAT_1BIT_FMT(CEIL_L, FMT_SD_S):
11403 mips32_op = OPC_CEIL_L_S;
11405 case FLOAT_1BIT_FMT(CEIL_L, FMT_SD_D):
11406 mips32_op = OPC_CEIL_L_D;
11408 case FLOAT_1BIT_FMT(CEIL_W, FMT_SD_S):
11409 mips32_op = OPC_CEIL_W_S;
11411 case FLOAT_1BIT_FMT(CEIL_W, FMT_SD_D):
11412 mips32_op = OPC_CEIL_W_D;
11416 case FLOAT_1BIT_FMT(TRUNC_L, FMT_SD_S):
11417 mips32_op = OPC_TRUNC_L_S;
11419 case FLOAT_1BIT_FMT(TRUNC_L, FMT_SD_D):
11420 mips32_op = OPC_TRUNC_L_D;
11422 case FLOAT_1BIT_FMT(TRUNC_W, FMT_SD_S):
11423 mips32_op = OPC_TRUNC_W_S;
11425 case FLOAT_1BIT_FMT(TRUNC_W, FMT_SD_D):
11426 mips32_op = OPC_TRUNC_W_D;
11430 case FLOAT_1BIT_FMT(ROUND_L, FMT_SD_S):
11431 mips32_op = OPC_ROUND_L_S;
11433 case FLOAT_1BIT_FMT(ROUND_L, FMT_SD_D):
11434 mips32_op = OPC_ROUND_L_D;
11436 case FLOAT_1BIT_FMT(ROUND_W, FMT_SD_S):
11437 mips32_op = OPC_ROUND_W_S;
11439 case FLOAT_1BIT_FMT(ROUND_W, FMT_SD_D):
11440 mips32_op = OPC_ROUND_W_D;
11443 /* Integer to floating-point conversion */
11444 case FLOAT_1BIT_FMT(CVT_L, FMT_SD_S):
11445 mips32_op = OPC_CVT_L_S;
11447 case FLOAT_1BIT_FMT(CVT_L, FMT_SD_D):
11448 mips32_op = OPC_CVT_L_D;
11450 case FLOAT_1BIT_FMT(CVT_W, FMT_SD_S):
11451 mips32_op = OPC_CVT_W_S;
11453 case FLOAT_1BIT_FMT(CVT_W, FMT_SD_D):
11454 mips32_op = OPC_CVT_W_D;
11457 /* Paired-foo conversions */
11458 case FLOAT_1BIT_FMT(CVT_S_PL, 0):
11459 mips32_op = OPC_CVT_S_PL;
11461 case FLOAT_1BIT_FMT(CVT_S_PU, 0):
11462 mips32_op = OPC_CVT_S_PU;
11464 case FLOAT_1BIT_FMT(CVT_PW_PS, 0):
11465 mips32_op = OPC_CVT_PW_PS;
11467 case FLOAT_1BIT_FMT(CVT_PS_PW, 0):
11468 mips32_op = OPC_CVT_PS_PW;
11471 /* Floating-point moves */
11472 case FLOAT_2BIT_FMT(MOV_FMT, FMT_SDPS_S):
11473 mips32_op = OPC_MOV_S;
11475 case FLOAT_2BIT_FMT(MOV_FMT, FMT_SDPS_D):
11476 mips32_op = OPC_MOV_D;
11478 case FLOAT_2BIT_FMT(MOV_FMT, FMT_SDPS_PS):
11479 mips32_op = OPC_MOV_PS;
11482 /* Absolute value */
11483 case FLOAT_2BIT_FMT(ABS_FMT, FMT_SDPS_S):
11484 mips32_op = OPC_ABS_S;
11486 case FLOAT_2BIT_FMT(ABS_FMT, FMT_SDPS_D):
11487 mips32_op = OPC_ABS_D;
11489 case FLOAT_2BIT_FMT(ABS_FMT, FMT_SDPS_PS):
11490 mips32_op = OPC_ABS_PS;
11494 case FLOAT_2BIT_FMT(NEG_FMT, FMT_SDPS_S):
11495 mips32_op = OPC_NEG_S;
11497 case FLOAT_2BIT_FMT(NEG_FMT, FMT_SDPS_D):
11498 mips32_op = OPC_NEG_D;
11500 case FLOAT_2BIT_FMT(NEG_FMT, FMT_SDPS_PS):
11501 mips32_op = OPC_NEG_PS;
11504 /* Reciprocal square root step */
11505 case FLOAT_2BIT_FMT(RSQRT1_FMT, FMT_SDPS_S):
11506 mips32_op = OPC_RSQRT1_S;
11508 case FLOAT_2BIT_FMT(RSQRT1_FMT, FMT_SDPS_D):
11509 mips32_op = OPC_RSQRT1_D;
11511 case FLOAT_2BIT_FMT(RSQRT1_FMT, FMT_SDPS_PS):
11512 mips32_op = OPC_RSQRT1_PS;
11515 /* Reciprocal step */
11516 case FLOAT_2BIT_FMT(RECIP1_FMT, FMT_SDPS_S):
11517 mips32_op = OPC_RECIP1_S;
11519 case FLOAT_2BIT_FMT(RECIP1_FMT, FMT_SDPS_D):
11520 mips32_op = OPC_RECIP1_S;
11522 case FLOAT_2BIT_FMT(RECIP1_FMT, FMT_SDPS_PS):
11523 mips32_op = OPC_RECIP1_PS;
11526 /* Conversions from double */
11527 case FLOAT_2BIT_FMT(CVT_D, FMT_SWL_S):
11528 mips32_op = OPC_CVT_D_S;
11530 case FLOAT_2BIT_FMT(CVT_D, FMT_SWL_W):
11531 mips32_op = OPC_CVT_D_W;
11533 case FLOAT_2BIT_FMT(CVT_D, FMT_SWL_L):
11534 mips32_op = OPC_CVT_D_L;
11537 /* Conversions from single */
11538 case FLOAT_2BIT_FMT(CVT_S, FMT_DWL_D):
11539 mips32_op = OPC_CVT_S_D;
11541 case FLOAT_2BIT_FMT(CVT_S, FMT_DWL_W):
11542 mips32_op = OPC_CVT_S_W;
11544 case FLOAT_2BIT_FMT(CVT_S, FMT_DWL_L):
11545 mips32_op = OPC_CVT_S_L;
11547 gen_farith(ctx, mips32_op, -1, rs, rt, 0);
11550 /* Conditional moves on floating-point codes */
11551 case COND_FLOAT_MOV(MOVT, 0):
11552 case COND_FLOAT_MOV(MOVT, 1):
11553 case COND_FLOAT_MOV(MOVT, 2):
11554 case COND_FLOAT_MOV(MOVT, 3):
11555 case COND_FLOAT_MOV(MOVT, 4):
11556 case COND_FLOAT_MOV(MOVT, 5):
11557 case COND_FLOAT_MOV(MOVT, 6):
11558 case COND_FLOAT_MOV(MOVT, 7):
11559 gen_movci(ctx, rt, rs, (ctx->opcode >> 13) & 0x7, 1);
11561 case COND_FLOAT_MOV(MOVF, 0):
11562 case COND_FLOAT_MOV(MOVF, 1):
11563 case COND_FLOAT_MOV(MOVF, 2):
11564 case COND_FLOAT_MOV(MOVF, 3):
11565 case COND_FLOAT_MOV(MOVF, 4):
11566 case COND_FLOAT_MOV(MOVF, 5):
11567 case COND_FLOAT_MOV(MOVF, 6):
11568 case COND_FLOAT_MOV(MOVF, 7):
11569 gen_movci(ctx, rt, rs, (ctx->opcode >> 13) & 0x7, 0);
11572 MIPS_INVAL("pool32fxf");
11573 generate_exception(ctx, EXCP_RI);
11578 static void decode_micromips32_opc (CPUMIPSState *env, DisasContext *ctx,
11579 uint16_t insn_hw1, int *is_branch)
11583 int rt, rs, rd, rr;
11585 uint32_t op, minor, mips32_op;
11586 uint32_t cond, fmt, cc;
11588 insn = cpu_lduw_code(env, ctx->pc + 2);
11589 ctx->opcode = (ctx->opcode << 16) | insn;
11591 rt = (ctx->opcode >> 21) & 0x1f;
11592 rs = (ctx->opcode >> 16) & 0x1f;
11593 rd = (ctx->opcode >> 11) & 0x1f;
11594 rr = (ctx->opcode >> 6) & 0x1f;
11595 imm = (int16_t) ctx->opcode;
11597 op = (ctx->opcode >> 26) & 0x3f;
11600 minor = ctx->opcode & 0x3f;
11603 minor = (ctx->opcode >> 6) & 0xf;
11606 mips32_op = OPC_SLL;
11609 mips32_op = OPC_SRA;
11612 mips32_op = OPC_SRL;
11615 mips32_op = OPC_ROTR;
11617 gen_shift_imm(ctx, mips32_op, rt, rs, rd);
11620 goto pool32a_invalid;
11624 minor = (ctx->opcode >> 6) & 0xf;
11628 mips32_op = OPC_ADD;
11631 mips32_op = OPC_ADDU;
11634 mips32_op = OPC_SUB;
11637 mips32_op = OPC_SUBU;
11640 mips32_op = OPC_MUL;
11642 gen_arith(ctx, mips32_op, rd, rs, rt);
11646 mips32_op = OPC_SLLV;
11649 mips32_op = OPC_SRLV;
11652 mips32_op = OPC_SRAV;
11655 mips32_op = OPC_ROTRV;
11657 gen_shift(ctx, mips32_op, rd, rs, rt);
11659 /* Logical operations */
11661 mips32_op = OPC_AND;
11664 mips32_op = OPC_OR;
11667 mips32_op = OPC_NOR;
11670 mips32_op = OPC_XOR;
11672 gen_logic(ctx, mips32_op, rd, rs, rt);
11674 /* Set less than */
11676 mips32_op = OPC_SLT;
11679 mips32_op = OPC_SLTU;
11681 gen_slt(ctx, mips32_op, rd, rs, rt);
11684 goto pool32a_invalid;
11688 minor = (ctx->opcode >> 6) & 0xf;
11690 /* Conditional moves */
11692 mips32_op = OPC_MOVN;
11695 mips32_op = OPC_MOVZ;
11697 gen_cond_move(ctx, mips32_op, rd, rs, rt);
11700 gen_ldxs(ctx, rs, rt, rd);
11703 goto pool32a_invalid;
11707 gen_bitops(ctx, OPC_INS, rt, rs, rr, rd);
11710 gen_bitops(ctx, OPC_EXT, rt, rs, rr, rd);
11713 gen_pool32axf(env, ctx, rt, rs, is_branch);
11716 generate_exception(ctx, EXCP_BREAK);
11720 MIPS_INVAL("pool32a");
11721 generate_exception(ctx, EXCP_RI);
11726 minor = (ctx->opcode >> 12) & 0xf;
11729 check_cp0_enabled(ctx);
11730 /* Treat as no-op. */
11734 /* COP2: Not implemented. */
11735 generate_exception_err(ctx, EXCP_CpU, 2);
11739 #ifdef TARGET_MIPS64
11743 gen_ldst_pair(ctx, minor, rt, rs, SIMM(ctx->opcode, 0, 12));
11747 #ifdef TARGET_MIPS64
11751 gen_ldst_multiple(ctx, minor, rt, rs, SIMM(ctx->opcode, 0, 12));
11754 MIPS_INVAL("pool32b");
11755 generate_exception(ctx, EXCP_RI);
11760 if (env->CP0_Config1 & (1 << CP0C1_FP)) {
11761 minor = ctx->opcode & 0x3f;
11762 check_cp1_enabled(ctx);
11765 mips32_op = OPC_ALNV_PS;
11768 mips32_op = OPC_MADD_S;
11771 mips32_op = OPC_MADD_D;
11774 mips32_op = OPC_MADD_PS;
11777 mips32_op = OPC_MSUB_S;
11780 mips32_op = OPC_MSUB_D;
11783 mips32_op = OPC_MSUB_PS;
11786 mips32_op = OPC_NMADD_S;
11789 mips32_op = OPC_NMADD_D;
11792 mips32_op = OPC_NMADD_PS;
11795 mips32_op = OPC_NMSUB_S;
11798 mips32_op = OPC_NMSUB_D;
11801 mips32_op = OPC_NMSUB_PS;
11803 gen_flt3_arith(ctx, mips32_op, rd, rr, rs, rt);
11805 case CABS_COND_FMT:
11806 cond = (ctx->opcode >> 6) & 0xf;
11807 cc = (ctx->opcode >> 13) & 0x7;
11808 fmt = (ctx->opcode >> 10) & 0x3;
11811 gen_cmpabs_s(ctx, cond, rt, rs, cc);
11814 gen_cmpabs_d(ctx, cond, rt, rs, cc);
11817 gen_cmpabs_ps(ctx, cond, rt, rs, cc);
11820 goto pool32f_invalid;
11824 cond = (ctx->opcode >> 6) & 0xf;
11825 cc = (ctx->opcode >> 13) & 0x7;
11826 fmt = (ctx->opcode >> 10) & 0x3;
11829 gen_cmp_s(ctx, cond, rt, rs, cc);
11832 gen_cmp_d(ctx, cond, rt, rs, cc);
11835 gen_cmp_ps(ctx, cond, rt, rs, cc);
11838 goto pool32f_invalid;
11842 gen_pool32fxf(ctx, rt, rs);
11846 switch ((ctx->opcode >> 6) & 0x7) {
11848 mips32_op = OPC_PLL_PS;
11851 mips32_op = OPC_PLU_PS;
11854 mips32_op = OPC_PUL_PS;
11857 mips32_op = OPC_PUU_PS;
11860 mips32_op = OPC_CVT_PS_S;
11862 gen_farith(ctx, mips32_op, rt, rs, rd, 0);
11865 goto pool32f_invalid;
11870 switch ((ctx->opcode >> 6) & 0x7) {
11872 mips32_op = OPC_LWXC1;
11875 mips32_op = OPC_SWXC1;
11878 mips32_op = OPC_LDXC1;
11881 mips32_op = OPC_SDXC1;
11884 mips32_op = OPC_LUXC1;
11887 mips32_op = OPC_SUXC1;
11889 gen_flt3_ldst(ctx, mips32_op, rd, rd, rt, rs);
11892 goto pool32f_invalid;
11897 fmt = (ctx->opcode >> 9) & 0x3;
11898 switch ((ctx->opcode >> 6) & 0x7) {
11902 mips32_op = OPC_RSQRT2_S;
11905 mips32_op = OPC_RSQRT2_D;
11908 mips32_op = OPC_RSQRT2_PS;
11911 goto pool32f_invalid;
11917 mips32_op = OPC_RECIP2_S;
11920 mips32_op = OPC_RECIP2_D;
11923 mips32_op = OPC_RECIP2_PS;
11926 goto pool32f_invalid;
11930 mips32_op = OPC_ADDR_PS;
11933 mips32_op = OPC_MULR_PS;
11935 gen_farith(ctx, mips32_op, rt, rs, rd, 0);
11938 goto pool32f_invalid;
11942 /* MOV[FT].fmt and PREFX */
11943 cc = (ctx->opcode >> 13) & 0x7;
11944 fmt = (ctx->opcode >> 9) & 0x3;
11945 switch ((ctx->opcode >> 6) & 0x7) {
11949 gen_movcf_s(rs, rt, cc, 0);
11952 gen_movcf_d(ctx, rs, rt, cc, 0);
11955 gen_movcf_ps(rs, rt, cc, 0);
11958 goto pool32f_invalid;
11964 gen_movcf_s(rs, rt, cc, 1);
11967 gen_movcf_d(ctx, rs, rt, cc, 1);
11970 gen_movcf_ps(rs, rt, cc, 1);
11973 goto pool32f_invalid;
11979 goto pool32f_invalid;
11982 #define FINSN_3ARG_SDPS(prfx) \
11983 switch ((ctx->opcode >> 8) & 0x3) { \
11985 mips32_op = OPC_##prfx##_S; \
11988 mips32_op = OPC_##prfx##_D; \
11990 case FMT_SDPS_PS: \
11991 mips32_op = OPC_##prfx##_PS; \
11994 goto pool32f_invalid; \
11997 /* regular FP ops */
11998 switch ((ctx->opcode >> 6) & 0x3) {
12000 FINSN_3ARG_SDPS(ADD);
12003 FINSN_3ARG_SDPS(SUB);
12006 FINSN_3ARG_SDPS(MUL);
12009 fmt = (ctx->opcode >> 8) & 0x3;
12011 mips32_op = OPC_DIV_D;
12012 } else if (fmt == 0) {
12013 mips32_op = OPC_DIV_S;
12015 goto pool32f_invalid;
12019 goto pool32f_invalid;
12024 switch ((ctx->opcode >> 6) & 0x3) {
12026 FINSN_3ARG_SDPS(MOVN);
12029 FINSN_3ARG_SDPS(MOVZ);
12032 goto pool32f_invalid;
12036 gen_farith(ctx, mips32_op, rt, rs, rd, 0);
12040 MIPS_INVAL("pool32f");
12041 generate_exception(ctx, EXCP_RI);
12045 generate_exception_err(ctx, EXCP_CpU, 1);
12049 minor = (ctx->opcode >> 21) & 0x1f;
12052 mips32_op = OPC_BLTZ;
12055 mips32_op = OPC_BLTZAL;
12058 mips32_op = OPC_BLTZALS;
12061 mips32_op = OPC_BGEZ;
12064 mips32_op = OPC_BGEZAL;
12067 mips32_op = OPC_BGEZALS;
12070 mips32_op = OPC_BLEZ;
12073 mips32_op = OPC_BGTZ;
12075 gen_compute_branch(ctx, mips32_op, 4, rs, -1, imm << 1);
12081 mips32_op = OPC_TLTI;
12084 mips32_op = OPC_TGEI;
12087 mips32_op = OPC_TLTIU;
12090 mips32_op = OPC_TGEIU;
12093 mips32_op = OPC_TNEI;
12096 mips32_op = OPC_TEQI;
12098 gen_trap(ctx, mips32_op, rs, -1, imm);
12103 gen_compute_branch(ctx, minor == BNEZC ? OPC_BNE : OPC_BEQ,
12104 4, rs, 0, imm << 1);
12105 /* Compact branches don't have a delay slot, so just let
12106 the normal delay slot handling take us to the branch
12110 gen_logic_imm(ctx, OPC_LUI, rs, -1, imm);
12116 /* COP2: Not implemented. */
12117 generate_exception_err(ctx, EXCP_CpU, 2);
12120 mips32_op = (ctx->opcode & (1 << 16)) ? OPC_BC1FANY2 : OPC_BC1F;
12123 mips32_op = (ctx->opcode & (1 << 16)) ? OPC_BC1TANY2 : OPC_BC1T;
12126 mips32_op = OPC_BC1FANY4;
12129 mips32_op = OPC_BC1TANY4;
12132 check_insn(ctx, ASE_MIPS3D);
12135 gen_compute_branch1(ctx, mips32_op,
12136 (ctx->opcode >> 18) & 0x7, imm << 1);
12141 /* MIPS DSP: not implemented */
12144 MIPS_INVAL("pool32i");
12145 generate_exception(ctx, EXCP_RI);
12150 minor = (ctx->opcode >> 12) & 0xf;
12153 mips32_op = OPC_LWL;
12156 mips32_op = OPC_SWL;
12159 mips32_op = OPC_LWR;
12162 mips32_op = OPC_SWR;
12164 #if defined(TARGET_MIPS64)
12166 mips32_op = OPC_LDL;
12169 mips32_op = OPC_SDL;
12172 mips32_op = OPC_LDR;
12175 mips32_op = OPC_SDR;
12178 mips32_op = OPC_LWU;
12181 mips32_op = OPC_LLD;
12185 mips32_op = OPC_LL;
12188 gen_ld(ctx, mips32_op, rt, rs, SIMM(ctx->opcode, 0, 12));
12191 gen_st(ctx, mips32_op, rt, rs, SIMM(ctx->opcode, 0, 12));
12194 gen_st_cond(ctx, OPC_SC, rt, rs, SIMM(ctx->opcode, 0, 12));
12196 #if defined(TARGET_MIPS64)
12198 gen_st_cond(ctx, OPC_SCD, rt, rs, SIMM(ctx->opcode, 0, 12));
12202 /* Treat as no-op */
12205 MIPS_INVAL("pool32c");
12206 generate_exception(ctx, EXCP_RI);
12211 mips32_op = OPC_ADDI;
12214 mips32_op = OPC_ADDIU;
12216 gen_arith_imm(ctx, mips32_op, rt, rs, imm);
12219 /* Logical operations */
12221 mips32_op = OPC_ORI;
12224 mips32_op = OPC_XORI;
12227 mips32_op = OPC_ANDI;
12229 gen_logic_imm(ctx, mips32_op, rt, rs, imm);
12232 /* Set less than immediate */
12234 mips32_op = OPC_SLTI;
12237 mips32_op = OPC_SLTIU;
12239 gen_slt_imm(ctx, mips32_op, rt, rs, imm);
12242 offset = (int32_t)(ctx->opcode & 0x3FFFFFF) << 2;
12243 gen_compute_branch(ctx, OPC_JALX, 4, rt, rs, offset);
12247 offset = (int32_t)(ctx->opcode & 0x3FFFFFF) << 1;
12248 gen_compute_branch(ctx, OPC_JALS, 4, rt, rs, offset);
12252 gen_compute_branch(ctx, OPC_BEQ, 4, rt, rs, imm << 1);
12256 gen_compute_branch(ctx, OPC_BNE, 4, rt, rs, imm << 1);
12260 gen_compute_branch(ctx, OPC_J, 4, rt, rs,
12261 (int32_t)(ctx->opcode & 0x3FFFFFF) << 1);
12265 gen_compute_branch(ctx, OPC_JAL, 4, rt, rs,
12266 (int32_t)(ctx->opcode & 0x3FFFFFF) << 1);
12269 /* Floating point (COP1) */
12271 mips32_op = OPC_LWC1;
12274 mips32_op = OPC_LDC1;
12277 mips32_op = OPC_SWC1;
12280 mips32_op = OPC_SDC1;
12282 gen_cop1_ldst(env, ctx, mips32_op, rt, rs, imm);
12286 int reg = mmreg(ZIMM(ctx->opcode, 23, 3));
12287 int offset = SIMM(ctx->opcode, 0, 23) << 2;
12289 gen_addiupc(ctx, reg, offset, 0, 0);
12292 /* Loads and stores */
12294 mips32_op = OPC_LB;
12297 mips32_op = OPC_LBU;
12300 mips32_op = OPC_LH;
12303 mips32_op = OPC_LHU;
12306 mips32_op = OPC_LW;
12308 #ifdef TARGET_MIPS64
12310 mips32_op = OPC_LD;
12313 mips32_op = OPC_SD;
12317 mips32_op = OPC_SB;
12320 mips32_op = OPC_SH;
12323 mips32_op = OPC_SW;
12326 gen_ld(ctx, mips32_op, rt, rs, imm);
12329 gen_st(ctx, mips32_op, rt, rs, imm);
12332 generate_exception(ctx, EXCP_RI);
12337 static int decode_micromips_opc (CPUMIPSState *env, DisasContext *ctx, int *is_branch)
12341 /* make sure instructions are on a halfword boundary */
12342 if (ctx->pc & 0x1) {
12343 env->CP0_BadVAddr = ctx->pc;
12344 generate_exception(ctx, EXCP_AdEL);
12345 ctx->bstate = BS_STOP;
12349 op = (ctx->opcode >> 10) & 0x3f;
12350 /* Enforce properly-sized instructions in a delay slot */
12351 if (ctx->hflags & MIPS_HFLAG_BMASK) {
12352 int bits = ctx->hflags & MIPS_HFLAG_BMASK_EXT;
12390 if (bits & MIPS_HFLAG_BDS16) {
12391 generate_exception(ctx, EXCP_RI);
12392 /* Just stop translation; the user is confused. */
12393 ctx->bstate = BS_STOP;
12418 if (bits & MIPS_HFLAG_BDS32) {
12419 generate_exception(ctx, EXCP_RI);
12420 /* Just stop translation; the user is confused. */
12421 ctx->bstate = BS_STOP;
12432 int rd = mmreg(uMIPS_RD(ctx->opcode));
12433 int rs1 = mmreg(uMIPS_RS1(ctx->opcode));
12434 int rs2 = mmreg(uMIPS_RS2(ctx->opcode));
12437 switch (ctx->opcode & 0x1) {
12446 gen_arith(ctx, opc, rd, rs1, rs2);
12451 int rd = mmreg(uMIPS_RD(ctx->opcode));
12452 int rs = mmreg(uMIPS_RS(ctx->opcode));
12453 int amount = (ctx->opcode >> 1) & 0x7;
12455 amount = amount == 0 ? 8 : amount;
12457 switch (ctx->opcode & 0x1) {
12466 gen_shift_imm(ctx, opc, rd, rs, amount);
12470 gen_pool16c_insn(ctx, is_branch);
12474 int rd = mmreg(uMIPS_RD(ctx->opcode));
12475 int rb = 28; /* GP */
12476 int16_t offset = SIMM(ctx->opcode, 0, 7) << 2;
12478 gen_ld(ctx, OPC_LW, rd, rb, offset);
12482 if (ctx->opcode & 1) {
12483 generate_exception(ctx, EXCP_RI);
12486 int enc_dest = uMIPS_RD(ctx->opcode);
12487 int enc_rt = uMIPS_RS2(ctx->opcode);
12488 int enc_rs = uMIPS_RS1(ctx->opcode);
12489 int rd, rs, re, rt;
12490 static const int rd_enc[] = { 5, 5, 6, 4, 4, 4, 4, 4 };
12491 static const int re_enc[] = { 6, 7, 7, 21, 22, 5, 6, 7 };
12492 static const int rs_rt_enc[] = { 0, 17, 2, 3, 16, 18, 19, 20 };
12494 rd = rd_enc[enc_dest];
12495 re = re_enc[enc_dest];
12496 rs = rs_rt_enc[enc_rs];
12497 rt = rs_rt_enc[enc_rt];
12499 gen_arith_imm(ctx, OPC_ADDIU, rd, rs, 0);
12500 gen_arith_imm(ctx, OPC_ADDIU, re, rt, 0);
12505 int rd = mmreg(uMIPS_RD(ctx->opcode));
12506 int rb = mmreg(uMIPS_RS(ctx->opcode));
12507 int16_t offset = ZIMM(ctx->opcode, 0, 4);
12508 offset = (offset == 0xf ? -1 : offset);
12510 gen_ld(ctx, OPC_LBU, rd, rb, offset);
12515 int rd = mmreg(uMIPS_RD(ctx->opcode));
12516 int rb = mmreg(uMIPS_RS(ctx->opcode));
12517 int16_t offset = ZIMM(ctx->opcode, 0, 4) << 1;
12519 gen_ld(ctx, OPC_LHU, rd, rb, offset);
12524 int rd = (ctx->opcode >> 5) & 0x1f;
12525 int rb = 29; /* SP */
12526 int16_t offset = ZIMM(ctx->opcode, 0, 5) << 2;
12528 gen_ld(ctx, OPC_LW, rd, rb, offset);
12533 int rd = mmreg(uMIPS_RD(ctx->opcode));
12534 int rb = mmreg(uMIPS_RS(ctx->opcode));
12535 int16_t offset = ZIMM(ctx->opcode, 0, 4) << 2;
12537 gen_ld(ctx, OPC_LW, rd, rb, offset);
12542 int rd = mmreg2(uMIPS_RD(ctx->opcode));
12543 int rb = mmreg(uMIPS_RS(ctx->opcode));
12544 int16_t offset = ZIMM(ctx->opcode, 0, 4);
12546 gen_st(ctx, OPC_SB, rd, rb, offset);
12551 int rd = mmreg2(uMIPS_RD(ctx->opcode));
12552 int rb = mmreg(uMIPS_RS(ctx->opcode));
12553 int16_t offset = ZIMM(ctx->opcode, 0, 4) << 1;
12555 gen_st(ctx, OPC_SH, rd, rb, offset);
12560 int rd = (ctx->opcode >> 5) & 0x1f;
12561 int rb = 29; /* SP */
12562 int16_t offset = ZIMM(ctx->opcode, 0, 5) << 2;
12564 gen_st(ctx, OPC_SW, rd, rb, offset);
12569 int rd = mmreg2(uMIPS_RD(ctx->opcode));
12570 int rb = mmreg(uMIPS_RS(ctx->opcode));
12571 int16_t offset = ZIMM(ctx->opcode, 0, 4) << 2;
12573 gen_st(ctx, OPC_SW, rd, rb, offset);
12578 int rd = uMIPS_RD5(ctx->opcode);
12579 int rs = uMIPS_RS5(ctx->opcode);
12581 gen_arith_imm(ctx, OPC_ADDIU, rd, rs, 0);
12588 switch (ctx->opcode & 0x1) {
12598 switch (ctx->opcode & 0x1) {
12603 gen_addiur1sp(ctx);
12608 gen_compute_branch(ctx, OPC_BEQ, 2, 0, 0,
12609 SIMM(ctx->opcode, 0, 10) << 1);
12614 gen_compute_branch(ctx, op == BNEZ16 ? OPC_BNE : OPC_BEQ, 2,
12615 mmreg(uMIPS_RD(ctx->opcode)),
12616 0, SIMM(ctx->opcode, 0, 7) << 1);
12621 int reg = mmreg(uMIPS_RD(ctx->opcode));
12622 int imm = ZIMM(ctx->opcode, 0, 7);
12624 imm = (imm == 0x7f ? -1 : imm);
12625 tcg_gen_movi_tl(cpu_gpr[reg], imm);
12635 generate_exception(ctx, EXCP_RI);
12638 decode_micromips32_opc (env, ctx, op, is_branch);
12645 /* SmartMIPS extension to MIPS32 */
12647 #if defined(TARGET_MIPS64)
12649 /* MDMX extension to MIPS64 */
12653 /* MIPSDSP functions. */
12654 static void gen_mipsdsp_ld(DisasContext *ctx, uint32_t opc,
12655 int rd, int base, int offset)
12657 const char *opn = "ldx";
12661 t0 = tcg_temp_new();
12664 gen_load_gpr(t0, offset);
12665 } else if (offset == 0) {
12666 gen_load_gpr(t0, base);
12668 gen_op_addr_add(ctx, t0, cpu_gpr[base], cpu_gpr[offset]);
12673 tcg_gen_qemu_ld8u(t0, t0, ctx->mem_idx);
12674 gen_store_gpr(t0, rd);
12678 tcg_gen_qemu_ld16s(t0, t0, ctx->mem_idx);
12679 gen_store_gpr(t0, rd);
12683 tcg_gen_qemu_ld32s(t0, t0, ctx->mem_idx);
12684 gen_store_gpr(t0, rd);
12687 #if defined(TARGET_MIPS64)
12689 tcg_gen_qemu_ld64(t0, t0, ctx->mem_idx);
12690 gen_store_gpr(t0, rd);
12695 (void)opn; /* avoid a compiler warning */
12696 MIPS_DEBUG("%s %s, %s(%s)", opn,
12697 regnames[rd], regnames[offset], regnames[base]);
12701 static void gen_mipsdsp_arith(DisasContext *ctx, uint32_t op1, uint32_t op2,
12702 int ret, int v1, int v2)
12704 const char *opn = "mipsdsp arith";
12709 /* Treat as NOP. */
12714 v1_t = tcg_temp_new();
12715 v2_t = tcg_temp_new();
12717 gen_load_gpr(v1_t, v1);
12718 gen_load_gpr(v2_t, v2);
12721 /* OPC_MULT_G_2E is equal OPC_ADDUH_QB_DSP */
12722 case OPC_MULT_G_2E:
12726 gen_helper_adduh_qb(cpu_gpr[ret], v1_t, v2_t);
12728 case OPC_ADDUH_R_QB:
12729 gen_helper_adduh_r_qb(cpu_gpr[ret], v1_t, v2_t);
12732 gen_helper_addqh_ph(cpu_gpr[ret], v1_t, v2_t);
12734 case OPC_ADDQH_R_PH:
12735 gen_helper_addqh_r_ph(cpu_gpr[ret], v1_t, v2_t);
12738 gen_helper_addqh_w(cpu_gpr[ret], v1_t, v2_t);
12740 case OPC_ADDQH_R_W:
12741 gen_helper_addqh_r_w(cpu_gpr[ret], v1_t, v2_t);
12744 gen_helper_subuh_qb(cpu_gpr[ret], v1_t, v2_t);
12746 case OPC_SUBUH_R_QB:
12747 gen_helper_subuh_r_qb(cpu_gpr[ret], v1_t, v2_t);
12750 gen_helper_subqh_ph(cpu_gpr[ret], v1_t, v2_t);
12752 case OPC_SUBQH_R_PH:
12753 gen_helper_subqh_r_ph(cpu_gpr[ret], v1_t, v2_t);
12756 gen_helper_subqh_w(cpu_gpr[ret], v1_t, v2_t);
12758 case OPC_SUBQH_R_W:
12759 gen_helper_subqh_r_w(cpu_gpr[ret], v1_t, v2_t);
12763 case OPC_ABSQ_S_PH_DSP:
12765 case OPC_ABSQ_S_QB:
12767 gen_helper_absq_s_qb(cpu_gpr[ret], v2_t, cpu_env);
12769 case OPC_ABSQ_S_PH:
12771 gen_helper_absq_s_ph(cpu_gpr[ret], v2_t, cpu_env);
12775 gen_helper_absq_s_w(cpu_gpr[ret], v2_t, cpu_env);
12777 case OPC_PRECEQ_W_PHL:
12779 tcg_gen_andi_tl(cpu_gpr[ret], v2_t, 0xFFFF0000);
12780 tcg_gen_ext32s_tl(cpu_gpr[ret], cpu_gpr[ret]);
12782 case OPC_PRECEQ_W_PHR:
12784 tcg_gen_andi_tl(cpu_gpr[ret], v2_t, 0x0000FFFF);
12785 tcg_gen_shli_tl(cpu_gpr[ret], cpu_gpr[ret], 16);
12786 tcg_gen_ext32s_tl(cpu_gpr[ret], cpu_gpr[ret]);
12788 case OPC_PRECEQU_PH_QBL:
12790 gen_helper_precequ_ph_qbl(cpu_gpr[ret], v2_t);
12792 case OPC_PRECEQU_PH_QBR:
12794 gen_helper_precequ_ph_qbr(cpu_gpr[ret], v2_t);
12796 case OPC_PRECEQU_PH_QBLA:
12798 gen_helper_precequ_ph_qbla(cpu_gpr[ret], v2_t);
12800 case OPC_PRECEQU_PH_QBRA:
12802 gen_helper_precequ_ph_qbra(cpu_gpr[ret], v2_t);
12804 case OPC_PRECEU_PH_QBL:
12806 gen_helper_preceu_ph_qbl(cpu_gpr[ret], v2_t);
12808 case OPC_PRECEU_PH_QBR:
12810 gen_helper_preceu_ph_qbr(cpu_gpr[ret], v2_t);
12812 case OPC_PRECEU_PH_QBLA:
12814 gen_helper_preceu_ph_qbla(cpu_gpr[ret], v2_t);
12816 case OPC_PRECEU_PH_QBRA:
12818 gen_helper_preceu_ph_qbra(cpu_gpr[ret], v2_t);
12822 case OPC_ADDU_QB_DSP:
12826 gen_helper_addq_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12828 case OPC_ADDQ_S_PH:
12830 gen_helper_addq_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12834 gen_helper_addq_s_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12838 gen_helper_addu_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12840 case OPC_ADDU_S_QB:
12842 gen_helper_addu_s_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12846 gen_helper_addu_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12848 case OPC_ADDU_S_PH:
12850 gen_helper_addu_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12854 gen_helper_subq_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12856 case OPC_SUBQ_S_PH:
12858 gen_helper_subq_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12862 gen_helper_subq_s_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12866 gen_helper_subu_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12868 case OPC_SUBU_S_QB:
12870 gen_helper_subu_s_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12874 gen_helper_subu_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12876 case OPC_SUBU_S_PH:
12878 gen_helper_subu_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12882 gen_helper_addsc(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12886 gen_helper_addwc(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12890 gen_helper_modsub(cpu_gpr[ret], v1_t, v2_t);
12892 case OPC_RADDU_W_QB:
12894 gen_helper_raddu_w_qb(cpu_gpr[ret], v1_t);
12898 case OPC_CMPU_EQ_QB_DSP:
12900 case OPC_PRECR_QB_PH:
12902 gen_helper_precr_qb_ph(cpu_gpr[ret], v1_t, v2_t);
12904 case OPC_PRECRQ_QB_PH:
12906 gen_helper_precrq_qb_ph(cpu_gpr[ret], v1_t, v2_t);
12908 case OPC_PRECR_SRA_PH_W:
12911 TCGv_i32 sa_t = tcg_const_i32(v2);
12912 gen_helper_precr_sra_ph_w(cpu_gpr[ret], sa_t, v1_t,
12914 tcg_temp_free_i32(sa_t);
12917 case OPC_PRECR_SRA_R_PH_W:
12920 TCGv_i32 sa_t = tcg_const_i32(v2);
12921 gen_helper_precr_sra_r_ph_w(cpu_gpr[ret], sa_t, v1_t,
12923 tcg_temp_free_i32(sa_t);
12926 case OPC_PRECRQ_PH_W:
12928 gen_helper_precrq_ph_w(cpu_gpr[ret], v1_t, v2_t);
12930 case OPC_PRECRQ_RS_PH_W:
12932 gen_helper_precrq_rs_ph_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12934 case OPC_PRECRQU_S_QB_PH:
12936 gen_helper_precrqu_s_qb_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12940 #ifdef TARGET_MIPS64
12941 case OPC_ABSQ_S_QH_DSP:
12943 case OPC_PRECEQ_L_PWL:
12945 tcg_gen_andi_tl(cpu_gpr[ret], v2_t, 0xFFFFFFFF00000000ull);
12947 case OPC_PRECEQ_L_PWR:
12949 tcg_gen_shli_tl(cpu_gpr[ret], v2_t, 32);
12951 case OPC_PRECEQ_PW_QHL:
12953 gen_helper_preceq_pw_qhl(cpu_gpr[ret], v2_t);
12955 case OPC_PRECEQ_PW_QHR:
12957 gen_helper_preceq_pw_qhr(cpu_gpr[ret], v2_t);
12959 case OPC_PRECEQ_PW_QHLA:
12961 gen_helper_preceq_pw_qhla(cpu_gpr[ret], v2_t);
12963 case OPC_PRECEQ_PW_QHRA:
12965 gen_helper_preceq_pw_qhra(cpu_gpr[ret], v2_t);
12967 case OPC_PRECEQU_QH_OBL:
12969 gen_helper_precequ_qh_obl(cpu_gpr[ret], v2_t);
12971 case OPC_PRECEQU_QH_OBR:
12973 gen_helper_precequ_qh_obr(cpu_gpr[ret], v2_t);
12975 case OPC_PRECEQU_QH_OBLA:
12977 gen_helper_precequ_qh_obla(cpu_gpr[ret], v2_t);
12979 case OPC_PRECEQU_QH_OBRA:
12981 gen_helper_precequ_qh_obra(cpu_gpr[ret], v2_t);
12983 case OPC_PRECEU_QH_OBL:
12985 gen_helper_preceu_qh_obl(cpu_gpr[ret], v2_t);
12987 case OPC_PRECEU_QH_OBR:
12989 gen_helper_preceu_qh_obr(cpu_gpr[ret], v2_t);
12991 case OPC_PRECEU_QH_OBLA:
12993 gen_helper_preceu_qh_obla(cpu_gpr[ret], v2_t);
12995 case OPC_PRECEU_QH_OBRA:
12997 gen_helper_preceu_qh_obra(cpu_gpr[ret], v2_t);
12999 case OPC_ABSQ_S_OB:
13001 gen_helper_absq_s_ob(cpu_gpr[ret], v2_t, cpu_env);
13003 case OPC_ABSQ_S_PW:
13005 gen_helper_absq_s_pw(cpu_gpr[ret], v2_t, cpu_env);
13007 case OPC_ABSQ_S_QH:
13009 gen_helper_absq_s_qh(cpu_gpr[ret], v2_t, cpu_env);
13013 case OPC_ADDU_OB_DSP:
13015 case OPC_RADDU_L_OB:
13017 gen_helper_raddu_l_ob(cpu_gpr[ret], v1_t);
13021 gen_helper_subq_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13023 case OPC_SUBQ_S_PW:
13025 gen_helper_subq_s_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13029 gen_helper_subq_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13031 case OPC_SUBQ_S_QH:
13033 gen_helper_subq_s_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13037 gen_helper_subu_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13039 case OPC_SUBU_S_OB:
13041 gen_helper_subu_s_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13045 gen_helper_subu_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13047 case OPC_SUBU_S_QH:
13049 gen_helper_subu_s_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13053 gen_helper_subuh_ob(cpu_gpr[ret], v1_t, v2_t);
13055 case OPC_SUBUH_R_OB:
13057 gen_helper_subuh_r_ob(cpu_gpr[ret], v1_t, v2_t);
13061 gen_helper_addq_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13063 case OPC_ADDQ_S_PW:
13065 gen_helper_addq_s_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13069 gen_helper_addq_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13071 case OPC_ADDQ_S_QH:
13073 gen_helper_addq_s_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13077 gen_helper_addu_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13079 case OPC_ADDU_S_OB:
13081 gen_helper_addu_s_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13085 gen_helper_addu_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13087 case OPC_ADDU_S_QH:
13089 gen_helper_addu_s_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13093 gen_helper_adduh_ob(cpu_gpr[ret], v1_t, v2_t);
13095 case OPC_ADDUH_R_OB:
13097 gen_helper_adduh_r_ob(cpu_gpr[ret], v1_t, v2_t);
13101 case OPC_CMPU_EQ_OB_DSP:
13103 case OPC_PRECR_OB_QH:
13105 gen_helper_precr_ob_qh(cpu_gpr[ret], v1_t, v2_t);
13107 case OPC_PRECR_SRA_QH_PW:
13110 TCGv_i32 ret_t = tcg_const_i32(ret);
13111 gen_helper_precr_sra_qh_pw(v2_t, v1_t, v2_t, ret_t);
13112 tcg_temp_free_i32(ret_t);
13115 case OPC_PRECR_SRA_R_QH_PW:
13118 TCGv_i32 sa_v = tcg_const_i32(ret);
13119 gen_helper_precr_sra_r_qh_pw(v2_t, v1_t, v2_t, sa_v);
13120 tcg_temp_free_i32(sa_v);
13123 case OPC_PRECRQ_OB_QH:
13125 gen_helper_precrq_ob_qh(cpu_gpr[ret], v1_t, v2_t);
13127 case OPC_PRECRQ_PW_L:
13129 gen_helper_precrq_pw_l(cpu_gpr[ret], v1_t, v2_t);
13131 case OPC_PRECRQ_QH_PW:
13133 gen_helper_precrq_qh_pw(cpu_gpr[ret], v1_t, v2_t);
13135 case OPC_PRECRQ_RS_QH_PW:
13137 gen_helper_precrq_rs_qh_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13139 case OPC_PRECRQU_S_OB_QH:
13141 gen_helper_precrqu_s_ob_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13148 tcg_temp_free(v1_t);
13149 tcg_temp_free(v2_t);
13151 (void)opn; /* avoid a compiler warning */
13152 MIPS_DEBUG("%s", opn);
13155 static void gen_mipsdsp_shift(DisasContext *ctx, uint32_t opc,
13156 int ret, int v1, int v2)
13159 const char *opn = "mipsdsp shift";
13165 /* Treat as NOP. */
13170 t0 = tcg_temp_new();
13171 v1_t = tcg_temp_new();
13172 v2_t = tcg_temp_new();
13174 tcg_gen_movi_tl(t0, v1);
13175 gen_load_gpr(v1_t, v1);
13176 gen_load_gpr(v2_t, v2);
13179 case OPC_SHLL_QB_DSP:
13181 op2 = MASK_SHLL_QB(ctx->opcode);
13185 gen_helper_shll_qb(cpu_gpr[ret], t0, v2_t, cpu_env);
13189 gen_helper_shll_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13193 gen_helper_shll_ph(cpu_gpr[ret], t0, v2_t, cpu_env);
13197 gen_helper_shll_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13199 case OPC_SHLL_S_PH:
13201 gen_helper_shll_s_ph(cpu_gpr[ret], t0, v2_t, cpu_env);
13203 case OPC_SHLLV_S_PH:
13205 gen_helper_shll_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13209 gen_helper_shll_s_w(cpu_gpr[ret], t0, v2_t, cpu_env);
13211 case OPC_SHLLV_S_W:
13213 gen_helper_shll_s_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13217 gen_helper_shrl_qb(cpu_gpr[ret], t0, v2_t);
13221 gen_helper_shrl_qb(cpu_gpr[ret], v1_t, v2_t);
13225 gen_helper_shrl_ph(cpu_gpr[ret], t0, v2_t);
13229 gen_helper_shrl_ph(cpu_gpr[ret], v1_t, v2_t);
13233 gen_helper_shra_qb(cpu_gpr[ret], t0, v2_t);
13235 case OPC_SHRA_R_QB:
13237 gen_helper_shra_r_qb(cpu_gpr[ret], t0, v2_t);
13241 gen_helper_shra_qb(cpu_gpr[ret], v1_t, v2_t);
13243 case OPC_SHRAV_R_QB:
13245 gen_helper_shra_r_qb(cpu_gpr[ret], v1_t, v2_t);
13249 gen_helper_shra_ph(cpu_gpr[ret], t0, v2_t);
13251 case OPC_SHRA_R_PH:
13253 gen_helper_shra_r_ph(cpu_gpr[ret], t0, v2_t);
13257 gen_helper_shra_ph(cpu_gpr[ret], v1_t, v2_t);
13259 case OPC_SHRAV_R_PH:
13261 gen_helper_shra_r_ph(cpu_gpr[ret], v1_t, v2_t);
13265 gen_helper_shra_r_w(cpu_gpr[ret], t0, v2_t);
13267 case OPC_SHRAV_R_W:
13269 gen_helper_shra_r_w(cpu_gpr[ret], v1_t, v2_t);
13271 default: /* Invalid */
13272 MIPS_INVAL("MASK SHLL.QB");
13273 generate_exception(ctx, EXCP_RI);
13278 #ifdef TARGET_MIPS64
13279 case OPC_SHLL_OB_DSP:
13280 op2 = MASK_SHLL_OB(ctx->opcode);
13284 gen_helper_shll_pw(cpu_gpr[ret], v2_t, t0, cpu_env);
13288 gen_helper_shll_pw(cpu_gpr[ret], v2_t, v1_t, cpu_env);
13290 case OPC_SHLL_S_PW:
13292 gen_helper_shll_s_pw(cpu_gpr[ret], v2_t, t0, cpu_env);
13294 case OPC_SHLLV_S_PW:
13296 gen_helper_shll_s_pw(cpu_gpr[ret], v2_t, v1_t, cpu_env);
13300 gen_helper_shll_ob(cpu_gpr[ret], v2_t, t0, cpu_env);
13304 gen_helper_shll_ob(cpu_gpr[ret], v2_t, v1_t, cpu_env);
13308 gen_helper_shll_qh(cpu_gpr[ret], v2_t, t0, cpu_env);
13312 gen_helper_shll_qh(cpu_gpr[ret], v2_t, v1_t, cpu_env);
13314 case OPC_SHLL_S_QH:
13316 gen_helper_shll_s_qh(cpu_gpr[ret], v2_t, t0, cpu_env);
13318 case OPC_SHLLV_S_QH:
13320 gen_helper_shll_s_qh(cpu_gpr[ret], v2_t, v1_t, cpu_env);
13324 gen_helper_shra_ob(cpu_gpr[ret], v2_t, t0);
13328 gen_helper_shra_ob(cpu_gpr[ret], v2_t, v1_t);
13330 case OPC_SHRA_R_OB:
13332 gen_helper_shra_r_ob(cpu_gpr[ret], v2_t, t0);
13334 case OPC_SHRAV_R_OB:
13336 gen_helper_shra_r_ob(cpu_gpr[ret], v2_t, v1_t);
13340 gen_helper_shra_pw(cpu_gpr[ret], v2_t, t0);
13344 gen_helper_shra_pw(cpu_gpr[ret], v2_t, v1_t);
13346 case OPC_SHRA_R_PW:
13348 gen_helper_shra_r_pw(cpu_gpr[ret], v2_t, t0);
13350 case OPC_SHRAV_R_PW:
13352 gen_helper_shra_r_pw(cpu_gpr[ret], v2_t, v1_t);
13356 gen_helper_shra_qh(cpu_gpr[ret], v2_t, t0);
13360 gen_helper_shra_qh(cpu_gpr[ret], v2_t, v1_t);
13362 case OPC_SHRA_R_QH:
13364 gen_helper_shra_r_qh(cpu_gpr[ret], v2_t, t0);
13366 case OPC_SHRAV_R_QH:
13368 gen_helper_shra_r_qh(cpu_gpr[ret], v2_t, v1_t);
13372 gen_helper_shrl_ob(cpu_gpr[ret], v2_t, t0);
13376 gen_helper_shrl_ob(cpu_gpr[ret], v2_t, v1_t);
13380 gen_helper_shrl_qh(cpu_gpr[ret], v2_t, t0);
13384 gen_helper_shrl_qh(cpu_gpr[ret], v2_t, v1_t);
13386 default: /* Invalid */
13387 MIPS_INVAL("MASK SHLL.OB");
13388 generate_exception(ctx, EXCP_RI);
13396 tcg_temp_free(v1_t);
13397 tcg_temp_free(v2_t);
13398 (void)opn; /* avoid a compiler warning */
13399 MIPS_DEBUG("%s", opn);
13402 static void gen_mipsdsp_multiply(DisasContext *ctx, uint32_t op1, uint32_t op2,
13403 int ret, int v1, int v2, int check_ret)
13405 const char *opn = "mipsdsp multiply";
13410 if ((ret == 0) && (check_ret == 1)) {
13411 /* Treat as NOP. */
13416 t0 = tcg_temp_new_i32();
13417 v1_t = tcg_temp_new();
13418 v2_t = tcg_temp_new();
13420 tcg_gen_movi_i32(t0, ret);
13421 gen_load_gpr(v1_t, v1);
13422 gen_load_gpr(v2_t, v2);
13425 /* OPC_MULT_G_2E, OPC_ADDUH_QB_DSP, OPC_MUL_PH_DSP have
13426 * the same mask and op1. */
13427 case OPC_MULT_G_2E:
13430 gen_helper_mul_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13433 gen_helper_mul_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13436 gen_helper_mulq_s_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13438 case OPC_MULQ_RS_W:
13439 gen_helper_mulq_rs_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13443 case OPC_DPA_W_PH_DSP:
13445 case OPC_DPAU_H_QBL:
13447 gen_helper_dpau_h_qbl(t0, v1_t, v2_t, cpu_env);
13449 case OPC_DPAU_H_QBR:
13451 gen_helper_dpau_h_qbr(t0, v1_t, v2_t, cpu_env);
13453 case OPC_DPSU_H_QBL:
13455 gen_helper_dpsu_h_qbl(t0, v1_t, v2_t, cpu_env);
13457 case OPC_DPSU_H_QBR:
13459 gen_helper_dpsu_h_qbr(t0, v1_t, v2_t, cpu_env);
13463 gen_helper_dpa_w_ph(t0, v1_t, v2_t, cpu_env);
13465 case OPC_DPAX_W_PH:
13467 gen_helper_dpax_w_ph(t0, v1_t, v2_t, cpu_env);
13469 case OPC_DPAQ_S_W_PH:
13471 gen_helper_dpaq_s_w_ph(t0, v1_t, v2_t, cpu_env);
13473 case OPC_DPAQX_S_W_PH:
13475 gen_helper_dpaqx_s_w_ph(t0, v1_t, v2_t, cpu_env);
13477 case OPC_DPAQX_SA_W_PH:
13479 gen_helper_dpaqx_sa_w_ph(t0, v1_t, v2_t, cpu_env);
13483 gen_helper_dps_w_ph(t0, v1_t, v2_t, cpu_env);
13485 case OPC_DPSX_W_PH:
13487 gen_helper_dpsx_w_ph(t0, v1_t, v2_t, cpu_env);
13489 case OPC_DPSQ_S_W_PH:
13491 gen_helper_dpsq_s_w_ph(t0, v1_t, v2_t, cpu_env);
13493 case OPC_DPSQX_S_W_PH:
13495 gen_helper_dpsqx_s_w_ph(t0, v1_t, v2_t, cpu_env);
13497 case OPC_DPSQX_SA_W_PH:
13499 gen_helper_dpsqx_sa_w_ph(t0, v1_t, v2_t, cpu_env);
13501 case OPC_MULSAQ_S_W_PH:
13503 gen_helper_mulsaq_s_w_ph(t0, v1_t, v2_t, cpu_env);
13505 case OPC_DPAQ_SA_L_W:
13507 gen_helper_dpaq_sa_l_w(t0, v1_t, v2_t, cpu_env);
13509 case OPC_DPSQ_SA_L_W:
13511 gen_helper_dpsq_sa_l_w(t0, v1_t, v2_t, cpu_env);
13513 case OPC_MAQ_S_W_PHL:
13515 gen_helper_maq_s_w_phl(t0, v1_t, v2_t, cpu_env);
13517 case OPC_MAQ_S_W_PHR:
13519 gen_helper_maq_s_w_phr(t0, v1_t, v2_t, cpu_env);
13521 case OPC_MAQ_SA_W_PHL:
13523 gen_helper_maq_sa_w_phl(t0, v1_t, v2_t, cpu_env);
13525 case OPC_MAQ_SA_W_PHR:
13527 gen_helper_maq_sa_w_phr(t0, v1_t, v2_t, cpu_env);
13529 case OPC_MULSA_W_PH:
13531 gen_helper_mulsa_w_ph(t0, v1_t, v2_t, cpu_env);
13535 #ifdef TARGET_MIPS64
13536 case OPC_DPAQ_W_QH_DSP:
13538 int ac = ret & 0x03;
13539 tcg_gen_movi_i32(t0, ac);
13544 gen_helper_dmadd(v1_t, v2_t, t0, cpu_env);
13548 gen_helper_dmaddu(v1_t, v2_t, t0, cpu_env);
13552 gen_helper_dmsub(v1_t, v2_t, t0, cpu_env);
13556 gen_helper_dmsubu(v1_t, v2_t, t0, cpu_env);
13560 gen_helper_dpa_w_qh(v1_t, v2_t, t0, cpu_env);
13562 case OPC_DPAQ_S_W_QH:
13564 gen_helper_dpaq_s_w_qh(v1_t, v2_t, t0, cpu_env);
13566 case OPC_DPAQ_SA_L_PW:
13568 gen_helper_dpaq_sa_l_pw(v1_t, v2_t, t0, cpu_env);
13570 case OPC_DPAU_H_OBL:
13572 gen_helper_dpau_h_obl(v1_t, v2_t, t0, cpu_env);
13574 case OPC_DPAU_H_OBR:
13576 gen_helper_dpau_h_obr(v1_t, v2_t, t0, cpu_env);
13580 gen_helper_dps_w_qh(v1_t, v2_t, t0, cpu_env);
13582 case OPC_DPSQ_S_W_QH:
13584 gen_helper_dpsq_s_w_qh(v1_t, v2_t, t0, cpu_env);
13586 case OPC_DPSQ_SA_L_PW:
13588 gen_helper_dpsq_sa_l_pw(v1_t, v2_t, t0, cpu_env);
13590 case OPC_DPSU_H_OBL:
13592 gen_helper_dpsu_h_obl(v1_t, v2_t, t0, cpu_env);
13594 case OPC_DPSU_H_OBR:
13596 gen_helper_dpsu_h_obr(v1_t, v2_t, t0, cpu_env);
13598 case OPC_MAQ_S_L_PWL:
13600 gen_helper_maq_s_l_pwl(v1_t, v2_t, t0, cpu_env);
13602 case OPC_MAQ_S_L_PWR:
13604 gen_helper_maq_s_l_pwr(v1_t, v2_t, t0, cpu_env);
13606 case OPC_MAQ_S_W_QHLL:
13608 gen_helper_maq_s_w_qhll(v1_t, v2_t, t0, cpu_env);
13610 case OPC_MAQ_SA_W_QHLL:
13612 gen_helper_maq_sa_w_qhll(v1_t, v2_t, t0, cpu_env);
13614 case OPC_MAQ_S_W_QHLR:
13616 gen_helper_maq_s_w_qhlr(v1_t, v2_t, t0, cpu_env);
13618 case OPC_MAQ_SA_W_QHLR:
13620 gen_helper_maq_sa_w_qhlr(v1_t, v2_t, t0, cpu_env);
13622 case OPC_MAQ_S_W_QHRL:
13624 gen_helper_maq_s_w_qhrl(v1_t, v2_t, t0, cpu_env);
13626 case OPC_MAQ_SA_W_QHRL:
13628 gen_helper_maq_sa_w_qhrl(v1_t, v2_t, t0, cpu_env);
13630 case OPC_MAQ_S_W_QHRR:
13632 gen_helper_maq_s_w_qhrr(v1_t, v2_t, t0, cpu_env);
13634 case OPC_MAQ_SA_W_QHRR:
13636 gen_helper_maq_sa_w_qhrr(v1_t, v2_t, t0, cpu_env);
13638 case OPC_MULSAQ_S_L_PW:
13640 gen_helper_mulsaq_s_l_pw(v1_t, v2_t, t0, cpu_env);
13642 case OPC_MULSAQ_S_W_QH:
13644 gen_helper_mulsaq_s_w_qh(v1_t, v2_t, t0, cpu_env);
13650 case OPC_ADDU_QB_DSP:
13652 case OPC_MULEU_S_PH_QBL:
13654 gen_helper_muleu_s_ph_qbl(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13656 case OPC_MULEU_S_PH_QBR:
13658 gen_helper_muleu_s_ph_qbr(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13660 case OPC_MULQ_RS_PH:
13662 gen_helper_mulq_rs_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13664 case OPC_MULEQ_S_W_PHL:
13666 gen_helper_muleq_s_w_phl(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13668 case OPC_MULEQ_S_W_PHR:
13670 gen_helper_muleq_s_w_phr(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13672 case OPC_MULQ_S_PH:
13674 gen_helper_mulq_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13678 #ifdef TARGET_MIPS64
13679 case OPC_ADDU_OB_DSP:
13681 case OPC_MULEQ_S_PW_QHL:
13683 gen_helper_muleq_s_pw_qhl(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13685 case OPC_MULEQ_S_PW_QHR:
13687 gen_helper_muleq_s_pw_qhr(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13689 case OPC_MULEU_S_QH_OBL:
13691 gen_helper_muleu_s_qh_obl(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13693 case OPC_MULEU_S_QH_OBR:
13695 gen_helper_muleu_s_qh_obr(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13697 case OPC_MULQ_RS_QH:
13699 gen_helper_mulq_rs_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13706 tcg_temp_free_i32(t0);
13707 tcg_temp_free(v1_t);
13708 tcg_temp_free(v2_t);
13710 (void)opn; /* avoid a compiler warning */
13711 MIPS_DEBUG("%s", opn);
13715 static void gen_mipsdsp_bitinsn(DisasContext *ctx, uint32_t op1, uint32_t op2,
13718 const char *opn = "mipsdsp Bit/ Manipulation";
13724 /* Treat as NOP. */
13729 t0 = tcg_temp_new();
13730 val_t = tcg_temp_new();
13731 gen_load_gpr(val_t, val);
13734 case OPC_ABSQ_S_PH_DSP:
13738 gen_helper_bitrev(cpu_gpr[ret], val_t);
13743 target_long result;
13744 imm = (ctx->opcode >> 16) & 0xFF;
13745 result = (uint32_t)imm << 24 |
13746 (uint32_t)imm << 16 |
13747 (uint32_t)imm << 8 |
13749 result = (int32_t)result;
13750 tcg_gen_movi_tl(cpu_gpr[ret], result);
13755 tcg_gen_ext8u_tl(cpu_gpr[ret], val_t);
13756 tcg_gen_shli_tl(t0, cpu_gpr[ret], 8);
13757 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
13758 tcg_gen_shli_tl(t0, cpu_gpr[ret], 16);
13759 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
13760 tcg_gen_ext32s_tl(cpu_gpr[ret], cpu_gpr[ret]);
13765 imm = (ctx->opcode >> 16) & 0x03FF;
13766 imm = (int16_t)(imm << 6) >> 6;
13767 tcg_gen_movi_tl(cpu_gpr[ret], \
13768 (target_long)((int32_t)imm << 16 | \
13774 tcg_gen_ext16u_tl(cpu_gpr[ret], val_t);
13775 tcg_gen_shli_tl(t0, cpu_gpr[ret], 16);
13776 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
13777 tcg_gen_ext32s_tl(cpu_gpr[ret], cpu_gpr[ret]);
13781 #ifdef TARGET_MIPS64
13782 case OPC_ABSQ_S_QH_DSP:
13789 imm = (ctx->opcode >> 16) & 0xFF;
13790 temp = ((uint64_t)imm << 8) | (uint64_t)imm;
13791 temp = (temp << 16) | temp;
13792 temp = (temp << 32) | temp;
13793 tcg_gen_movi_tl(cpu_gpr[ret], temp);
13801 imm = (ctx->opcode >> 16) & 0x03FF;
13802 imm = (int16_t)(imm << 6) >> 6;
13803 temp = ((target_long)imm << 32) \
13804 | ((target_long)imm & 0xFFFFFFFF);
13805 tcg_gen_movi_tl(cpu_gpr[ret], temp);
13813 imm = (ctx->opcode >> 16) & 0x03FF;
13814 imm = (int16_t)(imm << 6) >> 6;
13816 temp = ((uint64_t)(uint16_t)imm << 48) |
13817 ((uint64_t)(uint16_t)imm << 32) |
13818 ((uint64_t)(uint16_t)imm << 16) |
13819 (uint64_t)(uint16_t)imm;
13820 tcg_gen_movi_tl(cpu_gpr[ret], temp);
13825 tcg_gen_ext8u_tl(cpu_gpr[ret], val_t);
13826 tcg_gen_shli_tl(t0, cpu_gpr[ret], 8);
13827 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
13828 tcg_gen_shli_tl(t0, cpu_gpr[ret], 16);
13829 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
13830 tcg_gen_shli_tl(t0, cpu_gpr[ret], 32);
13831 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
13835 tcg_gen_ext32u_i64(cpu_gpr[ret], val_t);
13836 tcg_gen_shli_tl(t0, cpu_gpr[ret], 32);
13837 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
13841 tcg_gen_ext16u_tl(cpu_gpr[ret], val_t);
13842 tcg_gen_shli_tl(t0, cpu_gpr[ret], 16);
13843 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
13844 tcg_gen_shli_tl(t0, cpu_gpr[ret], 32);
13845 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
13852 tcg_temp_free(val_t);
13854 (void)opn; /* avoid a compiler warning */
13855 MIPS_DEBUG("%s", opn);
13858 static void gen_mipsdsp_add_cmp_pick(DisasContext *ctx,
13859 uint32_t op1, uint32_t op2,
13860 int ret, int v1, int v2, int check_ret)
13862 const char *opn = "mipsdsp add compare pick";
13868 if ((ret == 0) && (check_ret == 1)) {
13869 /* Treat as NOP. */
13874 t0 = tcg_temp_new_i32();
13875 t1 = tcg_temp_new();
13876 v1_t = tcg_temp_new();
13877 v2_t = tcg_temp_new();
13879 gen_load_gpr(v1_t, v1);
13880 gen_load_gpr(v2_t, v2);
13883 case OPC_APPEND_DSP:
13886 tcg_gen_movi_i32(t0, v2);
13887 gen_helper_append(cpu_gpr[ret], cpu_gpr[ret], v1_t, t0);
13890 tcg_gen_movi_i32(t0, v2);
13891 gen_helper_prepend(cpu_gpr[ret], v1_t, cpu_gpr[ret], t0);
13894 tcg_gen_movi_i32(t0, v2);
13895 gen_helper_balign(cpu_gpr[ret], v1_t, cpu_gpr[ret], t0);
13897 default: /* Invid */
13898 MIPS_INVAL("MASK APPEND");
13899 generate_exception(ctx, EXCP_RI);
13903 case OPC_CMPU_EQ_QB_DSP:
13905 case OPC_CMPU_EQ_QB:
13907 gen_helper_cmpu_eq_qb(v1_t, v2_t, cpu_env);
13909 case OPC_CMPU_LT_QB:
13911 gen_helper_cmpu_lt_qb(v1_t, v2_t, cpu_env);
13913 case OPC_CMPU_LE_QB:
13915 gen_helper_cmpu_le_qb(v1_t, v2_t, cpu_env);
13917 case OPC_CMPGU_EQ_QB:
13919 gen_helper_cmpgu_eq_qb(cpu_gpr[ret], v1_t, v2_t);
13921 case OPC_CMPGU_LT_QB:
13923 gen_helper_cmpgu_lt_qb(cpu_gpr[ret], v1_t, v2_t);
13925 case OPC_CMPGU_LE_QB:
13927 gen_helper_cmpgu_le_qb(cpu_gpr[ret], v1_t, v2_t);
13929 case OPC_CMPGDU_EQ_QB:
13931 gen_helper_cmpgu_eq_qb(t1, v1_t, v2_t);
13932 tcg_gen_mov_tl(cpu_gpr[ret], t1);
13933 tcg_gen_andi_tl(cpu_dspctrl, cpu_dspctrl, 0xF0FFFFFF);
13934 tcg_gen_shli_tl(t1, t1, 24);
13935 tcg_gen_or_tl(cpu_dspctrl, cpu_dspctrl, t1);
13937 case OPC_CMPGDU_LT_QB:
13939 gen_helper_cmpgu_lt_qb(t1, v1_t, v2_t);
13940 tcg_gen_mov_tl(cpu_gpr[ret], t1);
13941 tcg_gen_andi_tl(cpu_dspctrl, cpu_dspctrl, 0xF0FFFFFF);
13942 tcg_gen_shli_tl(t1, t1, 24);
13943 tcg_gen_or_tl(cpu_dspctrl, cpu_dspctrl, t1);
13945 case OPC_CMPGDU_LE_QB:
13947 gen_helper_cmpgu_le_qb(t1, v1_t, v2_t);
13948 tcg_gen_mov_tl(cpu_gpr[ret], t1);
13949 tcg_gen_andi_tl(cpu_dspctrl, cpu_dspctrl, 0xF0FFFFFF);
13950 tcg_gen_shli_tl(t1, t1, 24);
13951 tcg_gen_or_tl(cpu_dspctrl, cpu_dspctrl, t1);
13953 case OPC_CMP_EQ_PH:
13955 gen_helper_cmp_eq_ph(v1_t, v2_t, cpu_env);
13957 case OPC_CMP_LT_PH:
13959 gen_helper_cmp_lt_ph(v1_t, v2_t, cpu_env);
13961 case OPC_CMP_LE_PH:
13963 gen_helper_cmp_le_ph(v1_t, v2_t, cpu_env);
13967 gen_helper_pick_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13971 gen_helper_pick_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13973 case OPC_PACKRL_PH:
13975 gen_helper_packrl_ph(cpu_gpr[ret], v1_t, v2_t);
13979 #ifdef TARGET_MIPS64
13980 case OPC_CMPU_EQ_OB_DSP:
13982 case OPC_CMP_EQ_PW:
13984 gen_helper_cmp_eq_pw(v1_t, v2_t, cpu_env);
13986 case OPC_CMP_LT_PW:
13988 gen_helper_cmp_lt_pw(v1_t, v2_t, cpu_env);
13990 case OPC_CMP_LE_PW:
13992 gen_helper_cmp_le_pw(v1_t, v2_t, cpu_env);
13994 case OPC_CMP_EQ_QH:
13996 gen_helper_cmp_eq_qh(v1_t, v2_t, cpu_env);
13998 case OPC_CMP_LT_QH:
14000 gen_helper_cmp_lt_qh(v1_t, v2_t, cpu_env);
14002 case OPC_CMP_LE_QH:
14004 gen_helper_cmp_le_qh(v1_t, v2_t, cpu_env);
14006 case OPC_CMPGDU_EQ_OB:
14008 gen_helper_cmpgdu_eq_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
14010 case OPC_CMPGDU_LT_OB:
14012 gen_helper_cmpgdu_lt_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
14014 case OPC_CMPGDU_LE_OB:
14016 gen_helper_cmpgdu_le_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
14018 case OPC_CMPGU_EQ_OB:
14020 gen_helper_cmpgu_eq_ob(cpu_gpr[ret], v1_t, v2_t);
14022 case OPC_CMPGU_LT_OB:
14024 gen_helper_cmpgu_lt_ob(cpu_gpr[ret], v1_t, v2_t);
14026 case OPC_CMPGU_LE_OB:
14028 gen_helper_cmpgu_le_ob(cpu_gpr[ret], v1_t, v2_t);
14030 case OPC_CMPU_EQ_OB:
14032 gen_helper_cmpu_eq_ob(v1_t, v2_t, cpu_env);
14034 case OPC_CMPU_LT_OB:
14036 gen_helper_cmpu_lt_ob(v1_t, v2_t, cpu_env);
14038 case OPC_CMPU_LE_OB:
14040 gen_helper_cmpu_le_ob(v1_t, v2_t, cpu_env);
14042 case OPC_PACKRL_PW:
14044 gen_helper_packrl_pw(cpu_gpr[ret], v1_t, v2_t);
14048 gen_helper_pick_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
14052 gen_helper_pick_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
14056 gen_helper_pick_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
14060 case OPC_DAPPEND_DSP:
14063 tcg_gen_movi_i32(t0, v2);
14064 gen_helper_dappend(cpu_gpr[ret], v1_t, cpu_gpr[ret], t0);
14067 tcg_gen_movi_i32(t0, v2);
14068 gen_helper_prependd(cpu_gpr[ret], v1_t, cpu_gpr[ret], t0);
14071 tcg_gen_movi_i32(t0, v2);
14072 gen_helper_prependw(cpu_gpr[ret], v1_t, cpu_gpr[ret], t0);
14075 tcg_gen_movi_i32(t0, v2);
14076 gen_helper_dbalign(cpu_gpr[ret], v1_t, cpu_gpr[ret], t0);
14078 default: /* Invalid */
14079 MIPS_INVAL("MASK DAPPEND");
14080 generate_exception(ctx, EXCP_RI);
14087 tcg_temp_free_i32(t0);
14089 tcg_temp_free(v1_t);
14090 tcg_temp_free(v2_t);
14092 (void)opn; /* avoid a compiler warning */
14093 MIPS_DEBUG("%s", opn);
14096 static void gen_mipsdsp_accinsn(DisasContext *ctx, uint32_t op1, uint32_t op2,
14097 int ret, int v1, int v2, int check_ret)
14100 const char *opn = "mipsdsp accumulator";
14107 if ((ret == 0) && (check_ret == 1)) {
14108 /* Treat as NOP. */
14113 t0 = tcg_temp_new();
14114 t1 = tcg_temp_new();
14115 v1_t = tcg_temp_new();
14116 v2_t = tcg_temp_new();
14118 gen_load_gpr(v1_t, v1);
14119 gen_load_gpr(v2_t, v2);
14122 case OPC_EXTR_W_DSP:
14126 tcg_gen_movi_tl(t0, v2);
14127 tcg_gen_movi_tl(t1, v1);
14128 gen_helper_extr_w(cpu_gpr[ret], t0, t1, cpu_env);
14131 tcg_gen_movi_tl(t0, v2);
14132 tcg_gen_movi_tl(t1, v1);
14133 gen_helper_extr_r_w(cpu_gpr[ret], t0, t1, cpu_env);
14135 case OPC_EXTR_RS_W:
14136 tcg_gen_movi_tl(t0, v2);
14137 tcg_gen_movi_tl(t1, v1);
14138 gen_helper_extr_rs_w(cpu_gpr[ret], t0, t1, cpu_env);
14141 tcg_gen_movi_tl(t0, v2);
14142 tcg_gen_movi_tl(t1, v1);
14143 gen_helper_extr_s_h(cpu_gpr[ret], t0, t1, cpu_env);
14145 case OPC_EXTRV_S_H:
14146 tcg_gen_movi_tl(t0, v2);
14147 gen_helper_extr_s_h(cpu_gpr[ret], t0, v1_t, cpu_env);
14150 tcg_gen_movi_tl(t0, v2);
14151 gen_helper_extr_w(cpu_gpr[ret], t0, v1_t, cpu_env);
14153 case OPC_EXTRV_R_W:
14154 tcg_gen_movi_tl(t0, v2);
14155 gen_helper_extr_r_w(cpu_gpr[ret], t0, v1_t, cpu_env);
14157 case OPC_EXTRV_RS_W:
14158 tcg_gen_movi_tl(t0, v2);
14159 gen_helper_extr_rs_w(cpu_gpr[ret], t0, v1_t, cpu_env);
14162 tcg_gen_movi_tl(t0, v2);
14163 tcg_gen_movi_tl(t1, v1);
14164 gen_helper_extp(cpu_gpr[ret], t0, t1, cpu_env);
14167 tcg_gen_movi_tl(t0, v2);
14168 gen_helper_extp(cpu_gpr[ret], t0, v1_t, cpu_env);
14171 tcg_gen_movi_tl(t0, v2);
14172 tcg_gen_movi_tl(t1, v1);
14173 gen_helper_extpdp(cpu_gpr[ret], t0, t1, cpu_env);
14176 tcg_gen_movi_tl(t0, v2);
14177 gen_helper_extpdp(cpu_gpr[ret], t0, v1_t, cpu_env);
14180 imm = (ctx->opcode >> 20) & 0x3F;
14181 tcg_gen_movi_tl(t0, ret);
14182 tcg_gen_movi_tl(t1, imm);
14183 gen_helper_shilo(t0, t1, cpu_env);
14186 tcg_gen_movi_tl(t0, ret);
14187 gen_helper_shilo(t0, v1_t, cpu_env);
14190 tcg_gen_movi_tl(t0, ret);
14191 gen_helper_mthlip(t0, v1_t, cpu_env);
14194 imm = (ctx->opcode >> 11) & 0x3FF;
14195 tcg_gen_movi_tl(t0, imm);
14196 gen_helper_wrdsp(v1_t, t0, cpu_env);
14199 imm = (ctx->opcode >> 16) & 0x03FF;
14200 tcg_gen_movi_tl(t0, imm);
14201 gen_helper_rddsp(cpu_gpr[ret], t0, cpu_env);
14205 #ifdef TARGET_MIPS64
14206 case OPC_DEXTR_W_DSP:
14210 tcg_gen_movi_tl(t0, ret);
14211 gen_helper_dmthlip(v1_t, t0, cpu_env);
14215 int shift = (ctx->opcode >> 19) & 0x7F;
14216 int ac = (ctx->opcode >> 11) & 0x03;
14217 tcg_gen_movi_tl(t0, shift);
14218 tcg_gen_movi_tl(t1, ac);
14219 gen_helper_dshilo(t0, t1, cpu_env);
14224 int ac = (ctx->opcode >> 11) & 0x03;
14225 tcg_gen_movi_tl(t0, ac);
14226 gen_helper_dshilo(v1_t, t0, cpu_env);
14230 tcg_gen_movi_tl(t0, v2);
14231 tcg_gen_movi_tl(t1, v1);
14233 gen_helper_dextp(cpu_gpr[ret], t0, t1, cpu_env);
14236 tcg_gen_movi_tl(t0, v2);
14237 gen_helper_dextp(cpu_gpr[ret], t0, v1_t, cpu_env);
14240 tcg_gen_movi_tl(t0, v2);
14241 tcg_gen_movi_tl(t1, v1);
14242 gen_helper_dextpdp(cpu_gpr[ret], t0, t1, cpu_env);
14245 tcg_gen_movi_tl(t0, v2);
14246 gen_helper_dextpdp(cpu_gpr[ret], t0, v1_t, cpu_env);
14249 tcg_gen_movi_tl(t0, v2);
14250 tcg_gen_movi_tl(t1, v1);
14251 gen_helper_dextr_l(cpu_gpr[ret], t0, t1, cpu_env);
14253 case OPC_DEXTR_R_L:
14254 tcg_gen_movi_tl(t0, v2);
14255 tcg_gen_movi_tl(t1, v1);
14256 gen_helper_dextr_r_l(cpu_gpr[ret], t0, t1, cpu_env);
14258 case OPC_DEXTR_RS_L:
14259 tcg_gen_movi_tl(t0, v2);
14260 tcg_gen_movi_tl(t1, v1);
14261 gen_helper_dextr_rs_l(cpu_gpr[ret], t0, t1, cpu_env);
14264 tcg_gen_movi_tl(t0, v2);
14265 tcg_gen_movi_tl(t1, v1);
14266 gen_helper_dextr_w(cpu_gpr[ret], t0, t1, cpu_env);
14268 case OPC_DEXTR_R_W:
14269 tcg_gen_movi_tl(t0, v2);
14270 tcg_gen_movi_tl(t1, v1);
14271 gen_helper_dextr_r_w(cpu_gpr[ret], t0, t1, cpu_env);
14273 case OPC_DEXTR_RS_W:
14274 tcg_gen_movi_tl(t0, v2);
14275 tcg_gen_movi_tl(t1, v1);
14276 gen_helper_dextr_rs_w(cpu_gpr[ret], t0, t1, cpu_env);
14278 case OPC_DEXTR_S_H:
14279 tcg_gen_movi_tl(t0, v2);
14280 tcg_gen_movi_tl(t1, v1);
14281 gen_helper_dextr_s_h(cpu_gpr[ret], t0, t1, cpu_env);
14283 case OPC_DEXTRV_S_H:
14284 tcg_gen_movi_tl(t0, v2);
14285 tcg_gen_movi_tl(t1, v1);
14286 gen_helper_dextr_s_h(cpu_gpr[ret], t0, t1, cpu_env);
14289 tcg_gen_movi_tl(t0, v2);
14290 gen_helper_dextr_l(cpu_gpr[ret], t0, v1_t, cpu_env);
14292 case OPC_DEXTRV_R_L:
14293 tcg_gen_movi_tl(t0, v2);
14294 gen_helper_dextr_r_l(cpu_gpr[ret], t0, v1_t, cpu_env);
14296 case OPC_DEXTRV_RS_L:
14297 tcg_gen_movi_tl(t0, v2);
14298 gen_helper_dextr_rs_l(cpu_gpr[ret], t0, v1_t, cpu_env);
14301 tcg_gen_movi_tl(t0, v2);
14302 gen_helper_dextr_w(cpu_gpr[ret], t0, v1_t, cpu_env);
14304 case OPC_DEXTRV_R_W:
14305 tcg_gen_movi_tl(t0, v2);
14306 gen_helper_dextr_r_w(cpu_gpr[ret], t0, v1_t, cpu_env);
14308 case OPC_DEXTRV_RS_W:
14309 tcg_gen_movi_tl(t0, v2);
14310 gen_helper_dextr_rs_w(cpu_gpr[ret], t0, v1_t, cpu_env);
14319 tcg_temp_free(v1_t);
14320 tcg_temp_free(v2_t);
14322 (void)opn; /* avoid a compiler warning */
14323 MIPS_DEBUG("%s", opn);
14326 /* End MIPSDSP functions. */
14328 static void decode_opc (CPUMIPSState *env, DisasContext *ctx, int *is_branch)
14331 int rs, rt, rd, sa;
14332 uint32_t op, op1, op2;
14335 /* make sure instructions are on a word boundary */
14336 if (ctx->pc & 0x3) {
14337 env->CP0_BadVAddr = ctx->pc;
14338 generate_exception(ctx, EXCP_AdEL);
14342 /* Handle blikely not taken case */
14343 if ((ctx->hflags & MIPS_HFLAG_BMASK_BASE) == MIPS_HFLAG_BL) {
14344 int l1 = gen_new_label();
14346 MIPS_DEBUG("blikely condition (" TARGET_FMT_lx ")", ctx->pc + 4);
14347 tcg_gen_brcondi_tl(TCG_COND_NE, bcond, 0, l1);
14348 tcg_gen_movi_i32(hflags, ctx->hflags & ~MIPS_HFLAG_BMASK);
14349 gen_goto_tb(ctx, 1, ctx->pc + 4);
14353 if (unlikely(qemu_loglevel_mask(CPU_LOG_TB_OP | CPU_LOG_TB_OP_OPT))) {
14354 tcg_gen_debug_insn_start(ctx->pc);
14357 op = MASK_OP_MAJOR(ctx->opcode);
14358 rs = (ctx->opcode >> 21) & 0x1f;
14359 rt = (ctx->opcode >> 16) & 0x1f;
14360 rd = (ctx->opcode >> 11) & 0x1f;
14361 sa = (ctx->opcode >> 6) & 0x1f;
14362 imm = (int16_t)ctx->opcode;
14365 op1 = MASK_SPECIAL(ctx->opcode);
14367 case OPC_SLL: /* Shift with immediate */
14369 gen_shift_imm(ctx, op1, rd, rt, sa);
14372 switch ((ctx->opcode >> 21) & 0x1f) {
14374 /* rotr is decoded as srl on non-R2 CPUs */
14375 if (ctx->insn_flags & ISA_MIPS32R2) {
14380 gen_shift_imm(ctx, op1, rd, rt, sa);
14383 generate_exception(ctx, EXCP_RI);
14387 case OPC_MOVN: /* Conditional move */
14389 check_insn(ctx, ISA_MIPS4 | ISA_MIPS32 |
14390 INSN_LOONGSON2E | INSN_LOONGSON2F);
14391 gen_cond_move(ctx, op1, rd, rs, rt);
14393 case OPC_ADD ... OPC_SUBU:
14394 gen_arith(ctx, op1, rd, rs, rt);
14396 case OPC_SLLV: /* Shifts */
14398 gen_shift(ctx, op1, rd, rs, rt);
14401 switch ((ctx->opcode >> 6) & 0x1f) {
14403 /* rotrv is decoded as srlv on non-R2 CPUs */
14404 if (ctx->insn_flags & ISA_MIPS32R2) {
14409 gen_shift(ctx, op1, rd, rs, rt);
14412 generate_exception(ctx, EXCP_RI);
14416 case OPC_SLT: /* Set on less than */
14418 gen_slt(ctx, op1, rd, rs, rt);
14420 case OPC_AND: /* Logic*/
14424 gen_logic(ctx, op1, rd, rs, rt);
14426 case OPC_MULT ... OPC_DIVU:
14428 check_insn(ctx, INSN_VR54XX);
14429 op1 = MASK_MUL_VR54XX(ctx->opcode);
14430 gen_mul_vr54xx(ctx, op1, rd, rs, rt);
14432 gen_muldiv(ctx, op1, rs, rt);
14434 case OPC_JR ... OPC_JALR:
14435 gen_compute_branch(ctx, op1, 4, rs, rd, sa);
14438 case OPC_TGE ... OPC_TEQ: /* Traps */
14440 gen_trap(ctx, op1, rs, rt, -1);
14442 case OPC_MFHI: /* Move from HI/LO */
14444 gen_HILO(ctx, op1, rd);
14447 case OPC_MTLO: /* Move to HI/LO */
14448 gen_HILO(ctx, op1, rs);
14450 case OPC_PMON: /* Pmon entry point, also R4010 selsl */
14451 #ifdef MIPS_STRICT_STANDARD
14452 MIPS_INVAL("PMON / selsl");
14453 generate_exception(ctx, EXCP_RI);
14455 gen_helper_0e0i(pmon, sa);
14459 generate_exception(ctx, EXCP_SYSCALL);
14460 ctx->bstate = BS_STOP;
14463 generate_exception(ctx, EXCP_BREAK);
14466 #ifdef MIPS_STRICT_STANDARD
14467 MIPS_INVAL("SPIM");
14468 generate_exception(ctx, EXCP_RI);
14470 /* Implemented as RI exception for now. */
14471 MIPS_INVAL("spim (unofficial)");
14472 generate_exception(ctx, EXCP_RI);
14476 /* Treat as NOP. */
14480 check_insn(ctx, ISA_MIPS4 | ISA_MIPS32);
14481 if (env->CP0_Config1 & (1 << CP0C1_FP)) {
14482 check_cp1_enabled(ctx);
14483 gen_movci(ctx, rd, rs, (ctx->opcode >> 18) & 0x7,
14484 (ctx->opcode >> 16) & 1);
14486 generate_exception_err(ctx, EXCP_CpU, 1);
14490 #if defined(TARGET_MIPS64)
14491 /* MIPS64 specific opcodes */
14496 check_insn(ctx, ISA_MIPS3);
14497 check_mips_64(ctx);
14498 gen_shift_imm(ctx, op1, rd, rt, sa);
14501 switch ((ctx->opcode >> 21) & 0x1f) {
14503 /* drotr is decoded as dsrl on non-R2 CPUs */
14504 if (ctx->insn_flags & ISA_MIPS32R2) {
14509 check_insn(ctx, ISA_MIPS3);
14510 check_mips_64(ctx);
14511 gen_shift_imm(ctx, op1, rd, rt, sa);
14514 generate_exception(ctx, EXCP_RI);
14519 switch ((ctx->opcode >> 21) & 0x1f) {
14521 /* drotr32 is decoded as dsrl32 on non-R2 CPUs */
14522 if (ctx->insn_flags & ISA_MIPS32R2) {
14527 check_insn(ctx, ISA_MIPS3);
14528 check_mips_64(ctx);
14529 gen_shift_imm(ctx, op1, rd, rt, sa);
14532 generate_exception(ctx, EXCP_RI);
14536 case OPC_DADD ... OPC_DSUBU:
14537 check_insn(ctx, ISA_MIPS3);
14538 check_mips_64(ctx);
14539 gen_arith(ctx, op1, rd, rs, rt);
14543 check_insn(ctx, ISA_MIPS3);
14544 check_mips_64(ctx);
14545 gen_shift(ctx, op1, rd, rs, rt);
14548 switch ((ctx->opcode >> 6) & 0x1f) {
14550 /* drotrv is decoded as dsrlv on non-R2 CPUs */
14551 if (ctx->insn_flags & ISA_MIPS32R2) {
14556 check_insn(ctx, ISA_MIPS3);
14557 check_mips_64(ctx);
14558 gen_shift(ctx, op1, rd, rs, rt);
14561 generate_exception(ctx, EXCP_RI);
14565 case OPC_DMULT ... OPC_DDIVU:
14566 check_insn(ctx, ISA_MIPS3);
14567 check_mips_64(ctx);
14568 gen_muldiv(ctx, op1, rs, rt);
14571 default: /* Invalid */
14572 MIPS_INVAL("special");
14573 generate_exception(ctx, EXCP_RI);
14578 op1 = MASK_SPECIAL2(ctx->opcode);
14580 case OPC_MADD ... OPC_MADDU: /* Multiply and add/sub */
14581 case OPC_MSUB ... OPC_MSUBU:
14582 check_insn(ctx, ISA_MIPS32);
14583 gen_muldiv(ctx, op1, rs, rt);
14586 gen_arith(ctx, op1, rd, rs, rt);
14590 check_insn(ctx, ISA_MIPS32);
14591 gen_cl(ctx, op1, rd, rs);
14594 /* XXX: not clear which exception should be raised
14595 * when in debug mode...
14597 check_insn(ctx, ISA_MIPS32);
14598 if (!(ctx->hflags & MIPS_HFLAG_DM)) {
14599 generate_exception(ctx, EXCP_DBp);
14601 generate_exception(ctx, EXCP_DBp);
14603 /* Treat as NOP. */
14606 case OPC_DIVU_G_2F:
14607 case OPC_MULT_G_2F:
14608 case OPC_MULTU_G_2F:
14610 case OPC_MODU_G_2F:
14611 check_insn(ctx, INSN_LOONGSON2F);
14612 gen_loongson_integer(ctx, op1, rd, rs, rt);
14614 #if defined(TARGET_MIPS64)
14617 check_insn(ctx, ISA_MIPS64);
14618 check_mips_64(ctx);
14619 gen_cl(ctx, op1, rd, rs);
14621 case OPC_DMULT_G_2F:
14622 case OPC_DMULTU_G_2F:
14623 case OPC_DDIV_G_2F:
14624 case OPC_DDIVU_G_2F:
14625 case OPC_DMOD_G_2F:
14626 case OPC_DMODU_G_2F:
14627 check_insn(ctx, INSN_LOONGSON2F);
14628 gen_loongson_integer(ctx, op1, rd, rs, rt);
14631 default: /* Invalid */
14632 MIPS_INVAL("special2");
14633 generate_exception(ctx, EXCP_RI);
14638 op1 = MASK_SPECIAL3(ctx->opcode);
14642 check_insn(ctx, ISA_MIPS32R2);
14643 gen_bitops(ctx, op1, rt, rs, sa, rd);
14646 check_insn(ctx, ISA_MIPS32R2);
14647 op2 = MASK_BSHFL(ctx->opcode);
14648 gen_bshfl(ctx, op2, rt, rd);
14651 gen_rdhwr(ctx, rt, rd);
14654 check_insn(ctx, ASE_MT);
14656 TCGv t0 = tcg_temp_new();
14657 TCGv t1 = tcg_temp_new();
14659 gen_load_gpr(t0, rt);
14660 gen_load_gpr(t1, rs);
14661 gen_helper_fork(t0, t1);
14667 check_insn(ctx, ASE_MT);
14669 TCGv t0 = tcg_temp_new();
14671 save_cpu_state(ctx, 1);
14672 gen_load_gpr(t0, rs);
14673 gen_helper_yield(t0, cpu_env, t0);
14674 gen_store_gpr(t0, rd);
14678 case OPC_DIV_G_2E ... OPC_DIVU_G_2E:
14679 case OPC_MOD_G_2E ... OPC_MODU_G_2E:
14680 case OPC_MULT_G_2E ... OPC_MULTU_G_2E:
14681 /* OPC_MULT_G_2E, OPC_ADDUH_QB_DSP, OPC_MUL_PH_DSP have
14682 * the same mask and op1. */
14683 if ((ctx->insn_flags & ASE_DSPR2) && (op1 == OPC_MULT_G_2E)) {
14684 op2 = MASK_ADDUH_QB(ctx->opcode);
14687 case OPC_ADDUH_R_QB:
14689 case OPC_ADDQH_R_PH:
14691 case OPC_ADDQH_R_W:
14693 case OPC_SUBUH_R_QB:
14695 case OPC_SUBQH_R_PH:
14697 case OPC_SUBQH_R_W:
14698 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
14703 case OPC_MULQ_RS_W:
14704 gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 1);
14707 MIPS_INVAL("MASK ADDUH.QB");
14708 generate_exception(ctx, EXCP_RI);
14711 } else if (ctx->insn_flags & INSN_LOONGSON2E) {
14712 gen_loongson_integer(ctx, op1, rd, rs, rt);
14714 generate_exception(ctx, EXCP_RI);
14718 op2 = MASK_LX(ctx->opcode);
14720 #if defined(TARGET_MIPS64)
14726 gen_mipsdsp_ld(ctx, op2, rd, rs, rt);
14728 default: /* Invalid */
14729 MIPS_INVAL("MASK LX");
14730 generate_exception(ctx, EXCP_RI);
14734 case OPC_ABSQ_S_PH_DSP:
14735 op2 = MASK_ABSQ_S_PH(ctx->opcode);
14737 case OPC_ABSQ_S_QB:
14738 case OPC_ABSQ_S_PH:
14740 case OPC_PRECEQ_W_PHL:
14741 case OPC_PRECEQ_W_PHR:
14742 case OPC_PRECEQU_PH_QBL:
14743 case OPC_PRECEQU_PH_QBR:
14744 case OPC_PRECEQU_PH_QBLA:
14745 case OPC_PRECEQU_PH_QBRA:
14746 case OPC_PRECEU_PH_QBL:
14747 case OPC_PRECEU_PH_QBR:
14748 case OPC_PRECEU_PH_QBLA:
14749 case OPC_PRECEU_PH_QBRA:
14750 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
14757 gen_mipsdsp_bitinsn(ctx, op1, op2, rd, rt);
14760 MIPS_INVAL("MASK ABSQ_S.PH");
14761 generate_exception(ctx, EXCP_RI);
14765 case OPC_ADDU_QB_DSP:
14766 op2 = MASK_ADDU_QB(ctx->opcode);
14769 case OPC_ADDQ_S_PH:
14772 case OPC_ADDU_S_QB:
14774 case OPC_ADDU_S_PH:
14776 case OPC_SUBQ_S_PH:
14779 case OPC_SUBU_S_QB:
14781 case OPC_SUBU_S_PH:
14785 case OPC_RADDU_W_QB:
14786 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
14788 case OPC_MULEU_S_PH_QBL:
14789 case OPC_MULEU_S_PH_QBR:
14790 case OPC_MULQ_RS_PH:
14791 case OPC_MULEQ_S_W_PHL:
14792 case OPC_MULEQ_S_W_PHR:
14793 case OPC_MULQ_S_PH:
14794 gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 1);
14796 default: /* Invalid */
14797 MIPS_INVAL("MASK ADDU.QB");
14798 generate_exception(ctx, EXCP_RI);
14803 case OPC_CMPU_EQ_QB_DSP:
14804 op2 = MASK_CMPU_EQ_QB(ctx->opcode);
14806 case OPC_PRECR_SRA_PH_W:
14807 case OPC_PRECR_SRA_R_PH_W:
14808 gen_mipsdsp_arith(ctx, op1, op2, rt, rs, rd);
14810 case OPC_PRECR_QB_PH:
14811 case OPC_PRECRQ_QB_PH:
14812 case OPC_PRECRQ_PH_W:
14813 case OPC_PRECRQ_RS_PH_W:
14814 case OPC_PRECRQU_S_QB_PH:
14815 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
14817 case OPC_CMPU_EQ_QB:
14818 case OPC_CMPU_LT_QB:
14819 case OPC_CMPU_LE_QB:
14820 case OPC_CMP_EQ_PH:
14821 case OPC_CMP_LT_PH:
14822 case OPC_CMP_LE_PH:
14823 gen_mipsdsp_add_cmp_pick(ctx, op1, op2, rd, rs, rt, 0);
14825 case OPC_CMPGU_EQ_QB:
14826 case OPC_CMPGU_LT_QB:
14827 case OPC_CMPGU_LE_QB:
14828 case OPC_CMPGDU_EQ_QB:
14829 case OPC_CMPGDU_LT_QB:
14830 case OPC_CMPGDU_LE_QB:
14833 case OPC_PACKRL_PH:
14834 gen_mipsdsp_add_cmp_pick(ctx, op1, op2, rd, rs, rt, 1);
14836 default: /* Invalid */
14837 MIPS_INVAL("MASK CMPU.EQ.QB");
14838 generate_exception(ctx, EXCP_RI);
14842 case OPC_SHLL_QB_DSP:
14843 gen_mipsdsp_shift(ctx, op1, rd, rs, rt);
14845 case OPC_DPA_W_PH_DSP:
14846 op2 = MASK_DPA_W_PH(ctx->opcode);
14848 case OPC_DPAU_H_QBL:
14849 case OPC_DPAU_H_QBR:
14850 case OPC_DPSU_H_QBL:
14851 case OPC_DPSU_H_QBR:
14853 case OPC_DPAX_W_PH:
14854 case OPC_DPAQ_S_W_PH:
14855 case OPC_DPAQX_S_W_PH:
14856 case OPC_DPAQX_SA_W_PH:
14858 case OPC_DPSX_W_PH:
14859 case OPC_DPSQ_S_W_PH:
14860 case OPC_DPSQX_S_W_PH:
14861 case OPC_DPSQX_SA_W_PH:
14862 case OPC_MULSAQ_S_W_PH:
14863 case OPC_DPAQ_SA_L_W:
14864 case OPC_DPSQ_SA_L_W:
14865 case OPC_MAQ_S_W_PHL:
14866 case OPC_MAQ_S_W_PHR:
14867 case OPC_MAQ_SA_W_PHL:
14868 case OPC_MAQ_SA_W_PHR:
14869 case OPC_MULSA_W_PH:
14870 gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 0);
14872 default: /* Invalid */
14873 MIPS_INVAL("MASK DPAW.PH");
14874 generate_exception(ctx, EXCP_RI);
14879 op2 = MASK_INSV(ctx->opcode);
14891 t0 = tcg_temp_new();
14892 t1 = tcg_temp_new();
14894 gen_load_gpr(t0, rt);
14895 gen_load_gpr(t1, rs);
14897 gen_helper_insv(cpu_gpr[rt], cpu_env, t1, t0);
14903 default: /* Invalid */
14904 MIPS_INVAL("MASK INSV");
14905 generate_exception(ctx, EXCP_RI);
14909 case OPC_APPEND_DSP:
14911 op2 = MASK_APPEND(ctx->opcode);
14912 gen_mipsdsp_add_cmp_pick(ctx, op1, op2, rt, rs, rd, 1);
14914 case OPC_EXTR_W_DSP:
14915 op2 = MASK_EXTR_W(ctx->opcode);
14919 case OPC_EXTR_RS_W:
14921 case OPC_EXTRV_S_H:
14923 case OPC_EXTRV_R_W:
14924 case OPC_EXTRV_RS_W:
14929 gen_mipsdsp_accinsn(ctx, op1, op2, rt, rs, rd, 1);
14932 gen_mipsdsp_accinsn(ctx, op1, op2, rd, rs, rt, 1);
14938 gen_mipsdsp_accinsn(ctx, op1, op2, rd, rs, rt, 0);
14940 default: /* Invalid */
14941 MIPS_INVAL("MASK EXTR.W");
14942 generate_exception(ctx, EXCP_RI);
14946 #if defined(TARGET_MIPS64)
14947 case OPC_DEXTM ... OPC_DEXT:
14948 case OPC_DINSM ... OPC_DINS:
14949 check_insn(ctx, ISA_MIPS64R2);
14950 check_mips_64(ctx);
14951 gen_bitops(ctx, op1, rt, rs, sa, rd);
14954 check_insn(ctx, ISA_MIPS64R2);
14955 check_mips_64(ctx);
14956 op2 = MASK_DBSHFL(ctx->opcode);
14957 gen_bshfl(ctx, op2, rt, rd);
14959 case OPC_DDIV_G_2E ... OPC_DDIVU_G_2E:
14960 case OPC_DMULT_G_2E ... OPC_DMULTU_G_2E:
14961 case OPC_DMOD_G_2E ... OPC_DMODU_G_2E:
14962 check_insn(ctx, INSN_LOONGSON2E);
14963 gen_loongson_integer(ctx, op1, rd, rs, rt);
14965 case OPC_ABSQ_S_QH_DSP:
14966 op2 = MASK_ABSQ_S_QH(ctx->opcode);
14968 case OPC_PRECEQ_L_PWL:
14969 case OPC_PRECEQ_L_PWR:
14970 case OPC_PRECEQ_PW_QHL:
14971 case OPC_PRECEQ_PW_QHR:
14972 case OPC_PRECEQ_PW_QHLA:
14973 case OPC_PRECEQ_PW_QHRA:
14974 case OPC_PRECEQU_QH_OBL:
14975 case OPC_PRECEQU_QH_OBR:
14976 case OPC_PRECEQU_QH_OBLA:
14977 case OPC_PRECEQU_QH_OBRA:
14978 case OPC_PRECEU_QH_OBL:
14979 case OPC_PRECEU_QH_OBR:
14980 case OPC_PRECEU_QH_OBLA:
14981 case OPC_PRECEU_QH_OBRA:
14982 case OPC_ABSQ_S_OB:
14983 case OPC_ABSQ_S_PW:
14984 case OPC_ABSQ_S_QH:
14985 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
14993 gen_mipsdsp_bitinsn(ctx, op1, op2, rd, rt);
14995 default: /* Invalid */
14996 MIPS_INVAL("MASK ABSQ_S.QH");
14997 generate_exception(ctx, EXCP_RI);
15001 case OPC_ADDU_OB_DSP:
15002 op2 = MASK_ADDU_OB(ctx->opcode);
15004 case OPC_RADDU_L_OB:
15006 case OPC_SUBQ_S_PW:
15008 case OPC_SUBQ_S_QH:
15010 case OPC_SUBU_S_OB:
15012 case OPC_SUBU_S_QH:
15014 case OPC_SUBUH_R_OB:
15016 case OPC_ADDQ_S_PW:
15018 case OPC_ADDQ_S_QH:
15020 case OPC_ADDU_S_OB:
15022 case OPC_ADDU_S_QH:
15024 case OPC_ADDUH_R_OB:
15025 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
15027 case OPC_MULEQ_S_PW_QHL:
15028 case OPC_MULEQ_S_PW_QHR:
15029 case OPC_MULEU_S_QH_OBL:
15030 case OPC_MULEU_S_QH_OBR:
15031 case OPC_MULQ_RS_QH:
15032 gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 1);
15034 default: /* Invalid */
15035 MIPS_INVAL("MASK ADDU.OB");
15036 generate_exception(ctx, EXCP_RI);
15040 case OPC_CMPU_EQ_OB_DSP:
15041 op2 = MASK_CMPU_EQ_OB(ctx->opcode);
15043 case OPC_PRECR_SRA_QH_PW:
15044 case OPC_PRECR_SRA_R_QH_PW:
15045 /* Return value is rt. */
15046 gen_mipsdsp_arith(ctx, op1, op2, rt, rs, rd);
15048 case OPC_PRECR_OB_QH:
15049 case OPC_PRECRQ_OB_QH:
15050 case OPC_PRECRQ_PW_L:
15051 case OPC_PRECRQ_QH_PW:
15052 case OPC_PRECRQ_RS_QH_PW:
15053 case OPC_PRECRQU_S_OB_QH:
15054 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
15056 case OPC_CMPU_EQ_OB:
15057 case OPC_CMPU_LT_OB:
15058 case OPC_CMPU_LE_OB:
15059 case OPC_CMP_EQ_QH:
15060 case OPC_CMP_LT_QH:
15061 case OPC_CMP_LE_QH:
15062 case OPC_CMP_EQ_PW:
15063 case OPC_CMP_LT_PW:
15064 case OPC_CMP_LE_PW:
15065 gen_mipsdsp_add_cmp_pick(ctx, op1, op2, rd, rs, rt, 0);
15067 case OPC_CMPGDU_EQ_OB:
15068 case OPC_CMPGDU_LT_OB:
15069 case OPC_CMPGDU_LE_OB:
15070 case OPC_CMPGU_EQ_OB:
15071 case OPC_CMPGU_LT_OB:
15072 case OPC_CMPGU_LE_OB:
15073 case OPC_PACKRL_PW:
15077 gen_mipsdsp_add_cmp_pick(ctx, op1, op2, rd, rs, rt, 1);
15079 default: /* Invalid */
15080 MIPS_INVAL("MASK CMPU_EQ.OB");
15081 generate_exception(ctx, EXCP_RI);
15085 case OPC_DAPPEND_DSP:
15087 op2 = MASK_DAPPEND(ctx->opcode);
15088 gen_mipsdsp_add_cmp_pick(ctx, op1, op2, rt, rs, rd, 1);
15090 case OPC_DEXTR_W_DSP:
15091 op2 = MASK_DEXTR_W(ctx->opcode);
15098 case OPC_DEXTR_R_L:
15099 case OPC_DEXTR_RS_L:
15101 case OPC_DEXTR_R_W:
15102 case OPC_DEXTR_RS_W:
15103 case OPC_DEXTR_S_H:
15105 case OPC_DEXTRV_R_L:
15106 case OPC_DEXTRV_RS_L:
15107 case OPC_DEXTRV_S_H:
15109 case OPC_DEXTRV_R_W:
15110 case OPC_DEXTRV_RS_W:
15111 gen_mipsdsp_accinsn(ctx, op1, op2, rt, rs, rd, 1);
15116 gen_mipsdsp_accinsn(ctx, op1, op2, rd, rs, rt, 0);
15118 default: /* Invalid */
15119 MIPS_INVAL("MASK EXTR.W");
15120 generate_exception(ctx, EXCP_RI);
15124 case OPC_DPAQ_W_QH_DSP:
15125 op2 = MASK_DPAQ_W_QH(ctx->opcode);
15127 case OPC_DPAU_H_OBL:
15128 case OPC_DPAU_H_OBR:
15129 case OPC_DPSU_H_OBL:
15130 case OPC_DPSU_H_OBR:
15132 case OPC_DPAQ_S_W_QH:
15134 case OPC_DPSQ_S_W_QH:
15135 case OPC_MULSAQ_S_W_QH:
15136 case OPC_DPAQ_SA_L_PW:
15137 case OPC_DPSQ_SA_L_PW:
15138 case OPC_MULSAQ_S_L_PW:
15139 gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 0);
15141 case OPC_MAQ_S_W_QHLL:
15142 case OPC_MAQ_S_W_QHLR:
15143 case OPC_MAQ_S_W_QHRL:
15144 case OPC_MAQ_S_W_QHRR:
15145 case OPC_MAQ_SA_W_QHLL:
15146 case OPC_MAQ_SA_W_QHLR:
15147 case OPC_MAQ_SA_W_QHRL:
15148 case OPC_MAQ_SA_W_QHRR:
15149 case OPC_MAQ_S_L_PWL:
15150 case OPC_MAQ_S_L_PWR:
15155 gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 0);
15157 default: /* Invalid */
15158 MIPS_INVAL("MASK DPAQ.W.QH");
15159 generate_exception(ctx, EXCP_RI);
15163 case OPC_DINSV_DSP:
15164 op2 = MASK_INSV(ctx->opcode);
15176 t0 = tcg_temp_new();
15177 t1 = tcg_temp_new();
15179 gen_load_gpr(t0, rt);
15180 gen_load_gpr(t1, rs);
15182 gen_helper_dinsv(cpu_gpr[rt], cpu_env, t1, t0);
15185 default: /* Invalid */
15186 MIPS_INVAL("MASK DINSV");
15187 generate_exception(ctx, EXCP_RI);
15191 case OPC_SHLL_OB_DSP:
15192 gen_mipsdsp_shift(ctx, op1, rd, rs, rt);
15195 default: /* Invalid */
15196 MIPS_INVAL("special3");
15197 generate_exception(ctx, EXCP_RI);
15202 op1 = MASK_REGIMM(ctx->opcode);
15204 case OPC_BLTZ ... OPC_BGEZL: /* REGIMM branches */
15205 case OPC_BLTZAL ... OPC_BGEZALL:
15206 gen_compute_branch(ctx, op1, 4, rs, -1, imm << 2);
15209 case OPC_TGEI ... OPC_TEQI: /* REGIMM traps */
15211 gen_trap(ctx, op1, rs, -1, imm);
15214 check_insn(ctx, ISA_MIPS32R2);
15215 /* Treat as NOP. */
15217 case OPC_BPOSGE32: /* MIPS DSP branch */
15218 #if defined(TARGET_MIPS64)
15222 gen_compute_branch(ctx, op1, 4, -1, -2, (int32_t)imm << 2);
15225 default: /* Invalid */
15226 MIPS_INVAL("regimm");
15227 generate_exception(ctx, EXCP_RI);
15232 check_cp0_enabled(ctx);
15233 op1 = MASK_CP0(ctx->opcode);
15239 #if defined(TARGET_MIPS64)
15243 #ifndef CONFIG_USER_ONLY
15244 gen_cp0(env, ctx, op1, rt, rd);
15245 #endif /* !CONFIG_USER_ONLY */
15247 case OPC_C0_FIRST ... OPC_C0_LAST:
15248 #ifndef CONFIG_USER_ONLY
15249 gen_cp0(env, ctx, MASK_C0(ctx->opcode), rt, rd);
15250 #endif /* !CONFIG_USER_ONLY */
15253 #ifndef CONFIG_USER_ONLY
15255 TCGv t0 = tcg_temp_new();
15257 op2 = MASK_MFMC0(ctx->opcode);
15260 check_insn(ctx, ASE_MT);
15261 gen_helper_dmt(t0);
15262 gen_store_gpr(t0, rt);
15265 check_insn(ctx, ASE_MT);
15266 gen_helper_emt(t0);
15267 gen_store_gpr(t0, rt);
15270 check_insn(ctx, ASE_MT);
15271 gen_helper_dvpe(t0, cpu_env);
15272 gen_store_gpr(t0, rt);
15275 check_insn(ctx, ASE_MT);
15276 gen_helper_evpe(t0, cpu_env);
15277 gen_store_gpr(t0, rt);
15280 check_insn(ctx, ISA_MIPS32R2);
15281 save_cpu_state(ctx, 1);
15282 gen_helper_di(t0, cpu_env);
15283 gen_store_gpr(t0, rt);
15284 /* Stop translation as we may have switched the execution mode */
15285 ctx->bstate = BS_STOP;
15288 check_insn(ctx, ISA_MIPS32R2);
15289 save_cpu_state(ctx, 1);
15290 gen_helper_ei(t0, cpu_env);
15291 gen_store_gpr(t0, rt);
15292 /* Stop translation as we may have switched the execution mode */
15293 ctx->bstate = BS_STOP;
15295 default: /* Invalid */
15296 MIPS_INVAL("mfmc0");
15297 generate_exception(ctx, EXCP_RI);
15302 #endif /* !CONFIG_USER_ONLY */
15305 check_insn(ctx, ISA_MIPS32R2);
15306 gen_load_srsgpr(rt, rd);
15309 check_insn(ctx, ISA_MIPS32R2);
15310 gen_store_srsgpr(rt, rd);
15314 generate_exception(ctx, EXCP_RI);
15318 case OPC_ADDI: /* Arithmetic with immediate opcode */
15320 gen_arith_imm(ctx, op, rt, rs, imm);
15322 case OPC_SLTI: /* Set on less than with immediate opcode */
15324 gen_slt_imm(ctx, op, rt, rs, imm);
15326 case OPC_ANDI: /* Arithmetic with immediate opcode */
15330 gen_logic_imm(ctx, op, rt, rs, imm);
15332 case OPC_J ... OPC_JAL: /* Jump */
15333 offset = (int32_t)(ctx->opcode & 0x3FFFFFF) << 2;
15334 gen_compute_branch(ctx, op, 4, rs, rt, offset);
15337 case OPC_BEQ ... OPC_BGTZ: /* Branch */
15338 case OPC_BEQL ... OPC_BGTZL:
15339 gen_compute_branch(ctx, op, 4, rs, rt, imm << 2);
15342 case OPC_LB ... OPC_LWR: /* Load and stores */
15344 gen_ld(ctx, op, rt, rs, imm);
15346 case OPC_SB ... OPC_SW:
15348 gen_st(ctx, op, rt, rs, imm);
15351 gen_st_cond(ctx, op, rt, rs, imm);
15354 check_cp0_enabled(ctx);
15355 check_insn(ctx, ISA_MIPS3 | ISA_MIPS32);
15356 /* Treat as NOP. */
15359 check_insn(ctx, ISA_MIPS4 | ISA_MIPS32);
15360 /* Treat as NOP. */
15363 /* Floating point (COP1). */
15368 gen_cop1_ldst(env, ctx, op, rt, rs, imm);
15372 if (env->CP0_Config1 & (1 << CP0C1_FP)) {
15373 check_cp1_enabled(ctx);
15374 op1 = MASK_CP1(ctx->opcode);
15378 check_insn(ctx, ISA_MIPS32R2);
15383 gen_cp1(ctx, op1, rt, rd);
15385 #if defined(TARGET_MIPS64)
15388 check_insn(ctx, ISA_MIPS3);
15389 gen_cp1(ctx, op1, rt, rd);
15395 check_insn(ctx, ASE_MIPS3D);
15398 gen_compute_branch1(ctx, MASK_BC1(ctx->opcode),
15399 (rt >> 2) & 0x7, imm << 2);
15407 gen_farith(ctx, ctx->opcode & FOP(0x3f, 0x1f), rt, rd, sa,
15412 generate_exception (ctx, EXCP_RI);
15416 generate_exception_err(ctx, EXCP_CpU, 1);
15425 /* COP2: Not implemented. */
15426 generate_exception_err(ctx, EXCP_CpU, 2);
15429 check_insn(ctx, INSN_LOONGSON2F);
15430 /* Note that these instructions use different fields. */
15431 gen_loongson_multimedia(ctx, sa, rd, rt);
15435 if (env->CP0_Config1 & (1 << CP0C1_FP)) {
15436 check_cp1_enabled(ctx);
15437 op1 = MASK_CP3(ctx->opcode);
15445 gen_flt3_ldst(ctx, op1, sa, rd, rs, rt);
15448 /* Treat as NOP. */
15463 gen_flt3_arith(ctx, op1, sa, rs, rd, rt);
15467 generate_exception (ctx, EXCP_RI);
15471 generate_exception_err(ctx, EXCP_CpU, 1);
15475 #if defined(TARGET_MIPS64)
15476 /* MIPS64 opcodes */
15478 case OPC_LDL ... OPC_LDR:
15481 check_insn(ctx, ISA_MIPS3);
15482 check_mips_64(ctx);
15483 gen_ld(ctx, op, rt, rs, imm);
15485 case OPC_SDL ... OPC_SDR:
15487 check_insn(ctx, ISA_MIPS3);
15488 check_mips_64(ctx);
15489 gen_st(ctx, op, rt, rs, imm);
15492 check_insn(ctx, ISA_MIPS3);
15493 check_mips_64(ctx);
15494 gen_st_cond(ctx, op, rt, rs, imm);
15498 check_insn(ctx, ISA_MIPS3);
15499 check_mips_64(ctx);
15500 gen_arith_imm(ctx, op, rt, rs, imm);
15504 check_insn(ctx, ASE_MIPS16 | ASE_MICROMIPS);
15505 offset = (int32_t)(ctx->opcode & 0x3FFFFFF) << 2;
15506 gen_compute_branch(ctx, op, 4, rs, rt, offset);
15510 check_insn(ctx, ASE_MDMX);
15511 /* MDMX: Not implemented. */
15512 default: /* Invalid */
15513 MIPS_INVAL("major opcode");
15514 generate_exception(ctx, EXCP_RI);
15520 gen_intermediate_code_internal (CPUMIPSState *env, TranslationBlock *tb,
15524 target_ulong pc_start;
15525 uint16_t *gen_opc_end;
15534 qemu_log("search pc %d\n", search_pc);
15537 gen_opc_end = tcg_ctx.gen_opc_buf + OPC_MAX_SIZE;
15540 ctx.singlestep_enabled = env->singlestep_enabled;
15541 ctx.insn_flags = env->insn_flags;
15543 ctx.bstate = BS_NONE;
15544 /* Restore delay slot state from the tb context. */
15545 ctx.hflags = (uint32_t)tb->flags; /* FIXME: maybe use 64 bits here? */
15546 restore_cpu_state(env, &ctx);
15547 #ifdef CONFIG_USER_ONLY
15548 ctx.mem_idx = MIPS_HFLAG_UM;
15550 ctx.mem_idx = ctx.hflags & MIPS_HFLAG_KSU;
15553 max_insns = tb->cflags & CF_COUNT_MASK;
15554 if (max_insns == 0)
15555 max_insns = CF_COUNT_MASK;
15556 LOG_DISAS("\ntb %p idx %d hflags %04x\n", tb, ctx.mem_idx, ctx.hflags);
15557 gen_icount_start();
15558 while (ctx.bstate == BS_NONE) {
15559 if (unlikely(!QTAILQ_EMPTY(&env->breakpoints))) {
15560 QTAILQ_FOREACH(bp, &env->breakpoints, entry) {
15561 if (bp->pc == ctx.pc) {
15562 save_cpu_state(&ctx, 1);
15563 ctx.bstate = BS_BRANCH;
15564 gen_helper_0e0i(raise_exception, EXCP_DEBUG);
15565 /* Include the breakpoint location or the tb won't
15566 * be flushed when it must be. */
15568 goto done_generating;
15574 j = tcg_ctx.gen_opc_ptr - tcg_ctx.gen_opc_buf;
15578 tcg_ctx.gen_opc_instr_start[lj++] = 0;
15580 tcg_ctx.gen_opc_pc[lj] = ctx.pc;
15581 gen_opc_hflags[lj] = ctx.hflags & MIPS_HFLAG_BMASK;
15582 gen_opc_btarget[lj] = ctx.btarget;
15583 tcg_ctx.gen_opc_instr_start[lj] = 1;
15584 tcg_ctx.gen_opc_icount[lj] = num_insns;
15586 if (num_insns + 1 == max_insns && (tb->cflags & CF_LAST_IO))
15590 if (!(ctx.hflags & MIPS_HFLAG_M16)) {
15591 ctx.opcode = cpu_ldl_code(env, ctx.pc);
15593 decode_opc(env, &ctx, &is_branch);
15594 } else if (ctx.insn_flags & ASE_MICROMIPS) {
15595 ctx.opcode = cpu_lduw_code(env, ctx.pc);
15596 insn_bytes = decode_micromips_opc(env, &ctx, &is_branch);
15597 } else if (ctx.insn_flags & ASE_MIPS16) {
15598 ctx.opcode = cpu_lduw_code(env, ctx.pc);
15599 insn_bytes = decode_mips16_opc(env, &ctx, &is_branch);
15601 generate_exception(&ctx, EXCP_RI);
15602 ctx.bstate = BS_STOP;
15606 handle_delay_slot(&ctx, insn_bytes);
15608 ctx.pc += insn_bytes;
15612 /* Execute a branch and its delay slot as a single instruction.
15613 This is what GDB expects and is consistent with what the
15614 hardware does (e.g. if a delay slot instruction faults, the
15615 reported PC is the PC of the branch). */
15616 if (env->singlestep_enabled && (ctx.hflags & MIPS_HFLAG_BMASK) == 0)
15619 if ((ctx.pc & (TARGET_PAGE_SIZE - 1)) == 0)
15622 if (tcg_ctx.gen_opc_ptr >= gen_opc_end) {
15626 if (num_insns >= max_insns)
15632 if (tb->cflags & CF_LAST_IO)
15634 if (env->singlestep_enabled && ctx.bstate != BS_BRANCH) {
15635 save_cpu_state(&ctx, ctx.bstate == BS_NONE);
15636 gen_helper_0e0i(raise_exception, EXCP_DEBUG);
15638 switch (ctx.bstate) {
15640 gen_goto_tb(&ctx, 0, ctx.pc);
15643 save_cpu_state(&ctx, 0);
15644 gen_goto_tb(&ctx, 0, ctx.pc);
15647 tcg_gen_exit_tb(0);
15655 gen_icount_end(tb, num_insns);
15656 *tcg_ctx.gen_opc_ptr = INDEX_op_end;
15658 j = tcg_ctx.gen_opc_ptr - tcg_ctx.gen_opc_buf;
15661 tcg_ctx.gen_opc_instr_start[lj++] = 0;
15663 tb->size = ctx.pc - pc_start;
15664 tb->icount = num_insns;
15668 if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM)) {
15669 qemu_log("IN: %s\n", lookup_symbol(pc_start));
15670 log_target_disas(env, pc_start, ctx.pc - pc_start, 0);
15676 void gen_intermediate_code (CPUMIPSState *env, struct TranslationBlock *tb)
15678 gen_intermediate_code_internal(env, tb, 0);
15681 void gen_intermediate_code_pc (CPUMIPSState *env, struct TranslationBlock *tb)
15683 gen_intermediate_code_internal(env, tb, 1);
15686 static void fpu_dump_state(CPUMIPSState *env, FILE *f, fprintf_function fpu_fprintf,
15690 int is_fpu64 = !!(env->hflags & MIPS_HFLAG_F64);
15692 #define printfpr(fp) \
15695 fpu_fprintf(f, "w:%08x d:%016" PRIx64 \
15696 " fd:%13g fs:%13g psu: %13g\n", \
15697 (fp)->w[FP_ENDIAN_IDX], (fp)->d, \
15698 (double)(fp)->fd, \
15699 (double)(fp)->fs[FP_ENDIAN_IDX], \
15700 (double)(fp)->fs[!FP_ENDIAN_IDX]); \
15703 tmp.w[FP_ENDIAN_IDX] = (fp)->w[FP_ENDIAN_IDX]; \
15704 tmp.w[!FP_ENDIAN_IDX] = ((fp) + 1)->w[FP_ENDIAN_IDX]; \
15705 fpu_fprintf(f, "w:%08x d:%016" PRIx64 \
15706 " fd:%13g fs:%13g psu:%13g\n", \
15707 tmp.w[FP_ENDIAN_IDX], tmp.d, \
15709 (double)tmp.fs[FP_ENDIAN_IDX], \
15710 (double)tmp.fs[!FP_ENDIAN_IDX]); \
15715 fpu_fprintf(f, "CP1 FCR0 0x%08x FCR31 0x%08x SR.FR %d fp_status 0x%02x\n",
15716 env->active_fpu.fcr0, env->active_fpu.fcr31, is_fpu64,
15717 get_float_exception_flags(&env->active_fpu.fp_status));
15718 for (i = 0; i < 32; (is_fpu64) ? i++ : (i += 2)) {
15719 fpu_fprintf(f, "%3s: ", fregnames[i]);
15720 printfpr(&env->active_fpu.fpr[i]);
15726 #if defined(TARGET_MIPS64) && defined(MIPS_DEBUG_SIGN_EXTENSIONS)
15727 /* Debug help: The architecture requires 32bit code to maintain proper
15728 sign-extended values on 64bit machines. */
15730 #define SIGN_EXT_P(val) ((((val) & ~0x7fffffff) == 0) || (((val) & ~0x7fffffff) == ~0x7fffffff))
15733 cpu_mips_check_sign_extensions (CPUMIPSState *env, FILE *f,
15734 fprintf_function cpu_fprintf,
15739 if (!SIGN_EXT_P(env->active_tc.PC))
15740 cpu_fprintf(f, "BROKEN: pc=0x" TARGET_FMT_lx "\n", env->active_tc.PC);
15741 if (!SIGN_EXT_P(env->active_tc.HI[0]))
15742 cpu_fprintf(f, "BROKEN: HI=0x" TARGET_FMT_lx "\n", env->active_tc.HI[0]);
15743 if (!SIGN_EXT_P(env->active_tc.LO[0]))
15744 cpu_fprintf(f, "BROKEN: LO=0x" TARGET_FMT_lx "\n", env->active_tc.LO[0]);
15745 if (!SIGN_EXT_P(env->btarget))
15746 cpu_fprintf(f, "BROKEN: btarget=0x" TARGET_FMT_lx "\n", env->btarget);
15748 for (i = 0; i < 32; i++) {
15749 if (!SIGN_EXT_P(env->active_tc.gpr[i]))
15750 cpu_fprintf(f, "BROKEN: %s=0x" TARGET_FMT_lx "\n", regnames[i], env->active_tc.gpr[i]);
15753 if (!SIGN_EXT_P(env->CP0_EPC))
15754 cpu_fprintf(f, "BROKEN: EPC=0x" TARGET_FMT_lx "\n", env->CP0_EPC);
15755 if (!SIGN_EXT_P(env->lladdr))
15756 cpu_fprintf(f, "BROKEN: LLAddr=0x" TARGET_FMT_lx "\n", env->lladdr);
15760 void cpu_dump_state (CPUMIPSState *env, FILE *f, fprintf_function cpu_fprintf,
15765 cpu_fprintf(f, "pc=0x" TARGET_FMT_lx " HI=0x" TARGET_FMT_lx
15766 " LO=0x" TARGET_FMT_lx " ds %04x "
15767 TARGET_FMT_lx " " TARGET_FMT_ld "\n",
15768 env->active_tc.PC, env->active_tc.HI[0], env->active_tc.LO[0],
15769 env->hflags, env->btarget, env->bcond);
15770 for (i = 0; i < 32; i++) {
15772 cpu_fprintf(f, "GPR%02d:", i);
15773 cpu_fprintf(f, " %s " TARGET_FMT_lx, regnames[i], env->active_tc.gpr[i]);
15775 cpu_fprintf(f, "\n");
15778 cpu_fprintf(f, "CP0 Status 0x%08x Cause 0x%08x EPC 0x" TARGET_FMT_lx "\n",
15779 env->CP0_Status, env->CP0_Cause, env->CP0_EPC);
15780 cpu_fprintf(f, " Config0 0x%08x Config1 0x%08x LLAddr 0x" TARGET_FMT_lx "\n",
15781 env->CP0_Config0, env->CP0_Config1, env->lladdr);
15782 if (env->hflags & MIPS_HFLAG_FPU)
15783 fpu_dump_state(env, f, cpu_fprintf, flags);
15784 #if defined(TARGET_MIPS64) && defined(MIPS_DEBUG_SIGN_EXTENSIONS)
15785 cpu_mips_check_sign_extensions(env, f, cpu_fprintf, flags);
15789 static void mips_tcg_init(void)
15794 /* Initialize various static tables. */
15798 cpu_env = tcg_global_reg_new_ptr(TCG_AREG0, "env");
15799 TCGV_UNUSED(cpu_gpr[0]);
15800 for (i = 1; i < 32; i++)
15801 cpu_gpr[i] = tcg_global_mem_new(TCG_AREG0,
15802 offsetof(CPUMIPSState, active_tc.gpr[i]),
15805 for (i = 0; i < 32; i++) {
15806 int off = offsetof(CPUMIPSState, active_fpu.fpr[i]);
15807 fpu_f64[i] = tcg_global_mem_new_i64(TCG_AREG0, off, fregnames[i]);
15810 cpu_PC = tcg_global_mem_new(TCG_AREG0,
15811 offsetof(CPUMIPSState, active_tc.PC), "PC");
15812 for (i = 0; i < MIPS_DSP_ACC; i++) {
15813 cpu_HI[i] = tcg_global_mem_new(TCG_AREG0,
15814 offsetof(CPUMIPSState, active_tc.HI[i]),
15816 cpu_LO[i] = tcg_global_mem_new(TCG_AREG0,
15817 offsetof(CPUMIPSState, active_tc.LO[i]),
15819 cpu_ACX[i] = tcg_global_mem_new(TCG_AREG0,
15820 offsetof(CPUMIPSState, active_tc.ACX[i]),
15823 cpu_dspctrl = tcg_global_mem_new(TCG_AREG0,
15824 offsetof(CPUMIPSState, active_tc.DSPControl),
15826 bcond = tcg_global_mem_new(TCG_AREG0,
15827 offsetof(CPUMIPSState, bcond), "bcond");
15828 btarget = tcg_global_mem_new(TCG_AREG0,
15829 offsetof(CPUMIPSState, btarget), "btarget");
15830 hflags = tcg_global_mem_new_i32(TCG_AREG0,
15831 offsetof(CPUMIPSState, hflags), "hflags");
15833 fpu_fcr0 = tcg_global_mem_new_i32(TCG_AREG0,
15834 offsetof(CPUMIPSState, active_fpu.fcr0),
15836 fpu_fcr31 = tcg_global_mem_new_i32(TCG_AREG0,
15837 offsetof(CPUMIPSState, active_fpu.fcr31),
15840 /* register helpers */
15841 #define GEN_HELPER 2
15842 #include "helper.h"
15847 #include "translate_init.c"
15849 MIPSCPU *cpu_mips_init(const char *cpu_model)
15853 const mips_def_t *def;
15855 def = cpu_mips_find_by_name(cpu_model);
15858 cpu = MIPS_CPU(object_new(TYPE_MIPS_CPU));
15860 env->cpu_model = def;
15861 env->cpu_model_str = cpu_model;
15863 #ifndef CONFIG_USER_ONLY
15864 mmu_init(env, def);
15866 fpu_init(env, def);
15867 mvp_init(env, def);
15869 cpu_reset(CPU(cpu));
15870 qemu_init_vcpu(env);
15874 void cpu_state_reset(CPUMIPSState *env)
15876 #ifndef CONFIG_USER_ONLY
15877 MIPSCPU *cpu = mips_env_get_cpu(env);
15878 CPUState *cs = CPU(cpu);
15881 /* Reset registers to their default values */
15882 env->CP0_PRid = env->cpu_model->CP0_PRid;
15883 env->CP0_Config0 = env->cpu_model->CP0_Config0;
15884 #ifdef TARGET_WORDS_BIGENDIAN
15885 env->CP0_Config0 |= (1 << CP0C0_BE);
15887 env->CP0_Config1 = env->cpu_model->CP0_Config1;
15888 env->CP0_Config2 = env->cpu_model->CP0_Config2;
15889 env->CP0_Config3 = env->cpu_model->CP0_Config3;
15890 env->CP0_Config6 = env->cpu_model->CP0_Config6;
15891 env->CP0_Config7 = env->cpu_model->CP0_Config7;
15892 env->CP0_LLAddr_rw_bitmask = env->cpu_model->CP0_LLAddr_rw_bitmask
15893 << env->cpu_model->CP0_LLAddr_shift;
15894 env->CP0_LLAddr_shift = env->cpu_model->CP0_LLAddr_shift;
15895 env->SYNCI_Step = env->cpu_model->SYNCI_Step;
15896 env->CCRes = env->cpu_model->CCRes;
15897 env->CP0_Status_rw_bitmask = env->cpu_model->CP0_Status_rw_bitmask;
15898 env->CP0_TCStatus_rw_bitmask = env->cpu_model->CP0_TCStatus_rw_bitmask;
15899 env->CP0_SRSCtl = env->cpu_model->CP0_SRSCtl;
15900 env->current_tc = 0;
15901 env->SEGBITS = env->cpu_model->SEGBITS;
15902 env->SEGMask = (target_ulong)((1ULL << env->cpu_model->SEGBITS) - 1);
15903 #if defined(TARGET_MIPS64)
15904 if (env->cpu_model->insn_flags & ISA_MIPS3) {
15905 env->SEGMask |= 3ULL << 62;
15908 env->PABITS = env->cpu_model->PABITS;
15909 env->PAMask = (target_ulong)((1ULL << env->cpu_model->PABITS) - 1);
15910 env->CP0_SRSConf0_rw_bitmask = env->cpu_model->CP0_SRSConf0_rw_bitmask;
15911 env->CP0_SRSConf0 = env->cpu_model->CP0_SRSConf0;
15912 env->CP0_SRSConf1_rw_bitmask = env->cpu_model->CP0_SRSConf1_rw_bitmask;
15913 env->CP0_SRSConf1 = env->cpu_model->CP0_SRSConf1;
15914 env->CP0_SRSConf2_rw_bitmask = env->cpu_model->CP0_SRSConf2_rw_bitmask;
15915 env->CP0_SRSConf2 = env->cpu_model->CP0_SRSConf2;
15916 env->CP0_SRSConf3_rw_bitmask = env->cpu_model->CP0_SRSConf3_rw_bitmask;
15917 env->CP0_SRSConf3 = env->cpu_model->CP0_SRSConf3;
15918 env->CP0_SRSConf4_rw_bitmask = env->cpu_model->CP0_SRSConf4_rw_bitmask;
15919 env->CP0_SRSConf4 = env->cpu_model->CP0_SRSConf4;
15920 env->active_fpu.fcr0 = env->cpu_model->CP1_fcr0;
15921 env->insn_flags = env->cpu_model->insn_flags;
15923 #if defined(CONFIG_USER_ONLY)
15924 env->CP0_Status = (MIPS_HFLAG_UM << CP0St_KSU);
15925 /* Enable access to the CPUNum, SYNCI_Step, CC, and CCRes RDHWR
15926 hardware registers. */
15927 env->CP0_HWREna |= 0x0000000F;
15928 if (env->CP0_Config1 & (1 << CP0C1_FP)) {
15929 env->CP0_Status |= (1 << CP0St_CU1);
15931 if (env->cpu_model->insn_flags & ASE_DSPR2) {
15932 env->hflags |= MIPS_HFLAG_DSP | MIPS_HFLAG_DSPR2;
15933 } else if (env->cpu_model->insn_flags & ASE_DSP) {
15934 env->hflags |= MIPS_HFLAG_DSP;
15937 if (env->hflags & MIPS_HFLAG_BMASK) {
15938 /* If the exception was raised from a delay slot,
15939 come back to the jump. */
15940 env->CP0_ErrorEPC = env->active_tc.PC - 4;
15942 env->CP0_ErrorEPC = env->active_tc.PC;
15944 env->active_tc.PC = (int32_t)0xBFC00000;
15945 env->CP0_Random = env->tlb->nb_tlb - 1;
15946 env->tlb->tlb_in_use = env->tlb->nb_tlb;
15947 env->CP0_Wired = 0;
15948 env->CP0_EBase = 0x80000000 | (cs->cpu_index & 0x3FF);
15949 env->CP0_Status = (1 << CP0St_BEV) | (1 << CP0St_ERL);
15950 /* vectored interrupts not implemented, timer on int 7,
15951 no performance counters. */
15952 env->CP0_IntCtl = 0xe0000000;
15956 for (i = 0; i < 7; i++) {
15957 env->CP0_WatchLo[i] = 0;
15958 env->CP0_WatchHi[i] = 0x80000000;
15960 env->CP0_WatchLo[7] = 0;
15961 env->CP0_WatchHi[7] = 0;
15963 /* Count register increments in debug mode, EJTAG version 1 */
15964 env->CP0_Debug = (1 << CP0DB_CNT) | (0x1 << CP0DB_VER);
15966 if (env->CP0_Config3 & (1 << CP0C3_MT)) {
15969 /* Only TC0 on VPE 0 starts as active. */
15970 for (i = 0; i < ARRAY_SIZE(env->tcs); i++) {
15971 env->tcs[i].CP0_TCBind = cs->cpu_index << CP0TCBd_CurVPE;
15972 env->tcs[i].CP0_TCHalt = 1;
15974 env->active_tc.CP0_TCHalt = 1;
15977 if (cs->cpu_index == 0) {
15978 /* VPE0 starts up enabled. */
15979 env->mvp->CP0_MVPControl |= (1 << CP0MVPCo_EVP);
15980 env->CP0_VPEConf0 |= (1 << CP0VPEC0_MVP) | (1 << CP0VPEC0_VPA);
15982 /* TC0 starts up unhalted. */
15984 env->active_tc.CP0_TCHalt = 0;
15985 env->tcs[0].CP0_TCHalt = 0;
15986 /* With thread 0 active. */
15987 env->active_tc.CP0_TCStatus = (1 << CP0TCSt_A);
15988 env->tcs[0].CP0_TCStatus = (1 << CP0TCSt_A);
15992 compute_hflags(env);
15993 env->exception_index = EXCP_NONE;
15996 void restore_state_to_opc(CPUMIPSState *env, TranslationBlock *tb, int pc_pos)
15998 env->active_tc.PC = tcg_ctx.gen_opc_pc[pc_pos];
15999 env->hflags &= ~MIPS_HFLAG_BMASK;
16000 env->hflags |= gen_opc_hflags[pc_pos];
16001 switch (env->hflags & MIPS_HFLAG_BMASK_BASE) {
16002 case MIPS_HFLAG_BR:
16004 case MIPS_HFLAG_BC:
16005 case MIPS_HFLAG_BL:
16007 env->btarget = gen_opc_btarget[pc_pos];