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/>.
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 #if defined(TARGET_MIPS64)
322 OPC_ADDU_OB_DSP = 0x14 | OPC_SPECIAL3,
324 OPC_ABSQ_S_PH_DSP = 0x12 | OPC_SPECIAL3,
325 #if defined(TARGET_MIPS64)
326 OPC_ABSQ_S_QH_DSP = 0x16 | OPC_SPECIAL3,
328 /* OPC_ADDUH_QB_DSP is same as OPC_MULT_G_2E. */
329 /* OPC_ADDUH_QB_DSP = 0x18 | OPC_SPECIAL3, */
330 OPC_CMPU_EQ_QB_DSP = 0x11 | OPC_SPECIAL3,
331 #if defined(TARGET_MIPS64)
332 OPC_CMPU_EQ_OB_DSP = 0x15 | OPC_SPECIAL3,
334 /* MIPS DSP GPR-Based Shift Sub-class */
335 OPC_SHLL_QB_DSP = 0x13 | OPC_SPECIAL3,
336 #if defined(TARGET_MIPS64)
337 OPC_SHLL_OB_DSP = 0x17 | OPC_SPECIAL3,
339 /* MIPS DSP Multiply Sub-class insns */
340 /* OPC_MUL_PH_DSP is same as OPC_ADDUH_QB_DSP. */
341 /* OPC_MUL_PH_DSP = 0x18 | OPC_SPECIAL3, */
342 OPC_DPA_W_PH_DSP = 0x30 | OPC_SPECIAL3,
343 #if defined(TARGET_MIPS64)
344 OPC_DPAQ_W_QH_DSP = 0x34 | OPC_SPECIAL3,
346 /* DSP Bit/Manipulation Sub-class */
347 OPC_INSV_DSP = 0x0C | OPC_SPECIAL3,
348 #if defined(TARGET_MIPS64)
349 OPC_DINSV_DSP = 0x0D | OPC_SPECIAL3,
351 /* MIPS DSP Compare-Pick Sub-class */
352 OPC_APPEND_DSP = 0x31 | OPC_SPECIAL3,
353 #if defined(TARGET_MIPS64)
354 OPC_DAPPEND_DSP = 0x35 | OPC_SPECIAL3,
356 /* MIPS DSP Accumulator and DSPControl Access Sub-class */
357 OPC_EXTR_W_DSP = 0x38 | OPC_SPECIAL3,
358 #if defined(TARGET_MIPS64)
359 OPC_DEXTR_W_DSP = 0x3C | OPC_SPECIAL3,
364 #define MASK_BSHFL(op) MASK_SPECIAL3(op) | (op & (0x1F << 6))
367 OPC_WSBH = (0x02 << 6) | OPC_BSHFL,
368 OPC_SEB = (0x10 << 6) | OPC_BSHFL,
369 OPC_SEH = (0x18 << 6) | OPC_BSHFL,
373 #define MASK_DBSHFL(op) MASK_SPECIAL3(op) | (op & (0x1F << 6))
376 OPC_DSBH = (0x02 << 6) | OPC_DBSHFL,
377 OPC_DSHD = (0x05 << 6) | OPC_DBSHFL,
380 /* MIPS DSP REGIMM opcodes */
382 OPC_BPOSGE32 = (0x1C << 16) | OPC_REGIMM,
383 #if defined(TARGET_MIPS64)
384 OPC_BPOSGE64 = (0x1D << 16) | OPC_REGIMM,
388 #define MASK_LX(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
391 OPC_LBUX = (0x06 << 6) | OPC_LX_DSP,
392 OPC_LHX = (0x04 << 6) | OPC_LX_DSP,
393 OPC_LWX = (0x00 << 6) | OPC_LX_DSP,
394 #if defined(TARGET_MIPS64)
395 OPC_LDX = (0x08 << 6) | OPC_LX_DSP,
399 #define MASK_ADDU_QB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
401 /* MIPS DSP Arithmetic Sub-class */
402 OPC_ADDQ_PH = (0x0A << 6) | OPC_ADDU_QB_DSP,
403 OPC_ADDQ_S_PH = (0x0E << 6) | OPC_ADDU_QB_DSP,
404 OPC_ADDQ_S_W = (0x16 << 6) | OPC_ADDU_QB_DSP,
405 OPC_ADDU_QB = (0x00 << 6) | OPC_ADDU_QB_DSP,
406 OPC_ADDU_S_QB = (0x04 << 6) | OPC_ADDU_QB_DSP,
407 OPC_ADDU_PH = (0x08 << 6) | OPC_ADDU_QB_DSP,
408 OPC_ADDU_S_PH = (0x0C << 6) | OPC_ADDU_QB_DSP,
409 OPC_SUBQ_PH = (0x0B << 6) | OPC_ADDU_QB_DSP,
410 OPC_SUBQ_S_PH = (0x0F << 6) | OPC_ADDU_QB_DSP,
411 OPC_SUBQ_S_W = (0x17 << 6) | OPC_ADDU_QB_DSP,
412 OPC_SUBU_QB = (0x01 << 6) | OPC_ADDU_QB_DSP,
413 OPC_SUBU_S_QB = (0x05 << 6) | OPC_ADDU_QB_DSP,
414 OPC_SUBU_PH = (0x09 << 6) | OPC_ADDU_QB_DSP,
415 OPC_SUBU_S_PH = (0x0D << 6) | OPC_ADDU_QB_DSP,
416 OPC_ADDSC = (0x10 << 6) | OPC_ADDU_QB_DSP,
417 OPC_ADDWC = (0x11 << 6) | OPC_ADDU_QB_DSP,
418 OPC_MODSUB = (0x12 << 6) | OPC_ADDU_QB_DSP,
419 OPC_RADDU_W_QB = (0x14 << 6) | OPC_ADDU_QB_DSP,
420 /* MIPS DSP Multiply Sub-class insns */
421 OPC_MULEU_S_PH_QBL = (0x06 << 6) | OPC_ADDU_QB_DSP,
422 OPC_MULEU_S_PH_QBR = (0x07 << 6) | OPC_ADDU_QB_DSP,
423 OPC_MULQ_RS_PH = (0x1F << 6) | OPC_ADDU_QB_DSP,
424 OPC_MULEQ_S_W_PHL = (0x1C << 6) | OPC_ADDU_QB_DSP,
425 OPC_MULEQ_S_W_PHR = (0x1D << 6) | OPC_ADDU_QB_DSP,
426 OPC_MULQ_S_PH = (0x1E << 6) | OPC_ADDU_QB_DSP,
429 #define OPC_ADDUH_QB_DSP OPC_MULT_G_2E
430 #define MASK_ADDUH_QB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
432 /* MIPS DSP Arithmetic Sub-class */
433 OPC_ADDUH_QB = (0x00 << 6) | OPC_ADDUH_QB_DSP,
434 OPC_ADDUH_R_QB = (0x02 << 6) | OPC_ADDUH_QB_DSP,
435 OPC_ADDQH_PH = (0x08 << 6) | OPC_ADDUH_QB_DSP,
436 OPC_ADDQH_R_PH = (0x0A << 6) | OPC_ADDUH_QB_DSP,
437 OPC_ADDQH_W = (0x10 << 6) | OPC_ADDUH_QB_DSP,
438 OPC_ADDQH_R_W = (0x12 << 6) | OPC_ADDUH_QB_DSP,
439 OPC_SUBUH_QB = (0x01 << 6) | OPC_ADDUH_QB_DSP,
440 OPC_SUBUH_R_QB = (0x03 << 6) | OPC_ADDUH_QB_DSP,
441 OPC_SUBQH_PH = (0x09 << 6) | OPC_ADDUH_QB_DSP,
442 OPC_SUBQH_R_PH = (0x0B << 6) | OPC_ADDUH_QB_DSP,
443 OPC_SUBQH_W = (0x11 << 6) | OPC_ADDUH_QB_DSP,
444 OPC_SUBQH_R_W = (0x13 << 6) | OPC_ADDUH_QB_DSP,
445 /* MIPS DSP Multiply Sub-class insns */
446 OPC_MUL_PH = (0x0C << 6) | OPC_ADDUH_QB_DSP,
447 OPC_MUL_S_PH = (0x0E << 6) | OPC_ADDUH_QB_DSP,
448 OPC_MULQ_S_W = (0x16 << 6) | OPC_ADDUH_QB_DSP,
449 OPC_MULQ_RS_W = (0x17 << 6) | OPC_ADDUH_QB_DSP,
452 #define MASK_ABSQ_S_PH(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
454 /* MIPS DSP Arithmetic Sub-class */
455 OPC_ABSQ_S_QB = (0x01 << 6) | OPC_ABSQ_S_PH_DSP,
456 OPC_ABSQ_S_PH = (0x09 << 6) | OPC_ABSQ_S_PH_DSP,
457 OPC_ABSQ_S_W = (0x11 << 6) | OPC_ABSQ_S_PH_DSP,
458 OPC_PRECEQ_W_PHL = (0x0C << 6) | OPC_ABSQ_S_PH_DSP,
459 OPC_PRECEQ_W_PHR = (0x0D << 6) | OPC_ABSQ_S_PH_DSP,
460 OPC_PRECEQU_PH_QBL = (0x04 << 6) | OPC_ABSQ_S_PH_DSP,
461 OPC_PRECEQU_PH_QBR = (0x05 << 6) | OPC_ABSQ_S_PH_DSP,
462 OPC_PRECEQU_PH_QBLA = (0x06 << 6) | OPC_ABSQ_S_PH_DSP,
463 OPC_PRECEQU_PH_QBRA = (0x07 << 6) | OPC_ABSQ_S_PH_DSP,
464 OPC_PRECEU_PH_QBL = (0x1C << 6) | OPC_ABSQ_S_PH_DSP,
465 OPC_PRECEU_PH_QBR = (0x1D << 6) | OPC_ABSQ_S_PH_DSP,
466 OPC_PRECEU_PH_QBLA = (0x1E << 6) | OPC_ABSQ_S_PH_DSP,
467 OPC_PRECEU_PH_QBRA = (0x1F << 6) | OPC_ABSQ_S_PH_DSP,
468 /* DSP Bit/Manipulation Sub-class */
469 OPC_BITREV = (0x1B << 6) | OPC_ABSQ_S_PH_DSP,
470 OPC_REPL_QB = (0x02 << 6) | OPC_ABSQ_S_PH_DSP,
471 OPC_REPLV_QB = (0x03 << 6) | OPC_ABSQ_S_PH_DSP,
472 OPC_REPL_PH = (0x0A << 6) | OPC_ABSQ_S_PH_DSP,
473 OPC_REPLV_PH = (0x0B << 6) | OPC_ABSQ_S_PH_DSP,
476 #define MASK_CMPU_EQ_QB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
478 /* MIPS DSP Arithmetic Sub-class */
479 OPC_PRECR_QB_PH = (0x0D << 6) | OPC_CMPU_EQ_QB_DSP,
480 OPC_PRECRQ_QB_PH = (0x0C << 6) | OPC_CMPU_EQ_QB_DSP,
481 OPC_PRECR_SRA_PH_W = (0x1E << 6) | OPC_CMPU_EQ_QB_DSP,
482 OPC_PRECR_SRA_R_PH_W = (0x1F << 6) | OPC_CMPU_EQ_QB_DSP,
483 OPC_PRECRQ_PH_W = (0x14 << 6) | OPC_CMPU_EQ_QB_DSP,
484 OPC_PRECRQ_RS_PH_W = (0x15 << 6) | OPC_CMPU_EQ_QB_DSP,
485 OPC_PRECRQU_S_QB_PH = (0x0F << 6) | OPC_CMPU_EQ_QB_DSP,
486 /* DSP Compare-Pick Sub-class */
487 OPC_CMPU_EQ_QB = (0x00 << 6) | OPC_CMPU_EQ_QB_DSP,
488 OPC_CMPU_LT_QB = (0x01 << 6) | OPC_CMPU_EQ_QB_DSP,
489 OPC_CMPU_LE_QB = (0x02 << 6) | OPC_CMPU_EQ_QB_DSP,
490 OPC_CMPGU_EQ_QB = (0x04 << 6) | OPC_CMPU_EQ_QB_DSP,
491 OPC_CMPGU_LT_QB = (0x05 << 6) | OPC_CMPU_EQ_QB_DSP,
492 OPC_CMPGU_LE_QB = (0x06 << 6) | OPC_CMPU_EQ_QB_DSP,
493 OPC_CMPGDU_EQ_QB = (0x18 << 6) | OPC_CMPU_EQ_QB_DSP,
494 OPC_CMPGDU_LT_QB = (0x19 << 6) | OPC_CMPU_EQ_QB_DSP,
495 OPC_CMPGDU_LE_QB = (0x1A << 6) | OPC_CMPU_EQ_QB_DSP,
496 OPC_CMP_EQ_PH = (0x08 << 6) | OPC_CMPU_EQ_QB_DSP,
497 OPC_CMP_LT_PH = (0x09 << 6) | OPC_CMPU_EQ_QB_DSP,
498 OPC_CMP_LE_PH = (0x0A << 6) | OPC_CMPU_EQ_QB_DSP,
499 OPC_PICK_QB = (0x03 << 6) | OPC_CMPU_EQ_QB_DSP,
500 OPC_PICK_PH = (0x0B << 6) | OPC_CMPU_EQ_QB_DSP,
501 OPC_PACKRL_PH = (0x0E << 6) | OPC_CMPU_EQ_QB_DSP,
504 #define MASK_SHLL_QB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
506 /* MIPS DSP GPR-Based Shift Sub-class */
507 OPC_SHLL_QB = (0x00 << 6) | OPC_SHLL_QB_DSP,
508 OPC_SHLLV_QB = (0x02 << 6) | OPC_SHLL_QB_DSP,
509 OPC_SHLL_PH = (0x08 << 6) | OPC_SHLL_QB_DSP,
510 OPC_SHLLV_PH = (0x0A << 6) | OPC_SHLL_QB_DSP,
511 OPC_SHLL_S_PH = (0x0C << 6) | OPC_SHLL_QB_DSP,
512 OPC_SHLLV_S_PH = (0x0E << 6) | OPC_SHLL_QB_DSP,
513 OPC_SHLL_S_W = (0x14 << 6) | OPC_SHLL_QB_DSP,
514 OPC_SHLLV_S_W = (0x16 << 6) | OPC_SHLL_QB_DSP,
515 OPC_SHRL_QB = (0x01 << 6) | OPC_SHLL_QB_DSP,
516 OPC_SHRLV_QB = (0x03 << 6) | OPC_SHLL_QB_DSP,
517 OPC_SHRL_PH = (0x19 << 6) | OPC_SHLL_QB_DSP,
518 OPC_SHRLV_PH = (0x1B << 6) | OPC_SHLL_QB_DSP,
519 OPC_SHRA_QB = (0x04 << 6) | OPC_SHLL_QB_DSP,
520 OPC_SHRA_R_QB = (0x05 << 6) | OPC_SHLL_QB_DSP,
521 OPC_SHRAV_QB = (0x06 << 6) | OPC_SHLL_QB_DSP,
522 OPC_SHRAV_R_QB = (0x07 << 6) | OPC_SHLL_QB_DSP,
523 OPC_SHRA_PH = (0x09 << 6) | OPC_SHLL_QB_DSP,
524 OPC_SHRAV_PH = (0x0B << 6) | OPC_SHLL_QB_DSP,
525 OPC_SHRA_R_PH = (0x0D << 6) | OPC_SHLL_QB_DSP,
526 OPC_SHRAV_R_PH = (0x0F << 6) | OPC_SHLL_QB_DSP,
527 OPC_SHRA_R_W = (0x15 << 6) | OPC_SHLL_QB_DSP,
528 OPC_SHRAV_R_W = (0x17 << 6) | OPC_SHLL_QB_DSP,
531 #define MASK_DPA_W_PH(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
533 /* MIPS DSP Multiply Sub-class insns */
534 OPC_DPAU_H_QBL = (0x03 << 6) | OPC_DPA_W_PH_DSP,
535 OPC_DPAU_H_QBR = (0x07 << 6) | OPC_DPA_W_PH_DSP,
536 OPC_DPSU_H_QBL = (0x0B << 6) | OPC_DPA_W_PH_DSP,
537 OPC_DPSU_H_QBR = (0x0F << 6) | OPC_DPA_W_PH_DSP,
538 OPC_DPA_W_PH = (0x00 << 6) | OPC_DPA_W_PH_DSP,
539 OPC_DPAX_W_PH = (0x08 << 6) | OPC_DPA_W_PH_DSP,
540 OPC_DPAQ_S_W_PH = (0x04 << 6) | OPC_DPA_W_PH_DSP,
541 OPC_DPAQX_S_W_PH = (0x18 << 6) | OPC_DPA_W_PH_DSP,
542 OPC_DPAQX_SA_W_PH = (0x1A << 6) | OPC_DPA_W_PH_DSP,
543 OPC_DPS_W_PH = (0x01 << 6) | OPC_DPA_W_PH_DSP,
544 OPC_DPSX_W_PH = (0x09 << 6) | OPC_DPA_W_PH_DSP,
545 OPC_DPSQ_S_W_PH = (0x05 << 6) | OPC_DPA_W_PH_DSP,
546 OPC_DPSQX_S_W_PH = (0x19 << 6) | OPC_DPA_W_PH_DSP,
547 OPC_DPSQX_SA_W_PH = (0x1B << 6) | OPC_DPA_W_PH_DSP,
548 OPC_MULSAQ_S_W_PH = (0x06 << 6) | OPC_DPA_W_PH_DSP,
549 OPC_DPAQ_SA_L_W = (0x0C << 6) | OPC_DPA_W_PH_DSP,
550 OPC_DPSQ_SA_L_W = (0x0D << 6) | OPC_DPA_W_PH_DSP,
551 OPC_MAQ_S_W_PHL = (0x14 << 6) | OPC_DPA_W_PH_DSP,
552 OPC_MAQ_S_W_PHR = (0x16 << 6) | OPC_DPA_W_PH_DSP,
553 OPC_MAQ_SA_W_PHL = (0x10 << 6) | OPC_DPA_W_PH_DSP,
554 OPC_MAQ_SA_W_PHR = (0x12 << 6) | OPC_DPA_W_PH_DSP,
555 OPC_MULSA_W_PH = (0x02 << 6) | OPC_DPA_W_PH_DSP,
558 #define MASK_INSV(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
560 /* DSP Bit/Manipulation Sub-class */
561 OPC_INSV = (0x00 << 6) | OPC_INSV_DSP,
564 #define MASK_APPEND(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
566 /* MIPS DSP Compare-Pick Sub-class */
567 OPC_APPEND = (0x00 << 6) | OPC_APPEND_DSP,
568 OPC_PREPEND = (0x01 << 6) | OPC_APPEND_DSP,
569 OPC_BALIGN = (0x10 << 6) | OPC_APPEND_DSP,
572 #define MASK_EXTR_W(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
574 /* MIPS DSP Accumulator and DSPControl Access Sub-class */
575 OPC_EXTR_W = (0x00 << 6) | OPC_EXTR_W_DSP,
576 OPC_EXTR_R_W = (0x04 << 6) | OPC_EXTR_W_DSP,
577 OPC_EXTR_RS_W = (0x06 << 6) | OPC_EXTR_W_DSP,
578 OPC_EXTR_S_H = (0x0E << 6) | OPC_EXTR_W_DSP,
579 OPC_EXTRV_S_H = (0x0F << 6) | OPC_EXTR_W_DSP,
580 OPC_EXTRV_W = (0x01 << 6) | OPC_EXTR_W_DSP,
581 OPC_EXTRV_R_W = (0x05 << 6) | OPC_EXTR_W_DSP,
582 OPC_EXTRV_RS_W = (0x07 << 6) | OPC_EXTR_W_DSP,
583 OPC_EXTP = (0x02 << 6) | OPC_EXTR_W_DSP,
584 OPC_EXTPV = (0x03 << 6) | OPC_EXTR_W_DSP,
585 OPC_EXTPDP = (0x0A << 6) | OPC_EXTR_W_DSP,
586 OPC_EXTPDPV = (0x0B << 6) | OPC_EXTR_W_DSP,
587 OPC_SHILO = (0x1A << 6) | OPC_EXTR_W_DSP,
588 OPC_SHILOV = (0x1B << 6) | OPC_EXTR_W_DSP,
589 OPC_MTHLIP = (0x1F << 6) | OPC_EXTR_W_DSP,
590 OPC_WRDSP = (0x13 << 6) | OPC_EXTR_W_DSP,
591 OPC_RDDSP = (0x12 << 6) | OPC_EXTR_W_DSP,
596 #if defined(TARGET_MIPS64)
597 #define MASK_ABSQ_S_QH(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
599 /* MIPS DSP Arithmetic Sub-class */
600 OPC_PRECEQ_L_PWL = (0x14 << 6) | OPC_ABSQ_S_QH_DSP,
601 OPC_PRECEQ_L_PWR = (0x15 << 6) | OPC_ABSQ_S_QH_DSP,
602 OPC_PRECEQ_PW_QHL = (0x0C << 6) | OPC_ABSQ_S_QH_DSP,
603 OPC_PRECEQ_PW_QHR = (0x0D << 6) | OPC_ABSQ_S_QH_DSP,
604 OPC_PRECEQ_PW_QHLA = (0x0E << 6) | OPC_ABSQ_S_QH_DSP,
605 OPC_PRECEQ_PW_QHRA = (0x0F << 6) | OPC_ABSQ_S_QH_DSP,
606 OPC_PRECEQU_QH_OBL = (0x04 << 6) | OPC_ABSQ_S_QH_DSP,
607 OPC_PRECEQU_QH_OBR = (0x05 << 6) | OPC_ABSQ_S_QH_DSP,
608 OPC_PRECEQU_QH_OBLA = (0x06 << 6) | OPC_ABSQ_S_QH_DSP,
609 OPC_PRECEQU_QH_OBRA = (0x07 << 6) | OPC_ABSQ_S_QH_DSP,
610 OPC_PRECEU_QH_OBL = (0x1C << 6) | OPC_ABSQ_S_QH_DSP,
611 OPC_PRECEU_QH_OBR = (0x1D << 6) | OPC_ABSQ_S_QH_DSP,
612 OPC_PRECEU_QH_OBLA = (0x1E << 6) | OPC_ABSQ_S_QH_DSP,
613 OPC_PRECEU_QH_OBRA = (0x1F << 6) | OPC_ABSQ_S_QH_DSP,
614 OPC_ABSQ_S_OB = (0x01 << 6) | OPC_ABSQ_S_QH_DSP,
615 OPC_ABSQ_S_PW = (0x11 << 6) | OPC_ABSQ_S_QH_DSP,
616 OPC_ABSQ_S_QH = (0x09 << 6) | OPC_ABSQ_S_QH_DSP,
617 /* DSP Bit/Manipulation Sub-class */
618 OPC_REPL_OB = (0x02 << 6) | OPC_ABSQ_S_QH_DSP,
619 OPC_REPL_PW = (0x12 << 6) | OPC_ABSQ_S_QH_DSP,
620 OPC_REPL_QH = (0x0A << 6) | OPC_ABSQ_S_QH_DSP,
621 OPC_REPLV_OB = (0x03 << 6) | OPC_ABSQ_S_QH_DSP,
622 OPC_REPLV_PW = (0x13 << 6) | OPC_ABSQ_S_QH_DSP,
623 OPC_REPLV_QH = (0x0B << 6) | OPC_ABSQ_S_QH_DSP,
627 #if defined(TARGET_MIPS64)
628 #define MASK_ADDU_OB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
630 /* MIPS DSP Multiply Sub-class insns */
631 OPC_MULEQ_S_PW_QHL = (0x1C << 6) | OPC_ADDU_OB_DSP,
632 OPC_MULEQ_S_PW_QHR = (0x1D << 6) | OPC_ADDU_OB_DSP,
633 OPC_MULEU_S_QH_OBL = (0x06 << 6) | OPC_ADDU_OB_DSP,
634 OPC_MULEU_S_QH_OBR = (0x07 << 6) | OPC_ADDU_OB_DSP,
635 OPC_MULQ_RS_QH = (0x1F << 6) | OPC_ADDU_OB_DSP,
636 /* MIPS DSP Arithmetic Sub-class */
637 OPC_RADDU_L_OB = (0x14 << 6) | OPC_ADDU_OB_DSP,
638 OPC_SUBQ_PW = (0x13 << 6) | OPC_ADDU_OB_DSP,
639 OPC_SUBQ_S_PW = (0x17 << 6) | OPC_ADDU_OB_DSP,
640 OPC_SUBQ_QH = (0x0B << 6) | OPC_ADDU_OB_DSP,
641 OPC_SUBQ_S_QH = (0x0F << 6) | OPC_ADDU_OB_DSP,
642 OPC_SUBU_OB = (0x01 << 6) | OPC_ADDU_OB_DSP,
643 OPC_SUBU_S_OB = (0x05 << 6) | OPC_ADDU_OB_DSP,
644 OPC_SUBU_QH = (0x09 << 6) | OPC_ADDU_OB_DSP,
645 OPC_SUBU_S_QH = (0x0D << 6) | OPC_ADDU_OB_DSP,
646 OPC_SUBUH_OB = (0x19 << 6) | OPC_ADDU_OB_DSP,
647 OPC_SUBUH_R_OB = (0x1B << 6) | OPC_ADDU_OB_DSP,
648 OPC_ADDQ_PW = (0x12 << 6) | OPC_ADDU_OB_DSP,
649 OPC_ADDQ_S_PW = (0x16 << 6) | OPC_ADDU_OB_DSP,
650 OPC_ADDQ_QH = (0x0A << 6) | OPC_ADDU_OB_DSP,
651 OPC_ADDQ_S_QH = (0x0E << 6) | OPC_ADDU_OB_DSP,
652 OPC_ADDU_OB = (0x00 << 6) | OPC_ADDU_OB_DSP,
653 OPC_ADDU_S_OB = (0x04 << 6) | OPC_ADDU_OB_DSP,
654 OPC_ADDU_QH = (0x08 << 6) | OPC_ADDU_OB_DSP,
655 OPC_ADDU_S_QH = (0x0C << 6) | OPC_ADDU_OB_DSP,
656 OPC_ADDUH_OB = (0x18 << 6) | OPC_ADDU_OB_DSP,
657 OPC_ADDUH_R_OB = (0x1A << 6) | OPC_ADDU_OB_DSP,
661 #if defined(TARGET_MIPS64)
662 #define MASK_CMPU_EQ_OB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
664 /* DSP Compare-Pick Sub-class */
665 OPC_CMP_EQ_PW = (0x10 << 6) | OPC_CMPU_EQ_OB_DSP,
666 OPC_CMP_LT_PW = (0x11 << 6) | OPC_CMPU_EQ_OB_DSP,
667 OPC_CMP_LE_PW = (0x12 << 6) | OPC_CMPU_EQ_OB_DSP,
668 OPC_CMP_EQ_QH = (0x08 << 6) | OPC_CMPU_EQ_OB_DSP,
669 OPC_CMP_LT_QH = (0x09 << 6) | OPC_CMPU_EQ_OB_DSP,
670 OPC_CMP_LE_QH = (0x0A << 6) | OPC_CMPU_EQ_OB_DSP,
671 OPC_CMPGDU_EQ_OB = (0x18 << 6) | OPC_CMPU_EQ_OB_DSP,
672 OPC_CMPGDU_LT_OB = (0x19 << 6) | OPC_CMPU_EQ_OB_DSP,
673 OPC_CMPGDU_LE_OB = (0x1A << 6) | OPC_CMPU_EQ_OB_DSP,
674 OPC_CMPGU_EQ_OB = (0x04 << 6) | OPC_CMPU_EQ_OB_DSP,
675 OPC_CMPGU_LT_OB = (0x05 << 6) | OPC_CMPU_EQ_OB_DSP,
676 OPC_CMPGU_LE_OB = (0x06 << 6) | OPC_CMPU_EQ_OB_DSP,
677 OPC_CMPU_EQ_OB = (0x00 << 6) | OPC_CMPU_EQ_OB_DSP,
678 OPC_CMPU_LT_OB = (0x01 << 6) | OPC_CMPU_EQ_OB_DSP,
679 OPC_CMPU_LE_OB = (0x02 << 6) | OPC_CMPU_EQ_OB_DSP,
680 OPC_PACKRL_PW = (0x0E << 6) | OPC_CMPU_EQ_OB_DSP,
681 OPC_PICK_OB = (0x03 << 6) | OPC_CMPU_EQ_OB_DSP,
682 OPC_PICK_PW = (0x13 << 6) | OPC_CMPU_EQ_OB_DSP,
683 OPC_PICK_QH = (0x0B << 6) | OPC_CMPU_EQ_OB_DSP,
684 /* MIPS DSP Arithmetic Sub-class */
685 OPC_PRECR_OB_QH = (0x0D << 6) | OPC_CMPU_EQ_OB_DSP,
686 OPC_PRECR_SRA_QH_PW = (0x1E << 6) | OPC_CMPU_EQ_OB_DSP,
687 OPC_PRECR_SRA_R_QH_PW = (0x1F << 6) | OPC_CMPU_EQ_OB_DSP,
688 OPC_PRECRQ_OB_QH = (0x0C << 6) | OPC_CMPU_EQ_OB_DSP,
689 OPC_PRECRQ_PW_L = (0x1C << 6) | OPC_CMPU_EQ_OB_DSP,
690 OPC_PRECRQ_QH_PW = (0x14 << 6) | OPC_CMPU_EQ_OB_DSP,
691 OPC_PRECRQ_RS_QH_PW = (0x15 << 6) | OPC_CMPU_EQ_OB_DSP,
692 OPC_PRECRQU_S_OB_QH = (0x0F << 6) | OPC_CMPU_EQ_OB_DSP,
696 #if defined(TARGET_MIPS64)
697 #define MASK_DAPPEND(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
699 /* DSP Compare-Pick Sub-class */
700 OPC_DAPPEND = (0x00 << 6) | OPC_DAPPEND_DSP,
701 OPC_PREPENDD = (0x03 << 6) | OPC_DAPPEND_DSP,
702 OPC_PREPENDW = (0x01 << 6) | OPC_DAPPEND_DSP,
703 OPC_DBALIGN = (0x10 << 6) | OPC_DAPPEND_DSP,
707 #if defined(TARGET_MIPS64)
708 #define MASK_DEXTR_W(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
710 /* MIPS DSP Accumulator and DSPControl Access Sub-class */
711 OPC_DMTHLIP = (0x1F << 6) | OPC_DEXTR_W_DSP,
712 OPC_DSHILO = (0x1A << 6) | OPC_DEXTR_W_DSP,
713 OPC_DEXTP = (0x02 << 6) | OPC_DEXTR_W_DSP,
714 OPC_DEXTPDP = (0x0A << 6) | OPC_DEXTR_W_DSP,
715 OPC_DEXTPDPV = (0x0B << 6) | OPC_DEXTR_W_DSP,
716 OPC_DEXTPV = (0x03 << 6) | OPC_DEXTR_W_DSP,
717 OPC_DEXTR_L = (0x10 << 6) | OPC_DEXTR_W_DSP,
718 OPC_DEXTR_R_L = (0x14 << 6) | OPC_DEXTR_W_DSP,
719 OPC_DEXTR_RS_L = (0x16 << 6) | OPC_DEXTR_W_DSP,
720 OPC_DEXTR_W = (0x00 << 6) | OPC_DEXTR_W_DSP,
721 OPC_DEXTR_R_W = (0x04 << 6) | OPC_DEXTR_W_DSP,
722 OPC_DEXTR_RS_W = (0x06 << 6) | OPC_DEXTR_W_DSP,
723 OPC_DEXTR_S_H = (0x0E << 6) | OPC_DEXTR_W_DSP,
724 OPC_DEXTRV_L = (0x11 << 6) | OPC_DEXTR_W_DSP,
725 OPC_DEXTRV_R_L = (0x15 << 6) | OPC_DEXTR_W_DSP,
726 OPC_DEXTRV_RS_L = (0x17 << 6) | OPC_DEXTR_W_DSP,
727 OPC_DEXTRV_S_H = (0x0F << 6) | OPC_DEXTR_W_DSP,
728 OPC_DEXTRV_W = (0x01 << 6) | OPC_DEXTR_W_DSP,
729 OPC_DEXTRV_R_W = (0x05 << 6) | OPC_DEXTR_W_DSP,
730 OPC_DEXTRV_RS_W = (0x07 << 6) | OPC_DEXTR_W_DSP,
731 OPC_DSHILOV = (0x1B << 6) | OPC_DEXTR_W_DSP,
734 #define MASK_DINSV(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
736 /* DSP Bit/Manipulation Sub-class */
737 OPC_DINSV = (0x00 << 6) | OPC_DINSV_DSP,
741 #if defined(TARGET_MIPS64)
742 #define MASK_DPAQ_W_QH(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
744 /* MIPS DSP Multiply Sub-class insns */
745 OPC_DMADD = (0x19 << 6) | OPC_DPAQ_W_QH_DSP,
746 OPC_DMADDU = (0x1D << 6) | OPC_DPAQ_W_QH_DSP,
747 OPC_DMSUB = (0x1B << 6) | OPC_DPAQ_W_QH_DSP,
748 OPC_DMSUBU = (0x1F << 6) | OPC_DPAQ_W_QH_DSP,
749 OPC_DPA_W_QH = (0x00 << 6) | OPC_DPAQ_W_QH_DSP,
750 OPC_DPAQ_S_W_QH = (0x04 << 6) | OPC_DPAQ_W_QH_DSP,
751 OPC_DPAQ_SA_L_PW = (0x0C << 6) | OPC_DPAQ_W_QH_DSP,
752 OPC_DPAU_H_OBL = (0x03 << 6) | OPC_DPAQ_W_QH_DSP,
753 OPC_DPAU_H_OBR = (0x07 << 6) | OPC_DPAQ_W_QH_DSP,
754 OPC_DPS_W_QH = (0x01 << 6) | OPC_DPAQ_W_QH_DSP,
755 OPC_DPSQ_S_W_QH = (0x05 << 6) | OPC_DPAQ_W_QH_DSP,
756 OPC_DPSQ_SA_L_PW = (0x0D << 6) | OPC_DPAQ_W_QH_DSP,
757 OPC_DPSU_H_OBL = (0x0B << 6) | OPC_DPAQ_W_QH_DSP,
758 OPC_DPSU_H_OBR = (0x0F << 6) | OPC_DPAQ_W_QH_DSP,
759 OPC_MAQ_S_L_PWL = (0x1C << 6) | OPC_DPAQ_W_QH_DSP,
760 OPC_MAQ_S_L_PWR = (0x1E << 6) | OPC_DPAQ_W_QH_DSP,
761 OPC_MAQ_S_W_QHLL = (0x14 << 6) | OPC_DPAQ_W_QH_DSP,
762 OPC_MAQ_SA_W_QHLL = (0x10 << 6) | OPC_DPAQ_W_QH_DSP,
763 OPC_MAQ_S_W_QHLR = (0x15 << 6) | OPC_DPAQ_W_QH_DSP,
764 OPC_MAQ_SA_W_QHLR = (0x11 << 6) | OPC_DPAQ_W_QH_DSP,
765 OPC_MAQ_S_W_QHRL = (0x16 << 6) | OPC_DPAQ_W_QH_DSP,
766 OPC_MAQ_SA_W_QHRL = (0x12 << 6) | OPC_DPAQ_W_QH_DSP,
767 OPC_MAQ_S_W_QHRR = (0x17 << 6) | OPC_DPAQ_W_QH_DSP,
768 OPC_MAQ_SA_W_QHRR = (0x13 << 6) | OPC_DPAQ_W_QH_DSP,
769 OPC_MULSAQ_S_L_PW = (0x0E << 6) | OPC_DPAQ_W_QH_DSP,
770 OPC_MULSAQ_S_W_QH = (0x06 << 6) | OPC_DPAQ_W_QH_DSP,
774 #if defined(TARGET_MIPS64)
775 #define MASK_SHLL_OB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
777 /* MIPS DSP GPR-Based Shift Sub-class */
778 OPC_SHLL_PW = (0x10 << 6) | OPC_SHLL_OB_DSP,
779 OPC_SHLL_S_PW = (0x14 << 6) | OPC_SHLL_OB_DSP,
780 OPC_SHLLV_OB = (0x02 << 6) | OPC_SHLL_OB_DSP,
781 OPC_SHLLV_PW = (0x12 << 6) | OPC_SHLL_OB_DSP,
782 OPC_SHLLV_S_PW = (0x16 << 6) | OPC_SHLL_OB_DSP,
783 OPC_SHLLV_QH = (0x0A << 6) | OPC_SHLL_OB_DSP,
784 OPC_SHLLV_S_QH = (0x0E << 6) | OPC_SHLL_OB_DSP,
785 OPC_SHRA_PW = (0x11 << 6) | OPC_SHLL_OB_DSP,
786 OPC_SHRA_R_PW = (0x15 << 6) | OPC_SHLL_OB_DSP,
787 OPC_SHRAV_OB = (0x06 << 6) | OPC_SHLL_OB_DSP,
788 OPC_SHRAV_R_OB = (0x07 << 6) | OPC_SHLL_OB_DSP,
789 OPC_SHRAV_PW = (0x13 << 6) | OPC_SHLL_OB_DSP,
790 OPC_SHRAV_R_PW = (0x17 << 6) | OPC_SHLL_OB_DSP,
791 OPC_SHRAV_QH = (0x0B << 6) | OPC_SHLL_OB_DSP,
792 OPC_SHRAV_R_QH = (0x0F << 6) | OPC_SHLL_OB_DSP,
793 OPC_SHRLV_OB = (0x03 << 6) | OPC_SHLL_OB_DSP,
794 OPC_SHRLV_QH = (0x1B << 6) | OPC_SHLL_OB_DSP,
795 OPC_SHLL_OB = (0x00 << 6) | OPC_SHLL_OB_DSP,
796 OPC_SHLL_QH = (0x08 << 6) | OPC_SHLL_OB_DSP,
797 OPC_SHLL_S_QH = (0x0C << 6) | OPC_SHLL_OB_DSP,
798 OPC_SHRA_OB = (0x04 << 6) | OPC_SHLL_OB_DSP,
799 OPC_SHRA_R_OB = (0x05 << 6) | OPC_SHLL_OB_DSP,
800 OPC_SHRA_QH = (0x09 << 6) | OPC_SHLL_OB_DSP,
801 OPC_SHRA_R_QH = (0x0D << 6) | OPC_SHLL_OB_DSP,
802 OPC_SHRL_OB = (0x01 << 6) | OPC_SHLL_OB_DSP,
803 OPC_SHRL_QH = (0x19 << 6) | OPC_SHLL_OB_DSP,
807 /* Coprocessor 0 (rs field) */
808 #define MASK_CP0(op) MASK_OP_MAJOR(op) | (op & (0x1F << 21))
811 OPC_MFC0 = (0x00 << 21) | OPC_CP0,
812 OPC_DMFC0 = (0x01 << 21) | OPC_CP0,
813 OPC_MTC0 = (0x04 << 21) | OPC_CP0,
814 OPC_DMTC0 = (0x05 << 21) | OPC_CP0,
815 OPC_MFTR = (0x08 << 21) | OPC_CP0,
816 OPC_RDPGPR = (0x0A << 21) | OPC_CP0,
817 OPC_MFMC0 = (0x0B << 21) | OPC_CP0,
818 OPC_MTTR = (0x0C << 21) | OPC_CP0,
819 OPC_WRPGPR = (0x0E << 21) | OPC_CP0,
820 OPC_C0 = (0x10 << 21) | OPC_CP0,
821 OPC_C0_FIRST = (0x10 << 21) | OPC_CP0,
822 OPC_C0_LAST = (0x1F << 21) | OPC_CP0,
826 #define MASK_MFMC0(op) MASK_CP0(op) | (op & 0xFFFF)
829 OPC_DMT = 0x01 | (0 << 5) | (0x0F << 6) | (0x01 << 11) | OPC_MFMC0,
830 OPC_EMT = 0x01 | (1 << 5) | (0x0F << 6) | (0x01 << 11) | OPC_MFMC0,
831 OPC_DVPE = 0x01 | (0 << 5) | OPC_MFMC0,
832 OPC_EVPE = 0x01 | (1 << 5) | OPC_MFMC0,
833 OPC_DI = (0 << 5) | (0x0C << 11) | OPC_MFMC0,
834 OPC_EI = (1 << 5) | (0x0C << 11) | OPC_MFMC0,
837 /* Coprocessor 0 (with rs == C0) */
838 #define MASK_C0(op) MASK_CP0(op) | (op & 0x3F)
841 OPC_TLBR = 0x01 | OPC_C0,
842 OPC_TLBWI = 0x02 | OPC_C0,
843 OPC_TLBWR = 0x06 | OPC_C0,
844 OPC_TLBP = 0x08 | OPC_C0,
845 OPC_RFE = 0x10 | OPC_C0,
846 OPC_ERET = 0x18 | OPC_C0,
847 OPC_DERET = 0x1F | OPC_C0,
848 OPC_WAIT = 0x20 | OPC_C0,
851 /* Coprocessor 1 (rs field) */
852 #define MASK_CP1(op) MASK_OP_MAJOR(op) | (op & (0x1F << 21))
854 /* Values for the fmt field in FP instructions */
856 /* 0 - 15 are reserved */
857 FMT_S = 16, /* single fp */
858 FMT_D = 17, /* double fp */
859 FMT_E = 18, /* extended fp */
860 FMT_Q = 19, /* quad fp */
861 FMT_W = 20, /* 32-bit fixed */
862 FMT_L = 21, /* 64-bit fixed */
863 FMT_PS = 22, /* paired single fp */
864 /* 23 - 31 are reserved */
868 OPC_MFC1 = (0x00 << 21) | OPC_CP1,
869 OPC_DMFC1 = (0x01 << 21) | OPC_CP1,
870 OPC_CFC1 = (0x02 << 21) | OPC_CP1,
871 OPC_MFHC1 = (0x03 << 21) | OPC_CP1,
872 OPC_MTC1 = (0x04 << 21) | OPC_CP1,
873 OPC_DMTC1 = (0x05 << 21) | OPC_CP1,
874 OPC_CTC1 = (0x06 << 21) | OPC_CP1,
875 OPC_MTHC1 = (0x07 << 21) | OPC_CP1,
876 OPC_BC1 = (0x08 << 21) | OPC_CP1, /* bc */
877 OPC_BC1ANY2 = (0x09 << 21) | OPC_CP1,
878 OPC_BC1ANY4 = (0x0A << 21) | OPC_CP1,
879 OPC_S_FMT = (FMT_S << 21) | OPC_CP1,
880 OPC_D_FMT = (FMT_D << 21) | OPC_CP1,
881 OPC_E_FMT = (FMT_E << 21) | OPC_CP1,
882 OPC_Q_FMT = (FMT_Q << 21) | OPC_CP1,
883 OPC_W_FMT = (FMT_W << 21) | OPC_CP1,
884 OPC_L_FMT = (FMT_L << 21) | OPC_CP1,
885 OPC_PS_FMT = (FMT_PS << 21) | OPC_CP1,
888 #define MASK_CP1_FUNC(op) MASK_CP1(op) | (op & 0x3F)
889 #define MASK_BC1(op) MASK_CP1(op) | (op & (0x3 << 16))
892 OPC_BC1F = (0x00 << 16) | OPC_BC1,
893 OPC_BC1T = (0x01 << 16) | OPC_BC1,
894 OPC_BC1FL = (0x02 << 16) | OPC_BC1,
895 OPC_BC1TL = (0x03 << 16) | OPC_BC1,
899 OPC_BC1FANY2 = (0x00 << 16) | OPC_BC1ANY2,
900 OPC_BC1TANY2 = (0x01 << 16) | OPC_BC1ANY2,
904 OPC_BC1FANY4 = (0x00 << 16) | OPC_BC1ANY4,
905 OPC_BC1TANY4 = (0x01 << 16) | OPC_BC1ANY4,
908 #define MASK_CP2(op) MASK_OP_MAJOR(op) | (op & (0x1F << 21))
911 OPC_MFC2 = (0x00 << 21) | OPC_CP2,
912 OPC_DMFC2 = (0x01 << 21) | OPC_CP2,
913 OPC_CFC2 = (0x02 << 21) | OPC_CP2,
914 OPC_MFHC2 = (0x03 << 21) | OPC_CP2,
915 OPC_MTC2 = (0x04 << 21) | OPC_CP2,
916 OPC_DMTC2 = (0x05 << 21) | OPC_CP2,
917 OPC_CTC2 = (0x06 << 21) | OPC_CP2,
918 OPC_MTHC2 = (0x07 << 21) | OPC_CP2,
919 OPC_BC2 = (0x08 << 21) | OPC_CP2,
922 #define MASK_LMI(op) (MASK_OP_MAJOR(op) | (op & (0x1F << 21)) | (op & 0x1F))
925 OPC_PADDSH = (24 << 21) | (0x00) | OPC_CP2,
926 OPC_PADDUSH = (25 << 21) | (0x00) | OPC_CP2,
927 OPC_PADDH = (26 << 21) | (0x00) | OPC_CP2,
928 OPC_PADDW = (27 << 21) | (0x00) | OPC_CP2,
929 OPC_PADDSB = (28 << 21) | (0x00) | OPC_CP2,
930 OPC_PADDUSB = (29 << 21) | (0x00) | OPC_CP2,
931 OPC_PADDB = (30 << 21) | (0x00) | OPC_CP2,
932 OPC_PADDD = (31 << 21) | (0x00) | OPC_CP2,
934 OPC_PSUBSH = (24 << 21) | (0x01) | OPC_CP2,
935 OPC_PSUBUSH = (25 << 21) | (0x01) | OPC_CP2,
936 OPC_PSUBH = (26 << 21) | (0x01) | OPC_CP2,
937 OPC_PSUBW = (27 << 21) | (0x01) | OPC_CP2,
938 OPC_PSUBSB = (28 << 21) | (0x01) | OPC_CP2,
939 OPC_PSUBUSB = (29 << 21) | (0x01) | OPC_CP2,
940 OPC_PSUBB = (30 << 21) | (0x01) | OPC_CP2,
941 OPC_PSUBD = (31 << 21) | (0x01) | OPC_CP2,
943 OPC_PSHUFH = (24 << 21) | (0x02) | OPC_CP2,
944 OPC_PACKSSWH = (25 << 21) | (0x02) | OPC_CP2,
945 OPC_PACKSSHB = (26 << 21) | (0x02) | OPC_CP2,
946 OPC_PACKUSHB = (27 << 21) | (0x02) | OPC_CP2,
947 OPC_XOR_CP2 = (28 << 21) | (0x02) | OPC_CP2,
948 OPC_NOR_CP2 = (29 << 21) | (0x02) | OPC_CP2,
949 OPC_AND_CP2 = (30 << 21) | (0x02) | OPC_CP2,
950 OPC_PANDN = (31 << 21) | (0x02) | OPC_CP2,
952 OPC_PUNPCKLHW = (24 << 21) | (0x03) | OPC_CP2,
953 OPC_PUNPCKHHW = (25 << 21) | (0x03) | OPC_CP2,
954 OPC_PUNPCKLBH = (26 << 21) | (0x03) | OPC_CP2,
955 OPC_PUNPCKHBH = (27 << 21) | (0x03) | OPC_CP2,
956 OPC_PINSRH_0 = (28 << 21) | (0x03) | OPC_CP2,
957 OPC_PINSRH_1 = (29 << 21) | (0x03) | OPC_CP2,
958 OPC_PINSRH_2 = (30 << 21) | (0x03) | OPC_CP2,
959 OPC_PINSRH_3 = (31 << 21) | (0x03) | OPC_CP2,
961 OPC_PAVGH = (24 << 21) | (0x08) | OPC_CP2,
962 OPC_PAVGB = (25 << 21) | (0x08) | OPC_CP2,
963 OPC_PMAXSH = (26 << 21) | (0x08) | OPC_CP2,
964 OPC_PMINSH = (27 << 21) | (0x08) | OPC_CP2,
965 OPC_PMAXUB = (28 << 21) | (0x08) | OPC_CP2,
966 OPC_PMINUB = (29 << 21) | (0x08) | OPC_CP2,
968 OPC_PCMPEQW = (24 << 21) | (0x09) | OPC_CP2,
969 OPC_PCMPGTW = (25 << 21) | (0x09) | OPC_CP2,
970 OPC_PCMPEQH = (26 << 21) | (0x09) | OPC_CP2,
971 OPC_PCMPGTH = (27 << 21) | (0x09) | OPC_CP2,
972 OPC_PCMPEQB = (28 << 21) | (0x09) | OPC_CP2,
973 OPC_PCMPGTB = (29 << 21) | (0x09) | OPC_CP2,
975 OPC_PSLLW = (24 << 21) | (0x0A) | OPC_CP2,
976 OPC_PSLLH = (25 << 21) | (0x0A) | OPC_CP2,
977 OPC_PMULLH = (26 << 21) | (0x0A) | OPC_CP2,
978 OPC_PMULHH = (27 << 21) | (0x0A) | OPC_CP2,
979 OPC_PMULUW = (28 << 21) | (0x0A) | OPC_CP2,
980 OPC_PMULHUH = (29 << 21) | (0x0A) | OPC_CP2,
982 OPC_PSRLW = (24 << 21) | (0x0B) | OPC_CP2,
983 OPC_PSRLH = (25 << 21) | (0x0B) | OPC_CP2,
984 OPC_PSRAW = (26 << 21) | (0x0B) | OPC_CP2,
985 OPC_PSRAH = (27 << 21) | (0x0B) | OPC_CP2,
986 OPC_PUNPCKLWD = (28 << 21) | (0x0B) | OPC_CP2,
987 OPC_PUNPCKHWD = (29 << 21) | (0x0B) | OPC_CP2,
989 OPC_ADDU_CP2 = (24 << 21) | (0x0C) | OPC_CP2,
990 OPC_OR_CP2 = (25 << 21) | (0x0C) | OPC_CP2,
991 OPC_ADD_CP2 = (26 << 21) | (0x0C) | OPC_CP2,
992 OPC_DADD_CP2 = (27 << 21) | (0x0C) | OPC_CP2,
993 OPC_SEQU_CP2 = (28 << 21) | (0x0C) | OPC_CP2,
994 OPC_SEQ_CP2 = (29 << 21) | (0x0C) | OPC_CP2,
996 OPC_SUBU_CP2 = (24 << 21) | (0x0D) | OPC_CP2,
997 OPC_PASUBUB = (25 << 21) | (0x0D) | OPC_CP2,
998 OPC_SUB_CP2 = (26 << 21) | (0x0D) | OPC_CP2,
999 OPC_DSUB_CP2 = (27 << 21) | (0x0D) | OPC_CP2,
1000 OPC_SLTU_CP2 = (28 << 21) | (0x0D) | OPC_CP2,
1001 OPC_SLT_CP2 = (29 << 21) | (0x0D) | OPC_CP2,
1003 OPC_SLL_CP2 = (24 << 21) | (0x0E) | OPC_CP2,
1004 OPC_DSLL_CP2 = (25 << 21) | (0x0E) | OPC_CP2,
1005 OPC_PEXTRH = (26 << 21) | (0x0E) | OPC_CP2,
1006 OPC_PMADDHW = (27 << 21) | (0x0E) | OPC_CP2,
1007 OPC_SLEU_CP2 = (28 << 21) | (0x0E) | OPC_CP2,
1008 OPC_SLE_CP2 = (29 << 21) | (0x0E) | OPC_CP2,
1010 OPC_SRL_CP2 = (24 << 21) | (0x0F) | OPC_CP2,
1011 OPC_DSRL_CP2 = (25 << 21) | (0x0F) | OPC_CP2,
1012 OPC_SRA_CP2 = (26 << 21) | (0x0F) | OPC_CP2,
1013 OPC_DSRA_CP2 = (27 << 21) | (0x0F) | OPC_CP2,
1014 OPC_BIADD = (28 << 21) | (0x0F) | OPC_CP2,
1015 OPC_PMOVMSKB = (29 << 21) | (0x0F) | OPC_CP2,
1019 #define MASK_CP3(op) MASK_OP_MAJOR(op) | (op & 0x3F)
1022 OPC_LWXC1 = 0x00 | OPC_CP3,
1023 OPC_LDXC1 = 0x01 | OPC_CP3,
1024 OPC_LUXC1 = 0x05 | OPC_CP3,
1025 OPC_SWXC1 = 0x08 | OPC_CP3,
1026 OPC_SDXC1 = 0x09 | OPC_CP3,
1027 OPC_SUXC1 = 0x0D | OPC_CP3,
1028 OPC_PREFX = 0x0F | OPC_CP3,
1029 OPC_ALNV_PS = 0x1E | OPC_CP3,
1030 OPC_MADD_S = 0x20 | OPC_CP3,
1031 OPC_MADD_D = 0x21 | OPC_CP3,
1032 OPC_MADD_PS = 0x26 | OPC_CP3,
1033 OPC_MSUB_S = 0x28 | OPC_CP3,
1034 OPC_MSUB_D = 0x29 | OPC_CP3,
1035 OPC_MSUB_PS = 0x2E | OPC_CP3,
1036 OPC_NMADD_S = 0x30 | OPC_CP3,
1037 OPC_NMADD_D = 0x31 | OPC_CP3,
1038 OPC_NMADD_PS= 0x36 | OPC_CP3,
1039 OPC_NMSUB_S = 0x38 | OPC_CP3,
1040 OPC_NMSUB_D = 0x39 | OPC_CP3,
1041 OPC_NMSUB_PS= 0x3E | OPC_CP3,
1044 /* global register indices */
1045 static TCGv_ptr cpu_env;
1046 static TCGv cpu_gpr[32], cpu_PC;
1047 static TCGv cpu_HI[MIPS_DSP_ACC], cpu_LO[MIPS_DSP_ACC], cpu_ACX[MIPS_DSP_ACC];
1048 static TCGv cpu_dspctrl, btarget, bcond;
1049 static TCGv_i32 hflags;
1050 static TCGv_i32 fpu_fcr0, fpu_fcr31;
1051 static TCGv_i64 fpu_f64[32];
1053 static uint32_t gen_opc_hflags[OPC_BUF_SIZE];
1055 #include "gen-icount.h"
1057 #define gen_helper_0e0i(name, arg) do { \
1058 TCGv_i32 helper_tmp = tcg_const_i32(arg); \
1059 gen_helper_##name(cpu_env, helper_tmp); \
1060 tcg_temp_free_i32(helper_tmp); \
1063 #define gen_helper_0e1i(name, arg1, arg2) do { \
1064 TCGv_i32 helper_tmp = tcg_const_i32(arg2); \
1065 gen_helper_##name(cpu_env, arg1, helper_tmp); \
1066 tcg_temp_free_i32(helper_tmp); \
1069 #define gen_helper_1e0i(name, ret, arg1) do { \
1070 TCGv_i32 helper_tmp = tcg_const_i32(arg1); \
1071 gen_helper_##name(ret, cpu_env, helper_tmp); \
1072 tcg_temp_free_i32(helper_tmp); \
1075 #define gen_helper_1e1i(name, ret, arg1, arg2) do { \
1076 TCGv_i32 helper_tmp = tcg_const_i32(arg2); \
1077 gen_helper_##name(ret, cpu_env, arg1, helper_tmp); \
1078 tcg_temp_free_i32(helper_tmp); \
1081 #define gen_helper_0e2i(name, arg1, arg2, arg3) do { \
1082 TCGv_i32 helper_tmp = tcg_const_i32(arg3); \
1083 gen_helper_##name(cpu_env, arg1, arg2, helper_tmp); \
1084 tcg_temp_free_i32(helper_tmp); \
1087 #define gen_helper_1e2i(name, ret, arg1, arg2, arg3) do { \
1088 TCGv_i32 helper_tmp = tcg_const_i32(arg3); \
1089 gen_helper_##name(ret, cpu_env, arg1, arg2, helper_tmp); \
1090 tcg_temp_free_i32(helper_tmp); \
1093 #define gen_helper_0e3i(name, arg1, arg2, arg3, arg4) do { \
1094 TCGv_i32 helper_tmp = tcg_const_i32(arg4); \
1095 gen_helper_##name(cpu_env, arg1, arg2, arg3, helper_tmp); \
1096 tcg_temp_free_i32(helper_tmp); \
1099 typedef struct DisasContext {
1100 struct TranslationBlock *tb;
1101 target_ulong pc, saved_pc;
1103 int singlestep_enabled;
1104 /* Routine used to access memory */
1106 uint32_t hflags, saved_hflags;
1108 target_ulong btarget;
1112 BS_NONE = 0, /* We go out of the TB without reaching a branch or an
1113 * exception condition */
1114 BS_STOP = 1, /* We want to stop translation for any reason */
1115 BS_BRANCH = 2, /* We reached a branch condition */
1116 BS_EXCP = 3, /* We reached an exception condition */
1119 static const char * const regnames[] = {
1120 "r0", "at", "v0", "v1", "a0", "a1", "a2", "a3",
1121 "t0", "t1", "t2", "t3", "t4", "t5", "t6", "t7",
1122 "s0", "s1", "s2", "s3", "s4", "s5", "s6", "s7",
1123 "t8", "t9", "k0", "k1", "gp", "sp", "s8", "ra",
1126 static const char * const regnames_HI[] = {
1127 "HI0", "HI1", "HI2", "HI3",
1130 static const char * const regnames_LO[] = {
1131 "LO0", "LO1", "LO2", "LO3",
1134 static const char * const regnames_ACX[] = {
1135 "ACX0", "ACX1", "ACX2", "ACX3",
1138 static const char * const fregnames[] = {
1139 "f0", "f1", "f2", "f3", "f4", "f5", "f6", "f7",
1140 "f8", "f9", "f10", "f11", "f12", "f13", "f14", "f15",
1141 "f16", "f17", "f18", "f19", "f20", "f21", "f22", "f23",
1142 "f24", "f25", "f26", "f27", "f28", "f29", "f30", "f31",
1145 #define MIPS_DEBUG(fmt, ...) \
1147 if (MIPS_DEBUG_DISAS) { \
1148 qemu_log_mask(CPU_LOG_TB_IN_ASM, \
1149 TARGET_FMT_lx ": %08x " fmt "\n", \
1150 ctx->pc, ctx->opcode , ## __VA_ARGS__); \
1154 #define LOG_DISAS(...) \
1156 if (MIPS_DEBUG_DISAS) { \
1157 qemu_log_mask(CPU_LOG_TB_IN_ASM, ## __VA_ARGS__); \
1161 #define MIPS_INVAL(op) \
1162 MIPS_DEBUG("Invalid %s %03x %03x %03x", op, ctx->opcode >> 26, \
1163 ctx->opcode & 0x3F, ((ctx->opcode >> 16) & 0x1F))
1165 /* General purpose registers moves. */
1166 static inline void gen_load_gpr (TCGv t, int reg)
1169 tcg_gen_movi_tl(t, 0);
1171 tcg_gen_mov_tl(t, cpu_gpr[reg]);
1174 static inline void gen_store_gpr (TCGv t, int reg)
1177 tcg_gen_mov_tl(cpu_gpr[reg], t);
1180 /* Moves to/from ACX register. */
1181 static inline void gen_load_ACX (TCGv t, int reg)
1183 tcg_gen_mov_tl(t, cpu_ACX[reg]);
1186 static inline void gen_store_ACX (TCGv t, int reg)
1188 tcg_gen_mov_tl(cpu_ACX[reg], t);
1191 /* Moves to/from shadow registers. */
1192 static inline void gen_load_srsgpr (int from, int to)
1194 TCGv t0 = tcg_temp_new();
1197 tcg_gen_movi_tl(t0, 0);
1199 TCGv_i32 t2 = tcg_temp_new_i32();
1200 TCGv_ptr addr = tcg_temp_new_ptr();
1202 tcg_gen_ld_i32(t2, cpu_env, offsetof(CPUMIPSState, CP0_SRSCtl));
1203 tcg_gen_shri_i32(t2, t2, CP0SRSCtl_PSS);
1204 tcg_gen_andi_i32(t2, t2, 0xf);
1205 tcg_gen_muli_i32(t2, t2, sizeof(target_ulong) * 32);
1206 tcg_gen_ext_i32_ptr(addr, t2);
1207 tcg_gen_add_ptr(addr, cpu_env, addr);
1209 tcg_gen_ld_tl(t0, addr, sizeof(target_ulong) * from);
1210 tcg_temp_free_ptr(addr);
1211 tcg_temp_free_i32(t2);
1213 gen_store_gpr(t0, to);
1217 static inline void gen_store_srsgpr (int from, int to)
1220 TCGv t0 = tcg_temp_new();
1221 TCGv_i32 t2 = tcg_temp_new_i32();
1222 TCGv_ptr addr = tcg_temp_new_ptr();
1224 gen_load_gpr(t0, from);
1225 tcg_gen_ld_i32(t2, cpu_env, offsetof(CPUMIPSState, CP0_SRSCtl));
1226 tcg_gen_shri_i32(t2, t2, CP0SRSCtl_PSS);
1227 tcg_gen_andi_i32(t2, t2, 0xf);
1228 tcg_gen_muli_i32(t2, t2, sizeof(target_ulong) * 32);
1229 tcg_gen_ext_i32_ptr(addr, t2);
1230 tcg_gen_add_ptr(addr, cpu_env, addr);
1232 tcg_gen_st_tl(t0, addr, sizeof(target_ulong) * to);
1233 tcg_temp_free_ptr(addr);
1234 tcg_temp_free_i32(t2);
1239 /* Floating point register moves. */
1240 static void gen_load_fpr32(TCGv_i32 t, int reg)
1242 tcg_gen_trunc_i64_i32(t, fpu_f64[reg]);
1245 static void gen_store_fpr32(TCGv_i32 t, int reg)
1247 TCGv_i64 t64 = tcg_temp_new_i64();
1248 tcg_gen_extu_i32_i64(t64, t);
1249 tcg_gen_deposit_i64(fpu_f64[reg], fpu_f64[reg], t64, 0, 32);
1250 tcg_temp_free_i64(t64);
1253 static void gen_load_fpr32h(TCGv_i32 t, int reg)
1255 TCGv_i64 t64 = tcg_temp_new_i64();
1256 tcg_gen_shri_i64(t64, fpu_f64[reg], 32);
1257 tcg_gen_trunc_i64_i32(t, t64);
1258 tcg_temp_free_i64(t64);
1261 static void gen_store_fpr32h(TCGv_i32 t, int reg)
1263 TCGv_i64 t64 = tcg_temp_new_i64();
1264 tcg_gen_extu_i32_i64(t64, t);
1265 tcg_gen_deposit_i64(fpu_f64[reg], fpu_f64[reg], t64, 32, 32);
1266 tcg_temp_free_i64(t64);
1269 static void gen_load_fpr64(DisasContext *ctx, TCGv_i64 t, int reg)
1271 if (ctx->hflags & MIPS_HFLAG_F64) {
1272 tcg_gen_mov_i64(t, fpu_f64[reg]);
1274 tcg_gen_concat32_i64(t, fpu_f64[reg & ~1], fpu_f64[reg | 1]);
1278 static void gen_store_fpr64(DisasContext *ctx, TCGv_i64 t, int reg)
1280 if (ctx->hflags & MIPS_HFLAG_F64) {
1281 tcg_gen_mov_i64(fpu_f64[reg], t);
1284 tcg_gen_deposit_i64(fpu_f64[reg & ~1], fpu_f64[reg & ~1], t, 0, 32);
1285 t0 = tcg_temp_new_i64();
1286 tcg_gen_shri_i64(t0, t, 32);
1287 tcg_gen_deposit_i64(fpu_f64[reg | 1], fpu_f64[reg | 1], t0, 0, 32);
1288 tcg_temp_free_i64(t0);
1292 static inline int get_fp_bit (int cc)
1301 static inline void gen_save_pc(target_ulong pc)
1303 tcg_gen_movi_tl(cpu_PC, pc);
1306 static inline void save_cpu_state (DisasContext *ctx, int do_save_pc)
1308 LOG_DISAS("hflags %08x saved %08x\n", ctx->hflags, ctx->saved_hflags);
1309 if (do_save_pc && ctx->pc != ctx->saved_pc) {
1310 gen_save_pc(ctx->pc);
1311 ctx->saved_pc = ctx->pc;
1313 if (ctx->hflags != ctx->saved_hflags) {
1314 tcg_gen_movi_i32(hflags, ctx->hflags);
1315 ctx->saved_hflags = ctx->hflags;
1316 switch (ctx->hflags & MIPS_HFLAG_BMASK_BASE) {
1322 tcg_gen_movi_tl(btarget, ctx->btarget);
1328 static inline void restore_cpu_state (CPUMIPSState *env, DisasContext *ctx)
1330 ctx->saved_hflags = ctx->hflags;
1331 switch (ctx->hflags & MIPS_HFLAG_BMASK_BASE) {
1337 ctx->btarget = env->btarget;
1343 generate_exception_err (DisasContext *ctx, int excp, int err)
1345 TCGv_i32 texcp = tcg_const_i32(excp);
1346 TCGv_i32 terr = tcg_const_i32(err);
1347 save_cpu_state(ctx, 1);
1348 gen_helper_raise_exception_err(cpu_env, texcp, terr);
1349 tcg_temp_free_i32(terr);
1350 tcg_temp_free_i32(texcp);
1354 generate_exception (DisasContext *ctx, int excp)
1356 save_cpu_state(ctx, 1);
1357 gen_helper_0e0i(raise_exception, excp);
1360 /* Addresses computation */
1361 static inline void gen_op_addr_add (DisasContext *ctx, TCGv ret, TCGv arg0, TCGv arg1)
1363 tcg_gen_add_tl(ret, arg0, arg1);
1365 #if defined(TARGET_MIPS64)
1366 /* For compatibility with 32-bit code, data reference in user mode
1367 with Status_UX = 0 should be casted to 32-bit and sign extended.
1368 See the MIPS64 PRA manual, section 4.10. */
1369 if (((ctx->hflags & MIPS_HFLAG_KSU) == MIPS_HFLAG_UM) &&
1370 !(ctx->hflags & MIPS_HFLAG_UX)) {
1371 tcg_gen_ext32s_i64(ret, ret);
1376 static inline void check_cp0_enabled(DisasContext *ctx)
1378 if (unlikely(!(ctx->hflags & MIPS_HFLAG_CP0)))
1379 generate_exception_err(ctx, EXCP_CpU, 0);
1382 static inline void check_cp1_enabled(DisasContext *ctx)
1384 if (unlikely(!(ctx->hflags & MIPS_HFLAG_FPU)))
1385 generate_exception_err(ctx, EXCP_CpU, 1);
1388 /* Verify that the processor is running with COP1X instructions enabled.
1389 This is associated with the nabla symbol in the MIPS32 and MIPS64
1392 static inline void check_cop1x(DisasContext *ctx)
1394 if (unlikely(!(ctx->hflags & MIPS_HFLAG_COP1X)))
1395 generate_exception(ctx, EXCP_RI);
1398 /* Verify that the processor is running with 64-bit floating-point
1399 operations enabled. */
1401 static inline void check_cp1_64bitmode(DisasContext *ctx)
1403 if (unlikely(~ctx->hflags & (MIPS_HFLAG_F64 | MIPS_HFLAG_COP1X)))
1404 generate_exception(ctx, EXCP_RI);
1408 * Verify if floating point register is valid; an operation is not defined
1409 * if bit 0 of any register specification is set and the FR bit in the
1410 * Status register equals zero, since the register numbers specify an
1411 * even-odd pair of adjacent coprocessor general registers. When the FR bit
1412 * in the Status register equals one, both even and odd register numbers
1413 * are valid. This limitation exists only for 64 bit wide (d,l,ps) registers.
1415 * Multiple 64 bit wide registers can be checked by calling
1416 * gen_op_cp1_registers(freg1 | freg2 | ... | fregN);
1418 static inline void check_cp1_registers(DisasContext *ctx, int regs)
1420 if (unlikely(!(ctx->hflags & MIPS_HFLAG_F64) && (regs & 1)))
1421 generate_exception(ctx, EXCP_RI);
1424 /* Verify that the processor is running with DSP instructions enabled.
1425 This is enabled by CP0 Status register MX(24) bit.
1428 static inline void check_dsp(DisasContext *ctx)
1430 if (unlikely(!(ctx->hflags & MIPS_HFLAG_DSP))) {
1431 generate_exception(ctx, EXCP_DSPDIS);
1435 static inline void check_dspr2(DisasContext *ctx)
1437 if (unlikely(!(ctx->hflags & MIPS_HFLAG_DSPR2))) {
1438 generate_exception(ctx, EXCP_DSPDIS);
1442 /* This code generates a "reserved instruction" exception if the
1443 CPU does not support the instruction set corresponding to flags. */
1444 static inline void check_insn(CPUMIPSState *env, DisasContext *ctx, int flags)
1446 if (unlikely(!(env->insn_flags & flags)))
1447 generate_exception(ctx, EXCP_RI);
1450 /* This code generates a "reserved instruction" exception if 64-bit
1451 instructions are not enabled. */
1452 static inline void check_mips_64(DisasContext *ctx)
1454 if (unlikely(!(ctx->hflags & MIPS_HFLAG_64)))
1455 generate_exception(ctx, EXCP_RI);
1458 /* Define small wrappers for gen_load_fpr* so that we have a uniform
1459 calling interface for 32 and 64-bit FPRs. No sense in changing
1460 all callers for gen_load_fpr32 when we need the CTX parameter for
1462 #define gen_ldcmp_fpr32(ctx, x, y) gen_load_fpr32(x, y)
1463 #define gen_ldcmp_fpr64(ctx, x, y) gen_load_fpr64(ctx, x, y)
1464 #define FOP_CONDS(type, abs, fmt, ifmt, bits) \
1465 static inline void gen_cmp ## type ## _ ## fmt(DisasContext *ctx, int n, \
1466 int ft, int fs, int cc) \
1468 TCGv_i##bits fp0 = tcg_temp_new_i##bits (); \
1469 TCGv_i##bits fp1 = tcg_temp_new_i##bits (); \
1472 check_cp1_64bitmode(ctx); \
1478 check_cp1_registers(ctx, fs | ft); \
1486 gen_ldcmp_fpr##bits (ctx, fp0, fs); \
1487 gen_ldcmp_fpr##bits (ctx, fp1, ft); \
1489 case 0: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _f, fp0, fp1, cc); break;\
1490 case 1: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _un, fp0, fp1, cc); break;\
1491 case 2: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _eq, fp0, fp1, cc); break;\
1492 case 3: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ueq, fp0, fp1, cc); break;\
1493 case 4: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _olt, fp0, fp1, cc); break;\
1494 case 5: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ult, fp0, fp1, cc); break;\
1495 case 6: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ole, fp0, fp1, cc); break;\
1496 case 7: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ule, fp0, fp1, cc); break;\
1497 case 8: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _sf, fp0, fp1, cc); break;\
1498 case 9: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ngle, fp0, fp1, cc); break;\
1499 case 10: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _seq, fp0, fp1, cc); break;\
1500 case 11: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ngl, fp0, fp1, cc); break;\
1501 case 12: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _lt, fp0, fp1, cc); break;\
1502 case 13: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _nge, fp0, fp1, cc); break;\
1503 case 14: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _le, fp0, fp1, cc); break;\
1504 case 15: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ngt, fp0, fp1, cc); break;\
1507 tcg_temp_free_i##bits (fp0); \
1508 tcg_temp_free_i##bits (fp1); \
1511 FOP_CONDS(, 0, d, FMT_D, 64)
1512 FOP_CONDS(abs, 1, d, FMT_D, 64)
1513 FOP_CONDS(, 0, s, FMT_S, 32)
1514 FOP_CONDS(abs, 1, s, FMT_S, 32)
1515 FOP_CONDS(, 0, ps, FMT_PS, 64)
1516 FOP_CONDS(abs, 1, ps, FMT_PS, 64)
1518 #undef gen_ldcmp_fpr32
1519 #undef gen_ldcmp_fpr64
1521 /* load/store instructions. */
1522 #define OP_LD(insn,fname) \
1523 static inline void op_ld_##insn(TCGv ret, TCGv arg1, DisasContext *ctx) \
1525 tcg_gen_qemu_##fname(ret, arg1, ctx->mem_idx); \
1532 #if defined(TARGET_MIPS64)
1538 #define OP_ST(insn,fname) \
1539 static inline void op_st_##insn(TCGv arg1, TCGv arg2, DisasContext *ctx) \
1541 tcg_gen_qemu_##fname(arg1, arg2, ctx->mem_idx); \
1546 #if defined(TARGET_MIPS64)
1551 #ifdef CONFIG_USER_ONLY
1552 #define OP_LD_ATOMIC(insn,fname) \
1553 static inline void op_ld_##insn(TCGv ret, TCGv arg1, DisasContext *ctx) \
1555 TCGv t0 = tcg_temp_new(); \
1556 tcg_gen_mov_tl(t0, arg1); \
1557 tcg_gen_qemu_##fname(ret, arg1, ctx->mem_idx); \
1558 tcg_gen_st_tl(t0, cpu_env, offsetof(CPUMIPSState, lladdr)); \
1559 tcg_gen_st_tl(ret, cpu_env, offsetof(CPUMIPSState, llval)); \
1560 tcg_temp_free(t0); \
1563 #define OP_LD_ATOMIC(insn,fname) \
1564 static inline void op_ld_##insn(TCGv ret, TCGv arg1, DisasContext *ctx) \
1566 gen_helper_1e1i(insn, ret, arg1, ctx->mem_idx); \
1569 OP_LD_ATOMIC(ll,ld32s);
1570 #if defined(TARGET_MIPS64)
1571 OP_LD_ATOMIC(lld,ld64);
1575 #ifdef CONFIG_USER_ONLY
1576 #define OP_ST_ATOMIC(insn,fname,ldname,almask) \
1577 static inline void op_st_##insn(TCGv arg1, TCGv arg2, int rt, DisasContext *ctx) \
1579 TCGv t0 = tcg_temp_new(); \
1580 int l1 = gen_new_label(); \
1581 int l2 = gen_new_label(); \
1583 tcg_gen_andi_tl(t0, arg2, almask); \
1584 tcg_gen_brcondi_tl(TCG_COND_EQ, t0, 0, l1); \
1585 tcg_gen_st_tl(arg2, cpu_env, offsetof(CPUMIPSState, CP0_BadVAddr)); \
1586 generate_exception(ctx, EXCP_AdES); \
1587 gen_set_label(l1); \
1588 tcg_gen_ld_tl(t0, cpu_env, offsetof(CPUMIPSState, lladdr)); \
1589 tcg_gen_brcond_tl(TCG_COND_NE, arg2, t0, l2); \
1590 tcg_gen_movi_tl(t0, rt | ((almask << 3) & 0x20)); \
1591 tcg_gen_st_tl(t0, cpu_env, offsetof(CPUMIPSState, llreg)); \
1592 tcg_gen_st_tl(arg1, cpu_env, offsetof(CPUMIPSState, llnewval)); \
1593 gen_helper_0e0i(raise_exception, EXCP_SC); \
1594 gen_set_label(l2); \
1595 tcg_gen_movi_tl(t0, 0); \
1596 gen_store_gpr(t0, rt); \
1597 tcg_temp_free(t0); \
1600 #define OP_ST_ATOMIC(insn,fname,ldname,almask) \
1601 static inline void op_st_##insn(TCGv arg1, TCGv arg2, int rt, DisasContext *ctx) \
1603 TCGv t0 = tcg_temp_new(); \
1604 gen_helper_1e2i(insn, t0, arg1, arg2, ctx->mem_idx); \
1605 gen_store_gpr(t0, rt); \
1606 tcg_temp_free(t0); \
1609 OP_ST_ATOMIC(sc,st32,ld32s,0x3);
1610 #if defined(TARGET_MIPS64)
1611 OP_ST_ATOMIC(scd,st64,ld64,0x7);
1615 static void gen_base_offset_addr (DisasContext *ctx, TCGv addr,
1616 int base, int16_t offset)
1619 tcg_gen_movi_tl(addr, offset);
1620 } else if (offset == 0) {
1621 gen_load_gpr(addr, base);
1623 tcg_gen_movi_tl(addr, offset);
1624 gen_op_addr_add(ctx, addr, cpu_gpr[base], addr);
1628 static target_ulong pc_relative_pc (DisasContext *ctx)
1630 target_ulong pc = ctx->pc;
1632 if (ctx->hflags & MIPS_HFLAG_BMASK) {
1633 int branch_bytes = ctx->hflags & MIPS_HFLAG_BDS16 ? 2 : 4;
1638 pc &= ~(target_ulong)3;
1643 static void gen_ld (CPUMIPSState *env, DisasContext *ctx, uint32_t opc,
1644 int rt, int base, int16_t offset)
1646 const char *opn = "ld";
1649 if (rt == 0 && env->insn_flags & (INSN_LOONGSON2E | INSN_LOONGSON2F)) {
1650 /* Loongson CPU uses a load to zero register for prefetch.
1651 We emulate it as a NOP. On other CPU we must perform the
1652 actual memory access. */
1657 t0 = tcg_temp_new();
1658 t1 = tcg_temp_new();
1659 gen_base_offset_addr(ctx, t0, base, offset);
1662 #if defined(TARGET_MIPS64)
1664 save_cpu_state(ctx, 0);
1665 op_ld_lwu(t0, t0, ctx);
1666 gen_store_gpr(t0, rt);
1670 save_cpu_state(ctx, 0);
1671 op_ld_ld(t0, t0, ctx);
1672 gen_store_gpr(t0, rt);
1676 save_cpu_state(ctx, 1);
1677 op_ld_lld(t0, t0, ctx);
1678 gen_store_gpr(t0, rt);
1682 save_cpu_state(ctx, 1);
1683 gen_load_gpr(t1, rt);
1684 gen_helper_1e2i(ldl, t1, t1, t0, ctx->mem_idx);
1685 gen_store_gpr(t1, rt);
1689 save_cpu_state(ctx, 1);
1690 gen_load_gpr(t1, rt);
1691 gen_helper_1e2i(ldr, t1, t1, t0, ctx->mem_idx);
1692 gen_store_gpr(t1, rt);
1696 save_cpu_state(ctx, 0);
1697 tcg_gen_movi_tl(t1, pc_relative_pc(ctx));
1698 gen_op_addr_add(ctx, t0, t0, t1);
1699 op_ld_ld(t0, t0, ctx);
1700 gen_store_gpr(t0, rt);
1705 save_cpu_state(ctx, 0);
1706 tcg_gen_movi_tl(t1, pc_relative_pc(ctx));
1707 gen_op_addr_add(ctx, t0, t0, t1);
1708 op_ld_lw(t0, t0, ctx);
1709 gen_store_gpr(t0, rt);
1713 save_cpu_state(ctx, 0);
1714 op_ld_lw(t0, t0, ctx);
1715 gen_store_gpr(t0, rt);
1719 save_cpu_state(ctx, 0);
1720 op_ld_lh(t0, t0, ctx);
1721 gen_store_gpr(t0, rt);
1725 save_cpu_state(ctx, 0);
1726 op_ld_lhu(t0, t0, ctx);
1727 gen_store_gpr(t0, rt);
1731 save_cpu_state(ctx, 0);
1732 op_ld_lb(t0, t0, ctx);
1733 gen_store_gpr(t0, rt);
1737 save_cpu_state(ctx, 0);
1738 op_ld_lbu(t0, t0, ctx);
1739 gen_store_gpr(t0, rt);
1743 save_cpu_state(ctx, 1);
1744 gen_load_gpr(t1, rt);
1745 gen_helper_1e2i(lwl, t1, t1, t0, ctx->mem_idx);
1746 gen_store_gpr(t1, rt);
1750 save_cpu_state(ctx, 1);
1751 gen_load_gpr(t1, rt);
1752 gen_helper_1e2i(lwr, t1, t1, t0, ctx->mem_idx);
1753 gen_store_gpr(t1, rt);
1757 save_cpu_state(ctx, 1);
1758 op_ld_ll(t0, t0, ctx);
1759 gen_store_gpr(t0, rt);
1763 (void)opn; /* avoid a compiler warning */
1764 MIPS_DEBUG("%s %s, %d(%s)", opn, regnames[rt], offset, regnames[base]);
1770 static void gen_st (DisasContext *ctx, uint32_t opc, int rt,
1771 int base, int16_t offset)
1773 const char *opn = "st";
1774 TCGv t0 = tcg_temp_new();
1775 TCGv t1 = tcg_temp_new();
1777 gen_base_offset_addr(ctx, t0, base, offset);
1778 gen_load_gpr(t1, rt);
1780 #if defined(TARGET_MIPS64)
1782 save_cpu_state(ctx, 0);
1783 op_st_sd(t1, t0, ctx);
1787 save_cpu_state(ctx, 1);
1788 gen_helper_0e2i(sdl, t1, t0, ctx->mem_idx);
1792 save_cpu_state(ctx, 1);
1793 gen_helper_0e2i(sdr, t1, t0, ctx->mem_idx);
1798 save_cpu_state(ctx, 0);
1799 op_st_sw(t1, t0, ctx);
1803 save_cpu_state(ctx, 0);
1804 op_st_sh(t1, t0, ctx);
1808 save_cpu_state(ctx, 0);
1809 op_st_sb(t1, t0, ctx);
1813 save_cpu_state(ctx, 1);
1814 gen_helper_0e2i(swl, t1, t0, ctx->mem_idx);
1818 save_cpu_state(ctx, 1);
1819 gen_helper_0e2i(swr, t1, t0, ctx->mem_idx);
1823 (void)opn; /* avoid a compiler warning */
1824 MIPS_DEBUG("%s %s, %d(%s)", opn, regnames[rt], offset, regnames[base]);
1830 /* Store conditional */
1831 static void gen_st_cond (DisasContext *ctx, uint32_t opc, int rt,
1832 int base, int16_t offset)
1834 const char *opn = "st_cond";
1837 t0 = tcg_temp_local_new();
1839 gen_base_offset_addr(ctx, t0, base, offset);
1840 /* Don't do NOP if destination is zero: we must perform the actual
1843 t1 = tcg_temp_local_new();
1844 gen_load_gpr(t1, rt);
1846 #if defined(TARGET_MIPS64)
1848 save_cpu_state(ctx, 1);
1849 op_st_scd(t1, t0, rt, ctx);
1854 save_cpu_state(ctx, 1);
1855 op_st_sc(t1, t0, rt, ctx);
1859 (void)opn; /* avoid a compiler warning */
1860 MIPS_DEBUG("%s %s, %d(%s)", opn, regnames[rt], offset, regnames[base]);
1865 /* Load and store */
1866 static void gen_flt_ldst (DisasContext *ctx, uint32_t opc, int ft,
1867 int base, int16_t offset)
1869 const char *opn = "flt_ldst";
1870 TCGv t0 = tcg_temp_new();
1872 gen_base_offset_addr(ctx, t0, base, offset);
1873 /* Don't do NOP if destination is zero: we must perform the actual
1878 TCGv_i32 fp0 = tcg_temp_new_i32();
1880 tcg_gen_qemu_ld32s(t0, t0, ctx->mem_idx);
1881 tcg_gen_trunc_tl_i32(fp0, t0);
1882 gen_store_fpr32(fp0, ft);
1883 tcg_temp_free_i32(fp0);
1889 TCGv_i32 fp0 = tcg_temp_new_i32();
1890 TCGv t1 = tcg_temp_new();
1892 gen_load_fpr32(fp0, ft);
1893 tcg_gen_extu_i32_tl(t1, fp0);
1894 tcg_gen_qemu_st32(t1, t0, ctx->mem_idx);
1896 tcg_temp_free_i32(fp0);
1902 TCGv_i64 fp0 = tcg_temp_new_i64();
1904 tcg_gen_qemu_ld64(fp0, t0, ctx->mem_idx);
1905 gen_store_fpr64(ctx, fp0, ft);
1906 tcg_temp_free_i64(fp0);
1912 TCGv_i64 fp0 = tcg_temp_new_i64();
1914 gen_load_fpr64(ctx, fp0, ft);
1915 tcg_gen_qemu_st64(fp0, t0, ctx->mem_idx);
1916 tcg_temp_free_i64(fp0);
1922 generate_exception(ctx, EXCP_RI);
1925 (void)opn; /* avoid a compiler warning */
1926 MIPS_DEBUG("%s %s, %d(%s)", opn, fregnames[ft], offset, regnames[base]);
1931 static void gen_cop1_ldst(CPUMIPSState *env, DisasContext *ctx,
1932 uint32_t op, int rt, int rs, int16_t imm)
1934 if (env->CP0_Config1 & (1 << CP0C1_FP)) {
1935 check_cp1_enabled(ctx);
1936 gen_flt_ldst(ctx, op, rt, rs, imm);
1938 generate_exception_err(ctx, EXCP_CpU, 1);
1942 /* Arithmetic with immediate operand */
1943 static void gen_arith_imm (CPUMIPSState *env, DisasContext *ctx, uint32_t opc,
1944 int rt, int rs, int16_t imm)
1946 target_ulong uimm = (target_long)imm; /* Sign extend to 32/64 bits */
1947 const char *opn = "imm arith";
1949 if (rt == 0 && opc != OPC_ADDI && opc != OPC_DADDI) {
1950 /* If no destination, treat it as a NOP.
1951 For addi, we must generate the overflow exception when needed. */
1958 TCGv t0 = tcg_temp_local_new();
1959 TCGv t1 = tcg_temp_new();
1960 TCGv t2 = tcg_temp_new();
1961 int l1 = gen_new_label();
1963 gen_load_gpr(t1, rs);
1964 tcg_gen_addi_tl(t0, t1, uimm);
1965 tcg_gen_ext32s_tl(t0, t0);
1967 tcg_gen_xori_tl(t1, t1, ~uimm);
1968 tcg_gen_xori_tl(t2, t0, uimm);
1969 tcg_gen_and_tl(t1, t1, t2);
1971 tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
1973 /* operands of same sign, result different sign */
1974 generate_exception(ctx, EXCP_OVERFLOW);
1976 tcg_gen_ext32s_tl(t0, t0);
1977 gen_store_gpr(t0, rt);
1984 tcg_gen_addi_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
1985 tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]);
1987 tcg_gen_movi_tl(cpu_gpr[rt], uimm);
1991 #if defined(TARGET_MIPS64)
1994 TCGv t0 = tcg_temp_local_new();
1995 TCGv t1 = tcg_temp_new();
1996 TCGv t2 = tcg_temp_new();
1997 int l1 = gen_new_label();
1999 gen_load_gpr(t1, rs);
2000 tcg_gen_addi_tl(t0, t1, uimm);
2002 tcg_gen_xori_tl(t1, t1, ~uimm);
2003 tcg_gen_xori_tl(t2, t0, uimm);
2004 tcg_gen_and_tl(t1, t1, t2);
2006 tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
2008 /* operands of same sign, result different sign */
2009 generate_exception(ctx, EXCP_OVERFLOW);
2011 gen_store_gpr(t0, rt);
2018 tcg_gen_addi_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
2020 tcg_gen_movi_tl(cpu_gpr[rt], uimm);
2026 (void)opn; /* avoid a compiler warning */
2027 MIPS_DEBUG("%s %s, %s, " TARGET_FMT_lx, opn, regnames[rt], regnames[rs], uimm);
2030 /* Logic with immediate operand */
2031 static void gen_logic_imm(CPUMIPSState *env, DisasContext *ctx, uint32_t opc,
2032 int rt, int rs, int16_t imm)
2035 const char *opn = "imm logic";
2038 /* If no destination, treat it as a NOP. */
2042 uimm = (uint16_t)imm;
2045 if (likely(rs != 0))
2046 tcg_gen_andi_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
2048 tcg_gen_movi_tl(cpu_gpr[rt], 0);
2053 tcg_gen_ori_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
2055 tcg_gen_movi_tl(cpu_gpr[rt], uimm);
2059 if (likely(rs != 0))
2060 tcg_gen_xori_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
2062 tcg_gen_movi_tl(cpu_gpr[rt], uimm);
2066 tcg_gen_movi_tl(cpu_gpr[rt], imm << 16);
2070 (void)opn; /* avoid a compiler warning */
2071 MIPS_DEBUG("%s %s, %s, " TARGET_FMT_lx, opn, regnames[rt], regnames[rs], uimm);
2074 /* Set on less than with immediate operand */
2075 static void gen_slt_imm(CPUMIPSState *env, DisasContext *ctx, uint32_t opc,
2076 int rt, int rs, int16_t imm)
2078 target_ulong uimm = (target_long)imm; /* Sign extend to 32/64 bits */
2079 const char *opn = "imm arith";
2083 /* If no destination, treat it as a NOP. */
2087 t0 = tcg_temp_new();
2088 gen_load_gpr(t0, rs);
2091 tcg_gen_setcondi_tl(TCG_COND_LT, cpu_gpr[rt], t0, uimm);
2095 tcg_gen_setcondi_tl(TCG_COND_LTU, cpu_gpr[rt], t0, uimm);
2099 (void)opn; /* avoid a compiler warning */
2100 MIPS_DEBUG("%s %s, %s, " TARGET_FMT_lx, opn, regnames[rt], regnames[rs], uimm);
2104 /* Shifts with immediate operand */
2105 static void gen_shift_imm(CPUMIPSState *env, DisasContext *ctx, uint32_t opc,
2106 int rt, int rs, int16_t imm)
2108 target_ulong uimm = ((uint16_t)imm) & 0x1f;
2109 const char *opn = "imm shift";
2113 /* If no destination, treat it as a NOP. */
2118 t0 = tcg_temp_new();
2119 gen_load_gpr(t0, rs);
2122 tcg_gen_shli_tl(t0, t0, uimm);
2123 tcg_gen_ext32s_tl(cpu_gpr[rt], t0);
2127 tcg_gen_sari_tl(cpu_gpr[rt], t0, uimm);
2132 tcg_gen_ext32u_tl(t0, t0);
2133 tcg_gen_shri_tl(cpu_gpr[rt], t0, uimm);
2135 tcg_gen_ext32s_tl(cpu_gpr[rt], t0);
2141 TCGv_i32 t1 = tcg_temp_new_i32();
2143 tcg_gen_trunc_tl_i32(t1, t0);
2144 tcg_gen_rotri_i32(t1, t1, uimm);
2145 tcg_gen_ext_i32_tl(cpu_gpr[rt], t1);
2146 tcg_temp_free_i32(t1);
2148 tcg_gen_ext32s_tl(cpu_gpr[rt], t0);
2152 #if defined(TARGET_MIPS64)
2154 tcg_gen_shli_tl(cpu_gpr[rt], t0, uimm);
2158 tcg_gen_sari_tl(cpu_gpr[rt], t0, uimm);
2162 tcg_gen_shri_tl(cpu_gpr[rt], t0, uimm);
2167 tcg_gen_rotri_tl(cpu_gpr[rt], t0, uimm);
2169 tcg_gen_mov_tl(cpu_gpr[rt], t0);
2174 tcg_gen_shli_tl(cpu_gpr[rt], t0, uimm + 32);
2178 tcg_gen_sari_tl(cpu_gpr[rt], t0, uimm + 32);
2182 tcg_gen_shri_tl(cpu_gpr[rt], t0, uimm + 32);
2186 tcg_gen_rotri_tl(cpu_gpr[rt], t0, uimm + 32);
2191 (void)opn; /* avoid a compiler warning */
2192 MIPS_DEBUG("%s %s, %s, " TARGET_FMT_lx, opn, regnames[rt], regnames[rs], uimm);
2197 static void gen_arith (CPUMIPSState *env, DisasContext *ctx, uint32_t opc,
2198 int rd, int rs, int rt)
2200 const char *opn = "arith";
2202 if (rd == 0 && opc != OPC_ADD && opc != OPC_SUB
2203 && opc != OPC_DADD && opc != OPC_DSUB) {
2204 /* If no destination, treat it as a NOP.
2205 For add & sub, we must generate the overflow exception when needed. */
2213 TCGv t0 = tcg_temp_local_new();
2214 TCGv t1 = tcg_temp_new();
2215 TCGv t2 = tcg_temp_new();
2216 int l1 = gen_new_label();
2218 gen_load_gpr(t1, rs);
2219 gen_load_gpr(t2, rt);
2220 tcg_gen_add_tl(t0, t1, t2);
2221 tcg_gen_ext32s_tl(t0, t0);
2222 tcg_gen_xor_tl(t1, t1, t2);
2223 tcg_gen_xor_tl(t2, t0, t2);
2224 tcg_gen_andc_tl(t1, t2, t1);
2226 tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
2228 /* operands of same sign, result different sign */
2229 generate_exception(ctx, EXCP_OVERFLOW);
2231 gen_store_gpr(t0, rd);
2237 if (rs != 0 && rt != 0) {
2238 tcg_gen_add_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2239 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
2240 } else if (rs == 0 && rt != 0) {
2241 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rt]);
2242 } else if (rs != 0 && rt == 0) {
2243 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
2245 tcg_gen_movi_tl(cpu_gpr[rd], 0);
2251 TCGv t0 = tcg_temp_local_new();
2252 TCGv t1 = tcg_temp_new();
2253 TCGv t2 = tcg_temp_new();
2254 int l1 = gen_new_label();
2256 gen_load_gpr(t1, rs);
2257 gen_load_gpr(t2, rt);
2258 tcg_gen_sub_tl(t0, t1, t2);
2259 tcg_gen_ext32s_tl(t0, t0);
2260 tcg_gen_xor_tl(t2, t1, t2);
2261 tcg_gen_xor_tl(t1, t0, t1);
2262 tcg_gen_and_tl(t1, t1, t2);
2264 tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
2266 /* operands of different sign, first operand and result different sign */
2267 generate_exception(ctx, EXCP_OVERFLOW);
2269 gen_store_gpr(t0, rd);
2275 if (rs != 0 && rt != 0) {
2276 tcg_gen_sub_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2277 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
2278 } else if (rs == 0 && rt != 0) {
2279 tcg_gen_neg_tl(cpu_gpr[rd], cpu_gpr[rt]);
2280 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
2281 } else if (rs != 0 && rt == 0) {
2282 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
2284 tcg_gen_movi_tl(cpu_gpr[rd], 0);
2288 #if defined(TARGET_MIPS64)
2291 TCGv t0 = tcg_temp_local_new();
2292 TCGv t1 = tcg_temp_new();
2293 TCGv t2 = tcg_temp_new();
2294 int l1 = gen_new_label();
2296 gen_load_gpr(t1, rs);
2297 gen_load_gpr(t2, rt);
2298 tcg_gen_add_tl(t0, t1, t2);
2299 tcg_gen_xor_tl(t1, t1, t2);
2300 tcg_gen_xor_tl(t2, t0, t2);
2301 tcg_gen_andc_tl(t1, t2, t1);
2303 tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
2305 /* operands of same sign, result different sign */
2306 generate_exception(ctx, EXCP_OVERFLOW);
2308 gen_store_gpr(t0, rd);
2314 if (rs != 0 && rt != 0) {
2315 tcg_gen_add_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2316 } else if (rs == 0 && rt != 0) {
2317 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rt]);
2318 } else if (rs != 0 && rt == 0) {
2319 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
2321 tcg_gen_movi_tl(cpu_gpr[rd], 0);
2327 TCGv t0 = tcg_temp_local_new();
2328 TCGv t1 = tcg_temp_new();
2329 TCGv t2 = tcg_temp_new();
2330 int l1 = gen_new_label();
2332 gen_load_gpr(t1, rs);
2333 gen_load_gpr(t2, rt);
2334 tcg_gen_sub_tl(t0, t1, t2);
2335 tcg_gen_xor_tl(t2, t1, t2);
2336 tcg_gen_xor_tl(t1, t0, t1);
2337 tcg_gen_and_tl(t1, t1, t2);
2339 tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
2341 /* operands of different sign, first operand and result different sign */
2342 generate_exception(ctx, EXCP_OVERFLOW);
2344 gen_store_gpr(t0, rd);
2350 if (rs != 0 && rt != 0) {
2351 tcg_gen_sub_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2352 } else if (rs == 0 && rt != 0) {
2353 tcg_gen_neg_tl(cpu_gpr[rd], cpu_gpr[rt]);
2354 } else if (rs != 0 && rt == 0) {
2355 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
2357 tcg_gen_movi_tl(cpu_gpr[rd], 0);
2363 if (likely(rs != 0 && rt != 0)) {
2364 tcg_gen_mul_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2365 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
2367 tcg_gen_movi_tl(cpu_gpr[rd], 0);
2372 (void)opn; /* avoid a compiler warning */
2373 MIPS_DEBUG("%s %s, %s, %s", opn, regnames[rd], regnames[rs], regnames[rt]);
2376 /* Conditional move */
2377 static void gen_cond_move(CPUMIPSState *env, DisasContext *ctx, uint32_t opc,
2378 int rd, int rs, int rt)
2380 const char *opn = "cond move";
2384 /* If no destination, treat it as a NOP.
2385 For add & sub, we must generate the overflow exception when needed. */
2390 l1 = gen_new_label();
2393 if (likely(rt != 0))
2394 tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_gpr[rt], 0, l1);
2400 if (likely(rt != 0))
2401 tcg_gen_brcondi_tl(TCG_COND_NE, cpu_gpr[rt], 0, l1);
2406 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
2408 tcg_gen_movi_tl(cpu_gpr[rd], 0);
2411 (void)opn; /* avoid a compiler warning */
2412 MIPS_DEBUG("%s %s, %s, %s", opn, regnames[rd], regnames[rs], regnames[rt]);
2416 static void gen_logic(CPUMIPSState *env, DisasContext *ctx, uint32_t opc,
2417 int rd, int rs, int rt)
2419 const char *opn = "logic";
2422 /* If no destination, treat it as a NOP. */
2429 if (likely(rs != 0 && rt != 0)) {
2430 tcg_gen_and_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2432 tcg_gen_movi_tl(cpu_gpr[rd], 0);
2437 if (rs != 0 && rt != 0) {
2438 tcg_gen_nor_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2439 } else if (rs == 0 && rt != 0) {
2440 tcg_gen_not_tl(cpu_gpr[rd], cpu_gpr[rt]);
2441 } else if (rs != 0 && rt == 0) {
2442 tcg_gen_not_tl(cpu_gpr[rd], cpu_gpr[rs]);
2444 tcg_gen_movi_tl(cpu_gpr[rd], ~((target_ulong)0));
2449 if (likely(rs != 0 && rt != 0)) {
2450 tcg_gen_or_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2451 } else if (rs == 0 && rt != 0) {
2452 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rt]);
2453 } else if (rs != 0 && rt == 0) {
2454 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
2456 tcg_gen_movi_tl(cpu_gpr[rd], 0);
2461 if (likely(rs != 0 && rt != 0)) {
2462 tcg_gen_xor_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2463 } else if (rs == 0 && rt != 0) {
2464 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rt]);
2465 } else if (rs != 0 && rt == 0) {
2466 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
2468 tcg_gen_movi_tl(cpu_gpr[rd], 0);
2473 (void)opn; /* avoid a compiler warning */
2474 MIPS_DEBUG("%s %s, %s, %s", opn, regnames[rd], regnames[rs], regnames[rt]);
2477 /* Set on lower than */
2478 static void gen_slt(CPUMIPSState *env, DisasContext *ctx, uint32_t opc,
2479 int rd, int rs, int rt)
2481 const char *opn = "slt";
2485 /* If no destination, treat it as a NOP. */
2490 t0 = tcg_temp_new();
2491 t1 = tcg_temp_new();
2492 gen_load_gpr(t0, rs);
2493 gen_load_gpr(t1, rt);
2496 tcg_gen_setcond_tl(TCG_COND_LT, cpu_gpr[rd], t0, t1);
2500 tcg_gen_setcond_tl(TCG_COND_LTU, cpu_gpr[rd], t0, t1);
2504 (void)opn; /* avoid a compiler warning */
2505 MIPS_DEBUG("%s %s, %s, %s", opn, regnames[rd], regnames[rs], regnames[rt]);
2511 static void gen_shift (CPUMIPSState *env, DisasContext *ctx, uint32_t opc,
2512 int rd, int rs, int rt)
2514 const char *opn = "shifts";
2518 /* If no destination, treat it as a NOP.
2519 For add & sub, we must generate the overflow exception when needed. */
2524 t0 = tcg_temp_new();
2525 t1 = tcg_temp_new();
2526 gen_load_gpr(t0, rs);
2527 gen_load_gpr(t1, rt);
2530 tcg_gen_andi_tl(t0, t0, 0x1f);
2531 tcg_gen_shl_tl(t0, t1, t0);
2532 tcg_gen_ext32s_tl(cpu_gpr[rd], t0);
2536 tcg_gen_andi_tl(t0, t0, 0x1f);
2537 tcg_gen_sar_tl(cpu_gpr[rd], t1, t0);
2541 tcg_gen_ext32u_tl(t1, t1);
2542 tcg_gen_andi_tl(t0, t0, 0x1f);
2543 tcg_gen_shr_tl(t0, t1, t0);
2544 tcg_gen_ext32s_tl(cpu_gpr[rd], t0);
2549 TCGv_i32 t2 = tcg_temp_new_i32();
2550 TCGv_i32 t3 = tcg_temp_new_i32();
2552 tcg_gen_trunc_tl_i32(t2, t0);
2553 tcg_gen_trunc_tl_i32(t3, t1);
2554 tcg_gen_andi_i32(t2, t2, 0x1f);
2555 tcg_gen_rotr_i32(t2, t3, t2);
2556 tcg_gen_ext_i32_tl(cpu_gpr[rd], t2);
2557 tcg_temp_free_i32(t2);
2558 tcg_temp_free_i32(t3);
2562 #if defined(TARGET_MIPS64)
2564 tcg_gen_andi_tl(t0, t0, 0x3f);
2565 tcg_gen_shl_tl(cpu_gpr[rd], t1, t0);
2569 tcg_gen_andi_tl(t0, t0, 0x3f);
2570 tcg_gen_sar_tl(cpu_gpr[rd], t1, t0);
2574 tcg_gen_andi_tl(t0, t0, 0x3f);
2575 tcg_gen_shr_tl(cpu_gpr[rd], t1, t0);
2579 tcg_gen_andi_tl(t0, t0, 0x3f);
2580 tcg_gen_rotr_tl(cpu_gpr[rd], t1, t0);
2585 (void)opn; /* avoid a compiler warning */
2586 MIPS_DEBUG("%s %s, %s, %s", opn, regnames[rd], regnames[rs], regnames[rt]);
2591 /* Arithmetic on HI/LO registers */
2592 static void gen_HILO (DisasContext *ctx, uint32_t opc, int reg)
2594 const char *opn = "hilo";
2597 if (reg == 0 && (opc == OPC_MFHI || opc == OPC_MFLO)) {
2603 if (opc == OPC_MFHI || opc == OPC_MFLO) {
2604 acc = ((ctx->opcode) >> 21) & 0x03;
2606 acc = ((ctx->opcode) >> 11) & 0x03;
2615 #if defined(TARGET_MIPS64)
2617 tcg_gen_ext32s_tl(cpu_gpr[reg], cpu_HI[acc]);
2621 tcg_gen_mov_tl(cpu_gpr[reg], cpu_HI[acc]);
2626 #if defined(TARGET_MIPS64)
2628 tcg_gen_ext32s_tl(cpu_gpr[reg], cpu_LO[acc]);
2632 tcg_gen_mov_tl(cpu_gpr[reg], cpu_LO[acc]);
2638 #if defined(TARGET_MIPS64)
2640 tcg_gen_ext32s_tl(cpu_HI[acc], cpu_gpr[reg]);
2644 tcg_gen_mov_tl(cpu_HI[acc], cpu_gpr[reg]);
2647 tcg_gen_movi_tl(cpu_HI[acc], 0);
2653 #if defined(TARGET_MIPS64)
2655 tcg_gen_ext32s_tl(cpu_LO[acc], cpu_gpr[reg]);
2659 tcg_gen_mov_tl(cpu_LO[acc], cpu_gpr[reg]);
2662 tcg_gen_movi_tl(cpu_LO[acc], 0);
2667 (void)opn; /* avoid a compiler warning */
2668 MIPS_DEBUG("%s %s", opn, regnames[reg]);
2671 static void gen_muldiv (DisasContext *ctx, uint32_t opc,
2674 const char *opn = "mul/div";
2681 #if defined(TARGET_MIPS64)
2685 t0 = tcg_temp_local_new();
2686 t1 = tcg_temp_local_new();
2689 t0 = tcg_temp_new();
2690 t1 = tcg_temp_new();
2694 gen_load_gpr(t0, rs);
2695 gen_load_gpr(t1, rt);
2699 int l1 = gen_new_label();
2700 int l2 = gen_new_label();
2702 tcg_gen_ext32s_tl(t0, t0);
2703 tcg_gen_ext32s_tl(t1, t1);
2704 tcg_gen_brcondi_tl(TCG_COND_EQ, t1, 0, l1);
2705 tcg_gen_brcondi_tl(TCG_COND_NE, t0, INT_MIN, l2);
2706 tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1, l2);
2708 tcg_gen_mov_tl(cpu_LO[0], t0);
2709 tcg_gen_movi_tl(cpu_HI[0], 0);
2712 tcg_gen_div_tl(cpu_LO[0], t0, t1);
2713 tcg_gen_rem_tl(cpu_HI[0], t0, t1);
2714 tcg_gen_ext32s_tl(cpu_LO[0], cpu_LO[0]);
2715 tcg_gen_ext32s_tl(cpu_HI[0], cpu_HI[0]);
2722 int l1 = gen_new_label();
2724 tcg_gen_ext32u_tl(t0, t0);
2725 tcg_gen_ext32u_tl(t1, t1);
2726 tcg_gen_brcondi_tl(TCG_COND_EQ, t1, 0, l1);
2727 tcg_gen_divu_tl(cpu_LO[0], t0, t1);
2728 tcg_gen_remu_tl(cpu_HI[0], t0, t1);
2729 tcg_gen_ext32s_tl(cpu_LO[0], cpu_LO[0]);
2730 tcg_gen_ext32s_tl(cpu_HI[0], cpu_HI[0]);
2737 TCGv_i64 t2 = tcg_temp_new_i64();
2738 TCGv_i64 t3 = tcg_temp_new_i64();
2739 acc = ((ctx->opcode) >> 11) & 0x03;
2744 tcg_gen_ext_tl_i64(t2, t0);
2745 tcg_gen_ext_tl_i64(t3, t1);
2746 tcg_gen_mul_i64(t2, t2, t3);
2747 tcg_temp_free_i64(t3);
2748 tcg_gen_trunc_i64_tl(t0, t2);
2749 tcg_gen_shri_i64(t2, t2, 32);
2750 tcg_gen_trunc_i64_tl(t1, t2);
2751 tcg_temp_free_i64(t2);
2752 tcg_gen_ext32s_tl(cpu_LO[acc], t0);
2753 tcg_gen_ext32s_tl(cpu_HI[acc], t1);
2759 TCGv_i64 t2 = tcg_temp_new_i64();
2760 TCGv_i64 t3 = tcg_temp_new_i64();
2761 acc = ((ctx->opcode) >> 11) & 0x03;
2766 tcg_gen_ext32u_tl(t0, t0);
2767 tcg_gen_ext32u_tl(t1, t1);
2768 tcg_gen_extu_tl_i64(t2, t0);
2769 tcg_gen_extu_tl_i64(t3, t1);
2770 tcg_gen_mul_i64(t2, t2, t3);
2771 tcg_temp_free_i64(t3);
2772 tcg_gen_trunc_i64_tl(t0, t2);
2773 tcg_gen_shri_i64(t2, t2, 32);
2774 tcg_gen_trunc_i64_tl(t1, t2);
2775 tcg_temp_free_i64(t2);
2776 tcg_gen_ext32s_tl(cpu_LO[acc], t0);
2777 tcg_gen_ext32s_tl(cpu_HI[acc], t1);
2781 #if defined(TARGET_MIPS64)
2784 int l1 = gen_new_label();
2785 int l2 = gen_new_label();
2787 tcg_gen_brcondi_tl(TCG_COND_EQ, t1, 0, l1);
2788 tcg_gen_brcondi_tl(TCG_COND_NE, t0, -1LL << 63, l2);
2789 tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1LL, l2);
2790 tcg_gen_mov_tl(cpu_LO[0], t0);
2791 tcg_gen_movi_tl(cpu_HI[0], 0);
2794 tcg_gen_div_i64(cpu_LO[0], t0, t1);
2795 tcg_gen_rem_i64(cpu_HI[0], t0, t1);
2802 int l1 = gen_new_label();
2804 tcg_gen_brcondi_tl(TCG_COND_EQ, t1, 0, l1);
2805 tcg_gen_divu_i64(cpu_LO[0], t0, t1);
2806 tcg_gen_remu_i64(cpu_HI[0], t0, t1);
2812 gen_helper_dmult(cpu_env, t0, t1);
2816 gen_helper_dmultu(cpu_env, t0, t1);
2822 TCGv_i64 t2 = tcg_temp_new_i64();
2823 TCGv_i64 t3 = tcg_temp_new_i64();
2824 acc = ((ctx->opcode) >> 11) & 0x03;
2829 tcg_gen_ext_tl_i64(t2, t0);
2830 tcg_gen_ext_tl_i64(t3, t1);
2831 tcg_gen_mul_i64(t2, t2, t3);
2832 tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]);
2833 tcg_gen_add_i64(t2, t2, t3);
2834 tcg_temp_free_i64(t3);
2835 tcg_gen_trunc_i64_tl(t0, t2);
2836 tcg_gen_shri_i64(t2, t2, 32);
2837 tcg_gen_trunc_i64_tl(t1, t2);
2838 tcg_temp_free_i64(t2);
2839 tcg_gen_ext32s_tl(cpu_LO[acc], t0);
2840 tcg_gen_ext32s_tl(cpu_HI[acc], t1);
2846 TCGv_i64 t2 = tcg_temp_new_i64();
2847 TCGv_i64 t3 = tcg_temp_new_i64();
2848 acc = ((ctx->opcode) >> 11) & 0x03;
2853 tcg_gen_ext32u_tl(t0, t0);
2854 tcg_gen_ext32u_tl(t1, t1);
2855 tcg_gen_extu_tl_i64(t2, t0);
2856 tcg_gen_extu_tl_i64(t3, t1);
2857 tcg_gen_mul_i64(t2, t2, t3);
2858 tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]);
2859 tcg_gen_add_i64(t2, t2, t3);
2860 tcg_temp_free_i64(t3);
2861 tcg_gen_trunc_i64_tl(t0, t2);
2862 tcg_gen_shri_i64(t2, t2, 32);
2863 tcg_gen_trunc_i64_tl(t1, t2);
2864 tcg_temp_free_i64(t2);
2865 tcg_gen_ext32s_tl(cpu_LO[acc], t0);
2866 tcg_gen_ext32s_tl(cpu_HI[acc], t1);
2872 TCGv_i64 t2 = tcg_temp_new_i64();
2873 TCGv_i64 t3 = tcg_temp_new_i64();
2874 acc = ((ctx->opcode) >> 11) & 0x03;
2879 tcg_gen_ext_tl_i64(t2, t0);
2880 tcg_gen_ext_tl_i64(t3, t1);
2881 tcg_gen_mul_i64(t2, t2, t3);
2882 tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]);
2883 tcg_gen_sub_i64(t2, t3, t2);
2884 tcg_temp_free_i64(t3);
2885 tcg_gen_trunc_i64_tl(t0, t2);
2886 tcg_gen_shri_i64(t2, t2, 32);
2887 tcg_gen_trunc_i64_tl(t1, t2);
2888 tcg_temp_free_i64(t2);
2889 tcg_gen_ext32s_tl(cpu_LO[acc], t0);
2890 tcg_gen_ext32s_tl(cpu_HI[acc], t1);
2896 TCGv_i64 t2 = tcg_temp_new_i64();
2897 TCGv_i64 t3 = tcg_temp_new_i64();
2898 acc = ((ctx->opcode) >> 11) & 0x03;
2903 tcg_gen_ext32u_tl(t0, t0);
2904 tcg_gen_ext32u_tl(t1, t1);
2905 tcg_gen_extu_tl_i64(t2, t0);
2906 tcg_gen_extu_tl_i64(t3, t1);
2907 tcg_gen_mul_i64(t2, t2, t3);
2908 tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]);
2909 tcg_gen_sub_i64(t2, t3, t2);
2910 tcg_temp_free_i64(t3);
2911 tcg_gen_trunc_i64_tl(t0, t2);
2912 tcg_gen_shri_i64(t2, t2, 32);
2913 tcg_gen_trunc_i64_tl(t1, t2);
2914 tcg_temp_free_i64(t2);
2915 tcg_gen_ext32s_tl(cpu_LO[acc], t0);
2916 tcg_gen_ext32s_tl(cpu_HI[acc], t1);
2922 generate_exception(ctx, EXCP_RI);
2925 (void)opn; /* avoid a compiler warning */
2926 MIPS_DEBUG("%s %s %s", opn, regnames[rs], regnames[rt]);
2932 static void gen_mul_vr54xx (DisasContext *ctx, uint32_t opc,
2933 int rd, int rs, int rt)
2935 const char *opn = "mul vr54xx";
2936 TCGv t0 = tcg_temp_new();
2937 TCGv t1 = tcg_temp_new();
2939 gen_load_gpr(t0, rs);
2940 gen_load_gpr(t1, rt);
2943 case OPC_VR54XX_MULS:
2944 gen_helper_muls(t0, cpu_env, t0, t1);
2947 case OPC_VR54XX_MULSU:
2948 gen_helper_mulsu(t0, cpu_env, t0, t1);
2951 case OPC_VR54XX_MACC:
2952 gen_helper_macc(t0, cpu_env, t0, t1);
2955 case OPC_VR54XX_MACCU:
2956 gen_helper_maccu(t0, cpu_env, t0, t1);
2959 case OPC_VR54XX_MSAC:
2960 gen_helper_msac(t0, cpu_env, t0, t1);
2963 case OPC_VR54XX_MSACU:
2964 gen_helper_msacu(t0, cpu_env, t0, t1);
2967 case OPC_VR54XX_MULHI:
2968 gen_helper_mulhi(t0, cpu_env, t0, t1);
2971 case OPC_VR54XX_MULHIU:
2972 gen_helper_mulhiu(t0, cpu_env, t0, t1);
2975 case OPC_VR54XX_MULSHI:
2976 gen_helper_mulshi(t0, cpu_env, t0, t1);
2979 case OPC_VR54XX_MULSHIU:
2980 gen_helper_mulshiu(t0, cpu_env, t0, t1);
2983 case OPC_VR54XX_MACCHI:
2984 gen_helper_macchi(t0, cpu_env, t0, t1);
2987 case OPC_VR54XX_MACCHIU:
2988 gen_helper_macchiu(t0, cpu_env, t0, t1);
2991 case OPC_VR54XX_MSACHI:
2992 gen_helper_msachi(t0, cpu_env, t0, t1);
2995 case OPC_VR54XX_MSACHIU:
2996 gen_helper_msachiu(t0, cpu_env, t0, t1);
3000 MIPS_INVAL("mul vr54xx");
3001 generate_exception(ctx, EXCP_RI);
3004 gen_store_gpr(t0, rd);
3005 (void)opn; /* avoid a compiler warning */
3006 MIPS_DEBUG("%s %s, %s, %s", opn, regnames[rd], regnames[rs], regnames[rt]);
3013 static void gen_cl (DisasContext *ctx, uint32_t opc,
3016 const char *opn = "CLx";
3024 t0 = tcg_temp_new();
3025 gen_load_gpr(t0, rs);
3028 gen_helper_clo(cpu_gpr[rd], t0);
3032 gen_helper_clz(cpu_gpr[rd], t0);
3035 #if defined(TARGET_MIPS64)
3037 gen_helper_dclo(cpu_gpr[rd], t0);
3041 gen_helper_dclz(cpu_gpr[rd], t0);
3046 (void)opn; /* avoid a compiler warning */
3047 MIPS_DEBUG("%s %s, %s", opn, regnames[rd], regnames[rs]);
3051 /* Godson integer instructions */
3052 static void gen_loongson_integer(DisasContext *ctx, uint32_t opc,
3053 int rd, int rs, int rt)
3055 const char *opn = "loongson";
3067 case OPC_MULTU_G_2E:
3068 case OPC_MULTU_G_2F:
3069 #if defined(TARGET_MIPS64)
3070 case OPC_DMULT_G_2E:
3071 case OPC_DMULT_G_2F:
3072 case OPC_DMULTU_G_2E:
3073 case OPC_DMULTU_G_2F:
3075 t0 = tcg_temp_new();
3076 t1 = tcg_temp_new();
3079 t0 = tcg_temp_local_new();
3080 t1 = tcg_temp_local_new();
3084 gen_load_gpr(t0, rs);
3085 gen_load_gpr(t1, rt);
3090 tcg_gen_mul_tl(cpu_gpr[rd], t0, t1);
3091 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3094 case OPC_MULTU_G_2E:
3095 case OPC_MULTU_G_2F:
3096 tcg_gen_ext32u_tl(t0, t0);
3097 tcg_gen_ext32u_tl(t1, t1);
3098 tcg_gen_mul_tl(cpu_gpr[rd], t0, t1);
3099 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3105 int l1 = gen_new_label();
3106 int l2 = gen_new_label();
3107 int l3 = gen_new_label();
3108 tcg_gen_ext32s_tl(t0, t0);
3109 tcg_gen_ext32s_tl(t1, t1);
3110 tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
3111 tcg_gen_movi_tl(cpu_gpr[rd], 0);
3114 tcg_gen_brcondi_tl(TCG_COND_NE, t0, INT_MIN, l2);
3115 tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1, l2);
3116 tcg_gen_mov_tl(cpu_gpr[rd], t0);
3119 tcg_gen_div_tl(cpu_gpr[rd], t0, t1);
3120 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3128 int l1 = gen_new_label();
3129 int l2 = gen_new_label();
3130 tcg_gen_ext32u_tl(t0, t0);
3131 tcg_gen_ext32u_tl(t1, t1);
3132 tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
3133 tcg_gen_movi_tl(cpu_gpr[rd], 0);
3136 tcg_gen_divu_tl(cpu_gpr[rd], t0, t1);
3137 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3145 int l1 = gen_new_label();
3146 int l2 = gen_new_label();
3147 int l3 = gen_new_label();
3148 tcg_gen_ext32u_tl(t0, t0);
3149 tcg_gen_ext32u_tl(t1, t1);
3150 tcg_gen_brcondi_tl(TCG_COND_EQ, t1, 0, l1);
3151 tcg_gen_brcondi_tl(TCG_COND_NE, t0, INT_MIN, l2);
3152 tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1, l2);
3154 tcg_gen_movi_tl(cpu_gpr[rd], 0);
3157 tcg_gen_rem_tl(cpu_gpr[rd], t0, t1);
3158 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3166 int l1 = gen_new_label();
3167 int l2 = gen_new_label();
3168 tcg_gen_ext32u_tl(t0, t0);
3169 tcg_gen_ext32u_tl(t1, t1);
3170 tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
3171 tcg_gen_movi_tl(cpu_gpr[rd], 0);
3174 tcg_gen_remu_tl(cpu_gpr[rd], t0, t1);
3175 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3180 #if defined(TARGET_MIPS64)
3181 case OPC_DMULT_G_2E:
3182 case OPC_DMULT_G_2F:
3183 tcg_gen_mul_tl(cpu_gpr[rd], t0, t1);
3186 case OPC_DMULTU_G_2E:
3187 case OPC_DMULTU_G_2F:
3188 tcg_gen_mul_tl(cpu_gpr[rd], t0, t1);
3194 int l1 = gen_new_label();
3195 int l2 = gen_new_label();
3196 int l3 = gen_new_label();
3197 tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
3198 tcg_gen_movi_tl(cpu_gpr[rd], 0);
3201 tcg_gen_brcondi_tl(TCG_COND_NE, t0, -1LL << 63, l2);
3202 tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1LL, l2);
3203 tcg_gen_mov_tl(cpu_gpr[rd], t0);
3206 tcg_gen_div_tl(cpu_gpr[rd], t0, t1);
3211 case OPC_DDIVU_G_2E:
3212 case OPC_DDIVU_G_2F:
3214 int l1 = gen_new_label();
3215 int l2 = gen_new_label();
3216 tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
3217 tcg_gen_movi_tl(cpu_gpr[rd], 0);
3220 tcg_gen_divu_tl(cpu_gpr[rd], t0, t1);
3228 int l1 = gen_new_label();
3229 int l2 = gen_new_label();
3230 int l3 = gen_new_label();
3231 tcg_gen_brcondi_tl(TCG_COND_EQ, t1, 0, l1);
3232 tcg_gen_brcondi_tl(TCG_COND_NE, t0, -1LL << 63, l2);
3233 tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1LL, l2);
3235 tcg_gen_movi_tl(cpu_gpr[rd], 0);
3238 tcg_gen_rem_tl(cpu_gpr[rd], t0, t1);
3243 case OPC_DMODU_G_2E:
3244 case OPC_DMODU_G_2F:
3246 int l1 = gen_new_label();
3247 int l2 = gen_new_label();
3248 tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
3249 tcg_gen_movi_tl(cpu_gpr[rd], 0);
3252 tcg_gen_remu_tl(cpu_gpr[rd], t0, t1);
3260 (void)opn; /* avoid a compiler warning */
3261 MIPS_DEBUG("%s %s, %s", opn, regnames[rd], regnames[rs]);
3266 /* Loongson multimedia instructions */
3267 static void gen_loongson_multimedia(DisasContext *ctx, int rd, int rs, int rt)
3269 const char *opn = "loongson_cp2";
3270 uint32_t opc, shift_max;
3273 opc = MASK_LMI(ctx->opcode);
3279 t0 = tcg_temp_local_new_i64();
3280 t1 = tcg_temp_local_new_i64();
3283 t0 = tcg_temp_new_i64();
3284 t1 = tcg_temp_new_i64();
3288 gen_load_fpr64(ctx, t0, rs);
3289 gen_load_fpr64(ctx, t1, rt);
3291 #define LMI_HELPER(UP, LO) \
3292 case OPC_##UP: gen_helper_##LO(t0, t0, t1); opn = #LO; break
3293 #define LMI_HELPER_1(UP, LO) \
3294 case OPC_##UP: gen_helper_##LO(t0, t0); opn = #LO; break
3295 #define LMI_DIRECT(UP, LO, OP) \
3296 case OPC_##UP: tcg_gen_##OP##_i64(t0, t0, t1); opn = #LO; break
3299 LMI_HELPER(PADDSH, paddsh);
3300 LMI_HELPER(PADDUSH, paddush);
3301 LMI_HELPER(PADDH, paddh);
3302 LMI_HELPER(PADDW, paddw);
3303 LMI_HELPER(PADDSB, paddsb);
3304 LMI_HELPER(PADDUSB, paddusb);
3305 LMI_HELPER(PADDB, paddb);
3307 LMI_HELPER(PSUBSH, psubsh);
3308 LMI_HELPER(PSUBUSH, psubush);
3309 LMI_HELPER(PSUBH, psubh);
3310 LMI_HELPER(PSUBW, psubw);
3311 LMI_HELPER(PSUBSB, psubsb);
3312 LMI_HELPER(PSUBUSB, psubusb);
3313 LMI_HELPER(PSUBB, psubb);
3315 LMI_HELPER(PSHUFH, pshufh);
3316 LMI_HELPER(PACKSSWH, packsswh);
3317 LMI_HELPER(PACKSSHB, packsshb);
3318 LMI_HELPER(PACKUSHB, packushb);
3320 LMI_HELPER(PUNPCKLHW, punpcklhw);
3321 LMI_HELPER(PUNPCKHHW, punpckhhw);
3322 LMI_HELPER(PUNPCKLBH, punpcklbh);
3323 LMI_HELPER(PUNPCKHBH, punpckhbh);
3324 LMI_HELPER(PUNPCKLWD, punpcklwd);
3325 LMI_HELPER(PUNPCKHWD, punpckhwd);
3327 LMI_HELPER(PAVGH, pavgh);
3328 LMI_HELPER(PAVGB, pavgb);
3329 LMI_HELPER(PMAXSH, pmaxsh);
3330 LMI_HELPER(PMINSH, pminsh);
3331 LMI_HELPER(PMAXUB, pmaxub);
3332 LMI_HELPER(PMINUB, pminub);
3334 LMI_HELPER(PCMPEQW, pcmpeqw);
3335 LMI_HELPER(PCMPGTW, pcmpgtw);
3336 LMI_HELPER(PCMPEQH, pcmpeqh);
3337 LMI_HELPER(PCMPGTH, pcmpgth);
3338 LMI_HELPER(PCMPEQB, pcmpeqb);
3339 LMI_HELPER(PCMPGTB, pcmpgtb);
3341 LMI_HELPER(PSLLW, psllw);
3342 LMI_HELPER(PSLLH, psllh);
3343 LMI_HELPER(PSRLW, psrlw);
3344 LMI_HELPER(PSRLH, psrlh);
3345 LMI_HELPER(PSRAW, psraw);
3346 LMI_HELPER(PSRAH, psrah);
3348 LMI_HELPER(PMULLH, pmullh);
3349 LMI_HELPER(PMULHH, pmulhh);
3350 LMI_HELPER(PMULHUH, pmulhuh);
3351 LMI_HELPER(PMADDHW, pmaddhw);
3353 LMI_HELPER(PASUBUB, pasubub);
3354 LMI_HELPER_1(BIADD, biadd);
3355 LMI_HELPER_1(PMOVMSKB, pmovmskb);
3357 LMI_DIRECT(PADDD, paddd, add);
3358 LMI_DIRECT(PSUBD, psubd, sub);
3359 LMI_DIRECT(XOR_CP2, xor, xor);
3360 LMI_DIRECT(NOR_CP2, nor, nor);
3361 LMI_DIRECT(AND_CP2, and, and);
3362 LMI_DIRECT(PANDN, pandn, andc);
3363 LMI_DIRECT(OR, or, or);
3366 tcg_gen_deposit_i64(t0, t0, t1, 0, 16);
3370 tcg_gen_deposit_i64(t0, t0, t1, 16, 16);
3374 tcg_gen_deposit_i64(t0, t0, t1, 32, 16);
3378 tcg_gen_deposit_i64(t0, t0, t1, 48, 16);
3383 tcg_gen_andi_i64(t1, t1, 3);
3384 tcg_gen_shli_i64(t1, t1, 4);
3385 tcg_gen_shr_i64(t0, t0, t1);
3386 tcg_gen_ext16u_i64(t0, t0);
3391 tcg_gen_add_i64(t0, t0, t1);
3392 tcg_gen_ext32s_i64(t0, t0);
3396 tcg_gen_sub_i64(t0, t0, t1);
3397 tcg_gen_ext32s_i64(t0, t0);
3426 /* Make sure shift count isn't TCG undefined behaviour. */
3427 tcg_gen_andi_i64(t1, t1, shift_max - 1);
3432 tcg_gen_shl_i64(t0, t0, t1);
3436 /* Since SRA is UndefinedResult without sign-extended inputs,
3437 we can treat SRA and DSRA the same. */
3438 tcg_gen_sar_i64(t0, t0, t1);
3441 /* We want to shift in zeros for SRL; zero-extend first. */
3442 tcg_gen_ext32u_i64(t0, t0);
3445 tcg_gen_shr_i64(t0, t0, t1);
3449 if (shift_max == 32) {
3450 tcg_gen_ext32s_i64(t0, t0);
3453 /* Shifts larger than MAX produce zero. */
3454 tcg_gen_setcondi_i64(TCG_COND_LTU, t1, t1, shift_max);
3455 tcg_gen_neg_i64(t1, t1);
3456 tcg_gen_and_i64(t0, t0, t1);
3462 TCGv_i64 t2 = tcg_temp_new_i64();
3463 int lab = gen_new_label();
3465 tcg_gen_mov_i64(t2, t0);
3466 tcg_gen_add_i64(t0, t1, t2);
3467 if (opc == OPC_ADD_CP2) {
3468 tcg_gen_ext32s_i64(t0, t0);
3470 tcg_gen_xor_i64(t1, t1, t2);
3471 tcg_gen_xor_i64(t2, t2, t0);
3472 tcg_gen_andc_i64(t1, t2, t1);
3473 tcg_temp_free_i64(t2);
3474 tcg_gen_brcondi_i64(TCG_COND_GE, t1, 0, lab);
3475 generate_exception(ctx, EXCP_OVERFLOW);
3478 opn = (opc == OPC_ADD_CP2 ? "add" : "dadd");
3485 TCGv_i64 t2 = tcg_temp_new_i64();
3486 int lab = gen_new_label();
3488 tcg_gen_mov_i64(t2, t0);
3489 tcg_gen_sub_i64(t0, t1, t2);
3490 if (opc == OPC_SUB_CP2) {
3491 tcg_gen_ext32s_i64(t0, t0);
3493 tcg_gen_xor_i64(t1, t1, t2);
3494 tcg_gen_xor_i64(t2, t2, t0);
3495 tcg_gen_and_i64(t1, t1, t2);
3496 tcg_temp_free_i64(t2);
3497 tcg_gen_brcondi_i64(TCG_COND_GE, t1, 0, lab);
3498 generate_exception(ctx, EXCP_OVERFLOW);
3501 opn = (opc == OPC_SUB_CP2 ? "sub" : "dsub");
3506 tcg_gen_ext32u_i64(t0, t0);
3507 tcg_gen_ext32u_i64(t1, t1);
3508 tcg_gen_mul_i64(t0, t0, t1);
3518 /* ??? Document is unclear: Set FCC[CC]. Does that mean the
3519 FD field is the CC field? */
3522 generate_exception(ctx, EXCP_RI);
3529 gen_store_fpr64(ctx, t0, rd);
3531 (void)opn; /* avoid a compiler warning */
3532 MIPS_DEBUG("%s %s, %s, %s", opn,
3533 fregnames[rd], fregnames[rs], fregnames[rt]);
3534 tcg_temp_free_i64(t0);
3535 tcg_temp_free_i64(t1);
3539 static void gen_trap (DisasContext *ctx, uint32_t opc,
3540 int rs, int rt, int16_t imm)
3543 TCGv t0 = tcg_temp_new();
3544 TCGv t1 = tcg_temp_new();
3547 /* Load needed operands */
3555 /* Compare two registers */
3557 gen_load_gpr(t0, rs);
3558 gen_load_gpr(t1, rt);
3568 /* Compare register to immediate */
3569 if (rs != 0 || imm != 0) {
3570 gen_load_gpr(t0, rs);
3571 tcg_gen_movi_tl(t1, (int32_t)imm);
3578 case OPC_TEQ: /* rs == rs */
3579 case OPC_TEQI: /* r0 == 0 */
3580 case OPC_TGE: /* rs >= rs */
3581 case OPC_TGEI: /* r0 >= 0 */
3582 case OPC_TGEU: /* rs >= rs unsigned */
3583 case OPC_TGEIU: /* r0 >= 0 unsigned */
3585 generate_exception(ctx, EXCP_TRAP);
3587 case OPC_TLT: /* rs < rs */
3588 case OPC_TLTI: /* r0 < 0 */
3589 case OPC_TLTU: /* rs < rs unsigned */
3590 case OPC_TLTIU: /* r0 < 0 unsigned */
3591 case OPC_TNE: /* rs != rs */
3592 case OPC_TNEI: /* r0 != 0 */
3593 /* Never trap: treat as NOP. */
3597 int l1 = gen_new_label();
3602 tcg_gen_brcond_tl(TCG_COND_NE, t0, t1, l1);
3606 tcg_gen_brcond_tl(TCG_COND_LT, t0, t1, l1);
3610 tcg_gen_brcond_tl(TCG_COND_LTU, t0, t1, l1);
3614 tcg_gen_brcond_tl(TCG_COND_GE, t0, t1, l1);
3618 tcg_gen_brcond_tl(TCG_COND_GEU, t0, t1, l1);
3622 tcg_gen_brcond_tl(TCG_COND_EQ, t0, t1, l1);
3625 generate_exception(ctx, EXCP_TRAP);
3632 static inline void gen_goto_tb(DisasContext *ctx, int n, target_ulong dest)
3634 TranslationBlock *tb;
3636 if ((tb->pc & TARGET_PAGE_MASK) == (dest & TARGET_PAGE_MASK) &&
3637 likely(!ctx->singlestep_enabled)) {
3640 tcg_gen_exit_tb((tcg_target_long)tb + n);
3643 if (ctx->singlestep_enabled) {
3644 save_cpu_state(ctx, 0);
3645 gen_helper_0e0i(raise_exception, EXCP_DEBUG);
3651 /* Branches (before delay slot) */
3652 static void gen_compute_branch (DisasContext *ctx, uint32_t opc,
3654 int rs, int rt, int32_t offset)
3656 target_ulong btgt = -1;
3658 int bcond_compute = 0;
3659 TCGv t0 = tcg_temp_new();
3660 TCGv t1 = tcg_temp_new();
3662 if (ctx->hflags & MIPS_HFLAG_BMASK) {
3663 #ifdef MIPS_DEBUG_DISAS
3664 LOG_DISAS("Branch in delay slot at PC 0x" TARGET_FMT_lx "\n", ctx->pc);
3666 generate_exception(ctx, EXCP_RI);
3670 /* Load needed operands */
3676 /* Compare two registers */
3678 gen_load_gpr(t0, rs);
3679 gen_load_gpr(t1, rt);
3682 btgt = ctx->pc + insn_bytes + offset;
3698 /* Compare to zero */
3700 gen_load_gpr(t0, rs);
3703 btgt = ctx->pc + insn_bytes + offset;
3706 #if defined(TARGET_MIPS64)
3708 tcg_gen_andi_tl(t0, cpu_dspctrl, 0x7F);
3710 tcg_gen_andi_tl(t0, cpu_dspctrl, 0x3F);
3713 btgt = ctx->pc + insn_bytes + offset;
3720 /* Jump to immediate */
3721 btgt = ((ctx->pc + insn_bytes) & (int32_t)0xF0000000) | (uint32_t)offset;
3727 /* Jump to register */
3728 if (offset != 0 && offset != 16) {
3729 /* Hint = 0 is JR/JALR, hint 16 is JR.HB/JALR.HB, the
3730 others are reserved. */
3731 MIPS_INVAL("jump hint");
3732 generate_exception(ctx, EXCP_RI);
3735 gen_load_gpr(btarget, rs);
3738 MIPS_INVAL("branch/jump");
3739 generate_exception(ctx, EXCP_RI);
3742 if (bcond_compute == 0) {
3743 /* No condition to be computed */
3745 case OPC_BEQ: /* rx == rx */
3746 case OPC_BEQL: /* rx == rx likely */
3747 case OPC_BGEZ: /* 0 >= 0 */
3748 case OPC_BGEZL: /* 0 >= 0 likely */
3749 case OPC_BLEZ: /* 0 <= 0 */
3750 case OPC_BLEZL: /* 0 <= 0 likely */
3752 ctx->hflags |= MIPS_HFLAG_B;
3753 MIPS_DEBUG("balways");
3756 case OPC_BGEZAL: /* 0 >= 0 */
3757 case OPC_BGEZALL: /* 0 >= 0 likely */
3758 ctx->hflags |= (opc == OPC_BGEZALS
3760 : MIPS_HFLAG_BDS32);
3761 /* Always take and link */
3763 ctx->hflags |= MIPS_HFLAG_B;
3764 MIPS_DEBUG("balways and link");
3766 case OPC_BNE: /* rx != rx */
3767 case OPC_BGTZ: /* 0 > 0 */
3768 case OPC_BLTZ: /* 0 < 0 */
3770 MIPS_DEBUG("bnever (NOP)");
3773 case OPC_BLTZAL: /* 0 < 0 */
3774 ctx->hflags |= (opc == OPC_BLTZALS
3776 : MIPS_HFLAG_BDS32);
3777 /* Handle as an unconditional branch to get correct delay
3780 btgt = ctx->pc + (opc == OPC_BLTZALS ? 6 : 8);
3781 ctx->hflags |= MIPS_HFLAG_B;
3782 MIPS_DEBUG("bnever and link");
3784 case OPC_BLTZALL: /* 0 < 0 likely */
3785 tcg_gen_movi_tl(cpu_gpr[31], ctx->pc + 8);
3786 /* Skip the instruction in the delay slot */
3787 MIPS_DEBUG("bnever, link and skip");
3790 case OPC_BNEL: /* rx != rx likely */
3791 case OPC_BGTZL: /* 0 > 0 likely */
3792 case OPC_BLTZL: /* 0 < 0 likely */
3793 /* Skip the instruction in the delay slot */
3794 MIPS_DEBUG("bnever and skip");
3798 ctx->hflags |= MIPS_HFLAG_B;
3799 MIPS_DEBUG("j " TARGET_FMT_lx, btgt);
3803 ctx->hflags |= MIPS_HFLAG_BX;
3808 ctx->hflags |= MIPS_HFLAG_B;
3809 ctx->hflags |= ((opc == OPC_JALS || opc == OPC_JALXS)
3811 : MIPS_HFLAG_BDS32);
3812 MIPS_DEBUG("jal " TARGET_FMT_lx, btgt);
3815 ctx->hflags |= MIPS_HFLAG_BR;
3816 if (insn_bytes == 4)
3817 ctx->hflags |= MIPS_HFLAG_BDS32;
3818 MIPS_DEBUG("jr %s", regnames[rs]);
3824 ctx->hflags |= MIPS_HFLAG_BR;
3825 ctx->hflags |= (opc == OPC_JALRS
3827 : MIPS_HFLAG_BDS32);
3828 MIPS_DEBUG("jalr %s, %s", regnames[rt], regnames[rs]);
3831 MIPS_INVAL("branch/jump");
3832 generate_exception(ctx, EXCP_RI);
3838 tcg_gen_setcond_tl(TCG_COND_EQ, bcond, t0, t1);
3839 MIPS_DEBUG("beq %s, %s, " TARGET_FMT_lx,
3840 regnames[rs], regnames[rt], btgt);
3843 tcg_gen_setcond_tl(TCG_COND_EQ, bcond, t0, t1);
3844 MIPS_DEBUG("beql %s, %s, " TARGET_FMT_lx,
3845 regnames[rs], regnames[rt], btgt);
3848 tcg_gen_setcond_tl(TCG_COND_NE, bcond, t0, t1);
3849 MIPS_DEBUG("bne %s, %s, " TARGET_FMT_lx,
3850 regnames[rs], regnames[rt], btgt);
3853 tcg_gen_setcond_tl(TCG_COND_NE, bcond, t0, t1);
3854 MIPS_DEBUG("bnel %s, %s, " TARGET_FMT_lx,
3855 regnames[rs], regnames[rt], btgt);
3858 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 0);
3859 MIPS_DEBUG("bgez %s, " TARGET_FMT_lx, regnames[rs], btgt);
3862 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 0);
3863 MIPS_DEBUG("bgezl %s, " TARGET_FMT_lx, regnames[rs], btgt);
3867 ctx->hflags |= (opc == OPC_BGEZALS
3869 : MIPS_HFLAG_BDS32);
3870 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 0);
3871 MIPS_DEBUG("bgezal %s, " TARGET_FMT_lx, regnames[rs], btgt);
3875 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 0);
3877 MIPS_DEBUG("bgezall %s, " TARGET_FMT_lx, regnames[rs], btgt);
3880 tcg_gen_setcondi_tl(TCG_COND_GT, bcond, t0, 0);
3881 MIPS_DEBUG("bgtz %s, " TARGET_FMT_lx, regnames[rs], btgt);
3884 tcg_gen_setcondi_tl(TCG_COND_GT, bcond, t0, 0);
3885 MIPS_DEBUG("bgtzl %s, " TARGET_FMT_lx, regnames[rs], btgt);
3888 tcg_gen_setcondi_tl(TCG_COND_LE, bcond, t0, 0);
3889 MIPS_DEBUG("blez %s, " TARGET_FMT_lx, regnames[rs], btgt);
3892 tcg_gen_setcondi_tl(TCG_COND_LE, bcond, t0, 0);
3893 MIPS_DEBUG("blezl %s, " TARGET_FMT_lx, regnames[rs], btgt);
3896 tcg_gen_setcondi_tl(TCG_COND_LT, bcond, t0, 0);
3897 MIPS_DEBUG("bltz %s, " TARGET_FMT_lx, regnames[rs], btgt);
3900 tcg_gen_setcondi_tl(TCG_COND_LT, bcond, t0, 0);
3901 MIPS_DEBUG("bltzl %s, " TARGET_FMT_lx, regnames[rs], btgt);
3904 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 32);
3905 MIPS_DEBUG("bposge32 " TARGET_FMT_lx, btgt);
3907 #if defined(TARGET_MIPS64)
3909 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 64);
3910 MIPS_DEBUG("bposge64 " TARGET_FMT_lx, btgt);
3915 ctx->hflags |= (opc == OPC_BLTZALS
3917 : MIPS_HFLAG_BDS32);
3918 tcg_gen_setcondi_tl(TCG_COND_LT, bcond, t0, 0);
3920 MIPS_DEBUG("bltzal %s, " TARGET_FMT_lx, regnames[rs], btgt);
3922 ctx->hflags |= MIPS_HFLAG_BC;
3925 tcg_gen_setcondi_tl(TCG_COND_LT, bcond, t0, 0);
3927 MIPS_DEBUG("bltzall %s, " TARGET_FMT_lx, regnames[rs], btgt);
3929 ctx->hflags |= MIPS_HFLAG_BL;
3932 MIPS_INVAL("conditional branch/jump");
3933 generate_exception(ctx, EXCP_RI);
3937 MIPS_DEBUG("enter ds: link %d cond %02x target " TARGET_FMT_lx,
3938 blink, ctx->hflags, btgt);
3940 ctx->btarget = btgt;
3942 int post_delay = insn_bytes;
3943 int lowbit = !!(ctx->hflags & MIPS_HFLAG_M16);
3945 if (opc != OPC_JALRC)
3946 post_delay += ((ctx->hflags & MIPS_HFLAG_BDS16) ? 2 : 4);
3948 tcg_gen_movi_tl(cpu_gpr[blink], ctx->pc + post_delay + lowbit);
3952 if (insn_bytes == 2)
3953 ctx->hflags |= MIPS_HFLAG_B16;
3958 /* special3 bitfield operations */
3959 static void gen_bitops (DisasContext *ctx, uint32_t opc, int rt,
3960 int rs, int lsb, int msb)
3962 TCGv t0 = tcg_temp_new();
3963 TCGv t1 = tcg_temp_new();
3966 gen_load_gpr(t1, rs);
3971 tcg_gen_shri_tl(t0, t1, lsb);
3973 tcg_gen_andi_tl(t0, t0, (1 << (msb + 1)) - 1);
3975 tcg_gen_ext32s_tl(t0, t0);
3978 #if defined(TARGET_MIPS64)
3980 tcg_gen_shri_tl(t0, t1, lsb);
3982 tcg_gen_andi_tl(t0, t0, (1ULL << (msb + 1 + 32)) - 1);
3986 tcg_gen_shri_tl(t0, t1, lsb + 32);
3987 tcg_gen_andi_tl(t0, t0, (1ULL << (msb + 1)) - 1);
3990 tcg_gen_shri_tl(t0, t1, lsb);
3991 tcg_gen_andi_tl(t0, t0, (1ULL << (msb + 1)) - 1);
3997 mask = ((msb - lsb + 1 < 32) ? ((1 << (msb - lsb + 1)) - 1) : ~0) << lsb;
3998 gen_load_gpr(t0, rt);
3999 tcg_gen_andi_tl(t0, t0, ~mask);
4000 tcg_gen_shli_tl(t1, t1, lsb);
4001 tcg_gen_andi_tl(t1, t1, mask);
4002 tcg_gen_or_tl(t0, t0, t1);
4003 tcg_gen_ext32s_tl(t0, t0);
4005 #if defined(TARGET_MIPS64)
4009 mask = ((msb - lsb + 1 + 32 < 64) ? ((1ULL << (msb - lsb + 1 + 32)) - 1) : ~0ULL) << lsb;
4010 gen_load_gpr(t0, rt);
4011 tcg_gen_andi_tl(t0, t0, ~mask);
4012 tcg_gen_shli_tl(t1, t1, lsb);
4013 tcg_gen_andi_tl(t1, t1, mask);
4014 tcg_gen_or_tl(t0, t0, t1);
4019 mask = ((1ULL << (msb - lsb + 1)) - 1) << (lsb + 32);
4020 gen_load_gpr(t0, rt);
4021 tcg_gen_andi_tl(t0, t0, ~mask);
4022 tcg_gen_shli_tl(t1, t1, lsb + 32);
4023 tcg_gen_andi_tl(t1, t1, mask);
4024 tcg_gen_or_tl(t0, t0, t1);
4029 gen_load_gpr(t0, rt);
4030 mask = ((1ULL << (msb - lsb + 1)) - 1) << lsb;
4031 gen_load_gpr(t0, rt);
4032 tcg_gen_andi_tl(t0, t0, ~mask);
4033 tcg_gen_shli_tl(t1, t1, lsb);
4034 tcg_gen_andi_tl(t1, t1, mask);
4035 tcg_gen_or_tl(t0, t0, t1);
4040 MIPS_INVAL("bitops");
4041 generate_exception(ctx, EXCP_RI);
4046 gen_store_gpr(t0, rt);
4051 static void gen_bshfl (DisasContext *ctx, uint32_t op2, int rt, int rd)
4056 /* If no destination, treat it as a NOP. */
4061 t0 = tcg_temp_new();
4062 gen_load_gpr(t0, rt);
4066 TCGv t1 = tcg_temp_new();
4068 tcg_gen_shri_tl(t1, t0, 8);
4069 tcg_gen_andi_tl(t1, t1, 0x00FF00FF);
4070 tcg_gen_shli_tl(t0, t0, 8);
4071 tcg_gen_andi_tl(t0, t0, ~0x00FF00FF);
4072 tcg_gen_or_tl(t0, t0, t1);
4074 tcg_gen_ext32s_tl(cpu_gpr[rd], t0);
4078 tcg_gen_ext8s_tl(cpu_gpr[rd], t0);
4081 tcg_gen_ext16s_tl(cpu_gpr[rd], t0);
4083 #if defined(TARGET_MIPS64)
4086 TCGv t1 = tcg_temp_new();
4088 tcg_gen_shri_tl(t1, t0, 8);
4089 tcg_gen_andi_tl(t1, t1, 0x00FF00FF00FF00FFULL);
4090 tcg_gen_shli_tl(t0, t0, 8);
4091 tcg_gen_andi_tl(t0, t0, ~0x00FF00FF00FF00FFULL);
4092 tcg_gen_or_tl(cpu_gpr[rd], t0, t1);
4098 TCGv t1 = tcg_temp_new();
4100 tcg_gen_shri_tl(t1, t0, 16);
4101 tcg_gen_andi_tl(t1, t1, 0x0000FFFF0000FFFFULL);
4102 tcg_gen_shli_tl(t0, t0, 16);
4103 tcg_gen_andi_tl(t0, t0, ~0x0000FFFF0000FFFFULL);
4104 tcg_gen_or_tl(t0, t0, t1);
4105 tcg_gen_shri_tl(t1, t0, 32);
4106 tcg_gen_shli_tl(t0, t0, 32);
4107 tcg_gen_or_tl(cpu_gpr[rd], t0, t1);
4113 MIPS_INVAL("bsfhl");
4114 generate_exception(ctx, EXCP_RI);
4121 #ifndef CONFIG_USER_ONLY
4122 /* CP0 (MMU and control) */
4123 static inline void gen_mfc0_load32 (TCGv arg, target_ulong off)
4125 TCGv_i32 t0 = tcg_temp_new_i32();
4127 tcg_gen_ld_i32(t0, cpu_env, off);
4128 tcg_gen_ext_i32_tl(arg, t0);
4129 tcg_temp_free_i32(t0);
4132 static inline void gen_mfc0_load64 (TCGv arg, target_ulong off)
4134 tcg_gen_ld_tl(arg, cpu_env, off);
4135 tcg_gen_ext32s_tl(arg, arg);
4138 static inline void gen_mtc0_store32 (TCGv arg, target_ulong off)
4140 TCGv_i32 t0 = tcg_temp_new_i32();
4142 tcg_gen_trunc_tl_i32(t0, arg);
4143 tcg_gen_st_i32(t0, cpu_env, off);
4144 tcg_temp_free_i32(t0);
4147 static inline void gen_mtc0_store64 (TCGv arg, target_ulong off)
4149 tcg_gen_ext32s_tl(arg, arg);
4150 tcg_gen_st_tl(arg, cpu_env, off);
4153 static void gen_mfc0 (CPUMIPSState *env, DisasContext *ctx, TCGv arg, int reg, int sel)
4155 const char *rn = "invalid";
4158 check_insn(env, ctx, ISA_MIPS32);
4164 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Index));
4168 check_insn(env, ctx, ASE_MT);
4169 gen_helper_mfc0_mvpcontrol(arg, cpu_env);
4173 check_insn(env, ctx, ASE_MT);
4174 gen_helper_mfc0_mvpconf0(arg, cpu_env);
4178 check_insn(env, ctx, ASE_MT);
4179 gen_helper_mfc0_mvpconf1(arg, cpu_env);
4189 gen_helper_mfc0_random(arg, cpu_env);
4193 check_insn(env, ctx, ASE_MT);
4194 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEControl));
4198 check_insn(env, ctx, ASE_MT);
4199 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEConf0));
4203 check_insn(env, ctx, ASE_MT);
4204 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEConf1));
4208 check_insn(env, ctx, ASE_MT);
4209 gen_mfc0_load64(arg, offsetof(CPUMIPSState, CP0_YQMask));
4213 check_insn(env, ctx, ASE_MT);
4214 gen_mfc0_load64(arg, offsetof(CPUMIPSState, CP0_VPESchedule));
4218 check_insn(env, ctx, ASE_MT);
4219 gen_mfc0_load64(arg, offsetof(CPUMIPSState, CP0_VPEScheFBack));
4220 rn = "VPEScheFBack";
4223 check_insn(env, ctx, ASE_MT);
4224 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEOpt));
4234 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EntryLo0));
4235 tcg_gen_ext32s_tl(arg, arg);
4239 check_insn(env, ctx, ASE_MT);
4240 gen_helper_mfc0_tcstatus(arg, cpu_env);
4244 check_insn(env, ctx, ASE_MT);
4245 gen_helper_mfc0_tcbind(arg, cpu_env);
4249 check_insn(env, ctx, ASE_MT);
4250 gen_helper_mfc0_tcrestart(arg, cpu_env);
4254 check_insn(env, ctx, ASE_MT);
4255 gen_helper_mfc0_tchalt(arg, cpu_env);
4259 check_insn(env, ctx, ASE_MT);
4260 gen_helper_mfc0_tccontext(arg, cpu_env);
4264 check_insn(env, ctx, ASE_MT);
4265 gen_helper_mfc0_tcschedule(arg, cpu_env);
4269 check_insn(env, ctx, ASE_MT);
4270 gen_helper_mfc0_tcschefback(arg, cpu_env);
4280 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EntryLo1));
4281 tcg_gen_ext32s_tl(arg, arg);
4291 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_Context));
4292 tcg_gen_ext32s_tl(arg, arg);
4296 // gen_helper_mfc0_contextconfig(arg); /* SmartMIPS ASE */
4297 rn = "ContextConfig";
4306 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PageMask));
4310 check_insn(env, ctx, ISA_MIPS32R2);
4311 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PageGrain));
4321 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Wired));
4325 check_insn(env, ctx, ISA_MIPS32R2);
4326 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf0));
4330 check_insn(env, ctx, ISA_MIPS32R2);
4331 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf1));
4335 check_insn(env, ctx, ISA_MIPS32R2);
4336 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf2));
4340 check_insn(env, ctx, ISA_MIPS32R2);
4341 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf3));
4345 check_insn(env, ctx, ISA_MIPS32R2);
4346 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf4));
4356 check_insn(env, ctx, ISA_MIPS32R2);
4357 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_HWREna));
4367 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_BadVAddr));
4368 tcg_gen_ext32s_tl(arg, arg);
4378 /* Mark as an IO operation because we read the time. */
4381 gen_helper_mfc0_count(arg, cpu_env);
4385 /* Break the TB to be able to take timer interrupts immediately
4386 after reading count. */
4387 ctx->bstate = BS_STOP;
4390 /* 6,7 are implementation dependent */
4398 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EntryHi));
4399 tcg_gen_ext32s_tl(arg, arg);
4409 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Compare));
4412 /* 6,7 are implementation dependent */
4420 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Status));
4424 check_insn(env, ctx, ISA_MIPS32R2);
4425 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_IntCtl));
4429 check_insn(env, ctx, ISA_MIPS32R2);
4430 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSCtl));
4434 check_insn(env, ctx, ISA_MIPS32R2);
4435 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSMap));
4445 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Cause));
4455 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EPC));
4456 tcg_gen_ext32s_tl(arg, arg);
4466 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PRid));
4470 check_insn(env, ctx, ISA_MIPS32R2);
4471 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_EBase));
4481 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config0));
4485 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config1));
4489 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config2));
4493 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config3));
4496 /* 4,5 are reserved */
4497 /* 6,7 are implementation dependent */
4499 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config6));
4503 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config7));
4513 gen_helper_mfc0_lladdr(arg, cpu_env);
4523 gen_helper_1e0i(mfc0_watchlo, arg, sel);
4533 gen_helper_1e0i(mfc0_watchhi, arg, sel);
4543 #if defined(TARGET_MIPS64)
4544 check_insn(env, ctx, ISA_MIPS3);
4545 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_XContext));
4546 tcg_gen_ext32s_tl(arg, arg);
4555 /* Officially reserved, but sel 0 is used for R1x000 framemask */
4558 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Framemask));
4566 tcg_gen_movi_tl(arg, 0); /* unimplemented */
4567 rn = "'Diagnostic"; /* implementation dependent */
4572 gen_helper_mfc0_debug(arg, cpu_env); /* EJTAG support */
4576 // gen_helper_mfc0_tracecontrol(arg); /* PDtrace support */
4577 rn = "TraceControl";
4580 // gen_helper_mfc0_tracecontrol2(arg); /* PDtrace support */
4581 rn = "TraceControl2";
4584 // gen_helper_mfc0_usertracedata(arg); /* PDtrace support */
4585 rn = "UserTraceData";
4588 // gen_helper_mfc0_tracebpc(arg); /* PDtrace support */
4599 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_DEPC));
4600 tcg_gen_ext32s_tl(arg, arg);
4610 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Performance0));
4611 rn = "Performance0";
4614 // gen_helper_mfc0_performance1(arg);
4615 rn = "Performance1";
4618 // gen_helper_mfc0_performance2(arg);
4619 rn = "Performance2";
4622 // gen_helper_mfc0_performance3(arg);
4623 rn = "Performance3";
4626 // gen_helper_mfc0_performance4(arg);
4627 rn = "Performance4";
4630 // gen_helper_mfc0_performance5(arg);
4631 rn = "Performance5";
4634 // gen_helper_mfc0_performance6(arg);
4635 rn = "Performance6";
4638 // gen_helper_mfc0_performance7(arg);
4639 rn = "Performance7";
4646 tcg_gen_movi_tl(arg, 0); /* unimplemented */
4652 tcg_gen_movi_tl(arg, 0); /* unimplemented */
4665 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_TagLo));
4672 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DataLo));
4685 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_TagHi));
4692 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DataHi));
4702 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_ErrorEPC));
4703 tcg_gen_ext32s_tl(arg, arg);
4714 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DESAVE));
4724 (void)rn; /* avoid a compiler warning */
4725 LOG_DISAS("mfc0 %s (reg %d sel %d)\n", rn, reg, sel);
4729 LOG_DISAS("mfc0 %s (reg %d sel %d)\n", rn, reg, sel);
4730 generate_exception(ctx, EXCP_RI);
4733 static void gen_mtc0 (CPUMIPSState *env, DisasContext *ctx, TCGv arg, int reg, int sel)
4735 const char *rn = "invalid";
4738 check_insn(env, ctx, ISA_MIPS32);
4747 gen_helper_mtc0_index(cpu_env, arg);
4751 check_insn(env, ctx, ASE_MT);
4752 gen_helper_mtc0_mvpcontrol(cpu_env, arg);
4756 check_insn(env, ctx, ASE_MT);
4761 check_insn(env, ctx, ASE_MT);
4776 check_insn(env, ctx, ASE_MT);
4777 gen_helper_mtc0_vpecontrol(cpu_env, arg);
4781 check_insn(env, ctx, ASE_MT);
4782 gen_helper_mtc0_vpeconf0(cpu_env, arg);
4786 check_insn(env, ctx, ASE_MT);
4787 gen_helper_mtc0_vpeconf1(cpu_env, arg);
4791 check_insn(env, ctx, ASE_MT);
4792 gen_helper_mtc0_yqmask(cpu_env, arg);
4796 check_insn(env, ctx, ASE_MT);
4797 gen_mtc0_store64(arg, offsetof(CPUMIPSState, CP0_VPESchedule));
4801 check_insn(env, ctx, ASE_MT);
4802 gen_mtc0_store64(arg, offsetof(CPUMIPSState, CP0_VPEScheFBack));
4803 rn = "VPEScheFBack";
4806 check_insn(env, ctx, ASE_MT);
4807 gen_helper_mtc0_vpeopt(cpu_env, arg);
4817 gen_helper_mtc0_entrylo0(cpu_env, arg);
4821 check_insn(env, ctx, ASE_MT);
4822 gen_helper_mtc0_tcstatus(cpu_env, arg);
4826 check_insn(env, ctx, ASE_MT);
4827 gen_helper_mtc0_tcbind(cpu_env, arg);
4831 check_insn(env, ctx, ASE_MT);
4832 gen_helper_mtc0_tcrestart(cpu_env, arg);
4836 check_insn(env, ctx, ASE_MT);
4837 gen_helper_mtc0_tchalt(cpu_env, arg);
4841 check_insn(env, ctx, ASE_MT);
4842 gen_helper_mtc0_tccontext(cpu_env, arg);
4846 check_insn(env, ctx, ASE_MT);
4847 gen_helper_mtc0_tcschedule(cpu_env, arg);
4851 check_insn(env, ctx, ASE_MT);
4852 gen_helper_mtc0_tcschefback(cpu_env, arg);
4862 gen_helper_mtc0_entrylo1(cpu_env, arg);
4872 gen_helper_mtc0_context(cpu_env, arg);
4876 // gen_helper_mtc0_contextconfig(cpu_env, arg); /* SmartMIPS ASE */
4877 rn = "ContextConfig";
4886 gen_helper_mtc0_pagemask(cpu_env, arg);
4890 check_insn(env, ctx, ISA_MIPS32R2);
4891 gen_helper_mtc0_pagegrain(cpu_env, arg);
4901 gen_helper_mtc0_wired(cpu_env, arg);
4905 check_insn(env, ctx, ISA_MIPS32R2);
4906 gen_helper_mtc0_srsconf0(cpu_env, arg);
4910 check_insn(env, ctx, ISA_MIPS32R2);
4911 gen_helper_mtc0_srsconf1(cpu_env, arg);
4915 check_insn(env, ctx, ISA_MIPS32R2);
4916 gen_helper_mtc0_srsconf2(cpu_env, arg);
4920 check_insn(env, ctx, ISA_MIPS32R2);
4921 gen_helper_mtc0_srsconf3(cpu_env, arg);
4925 check_insn(env, ctx, ISA_MIPS32R2);
4926 gen_helper_mtc0_srsconf4(cpu_env, arg);
4936 check_insn(env, ctx, ISA_MIPS32R2);
4937 gen_helper_mtc0_hwrena(cpu_env, arg);
4951 gen_helper_mtc0_count(cpu_env, arg);
4954 /* 6,7 are implementation dependent */
4962 gen_helper_mtc0_entryhi(cpu_env, arg);
4972 gen_helper_mtc0_compare(cpu_env, arg);
4975 /* 6,7 are implementation dependent */
4983 save_cpu_state(ctx, 1);
4984 gen_helper_mtc0_status(cpu_env, arg);
4985 /* BS_STOP isn't good enough here, hflags may have changed. */
4986 gen_save_pc(ctx->pc + 4);
4987 ctx->bstate = BS_EXCP;
4991 check_insn(env, ctx, ISA_MIPS32R2);
4992 gen_helper_mtc0_intctl(cpu_env, arg);
4993 /* Stop translation as we may have switched the execution mode */
4994 ctx->bstate = BS_STOP;
4998 check_insn(env, ctx, ISA_MIPS32R2);
4999 gen_helper_mtc0_srsctl(cpu_env, arg);
5000 /* Stop translation as we may have switched the execution mode */
5001 ctx->bstate = BS_STOP;
5005 check_insn(env, ctx, ISA_MIPS32R2);
5006 gen_mtc0_store32(arg, offsetof(CPUMIPSState, CP0_SRSMap));
5007 /* Stop translation as we may have switched the execution mode */
5008 ctx->bstate = BS_STOP;
5018 save_cpu_state(ctx, 1);
5019 gen_helper_mtc0_cause(cpu_env, arg);
5029 gen_mtc0_store64(arg, offsetof(CPUMIPSState, CP0_EPC));
5043 check_insn(env, ctx, ISA_MIPS32R2);
5044 gen_helper_mtc0_ebase(cpu_env, arg);
5054 gen_helper_mtc0_config0(cpu_env, arg);
5056 /* Stop translation as we may have switched the execution mode */
5057 ctx->bstate = BS_STOP;
5060 /* ignored, read only */
5064 gen_helper_mtc0_config2(cpu_env, arg);
5066 /* Stop translation as we may have switched the execution mode */
5067 ctx->bstate = BS_STOP;
5070 /* ignored, read only */
5073 /* 4,5 are reserved */
5074 /* 6,7 are implementation dependent */
5084 rn = "Invalid config selector";
5091 gen_helper_mtc0_lladdr(cpu_env, arg);
5101 gen_helper_0e1i(mtc0_watchlo, arg, sel);
5111 gen_helper_0e1i(mtc0_watchhi, arg, sel);
5121 #if defined(TARGET_MIPS64)
5122 check_insn(env, ctx, ISA_MIPS3);
5123 gen_helper_mtc0_xcontext(cpu_env, arg);
5132 /* Officially reserved, but sel 0 is used for R1x000 framemask */
5135 gen_helper_mtc0_framemask(cpu_env, arg);
5144 rn = "Diagnostic"; /* implementation dependent */
5149 gen_helper_mtc0_debug(cpu_env, arg); /* EJTAG support */
5150 /* BS_STOP isn't good enough here, hflags may have changed. */
5151 gen_save_pc(ctx->pc + 4);
5152 ctx->bstate = BS_EXCP;
5156 // gen_helper_mtc0_tracecontrol(cpu_env, arg); /* PDtrace support */
5157 rn = "TraceControl";
5158 /* Stop translation as we may have switched the execution mode */
5159 ctx->bstate = BS_STOP;
5162 // gen_helper_mtc0_tracecontrol2(cpu_env, arg); /* PDtrace support */
5163 rn = "TraceControl2";
5164 /* Stop translation as we may have switched the execution mode */
5165 ctx->bstate = BS_STOP;
5168 /* Stop translation as we may have switched the execution mode */
5169 ctx->bstate = BS_STOP;
5170 // gen_helper_mtc0_usertracedata(cpu_env, arg); /* PDtrace support */
5171 rn = "UserTraceData";
5172 /* Stop translation as we may have switched the execution mode */
5173 ctx->bstate = BS_STOP;
5176 // gen_helper_mtc0_tracebpc(cpu_env, arg); /* PDtrace support */
5177 /* Stop translation as we may have switched the execution mode */
5178 ctx->bstate = BS_STOP;
5189 gen_mtc0_store64(arg, offsetof(CPUMIPSState, CP0_DEPC));
5199 gen_helper_mtc0_performance0(cpu_env, arg);
5200 rn = "Performance0";
5203 // gen_helper_mtc0_performance1(arg);
5204 rn = "Performance1";
5207 // gen_helper_mtc0_performance2(arg);
5208 rn = "Performance2";
5211 // gen_helper_mtc0_performance3(arg);
5212 rn = "Performance3";
5215 // gen_helper_mtc0_performance4(arg);
5216 rn = "Performance4";
5219 // gen_helper_mtc0_performance5(arg);
5220 rn = "Performance5";
5223 // gen_helper_mtc0_performance6(arg);
5224 rn = "Performance6";
5227 // gen_helper_mtc0_performance7(arg);
5228 rn = "Performance7";
5254 gen_helper_mtc0_taglo(cpu_env, arg);
5261 gen_helper_mtc0_datalo(cpu_env, arg);
5274 gen_helper_mtc0_taghi(cpu_env, arg);
5281 gen_helper_mtc0_datahi(cpu_env, arg);
5292 gen_mtc0_store64(arg, offsetof(CPUMIPSState, CP0_ErrorEPC));
5303 gen_mtc0_store32(arg, offsetof(CPUMIPSState, CP0_DESAVE));
5309 /* Stop translation as we may have switched the execution mode */
5310 ctx->bstate = BS_STOP;
5315 (void)rn; /* avoid a compiler warning */
5316 LOG_DISAS("mtc0 %s (reg %d sel %d)\n", rn, reg, sel);
5317 /* For simplicity assume that all writes can cause interrupts. */
5320 ctx->bstate = BS_STOP;
5325 LOG_DISAS("mtc0 %s (reg %d sel %d)\n", rn, reg, sel);
5326 generate_exception(ctx, EXCP_RI);
5329 #if defined(TARGET_MIPS64)
5330 static void gen_dmfc0 (CPUMIPSState *env, DisasContext *ctx, TCGv arg, int reg, int sel)
5332 const char *rn = "invalid";
5335 check_insn(env, ctx, ISA_MIPS64);
5341 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Index));
5345 check_insn(env, ctx, ASE_MT);
5346 gen_helper_mfc0_mvpcontrol(arg, cpu_env);
5350 check_insn(env, ctx, ASE_MT);
5351 gen_helper_mfc0_mvpconf0(arg, cpu_env);
5355 check_insn(env, ctx, ASE_MT);
5356 gen_helper_mfc0_mvpconf1(arg, cpu_env);
5366 gen_helper_mfc0_random(arg, cpu_env);
5370 check_insn(env, ctx, ASE_MT);
5371 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEControl));
5375 check_insn(env, ctx, ASE_MT);
5376 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEConf0));
5380 check_insn(env, ctx, ASE_MT);
5381 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEConf1));
5385 check_insn(env, ctx, ASE_MT);
5386 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_YQMask));
5390 check_insn(env, ctx, ASE_MT);
5391 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_VPESchedule));
5395 check_insn(env, ctx, ASE_MT);
5396 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_VPEScheFBack));
5397 rn = "VPEScheFBack";
5400 check_insn(env, ctx, ASE_MT);
5401 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEOpt));
5411 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EntryLo0));
5415 check_insn(env, ctx, ASE_MT);
5416 gen_helper_mfc0_tcstatus(arg, cpu_env);
5420 check_insn(env, ctx, ASE_MT);
5421 gen_helper_mfc0_tcbind(arg, cpu_env);
5425 check_insn(env, ctx, ASE_MT);
5426 gen_helper_dmfc0_tcrestart(arg, cpu_env);
5430 check_insn(env, ctx, ASE_MT);
5431 gen_helper_dmfc0_tchalt(arg, cpu_env);
5435 check_insn(env, ctx, ASE_MT);
5436 gen_helper_dmfc0_tccontext(arg, cpu_env);
5440 check_insn(env, ctx, ASE_MT);
5441 gen_helper_dmfc0_tcschedule(arg, cpu_env);
5445 check_insn(env, ctx, ASE_MT);
5446 gen_helper_dmfc0_tcschefback(arg, cpu_env);
5456 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EntryLo1));
5466 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_Context));
5470 // gen_helper_dmfc0_contextconfig(arg); /* SmartMIPS ASE */
5471 rn = "ContextConfig";
5480 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PageMask));
5484 check_insn(env, ctx, ISA_MIPS32R2);
5485 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PageGrain));
5495 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Wired));
5499 check_insn(env, ctx, ISA_MIPS32R2);
5500 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf0));
5504 check_insn(env, ctx, ISA_MIPS32R2);
5505 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf1));
5509 check_insn(env, ctx, ISA_MIPS32R2);
5510 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf2));
5514 check_insn(env, ctx, ISA_MIPS32R2);
5515 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf3));
5519 check_insn(env, ctx, ISA_MIPS32R2);
5520 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf4));
5530 check_insn(env, ctx, ISA_MIPS32R2);
5531 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_HWREna));
5541 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_BadVAddr));
5551 /* Mark as an IO operation because we read the time. */
5554 gen_helper_mfc0_count(arg, cpu_env);
5558 /* Break the TB to be able to take timer interrupts immediately
5559 after reading count. */
5560 ctx->bstate = BS_STOP;
5563 /* 6,7 are implementation dependent */
5571 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EntryHi));
5581 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Compare));
5584 /* 6,7 are implementation dependent */
5592 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Status));
5596 check_insn(env, ctx, ISA_MIPS32R2);
5597 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_IntCtl));
5601 check_insn(env, ctx, ISA_MIPS32R2);
5602 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSCtl));
5606 check_insn(env, ctx, ISA_MIPS32R2);
5607 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSMap));
5617 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Cause));
5627 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EPC));
5637 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PRid));
5641 check_insn(env, ctx, ISA_MIPS32R2);
5642 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_EBase));
5652 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config0));
5656 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config1));
5660 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config2));
5664 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config3));
5667 /* 6,7 are implementation dependent */
5669 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config6));
5673 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config7));
5683 gen_helper_dmfc0_lladdr(arg, cpu_env);
5693 gen_helper_1e0i(dmfc0_watchlo, arg, sel);
5703 gen_helper_1e0i(mfc0_watchhi, arg, sel);
5713 check_insn(env, ctx, ISA_MIPS3);
5714 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_XContext));
5722 /* Officially reserved, but sel 0 is used for R1x000 framemask */
5725 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Framemask));
5733 tcg_gen_movi_tl(arg, 0); /* unimplemented */
5734 rn = "'Diagnostic"; /* implementation dependent */
5739 gen_helper_mfc0_debug(arg, cpu_env); /* EJTAG support */
5743 // gen_helper_dmfc0_tracecontrol(arg, cpu_env); /* PDtrace support */
5744 rn = "TraceControl";
5747 // gen_helper_dmfc0_tracecontrol2(arg, cpu_env); /* PDtrace support */
5748 rn = "TraceControl2";
5751 // gen_helper_dmfc0_usertracedata(arg, cpu_env); /* PDtrace support */
5752 rn = "UserTraceData";
5755 // gen_helper_dmfc0_tracebpc(arg, cpu_env); /* PDtrace support */
5766 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_DEPC));
5776 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Performance0));
5777 rn = "Performance0";
5780 // gen_helper_dmfc0_performance1(arg);
5781 rn = "Performance1";
5784 // gen_helper_dmfc0_performance2(arg);
5785 rn = "Performance2";
5788 // gen_helper_dmfc0_performance3(arg);
5789 rn = "Performance3";
5792 // gen_helper_dmfc0_performance4(arg);
5793 rn = "Performance4";
5796 // gen_helper_dmfc0_performance5(arg);
5797 rn = "Performance5";
5800 // gen_helper_dmfc0_performance6(arg);
5801 rn = "Performance6";
5804 // gen_helper_dmfc0_performance7(arg);
5805 rn = "Performance7";
5812 tcg_gen_movi_tl(arg, 0); /* unimplemented */
5819 tcg_gen_movi_tl(arg, 0); /* unimplemented */
5832 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_TagLo));
5839 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DataLo));
5852 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_TagHi));
5859 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DataHi));
5869 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_ErrorEPC));
5880 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DESAVE));
5890 (void)rn; /* avoid a compiler warning */
5891 LOG_DISAS("dmfc0 %s (reg %d sel %d)\n", rn, reg, sel);
5895 LOG_DISAS("dmfc0 %s (reg %d sel %d)\n", rn, reg, sel);
5896 generate_exception(ctx, EXCP_RI);
5899 static void gen_dmtc0 (CPUMIPSState *env, DisasContext *ctx, TCGv arg, int reg, int sel)
5901 const char *rn = "invalid";
5904 check_insn(env, ctx, ISA_MIPS64);
5913 gen_helper_mtc0_index(cpu_env, arg);
5917 check_insn(env, ctx, ASE_MT);
5918 gen_helper_mtc0_mvpcontrol(cpu_env, arg);
5922 check_insn(env, ctx, ASE_MT);
5927 check_insn(env, ctx, ASE_MT);
5942 check_insn(env, ctx, ASE_MT);
5943 gen_helper_mtc0_vpecontrol(cpu_env, arg);
5947 check_insn(env, ctx, ASE_MT);
5948 gen_helper_mtc0_vpeconf0(cpu_env, arg);
5952 check_insn(env, ctx, ASE_MT);
5953 gen_helper_mtc0_vpeconf1(cpu_env, arg);
5957 check_insn(env, ctx, ASE_MT);
5958 gen_helper_mtc0_yqmask(cpu_env, arg);
5962 check_insn(env, ctx, ASE_MT);
5963 tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_VPESchedule));
5967 check_insn(env, ctx, ASE_MT);
5968 tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_VPEScheFBack));
5969 rn = "VPEScheFBack";
5972 check_insn(env, ctx, ASE_MT);
5973 gen_helper_mtc0_vpeopt(cpu_env, arg);
5983 gen_helper_mtc0_entrylo0(cpu_env, arg);
5987 check_insn(env, ctx, ASE_MT);
5988 gen_helper_mtc0_tcstatus(cpu_env, arg);
5992 check_insn(env, ctx, ASE_MT);
5993 gen_helper_mtc0_tcbind(cpu_env, arg);
5997 check_insn(env, ctx, ASE_MT);
5998 gen_helper_mtc0_tcrestart(cpu_env, arg);
6002 check_insn(env, ctx, ASE_MT);
6003 gen_helper_mtc0_tchalt(cpu_env, arg);
6007 check_insn(env, ctx, ASE_MT);
6008 gen_helper_mtc0_tccontext(cpu_env, arg);
6012 check_insn(env, ctx, ASE_MT);
6013 gen_helper_mtc0_tcschedule(cpu_env, arg);
6017 check_insn(env, ctx, ASE_MT);
6018 gen_helper_mtc0_tcschefback(cpu_env, arg);
6028 gen_helper_mtc0_entrylo1(cpu_env, arg);
6038 gen_helper_mtc0_context(cpu_env, arg);
6042 // gen_helper_mtc0_contextconfig(cpu_env, arg); /* SmartMIPS ASE */
6043 rn = "ContextConfig";
6052 gen_helper_mtc0_pagemask(cpu_env, arg);
6056 check_insn(env, ctx, ISA_MIPS32R2);
6057 gen_helper_mtc0_pagegrain(cpu_env, arg);
6067 gen_helper_mtc0_wired(cpu_env, arg);
6071 check_insn(env, ctx, ISA_MIPS32R2);
6072 gen_helper_mtc0_srsconf0(cpu_env, arg);
6076 check_insn(env, ctx, ISA_MIPS32R2);
6077 gen_helper_mtc0_srsconf1(cpu_env, arg);
6081 check_insn(env, ctx, ISA_MIPS32R2);
6082 gen_helper_mtc0_srsconf2(cpu_env, arg);
6086 check_insn(env, ctx, ISA_MIPS32R2);
6087 gen_helper_mtc0_srsconf3(cpu_env, arg);
6091 check_insn(env, ctx, ISA_MIPS32R2);
6092 gen_helper_mtc0_srsconf4(cpu_env, arg);
6102 check_insn(env, ctx, ISA_MIPS32R2);
6103 gen_helper_mtc0_hwrena(cpu_env, arg);
6117 gen_helper_mtc0_count(cpu_env, arg);
6120 /* 6,7 are implementation dependent */
6124 /* Stop translation as we may have switched the execution mode */
6125 ctx->bstate = BS_STOP;
6130 gen_helper_mtc0_entryhi(cpu_env, arg);
6140 gen_helper_mtc0_compare(cpu_env, arg);
6143 /* 6,7 are implementation dependent */
6147 /* Stop translation as we may have switched the execution mode */
6148 ctx->bstate = BS_STOP;
6153 save_cpu_state(ctx, 1);
6154 gen_helper_mtc0_status(cpu_env, arg);
6155 /* BS_STOP isn't good enough here, hflags may have changed. */
6156 gen_save_pc(ctx->pc + 4);
6157 ctx->bstate = BS_EXCP;
6161 check_insn(env, ctx, ISA_MIPS32R2);
6162 gen_helper_mtc0_intctl(cpu_env, arg);
6163 /* Stop translation as we may have switched the execution mode */
6164 ctx->bstate = BS_STOP;
6168 check_insn(env, ctx, ISA_MIPS32R2);
6169 gen_helper_mtc0_srsctl(cpu_env, arg);
6170 /* Stop translation as we may have switched the execution mode */
6171 ctx->bstate = BS_STOP;
6175 check_insn(env, ctx, ISA_MIPS32R2);
6176 gen_mtc0_store32(arg, offsetof(CPUMIPSState, CP0_SRSMap));
6177 /* Stop translation as we may have switched the execution mode */
6178 ctx->bstate = BS_STOP;
6188 save_cpu_state(ctx, 1);
6189 /* Mark as an IO operation because we may trigger a software
6194 gen_helper_mtc0_cause(cpu_env, arg);
6198 /* Stop translation as we may have triggered an intetrupt */
6199 ctx->bstate = BS_STOP;
6209 tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EPC));
6223 check_insn(env, ctx, ISA_MIPS32R2);
6224 gen_helper_mtc0_ebase(cpu_env, arg);
6234 gen_helper_mtc0_config0(cpu_env, arg);
6236 /* Stop translation as we may have switched the execution mode */
6237 ctx->bstate = BS_STOP;
6240 /* ignored, read only */
6244 gen_helper_mtc0_config2(cpu_env, arg);
6246 /* Stop translation as we may have switched the execution mode */
6247 ctx->bstate = BS_STOP;
6253 /* 6,7 are implementation dependent */
6255 rn = "Invalid config selector";
6262 gen_helper_mtc0_lladdr(cpu_env, arg);
6272 gen_helper_0e1i(mtc0_watchlo, arg, sel);
6282 gen_helper_0e1i(mtc0_watchhi, arg, sel);
6292 check_insn(env, ctx, ISA_MIPS3);
6293 gen_helper_mtc0_xcontext(cpu_env, arg);
6301 /* Officially reserved, but sel 0 is used for R1x000 framemask */
6304 gen_helper_mtc0_framemask(cpu_env, arg);
6313 rn = "Diagnostic"; /* implementation dependent */
6318 gen_helper_mtc0_debug(cpu_env, arg); /* EJTAG support */
6319 /* BS_STOP isn't good enough here, hflags may have changed. */
6320 gen_save_pc(ctx->pc + 4);
6321 ctx->bstate = BS_EXCP;
6325 // gen_helper_mtc0_tracecontrol(cpu_env, arg); /* PDtrace support */
6326 /* Stop translation as we may have switched the execution mode */
6327 ctx->bstate = BS_STOP;
6328 rn = "TraceControl";
6331 // gen_helper_mtc0_tracecontrol2(cpu_env, arg); /* PDtrace support */
6332 /* Stop translation as we may have switched the execution mode */
6333 ctx->bstate = BS_STOP;
6334 rn = "TraceControl2";
6337 // gen_helper_mtc0_usertracedata(cpu_env, arg); /* PDtrace support */
6338 /* Stop translation as we may have switched the execution mode */
6339 ctx->bstate = BS_STOP;
6340 rn = "UserTraceData";
6343 // gen_helper_mtc0_tracebpc(cpu_env, arg); /* PDtrace support */
6344 /* Stop translation as we may have switched the execution mode */
6345 ctx->bstate = BS_STOP;
6356 tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_DEPC));
6366 gen_helper_mtc0_performance0(cpu_env, arg);
6367 rn = "Performance0";
6370 // gen_helper_mtc0_performance1(cpu_env, arg);
6371 rn = "Performance1";
6374 // gen_helper_mtc0_performance2(cpu_env, arg);
6375 rn = "Performance2";
6378 // gen_helper_mtc0_performance3(cpu_env, arg);
6379 rn = "Performance3";
6382 // gen_helper_mtc0_performance4(cpu_env, arg);
6383 rn = "Performance4";
6386 // gen_helper_mtc0_performance5(cpu_env, arg);
6387 rn = "Performance5";
6390 // gen_helper_mtc0_performance6(cpu_env, arg);
6391 rn = "Performance6";
6394 // gen_helper_mtc0_performance7(cpu_env, arg);
6395 rn = "Performance7";
6421 gen_helper_mtc0_taglo(cpu_env, arg);
6428 gen_helper_mtc0_datalo(cpu_env, arg);
6441 gen_helper_mtc0_taghi(cpu_env, arg);
6448 gen_helper_mtc0_datahi(cpu_env, arg);
6459 tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_ErrorEPC));
6470 gen_mtc0_store32(arg, offsetof(CPUMIPSState, CP0_DESAVE));
6476 /* Stop translation as we may have switched the execution mode */
6477 ctx->bstate = BS_STOP;
6482 (void)rn; /* avoid a compiler warning */
6483 LOG_DISAS("dmtc0 %s (reg %d sel %d)\n", rn, reg, sel);
6484 /* For simplicity assume that all writes can cause interrupts. */
6487 ctx->bstate = BS_STOP;
6492 LOG_DISAS("dmtc0 %s (reg %d sel %d)\n", rn, reg, sel);
6493 generate_exception(ctx, EXCP_RI);
6495 #endif /* TARGET_MIPS64 */
6497 static void gen_mftr(CPUMIPSState *env, DisasContext *ctx, int rt, int rd,
6498 int u, int sel, int h)
6500 int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
6501 TCGv t0 = tcg_temp_local_new();
6503 if ((env->CP0_VPEConf0 & (1 << CP0VPEC0_MVP)) == 0 &&
6504 ((env->tcs[other_tc].CP0_TCBind & (0xf << CP0TCBd_CurVPE)) !=
6505 (env->active_tc.CP0_TCBind & (0xf << CP0TCBd_CurVPE))))
6506 tcg_gen_movi_tl(t0, -1);
6507 else if ((env->CP0_VPEControl & (0xff << CP0VPECo_TargTC)) >
6508 (env->mvp->CP0_MVPConf0 & (0xff << CP0MVPC0_PTC)))
6509 tcg_gen_movi_tl(t0, -1);
6515 gen_helper_mftc0_vpecontrol(t0, cpu_env);
6518 gen_helper_mftc0_vpeconf0(t0, cpu_env);
6528 gen_helper_mftc0_tcstatus(t0, cpu_env);
6531 gen_helper_mftc0_tcbind(t0, cpu_env);
6534 gen_helper_mftc0_tcrestart(t0, cpu_env);
6537 gen_helper_mftc0_tchalt(t0, cpu_env);
6540 gen_helper_mftc0_tccontext(t0, cpu_env);
6543 gen_helper_mftc0_tcschedule(t0, cpu_env);
6546 gen_helper_mftc0_tcschefback(t0, cpu_env);
6549 gen_mfc0(env, ctx, t0, rt, sel);
6556 gen_helper_mftc0_entryhi(t0, cpu_env);
6559 gen_mfc0(env, ctx, t0, rt, sel);
6565 gen_helper_mftc0_status(t0, cpu_env);
6568 gen_mfc0(env, ctx, t0, rt, sel);
6574 gen_helper_mftc0_cause(t0, cpu_env);
6584 gen_helper_mftc0_epc(t0, cpu_env);
6594 gen_helper_mftc0_ebase(t0, cpu_env);
6604 gen_helper_mftc0_configx(t0, cpu_env, tcg_const_tl(sel));
6614 gen_helper_mftc0_debug(t0, cpu_env);
6617 gen_mfc0(env, ctx, t0, rt, sel);
6622 gen_mfc0(env, ctx, t0, rt, sel);
6624 } else switch (sel) {
6625 /* GPR registers. */
6627 gen_helper_1e0i(mftgpr, t0, rt);
6629 /* Auxiliary CPU registers */
6633 gen_helper_1e0i(mftlo, t0, 0);
6636 gen_helper_1e0i(mfthi, t0, 0);
6639 gen_helper_1e0i(mftacx, t0, 0);
6642 gen_helper_1e0i(mftlo, t0, 1);
6645 gen_helper_1e0i(mfthi, t0, 1);
6648 gen_helper_1e0i(mftacx, t0, 1);
6651 gen_helper_1e0i(mftlo, t0, 2);
6654 gen_helper_1e0i(mfthi, t0, 2);
6657 gen_helper_1e0i(mftacx, t0, 2);
6660 gen_helper_1e0i(mftlo, t0, 3);
6663 gen_helper_1e0i(mfthi, t0, 3);
6666 gen_helper_1e0i(mftacx, t0, 3);
6669 gen_helper_mftdsp(t0, cpu_env);
6675 /* Floating point (COP1). */
6677 /* XXX: For now we support only a single FPU context. */
6679 TCGv_i32 fp0 = tcg_temp_new_i32();
6681 gen_load_fpr32(fp0, rt);
6682 tcg_gen_ext_i32_tl(t0, fp0);
6683 tcg_temp_free_i32(fp0);
6685 TCGv_i32 fp0 = tcg_temp_new_i32();
6687 gen_load_fpr32h(fp0, rt);
6688 tcg_gen_ext_i32_tl(t0, fp0);
6689 tcg_temp_free_i32(fp0);
6693 /* XXX: For now we support only a single FPU context. */
6694 gen_helper_1e0i(cfc1, t0, rt);
6696 /* COP2: Not implemented. */
6703 LOG_DISAS("mftr (reg %d u %d sel %d h %d)\n", rt, u, sel, h);
6704 gen_store_gpr(t0, rd);
6710 LOG_DISAS("mftr (reg %d u %d sel %d h %d)\n", rt, u, sel, h);
6711 generate_exception(ctx, EXCP_RI);
6714 static void gen_mttr(CPUMIPSState *env, DisasContext *ctx, int rd, int rt,
6715 int u, int sel, int h)
6717 int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
6718 TCGv t0 = tcg_temp_local_new();
6720 gen_load_gpr(t0, rt);
6721 if ((env->CP0_VPEConf0 & (1 << CP0VPEC0_MVP)) == 0 &&
6722 ((env->tcs[other_tc].CP0_TCBind & (0xf << CP0TCBd_CurVPE)) !=
6723 (env->active_tc.CP0_TCBind & (0xf << CP0TCBd_CurVPE))))
6725 else if ((env->CP0_VPEControl & (0xff << CP0VPECo_TargTC)) >
6726 (env->mvp->CP0_MVPConf0 & (0xff << CP0MVPC0_PTC)))
6733 gen_helper_mttc0_vpecontrol(cpu_env, t0);
6736 gen_helper_mttc0_vpeconf0(cpu_env, t0);
6746 gen_helper_mttc0_tcstatus(cpu_env, t0);
6749 gen_helper_mttc0_tcbind(cpu_env, t0);
6752 gen_helper_mttc0_tcrestart(cpu_env, t0);
6755 gen_helper_mttc0_tchalt(cpu_env, t0);
6758 gen_helper_mttc0_tccontext(cpu_env, t0);
6761 gen_helper_mttc0_tcschedule(cpu_env, t0);
6764 gen_helper_mttc0_tcschefback(cpu_env, t0);
6767 gen_mtc0(env, ctx, t0, rd, sel);
6774 gen_helper_mttc0_entryhi(cpu_env, t0);
6777 gen_mtc0(env, ctx, t0, rd, sel);
6783 gen_helper_mttc0_status(cpu_env, t0);
6786 gen_mtc0(env, ctx, t0, rd, sel);
6792 gen_helper_mttc0_cause(cpu_env, t0);
6802 gen_helper_mttc0_ebase(cpu_env, t0);
6812 gen_helper_mttc0_debug(cpu_env, t0);
6815 gen_mtc0(env, ctx, t0, rd, sel);
6820 gen_mtc0(env, ctx, t0, rd, sel);
6822 } else switch (sel) {
6823 /* GPR registers. */
6825 gen_helper_0e1i(mttgpr, t0, rd);
6827 /* Auxiliary CPU registers */
6831 gen_helper_0e1i(mttlo, t0, 0);
6834 gen_helper_0e1i(mtthi, t0, 0);
6837 gen_helper_0e1i(mttacx, t0, 0);
6840 gen_helper_0e1i(mttlo, t0, 1);
6843 gen_helper_0e1i(mtthi, t0, 1);
6846 gen_helper_0e1i(mttacx, t0, 1);
6849 gen_helper_0e1i(mttlo, t0, 2);
6852 gen_helper_0e1i(mtthi, t0, 2);
6855 gen_helper_0e1i(mttacx, t0, 2);
6858 gen_helper_0e1i(mttlo, t0, 3);
6861 gen_helper_0e1i(mtthi, t0, 3);
6864 gen_helper_0e1i(mttacx, t0, 3);
6867 gen_helper_mttdsp(cpu_env, t0);
6873 /* Floating point (COP1). */
6875 /* XXX: For now we support only a single FPU context. */
6877 TCGv_i32 fp0 = tcg_temp_new_i32();
6879 tcg_gen_trunc_tl_i32(fp0, t0);
6880 gen_store_fpr32(fp0, rd);
6881 tcg_temp_free_i32(fp0);
6883 TCGv_i32 fp0 = tcg_temp_new_i32();
6885 tcg_gen_trunc_tl_i32(fp0, t0);
6886 gen_store_fpr32h(fp0, rd);
6887 tcg_temp_free_i32(fp0);
6891 /* XXX: For now we support only a single FPU context. */
6892 gen_helper_0e1i(ctc1, t0, rd);
6894 /* COP2: Not implemented. */
6901 LOG_DISAS("mttr (reg %d u %d sel %d h %d)\n", rd, u, sel, h);
6907 LOG_DISAS("mttr (reg %d u %d sel %d h %d)\n", rd, u, sel, h);
6908 generate_exception(ctx, EXCP_RI);
6911 static void gen_cp0 (CPUMIPSState *env, DisasContext *ctx, uint32_t opc, int rt, int rd)
6913 const char *opn = "ldst";
6915 check_cp0_enabled(ctx);
6922 gen_mfc0(env, ctx, cpu_gpr[rt], rd, ctx->opcode & 0x7);
6927 TCGv t0 = tcg_temp_new();
6929 gen_load_gpr(t0, rt);
6930 gen_mtc0(env, ctx, t0, rd, ctx->opcode & 0x7);
6935 #if defined(TARGET_MIPS64)
6937 check_insn(env, ctx, ISA_MIPS3);
6942 gen_dmfc0(env, ctx, cpu_gpr[rt], rd, ctx->opcode & 0x7);
6946 check_insn(env, ctx, ISA_MIPS3);
6948 TCGv t0 = tcg_temp_new();
6950 gen_load_gpr(t0, rt);
6951 gen_dmtc0(env, ctx, t0, rd, ctx->opcode & 0x7);
6958 check_insn(env, ctx, ASE_MT);
6963 gen_mftr(env, ctx, rt, rd, (ctx->opcode >> 5) & 1,
6964 ctx->opcode & 0x7, (ctx->opcode >> 4) & 1);
6968 check_insn(env, ctx, ASE_MT);
6969 gen_mttr(env, ctx, rd, rt, (ctx->opcode >> 5) & 1,
6970 ctx->opcode & 0x7, (ctx->opcode >> 4) & 1);
6975 if (!env->tlb->helper_tlbwi)
6977 gen_helper_tlbwi(cpu_env);
6981 if (!env->tlb->helper_tlbwr)
6983 gen_helper_tlbwr(cpu_env);
6987 if (!env->tlb->helper_tlbp)
6989 gen_helper_tlbp(cpu_env);
6993 if (!env->tlb->helper_tlbr)
6995 gen_helper_tlbr(cpu_env);
6999 check_insn(env, ctx, ISA_MIPS2);
7000 gen_helper_eret(cpu_env);
7001 ctx->bstate = BS_EXCP;
7005 check_insn(env, ctx, ISA_MIPS32);
7006 if (!(ctx->hflags & MIPS_HFLAG_DM)) {
7008 generate_exception(ctx, EXCP_RI);
7010 gen_helper_deret(cpu_env);
7011 ctx->bstate = BS_EXCP;
7016 check_insn(env, ctx, ISA_MIPS3 | ISA_MIPS32);
7017 /* If we get an exception, we want to restart at next instruction */
7019 save_cpu_state(ctx, 1);
7021 gen_helper_wait(cpu_env);
7022 ctx->bstate = BS_EXCP;
7027 generate_exception(ctx, EXCP_RI);
7030 (void)opn; /* avoid a compiler warning */
7031 MIPS_DEBUG("%s %s %d", opn, regnames[rt], rd);
7033 #endif /* !CONFIG_USER_ONLY */
7035 /* CP1 Branches (before delay slot) */
7036 static void gen_compute_branch1 (CPUMIPSState *env, DisasContext *ctx, uint32_t op,
7037 int32_t cc, int32_t offset)
7039 target_ulong btarget;
7040 const char *opn = "cp1 cond branch";
7041 TCGv_i32 t0 = tcg_temp_new_i32();
7044 check_insn(env, ctx, ISA_MIPS4 | ISA_MIPS32);
7046 btarget = ctx->pc + 4 + offset;
7050 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
7051 tcg_gen_not_i32(t0, t0);
7052 tcg_gen_andi_i32(t0, t0, 1);
7053 tcg_gen_extu_i32_tl(bcond, t0);
7057 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
7058 tcg_gen_not_i32(t0, t0);
7059 tcg_gen_andi_i32(t0, t0, 1);
7060 tcg_gen_extu_i32_tl(bcond, t0);
7064 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
7065 tcg_gen_andi_i32(t0, t0, 1);
7066 tcg_gen_extu_i32_tl(bcond, t0);
7070 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
7071 tcg_gen_andi_i32(t0, t0, 1);
7072 tcg_gen_extu_i32_tl(bcond, t0);
7075 ctx->hflags |= MIPS_HFLAG_BL;
7079 TCGv_i32 t1 = tcg_temp_new_i32();
7080 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
7081 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+1));
7082 tcg_gen_nand_i32(t0, t0, t1);
7083 tcg_temp_free_i32(t1);
7084 tcg_gen_andi_i32(t0, t0, 1);
7085 tcg_gen_extu_i32_tl(bcond, t0);
7091 TCGv_i32 t1 = tcg_temp_new_i32();
7092 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
7093 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+1));
7094 tcg_gen_or_i32(t0, t0, t1);
7095 tcg_temp_free_i32(t1);
7096 tcg_gen_andi_i32(t0, t0, 1);
7097 tcg_gen_extu_i32_tl(bcond, t0);
7103 TCGv_i32 t1 = tcg_temp_new_i32();
7104 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
7105 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+1));
7106 tcg_gen_and_i32(t0, t0, t1);
7107 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+2));
7108 tcg_gen_and_i32(t0, t0, t1);
7109 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+3));
7110 tcg_gen_nand_i32(t0, t0, t1);
7111 tcg_temp_free_i32(t1);
7112 tcg_gen_andi_i32(t0, t0, 1);
7113 tcg_gen_extu_i32_tl(bcond, t0);
7119 TCGv_i32 t1 = tcg_temp_new_i32();
7120 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
7121 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+1));
7122 tcg_gen_or_i32(t0, t0, t1);
7123 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+2));
7124 tcg_gen_or_i32(t0, t0, t1);
7125 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+3));
7126 tcg_gen_or_i32(t0, t0, t1);
7127 tcg_temp_free_i32(t1);
7128 tcg_gen_andi_i32(t0, t0, 1);
7129 tcg_gen_extu_i32_tl(bcond, t0);
7133 ctx->hflags |= MIPS_HFLAG_BC;
7137 generate_exception (ctx, EXCP_RI);
7140 (void)opn; /* avoid a compiler warning */
7141 MIPS_DEBUG("%s: cond %02x target " TARGET_FMT_lx, opn,
7142 ctx->hflags, btarget);
7143 ctx->btarget = btarget;
7146 tcg_temp_free_i32(t0);
7149 /* Coprocessor 1 (FPU) */
7151 #define FOP(func, fmt) (((fmt) << 21) | (func))
7154 OPC_ADD_S = FOP(0, FMT_S),
7155 OPC_SUB_S = FOP(1, FMT_S),
7156 OPC_MUL_S = FOP(2, FMT_S),
7157 OPC_DIV_S = FOP(3, FMT_S),
7158 OPC_SQRT_S = FOP(4, FMT_S),
7159 OPC_ABS_S = FOP(5, FMT_S),
7160 OPC_MOV_S = FOP(6, FMT_S),
7161 OPC_NEG_S = FOP(7, FMT_S),
7162 OPC_ROUND_L_S = FOP(8, FMT_S),
7163 OPC_TRUNC_L_S = FOP(9, FMT_S),
7164 OPC_CEIL_L_S = FOP(10, FMT_S),
7165 OPC_FLOOR_L_S = FOP(11, FMT_S),
7166 OPC_ROUND_W_S = FOP(12, FMT_S),
7167 OPC_TRUNC_W_S = FOP(13, FMT_S),
7168 OPC_CEIL_W_S = FOP(14, FMT_S),
7169 OPC_FLOOR_W_S = FOP(15, FMT_S),
7170 OPC_MOVCF_S = FOP(17, FMT_S),
7171 OPC_MOVZ_S = FOP(18, FMT_S),
7172 OPC_MOVN_S = FOP(19, FMT_S),
7173 OPC_RECIP_S = FOP(21, FMT_S),
7174 OPC_RSQRT_S = FOP(22, FMT_S),
7175 OPC_RECIP2_S = FOP(28, FMT_S),
7176 OPC_RECIP1_S = FOP(29, FMT_S),
7177 OPC_RSQRT1_S = FOP(30, FMT_S),
7178 OPC_RSQRT2_S = FOP(31, FMT_S),
7179 OPC_CVT_D_S = FOP(33, FMT_S),
7180 OPC_CVT_W_S = FOP(36, FMT_S),
7181 OPC_CVT_L_S = FOP(37, FMT_S),
7182 OPC_CVT_PS_S = FOP(38, FMT_S),
7183 OPC_CMP_F_S = FOP (48, FMT_S),
7184 OPC_CMP_UN_S = FOP (49, FMT_S),
7185 OPC_CMP_EQ_S = FOP (50, FMT_S),
7186 OPC_CMP_UEQ_S = FOP (51, FMT_S),
7187 OPC_CMP_OLT_S = FOP (52, FMT_S),
7188 OPC_CMP_ULT_S = FOP (53, FMT_S),
7189 OPC_CMP_OLE_S = FOP (54, FMT_S),
7190 OPC_CMP_ULE_S = FOP (55, FMT_S),
7191 OPC_CMP_SF_S = FOP (56, FMT_S),
7192 OPC_CMP_NGLE_S = FOP (57, FMT_S),
7193 OPC_CMP_SEQ_S = FOP (58, FMT_S),
7194 OPC_CMP_NGL_S = FOP (59, FMT_S),
7195 OPC_CMP_LT_S = FOP (60, FMT_S),
7196 OPC_CMP_NGE_S = FOP (61, FMT_S),
7197 OPC_CMP_LE_S = FOP (62, FMT_S),
7198 OPC_CMP_NGT_S = FOP (63, FMT_S),
7200 OPC_ADD_D = FOP(0, FMT_D),
7201 OPC_SUB_D = FOP(1, FMT_D),
7202 OPC_MUL_D = FOP(2, FMT_D),
7203 OPC_DIV_D = FOP(3, FMT_D),
7204 OPC_SQRT_D = FOP(4, FMT_D),
7205 OPC_ABS_D = FOP(5, FMT_D),
7206 OPC_MOV_D = FOP(6, FMT_D),
7207 OPC_NEG_D = FOP(7, FMT_D),
7208 OPC_ROUND_L_D = FOP(8, FMT_D),
7209 OPC_TRUNC_L_D = FOP(9, FMT_D),
7210 OPC_CEIL_L_D = FOP(10, FMT_D),
7211 OPC_FLOOR_L_D = FOP(11, FMT_D),
7212 OPC_ROUND_W_D = FOP(12, FMT_D),
7213 OPC_TRUNC_W_D = FOP(13, FMT_D),
7214 OPC_CEIL_W_D = FOP(14, FMT_D),
7215 OPC_FLOOR_W_D = FOP(15, FMT_D),
7216 OPC_MOVCF_D = FOP(17, FMT_D),
7217 OPC_MOVZ_D = FOP(18, FMT_D),
7218 OPC_MOVN_D = FOP(19, FMT_D),
7219 OPC_RECIP_D = FOP(21, FMT_D),
7220 OPC_RSQRT_D = FOP(22, FMT_D),
7221 OPC_RECIP2_D = FOP(28, FMT_D),
7222 OPC_RECIP1_D = FOP(29, FMT_D),
7223 OPC_RSQRT1_D = FOP(30, FMT_D),
7224 OPC_RSQRT2_D = FOP(31, FMT_D),
7225 OPC_CVT_S_D = FOP(32, FMT_D),
7226 OPC_CVT_W_D = FOP(36, FMT_D),
7227 OPC_CVT_L_D = FOP(37, FMT_D),
7228 OPC_CMP_F_D = FOP (48, FMT_D),
7229 OPC_CMP_UN_D = FOP (49, FMT_D),
7230 OPC_CMP_EQ_D = FOP (50, FMT_D),
7231 OPC_CMP_UEQ_D = FOP (51, FMT_D),
7232 OPC_CMP_OLT_D = FOP (52, FMT_D),
7233 OPC_CMP_ULT_D = FOP (53, FMT_D),
7234 OPC_CMP_OLE_D = FOP (54, FMT_D),
7235 OPC_CMP_ULE_D = FOP (55, FMT_D),
7236 OPC_CMP_SF_D = FOP (56, FMT_D),
7237 OPC_CMP_NGLE_D = FOP (57, FMT_D),
7238 OPC_CMP_SEQ_D = FOP (58, FMT_D),
7239 OPC_CMP_NGL_D = FOP (59, FMT_D),
7240 OPC_CMP_LT_D = FOP (60, FMT_D),
7241 OPC_CMP_NGE_D = FOP (61, FMT_D),
7242 OPC_CMP_LE_D = FOP (62, FMT_D),
7243 OPC_CMP_NGT_D = FOP (63, FMT_D),
7245 OPC_CVT_S_W = FOP(32, FMT_W),
7246 OPC_CVT_D_W = FOP(33, FMT_W),
7247 OPC_CVT_S_L = FOP(32, FMT_L),
7248 OPC_CVT_D_L = FOP(33, FMT_L),
7249 OPC_CVT_PS_PW = FOP(38, FMT_W),
7251 OPC_ADD_PS = FOP(0, FMT_PS),
7252 OPC_SUB_PS = FOP(1, FMT_PS),
7253 OPC_MUL_PS = FOP(2, FMT_PS),
7254 OPC_DIV_PS = FOP(3, FMT_PS),
7255 OPC_ABS_PS = FOP(5, FMT_PS),
7256 OPC_MOV_PS = FOP(6, FMT_PS),
7257 OPC_NEG_PS = FOP(7, FMT_PS),
7258 OPC_MOVCF_PS = FOP(17, FMT_PS),
7259 OPC_MOVZ_PS = FOP(18, FMT_PS),
7260 OPC_MOVN_PS = FOP(19, FMT_PS),
7261 OPC_ADDR_PS = FOP(24, FMT_PS),
7262 OPC_MULR_PS = FOP(26, FMT_PS),
7263 OPC_RECIP2_PS = FOP(28, FMT_PS),
7264 OPC_RECIP1_PS = FOP(29, FMT_PS),
7265 OPC_RSQRT1_PS = FOP(30, FMT_PS),
7266 OPC_RSQRT2_PS = FOP(31, FMT_PS),
7268 OPC_CVT_S_PU = FOP(32, FMT_PS),
7269 OPC_CVT_PW_PS = FOP(36, FMT_PS),
7270 OPC_CVT_S_PL = FOP(40, FMT_PS),
7271 OPC_PLL_PS = FOP(44, FMT_PS),
7272 OPC_PLU_PS = FOP(45, FMT_PS),
7273 OPC_PUL_PS = FOP(46, FMT_PS),
7274 OPC_PUU_PS = FOP(47, FMT_PS),
7275 OPC_CMP_F_PS = FOP (48, FMT_PS),
7276 OPC_CMP_UN_PS = FOP (49, FMT_PS),
7277 OPC_CMP_EQ_PS = FOP (50, FMT_PS),
7278 OPC_CMP_UEQ_PS = FOP (51, FMT_PS),
7279 OPC_CMP_OLT_PS = FOP (52, FMT_PS),
7280 OPC_CMP_ULT_PS = FOP (53, FMT_PS),
7281 OPC_CMP_OLE_PS = FOP (54, FMT_PS),
7282 OPC_CMP_ULE_PS = FOP (55, FMT_PS),
7283 OPC_CMP_SF_PS = FOP (56, FMT_PS),
7284 OPC_CMP_NGLE_PS = FOP (57, FMT_PS),
7285 OPC_CMP_SEQ_PS = FOP (58, FMT_PS),
7286 OPC_CMP_NGL_PS = FOP (59, FMT_PS),
7287 OPC_CMP_LT_PS = FOP (60, FMT_PS),
7288 OPC_CMP_NGE_PS = FOP (61, FMT_PS),
7289 OPC_CMP_LE_PS = FOP (62, FMT_PS),
7290 OPC_CMP_NGT_PS = FOP (63, FMT_PS),
7293 static void gen_cp1 (DisasContext *ctx, uint32_t opc, int rt, int fs)
7295 const char *opn = "cp1 move";
7296 TCGv t0 = tcg_temp_new();
7301 TCGv_i32 fp0 = tcg_temp_new_i32();
7303 gen_load_fpr32(fp0, fs);
7304 tcg_gen_ext_i32_tl(t0, fp0);
7305 tcg_temp_free_i32(fp0);
7307 gen_store_gpr(t0, rt);
7311 gen_load_gpr(t0, rt);
7313 TCGv_i32 fp0 = tcg_temp_new_i32();
7315 tcg_gen_trunc_tl_i32(fp0, t0);
7316 gen_store_fpr32(fp0, fs);
7317 tcg_temp_free_i32(fp0);
7322 gen_helper_1e0i(cfc1, t0, fs);
7323 gen_store_gpr(t0, rt);
7327 gen_load_gpr(t0, rt);
7328 gen_helper_0e1i(ctc1, t0, fs);
7331 #if defined(TARGET_MIPS64)
7333 gen_load_fpr64(ctx, t0, fs);
7334 gen_store_gpr(t0, rt);
7338 gen_load_gpr(t0, rt);
7339 gen_store_fpr64(ctx, t0, fs);
7345 TCGv_i32 fp0 = tcg_temp_new_i32();
7347 gen_load_fpr32h(fp0, fs);
7348 tcg_gen_ext_i32_tl(t0, fp0);
7349 tcg_temp_free_i32(fp0);
7351 gen_store_gpr(t0, rt);
7355 gen_load_gpr(t0, rt);
7357 TCGv_i32 fp0 = tcg_temp_new_i32();
7359 tcg_gen_trunc_tl_i32(fp0, t0);
7360 gen_store_fpr32h(fp0, fs);
7361 tcg_temp_free_i32(fp0);
7367 generate_exception (ctx, EXCP_RI);
7370 (void)opn; /* avoid a compiler warning */
7371 MIPS_DEBUG("%s %s %s", opn, regnames[rt], fregnames[fs]);
7377 static void gen_movci (DisasContext *ctx, int rd, int rs, int cc, int tf)
7393 l1 = gen_new_label();
7394 t0 = tcg_temp_new_i32();
7395 tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc));
7396 tcg_gen_brcondi_i32(cond, t0, 0, l1);
7397 tcg_temp_free_i32(t0);
7399 tcg_gen_movi_tl(cpu_gpr[rd], 0);
7401 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
7406 static inline void gen_movcf_s (int fs, int fd, int cc, int tf)
7409 TCGv_i32 t0 = tcg_temp_new_i32();
7410 int l1 = gen_new_label();
7417 tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc));
7418 tcg_gen_brcondi_i32(cond, t0, 0, l1);
7419 gen_load_fpr32(t0, fs);
7420 gen_store_fpr32(t0, fd);
7422 tcg_temp_free_i32(t0);
7425 static inline void gen_movcf_d (DisasContext *ctx, int fs, int fd, int cc, int tf)
7428 TCGv_i32 t0 = tcg_temp_new_i32();
7430 int l1 = gen_new_label();
7437 tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc));
7438 tcg_gen_brcondi_i32(cond, t0, 0, l1);
7439 tcg_temp_free_i32(t0);
7440 fp0 = tcg_temp_new_i64();
7441 gen_load_fpr64(ctx, fp0, fs);
7442 gen_store_fpr64(ctx, fp0, fd);
7443 tcg_temp_free_i64(fp0);
7447 static inline void gen_movcf_ps (int fs, int fd, int cc, int tf)
7450 TCGv_i32 t0 = tcg_temp_new_i32();
7451 int l1 = gen_new_label();
7452 int l2 = gen_new_label();
7459 tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc));
7460 tcg_gen_brcondi_i32(cond, t0, 0, l1);
7461 gen_load_fpr32(t0, fs);
7462 gen_store_fpr32(t0, fd);
7465 tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc+1));
7466 tcg_gen_brcondi_i32(cond, t0, 0, l2);
7467 gen_load_fpr32h(t0, fs);
7468 gen_store_fpr32h(t0, fd);
7469 tcg_temp_free_i32(t0);
7474 static void gen_farith (DisasContext *ctx, enum fopcode op1,
7475 int ft, int fs, int fd, int cc)
7477 const char *opn = "farith";
7478 const char *condnames[] = {
7496 const char *condnames_abs[] = {
7514 enum { BINOP, CMPOP, OTHEROP } optype = OTHEROP;
7515 uint32_t func = ctx->opcode & 0x3f;
7520 TCGv_i32 fp0 = tcg_temp_new_i32();
7521 TCGv_i32 fp1 = tcg_temp_new_i32();
7523 gen_load_fpr32(fp0, fs);
7524 gen_load_fpr32(fp1, ft);
7525 gen_helper_float_add_s(fp0, cpu_env, fp0, fp1);
7526 tcg_temp_free_i32(fp1);
7527 gen_store_fpr32(fp0, fd);
7528 tcg_temp_free_i32(fp0);
7535 TCGv_i32 fp0 = tcg_temp_new_i32();
7536 TCGv_i32 fp1 = tcg_temp_new_i32();
7538 gen_load_fpr32(fp0, fs);
7539 gen_load_fpr32(fp1, ft);
7540 gen_helper_float_sub_s(fp0, cpu_env, fp0, fp1);
7541 tcg_temp_free_i32(fp1);
7542 gen_store_fpr32(fp0, fd);
7543 tcg_temp_free_i32(fp0);
7550 TCGv_i32 fp0 = tcg_temp_new_i32();
7551 TCGv_i32 fp1 = tcg_temp_new_i32();
7553 gen_load_fpr32(fp0, fs);
7554 gen_load_fpr32(fp1, ft);
7555 gen_helper_float_mul_s(fp0, cpu_env, fp0, fp1);
7556 tcg_temp_free_i32(fp1);
7557 gen_store_fpr32(fp0, fd);
7558 tcg_temp_free_i32(fp0);
7565 TCGv_i32 fp0 = tcg_temp_new_i32();
7566 TCGv_i32 fp1 = tcg_temp_new_i32();
7568 gen_load_fpr32(fp0, fs);
7569 gen_load_fpr32(fp1, ft);
7570 gen_helper_float_div_s(fp0, cpu_env, fp0, fp1);
7571 tcg_temp_free_i32(fp1);
7572 gen_store_fpr32(fp0, fd);
7573 tcg_temp_free_i32(fp0);
7580 TCGv_i32 fp0 = tcg_temp_new_i32();
7582 gen_load_fpr32(fp0, fs);
7583 gen_helper_float_sqrt_s(fp0, cpu_env, fp0);
7584 gen_store_fpr32(fp0, fd);
7585 tcg_temp_free_i32(fp0);
7591 TCGv_i32 fp0 = tcg_temp_new_i32();
7593 gen_load_fpr32(fp0, fs);
7594 gen_helper_float_abs_s(fp0, fp0);
7595 gen_store_fpr32(fp0, fd);
7596 tcg_temp_free_i32(fp0);
7602 TCGv_i32 fp0 = tcg_temp_new_i32();
7604 gen_load_fpr32(fp0, fs);
7605 gen_store_fpr32(fp0, fd);
7606 tcg_temp_free_i32(fp0);
7612 TCGv_i32 fp0 = tcg_temp_new_i32();
7614 gen_load_fpr32(fp0, fs);
7615 gen_helper_float_chs_s(fp0, fp0);
7616 gen_store_fpr32(fp0, fd);
7617 tcg_temp_free_i32(fp0);
7622 check_cp1_64bitmode(ctx);
7624 TCGv_i32 fp32 = tcg_temp_new_i32();
7625 TCGv_i64 fp64 = tcg_temp_new_i64();
7627 gen_load_fpr32(fp32, fs);
7628 gen_helper_float_roundl_s(fp64, cpu_env, fp32);
7629 tcg_temp_free_i32(fp32);
7630 gen_store_fpr64(ctx, fp64, fd);
7631 tcg_temp_free_i64(fp64);
7636 check_cp1_64bitmode(ctx);
7638 TCGv_i32 fp32 = tcg_temp_new_i32();
7639 TCGv_i64 fp64 = tcg_temp_new_i64();
7641 gen_load_fpr32(fp32, fs);
7642 gen_helper_float_truncl_s(fp64, cpu_env, fp32);
7643 tcg_temp_free_i32(fp32);
7644 gen_store_fpr64(ctx, fp64, fd);
7645 tcg_temp_free_i64(fp64);
7650 check_cp1_64bitmode(ctx);
7652 TCGv_i32 fp32 = tcg_temp_new_i32();
7653 TCGv_i64 fp64 = tcg_temp_new_i64();
7655 gen_load_fpr32(fp32, fs);
7656 gen_helper_float_ceill_s(fp64, cpu_env, fp32);
7657 tcg_temp_free_i32(fp32);
7658 gen_store_fpr64(ctx, fp64, fd);
7659 tcg_temp_free_i64(fp64);
7664 check_cp1_64bitmode(ctx);
7666 TCGv_i32 fp32 = tcg_temp_new_i32();
7667 TCGv_i64 fp64 = tcg_temp_new_i64();
7669 gen_load_fpr32(fp32, fs);
7670 gen_helper_float_floorl_s(fp64, cpu_env, fp32);
7671 tcg_temp_free_i32(fp32);
7672 gen_store_fpr64(ctx, fp64, fd);
7673 tcg_temp_free_i64(fp64);
7679 TCGv_i32 fp0 = tcg_temp_new_i32();
7681 gen_load_fpr32(fp0, fs);
7682 gen_helper_float_roundw_s(fp0, cpu_env, fp0);
7683 gen_store_fpr32(fp0, fd);
7684 tcg_temp_free_i32(fp0);
7690 TCGv_i32 fp0 = tcg_temp_new_i32();
7692 gen_load_fpr32(fp0, fs);
7693 gen_helper_float_truncw_s(fp0, cpu_env, fp0);
7694 gen_store_fpr32(fp0, fd);
7695 tcg_temp_free_i32(fp0);
7701 TCGv_i32 fp0 = tcg_temp_new_i32();
7703 gen_load_fpr32(fp0, fs);
7704 gen_helper_float_ceilw_s(fp0, cpu_env, fp0);
7705 gen_store_fpr32(fp0, fd);
7706 tcg_temp_free_i32(fp0);
7712 TCGv_i32 fp0 = tcg_temp_new_i32();
7714 gen_load_fpr32(fp0, fs);
7715 gen_helper_float_floorw_s(fp0, cpu_env, fp0);
7716 gen_store_fpr32(fp0, fd);
7717 tcg_temp_free_i32(fp0);
7722 gen_movcf_s(fs, fd, (ft >> 2) & 0x7, ft & 0x1);
7727 int l1 = gen_new_label();
7731 tcg_gen_brcondi_tl(TCG_COND_NE, cpu_gpr[ft], 0, l1);
7733 fp0 = tcg_temp_new_i32();
7734 gen_load_fpr32(fp0, fs);
7735 gen_store_fpr32(fp0, fd);
7736 tcg_temp_free_i32(fp0);
7743 int l1 = gen_new_label();
7747 tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_gpr[ft], 0, l1);
7748 fp0 = tcg_temp_new_i32();
7749 gen_load_fpr32(fp0, fs);
7750 gen_store_fpr32(fp0, fd);
7751 tcg_temp_free_i32(fp0);
7760 TCGv_i32 fp0 = tcg_temp_new_i32();
7762 gen_load_fpr32(fp0, fs);
7763 gen_helper_float_recip_s(fp0, cpu_env, fp0);
7764 gen_store_fpr32(fp0, fd);
7765 tcg_temp_free_i32(fp0);
7772 TCGv_i32 fp0 = tcg_temp_new_i32();
7774 gen_load_fpr32(fp0, fs);
7775 gen_helper_float_rsqrt_s(fp0, cpu_env, fp0);
7776 gen_store_fpr32(fp0, fd);
7777 tcg_temp_free_i32(fp0);
7782 check_cp1_64bitmode(ctx);
7784 TCGv_i32 fp0 = tcg_temp_new_i32();
7785 TCGv_i32 fp1 = tcg_temp_new_i32();
7787 gen_load_fpr32(fp0, fs);
7788 gen_load_fpr32(fp1, ft);
7789 gen_helper_float_recip2_s(fp0, cpu_env, fp0, fp1);
7790 tcg_temp_free_i32(fp1);
7791 gen_store_fpr32(fp0, fd);
7792 tcg_temp_free_i32(fp0);
7797 check_cp1_64bitmode(ctx);
7799 TCGv_i32 fp0 = tcg_temp_new_i32();
7801 gen_load_fpr32(fp0, fs);
7802 gen_helper_float_recip1_s(fp0, cpu_env, fp0);
7803 gen_store_fpr32(fp0, fd);
7804 tcg_temp_free_i32(fp0);
7809 check_cp1_64bitmode(ctx);
7811 TCGv_i32 fp0 = tcg_temp_new_i32();
7813 gen_load_fpr32(fp0, fs);
7814 gen_helper_float_rsqrt1_s(fp0, cpu_env, fp0);
7815 gen_store_fpr32(fp0, fd);
7816 tcg_temp_free_i32(fp0);
7821 check_cp1_64bitmode(ctx);
7823 TCGv_i32 fp0 = tcg_temp_new_i32();
7824 TCGv_i32 fp1 = tcg_temp_new_i32();
7826 gen_load_fpr32(fp0, fs);
7827 gen_load_fpr32(fp1, ft);
7828 gen_helper_float_rsqrt2_s(fp0, cpu_env, fp0, fp1);
7829 tcg_temp_free_i32(fp1);
7830 gen_store_fpr32(fp0, fd);
7831 tcg_temp_free_i32(fp0);
7836 check_cp1_registers(ctx, fd);
7838 TCGv_i32 fp32 = tcg_temp_new_i32();
7839 TCGv_i64 fp64 = tcg_temp_new_i64();
7841 gen_load_fpr32(fp32, fs);
7842 gen_helper_float_cvtd_s(fp64, cpu_env, fp32);
7843 tcg_temp_free_i32(fp32);
7844 gen_store_fpr64(ctx, fp64, fd);
7845 tcg_temp_free_i64(fp64);
7851 TCGv_i32 fp0 = tcg_temp_new_i32();
7853 gen_load_fpr32(fp0, fs);
7854 gen_helper_float_cvtw_s(fp0, cpu_env, fp0);
7855 gen_store_fpr32(fp0, fd);
7856 tcg_temp_free_i32(fp0);
7861 check_cp1_64bitmode(ctx);
7863 TCGv_i32 fp32 = tcg_temp_new_i32();
7864 TCGv_i64 fp64 = tcg_temp_new_i64();
7866 gen_load_fpr32(fp32, fs);
7867 gen_helper_float_cvtl_s(fp64, cpu_env, fp32);
7868 tcg_temp_free_i32(fp32);
7869 gen_store_fpr64(ctx, fp64, fd);
7870 tcg_temp_free_i64(fp64);
7875 check_cp1_64bitmode(ctx);
7877 TCGv_i64 fp64 = tcg_temp_new_i64();
7878 TCGv_i32 fp32_0 = tcg_temp_new_i32();
7879 TCGv_i32 fp32_1 = tcg_temp_new_i32();
7881 gen_load_fpr32(fp32_0, fs);
7882 gen_load_fpr32(fp32_1, ft);
7883 tcg_gen_concat_i32_i64(fp64, fp32_1, fp32_0);
7884 tcg_temp_free_i32(fp32_1);
7885 tcg_temp_free_i32(fp32_0);
7886 gen_store_fpr64(ctx, fp64, fd);
7887 tcg_temp_free_i64(fp64);
7900 case OPC_CMP_NGLE_S:
7907 if (ctx->opcode & (1 << 6)) {
7908 gen_cmpabs_s(ctx, func-48, ft, fs, cc);
7909 opn = condnames_abs[func-48];
7911 gen_cmp_s(ctx, func-48, ft, fs, cc);
7912 opn = condnames[func-48];
7916 check_cp1_registers(ctx, fs | ft | fd);
7918 TCGv_i64 fp0 = tcg_temp_new_i64();
7919 TCGv_i64 fp1 = tcg_temp_new_i64();
7921 gen_load_fpr64(ctx, fp0, fs);
7922 gen_load_fpr64(ctx, fp1, ft);
7923 gen_helper_float_add_d(fp0, cpu_env, fp0, fp1);
7924 tcg_temp_free_i64(fp1);
7925 gen_store_fpr64(ctx, fp0, fd);
7926 tcg_temp_free_i64(fp0);
7932 check_cp1_registers(ctx, fs | ft | fd);
7934 TCGv_i64 fp0 = tcg_temp_new_i64();
7935 TCGv_i64 fp1 = tcg_temp_new_i64();
7937 gen_load_fpr64(ctx, fp0, fs);
7938 gen_load_fpr64(ctx, fp1, ft);
7939 gen_helper_float_sub_d(fp0, cpu_env, fp0, fp1);
7940 tcg_temp_free_i64(fp1);
7941 gen_store_fpr64(ctx, fp0, fd);
7942 tcg_temp_free_i64(fp0);
7948 check_cp1_registers(ctx, fs | ft | fd);
7950 TCGv_i64 fp0 = tcg_temp_new_i64();
7951 TCGv_i64 fp1 = tcg_temp_new_i64();
7953 gen_load_fpr64(ctx, fp0, fs);
7954 gen_load_fpr64(ctx, fp1, ft);
7955 gen_helper_float_mul_d(fp0, cpu_env, fp0, fp1);
7956 tcg_temp_free_i64(fp1);
7957 gen_store_fpr64(ctx, fp0, fd);
7958 tcg_temp_free_i64(fp0);
7964 check_cp1_registers(ctx, fs | ft | fd);
7966 TCGv_i64 fp0 = tcg_temp_new_i64();
7967 TCGv_i64 fp1 = tcg_temp_new_i64();
7969 gen_load_fpr64(ctx, fp0, fs);
7970 gen_load_fpr64(ctx, fp1, ft);
7971 gen_helper_float_div_d(fp0, cpu_env, fp0, fp1);
7972 tcg_temp_free_i64(fp1);
7973 gen_store_fpr64(ctx, fp0, fd);
7974 tcg_temp_free_i64(fp0);
7980 check_cp1_registers(ctx, fs | fd);
7982 TCGv_i64 fp0 = tcg_temp_new_i64();
7984 gen_load_fpr64(ctx, fp0, fs);
7985 gen_helper_float_sqrt_d(fp0, cpu_env, fp0);
7986 gen_store_fpr64(ctx, fp0, fd);
7987 tcg_temp_free_i64(fp0);
7992 check_cp1_registers(ctx, fs | fd);
7994 TCGv_i64 fp0 = tcg_temp_new_i64();
7996 gen_load_fpr64(ctx, fp0, fs);
7997 gen_helper_float_abs_d(fp0, fp0);
7998 gen_store_fpr64(ctx, fp0, fd);
7999 tcg_temp_free_i64(fp0);
8004 check_cp1_registers(ctx, fs | fd);
8006 TCGv_i64 fp0 = tcg_temp_new_i64();
8008 gen_load_fpr64(ctx, fp0, fs);
8009 gen_store_fpr64(ctx, fp0, fd);
8010 tcg_temp_free_i64(fp0);
8015 check_cp1_registers(ctx, fs | fd);
8017 TCGv_i64 fp0 = tcg_temp_new_i64();
8019 gen_load_fpr64(ctx, fp0, fs);
8020 gen_helper_float_chs_d(fp0, fp0);
8021 gen_store_fpr64(ctx, fp0, fd);
8022 tcg_temp_free_i64(fp0);
8027 check_cp1_64bitmode(ctx);
8029 TCGv_i64 fp0 = tcg_temp_new_i64();
8031 gen_load_fpr64(ctx, fp0, fs);
8032 gen_helper_float_roundl_d(fp0, cpu_env, fp0);
8033 gen_store_fpr64(ctx, fp0, fd);
8034 tcg_temp_free_i64(fp0);
8039 check_cp1_64bitmode(ctx);
8041 TCGv_i64 fp0 = tcg_temp_new_i64();
8043 gen_load_fpr64(ctx, fp0, fs);
8044 gen_helper_float_truncl_d(fp0, cpu_env, fp0);
8045 gen_store_fpr64(ctx, fp0, fd);
8046 tcg_temp_free_i64(fp0);
8051 check_cp1_64bitmode(ctx);
8053 TCGv_i64 fp0 = tcg_temp_new_i64();
8055 gen_load_fpr64(ctx, fp0, fs);
8056 gen_helper_float_ceill_d(fp0, cpu_env, fp0);
8057 gen_store_fpr64(ctx, fp0, fd);
8058 tcg_temp_free_i64(fp0);
8063 check_cp1_64bitmode(ctx);
8065 TCGv_i64 fp0 = tcg_temp_new_i64();
8067 gen_load_fpr64(ctx, fp0, fs);
8068 gen_helper_float_floorl_d(fp0, cpu_env, fp0);
8069 gen_store_fpr64(ctx, fp0, fd);
8070 tcg_temp_free_i64(fp0);
8075 check_cp1_registers(ctx, fs);
8077 TCGv_i32 fp32 = tcg_temp_new_i32();
8078 TCGv_i64 fp64 = tcg_temp_new_i64();
8080 gen_load_fpr64(ctx, fp64, fs);
8081 gen_helper_float_roundw_d(fp32, cpu_env, fp64);
8082 tcg_temp_free_i64(fp64);
8083 gen_store_fpr32(fp32, fd);
8084 tcg_temp_free_i32(fp32);
8089 check_cp1_registers(ctx, fs);
8091 TCGv_i32 fp32 = tcg_temp_new_i32();
8092 TCGv_i64 fp64 = tcg_temp_new_i64();
8094 gen_load_fpr64(ctx, fp64, fs);
8095 gen_helper_float_truncw_d(fp32, cpu_env, fp64);
8096 tcg_temp_free_i64(fp64);
8097 gen_store_fpr32(fp32, fd);
8098 tcg_temp_free_i32(fp32);
8103 check_cp1_registers(ctx, fs);
8105 TCGv_i32 fp32 = tcg_temp_new_i32();
8106 TCGv_i64 fp64 = tcg_temp_new_i64();
8108 gen_load_fpr64(ctx, fp64, fs);
8109 gen_helper_float_ceilw_d(fp32, cpu_env, fp64);
8110 tcg_temp_free_i64(fp64);
8111 gen_store_fpr32(fp32, fd);
8112 tcg_temp_free_i32(fp32);
8117 check_cp1_registers(ctx, fs);
8119 TCGv_i32 fp32 = tcg_temp_new_i32();
8120 TCGv_i64 fp64 = tcg_temp_new_i64();
8122 gen_load_fpr64(ctx, fp64, fs);
8123 gen_helper_float_floorw_d(fp32, cpu_env, fp64);
8124 tcg_temp_free_i64(fp64);
8125 gen_store_fpr32(fp32, fd);
8126 tcg_temp_free_i32(fp32);
8131 gen_movcf_d(ctx, fs, fd, (ft >> 2) & 0x7, ft & 0x1);
8136 int l1 = gen_new_label();
8140 tcg_gen_brcondi_tl(TCG_COND_NE, cpu_gpr[ft], 0, l1);
8142 fp0 = tcg_temp_new_i64();
8143 gen_load_fpr64(ctx, fp0, fs);
8144 gen_store_fpr64(ctx, fp0, fd);
8145 tcg_temp_free_i64(fp0);
8152 int l1 = gen_new_label();
8156 tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_gpr[ft], 0, l1);
8157 fp0 = tcg_temp_new_i64();
8158 gen_load_fpr64(ctx, fp0, fs);
8159 gen_store_fpr64(ctx, fp0, fd);
8160 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_recip_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();
8183 gen_load_fpr64(ctx, fp0, fs);
8184 gen_helper_float_rsqrt_d(fp0, cpu_env, fp0);
8185 gen_store_fpr64(ctx, fp0, fd);
8186 tcg_temp_free_i64(fp0);
8191 check_cp1_64bitmode(ctx);
8193 TCGv_i64 fp0 = tcg_temp_new_i64();
8194 TCGv_i64 fp1 = tcg_temp_new_i64();
8196 gen_load_fpr64(ctx, fp0, fs);
8197 gen_load_fpr64(ctx, fp1, ft);
8198 gen_helper_float_recip2_d(fp0, cpu_env, fp0, fp1);
8199 tcg_temp_free_i64(fp1);
8200 gen_store_fpr64(ctx, fp0, fd);
8201 tcg_temp_free_i64(fp0);
8206 check_cp1_64bitmode(ctx);
8208 TCGv_i64 fp0 = tcg_temp_new_i64();
8210 gen_load_fpr64(ctx, fp0, fs);
8211 gen_helper_float_recip1_d(fp0, cpu_env, fp0);
8212 gen_store_fpr64(ctx, fp0, fd);
8213 tcg_temp_free_i64(fp0);
8218 check_cp1_64bitmode(ctx);
8220 TCGv_i64 fp0 = tcg_temp_new_i64();
8222 gen_load_fpr64(ctx, fp0, fs);
8223 gen_helper_float_rsqrt1_d(fp0, cpu_env, fp0);
8224 gen_store_fpr64(ctx, fp0, fd);
8225 tcg_temp_free_i64(fp0);
8230 check_cp1_64bitmode(ctx);
8232 TCGv_i64 fp0 = tcg_temp_new_i64();
8233 TCGv_i64 fp1 = tcg_temp_new_i64();
8235 gen_load_fpr64(ctx, fp0, fs);
8236 gen_load_fpr64(ctx, fp1, ft);
8237 gen_helper_float_rsqrt2_d(fp0, cpu_env, fp0, fp1);
8238 tcg_temp_free_i64(fp1);
8239 gen_store_fpr64(ctx, fp0, fd);
8240 tcg_temp_free_i64(fp0);
8253 case OPC_CMP_NGLE_D:
8260 if (ctx->opcode & (1 << 6)) {
8261 gen_cmpabs_d(ctx, func-48, ft, fs, cc);
8262 opn = condnames_abs[func-48];
8264 gen_cmp_d(ctx, func-48, ft, fs, cc);
8265 opn = condnames[func-48];
8269 check_cp1_registers(ctx, fs);
8271 TCGv_i32 fp32 = tcg_temp_new_i32();
8272 TCGv_i64 fp64 = tcg_temp_new_i64();
8274 gen_load_fpr64(ctx, fp64, fs);
8275 gen_helper_float_cvts_d(fp32, cpu_env, fp64);
8276 tcg_temp_free_i64(fp64);
8277 gen_store_fpr32(fp32, fd);
8278 tcg_temp_free_i32(fp32);
8283 check_cp1_registers(ctx, fs);
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_cvtw_d(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_cvtl_d(fp0, cpu_env, fp0);
8303 gen_store_fpr64(ctx, fp0, fd);
8304 tcg_temp_free_i64(fp0);
8310 TCGv_i32 fp0 = tcg_temp_new_i32();
8312 gen_load_fpr32(fp0, fs);
8313 gen_helper_float_cvts_w(fp0, cpu_env, fp0);
8314 gen_store_fpr32(fp0, fd);
8315 tcg_temp_free_i32(fp0);
8320 check_cp1_registers(ctx, fd);
8322 TCGv_i32 fp32 = tcg_temp_new_i32();
8323 TCGv_i64 fp64 = tcg_temp_new_i64();
8325 gen_load_fpr32(fp32, fs);
8326 gen_helper_float_cvtd_w(fp64, cpu_env, fp32);
8327 tcg_temp_free_i32(fp32);
8328 gen_store_fpr64(ctx, fp64, fd);
8329 tcg_temp_free_i64(fp64);
8334 check_cp1_64bitmode(ctx);
8336 TCGv_i32 fp32 = tcg_temp_new_i32();
8337 TCGv_i64 fp64 = tcg_temp_new_i64();
8339 gen_load_fpr64(ctx, fp64, fs);
8340 gen_helper_float_cvts_l(fp32, cpu_env, fp64);
8341 tcg_temp_free_i64(fp64);
8342 gen_store_fpr32(fp32, fd);
8343 tcg_temp_free_i32(fp32);
8348 check_cp1_64bitmode(ctx);
8350 TCGv_i64 fp0 = tcg_temp_new_i64();
8352 gen_load_fpr64(ctx, fp0, fs);
8353 gen_helper_float_cvtd_l(fp0, cpu_env, fp0);
8354 gen_store_fpr64(ctx, fp0, fd);
8355 tcg_temp_free_i64(fp0);
8360 check_cp1_64bitmode(ctx);
8362 TCGv_i64 fp0 = tcg_temp_new_i64();
8364 gen_load_fpr64(ctx, fp0, fs);
8365 gen_helper_float_cvtps_pw(fp0, cpu_env, fp0);
8366 gen_store_fpr64(ctx, fp0, fd);
8367 tcg_temp_free_i64(fp0);
8372 check_cp1_64bitmode(ctx);
8374 TCGv_i64 fp0 = tcg_temp_new_i64();
8375 TCGv_i64 fp1 = tcg_temp_new_i64();
8377 gen_load_fpr64(ctx, fp0, fs);
8378 gen_load_fpr64(ctx, fp1, ft);
8379 gen_helper_float_add_ps(fp0, cpu_env, fp0, fp1);
8380 tcg_temp_free_i64(fp1);
8381 gen_store_fpr64(ctx, fp0, fd);
8382 tcg_temp_free_i64(fp0);
8387 check_cp1_64bitmode(ctx);
8389 TCGv_i64 fp0 = tcg_temp_new_i64();
8390 TCGv_i64 fp1 = tcg_temp_new_i64();
8392 gen_load_fpr64(ctx, fp0, fs);
8393 gen_load_fpr64(ctx, fp1, ft);
8394 gen_helper_float_sub_ps(fp0, cpu_env, fp0, fp1);
8395 tcg_temp_free_i64(fp1);
8396 gen_store_fpr64(ctx, fp0, fd);
8397 tcg_temp_free_i64(fp0);
8402 check_cp1_64bitmode(ctx);
8404 TCGv_i64 fp0 = tcg_temp_new_i64();
8405 TCGv_i64 fp1 = tcg_temp_new_i64();
8407 gen_load_fpr64(ctx, fp0, fs);
8408 gen_load_fpr64(ctx, fp1, ft);
8409 gen_helper_float_mul_ps(fp0, cpu_env, fp0, fp1);
8410 tcg_temp_free_i64(fp1);
8411 gen_store_fpr64(ctx, fp0, fd);
8412 tcg_temp_free_i64(fp0);
8417 check_cp1_64bitmode(ctx);
8419 TCGv_i64 fp0 = tcg_temp_new_i64();
8421 gen_load_fpr64(ctx, fp0, fs);
8422 gen_helper_float_abs_ps(fp0, fp0);
8423 gen_store_fpr64(ctx, fp0, fd);
8424 tcg_temp_free_i64(fp0);
8429 check_cp1_64bitmode(ctx);
8431 TCGv_i64 fp0 = tcg_temp_new_i64();
8433 gen_load_fpr64(ctx, fp0, fs);
8434 gen_store_fpr64(ctx, fp0, fd);
8435 tcg_temp_free_i64(fp0);
8440 check_cp1_64bitmode(ctx);
8442 TCGv_i64 fp0 = tcg_temp_new_i64();
8444 gen_load_fpr64(ctx, fp0, fs);
8445 gen_helper_float_chs_ps(fp0, fp0);
8446 gen_store_fpr64(ctx, fp0, fd);
8447 tcg_temp_free_i64(fp0);
8452 check_cp1_64bitmode(ctx);
8453 gen_movcf_ps(fs, fd, (ft >> 2) & 0x7, ft & 0x1);
8457 check_cp1_64bitmode(ctx);
8459 int l1 = gen_new_label();
8463 tcg_gen_brcondi_tl(TCG_COND_NE, cpu_gpr[ft], 0, l1);
8464 fp0 = tcg_temp_new_i64();
8465 gen_load_fpr64(ctx, fp0, fs);
8466 gen_store_fpr64(ctx, fp0, fd);
8467 tcg_temp_free_i64(fp0);
8473 check_cp1_64bitmode(ctx);
8475 int l1 = gen_new_label();
8479 tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_gpr[ft], 0, l1);
8480 fp0 = tcg_temp_new_i64();
8481 gen_load_fpr64(ctx, fp0, fs);
8482 gen_store_fpr64(ctx, fp0, fd);
8483 tcg_temp_free_i64(fp0);
8490 check_cp1_64bitmode(ctx);
8492 TCGv_i64 fp0 = tcg_temp_new_i64();
8493 TCGv_i64 fp1 = tcg_temp_new_i64();
8495 gen_load_fpr64(ctx, fp0, ft);
8496 gen_load_fpr64(ctx, fp1, fs);
8497 gen_helper_float_addr_ps(fp0, cpu_env, fp0, fp1);
8498 tcg_temp_free_i64(fp1);
8499 gen_store_fpr64(ctx, fp0, fd);
8500 tcg_temp_free_i64(fp0);
8505 check_cp1_64bitmode(ctx);
8507 TCGv_i64 fp0 = tcg_temp_new_i64();
8508 TCGv_i64 fp1 = tcg_temp_new_i64();
8510 gen_load_fpr64(ctx, fp0, ft);
8511 gen_load_fpr64(ctx, fp1, fs);
8512 gen_helper_float_mulr_ps(fp0, cpu_env, fp0, fp1);
8513 tcg_temp_free_i64(fp1);
8514 gen_store_fpr64(ctx, fp0, fd);
8515 tcg_temp_free_i64(fp0);
8520 check_cp1_64bitmode(ctx);
8522 TCGv_i64 fp0 = tcg_temp_new_i64();
8523 TCGv_i64 fp1 = tcg_temp_new_i64();
8525 gen_load_fpr64(ctx, fp0, fs);
8526 gen_load_fpr64(ctx, fp1, ft);
8527 gen_helper_float_recip2_ps(fp0, cpu_env, fp0, fp1);
8528 tcg_temp_free_i64(fp1);
8529 gen_store_fpr64(ctx, fp0, fd);
8530 tcg_temp_free_i64(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_recip1_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_i64 fp0 = tcg_temp_new_i64();
8551 gen_load_fpr64(ctx, fp0, fs);
8552 gen_helper_float_rsqrt1_ps(fp0, cpu_env, fp0);
8553 gen_store_fpr64(ctx, fp0, fd);
8554 tcg_temp_free_i64(fp0);
8559 check_cp1_64bitmode(ctx);
8561 TCGv_i64 fp0 = tcg_temp_new_i64();
8562 TCGv_i64 fp1 = tcg_temp_new_i64();
8564 gen_load_fpr64(ctx, fp0, fs);
8565 gen_load_fpr64(ctx, fp1, ft);
8566 gen_helper_float_rsqrt2_ps(fp0, cpu_env, fp0, fp1);
8567 tcg_temp_free_i64(fp1);
8568 gen_store_fpr64(ctx, fp0, fd);
8569 tcg_temp_free_i64(fp0);
8574 check_cp1_64bitmode(ctx);
8576 TCGv_i32 fp0 = tcg_temp_new_i32();
8578 gen_load_fpr32h(fp0, fs);
8579 gen_helper_float_cvts_pu(fp0, cpu_env, fp0);
8580 gen_store_fpr32(fp0, fd);
8581 tcg_temp_free_i32(fp0);
8586 check_cp1_64bitmode(ctx);
8588 TCGv_i64 fp0 = tcg_temp_new_i64();
8590 gen_load_fpr64(ctx, fp0, fs);
8591 gen_helper_float_cvtpw_ps(fp0, cpu_env, fp0);
8592 gen_store_fpr64(ctx, fp0, fd);
8593 tcg_temp_free_i64(fp0);
8598 check_cp1_64bitmode(ctx);
8600 TCGv_i32 fp0 = tcg_temp_new_i32();
8602 gen_load_fpr32(fp0, fs);
8603 gen_helper_float_cvts_pl(fp0, cpu_env, fp0);
8604 gen_store_fpr32(fp0, fd);
8605 tcg_temp_free_i32(fp0);
8610 check_cp1_64bitmode(ctx);
8612 TCGv_i32 fp0 = tcg_temp_new_i32();
8613 TCGv_i32 fp1 = tcg_temp_new_i32();
8615 gen_load_fpr32(fp0, fs);
8616 gen_load_fpr32(fp1, ft);
8617 gen_store_fpr32h(fp0, fd);
8618 gen_store_fpr32(fp1, fd);
8619 tcg_temp_free_i32(fp0);
8620 tcg_temp_free_i32(fp1);
8625 check_cp1_64bitmode(ctx);
8627 TCGv_i32 fp0 = tcg_temp_new_i32();
8628 TCGv_i32 fp1 = tcg_temp_new_i32();
8630 gen_load_fpr32(fp0, fs);
8631 gen_load_fpr32h(fp1, ft);
8632 gen_store_fpr32(fp1, fd);
8633 gen_store_fpr32h(fp0, fd);
8634 tcg_temp_free_i32(fp0);
8635 tcg_temp_free_i32(fp1);
8640 check_cp1_64bitmode(ctx);
8642 TCGv_i32 fp0 = tcg_temp_new_i32();
8643 TCGv_i32 fp1 = tcg_temp_new_i32();
8645 gen_load_fpr32h(fp0, fs);
8646 gen_load_fpr32(fp1, ft);
8647 gen_store_fpr32(fp1, fd);
8648 gen_store_fpr32h(fp0, fd);
8649 tcg_temp_free_i32(fp0);
8650 tcg_temp_free_i32(fp1);
8655 check_cp1_64bitmode(ctx);
8657 TCGv_i32 fp0 = tcg_temp_new_i32();
8658 TCGv_i32 fp1 = tcg_temp_new_i32();
8660 gen_load_fpr32h(fp0, fs);
8661 gen_load_fpr32h(fp1, ft);
8662 gen_store_fpr32(fp1, fd);
8663 gen_store_fpr32h(fp0, fd);
8664 tcg_temp_free_i32(fp0);
8665 tcg_temp_free_i32(fp1);
8672 case OPC_CMP_UEQ_PS:
8673 case OPC_CMP_OLT_PS:
8674 case OPC_CMP_ULT_PS:
8675 case OPC_CMP_OLE_PS:
8676 case OPC_CMP_ULE_PS:
8678 case OPC_CMP_NGLE_PS:
8679 case OPC_CMP_SEQ_PS:
8680 case OPC_CMP_NGL_PS:
8682 case OPC_CMP_NGE_PS:
8684 case OPC_CMP_NGT_PS:
8685 if (ctx->opcode & (1 << 6)) {
8686 gen_cmpabs_ps(ctx, func-48, ft, fs, cc);
8687 opn = condnames_abs[func-48];
8689 gen_cmp_ps(ctx, func-48, ft, fs, cc);
8690 opn = condnames[func-48];
8695 generate_exception (ctx, EXCP_RI);
8698 (void)opn; /* avoid a compiler warning */
8701 MIPS_DEBUG("%s %s, %s, %s", opn, fregnames[fd], fregnames[fs], fregnames[ft]);
8704 MIPS_DEBUG("%s %s,%s", opn, fregnames[fs], fregnames[ft]);
8707 MIPS_DEBUG("%s %s,%s", opn, fregnames[fd], fregnames[fs]);
8712 /* Coprocessor 3 (FPU) */
8713 static void gen_flt3_ldst (DisasContext *ctx, uint32_t opc,
8714 int fd, int fs, int base, int index)
8716 const char *opn = "extended float load/store";
8718 TCGv t0 = tcg_temp_new();
8721 gen_load_gpr(t0, index);
8722 } else if (index == 0) {
8723 gen_load_gpr(t0, base);
8725 gen_op_addr_add(ctx, t0, cpu_gpr[base], cpu_gpr[index]);
8727 /* Don't do NOP if destination is zero: we must perform the actual
8729 save_cpu_state(ctx, 0);
8734 TCGv_i32 fp0 = tcg_temp_new_i32();
8736 tcg_gen_qemu_ld32s(t0, t0, ctx->mem_idx);
8737 tcg_gen_trunc_tl_i32(fp0, t0);
8738 gen_store_fpr32(fp0, fd);
8739 tcg_temp_free_i32(fp0);
8745 check_cp1_registers(ctx, fd);
8747 TCGv_i64 fp0 = tcg_temp_new_i64();
8749 tcg_gen_qemu_ld64(fp0, t0, ctx->mem_idx);
8750 gen_store_fpr64(ctx, fp0, fd);
8751 tcg_temp_free_i64(fp0);
8756 check_cp1_64bitmode(ctx);
8757 tcg_gen_andi_tl(t0, t0, ~0x7);
8759 TCGv_i64 fp0 = tcg_temp_new_i64();
8761 tcg_gen_qemu_ld64(fp0, t0, ctx->mem_idx);
8762 gen_store_fpr64(ctx, fp0, fd);
8763 tcg_temp_free_i64(fp0);
8770 TCGv_i32 fp0 = tcg_temp_new_i32();
8771 TCGv t1 = tcg_temp_new();
8773 gen_load_fpr32(fp0, fs);
8774 tcg_gen_extu_i32_tl(t1, fp0);
8775 tcg_gen_qemu_st32(t1, t0, ctx->mem_idx);
8776 tcg_temp_free_i32(fp0);
8784 check_cp1_registers(ctx, fs);
8786 TCGv_i64 fp0 = tcg_temp_new_i64();
8788 gen_load_fpr64(ctx, fp0, fs);
8789 tcg_gen_qemu_st64(fp0, t0, ctx->mem_idx);
8790 tcg_temp_free_i64(fp0);
8796 check_cp1_64bitmode(ctx);
8797 tcg_gen_andi_tl(t0, t0, ~0x7);
8799 TCGv_i64 fp0 = tcg_temp_new_i64();
8801 gen_load_fpr64(ctx, fp0, fs);
8802 tcg_gen_qemu_st64(fp0, t0, ctx->mem_idx);
8803 tcg_temp_free_i64(fp0);
8810 (void)opn; (void)store; /* avoid compiler warnings */
8811 MIPS_DEBUG("%s %s, %s(%s)", opn, fregnames[store ? fs : fd],
8812 regnames[index], regnames[base]);
8815 static void gen_flt3_arith (DisasContext *ctx, uint32_t opc,
8816 int fd, int fr, int fs, int ft)
8818 const char *opn = "flt3_arith";
8822 check_cp1_64bitmode(ctx);
8824 TCGv t0 = tcg_temp_local_new();
8825 TCGv_i32 fp = tcg_temp_new_i32();
8826 TCGv_i32 fph = tcg_temp_new_i32();
8827 int l1 = gen_new_label();
8828 int l2 = gen_new_label();
8830 gen_load_gpr(t0, fr);
8831 tcg_gen_andi_tl(t0, t0, 0x7);
8833 tcg_gen_brcondi_tl(TCG_COND_NE, t0, 0, l1);
8834 gen_load_fpr32(fp, fs);
8835 gen_load_fpr32h(fph, fs);
8836 gen_store_fpr32(fp, fd);
8837 gen_store_fpr32h(fph, fd);
8840 tcg_gen_brcondi_tl(TCG_COND_NE, t0, 4, l2);
8842 #ifdef TARGET_WORDS_BIGENDIAN
8843 gen_load_fpr32(fp, fs);
8844 gen_load_fpr32h(fph, ft);
8845 gen_store_fpr32h(fp, fd);
8846 gen_store_fpr32(fph, fd);
8848 gen_load_fpr32h(fph, fs);
8849 gen_load_fpr32(fp, ft);
8850 gen_store_fpr32(fph, fd);
8851 gen_store_fpr32h(fp, fd);
8854 tcg_temp_free_i32(fp);
8855 tcg_temp_free_i32(fph);
8862 TCGv_i32 fp0 = tcg_temp_new_i32();
8863 TCGv_i32 fp1 = tcg_temp_new_i32();
8864 TCGv_i32 fp2 = tcg_temp_new_i32();
8866 gen_load_fpr32(fp0, fs);
8867 gen_load_fpr32(fp1, ft);
8868 gen_load_fpr32(fp2, fr);
8869 gen_helper_float_muladd_s(fp2, cpu_env, fp0, fp1, fp2);
8870 tcg_temp_free_i32(fp0);
8871 tcg_temp_free_i32(fp1);
8872 gen_store_fpr32(fp2, fd);
8873 tcg_temp_free_i32(fp2);
8879 check_cp1_registers(ctx, fd | fs | ft | fr);
8881 TCGv_i64 fp0 = tcg_temp_new_i64();
8882 TCGv_i64 fp1 = tcg_temp_new_i64();
8883 TCGv_i64 fp2 = tcg_temp_new_i64();
8885 gen_load_fpr64(ctx, fp0, fs);
8886 gen_load_fpr64(ctx, fp1, ft);
8887 gen_load_fpr64(ctx, fp2, fr);
8888 gen_helper_float_muladd_d(fp2, cpu_env, fp0, fp1, fp2);
8889 tcg_temp_free_i64(fp0);
8890 tcg_temp_free_i64(fp1);
8891 gen_store_fpr64(ctx, fp2, fd);
8892 tcg_temp_free_i64(fp2);
8897 check_cp1_64bitmode(ctx);
8899 TCGv_i64 fp0 = tcg_temp_new_i64();
8900 TCGv_i64 fp1 = tcg_temp_new_i64();
8901 TCGv_i64 fp2 = tcg_temp_new_i64();
8903 gen_load_fpr64(ctx, fp0, fs);
8904 gen_load_fpr64(ctx, fp1, ft);
8905 gen_load_fpr64(ctx, fp2, fr);
8906 gen_helper_float_muladd_ps(fp2, cpu_env, fp0, fp1, fp2);
8907 tcg_temp_free_i64(fp0);
8908 tcg_temp_free_i64(fp1);
8909 gen_store_fpr64(ctx, fp2, fd);
8910 tcg_temp_free_i64(fp2);
8917 TCGv_i32 fp0 = tcg_temp_new_i32();
8918 TCGv_i32 fp1 = tcg_temp_new_i32();
8919 TCGv_i32 fp2 = tcg_temp_new_i32();
8921 gen_load_fpr32(fp0, fs);
8922 gen_load_fpr32(fp1, ft);
8923 gen_load_fpr32(fp2, fr);
8924 gen_helper_float_mulsub_s(fp2, cpu_env, fp0, fp1, fp2);
8925 tcg_temp_free_i32(fp0);
8926 tcg_temp_free_i32(fp1);
8927 gen_store_fpr32(fp2, fd);
8928 tcg_temp_free_i32(fp2);
8934 check_cp1_registers(ctx, fd | fs | ft | fr);
8936 TCGv_i64 fp0 = tcg_temp_new_i64();
8937 TCGv_i64 fp1 = tcg_temp_new_i64();
8938 TCGv_i64 fp2 = tcg_temp_new_i64();
8940 gen_load_fpr64(ctx, fp0, fs);
8941 gen_load_fpr64(ctx, fp1, ft);
8942 gen_load_fpr64(ctx, fp2, fr);
8943 gen_helper_float_mulsub_d(fp2, cpu_env, fp0, fp1, fp2);
8944 tcg_temp_free_i64(fp0);
8945 tcg_temp_free_i64(fp1);
8946 gen_store_fpr64(ctx, fp2, fd);
8947 tcg_temp_free_i64(fp2);
8952 check_cp1_64bitmode(ctx);
8954 TCGv_i64 fp0 = tcg_temp_new_i64();
8955 TCGv_i64 fp1 = tcg_temp_new_i64();
8956 TCGv_i64 fp2 = tcg_temp_new_i64();
8958 gen_load_fpr64(ctx, fp0, fs);
8959 gen_load_fpr64(ctx, fp1, ft);
8960 gen_load_fpr64(ctx, fp2, fr);
8961 gen_helper_float_mulsub_ps(fp2, cpu_env, fp0, fp1, fp2);
8962 tcg_temp_free_i64(fp0);
8963 tcg_temp_free_i64(fp1);
8964 gen_store_fpr64(ctx, fp2, fd);
8965 tcg_temp_free_i64(fp2);
8972 TCGv_i32 fp0 = tcg_temp_new_i32();
8973 TCGv_i32 fp1 = tcg_temp_new_i32();
8974 TCGv_i32 fp2 = tcg_temp_new_i32();
8976 gen_load_fpr32(fp0, fs);
8977 gen_load_fpr32(fp1, ft);
8978 gen_load_fpr32(fp2, fr);
8979 gen_helper_float_nmuladd_s(fp2, cpu_env, fp0, fp1, fp2);
8980 tcg_temp_free_i32(fp0);
8981 tcg_temp_free_i32(fp1);
8982 gen_store_fpr32(fp2, fd);
8983 tcg_temp_free_i32(fp2);
8989 check_cp1_registers(ctx, fd | fs | ft | fr);
8991 TCGv_i64 fp0 = tcg_temp_new_i64();
8992 TCGv_i64 fp1 = tcg_temp_new_i64();
8993 TCGv_i64 fp2 = tcg_temp_new_i64();
8995 gen_load_fpr64(ctx, fp0, fs);
8996 gen_load_fpr64(ctx, fp1, ft);
8997 gen_load_fpr64(ctx, fp2, fr);
8998 gen_helper_float_nmuladd_d(fp2, cpu_env, fp0, fp1, fp2);
8999 tcg_temp_free_i64(fp0);
9000 tcg_temp_free_i64(fp1);
9001 gen_store_fpr64(ctx, fp2, fd);
9002 tcg_temp_free_i64(fp2);
9007 check_cp1_64bitmode(ctx);
9009 TCGv_i64 fp0 = tcg_temp_new_i64();
9010 TCGv_i64 fp1 = tcg_temp_new_i64();
9011 TCGv_i64 fp2 = tcg_temp_new_i64();
9013 gen_load_fpr64(ctx, fp0, fs);
9014 gen_load_fpr64(ctx, fp1, ft);
9015 gen_load_fpr64(ctx, fp2, fr);
9016 gen_helper_float_nmuladd_ps(fp2, cpu_env, fp0, fp1, fp2);
9017 tcg_temp_free_i64(fp0);
9018 tcg_temp_free_i64(fp1);
9019 gen_store_fpr64(ctx, fp2, fd);
9020 tcg_temp_free_i64(fp2);
9027 TCGv_i32 fp0 = tcg_temp_new_i32();
9028 TCGv_i32 fp1 = tcg_temp_new_i32();
9029 TCGv_i32 fp2 = tcg_temp_new_i32();
9031 gen_load_fpr32(fp0, fs);
9032 gen_load_fpr32(fp1, ft);
9033 gen_load_fpr32(fp2, fr);
9034 gen_helper_float_nmulsub_s(fp2, cpu_env, fp0, fp1, fp2);
9035 tcg_temp_free_i32(fp0);
9036 tcg_temp_free_i32(fp1);
9037 gen_store_fpr32(fp2, fd);
9038 tcg_temp_free_i32(fp2);
9044 check_cp1_registers(ctx, fd | fs | ft | fr);
9046 TCGv_i64 fp0 = tcg_temp_new_i64();
9047 TCGv_i64 fp1 = tcg_temp_new_i64();
9048 TCGv_i64 fp2 = tcg_temp_new_i64();
9050 gen_load_fpr64(ctx, fp0, fs);
9051 gen_load_fpr64(ctx, fp1, ft);
9052 gen_load_fpr64(ctx, fp2, fr);
9053 gen_helper_float_nmulsub_d(fp2, cpu_env, fp0, fp1, fp2);
9054 tcg_temp_free_i64(fp0);
9055 tcg_temp_free_i64(fp1);
9056 gen_store_fpr64(ctx, fp2, fd);
9057 tcg_temp_free_i64(fp2);
9062 check_cp1_64bitmode(ctx);
9064 TCGv_i64 fp0 = tcg_temp_new_i64();
9065 TCGv_i64 fp1 = tcg_temp_new_i64();
9066 TCGv_i64 fp2 = tcg_temp_new_i64();
9068 gen_load_fpr64(ctx, fp0, fs);
9069 gen_load_fpr64(ctx, fp1, ft);
9070 gen_load_fpr64(ctx, fp2, fr);
9071 gen_helper_float_nmulsub_ps(fp2, cpu_env, fp0, fp1, fp2);
9072 tcg_temp_free_i64(fp0);
9073 tcg_temp_free_i64(fp1);
9074 gen_store_fpr64(ctx, fp2, fd);
9075 tcg_temp_free_i64(fp2);
9081 generate_exception (ctx, EXCP_RI);
9084 (void)opn; /* avoid a compiler warning */
9085 MIPS_DEBUG("%s %s, %s, %s, %s", opn, fregnames[fd], fregnames[fr],
9086 fregnames[fs], fregnames[ft]);
9090 gen_rdhwr (CPUMIPSState *env, DisasContext *ctx, int rt, int rd)
9094 #if !defined(CONFIG_USER_ONLY)
9095 /* The Linux kernel will emulate rdhwr if it's not supported natively.
9096 Therefore only check the ISA in system mode. */
9097 check_insn(env, ctx, ISA_MIPS32R2);
9099 t0 = tcg_temp_new();
9103 save_cpu_state(ctx, 1);
9104 gen_helper_rdhwr_cpunum(t0, cpu_env);
9105 gen_store_gpr(t0, rt);
9108 save_cpu_state(ctx, 1);
9109 gen_helper_rdhwr_synci_step(t0, cpu_env);
9110 gen_store_gpr(t0, rt);
9113 save_cpu_state(ctx, 1);
9114 gen_helper_rdhwr_cc(t0, cpu_env);
9115 gen_store_gpr(t0, rt);
9118 save_cpu_state(ctx, 1);
9119 gen_helper_rdhwr_ccres(t0, cpu_env);
9120 gen_store_gpr(t0, rt);
9123 #if defined(CONFIG_USER_ONLY)
9124 tcg_gen_ld_tl(t0, cpu_env, offsetof(CPUMIPSState, tls_value));
9125 gen_store_gpr(t0, rt);
9128 /* XXX: Some CPUs implement this in hardware.
9129 Not supported yet. */
9131 default: /* Invalid */
9132 MIPS_INVAL("rdhwr");
9133 generate_exception(ctx, EXCP_RI);
9139 static void handle_delay_slot (CPUMIPSState *env, DisasContext *ctx,
9142 if (ctx->hflags & MIPS_HFLAG_BMASK) {
9143 int proc_hflags = ctx->hflags & MIPS_HFLAG_BMASK;
9144 /* Branches completion */
9145 ctx->hflags &= ~MIPS_HFLAG_BMASK;
9146 ctx->bstate = BS_BRANCH;
9147 save_cpu_state(ctx, 0);
9148 /* FIXME: Need to clear can_do_io. */
9149 switch (proc_hflags & MIPS_HFLAG_BMASK_BASE) {
9151 /* unconditional branch */
9152 MIPS_DEBUG("unconditional branch");
9153 if (proc_hflags & MIPS_HFLAG_BX) {
9154 tcg_gen_xori_i32(hflags, hflags, MIPS_HFLAG_M16);
9156 gen_goto_tb(ctx, 0, ctx->btarget);
9159 /* blikely taken case */
9160 MIPS_DEBUG("blikely branch taken");
9161 gen_goto_tb(ctx, 0, ctx->btarget);
9164 /* Conditional branch */
9165 MIPS_DEBUG("conditional branch");
9167 int l1 = gen_new_label();
9169 tcg_gen_brcondi_tl(TCG_COND_NE, bcond, 0, l1);
9170 gen_goto_tb(ctx, 1, ctx->pc + insn_bytes);
9172 gen_goto_tb(ctx, 0, ctx->btarget);
9176 /* unconditional branch to register */
9177 MIPS_DEBUG("branch to register");
9178 if (env->insn_flags & (ASE_MIPS16 | ASE_MICROMIPS)) {
9179 TCGv t0 = tcg_temp_new();
9180 TCGv_i32 t1 = tcg_temp_new_i32();
9182 tcg_gen_andi_tl(t0, btarget, 0x1);
9183 tcg_gen_trunc_tl_i32(t1, t0);
9185 tcg_gen_andi_i32(hflags, hflags, ~(uint32_t)MIPS_HFLAG_M16);
9186 tcg_gen_shli_i32(t1, t1, MIPS_HFLAG_M16_SHIFT);
9187 tcg_gen_or_i32(hflags, hflags, t1);
9188 tcg_temp_free_i32(t1);
9190 tcg_gen_andi_tl(cpu_PC, btarget, ~(target_ulong)0x1);
9192 tcg_gen_mov_tl(cpu_PC, btarget);
9194 if (ctx->singlestep_enabled) {
9195 save_cpu_state(ctx, 0);
9196 gen_helper_0e0i(raise_exception, EXCP_DEBUG);
9201 MIPS_DEBUG("unknown branch");
9207 /* ISA extensions (ASEs) */
9208 /* MIPS16 extension to MIPS32 */
9210 /* MIPS16 major opcodes */
9212 M16_OPC_ADDIUSP = 0x00,
9213 M16_OPC_ADDIUPC = 0x01,
9216 M16_OPC_BEQZ = 0x04,
9217 M16_OPC_BNEQZ = 0x05,
9218 M16_OPC_SHIFT = 0x06,
9220 M16_OPC_RRIA = 0x08,
9221 M16_OPC_ADDIU8 = 0x09,
9222 M16_OPC_SLTI = 0x0a,
9223 M16_OPC_SLTIU = 0x0b,
9226 M16_OPC_CMPI = 0x0e,
9230 M16_OPC_LWSP = 0x12,
9234 M16_OPC_LWPC = 0x16,
9238 M16_OPC_SWSP = 0x1a,
9242 M16_OPC_EXTEND = 0x1e,
9246 /* I8 funct field */
9265 /* RR funct field */
9299 /* I64 funct field */
9311 /* RR ry field for CNVT */
9313 RR_RY_CNVT_ZEB = 0x0,
9314 RR_RY_CNVT_ZEH = 0x1,
9315 RR_RY_CNVT_ZEW = 0x2,
9316 RR_RY_CNVT_SEB = 0x4,
9317 RR_RY_CNVT_SEH = 0x5,
9318 RR_RY_CNVT_SEW = 0x6,
9321 static int xlat (int r)
9323 static int map[] = { 16, 17, 2, 3, 4, 5, 6, 7 };
9328 static void gen_mips16_save (DisasContext *ctx,
9329 int xsregs, int aregs,
9330 int do_ra, int do_s0, int do_s1,
9333 TCGv t0 = tcg_temp_new();
9334 TCGv t1 = tcg_temp_new();
9364 generate_exception(ctx, EXCP_RI);
9370 gen_base_offset_addr(ctx, t0, 29, 12);
9371 gen_load_gpr(t1, 7);
9372 op_st_sw(t1, t0, ctx);
9375 gen_base_offset_addr(ctx, t0, 29, 8);
9376 gen_load_gpr(t1, 6);
9377 op_st_sw(t1, t0, ctx);
9380 gen_base_offset_addr(ctx, t0, 29, 4);
9381 gen_load_gpr(t1, 5);
9382 op_st_sw(t1, t0, ctx);
9385 gen_base_offset_addr(ctx, t0, 29, 0);
9386 gen_load_gpr(t1, 4);
9387 op_st_sw(t1, t0, ctx);
9390 gen_load_gpr(t0, 29);
9392 #define DECR_AND_STORE(reg) do { \
9393 tcg_gen_subi_tl(t0, t0, 4); \
9394 gen_load_gpr(t1, reg); \
9395 op_st_sw(t1, t0, ctx); \
9459 generate_exception(ctx, EXCP_RI);
9475 #undef DECR_AND_STORE
9477 tcg_gen_subi_tl(cpu_gpr[29], cpu_gpr[29], framesize);
9482 static void gen_mips16_restore (DisasContext *ctx,
9483 int xsregs, int aregs,
9484 int do_ra, int do_s0, int do_s1,
9488 TCGv t0 = tcg_temp_new();
9489 TCGv t1 = tcg_temp_new();
9491 tcg_gen_addi_tl(t0, cpu_gpr[29], framesize);
9493 #define DECR_AND_LOAD(reg) do { \
9494 tcg_gen_subi_tl(t0, t0, 4); \
9495 op_ld_lw(t1, t0, ctx); \
9496 gen_store_gpr(t1, reg); \
9560 generate_exception(ctx, EXCP_RI);
9576 #undef DECR_AND_LOAD
9578 tcg_gen_addi_tl(cpu_gpr[29], cpu_gpr[29], framesize);
9583 static void gen_addiupc (DisasContext *ctx, int rx, int imm,
9584 int is_64_bit, int extended)
9588 if (extended && (ctx->hflags & MIPS_HFLAG_BMASK)) {
9589 generate_exception(ctx, EXCP_RI);
9593 t0 = tcg_temp_new();
9595 tcg_gen_movi_tl(t0, pc_relative_pc(ctx));
9596 tcg_gen_addi_tl(cpu_gpr[rx], t0, imm);
9598 tcg_gen_ext32s_tl(cpu_gpr[rx], cpu_gpr[rx]);
9604 #if defined(TARGET_MIPS64)
9605 static void decode_i64_mips16 (CPUMIPSState *env, DisasContext *ctx,
9606 int ry, int funct, int16_t offset,
9612 offset = extended ? offset : offset << 3;
9613 gen_ld(env, ctx, OPC_LD, ry, 29, offset);
9617 offset = extended ? offset : offset << 3;
9618 gen_st(ctx, OPC_SD, ry, 29, offset);
9622 offset = extended ? offset : (ctx->opcode & 0xff) << 3;
9623 gen_st(ctx, OPC_SD, 31, 29, offset);
9627 offset = extended ? offset : ((int8_t)ctx->opcode) << 3;
9628 gen_arith_imm(env, ctx, OPC_DADDIU, 29, 29, offset);
9631 if (extended && (ctx->hflags & MIPS_HFLAG_BMASK)) {
9632 generate_exception(ctx, EXCP_RI);
9634 offset = extended ? offset : offset << 3;
9635 gen_ld(env, ctx, OPC_LDPC, ry, 0, offset);
9640 offset = extended ? offset : ((int8_t)(offset << 3)) >> 3;
9641 gen_arith_imm(env, ctx, OPC_DADDIU, ry, ry, offset);
9645 offset = extended ? offset : offset << 2;
9646 gen_addiupc(ctx, ry, offset, 1, extended);
9650 offset = extended ? offset : offset << 2;
9651 gen_arith_imm(env, ctx, OPC_DADDIU, ry, 29, offset);
9657 static int decode_extended_mips16_opc (CPUMIPSState *env, DisasContext *ctx,
9660 int extend = cpu_lduw_code(env, ctx->pc + 2);
9661 int op, rx, ry, funct, sa;
9662 int16_t imm, offset;
9664 ctx->opcode = (ctx->opcode << 16) | extend;
9665 op = (ctx->opcode >> 11) & 0x1f;
9666 sa = (ctx->opcode >> 22) & 0x1f;
9667 funct = (ctx->opcode >> 8) & 0x7;
9668 rx = xlat((ctx->opcode >> 8) & 0x7);
9669 ry = xlat((ctx->opcode >> 5) & 0x7);
9670 offset = imm = (int16_t) (((ctx->opcode >> 16) & 0x1f) << 11
9671 | ((ctx->opcode >> 21) & 0x3f) << 5
9672 | (ctx->opcode & 0x1f));
9674 /* The extended opcodes cleverly reuse the opcodes from their 16-bit
9677 case M16_OPC_ADDIUSP:
9678 gen_arith_imm(env, ctx, OPC_ADDIU, rx, 29, imm);
9680 case M16_OPC_ADDIUPC:
9681 gen_addiupc(ctx, rx, imm, 0, 1);
9684 gen_compute_branch(ctx, OPC_BEQ, 4, 0, 0, offset << 1);
9685 /* No delay slot, so just process as a normal instruction */
9688 gen_compute_branch(ctx, OPC_BEQ, 4, rx, 0, offset << 1);
9689 /* No delay slot, so just process as a normal instruction */
9692 gen_compute_branch(ctx, OPC_BNE, 4, rx, 0, offset << 1);
9693 /* No delay slot, so just process as a normal instruction */
9696 switch (ctx->opcode & 0x3) {
9698 gen_shift_imm(env, ctx, OPC_SLL, rx, ry, sa);
9701 #if defined(TARGET_MIPS64)
9703 gen_shift_imm(env, ctx, OPC_DSLL, rx, ry, sa);
9705 generate_exception(ctx, EXCP_RI);
9709 gen_shift_imm(env, ctx, OPC_SRL, rx, ry, sa);
9712 gen_shift_imm(env, ctx, OPC_SRA, rx, ry, sa);
9716 #if defined(TARGET_MIPS64)
9719 gen_ld(env, ctx, OPC_LD, ry, rx, offset);
9723 imm = ctx->opcode & 0xf;
9724 imm = imm | ((ctx->opcode >> 20) & 0x7f) << 4;
9725 imm = imm | ((ctx->opcode >> 16) & 0xf) << 11;
9726 imm = (int16_t) (imm << 1) >> 1;
9727 if ((ctx->opcode >> 4) & 0x1) {
9728 #if defined(TARGET_MIPS64)
9730 gen_arith_imm(env, ctx, OPC_DADDIU, ry, rx, imm);
9732 generate_exception(ctx, EXCP_RI);
9735 gen_arith_imm(env, ctx, OPC_ADDIU, ry, rx, imm);
9738 case M16_OPC_ADDIU8:
9739 gen_arith_imm(env, ctx, OPC_ADDIU, rx, rx, imm);
9742 gen_slt_imm(env, ctx, OPC_SLTI, 24, rx, imm);
9745 gen_slt_imm(env, ctx, OPC_SLTIU, 24, rx, imm);
9750 gen_compute_branch(ctx, OPC_BEQ, 4, 24, 0, offset << 1);
9753 gen_compute_branch(ctx, OPC_BNE, 4, 24, 0, offset << 1);
9756 gen_st(ctx, OPC_SW, 31, 29, imm);
9759 gen_arith_imm(env, ctx, OPC_ADDIU, 29, 29, imm);
9763 int xsregs = (ctx->opcode >> 24) & 0x7;
9764 int aregs = (ctx->opcode >> 16) & 0xf;
9765 int do_ra = (ctx->opcode >> 6) & 0x1;
9766 int do_s0 = (ctx->opcode >> 5) & 0x1;
9767 int do_s1 = (ctx->opcode >> 4) & 0x1;
9768 int framesize = (((ctx->opcode >> 20) & 0xf) << 4
9769 | (ctx->opcode & 0xf)) << 3;
9771 if (ctx->opcode & (1 << 7)) {
9772 gen_mips16_save(ctx, xsregs, aregs,
9773 do_ra, do_s0, do_s1,
9776 gen_mips16_restore(ctx, xsregs, aregs,
9777 do_ra, do_s0, do_s1,
9783 generate_exception(ctx, EXCP_RI);
9788 tcg_gen_movi_tl(cpu_gpr[rx], (uint16_t) imm);
9791 tcg_gen_xori_tl(cpu_gpr[24], cpu_gpr[rx], (uint16_t) imm);
9793 #if defined(TARGET_MIPS64)
9795 gen_st(ctx, OPC_SD, ry, rx, offset);
9799 gen_ld(env, ctx, OPC_LB, ry, rx, offset);
9802 gen_ld(env, ctx, OPC_LH, ry, rx, offset);
9805 gen_ld(env, ctx, OPC_LW, rx, 29, offset);
9808 gen_ld(env, ctx, OPC_LW, ry, rx, offset);
9811 gen_ld(env, ctx, OPC_LBU, ry, rx, offset);
9814 gen_ld(env, ctx, OPC_LHU, ry, rx, offset);
9817 gen_ld(env, ctx, OPC_LWPC, rx, 0, offset);
9819 #if defined(TARGET_MIPS64)
9821 gen_ld(env, ctx, OPC_LWU, ry, rx, offset);
9825 gen_st(ctx, OPC_SB, ry, rx, offset);
9828 gen_st(ctx, OPC_SH, ry, rx, offset);
9831 gen_st(ctx, OPC_SW, rx, 29, offset);
9834 gen_st(ctx, OPC_SW, ry, rx, offset);
9836 #if defined(TARGET_MIPS64)
9838 decode_i64_mips16(env, ctx, ry, funct, offset, 1);
9842 generate_exception(ctx, EXCP_RI);
9849 static int decode_mips16_opc (CPUMIPSState *env, DisasContext *ctx,
9854 int op, cnvt_op, op1, offset;
9858 op = (ctx->opcode >> 11) & 0x1f;
9859 sa = (ctx->opcode >> 2) & 0x7;
9860 sa = sa == 0 ? 8 : sa;
9861 rx = xlat((ctx->opcode >> 8) & 0x7);
9862 cnvt_op = (ctx->opcode >> 5) & 0x7;
9863 ry = xlat((ctx->opcode >> 5) & 0x7);
9864 op1 = offset = ctx->opcode & 0x1f;
9869 case M16_OPC_ADDIUSP:
9871 int16_t imm = ((uint8_t) ctx->opcode) << 2;
9873 gen_arith_imm(env, ctx, OPC_ADDIU, rx, 29, imm);
9876 case M16_OPC_ADDIUPC:
9877 gen_addiupc(ctx, rx, ((uint8_t) ctx->opcode) << 2, 0, 0);
9880 offset = (ctx->opcode & 0x7ff) << 1;
9881 offset = (int16_t)(offset << 4) >> 4;
9882 gen_compute_branch(ctx, OPC_BEQ, 2, 0, 0, offset);
9883 /* No delay slot, so just process as a normal instruction */
9886 offset = cpu_lduw_code(env, ctx->pc + 2);
9887 offset = (((ctx->opcode & 0x1f) << 21)
9888 | ((ctx->opcode >> 5) & 0x1f) << 16
9890 op = ((ctx->opcode >> 10) & 0x1) ? OPC_JALXS : OPC_JALS;
9891 gen_compute_branch(ctx, op, 4, rx, ry, offset);
9896 gen_compute_branch(ctx, OPC_BEQ, 2, rx, 0, ((int8_t)ctx->opcode) << 1);
9897 /* No delay slot, so just process as a normal instruction */
9900 gen_compute_branch(ctx, OPC_BNE, 2, rx, 0, ((int8_t)ctx->opcode) << 1);
9901 /* No delay slot, so just process as a normal instruction */
9904 switch (ctx->opcode & 0x3) {
9906 gen_shift_imm(env, ctx, OPC_SLL, rx, ry, sa);
9909 #if defined(TARGET_MIPS64)
9911 gen_shift_imm(env, ctx, OPC_DSLL, rx, ry, sa);
9913 generate_exception(ctx, EXCP_RI);
9917 gen_shift_imm(env, ctx, OPC_SRL, rx, ry, sa);
9920 gen_shift_imm(env, ctx, OPC_SRA, rx, ry, sa);
9924 #if defined(TARGET_MIPS64)
9927 gen_ld(env, ctx, OPC_LD, ry, rx, offset << 3);
9932 int16_t imm = (int8_t)((ctx->opcode & 0xf) << 4) >> 4;
9934 if ((ctx->opcode >> 4) & 1) {
9935 #if defined(TARGET_MIPS64)
9937 gen_arith_imm(env, ctx, OPC_DADDIU, ry, rx, imm);
9939 generate_exception(ctx, EXCP_RI);
9942 gen_arith_imm(env, ctx, OPC_ADDIU, ry, rx, imm);
9946 case M16_OPC_ADDIU8:
9948 int16_t imm = (int8_t) ctx->opcode;
9950 gen_arith_imm(env, ctx, OPC_ADDIU, rx, rx, imm);
9955 int16_t imm = (uint8_t) ctx->opcode;
9956 gen_slt_imm(env, ctx, OPC_SLTI, 24, rx, imm);
9961 int16_t imm = (uint8_t) ctx->opcode;
9962 gen_slt_imm(env, ctx, OPC_SLTIU, 24, rx, imm);
9969 funct = (ctx->opcode >> 8) & 0x7;
9972 gen_compute_branch(ctx, OPC_BEQ, 2, 24, 0,
9973 ((int8_t)ctx->opcode) << 1);
9976 gen_compute_branch(ctx, OPC_BNE, 2, 24, 0,
9977 ((int8_t)ctx->opcode) << 1);
9980 gen_st(ctx, OPC_SW, 31, 29, (ctx->opcode & 0xff) << 2);
9983 gen_arith_imm(env, ctx, OPC_ADDIU, 29, 29,
9984 ((int8_t)ctx->opcode) << 3);
9988 int do_ra = ctx->opcode & (1 << 6);
9989 int do_s0 = ctx->opcode & (1 << 5);
9990 int do_s1 = ctx->opcode & (1 << 4);
9991 int framesize = ctx->opcode & 0xf;
9993 if (framesize == 0) {
9996 framesize = framesize << 3;
9999 if (ctx->opcode & (1 << 7)) {
10000 gen_mips16_save(ctx, 0, 0,
10001 do_ra, do_s0, do_s1, framesize);
10003 gen_mips16_restore(ctx, 0, 0,
10004 do_ra, do_s0, do_s1, framesize);
10010 int rz = xlat(ctx->opcode & 0x7);
10012 reg32 = (((ctx->opcode >> 3) & 0x3) << 3) |
10013 ((ctx->opcode >> 5) & 0x7);
10014 gen_arith(env, ctx, OPC_ADDU, reg32, rz, 0);
10018 reg32 = ctx->opcode & 0x1f;
10019 gen_arith(env, ctx, OPC_ADDU, ry, reg32, 0);
10022 generate_exception(ctx, EXCP_RI);
10029 int16_t imm = (uint8_t) ctx->opcode;
10031 gen_arith_imm(env, ctx, OPC_ADDIU, rx, 0, imm);
10036 int16_t imm = (uint8_t) ctx->opcode;
10037 gen_logic_imm(env, ctx, OPC_XORI, 24, rx, imm);
10040 #if defined(TARGET_MIPS64)
10042 check_mips_64(ctx);
10043 gen_st(ctx, OPC_SD, ry, rx, offset << 3);
10047 gen_ld(env, ctx, OPC_LB, ry, rx, offset);
10050 gen_ld(env, ctx, OPC_LH, ry, rx, offset << 1);
10053 gen_ld(env, ctx, OPC_LW, rx, 29, ((uint8_t)ctx->opcode) << 2);
10056 gen_ld(env, ctx, OPC_LW, ry, rx, offset << 2);
10059 gen_ld(env, ctx, OPC_LBU, ry, rx, offset);
10062 gen_ld(env, ctx, OPC_LHU, ry, rx, offset << 1);
10065 gen_ld(env, ctx, OPC_LWPC, rx, 0, ((uint8_t)ctx->opcode) << 2);
10067 #if defined (TARGET_MIPS64)
10069 check_mips_64(ctx);
10070 gen_ld(env, ctx, OPC_LWU, ry, rx, offset << 2);
10074 gen_st(ctx, OPC_SB, ry, rx, offset);
10077 gen_st(ctx, OPC_SH, ry, rx, offset << 1);
10080 gen_st(ctx, OPC_SW, rx, 29, ((uint8_t)ctx->opcode) << 2);
10083 gen_st(ctx, OPC_SW, ry, rx, offset << 2);
10087 int rz = xlat((ctx->opcode >> 2) & 0x7);
10090 switch (ctx->opcode & 0x3) {
10092 mips32_op = OPC_ADDU;
10095 mips32_op = OPC_SUBU;
10097 #if defined(TARGET_MIPS64)
10099 mips32_op = OPC_DADDU;
10100 check_mips_64(ctx);
10103 mips32_op = OPC_DSUBU;
10104 check_mips_64(ctx);
10108 generate_exception(ctx, EXCP_RI);
10112 gen_arith(env, ctx, mips32_op, rz, rx, ry);
10121 int nd = (ctx->opcode >> 7) & 0x1;
10122 int link = (ctx->opcode >> 6) & 0x1;
10123 int ra = (ctx->opcode >> 5) & 0x1;
10126 op = nd ? OPC_JALRC : OPC_JALRS;
10131 gen_compute_branch(ctx, op, 2, ra ? 31 : rx, 31, 0);
10138 /* XXX: not clear which exception should be raised
10139 * when in debug mode...
10141 check_insn(env, ctx, ISA_MIPS32);
10142 if (!(ctx->hflags & MIPS_HFLAG_DM)) {
10143 generate_exception(ctx, EXCP_DBp);
10145 generate_exception(ctx, EXCP_DBp);
10149 gen_slt(env, ctx, OPC_SLT, 24, rx, ry);
10152 gen_slt(env, ctx, OPC_SLTU, 24, rx, ry);
10155 generate_exception(ctx, EXCP_BREAK);
10158 gen_shift(env, ctx, OPC_SLLV, ry, rx, ry);
10161 gen_shift(env, ctx, OPC_SRLV, ry, rx, ry);
10164 gen_shift(env, ctx, OPC_SRAV, ry, rx, ry);
10166 #if defined (TARGET_MIPS64)
10168 check_mips_64(ctx);
10169 gen_shift_imm(env, ctx, OPC_DSRL, ry, ry, sa);
10173 gen_logic(env, ctx, OPC_XOR, 24, rx, ry);
10176 gen_arith(env, ctx, OPC_SUBU, rx, 0, ry);
10179 gen_logic(env, ctx, OPC_AND, rx, rx, ry);
10182 gen_logic(env, ctx, OPC_OR, rx, rx, ry);
10185 gen_logic(env, ctx, OPC_XOR, rx, rx, ry);
10188 gen_logic(env, ctx, OPC_NOR, rx, ry, 0);
10191 gen_HILO(ctx, OPC_MFHI, rx);
10195 case RR_RY_CNVT_ZEB:
10196 tcg_gen_ext8u_tl(cpu_gpr[rx], cpu_gpr[rx]);
10198 case RR_RY_CNVT_ZEH:
10199 tcg_gen_ext16u_tl(cpu_gpr[rx], cpu_gpr[rx]);
10201 case RR_RY_CNVT_SEB:
10202 tcg_gen_ext8s_tl(cpu_gpr[rx], cpu_gpr[rx]);
10204 case RR_RY_CNVT_SEH:
10205 tcg_gen_ext16s_tl(cpu_gpr[rx], cpu_gpr[rx]);
10207 #if defined (TARGET_MIPS64)
10208 case RR_RY_CNVT_ZEW:
10209 check_mips_64(ctx);
10210 tcg_gen_ext32u_tl(cpu_gpr[rx], cpu_gpr[rx]);
10212 case RR_RY_CNVT_SEW:
10213 check_mips_64(ctx);
10214 tcg_gen_ext32s_tl(cpu_gpr[rx], cpu_gpr[rx]);
10218 generate_exception(ctx, EXCP_RI);
10223 gen_HILO(ctx, OPC_MFLO, rx);
10225 #if defined (TARGET_MIPS64)
10227 check_mips_64(ctx);
10228 gen_shift_imm(env, ctx, OPC_DSRA, ry, ry, sa);
10231 check_mips_64(ctx);
10232 gen_shift(env, ctx, OPC_DSLLV, ry, rx, ry);
10235 check_mips_64(ctx);
10236 gen_shift(env, ctx, OPC_DSRLV, ry, rx, ry);
10239 check_mips_64(ctx);
10240 gen_shift(env, ctx, OPC_DSRAV, ry, rx, ry);
10244 gen_muldiv(ctx, OPC_MULT, rx, ry);
10247 gen_muldiv(ctx, OPC_MULTU, rx, ry);
10250 gen_muldiv(ctx, OPC_DIV, rx, ry);
10253 gen_muldiv(ctx, OPC_DIVU, rx, ry);
10255 #if defined (TARGET_MIPS64)
10257 check_mips_64(ctx);
10258 gen_muldiv(ctx, OPC_DMULT, rx, ry);
10261 check_mips_64(ctx);
10262 gen_muldiv(ctx, OPC_DMULTU, rx, ry);
10265 check_mips_64(ctx);
10266 gen_muldiv(ctx, OPC_DDIV, rx, ry);
10269 check_mips_64(ctx);
10270 gen_muldiv(ctx, OPC_DDIVU, rx, ry);
10274 generate_exception(ctx, EXCP_RI);
10278 case M16_OPC_EXTEND:
10279 decode_extended_mips16_opc(env, ctx, is_branch);
10282 #if defined(TARGET_MIPS64)
10284 funct = (ctx->opcode >> 8) & 0x7;
10285 decode_i64_mips16(env, ctx, ry, funct, offset, 0);
10289 generate_exception(ctx, EXCP_RI);
10296 /* microMIPS extension to MIPS32 */
10298 /* microMIPS32 major opcodes */
10337 /* 0x20 is reserved */
10347 /* 0x28 and 0x29 are reserved */
10357 /* 0x30 and 0x31 are reserved */
10367 /* 0x38 and 0x39 are reserved */
10378 /* POOL32A encoding of minor opcode field */
10381 /* These opcodes are distinguished only by bits 9..6; those bits are
10382 * what are recorded below. */
10408 /* The following can be distinguished by their lower 6 bits. */
10414 /* POOL32AXF encoding of minor opcode field extension */
10428 /* bits 13..12 for 0x01 */
10434 /* bits 13..12 for 0x2a */
10440 /* bits 13..12 for 0x32 */
10444 /* bits 15..12 for 0x2c */
10460 /* bits 15..12 for 0x34 */
10468 /* bits 15..12 for 0x3c */
10470 JR = 0x0, /* alias */
10475 /* bits 15..12 for 0x05 */
10479 /* bits 15..12 for 0x0d */
10489 /* bits 15..12 for 0x15 */
10495 /* bits 15..12 for 0x1d */
10499 /* bits 15..12 for 0x2d */
10504 /* bits 15..12 for 0x35 */
10511 /* POOL32B encoding of minor opcode field (bits 15..12) */
10527 /* POOL32C encoding of minor opcode field (bits 15..12) */
10535 /* 0xa is reserved */
10542 /* 0x6 is reserved */
10548 /* POOL32F encoding of minor opcode field (bits 5..0) */
10551 /* These are the bit 7..6 values */
10562 /* These are the bit 8..6 values */
10606 CABS_COND_FMT = 0x1c, /* MIPS3D */
10610 /* POOL32Fxf encoding of minor opcode extension field */
10648 /* POOL32I encoding of minor opcode field (bits 25..21) */
10673 /* These overlap and are distinguished by bit16 of the instruction */
10682 /* POOL16A encoding of minor opcode field */
10689 /* POOL16B encoding of minor opcode field */
10696 /* POOL16C encoding of minor opcode field */
10716 /* POOL16D encoding of minor opcode field */
10723 /* POOL16E encoding of minor opcode field */
10730 static int mmreg (int r)
10732 static const int map[] = { 16, 17, 2, 3, 4, 5, 6, 7 };
10737 /* Used for 16-bit store instructions. */
10738 static int mmreg2 (int r)
10740 static const int map[] = { 0, 17, 2, 3, 4, 5, 6, 7 };
10745 #define uMIPS_RD(op) ((op >> 7) & 0x7)
10746 #define uMIPS_RS(op) ((op >> 4) & 0x7)
10747 #define uMIPS_RS2(op) uMIPS_RS(op)
10748 #define uMIPS_RS1(op) ((op >> 1) & 0x7)
10749 #define uMIPS_RD5(op) ((op >> 5) & 0x1f)
10750 #define uMIPS_RS5(op) (op & 0x1f)
10752 /* Signed immediate */
10753 #define SIMM(op, start, width) \
10754 ((int32_t)(((op >> start) & ((~0U) >> (32-width))) \
10757 /* Zero-extended immediate */
10758 #define ZIMM(op, start, width) ((op >> start) & ((~0U) >> (32-width)))
10760 static void gen_addiur1sp (CPUMIPSState *env, DisasContext *ctx)
10762 int rd = mmreg(uMIPS_RD(ctx->opcode));
10764 gen_arith_imm(env, ctx, OPC_ADDIU, rd, 29, ((ctx->opcode >> 1) & 0x3f) << 2);
10767 static void gen_addiur2 (CPUMIPSState *env, DisasContext *ctx)
10769 static const int decoded_imm[] = { 1, 4, 8, 12, 16, 20, 24, -1 };
10770 int rd = mmreg(uMIPS_RD(ctx->opcode));
10771 int rs = mmreg(uMIPS_RS(ctx->opcode));
10773 gen_arith_imm(env, ctx, OPC_ADDIU, rd, rs, decoded_imm[ZIMM(ctx->opcode, 1, 3)]);
10776 static void gen_addiusp (CPUMIPSState *env, DisasContext *ctx)
10778 int encoded = ZIMM(ctx->opcode, 1, 9);
10781 if (encoded <= 1) {
10782 decoded = 256 + encoded;
10783 } else if (encoded <= 255) {
10785 } else if (encoded <= 509) {
10786 decoded = encoded - 512;
10788 decoded = encoded - 768;
10791 gen_arith_imm(env, ctx, OPC_ADDIU, 29, 29, decoded << 2);
10794 static void gen_addius5 (CPUMIPSState *env, DisasContext *ctx)
10796 int imm = SIMM(ctx->opcode, 1, 4);
10797 int rd = (ctx->opcode >> 5) & 0x1f;
10799 gen_arith_imm(env, ctx, OPC_ADDIU, rd, rd, imm);
10802 static void gen_andi16 (CPUMIPSState *env, DisasContext *ctx)
10804 static const int decoded_imm[] = { 128, 1, 2, 3, 4, 7, 8, 15, 16,
10805 31, 32, 63, 64, 255, 32768, 65535 };
10806 int rd = mmreg(uMIPS_RD(ctx->opcode));
10807 int rs = mmreg(uMIPS_RS(ctx->opcode));
10808 int encoded = ZIMM(ctx->opcode, 0, 4);
10810 gen_logic_imm(env, ctx, OPC_ANDI, rd, rs, decoded_imm[encoded]);
10813 static void gen_ldst_multiple (DisasContext *ctx, uint32_t opc, int reglist,
10814 int base, int16_t offset)
10816 const char *opn = "ldst_multiple";
10820 if (ctx->hflags & MIPS_HFLAG_BMASK) {
10821 generate_exception(ctx, EXCP_RI);
10825 t0 = tcg_temp_new();
10827 gen_base_offset_addr(ctx, t0, base, offset);
10829 t1 = tcg_const_tl(reglist);
10830 t2 = tcg_const_i32(ctx->mem_idx);
10832 save_cpu_state(ctx, 1);
10835 gen_helper_lwm(cpu_env, t0, t1, t2);
10839 gen_helper_swm(cpu_env, t0, t1, t2);
10842 #ifdef TARGET_MIPS64
10844 gen_helper_ldm(cpu_env, t0, t1, t2);
10848 gen_helper_sdm(cpu_env, t0, t1, t2);
10854 MIPS_DEBUG("%s, %x, %d(%s)", opn, reglist, offset, regnames[base]);
10857 tcg_temp_free_i32(t2);
10861 static void gen_pool16c_insn (CPUMIPSState *env, DisasContext *ctx, int *is_branch)
10863 int rd = mmreg((ctx->opcode >> 3) & 0x7);
10864 int rs = mmreg(ctx->opcode & 0x7);
10867 switch (((ctx->opcode) >> 4) & 0x3f) {
10872 gen_logic(env, ctx, OPC_NOR, rd, rs, 0);
10878 gen_logic(env, ctx, OPC_XOR, rd, rd, rs);
10884 gen_logic(env, ctx, OPC_AND, rd, rd, rs);
10890 gen_logic(env, ctx, OPC_OR, rd, rd, rs);
10897 static const int lwm_convert[] = { 0x11, 0x12, 0x13, 0x14 };
10898 int offset = ZIMM(ctx->opcode, 0, 4);
10900 gen_ldst_multiple(ctx, LWM32, lwm_convert[(ctx->opcode >> 4) & 0x3],
10909 static const int swm_convert[] = { 0x11, 0x12, 0x13, 0x14 };
10910 int offset = ZIMM(ctx->opcode, 0, 4);
10912 gen_ldst_multiple(ctx, SWM32, swm_convert[(ctx->opcode >> 4) & 0x3],
10919 int reg = ctx->opcode & 0x1f;
10921 gen_compute_branch(ctx, OPC_JR, 2, reg, 0, 0);
10928 int reg = ctx->opcode & 0x1f;
10930 gen_compute_branch(ctx, OPC_JR, 2, reg, 0, 0);
10931 /* Let normal delay slot handling in our caller take us
10932 to the branch target. */
10944 int reg = ctx->opcode & 0x1f;
10946 gen_compute_branch(ctx, opc, 2, reg, 31, 0);
10952 gen_HILO(ctx, OPC_MFHI, uMIPS_RS5(ctx->opcode));
10956 gen_HILO(ctx, OPC_MFLO, uMIPS_RS5(ctx->opcode));
10959 generate_exception(ctx, EXCP_BREAK);
10962 /* XXX: not clear which exception should be raised
10963 * when in debug mode...
10965 check_insn(env, ctx, ISA_MIPS32);
10966 if (!(ctx->hflags & MIPS_HFLAG_DM)) {
10967 generate_exception(ctx, EXCP_DBp);
10969 generate_exception(ctx, EXCP_DBp);
10972 case JRADDIUSP + 0:
10973 case JRADDIUSP + 1:
10975 int imm = ZIMM(ctx->opcode, 0, 5);
10977 gen_compute_branch(ctx, OPC_JR, 2, 31, 0, 0);
10978 gen_arith_imm(env, ctx, OPC_ADDIU, 29, 29, imm << 2);
10979 /* Let normal delay slot handling in our caller take us
10980 to the branch target. */
10984 generate_exception(ctx, EXCP_RI);
10989 static void gen_ldxs (DisasContext *ctx, int base, int index, int rd)
10991 TCGv t0 = tcg_temp_new();
10992 TCGv t1 = tcg_temp_new();
10994 gen_load_gpr(t0, base);
10997 gen_load_gpr(t1, index);
10998 tcg_gen_shli_tl(t1, t1, 2);
10999 gen_op_addr_add(ctx, t0, t1, t0);
11002 save_cpu_state(ctx, 0);
11003 op_ld_lw(t1, t0, ctx);
11004 gen_store_gpr(t1, rd);
11010 static void gen_ldst_pair (DisasContext *ctx, uint32_t opc, int rd,
11011 int base, int16_t offset)
11013 const char *opn = "ldst_pair";
11016 if (ctx->hflags & MIPS_HFLAG_BMASK || rd == 31) {
11017 generate_exception(ctx, EXCP_RI);
11021 t0 = tcg_temp_new();
11022 t1 = tcg_temp_new();
11024 gen_base_offset_addr(ctx, t0, base, offset);
11029 generate_exception(ctx, EXCP_RI);
11032 save_cpu_state(ctx, 0);
11033 op_ld_lw(t1, t0, ctx);
11034 gen_store_gpr(t1, rd);
11035 tcg_gen_movi_tl(t1, 4);
11036 gen_op_addr_add(ctx, t0, t0, t1);
11037 op_ld_lw(t1, t0, ctx);
11038 gen_store_gpr(t1, rd+1);
11042 save_cpu_state(ctx, 0);
11043 gen_load_gpr(t1, rd);
11044 op_st_sw(t1, t0, ctx);
11045 tcg_gen_movi_tl(t1, 4);
11046 gen_op_addr_add(ctx, t0, t0, t1);
11047 gen_load_gpr(t1, rd+1);
11048 op_st_sw(t1, t0, ctx);
11051 #ifdef TARGET_MIPS64
11054 generate_exception(ctx, EXCP_RI);
11057 save_cpu_state(ctx, 0);
11058 op_ld_ld(t1, t0, ctx);
11059 gen_store_gpr(t1, rd);
11060 tcg_gen_movi_tl(t1, 8);
11061 gen_op_addr_add(ctx, t0, t0, t1);
11062 op_ld_ld(t1, t0, ctx);
11063 gen_store_gpr(t1, rd+1);
11067 save_cpu_state(ctx, 0);
11068 gen_load_gpr(t1, rd);
11069 op_st_sd(t1, t0, ctx);
11070 tcg_gen_movi_tl(t1, 8);
11071 gen_op_addr_add(ctx, t0, t0, t1);
11072 gen_load_gpr(t1, rd+1);
11073 op_st_sd(t1, t0, ctx);
11078 (void)opn; /* avoid a compiler warning */
11079 MIPS_DEBUG("%s, %s, %d(%s)", opn, regnames[rd], offset, regnames[base]);
11084 static void gen_pool32axf (CPUMIPSState *env, DisasContext *ctx, int rt, int rs,
11087 int extension = (ctx->opcode >> 6) & 0x3f;
11088 int minor = (ctx->opcode >> 12) & 0xf;
11089 uint32_t mips32_op;
11091 switch (extension) {
11093 mips32_op = OPC_TEQ;
11096 mips32_op = OPC_TGE;
11099 mips32_op = OPC_TGEU;
11102 mips32_op = OPC_TLT;
11105 mips32_op = OPC_TLTU;
11108 mips32_op = OPC_TNE;
11110 gen_trap(ctx, mips32_op, rs, rt, -1);
11112 #ifndef CONFIG_USER_ONLY
11115 check_cp0_enabled(ctx);
11117 /* Treat as NOP. */
11120 gen_mfc0(env, ctx, cpu_gpr[rt], rs, (ctx->opcode >> 11) & 0x7);
11124 check_cp0_enabled(ctx);
11126 TCGv t0 = tcg_temp_new();
11128 gen_load_gpr(t0, rt);
11129 gen_mtc0(env, ctx, t0, rs, (ctx->opcode >> 11) & 0x7);
11137 gen_bshfl(ctx, OPC_SEB, rs, rt);
11140 gen_bshfl(ctx, OPC_SEH, rs, rt);
11143 mips32_op = OPC_CLO;
11146 mips32_op = OPC_CLZ;
11148 check_insn(env, ctx, ISA_MIPS32);
11149 gen_cl(ctx, mips32_op, rt, rs);
11152 gen_rdhwr(env, ctx, rt, rs);
11155 gen_bshfl(ctx, OPC_WSBH, rs, rt);
11158 mips32_op = OPC_MULT;
11161 mips32_op = OPC_MULTU;
11164 mips32_op = OPC_DIV;
11167 mips32_op = OPC_DIVU;
11170 mips32_op = OPC_MADD;
11173 mips32_op = OPC_MADDU;
11176 mips32_op = OPC_MSUB;
11179 mips32_op = OPC_MSUBU;
11181 check_insn(env, ctx, ISA_MIPS32);
11182 gen_muldiv(ctx, mips32_op, rs, rt);
11185 goto pool32axf_invalid;
11196 generate_exception_err(ctx, EXCP_CpU, 2);
11199 goto pool32axf_invalid;
11206 gen_compute_branch (ctx, OPC_JALR, 4, rs, rt, 0);
11211 gen_compute_branch (ctx, OPC_JALRS, 4, rs, rt, 0);
11215 goto pool32axf_invalid;
11221 check_cp0_enabled(ctx);
11222 check_insn(env, ctx, ISA_MIPS32R2);
11223 gen_load_srsgpr(rt, rs);
11226 check_cp0_enabled(ctx);
11227 check_insn(env, ctx, ISA_MIPS32R2);
11228 gen_store_srsgpr(rt, rs);
11231 goto pool32axf_invalid;
11234 #ifndef CONFIG_USER_ONLY
11238 mips32_op = OPC_TLBP;
11241 mips32_op = OPC_TLBR;
11244 mips32_op = OPC_TLBWI;
11247 mips32_op = OPC_TLBWR;
11250 mips32_op = OPC_WAIT;
11253 mips32_op = OPC_DERET;
11256 mips32_op = OPC_ERET;
11258 gen_cp0(env, ctx, mips32_op, rt, rs);
11261 goto pool32axf_invalid;
11267 check_cp0_enabled(ctx);
11269 TCGv t0 = tcg_temp_new();
11271 save_cpu_state(ctx, 1);
11272 gen_helper_di(t0, cpu_env);
11273 gen_store_gpr(t0, rs);
11274 /* Stop translation as we may have switched the execution mode */
11275 ctx->bstate = BS_STOP;
11280 check_cp0_enabled(ctx);
11282 TCGv t0 = tcg_temp_new();
11284 save_cpu_state(ctx, 1);
11285 gen_helper_ei(t0, cpu_env);
11286 gen_store_gpr(t0, rs);
11287 /* Stop translation as we may have switched the execution mode */
11288 ctx->bstate = BS_STOP;
11293 goto pool32axf_invalid;
11303 generate_exception(ctx, EXCP_SYSCALL);
11304 ctx->bstate = BS_STOP;
11307 check_insn(env, ctx, ISA_MIPS32);
11308 if (!(ctx->hflags & MIPS_HFLAG_DM)) {
11309 generate_exception(ctx, EXCP_DBp);
11311 generate_exception(ctx, EXCP_DBp);
11315 goto pool32axf_invalid;
11321 gen_HILO(ctx, OPC_MFHI, rs);
11324 gen_HILO(ctx, OPC_MFLO, rs);
11327 gen_HILO(ctx, OPC_MTHI, rs);
11330 gen_HILO(ctx, OPC_MTLO, rs);
11333 goto pool32axf_invalid;
11338 MIPS_INVAL("pool32axf");
11339 generate_exception(ctx, EXCP_RI);
11344 /* Values for microMIPS fmt field. Variable-width, depending on which
11345 formats the instruction supports. */
11364 static void gen_pool32fxf (CPUMIPSState *env, DisasContext *ctx, int rt, int rs)
11366 int extension = (ctx->opcode >> 6) & 0x3ff;
11367 uint32_t mips32_op;
11369 #define FLOAT_1BIT_FMT(opc, fmt) (fmt << 8) | opc
11370 #define FLOAT_2BIT_FMT(opc, fmt) (fmt << 7) | opc
11371 #define COND_FLOAT_MOV(opc, cond) (cond << 7) | opc
11373 switch (extension) {
11374 case FLOAT_1BIT_FMT(CFC1, 0):
11375 mips32_op = OPC_CFC1;
11377 case FLOAT_1BIT_FMT(CTC1, 0):
11378 mips32_op = OPC_CTC1;
11380 case FLOAT_1BIT_FMT(MFC1, 0):
11381 mips32_op = OPC_MFC1;
11383 case FLOAT_1BIT_FMT(MTC1, 0):
11384 mips32_op = OPC_MTC1;
11386 case FLOAT_1BIT_FMT(MFHC1, 0):
11387 mips32_op = OPC_MFHC1;
11389 case FLOAT_1BIT_FMT(MTHC1, 0):
11390 mips32_op = OPC_MTHC1;
11392 gen_cp1(ctx, mips32_op, rt, rs);
11395 /* Reciprocal square root */
11396 case FLOAT_1BIT_FMT(RSQRT_FMT, FMT_SD_S):
11397 mips32_op = OPC_RSQRT_S;
11399 case FLOAT_1BIT_FMT(RSQRT_FMT, FMT_SD_D):
11400 mips32_op = OPC_RSQRT_D;
11404 case FLOAT_1BIT_FMT(SQRT_FMT, FMT_SD_S):
11405 mips32_op = OPC_SQRT_S;
11407 case FLOAT_1BIT_FMT(SQRT_FMT, FMT_SD_D):
11408 mips32_op = OPC_SQRT_D;
11412 case FLOAT_1BIT_FMT(RECIP_FMT, FMT_SD_S):
11413 mips32_op = OPC_RECIP_S;
11415 case FLOAT_1BIT_FMT(RECIP_FMT, FMT_SD_D):
11416 mips32_op = OPC_RECIP_D;
11420 case FLOAT_1BIT_FMT(FLOOR_L, FMT_SD_S):
11421 mips32_op = OPC_FLOOR_L_S;
11423 case FLOAT_1BIT_FMT(FLOOR_L, FMT_SD_D):
11424 mips32_op = OPC_FLOOR_L_D;
11426 case FLOAT_1BIT_FMT(FLOOR_W, FMT_SD_S):
11427 mips32_op = OPC_FLOOR_W_S;
11429 case FLOAT_1BIT_FMT(FLOOR_W, FMT_SD_D):
11430 mips32_op = OPC_FLOOR_W_D;
11434 case FLOAT_1BIT_FMT(CEIL_L, FMT_SD_S):
11435 mips32_op = OPC_CEIL_L_S;
11437 case FLOAT_1BIT_FMT(CEIL_L, FMT_SD_D):
11438 mips32_op = OPC_CEIL_L_D;
11440 case FLOAT_1BIT_FMT(CEIL_W, FMT_SD_S):
11441 mips32_op = OPC_CEIL_W_S;
11443 case FLOAT_1BIT_FMT(CEIL_W, FMT_SD_D):
11444 mips32_op = OPC_CEIL_W_D;
11448 case FLOAT_1BIT_FMT(TRUNC_L, FMT_SD_S):
11449 mips32_op = OPC_TRUNC_L_S;
11451 case FLOAT_1BIT_FMT(TRUNC_L, FMT_SD_D):
11452 mips32_op = OPC_TRUNC_L_D;
11454 case FLOAT_1BIT_FMT(TRUNC_W, FMT_SD_S):
11455 mips32_op = OPC_TRUNC_W_S;
11457 case FLOAT_1BIT_FMT(TRUNC_W, FMT_SD_D):
11458 mips32_op = OPC_TRUNC_W_D;
11462 case FLOAT_1BIT_FMT(ROUND_L, FMT_SD_S):
11463 mips32_op = OPC_ROUND_L_S;
11465 case FLOAT_1BIT_FMT(ROUND_L, FMT_SD_D):
11466 mips32_op = OPC_ROUND_L_D;
11468 case FLOAT_1BIT_FMT(ROUND_W, FMT_SD_S):
11469 mips32_op = OPC_ROUND_W_S;
11471 case FLOAT_1BIT_FMT(ROUND_W, FMT_SD_D):
11472 mips32_op = OPC_ROUND_W_D;
11475 /* Integer to floating-point conversion */
11476 case FLOAT_1BIT_FMT(CVT_L, FMT_SD_S):
11477 mips32_op = OPC_CVT_L_S;
11479 case FLOAT_1BIT_FMT(CVT_L, FMT_SD_D):
11480 mips32_op = OPC_CVT_L_D;
11482 case FLOAT_1BIT_FMT(CVT_W, FMT_SD_S):
11483 mips32_op = OPC_CVT_W_S;
11485 case FLOAT_1BIT_FMT(CVT_W, FMT_SD_D):
11486 mips32_op = OPC_CVT_W_D;
11489 /* Paired-foo conversions */
11490 case FLOAT_1BIT_FMT(CVT_S_PL, 0):
11491 mips32_op = OPC_CVT_S_PL;
11493 case FLOAT_1BIT_FMT(CVT_S_PU, 0):
11494 mips32_op = OPC_CVT_S_PU;
11496 case FLOAT_1BIT_FMT(CVT_PW_PS, 0):
11497 mips32_op = OPC_CVT_PW_PS;
11499 case FLOAT_1BIT_FMT(CVT_PS_PW, 0):
11500 mips32_op = OPC_CVT_PS_PW;
11503 /* Floating-point moves */
11504 case FLOAT_2BIT_FMT(MOV_FMT, FMT_SDPS_S):
11505 mips32_op = OPC_MOV_S;
11507 case FLOAT_2BIT_FMT(MOV_FMT, FMT_SDPS_D):
11508 mips32_op = OPC_MOV_D;
11510 case FLOAT_2BIT_FMT(MOV_FMT, FMT_SDPS_PS):
11511 mips32_op = OPC_MOV_PS;
11514 /* Absolute value */
11515 case FLOAT_2BIT_FMT(ABS_FMT, FMT_SDPS_S):
11516 mips32_op = OPC_ABS_S;
11518 case FLOAT_2BIT_FMT(ABS_FMT, FMT_SDPS_D):
11519 mips32_op = OPC_ABS_D;
11521 case FLOAT_2BIT_FMT(ABS_FMT, FMT_SDPS_PS):
11522 mips32_op = OPC_ABS_PS;
11526 case FLOAT_2BIT_FMT(NEG_FMT, FMT_SDPS_S):
11527 mips32_op = OPC_NEG_S;
11529 case FLOAT_2BIT_FMT(NEG_FMT, FMT_SDPS_D):
11530 mips32_op = OPC_NEG_D;
11532 case FLOAT_2BIT_FMT(NEG_FMT, FMT_SDPS_PS):
11533 mips32_op = OPC_NEG_PS;
11536 /* Reciprocal square root step */
11537 case FLOAT_2BIT_FMT(RSQRT1_FMT, FMT_SDPS_S):
11538 mips32_op = OPC_RSQRT1_S;
11540 case FLOAT_2BIT_FMT(RSQRT1_FMT, FMT_SDPS_D):
11541 mips32_op = OPC_RSQRT1_D;
11543 case FLOAT_2BIT_FMT(RSQRT1_FMT, FMT_SDPS_PS):
11544 mips32_op = OPC_RSQRT1_PS;
11547 /* Reciprocal step */
11548 case FLOAT_2BIT_FMT(RECIP1_FMT, FMT_SDPS_S):
11549 mips32_op = OPC_RECIP1_S;
11551 case FLOAT_2BIT_FMT(RECIP1_FMT, FMT_SDPS_D):
11552 mips32_op = OPC_RECIP1_S;
11554 case FLOAT_2BIT_FMT(RECIP1_FMT, FMT_SDPS_PS):
11555 mips32_op = OPC_RECIP1_PS;
11558 /* Conversions from double */
11559 case FLOAT_2BIT_FMT(CVT_D, FMT_SWL_S):
11560 mips32_op = OPC_CVT_D_S;
11562 case FLOAT_2BIT_FMT(CVT_D, FMT_SWL_W):
11563 mips32_op = OPC_CVT_D_W;
11565 case FLOAT_2BIT_FMT(CVT_D, FMT_SWL_L):
11566 mips32_op = OPC_CVT_D_L;
11569 /* Conversions from single */
11570 case FLOAT_2BIT_FMT(CVT_S, FMT_DWL_D):
11571 mips32_op = OPC_CVT_S_D;
11573 case FLOAT_2BIT_FMT(CVT_S, FMT_DWL_W):
11574 mips32_op = OPC_CVT_S_W;
11576 case FLOAT_2BIT_FMT(CVT_S, FMT_DWL_L):
11577 mips32_op = OPC_CVT_S_L;
11579 gen_farith(ctx, mips32_op, -1, rs, rt, 0);
11582 /* Conditional moves on floating-point codes */
11583 case COND_FLOAT_MOV(MOVT, 0):
11584 case COND_FLOAT_MOV(MOVT, 1):
11585 case COND_FLOAT_MOV(MOVT, 2):
11586 case COND_FLOAT_MOV(MOVT, 3):
11587 case COND_FLOAT_MOV(MOVT, 4):
11588 case COND_FLOAT_MOV(MOVT, 5):
11589 case COND_FLOAT_MOV(MOVT, 6):
11590 case COND_FLOAT_MOV(MOVT, 7):
11591 gen_movci(ctx, rt, rs, (ctx->opcode >> 13) & 0x7, 1);
11593 case COND_FLOAT_MOV(MOVF, 0):
11594 case COND_FLOAT_MOV(MOVF, 1):
11595 case COND_FLOAT_MOV(MOVF, 2):
11596 case COND_FLOAT_MOV(MOVF, 3):
11597 case COND_FLOAT_MOV(MOVF, 4):
11598 case COND_FLOAT_MOV(MOVF, 5):
11599 case COND_FLOAT_MOV(MOVF, 6):
11600 case COND_FLOAT_MOV(MOVF, 7):
11601 gen_movci(ctx, rt, rs, (ctx->opcode >> 13) & 0x7, 0);
11604 MIPS_INVAL("pool32fxf");
11605 generate_exception(ctx, EXCP_RI);
11610 static void decode_micromips32_opc (CPUMIPSState *env, DisasContext *ctx,
11611 uint16_t insn_hw1, int *is_branch)
11615 int rt, rs, rd, rr;
11617 uint32_t op, minor, mips32_op;
11618 uint32_t cond, fmt, cc;
11620 insn = cpu_lduw_code(env, ctx->pc + 2);
11621 ctx->opcode = (ctx->opcode << 16) | insn;
11623 rt = (ctx->opcode >> 21) & 0x1f;
11624 rs = (ctx->opcode >> 16) & 0x1f;
11625 rd = (ctx->opcode >> 11) & 0x1f;
11626 rr = (ctx->opcode >> 6) & 0x1f;
11627 imm = (int16_t) ctx->opcode;
11629 op = (ctx->opcode >> 26) & 0x3f;
11632 minor = ctx->opcode & 0x3f;
11635 minor = (ctx->opcode >> 6) & 0xf;
11638 mips32_op = OPC_SLL;
11641 mips32_op = OPC_SRA;
11644 mips32_op = OPC_SRL;
11647 mips32_op = OPC_ROTR;
11649 gen_shift_imm(env, ctx, mips32_op, rt, rs, rd);
11652 goto pool32a_invalid;
11656 minor = (ctx->opcode >> 6) & 0xf;
11660 mips32_op = OPC_ADD;
11663 mips32_op = OPC_ADDU;
11666 mips32_op = OPC_SUB;
11669 mips32_op = OPC_SUBU;
11672 mips32_op = OPC_MUL;
11674 gen_arith(env, ctx, mips32_op, rd, rs, rt);
11678 mips32_op = OPC_SLLV;
11681 mips32_op = OPC_SRLV;
11684 mips32_op = OPC_SRAV;
11687 mips32_op = OPC_ROTRV;
11689 gen_shift(env, ctx, mips32_op, rd, rs, rt);
11691 /* Logical operations */
11693 mips32_op = OPC_AND;
11696 mips32_op = OPC_OR;
11699 mips32_op = OPC_NOR;
11702 mips32_op = OPC_XOR;
11704 gen_logic(env, ctx, mips32_op, rd, rs, rt);
11706 /* Set less than */
11708 mips32_op = OPC_SLT;
11711 mips32_op = OPC_SLTU;
11713 gen_slt(env, ctx, mips32_op, rd, rs, rt);
11716 goto pool32a_invalid;
11720 minor = (ctx->opcode >> 6) & 0xf;
11722 /* Conditional moves */
11724 mips32_op = OPC_MOVN;
11727 mips32_op = OPC_MOVZ;
11729 gen_cond_move(env, ctx, mips32_op, rd, rs, rt);
11732 gen_ldxs(ctx, rs, rt, rd);
11735 goto pool32a_invalid;
11739 gen_bitops(ctx, OPC_INS, rt, rs, rr, rd);
11742 gen_bitops(ctx, OPC_EXT, rt, rs, rr, rd);
11745 gen_pool32axf(env, ctx, rt, rs, is_branch);
11748 generate_exception(ctx, EXCP_BREAK);
11752 MIPS_INVAL("pool32a");
11753 generate_exception(ctx, EXCP_RI);
11758 minor = (ctx->opcode >> 12) & 0xf;
11761 check_cp0_enabled(ctx);
11762 /* Treat as no-op. */
11766 /* COP2: Not implemented. */
11767 generate_exception_err(ctx, EXCP_CpU, 2);
11771 #ifdef TARGET_MIPS64
11775 gen_ldst_pair(ctx, minor, rt, rs, SIMM(ctx->opcode, 0, 12));
11779 #ifdef TARGET_MIPS64
11783 gen_ldst_multiple(ctx, minor, rt, rs, SIMM(ctx->opcode, 0, 12));
11786 MIPS_INVAL("pool32b");
11787 generate_exception(ctx, EXCP_RI);
11792 if (env->CP0_Config1 & (1 << CP0C1_FP)) {
11793 minor = ctx->opcode & 0x3f;
11794 check_cp1_enabled(ctx);
11797 mips32_op = OPC_ALNV_PS;
11800 mips32_op = OPC_MADD_S;
11803 mips32_op = OPC_MADD_D;
11806 mips32_op = OPC_MADD_PS;
11809 mips32_op = OPC_MSUB_S;
11812 mips32_op = OPC_MSUB_D;
11815 mips32_op = OPC_MSUB_PS;
11818 mips32_op = OPC_NMADD_S;
11821 mips32_op = OPC_NMADD_D;
11824 mips32_op = OPC_NMADD_PS;
11827 mips32_op = OPC_NMSUB_S;
11830 mips32_op = OPC_NMSUB_D;
11833 mips32_op = OPC_NMSUB_PS;
11835 gen_flt3_arith(ctx, mips32_op, rd, rr, rs, rt);
11837 case CABS_COND_FMT:
11838 cond = (ctx->opcode >> 6) & 0xf;
11839 cc = (ctx->opcode >> 13) & 0x7;
11840 fmt = (ctx->opcode >> 10) & 0x3;
11843 gen_cmpabs_s(ctx, cond, rt, rs, cc);
11846 gen_cmpabs_d(ctx, cond, rt, rs, cc);
11849 gen_cmpabs_ps(ctx, cond, rt, rs, cc);
11852 goto pool32f_invalid;
11856 cond = (ctx->opcode >> 6) & 0xf;
11857 cc = (ctx->opcode >> 13) & 0x7;
11858 fmt = (ctx->opcode >> 10) & 0x3;
11861 gen_cmp_s(ctx, cond, rt, rs, cc);
11864 gen_cmp_d(ctx, cond, rt, rs, cc);
11867 gen_cmp_ps(ctx, cond, rt, rs, cc);
11870 goto pool32f_invalid;
11874 gen_pool32fxf(env, ctx, rt, rs);
11878 switch ((ctx->opcode >> 6) & 0x7) {
11880 mips32_op = OPC_PLL_PS;
11883 mips32_op = OPC_PLU_PS;
11886 mips32_op = OPC_PUL_PS;
11889 mips32_op = OPC_PUU_PS;
11892 mips32_op = OPC_CVT_PS_S;
11894 gen_farith(ctx, mips32_op, rt, rs, rd, 0);
11897 goto pool32f_invalid;
11902 switch ((ctx->opcode >> 6) & 0x7) {
11904 mips32_op = OPC_LWXC1;
11907 mips32_op = OPC_SWXC1;
11910 mips32_op = OPC_LDXC1;
11913 mips32_op = OPC_SDXC1;
11916 mips32_op = OPC_LUXC1;
11919 mips32_op = OPC_SUXC1;
11921 gen_flt3_ldst(ctx, mips32_op, rd, rd, rt, rs);
11924 goto pool32f_invalid;
11929 fmt = (ctx->opcode >> 9) & 0x3;
11930 switch ((ctx->opcode >> 6) & 0x7) {
11934 mips32_op = OPC_RSQRT2_S;
11937 mips32_op = OPC_RSQRT2_D;
11940 mips32_op = OPC_RSQRT2_PS;
11943 goto pool32f_invalid;
11949 mips32_op = OPC_RECIP2_S;
11952 mips32_op = OPC_RECIP2_D;
11955 mips32_op = OPC_RECIP2_PS;
11958 goto pool32f_invalid;
11962 mips32_op = OPC_ADDR_PS;
11965 mips32_op = OPC_MULR_PS;
11967 gen_farith(ctx, mips32_op, rt, rs, rd, 0);
11970 goto pool32f_invalid;
11974 /* MOV[FT].fmt and PREFX */
11975 cc = (ctx->opcode >> 13) & 0x7;
11976 fmt = (ctx->opcode >> 9) & 0x3;
11977 switch ((ctx->opcode >> 6) & 0x7) {
11981 gen_movcf_s(rs, rt, cc, 0);
11984 gen_movcf_d(ctx, rs, rt, cc, 0);
11987 gen_movcf_ps(rs, rt, cc, 0);
11990 goto pool32f_invalid;
11996 gen_movcf_s(rs, rt, cc, 1);
11999 gen_movcf_d(ctx, rs, rt, cc, 1);
12002 gen_movcf_ps(rs, rt, cc, 1);
12005 goto pool32f_invalid;
12011 goto pool32f_invalid;
12014 #define FINSN_3ARG_SDPS(prfx) \
12015 switch ((ctx->opcode >> 8) & 0x3) { \
12017 mips32_op = OPC_##prfx##_S; \
12020 mips32_op = OPC_##prfx##_D; \
12022 case FMT_SDPS_PS: \
12023 mips32_op = OPC_##prfx##_PS; \
12026 goto pool32f_invalid; \
12029 /* regular FP ops */
12030 switch ((ctx->opcode >> 6) & 0x3) {
12032 FINSN_3ARG_SDPS(ADD);
12035 FINSN_3ARG_SDPS(SUB);
12038 FINSN_3ARG_SDPS(MUL);
12041 fmt = (ctx->opcode >> 8) & 0x3;
12043 mips32_op = OPC_DIV_D;
12044 } else if (fmt == 0) {
12045 mips32_op = OPC_DIV_S;
12047 goto pool32f_invalid;
12051 goto pool32f_invalid;
12056 switch ((ctx->opcode >> 6) & 0x3) {
12058 FINSN_3ARG_SDPS(MOVN);
12061 FINSN_3ARG_SDPS(MOVZ);
12064 goto pool32f_invalid;
12068 gen_farith(ctx, mips32_op, rt, rs, rd, 0);
12072 MIPS_INVAL("pool32f");
12073 generate_exception(ctx, EXCP_RI);
12077 generate_exception_err(ctx, EXCP_CpU, 1);
12081 minor = (ctx->opcode >> 21) & 0x1f;
12084 mips32_op = OPC_BLTZ;
12087 mips32_op = OPC_BLTZAL;
12090 mips32_op = OPC_BLTZALS;
12093 mips32_op = OPC_BGEZ;
12096 mips32_op = OPC_BGEZAL;
12099 mips32_op = OPC_BGEZALS;
12102 mips32_op = OPC_BLEZ;
12105 mips32_op = OPC_BGTZ;
12107 gen_compute_branch(ctx, mips32_op, 4, rs, -1, imm << 1);
12113 mips32_op = OPC_TLTI;
12116 mips32_op = OPC_TGEI;
12119 mips32_op = OPC_TLTIU;
12122 mips32_op = OPC_TGEIU;
12125 mips32_op = OPC_TNEI;
12128 mips32_op = OPC_TEQI;
12130 gen_trap(ctx, mips32_op, rs, -1, imm);
12135 gen_compute_branch(ctx, minor == BNEZC ? OPC_BNE : OPC_BEQ,
12136 4, rs, 0, imm << 1);
12137 /* Compact branches don't have a delay slot, so just let
12138 the normal delay slot handling take us to the branch
12142 gen_logic_imm(env, ctx, OPC_LUI, rs, -1, imm);
12148 /* COP2: Not implemented. */
12149 generate_exception_err(ctx, EXCP_CpU, 2);
12152 mips32_op = (ctx->opcode & (1 << 16)) ? OPC_BC1FANY2 : OPC_BC1F;
12155 mips32_op = (ctx->opcode & (1 << 16)) ? OPC_BC1TANY2 : OPC_BC1T;
12158 mips32_op = OPC_BC1FANY4;
12161 mips32_op = OPC_BC1TANY4;
12164 check_insn(env, ctx, ASE_MIPS3D);
12167 gen_compute_branch1(env, ctx, mips32_op,
12168 (ctx->opcode >> 18) & 0x7, imm << 1);
12173 /* MIPS DSP: not implemented */
12176 MIPS_INVAL("pool32i");
12177 generate_exception(ctx, EXCP_RI);
12182 minor = (ctx->opcode >> 12) & 0xf;
12185 mips32_op = OPC_LWL;
12188 mips32_op = OPC_SWL;
12191 mips32_op = OPC_LWR;
12194 mips32_op = OPC_SWR;
12196 #if defined(TARGET_MIPS64)
12198 mips32_op = OPC_LDL;
12201 mips32_op = OPC_SDL;
12204 mips32_op = OPC_LDR;
12207 mips32_op = OPC_SDR;
12210 mips32_op = OPC_LWU;
12213 mips32_op = OPC_LLD;
12217 mips32_op = OPC_LL;
12220 gen_ld(env, ctx, mips32_op, rt, rs, SIMM(ctx->opcode, 0, 12));
12223 gen_st(ctx, mips32_op, rt, rs, SIMM(ctx->opcode, 0, 12));
12226 gen_st_cond(ctx, OPC_SC, rt, rs, SIMM(ctx->opcode, 0, 12));
12228 #if defined(TARGET_MIPS64)
12230 gen_st_cond(ctx, OPC_SCD, rt, rs, SIMM(ctx->opcode, 0, 12));
12234 /* Treat as no-op */
12237 MIPS_INVAL("pool32c");
12238 generate_exception(ctx, EXCP_RI);
12243 mips32_op = OPC_ADDI;
12246 mips32_op = OPC_ADDIU;
12248 gen_arith_imm(env, ctx, mips32_op, rt, rs, imm);
12251 /* Logical operations */
12253 mips32_op = OPC_ORI;
12256 mips32_op = OPC_XORI;
12259 mips32_op = OPC_ANDI;
12261 gen_logic_imm(env, ctx, mips32_op, rt, rs, imm);
12264 /* Set less than immediate */
12266 mips32_op = OPC_SLTI;
12269 mips32_op = OPC_SLTIU;
12271 gen_slt_imm(env, ctx, mips32_op, rt, rs, imm);
12274 offset = (int32_t)(ctx->opcode & 0x3FFFFFF) << 2;
12275 gen_compute_branch(ctx, OPC_JALX, 4, rt, rs, offset);
12279 offset = (int32_t)(ctx->opcode & 0x3FFFFFF) << 1;
12280 gen_compute_branch(ctx, OPC_JALS, 4, rt, rs, offset);
12284 gen_compute_branch(ctx, OPC_BEQ, 4, rt, rs, imm << 1);
12288 gen_compute_branch(ctx, OPC_BNE, 4, rt, rs, imm << 1);
12292 gen_compute_branch(ctx, OPC_J, 4, rt, rs,
12293 (int32_t)(ctx->opcode & 0x3FFFFFF) << 1);
12297 gen_compute_branch(ctx, OPC_JAL, 4, rt, rs,
12298 (int32_t)(ctx->opcode & 0x3FFFFFF) << 1);
12301 /* Floating point (COP1) */
12303 mips32_op = OPC_LWC1;
12306 mips32_op = OPC_LDC1;
12309 mips32_op = OPC_SWC1;
12312 mips32_op = OPC_SDC1;
12314 gen_cop1_ldst(env, ctx, mips32_op, rt, rs, imm);
12318 int reg = mmreg(ZIMM(ctx->opcode, 23, 3));
12319 int offset = SIMM(ctx->opcode, 0, 23) << 2;
12321 gen_addiupc(ctx, reg, offset, 0, 0);
12324 /* Loads and stores */
12326 mips32_op = OPC_LB;
12329 mips32_op = OPC_LBU;
12332 mips32_op = OPC_LH;
12335 mips32_op = OPC_LHU;
12338 mips32_op = OPC_LW;
12340 #ifdef TARGET_MIPS64
12342 mips32_op = OPC_LD;
12345 mips32_op = OPC_SD;
12349 mips32_op = OPC_SB;
12352 mips32_op = OPC_SH;
12355 mips32_op = OPC_SW;
12358 gen_ld(env, ctx, mips32_op, rt, rs, imm);
12361 gen_st(ctx, mips32_op, rt, rs, imm);
12364 generate_exception(ctx, EXCP_RI);
12369 static int decode_micromips_opc (CPUMIPSState *env, DisasContext *ctx, int *is_branch)
12373 /* make sure instructions are on a halfword boundary */
12374 if (ctx->pc & 0x1) {
12375 env->CP0_BadVAddr = ctx->pc;
12376 generate_exception(ctx, EXCP_AdEL);
12377 ctx->bstate = BS_STOP;
12381 op = (ctx->opcode >> 10) & 0x3f;
12382 /* Enforce properly-sized instructions in a delay slot */
12383 if (ctx->hflags & MIPS_HFLAG_BMASK) {
12384 int bits = ctx->hflags & MIPS_HFLAG_BMASK_EXT;
12418 case POOL48A: /* ??? */
12423 if (bits & MIPS_HFLAG_BDS16) {
12424 generate_exception(ctx, EXCP_RI);
12425 /* Just stop translation; the user is confused. */
12426 ctx->bstate = BS_STOP;
12451 if (bits & MIPS_HFLAG_BDS32) {
12452 generate_exception(ctx, EXCP_RI);
12453 /* Just stop translation; the user is confused. */
12454 ctx->bstate = BS_STOP;
12465 int rd = mmreg(uMIPS_RD(ctx->opcode));
12466 int rs1 = mmreg(uMIPS_RS1(ctx->opcode));
12467 int rs2 = mmreg(uMIPS_RS2(ctx->opcode));
12470 switch (ctx->opcode & 0x1) {
12479 gen_arith(env, ctx, opc, rd, rs1, rs2);
12484 int rd = mmreg(uMIPS_RD(ctx->opcode));
12485 int rs = mmreg(uMIPS_RS(ctx->opcode));
12486 int amount = (ctx->opcode >> 1) & 0x7;
12488 amount = amount == 0 ? 8 : amount;
12490 switch (ctx->opcode & 0x1) {
12499 gen_shift_imm(env, ctx, opc, rd, rs, amount);
12503 gen_pool16c_insn(env, ctx, is_branch);
12507 int rd = mmreg(uMIPS_RD(ctx->opcode));
12508 int rb = 28; /* GP */
12509 int16_t offset = SIMM(ctx->opcode, 0, 7) << 2;
12511 gen_ld(env, ctx, OPC_LW, rd, rb, offset);
12515 if (ctx->opcode & 1) {
12516 generate_exception(ctx, EXCP_RI);
12519 int enc_dest = uMIPS_RD(ctx->opcode);
12520 int enc_rt = uMIPS_RS2(ctx->opcode);
12521 int enc_rs = uMIPS_RS1(ctx->opcode);
12522 int rd, rs, re, rt;
12523 static const int rd_enc[] = { 5, 5, 6, 4, 4, 4, 4, 4 };
12524 static const int re_enc[] = { 6, 7, 7, 21, 22, 5, 6, 7 };
12525 static const int rs_rt_enc[] = { 0, 17, 2, 3, 16, 18, 19, 20 };
12527 rd = rd_enc[enc_dest];
12528 re = re_enc[enc_dest];
12529 rs = rs_rt_enc[enc_rs];
12530 rt = rs_rt_enc[enc_rt];
12532 gen_arith_imm(env, ctx, OPC_ADDIU, rd, rs, 0);
12533 gen_arith_imm(env, ctx, OPC_ADDIU, re, rt, 0);
12538 int rd = mmreg(uMIPS_RD(ctx->opcode));
12539 int rb = mmreg(uMIPS_RS(ctx->opcode));
12540 int16_t offset = ZIMM(ctx->opcode, 0, 4);
12541 offset = (offset == 0xf ? -1 : offset);
12543 gen_ld(env, ctx, OPC_LBU, rd, rb, offset);
12548 int rd = mmreg(uMIPS_RD(ctx->opcode));
12549 int rb = mmreg(uMIPS_RS(ctx->opcode));
12550 int16_t offset = ZIMM(ctx->opcode, 0, 4) << 1;
12552 gen_ld(env, ctx, OPC_LHU, rd, rb, offset);
12557 int rd = (ctx->opcode >> 5) & 0x1f;
12558 int rb = 29; /* SP */
12559 int16_t offset = ZIMM(ctx->opcode, 0, 5) << 2;
12561 gen_ld(env, ctx, OPC_LW, rd, rb, offset);
12566 int rd = mmreg(uMIPS_RD(ctx->opcode));
12567 int rb = mmreg(uMIPS_RS(ctx->opcode));
12568 int16_t offset = ZIMM(ctx->opcode, 0, 4) << 2;
12570 gen_ld(env, ctx, OPC_LW, rd, rb, offset);
12575 int rd = mmreg2(uMIPS_RD(ctx->opcode));
12576 int rb = mmreg(uMIPS_RS(ctx->opcode));
12577 int16_t offset = ZIMM(ctx->opcode, 0, 4);
12579 gen_st(ctx, OPC_SB, rd, rb, offset);
12584 int rd = mmreg2(uMIPS_RD(ctx->opcode));
12585 int rb = mmreg(uMIPS_RS(ctx->opcode));
12586 int16_t offset = ZIMM(ctx->opcode, 0, 4) << 1;
12588 gen_st(ctx, OPC_SH, rd, rb, offset);
12593 int rd = (ctx->opcode >> 5) & 0x1f;
12594 int rb = 29; /* SP */
12595 int16_t offset = ZIMM(ctx->opcode, 0, 5) << 2;
12597 gen_st(ctx, OPC_SW, rd, rb, offset);
12602 int rd = mmreg2(uMIPS_RD(ctx->opcode));
12603 int rb = mmreg(uMIPS_RS(ctx->opcode));
12604 int16_t offset = ZIMM(ctx->opcode, 0, 4) << 2;
12606 gen_st(ctx, OPC_SW, rd, rb, offset);
12611 int rd = uMIPS_RD5(ctx->opcode);
12612 int rs = uMIPS_RS5(ctx->opcode);
12614 gen_arith_imm(env, ctx, OPC_ADDIU, rd, rs, 0);
12618 gen_andi16(env, ctx);
12621 switch (ctx->opcode & 0x1) {
12623 gen_addius5(env, ctx);
12626 gen_addiusp(env, ctx);
12631 switch (ctx->opcode & 0x1) {
12633 gen_addiur2(env, ctx);
12636 gen_addiur1sp(env, ctx);
12641 gen_compute_branch(ctx, OPC_BEQ, 2, 0, 0,
12642 SIMM(ctx->opcode, 0, 10) << 1);
12647 gen_compute_branch(ctx, op == BNEZ16 ? OPC_BNE : OPC_BEQ, 2,
12648 mmreg(uMIPS_RD(ctx->opcode)),
12649 0, SIMM(ctx->opcode, 0, 7) << 1);
12654 int reg = mmreg(uMIPS_RD(ctx->opcode));
12655 int imm = ZIMM(ctx->opcode, 0, 7);
12657 imm = (imm == 0x7f ? -1 : imm);
12658 tcg_gen_movi_tl(cpu_gpr[reg], imm);
12668 generate_exception(ctx, EXCP_RI);
12671 decode_micromips32_opc (env, ctx, op, is_branch);
12678 /* SmartMIPS extension to MIPS32 */
12680 #if defined(TARGET_MIPS64)
12682 /* MDMX extension to MIPS64 */
12686 /* MIPSDSP functions. */
12687 static void gen_mipsdsp_ld(CPUMIPSState *env, DisasContext *ctx, uint32_t opc,
12688 int rd, int base, int offset)
12690 const char *opn = "ldx";
12699 t0 = tcg_temp_new();
12702 gen_load_gpr(t0, offset);
12703 } else if (offset == 0) {
12704 gen_load_gpr(t0, base);
12706 gen_op_addr_add(ctx, t0, cpu_gpr[base], cpu_gpr[offset]);
12709 save_cpu_state(ctx, 0);
12712 op_ld_lbu(t0, t0, ctx);
12713 gen_store_gpr(t0, rd);
12717 op_ld_lh(t0, t0, ctx);
12718 gen_store_gpr(t0, rd);
12722 op_ld_lw(t0, t0, ctx);
12723 gen_store_gpr(t0, rd);
12726 #if defined(TARGET_MIPS64)
12728 op_ld_ld(t0, t0, ctx);
12729 gen_store_gpr(t0, rd);
12734 (void)opn; /* avoid a compiler warning */
12735 MIPS_DEBUG("%s %s, %s(%s)", opn,
12736 regnames[rd], regnames[offset], regnames[base]);
12740 static void gen_mipsdsp_arith(DisasContext *ctx, uint32_t op1, uint32_t op2,
12741 int ret, int v1, int v2)
12743 const char *opn = "mipsdsp arith";
12748 /* Treat as NOP. */
12753 v1_t = tcg_temp_new();
12754 v2_t = tcg_temp_new();
12756 gen_load_gpr(v1_t, v1);
12757 gen_load_gpr(v2_t, v2);
12760 /* OPC_MULT_G_2E is equal OPC_ADDUH_QB_DSP */
12761 case OPC_MULT_G_2E:
12765 gen_helper_adduh_qb(cpu_gpr[ret], v1_t, v2_t);
12767 case OPC_ADDUH_R_QB:
12768 gen_helper_adduh_r_qb(cpu_gpr[ret], v1_t, v2_t);
12771 gen_helper_addqh_ph(cpu_gpr[ret], v1_t, v2_t);
12773 case OPC_ADDQH_R_PH:
12774 gen_helper_addqh_r_ph(cpu_gpr[ret], v1_t, v2_t);
12777 gen_helper_addqh_w(cpu_gpr[ret], v1_t, v2_t);
12779 case OPC_ADDQH_R_W:
12780 gen_helper_addqh_r_w(cpu_gpr[ret], v1_t, v2_t);
12783 gen_helper_subuh_qb(cpu_gpr[ret], v1_t, v2_t);
12785 case OPC_SUBUH_R_QB:
12786 gen_helper_subuh_r_qb(cpu_gpr[ret], v1_t, v2_t);
12789 gen_helper_subqh_ph(cpu_gpr[ret], v1_t, v2_t);
12791 case OPC_SUBQH_R_PH:
12792 gen_helper_subqh_r_ph(cpu_gpr[ret], v1_t, v2_t);
12795 gen_helper_subqh_w(cpu_gpr[ret], v1_t, v2_t);
12797 case OPC_SUBQH_R_W:
12798 gen_helper_subqh_r_w(cpu_gpr[ret], v1_t, v2_t);
12802 case OPC_ABSQ_S_PH_DSP:
12804 case OPC_ABSQ_S_QB:
12806 gen_helper_absq_s_qb(cpu_gpr[ret], v2_t, cpu_env);
12808 case OPC_ABSQ_S_PH:
12810 gen_helper_absq_s_ph(cpu_gpr[ret], v2_t, cpu_env);
12814 gen_helper_absq_s_w(cpu_gpr[ret], v2_t, cpu_env);
12816 case OPC_PRECEQ_W_PHL:
12818 tcg_gen_andi_tl(cpu_gpr[ret], v2_t, 0xFFFF0000);
12819 tcg_gen_ext32s_tl(cpu_gpr[ret], cpu_gpr[ret]);
12821 case OPC_PRECEQ_W_PHR:
12823 tcg_gen_andi_tl(cpu_gpr[ret], v2_t, 0x0000FFFF);
12824 tcg_gen_shli_tl(cpu_gpr[ret], cpu_gpr[ret], 16);
12825 tcg_gen_ext32s_tl(cpu_gpr[ret], cpu_gpr[ret]);
12827 case OPC_PRECEQU_PH_QBL:
12829 gen_helper_precequ_ph_qbl(cpu_gpr[ret], v2_t);
12831 case OPC_PRECEQU_PH_QBR:
12833 gen_helper_precequ_ph_qbr(cpu_gpr[ret], v2_t);
12835 case OPC_PRECEQU_PH_QBLA:
12837 gen_helper_precequ_ph_qbla(cpu_gpr[ret], v2_t);
12839 case OPC_PRECEQU_PH_QBRA:
12841 gen_helper_precequ_ph_qbra(cpu_gpr[ret], v2_t);
12843 case OPC_PRECEU_PH_QBL:
12845 gen_helper_preceu_ph_qbl(cpu_gpr[ret], v2_t);
12847 case OPC_PRECEU_PH_QBR:
12849 gen_helper_preceu_ph_qbr(cpu_gpr[ret], v2_t);
12851 case OPC_PRECEU_PH_QBLA:
12853 gen_helper_preceu_ph_qbla(cpu_gpr[ret], v2_t);
12855 case OPC_PRECEU_PH_QBRA:
12857 gen_helper_preceu_ph_qbra(cpu_gpr[ret], v2_t);
12861 case OPC_ADDU_QB_DSP:
12865 gen_helper_addq_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12867 case OPC_ADDQ_S_PH:
12869 gen_helper_addq_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12873 gen_helper_addq_s_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12877 gen_helper_addu_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12879 case OPC_ADDU_S_QB:
12881 gen_helper_addu_s_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12885 gen_helper_addu_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12887 case OPC_ADDU_S_PH:
12889 gen_helper_addu_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12893 gen_helper_subq_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12895 case OPC_SUBQ_S_PH:
12897 gen_helper_subq_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12901 gen_helper_subq_s_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12905 gen_helper_subu_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12907 case OPC_SUBU_S_QB:
12909 gen_helper_subu_s_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12913 gen_helper_subu_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12915 case OPC_SUBU_S_PH:
12917 gen_helper_subu_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12921 gen_helper_addsc(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12925 gen_helper_addwc(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12929 gen_helper_modsub(cpu_gpr[ret], v1_t, v2_t);
12931 case OPC_RADDU_W_QB:
12933 gen_helper_raddu_w_qb(cpu_gpr[ret], v1_t);
12937 case OPC_CMPU_EQ_QB_DSP:
12939 case OPC_PRECR_QB_PH:
12941 gen_helper_precr_qb_ph(cpu_gpr[ret], v1_t, v2_t);
12943 case OPC_PRECRQ_QB_PH:
12945 gen_helper_precrq_qb_ph(cpu_gpr[ret], v1_t, v2_t);
12947 case OPC_PRECR_SRA_PH_W:
12950 TCGv_i32 sa_t = tcg_const_i32(v2);
12951 gen_helper_precr_sra_ph_w(cpu_gpr[ret], sa_t, v1_t,
12953 tcg_temp_free_i32(sa_t);
12956 case OPC_PRECR_SRA_R_PH_W:
12959 TCGv_i32 sa_t = tcg_const_i32(v2);
12960 gen_helper_precr_sra_r_ph_w(cpu_gpr[ret], sa_t, v1_t,
12962 tcg_temp_free_i32(sa_t);
12965 case OPC_PRECRQ_PH_W:
12967 gen_helper_precrq_ph_w(cpu_gpr[ret], v1_t, v2_t);
12969 case OPC_PRECRQ_RS_PH_W:
12971 gen_helper_precrq_rs_ph_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12973 case OPC_PRECRQU_S_QB_PH:
12975 gen_helper_precrqu_s_qb_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12979 #ifdef TARGET_MIPS64
12980 case OPC_ABSQ_S_QH_DSP:
12982 case OPC_PRECEQ_L_PWL:
12984 tcg_gen_andi_tl(cpu_gpr[ret], v2_t, 0xFFFFFFFF00000000ull);
12986 case OPC_PRECEQ_L_PWR:
12988 tcg_gen_shli_tl(cpu_gpr[ret], v2_t, 32);
12990 case OPC_PRECEQ_PW_QHL:
12992 gen_helper_preceq_pw_qhl(cpu_gpr[ret], v2_t);
12994 case OPC_PRECEQ_PW_QHR:
12996 gen_helper_preceq_pw_qhr(cpu_gpr[ret], v2_t);
12998 case OPC_PRECEQ_PW_QHLA:
13000 gen_helper_preceq_pw_qhla(cpu_gpr[ret], v2_t);
13002 case OPC_PRECEQ_PW_QHRA:
13004 gen_helper_preceq_pw_qhra(cpu_gpr[ret], v2_t);
13006 case OPC_PRECEQU_QH_OBL:
13008 gen_helper_precequ_qh_obl(cpu_gpr[ret], v2_t);
13010 case OPC_PRECEQU_QH_OBR:
13012 gen_helper_precequ_qh_obr(cpu_gpr[ret], v2_t);
13014 case OPC_PRECEQU_QH_OBLA:
13016 gen_helper_precequ_qh_obla(cpu_gpr[ret], v2_t);
13018 case OPC_PRECEQU_QH_OBRA:
13020 gen_helper_precequ_qh_obra(cpu_gpr[ret], v2_t);
13022 case OPC_PRECEU_QH_OBL:
13024 gen_helper_preceu_qh_obl(cpu_gpr[ret], v2_t);
13026 case OPC_PRECEU_QH_OBR:
13028 gen_helper_preceu_qh_obr(cpu_gpr[ret], v2_t);
13030 case OPC_PRECEU_QH_OBLA:
13032 gen_helper_preceu_qh_obla(cpu_gpr[ret], v2_t);
13034 case OPC_PRECEU_QH_OBRA:
13036 gen_helper_preceu_qh_obra(cpu_gpr[ret], v2_t);
13038 case OPC_ABSQ_S_OB:
13040 gen_helper_absq_s_ob(cpu_gpr[ret], v2_t, cpu_env);
13042 case OPC_ABSQ_S_PW:
13044 gen_helper_absq_s_pw(cpu_gpr[ret], v2_t, cpu_env);
13046 case OPC_ABSQ_S_QH:
13048 gen_helper_absq_s_qh(cpu_gpr[ret], v2_t, cpu_env);
13052 case OPC_ADDU_OB_DSP:
13054 case OPC_RADDU_L_OB:
13056 gen_helper_raddu_l_ob(cpu_gpr[ret], v1_t);
13060 gen_helper_subq_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13062 case OPC_SUBQ_S_PW:
13064 gen_helper_subq_s_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13068 gen_helper_subq_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13070 case OPC_SUBQ_S_QH:
13072 gen_helper_subq_s_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13076 gen_helper_subu_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13078 case OPC_SUBU_S_OB:
13080 gen_helper_subu_s_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13084 gen_helper_subu_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13086 case OPC_SUBU_S_QH:
13088 gen_helper_subu_s_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13092 gen_helper_subuh_ob(cpu_gpr[ret], v1_t, v2_t);
13094 case OPC_SUBUH_R_OB:
13096 gen_helper_subuh_r_ob(cpu_gpr[ret], v1_t, v2_t);
13100 gen_helper_addq_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13102 case OPC_ADDQ_S_PW:
13104 gen_helper_addq_s_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13108 gen_helper_addq_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13110 case OPC_ADDQ_S_QH:
13112 gen_helper_addq_s_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13116 gen_helper_addu_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13118 case OPC_ADDU_S_OB:
13120 gen_helper_addu_s_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13124 gen_helper_addu_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13126 case OPC_ADDU_S_QH:
13128 gen_helper_addu_s_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13132 gen_helper_adduh_ob(cpu_gpr[ret], v1_t, v2_t);
13134 case OPC_ADDUH_R_OB:
13136 gen_helper_adduh_r_ob(cpu_gpr[ret], v1_t, v2_t);
13140 case OPC_CMPU_EQ_OB_DSP:
13142 case OPC_PRECR_OB_QH:
13144 gen_helper_precr_ob_qh(cpu_gpr[ret], v1_t, v2_t);
13146 case OPC_PRECR_SRA_QH_PW:
13149 TCGv_i32 ret_t = tcg_const_i32(ret);
13150 gen_helper_precr_sra_qh_pw(v2_t, v1_t, v2_t, ret_t);
13151 tcg_temp_free_i32(ret_t);
13154 case OPC_PRECR_SRA_R_QH_PW:
13157 TCGv_i32 sa_v = tcg_const_i32(ret);
13158 gen_helper_precr_sra_r_qh_pw(v2_t, v1_t, v2_t, sa_v);
13159 tcg_temp_free_i32(sa_v);
13162 case OPC_PRECRQ_OB_QH:
13164 gen_helper_precrq_ob_qh(cpu_gpr[ret], v1_t, v2_t);
13166 case OPC_PRECRQ_PW_L:
13168 gen_helper_precrq_pw_l(cpu_gpr[ret], v1_t, v2_t);
13170 case OPC_PRECRQ_QH_PW:
13172 gen_helper_precrq_qh_pw(cpu_gpr[ret], v1_t, v2_t);
13174 case OPC_PRECRQ_RS_QH_PW:
13176 gen_helper_precrq_rs_qh_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13178 case OPC_PRECRQU_S_OB_QH:
13180 gen_helper_precrqu_s_ob_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13187 tcg_temp_free(v1_t);
13188 tcg_temp_free(v2_t);
13190 (void)opn; /* avoid a compiler warning */
13191 MIPS_DEBUG("%s", opn);
13194 static void gen_mipsdsp_shift(DisasContext *ctx, uint32_t opc,
13195 int ret, int v1, int v2)
13198 const char *opn = "mipsdsp shift";
13204 /* Treat as NOP. */
13209 t0 = tcg_temp_new();
13210 v1_t = tcg_temp_new();
13211 v2_t = tcg_temp_new();
13213 tcg_gen_movi_tl(t0, v1);
13214 gen_load_gpr(v1_t, v1);
13215 gen_load_gpr(v2_t, v2);
13218 case OPC_SHLL_QB_DSP:
13220 op2 = MASK_SHLL_QB(ctx->opcode);
13224 gen_helper_shll_qb(cpu_gpr[ret], t0, v2_t, cpu_env);
13228 gen_helper_shll_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13232 gen_helper_shll_ph(cpu_gpr[ret], t0, v2_t, cpu_env);
13236 gen_helper_shll_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13238 case OPC_SHLL_S_PH:
13240 gen_helper_shll_s_ph(cpu_gpr[ret], t0, v2_t, cpu_env);
13242 case OPC_SHLLV_S_PH:
13244 gen_helper_shll_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13248 gen_helper_shll_s_w(cpu_gpr[ret], t0, v2_t, cpu_env);
13250 case OPC_SHLLV_S_W:
13252 gen_helper_shll_s_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13256 gen_helper_shrl_qb(cpu_gpr[ret], t0, v2_t);
13260 gen_helper_shrl_qb(cpu_gpr[ret], v1_t, v2_t);
13264 gen_helper_shrl_ph(cpu_gpr[ret], t0, v2_t);
13268 gen_helper_shrl_ph(cpu_gpr[ret], v1_t, v2_t);
13272 gen_helper_shra_qb(cpu_gpr[ret], t0, v2_t);
13274 case OPC_SHRA_R_QB:
13276 gen_helper_shra_r_qb(cpu_gpr[ret], t0, v2_t);
13280 gen_helper_shra_qb(cpu_gpr[ret], v1_t, v2_t);
13282 case OPC_SHRAV_R_QB:
13284 gen_helper_shra_r_qb(cpu_gpr[ret], v1_t, v2_t);
13288 gen_helper_shra_ph(cpu_gpr[ret], t0, v2_t);
13290 case OPC_SHRA_R_PH:
13292 gen_helper_shra_r_ph(cpu_gpr[ret], t0, v2_t);
13296 gen_helper_shra_ph(cpu_gpr[ret], v1_t, v2_t);
13298 case OPC_SHRAV_R_PH:
13300 gen_helper_shra_r_ph(cpu_gpr[ret], v1_t, v2_t);
13304 gen_helper_shra_r_w(cpu_gpr[ret], t0, v2_t);
13306 case OPC_SHRAV_R_W:
13308 gen_helper_shra_r_w(cpu_gpr[ret], v1_t, v2_t);
13310 default: /* Invalid */
13311 MIPS_INVAL("MASK SHLL.QB");
13312 generate_exception(ctx, EXCP_RI);
13317 #ifdef TARGET_MIPS64
13318 case OPC_SHLL_OB_DSP:
13319 op2 = MASK_SHLL_OB(ctx->opcode);
13323 gen_helper_shll_pw(cpu_gpr[ret], v2_t, t0, cpu_env);
13327 gen_helper_shll_pw(cpu_gpr[ret], v2_t, v1_t, cpu_env);
13329 case OPC_SHLL_S_PW:
13331 gen_helper_shll_s_pw(cpu_gpr[ret], v2_t, t0, cpu_env);
13333 case OPC_SHLLV_S_PW:
13335 gen_helper_shll_s_pw(cpu_gpr[ret], v2_t, v1_t, cpu_env);
13339 gen_helper_shll_ob(cpu_gpr[ret], v2_t, t0, cpu_env);
13343 gen_helper_shll_ob(cpu_gpr[ret], v2_t, v1_t, cpu_env);
13347 gen_helper_shll_qh(cpu_gpr[ret], v2_t, t0, cpu_env);
13351 gen_helper_shll_qh(cpu_gpr[ret], v2_t, v1_t, cpu_env);
13353 case OPC_SHLL_S_QH:
13355 gen_helper_shll_s_qh(cpu_gpr[ret], v2_t, t0, cpu_env);
13357 case OPC_SHLLV_S_QH:
13359 gen_helper_shll_s_qh(cpu_gpr[ret], v2_t, v1_t, cpu_env);
13363 gen_helper_shra_ob(cpu_gpr[ret], v2_t, t0);
13367 gen_helper_shra_ob(cpu_gpr[ret], v2_t, v1_t);
13369 case OPC_SHRA_R_OB:
13371 gen_helper_shra_r_ob(cpu_gpr[ret], v2_t, t0);
13373 case OPC_SHRAV_R_OB:
13375 gen_helper_shra_r_ob(cpu_gpr[ret], v2_t, v1_t);
13379 gen_helper_shra_pw(cpu_gpr[ret], v2_t, t0);
13383 gen_helper_shra_pw(cpu_gpr[ret], v2_t, v1_t);
13385 case OPC_SHRA_R_PW:
13387 gen_helper_shra_r_pw(cpu_gpr[ret], v2_t, t0);
13389 case OPC_SHRAV_R_PW:
13391 gen_helper_shra_r_pw(cpu_gpr[ret], v2_t, v1_t);
13395 gen_helper_shra_qh(cpu_gpr[ret], v2_t, t0);
13399 gen_helper_shra_qh(cpu_gpr[ret], v2_t, v1_t);
13401 case OPC_SHRA_R_QH:
13403 gen_helper_shra_r_qh(cpu_gpr[ret], v2_t, t0);
13405 case OPC_SHRAV_R_QH:
13407 gen_helper_shra_r_qh(cpu_gpr[ret], v2_t, v1_t);
13411 gen_helper_shrl_ob(cpu_gpr[ret], v2_t, t0);
13415 gen_helper_shrl_ob(cpu_gpr[ret], v2_t, v1_t);
13419 gen_helper_shrl_qh(cpu_gpr[ret], v2_t, t0);
13423 gen_helper_shrl_qh(cpu_gpr[ret], v2_t, v1_t);
13425 default: /* Invalid */
13426 MIPS_INVAL("MASK SHLL.OB");
13427 generate_exception(ctx, EXCP_RI);
13435 tcg_temp_free(v1_t);
13436 tcg_temp_free(v2_t);
13437 (void)opn; /* avoid a compiler warning */
13438 MIPS_DEBUG("%s", opn);
13441 static void gen_mipsdsp_multiply(DisasContext *ctx, uint32_t op1, uint32_t op2,
13442 int ret, int v1, int v2, int check_ret)
13444 const char *opn = "mipsdsp multiply";
13449 if ((ret == 0) && (check_ret == 1)) {
13450 /* Treat as NOP. */
13455 t0 = tcg_temp_new_i32();
13456 v1_t = tcg_temp_new();
13457 v2_t = tcg_temp_new();
13459 tcg_gen_movi_i32(t0, ret);
13460 gen_load_gpr(v1_t, v1);
13461 gen_load_gpr(v2_t, v2);
13464 /* OPC_MULT_G_2E, OPC_ADDUH_QB_DSP, OPC_MUL_PH_DSP have
13465 * the same mask and op1. */
13466 case OPC_MULT_G_2E:
13469 gen_helper_mul_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13472 gen_helper_mul_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13475 gen_helper_mulq_s_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13477 case OPC_MULQ_RS_W:
13478 gen_helper_mulq_rs_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13482 case OPC_DPA_W_PH_DSP:
13484 case OPC_DPAU_H_QBL:
13486 gen_helper_dpau_h_qbl(t0, v1_t, v2_t, cpu_env);
13488 case OPC_DPAU_H_QBR:
13490 gen_helper_dpau_h_qbr(t0, v1_t, v2_t, cpu_env);
13492 case OPC_DPSU_H_QBL:
13494 gen_helper_dpsu_h_qbl(t0, v1_t, v2_t, cpu_env);
13496 case OPC_DPSU_H_QBR:
13498 gen_helper_dpsu_h_qbr(t0, v1_t, v2_t, cpu_env);
13502 gen_helper_dpa_w_ph(t0, v1_t, v2_t, cpu_env);
13504 case OPC_DPAX_W_PH:
13506 gen_helper_dpax_w_ph(t0, v1_t, v2_t, cpu_env);
13508 case OPC_DPAQ_S_W_PH:
13510 gen_helper_dpaq_s_w_ph(t0, v1_t, v2_t, cpu_env);
13512 case OPC_DPAQX_S_W_PH:
13514 gen_helper_dpaqx_s_w_ph(t0, v1_t, v2_t, cpu_env);
13516 case OPC_DPAQX_SA_W_PH:
13518 gen_helper_dpaqx_sa_w_ph(t0, v1_t, v2_t, cpu_env);
13522 gen_helper_dps_w_ph(t0, v1_t, v2_t, cpu_env);
13524 case OPC_DPSX_W_PH:
13526 gen_helper_dpsx_w_ph(t0, v1_t, v2_t, cpu_env);
13528 case OPC_DPSQ_S_W_PH:
13530 gen_helper_dpsq_s_w_ph(t0, v1_t, v2_t, cpu_env);
13532 case OPC_DPSQX_S_W_PH:
13534 gen_helper_dpsqx_s_w_ph(t0, v1_t, v2_t, cpu_env);
13536 case OPC_DPSQX_SA_W_PH:
13538 gen_helper_dpsqx_sa_w_ph(t0, v1_t, v2_t, cpu_env);
13540 case OPC_MULSAQ_S_W_PH:
13542 gen_helper_mulsaq_s_w_ph(t0, v1_t, v2_t, cpu_env);
13544 case OPC_DPAQ_SA_L_W:
13546 gen_helper_dpaq_sa_l_w(t0, v1_t, v2_t, cpu_env);
13548 case OPC_DPSQ_SA_L_W:
13550 gen_helper_dpsq_sa_l_w(t0, v1_t, v2_t, cpu_env);
13552 case OPC_MAQ_S_W_PHL:
13554 gen_helper_maq_s_w_phl(t0, v1_t, v2_t, cpu_env);
13556 case OPC_MAQ_S_W_PHR:
13558 gen_helper_maq_s_w_phr(t0, v1_t, v2_t, cpu_env);
13560 case OPC_MAQ_SA_W_PHL:
13562 gen_helper_maq_sa_w_phl(t0, v1_t, v2_t, cpu_env);
13564 case OPC_MAQ_SA_W_PHR:
13566 gen_helper_maq_sa_w_phr(t0, v1_t, v2_t, cpu_env);
13568 case OPC_MULSA_W_PH:
13570 gen_helper_mulsa_w_ph(t0, v1_t, v2_t, cpu_env);
13574 #ifdef TARGET_MIPS64
13575 case OPC_DPAQ_W_QH_DSP:
13577 int ac = ret & 0x03;
13578 tcg_gen_movi_i32(t0, ac);
13583 gen_helper_dmadd(v1_t, v2_t, t0, cpu_env);
13587 gen_helper_dmaddu(v1_t, v2_t, t0, cpu_env);
13591 gen_helper_dmsub(v1_t, v2_t, t0, cpu_env);
13595 gen_helper_dmsubu(v1_t, v2_t, t0, cpu_env);
13599 gen_helper_dpa_w_qh(v1_t, v2_t, t0, cpu_env);
13601 case OPC_DPAQ_S_W_QH:
13603 gen_helper_dpaq_s_w_qh(v1_t, v2_t, t0, cpu_env);
13605 case OPC_DPAQ_SA_L_PW:
13607 gen_helper_dpaq_sa_l_pw(v1_t, v2_t, t0, cpu_env);
13609 case OPC_DPAU_H_OBL:
13611 gen_helper_dpau_h_obl(v1_t, v2_t, t0, cpu_env);
13613 case OPC_DPAU_H_OBR:
13615 gen_helper_dpau_h_obr(v1_t, v2_t, t0, cpu_env);
13619 gen_helper_dps_w_qh(v1_t, v2_t, t0, cpu_env);
13621 case OPC_DPSQ_S_W_QH:
13623 gen_helper_dpsq_s_w_qh(v1_t, v2_t, t0, cpu_env);
13625 case OPC_DPSQ_SA_L_PW:
13627 gen_helper_dpsq_sa_l_pw(v1_t, v2_t, t0, cpu_env);
13629 case OPC_DPSU_H_OBL:
13631 gen_helper_dpsu_h_obl(v1_t, v2_t, t0, cpu_env);
13633 case OPC_DPSU_H_OBR:
13635 gen_helper_dpsu_h_obr(v1_t, v2_t, t0, cpu_env);
13637 case OPC_MAQ_S_L_PWL:
13639 gen_helper_maq_s_l_pwl(v1_t, v2_t, t0, cpu_env);
13641 case OPC_MAQ_S_L_PWR:
13643 gen_helper_maq_s_l_pwr(v1_t, v2_t, t0, cpu_env);
13645 case OPC_MAQ_S_W_QHLL:
13647 gen_helper_maq_s_w_qhll(v1_t, v2_t, t0, cpu_env);
13649 case OPC_MAQ_SA_W_QHLL:
13651 gen_helper_maq_sa_w_qhll(v1_t, v2_t, t0, cpu_env);
13653 case OPC_MAQ_S_W_QHLR:
13655 gen_helper_maq_s_w_qhlr(v1_t, v2_t, t0, cpu_env);
13657 case OPC_MAQ_SA_W_QHLR:
13659 gen_helper_maq_sa_w_qhlr(v1_t, v2_t, t0, cpu_env);
13661 case OPC_MAQ_S_W_QHRL:
13663 gen_helper_maq_s_w_qhrl(v1_t, v2_t, t0, cpu_env);
13665 case OPC_MAQ_SA_W_QHRL:
13667 gen_helper_maq_sa_w_qhrl(v1_t, v2_t, t0, cpu_env);
13669 case OPC_MAQ_S_W_QHRR:
13671 gen_helper_maq_s_w_qhrr(v1_t, v2_t, t0, cpu_env);
13673 case OPC_MAQ_SA_W_QHRR:
13675 gen_helper_maq_sa_w_qhrr(v1_t, v2_t, t0, cpu_env);
13677 case OPC_MULSAQ_S_L_PW:
13679 gen_helper_mulsaq_s_l_pw(v1_t, v2_t, t0, cpu_env);
13681 case OPC_MULSAQ_S_W_QH:
13683 gen_helper_mulsaq_s_w_qh(v1_t, v2_t, t0, cpu_env);
13689 case OPC_ADDU_QB_DSP:
13691 case OPC_MULEU_S_PH_QBL:
13693 gen_helper_muleu_s_ph_qbl(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13695 case OPC_MULEU_S_PH_QBR:
13697 gen_helper_muleu_s_ph_qbr(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13699 case OPC_MULQ_RS_PH:
13701 gen_helper_mulq_rs_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13703 case OPC_MULEQ_S_W_PHL:
13705 gen_helper_muleq_s_w_phl(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13707 case OPC_MULEQ_S_W_PHR:
13709 gen_helper_muleq_s_w_phr(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13711 case OPC_MULQ_S_PH:
13713 gen_helper_mulq_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13717 #ifdef TARGET_MIPS64
13718 case OPC_ADDU_OB_DSP:
13720 case OPC_MULEQ_S_PW_QHL:
13722 gen_helper_muleq_s_pw_qhl(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13724 case OPC_MULEQ_S_PW_QHR:
13726 gen_helper_muleq_s_pw_qhr(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13728 case OPC_MULEU_S_QH_OBL:
13730 gen_helper_muleu_s_qh_obl(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13732 case OPC_MULEU_S_QH_OBR:
13734 gen_helper_muleu_s_qh_obr(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13736 case OPC_MULQ_RS_QH:
13738 gen_helper_mulq_rs_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13745 tcg_temp_free_i32(t0);
13746 tcg_temp_free(v1_t);
13747 tcg_temp_free(v2_t);
13749 (void)opn; /* avoid a compiler warning */
13750 MIPS_DEBUG("%s", opn);
13754 static void gen_mipsdsp_bitinsn(CPUMIPSState *env, DisasContext *ctx,
13755 uint32_t op1, uint32_t op2,
13758 const char *opn = "mipsdsp Bit/ Manipulation";
13764 /* Treat as NOP. */
13769 t0 = tcg_temp_new();
13770 val_t = tcg_temp_new();
13771 gen_load_gpr(val_t, val);
13774 case OPC_ABSQ_S_PH_DSP:
13778 gen_helper_bitrev(cpu_gpr[ret], val_t);
13783 target_long result;
13784 imm = (ctx->opcode >> 16) & 0xFF;
13785 result = (uint32_t)imm << 24 |
13786 (uint32_t)imm << 16 |
13787 (uint32_t)imm << 8 |
13789 result = (int32_t)result;
13790 tcg_gen_movi_tl(cpu_gpr[ret], result);
13795 tcg_gen_ext8u_tl(cpu_gpr[ret], val_t);
13796 tcg_gen_shli_tl(t0, cpu_gpr[ret], 8);
13797 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
13798 tcg_gen_shli_tl(t0, cpu_gpr[ret], 16);
13799 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
13800 tcg_gen_ext32s_tl(cpu_gpr[ret], cpu_gpr[ret]);
13805 imm = (ctx->opcode >> 16) & 0x03FF;
13806 tcg_gen_movi_tl(cpu_gpr[ret], \
13807 (target_long)((int32_t)imm << 16 | \
13808 (uint32_t)(uint16_t)imm));
13813 tcg_gen_ext16u_tl(cpu_gpr[ret], val_t);
13814 tcg_gen_shli_tl(t0, cpu_gpr[ret], 16);
13815 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
13816 tcg_gen_ext32s_tl(cpu_gpr[ret], cpu_gpr[ret]);
13820 #ifdef TARGET_MIPS64
13821 case OPC_ABSQ_S_QH_DSP:
13828 imm = (ctx->opcode >> 16) & 0xFF;
13829 temp = ((uint64_t)imm << 8) | (uint64_t)imm;
13830 temp = (temp << 16) | temp;
13831 temp = (temp << 32) | temp;
13832 tcg_gen_movi_tl(cpu_gpr[ret], temp);
13840 imm = (ctx->opcode >> 16) & 0x03FF;
13841 imm = (int16_t)(imm << 6) >> 6;
13842 temp = ((target_long)imm << 32) \
13843 | ((target_long)imm & 0xFFFFFFFF);
13844 tcg_gen_movi_tl(cpu_gpr[ret], temp);
13852 imm = (ctx->opcode >> 16) & 0x03FF;
13853 imm = (int16_t)(imm << 6) >> 6;
13855 temp = ((uint64_t)(uint16_t)imm << 48) |
13856 ((uint64_t)(uint16_t)imm << 32) |
13857 ((uint64_t)(uint16_t)imm << 16) |
13858 (uint64_t)(uint16_t)imm;
13859 tcg_gen_movi_tl(cpu_gpr[ret], temp);
13864 tcg_gen_ext8u_tl(cpu_gpr[ret], val_t);
13865 tcg_gen_shli_tl(t0, cpu_gpr[ret], 8);
13866 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
13867 tcg_gen_shli_tl(t0, cpu_gpr[ret], 16);
13868 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
13869 tcg_gen_shli_tl(t0, cpu_gpr[ret], 32);
13870 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
13874 tcg_gen_ext32u_i64(cpu_gpr[ret], val_t);
13875 tcg_gen_shli_tl(t0, cpu_gpr[ret], 32);
13876 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
13880 tcg_gen_ext16u_tl(cpu_gpr[ret], val_t);
13881 tcg_gen_shli_tl(t0, cpu_gpr[ret], 16);
13882 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
13883 tcg_gen_shli_tl(t0, cpu_gpr[ret], 32);
13884 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
13891 tcg_temp_free(val_t);
13893 (void)opn; /* avoid a compiler warning */
13894 MIPS_DEBUG("%s", opn);
13897 static void gen_mipsdsp_add_cmp_pick(DisasContext *ctx,
13898 uint32_t op1, uint32_t op2,
13899 int ret, int v1, int v2, int check_ret)
13901 const char *opn = "mipsdsp add compare pick";
13907 if ((ret == 0) && (check_ret == 1)) {
13908 /* Treat as NOP. */
13913 t0 = tcg_temp_new_i32();
13914 t1 = tcg_temp_new();
13915 v1_t = tcg_temp_new();
13916 v2_t = tcg_temp_new();
13918 gen_load_gpr(v1_t, v1);
13919 gen_load_gpr(v2_t, v2);
13922 case OPC_APPEND_DSP:
13925 tcg_gen_movi_i32(t0, v2);
13926 gen_helper_append(cpu_gpr[ret], cpu_gpr[ret], v1_t, t0);
13929 tcg_gen_movi_i32(t0, v2);
13930 gen_helper_prepend(cpu_gpr[ret], v1_t, cpu_gpr[ret], t0);
13933 tcg_gen_movi_i32(t0, v2);
13934 gen_helper_balign(cpu_gpr[ret], v1_t, cpu_gpr[ret], t0);
13936 default: /* Invid */
13937 MIPS_INVAL("MASK APPEND");
13938 generate_exception(ctx, EXCP_RI);
13942 case OPC_CMPU_EQ_QB_DSP:
13944 case OPC_CMPU_EQ_QB:
13946 gen_helper_cmpu_eq_qb(v1_t, v2_t, cpu_env);
13948 case OPC_CMPU_LT_QB:
13950 gen_helper_cmpu_lt_qb(v1_t, v2_t, cpu_env);
13952 case OPC_CMPU_LE_QB:
13954 gen_helper_cmpu_le_qb(v1_t, v2_t, cpu_env);
13956 case OPC_CMPGU_EQ_QB:
13958 gen_helper_cmpgu_eq_qb(cpu_gpr[ret], v1_t, v2_t);
13960 case OPC_CMPGU_LT_QB:
13962 gen_helper_cmpgu_lt_qb(cpu_gpr[ret], v1_t, v2_t);
13964 case OPC_CMPGU_LE_QB:
13966 gen_helper_cmpgu_le_qb(cpu_gpr[ret], v1_t, v2_t);
13968 case OPC_CMPGDU_EQ_QB:
13970 gen_helper_cmpgu_eq_qb(t1, v1_t, v2_t);
13971 tcg_gen_mov_tl(cpu_gpr[ret], t1);
13972 tcg_gen_andi_tl(cpu_dspctrl, cpu_dspctrl, 0xF0FFFFFF);
13973 tcg_gen_shli_tl(t1, t1, 24);
13974 tcg_gen_or_tl(cpu_dspctrl, cpu_dspctrl, t1);
13976 case OPC_CMPGDU_LT_QB:
13978 gen_helper_cmpgu_lt_qb(t1, v1_t, v2_t);
13979 tcg_gen_mov_tl(cpu_gpr[ret], t1);
13980 tcg_gen_andi_tl(cpu_dspctrl, cpu_dspctrl, 0xF0FFFFFF);
13981 tcg_gen_shli_tl(t1, t1, 24);
13982 tcg_gen_or_tl(cpu_dspctrl, cpu_dspctrl, t1);
13984 case OPC_CMPGDU_LE_QB:
13986 gen_helper_cmpgu_le_qb(t1, v1_t, v2_t);
13987 tcg_gen_mov_tl(cpu_gpr[ret], t1);
13988 tcg_gen_andi_tl(cpu_dspctrl, cpu_dspctrl, 0xF0FFFFFF);
13989 tcg_gen_shli_tl(t1, t1, 24);
13990 tcg_gen_or_tl(cpu_dspctrl, cpu_dspctrl, t1);
13992 case OPC_CMP_EQ_PH:
13994 gen_helper_cmp_eq_ph(v1_t, v2_t, cpu_env);
13996 case OPC_CMP_LT_PH:
13998 gen_helper_cmp_lt_ph(v1_t, v2_t, cpu_env);
14000 case OPC_CMP_LE_PH:
14002 gen_helper_cmp_le_ph(v1_t, v2_t, cpu_env);
14006 gen_helper_pick_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
14010 gen_helper_pick_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
14012 case OPC_PACKRL_PH:
14014 gen_helper_packrl_ph(cpu_gpr[ret], v1_t, v2_t);
14018 #ifdef TARGET_MIPS64
14019 case OPC_CMPU_EQ_OB_DSP:
14021 case OPC_CMP_EQ_PW:
14023 gen_helper_cmp_eq_pw(v1_t, v2_t, cpu_env);
14025 case OPC_CMP_LT_PW:
14027 gen_helper_cmp_lt_pw(v1_t, v2_t, cpu_env);
14029 case OPC_CMP_LE_PW:
14031 gen_helper_cmp_le_pw(v1_t, v2_t, cpu_env);
14033 case OPC_CMP_EQ_QH:
14035 gen_helper_cmp_eq_qh(v1_t, v2_t, cpu_env);
14037 case OPC_CMP_LT_QH:
14039 gen_helper_cmp_lt_qh(v1_t, v2_t, cpu_env);
14041 case OPC_CMP_LE_QH:
14043 gen_helper_cmp_le_qh(v1_t, v2_t, cpu_env);
14045 case OPC_CMPGDU_EQ_OB:
14047 gen_helper_cmpgdu_eq_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
14049 case OPC_CMPGDU_LT_OB:
14051 gen_helper_cmpgdu_lt_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
14053 case OPC_CMPGDU_LE_OB:
14055 gen_helper_cmpgdu_le_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
14057 case OPC_CMPGU_EQ_OB:
14059 gen_helper_cmpgu_eq_ob(cpu_gpr[ret], v1_t, v2_t);
14061 case OPC_CMPGU_LT_OB:
14063 gen_helper_cmpgu_lt_ob(cpu_gpr[ret], v1_t, v2_t);
14065 case OPC_CMPGU_LE_OB:
14067 gen_helper_cmpgu_le_ob(cpu_gpr[ret], v1_t, v2_t);
14069 case OPC_CMPU_EQ_OB:
14071 gen_helper_cmpu_eq_ob(v1_t, v2_t, cpu_env);
14073 case OPC_CMPU_LT_OB:
14075 gen_helper_cmpu_lt_ob(v1_t, v2_t, cpu_env);
14077 case OPC_CMPU_LE_OB:
14079 gen_helper_cmpu_le_ob(v1_t, v2_t, cpu_env);
14081 case OPC_PACKRL_PW:
14083 gen_helper_packrl_pw(cpu_gpr[ret], v1_t, v2_t);
14087 gen_helper_pick_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
14091 gen_helper_pick_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
14095 gen_helper_pick_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
14099 case OPC_DAPPEND_DSP:
14102 tcg_gen_movi_i32(t0, v2);
14103 gen_helper_dappend(cpu_gpr[ret], v1_t, cpu_gpr[ret], t0);
14106 tcg_gen_movi_i32(t0, v2);
14107 gen_helper_prependd(cpu_gpr[ret], v1_t, cpu_gpr[ret], t0);
14110 tcg_gen_movi_i32(t0, v2);
14111 gen_helper_prependw(cpu_gpr[ret], v1_t, cpu_gpr[ret], t0);
14114 tcg_gen_movi_i32(t0, v2);
14115 gen_helper_dbalign(cpu_gpr[ret], v1_t, cpu_gpr[ret], t0);
14117 default: /* Invalid */
14118 MIPS_INVAL("MASK DAPPEND");
14119 generate_exception(ctx, EXCP_RI);
14126 tcg_temp_free_i32(t0);
14128 tcg_temp_free(v1_t);
14129 tcg_temp_free(v2_t);
14131 (void)opn; /* avoid a compiler warning */
14132 MIPS_DEBUG("%s", opn);
14135 static void gen_mipsdsp_accinsn(DisasContext *ctx, uint32_t op1, uint32_t op2,
14136 int ret, int v1, int v2, int check_ret)
14139 const char *opn = "mipsdsp accumulator";
14146 if ((ret == 0) && (check_ret == 1)) {
14147 /* Treat as NOP. */
14152 t0 = tcg_temp_new();
14153 t1 = tcg_temp_new();
14154 v1_t = tcg_temp_new();
14155 v2_t = tcg_temp_new();
14157 gen_load_gpr(v1_t, v1);
14158 gen_load_gpr(v2_t, v2);
14161 case OPC_EXTR_W_DSP:
14165 tcg_gen_movi_tl(t0, v2);
14166 tcg_gen_movi_tl(t1, v1);
14167 gen_helper_extr_w(cpu_gpr[ret], t0, t1, cpu_env);
14170 tcg_gen_movi_tl(t0, v2);
14171 tcg_gen_movi_tl(t1, v1);
14172 gen_helper_extr_r_w(cpu_gpr[ret], t0, t1, cpu_env);
14174 case OPC_EXTR_RS_W:
14175 tcg_gen_movi_tl(t0, v2);
14176 tcg_gen_movi_tl(t1, v1);
14177 gen_helper_extr_rs_w(cpu_gpr[ret], t0, t1, cpu_env);
14180 tcg_gen_movi_tl(t0, v2);
14181 tcg_gen_movi_tl(t1, v1);
14182 gen_helper_extr_s_h(cpu_gpr[ret], t0, t1, cpu_env);
14184 case OPC_EXTRV_S_H:
14185 tcg_gen_movi_tl(t0, v2);
14186 gen_helper_extr_s_h(cpu_gpr[ret], t0, v1_t, cpu_env);
14189 tcg_gen_movi_tl(t0, v2);
14190 gen_helper_extr_w(cpu_gpr[ret], t0, v1_t, cpu_env);
14192 case OPC_EXTRV_R_W:
14193 tcg_gen_movi_tl(t0, v2);
14194 gen_helper_extr_r_w(cpu_gpr[ret], t0, v1_t, cpu_env);
14196 case OPC_EXTRV_RS_W:
14197 tcg_gen_movi_tl(t0, v2);
14198 gen_helper_extr_rs_w(cpu_gpr[ret], t0, v1_t, cpu_env);
14201 tcg_gen_movi_tl(t0, v2);
14202 tcg_gen_movi_tl(t1, v1);
14203 gen_helper_extp(cpu_gpr[ret], t0, t1, cpu_env);
14206 tcg_gen_movi_tl(t0, v2);
14207 gen_helper_extp(cpu_gpr[ret], t0, v1_t, cpu_env);
14210 tcg_gen_movi_tl(t0, v2);
14211 tcg_gen_movi_tl(t1, v1);
14212 gen_helper_extpdp(cpu_gpr[ret], t0, t1, cpu_env);
14215 tcg_gen_movi_tl(t0, v2);
14216 gen_helper_extpdp(cpu_gpr[ret], t0, v1_t, cpu_env);
14219 imm = (ctx->opcode >> 20) & 0x3F;
14220 tcg_gen_movi_tl(t0, ret);
14221 tcg_gen_movi_tl(t1, imm);
14222 gen_helper_shilo(t0, t1, cpu_env);
14225 tcg_gen_movi_tl(t0, ret);
14226 gen_helper_shilo(t0, v1_t, cpu_env);
14229 tcg_gen_movi_tl(t0, ret);
14230 gen_helper_mthlip(t0, v1_t, cpu_env);
14233 imm = (ctx->opcode >> 11) & 0x3FF;
14234 tcg_gen_movi_tl(t0, imm);
14235 gen_helper_wrdsp(v1_t, t0, cpu_env);
14238 imm = (ctx->opcode >> 16) & 0x03FF;
14239 tcg_gen_movi_tl(t0, imm);
14240 gen_helper_rddsp(cpu_gpr[ret], t0, cpu_env);
14244 #ifdef TARGET_MIPS64
14245 case OPC_DEXTR_W_DSP:
14249 tcg_gen_movi_tl(t0, ret);
14250 gen_helper_dmthlip(v1_t, t0, cpu_env);
14254 int shift = (ctx->opcode >> 19) & 0x7F;
14255 int ac = (ctx->opcode >> 11) & 0x03;
14256 tcg_gen_movi_tl(t0, shift);
14257 tcg_gen_movi_tl(t1, ac);
14258 gen_helper_dshilo(t0, t1, cpu_env);
14263 int ac = (ctx->opcode >> 11) & 0x03;
14264 tcg_gen_movi_tl(t0, ac);
14265 gen_helper_dshilo(v1_t, t0, cpu_env);
14269 tcg_gen_movi_tl(t0, v2);
14270 tcg_gen_movi_tl(t1, v1);
14272 gen_helper_dextp(cpu_gpr[ret], t0, t1, cpu_env);
14275 tcg_gen_movi_tl(t0, v2);
14276 gen_helper_dextp(cpu_gpr[ret], t0, v1_t, cpu_env);
14279 tcg_gen_movi_tl(t0, v2);
14280 tcg_gen_movi_tl(t1, v1);
14281 gen_helper_dextpdp(cpu_gpr[ret], t0, t1, cpu_env);
14284 tcg_gen_movi_tl(t0, v2);
14285 gen_helper_dextpdp(cpu_gpr[ret], t0, v1_t, cpu_env);
14288 tcg_gen_movi_tl(t0, v2);
14289 tcg_gen_movi_tl(t1, v1);
14290 gen_helper_dextr_l(cpu_gpr[ret], t0, t1, cpu_env);
14292 case OPC_DEXTR_R_L:
14293 tcg_gen_movi_tl(t0, v2);
14294 tcg_gen_movi_tl(t1, v1);
14295 gen_helper_dextr_r_l(cpu_gpr[ret], t0, t1, cpu_env);
14297 case OPC_DEXTR_RS_L:
14298 tcg_gen_movi_tl(t0, v2);
14299 tcg_gen_movi_tl(t1, v1);
14300 gen_helper_dextr_rs_l(cpu_gpr[ret], t0, t1, cpu_env);
14303 tcg_gen_movi_tl(t0, v2);
14304 tcg_gen_movi_tl(t1, v1);
14305 gen_helper_dextr_w(cpu_gpr[ret], t0, t1, cpu_env);
14307 case OPC_DEXTR_R_W:
14308 tcg_gen_movi_tl(t0, v2);
14309 tcg_gen_movi_tl(t1, v1);
14310 gen_helper_dextr_r_w(cpu_gpr[ret], t0, t1, cpu_env);
14312 case OPC_DEXTR_RS_W:
14313 tcg_gen_movi_tl(t0, v2);
14314 tcg_gen_movi_tl(t1, v1);
14315 gen_helper_dextr_rs_w(cpu_gpr[ret], t0, t1, cpu_env);
14317 case OPC_DEXTR_S_H:
14318 tcg_gen_movi_tl(t0, v2);
14319 tcg_gen_movi_tl(t1, v1);
14320 gen_helper_dextr_s_h(cpu_gpr[ret], t0, t1, cpu_env);
14322 case OPC_DEXTRV_S_H:
14323 tcg_gen_movi_tl(t0, v2);
14324 tcg_gen_movi_tl(t1, v1);
14325 gen_helper_dextr_s_h(cpu_gpr[ret], t0, t1, cpu_env);
14328 tcg_gen_movi_tl(t0, v2);
14329 gen_helper_dextr_l(cpu_gpr[ret], t0, v1_t, cpu_env);
14331 case OPC_DEXTRV_R_L:
14332 tcg_gen_movi_tl(t0, v2);
14333 gen_helper_dextr_r_l(cpu_gpr[ret], t0, v1_t, cpu_env);
14335 case OPC_DEXTRV_RS_L:
14336 tcg_gen_movi_tl(t0, v2);
14337 gen_helper_dextr_rs_l(cpu_gpr[ret], t0, v1_t, cpu_env);
14340 tcg_gen_movi_tl(t0, v2);
14341 gen_helper_dextr_w(cpu_gpr[ret], t0, v1_t, cpu_env);
14343 case OPC_DEXTRV_R_W:
14344 tcg_gen_movi_tl(t0, v2);
14345 gen_helper_dextr_r_w(cpu_gpr[ret], t0, v1_t, cpu_env);
14347 case OPC_DEXTRV_RS_W:
14348 tcg_gen_movi_tl(t0, v2);
14349 gen_helper_dextr_rs_w(cpu_gpr[ret], t0, v1_t, cpu_env);
14358 tcg_temp_free(v1_t);
14359 tcg_temp_free(v2_t);
14361 (void)opn; /* avoid a compiler warning */
14362 MIPS_DEBUG("%s", opn);
14365 /* End MIPSDSP functions. */
14367 static void decode_opc (CPUMIPSState *env, DisasContext *ctx, int *is_branch)
14370 int rs, rt, rd, sa;
14371 uint32_t op, op1, op2;
14374 /* make sure instructions are on a word boundary */
14375 if (ctx->pc & 0x3) {
14376 env->CP0_BadVAddr = ctx->pc;
14377 generate_exception(ctx, EXCP_AdEL);
14381 /* Handle blikely not taken case */
14382 if ((ctx->hflags & MIPS_HFLAG_BMASK_BASE) == MIPS_HFLAG_BL) {
14383 int l1 = gen_new_label();
14385 MIPS_DEBUG("blikely condition (" TARGET_FMT_lx ")", ctx->pc + 4);
14386 tcg_gen_brcondi_tl(TCG_COND_NE, bcond, 0, l1);
14387 tcg_gen_movi_i32(hflags, ctx->hflags & ~MIPS_HFLAG_BMASK);
14388 gen_goto_tb(ctx, 1, ctx->pc + 4);
14392 if (unlikely(qemu_loglevel_mask(CPU_LOG_TB_OP | CPU_LOG_TB_OP_OPT))) {
14393 tcg_gen_debug_insn_start(ctx->pc);
14396 op = MASK_OP_MAJOR(ctx->opcode);
14397 rs = (ctx->opcode >> 21) & 0x1f;
14398 rt = (ctx->opcode >> 16) & 0x1f;
14399 rd = (ctx->opcode >> 11) & 0x1f;
14400 sa = (ctx->opcode >> 6) & 0x1f;
14401 imm = (int16_t)ctx->opcode;
14404 op1 = MASK_SPECIAL(ctx->opcode);
14406 case OPC_SLL: /* Shift with immediate */
14408 gen_shift_imm(env, ctx, op1, rd, rt, sa);
14411 switch ((ctx->opcode >> 21) & 0x1f) {
14413 /* rotr is decoded as srl on non-R2 CPUs */
14414 if (env->insn_flags & ISA_MIPS32R2) {
14419 gen_shift_imm(env, ctx, op1, rd, rt, sa);
14422 generate_exception(ctx, EXCP_RI);
14426 case OPC_MOVN: /* Conditional move */
14428 check_insn(env, ctx, ISA_MIPS4 | ISA_MIPS32 |
14429 INSN_LOONGSON2E | INSN_LOONGSON2F);
14430 gen_cond_move(env, ctx, op1, rd, rs, rt);
14432 case OPC_ADD ... OPC_SUBU:
14433 gen_arith(env, ctx, op1, rd, rs, rt);
14435 case OPC_SLLV: /* Shifts */
14437 gen_shift(env, ctx, op1, rd, rs, rt);
14440 switch ((ctx->opcode >> 6) & 0x1f) {
14442 /* rotrv is decoded as srlv on non-R2 CPUs */
14443 if (env->insn_flags & ISA_MIPS32R2) {
14448 gen_shift(env, ctx, op1, rd, rs, rt);
14451 generate_exception(ctx, EXCP_RI);
14455 case OPC_SLT: /* Set on less than */
14457 gen_slt(env, ctx, op1, rd, rs, rt);
14459 case OPC_AND: /* Logic*/
14463 gen_logic(env, ctx, op1, rd, rs, rt);
14465 case OPC_MULT ... OPC_DIVU:
14467 check_insn(env, ctx, INSN_VR54XX);
14468 op1 = MASK_MUL_VR54XX(ctx->opcode);
14469 gen_mul_vr54xx(ctx, op1, rd, rs, rt);
14471 gen_muldiv(ctx, op1, rs, rt);
14473 case OPC_JR ... OPC_JALR:
14474 gen_compute_branch(ctx, op1, 4, rs, rd, sa);
14477 case OPC_TGE ... OPC_TEQ: /* Traps */
14479 gen_trap(ctx, op1, rs, rt, -1);
14481 case OPC_MFHI: /* Move from HI/LO */
14483 gen_HILO(ctx, op1, rd);
14486 case OPC_MTLO: /* Move to HI/LO */
14487 gen_HILO(ctx, op1, rs);
14489 case OPC_PMON: /* Pmon entry point, also R4010 selsl */
14490 #ifdef MIPS_STRICT_STANDARD
14491 MIPS_INVAL("PMON / selsl");
14492 generate_exception(ctx, EXCP_RI);
14494 gen_helper_0e0i(pmon, sa);
14498 generate_exception(ctx, EXCP_SYSCALL);
14499 ctx->bstate = BS_STOP;
14502 generate_exception(ctx, EXCP_BREAK);
14505 #ifdef MIPS_STRICT_STANDARD
14506 MIPS_INVAL("SPIM");
14507 generate_exception(ctx, EXCP_RI);
14509 /* Implemented as RI exception for now. */
14510 MIPS_INVAL("spim (unofficial)");
14511 generate_exception(ctx, EXCP_RI);
14515 /* Treat as NOP. */
14519 check_insn(env, ctx, ISA_MIPS4 | ISA_MIPS32);
14520 if (env->CP0_Config1 & (1 << CP0C1_FP)) {
14521 check_cp1_enabled(ctx);
14522 gen_movci(ctx, rd, rs, (ctx->opcode >> 18) & 0x7,
14523 (ctx->opcode >> 16) & 1);
14525 generate_exception_err(ctx, EXCP_CpU, 1);
14529 #if defined(TARGET_MIPS64)
14530 /* MIPS64 specific opcodes */
14535 check_insn(env, ctx, ISA_MIPS3);
14536 check_mips_64(ctx);
14537 gen_shift_imm(env, ctx, op1, rd, rt, sa);
14540 switch ((ctx->opcode >> 21) & 0x1f) {
14542 /* drotr is decoded as dsrl on non-R2 CPUs */
14543 if (env->insn_flags & ISA_MIPS32R2) {
14548 check_insn(env, ctx, ISA_MIPS3);
14549 check_mips_64(ctx);
14550 gen_shift_imm(env, ctx, op1, rd, rt, sa);
14553 generate_exception(ctx, EXCP_RI);
14558 switch ((ctx->opcode >> 21) & 0x1f) {
14560 /* drotr32 is decoded as dsrl32 on non-R2 CPUs */
14561 if (env->insn_flags & ISA_MIPS32R2) {
14566 check_insn(env, ctx, ISA_MIPS3);
14567 check_mips_64(ctx);
14568 gen_shift_imm(env, ctx, op1, rd, rt, sa);
14571 generate_exception(ctx, EXCP_RI);
14575 case OPC_DADD ... OPC_DSUBU:
14576 check_insn(env, ctx, ISA_MIPS3);
14577 check_mips_64(ctx);
14578 gen_arith(env, ctx, op1, rd, rs, rt);
14582 check_insn(env, ctx, ISA_MIPS3);
14583 check_mips_64(ctx);
14584 gen_shift(env, ctx, op1, rd, rs, rt);
14587 switch ((ctx->opcode >> 6) & 0x1f) {
14589 /* drotrv is decoded as dsrlv on non-R2 CPUs */
14590 if (env->insn_flags & ISA_MIPS32R2) {
14595 check_insn(env, ctx, ISA_MIPS3);
14596 check_mips_64(ctx);
14597 gen_shift(env, ctx, op1, rd, rs, rt);
14600 generate_exception(ctx, EXCP_RI);
14604 case OPC_DMULT ... OPC_DDIVU:
14605 check_insn(env, ctx, ISA_MIPS3);
14606 check_mips_64(ctx);
14607 gen_muldiv(ctx, op1, rs, rt);
14610 default: /* Invalid */
14611 MIPS_INVAL("special");
14612 generate_exception(ctx, EXCP_RI);
14617 op1 = MASK_SPECIAL2(ctx->opcode);
14619 case OPC_MADD ... OPC_MADDU: /* Multiply and add/sub */
14620 case OPC_MSUB ... OPC_MSUBU:
14621 check_insn(env, ctx, ISA_MIPS32);
14622 gen_muldiv(ctx, op1, rs, rt);
14625 gen_arith(env, ctx, op1, rd, rs, rt);
14629 check_insn(env, ctx, ISA_MIPS32);
14630 gen_cl(ctx, op1, rd, rs);
14633 /* XXX: not clear which exception should be raised
14634 * when in debug mode...
14636 check_insn(env, ctx, ISA_MIPS32);
14637 if (!(ctx->hflags & MIPS_HFLAG_DM)) {
14638 generate_exception(ctx, EXCP_DBp);
14640 generate_exception(ctx, EXCP_DBp);
14642 /* Treat as NOP. */
14645 case OPC_DIVU_G_2F:
14646 case OPC_MULT_G_2F:
14647 case OPC_MULTU_G_2F:
14649 case OPC_MODU_G_2F:
14650 check_insn(env, ctx, INSN_LOONGSON2F);
14651 gen_loongson_integer(ctx, op1, rd, rs, rt);
14653 #if defined(TARGET_MIPS64)
14656 check_insn(env, ctx, ISA_MIPS64);
14657 check_mips_64(ctx);
14658 gen_cl(ctx, op1, rd, rs);
14660 case OPC_DMULT_G_2F:
14661 case OPC_DMULTU_G_2F:
14662 case OPC_DDIV_G_2F:
14663 case OPC_DDIVU_G_2F:
14664 case OPC_DMOD_G_2F:
14665 case OPC_DMODU_G_2F:
14666 check_insn(env, ctx, INSN_LOONGSON2F);
14667 gen_loongson_integer(ctx, op1, rd, rs, rt);
14670 default: /* Invalid */
14671 MIPS_INVAL("special2");
14672 generate_exception(ctx, EXCP_RI);
14677 op1 = MASK_SPECIAL3(ctx->opcode);
14681 check_insn(env, ctx, ISA_MIPS32R2);
14682 gen_bitops(ctx, op1, rt, rs, sa, rd);
14685 check_insn(env, ctx, ISA_MIPS32R2);
14686 op2 = MASK_BSHFL(ctx->opcode);
14687 gen_bshfl(ctx, op2, rt, rd);
14690 gen_rdhwr(env, ctx, rt, rd);
14693 check_insn(env, ctx, ASE_MT);
14695 TCGv t0 = tcg_temp_new();
14696 TCGv t1 = tcg_temp_new();
14698 gen_load_gpr(t0, rt);
14699 gen_load_gpr(t1, rs);
14700 gen_helper_fork(t0, t1);
14706 check_insn(env, ctx, ASE_MT);
14708 TCGv t0 = tcg_temp_new();
14710 save_cpu_state(ctx, 1);
14711 gen_load_gpr(t0, rs);
14712 gen_helper_yield(t0, cpu_env, t0);
14713 gen_store_gpr(t0, rd);
14717 case OPC_DIV_G_2E ... OPC_DIVU_G_2E:
14718 case OPC_MOD_G_2E ... OPC_MODU_G_2E:
14719 case OPC_MULT_G_2E ... OPC_MULTU_G_2E:
14720 /* OPC_MULT_G_2E, OPC_ADDUH_QB_DSP, OPC_MUL_PH_DSP have
14721 * the same mask and op1. */
14722 if ((env->insn_flags & ASE_DSPR2) && (op1 == OPC_MULT_G_2E)) {
14723 op2 = MASK_ADDUH_QB(ctx->opcode);
14726 case OPC_ADDUH_R_QB:
14728 case OPC_ADDQH_R_PH:
14730 case OPC_ADDQH_R_W:
14732 case OPC_SUBUH_R_QB:
14734 case OPC_SUBQH_R_PH:
14736 case OPC_SUBQH_R_W:
14737 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
14742 case OPC_MULQ_RS_W:
14743 gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 1);
14746 MIPS_INVAL("MASK ADDUH.QB");
14747 generate_exception(ctx, EXCP_RI);
14750 } else if (env->insn_flags & INSN_LOONGSON2E) {
14751 gen_loongson_integer(ctx, op1, rd, rs, rt);
14753 generate_exception(ctx, EXCP_RI);
14757 op2 = MASK_LX(ctx->opcode);
14759 #if defined(TARGET_MIPS64)
14765 gen_mipsdsp_ld(env, ctx, op2, rd, rs, rt);
14767 default: /* Invalid */
14768 MIPS_INVAL("MASK LX");
14769 generate_exception(ctx, EXCP_RI);
14773 case OPC_ABSQ_S_PH_DSP:
14774 op2 = MASK_ABSQ_S_PH(ctx->opcode);
14776 case OPC_ABSQ_S_QB:
14777 case OPC_ABSQ_S_PH:
14779 case OPC_PRECEQ_W_PHL:
14780 case OPC_PRECEQ_W_PHR:
14781 case OPC_PRECEQU_PH_QBL:
14782 case OPC_PRECEQU_PH_QBR:
14783 case OPC_PRECEQU_PH_QBLA:
14784 case OPC_PRECEQU_PH_QBRA:
14785 case OPC_PRECEU_PH_QBL:
14786 case OPC_PRECEU_PH_QBR:
14787 case OPC_PRECEU_PH_QBLA:
14788 case OPC_PRECEU_PH_QBRA:
14789 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
14796 gen_mipsdsp_bitinsn(env, ctx, op1, op2, rd, rt);
14799 MIPS_INVAL("MASK ABSQ_S.PH");
14800 generate_exception(ctx, EXCP_RI);
14804 case OPC_ADDU_QB_DSP:
14805 op2 = MASK_ADDU_QB(ctx->opcode);
14808 case OPC_ADDQ_S_PH:
14811 case OPC_ADDU_S_QB:
14813 case OPC_ADDU_S_PH:
14815 case OPC_SUBQ_S_PH:
14818 case OPC_SUBU_S_QB:
14820 case OPC_SUBU_S_PH:
14824 case OPC_RADDU_W_QB:
14825 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
14827 case OPC_MULEU_S_PH_QBL:
14828 case OPC_MULEU_S_PH_QBR:
14829 case OPC_MULQ_RS_PH:
14830 case OPC_MULEQ_S_W_PHL:
14831 case OPC_MULEQ_S_W_PHR:
14832 case OPC_MULQ_S_PH:
14833 gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 1);
14835 default: /* Invalid */
14836 MIPS_INVAL("MASK ADDU.QB");
14837 generate_exception(ctx, EXCP_RI);
14842 case OPC_CMPU_EQ_QB_DSP:
14843 op2 = MASK_CMPU_EQ_QB(ctx->opcode);
14845 case OPC_PRECR_SRA_PH_W:
14846 case OPC_PRECR_SRA_R_PH_W:
14847 gen_mipsdsp_arith(ctx, op1, op2, rt, rs, rd);
14849 case OPC_PRECR_QB_PH:
14850 case OPC_PRECRQ_QB_PH:
14851 case OPC_PRECRQ_PH_W:
14852 case OPC_PRECRQ_RS_PH_W:
14853 case OPC_PRECRQU_S_QB_PH:
14854 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
14856 case OPC_CMPU_EQ_QB:
14857 case OPC_CMPU_LT_QB:
14858 case OPC_CMPU_LE_QB:
14859 case OPC_CMP_EQ_PH:
14860 case OPC_CMP_LT_PH:
14861 case OPC_CMP_LE_PH:
14862 gen_mipsdsp_add_cmp_pick(ctx, op1, op2, rd, rs, rt, 0);
14864 case OPC_CMPGU_EQ_QB:
14865 case OPC_CMPGU_LT_QB:
14866 case OPC_CMPGU_LE_QB:
14867 case OPC_CMPGDU_EQ_QB:
14868 case OPC_CMPGDU_LT_QB:
14869 case OPC_CMPGDU_LE_QB:
14872 case OPC_PACKRL_PH:
14873 gen_mipsdsp_add_cmp_pick(ctx, op1, op2, rd, rs, rt, 1);
14875 default: /* Invalid */
14876 MIPS_INVAL("MASK CMPU.EQ.QB");
14877 generate_exception(ctx, EXCP_RI);
14881 case OPC_SHLL_QB_DSP:
14882 gen_mipsdsp_shift(ctx, op1, rd, rs, rt);
14884 case OPC_DPA_W_PH_DSP:
14885 op2 = MASK_DPA_W_PH(ctx->opcode);
14887 case OPC_DPAU_H_QBL:
14888 case OPC_DPAU_H_QBR:
14889 case OPC_DPSU_H_QBL:
14890 case OPC_DPSU_H_QBR:
14892 case OPC_DPAX_W_PH:
14893 case OPC_DPAQ_S_W_PH:
14894 case OPC_DPAQX_S_W_PH:
14895 case OPC_DPAQX_SA_W_PH:
14897 case OPC_DPSX_W_PH:
14898 case OPC_DPSQ_S_W_PH:
14899 case OPC_DPSQX_S_W_PH:
14900 case OPC_DPSQX_SA_W_PH:
14901 case OPC_MULSAQ_S_W_PH:
14902 case OPC_DPAQ_SA_L_W:
14903 case OPC_DPSQ_SA_L_W:
14904 case OPC_MAQ_S_W_PHL:
14905 case OPC_MAQ_S_W_PHR:
14906 case OPC_MAQ_SA_W_PHL:
14907 case OPC_MAQ_SA_W_PHR:
14908 case OPC_MULSA_W_PH:
14909 gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 0);
14911 default: /* Invalid */
14912 MIPS_INVAL("MASK DPAW.PH");
14913 generate_exception(ctx, EXCP_RI);
14918 op2 = MASK_INSV(ctx->opcode);
14930 t0 = tcg_temp_new();
14931 t1 = tcg_temp_new();
14933 gen_load_gpr(t0, rt);
14934 gen_load_gpr(t1, rs);
14936 gen_helper_insv(cpu_gpr[rt], cpu_env, t1, t0);
14942 default: /* Invalid */
14943 MIPS_INVAL("MASK INSV");
14944 generate_exception(ctx, EXCP_RI);
14948 case OPC_APPEND_DSP:
14950 op2 = MASK_APPEND(ctx->opcode);
14951 gen_mipsdsp_add_cmp_pick(ctx, op1, op2, rt, rs, rd, 1);
14953 case OPC_EXTR_W_DSP:
14954 op2 = MASK_EXTR_W(ctx->opcode);
14958 case OPC_EXTR_RS_W:
14960 case OPC_EXTRV_S_H:
14962 case OPC_EXTRV_R_W:
14963 case OPC_EXTRV_RS_W:
14968 gen_mipsdsp_accinsn(ctx, op1, op2, rt, rs, rd, 1);
14971 gen_mipsdsp_accinsn(ctx, op1, op2, rd, rs, rt, 1);
14977 gen_mipsdsp_accinsn(ctx, op1, op2, rd, rs, rt, 0);
14979 default: /* Invalid */
14980 MIPS_INVAL("MASK EXTR.W");
14981 generate_exception(ctx, EXCP_RI);
14985 #if defined(TARGET_MIPS64)
14986 case OPC_DEXTM ... OPC_DEXT:
14987 case OPC_DINSM ... OPC_DINS:
14988 check_insn(env, ctx, ISA_MIPS64R2);
14989 check_mips_64(ctx);
14990 gen_bitops(ctx, op1, rt, rs, sa, rd);
14993 check_insn(env, ctx, ISA_MIPS64R2);
14994 check_mips_64(ctx);
14995 op2 = MASK_DBSHFL(ctx->opcode);
14996 gen_bshfl(ctx, op2, rt, rd);
14998 case OPC_DDIV_G_2E ... OPC_DDIVU_G_2E:
14999 case OPC_DMULT_G_2E ... OPC_DMULTU_G_2E:
15000 case OPC_DMOD_G_2E ... OPC_DMODU_G_2E:
15001 check_insn(env, ctx, INSN_LOONGSON2E);
15002 gen_loongson_integer(ctx, op1, rd, rs, rt);
15004 case OPC_ABSQ_S_QH_DSP:
15005 op2 = MASK_ABSQ_S_QH(ctx->opcode);
15007 case OPC_PRECEQ_L_PWL:
15008 case OPC_PRECEQ_L_PWR:
15009 case OPC_PRECEQ_PW_QHL:
15010 case OPC_PRECEQ_PW_QHR:
15011 case OPC_PRECEQ_PW_QHLA:
15012 case OPC_PRECEQ_PW_QHRA:
15013 case OPC_PRECEQU_QH_OBL:
15014 case OPC_PRECEQU_QH_OBR:
15015 case OPC_PRECEQU_QH_OBLA:
15016 case OPC_PRECEQU_QH_OBRA:
15017 case OPC_PRECEU_QH_OBL:
15018 case OPC_PRECEU_QH_OBR:
15019 case OPC_PRECEU_QH_OBLA:
15020 case OPC_PRECEU_QH_OBRA:
15021 case OPC_ABSQ_S_OB:
15022 case OPC_ABSQ_S_PW:
15023 case OPC_ABSQ_S_QH:
15024 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
15032 gen_mipsdsp_bitinsn(env, ctx, op1, op2, rd, rt);
15034 default: /* Invalid */
15035 MIPS_INVAL("MASK ABSQ_S.QH");
15036 generate_exception(ctx, EXCP_RI);
15040 case OPC_ADDU_OB_DSP:
15041 op2 = MASK_ADDU_OB(ctx->opcode);
15043 case OPC_RADDU_L_OB:
15045 case OPC_SUBQ_S_PW:
15047 case OPC_SUBQ_S_QH:
15049 case OPC_SUBU_S_OB:
15051 case OPC_SUBU_S_QH:
15053 case OPC_SUBUH_R_OB:
15055 case OPC_ADDQ_S_PW:
15057 case OPC_ADDQ_S_QH:
15059 case OPC_ADDU_S_OB:
15061 case OPC_ADDU_S_QH:
15063 case OPC_ADDUH_R_OB:
15064 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
15066 case OPC_MULEQ_S_PW_QHL:
15067 case OPC_MULEQ_S_PW_QHR:
15068 case OPC_MULEU_S_QH_OBL:
15069 case OPC_MULEU_S_QH_OBR:
15070 case OPC_MULQ_RS_QH:
15071 gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 1);
15073 default: /* Invalid */
15074 MIPS_INVAL("MASK ADDU.OB");
15075 generate_exception(ctx, EXCP_RI);
15079 case OPC_CMPU_EQ_OB_DSP:
15080 op2 = MASK_CMPU_EQ_OB(ctx->opcode);
15082 case OPC_PRECR_SRA_QH_PW:
15083 case OPC_PRECR_SRA_R_QH_PW:
15084 /* Return value is rt. */
15085 gen_mipsdsp_arith(ctx, op1, op2, rt, rs, rd);
15087 case OPC_PRECR_OB_QH:
15088 case OPC_PRECRQ_OB_QH:
15089 case OPC_PRECRQ_PW_L:
15090 case OPC_PRECRQ_QH_PW:
15091 case OPC_PRECRQ_RS_QH_PW:
15092 case OPC_PRECRQU_S_OB_QH:
15093 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
15095 case OPC_CMPU_EQ_OB:
15096 case OPC_CMPU_LT_OB:
15097 case OPC_CMPU_LE_OB:
15098 case OPC_CMP_EQ_QH:
15099 case OPC_CMP_LT_QH:
15100 case OPC_CMP_LE_QH:
15101 case OPC_CMP_EQ_PW:
15102 case OPC_CMP_LT_PW:
15103 case OPC_CMP_LE_PW:
15104 gen_mipsdsp_add_cmp_pick(ctx, op1, op2, rd, rs, rt, 0);
15106 case OPC_CMPGDU_EQ_OB:
15107 case OPC_CMPGDU_LT_OB:
15108 case OPC_CMPGDU_LE_OB:
15109 case OPC_CMPGU_EQ_OB:
15110 case OPC_CMPGU_LT_OB:
15111 case OPC_CMPGU_LE_OB:
15112 case OPC_PACKRL_PW:
15116 gen_mipsdsp_add_cmp_pick(ctx, op1, op2, rd, rs, rt, 1);
15118 default: /* Invalid */
15119 MIPS_INVAL("MASK CMPU_EQ.OB");
15120 generate_exception(ctx, EXCP_RI);
15124 case OPC_DAPPEND_DSP:
15126 op2 = MASK_DAPPEND(ctx->opcode);
15127 gen_mipsdsp_add_cmp_pick(ctx, op1, op2, rt, rs, rd, 1);
15129 case OPC_DEXTR_W_DSP:
15130 op2 = MASK_DEXTR_W(ctx->opcode);
15137 case OPC_DEXTR_R_L:
15138 case OPC_DEXTR_RS_L:
15140 case OPC_DEXTR_R_W:
15141 case OPC_DEXTR_RS_W:
15142 case OPC_DEXTR_S_H:
15144 case OPC_DEXTRV_R_L:
15145 case OPC_DEXTRV_RS_L:
15146 case OPC_DEXTRV_S_H:
15148 case OPC_DEXTRV_R_W:
15149 case OPC_DEXTRV_RS_W:
15150 gen_mipsdsp_accinsn(ctx, op1, op2, rt, rs, rd, 1);
15155 gen_mipsdsp_accinsn(ctx, op1, op2, rd, rs, rt, 0);
15157 default: /* Invalid */
15158 MIPS_INVAL("MASK EXTR.W");
15159 generate_exception(ctx, EXCP_RI);
15163 case OPC_DPAQ_W_QH_DSP:
15164 op2 = MASK_DPAQ_W_QH(ctx->opcode);
15166 case OPC_DPAU_H_OBL:
15167 case OPC_DPAU_H_OBR:
15168 case OPC_DPSU_H_OBL:
15169 case OPC_DPSU_H_OBR:
15171 case OPC_DPAQ_S_W_QH:
15173 case OPC_DPSQ_S_W_QH:
15174 case OPC_MULSAQ_S_W_QH:
15175 case OPC_DPAQ_SA_L_PW:
15176 case OPC_DPSQ_SA_L_PW:
15177 case OPC_MULSAQ_S_L_PW:
15178 gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 0);
15180 case OPC_MAQ_S_W_QHLL:
15181 case OPC_MAQ_S_W_QHLR:
15182 case OPC_MAQ_S_W_QHRL:
15183 case OPC_MAQ_S_W_QHRR:
15184 case OPC_MAQ_SA_W_QHLL:
15185 case OPC_MAQ_SA_W_QHLR:
15186 case OPC_MAQ_SA_W_QHRL:
15187 case OPC_MAQ_SA_W_QHRR:
15188 case OPC_MAQ_S_L_PWL:
15189 case OPC_MAQ_S_L_PWR:
15194 gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 0);
15196 default: /* Invalid */
15197 MIPS_INVAL("MASK DPAQ.W.QH");
15198 generate_exception(ctx, EXCP_RI);
15202 case OPC_DINSV_DSP:
15203 op2 = MASK_INSV(ctx->opcode);
15215 t0 = tcg_temp_new();
15216 t1 = tcg_temp_new();
15218 gen_load_gpr(t0, rt);
15219 gen_load_gpr(t1, rs);
15221 gen_helper_dinsv(cpu_gpr[rt], cpu_env, t1, t0);
15224 default: /* Invalid */
15225 MIPS_INVAL("MASK DINSV");
15226 generate_exception(ctx, EXCP_RI);
15230 case OPC_SHLL_OB_DSP:
15231 gen_mipsdsp_shift(ctx, op1, rd, rs, rt);
15234 default: /* Invalid */
15235 MIPS_INVAL("special3");
15236 generate_exception(ctx, EXCP_RI);
15241 op1 = MASK_REGIMM(ctx->opcode);
15243 case OPC_BLTZ ... OPC_BGEZL: /* REGIMM branches */
15244 case OPC_BLTZAL ... OPC_BGEZALL:
15245 gen_compute_branch(ctx, op1, 4, rs, -1, imm << 2);
15248 case OPC_TGEI ... OPC_TEQI: /* REGIMM traps */
15250 gen_trap(ctx, op1, rs, -1, imm);
15253 check_insn(env, ctx, ISA_MIPS32R2);
15254 /* Treat as NOP. */
15256 case OPC_BPOSGE32: /* MIPS DSP branch */
15257 #if defined(TARGET_MIPS64)
15261 gen_compute_branch(ctx, op1, 4, -1, -2, (int32_t)imm << 2);
15264 default: /* Invalid */
15265 MIPS_INVAL("regimm");
15266 generate_exception(ctx, EXCP_RI);
15271 check_cp0_enabled(ctx);
15272 op1 = MASK_CP0(ctx->opcode);
15278 #if defined(TARGET_MIPS64)
15282 #ifndef CONFIG_USER_ONLY
15283 gen_cp0(env, ctx, op1, rt, rd);
15284 #endif /* !CONFIG_USER_ONLY */
15286 case OPC_C0_FIRST ... OPC_C0_LAST:
15287 #ifndef CONFIG_USER_ONLY
15288 gen_cp0(env, ctx, MASK_C0(ctx->opcode), rt, rd);
15289 #endif /* !CONFIG_USER_ONLY */
15292 #ifndef CONFIG_USER_ONLY
15294 TCGv t0 = tcg_temp_new();
15296 op2 = MASK_MFMC0(ctx->opcode);
15299 check_insn(env, ctx, ASE_MT);
15300 gen_helper_dmt(t0);
15301 gen_store_gpr(t0, rt);
15304 check_insn(env, ctx, ASE_MT);
15305 gen_helper_emt(t0);
15306 gen_store_gpr(t0, rt);
15309 check_insn(env, ctx, ASE_MT);
15310 gen_helper_dvpe(t0, cpu_env);
15311 gen_store_gpr(t0, rt);
15314 check_insn(env, ctx, ASE_MT);
15315 gen_helper_evpe(t0, cpu_env);
15316 gen_store_gpr(t0, rt);
15319 check_insn(env, ctx, ISA_MIPS32R2);
15320 save_cpu_state(ctx, 1);
15321 gen_helper_di(t0, cpu_env);
15322 gen_store_gpr(t0, rt);
15323 /* Stop translation as we may have switched the execution mode */
15324 ctx->bstate = BS_STOP;
15327 check_insn(env, ctx, ISA_MIPS32R2);
15328 save_cpu_state(ctx, 1);
15329 gen_helper_ei(t0, cpu_env);
15330 gen_store_gpr(t0, rt);
15331 /* Stop translation as we may have switched the execution mode */
15332 ctx->bstate = BS_STOP;
15334 default: /* Invalid */
15335 MIPS_INVAL("mfmc0");
15336 generate_exception(ctx, EXCP_RI);
15341 #endif /* !CONFIG_USER_ONLY */
15344 check_insn(env, ctx, ISA_MIPS32R2);
15345 gen_load_srsgpr(rt, rd);
15348 check_insn(env, ctx, ISA_MIPS32R2);
15349 gen_store_srsgpr(rt, rd);
15353 generate_exception(ctx, EXCP_RI);
15357 case OPC_ADDI: /* Arithmetic with immediate opcode */
15359 gen_arith_imm(env, ctx, op, rt, rs, imm);
15361 case OPC_SLTI: /* Set on less than with immediate opcode */
15363 gen_slt_imm(env, ctx, op, rt, rs, imm);
15365 case OPC_ANDI: /* Arithmetic with immediate opcode */
15369 gen_logic_imm(env, ctx, op, rt, rs, imm);
15371 case OPC_J ... OPC_JAL: /* Jump */
15372 offset = (int32_t)(ctx->opcode & 0x3FFFFFF) << 2;
15373 gen_compute_branch(ctx, op, 4, rs, rt, offset);
15376 case OPC_BEQ ... OPC_BGTZ: /* Branch */
15377 case OPC_BEQL ... OPC_BGTZL:
15378 gen_compute_branch(ctx, op, 4, rs, rt, imm << 2);
15381 case OPC_LB ... OPC_LWR: /* Load and stores */
15383 gen_ld(env, ctx, op, rt, rs, imm);
15385 case OPC_SB ... OPC_SW:
15387 gen_st(ctx, op, rt, rs, imm);
15390 gen_st_cond(ctx, op, rt, rs, imm);
15393 check_cp0_enabled(ctx);
15394 check_insn(env, ctx, ISA_MIPS3 | ISA_MIPS32);
15395 /* Treat as NOP. */
15398 check_insn(env, ctx, ISA_MIPS4 | ISA_MIPS32);
15399 /* Treat as NOP. */
15402 /* Floating point (COP1). */
15407 gen_cop1_ldst(env, ctx, op, rt, rs, imm);
15411 if (env->CP0_Config1 & (1 << CP0C1_FP)) {
15412 check_cp1_enabled(ctx);
15413 op1 = MASK_CP1(ctx->opcode);
15417 check_insn(env, ctx, ISA_MIPS32R2);
15422 gen_cp1(ctx, op1, rt, rd);
15424 #if defined(TARGET_MIPS64)
15427 check_insn(env, ctx, ISA_MIPS3);
15428 gen_cp1(ctx, op1, rt, rd);
15434 check_insn(env, ctx, ASE_MIPS3D);
15437 gen_compute_branch1(env, ctx, MASK_BC1(ctx->opcode),
15438 (rt >> 2) & 0x7, imm << 2);
15446 gen_farith(ctx, ctx->opcode & FOP(0x3f, 0x1f), rt, rd, sa,
15451 generate_exception (ctx, EXCP_RI);
15455 generate_exception_err(ctx, EXCP_CpU, 1);
15464 /* COP2: Not implemented. */
15465 generate_exception_err(ctx, EXCP_CpU, 2);
15468 check_insn(env, ctx, INSN_LOONGSON2F);
15469 /* Note that these instructions use different fields. */
15470 gen_loongson_multimedia(ctx, sa, rd, rt);
15474 if (env->CP0_Config1 & (1 << CP0C1_FP)) {
15475 check_cp1_enabled(ctx);
15476 op1 = MASK_CP3(ctx->opcode);
15484 gen_flt3_ldst(ctx, op1, sa, rd, rs, rt);
15487 /* Treat as NOP. */
15502 gen_flt3_arith(ctx, op1, sa, rs, rd, rt);
15506 generate_exception (ctx, EXCP_RI);
15510 generate_exception_err(ctx, EXCP_CpU, 1);
15514 #if defined(TARGET_MIPS64)
15515 /* MIPS64 opcodes */
15517 case OPC_LDL ... OPC_LDR:
15520 check_insn(env, ctx, ISA_MIPS3);
15521 check_mips_64(ctx);
15522 gen_ld(env, ctx, op, rt, rs, imm);
15524 case OPC_SDL ... OPC_SDR:
15526 check_insn(env, ctx, ISA_MIPS3);
15527 check_mips_64(ctx);
15528 gen_st(ctx, op, rt, rs, imm);
15531 check_insn(env, ctx, ISA_MIPS3);
15532 check_mips_64(ctx);
15533 gen_st_cond(ctx, op, rt, rs, imm);
15537 check_insn(env, ctx, ISA_MIPS3);
15538 check_mips_64(ctx);
15539 gen_arith_imm(env, ctx, op, rt, rs, imm);
15543 check_insn(env, ctx, ASE_MIPS16 | ASE_MICROMIPS);
15544 offset = (int32_t)(ctx->opcode & 0x3FFFFFF) << 2;
15545 gen_compute_branch(ctx, op, 4, rs, rt, offset);
15549 check_insn(env, ctx, ASE_MDMX);
15550 /* MDMX: Not implemented. */
15551 default: /* Invalid */
15552 MIPS_INVAL("major opcode");
15553 generate_exception(ctx, EXCP_RI);
15559 gen_intermediate_code_internal (CPUMIPSState *env, TranslationBlock *tb,
15563 target_ulong pc_start;
15564 uint16_t *gen_opc_end;
15573 qemu_log("search pc %d\n", search_pc);
15576 gen_opc_end = gen_opc_buf + OPC_MAX_SIZE;
15579 ctx.singlestep_enabled = env->singlestep_enabled;
15581 ctx.bstate = BS_NONE;
15582 /* Restore delay slot state from the tb context. */
15583 ctx.hflags = (uint32_t)tb->flags; /* FIXME: maybe use 64 bits here? */
15584 restore_cpu_state(env, &ctx);
15585 #ifdef CONFIG_USER_ONLY
15586 ctx.mem_idx = MIPS_HFLAG_UM;
15588 ctx.mem_idx = ctx.hflags & MIPS_HFLAG_KSU;
15591 max_insns = tb->cflags & CF_COUNT_MASK;
15592 if (max_insns == 0)
15593 max_insns = CF_COUNT_MASK;
15594 LOG_DISAS("\ntb %p idx %d hflags %04x\n", tb, ctx.mem_idx, ctx.hflags);
15595 gen_icount_start();
15596 while (ctx.bstate == BS_NONE) {
15597 if (unlikely(!QTAILQ_EMPTY(&env->breakpoints))) {
15598 QTAILQ_FOREACH(bp, &env->breakpoints, entry) {
15599 if (bp->pc == ctx.pc) {
15600 save_cpu_state(&ctx, 1);
15601 ctx.bstate = BS_BRANCH;
15602 gen_helper_0e0i(raise_exception, EXCP_DEBUG);
15603 /* Include the breakpoint location or the tb won't
15604 * be flushed when it must be. */
15606 goto done_generating;
15612 j = gen_opc_ptr - gen_opc_buf;
15616 gen_opc_instr_start[lj++] = 0;
15618 gen_opc_pc[lj] = ctx.pc;
15619 gen_opc_hflags[lj] = ctx.hflags & MIPS_HFLAG_BMASK;
15620 gen_opc_instr_start[lj] = 1;
15621 gen_opc_icount[lj] = num_insns;
15623 if (num_insns + 1 == max_insns && (tb->cflags & CF_LAST_IO))
15627 if (!(ctx.hflags & MIPS_HFLAG_M16)) {
15628 ctx.opcode = cpu_ldl_code(env, ctx.pc);
15630 decode_opc(env, &ctx, &is_branch);
15631 } else if (env->insn_flags & ASE_MICROMIPS) {
15632 ctx.opcode = cpu_lduw_code(env, ctx.pc);
15633 insn_bytes = decode_micromips_opc(env, &ctx, &is_branch);
15634 } else if (env->insn_flags & ASE_MIPS16) {
15635 ctx.opcode = cpu_lduw_code(env, ctx.pc);
15636 insn_bytes = decode_mips16_opc(env, &ctx, &is_branch);
15638 generate_exception(&ctx, EXCP_RI);
15639 ctx.bstate = BS_STOP;
15643 handle_delay_slot(env, &ctx, insn_bytes);
15645 ctx.pc += insn_bytes;
15649 /* Execute a branch and its delay slot as a single instruction.
15650 This is what GDB expects and is consistent with what the
15651 hardware does (e.g. if a delay slot instruction faults, the
15652 reported PC is the PC of the branch). */
15653 if (env->singlestep_enabled && (ctx.hflags & MIPS_HFLAG_BMASK) == 0)
15656 if ((ctx.pc & (TARGET_PAGE_SIZE - 1)) == 0)
15659 if (gen_opc_ptr >= gen_opc_end)
15662 if (num_insns >= max_insns)
15668 if (tb->cflags & CF_LAST_IO)
15670 if (env->singlestep_enabled && ctx.bstate != BS_BRANCH) {
15671 save_cpu_state(&ctx, ctx.bstate == BS_NONE);
15672 gen_helper_0e0i(raise_exception, EXCP_DEBUG);
15674 switch (ctx.bstate) {
15676 gen_goto_tb(&ctx, 0, ctx.pc);
15679 save_cpu_state(&ctx, 0);
15680 gen_goto_tb(&ctx, 0, ctx.pc);
15683 tcg_gen_exit_tb(0);
15691 gen_icount_end(tb, num_insns);
15692 *gen_opc_ptr = INDEX_op_end;
15694 j = gen_opc_ptr - gen_opc_buf;
15697 gen_opc_instr_start[lj++] = 0;
15699 tb->size = ctx.pc - pc_start;
15700 tb->icount = num_insns;
15704 if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM)) {
15705 qemu_log("IN: %s\n", lookup_symbol(pc_start));
15706 log_target_disas(pc_start, ctx.pc - pc_start, 0);
15712 void gen_intermediate_code (CPUMIPSState *env, struct TranslationBlock *tb)
15714 gen_intermediate_code_internal(env, tb, 0);
15717 void gen_intermediate_code_pc (CPUMIPSState *env, struct TranslationBlock *tb)
15719 gen_intermediate_code_internal(env, tb, 1);
15722 static void fpu_dump_state(CPUMIPSState *env, FILE *f, fprintf_function fpu_fprintf,
15726 int is_fpu64 = !!(env->hflags & MIPS_HFLAG_F64);
15728 #define printfpr(fp) \
15731 fpu_fprintf(f, "w:%08x d:%016" PRIx64 \
15732 " fd:%13g fs:%13g psu: %13g\n", \
15733 (fp)->w[FP_ENDIAN_IDX], (fp)->d, \
15734 (double)(fp)->fd, \
15735 (double)(fp)->fs[FP_ENDIAN_IDX], \
15736 (double)(fp)->fs[!FP_ENDIAN_IDX]); \
15739 tmp.w[FP_ENDIAN_IDX] = (fp)->w[FP_ENDIAN_IDX]; \
15740 tmp.w[!FP_ENDIAN_IDX] = ((fp) + 1)->w[FP_ENDIAN_IDX]; \
15741 fpu_fprintf(f, "w:%08x d:%016" PRIx64 \
15742 " fd:%13g fs:%13g psu:%13g\n", \
15743 tmp.w[FP_ENDIAN_IDX], tmp.d, \
15745 (double)tmp.fs[FP_ENDIAN_IDX], \
15746 (double)tmp.fs[!FP_ENDIAN_IDX]); \
15751 fpu_fprintf(f, "CP1 FCR0 0x%08x FCR31 0x%08x SR.FR %d fp_status 0x%02x\n",
15752 env->active_fpu.fcr0, env->active_fpu.fcr31, is_fpu64,
15753 get_float_exception_flags(&env->active_fpu.fp_status));
15754 for (i = 0; i < 32; (is_fpu64) ? i++ : (i += 2)) {
15755 fpu_fprintf(f, "%3s: ", fregnames[i]);
15756 printfpr(&env->active_fpu.fpr[i]);
15762 #if defined(TARGET_MIPS64) && defined(MIPS_DEBUG_SIGN_EXTENSIONS)
15763 /* Debug help: The architecture requires 32bit code to maintain proper
15764 sign-extended values on 64bit machines. */
15766 #define SIGN_EXT_P(val) ((((val) & ~0x7fffffff) == 0) || (((val) & ~0x7fffffff) == ~0x7fffffff))
15769 cpu_mips_check_sign_extensions (CPUMIPSState *env, FILE *f,
15770 fprintf_function cpu_fprintf,
15775 if (!SIGN_EXT_P(env->active_tc.PC))
15776 cpu_fprintf(f, "BROKEN: pc=0x" TARGET_FMT_lx "\n", env->active_tc.PC);
15777 if (!SIGN_EXT_P(env->active_tc.HI[0]))
15778 cpu_fprintf(f, "BROKEN: HI=0x" TARGET_FMT_lx "\n", env->active_tc.HI[0]);
15779 if (!SIGN_EXT_P(env->active_tc.LO[0]))
15780 cpu_fprintf(f, "BROKEN: LO=0x" TARGET_FMT_lx "\n", env->active_tc.LO[0]);
15781 if (!SIGN_EXT_P(env->btarget))
15782 cpu_fprintf(f, "BROKEN: btarget=0x" TARGET_FMT_lx "\n", env->btarget);
15784 for (i = 0; i < 32; i++) {
15785 if (!SIGN_EXT_P(env->active_tc.gpr[i]))
15786 cpu_fprintf(f, "BROKEN: %s=0x" TARGET_FMT_lx "\n", regnames[i], env->active_tc.gpr[i]);
15789 if (!SIGN_EXT_P(env->CP0_EPC))
15790 cpu_fprintf(f, "BROKEN: EPC=0x" TARGET_FMT_lx "\n", env->CP0_EPC);
15791 if (!SIGN_EXT_P(env->lladdr))
15792 cpu_fprintf(f, "BROKEN: LLAddr=0x" TARGET_FMT_lx "\n", env->lladdr);
15796 void cpu_dump_state (CPUMIPSState *env, FILE *f, fprintf_function cpu_fprintf,
15801 cpu_fprintf(f, "pc=0x" TARGET_FMT_lx " HI=0x" TARGET_FMT_lx
15802 " LO=0x" TARGET_FMT_lx " ds %04x "
15803 TARGET_FMT_lx " " TARGET_FMT_ld "\n",
15804 env->active_tc.PC, env->active_tc.HI[0], env->active_tc.LO[0],
15805 env->hflags, env->btarget, env->bcond);
15806 for (i = 0; i < 32; i++) {
15808 cpu_fprintf(f, "GPR%02d:", i);
15809 cpu_fprintf(f, " %s " TARGET_FMT_lx, regnames[i], env->active_tc.gpr[i]);
15811 cpu_fprintf(f, "\n");
15814 cpu_fprintf(f, "CP0 Status 0x%08x Cause 0x%08x EPC 0x" TARGET_FMT_lx "\n",
15815 env->CP0_Status, env->CP0_Cause, env->CP0_EPC);
15816 cpu_fprintf(f, " Config0 0x%08x Config1 0x%08x LLAddr 0x" TARGET_FMT_lx "\n",
15817 env->CP0_Config0, env->CP0_Config1, env->lladdr);
15818 if (env->hflags & MIPS_HFLAG_FPU)
15819 fpu_dump_state(env, f, cpu_fprintf, flags);
15820 #if defined(TARGET_MIPS64) && defined(MIPS_DEBUG_SIGN_EXTENSIONS)
15821 cpu_mips_check_sign_extensions(env, f, cpu_fprintf, flags);
15825 static void mips_tcg_init(void)
15830 /* Initialize various static tables. */
15834 cpu_env = tcg_global_reg_new_ptr(TCG_AREG0, "env");
15835 TCGV_UNUSED(cpu_gpr[0]);
15836 for (i = 1; i < 32; i++)
15837 cpu_gpr[i] = tcg_global_mem_new(TCG_AREG0,
15838 offsetof(CPUMIPSState, active_tc.gpr[i]),
15841 for (i = 0; i < 32; i++) {
15842 int off = offsetof(CPUMIPSState, active_fpu.fpr[i]);
15843 fpu_f64[i] = tcg_global_mem_new_i64(TCG_AREG0, off, fregnames[i]);
15846 cpu_PC = tcg_global_mem_new(TCG_AREG0,
15847 offsetof(CPUMIPSState, active_tc.PC), "PC");
15848 for (i = 0; i < MIPS_DSP_ACC; i++) {
15849 cpu_HI[i] = tcg_global_mem_new(TCG_AREG0,
15850 offsetof(CPUMIPSState, active_tc.HI[i]),
15852 cpu_LO[i] = tcg_global_mem_new(TCG_AREG0,
15853 offsetof(CPUMIPSState, active_tc.LO[i]),
15855 cpu_ACX[i] = tcg_global_mem_new(TCG_AREG0,
15856 offsetof(CPUMIPSState, active_tc.ACX[i]),
15859 cpu_dspctrl = tcg_global_mem_new(TCG_AREG0,
15860 offsetof(CPUMIPSState, active_tc.DSPControl),
15862 bcond = tcg_global_mem_new(TCG_AREG0,
15863 offsetof(CPUMIPSState, bcond), "bcond");
15864 btarget = tcg_global_mem_new(TCG_AREG0,
15865 offsetof(CPUMIPSState, btarget), "btarget");
15866 hflags = tcg_global_mem_new_i32(TCG_AREG0,
15867 offsetof(CPUMIPSState, hflags), "hflags");
15869 fpu_fcr0 = tcg_global_mem_new_i32(TCG_AREG0,
15870 offsetof(CPUMIPSState, active_fpu.fcr0),
15872 fpu_fcr31 = tcg_global_mem_new_i32(TCG_AREG0,
15873 offsetof(CPUMIPSState, active_fpu.fcr31),
15876 /* register helpers */
15877 #define GEN_HELPER 2
15878 #include "helper.h"
15883 #include "translate_init.c"
15885 MIPSCPU *cpu_mips_init(const char *cpu_model)
15889 const mips_def_t *def;
15891 def = cpu_mips_find_by_name(cpu_model);
15894 cpu = MIPS_CPU(object_new(TYPE_MIPS_CPU));
15896 env->cpu_model = def;
15897 env->cpu_model_str = cpu_model;
15899 #ifndef CONFIG_USER_ONLY
15900 mmu_init(env, def);
15902 fpu_init(env, def);
15903 mvp_init(env, def);
15905 cpu_reset(CPU(cpu));
15906 qemu_init_vcpu(env);
15910 void cpu_state_reset(CPUMIPSState *env)
15912 if (qemu_loglevel_mask(CPU_LOG_RESET)) {
15913 qemu_log("CPU Reset (CPU %d)\n", env->cpu_index);
15914 log_cpu_state(env, 0);
15917 memset(env, 0, offsetof(CPUMIPSState, breakpoints));
15920 /* Reset registers to their default values */
15921 env->CP0_PRid = env->cpu_model->CP0_PRid;
15922 env->CP0_Config0 = env->cpu_model->CP0_Config0;
15923 #ifdef TARGET_WORDS_BIGENDIAN
15924 env->CP0_Config0 |= (1 << CP0C0_BE);
15926 env->CP0_Config1 = env->cpu_model->CP0_Config1;
15927 env->CP0_Config2 = env->cpu_model->CP0_Config2;
15928 env->CP0_Config3 = env->cpu_model->CP0_Config3;
15929 env->CP0_Config6 = env->cpu_model->CP0_Config6;
15930 env->CP0_Config7 = env->cpu_model->CP0_Config7;
15931 env->CP0_LLAddr_rw_bitmask = env->cpu_model->CP0_LLAddr_rw_bitmask
15932 << env->cpu_model->CP0_LLAddr_shift;
15933 env->CP0_LLAddr_shift = env->cpu_model->CP0_LLAddr_shift;
15934 env->SYNCI_Step = env->cpu_model->SYNCI_Step;
15935 env->CCRes = env->cpu_model->CCRes;
15936 env->CP0_Status_rw_bitmask = env->cpu_model->CP0_Status_rw_bitmask;
15937 env->CP0_TCStatus_rw_bitmask = env->cpu_model->CP0_TCStatus_rw_bitmask;
15938 env->CP0_SRSCtl = env->cpu_model->CP0_SRSCtl;
15939 env->current_tc = 0;
15940 env->SEGBITS = env->cpu_model->SEGBITS;
15941 env->SEGMask = (target_ulong)((1ULL << env->cpu_model->SEGBITS) - 1);
15942 #if defined(TARGET_MIPS64)
15943 if (env->cpu_model->insn_flags & ISA_MIPS3) {
15944 env->SEGMask |= 3ULL << 62;
15947 env->PABITS = env->cpu_model->PABITS;
15948 env->PAMask = (target_ulong)((1ULL << env->cpu_model->PABITS) - 1);
15949 env->CP0_SRSConf0_rw_bitmask = env->cpu_model->CP0_SRSConf0_rw_bitmask;
15950 env->CP0_SRSConf0 = env->cpu_model->CP0_SRSConf0;
15951 env->CP0_SRSConf1_rw_bitmask = env->cpu_model->CP0_SRSConf1_rw_bitmask;
15952 env->CP0_SRSConf1 = env->cpu_model->CP0_SRSConf1;
15953 env->CP0_SRSConf2_rw_bitmask = env->cpu_model->CP0_SRSConf2_rw_bitmask;
15954 env->CP0_SRSConf2 = env->cpu_model->CP0_SRSConf2;
15955 env->CP0_SRSConf3_rw_bitmask = env->cpu_model->CP0_SRSConf3_rw_bitmask;
15956 env->CP0_SRSConf3 = env->cpu_model->CP0_SRSConf3;
15957 env->CP0_SRSConf4_rw_bitmask = env->cpu_model->CP0_SRSConf4_rw_bitmask;
15958 env->CP0_SRSConf4 = env->cpu_model->CP0_SRSConf4;
15959 env->active_fpu.fcr0 = env->cpu_model->CP1_fcr0;
15960 env->insn_flags = env->cpu_model->insn_flags;
15962 #if defined(CONFIG_USER_ONLY)
15963 env->CP0_Status = (MIPS_HFLAG_UM << CP0St_KSU);
15964 /* Enable access to the CPUNum, SYNCI_Step, CC, and CCRes RDHWR
15965 hardware registers. */
15966 env->CP0_HWREna |= 0x0000000F;
15967 if (env->CP0_Config1 & (1 << CP0C1_FP)) {
15968 env->CP0_Status |= (1 << CP0St_CU1);
15970 if (env->cpu_model->insn_flags & ASE_DSPR2) {
15971 env->hflags |= MIPS_HFLAG_DSP | MIPS_HFLAG_DSPR2;
15972 } else if (env->cpu_model->insn_flags & ASE_DSP) {
15973 env->hflags |= MIPS_HFLAG_DSP;
15976 if (env->hflags & MIPS_HFLAG_BMASK) {
15977 /* If the exception was raised from a delay slot,
15978 come back to the jump. */
15979 env->CP0_ErrorEPC = env->active_tc.PC - 4;
15981 env->CP0_ErrorEPC = env->active_tc.PC;
15983 env->active_tc.PC = (int32_t)0xBFC00000;
15984 env->CP0_Random = env->tlb->nb_tlb - 1;
15985 env->tlb->tlb_in_use = env->tlb->nb_tlb;
15986 env->CP0_Wired = 0;
15987 env->CP0_EBase = 0x80000000 | (env->cpu_index & 0x3FF);
15988 env->CP0_Status = (1 << CP0St_BEV) | (1 << CP0St_ERL);
15989 /* vectored interrupts not implemented, timer on int 7,
15990 no performance counters. */
15991 env->CP0_IntCtl = 0xe0000000;
15995 for (i = 0; i < 7; i++) {
15996 env->CP0_WatchLo[i] = 0;
15997 env->CP0_WatchHi[i] = 0x80000000;
15999 env->CP0_WatchLo[7] = 0;
16000 env->CP0_WatchHi[7] = 0;
16002 /* Count register increments in debug mode, EJTAG version 1 */
16003 env->CP0_Debug = (1 << CP0DB_CNT) | (0x1 << CP0DB_VER);
16005 if (env->CP0_Config3 & (1 << CP0C3_MT)) {
16008 /* Only TC0 on VPE 0 starts as active. */
16009 for (i = 0; i < ARRAY_SIZE(env->tcs); i++) {
16010 env->tcs[i].CP0_TCBind = env->cpu_index << CP0TCBd_CurVPE;
16011 env->tcs[i].CP0_TCHalt = 1;
16013 env->active_tc.CP0_TCHalt = 1;
16016 if (!env->cpu_index) {
16017 /* VPE0 starts up enabled. */
16018 env->mvp->CP0_MVPControl |= (1 << CP0MVPCo_EVP);
16019 env->CP0_VPEConf0 |= (1 << CP0VPEC0_MVP) | (1 << CP0VPEC0_VPA);
16021 /* TC0 starts up unhalted. */
16023 env->active_tc.CP0_TCHalt = 0;
16024 env->tcs[0].CP0_TCHalt = 0;
16025 /* With thread 0 active. */
16026 env->active_tc.CP0_TCStatus = (1 << CP0TCSt_A);
16027 env->tcs[0].CP0_TCStatus = (1 << CP0TCSt_A);
16031 compute_hflags(env);
16032 env->exception_index = EXCP_NONE;
16035 void restore_state_to_opc(CPUMIPSState *env, TranslationBlock *tb, int pc_pos)
16037 env->active_tc.PC = gen_opc_pc[pc_pos];
16038 env->hflags &= ~MIPS_HFLAG_BMASK;
16039 env->hflags |= gen_opc_hflags[pc_pos];