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 OPC_ADDU_OB_DSP = 0x14 | OPC_SPECIAL3,
322 OPC_ABSQ_S_PH_DSP = 0x12 | OPC_SPECIAL3,
323 OPC_ABSQ_S_QH_DSP = 0x16 | OPC_SPECIAL3,
324 /* OPC_ADDUH_QB_DSP is same as OPC_MULT_G_2E. */
325 /* OPC_ADDUH_QB_DSP = 0x18 | OPC_SPECIAL3, */
326 OPC_CMPU_EQ_QB_DSP = 0x11 | OPC_SPECIAL3,
327 OPC_CMPU_EQ_OB_DSP = 0x15 | OPC_SPECIAL3,
328 /* MIPS DSP GPR-Based Shift Sub-class */
329 OPC_SHLL_QB_DSP = 0x13 | OPC_SPECIAL3,
330 OPC_SHLL_OB_DSP = 0x17 | OPC_SPECIAL3,
331 /* MIPS DSP Multiply Sub-class insns */
332 /* OPC_MUL_PH_DSP is same as OPC_ADDUH_QB_DSP. */
333 /* OPC_MUL_PH_DSP = 0x18 | OPC_SPECIAL3, */
334 OPC_DPA_W_PH_DSP = 0x30 | OPC_SPECIAL3,
335 OPC_DPAQ_W_QH_DSP = 0x34 | OPC_SPECIAL3,
336 /* DSP Bit/Manipulation Sub-class */
337 OPC_INSV_DSP = 0x0C | OPC_SPECIAL3,
338 OPC_DINSV_DSP = 0x0D | OPC_SPECIAL3,
339 /* MIPS DSP Compare-Pick Sub-class */
340 OPC_APPEND_DSP = 0x31 | OPC_SPECIAL3,
341 OPC_DAPPEND_DSP = 0x35 | OPC_SPECIAL3,
342 /* MIPS DSP Accumulator and DSPControl Access Sub-class */
343 OPC_EXTR_W_DSP = 0x38 | OPC_SPECIAL3,
344 OPC_DEXTR_W_DSP = 0x3C | OPC_SPECIAL3,
348 #define MASK_BSHFL(op) MASK_SPECIAL3(op) | (op & (0x1F << 6))
351 OPC_WSBH = (0x02 << 6) | OPC_BSHFL,
352 OPC_SEB = (0x10 << 6) | OPC_BSHFL,
353 OPC_SEH = (0x18 << 6) | OPC_BSHFL,
357 #define MASK_DBSHFL(op) MASK_SPECIAL3(op) | (op & (0x1F << 6))
360 OPC_DSBH = (0x02 << 6) | OPC_DBSHFL,
361 OPC_DSHD = (0x05 << 6) | OPC_DBSHFL,
364 /* MIPS DSP REGIMM opcodes */
366 OPC_BPOSGE32 = (0x1C << 16) | OPC_REGIMM,
367 OPC_BPOSGE64 = (0x1D << 16) | OPC_REGIMM,
370 #define MASK_LX(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
373 OPC_LBUX = (0x06 << 6) | OPC_LX_DSP,
374 OPC_LHX = (0x04 << 6) | OPC_LX_DSP,
375 OPC_LWX = (0x00 << 6) | OPC_LX_DSP,
376 OPC_LDX = (0x08 << 6) | OPC_LX_DSP,
379 #define MASK_ADDU_QB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
381 /* MIPS DSP Arithmetic Sub-class */
382 OPC_ADDQ_PH = (0x0A << 6) | OPC_ADDU_QB_DSP,
383 OPC_ADDQ_S_PH = (0x0E << 6) | OPC_ADDU_QB_DSP,
384 OPC_ADDQ_S_W = (0x16 << 6) | OPC_ADDU_QB_DSP,
385 OPC_ADDU_QB = (0x00 << 6) | OPC_ADDU_QB_DSP,
386 OPC_ADDU_S_QB = (0x04 << 6) | OPC_ADDU_QB_DSP,
387 OPC_ADDU_PH = (0x08 << 6) | OPC_ADDU_QB_DSP,
388 OPC_ADDU_S_PH = (0x0C << 6) | OPC_ADDU_QB_DSP,
389 OPC_SUBQ_PH = (0x0B << 6) | OPC_ADDU_QB_DSP,
390 OPC_SUBQ_S_PH = (0x0F << 6) | OPC_ADDU_QB_DSP,
391 OPC_SUBQ_S_W = (0x17 << 6) | OPC_ADDU_QB_DSP,
392 OPC_SUBU_QB = (0x01 << 6) | OPC_ADDU_QB_DSP,
393 OPC_SUBU_S_QB = (0x05 << 6) | OPC_ADDU_QB_DSP,
394 OPC_SUBU_PH = (0x09 << 6) | OPC_ADDU_QB_DSP,
395 OPC_SUBU_S_PH = (0x0D << 6) | OPC_ADDU_QB_DSP,
396 OPC_ADDSC = (0x10 << 6) | OPC_ADDU_QB_DSP,
397 OPC_ADDWC = (0x11 << 6) | OPC_ADDU_QB_DSP,
398 OPC_MODSUB = (0x12 << 6) | OPC_ADDU_QB_DSP,
399 OPC_RADDU_W_QB = (0x14 << 6) | OPC_ADDU_QB_DSP,
400 /* MIPS DSP Multiply Sub-class insns */
401 OPC_MULEU_S_PH_QBL = (0x06 << 6) | OPC_ADDU_QB_DSP,
402 OPC_MULEU_S_PH_QBR = (0x07 << 6) | OPC_ADDU_QB_DSP,
403 OPC_MULQ_RS_PH = (0x1F << 6) | OPC_ADDU_QB_DSP,
404 OPC_MULEQ_S_W_PHL = (0x1C << 6) | OPC_ADDU_QB_DSP,
405 OPC_MULEQ_S_W_PHR = (0x1D << 6) | OPC_ADDU_QB_DSP,
406 OPC_MULQ_S_PH = (0x1E << 6) | OPC_ADDU_QB_DSP,
409 #define OPC_ADDUH_QB_DSP OPC_MULT_G_2E
410 #define MASK_ADDUH_QB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
412 /* MIPS DSP Arithmetic Sub-class */
413 OPC_ADDUH_QB = (0x00 << 6) | OPC_ADDUH_QB_DSP,
414 OPC_ADDUH_R_QB = (0x02 << 6) | OPC_ADDUH_QB_DSP,
415 OPC_ADDQH_PH = (0x08 << 6) | OPC_ADDUH_QB_DSP,
416 OPC_ADDQH_R_PH = (0x0A << 6) | OPC_ADDUH_QB_DSP,
417 OPC_ADDQH_W = (0x10 << 6) | OPC_ADDUH_QB_DSP,
418 OPC_ADDQH_R_W = (0x12 << 6) | OPC_ADDUH_QB_DSP,
419 OPC_SUBUH_QB = (0x01 << 6) | OPC_ADDUH_QB_DSP,
420 OPC_SUBUH_R_QB = (0x03 << 6) | OPC_ADDUH_QB_DSP,
421 OPC_SUBQH_PH = (0x09 << 6) | OPC_ADDUH_QB_DSP,
422 OPC_SUBQH_R_PH = (0x0B << 6) | OPC_ADDUH_QB_DSP,
423 OPC_SUBQH_W = (0x11 << 6) | OPC_ADDUH_QB_DSP,
424 OPC_SUBQH_R_W = (0x13 << 6) | OPC_ADDUH_QB_DSP,
425 /* MIPS DSP Multiply Sub-class insns */
426 OPC_MUL_PH = (0x0C << 6) | OPC_ADDUH_QB_DSP,
427 OPC_MUL_S_PH = (0x0E << 6) | OPC_ADDUH_QB_DSP,
428 OPC_MULQ_S_W = (0x16 << 6) | OPC_ADDUH_QB_DSP,
429 OPC_MULQ_RS_W = (0x17 << 6) | OPC_ADDUH_QB_DSP,
432 #define MASK_ABSQ_S_PH(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
434 /* MIPS DSP Arithmetic Sub-class */
435 OPC_ABSQ_S_QB = (0x01 << 6) | OPC_ABSQ_S_PH_DSP,
436 OPC_ABSQ_S_PH = (0x09 << 6) | OPC_ABSQ_S_PH_DSP,
437 OPC_ABSQ_S_W = (0x11 << 6) | OPC_ABSQ_S_PH_DSP,
438 OPC_PRECEQ_W_PHL = (0x0C << 6) | OPC_ABSQ_S_PH_DSP,
439 OPC_PRECEQ_W_PHR = (0x0D << 6) | OPC_ABSQ_S_PH_DSP,
440 OPC_PRECEQU_PH_QBL = (0x04 << 6) | OPC_ABSQ_S_PH_DSP,
441 OPC_PRECEQU_PH_QBR = (0x05 << 6) | OPC_ABSQ_S_PH_DSP,
442 OPC_PRECEQU_PH_QBLA = (0x06 << 6) | OPC_ABSQ_S_PH_DSP,
443 OPC_PRECEQU_PH_QBRA = (0x07 << 6) | OPC_ABSQ_S_PH_DSP,
444 OPC_PRECEU_PH_QBL = (0x1C << 6) | OPC_ABSQ_S_PH_DSP,
445 OPC_PRECEU_PH_QBR = (0x1D << 6) | OPC_ABSQ_S_PH_DSP,
446 OPC_PRECEU_PH_QBLA = (0x1E << 6) | OPC_ABSQ_S_PH_DSP,
447 OPC_PRECEU_PH_QBRA = (0x1F << 6) | OPC_ABSQ_S_PH_DSP,
448 /* DSP Bit/Manipulation Sub-class */
449 OPC_BITREV = (0x1B << 6) | OPC_ABSQ_S_PH_DSP,
450 OPC_REPL_QB = (0x02 << 6) | OPC_ABSQ_S_PH_DSP,
451 OPC_REPLV_QB = (0x03 << 6) | OPC_ABSQ_S_PH_DSP,
452 OPC_REPL_PH = (0x0A << 6) | OPC_ABSQ_S_PH_DSP,
453 OPC_REPLV_PH = (0x0B << 6) | OPC_ABSQ_S_PH_DSP,
456 #define MASK_CMPU_EQ_QB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
458 /* MIPS DSP Arithmetic Sub-class */
459 OPC_PRECR_QB_PH = (0x0D << 6) | OPC_CMPU_EQ_QB_DSP,
460 OPC_PRECRQ_QB_PH = (0x0C << 6) | OPC_CMPU_EQ_QB_DSP,
461 OPC_PRECR_SRA_PH_W = (0x1E << 6) | OPC_CMPU_EQ_QB_DSP,
462 OPC_PRECR_SRA_R_PH_W = (0x1F << 6) | OPC_CMPU_EQ_QB_DSP,
463 OPC_PRECRQ_PH_W = (0x14 << 6) | OPC_CMPU_EQ_QB_DSP,
464 OPC_PRECRQ_RS_PH_W = (0x15 << 6) | OPC_CMPU_EQ_QB_DSP,
465 OPC_PRECRQU_S_QB_PH = (0x0F << 6) | OPC_CMPU_EQ_QB_DSP,
466 /* DSP Compare-Pick Sub-class */
467 OPC_CMPU_EQ_QB = (0x00 << 6) | OPC_CMPU_EQ_QB_DSP,
468 OPC_CMPU_LT_QB = (0x01 << 6) | OPC_CMPU_EQ_QB_DSP,
469 OPC_CMPU_LE_QB = (0x02 << 6) | OPC_CMPU_EQ_QB_DSP,
470 OPC_CMPGU_EQ_QB = (0x04 << 6) | OPC_CMPU_EQ_QB_DSP,
471 OPC_CMPGU_LT_QB = (0x05 << 6) | OPC_CMPU_EQ_QB_DSP,
472 OPC_CMPGU_LE_QB = (0x06 << 6) | OPC_CMPU_EQ_QB_DSP,
473 OPC_CMPGDU_EQ_QB = (0x18 << 6) | OPC_CMPU_EQ_QB_DSP,
474 OPC_CMPGDU_LT_QB = (0x19 << 6) | OPC_CMPU_EQ_QB_DSP,
475 OPC_CMPGDU_LE_QB = (0x1A << 6) | OPC_CMPU_EQ_QB_DSP,
476 OPC_CMP_EQ_PH = (0x08 << 6) | OPC_CMPU_EQ_QB_DSP,
477 OPC_CMP_LT_PH = (0x09 << 6) | OPC_CMPU_EQ_QB_DSP,
478 OPC_CMP_LE_PH = (0x0A << 6) | OPC_CMPU_EQ_QB_DSP,
479 OPC_PICK_QB = (0x03 << 6) | OPC_CMPU_EQ_QB_DSP,
480 OPC_PICK_PH = (0x0B << 6) | OPC_CMPU_EQ_QB_DSP,
481 OPC_PACKRL_PH = (0x0E << 6) | OPC_CMPU_EQ_QB_DSP,
484 #define MASK_SHLL_QB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
486 /* MIPS DSP GPR-Based Shift Sub-class */
487 OPC_SHLL_QB = (0x00 << 6) | OPC_SHLL_QB_DSP,
488 OPC_SHLLV_QB = (0x02 << 6) | OPC_SHLL_QB_DSP,
489 OPC_SHLL_PH = (0x08 << 6) | OPC_SHLL_QB_DSP,
490 OPC_SHLLV_PH = (0x0A << 6) | OPC_SHLL_QB_DSP,
491 OPC_SHLL_S_PH = (0x0C << 6) | OPC_SHLL_QB_DSP,
492 OPC_SHLLV_S_PH = (0x0E << 6) | OPC_SHLL_QB_DSP,
493 OPC_SHLL_S_W = (0x14 << 6) | OPC_SHLL_QB_DSP,
494 OPC_SHLLV_S_W = (0x16 << 6) | OPC_SHLL_QB_DSP,
495 OPC_SHRL_QB = (0x01 << 6) | OPC_SHLL_QB_DSP,
496 OPC_SHRLV_QB = (0x03 << 6) | OPC_SHLL_QB_DSP,
497 OPC_SHRL_PH = (0x19 << 6) | OPC_SHLL_QB_DSP,
498 OPC_SHRLV_PH = (0x1B << 6) | OPC_SHLL_QB_DSP,
499 OPC_SHRA_QB = (0x04 << 6) | OPC_SHLL_QB_DSP,
500 OPC_SHRA_R_QB = (0x05 << 6) | OPC_SHLL_QB_DSP,
501 OPC_SHRAV_QB = (0x06 << 6) | OPC_SHLL_QB_DSP,
502 OPC_SHRAV_R_QB = (0x07 << 6) | OPC_SHLL_QB_DSP,
503 OPC_SHRA_PH = (0x09 << 6) | OPC_SHLL_QB_DSP,
504 OPC_SHRAV_PH = (0x0B << 6) | OPC_SHLL_QB_DSP,
505 OPC_SHRA_R_PH = (0x0D << 6) | OPC_SHLL_QB_DSP,
506 OPC_SHRAV_R_PH = (0x0F << 6) | OPC_SHLL_QB_DSP,
507 OPC_SHRA_R_W = (0x15 << 6) | OPC_SHLL_QB_DSP,
508 OPC_SHRAV_R_W = (0x17 << 6) | OPC_SHLL_QB_DSP,
511 #define MASK_DPA_W_PH(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
513 /* MIPS DSP Multiply Sub-class insns */
514 OPC_DPAU_H_QBL = (0x03 << 6) | OPC_DPA_W_PH_DSP,
515 OPC_DPAU_H_QBR = (0x07 << 6) | OPC_DPA_W_PH_DSP,
516 OPC_DPSU_H_QBL = (0x0B << 6) | OPC_DPA_W_PH_DSP,
517 OPC_DPSU_H_QBR = (0x0F << 6) | OPC_DPA_W_PH_DSP,
518 OPC_DPA_W_PH = (0x00 << 6) | OPC_DPA_W_PH_DSP,
519 OPC_DPAX_W_PH = (0x08 << 6) | OPC_DPA_W_PH_DSP,
520 OPC_DPAQ_S_W_PH = (0x04 << 6) | OPC_DPA_W_PH_DSP,
521 OPC_DPAQX_S_W_PH = (0x18 << 6) | OPC_DPA_W_PH_DSP,
522 OPC_DPAQX_SA_W_PH = (0x1A << 6) | OPC_DPA_W_PH_DSP,
523 OPC_DPS_W_PH = (0x01 << 6) | OPC_DPA_W_PH_DSP,
524 OPC_DPSX_W_PH = (0x09 << 6) | OPC_DPA_W_PH_DSP,
525 OPC_DPSQ_S_W_PH = (0x05 << 6) | OPC_DPA_W_PH_DSP,
526 OPC_DPSQX_S_W_PH = (0x19 << 6) | OPC_DPA_W_PH_DSP,
527 OPC_DPSQX_SA_W_PH = (0x1B << 6) | OPC_DPA_W_PH_DSP,
528 OPC_MULSAQ_S_W_PH = (0x06 << 6) | OPC_DPA_W_PH_DSP,
529 OPC_DPAQ_SA_L_W = (0x0C << 6) | OPC_DPA_W_PH_DSP,
530 OPC_DPSQ_SA_L_W = (0x0D << 6) | OPC_DPA_W_PH_DSP,
531 OPC_MAQ_S_W_PHL = (0x14 << 6) | OPC_DPA_W_PH_DSP,
532 OPC_MAQ_S_W_PHR = (0x16 << 6) | OPC_DPA_W_PH_DSP,
533 OPC_MAQ_SA_W_PHL = (0x10 << 6) | OPC_DPA_W_PH_DSP,
534 OPC_MAQ_SA_W_PHR = (0x12 << 6) | OPC_DPA_W_PH_DSP,
535 OPC_MULSA_W_PH = (0x02 << 6) | OPC_DPA_W_PH_DSP,
538 #define MASK_INSV(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
540 /* DSP Bit/Manipulation Sub-class */
541 OPC_INSV = (0x00 << 6) | OPC_INSV_DSP,
544 #define MASK_APPEND(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
546 /* MIPS DSP Compare-Pick Sub-class */
547 OPC_APPEND = (0x00 << 6) | OPC_APPEND_DSP,
548 OPC_PREPEND = (0x01 << 6) | OPC_APPEND_DSP,
549 OPC_BALIGN = (0x10 << 6) | OPC_APPEND_DSP,
552 #define MASK_EXTR_W(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
554 /* MIPS DSP Accumulator and DSPControl Access Sub-class */
555 OPC_EXTR_W = (0x00 << 6) | OPC_EXTR_W_DSP,
556 OPC_EXTR_R_W = (0x04 << 6) | OPC_EXTR_W_DSP,
557 OPC_EXTR_RS_W = (0x06 << 6) | OPC_EXTR_W_DSP,
558 OPC_EXTR_S_H = (0x0E << 6) | OPC_EXTR_W_DSP,
559 OPC_EXTRV_S_H = (0x0F << 6) | OPC_EXTR_W_DSP,
560 OPC_EXTRV_W = (0x01 << 6) | OPC_EXTR_W_DSP,
561 OPC_EXTRV_R_W = (0x05 << 6) | OPC_EXTR_W_DSP,
562 OPC_EXTRV_RS_W = (0x07 << 6) | OPC_EXTR_W_DSP,
563 OPC_EXTP = (0x02 << 6) | OPC_EXTR_W_DSP,
564 OPC_EXTPV = (0x03 << 6) | OPC_EXTR_W_DSP,
565 OPC_EXTPDP = (0x0A << 6) | OPC_EXTR_W_DSP,
566 OPC_EXTPDPV = (0x0B << 6) | OPC_EXTR_W_DSP,
567 OPC_SHILO = (0x1A << 6) | OPC_EXTR_W_DSP,
568 OPC_SHILOV = (0x1B << 6) | OPC_EXTR_W_DSP,
569 OPC_MTHLIP = (0x1F << 6) | OPC_EXTR_W_DSP,
570 OPC_WRDSP = (0x13 << 6) | OPC_EXTR_W_DSP,
571 OPC_RDDSP = (0x12 << 6) | OPC_EXTR_W_DSP,
574 #define MASK_ABSQ_S_QH(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
576 /* MIPS DSP Arithmetic Sub-class */
577 OPC_PRECEQ_L_PWL = (0x14 << 6) | OPC_ABSQ_S_QH_DSP,
578 OPC_PRECEQ_L_PWR = (0x15 << 6) | OPC_ABSQ_S_QH_DSP,
579 OPC_PRECEQ_PW_QHL = (0x0C << 6) | OPC_ABSQ_S_QH_DSP,
580 OPC_PRECEQ_PW_QHR = (0x0D << 6) | OPC_ABSQ_S_QH_DSP,
581 OPC_PRECEQ_PW_QHLA = (0x0E << 6) | OPC_ABSQ_S_QH_DSP,
582 OPC_PRECEQ_PW_QHRA = (0x0F << 6) | OPC_ABSQ_S_QH_DSP,
583 OPC_PRECEQU_QH_OBL = (0x04 << 6) | OPC_ABSQ_S_QH_DSP,
584 OPC_PRECEQU_QH_OBR = (0x05 << 6) | OPC_ABSQ_S_QH_DSP,
585 OPC_PRECEQU_QH_OBLA = (0x06 << 6) | OPC_ABSQ_S_QH_DSP,
586 OPC_PRECEQU_QH_OBRA = (0x07 << 6) | OPC_ABSQ_S_QH_DSP,
587 OPC_PRECEU_QH_OBL = (0x1C << 6) | OPC_ABSQ_S_QH_DSP,
588 OPC_PRECEU_QH_OBR = (0x1D << 6) | OPC_ABSQ_S_QH_DSP,
589 OPC_PRECEU_QH_OBLA = (0x1E << 6) | OPC_ABSQ_S_QH_DSP,
590 OPC_PRECEU_QH_OBRA = (0x1F << 6) | OPC_ABSQ_S_QH_DSP,
591 OPC_ABSQ_S_OB = (0x01 << 6) | OPC_ABSQ_S_QH_DSP,
592 OPC_ABSQ_S_PW = (0x11 << 6) | OPC_ABSQ_S_QH_DSP,
593 OPC_ABSQ_S_QH = (0x09 << 6) | OPC_ABSQ_S_QH_DSP,
594 /* DSP Bit/Manipulation Sub-class */
595 OPC_REPL_OB = (0x02 << 6) | OPC_ABSQ_S_QH_DSP,
596 OPC_REPL_PW = (0x12 << 6) | OPC_ABSQ_S_QH_DSP,
597 OPC_REPL_QH = (0x0A << 6) | OPC_ABSQ_S_QH_DSP,
598 OPC_REPLV_OB = (0x03 << 6) | OPC_ABSQ_S_QH_DSP,
599 OPC_REPLV_PW = (0x13 << 6) | OPC_ABSQ_S_QH_DSP,
600 OPC_REPLV_QH = (0x0B << 6) | OPC_ABSQ_S_QH_DSP,
603 #define MASK_ADDU_OB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
605 /* MIPS DSP Multiply Sub-class insns */
606 OPC_MULEQ_S_PW_QHL = (0x1C << 6) | OPC_ADDU_OB_DSP,
607 OPC_MULEQ_S_PW_QHR = (0x1D << 6) | OPC_ADDU_OB_DSP,
608 OPC_MULEU_S_QH_OBL = (0x06 << 6) | OPC_ADDU_OB_DSP,
609 OPC_MULEU_S_QH_OBR = (0x07 << 6) | OPC_ADDU_OB_DSP,
610 OPC_MULQ_RS_QH = (0x1F << 6) | OPC_ADDU_OB_DSP,
611 /* MIPS DSP Arithmetic Sub-class */
612 OPC_RADDU_L_OB = (0x14 << 6) | OPC_ADDU_OB_DSP,
613 OPC_SUBQ_PW = (0x13 << 6) | OPC_ADDU_OB_DSP,
614 OPC_SUBQ_S_PW = (0x17 << 6) | OPC_ADDU_OB_DSP,
615 OPC_SUBQ_QH = (0x0B << 6) | OPC_ADDU_OB_DSP,
616 OPC_SUBQ_S_QH = (0x0F << 6) | OPC_ADDU_OB_DSP,
617 OPC_SUBU_OB = (0x01 << 6) | OPC_ADDU_OB_DSP,
618 OPC_SUBU_S_OB = (0x05 << 6) | OPC_ADDU_OB_DSP,
619 OPC_SUBU_QH = (0x09 << 6) | OPC_ADDU_OB_DSP,
620 OPC_SUBU_S_QH = (0x0D << 6) | OPC_ADDU_OB_DSP,
621 OPC_SUBUH_OB = (0x19 << 6) | OPC_ADDU_OB_DSP,
622 OPC_SUBUH_R_OB = (0x1B << 6) | OPC_ADDU_OB_DSP,
623 OPC_ADDQ_PW = (0x12 << 6) | OPC_ADDU_OB_DSP,
624 OPC_ADDQ_S_PW = (0x16 << 6) | OPC_ADDU_OB_DSP,
625 OPC_ADDQ_QH = (0x0A << 6) | OPC_ADDU_OB_DSP,
626 OPC_ADDQ_S_QH = (0x0E << 6) | OPC_ADDU_OB_DSP,
627 OPC_ADDU_OB = (0x00 << 6) | OPC_ADDU_OB_DSP,
628 OPC_ADDU_S_OB = (0x04 << 6) | OPC_ADDU_OB_DSP,
629 OPC_ADDU_QH = (0x08 << 6) | OPC_ADDU_OB_DSP,
630 OPC_ADDU_S_QH = (0x0C << 6) | OPC_ADDU_OB_DSP,
631 OPC_ADDUH_OB = (0x18 << 6) | OPC_ADDU_OB_DSP,
632 OPC_ADDUH_R_OB = (0x1A << 6) | OPC_ADDU_OB_DSP,
635 #define MASK_CMPU_EQ_OB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
637 /* DSP Compare-Pick Sub-class */
638 OPC_CMP_EQ_PW = (0x10 << 6) | OPC_CMPU_EQ_OB_DSP,
639 OPC_CMP_LT_PW = (0x11 << 6) | OPC_CMPU_EQ_OB_DSP,
640 OPC_CMP_LE_PW = (0x12 << 6) | OPC_CMPU_EQ_OB_DSP,
641 OPC_CMP_EQ_QH = (0x08 << 6) | OPC_CMPU_EQ_OB_DSP,
642 OPC_CMP_LT_QH = (0x09 << 6) | OPC_CMPU_EQ_OB_DSP,
643 OPC_CMP_LE_QH = (0x0A << 6) | OPC_CMPU_EQ_OB_DSP,
644 OPC_CMPGDU_EQ_OB = (0x18 << 6) | OPC_CMPU_EQ_OB_DSP,
645 OPC_CMPGDU_LT_OB = (0x19 << 6) | OPC_CMPU_EQ_OB_DSP,
646 OPC_CMPGDU_LE_OB = (0x1A << 6) | OPC_CMPU_EQ_OB_DSP,
647 OPC_CMPGU_EQ_OB = (0x04 << 6) | OPC_CMPU_EQ_OB_DSP,
648 OPC_CMPGU_LT_OB = (0x05 << 6) | OPC_CMPU_EQ_OB_DSP,
649 OPC_CMPGU_LE_OB = (0x06 << 6) | OPC_CMPU_EQ_OB_DSP,
650 OPC_CMPU_EQ_OB = (0x00 << 6) | OPC_CMPU_EQ_OB_DSP,
651 OPC_CMPU_LT_OB = (0x01 << 6) | OPC_CMPU_EQ_OB_DSP,
652 OPC_CMPU_LE_OB = (0x02 << 6) | OPC_CMPU_EQ_OB_DSP,
653 OPC_PACKRL_PW = (0x0E << 6) | OPC_CMPU_EQ_OB_DSP,
654 OPC_PICK_OB = (0x03 << 6) | OPC_CMPU_EQ_OB_DSP,
655 OPC_PICK_PW = (0x13 << 6) | OPC_CMPU_EQ_OB_DSP,
656 OPC_PICK_QH = (0x0B << 6) | OPC_CMPU_EQ_OB_DSP,
657 /* MIPS DSP Arithmetic Sub-class */
658 OPC_PRECR_OB_QH = (0x0D << 6) | OPC_CMPU_EQ_OB_DSP,
659 OPC_PRECR_SRA_QH_PW = (0x1E << 6) | OPC_CMPU_EQ_OB_DSP,
660 OPC_PRECR_SRA_R_QH_PW = (0x1F << 6) | OPC_CMPU_EQ_OB_DSP,
661 OPC_PRECRQ_OB_QH = (0x0C << 6) | OPC_CMPU_EQ_OB_DSP,
662 OPC_PRECRQ_PW_L = (0x1C << 6) | OPC_CMPU_EQ_OB_DSP,
663 OPC_PRECRQ_QH_PW = (0x14 << 6) | OPC_CMPU_EQ_OB_DSP,
664 OPC_PRECRQ_RS_QH_PW = (0x15 << 6) | OPC_CMPU_EQ_OB_DSP,
665 OPC_PRECRQU_S_OB_QH = (0x0F << 6) | OPC_CMPU_EQ_OB_DSP,
668 #define MASK_DAPPEND(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
670 /* DSP Compare-Pick Sub-class */
671 OPC_DAPPEND = (0x00 << 6) | OPC_DAPPEND_DSP,
672 OPC_PREPENDD = (0x03 << 6) | OPC_DAPPEND_DSP,
673 OPC_PREPENDW = (0x01 << 6) | OPC_DAPPEND_DSP,
674 OPC_DBALIGN = (0x10 << 6) | OPC_DAPPEND_DSP,
677 #define MASK_DEXTR_W(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
679 /* MIPS DSP Accumulator and DSPControl Access Sub-class */
680 OPC_DMTHLIP = (0x1F << 6) | OPC_DEXTR_W_DSP,
681 OPC_DSHILO = (0x1A << 6) | OPC_DEXTR_W_DSP,
682 OPC_DEXTP = (0x02 << 6) | OPC_DEXTR_W_DSP,
683 OPC_DEXTPDP = (0x0A << 6) | OPC_DEXTR_W_DSP,
684 OPC_DEXTPDPV = (0x0B << 6) | OPC_DEXTR_W_DSP,
685 OPC_DEXTPV = (0x03 << 6) | OPC_DEXTR_W_DSP,
686 OPC_DEXTR_L = (0x10 << 6) | OPC_DEXTR_W_DSP,
687 OPC_DEXTR_R_L = (0x14 << 6) | OPC_DEXTR_W_DSP,
688 OPC_DEXTR_RS_L = (0x16 << 6) | OPC_DEXTR_W_DSP,
689 OPC_DEXTR_W = (0x00 << 6) | OPC_DEXTR_W_DSP,
690 OPC_DEXTR_R_W = (0x04 << 6) | OPC_DEXTR_W_DSP,
691 OPC_DEXTR_RS_W = (0x06 << 6) | OPC_DEXTR_W_DSP,
692 OPC_DEXTR_S_H = (0x0E << 6) | OPC_DEXTR_W_DSP,
693 OPC_DEXTRV_L = (0x11 << 6) | OPC_DEXTR_W_DSP,
694 OPC_DEXTRV_R_L = (0x15 << 6) | OPC_DEXTR_W_DSP,
695 OPC_DEXTRV_RS_L = (0x17 << 6) | OPC_DEXTR_W_DSP,
696 OPC_DEXTRV_S_H = (0x0F << 6) | OPC_DEXTR_W_DSP,
697 OPC_DEXTRV_W = (0x01 << 6) | OPC_DEXTR_W_DSP,
698 OPC_DEXTRV_R_W = (0x05 << 6) | OPC_DEXTR_W_DSP,
699 OPC_DEXTRV_RS_W = (0x07 << 6) | OPC_DEXTR_W_DSP,
700 OPC_DSHILOV = (0x1B << 6) | OPC_DEXTR_W_DSP,
703 #define MASK_DINSV(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
705 /* DSP Bit/Manipulation Sub-class */
706 OPC_DINSV = (0x00 << 6) | OPC_DINSV_DSP,
709 #define MASK_DPAQ_W_QH(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
711 /* MIPS DSP Multiply Sub-class insns */
712 OPC_DMADD = (0x19 << 6) | OPC_DPAQ_W_QH_DSP,
713 OPC_DMADDU = (0x1D << 6) | OPC_DPAQ_W_QH_DSP,
714 OPC_DMSUB = (0x1B << 6) | OPC_DPAQ_W_QH_DSP,
715 OPC_DMSUBU = (0x1F << 6) | OPC_DPAQ_W_QH_DSP,
716 OPC_DPA_W_QH = (0x00 << 6) | OPC_DPAQ_W_QH_DSP,
717 OPC_DPAQ_S_W_QH = (0x04 << 6) | OPC_DPAQ_W_QH_DSP,
718 OPC_DPAQ_SA_L_PW = (0x0C << 6) | OPC_DPAQ_W_QH_DSP,
719 OPC_DPAU_H_OBL = (0x03 << 6) | OPC_DPAQ_W_QH_DSP,
720 OPC_DPAU_H_OBR = (0x07 << 6) | OPC_DPAQ_W_QH_DSP,
721 OPC_DPS_W_QH = (0x01 << 6) | OPC_DPAQ_W_QH_DSP,
722 OPC_DPSQ_S_W_QH = (0x05 << 6) | OPC_DPAQ_W_QH_DSP,
723 OPC_DPSQ_SA_L_PW = (0x0D << 6) | OPC_DPAQ_W_QH_DSP,
724 OPC_DPSU_H_OBL = (0x0B << 6) | OPC_DPAQ_W_QH_DSP,
725 OPC_DPSU_H_OBR = (0x0F << 6) | OPC_DPAQ_W_QH_DSP,
726 OPC_MAQ_S_L_PWL = (0x1C << 6) | OPC_DPAQ_W_QH_DSP,
727 OPC_MAQ_S_L_PWR = (0x1E << 6) | OPC_DPAQ_W_QH_DSP,
728 OPC_MAQ_S_W_QHLL = (0x14 << 6) | OPC_DPAQ_W_QH_DSP,
729 OPC_MAQ_SA_W_QHLL = (0x10 << 6) | OPC_DPAQ_W_QH_DSP,
730 OPC_MAQ_S_W_QHLR = (0x15 << 6) | OPC_DPAQ_W_QH_DSP,
731 OPC_MAQ_SA_W_QHLR = (0x11 << 6) | OPC_DPAQ_W_QH_DSP,
732 OPC_MAQ_S_W_QHRL = (0x16 << 6) | OPC_DPAQ_W_QH_DSP,
733 OPC_MAQ_SA_W_QHRL = (0x12 << 6) | OPC_DPAQ_W_QH_DSP,
734 OPC_MAQ_S_W_QHRR = (0x17 << 6) | OPC_DPAQ_W_QH_DSP,
735 OPC_MAQ_SA_W_QHRR = (0x13 << 6) | OPC_DPAQ_W_QH_DSP,
736 OPC_MULSAQ_S_L_PW = (0x0E << 6) | OPC_DPAQ_W_QH_DSP,
737 OPC_MULSAQ_S_W_QH = (0x06 << 6) | OPC_DPAQ_W_QH_DSP,
740 #define MASK_SHLL_OB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
742 /* MIPS DSP GPR-Based Shift Sub-class */
743 OPC_SHLL_PW = (0x10 << 6) | OPC_SHLL_OB_DSP,
744 OPC_SHLL_S_PW = (0x14 << 6) | OPC_SHLL_OB_DSP,
745 OPC_SHLLV_OB = (0x02 << 6) | OPC_SHLL_OB_DSP,
746 OPC_SHLLV_PW = (0x12 << 6) | OPC_SHLL_OB_DSP,
747 OPC_SHLLV_S_PW = (0x16 << 6) | OPC_SHLL_OB_DSP,
748 OPC_SHLLV_QH = (0x0A << 6) | OPC_SHLL_OB_DSP,
749 OPC_SHLLV_S_QH = (0x0E << 6) | OPC_SHLL_OB_DSP,
750 OPC_SHRA_PW = (0x11 << 6) | OPC_SHLL_OB_DSP,
751 OPC_SHRA_R_PW = (0x15 << 6) | OPC_SHLL_OB_DSP,
752 OPC_SHRAV_OB = (0x06 << 6) | OPC_SHLL_OB_DSP,
753 OPC_SHRAV_R_OB = (0x07 << 6) | OPC_SHLL_OB_DSP,
754 OPC_SHRAV_PW = (0x13 << 6) | OPC_SHLL_OB_DSP,
755 OPC_SHRAV_R_PW = (0x17 << 6) | OPC_SHLL_OB_DSP,
756 OPC_SHRAV_QH = (0x0B << 6) | OPC_SHLL_OB_DSP,
757 OPC_SHRAV_R_QH = (0x0F << 6) | OPC_SHLL_OB_DSP,
758 OPC_SHRLV_OB = (0x03 << 6) | OPC_SHLL_OB_DSP,
759 OPC_SHRLV_QH = (0x1B << 6) | OPC_SHLL_OB_DSP,
760 OPC_SHLL_OB = (0x00 << 6) | OPC_SHLL_OB_DSP,
761 OPC_SHLL_QH = (0x08 << 6) | OPC_SHLL_OB_DSP,
762 OPC_SHLL_S_QH = (0x0C << 6) | OPC_SHLL_OB_DSP,
763 OPC_SHRA_OB = (0x04 << 6) | OPC_SHLL_OB_DSP,
764 OPC_SHRA_R_OB = (0x05 << 6) | OPC_SHLL_OB_DSP,
765 OPC_SHRA_QH = (0x09 << 6) | OPC_SHLL_OB_DSP,
766 OPC_SHRA_R_QH = (0x0D << 6) | OPC_SHLL_OB_DSP,
767 OPC_SHRL_OB = (0x01 << 6) | OPC_SHLL_OB_DSP,
768 OPC_SHRL_QH = (0x19 << 6) | OPC_SHLL_OB_DSP,
771 /* Coprocessor 0 (rs field) */
772 #define MASK_CP0(op) MASK_OP_MAJOR(op) | (op & (0x1F << 21))
775 OPC_MFC0 = (0x00 << 21) | OPC_CP0,
776 OPC_DMFC0 = (0x01 << 21) | OPC_CP0,
777 OPC_MTC0 = (0x04 << 21) | OPC_CP0,
778 OPC_DMTC0 = (0x05 << 21) | OPC_CP0,
779 OPC_MFTR = (0x08 << 21) | OPC_CP0,
780 OPC_RDPGPR = (0x0A << 21) | OPC_CP0,
781 OPC_MFMC0 = (0x0B << 21) | OPC_CP0,
782 OPC_MTTR = (0x0C << 21) | OPC_CP0,
783 OPC_WRPGPR = (0x0E << 21) | OPC_CP0,
784 OPC_C0 = (0x10 << 21) | OPC_CP0,
785 OPC_C0_FIRST = (0x10 << 21) | OPC_CP0,
786 OPC_C0_LAST = (0x1F << 21) | OPC_CP0,
790 #define MASK_MFMC0(op) MASK_CP0(op) | (op & 0xFFFF)
793 OPC_DMT = 0x01 | (0 << 5) | (0x0F << 6) | (0x01 << 11) | OPC_MFMC0,
794 OPC_EMT = 0x01 | (1 << 5) | (0x0F << 6) | (0x01 << 11) | OPC_MFMC0,
795 OPC_DVPE = 0x01 | (0 << 5) | OPC_MFMC0,
796 OPC_EVPE = 0x01 | (1 << 5) | OPC_MFMC0,
797 OPC_DI = (0 << 5) | (0x0C << 11) | OPC_MFMC0,
798 OPC_EI = (1 << 5) | (0x0C << 11) | OPC_MFMC0,
801 /* Coprocessor 0 (with rs == C0) */
802 #define MASK_C0(op) MASK_CP0(op) | (op & 0x3F)
805 OPC_TLBR = 0x01 | OPC_C0,
806 OPC_TLBWI = 0x02 | OPC_C0,
807 OPC_TLBWR = 0x06 | OPC_C0,
808 OPC_TLBP = 0x08 | OPC_C0,
809 OPC_RFE = 0x10 | OPC_C0,
810 OPC_ERET = 0x18 | OPC_C0,
811 OPC_DERET = 0x1F | OPC_C0,
812 OPC_WAIT = 0x20 | OPC_C0,
815 /* Coprocessor 1 (rs field) */
816 #define MASK_CP1(op) MASK_OP_MAJOR(op) | (op & (0x1F << 21))
818 /* Values for the fmt field in FP instructions */
820 /* 0 - 15 are reserved */
821 FMT_S = 16, /* single fp */
822 FMT_D = 17, /* double fp */
823 FMT_E = 18, /* extended fp */
824 FMT_Q = 19, /* quad fp */
825 FMT_W = 20, /* 32-bit fixed */
826 FMT_L = 21, /* 64-bit fixed */
827 FMT_PS = 22, /* paired single fp */
828 /* 23 - 31 are reserved */
832 OPC_MFC1 = (0x00 << 21) | OPC_CP1,
833 OPC_DMFC1 = (0x01 << 21) | OPC_CP1,
834 OPC_CFC1 = (0x02 << 21) | OPC_CP1,
835 OPC_MFHC1 = (0x03 << 21) | OPC_CP1,
836 OPC_MTC1 = (0x04 << 21) | OPC_CP1,
837 OPC_DMTC1 = (0x05 << 21) | OPC_CP1,
838 OPC_CTC1 = (0x06 << 21) | OPC_CP1,
839 OPC_MTHC1 = (0x07 << 21) | OPC_CP1,
840 OPC_BC1 = (0x08 << 21) | OPC_CP1, /* bc */
841 OPC_BC1ANY2 = (0x09 << 21) | OPC_CP1,
842 OPC_BC1ANY4 = (0x0A << 21) | OPC_CP1,
843 OPC_S_FMT = (FMT_S << 21) | OPC_CP1,
844 OPC_D_FMT = (FMT_D << 21) | OPC_CP1,
845 OPC_E_FMT = (FMT_E << 21) | OPC_CP1,
846 OPC_Q_FMT = (FMT_Q << 21) | OPC_CP1,
847 OPC_W_FMT = (FMT_W << 21) | OPC_CP1,
848 OPC_L_FMT = (FMT_L << 21) | OPC_CP1,
849 OPC_PS_FMT = (FMT_PS << 21) | OPC_CP1,
852 #define MASK_CP1_FUNC(op) MASK_CP1(op) | (op & 0x3F)
853 #define MASK_BC1(op) MASK_CP1(op) | (op & (0x3 << 16))
856 OPC_BC1F = (0x00 << 16) | OPC_BC1,
857 OPC_BC1T = (0x01 << 16) | OPC_BC1,
858 OPC_BC1FL = (0x02 << 16) | OPC_BC1,
859 OPC_BC1TL = (0x03 << 16) | OPC_BC1,
863 OPC_BC1FANY2 = (0x00 << 16) | OPC_BC1ANY2,
864 OPC_BC1TANY2 = (0x01 << 16) | OPC_BC1ANY2,
868 OPC_BC1FANY4 = (0x00 << 16) | OPC_BC1ANY4,
869 OPC_BC1TANY4 = (0x01 << 16) | OPC_BC1ANY4,
872 #define MASK_CP2(op) MASK_OP_MAJOR(op) | (op & (0x1F << 21))
875 OPC_MFC2 = (0x00 << 21) | OPC_CP2,
876 OPC_DMFC2 = (0x01 << 21) | OPC_CP2,
877 OPC_CFC2 = (0x02 << 21) | OPC_CP2,
878 OPC_MFHC2 = (0x03 << 21) | OPC_CP2,
879 OPC_MTC2 = (0x04 << 21) | OPC_CP2,
880 OPC_DMTC2 = (0x05 << 21) | OPC_CP2,
881 OPC_CTC2 = (0x06 << 21) | OPC_CP2,
882 OPC_MTHC2 = (0x07 << 21) | OPC_CP2,
883 OPC_BC2 = (0x08 << 21) | OPC_CP2,
886 #define MASK_LMI(op) (MASK_OP_MAJOR(op) | (op & (0x1F << 21)) | (op & 0x1F))
889 OPC_PADDSH = (24 << 21) | (0x00) | OPC_CP2,
890 OPC_PADDUSH = (25 << 21) | (0x00) | OPC_CP2,
891 OPC_PADDH = (26 << 21) | (0x00) | OPC_CP2,
892 OPC_PADDW = (27 << 21) | (0x00) | OPC_CP2,
893 OPC_PADDSB = (28 << 21) | (0x00) | OPC_CP2,
894 OPC_PADDUSB = (29 << 21) | (0x00) | OPC_CP2,
895 OPC_PADDB = (30 << 21) | (0x00) | OPC_CP2,
896 OPC_PADDD = (31 << 21) | (0x00) | OPC_CP2,
898 OPC_PSUBSH = (24 << 21) | (0x01) | OPC_CP2,
899 OPC_PSUBUSH = (25 << 21) | (0x01) | OPC_CP2,
900 OPC_PSUBH = (26 << 21) | (0x01) | OPC_CP2,
901 OPC_PSUBW = (27 << 21) | (0x01) | OPC_CP2,
902 OPC_PSUBSB = (28 << 21) | (0x01) | OPC_CP2,
903 OPC_PSUBUSB = (29 << 21) | (0x01) | OPC_CP2,
904 OPC_PSUBB = (30 << 21) | (0x01) | OPC_CP2,
905 OPC_PSUBD = (31 << 21) | (0x01) | OPC_CP2,
907 OPC_PSHUFH = (24 << 21) | (0x02) | OPC_CP2,
908 OPC_PACKSSWH = (25 << 21) | (0x02) | OPC_CP2,
909 OPC_PACKSSHB = (26 << 21) | (0x02) | OPC_CP2,
910 OPC_PACKUSHB = (27 << 21) | (0x02) | OPC_CP2,
911 OPC_XOR_CP2 = (28 << 21) | (0x02) | OPC_CP2,
912 OPC_NOR_CP2 = (29 << 21) | (0x02) | OPC_CP2,
913 OPC_AND_CP2 = (30 << 21) | (0x02) | OPC_CP2,
914 OPC_PANDN = (31 << 21) | (0x02) | OPC_CP2,
916 OPC_PUNPCKLHW = (24 << 21) | (0x03) | OPC_CP2,
917 OPC_PUNPCKHHW = (25 << 21) | (0x03) | OPC_CP2,
918 OPC_PUNPCKLBH = (26 << 21) | (0x03) | OPC_CP2,
919 OPC_PUNPCKHBH = (27 << 21) | (0x03) | OPC_CP2,
920 OPC_PINSRH_0 = (28 << 21) | (0x03) | OPC_CP2,
921 OPC_PINSRH_1 = (29 << 21) | (0x03) | OPC_CP2,
922 OPC_PINSRH_2 = (30 << 21) | (0x03) | OPC_CP2,
923 OPC_PINSRH_3 = (31 << 21) | (0x03) | OPC_CP2,
925 OPC_PAVGH = (24 << 21) | (0x08) | OPC_CP2,
926 OPC_PAVGB = (25 << 21) | (0x08) | OPC_CP2,
927 OPC_PMAXSH = (26 << 21) | (0x08) | OPC_CP2,
928 OPC_PMINSH = (27 << 21) | (0x08) | OPC_CP2,
929 OPC_PMAXUB = (28 << 21) | (0x08) | OPC_CP2,
930 OPC_PMINUB = (29 << 21) | (0x08) | OPC_CP2,
932 OPC_PCMPEQW = (24 << 21) | (0x09) | OPC_CP2,
933 OPC_PCMPGTW = (25 << 21) | (0x09) | OPC_CP2,
934 OPC_PCMPEQH = (26 << 21) | (0x09) | OPC_CP2,
935 OPC_PCMPGTH = (27 << 21) | (0x09) | OPC_CP2,
936 OPC_PCMPEQB = (28 << 21) | (0x09) | OPC_CP2,
937 OPC_PCMPGTB = (29 << 21) | (0x09) | OPC_CP2,
939 OPC_PSLLW = (24 << 21) | (0x0A) | OPC_CP2,
940 OPC_PSLLH = (25 << 21) | (0x0A) | OPC_CP2,
941 OPC_PMULLH = (26 << 21) | (0x0A) | OPC_CP2,
942 OPC_PMULHH = (27 << 21) | (0x0A) | OPC_CP2,
943 OPC_PMULUW = (28 << 21) | (0x0A) | OPC_CP2,
944 OPC_PMULHUH = (29 << 21) | (0x0A) | OPC_CP2,
946 OPC_PSRLW = (24 << 21) | (0x0B) | OPC_CP2,
947 OPC_PSRLH = (25 << 21) | (0x0B) | OPC_CP2,
948 OPC_PSRAW = (26 << 21) | (0x0B) | OPC_CP2,
949 OPC_PSRAH = (27 << 21) | (0x0B) | OPC_CP2,
950 OPC_PUNPCKLWD = (28 << 21) | (0x0B) | OPC_CP2,
951 OPC_PUNPCKHWD = (29 << 21) | (0x0B) | OPC_CP2,
953 OPC_ADDU_CP2 = (24 << 21) | (0x0C) | OPC_CP2,
954 OPC_OR_CP2 = (25 << 21) | (0x0C) | OPC_CP2,
955 OPC_ADD_CP2 = (26 << 21) | (0x0C) | OPC_CP2,
956 OPC_DADD_CP2 = (27 << 21) | (0x0C) | OPC_CP2,
957 OPC_SEQU_CP2 = (28 << 21) | (0x0C) | OPC_CP2,
958 OPC_SEQ_CP2 = (29 << 21) | (0x0C) | OPC_CP2,
960 OPC_SUBU_CP2 = (24 << 21) | (0x0D) | OPC_CP2,
961 OPC_PASUBUB = (25 << 21) | (0x0D) | OPC_CP2,
962 OPC_SUB_CP2 = (26 << 21) | (0x0D) | OPC_CP2,
963 OPC_DSUB_CP2 = (27 << 21) | (0x0D) | OPC_CP2,
964 OPC_SLTU_CP2 = (28 << 21) | (0x0D) | OPC_CP2,
965 OPC_SLT_CP2 = (29 << 21) | (0x0D) | OPC_CP2,
967 OPC_SLL_CP2 = (24 << 21) | (0x0E) | OPC_CP2,
968 OPC_DSLL_CP2 = (25 << 21) | (0x0E) | OPC_CP2,
969 OPC_PEXTRH = (26 << 21) | (0x0E) | OPC_CP2,
970 OPC_PMADDHW = (27 << 21) | (0x0E) | OPC_CP2,
971 OPC_SLEU_CP2 = (28 << 21) | (0x0E) | OPC_CP2,
972 OPC_SLE_CP2 = (29 << 21) | (0x0E) | OPC_CP2,
974 OPC_SRL_CP2 = (24 << 21) | (0x0F) | OPC_CP2,
975 OPC_DSRL_CP2 = (25 << 21) | (0x0F) | OPC_CP2,
976 OPC_SRA_CP2 = (26 << 21) | (0x0F) | OPC_CP2,
977 OPC_DSRA_CP2 = (27 << 21) | (0x0F) | OPC_CP2,
978 OPC_BIADD = (28 << 21) | (0x0F) | OPC_CP2,
979 OPC_PMOVMSKB = (29 << 21) | (0x0F) | OPC_CP2,
983 #define MASK_CP3(op) MASK_OP_MAJOR(op) | (op & 0x3F)
986 OPC_LWXC1 = 0x00 | OPC_CP3,
987 OPC_LDXC1 = 0x01 | OPC_CP3,
988 OPC_LUXC1 = 0x05 | OPC_CP3,
989 OPC_SWXC1 = 0x08 | OPC_CP3,
990 OPC_SDXC1 = 0x09 | OPC_CP3,
991 OPC_SUXC1 = 0x0D | OPC_CP3,
992 OPC_PREFX = 0x0F | OPC_CP3,
993 OPC_ALNV_PS = 0x1E | OPC_CP3,
994 OPC_MADD_S = 0x20 | OPC_CP3,
995 OPC_MADD_D = 0x21 | OPC_CP3,
996 OPC_MADD_PS = 0x26 | OPC_CP3,
997 OPC_MSUB_S = 0x28 | OPC_CP3,
998 OPC_MSUB_D = 0x29 | OPC_CP3,
999 OPC_MSUB_PS = 0x2E | OPC_CP3,
1000 OPC_NMADD_S = 0x30 | OPC_CP3,
1001 OPC_NMADD_D = 0x31 | OPC_CP3,
1002 OPC_NMADD_PS= 0x36 | OPC_CP3,
1003 OPC_NMSUB_S = 0x38 | OPC_CP3,
1004 OPC_NMSUB_D = 0x39 | OPC_CP3,
1005 OPC_NMSUB_PS= 0x3E | OPC_CP3,
1008 /* global register indices */
1009 static TCGv_ptr cpu_env;
1010 static TCGv cpu_gpr[32], cpu_PC;
1011 static TCGv cpu_HI[MIPS_DSP_ACC], cpu_LO[MIPS_DSP_ACC], cpu_ACX[MIPS_DSP_ACC];
1012 static TCGv cpu_dspctrl, btarget, bcond;
1013 static TCGv_i32 hflags;
1014 static TCGv_i32 fpu_fcr0, fpu_fcr31;
1015 static TCGv_i64 fpu_f64[32];
1017 static uint32_t gen_opc_hflags[OPC_BUF_SIZE];
1018 static target_ulong gen_opc_btarget[OPC_BUF_SIZE];
1020 #include "gen-icount.h"
1022 #define gen_helper_0e0i(name, arg) do { \
1023 TCGv_i32 helper_tmp = tcg_const_i32(arg); \
1024 gen_helper_##name(cpu_env, helper_tmp); \
1025 tcg_temp_free_i32(helper_tmp); \
1028 #define gen_helper_0e1i(name, arg1, arg2) do { \
1029 TCGv_i32 helper_tmp = tcg_const_i32(arg2); \
1030 gen_helper_##name(cpu_env, arg1, helper_tmp); \
1031 tcg_temp_free_i32(helper_tmp); \
1034 #define gen_helper_1e0i(name, ret, arg1) do { \
1035 TCGv_i32 helper_tmp = tcg_const_i32(arg1); \
1036 gen_helper_##name(ret, cpu_env, helper_tmp); \
1037 tcg_temp_free_i32(helper_tmp); \
1040 #define gen_helper_1e1i(name, ret, arg1, arg2) do { \
1041 TCGv_i32 helper_tmp = tcg_const_i32(arg2); \
1042 gen_helper_##name(ret, cpu_env, arg1, helper_tmp); \
1043 tcg_temp_free_i32(helper_tmp); \
1046 #define gen_helper_0e2i(name, arg1, arg2, arg3) do { \
1047 TCGv_i32 helper_tmp = tcg_const_i32(arg3); \
1048 gen_helper_##name(cpu_env, arg1, arg2, helper_tmp); \
1049 tcg_temp_free_i32(helper_tmp); \
1052 #define gen_helper_1e2i(name, ret, arg1, arg2, arg3) do { \
1053 TCGv_i32 helper_tmp = tcg_const_i32(arg3); \
1054 gen_helper_##name(ret, cpu_env, arg1, arg2, helper_tmp); \
1055 tcg_temp_free_i32(helper_tmp); \
1058 #define gen_helper_0e3i(name, arg1, arg2, arg3, arg4) do { \
1059 TCGv_i32 helper_tmp = tcg_const_i32(arg4); \
1060 gen_helper_##name(cpu_env, arg1, arg2, arg3, helper_tmp); \
1061 tcg_temp_free_i32(helper_tmp); \
1064 typedef struct DisasContext {
1065 struct TranslationBlock *tb;
1066 target_ulong pc, saved_pc;
1068 int singlestep_enabled;
1069 /* Routine used to access memory */
1071 uint32_t hflags, saved_hflags;
1073 target_ulong btarget;
1077 BS_NONE = 0, /* We go out of the TB without reaching a branch or an
1078 * exception condition */
1079 BS_STOP = 1, /* We want to stop translation for any reason */
1080 BS_BRANCH = 2, /* We reached a branch condition */
1081 BS_EXCP = 3, /* We reached an exception condition */
1084 static const char * const regnames[] = {
1085 "r0", "at", "v0", "v1", "a0", "a1", "a2", "a3",
1086 "t0", "t1", "t2", "t3", "t4", "t5", "t6", "t7",
1087 "s0", "s1", "s2", "s3", "s4", "s5", "s6", "s7",
1088 "t8", "t9", "k0", "k1", "gp", "sp", "s8", "ra",
1091 static const char * const regnames_HI[] = {
1092 "HI0", "HI1", "HI2", "HI3",
1095 static const char * const regnames_LO[] = {
1096 "LO0", "LO1", "LO2", "LO3",
1099 static const char * const regnames_ACX[] = {
1100 "ACX0", "ACX1", "ACX2", "ACX3",
1103 static const char * const fregnames[] = {
1104 "f0", "f1", "f2", "f3", "f4", "f5", "f6", "f7",
1105 "f8", "f9", "f10", "f11", "f12", "f13", "f14", "f15",
1106 "f16", "f17", "f18", "f19", "f20", "f21", "f22", "f23",
1107 "f24", "f25", "f26", "f27", "f28", "f29", "f30", "f31",
1110 #define MIPS_DEBUG(fmt, ...) \
1112 if (MIPS_DEBUG_DISAS) { \
1113 qemu_log_mask(CPU_LOG_TB_IN_ASM, \
1114 TARGET_FMT_lx ": %08x " fmt "\n", \
1115 ctx->pc, ctx->opcode , ## __VA_ARGS__); \
1119 #define LOG_DISAS(...) \
1121 if (MIPS_DEBUG_DISAS) { \
1122 qemu_log_mask(CPU_LOG_TB_IN_ASM, ## __VA_ARGS__); \
1126 #define MIPS_INVAL(op) \
1127 MIPS_DEBUG("Invalid %s %03x %03x %03x", op, ctx->opcode >> 26, \
1128 ctx->opcode & 0x3F, ((ctx->opcode >> 16) & 0x1F))
1130 /* General purpose registers moves. */
1131 static inline void gen_load_gpr (TCGv t, int reg)
1134 tcg_gen_movi_tl(t, 0);
1136 tcg_gen_mov_tl(t, cpu_gpr[reg]);
1139 static inline void gen_store_gpr (TCGv t, int reg)
1142 tcg_gen_mov_tl(cpu_gpr[reg], t);
1145 /* Moves to/from ACX register. */
1146 static inline void gen_load_ACX (TCGv t, int reg)
1148 tcg_gen_mov_tl(t, cpu_ACX[reg]);
1151 static inline void gen_store_ACX (TCGv t, int reg)
1153 tcg_gen_mov_tl(cpu_ACX[reg], t);
1156 /* Moves to/from shadow registers. */
1157 static inline void gen_load_srsgpr (int from, int to)
1159 TCGv t0 = tcg_temp_new();
1162 tcg_gen_movi_tl(t0, 0);
1164 TCGv_i32 t2 = tcg_temp_new_i32();
1165 TCGv_ptr addr = tcg_temp_new_ptr();
1167 tcg_gen_ld_i32(t2, cpu_env, offsetof(CPUMIPSState, CP0_SRSCtl));
1168 tcg_gen_shri_i32(t2, t2, CP0SRSCtl_PSS);
1169 tcg_gen_andi_i32(t2, t2, 0xf);
1170 tcg_gen_muli_i32(t2, t2, sizeof(target_ulong) * 32);
1171 tcg_gen_ext_i32_ptr(addr, t2);
1172 tcg_gen_add_ptr(addr, cpu_env, addr);
1174 tcg_gen_ld_tl(t0, addr, sizeof(target_ulong) * from);
1175 tcg_temp_free_ptr(addr);
1176 tcg_temp_free_i32(t2);
1178 gen_store_gpr(t0, to);
1182 static inline void gen_store_srsgpr (int from, int to)
1185 TCGv t0 = tcg_temp_new();
1186 TCGv_i32 t2 = tcg_temp_new_i32();
1187 TCGv_ptr addr = tcg_temp_new_ptr();
1189 gen_load_gpr(t0, from);
1190 tcg_gen_ld_i32(t2, cpu_env, offsetof(CPUMIPSState, CP0_SRSCtl));
1191 tcg_gen_shri_i32(t2, t2, CP0SRSCtl_PSS);
1192 tcg_gen_andi_i32(t2, t2, 0xf);
1193 tcg_gen_muli_i32(t2, t2, sizeof(target_ulong) * 32);
1194 tcg_gen_ext_i32_ptr(addr, t2);
1195 tcg_gen_add_ptr(addr, cpu_env, addr);
1197 tcg_gen_st_tl(t0, addr, sizeof(target_ulong) * to);
1198 tcg_temp_free_ptr(addr);
1199 tcg_temp_free_i32(t2);
1204 /* Floating point register moves. */
1205 static void gen_load_fpr32(TCGv_i32 t, int reg)
1207 tcg_gen_trunc_i64_i32(t, fpu_f64[reg]);
1210 static void gen_store_fpr32(TCGv_i32 t, int reg)
1212 TCGv_i64 t64 = tcg_temp_new_i64();
1213 tcg_gen_extu_i32_i64(t64, t);
1214 tcg_gen_deposit_i64(fpu_f64[reg], fpu_f64[reg], t64, 0, 32);
1215 tcg_temp_free_i64(t64);
1218 static void gen_load_fpr32h(TCGv_i32 t, int reg)
1220 TCGv_i64 t64 = tcg_temp_new_i64();
1221 tcg_gen_shri_i64(t64, fpu_f64[reg], 32);
1222 tcg_gen_trunc_i64_i32(t, t64);
1223 tcg_temp_free_i64(t64);
1226 static void gen_store_fpr32h(TCGv_i32 t, int reg)
1228 TCGv_i64 t64 = tcg_temp_new_i64();
1229 tcg_gen_extu_i32_i64(t64, t);
1230 tcg_gen_deposit_i64(fpu_f64[reg], fpu_f64[reg], t64, 32, 32);
1231 tcg_temp_free_i64(t64);
1234 static void gen_load_fpr64(DisasContext *ctx, TCGv_i64 t, int reg)
1236 if (ctx->hflags & MIPS_HFLAG_F64) {
1237 tcg_gen_mov_i64(t, fpu_f64[reg]);
1239 tcg_gen_concat32_i64(t, fpu_f64[reg & ~1], fpu_f64[reg | 1]);
1243 static void gen_store_fpr64(DisasContext *ctx, TCGv_i64 t, int reg)
1245 if (ctx->hflags & MIPS_HFLAG_F64) {
1246 tcg_gen_mov_i64(fpu_f64[reg], t);
1249 tcg_gen_deposit_i64(fpu_f64[reg & ~1], fpu_f64[reg & ~1], t, 0, 32);
1250 t0 = tcg_temp_new_i64();
1251 tcg_gen_shri_i64(t0, t, 32);
1252 tcg_gen_deposit_i64(fpu_f64[reg | 1], fpu_f64[reg | 1], t0, 0, 32);
1253 tcg_temp_free_i64(t0);
1257 static inline int get_fp_bit (int cc)
1266 static inline void gen_save_pc(target_ulong pc)
1268 tcg_gen_movi_tl(cpu_PC, pc);
1271 static inline void save_cpu_state (DisasContext *ctx, int do_save_pc)
1273 LOG_DISAS("hflags %08x saved %08x\n", ctx->hflags, ctx->saved_hflags);
1274 if (do_save_pc && ctx->pc != ctx->saved_pc) {
1275 gen_save_pc(ctx->pc);
1276 ctx->saved_pc = ctx->pc;
1278 if (ctx->hflags != ctx->saved_hflags) {
1279 tcg_gen_movi_i32(hflags, ctx->hflags);
1280 ctx->saved_hflags = ctx->hflags;
1281 switch (ctx->hflags & MIPS_HFLAG_BMASK_BASE) {
1287 tcg_gen_movi_tl(btarget, ctx->btarget);
1293 static inline void restore_cpu_state (CPUMIPSState *env, DisasContext *ctx)
1295 ctx->saved_hflags = ctx->hflags;
1296 switch (ctx->hflags & MIPS_HFLAG_BMASK_BASE) {
1302 ctx->btarget = env->btarget;
1308 generate_exception_err (DisasContext *ctx, int excp, int err)
1310 TCGv_i32 texcp = tcg_const_i32(excp);
1311 TCGv_i32 terr = tcg_const_i32(err);
1312 save_cpu_state(ctx, 1);
1313 gen_helper_raise_exception_err(cpu_env, texcp, terr);
1314 tcg_temp_free_i32(terr);
1315 tcg_temp_free_i32(texcp);
1319 generate_exception (DisasContext *ctx, int excp)
1321 save_cpu_state(ctx, 1);
1322 gen_helper_0e0i(raise_exception, excp);
1325 /* Addresses computation */
1326 static inline void gen_op_addr_add (DisasContext *ctx, TCGv ret, TCGv arg0, TCGv arg1)
1328 tcg_gen_add_tl(ret, arg0, arg1);
1330 #if defined(TARGET_MIPS64)
1331 /* For compatibility with 32-bit code, data reference in user mode
1332 with Status_UX = 0 should be casted to 32-bit and sign extended.
1333 See the MIPS64 PRA manual, section 4.10. */
1334 if (((ctx->hflags & MIPS_HFLAG_KSU) == MIPS_HFLAG_UM) &&
1335 !(ctx->hflags & MIPS_HFLAG_UX)) {
1336 tcg_gen_ext32s_i64(ret, ret);
1341 static inline void check_cp0_enabled(DisasContext *ctx)
1343 if (unlikely(!(ctx->hflags & MIPS_HFLAG_CP0)))
1344 generate_exception_err(ctx, EXCP_CpU, 0);
1347 static inline void check_cp1_enabled(DisasContext *ctx)
1349 if (unlikely(!(ctx->hflags & MIPS_HFLAG_FPU)))
1350 generate_exception_err(ctx, EXCP_CpU, 1);
1353 /* Verify that the processor is running with COP1X instructions enabled.
1354 This is associated with the nabla symbol in the MIPS32 and MIPS64
1357 static inline void check_cop1x(DisasContext *ctx)
1359 if (unlikely(!(ctx->hflags & MIPS_HFLAG_COP1X)))
1360 generate_exception(ctx, EXCP_RI);
1363 /* Verify that the processor is running with 64-bit floating-point
1364 operations enabled. */
1366 static inline void check_cp1_64bitmode(DisasContext *ctx)
1368 if (unlikely(~ctx->hflags & (MIPS_HFLAG_F64 | MIPS_HFLAG_COP1X)))
1369 generate_exception(ctx, EXCP_RI);
1373 * Verify if floating point register is valid; an operation is not defined
1374 * if bit 0 of any register specification is set and the FR bit in the
1375 * Status register equals zero, since the register numbers specify an
1376 * even-odd pair of adjacent coprocessor general registers. When the FR bit
1377 * in the Status register equals one, both even and odd register numbers
1378 * are valid. This limitation exists only for 64 bit wide (d,l,ps) registers.
1380 * Multiple 64 bit wide registers can be checked by calling
1381 * gen_op_cp1_registers(freg1 | freg2 | ... | fregN);
1383 static inline void check_cp1_registers(DisasContext *ctx, int regs)
1385 if (unlikely(!(ctx->hflags & MIPS_HFLAG_F64) && (regs & 1)))
1386 generate_exception(ctx, EXCP_RI);
1389 /* Verify that the processor is running with DSP instructions enabled.
1390 This is enabled by CP0 Status register MX(24) bit.
1393 static inline void check_dsp(DisasContext *ctx)
1395 if (unlikely(!(ctx->hflags & MIPS_HFLAG_DSP))) {
1396 generate_exception(ctx, EXCP_DSPDIS);
1400 static inline void check_dspr2(DisasContext *ctx)
1402 if (unlikely(!(ctx->hflags & MIPS_HFLAG_DSPR2))) {
1403 generate_exception(ctx, EXCP_DSPDIS);
1407 /* This code generates a "reserved instruction" exception if the
1408 CPU does not support the instruction set corresponding to flags. */
1409 static inline void check_insn(CPUMIPSState *env, DisasContext *ctx, int flags)
1411 if (unlikely(!(env->insn_flags & flags)))
1412 generate_exception(ctx, EXCP_RI);
1415 /* This code generates a "reserved instruction" exception if 64-bit
1416 instructions are not enabled. */
1417 static inline void check_mips_64(DisasContext *ctx)
1419 if (unlikely(!(ctx->hflags & MIPS_HFLAG_64)))
1420 generate_exception(ctx, EXCP_RI);
1423 /* Define small wrappers for gen_load_fpr* so that we have a uniform
1424 calling interface for 32 and 64-bit FPRs. No sense in changing
1425 all callers for gen_load_fpr32 when we need the CTX parameter for
1427 #define gen_ldcmp_fpr32(ctx, x, y) gen_load_fpr32(x, y)
1428 #define gen_ldcmp_fpr64(ctx, x, y) gen_load_fpr64(ctx, x, y)
1429 #define FOP_CONDS(type, abs, fmt, ifmt, bits) \
1430 static inline void gen_cmp ## type ## _ ## fmt(DisasContext *ctx, int n, \
1431 int ft, int fs, int cc) \
1433 TCGv_i##bits fp0 = tcg_temp_new_i##bits (); \
1434 TCGv_i##bits fp1 = tcg_temp_new_i##bits (); \
1437 check_cp1_64bitmode(ctx); \
1443 check_cp1_registers(ctx, fs | ft); \
1451 gen_ldcmp_fpr##bits (ctx, fp0, fs); \
1452 gen_ldcmp_fpr##bits (ctx, fp1, ft); \
1454 case 0: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _f, fp0, fp1, cc); break;\
1455 case 1: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _un, fp0, fp1, cc); break;\
1456 case 2: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _eq, fp0, fp1, cc); break;\
1457 case 3: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ueq, fp0, fp1, cc); break;\
1458 case 4: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _olt, fp0, fp1, cc); break;\
1459 case 5: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ult, fp0, fp1, cc); break;\
1460 case 6: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ole, fp0, fp1, cc); break;\
1461 case 7: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ule, fp0, fp1, cc); break;\
1462 case 8: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _sf, fp0, fp1, cc); break;\
1463 case 9: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ngle, fp0, fp1, cc); break;\
1464 case 10: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _seq, fp0, fp1, cc); break;\
1465 case 11: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ngl, fp0, fp1, cc); break;\
1466 case 12: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _lt, fp0, fp1, cc); break;\
1467 case 13: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _nge, fp0, fp1, cc); break;\
1468 case 14: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _le, fp0, fp1, cc); break;\
1469 case 15: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ngt, fp0, fp1, cc); break;\
1472 tcg_temp_free_i##bits (fp0); \
1473 tcg_temp_free_i##bits (fp1); \
1476 FOP_CONDS(, 0, d, FMT_D, 64)
1477 FOP_CONDS(abs, 1, d, FMT_D, 64)
1478 FOP_CONDS(, 0, s, FMT_S, 32)
1479 FOP_CONDS(abs, 1, s, FMT_S, 32)
1480 FOP_CONDS(, 0, ps, FMT_PS, 64)
1481 FOP_CONDS(abs, 1, ps, FMT_PS, 64)
1483 #undef gen_ldcmp_fpr32
1484 #undef gen_ldcmp_fpr64
1486 /* load/store instructions. */
1487 #ifdef CONFIG_USER_ONLY
1488 #define OP_LD_ATOMIC(insn,fname) \
1489 static inline void op_ld_##insn(TCGv ret, TCGv arg1, DisasContext *ctx) \
1491 TCGv t0 = tcg_temp_new(); \
1492 tcg_gen_mov_tl(t0, arg1); \
1493 tcg_gen_qemu_##fname(ret, arg1, ctx->mem_idx); \
1494 tcg_gen_st_tl(t0, cpu_env, offsetof(CPUMIPSState, lladdr)); \
1495 tcg_gen_st_tl(ret, cpu_env, offsetof(CPUMIPSState, llval)); \
1496 tcg_temp_free(t0); \
1499 #define OP_LD_ATOMIC(insn,fname) \
1500 static inline void op_ld_##insn(TCGv ret, TCGv arg1, DisasContext *ctx) \
1502 gen_helper_1e1i(insn, ret, arg1, ctx->mem_idx); \
1505 OP_LD_ATOMIC(ll,ld32s);
1506 #if defined(TARGET_MIPS64)
1507 OP_LD_ATOMIC(lld,ld64);
1511 #ifdef CONFIG_USER_ONLY
1512 #define OP_ST_ATOMIC(insn,fname,ldname,almask) \
1513 static inline void op_st_##insn(TCGv arg1, TCGv arg2, int rt, DisasContext *ctx) \
1515 TCGv t0 = tcg_temp_new(); \
1516 int l1 = gen_new_label(); \
1517 int l2 = gen_new_label(); \
1519 tcg_gen_andi_tl(t0, arg2, almask); \
1520 tcg_gen_brcondi_tl(TCG_COND_EQ, t0, 0, l1); \
1521 tcg_gen_st_tl(arg2, cpu_env, offsetof(CPUMIPSState, CP0_BadVAddr)); \
1522 generate_exception(ctx, EXCP_AdES); \
1523 gen_set_label(l1); \
1524 tcg_gen_ld_tl(t0, cpu_env, offsetof(CPUMIPSState, lladdr)); \
1525 tcg_gen_brcond_tl(TCG_COND_NE, arg2, t0, l2); \
1526 tcg_gen_movi_tl(t0, rt | ((almask << 3) & 0x20)); \
1527 tcg_gen_st_tl(t0, cpu_env, offsetof(CPUMIPSState, llreg)); \
1528 tcg_gen_st_tl(arg1, cpu_env, offsetof(CPUMIPSState, llnewval)); \
1529 gen_helper_0e0i(raise_exception, EXCP_SC); \
1530 gen_set_label(l2); \
1531 tcg_gen_movi_tl(t0, 0); \
1532 gen_store_gpr(t0, rt); \
1533 tcg_temp_free(t0); \
1536 #define OP_ST_ATOMIC(insn,fname,ldname,almask) \
1537 static inline void op_st_##insn(TCGv arg1, TCGv arg2, int rt, DisasContext *ctx) \
1539 TCGv t0 = tcg_temp_new(); \
1540 gen_helper_1e2i(insn, t0, arg1, arg2, ctx->mem_idx); \
1541 gen_store_gpr(t0, rt); \
1542 tcg_temp_free(t0); \
1545 OP_ST_ATOMIC(sc,st32,ld32s,0x3);
1546 #if defined(TARGET_MIPS64)
1547 OP_ST_ATOMIC(scd,st64,ld64,0x7);
1551 static void gen_base_offset_addr (DisasContext *ctx, TCGv addr,
1552 int base, int16_t offset)
1555 tcg_gen_movi_tl(addr, offset);
1556 } else if (offset == 0) {
1557 gen_load_gpr(addr, base);
1559 tcg_gen_movi_tl(addr, offset);
1560 gen_op_addr_add(ctx, addr, cpu_gpr[base], addr);
1564 static target_ulong pc_relative_pc (DisasContext *ctx)
1566 target_ulong pc = ctx->pc;
1568 if (ctx->hflags & MIPS_HFLAG_BMASK) {
1569 int branch_bytes = ctx->hflags & MIPS_HFLAG_BDS16 ? 2 : 4;
1574 pc &= ~(target_ulong)3;
1579 static void gen_ld (CPUMIPSState *env, DisasContext *ctx, uint32_t opc,
1580 int rt, int base, int16_t offset)
1582 const char *opn = "ld";
1585 if (rt == 0 && env->insn_flags & (INSN_LOONGSON2E | INSN_LOONGSON2F)) {
1586 /* Loongson CPU uses a load to zero register for prefetch.
1587 We emulate it as a NOP. On other CPU we must perform the
1588 actual memory access. */
1593 t0 = tcg_temp_new();
1594 gen_base_offset_addr(ctx, t0, base, offset);
1597 #if defined(TARGET_MIPS64)
1599 tcg_gen_qemu_ld32u(t0, t0, ctx->mem_idx);
1600 gen_store_gpr(t0, rt);
1604 tcg_gen_qemu_ld64(t0, t0, ctx->mem_idx);
1605 gen_store_gpr(t0, rt);
1609 save_cpu_state(ctx, 1);
1610 op_ld_lld(t0, t0, ctx);
1611 gen_store_gpr(t0, rt);
1615 t1 = tcg_temp_new();
1616 tcg_gen_andi_tl(t1, t0, 7);
1617 #ifndef TARGET_WORDS_BIGENDIAN
1618 tcg_gen_xori_tl(t1, t1, 7);
1620 tcg_gen_shli_tl(t1, t1, 3);
1621 tcg_gen_andi_tl(t0, t0, ~7);
1622 tcg_gen_qemu_ld64(t0, t0, ctx->mem_idx);
1623 tcg_gen_shl_tl(t0, t0, t1);
1624 tcg_gen_xori_tl(t1, t1, 63);
1625 t2 = tcg_const_tl(0x7fffffffffffffffull);
1626 tcg_gen_shr_tl(t2, t2, t1);
1627 gen_load_gpr(t1, rt);
1628 tcg_gen_and_tl(t1, t1, t2);
1630 tcg_gen_or_tl(t0, t0, t1);
1632 gen_store_gpr(t0, rt);
1636 t1 = tcg_temp_new();
1637 tcg_gen_andi_tl(t1, t0, 7);
1638 #ifdef TARGET_WORDS_BIGENDIAN
1639 tcg_gen_xori_tl(t1, t1, 7);
1641 tcg_gen_shli_tl(t1, t1, 3);
1642 tcg_gen_andi_tl(t0, t0, ~7);
1643 tcg_gen_qemu_ld64(t0, t0, ctx->mem_idx);
1644 tcg_gen_shr_tl(t0, t0, t1);
1645 tcg_gen_xori_tl(t1, t1, 63);
1646 t2 = tcg_const_tl(0xfffffffffffffffeull);
1647 tcg_gen_shl_tl(t2, t2, t1);
1648 gen_load_gpr(t1, rt);
1649 tcg_gen_and_tl(t1, t1, t2);
1651 tcg_gen_or_tl(t0, t0, t1);
1653 gen_store_gpr(t0, rt);
1657 t1 = tcg_const_tl(pc_relative_pc(ctx));
1658 gen_op_addr_add(ctx, t0, t0, t1);
1660 tcg_gen_qemu_ld64(t0, t0, ctx->mem_idx);
1661 gen_store_gpr(t0, rt);
1666 t1 = tcg_const_tl(pc_relative_pc(ctx));
1667 gen_op_addr_add(ctx, t0, t0, t1);
1669 tcg_gen_qemu_ld32s(t0, t0, ctx->mem_idx);
1670 gen_store_gpr(t0, rt);
1674 tcg_gen_qemu_ld32s(t0, t0, ctx->mem_idx);
1675 gen_store_gpr(t0, rt);
1679 tcg_gen_qemu_ld16s(t0, t0, ctx->mem_idx);
1680 gen_store_gpr(t0, rt);
1684 tcg_gen_qemu_ld16u(t0, t0, ctx->mem_idx);
1685 gen_store_gpr(t0, rt);
1689 tcg_gen_qemu_ld8s(t0, t0, ctx->mem_idx);
1690 gen_store_gpr(t0, rt);
1694 tcg_gen_qemu_ld8u(t0, t0, ctx->mem_idx);
1695 gen_store_gpr(t0, rt);
1699 t1 = tcg_temp_new();
1700 tcg_gen_andi_tl(t1, t0, 3);
1701 #ifndef TARGET_WORDS_BIGENDIAN
1702 tcg_gen_xori_tl(t1, t1, 3);
1704 tcg_gen_shli_tl(t1, t1, 3);
1705 tcg_gen_andi_tl(t0, t0, ~3);
1706 tcg_gen_qemu_ld32u(t0, t0, ctx->mem_idx);
1707 tcg_gen_shl_tl(t0, t0, t1);
1708 tcg_gen_xori_tl(t1, t1, 31);
1709 t2 = tcg_const_tl(0x7fffffffull);
1710 tcg_gen_shr_tl(t2, t2, t1);
1711 gen_load_gpr(t1, rt);
1712 tcg_gen_and_tl(t1, t1, t2);
1714 tcg_gen_or_tl(t0, t0, t1);
1716 tcg_gen_ext32s_tl(t0, t0);
1717 gen_store_gpr(t0, rt);
1721 t1 = tcg_temp_new();
1722 tcg_gen_andi_tl(t1, t0, 3);
1723 #ifdef TARGET_WORDS_BIGENDIAN
1724 tcg_gen_xori_tl(t1, t1, 3);
1726 tcg_gen_shli_tl(t1, t1, 3);
1727 tcg_gen_andi_tl(t0, t0, ~3);
1728 tcg_gen_qemu_ld32u(t0, t0, ctx->mem_idx);
1729 tcg_gen_shr_tl(t0, t0, t1);
1730 tcg_gen_xori_tl(t1, t1, 31);
1731 t2 = tcg_const_tl(0xfffffffeull);
1732 tcg_gen_shl_tl(t2, t2, t1);
1733 gen_load_gpr(t1, rt);
1734 tcg_gen_and_tl(t1, t1, t2);
1736 tcg_gen_or_tl(t0, t0, t1);
1738 gen_store_gpr(t0, rt);
1742 save_cpu_state(ctx, 1);
1743 op_ld_ll(t0, t0, ctx);
1744 gen_store_gpr(t0, rt);
1748 (void)opn; /* avoid a compiler warning */
1749 MIPS_DEBUG("%s %s, %d(%s)", opn, regnames[rt], offset, regnames[base]);
1754 static void gen_st (DisasContext *ctx, uint32_t opc, int rt,
1755 int base, int16_t offset)
1757 const char *opn = "st";
1758 TCGv t0 = tcg_temp_new();
1759 TCGv t1 = tcg_temp_new();
1761 gen_base_offset_addr(ctx, t0, base, offset);
1762 gen_load_gpr(t1, rt);
1764 #if defined(TARGET_MIPS64)
1766 tcg_gen_qemu_st64(t1, t0, ctx->mem_idx);
1770 save_cpu_state(ctx, 1);
1771 gen_helper_0e2i(sdl, t1, t0, ctx->mem_idx);
1775 save_cpu_state(ctx, 1);
1776 gen_helper_0e2i(sdr, t1, t0, ctx->mem_idx);
1781 tcg_gen_qemu_st32(t1, t0, ctx->mem_idx);
1785 tcg_gen_qemu_st16(t1, t0, ctx->mem_idx);
1789 tcg_gen_qemu_st8(t1, t0, ctx->mem_idx);
1793 save_cpu_state(ctx, 1);
1794 gen_helper_0e2i(swl, t1, t0, ctx->mem_idx);
1798 save_cpu_state(ctx, 1);
1799 gen_helper_0e2i(swr, t1, t0, ctx->mem_idx);
1803 (void)opn; /* avoid a compiler warning */
1804 MIPS_DEBUG("%s %s, %d(%s)", opn, regnames[rt], offset, regnames[base]);
1810 /* Store conditional */
1811 static void gen_st_cond (DisasContext *ctx, uint32_t opc, int rt,
1812 int base, int16_t offset)
1814 const char *opn = "st_cond";
1817 t0 = tcg_temp_local_new();
1819 gen_base_offset_addr(ctx, t0, base, offset);
1820 /* Don't do NOP if destination is zero: we must perform the actual
1823 t1 = tcg_temp_local_new();
1824 gen_load_gpr(t1, rt);
1826 #if defined(TARGET_MIPS64)
1828 save_cpu_state(ctx, 1);
1829 op_st_scd(t1, t0, rt, ctx);
1834 save_cpu_state(ctx, 1);
1835 op_st_sc(t1, t0, rt, ctx);
1839 (void)opn; /* avoid a compiler warning */
1840 MIPS_DEBUG("%s %s, %d(%s)", opn, regnames[rt], offset, regnames[base]);
1845 /* Load and store */
1846 static void gen_flt_ldst (DisasContext *ctx, uint32_t opc, int ft,
1847 int base, int16_t offset)
1849 const char *opn = "flt_ldst";
1850 TCGv t0 = tcg_temp_new();
1852 gen_base_offset_addr(ctx, t0, base, offset);
1853 /* Don't do NOP if destination is zero: we must perform the actual
1858 TCGv_i32 fp0 = tcg_temp_new_i32();
1860 tcg_gen_qemu_ld32s(t0, t0, ctx->mem_idx);
1861 tcg_gen_trunc_tl_i32(fp0, t0);
1862 gen_store_fpr32(fp0, ft);
1863 tcg_temp_free_i32(fp0);
1869 TCGv_i32 fp0 = tcg_temp_new_i32();
1870 TCGv t1 = tcg_temp_new();
1872 gen_load_fpr32(fp0, ft);
1873 tcg_gen_extu_i32_tl(t1, fp0);
1874 tcg_gen_qemu_st32(t1, t0, ctx->mem_idx);
1876 tcg_temp_free_i32(fp0);
1882 TCGv_i64 fp0 = tcg_temp_new_i64();
1884 tcg_gen_qemu_ld64(fp0, t0, ctx->mem_idx);
1885 gen_store_fpr64(ctx, fp0, ft);
1886 tcg_temp_free_i64(fp0);
1892 TCGv_i64 fp0 = tcg_temp_new_i64();
1894 gen_load_fpr64(ctx, fp0, ft);
1895 tcg_gen_qemu_st64(fp0, t0, ctx->mem_idx);
1896 tcg_temp_free_i64(fp0);
1902 generate_exception(ctx, EXCP_RI);
1905 (void)opn; /* avoid a compiler warning */
1906 MIPS_DEBUG("%s %s, %d(%s)", opn, fregnames[ft], offset, regnames[base]);
1911 static void gen_cop1_ldst(CPUMIPSState *env, DisasContext *ctx,
1912 uint32_t op, int rt, int rs, int16_t imm)
1914 if (env->CP0_Config1 & (1 << CP0C1_FP)) {
1915 check_cp1_enabled(ctx);
1916 gen_flt_ldst(ctx, op, rt, rs, imm);
1918 generate_exception_err(ctx, EXCP_CpU, 1);
1922 /* Arithmetic with immediate operand */
1923 static void gen_arith_imm (CPUMIPSState *env, DisasContext *ctx, uint32_t opc,
1924 int rt, int rs, int16_t imm)
1926 target_ulong uimm = (target_long)imm; /* Sign extend to 32/64 bits */
1927 const char *opn = "imm arith";
1929 if (rt == 0 && opc != OPC_ADDI && opc != OPC_DADDI) {
1930 /* If no destination, treat it as a NOP.
1931 For addi, we must generate the overflow exception when needed. */
1938 TCGv t0 = tcg_temp_local_new();
1939 TCGv t1 = tcg_temp_new();
1940 TCGv t2 = tcg_temp_new();
1941 int l1 = gen_new_label();
1943 gen_load_gpr(t1, rs);
1944 tcg_gen_addi_tl(t0, t1, uimm);
1945 tcg_gen_ext32s_tl(t0, t0);
1947 tcg_gen_xori_tl(t1, t1, ~uimm);
1948 tcg_gen_xori_tl(t2, t0, uimm);
1949 tcg_gen_and_tl(t1, t1, t2);
1951 tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
1953 /* operands of same sign, result different sign */
1954 generate_exception(ctx, EXCP_OVERFLOW);
1956 tcg_gen_ext32s_tl(t0, t0);
1957 gen_store_gpr(t0, rt);
1964 tcg_gen_addi_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
1965 tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]);
1967 tcg_gen_movi_tl(cpu_gpr[rt], uimm);
1971 #if defined(TARGET_MIPS64)
1974 TCGv t0 = tcg_temp_local_new();
1975 TCGv t1 = tcg_temp_new();
1976 TCGv t2 = tcg_temp_new();
1977 int l1 = gen_new_label();
1979 gen_load_gpr(t1, rs);
1980 tcg_gen_addi_tl(t0, t1, uimm);
1982 tcg_gen_xori_tl(t1, t1, ~uimm);
1983 tcg_gen_xori_tl(t2, t0, uimm);
1984 tcg_gen_and_tl(t1, t1, t2);
1986 tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
1988 /* operands of same sign, result different sign */
1989 generate_exception(ctx, EXCP_OVERFLOW);
1991 gen_store_gpr(t0, rt);
1998 tcg_gen_addi_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
2000 tcg_gen_movi_tl(cpu_gpr[rt], uimm);
2006 (void)opn; /* avoid a compiler warning */
2007 MIPS_DEBUG("%s %s, %s, " TARGET_FMT_lx, opn, regnames[rt], regnames[rs], uimm);
2010 /* Logic with immediate operand */
2011 static void gen_logic_imm(CPUMIPSState *env, DisasContext *ctx, uint32_t opc,
2012 int rt, int rs, int16_t imm)
2015 const char *opn = "imm logic";
2018 /* If no destination, treat it as a NOP. */
2022 uimm = (uint16_t)imm;
2025 if (likely(rs != 0))
2026 tcg_gen_andi_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
2028 tcg_gen_movi_tl(cpu_gpr[rt], 0);
2033 tcg_gen_ori_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
2035 tcg_gen_movi_tl(cpu_gpr[rt], uimm);
2039 if (likely(rs != 0))
2040 tcg_gen_xori_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
2042 tcg_gen_movi_tl(cpu_gpr[rt], uimm);
2046 tcg_gen_movi_tl(cpu_gpr[rt], imm << 16);
2050 (void)opn; /* avoid a compiler warning */
2051 MIPS_DEBUG("%s %s, %s, " TARGET_FMT_lx, opn, regnames[rt], regnames[rs], uimm);
2054 /* Set on less than with immediate operand */
2055 static void gen_slt_imm(CPUMIPSState *env, DisasContext *ctx, uint32_t opc,
2056 int rt, int rs, int16_t imm)
2058 target_ulong uimm = (target_long)imm; /* Sign extend to 32/64 bits */
2059 const char *opn = "imm arith";
2063 /* If no destination, treat it as a NOP. */
2067 t0 = tcg_temp_new();
2068 gen_load_gpr(t0, rs);
2071 tcg_gen_setcondi_tl(TCG_COND_LT, cpu_gpr[rt], t0, uimm);
2075 tcg_gen_setcondi_tl(TCG_COND_LTU, cpu_gpr[rt], t0, uimm);
2079 (void)opn; /* avoid a compiler warning */
2080 MIPS_DEBUG("%s %s, %s, " TARGET_FMT_lx, opn, regnames[rt], regnames[rs], uimm);
2084 /* Shifts with immediate operand */
2085 static void gen_shift_imm(CPUMIPSState *env, DisasContext *ctx, uint32_t opc,
2086 int rt, int rs, int16_t imm)
2088 target_ulong uimm = ((uint16_t)imm) & 0x1f;
2089 const char *opn = "imm shift";
2093 /* If no destination, treat it as a NOP. */
2098 t0 = tcg_temp_new();
2099 gen_load_gpr(t0, rs);
2102 tcg_gen_shli_tl(t0, t0, uimm);
2103 tcg_gen_ext32s_tl(cpu_gpr[rt], t0);
2107 tcg_gen_sari_tl(cpu_gpr[rt], t0, uimm);
2112 tcg_gen_ext32u_tl(t0, t0);
2113 tcg_gen_shri_tl(cpu_gpr[rt], t0, uimm);
2115 tcg_gen_ext32s_tl(cpu_gpr[rt], t0);
2121 TCGv_i32 t1 = tcg_temp_new_i32();
2123 tcg_gen_trunc_tl_i32(t1, t0);
2124 tcg_gen_rotri_i32(t1, t1, uimm);
2125 tcg_gen_ext_i32_tl(cpu_gpr[rt], t1);
2126 tcg_temp_free_i32(t1);
2128 tcg_gen_ext32s_tl(cpu_gpr[rt], t0);
2132 #if defined(TARGET_MIPS64)
2134 tcg_gen_shli_tl(cpu_gpr[rt], t0, uimm);
2138 tcg_gen_sari_tl(cpu_gpr[rt], t0, uimm);
2142 tcg_gen_shri_tl(cpu_gpr[rt], t0, uimm);
2147 tcg_gen_rotri_tl(cpu_gpr[rt], t0, uimm);
2149 tcg_gen_mov_tl(cpu_gpr[rt], t0);
2154 tcg_gen_shli_tl(cpu_gpr[rt], t0, uimm + 32);
2158 tcg_gen_sari_tl(cpu_gpr[rt], t0, uimm + 32);
2162 tcg_gen_shri_tl(cpu_gpr[rt], t0, uimm + 32);
2166 tcg_gen_rotri_tl(cpu_gpr[rt], t0, uimm + 32);
2171 (void)opn; /* avoid a compiler warning */
2172 MIPS_DEBUG("%s %s, %s, " TARGET_FMT_lx, opn, regnames[rt], regnames[rs], uimm);
2177 static void gen_arith (CPUMIPSState *env, DisasContext *ctx, uint32_t opc,
2178 int rd, int rs, int rt)
2180 const char *opn = "arith";
2182 if (rd == 0 && opc != OPC_ADD && opc != OPC_SUB
2183 && opc != OPC_DADD && opc != OPC_DSUB) {
2184 /* If no destination, treat it as a NOP.
2185 For add & sub, we must generate the overflow exception when needed. */
2193 TCGv t0 = tcg_temp_local_new();
2194 TCGv t1 = tcg_temp_new();
2195 TCGv t2 = tcg_temp_new();
2196 int l1 = gen_new_label();
2198 gen_load_gpr(t1, rs);
2199 gen_load_gpr(t2, rt);
2200 tcg_gen_add_tl(t0, t1, t2);
2201 tcg_gen_ext32s_tl(t0, t0);
2202 tcg_gen_xor_tl(t1, t1, t2);
2203 tcg_gen_xor_tl(t2, t0, t2);
2204 tcg_gen_andc_tl(t1, t2, t1);
2206 tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
2208 /* operands of same sign, result different sign */
2209 generate_exception(ctx, EXCP_OVERFLOW);
2211 gen_store_gpr(t0, rd);
2217 if (rs != 0 && rt != 0) {
2218 tcg_gen_add_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2219 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
2220 } else if (rs == 0 && rt != 0) {
2221 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rt]);
2222 } else if (rs != 0 && rt == 0) {
2223 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
2225 tcg_gen_movi_tl(cpu_gpr[rd], 0);
2231 TCGv t0 = tcg_temp_local_new();
2232 TCGv t1 = tcg_temp_new();
2233 TCGv t2 = tcg_temp_new();
2234 int l1 = gen_new_label();
2236 gen_load_gpr(t1, rs);
2237 gen_load_gpr(t2, rt);
2238 tcg_gen_sub_tl(t0, t1, t2);
2239 tcg_gen_ext32s_tl(t0, t0);
2240 tcg_gen_xor_tl(t2, t1, t2);
2241 tcg_gen_xor_tl(t1, t0, t1);
2242 tcg_gen_and_tl(t1, t1, t2);
2244 tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
2246 /* operands of different sign, first operand and result different sign */
2247 generate_exception(ctx, EXCP_OVERFLOW);
2249 gen_store_gpr(t0, rd);
2255 if (rs != 0 && rt != 0) {
2256 tcg_gen_sub_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2257 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
2258 } else if (rs == 0 && rt != 0) {
2259 tcg_gen_neg_tl(cpu_gpr[rd], cpu_gpr[rt]);
2260 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
2261 } else if (rs != 0 && rt == 0) {
2262 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
2264 tcg_gen_movi_tl(cpu_gpr[rd], 0);
2268 #if defined(TARGET_MIPS64)
2271 TCGv t0 = tcg_temp_local_new();
2272 TCGv t1 = tcg_temp_new();
2273 TCGv t2 = tcg_temp_new();
2274 int l1 = gen_new_label();
2276 gen_load_gpr(t1, rs);
2277 gen_load_gpr(t2, rt);
2278 tcg_gen_add_tl(t0, t1, t2);
2279 tcg_gen_xor_tl(t1, t1, t2);
2280 tcg_gen_xor_tl(t2, t0, t2);
2281 tcg_gen_andc_tl(t1, t2, t1);
2283 tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
2285 /* operands of same sign, result different sign */
2286 generate_exception(ctx, EXCP_OVERFLOW);
2288 gen_store_gpr(t0, rd);
2294 if (rs != 0 && rt != 0) {
2295 tcg_gen_add_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2296 } else if (rs == 0 && rt != 0) {
2297 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rt]);
2298 } else if (rs != 0 && rt == 0) {
2299 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
2301 tcg_gen_movi_tl(cpu_gpr[rd], 0);
2307 TCGv t0 = tcg_temp_local_new();
2308 TCGv t1 = tcg_temp_new();
2309 TCGv t2 = tcg_temp_new();
2310 int l1 = gen_new_label();
2312 gen_load_gpr(t1, rs);
2313 gen_load_gpr(t2, rt);
2314 tcg_gen_sub_tl(t0, t1, t2);
2315 tcg_gen_xor_tl(t2, t1, t2);
2316 tcg_gen_xor_tl(t1, t0, t1);
2317 tcg_gen_and_tl(t1, t1, t2);
2319 tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
2321 /* operands of different sign, first operand and result different sign */
2322 generate_exception(ctx, EXCP_OVERFLOW);
2324 gen_store_gpr(t0, rd);
2330 if (rs != 0 && rt != 0) {
2331 tcg_gen_sub_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2332 } else if (rs == 0 && rt != 0) {
2333 tcg_gen_neg_tl(cpu_gpr[rd], cpu_gpr[rt]);
2334 } else if (rs != 0 && rt == 0) {
2335 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
2337 tcg_gen_movi_tl(cpu_gpr[rd], 0);
2343 if (likely(rs != 0 && rt != 0)) {
2344 tcg_gen_mul_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2345 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
2347 tcg_gen_movi_tl(cpu_gpr[rd], 0);
2352 (void)opn; /* avoid a compiler warning */
2353 MIPS_DEBUG("%s %s, %s, %s", opn, regnames[rd], regnames[rs], regnames[rt]);
2356 /* Conditional move */
2357 static void gen_cond_move(CPUMIPSState *env, DisasContext *ctx, uint32_t opc,
2358 int rd, int rs, int rt)
2360 const char *opn = "cond move";
2364 /* If no destination, treat it as a NOP.
2365 For add & sub, we must generate the overflow exception when needed. */
2370 l1 = gen_new_label();
2373 if (likely(rt != 0))
2374 tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_gpr[rt], 0, l1);
2380 if (likely(rt != 0))
2381 tcg_gen_brcondi_tl(TCG_COND_NE, cpu_gpr[rt], 0, l1);
2386 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
2388 tcg_gen_movi_tl(cpu_gpr[rd], 0);
2391 (void)opn; /* avoid a compiler warning */
2392 MIPS_DEBUG("%s %s, %s, %s", opn, regnames[rd], regnames[rs], regnames[rt]);
2396 static void gen_logic(CPUMIPSState *env, DisasContext *ctx, uint32_t opc,
2397 int rd, int rs, int rt)
2399 const char *opn = "logic";
2402 /* If no destination, treat it as a NOP. */
2409 if (likely(rs != 0 && rt != 0)) {
2410 tcg_gen_and_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2412 tcg_gen_movi_tl(cpu_gpr[rd], 0);
2417 if (rs != 0 && rt != 0) {
2418 tcg_gen_nor_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2419 } else if (rs == 0 && rt != 0) {
2420 tcg_gen_not_tl(cpu_gpr[rd], cpu_gpr[rt]);
2421 } else if (rs != 0 && rt == 0) {
2422 tcg_gen_not_tl(cpu_gpr[rd], cpu_gpr[rs]);
2424 tcg_gen_movi_tl(cpu_gpr[rd], ~((target_ulong)0));
2429 if (likely(rs != 0 && rt != 0)) {
2430 tcg_gen_or_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2431 } else if (rs == 0 && rt != 0) {
2432 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rt]);
2433 } else if (rs != 0 && rt == 0) {
2434 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
2436 tcg_gen_movi_tl(cpu_gpr[rd], 0);
2441 if (likely(rs != 0 && rt != 0)) {
2442 tcg_gen_xor_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2443 } else if (rs == 0 && rt != 0) {
2444 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rt]);
2445 } else if (rs != 0 && rt == 0) {
2446 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
2448 tcg_gen_movi_tl(cpu_gpr[rd], 0);
2453 (void)opn; /* avoid a compiler warning */
2454 MIPS_DEBUG("%s %s, %s, %s", opn, regnames[rd], regnames[rs], regnames[rt]);
2457 /* Set on lower than */
2458 static void gen_slt(CPUMIPSState *env, DisasContext *ctx, uint32_t opc,
2459 int rd, int rs, int rt)
2461 const char *opn = "slt";
2465 /* If no destination, treat it as a NOP. */
2470 t0 = tcg_temp_new();
2471 t1 = tcg_temp_new();
2472 gen_load_gpr(t0, rs);
2473 gen_load_gpr(t1, rt);
2476 tcg_gen_setcond_tl(TCG_COND_LT, cpu_gpr[rd], t0, t1);
2480 tcg_gen_setcond_tl(TCG_COND_LTU, cpu_gpr[rd], t0, t1);
2484 (void)opn; /* avoid a compiler warning */
2485 MIPS_DEBUG("%s %s, %s, %s", opn, regnames[rd], regnames[rs], regnames[rt]);
2491 static void gen_shift (CPUMIPSState *env, DisasContext *ctx, uint32_t opc,
2492 int rd, int rs, int rt)
2494 const char *opn = "shifts";
2498 /* If no destination, treat it as a NOP.
2499 For add & sub, we must generate the overflow exception when needed. */
2504 t0 = tcg_temp_new();
2505 t1 = tcg_temp_new();
2506 gen_load_gpr(t0, rs);
2507 gen_load_gpr(t1, rt);
2510 tcg_gen_andi_tl(t0, t0, 0x1f);
2511 tcg_gen_shl_tl(t0, t1, t0);
2512 tcg_gen_ext32s_tl(cpu_gpr[rd], t0);
2516 tcg_gen_andi_tl(t0, t0, 0x1f);
2517 tcg_gen_sar_tl(cpu_gpr[rd], t1, t0);
2521 tcg_gen_ext32u_tl(t1, t1);
2522 tcg_gen_andi_tl(t0, t0, 0x1f);
2523 tcg_gen_shr_tl(t0, t1, t0);
2524 tcg_gen_ext32s_tl(cpu_gpr[rd], t0);
2529 TCGv_i32 t2 = tcg_temp_new_i32();
2530 TCGv_i32 t3 = tcg_temp_new_i32();
2532 tcg_gen_trunc_tl_i32(t2, t0);
2533 tcg_gen_trunc_tl_i32(t3, t1);
2534 tcg_gen_andi_i32(t2, t2, 0x1f);
2535 tcg_gen_rotr_i32(t2, t3, t2);
2536 tcg_gen_ext_i32_tl(cpu_gpr[rd], t2);
2537 tcg_temp_free_i32(t2);
2538 tcg_temp_free_i32(t3);
2542 #if defined(TARGET_MIPS64)
2544 tcg_gen_andi_tl(t0, t0, 0x3f);
2545 tcg_gen_shl_tl(cpu_gpr[rd], t1, t0);
2549 tcg_gen_andi_tl(t0, t0, 0x3f);
2550 tcg_gen_sar_tl(cpu_gpr[rd], t1, t0);
2554 tcg_gen_andi_tl(t0, t0, 0x3f);
2555 tcg_gen_shr_tl(cpu_gpr[rd], t1, t0);
2559 tcg_gen_andi_tl(t0, t0, 0x3f);
2560 tcg_gen_rotr_tl(cpu_gpr[rd], t1, t0);
2565 (void)opn; /* avoid a compiler warning */
2566 MIPS_DEBUG("%s %s, %s, %s", opn, regnames[rd], regnames[rs], regnames[rt]);
2571 /* Arithmetic on HI/LO registers */
2572 static void gen_HILO (DisasContext *ctx, uint32_t opc, int reg)
2574 const char *opn = "hilo";
2577 if (reg == 0 && (opc == OPC_MFHI || opc == OPC_MFLO)) {
2583 if (opc == OPC_MFHI || opc == OPC_MFLO) {
2584 acc = ((ctx->opcode) >> 21) & 0x03;
2586 acc = ((ctx->opcode) >> 11) & 0x03;
2595 #if defined(TARGET_MIPS64)
2597 tcg_gen_ext32s_tl(cpu_gpr[reg], cpu_HI[acc]);
2601 tcg_gen_mov_tl(cpu_gpr[reg], cpu_HI[acc]);
2606 #if defined(TARGET_MIPS64)
2608 tcg_gen_ext32s_tl(cpu_gpr[reg], cpu_LO[acc]);
2612 tcg_gen_mov_tl(cpu_gpr[reg], cpu_LO[acc]);
2618 #if defined(TARGET_MIPS64)
2620 tcg_gen_ext32s_tl(cpu_HI[acc], cpu_gpr[reg]);
2624 tcg_gen_mov_tl(cpu_HI[acc], cpu_gpr[reg]);
2627 tcg_gen_movi_tl(cpu_HI[acc], 0);
2633 #if defined(TARGET_MIPS64)
2635 tcg_gen_ext32s_tl(cpu_LO[acc], cpu_gpr[reg]);
2639 tcg_gen_mov_tl(cpu_LO[acc], cpu_gpr[reg]);
2642 tcg_gen_movi_tl(cpu_LO[acc], 0);
2647 (void)opn; /* avoid a compiler warning */
2648 MIPS_DEBUG("%s %s", opn, regnames[reg]);
2651 static void gen_muldiv (DisasContext *ctx, uint32_t opc,
2654 const char *opn = "mul/div";
2661 #if defined(TARGET_MIPS64)
2665 t0 = tcg_temp_local_new();
2666 t1 = tcg_temp_local_new();
2669 t0 = tcg_temp_new();
2670 t1 = tcg_temp_new();
2674 gen_load_gpr(t0, rs);
2675 gen_load_gpr(t1, rt);
2679 int l1 = gen_new_label();
2680 int l2 = gen_new_label();
2682 tcg_gen_ext32s_tl(t0, t0);
2683 tcg_gen_ext32s_tl(t1, t1);
2684 tcg_gen_brcondi_tl(TCG_COND_EQ, t1, 0, l1);
2685 tcg_gen_brcondi_tl(TCG_COND_NE, t0, INT_MIN, l2);
2686 tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1, l2);
2688 tcg_gen_mov_tl(cpu_LO[0], t0);
2689 tcg_gen_movi_tl(cpu_HI[0], 0);
2692 tcg_gen_div_tl(cpu_LO[0], t0, t1);
2693 tcg_gen_rem_tl(cpu_HI[0], t0, t1);
2694 tcg_gen_ext32s_tl(cpu_LO[0], cpu_LO[0]);
2695 tcg_gen_ext32s_tl(cpu_HI[0], cpu_HI[0]);
2702 int l1 = gen_new_label();
2704 tcg_gen_ext32u_tl(t0, t0);
2705 tcg_gen_ext32u_tl(t1, t1);
2706 tcg_gen_brcondi_tl(TCG_COND_EQ, t1, 0, l1);
2707 tcg_gen_divu_tl(cpu_LO[0], t0, t1);
2708 tcg_gen_remu_tl(cpu_HI[0], t0, t1);
2709 tcg_gen_ext32s_tl(cpu_LO[0], cpu_LO[0]);
2710 tcg_gen_ext32s_tl(cpu_HI[0], cpu_HI[0]);
2717 TCGv_i64 t2 = tcg_temp_new_i64();
2718 TCGv_i64 t3 = tcg_temp_new_i64();
2719 acc = ((ctx->opcode) >> 11) & 0x03;
2724 tcg_gen_ext_tl_i64(t2, t0);
2725 tcg_gen_ext_tl_i64(t3, t1);
2726 tcg_gen_mul_i64(t2, t2, t3);
2727 tcg_temp_free_i64(t3);
2728 tcg_gen_trunc_i64_tl(t0, t2);
2729 tcg_gen_shri_i64(t2, t2, 32);
2730 tcg_gen_trunc_i64_tl(t1, t2);
2731 tcg_temp_free_i64(t2);
2732 tcg_gen_ext32s_tl(cpu_LO[acc], t0);
2733 tcg_gen_ext32s_tl(cpu_HI[acc], t1);
2739 TCGv_i64 t2 = tcg_temp_new_i64();
2740 TCGv_i64 t3 = tcg_temp_new_i64();
2741 acc = ((ctx->opcode) >> 11) & 0x03;
2746 tcg_gen_ext32u_tl(t0, t0);
2747 tcg_gen_ext32u_tl(t1, t1);
2748 tcg_gen_extu_tl_i64(t2, t0);
2749 tcg_gen_extu_tl_i64(t3, t1);
2750 tcg_gen_mul_i64(t2, t2, t3);
2751 tcg_temp_free_i64(t3);
2752 tcg_gen_trunc_i64_tl(t0, t2);
2753 tcg_gen_shri_i64(t2, t2, 32);
2754 tcg_gen_trunc_i64_tl(t1, t2);
2755 tcg_temp_free_i64(t2);
2756 tcg_gen_ext32s_tl(cpu_LO[acc], t0);
2757 tcg_gen_ext32s_tl(cpu_HI[acc], t1);
2761 #if defined(TARGET_MIPS64)
2764 int l1 = gen_new_label();
2765 int l2 = gen_new_label();
2767 tcg_gen_brcondi_tl(TCG_COND_EQ, t1, 0, l1);
2768 tcg_gen_brcondi_tl(TCG_COND_NE, t0, -1LL << 63, l2);
2769 tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1LL, l2);
2770 tcg_gen_mov_tl(cpu_LO[0], t0);
2771 tcg_gen_movi_tl(cpu_HI[0], 0);
2774 tcg_gen_div_i64(cpu_LO[0], t0, t1);
2775 tcg_gen_rem_i64(cpu_HI[0], t0, t1);
2782 int l1 = gen_new_label();
2784 tcg_gen_brcondi_tl(TCG_COND_EQ, t1, 0, l1);
2785 tcg_gen_divu_i64(cpu_LO[0], t0, t1);
2786 tcg_gen_remu_i64(cpu_HI[0], t0, t1);
2792 gen_helper_dmult(cpu_env, t0, t1);
2796 gen_helper_dmultu(cpu_env, t0, t1);
2802 TCGv_i64 t2 = tcg_temp_new_i64();
2803 TCGv_i64 t3 = tcg_temp_new_i64();
2804 acc = ((ctx->opcode) >> 11) & 0x03;
2809 tcg_gen_ext_tl_i64(t2, t0);
2810 tcg_gen_ext_tl_i64(t3, t1);
2811 tcg_gen_mul_i64(t2, t2, t3);
2812 tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]);
2813 tcg_gen_add_i64(t2, t2, t3);
2814 tcg_temp_free_i64(t3);
2815 tcg_gen_trunc_i64_tl(t0, t2);
2816 tcg_gen_shri_i64(t2, t2, 32);
2817 tcg_gen_trunc_i64_tl(t1, t2);
2818 tcg_temp_free_i64(t2);
2819 tcg_gen_ext32s_tl(cpu_LO[acc], t0);
2820 tcg_gen_ext32s_tl(cpu_HI[acc], t1);
2826 TCGv_i64 t2 = tcg_temp_new_i64();
2827 TCGv_i64 t3 = tcg_temp_new_i64();
2828 acc = ((ctx->opcode) >> 11) & 0x03;
2833 tcg_gen_ext32u_tl(t0, t0);
2834 tcg_gen_ext32u_tl(t1, t1);
2835 tcg_gen_extu_tl_i64(t2, t0);
2836 tcg_gen_extu_tl_i64(t3, t1);
2837 tcg_gen_mul_i64(t2, t2, t3);
2838 tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]);
2839 tcg_gen_add_i64(t2, t2, t3);
2840 tcg_temp_free_i64(t3);
2841 tcg_gen_trunc_i64_tl(t0, t2);
2842 tcg_gen_shri_i64(t2, t2, 32);
2843 tcg_gen_trunc_i64_tl(t1, t2);
2844 tcg_temp_free_i64(t2);
2845 tcg_gen_ext32s_tl(cpu_LO[acc], t0);
2846 tcg_gen_ext32s_tl(cpu_HI[acc], t1);
2852 TCGv_i64 t2 = tcg_temp_new_i64();
2853 TCGv_i64 t3 = tcg_temp_new_i64();
2854 acc = ((ctx->opcode) >> 11) & 0x03;
2859 tcg_gen_ext_tl_i64(t2, t0);
2860 tcg_gen_ext_tl_i64(t3, t1);
2861 tcg_gen_mul_i64(t2, t2, t3);
2862 tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]);
2863 tcg_gen_sub_i64(t2, t3, t2);
2864 tcg_temp_free_i64(t3);
2865 tcg_gen_trunc_i64_tl(t0, t2);
2866 tcg_gen_shri_i64(t2, t2, 32);
2867 tcg_gen_trunc_i64_tl(t1, t2);
2868 tcg_temp_free_i64(t2);
2869 tcg_gen_ext32s_tl(cpu_LO[acc], t0);
2870 tcg_gen_ext32s_tl(cpu_HI[acc], t1);
2876 TCGv_i64 t2 = tcg_temp_new_i64();
2877 TCGv_i64 t3 = tcg_temp_new_i64();
2878 acc = ((ctx->opcode) >> 11) & 0x03;
2883 tcg_gen_ext32u_tl(t0, t0);
2884 tcg_gen_ext32u_tl(t1, t1);
2885 tcg_gen_extu_tl_i64(t2, t0);
2886 tcg_gen_extu_tl_i64(t3, t1);
2887 tcg_gen_mul_i64(t2, t2, t3);
2888 tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]);
2889 tcg_gen_sub_i64(t2, t3, t2);
2890 tcg_temp_free_i64(t3);
2891 tcg_gen_trunc_i64_tl(t0, t2);
2892 tcg_gen_shri_i64(t2, t2, 32);
2893 tcg_gen_trunc_i64_tl(t1, t2);
2894 tcg_temp_free_i64(t2);
2895 tcg_gen_ext32s_tl(cpu_LO[acc], t0);
2896 tcg_gen_ext32s_tl(cpu_HI[acc], t1);
2902 generate_exception(ctx, EXCP_RI);
2905 (void)opn; /* avoid a compiler warning */
2906 MIPS_DEBUG("%s %s %s", opn, regnames[rs], regnames[rt]);
2912 static void gen_mul_vr54xx (DisasContext *ctx, uint32_t opc,
2913 int rd, int rs, int rt)
2915 const char *opn = "mul vr54xx";
2916 TCGv t0 = tcg_temp_new();
2917 TCGv t1 = tcg_temp_new();
2919 gen_load_gpr(t0, rs);
2920 gen_load_gpr(t1, rt);
2923 case OPC_VR54XX_MULS:
2924 gen_helper_muls(t0, cpu_env, t0, t1);
2927 case OPC_VR54XX_MULSU:
2928 gen_helper_mulsu(t0, cpu_env, t0, t1);
2931 case OPC_VR54XX_MACC:
2932 gen_helper_macc(t0, cpu_env, t0, t1);
2935 case OPC_VR54XX_MACCU:
2936 gen_helper_maccu(t0, cpu_env, t0, t1);
2939 case OPC_VR54XX_MSAC:
2940 gen_helper_msac(t0, cpu_env, t0, t1);
2943 case OPC_VR54XX_MSACU:
2944 gen_helper_msacu(t0, cpu_env, t0, t1);
2947 case OPC_VR54XX_MULHI:
2948 gen_helper_mulhi(t0, cpu_env, t0, t1);
2951 case OPC_VR54XX_MULHIU:
2952 gen_helper_mulhiu(t0, cpu_env, t0, t1);
2955 case OPC_VR54XX_MULSHI:
2956 gen_helper_mulshi(t0, cpu_env, t0, t1);
2959 case OPC_VR54XX_MULSHIU:
2960 gen_helper_mulshiu(t0, cpu_env, t0, t1);
2963 case OPC_VR54XX_MACCHI:
2964 gen_helper_macchi(t0, cpu_env, t0, t1);
2967 case OPC_VR54XX_MACCHIU:
2968 gen_helper_macchiu(t0, cpu_env, t0, t1);
2971 case OPC_VR54XX_MSACHI:
2972 gen_helper_msachi(t0, cpu_env, t0, t1);
2975 case OPC_VR54XX_MSACHIU:
2976 gen_helper_msachiu(t0, cpu_env, t0, t1);
2980 MIPS_INVAL("mul vr54xx");
2981 generate_exception(ctx, EXCP_RI);
2984 gen_store_gpr(t0, rd);
2985 (void)opn; /* avoid a compiler warning */
2986 MIPS_DEBUG("%s %s, %s, %s", opn, regnames[rd], regnames[rs], regnames[rt]);
2993 static void gen_cl (DisasContext *ctx, uint32_t opc,
2996 const char *opn = "CLx";
3004 t0 = tcg_temp_new();
3005 gen_load_gpr(t0, rs);
3008 gen_helper_clo(cpu_gpr[rd], t0);
3012 gen_helper_clz(cpu_gpr[rd], t0);
3015 #if defined(TARGET_MIPS64)
3017 gen_helper_dclo(cpu_gpr[rd], t0);
3021 gen_helper_dclz(cpu_gpr[rd], t0);
3026 (void)opn; /* avoid a compiler warning */
3027 MIPS_DEBUG("%s %s, %s", opn, regnames[rd], regnames[rs]);
3031 /* Godson integer instructions */
3032 static void gen_loongson_integer(DisasContext *ctx, uint32_t opc,
3033 int rd, int rs, int rt)
3035 const char *opn = "loongson";
3047 case OPC_MULTU_G_2E:
3048 case OPC_MULTU_G_2F:
3049 #if defined(TARGET_MIPS64)
3050 case OPC_DMULT_G_2E:
3051 case OPC_DMULT_G_2F:
3052 case OPC_DMULTU_G_2E:
3053 case OPC_DMULTU_G_2F:
3055 t0 = tcg_temp_new();
3056 t1 = tcg_temp_new();
3059 t0 = tcg_temp_local_new();
3060 t1 = tcg_temp_local_new();
3064 gen_load_gpr(t0, rs);
3065 gen_load_gpr(t1, rt);
3070 tcg_gen_mul_tl(cpu_gpr[rd], t0, t1);
3071 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3074 case OPC_MULTU_G_2E:
3075 case OPC_MULTU_G_2F:
3076 tcg_gen_ext32u_tl(t0, t0);
3077 tcg_gen_ext32u_tl(t1, t1);
3078 tcg_gen_mul_tl(cpu_gpr[rd], t0, t1);
3079 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3085 int l1 = gen_new_label();
3086 int l2 = gen_new_label();
3087 int l3 = gen_new_label();
3088 tcg_gen_ext32s_tl(t0, t0);
3089 tcg_gen_ext32s_tl(t1, t1);
3090 tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
3091 tcg_gen_movi_tl(cpu_gpr[rd], 0);
3094 tcg_gen_brcondi_tl(TCG_COND_NE, t0, INT_MIN, l2);
3095 tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1, l2);
3096 tcg_gen_mov_tl(cpu_gpr[rd], t0);
3099 tcg_gen_div_tl(cpu_gpr[rd], t0, t1);
3100 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3108 int l1 = gen_new_label();
3109 int l2 = gen_new_label();
3110 tcg_gen_ext32u_tl(t0, t0);
3111 tcg_gen_ext32u_tl(t1, t1);
3112 tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
3113 tcg_gen_movi_tl(cpu_gpr[rd], 0);
3116 tcg_gen_divu_tl(cpu_gpr[rd], t0, t1);
3117 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3125 int l1 = gen_new_label();
3126 int l2 = gen_new_label();
3127 int l3 = gen_new_label();
3128 tcg_gen_ext32u_tl(t0, t0);
3129 tcg_gen_ext32u_tl(t1, t1);
3130 tcg_gen_brcondi_tl(TCG_COND_EQ, t1, 0, l1);
3131 tcg_gen_brcondi_tl(TCG_COND_NE, t0, INT_MIN, l2);
3132 tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1, l2);
3134 tcg_gen_movi_tl(cpu_gpr[rd], 0);
3137 tcg_gen_rem_tl(cpu_gpr[rd], t0, t1);
3138 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3146 int l1 = gen_new_label();
3147 int l2 = gen_new_label();
3148 tcg_gen_ext32u_tl(t0, t0);
3149 tcg_gen_ext32u_tl(t1, t1);
3150 tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
3151 tcg_gen_movi_tl(cpu_gpr[rd], 0);
3154 tcg_gen_remu_tl(cpu_gpr[rd], t0, t1);
3155 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3160 #if defined(TARGET_MIPS64)
3161 case OPC_DMULT_G_2E:
3162 case OPC_DMULT_G_2F:
3163 tcg_gen_mul_tl(cpu_gpr[rd], t0, t1);
3166 case OPC_DMULTU_G_2E:
3167 case OPC_DMULTU_G_2F:
3168 tcg_gen_mul_tl(cpu_gpr[rd], t0, t1);
3174 int l1 = gen_new_label();
3175 int l2 = gen_new_label();
3176 int l3 = gen_new_label();
3177 tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
3178 tcg_gen_movi_tl(cpu_gpr[rd], 0);
3181 tcg_gen_brcondi_tl(TCG_COND_NE, t0, -1LL << 63, l2);
3182 tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1LL, l2);
3183 tcg_gen_mov_tl(cpu_gpr[rd], t0);
3186 tcg_gen_div_tl(cpu_gpr[rd], t0, t1);
3191 case OPC_DDIVU_G_2E:
3192 case OPC_DDIVU_G_2F:
3194 int l1 = gen_new_label();
3195 int l2 = gen_new_label();
3196 tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
3197 tcg_gen_movi_tl(cpu_gpr[rd], 0);
3200 tcg_gen_divu_tl(cpu_gpr[rd], t0, t1);
3208 int l1 = gen_new_label();
3209 int l2 = gen_new_label();
3210 int l3 = gen_new_label();
3211 tcg_gen_brcondi_tl(TCG_COND_EQ, t1, 0, l1);
3212 tcg_gen_brcondi_tl(TCG_COND_NE, t0, -1LL << 63, l2);
3213 tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1LL, l2);
3215 tcg_gen_movi_tl(cpu_gpr[rd], 0);
3218 tcg_gen_rem_tl(cpu_gpr[rd], t0, t1);
3223 case OPC_DMODU_G_2E:
3224 case OPC_DMODU_G_2F:
3226 int l1 = gen_new_label();
3227 int l2 = gen_new_label();
3228 tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
3229 tcg_gen_movi_tl(cpu_gpr[rd], 0);
3232 tcg_gen_remu_tl(cpu_gpr[rd], t0, t1);
3240 (void)opn; /* avoid a compiler warning */
3241 MIPS_DEBUG("%s %s, %s", opn, regnames[rd], regnames[rs]);
3246 /* Loongson multimedia instructions */
3247 static void gen_loongson_multimedia(DisasContext *ctx, int rd, int rs, int rt)
3249 const char *opn = "loongson_cp2";
3250 uint32_t opc, shift_max;
3253 opc = MASK_LMI(ctx->opcode);
3259 t0 = tcg_temp_local_new_i64();
3260 t1 = tcg_temp_local_new_i64();
3263 t0 = tcg_temp_new_i64();
3264 t1 = tcg_temp_new_i64();
3268 gen_load_fpr64(ctx, t0, rs);
3269 gen_load_fpr64(ctx, t1, rt);
3271 #define LMI_HELPER(UP, LO) \
3272 case OPC_##UP: gen_helper_##LO(t0, t0, t1); opn = #LO; break
3273 #define LMI_HELPER_1(UP, LO) \
3274 case OPC_##UP: gen_helper_##LO(t0, t0); opn = #LO; break
3275 #define LMI_DIRECT(UP, LO, OP) \
3276 case OPC_##UP: tcg_gen_##OP##_i64(t0, t0, t1); opn = #LO; break
3279 LMI_HELPER(PADDSH, paddsh);
3280 LMI_HELPER(PADDUSH, paddush);
3281 LMI_HELPER(PADDH, paddh);
3282 LMI_HELPER(PADDW, paddw);
3283 LMI_HELPER(PADDSB, paddsb);
3284 LMI_HELPER(PADDUSB, paddusb);
3285 LMI_HELPER(PADDB, paddb);
3287 LMI_HELPER(PSUBSH, psubsh);
3288 LMI_HELPER(PSUBUSH, psubush);
3289 LMI_HELPER(PSUBH, psubh);
3290 LMI_HELPER(PSUBW, psubw);
3291 LMI_HELPER(PSUBSB, psubsb);
3292 LMI_HELPER(PSUBUSB, psubusb);
3293 LMI_HELPER(PSUBB, psubb);
3295 LMI_HELPER(PSHUFH, pshufh);
3296 LMI_HELPER(PACKSSWH, packsswh);
3297 LMI_HELPER(PACKSSHB, packsshb);
3298 LMI_HELPER(PACKUSHB, packushb);
3300 LMI_HELPER(PUNPCKLHW, punpcklhw);
3301 LMI_HELPER(PUNPCKHHW, punpckhhw);
3302 LMI_HELPER(PUNPCKLBH, punpcklbh);
3303 LMI_HELPER(PUNPCKHBH, punpckhbh);
3304 LMI_HELPER(PUNPCKLWD, punpcklwd);
3305 LMI_HELPER(PUNPCKHWD, punpckhwd);
3307 LMI_HELPER(PAVGH, pavgh);
3308 LMI_HELPER(PAVGB, pavgb);
3309 LMI_HELPER(PMAXSH, pmaxsh);
3310 LMI_HELPER(PMINSH, pminsh);
3311 LMI_HELPER(PMAXUB, pmaxub);
3312 LMI_HELPER(PMINUB, pminub);
3314 LMI_HELPER(PCMPEQW, pcmpeqw);
3315 LMI_HELPER(PCMPGTW, pcmpgtw);
3316 LMI_HELPER(PCMPEQH, pcmpeqh);
3317 LMI_HELPER(PCMPGTH, pcmpgth);
3318 LMI_HELPER(PCMPEQB, pcmpeqb);
3319 LMI_HELPER(PCMPGTB, pcmpgtb);
3321 LMI_HELPER(PSLLW, psllw);
3322 LMI_HELPER(PSLLH, psllh);
3323 LMI_HELPER(PSRLW, psrlw);
3324 LMI_HELPER(PSRLH, psrlh);
3325 LMI_HELPER(PSRAW, psraw);
3326 LMI_HELPER(PSRAH, psrah);
3328 LMI_HELPER(PMULLH, pmullh);
3329 LMI_HELPER(PMULHH, pmulhh);
3330 LMI_HELPER(PMULHUH, pmulhuh);
3331 LMI_HELPER(PMADDHW, pmaddhw);
3333 LMI_HELPER(PASUBUB, pasubub);
3334 LMI_HELPER_1(BIADD, biadd);
3335 LMI_HELPER_1(PMOVMSKB, pmovmskb);
3337 LMI_DIRECT(PADDD, paddd, add);
3338 LMI_DIRECT(PSUBD, psubd, sub);
3339 LMI_DIRECT(XOR_CP2, xor, xor);
3340 LMI_DIRECT(NOR_CP2, nor, nor);
3341 LMI_DIRECT(AND_CP2, and, and);
3342 LMI_DIRECT(PANDN, pandn, andc);
3343 LMI_DIRECT(OR, or, or);
3346 tcg_gen_deposit_i64(t0, t0, t1, 0, 16);
3350 tcg_gen_deposit_i64(t0, t0, t1, 16, 16);
3354 tcg_gen_deposit_i64(t0, t0, t1, 32, 16);
3358 tcg_gen_deposit_i64(t0, t0, t1, 48, 16);
3363 tcg_gen_andi_i64(t1, t1, 3);
3364 tcg_gen_shli_i64(t1, t1, 4);
3365 tcg_gen_shr_i64(t0, t0, t1);
3366 tcg_gen_ext16u_i64(t0, t0);
3371 tcg_gen_add_i64(t0, t0, t1);
3372 tcg_gen_ext32s_i64(t0, t0);
3376 tcg_gen_sub_i64(t0, t0, t1);
3377 tcg_gen_ext32s_i64(t0, t0);
3406 /* Make sure shift count isn't TCG undefined behaviour. */
3407 tcg_gen_andi_i64(t1, t1, shift_max - 1);
3412 tcg_gen_shl_i64(t0, t0, t1);
3416 /* Since SRA is UndefinedResult without sign-extended inputs,
3417 we can treat SRA and DSRA the same. */
3418 tcg_gen_sar_i64(t0, t0, t1);
3421 /* We want to shift in zeros for SRL; zero-extend first. */
3422 tcg_gen_ext32u_i64(t0, t0);
3425 tcg_gen_shr_i64(t0, t0, t1);
3429 if (shift_max == 32) {
3430 tcg_gen_ext32s_i64(t0, t0);
3433 /* Shifts larger than MAX produce zero. */
3434 tcg_gen_setcondi_i64(TCG_COND_LTU, t1, t1, shift_max);
3435 tcg_gen_neg_i64(t1, t1);
3436 tcg_gen_and_i64(t0, t0, t1);
3442 TCGv_i64 t2 = tcg_temp_new_i64();
3443 int lab = gen_new_label();
3445 tcg_gen_mov_i64(t2, t0);
3446 tcg_gen_add_i64(t0, t1, t2);
3447 if (opc == OPC_ADD_CP2) {
3448 tcg_gen_ext32s_i64(t0, t0);
3450 tcg_gen_xor_i64(t1, t1, t2);
3451 tcg_gen_xor_i64(t2, t2, t0);
3452 tcg_gen_andc_i64(t1, t2, t1);
3453 tcg_temp_free_i64(t2);
3454 tcg_gen_brcondi_i64(TCG_COND_GE, t1, 0, lab);
3455 generate_exception(ctx, EXCP_OVERFLOW);
3458 opn = (opc == OPC_ADD_CP2 ? "add" : "dadd");
3465 TCGv_i64 t2 = tcg_temp_new_i64();
3466 int lab = gen_new_label();
3468 tcg_gen_mov_i64(t2, t0);
3469 tcg_gen_sub_i64(t0, t1, t2);
3470 if (opc == OPC_SUB_CP2) {
3471 tcg_gen_ext32s_i64(t0, t0);
3473 tcg_gen_xor_i64(t1, t1, t2);
3474 tcg_gen_xor_i64(t2, t2, t0);
3475 tcg_gen_and_i64(t1, t1, t2);
3476 tcg_temp_free_i64(t2);
3477 tcg_gen_brcondi_i64(TCG_COND_GE, t1, 0, lab);
3478 generate_exception(ctx, EXCP_OVERFLOW);
3481 opn = (opc == OPC_SUB_CP2 ? "sub" : "dsub");
3486 tcg_gen_ext32u_i64(t0, t0);
3487 tcg_gen_ext32u_i64(t1, t1);
3488 tcg_gen_mul_i64(t0, t0, t1);
3498 /* ??? Document is unclear: Set FCC[CC]. Does that mean the
3499 FD field is the CC field? */
3502 generate_exception(ctx, EXCP_RI);
3509 gen_store_fpr64(ctx, t0, rd);
3511 (void)opn; /* avoid a compiler warning */
3512 MIPS_DEBUG("%s %s, %s, %s", opn,
3513 fregnames[rd], fregnames[rs], fregnames[rt]);
3514 tcg_temp_free_i64(t0);
3515 tcg_temp_free_i64(t1);
3519 static void gen_trap (DisasContext *ctx, uint32_t opc,
3520 int rs, int rt, int16_t imm)
3523 TCGv t0 = tcg_temp_new();
3524 TCGv t1 = tcg_temp_new();
3527 /* Load needed operands */
3535 /* Compare two registers */
3537 gen_load_gpr(t0, rs);
3538 gen_load_gpr(t1, rt);
3548 /* Compare register to immediate */
3549 if (rs != 0 || imm != 0) {
3550 gen_load_gpr(t0, rs);
3551 tcg_gen_movi_tl(t1, (int32_t)imm);
3558 case OPC_TEQ: /* rs == rs */
3559 case OPC_TEQI: /* r0 == 0 */
3560 case OPC_TGE: /* rs >= rs */
3561 case OPC_TGEI: /* r0 >= 0 */
3562 case OPC_TGEU: /* rs >= rs unsigned */
3563 case OPC_TGEIU: /* r0 >= 0 unsigned */
3565 generate_exception(ctx, EXCP_TRAP);
3567 case OPC_TLT: /* rs < rs */
3568 case OPC_TLTI: /* r0 < 0 */
3569 case OPC_TLTU: /* rs < rs unsigned */
3570 case OPC_TLTIU: /* r0 < 0 unsigned */
3571 case OPC_TNE: /* rs != rs */
3572 case OPC_TNEI: /* r0 != 0 */
3573 /* Never trap: treat as NOP. */
3577 int l1 = gen_new_label();
3582 tcg_gen_brcond_tl(TCG_COND_NE, t0, t1, l1);
3586 tcg_gen_brcond_tl(TCG_COND_LT, t0, t1, l1);
3590 tcg_gen_brcond_tl(TCG_COND_LTU, t0, t1, l1);
3594 tcg_gen_brcond_tl(TCG_COND_GE, t0, t1, l1);
3598 tcg_gen_brcond_tl(TCG_COND_GEU, t0, t1, l1);
3602 tcg_gen_brcond_tl(TCG_COND_EQ, t0, t1, l1);
3605 generate_exception(ctx, EXCP_TRAP);
3612 static inline void gen_goto_tb(DisasContext *ctx, int n, target_ulong dest)
3614 TranslationBlock *tb;
3616 if ((tb->pc & TARGET_PAGE_MASK) == (dest & TARGET_PAGE_MASK) &&
3617 likely(!ctx->singlestep_enabled)) {
3620 tcg_gen_exit_tb((tcg_target_long)tb + n);
3623 if (ctx->singlestep_enabled) {
3624 save_cpu_state(ctx, 0);
3625 gen_helper_0e0i(raise_exception, EXCP_DEBUG);
3631 /* Branches (before delay slot) */
3632 static void gen_compute_branch (DisasContext *ctx, uint32_t opc,
3634 int rs, int rt, int32_t offset)
3636 target_ulong btgt = -1;
3638 int bcond_compute = 0;
3639 TCGv t0 = tcg_temp_new();
3640 TCGv t1 = tcg_temp_new();
3642 if (ctx->hflags & MIPS_HFLAG_BMASK) {
3643 #ifdef MIPS_DEBUG_DISAS
3644 LOG_DISAS("Branch in delay slot at PC 0x" TARGET_FMT_lx "\n", ctx->pc);
3646 generate_exception(ctx, EXCP_RI);
3650 /* Load needed operands */
3656 /* Compare two registers */
3658 gen_load_gpr(t0, rs);
3659 gen_load_gpr(t1, rt);
3662 btgt = ctx->pc + insn_bytes + offset;
3678 /* Compare to zero */
3680 gen_load_gpr(t0, rs);
3683 btgt = ctx->pc + insn_bytes + offset;
3686 #if defined(TARGET_MIPS64)
3688 tcg_gen_andi_tl(t0, cpu_dspctrl, 0x7F);
3690 tcg_gen_andi_tl(t0, cpu_dspctrl, 0x3F);
3693 btgt = ctx->pc + insn_bytes + offset;
3700 /* Jump to immediate */
3701 btgt = ((ctx->pc + insn_bytes) & (int32_t)0xF0000000) | (uint32_t)offset;
3707 /* Jump to register */
3708 if (offset != 0 && offset != 16) {
3709 /* Hint = 0 is JR/JALR, hint 16 is JR.HB/JALR.HB, the
3710 others are reserved. */
3711 MIPS_INVAL("jump hint");
3712 generate_exception(ctx, EXCP_RI);
3715 gen_load_gpr(btarget, rs);
3718 MIPS_INVAL("branch/jump");
3719 generate_exception(ctx, EXCP_RI);
3722 if (bcond_compute == 0) {
3723 /* No condition to be computed */
3725 case OPC_BEQ: /* rx == rx */
3726 case OPC_BEQL: /* rx == rx likely */
3727 case OPC_BGEZ: /* 0 >= 0 */
3728 case OPC_BGEZL: /* 0 >= 0 likely */
3729 case OPC_BLEZ: /* 0 <= 0 */
3730 case OPC_BLEZL: /* 0 <= 0 likely */
3732 ctx->hflags |= MIPS_HFLAG_B;
3733 MIPS_DEBUG("balways");
3736 case OPC_BGEZAL: /* 0 >= 0 */
3737 case OPC_BGEZALL: /* 0 >= 0 likely */
3738 ctx->hflags |= (opc == OPC_BGEZALS
3740 : MIPS_HFLAG_BDS32);
3741 /* Always take and link */
3743 ctx->hflags |= MIPS_HFLAG_B;
3744 MIPS_DEBUG("balways and link");
3746 case OPC_BNE: /* rx != rx */
3747 case OPC_BGTZ: /* 0 > 0 */
3748 case OPC_BLTZ: /* 0 < 0 */
3750 MIPS_DEBUG("bnever (NOP)");
3753 case OPC_BLTZAL: /* 0 < 0 */
3754 ctx->hflags |= (opc == OPC_BLTZALS
3756 : MIPS_HFLAG_BDS32);
3757 /* Handle as an unconditional branch to get correct delay
3760 btgt = ctx->pc + (opc == OPC_BLTZALS ? 6 : 8);
3761 ctx->hflags |= MIPS_HFLAG_B;
3762 MIPS_DEBUG("bnever and link");
3764 case OPC_BLTZALL: /* 0 < 0 likely */
3765 tcg_gen_movi_tl(cpu_gpr[31], ctx->pc + 8);
3766 /* Skip the instruction in the delay slot */
3767 MIPS_DEBUG("bnever, link and skip");
3770 case OPC_BNEL: /* rx != rx likely */
3771 case OPC_BGTZL: /* 0 > 0 likely */
3772 case OPC_BLTZL: /* 0 < 0 likely */
3773 /* Skip the instruction in the delay slot */
3774 MIPS_DEBUG("bnever and skip");
3778 ctx->hflags |= MIPS_HFLAG_B;
3779 MIPS_DEBUG("j " TARGET_FMT_lx, btgt);
3783 ctx->hflags |= MIPS_HFLAG_BX;
3788 ctx->hflags |= MIPS_HFLAG_B;
3789 ctx->hflags |= ((opc == OPC_JALS || opc == OPC_JALXS)
3791 : MIPS_HFLAG_BDS32);
3792 MIPS_DEBUG("jal " TARGET_FMT_lx, btgt);
3795 ctx->hflags |= MIPS_HFLAG_BR;
3796 if (insn_bytes == 4)
3797 ctx->hflags |= MIPS_HFLAG_BDS32;
3798 MIPS_DEBUG("jr %s", regnames[rs]);
3804 ctx->hflags |= MIPS_HFLAG_BR;
3805 ctx->hflags |= (opc == OPC_JALRS
3807 : MIPS_HFLAG_BDS32);
3808 MIPS_DEBUG("jalr %s, %s", regnames[rt], regnames[rs]);
3811 MIPS_INVAL("branch/jump");
3812 generate_exception(ctx, EXCP_RI);
3818 tcg_gen_setcond_tl(TCG_COND_EQ, bcond, t0, t1);
3819 MIPS_DEBUG("beq %s, %s, " TARGET_FMT_lx,
3820 regnames[rs], regnames[rt], btgt);
3823 tcg_gen_setcond_tl(TCG_COND_EQ, bcond, t0, t1);
3824 MIPS_DEBUG("beql %s, %s, " TARGET_FMT_lx,
3825 regnames[rs], regnames[rt], btgt);
3828 tcg_gen_setcond_tl(TCG_COND_NE, bcond, t0, t1);
3829 MIPS_DEBUG("bne %s, %s, " TARGET_FMT_lx,
3830 regnames[rs], regnames[rt], btgt);
3833 tcg_gen_setcond_tl(TCG_COND_NE, bcond, t0, t1);
3834 MIPS_DEBUG("bnel %s, %s, " TARGET_FMT_lx,
3835 regnames[rs], regnames[rt], btgt);
3838 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 0);
3839 MIPS_DEBUG("bgez %s, " TARGET_FMT_lx, regnames[rs], btgt);
3842 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 0);
3843 MIPS_DEBUG("bgezl %s, " TARGET_FMT_lx, regnames[rs], btgt);
3847 ctx->hflags |= (opc == OPC_BGEZALS
3849 : MIPS_HFLAG_BDS32);
3850 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 0);
3851 MIPS_DEBUG("bgezal %s, " TARGET_FMT_lx, regnames[rs], btgt);
3855 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 0);
3857 MIPS_DEBUG("bgezall %s, " TARGET_FMT_lx, regnames[rs], btgt);
3860 tcg_gen_setcondi_tl(TCG_COND_GT, bcond, t0, 0);
3861 MIPS_DEBUG("bgtz %s, " TARGET_FMT_lx, regnames[rs], btgt);
3864 tcg_gen_setcondi_tl(TCG_COND_GT, bcond, t0, 0);
3865 MIPS_DEBUG("bgtzl %s, " TARGET_FMT_lx, regnames[rs], btgt);
3868 tcg_gen_setcondi_tl(TCG_COND_LE, bcond, t0, 0);
3869 MIPS_DEBUG("blez %s, " TARGET_FMT_lx, regnames[rs], btgt);
3872 tcg_gen_setcondi_tl(TCG_COND_LE, bcond, t0, 0);
3873 MIPS_DEBUG("blezl %s, " TARGET_FMT_lx, regnames[rs], btgt);
3876 tcg_gen_setcondi_tl(TCG_COND_LT, bcond, t0, 0);
3877 MIPS_DEBUG("bltz %s, " TARGET_FMT_lx, regnames[rs], btgt);
3880 tcg_gen_setcondi_tl(TCG_COND_LT, bcond, t0, 0);
3881 MIPS_DEBUG("bltzl %s, " TARGET_FMT_lx, regnames[rs], btgt);
3884 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 32);
3885 MIPS_DEBUG("bposge32 " TARGET_FMT_lx, btgt);
3887 #if defined(TARGET_MIPS64)
3889 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 64);
3890 MIPS_DEBUG("bposge64 " TARGET_FMT_lx, btgt);
3895 ctx->hflags |= (opc == OPC_BLTZALS
3897 : MIPS_HFLAG_BDS32);
3898 tcg_gen_setcondi_tl(TCG_COND_LT, bcond, t0, 0);
3900 MIPS_DEBUG("bltzal %s, " TARGET_FMT_lx, regnames[rs], btgt);
3902 ctx->hflags |= MIPS_HFLAG_BC;
3905 tcg_gen_setcondi_tl(TCG_COND_LT, bcond, t0, 0);
3907 MIPS_DEBUG("bltzall %s, " TARGET_FMT_lx, regnames[rs], btgt);
3909 ctx->hflags |= MIPS_HFLAG_BL;
3912 MIPS_INVAL("conditional branch/jump");
3913 generate_exception(ctx, EXCP_RI);
3917 MIPS_DEBUG("enter ds: link %d cond %02x target " TARGET_FMT_lx,
3918 blink, ctx->hflags, btgt);
3920 ctx->btarget = btgt;
3922 int post_delay = insn_bytes;
3923 int lowbit = !!(ctx->hflags & MIPS_HFLAG_M16);
3925 if (opc != OPC_JALRC)
3926 post_delay += ((ctx->hflags & MIPS_HFLAG_BDS16) ? 2 : 4);
3928 tcg_gen_movi_tl(cpu_gpr[blink], ctx->pc + post_delay + lowbit);
3932 if (insn_bytes == 2)
3933 ctx->hflags |= MIPS_HFLAG_B16;
3938 /* special3 bitfield operations */
3939 static void gen_bitops (DisasContext *ctx, uint32_t opc, int rt,
3940 int rs, int lsb, int msb)
3942 TCGv t0 = tcg_temp_new();
3943 TCGv t1 = tcg_temp_new();
3946 gen_load_gpr(t1, rs);
3951 tcg_gen_shri_tl(t0, t1, lsb);
3953 tcg_gen_andi_tl(t0, t0, (1 << (msb + 1)) - 1);
3955 tcg_gen_ext32s_tl(t0, t0);
3958 #if defined(TARGET_MIPS64)
3960 tcg_gen_shri_tl(t0, t1, lsb);
3962 tcg_gen_andi_tl(t0, t0, (1ULL << (msb + 1 + 32)) - 1);
3966 tcg_gen_shri_tl(t0, t1, lsb + 32);
3967 tcg_gen_andi_tl(t0, t0, (1ULL << (msb + 1)) - 1);
3970 tcg_gen_shri_tl(t0, t1, lsb);
3971 tcg_gen_andi_tl(t0, t0, (1ULL << (msb + 1)) - 1);
3977 mask = ((msb - lsb + 1 < 32) ? ((1 << (msb - lsb + 1)) - 1) : ~0) << lsb;
3978 gen_load_gpr(t0, rt);
3979 tcg_gen_andi_tl(t0, t0, ~mask);
3980 tcg_gen_shli_tl(t1, t1, lsb);
3981 tcg_gen_andi_tl(t1, t1, mask);
3982 tcg_gen_or_tl(t0, t0, t1);
3983 tcg_gen_ext32s_tl(t0, t0);
3985 #if defined(TARGET_MIPS64)
3989 mask = ((msb - lsb + 1 + 32 < 64) ? ((1ULL << (msb - lsb + 1 + 32)) - 1) : ~0ULL) << lsb;
3990 gen_load_gpr(t0, rt);
3991 tcg_gen_andi_tl(t0, t0, ~mask);
3992 tcg_gen_shli_tl(t1, t1, lsb);
3993 tcg_gen_andi_tl(t1, t1, mask);
3994 tcg_gen_or_tl(t0, t0, t1);
3999 mask = ((1ULL << (msb - lsb + 1)) - 1) << (lsb + 32);
4000 gen_load_gpr(t0, rt);
4001 tcg_gen_andi_tl(t0, t0, ~mask);
4002 tcg_gen_shli_tl(t1, t1, lsb + 32);
4003 tcg_gen_andi_tl(t1, t1, mask);
4004 tcg_gen_or_tl(t0, t0, t1);
4009 gen_load_gpr(t0, rt);
4010 mask = ((1ULL << (msb - lsb + 1)) - 1) << lsb;
4011 gen_load_gpr(t0, rt);
4012 tcg_gen_andi_tl(t0, t0, ~mask);
4013 tcg_gen_shli_tl(t1, t1, lsb);
4014 tcg_gen_andi_tl(t1, t1, mask);
4015 tcg_gen_or_tl(t0, t0, t1);
4020 MIPS_INVAL("bitops");
4021 generate_exception(ctx, EXCP_RI);
4026 gen_store_gpr(t0, rt);
4031 static void gen_bshfl (DisasContext *ctx, uint32_t op2, int rt, int rd)
4036 /* If no destination, treat it as a NOP. */
4041 t0 = tcg_temp_new();
4042 gen_load_gpr(t0, rt);
4046 TCGv t1 = tcg_temp_new();
4048 tcg_gen_shri_tl(t1, t0, 8);
4049 tcg_gen_andi_tl(t1, t1, 0x00FF00FF);
4050 tcg_gen_shli_tl(t0, t0, 8);
4051 tcg_gen_andi_tl(t0, t0, ~0x00FF00FF);
4052 tcg_gen_or_tl(t0, t0, t1);
4054 tcg_gen_ext32s_tl(cpu_gpr[rd], t0);
4058 tcg_gen_ext8s_tl(cpu_gpr[rd], t0);
4061 tcg_gen_ext16s_tl(cpu_gpr[rd], t0);
4063 #if defined(TARGET_MIPS64)
4066 TCGv t1 = tcg_temp_new();
4068 tcg_gen_shri_tl(t1, t0, 8);
4069 tcg_gen_andi_tl(t1, t1, 0x00FF00FF00FF00FFULL);
4070 tcg_gen_shli_tl(t0, t0, 8);
4071 tcg_gen_andi_tl(t0, t0, ~0x00FF00FF00FF00FFULL);
4072 tcg_gen_or_tl(cpu_gpr[rd], t0, t1);
4078 TCGv t1 = tcg_temp_new();
4080 tcg_gen_shri_tl(t1, t0, 16);
4081 tcg_gen_andi_tl(t1, t1, 0x0000FFFF0000FFFFULL);
4082 tcg_gen_shli_tl(t0, t0, 16);
4083 tcg_gen_andi_tl(t0, t0, ~0x0000FFFF0000FFFFULL);
4084 tcg_gen_or_tl(t0, t0, t1);
4085 tcg_gen_shri_tl(t1, t0, 32);
4086 tcg_gen_shli_tl(t0, t0, 32);
4087 tcg_gen_or_tl(cpu_gpr[rd], t0, t1);
4093 MIPS_INVAL("bsfhl");
4094 generate_exception(ctx, EXCP_RI);
4101 #ifndef CONFIG_USER_ONLY
4102 /* CP0 (MMU and control) */
4103 static inline void gen_mfc0_load32 (TCGv arg, target_ulong off)
4105 TCGv_i32 t0 = tcg_temp_new_i32();
4107 tcg_gen_ld_i32(t0, cpu_env, off);
4108 tcg_gen_ext_i32_tl(arg, t0);
4109 tcg_temp_free_i32(t0);
4112 static inline void gen_mfc0_load64 (TCGv arg, target_ulong off)
4114 tcg_gen_ld_tl(arg, cpu_env, off);
4115 tcg_gen_ext32s_tl(arg, arg);
4118 static inline void gen_mtc0_store32 (TCGv arg, target_ulong off)
4120 TCGv_i32 t0 = tcg_temp_new_i32();
4122 tcg_gen_trunc_tl_i32(t0, arg);
4123 tcg_gen_st_i32(t0, cpu_env, off);
4124 tcg_temp_free_i32(t0);
4127 static inline void gen_mtc0_store64 (TCGv arg, target_ulong off)
4129 tcg_gen_ext32s_tl(arg, arg);
4130 tcg_gen_st_tl(arg, cpu_env, off);
4133 static void gen_mfc0 (CPUMIPSState *env, DisasContext *ctx, TCGv arg, int reg, int sel)
4135 const char *rn = "invalid";
4138 check_insn(env, ctx, ISA_MIPS32);
4144 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Index));
4148 check_insn(env, ctx, ASE_MT);
4149 gen_helper_mfc0_mvpcontrol(arg, cpu_env);
4153 check_insn(env, ctx, ASE_MT);
4154 gen_helper_mfc0_mvpconf0(arg, cpu_env);
4158 check_insn(env, ctx, ASE_MT);
4159 gen_helper_mfc0_mvpconf1(arg, cpu_env);
4169 gen_helper_mfc0_random(arg, cpu_env);
4173 check_insn(env, ctx, ASE_MT);
4174 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEControl));
4178 check_insn(env, ctx, ASE_MT);
4179 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEConf0));
4183 check_insn(env, ctx, ASE_MT);
4184 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEConf1));
4188 check_insn(env, ctx, ASE_MT);
4189 gen_mfc0_load64(arg, offsetof(CPUMIPSState, CP0_YQMask));
4193 check_insn(env, ctx, ASE_MT);
4194 gen_mfc0_load64(arg, offsetof(CPUMIPSState, CP0_VPESchedule));
4198 check_insn(env, ctx, ASE_MT);
4199 gen_mfc0_load64(arg, offsetof(CPUMIPSState, CP0_VPEScheFBack));
4200 rn = "VPEScheFBack";
4203 check_insn(env, ctx, ASE_MT);
4204 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEOpt));
4214 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EntryLo0));
4215 tcg_gen_ext32s_tl(arg, arg);
4219 check_insn(env, ctx, ASE_MT);
4220 gen_helper_mfc0_tcstatus(arg, cpu_env);
4224 check_insn(env, ctx, ASE_MT);
4225 gen_helper_mfc0_tcbind(arg, cpu_env);
4229 check_insn(env, ctx, ASE_MT);
4230 gen_helper_mfc0_tcrestart(arg, cpu_env);
4234 check_insn(env, ctx, ASE_MT);
4235 gen_helper_mfc0_tchalt(arg, cpu_env);
4239 check_insn(env, ctx, ASE_MT);
4240 gen_helper_mfc0_tccontext(arg, cpu_env);
4244 check_insn(env, ctx, ASE_MT);
4245 gen_helper_mfc0_tcschedule(arg, cpu_env);
4249 check_insn(env, ctx, ASE_MT);
4250 gen_helper_mfc0_tcschefback(arg, cpu_env);
4260 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EntryLo1));
4261 tcg_gen_ext32s_tl(arg, arg);
4271 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_Context));
4272 tcg_gen_ext32s_tl(arg, arg);
4276 // gen_helper_mfc0_contextconfig(arg); /* SmartMIPS ASE */
4277 rn = "ContextConfig";
4286 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PageMask));
4290 check_insn(env, ctx, ISA_MIPS32R2);
4291 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PageGrain));
4301 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Wired));
4305 check_insn(env, ctx, ISA_MIPS32R2);
4306 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf0));
4310 check_insn(env, ctx, ISA_MIPS32R2);
4311 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf1));
4315 check_insn(env, ctx, ISA_MIPS32R2);
4316 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf2));
4320 check_insn(env, ctx, ISA_MIPS32R2);
4321 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf3));
4325 check_insn(env, ctx, ISA_MIPS32R2);
4326 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf4));
4336 check_insn(env, ctx, ISA_MIPS32R2);
4337 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_HWREna));
4347 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_BadVAddr));
4348 tcg_gen_ext32s_tl(arg, arg);
4358 /* Mark as an IO operation because we read the time. */
4361 gen_helper_mfc0_count(arg, cpu_env);
4365 /* Break the TB to be able to take timer interrupts immediately
4366 after reading count. */
4367 ctx->bstate = BS_STOP;
4370 /* 6,7 are implementation dependent */
4378 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EntryHi));
4379 tcg_gen_ext32s_tl(arg, arg);
4389 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Compare));
4392 /* 6,7 are implementation dependent */
4400 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Status));
4404 check_insn(env, ctx, ISA_MIPS32R2);
4405 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_IntCtl));
4409 check_insn(env, ctx, ISA_MIPS32R2);
4410 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSCtl));
4414 check_insn(env, ctx, ISA_MIPS32R2);
4415 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSMap));
4425 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Cause));
4435 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EPC));
4436 tcg_gen_ext32s_tl(arg, arg);
4446 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PRid));
4450 check_insn(env, ctx, ISA_MIPS32R2);
4451 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_EBase));
4461 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config0));
4465 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config1));
4469 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config2));
4473 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config3));
4476 /* 4,5 are reserved */
4477 /* 6,7 are implementation dependent */
4479 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config6));
4483 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config7));
4493 gen_helper_mfc0_lladdr(arg, cpu_env);
4503 gen_helper_1e0i(mfc0_watchlo, arg, sel);
4513 gen_helper_1e0i(mfc0_watchhi, arg, sel);
4523 #if defined(TARGET_MIPS64)
4524 check_insn(env, ctx, ISA_MIPS3);
4525 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_XContext));
4526 tcg_gen_ext32s_tl(arg, arg);
4535 /* Officially reserved, but sel 0 is used for R1x000 framemask */
4538 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Framemask));
4546 tcg_gen_movi_tl(arg, 0); /* unimplemented */
4547 rn = "'Diagnostic"; /* implementation dependent */
4552 gen_helper_mfc0_debug(arg, cpu_env); /* EJTAG support */
4556 // gen_helper_mfc0_tracecontrol(arg); /* PDtrace support */
4557 rn = "TraceControl";
4560 // gen_helper_mfc0_tracecontrol2(arg); /* PDtrace support */
4561 rn = "TraceControl2";
4564 // gen_helper_mfc0_usertracedata(arg); /* PDtrace support */
4565 rn = "UserTraceData";
4568 // gen_helper_mfc0_tracebpc(arg); /* PDtrace support */
4579 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_DEPC));
4580 tcg_gen_ext32s_tl(arg, arg);
4590 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Performance0));
4591 rn = "Performance0";
4594 // gen_helper_mfc0_performance1(arg);
4595 rn = "Performance1";
4598 // gen_helper_mfc0_performance2(arg);
4599 rn = "Performance2";
4602 // gen_helper_mfc0_performance3(arg);
4603 rn = "Performance3";
4606 // gen_helper_mfc0_performance4(arg);
4607 rn = "Performance4";
4610 // gen_helper_mfc0_performance5(arg);
4611 rn = "Performance5";
4614 // gen_helper_mfc0_performance6(arg);
4615 rn = "Performance6";
4618 // gen_helper_mfc0_performance7(arg);
4619 rn = "Performance7";
4626 tcg_gen_movi_tl(arg, 0); /* unimplemented */
4632 tcg_gen_movi_tl(arg, 0); /* unimplemented */
4645 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_TagLo));
4652 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DataLo));
4665 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_TagHi));
4672 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DataHi));
4682 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_ErrorEPC));
4683 tcg_gen_ext32s_tl(arg, arg);
4694 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DESAVE));
4704 (void)rn; /* avoid a compiler warning */
4705 LOG_DISAS("mfc0 %s (reg %d sel %d)\n", rn, reg, sel);
4709 LOG_DISAS("mfc0 %s (reg %d sel %d)\n", rn, reg, sel);
4710 generate_exception(ctx, EXCP_RI);
4713 static void gen_mtc0 (CPUMIPSState *env, DisasContext *ctx, TCGv arg, int reg, int sel)
4715 const char *rn = "invalid";
4718 check_insn(env, ctx, ISA_MIPS32);
4727 gen_helper_mtc0_index(cpu_env, arg);
4731 check_insn(env, ctx, ASE_MT);
4732 gen_helper_mtc0_mvpcontrol(cpu_env, arg);
4736 check_insn(env, ctx, ASE_MT);
4741 check_insn(env, ctx, ASE_MT);
4756 check_insn(env, ctx, ASE_MT);
4757 gen_helper_mtc0_vpecontrol(cpu_env, arg);
4761 check_insn(env, ctx, ASE_MT);
4762 gen_helper_mtc0_vpeconf0(cpu_env, arg);
4766 check_insn(env, ctx, ASE_MT);
4767 gen_helper_mtc0_vpeconf1(cpu_env, arg);
4771 check_insn(env, ctx, ASE_MT);
4772 gen_helper_mtc0_yqmask(cpu_env, arg);
4776 check_insn(env, ctx, ASE_MT);
4777 gen_mtc0_store64(arg, offsetof(CPUMIPSState, CP0_VPESchedule));
4781 check_insn(env, ctx, ASE_MT);
4782 gen_mtc0_store64(arg, offsetof(CPUMIPSState, CP0_VPEScheFBack));
4783 rn = "VPEScheFBack";
4786 check_insn(env, ctx, ASE_MT);
4787 gen_helper_mtc0_vpeopt(cpu_env, arg);
4797 gen_helper_mtc0_entrylo0(cpu_env, arg);
4801 check_insn(env, ctx, ASE_MT);
4802 gen_helper_mtc0_tcstatus(cpu_env, arg);
4806 check_insn(env, ctx, ASE_MT);
4807 gen_helper_mtc0_tcbind(cpu_env, arg);
4811 check_insn(env, ctx, ASE_MT);
4812 gen_helper_mtc0_tcrestart(cpu_env, arg);
4816 check_insn(env, ctx, ASE_MT);
4817 gen_helper_mtc0_tchalt(cpu_env, arg);
4821 check_insn(env, ctx, ASE_MT);
4822 gen_helper_mtc0_tccontext(cpu_env, arg);
4826 check_insn(env, ctx, ASE_MT);
4827 gen_helper_mtc0_tcschedule(cpu_env, arg);
4831 check_insn(env, ctx, ASE_MT);
4832 gen_helper_mtc0_tcschefback(cpu_env, arg);
4842 gen_helper_mtc0_entrylo1(cpu_env, arg);
4852 gen_helper_mtc0_context(cpu_env, arg);
4856 // gen_helper_mtc0_contextconfig(cpu_env, arg); /* SmartMIPS ASE */
4857 rn = "ContextConfig";
4866 gen_helper_mtc0_pagemask(cpu_env, arg);
4870 check_insn(env, ctx, ISA_MIPS32R2);
4871 gen_helper_mtc0_pagegrain(cpu_env, arg);
4881 gen_helper_mtc0_wired(cpu_env, arg);
4885 check_insn(env, ctx, ISA_MIPS32R2);
4886 gen_helper_mtc0_srsconf0(cpu_env, arg);
4890 check_insn(env, ctx, ISA_MIPS32R2);
4891 gen_helper_mtc0_srsconf1(cpu_env, arg);
4895 check_insn(env, ctx, ISA_MIPS32R2);
4896 gen_helper_mtc0_srsconf2(cpu_env, arg);
4900 check_insn(env, ctx, ISA_MIPS32R2);
4901 gen_helper_mtc0_srsconf3(cpu_env, arg);
4905 check_insn(env, ctx, ISA_MIPS32R2);
4906 gen_helper_mtc0_srsconf4(cpu_env, arg);
4916 check_insn(env, ctx, ISA_MIPS32R2);
4917 gen_helper_mtc0_hwrena(cpu_env, arg);
4931 gen_helper_mtc0_count(cpu_env, arg);
4934 /* 6,7 are implementation dependent */
4942 gen_helper_mtc0_entryhi(cpu_env, arg);
4952 gen_helper_mtc0_compare(cpu_env, arg);
4955 /* 6,7 are implementation dependent */
4963 save_cpu_state(ctx, 1);
4964 gen_helper_mtc0_status(cpu_env, arg);
4965 /* BS_STOP isn't good enough here, hflags may have changed. */
4966 gen_save_pc(ctx->pc + 4);
4967 ctx->bstate = BS_EXCP;
4971 check_insn(env, ctx, ISA_MIPS32R2);
4972 gen_helper_mtc0_intctl(cpu_env, arg);
4973 /* Stop translation as we may have switched the execution mode */
4974 ctx->bstate = BS_STOP;
4978 check_insn(env, ctx, ISA_MIPS32R2);
4979 gen_helper_mtc0_srsctl(cpu_env, arg);
4980 /* Stop translation as we may have switched the execution mode */
4981 ctx->bstate = BS_STOP;
4985 check_insn(env, ctx, ISA_MIPS32R2);
4986 gen_mtc0_store32(arg, offsetof(CPUMIPSState, CP0_SRSMap));
4987 /* Stop translation as we may have switched the execution mode */
4988 ctx->bstate = BS_STOP;
4998 save_cpu_state(ctx, 1);
4999 gen_helper_mtc0_cause(cpu_env, arg);
5009 gen_mtc0_store64(arg, offsetof(CPUMIPSState, CP0_EPC));
5023 check_insn(env, ctx, ISA_MIPS32R2);
5024 gen_helper_mtc0_ebase(cpu_env, arg);
5034 gen_helper_mtc0_config0(cpu_env, arg);
5036 /* Stop translation as we may have switched the execution mode */
5037 ctx->bstate = BS_STOP;
5040 /* ignored, read only */
5044 gen_helper_mtc0_config2(cpu_env, arg);
5046 /* Stop translation as we may have switched the execution mode */
5047 ctx->bstate = BS_STOP;
5050 /* ignored, read only */
5053 /* 4,5 are reserved */
5054 /* 6,7 are implementation dependent */
5064 rn = "Invalid config selector";
5071 gen_helper_mtc0_lladdr(cpu_env, arg);
5081 gen_helper_0e1i(mtc0_watchlo, arg, sel);
5091 gen_helper_0e1i(mtc0_watchhi, arg, sel);
5101 #if defined(TARGET_MIPS64)
5102 check_insn(env, ctx, ISA_MIPS3);
5103 gen_helper_mtc0_xcontext(cpu_env, arg);
5112 /* Officially reserved, but sel 0 is used for R1x000 framemask */
5115 gen_helper_mtc0_framemask(cpu_env, arg);
5124 rn = "Diagnostic"; /* implementation dependent */
5129 gen_helper_mtc0_debug(cpu_env, arg); /* EJTAG support */
5130 /* BS_STOP isn't good enough here, hflags may have changed. */
5131 gen_save_pc(ctx->pc + 4);
5132 ctx->bstate = BS_EXCP;
5136 // gen_helper_mtc0_tracecontrol(cpu_env, arg); /* PDtrace support */
5137 rn = "TraceControl";
5138 /* Stop translation as we may have switched the execution mode */
5139 ctx->bstate = BS_STOP;
5142 // gen_helper_mtc0_tracecontrol2(cpu_env, arg); /* PDtrace support */
5143 rn = "TraceControl2";
5144 /* Stop translation as we may have switched the execution mode */
5145 ctx->bstate = BS_STOP;
5148 /* Stop translation as we may have switched the execution mode */
5149 ctx->bstate = BS_STOP;
5150 // gen_helper_mtc0_usertracedata(cpu_env, arg); /* PDtrace support */
5151 rn = "UserTraceData";
5152 /* Stop translation as we may have switched the execution mode */
5153 ctx->bstate = BS_STOP;
5156 // gen_helper_mtc0_tracebpc(cpu_env, arg); /* PDtrace support */
5157 /* Stop translation as we may have switched the execution mode */
5158 ctx->bstate = BS_STOP;
5169 gen_mtc0_store64(arg, offsetof(CPUMIPSState, CP0_DEPC));
5179 gen_helper_mtc0_performance0(cpu_env, arg);
5180 rn = "Performance0";
5183 // gen_helper_mtc0_performance1(arg);
5184 rn = "Performance1";
5187 // gen_helper_mtc0_performance2(arg);
5188 rn = "Performance2";
5191 // gen_helper_mtc0_performance3(arg);
5192 rn = "Performance3";
5195 // gen_helper_mtc0_performance4(arg);
5196 rn = "Performance4";
5199 // gen_helper_mtc0_performance5(arg);
5200 rn = "Performance5";
5203 // gen_helper_mtc0_performance6(arg);
5204 rn = "Performance6";
5207 // gen_helper_mtc0_performance7(arg);
5208 rn = "Performance7";
5234 gen_helper_mtc0_taglo(cpu_env, arg);
5241 gen_helper_mtc0_datalo(cpu_env, arg);
5254 gen_helper_mtc0_taghi(cpu_env, arg);
5261 gen_helper_mtc0_datahi(cpu_env, arg);
5272 gen_mtc0_store64(arg, offsetof(CPUMIPSState, CP0_ErrorEPC));
5283 gen_mtc0_store32(arg, offsetof(CPUMIPSState, CP0_DESAVE));
5289 /* Stop translation as we may have switched the execution mode */
5290 ctx->bstate = BS_STOP;
5295 (void)rn; /* avoid a compiler warning */
5296 LOG_DISAS("mtc0 %s (reg %d sel %d)\n", rn, reg, sel);
5297 /* For simplicity assume that all writes can cause interrupts. */
5300 ctx->bstate = BS_STOP;
5305 LOG_DISAS("mtc0 %s (reg %d sel %d)\n", rn, reg, sel);
5306 generate_exception(ctx, EXCP_RI);
5309 #if defined(TARGET_MIPS64)
5310 static void gen_dmfc0 (CPUMIPSState *env, DisasContext *ctx, TCGv arg, int reg, int sel)
5312 const char *rn = "invalid";
5315 check_insn(env, ctx, ISA_MIPS64);
5321 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Index));
5325 check_insn(env, ctx, ASE_MT);
5326 gen_helper_mfc0_mvpcontrol(arg, cpu_env);
5330 check_insn(env, ctx, ASE_MT);
5331 gen_helper_mfc0_mvpconf0(arg, cpu_env);
5335 check_insn(env, ctx, ASE_MT);
5336 gen_helper_mfc0_mvpconf1(arg, cpu_env);
5346 gen_helper_mfc0_random(arg, cpu_env);
5350 check_insn(env, ctx, ASE_MT);
5351 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEControl));
5355 check_insn(env, ctx, ASE_MT);
5356 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEConf0));
5360 check_insn(env, ctx, ASE_MT);
5361 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEConf1));
5365 check_insn(env, ctx, ASE_MT);
5366 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_YQMask));
5370 check_insn(env, ctx, ASE_MT);
5371 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_VPESchedule));
5375 check_insn(env, ctx, ASE_MT);
5376 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_VPEScheFBack));
5377 rn = "VPEScheFBack";
5380 check_insn(env, ctx, ASE_MT);
5381 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEOpt));
5391 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EntryLo0));
5395 check_insn(env, ctx, ASE_MT);
5396 gen_helper_mfc0_tcstatus(arg, cpu_env);
5400 check_insn(env, ctx, ASE_MT);
5401 gen_helper_mfc0_tcbind(arg, cpu_env);
5405 check_insn(env, ctx, ASE_MT);
5406 gen_helper_dmfc0_tcrestart(arg, cpu_env);
5410 check_insn(env, ctx, ASE_MT);
5411 gen_helper_dmfc0_tchalt(arg, cpu_env);
5415 check_insn(env, ctx, ASE_MT);
5416 gen_helper_dmfc0_tccontext(arg, cpu_env);
5420 check_insn(env, ctx, ASE_MT);
5421 gen_helper_dmfc0_tcschedule(arg, cpu_env);
5425 check_insn(env, ctx, ASE_MT);
5426 gen_helper_dmfc0_tcschefback(arg, cpu_env);
5436 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EntryLo1));
5446 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_Context));
5450 // gen_helper_dmfc0_contextconfig(arg); /* SmartMIPS ASE */
5451 rn = "ContextConfig";
5460 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PageMask));
5464 check_insn(env, ctx, ISA_MIPS32R2);
5465 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PageGrain));
5475 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Wired));
5479 check_insn(env, ctx, ISA_MIPS32R2);
5480 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf0));
5484 check_insn(env, ctx, ISA_MIPS32R2);
5485 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf1));
5489 check_insn(env, ctx, ISA_MIPS32R2);
5490 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf2));
5494 check_insn(env, ctx, ISA_MIPS32R2);
5495 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf3));
5499 check_insn(env, ctx, ISA_MIPS32R2);
5500 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf4));
5510 check_insn(env, ctx, ISA_MIPS32R2);
5511 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_HWREna));
5521 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_BadVAddr));
5531 /* Mark as an IO operation because we read the time. */
5534 gen_helper_mfc0_count(arg, cpu_env);
5538 /* Break the TB to be able to take timer interrupts immediately
5539 after reading count. */
5540 ctx->bstate = BS_STOP;
5543 /* 6,7 are implementation dependent */
5551 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EntryHi));
5561 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Compare));
5564 /* 6,7 are implementation dependent */
5572 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Status));
5576 check_insn(env, ctx, ISA_MIPS32R2);
5577 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_IntCtl));
5581 check_insn(env, ctx, ISA_MIPS32R2);
5582 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSCtl));
5586 check_insn(env, ctx, ISA_MIPS32R2);
5587 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSMap));
5597 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Cause));
5607 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EPC));
5617 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PRid));
5621 check_insn(env, ctx, ISA_MIPS32R2);
5622 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_EBase));
5632 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config0));
5636 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config1));
5640 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config2));
5644 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config3));
5647 /* 6,7 are implementation dependent */
5649 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config6));
5653 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config7));
5663 gen_helper_dmfc0_lladdr(arg, cpu_env);
5673 gen_helper_1e0i(dmfc0_watchlo, arg, sel);
5683 gen_helper_1e0i(mfc0_watchhi, arg, sel);
5693 check_insn(env, ctx, ISA_MIPS3);
5694 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_XContext));
5702 /* Officially reserved, but sel 0 is used for R1x000 framemask */
5705 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Framemask));
5713 tcg_gen_movi_tl(arg, 0); /* unimplemented */
5714 rn = "'Diagnostic"; /* implementation dependent */
5719 gen_helper_mfc0_debug(arg, cpu_env); /* EJTAG support */
5723 // gen_helper_dmfc0_tracecontrol(arg, cpu_env); /* PDtrace support */
5724 rn = "TraceControl";
5727 // gen_helper_dmfc0_tracecontrol2(arg, cpu_env); /* PDtrace support */
5728 rn = "TraceControl2";
5731 // gen_helper_dmfc0_usertracedata(arg, cpu_env); /* PDtrace support */
5732 rn = "UserTraceData";
5735 // gen_helper_dmfc0_tracebpc(arg, cpu_env); /* PDtrace support */
5746 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_DEPC));
5756 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Performance0));
5757 rn = "Performance0";
5760 // gen_helper_dmfc0_performance1(arg);
5761 rn = "Performance1";
5764 // gen_helper_dmfc0_performance2(arg);
5765 rn = "Performance2";
5768 // gen_helper_dmfc0_performance3(arg);
5769 rn = "Performance3";
5772 // gen_helper_dmfc0_performance4(arg);
5773 rn = "Performance4";
5776 // gen_helper_dmfc0_performance5(arg);
5777 rn = "Performance5";
5780 // gen_helper_dmfc0_performance6(arg);
5781 rn = "Performance6";
5784 // gen_helper_dmfc0_performance7(arg);
5785 rn = "Performance7";
5792 tcg_gen_movi_tl(arg, 0); /* unimplemented */
5799 tcg_gen_movi_tl(arg, 0); /* unimplemented */
5812 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_TagLo));
5819 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DataLo));
5832 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_TagHi));
5839 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DataHi));
5849 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_ErrorEPC));
5860 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DESAVE));
5870 (void)rn; /* avoid a compiler warning */
5871 LOG_DISAS("dmfc0 %s (reg %d sel %d)\n", rn, reg, sel);
5875 LOG_DISAS("dmfc0 %s (reg %d sel %d)\n", rn, reg, sel);
5876 generate_exception(ctx, EXCP_RI);
5879 static void gen_dmtc0 (CPUMIPSState *env, DisasContext *ctx, TCGv arg, int reg, int sel)
5881 const char *rn = "invalid";
5884 check_insn(env, ctx, ISA_MIPS64);
5893 gen_helper_mtc0_index(cpu_env, arg);
5897 check_insn(env, ctx, ASE_MT);
5898 gen_helper_mtc0_mvpcontrol(cpu_env, arg);
5902 check_insn(env, ctx, ASE_MT);
5907 check_insn(env, ctx, ASE_MT);
5922 check_insn(env, ctx, ASE_MT);
5923 gen_helper_mtc0_vpecontrol(cpu_env, arg);
5927 check_insn(env, ctx, ASE_MT);
5928 gen_helper_mtc0_vpeconf0(cpu_env, arg);
5932 check_insn(env, ctx, ASE_MT);
5933 gen_helper_mtc0_vpeconf1(cpu_env, arg);
5937 check_insn(env, ctx, ASE_MT);
5938 gen_helper_mtc0_yqmask(cpu_env, arg);
5942 check_insn(env, ctx, ASE_MT);
5943 tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_VPESchedule));
5947 check_insn(env, ctx, ASE_MT);
5948 tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_VPEScheFBack));
5949 rn = "VPEScheFBack";
5952 check_insn(env, ctx, ASE_MT);
5953 gen_helper_mtc0_vpeopt(cpu_env, arg);
5963 gen_helper_mtc0_entrylo0(cpu_env, arg);
5967 check_insn(env, ctx, ASE_MT);
5968 gen_helper_mtc0_tcstatus(cpu_env, arg);
5972 check_insn(env, ctx, ASE_MT);
5973 gen_helper_mtc0_tcbind(cpu_env, arg);
5977 check_insn(env, ctx, ASE_MT);
5978 gen_helper_mtc0_tcrestart(cpu_env, arg);
5982 check_insn(env, ctx, ASE_MT);
5983 gen_helper_mtc0_tchalt(cpu_env, arg);
5987 check_insn(env, ctx, ASE_MT);
5988 gen_helper_mtc0_tccontext(cpu_env, arg);
5992 check_insn(env, ctx, ASE_MT);
5993 gen_helper_mtc0_tcschedule(cpu_env, arg);
5997 check_insn(env, ctx, ASE_MT);
5998 gen_helper_mtc0_tcschefback(cpu_env, arg);
6008 gen_helper_mtc0_entrylo1(cpu_env, arg);
6018 gen_helper_mtc0_context(cpu_env, arg);
6022 // gen_helper_mtc0_contextconfig(cpu_env, arg); /* SmartMIPS ASE */
6023 rn = "ContextConfig";
6032 gen_helper_mtc0_pagemask(cpu_env, arg);
6036 check_insn(env, ctx, ISA_MIPS32R2);
6037 gen_helper_mtc0_pagegrain(cpu_env, arg);
6047 gen_helper_mtc0_wired(cpu_env, arg);
6051 check_insn(env, ctx, ISA_MIPS32R2);
6052 gen_helper_mtc0_srsconf0(cpu_env, arg);
6056 check_insn(env, ctx, ISA_MIPS32R2);
6057 gen_helper_mtc0_srsconf1(cpu_env, arg);
6061 check_insn(env, ctx, ISA_MIPS32R2);
6062 gen_helper_mtc0_srsconf2(cpu_env, arg);
6066 check_insn(env, ctx, ISA_MIPS32R2);
6067 gen_helper_mtc0_srsconf3(cpu_env, arg);
6071 check_insn(env, ctx, ISA_MIPS32R2);
6072 gen_helper_mtc0_srsconf4(cpu_env, arg);
6082 check_insn(env, ctx, ISA_MIPS32R2);
6083 gen_helper_mtc0_hwrena(cpu_env, arg);
6097 gen_helper_mtc0_count(cpu_env, arg);
6100 /* 6,7 are implementation dependent */
6104 /* Stop translation as we may have switched the execution mode */
6105 ctx->bstate = BS_STOP;
6110 gen_helper_mtc0_entryhi(cpu_env, arg);
6120 gen_helper_mtc0_compare(cpu_env, arg);
6123 /* 6,7 are implementation dependent */
6127 /* Stop translation as we may have switched the execution mode */
6128 ctx->bstate = BS_STOP;
6133 save_cpu_state(ctx, 1);
6134 gen_helper_mtc0_status(cpu_env, arg);
6135 /* BS_STOP isn't good enough here, hflags may have changed. */
6136 gen_save_pc(ctx->pc + 4);
6137 ctx->bstate = BS_EXCP;
6141 check_insn(env, ctx, ISA_MIPS32R2);
6142 gen_helper_mtc0_intctl(cpu_env, arg);
6143 /* Stop translation as we may have switched the execution mode */
6144 ctx->bstate = BS_STOP;
6148 check_insn(env, ctx, ISA_MIPS32R2);
6149 gen_helper_mtc0_srsctl(cpu_env, arg);
6150 /* Stop translation as we may have switched the execution mode */
6151 ctx->bstate = BS_STOP;
6155 check_insn(env, ctx, ISA_MIPS32R2);
6156 gen_mtc0_store32(arg, offsetof(CPUMIPSState, CP0_SRSMap));
6157 /* Stop translation as we may have switched the execution mode */
6158 ctx->bstate = BS_STOP;
6168 save_cpu_state(ctx, 1);
6169 /* Mark as an IO operation because we may trigger a software
6174 gen_helper_mtc0_cause(cpu_env, arg);
6178 /* Stop translation as we may have triggered an intetrupt */
6179 ctx->bstate = BS_STOP;
6189 tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EPC));
6203 check_insn(env, ctx, ISA_MIPS32R2);
6204 gen_helper_mtc0_ebase(cpu_env, arg);
6214 gen_helper_mtc0_config0(cpu_env, arg);
6216 /* Stop translation as we may have switched the execution mode */
6217 ctx->bstate = BS_STOP;
6220 /* ignored, read only */
6224 gen_helper_mtc0_config2(cpu_env, arg);
6226 /* Stop translation as we may have switched the execution mode */
6227 ctx->bstate = BS_STOP;
6233 /* 6,7 are implementation dependent */
6235 rn = "Invalid config selector";
6242 gen_helper_mtc0_lladdr(cpu_env, arg);
6252 gen_helper_0e1i(mtc0_watchlo, arg, sel);
6262 gen_helper_0e1i(mtc0_watchhi, arg, sel);
6272 check_insn(env, ctx, ISA_MIPS3);
6273 gen_helper_mtc0_xcontext(cpu_env, arg);
6281 /* Officially reserved, but sel 0 is used for R1x000 framemask */
6284 gen_helper_mtc0_framemask(cpu_env, arg);
6293 rn = "Diagnostic"; /* implementation dependent */
6298 gen_helper_mtc0_debug(cpu_env, arg); /* EJTAG support */
6299 /* BS_STOP isn't good enough here, hflags may have changed. */
6300 gen_save_pc(ctx->pc + 4);
6301 ctx->bstate = BS_EXCP;
6305 // gen_helper_mtc0_tracecontrol(cpu_env, arg); /* PDtrace support */
6306 /* Stop translation as we may have switched the execution mode */
6307 ctx->bstate = BS_STOP;
6308 rn = "TraceControl";
6311 // gen_helper_mtc0_tracecontrol2(cpu_env, arg); /* PDtrace support */
6312 /* Stop translation as we may have switched the execution mode */
6313 ctx->bstate = BS_STOP;
6314 rn = "TraceControl2";
6317 // gen_helper_mtc0_usertracedata(cpu_env, arg); /* PDtrace support */
6318 /* Stop translation as we may have switched the execution mode */
6319 ctx->bstate = BS_STOP;
6320 rn = "UserTraceData";
6323 // gen_helper_mtc0_tracebpc(cpu_env, arg); /* PDtrace support */
6324 /* Stop translation as we may have switched the execution mode */
6325 ctx->bstate = BS_STOP;
6336 tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_DEPC));
6346 gen_helper_mtc0_performance0(cpu_env, arg);
6347 rn = "Performance0";
6350 // gen_helper_mtc0_performance1(cpu_env, arg);
6351 rn = "Performance1";
6354 // gen_helper_mtc0_performance2(cpu_env, arg);
6355 rn = "Performance2";
6358 // gen_helper_mtc0_performance3(cpu_env, arg);
6359 rn = "Performance3";
6362 // gen_helper_mtc0_performance4(cpu_env, arg);
6363 rn = "Performance4";
6366 // gen_helper_mtc0_performance5(cpu_env, arg);
6367 rn = "Performance5";
6370 // gen_helper_mtc0_performance6(cpu_env, arg);
6371 rn = "Performance6";
6374 // gen_helper_mtc0_performance7(cpu_env, arg);
6375 rn = "Performance7";
6401 gen_helper_mtc0_taglo(cpu_env, arg);
6408 gen_helper_mtc0_datalo(cpu_env, arg);
6421 gen_helper_mtc0_taghi(cpu_env, arg);
6428 gen_helper_mtc0_datahi(cpu_env, arg);
6439 tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_ErrorEPC));
6450 gen_mtc0_store32(arg, offsetof(CPUMIPSState, CP0_DESAVE));
6456 /* Stop translation as we may have switched the execution mode */
6457 ctx->bstate = BS_STOP;
6462 (void)rn; /* avoid a compiler warning */
6463 LOG_DISAS("dmtc0 %s (reg %d sel %d)\n", rn, reg, sel);
6464 /* For simplicity assume that all writes can cause interrupts. */
6467 ctx->bstate = BS_STOP;
6472 LOG_DISAS("dmtc0 %s (reg %d sel %d)\n", rn, reg, sel);
6473 generate_exception(ctx, EXCP_RI);
6475 #endif /* TARGET_MIPS64 */
6477 static void gen_mftr(CPUMIPSState *env, DisasContext *ctx, int rt, int rd,
6478 int u, int sel, int h)
6480 int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
6481 TCGv t0 = tcg_temp_local_new();
6483 if ((env->CP0_VPEConf0 & (1 << CP0VPEC0_MVP)) == 0 &&
6484 ((env->tcs[other_tc].CP0_TCBind & (0xf << CP0TCBd_CurVPE)) !=
6485 (env->active_tc.CP0_TCBind & (0xf << CP0TCBd_CurVPE))))
6486 tcg_gen_movi_tl(t0, -1);
6487 else if ((env->CP0_VPEControl & (0xff << CP0VPECo_TargTC)) >
6488 (env->mvp->CP0_MVPConf0 & (0xff << CP0MVPC0_PTC)))
6489 tcg_gen_movi_tl(t0, -1);
6495 gen_helper_mftc0_vpecontrol(t0, cpu_env);
6498 gen_helper_mftc0_vpeconf0(t0, cpu_env);
6508 gen_helper_mftc0_tcstatus(t0, cpu_env);
6511 gen_helper_mftc0_tcbind(t0, cpu_env);
6514 gen_helper_mftc0_tcrestart(t0, cpu_env);
6517 gen_helper_mftc0_tchalt(t0, cpu_env);
6520 gen_helper_mftc0_tccontext(t0, cpu_env);
6523 gen_helper_mftc0_tcschedule(t0, cpu_env);
6526 gen_helper_mftc0_tcschefback(t0, cpu_env);
6529 gen_mfc0(env, ctx, t0, rt, sel);
6536 gen_helper_mftc0_entryhi(t0, cpu_env);
6539 gen_mfc0(env, ctx, t0, rt, sel);
6545 gen_helper_mftc0_status(t0, cpu_env);
6548 gen_mfc0(env, ctx, t0, rt, sel);
6554 gen_helper_mftc0_cause(t0, cpu_env);
6564 gen_helper_mftc0_epc(t0, cpu_env);
6574 gen_helper_mftc0_ebase(t0, cpu_env);
6584 gen_helper_mftc0_configx(t0, cpu_env, tcg_const_tl(sel));
6594 gen_helper_mftc0_debug(t0, cpu_env);
6597 gen_mfc0(env, ctx, t0, rt, sel);
6602 gen_mfc0(env, ctx, t0, rt, sel);
6604 } else switch (sel) {
6605 /* GPR registers. */
6607 gen_helper_1e0i(mftgpr, t0, rt);
6609 /* Auxiliary CPU registers */
6613 gen_helper_1e0i(mftlo, t0, 0);
6616 gen_helper_1e0i(mfthi, t0, 0);
6619 gen_helper_1e0i(mftacx, t0, 0);
6622 gen_helper_1e0i(mftlo, t0, 1);
6625 gen_helper_1e0i(mfthi, t0, 1);
6628 gen_helper_1e0i(mftacx, t0, 1);
6631 gen_helper_1e0i(mftlo, t0, 2);
6634 gen_helper_1e0i(mfthi, t0, 2);
6637 gen_helper_1e0i(mftacx, t0, 2);
6640 gen_helper_1e0i(mftlo, t0, 3);
6643 gen_helper_1e0i(mfthi, t0, 3);
6646 gen_helper_1e0i(mftacx, t0, 3);
6649 gen_helper_mftdsp(t0, cpu_env);
6655 /* Floating point (COP1). */
6657 /* XXX: For now we support only a single FPU context. */
6659 TCGv_i32 fp0 = tcg_temp_new_i32();
6661 gen_load_fpr32(fp0, rt);
6662 tcg_gen_ext_i32_tl(t0, fp0);
6663 tcg_temp_free_i32(fp0);
6665 TCGv_i32 fp0 = tcg_temp_new_i32();
6667 gen_load_fpr32h(fp0, rt);
6668 tcg_gen_ext_i32_tl(t0, fp0);
6669 tcg_temp_free_i32(fp0);
6673 /* XXX: For now we support only a single FPU context. */
6674 gen_helper_1e0i(cfc1, t0, rt);
6676 /* COP2: Not implemented. */
6683 LOG_DISAS("mftr (reg %d u %d sel %d h %d)\n", rt, u, sel, h);
6684 gen_store_gpr(t0, rd);
6690 LOG_DISAS("mftr (reg %d u %d sel %d h %d)\n", rt, u, sel, h);
6691 generate_exception(ctx, EXCP_RI);
6694 static void gen_mttr(CPUMIPSState *env, DisasContext *ctx, int rd, int rt,
6695 int u, int sel, int h)
6697 int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
6698 TCGv t0 = tcg_temp_local_new();
6700 gen_load_gpr(t0, rt);
6701 if ((env->CP0_VPEConf0 & (1 << CP0VPEC0_MVP)) == 0 &&
6702 ((env->tcs[other_tc].CP0_TCBind & (0xf << CP0TCBd_CurVPE)) !=
6703 (env->active_tc.CP0_TCBind & (0xf << CP0TCBd_CurVPE))))
6705 else if ((env->CP0_VPEControl & (0xff << CP0VPECo_TargTC)) >
6706 (env->mvp->CP0_MVPConf0 & (0xff << CP0MVPC0_PTC)))
6713 gen_helper_mttc0_vpecontrol(cpu_env, t0);
6716 gen_helper_mttc0_vpeconf0(cpu_env, t0);
6726 gen_helper_mttc0_tcstatus(cpu_env, t0);
6729 gen_helper_mttc0_tcbind(cpu_env, t0);
6732 gen_helper_mttc0_tcrestart(cpu_env, t0);
6735 gen_helper_mttc0_tchalt(cpu_env, t0);
6738 gen_helper_mttc0_tccontext(cpu_env, t0);
6741 gen_helper_mttc0_tcschedule(cpu_env, t0);
6744 gen_helper_mttc0_tcschefback(cpu_env, t0);
6747 gen_mtc0(env, ctx, t0, rd, sel);
6754 gen_helper_mttc0_entryhi(cpu_env, t0);
6757 gen_mtc0(env, ctx, t0, rd, sel);
6763 gen_helper_mttc0_status(cpu_env, t0);
6766 gen_mtc0(env, ctx, t0, rd, sel);
6772 gen_helper_mttc0_cause(cpu_env, t0);
6782 gen_helper_mttc0_ebase(cpu_env, t0);
6792 gen_helper_mttc0_debug(cpu_env, t0);
6795 gen_mtc0(env, ctx, t0, rd, sel);
6800 gen_mtc0(env, ctx, t0, rd, sel);
6802 } else switch (sel) {
6803 /* GPR registers. */
6805 gen_helper_0e1i(mttgpr, t0, rd);
6807 /* Auxiliary CPU registers */
6811 gen_helper_0e1i(mttlo, t0, 0);
6814 gen_helper_0e1i(mtthi, t0, 0);
6817 gen_helper_0e1i(mttacx, t0, 0);
6820 gen_helper_0e1i(mttlo, t0, 1);
6823 gen_helper_0e1i(mtthi, t0, 1);
6826 gen_helper_0e1i(mttacx, t0, 1);
6829 gen_helper_0e1i(mttlo, t0, 2);
6832 gen_helper_0e1i(mtthi, t0, 2);
6835 gen_helper_0e1i(mttacx, t0, 2);
6838 gen_helper_0e1i(mttlo, t0, 3);
6841 gen_helper_0e1i(mtthi, t0, 3);
6844 gen_helper_0e1i(mttacx, t0, 3);
6847 gen_helper_mttdsp(cpu_env, t0);
6853 /* Floating point (COP1). */
6855 /* XXX: For now we support only a single FPU context. */
6857 TCGv_i32 fp0 = tcg_temp_new_i32();
6859 tcg_gen_trunc_tl_i32(fp0, t0);
6860 gen_store_fpr32(fp0, rd);
6861 tcg_temp_free_i32(fp0);
6863 TCGv_i32 fp0 = tcg_temp_new_i32();
6865 tcg_gen_trunc_tl_i32(fp0, t0);
6866 gen_store_fpr32h(fp0, rd);
6867 tcg_temp_free_i32(fp0);
6871 /* XXX: For now we support only a single FPU context. */
6872 gen_helper_0e1i(ctc1, t0, rd);
6874 /* COP2: Not implemented. */
6881 LOG_DISAS("mttr (reg %d u %d sel %d h %d)\n", rd, u, sel, h);
6887 LOG_DISAS("mttr (reg %d u %d sel %d h %d)\n", rd, u, sel, h);
6888 generate_exception(ctx, EXCP_RI);
6891 static void gen_cp0 (CPUMIPSState *env, DisasContext *ctx, uint32_t opc, int rt, int rd)
6893 const char *opn = "ldst";
6895 check_cp0_enabled(ctx);
6902 gen_mfc0(env, ctx, cpu_gpr[rt], rd, ctx->opcode & 0x7);
6907 TCGv t0 = tcg_temp_new();
6909 gen_load_gpr(t0, rt);
6910 gen_mtc0(env, ctx, t0, rd, ctx->opcode & 0x7);
6915 #if defined(TARGET_MIPS64)
6917 check_insn(env, ctx, ISA_MIPS3);
6922 gen_dmfc0(env, ctx, cpu_gpr[rt], rd, ctx->opcode & 0x7);
6926 check_insn(env, ctx, ISA_MIPS3);
6928 TCGv t0 = tcg_temp_new();
6930 gen_load_gpr(t0, rt);
6931 gen_dmtc0(env, ctx, t0, rd, ctx->opcode & 0x7);
6938 check_insn(env, ctx, ASE_MT);
6943 gen_mftr(env, ctx, rt, rd, (ctx->opcode >> 5) & 1,
6944 ctx->opcode & 0x7, (ctx->opcode >> 4) & 1);
6948 check_insn(env, ctx, ASE_MT);
6949 gen_mttr(env, ctx, rd, rt, (ctx->opcode >> 5) & 1,
6950 ctx->opcode & 0x7, (ctx->opcode >> 4) & 1);
6955 if (!env->tlb->helper_tlbwi)
6957 gen_helper_tlbwi(cpu_env);
6961 if (!env->tlb->helper_tlbwr)
6963 gen_helper_tlbwr(cpu_env);
6967 if (!env->tlb->helper_tlbp)
6969 gen_helper_tlbp(cpu_env);
6973 if (!env->tlb->helper_tlbr)
6975 gen_helper_tlbr(cpu_env);
6979 check_insn(env, ctx, ISA_MIPS2);
6980 gen_helper_eret(cpu_env);
6981 ctx->bstate = BS_EXCP;
6985 check_insn(env, ctx, ISA_MIPS32);
6986 if (!(ctx->hflags & MIPS_HFLAG_DM)) {
6988 generate_exception(ctx, EXCP_RI);
6990 gen_helper_deret(cpu_env);
6991 ctx->bstate = BS_EXCP;
6996 check_insn(env, ctx, ISA_MIPS3 | ISA_MIPS32);
6997 /* If we get an exception, we want to restart at next instruction */
6999 save_cpu_state(ctx, 1);
7001 gen_helper_wait(cpu_env);
7002 ctx->bstate = BS_EXCP;
7007 generate_exception(ctx, EXCP_RI);
7010 (void)opn; /* avoid a compiler warning */
7011 MIPS_DEBUG("%s %s %d", opn, regnames[rt], rd);
7013 #endif /* !CONFIG_USER_ONLY */
7015 /* CP1 Branches (before delay slot) */
7016 static void gen_compute_branch1 (CPUMIPSState *env, DisasContext *ctx, uint32_t op,
7017 int32_t cc, int32_t offset)
7019 target_ulong btarget;
7020 const char *opn = "cp1 cond branch";
7021 TCGv_i32 t0 = tcg_temp_new_i32();
7024 check_insn(env, ctx, ISA_MIPS4 | ISA_MIPS32);
7026 btarget = ctx->pc + 4 + offset;
7030 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
7031 tcg_gen_not_i32(t0, t0);
7032 tcg_gen_andi_i32(t0, t0, 1);
7033 tcg_gen_extu_i32_tl(bcond, t0);
7037 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
7038 tcg_gen_not_i32(t0, t0);
7039 tcg_gen_andi_i32(t0, t0, 1);
7040 tcg_gen_extu_i32_tl(bcond, t0);
7044 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
7045 tcg_gen_andi_i32(t0, t0, 1);
7046 tcg_gen_extu_i32_tl(bcond, t0);
7050 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
7051 tcg_gen_andi_i32(t0, t0, 1);
7052 tcg_gen_extu_i32_tl(bcond, t0);
7055 ctx->hflags |= MIPS_HFLAG_BL;
7059 TCGv_i32 t1 = tcg_temp_new_i32();
7060 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
7061 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+1));
7062 tcg_gen_nand_i32(t0, t0, t1);
7063 tcg_temp_free_i32(t1);
7064 tcg_gen_andi_i32(t0, t0, 1);
7065 tcg_gen_extu_i32_tl(bcond, t0);
7071 TCGv_i32 t1 = tcg_temp_new_i32();
7072 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
7073 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+1));
7074 tcg_gen_or_i32(t0, t0, t1);
7075 tcg_temp_free_i32(t1);
7076 tcg_gen_andi_i32(t0, t0, 1);
7077 tcg_gen_extu_i32_tl(bcond, t0);
7083 TCGv_i32 t1 = tcg_temp_new_i32();
7084 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
7085 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+1));
7086 tcg_gen_and_i32(t0, t0, t1);
7087 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+2));
7088 tcg_gen_and_i32(t0, t0, t1);
7089 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+3));
7090 tcg_gen_nand_i32(t0, t0, t1);
7091 tcg_temp_free_i32(t1);
7092 tcg_gen_andi_i32(t0, t0, 1);
7093 tcg_gen_extu_i32_tl(bcond, t0);
7099 TCGv_i32 t1 = tcg_temp_new_i32();
7100 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
7101 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+1));
7102 tcg_gen_or_i32(t0, t0, t1);
7103 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+2));
7104 tcg_gen_or_i32(t0, t0, t1);
7105 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+3));
7106 tcg_gen_or_i32(t0, t0, t1);
7107 tcg_temp_free_i32(t1);
7108 tcg_gen_andi_i32(t0, t0, 1);
7109 tcg_gen_extu_i32_tl(bcond, t0);
7113 ctx->hflags |= MIPS_HFLAG_BC;
7117 generate_exception (ctx, EXCP_RI);
7120 (void)opn; /* avoid a compiler warning */
7121 MIPS_DEBUG("%s: cond %02x target " TARGET_FMT_lx, opn,
7122 ctx->hflags, btarget);
7123 ctx->btarget = btarget;
7126 tcg_temp_free_i32(t0);
7129 /* Coprocessor 1 (FPU) */
7131 #define FOP(func, fmt) (((fmt) << 21) | (func))
7134 OPC_ADD_S = FOP(0, FMT_S),
7135 OPC_SUB_S = FOP(1, FMT_S),
7136 OPC_MUL_S = FOP(2, FMT_S),
7137 OPC_DIV_S = FOP(3, FMT_S),
7138 OPC_SQRT_S = FOP(4, FMT_S),
7139 OPC_ABS_S = FOP(5, FMT_S),
7140 OPC_MOV_S = FOP(6, FMT_S),
7141 OPC_NEG_S = FOP(7, FMT_S),
7142 OPC_ROUND_L_S = FOP(8, FMT_S),
7143 OPC_TRUNC_L_S = FOP(9, FMT_S),
7144 OPC_CEIL_L_S = FOP(10, FMT_S),
7145 OPC_FLOOR_L_S = FOP(11, FMT_S),
7146 OPC_ROUND_W_S = FOP(12, FMT_S),
7147 OPC_TRUNC_W_S = FOP(13, FMT_S),
7148 OPC_CEIL_W_S = FOP(14, FMT_S),
7149 OPC_FLOOR_W_S = FOP(15, FMT_S),
7150 OPC_MOVCF_S = FOP(17, FMT_S),
7151 OPC_MOVZ_S = FOP(18, FMT_S),
7152 OPC_MOVN_S = FOP(19, FMT_S),
7153 OPC_RECIP_S = FOP(21, FMT_S),
7154 OPC_RSQRT_S = FOP(22, FMT_S),
7155 OPC_RECIP2_S = FOP(28, FMT_S),
7156 OPC_RECIP1_S = FOP(29, FMT_S),
7157 OPC_RSQRT1_S = FOP(30, FMT_S),
7158 OPC_RSQRT2_S = FOP(31, FMT_S),
7159 OPC_CVT_D_S = FOP(33, FMT_S),
7160 OPC_CVT_W_S = FOP(36, FMT_S),
7161 OPC_CVT_L_S = FOP(37, FMT_S),
7162 OPC_CVT_PS_S = FOP(38, FMT_S),
7163 OPC_CMP_F_S = FOP (48, FMT_S),
7164 OPC_CMP_UN_S = FOP (49, FMT_S),
7165 OPC_CMP_EQ_S = FOP (50, FMT_S),
7166 OPC_CMP_UEQ_S = FOP (51, FMT_S),
7167 OPC_CMP_OLT_S = FOP (52, FMT_S),
7168 OPC_CMP_ULT_S = FOP (53, FMT_S),
7169 OPC_CMP_OLE_S = FOP (54, FMT_S),
7170 OPC_CMP_ULE_S = FOP (55, FMT_S),
7171 OPC_CMP_SF_S = FOP (56, FMT_S),
7172 OPC_CMP_NGLE_S = FOP (57, FMT_S),
7173 OPC_CMP_SEQ_S = FOP (58, FMT_S),
7174 OPC_CMP_NGL_S = FOP (59, FMT_S),
7175 OPC_CMP_LT_S = FOP (60, FMT_S),
7176 OPC_CMP_NGE_S = FOP (61, FMT_S),
7177 OPC_CMP_LE_S = FOP (62, FMT_S),
7178 OPC_CMP_NGT_S = FOP (63, FMT_S),
7180 OPC_ADD_D = FOP(0, FMT_D),
7181 OPC_SUB_D = FOP(1, FMT_D),
7182 OPC_MUL_D = FOP(2, FMT_D),
7183 OPC_DIV_D = FOP(3, FMT_D),
7184 OPC_SQRT_D = FOP(4, FMT_D),
7185 OPC_ABS_D = FOP(5, FMT_D),
7186 OPC_MOV_D = FOP(6, FMT_D),
7187 OPC_NEG_D = FOP(7, FMT_D),
7188 OPC_ROUND_L_D = FOP(8, FMT_D),
7189 OPC_TRUNC_L_D = FOP(9, FMT_D),
7190 OPC_CEIL_L_D = FOP(10, FMT_D),
7191 OPC_FLOOR_L_D = FOP(11, FMT_D),
7192 OPC_ROUND_W_D = FOP(12, FMT_D),
7193 OPC_TRUNC_W_D = FOP(13, FMT_D),
7194 OPC_CEIL_W_D = FOP(14, FMT_D),
7195 OPC_FLOOR_W_D = FOP(15, FMT_D),
7196 OPC_MOVCF_D = FOP(17, FMT_D),
7197 OPC_MOVZ_D = FOP(18, FMT_D),
7198 OPC_MOVN_D = FOP(19, FMT_D),
7199 OPC_RECIP_D = FOP(21, FMT_D),
7200 OPC_RSQRT_D = FOP(22, FMT_D),
7201 OPC_RECIP2_D = FOP(28, FMT_D),
7202 OPC_RECIP1_D = FOP(29, FMT_D),
7203 OPC_RSQRT1_D = FOP(30, FMT_D),
7204 OPC_RSQRT2_D = FOP(31, FMT_D),
7205 OPC_CVT_S_D = FOP(32, FMT_D),
7206 OPC_CVT_W_D = FOP(36, FMT_D),
7207 OPC_CVT_L_D = FOP(37, FMT_D),
7208 OPC_CMP_F_D = FOP (48, FMT_D),
7209 OPC_CMP_UN_D = FOP (49, FMT_D),
7210 OPC_CMP_EQ_D = FOP (50, FMT_D),
7211 OPC_CMP_UEQ_D = FOP (51, FMT_D),
7212 OPC_CMP_OLT_D = FOP (52, FMT_D),
7213 OPC_CMP_ULT_D = FOP (53, FMT_D),
7214 OPC_CMP_OLE_D = FOP (54, FMT_D),
7215 OPC_CMP_ULE_D = FOP (55, FMT_D),
7216 OPC_CMP_SF_D = FOP (56, FMT_D),
7217 OPC_CMP_NGLE_D = FOP (57, FMT_D),
7218 OPC_CMP_SEQ_D = FOP (58, FMT_D),
7219 OPC_CMP_NGL_D = FOP (59, FMT_D),
7220 OPC_CMP_LT_D = FOP (60, FMT_D),
7221 OPC_CMP_NGE_D = FOP (61, FMT_D),
7222 OPC_CMP_LE_D = FOP (62, FMT_D),
7223 OPC_CMP_NGT_D = FOP (63, FMT_D),
7225 OPC_CVT_S_W = FOP(32, FMT_W),
7226 OPC_CVT_D_W = FOP(33, FMT_W),
7227 OPC_CVT_S_L = FOP(32, FMT_L),
7228 OPC_CVT_D_L = FOP(33, FMT_L),
7229 OPC_CVT_PS_PW = FOP(38, FMT_W),
7231 OPC_ADD_PS = FOP(0, FMT_PS),
7232 OPC_SUB_PS = FOP(1, FMT_PS),
7233 OPC_MUL_PS = FOP(2, FMT_PS),
7234 OPC_DIV_PS = FOP(3, FMT_PS),
7235 OPC_ABS_PS = FOP(5, FMT_PS),
7236 OPC_MOV_PS = FOP(6, FMT_PS),
7237 OPC_NEG_PS = FOP(7, FMT_PS),
7238 OPC_MOVCF_PS = FOP(17, FMT_PS),
7239 OPC_MOVZ_PS = FOP(18, FMT_PS),
7240 OPC_MOVN_PS = FOP(19, FMT_PS),
7241 OPC_ADDR_PS = FOP(24, FMT_PS),
7242 OPC_MULR_PS = FOP(26, FMT_PS),
7243 OPC_RECIP2_PS = FOP(28, FMT_PS),
7244 OPC_RECIP1_PS = FOP(29, FMT_PS),
7245 OPC_RSQRT1_PS = FOP(30, FMT_PS),
7246 OPC_RSQRT2_PS = FOP(31, FMT_PS),
7248 OPC_CVT_S_PU = FOP(32, FMT_PS),
7249 OPC_CVT_PW_PS = FOP(36, FMT_PS),
7250 OPC_CVT_S_PL = FOP(40, FMT_PS),
7251 OPC_PLL_PS = FOP(44, FMT_PS),
7252 OPC_PLU_PS = FOP(45, FMT_PS),
7253 OPC_PUL_PS = FOP(46, FMT_PS),
7254 OPC_PUU_PS = FOP(47, FMT_PS),
7255 OPC_CMP_F_PS = FOP (48, FMT_PS),
7256 OPC_CMP_UN_PS = FOP (49, FMT_PS),
7257 OPC_CMP_EQ_PS = FOP (50, FMT_PS),
7258 OPC_CMP_UEQ_PS = FOP (51, FMT_PS),
7259 OPC_CMP_OLT_PS = FOP (52, FMT_PS),
7260 OPC_CMP_ULT_PS = FOP (53, FMT_PS),
7261 OPC_CMP_OLE_PS = FOP (54, FMT_PS),
7262 OPC_CMP_ULE_PS = FOP (55, FMT_PS),
7263 OPC_CMP_SF_PS = FOP (56, FMT_PS),
7264 OPC_CMP_NGLE_PS = FOP (57, FMT_PS),
7265 OPC_CMP_SEQ_PS = FOP (58, FMT_PS),
7266 OPC_CMP_NGL_PS = FOP (59, FMT_PS),
7267 OPC_CMP_LT_PS = FOP (60, FMT_PS),
7268 OPC_CMP_NGE_PS = FOP (61, FMT_PS),
7269 OPC_CMP_LE_PS = FOP (62, FMT_PS),
7270 OPC_CMP_NGT_PS = FOP (63, FMT_PS),
7273 static void gen_cp1 (DisasContext *ctx, uint32_t opc, int rt, int fs)
7275 const char *opn = "cp1 move";
7276 TCGv t0 = tcg_temp_new();
7281 TCGv_i32 fp0 = tcg_temp_new_i32();
7283 gen_load_fpr32(fp0, fs);
7284 tcg_gen_ext_i32_tl(t0, fp0);
7285 tcg_temp_free_i32(fp0);
7287 gen_store_gpr(t0, rt);
7291 gen_load_gpr(t0, rt);
7293 TCGv_i32 fp0 = tcg_temp_new_i32();
7295 tcg_gen_trunc_tl_i32(fp0, t0);
7296 gen_store_fpr32(fp0, fs);
7297 tcg_temp_free_i32(fp0);
7302 gen_helper_1e0i(cfc1, t0, fs);
7303 gen_store_gpr(t0, rt);
7307 gen_load_gpr(t0, rt);
7308 gen_helper_0e1i(ctc1, t0, fs);
7311 #if defined(TARGET_MIPS64)
7313 gen_load_fpr64(ctx, t0, fs);
7314 gen_store_gpr(t0, rt);
7318 gen_load_gpr(t0, rt);
7319 gen_store_fpr64(ctx, t0, fs);
7325 TCGv_i32 fp0 = tcg_temp_new_i32();
7327 gen_load_fpr32h(fp0, fs);
7328 tcg_gen_ext_i32_tl(t0, fp0);
7329 tcg_temp_free_i32(fp0);
7331 gen_store_gpr(t0, rt);
7335 gen_load_gpr(t0, rt);
7337 TCGv_i32 fp0 = tcg_temp_new_i32();
7339 tcg_gen_trunc_tl_i32(fp0, t0);
7340 gen_store_fpr32h(fp0, fs);
7341 tcg_temp_free_i32(fp0);
7347 generate_exception (ctx, EXCP_RI);
7350 (void)opn; /* avoid a compiler warning */
7351 MIPS_DEBUG("%s %s %s", opn, regnames[rt], fregnames[fs]);
7357 static void gen_movci (DisasContext *ctx, int rd, int rs, int cc, int tf)
7373 l1 = gen_new_label();
7374 t0 = tcg_temp_new_i32();
7375 tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc));
7376 tcg_gen_brcondi_i32(cond, t0, 0, l1);
7377 tcg_temp_free_i32(t0);
7379 tcg_gen_movi_tl(cpu_gpr[rd], 0);
7381 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
7386 static inline void gen_movcf_s (int fs, int fd, int cc, int tf)
7389 TCGv_i32 t0 = tcg_temp_new_i32();
7390 int l1 = gen_new_label();
7397 tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc));
7398 tcg_gen_brcondi_i32(cond, t0, 0, l1);
7399 gen_load_fpr32(t0, fs);
7400 gen_store_fpr32(t0, fd);
7402 tcg_temp_free_i32(t0);
7405 static inline void gen_movcf_d (DisasContext *ctx, int fs, int fd, int cc, int tf)
7408 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 tcg_temp_free_i32(t0);
7420 fp0 = tcg_temp_new_i64();
7421 gen_load_fpr64(ctx, fp0, fs);
7422 gen_store_fpr64(ctx, fp0, fd);
7423 tcg_temp_free_i64(fp0);
7427 static inline void gen_movcf_ps (int fs, int fd, int cc, int tf)
7430 TCGv_i32 t0 = tcg_temp_new_i32();
7431 int l1 = gen_new_label();
7432 int l2 = gen_new_label();
7439 tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc));
7440 tcg_gen_brcondi_i32(cond, t0, 0, l1);
7441 gen_load_fpr32(t0, fs);
7442 gen_store_fpr32(t0, fd);
7445 tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc+1));
7446 tcg_gen_brcondi_i32(cond, t0, 0, l2);
7447 gen_load_fpr32h(t0, fs);
7448 gen_store_fpr32h(t0, fd);
7449 tcg_temp_free_i32(t0);
7454 static void gen_farith (DisasContext *ctx, enum fopcode op1,
7455 int ft, int fs, int fd, int cc)
7457 const char *opn = "farith";
7458 const char *condnames[] = {
7476 const char *condnames_abs[] = {
7494 enum { BINOP, CMPOP, OTHEROP } optype = OTHEROP;
7495 uint32_t func = ctx->opcode & 0x3f;
7500 TCGv_i32 fp0 = tcg_temp_new_i32();
7501 TCGv_i32 fp1 = tcg_temp_new_i32();
7503 gen_load_fpr32(fp0, fs);
7504 gen_load_fpr32(fp1, ft);
7505 gen_helper_float_add_s(fp0, cpu_env, fp0, fp1);
7506 tcg_temp_free_i32(fp1);
7507 gen_store_fpr32(fp0, fd);
7508 tcg_temp_free_i32(fp0);
7515 TCGv_i32 fp0 = tcg_temp_new_i32();
7516 TCGv_i32 fp1 = tcg_temp_new_i32();
7518 gen_load_fpr32(fp0, fs);
7519 gen_load_fpr32(fp1, ft);
7520 gen_helper_float_sub_s(fp0, cpu_env, fp0, fp1);
7521 tcg_temp_free_i32(fp1);
7522 gen_store_fpr32(fp0, fd);
7523 tcg_temp_free_i32(fp0);
7530 TCGv_i32 fp0 = tcg_temp_new_i32();
7531 TCGv_i32 fp1 = tcg_temp_new_i32();
7533 gen_load_fpr32(fp0, fs);
7534 gen_load_fpr32(fp1, ft);
7535 gen_helper_float_mul_s(fp0, cpu_env, fp0, fp1);
7536 tcg_temp_free_i32(fp1);
7537 gen_store_fpr32(fp0, fd);
7538 tcg_temp_free_i32(fp0);
7545 TCGv_i32 fp0 = tcg_temp_new_i32();
7546 TCGv_i32 fp1 = tcg_temp_new_i32();
7548 gen_load_fpr32(fp0, fs);
7549 gen_load_fpr32(fp1, ft);
7550 gen_helper_float_div_s(fp0, cpu_env, fp0, fp1);
7551 tcg_temp_free_i32(fp1);
7552 gen_store_fpr32(fp0, fd);
7553 tcg_temp_free_i32(fp0);
7560 TCGv_i32 fp0 = tcg_temp_new_i32();
7562 gen_load_fpr32(fp0, fs);
7563 gen_helper_float_sqrt_s(fp0, cpu_env, fp0);
7564 gen_store_fpr32(fp0, fd);
7565 tcg_temp_free_i32(fp0);
7571 TCGv_i32 fp0 = tcg_temp_new_i32();
7573 gen_load_fpr32(fp0, fs);
7574 gen_helper_float_abs_s(fp0, fp0);
7575 gen_store_fpr32(fp0, fd);
7576 tcg_temp_free_i32(fp0);
7582 TCGv_i32 fp0 = tcg_temp_new_i32();
7584 gen_load_fpr32(fp0, fs);
7585 gen_store_fpr32(fp0, fd);
7586 tcg_temp_free_i32(fp0);
7592 TCGv_i32 fp0 = tcg_temp_new_i32();
7594 gen_load_fpr32(fp0, fs);
7595 gen_helper_float_chs_s(fp0, fp0);
7596 gen_store_fpr32(fp0, fd);
7597 tcg_temp_free_i32(fp0);
7602 check_cp1_64bitmode(ctx);
7604 TCGv_i32 fp32 = tcg_temp_new_i32();
7605 TCGv_i64 fp64 = tcg_temp_new_i64();
7607 gen_load_fpr32(fp32, fs);
7608 gen_helper_float_roundl_s(fp64, cpu_env, fp32);
7609 tcg_temp_free_i32(fp32);
7610 gen_store_fpr64(ctx, fp64, fd);
7611 tcg_temp_free_i64(fp64);
7616 check_cp1_64bitmode(ctx);
7618 TCGv_i32 fp32 = tcg_temp_new_i32();
7619 TCGv_i64 fp64 = tcg_temp_new_i64();
7621 gen_load_fpr32(fp32, fs);
7622 gen_helper_float_truncl_s(fp64, cpu_env, fp32);
7623 tcg_temp_free_i32(fp32);
7624 gen_store_fpr64(ctx, fp64, fd);
7625 tcg_temp_free_i64(fp64);
7630 check_cp1_64bitmode(ctx);
7632 TCGv_i32 fp32 = tcg_temp_new_i32();
7633 TCGv_i64 fp64 = tcg_temp_new_i64();
7635 gen_load_fpr32(fp32, fs);
7636 gen_helper_float_ceill_s(fp64, cpu_env, fp32);
7637 tcg_temp_free_i32(fp32);
7638 gen_store_fpr64(ctx, fp64, fd);
7639 tcg_temp_free_i64(fp64);
7644 check_cp1_64bitmode(ctx);
7646 TCGv_i32 fp32 = tcg_temp_new_i32();
7647 TCGv_i64 fp64 = tcg_temp_new_i64();
7649 gen_load_fpr32(fp32, fs);
7650 gen_helper_float_floorl_s(fp64, cpu_env, fp32);
7651 tcg_temp_free_i32(fp32);
7652 gen_store_fpr64(ctx, fp64, fd);
7653 tcg_temp_free_i64(fp64);
7659 TCGv_i32 fp0 = tcg_temp_new_i32();
7661 gen_load_fpr32(fp0, fs);
7662 gen_helper_float_roundw_s(fp0, cpu_env, fp0);
7663 gen_store_fpr32(fp0, fd);
7664 tcg_temp_free_i32(fp0);
7670 TCGv_i32 fp0 = tcg_temp_new_i32();
7672 gen_load_fpr32(fp0, fs);
7673 gen_helper_float_truncw_s(fp0, cpu_env, fp0);
7674 gen_store_fpr32(fp0, fd);
7675 tcg_temp_free_i32(fp0);
7681 TCGv_i32 fp0 = tcg_temp_new_i32();
7683 gen_load_fpr32(fp0, fs);
7684 gen_helper_float_ceilw_s(fp0, cpu_env, fp0);
7685 gen_store_fpr32(fp0, fd);
7686 tcg_temp_free_i32(fp0);
7692 TCGv_i32 fp0 = tcg_temp_new_i32();
7694 gen_load_fpr32(fp0, fs);
7695 gen_helper_float_floorw_s(fp0, cpu_env, fp0);
7696 gen_store_fpr32(fp0, fd);
7697 tcg_temp_free_i32(fp0);
7702 gen_movcf_s(fs, fd, (ft >> 2) & 0x7, ft & 0x1);
7707 int l1 = gen_new_label();
7711 tcg_gen_brcondi_tl(TCG_COND_NE, cpu_gpr[ft], 0, l1);
7713 fp0 = tcg_temp_new_i32();
7714 gen_load_fpr32(fp0, fs);
7715 gen_store_fpr32(fp0, fd);
7716 tcg_temp_free_i32(fp0);
7723 int l1 = gen_new_label();
7727 tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_gpr[ft], 0, l1);
7728 fp0 = tcg_temp_new_i32();
7729 gen_load_fpr32(fp0, fs);
7730 gen_store_fpr32(fp0, fd);
7731 tcg_temp_free_i32(fp0);
7740 TCGv_i32 fp0 = tcg_temp_new_i32();
7742 gen_load_fpr32(fp0, fs);
7743 gen_helper_float_recip_s(fp0, cpu_env, fp0);
7744 gen_store_fpr32(fp0, fd);
7745 tcg_temp_free_i32(fp0);
7752 TCGv_i32 fp0 = tcg_temp_new_i32();
7754 gen_load_fpr32(fp0, fs);
7755 gen_helper_float_rsqrt_s(fp0, cpu_env, fp0);
7756 gen_store_fpr32(fp0, fd);
7757 tcg_temp_free_i32(fp0);
7762 check_cp1_64bitmode(ctx);
7764 TCGv_i32 fp0 = tcg_temp_new_i32();
7765 TCGv_i32 fp1 = tcg_temp_new_i32();
7767 gen_load_fpr32(fp0, fs);
7768 gen_load_fpr32(fp1, ft);
7769 gen_helper_float_recip2_s(fp0, cpu_env, fp0, fp1);
7770 tcg_temp_free_i32(fp1);
7771 gen_store_fpr32(fp0, fd);
7772 tcg_temp_free_i32(fp0);
7777 check_cp1_64bitmode(ctx);
7779 TCGv_i32 fp0 = tcg_temp_new_i32();
7781 gen_load_fpr32(fp0, fs);
7782 gen_helper_float_recip1_s(fp0, cpu_env, fp0);
7783 gen_store_fpr32(fp0, fd);
7784 tcg_temp_free_i32(fp0);
7789 check_cp1_64bitmode(ctx);
7791 TCGv_i32 fp0 = tcg_temp_new_i32();
7793 gen_load_fpr32(fp0, fs);
7794 gen_helper_float_rsqrt1_s(fp0, cpu_env, fp0);
7795 gen_store_fpr32(fp0, fd);
7796 tcg_temp_free_i32(fp0);
7801 check_cp1_64bitmode(ctx);
7803 TCGv_i32 fp0 = tcg_temp_new_i32();
7804 TCGv_i32 fp1 = tcg_temp_new_i32();
7806 gen_load_fpr32(fp0, fs);
7807 gen_load_fpr32(fp1, ft);
7808 gen_helper_float_rsqrt2_s(fp0, cpu_env, fp0, fp1);
7809 tcg_temp_free_i32(fp1);
7810 gen_store_fpr32(fp0, fd);
7811 tcg_temp_free_i32(fp0);
7816 check_cp1_registers(ctx, fd);
7818 TCGv_i32 fp32 = tcg_temp_new_i32();
7819 TCGv_i64 fp64 = tcg_temp_new_i64();
7821 gen_load_fpr32(fp32, fs);
7822 gen_helper_float_cvtd_s(fp64, cpu_env, fp32);
7823 tcg_temp_free_i32(fp32);
7824 gen_store_fpr64(ctx, fp64, fd);
7825 tcg_temp_free_i64(fp64);
7831 TCGv_i32 fp0 = tcg_temp_new_i32();
7833 gen_load_fpr32(fp0, fs);
7834 gen_helper_float_cvtw_s(fp0, cpu_env, fp0);
7835 gen_store_fpr32(fp0, fd);
7836 tcg_temp_free_i32(fp0);
7841 check_cp1_64bitmode(ctx);
7843 TCGv_i32 fp32 = tcg_temp_new_i32();
7844 TCGv_i64 fp64 = tcg_temp_new_i64();
7846 gen_load_fpr32(fp32, fs);
7847 gen_helper_float_cvtl_s(fp64, cpu_env, fp32);
7848 tcg_temp_free_i32(fp32);
7849 gen_store_fpr64(ctx, fp64, fd);
7850 tcg_temp_free_i64(fp64);
7855 check_cp1_64bitmode(ctx);
7857 TCGv_i64 fp64 = tcg_temp_new_i64();
7858 TCGv_i32 fp32_0 = tcg_temp_new_i32();
7859 TCGv_i32 fp32_1 = tcg_temp_new_i32();
7861 gen_load_fpr32(fp32_0, fs);
7862 gen_load_fpr32(fp32_1, ft);
7863 tcg_gen_concat_i32_i64(fp64, fp32_1, fp32_0);
7864 tcg_temp_free_i32(fp32_1);
7865 tcg_temp_free_i32(fp32_0);
7866 gen_store_fpr64(ctx, fp64, fd);
7867 tcg_temp_free_i64(fp64);
7880 case OPC_CMP_NGLE_S:
7887 if (ctx->opcode & (1 << 6)) {
7888 gen_cmpabs_s(ctx, func-48, ft, fs, cc);
7889 opn = condnames_abs[func-48];
7891 gen_cmp_s(ctx, func-48, ft, fs, cc);
7892 opn = condnames[func-48];
7896 check_cp1_registers(ctx, fs | ft | fd);
7898 TCGv_i64 fp0 = tcg_temp_new_i64();
7899 TCGv_i64 fp1 = tcg_temp_new_i64();
7901 gen_load_fpr64(ctx, fp0, fs);
7902 gen_load_fpr64(ctx, fp1, ft);
7903 gen_helper_float_add_d(fp0, cpu_env, fp0, fp1);
7904 tcg_temp_free_i64(fp1);
7905 gen_store_fpr64(ctx, fp0, fd);
7906 tcg_temp_free_i64(fp0);
7912 check_cp1_registers(ctx, fs | ft | fd);
7914 TCGv_i64 fp0 = tcg_temp_new_i64();
7915 TCGv_i64 fp1 = tcg_temp_new_i64();
7917 gen_load_fpr64(ctx, fp0, fs);
7918 gen_load_fpr64(ctx, fp1, ft);
7919 gen_helper_float_sub_d(fp0, cpu_env, fp0, fp1);
7920 tcg_temp_free_i64(fp1);
7921 gen_store_fpr64(ctx, fp0, fd);
7922 tcg_temp_free_i64(fp0);
7928 check_cp1_registers(ctx, fs | ft | fd);
7930 TCGv_i64 fp0 = tcg_temp_new_i64();
7931 TCGv_i64 fp1 = tcg_temp_new_i64();
7933 gen_load_fpr64(ctx, fp0, fs);
7934 gen_load_fpr64(ctx, fp1, ft);
7935 gen_helper_float_mul_d(fp0, cpu_env, fp0, fp1);
7936 tcg_temp_free_i64(fp1);
7937 gen_store_fpr64(ctx, fp0, fd);
7938 tcg_temp_free_i64(fp0);
7944 check_cp1_registers(ctx, fs | ft | fd);
7946 TCGv_i64 fp0 = tcg_temp_new_i64();
7947 TCGv_i64 fp1 = tcg_temp_new_i64();
7949 gen_load_fpr64(ctx, fp0, fs);
7950 gen_load_fpr64(ctx, fp1, ft);
7951 gen_helper_float_div_d(fp0, cpu_env, fp0, fp1);
7952 tcg_temp_free_i64(fp1);
7953 gen_store_fpr64(ctx, fp0, fd);
7954 tcg_temp_free_i64(fp0);
7960 check_cp1_registers(ctx, fs | fd);
7962 TCGv_i64 fp0 = tcg_temp_new_i64();
7964 gen_load_fpr64(ctx, fp0, fs);
7965 gen_helper_float_sqrt_d(fp0, cpu_env, fp0);
7966 gen_store_fpr64(ctx, fp0, fd);
7967 tcg_temp_free_i64(fp0);
7972 check_cp1_registers(ctx, fs | fd);
7974 TCGv_i64 fp0 = tcg_temp_new_i64();
7976 gen_load_fpr64(ctx, fp0, fs);
7977 gen_helper_float_abs_d(fp0, fp0);
7978 gen_store_fpr64(ctx, fp0, fd);
7979 tcg_temp_free_i64(fp0);
7984 check_cp1_registers(ctx, fs | fd);
7986 TCGv_i64 fp0 = tcg_temp_new_i64();
7988 gen_load_fpr64(ctx, fp0, fs);
7989 gen_store_fpr64(ctx, fp0, fd);
7990 tcg_temp_free_i64(fp0);
7995 check_cp1_registers(ctx, fs | fd);
7997 TCGv_i64 fp0 = tcg_temp_new_i64();
7999 gen_load_fpr64(ctx, fp0, fs);
8000 gen_helper_float_chs_d(fp0, fp0);
8001 gen_store_fpr64(ctx, fp0, fd);
8002 tcg_temp_free_i64(fp0);
8007 check_cp1_64bitmode(ctx);
8009 TCGv_i64 fp0 = tcg_temp_new_i64();
8011 gen_load_fpr64(ctx, fp0, fs);
8012 gen_helper_float_roundl_d(fp0, cpu_env, fp0);
8013 gen_store_fpr64(ctx, fp0, fd);
8014 tcg_temp_free_i64(fp0);
8019 check_cp1_64bitmode(ctx);
8021 TCGv_i64 fp0 = tcg_temp_new_i64();
8023 gen_load_fpr64(ctx, fp0, fs);
8024 gen_helper_float_truncl_d(fp0, cpu_env, fp0);
8025 gen_store_fpr64(ctx, fp0, fd);
8026 tcg_temp_free_i64(fp0);
8031 check_cp1_64bitmode(ctx);
8033 TCGv_i64 fp0 = tcg_temp_new_i64();
8035 gen_load_fpr64(ctx, fp0, fs);
8036 gen_helper_float_ceill_d(fp0, cpu_env, fp0);
8037 gen_store_fpr64(ctx, fp0, fd);
8038 tcg_temp_free_i64(fp0);
8043 check_cp1_64bitmode(ctx);
8045 TCGv_i64 fp0 = tcg_temp_new_i64();
8047 gen_load_fpr64(ctx, fp0, fs);
8048 gen_helper_float_floorl_d(fp0, cpu_env, fp0);
8049 gen_store_fpr64(ctx, fp0, fd);
8050 tcg_temp_free_i64(fp0);
8055 check_cp1_registers(ctx, fs);
8057 TCGv_i32 fp32 = tcg_temp_new_i32();
8058 TCGv_i64 fp64 = tcg_temp_new_i64();
8060 gen_load_fpr64(ctx, fp64, fs);
8061 gen_helper_float_roundw_d(fp32, cpu_env, fp64);
8062 tcg_temp_free_i64(fp64);
8063 gen_store_fpr32(fp32, fd);
8064 tcg_temp_free_i32(fp32);
8069 check_cp1_registers(ctx, fs);
8071 TCGv_i32 fp32 = tcg_temp_new_i32();
8072 TCGv_i64 fp64 = tcg_temp_new_i64();
8074 gen_load_fpr64(ctx, fp64, fs);
8075 gen_helper_float_truncw_d(fp32, cpu_env, fp64);
8076 tcg_temp_free_i64(fp64);
8077 gen_store_fpr32(fp32, fd);
8078 tcg_temp_free_i32(fp32);
8083 check_cp1_registers(ctx, fs);
8085 TCGv_i32 fp32 = tcg_temp_new_i32();
8086 TCGv_i64 fp64 = tcg_temp_new_i64();
8088 gen_load_fpr64(ctx, fp64, fs);
8089 gen_helper_float_ceilw_d(fp32, cpu_env, fp64);
8090 tcg_temp_free_i64(fp64);
8091 gen_store_fpr32(fp32, fd);
8092 tcg_temp_free_i32(fp32);
8097 check_cp1_registers(ctx, fs);
8099 TCGv_i32 fp32 = tcg_temp_new_i32();
8100 TCGv_i64 fp64 = tcg_temp_new_i64();
8102 gen_load_fpr64(ctx, fp64, fs);
8103 gen_helper_float_floorw_d(fp32, cpu_env, fp64);
8104 tcg_temp_free_i64(fp64);
8105 gen_store_fpr32(fp32, fd);
8106 tcg_temp_free_i32(fp32);
8111 gen_movcf_d(ctx, fs, fd, (ft >> 2) & 0x7, ft & 0x1);
8116 int l1 = gen_new_label();
8120 tcg_gen_brcondi_tl(TCG_COND_NE, cpu_gpr[ft], 0, l1);
8122 fp0 = tcg_temp_new_i64();
8123 gen_load_fpr64(ctx, fp0, fs);
8124 gen_store_fpr64(ctx, fp0, fd);
8125 tcg_temp_free_i64(fp0);
8132 int l1 = gen_new_label();
8136 tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_gpr[ft], 0, l1);
8137 fp0 = tcg_temp_new_i64();
8138 gen_load_fpr64(ctx, fp0, fs);
8139 gen_store_fpr64(ctx, fp0, fd);
8140 tcg_temp_free_i64(fp0);
8147 check_cp1_64bitmode(ctx);
8149 TCGv_i64 fp0 = tcg_temp_new_i64();
8151 gen_load_fpr64(ctx, fp0, fs);
8152 gen_helper_float_recip_d(fp0, cpu_env, fp0);
8153 gen_store_fpr64(ctx, fp0, fd);
8154 tcg_temp_free_i64(fp0);
8159 check_cp1_64bitmode(ctx);
8161 TCGv_i64 fp0 = tcg_temp_new_i64();
8163 gen_load_fpr64(ctx, fp0, fs);
8164 gen_helper_float_rsqrt_d(fp0, cpu_env, fp0);
8165 gen_store_fpr64(ctx, fp0, fd);
8166 tcg_temp_free_i64(fp0);
8171 check_cp1_64bitmode(ctx);
8173 TCGv_i64 fp0 = tcg_temp_new_i64();
8174 TCGv_i64 fp1 = tcg_temp_new_i64();
8176 gen_load_fpr64(ctx, fp0, fs);
8177 gen_load_fpr64(ctx, fp1, ft);
8178 gen_helper_float_recip2_d(fp0, cpu_env, fp0, fp1);
8179 tcg_temp_free_i64(fp1);
8180 gen_store_fpr64(ctx, fp0, fd);
8181 tcg_temp_free_i64(fp0);
8186 check_cp1_64bitmode(ctx);
8188 TCGv_i64 fp0 = tcg_temp_new_i64();
8190 gen_load_fpr64(ctx, fp0, fs);
8191 gen_helper_float_recip1_d(fp0, cpu_env, fp0);
8192 gen_store_fpr64(ctx, fp0, fd);
8193 tcg_temp_free_i64(fp0);
8198 check_cp1_64bitmode(ctx);
8200 TCGv_i64 fp0 = tcg_temp_new_i64();
8202 gen_load_fpr64(ctx, fp0, fs);
8203 gen_helper_float_rsqrt1_d(fp0, cpu_env, fp0);
8204 gen_store_fpr64(ctx, fp0, fd);
8205 tcg_temp_free_i64(fp0);
8210 check_cp1_64bitmode(ctx);
8212 TCGv_i64 fp0 = tcg_temp_new_i64();
8213 TCGv_i64 fp1 = tcg_temp_new_i64();
8215 gen_load_fpr64(ctx, fp0, fs);
8216 gen_load_fpr64(ctx, fp1, ft);
8217 gen_helper_float_rsqrt2_d(fp0, cpu_env, fp0, fp1);
8218 tcg_temp_free_i64(fp1);
8219 gen_store_fpr64(ctx, fp0, fd);
8220 tcg_temp_free_i64(fp0);
8233 case OPC_CMP_NGLE_D:
8240 if (ctx->opcode & (1 << 6)) {
8241 gen_cmpabs_d(ctx, func-48, ft, fs, cc);
8242 opn = condnames_abs[func-48];
8244 gen_cmp_d(ctx, func-48, ft, fs, cc);
8245 opn = condnames[func-48];
8249 check_cp1_registers(ctx, fs);
8251 TCGv_i32 fp32 = tcg_temp_new_i32();
8252 TCGv_i64 fp64 = tcg_temp_new_i64();
8254 gen_load_fpr64(ctx, fp64, fs);
8255 gen_helper_float_cvts_d(fp32, cpu_env, fp64);
8256 tcg_temp_free_i64(fp64);
8257 gen_store_fpr32(fp32, fd);
8258 tcg_temp_free_i32(fp32);
8263 check_cp1_registers(ctx, fs);
8265 TCGv_i32 fp32 = tcg_temp_new_i32();
8266 TCGv_i64 fp64 = tcg_temp_new_i64();
8268 gen_load_fpr64(ctx, fp64, fs);
8269 gen_helper_float_cvtw_d(fp32, cpu_env, fp64);
8270 tcg_temp_free_i64(fp64);
8271 gen_store_fpr32(fp32, fd);
8272 tcg_temp_free_i32(fp32);
8277 check_cp1_64bitmode(ctx);
8279 TCGv_i64 fp0 = tcg_temp_new_i64();
8281 gen_load_fpr64(ctx, fp0, fs);
8282 gen_helper_float_cvtl_d(fp0, cpu_env, fp0);
8283 gen_store_fpr64(ctx, fp0, fd);
8284 tcg_temp_free_i64(fp0);
8290 TCGv_i32 fp0 = tcg_temp_new_i32();
8292 gen_load_fpr32(fp0, fs);
8293 gen_helper_float_cvts_w(fp0, cpu_env, fp0);
8294 gen_store_fpr32(fp0, fd);
8295 tcg_temp_free_i32(fp0);
8300 check_cp1_registers(ctx, fd);
8302 TCGv_i32 fp32 = tcg_temp_new_i32();
8303 TCGv_i64 fp64 = tcg_temp_new_i64();
8305 gen_load_fpr32(fp32, fs);
8306 gen_helper_float_cvtd_w(fp64, cpu_env, fp32);
8307 tcg_temp_free_i32(fp32);
8308 gen_store_fpr64(ctx, fp64, fd);
8309 tcg_temp_free_i64(fp64);
8314 check_cp1_64bitmode(ctx);
8316 TCGv_i32 fp32 = tcg_temp_new_i32();
8317 TCGv_i64 fp64 = tcg_temp_new_i64();
8319 gen_load_fpr64(ctx, fp64, fs);
8320 gen_helper_float_cvts_l(fp32, cpu_env, fp64);
8321 tcg_temp_free_i64(fp64);
8322 gen_store_fpr32(fp32, fd);
8323 tcg_temp_free_i32(fp32);
8328 check_cp1_64bitmode(ctx);
8330 TCGv_i64 fp0 = tcg_temp_new_i64();
8332 gen_load_fpr64(ctx, fp0, fs);
8333 gen_helper_float_cvtd_l(fp0, cpu_env, fp0);
8334 gen_store_fpr64(ctx, fp0, fd);
8335 tcg_temp_free_i64(fp0);
8340 check_cp1_64bitmode(ctx);
8342 TCGv_i64 fp0 = tcg_temp_new_i64();
8344 gen_load_fpr64(ctx, fp0, fs);
8345 gen_helper_float_cvtps_pw(fp0, cpu_env, fp0);
8346 gen_store_fpr64(ctx, fp0, fd);
8347 tcg_temp_free_i64(fp0);
8352 check_cp1_64bitmode(ctx);
8354 TCGv_i64 fp0 = tcg_temp_new_i64();
8355 TCGv_i64 fp1 = tcg_temp_new_i64();
8357 gen_load_fpr64(ctx, fp0, fs);
8358 gen_load_fpr64(ctx, fp1, ft);
8359 gen_helper_float_add_ps(fp0, cpu_env, fp0, fp1);
8360 tcg_temp_free_i64(fp1);
8361 gen_store_fpr64(ctx, fp0, fd);
8362 tcg_temp_free_i64(fp0);
8367 check_cp1_64bitmode(ctx);
8369 TCGv_i64 fp0 = tcg_temp_new_i64();
8370 TCGv_i64 fp1 = tcg_temp_new_i64();
8372 gen_load_fpr64(ctx, fp0, fs);
8373 gen_load_fpr64(ctx, fp1, ft);
8374 gen_helper_float_sub_ps(fp0, cpu_env, fp0, fp1);
8375 tcg_temp_free_i64(fp1);
8376 gen_store_fpr64(ctx, fp0, fd);
8377 tcg_temp_free_i64(fp0);
8382 check_cp1_64bitmode(ctx);
8384 TCGv_i64 fp0 = tcg_temp_new_i64();
8385 TCGv_i64 fp1 = tcg_temp_new_i64();
8387 gen_load_fpr64(ctx, fp0, fs);
8388 gen_load_fpr64(ctx, fp1, ft);
8389 gen_helper_float_mul_ps(fp0, cpu_env, fp0, fp1);
8390 tcg_temp_free_i64(fp1);
8391 gen_store_fpr64(ctx, fp0, fd);
8392 tcg_temp_free_i64(fp0);
8397 check_cp1_64bitmode(ctx);
8399 TCGv_i64 fp0 = tcg_temp_new_i64();
8401 gen_load_fpr64(ctx, fp0, fs);
8402 gen_helper_float_abs_ps(fp0, fp0);
8403 gen_store_fpr64(ctx, fp0, fd);
8404 tcg_temp_free_i64(fp0);
8409 check_cp1_64bitmode(ctx);
8411 TCGv_i64 fp0 = tcg_temp_new_i64();
8413 gen_load_fpr64(ctx, fp0, fs);
8414 gen_store_fpr64(ctx, fp0, fd);
8415 tcg_temp_free_i64(fp0);
8420 check_cp1_64bitmode(ctx);
8422 TCGv_i64 fp0 = tcg_temp_new_i64();
8424 gen_load_fpr64(ctx, fp0, fs);
8425 gen_helper_float_chs_ps(fp0, fp0);
8426 gen_store_fpr64(ctx, fp0, fd);
8427 tcg_temp_free_i64(fp0);
8432 check_cp1_64bitmode(ctx);
8433 gen_movcf_ps(fs, fd, (ft >> 2) & 0x7, ft & 0x1);
8437 check_cp1_64bitmode(ctx);
8439 int l1 = gen_new_label();
8443 tcg_gen_brcondi_tl(TCG_COND_NE, cpu_gpr[ft], 0, l1);
8444 fp0 = tcg_temp_new_i64();
8445 gen_load_fpr64(ctx, fp0, fs);
8446 gen_store_fpr64(ctx, fp0, fd);
8447 tcg_temp_free_i64(fp0);
8453 check_cp1_64bitmode(ctx);
8455 int l1 = gen_new_label();
8459 tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_gpr[ft], 0, l1);
8460 fp0 = tcg_temp_new_i64();
8461 gen_load_fpr64(ctx, fp0, fs);
8462 gen_store_fpr64(ctx, fp0, fd);
8463 tcg_temp_free_i64(fp0);
8470 check_cp1_64bitmode(ctx);
8472 TCGv_i64 fp0 = tcg_temp_new_i64();
8473 TCGv_i64 fp1 = tcg_temp_new_i64();
8475 gen_load_fpr64(ctx, fp0, ft);
8476 gen_load_fpr64(ctx, fp1, fs);
8477 gen_helper_float_addr_ps(fp0, cpu_env, fp0, fp1);
8478 tcg_temp_free_i64(fp1);
8479 gen_store_fpr64(ctx, fp0, fd);
8480 tcg_temp_free_i64(fp0);
8485 check_cp1_64bitmode(ctx);
8487 TCGv_i64 fp0 = tcg_temp_new_i64();
8488 TCGv_i64 fp1 = tcg_temp_new_i64();
8490 gen_load_fpr64(ctx, fp0, ft);
8491 gen_load_fpr64(ctx, fp1, fs);
8492 gen_helper_float_mulr_ps(fp0, cpu_env, fp0, fp1);
8493 tcg_temp_free_i64(fp1);
8494 gen_store_fpr64(ctx, fp0, fd);
8495 tcg_temp_free_i64(fp0);
8500 check_cp1_64bitmode(ctx);
8502 TCGv_i64 fp0 = tcg_temp_new_i64();
8503 TCGv_i64 fp1 = tcg_temp_new_i64();
8505 gen_load_fpr64(ctx, fp0, fs);
8506 gen_load_fpr64(ctx, fp1, ft);
8507 gen_helper_float_recip2_ps(fp0, cpu_env, fp0, fp1);
8508 tcg_temp_free_i64(fp1);
8509 gen_store_fpr64(ctx, fp0, fd);
8510 tcg_temp_free_i64(fp0);
8515 check_cp1_64bitmode(ctx);
8517 TCGv_i64 fp0 = tcg_temp_new_i64();
8519 gen_load_fpr64(ctx, fp0, fs);
8520 gen_helper_float_recip1_ps(fp0, cpu_env, fp0);
8521 gen_store_fpr64(ctx, fp0, fd);
8522 tcg_temp_free_i64(fp0);
8527 check_cp1_64bitmode(ctx);
8529 TCGv_i64 fp0 = tcg_temp_new_i64();
8531 gen_load_fpr64(ctx, fp0, fs);
8532 gen_helper_float_rsqrt1_ps(fp0, cpu_env, fp0);
8533 gen_store_fpr64(ctx, fp0, fd);
8534 tcg_temp_free_i64(fp0);
8539 check_cp1_64bitmode(ctx);
8541 TCGv_i64 fp0 = tcg_temp_new_i64();
8542 TCGv_i64 fp1 = tcg_temp_new_i64();
8544 gen_load_fpr64(ctx, fp0, fs);
8545 gen_load_fpr64(ctx, fp1, ft);
8546 gen_helper_float_rsqrt2_ps(fp0, cpu_env, fp0, fp1);
8547 tcg_temp_free_i64(fp1);
8548 gen_store_fpr64(ctx, fp0, fd);
8549 tcg_temp_free_i64(fp0);
8554 check_cp1_64bitmode(ctx);
8556 TCGv_i32 fp0 = tcg_temp_new_i32();
8558 gen_load_fpr32h(fp0, fs);
8559 gen_helper_float_cvts_pu(fp0, cpu_env, fp0);
8560 gen_store_fpr32(fp0, fd);
8561 tcg_temp_free_i32(fp0);
8566 check_cp1_64bitmode(ctx);
8568 TCGv_i64 fp0 = tcg_temp_new_i64();
8570 gen_load_fpr64(ctx, fp0, fs);
8571 gen_helper_float_cvtpw_ps(fp0, cpu_env, fp0);
8572 gen_store_fpr64(ctx, fp0, fd);
8573 tcg_temp_free_i64(fp0);
8578 check_cp1_64bitmode(ctx);
8580 TCGv_i32 fp0 = tcg_temp_new_i32();
8582 gen_load_fpr32(fp0, fs);
8583 gen_helper_float_cvts_pl(fp0, cpu_env, fp0);
8584 gen_store_fpr32(fp0, fd);
8585 tcg_temp_free_i32(fp0);
8590 check_cp1_64bitmode(ctx);
8592 TCGv_i32 fp0 = tcg_temp_new_i32();
8593 TCGv_i32 fp1 = tcg_temp_new_i32();
8595 gen_load_fpr32(fp0, fs);
8596 gen_load_fpr32(fp1, ft);
8597 gen_store_fpr32h(fp0, fd);
8598 gen_store_fpr32(fp1, fd);
8599 tcg_temp_free_i32(fp0);
8600 tcg_temp_free_i32(fp1);
8605 check_cp1_64bitmode(ctx);
8607 TCGv_i32 fp0 = tcg_temp_new_i32();
8608 TCGv_i32 fp1 = tcg_temp_new_i32();
8610 gen_load_fpr32(fp0, fs);
8611 gen_load_fpr32h(fp1, ft);
8612 gen_store_fpr32(fp1, fd);
8613 gen_store_fpr32h(fp0, fd);
8614 tcg_temp_free_i32(fp0);
8615 tcg_temp_free_i32(fp1);
8620 check_cp1_64bitmode(ctx);
8622 TCGv_i32 fp0 = tcg_temp_new_i32();
8623 TCGv_i32 fp1 = tcg_temp_new_i32();
8625 gen_load_fpr32h(fp0, fs);
8626 gen_load_fpr32(fp1, ft);
8627 gen_store_fpr32(fp1, fd);
8628 gen_store_fpr32h(fp0, fd);
8629 tcg_temp_free_i32(fp0);
8630 tcg_temp_free_i32(fp1);
8635 check_cp1_64bitmode(ctx);
8637 TCGv_i32 fp0 = tcg_temp_new_i32();
8638 TCGv_i32 fp1 = tcg_temp_new_i32();
8640 gen_load_fpr32h(fp0, fs);
8641 gen_load_fpr32h(fp1, ft);
8642 gen_store_fpr32(fp1, fd);
8643 gen_store_fpr32h(fp0, fd);
8644 tcg_temp_free_i32(fp0);
8645 tcg_temp_free_i32(fp1);
8652 case OPC_CMP_UEQ_PS:
8653 case OPC_CMP_OLT_PS:
8654 case OPC_CMP_ULT_PS:
8655 case OPC_CMP_OLE_PS:
8656 case OPC_CMP_ULE_PS:
8658 case OPC_CMP_NGLE_PS:
8659 case OPC_CMP_SEQ_PS:
8660 case OPC_CMP_NGL_PS:
8662 case OPC_CMP_NGE_PS:
8664 case OPC_CMP_NGT_PS:
8665 if (ctx->opcode & (1 << 6)) {
8666 gen_cmpabs_ps(ctx, func-48, ft, fs, cc);
8667 opn = condnames_abs[func-48];
8669 gen_cmp_ps(ctx, func-48, ft, fs, cc);
8670 opn = condnames[func-48];
8675 generate_exception (ctx, EXCP_RI);
8678 (void)opn; /* avoid a compiler warning */
8681 MIPS_DEBUG("%s %s, %s, %s", opn, fregnames[fd], fregnames[fs], fregnames[ft]);
8684 MIPS_DEBUG("%s %s,%s", opn, fregnames[fs], fregnames[ft]);
8687 MIPS_DEBUG("%s %s,%s", opn, fregnames[fd], fregnames[fs]);
8692 /* Coprocessor 3 (FPU) */
8693 static void gen_flt3_ldst (DisasContext *ctx, uint32_t opc,
8694 int fd, int fs, int base, int index)
8696 const char *opn = "extended float load/store";
8698 TCGv t0 = tcg_temp_new();
8701 gen_load_gpr(t0, index);
8702 } else if (index == 0) {
8703 gen_load_gpr(t0, base);
8705 gen_op_addr_add(ctx, t0, cpu_gpr[base], cpu_gpr[index]);
8707 /* Don't do NOP if destination is zero: we must perform the actual
8713 TCGv_i32 fp0 = tcg_temp_new_i32();
8715 tcg_gen_qemu_ld32s(t0, t0, ctx->mem_idx);
8716 tcg_gen_trunc_tl_i32(fp0, t0);
8717 gen_store_fpr32(fp0, fd);
8718 tcg_temp_free_i32(fp0);
8724 check_cp1_registers(ctx, fd);
8726 TCGv_i64 fp0 = tcg_temp_new_i64();
8728 tcg_gen_qemu_ld64(fp0, t0, ctx->mem_idx);
8729 gen_store_fpr64(ctx, fp0, fd);
8730 tcg_temp_free_i64(fp0);
8735 check_cp1_64bitmode(ctx);
8736 tcg_gen_andi_tl(t0, t0, ~0x7);
8738 TCGv_i64 fp0 = tcg_temp_new_i64();
8740 tcg_gen_qemu_ld64(fp0, t0, ctx->mem_idx);
8741 gen_store_fpr64(ctx, fp0, fd);
8742 tcg_temp_free_i64(fp0);
8749 TCGv_i32 fp0 = tcg_temp_new_i32();
8750 TCGv t1 = tcg_temp_new();
8752 gen_load_fpr32(fp0, fs);
8753 tcg_gen_extu_i32_tl(t1, fp0);
8754 tcg_gen_qemu_st32(t1, t0, ctx->mem_idx);
8755 tcg_temp_free_i32(fp0);
8763 check_cp1_registers(ctx, fs);
8765 TCGv_i64 fp0 = tcg_temp_new_i64();
8767 gen_load_fpr64(ctx, fp0, fs);
8768 tcg_gen_qemu_st64(fp0, t0, ctx->mem_idx);
8769 tcg_temp_free_i64(fp0);
8775 check_cp1_64bitmode(ctx);
8776 tcg_gen_andi_tl(t0, t0, ~0x7);
8778 TCGv_i64 fp0 = tcg_temp_new_i64();
8780 gen_load_fpr64(ctx, fp0, fs);
8781 tcg_gen_qemu_st64(fp0, t0, ctx->mem_idx);
8782 tcg_temp_free_i64(fp0);
8789 (void)opn; (void)store; /* avoid compiler warnings */
8790 MIPS_DEBUG("%s %s, %s(%s)", opn, fregnames[store ? fs : fd],
8791 regnames[index], regnames[base]);
8794 static void gen_flt3_arith (DisasContext *ctx, uint32_t opc,
8795 int fd, int fr, int fs, int ft)
8797 const char *opn = "flt3_arith";
8801 check_cp1_64bitmode(ctx);
8803 TCGv t0 = tcg_temp_local_new();
8804 TCGv_i32 fp = tcg_temp_new_i32();
8805 TCGv_i32 fph = tcg_temp_new_i32();
8806 int l1 = gen_new_label();
8807 int l2 = gen_new_label();
8809 gen_load_gpr(t0, fr);
8810 tcg_gen_andi_tl(t0, t0, 0x7);
8812 tcg_gen_brcondi_tl(TCG_COND_NE, t0, 0, l1);
8813 gen_load_fpr32(fp, fs);
8814 gen_load_fpr32h(fph, fs);
8815 gen_store_fpr32(fp, fd);
8816 gen_store_fpr32h(fph, fd);
8819 tcg_gen_brcondi_tl(TCG_COND_NE, t0, 4, l2);
8821 #ifdef TARGET_WORDS_BIGENDIAN
8822 gen_load_fpr32(fp, fs);
8823 gen_load_fpr32h(fph, ft);
8824 gen_store_fpr32h(fp, fd);
8825 gen_store_fpr32(fph, fd);
8827 gen_load_fpr32h(fph, fs);
8828 gen_load_fpr32(fp, ft);
8829 gen_store_fpr32(fph, fd);
8830 gen_store_fpr32h(fp, fd);
8833 tcg_temp_free_i32(fp);
8834 tcg_temp_free_i32(fph);
8841 TCGv_i32 fp0 = tcg_temp_new_i32();
8842 TCGv_i32 fp1 = tcg_temp_new_i32();
8843 TCGv_i32 fp2 = tcg_temp_new_i32();
8845 gen_load_fpr32(fp0, fs);
8846 gen_load_fpr32(fp1, ft);
8847 gen_load_fpr32(fp2, fr);
8848 gen_helper_float_madd_s(fp2, cpu_env, fp0, fp1, fp2);
8849 tcg_temp_free_i32(fp0);
8850 tcg_temp_free_i32(fp1);
8851 gen_store_fpr32(fp2, fd);
8852 tcg_temp_free_i32(fp2);
8858 check_cp1_registers(ctx, fd | fs | ft | fr);
8860 TCGv_i64 fp0 = tcg_temp_new_i64();
8861 TCGv_i64 fp1 = tcg_temp_new_i64();
8862 TCGv_i64 fp2 = tcg_temp_new_i64();
8864 gen_load_fpr64(ctx, fp0, fs);
8865 gen_load_fpr64(ctx, fp1, ft);
8866 gen_load_fpr64(ctx, fp2, fr);
8867 gen_helper_float_madd_d(fp2, cpu_env, fp0, fp1, fp2);
8868 tcg_temp_free_i64(fp0);
8869 tcg_temp_free_i64(fp1);
8870 gen_store_fpr64(ctx, fp2, fd);
8871 tcg_temp_free_i64(fp2);
8876 check_cp1_64bitmode(ctx);
8878 TCGv_i64 fp0 = tcg_temp_new_i64();
8879 TCGv_i64 fp1 = tcg_temp_new_i64();
8880 TCGv_i64 fp2 = tcg_temp_new_i64();
8882 gen_load_fpr64(ctx, fp0, fs);
8883 gen_load_fpr64(ctx, fp1, ft);
8884 gen_load_fpr64(ctx, fp2, fr);
8885 gen_helper_float_madd_ps(fp2, cpu_env, fp0, fp1, fp2);
8886 tcg_temp_free_i64(fp0);
8887 tcg_temp_free_i64(fp1);
8888 gen_store_fpr64(ctx, fp2, fd);
8889 tcg_temp_free_i64(fp2);
8896 TCGv_i32 fp0 = tcg_temp_new_i32();
8897 TCGv_i32 fp1 = tcg_temp_new_i32();
8898 TCGv_i32 fp2 = tcg_temp_new_i32();
8900 gen_load_fpr32(fp0, fs);
8901 gen_load_fpr32(fp1, ft);
8902 gen_load_fpr32(fp2, fr);
8903 gen_helper_float_msub_s(fp2, cpu_env, fp0, fp1, fp2);
8904 tcg_temp_free_i32(fp0);
8905 tcg_temp_free_i32(fp1);
8906 gen_store_fpr32(fp2, fd);
8907 tcg_temp_free_i32(fp2);
8913 check_cp1_registers(ctx, fd | fs | ft | fr);
8915 TCGv_i64 fp0 = tcg_temp_new_i64();
8916 TCGv_i64 fp1 = tcg_temp_new_i64();
8917 TCGv_i64 fp2 = tcg_temp_new_i64();
8919 gen_load_fpr64(ctx, fp0, fs);
8920 gen_load_fpr64(ctx, fp1, ft);
8921 gen_load_fpr64(ctx, fp2, fr);
8922 gen_helper_float_msub_d(fp2, cpu_env, fp0, fp1, fp2);
8923 tcg_temp_free_i64(fp0);
8924 tcg_temp_free_i64(fp1);
8925 gen_store_fpr64(ctx, fp2, fd);
8926 tcg_temp_free_i64(fp2);
8931 check_cp1_64bitmode(ctx);
8933 TCGv_i64 fp0 = tcg_temp_new_i64();
8934 TCGv_i64 fp1 = tcg_temp_new_i64();
8935 TCGv_i64 fp2 = tcg_temp_new_i64();
8937 gen_load_fpr64(ctx, fp0, fs);
8938 gen_load_fpr64(ctx, fp1, ft);
8939 gen_load_fpr64(ctx, fp2, fr);
8940 gen_helper_float_msub_ps(fp2, cpu_env, fp0, fp1, fp2);
8941 tcg_temp_free_i64(fp0);
8942 tcg_temp_free_i64(fp1);
8943 gen_store_fpr64(ctx, fp2, fd);
8944 tcg_temp_free_i64(fp2);
8951 TCGv_i32 fp0 = tcg_temp_new_i32();
8952 TCGv_i32 fp1 = tcg_temp_new_i32();
8953 TCGv_i32 fp2 = tcg_temp_new_i32();
8955 gen_load_fpr32(fp0, fs);
8956 gen_load_fpr32(fp1, ft);
8957 gen_load_fpr32(fp2, fr);
8958 gen_helper_float_nmadd_s(fp2, cpu_env, fp0, fp1, fp2);
8959 tcg_temp_free_i32(fp0);
8960 tcg_temp_free_i32(fp1);
8961 gen_store_fpr32(fp2, fd);
8962 tcg_temp_free_i32(fp2);
8968 check_cp1_registers(ctx, fd | fs | ft | fr);
8970 TCGv_i64 fp0 = tcg_temp_new_i64();
8971 TCGv_i64 fp1 = tcg_temp_new_i64();
8972 TCGv_i64 fp2 = tcg_temp_new_i64();
8974 gen_load_fpr64(ctx, fp0, fs);
8975 gen_load_fpr64(ctx, fp1, ft);
8976 gen_load_fpr64(ctx, fp2, fr);
8977 gen_helper_float_nmadd_d(fp2, cpu_env, fp0, fp1, fp2);
8978 tcg_temp_free_i64(fp0);
8979 tcg_temp_free_i64(fp1);
8980 gen_store_fpr64(ctx, fp2, fd);
8981 tcg_temp_free_i64(fp2);
8986 check_cp1_64bitmode(ctx);
8988 TCGv_i64 fp0 = tcg_temp_new_i64();
8989 TCGv_i64 fp1 = tcg_temp_new_i64();
8990 TCGv_i64 fp2 = tcg_temp_new_i64();
8992 gen_load_fpr64(ctx, fp0, fs);
8993 gen_load_fpr64(ctx, fp1, ft);
8994 gen_load_fpr64(ctx, fp2, fr);
8995 gen_helper_float_nmadd_ps(fp2, cpu_env, fp0, fp1, fp2);
8996 tcg_temp_free_i64(fp0);
8997 tcg_temp_free_i64(fp1);
8998 gen_store_fpr64(ctx, fp2, fd);
8999 tcg_temp_free_i64(fp2);
9006 TCGv_i32 fp0 = tcg_temp_new_i32();
9007 TCGv_i32 fp1 = tcg_temp_new_i32();
9008 TCGv_i32 fp2 = tcg_temp_new_i32();
9010 gen_load_fpr32(fp0, fs);
9011 gen_load_fpr32(fp1, ft);
9012 gen_load_fpr32(fp2, fr);
9013 gen_helper_float_nmsub_s(fp2, cpu_env, fp0, fp1, fp2);
9014 tcg_temp_free_i32(fp0);
9015 tcg_temp_free_i32(fp1);
9016 gen_store_fpr32(fp2, fd);
9017 tcg_temp_free_i32(fp2);
9023 check_cp1_registers(ctx, fd | fs | ft | fr);
9025 TCGv_i64 fp0 = tcg_temp_new_i64();
9026 TCGv_i64 fp1 = tcg_temp_new_i64();
9027 TCGv_i64 fp2 = tcg_temp_new_i64();
9029 gen_load_fpr64(ctx, fp0, fs);
9030 gen_load_fpr64(ctx, fp1, ft);
9031 gen_load_fpr64(ctx, fp2, fr);
9032 gen_helper_float_nmsub_d(fp2, cpu_env, fp0, fp1, fp2);
9033 tcg_temp_free_i64(fp0);
9034 tcg_temp_free_i64(fp1);
9035 gen_store_fpr64(ctx, fp2, fd);
9036 tcg_temp_free_i64(fp2);
9041 check_cp1_64bitmode(ctx);
9043 TCGv_i64 fp0 = tcg_temp_new_i64();
9044 TCGv_i64 fp1 = tcg_temp_new_i64();
9045 TCGv_i64 fp2 = tcg_temp_new_i64();
9047 gen_load_fpr64(ctx, fp0, fs);
9048 gen_load_fpr64(ctx, fp1, ft);
9049 gen_load_fpr64(ctx, fp2, fr);
9050 gen_helper_float_nmsub_ps(fp2, cpu_env, fp0, fp1, fp2);
9051 tcg_temp_free_i64(fp0);
9052 tcg_temp_free_i64(fp1);
9053 gen_store_fpr64(ctx, fp2, fd);
9054 tcg_temp_free_i64(fp2);
9060 generate_exception (ctx, EXCP_RI);
9063 (void)opn; /* avoid a compiler warning */
9064 MIPS_DEBUG("%s %s, %s, %s, %s", opn, fregnames[fd], fregnames[fr],
9065 fregnames[fs], fregnames[ft]);
9069 gen_rdhwr (CPUMIPSState *env, DisasContext *ctx, int rt, int rd)
9073 #if !defined(CONFIG_USER_ONLY)
9074 /* The Linux kernel will emulate rdhwr if it's not supported natively.
9075 Therefore only check the ISA in system mode. */
9076 check_insn(env, ctx, ISA_MIPS32R2);
9078 t0 = tcg_temp_new();
9082 save_cpu_state(ctx, 1);
9083 gen_helper_rdhwr_cpunum(t0, cpu_env);
9084 gen_store_gpr(t0, rt);
9087 save_cpu_state(ctx, 1);
9088 gen_helper_rdhwr_synci_step(t0, cpu_env);
9089 gen_store_gpr(t0, rt);
9092 save_cpu_state(ctx, 1);
9093 gen_helper_rdhwr_cc(t0, cpu_env);
9094 gen_store_gpr(t0, rt);
9097 save_cpu_state(ctx, 1);
9098 gen_helper_rdhwr_ccres(t0, cpu_env);
9099 gen_store_gpr(t0, rt);
9102 #if defined(CONFIG_USER_ONLY)
9103 tcg_gen_ld_tl(t0, cpu_env, offsetof(CPUMIPSState, tls_value));
9104 gen_store_gpr(t0, rt);
9107 /* XXX: Some CPUs implement this in hardware.
9108 Not supported yet. */
9110 default: /* Invalid */
9111 MIPS_INVAL("rdhwr");
9112 generate_exception(ctx, EXCP_RI);
9118 static void handle_delay_slot (CPUMIPSState *env, DisasContext *ctx,
9121 if (ctx->hflags & MIPS_HFLAG_BMASK) {
9122 int proc_hflags = ctx->hflags & MIPS_HFLAG_BMASK;
9123 /* Branches completion */
9124 ctx->hflags &= ~MIPS_HFLAG_BMASK;
9125 ctx->bstate = BS_BRANCH;
9126 save_cpu_state(ctx, 0);
9127 /* FIXME: Need to clear can_do_io. */
9128 switch (proc_hflags & MIPS_HFLAG_BMASK_BASE) {
9130 /* unconditional branch */
9131 MIPS_DEBUG("unconditional branch");
9132 if (proc_hflags & MIPS_HFLAG_BX) {
9133 tcg_gen_xori_i32(hflags, hflags, MIPS_HFLAG_M16);
9135 gen_goto_tb(ctx, 0, ctx->btarget);
9138 /* blikely taken case */
9139 MIPS_DEBUG("blikely branch taken");
9140 gen_goto_tb(ctx, 0, ctx->btarget);
9143 /* Conditional branch */
9144 MIPS_DEBUG("conditional branch");
9146 int l1 = gen_new_label();
9148 tcg_gen_brcondi_tl(TCG_COND_NE, bcond, 0, l1);
9149 gen_goto_tb(ctx, 1, ctx->pc + insn_bytes);
9151 gen_goto_tb(ctx, 0, ctx->btarget);
9155 /* unconditional branch to register */
9156 MIPS_DEBUG("branch to register");
9157 if (env->insn_flags & (ASE_MIPS16 | ASE_MICROMIPS)) {
9158 TCGv t0 = tcg_temp_new();
9159 TCGv_i32 t1 = tcg_temp_new_i32();
9161 tcg_gen_andi_tl(t0, btarget, 0x1);
9162 tcg_gen_trunc_tl_i32(t1, t0);
9164 tcg_gen_andi_i32(hflags, hflags, ~(uint32_t)MIPS_HFLAG_M16);
9165 tcg_gen_shli_i32(t1, t1, MIPS_HFLAG_M16_SHIFT);
9166 tcg_gen_or_i32(hflags, hflags, t1);
9167 tcg_temp_free_i32(t1);
9169 tcg_gen_andi_tl(cpu_PC, btarget, ~(target_ulong)0x1);
9171 tcg_gen_mov_tl(cpu_PC, btarget);
9173 if (ctx->singlestep_enabled) {
9174 save_cpu_state(ctx, 0);
9175 gen_helper_0e0i(raise_exception, EXCP_DEBUG);
9180 MIPS_DEBUG("unknown branch");
9186 /* ISA extensions (ASEs) */
9187 /* MIPS16 extension to MIPS32 */
9189 /* MIPS16 major opcodes */
9191 M16_OPC_ADDIUSP = 0x00,
9192 M16_OPC_ADDIUPC = 0x01,
9195 M16_OPC_BEQZ = 0x04,
9196 M16_OPC_BNEQZ = 0x05,
9197 M16_OPC_SHIFT = 0x06,
9199 M16_OPC_RRIA = 0x08,
9200 M16_OPC_ADDIU8 = 0x09,
9201 M16_OPC_SLTI = 0x0a,
9202 M16_OPC_SLTIU = 0x0b,
9205 M16_OPC_CMPI = 0x0e,
9209 M16_OPC_LWSP = 0x12,
9213 M16_OPC_LWPC = 0x16,
9217 M16_OPC_SWSP = 0x1a,
9221 M16_OPC_EXTEND = 0x1e,
9225 /* I8 funct field */
9244 /* RR funct field */
9278 /* I64 funct field */
9290 /* RR ry field for CNVT */
9292 RR_RY_CNVT_ZEB = 0x0,
9293 RR_RY_CNVT_ZEH = 0x1,
9294 RR_RY_CNVT_ZEW = 0x2,
9295 RR_RY_CNVT_SEB = 0x4,
9296 RR_RY_CNVT_SEH = 0x5,
9297 RR_RY_CNVT_SEW = 0x6,
9300 static int xlat (int r)
9302 static int map[] = { 16, 17, 2, 3, 4, 5, 6, 7 };
9307 static void gen_mips16_save (DisasContext *ctx,
9308 int xsregs, int aregs,
9309 int do_ra, int do_s0, int do_s1,
9312 TCGv t0 = tcg_temp_new();
9313 TCGv t1 = tcg_temp_new();
9343 generate_exception(ctx, EXCP_RI);
9349 gen_base_offset_addr(ctx, t0, 29, 12);
9350 gen_load_gpr(t1, 7);
9351 tcg_gen_qemu_st32(t1, t0, ctx->mem_idx);
9354 gen_base_offset_addr(ctx, t0, 29, 8);
9355 gen_load_gpr(t1, 6);
9356 tcg_gen_qemu_st32(t1, t0, ctx->mem_idx);
9359 gen_base_offset_addr(ctx, t0, 29, 4);
9360 gen_load_gpr(t1, 5);
9361 tcg_gen_qemu_st32(t1, t0, ctx->mem_idx);
9364 gen_base_offset_addr(ctx, t0, 29, 0);
9365 gen_load_gpr(t1, 4);
9366 tcg_gen_qemu_st32(t1, t0, ctx->mem_idx);
9369 gen_load_gpr(t0, 29);
9371 #define DECR_AND_STORE(reg) do { \
9372 tcg_gen_subi_tl(t0, t0, 4); \
9373 gen_load_gpr(t1, reg); \
9374 tcg_gen_qemu_st32(t1, t0, ctx->mem_idx); \
9438 generate_exception(ctx, EXCP_RI);
9454 #undef DECR_AND_STORE
9456 tcg_gen_subi_tl(cpu_gpr[29], cpu_gpr[29], framesize);
9461 static void gen_mips16_restore (DisasContext *ctx,
9462 int xsregs, int aregs,
9463 int do_ra, int do_s0, int do_s1,
9467 TCGv t0 = tcg_temp_new();
9468 TCGv t1 = tcg_temp_new();
9470 tcg_gen_addi_tl(t0, cpu_gpr[29], framesize);
9472 #define DECR_AND_LOAD(reg) do { \
9473 tcg_gen_subi_tl(t0, t0, 4); \
9474 tcg_gen_qemu_ld32u(t1, t0, ctx->mem_idx); \
9475 gen_store_gpr(t1, reg); \
9539 generate_exception(ctx, EXCP_RI);
9555 #undef DECR_AND_LOAD
9557 tcg_gen_addi_tl(cpu_gpr[29], cpu_gpr[29], framesize);
9562 static void gen_addiupc (DisasContext *ctx, int rx, int imm,
9563 int is_64_bit, int extended)
9567 if (extended && (ctx->hflags & MIPS_HFLAG_BMASK)) {
9568 generate_exception(ctx, EXCP_RI);
9572 t0 = tcg_temp_new();
9574 tcg_gen_movi_tl(t0, pc_relative_pc(ctx));
9575 tcg_gen_addi_tl(cpu_gpr[rx], t0, imm);
9577 tcg_gen_ext32s_tl(cpu_gpr[rx], cpu_gpr[rx]);
9583 #if defined(TARGET_MIPS64)
9584 static void decode_i64_mips16 (CPUMIPSState *env, DisasContext *ctx,
9585 int ry, int funct, int16_t offset,
9591 offset = extended ? offset : offset << 3;
9592 gen_ld(env, ctx, OPC_LD, ry, 29, offset);
9596 offset = extended ? offset : offset << 3;
9597 gen_st(ctx, OPC_SD, ry, 29, offset);
9601 offset = extended ? offset : (ctx->opcode & 0xff) << 3;
9602 gen_st(ctx, OPC_SD, 31, 29, offset);
9606 offset = extended ? offset : ((int8_t)ctx->opcode) << 3;
9607 gen_arith_imm(env, ctx, OPC_DADDIU, 29, 29, offset);
9610 if (extended && (ctx->hflags & MIPS_HFLAG_BMASK)) {
9611 generate_exception(ctx, EXCP_RI);
9613 offset = extended ? offset : offset << 3;
9614 gen_ld(env, ctx, OPC_LDPC, ry, 0, offset);
9619 offset = extended ? offset : ((int8_t)(offset << 3)) >> 3;
9620 gen_arith_imm(env, ctx, OPC_DADDIU, ry, ry, offset);
9624 offset = extended ? offset : offset << 2;
9625 gen_addiupc(ctx, ry, offset, 1, extended);
9629 offset = extended ? offset : offset << 2;
9630 gen_arith_imm(env, ctx, OPC_DADDIU, ry, 29, offset);
9636 static int decode_extended_mips16_opc (CPUMIPSState *env, DisasContext *ctx,
9639 int extend = cpu_lduw_code(env, ctx->pc + 2);
9640 int op, rx, ry, funct, sa;
9641 int16_t imm, offset;
9643 ctx->opcode = (ctx->opcode << 16) | extend;
9644 op = (ctx->opcode >> 11) & 0x1f;
9645 sa = (ctx->opcode >> 22) & 0x1f;
9646 funct = (ctx->opcode >> 8) & 0x7;
9647 rx = xlat((ctx->opcode >> 8) & 0x7);
9648 ry = xlat((ctx->opcode >> 5) & 0x7);
9649 offset = imm = (int16_t) (((ctx->opcode >> 16) & 0x1f) << 11
9650 | ((ctx->opcode >> 21) & 0x3f) << 5
9651 | (ctx->opcode & 0x1f));
9653 /* The extended opcodes cleverly reuse the opcodes from their 16-bit
9656 case M16_OPC_ADDIUSP:
9657 gen_arith_imm(env, ctx, OPC_ADDIU, rx, 29, imm);
9659 case M16_OPC_ADDIUPC:
9660 gen_addiupc(ctx, rx, imm, 0, 1);
9663 gen_compute_branch(ctx, OPC_BEQ, 4, 0, 0, offset << 1);
9664 /* No delay slot, so just process as a normal instruction */
9667 gen_compute_branch(ctx, OPC_BEQ, 4, rx, 0, offset << 1);
9668 /* No delay slot, so just process as a normal instruction */
9671 gen_compute_branch(ctx, OPC_BNE, 4, rx, 0, offset << 1);
9672 /* No delay slot, so just process as a normal instruction */
9675 switch (ctx->opcode & 0x3) {
9677 gen_shift_imm(env, ctx, OPC_SLL, rx, ry, sa);
9680 #if defined(TARGET_MIPS64)
9682 gen_shift_imm(env, ctx, OPC_DSLL, rx, ry, sa);
9684 generate_exception(ctx, EXCP_RI);
9688 gen_shift_imm(env, ctx, OPC_SRL, rx, ry, sa);
9691 gen_shift_imm(env, ctx, OPC_SRA, rx, ry, sa);
9695 #if defined(TARGET_MIPS64)
9698 gen_ld(env, ctx, OPC_LD, ry, rx, offset);
9702 imm = ctx->opcode & 0xf;
9703 imm = imm | ((ctx->opcode >> 20) & 0x7f) << 4;
9704 imm = imm | ((ctx->opcode >> 16) & 0xf) << 11;
9705 imm = (int16_t) (imm << 1) >> 1;
9706 if ((ctx->opcode >> 4) & 0x1) {
9707 #if defined(TARGET_MIPS64)
9709 gen_arith_imm(env, ctx, OPC_DADDIU, ry, rx, imm);
9711 generate_exception(ctx, EXCP_RI);
9714 gen_arith_imm(env, ctx, OPC_ADDIU, ry, rx, imm);
9717 case M16_OPC_ADDIU8:
9718 gen_arith_imm(env, ctx, OPC_ADDIU, rx, rx, imm);
9721 gen_slt_imm(env, ctx, OPC_SLTI, 24, rx, imm);
9724 gen_slt_imm(env, ctx, OPC_SLTIU, 24, rx, imm);
9729 gen_compute_branch(ctx, OPC_BEQ, 4, 24, 0, offset << 1);
9732 gen_compute_branch(ctx, OPC_BNE, 4, 24, 0, offset << 1);
9735 gen_st(ctx, OPC_SW, 31, 29, imm);
9738 gen_arith_imm(env, ctx, OPC_ADDIU, 29, 29, imm);
9742 int xsregs = (ctx->opcode >> 24) & 0x7;
9743 int aregs = (ctx->opcode >> 16) & 0xf;
9744 int do_ra = (ctx->opcode >> 6) & 0x1;
9745 int do_s0 = (ctx->opcode >> 5) & 0x1;
9746 int do_s1 = (ctx->opcode >> 4) & 0x1;
9747 int framesize = (((ctx->opcode >> 20) & 0xf) << 4
9748 | (ctx->opcode & 0xf)) << 3;
9750 if (ctx->opcode & (1 << 7)) {
9751 gen_mips16_save(ctx, xsregs, aregs,
9752 do_ra, do_s0, do_s1,
9755 gen_mips16_restore(ctx, xsregs, aregs,
9756 do_ra, do_s0, do_s1,
9762 generate_exception(ctx, EXCP_RI);
9767 tcg_gen_movi_tl(cpu_gpr[rx], (uint16_t) imm);
9770 tcg_gen_xori_tl(cpu_gpr[24], cpu_gpr[rx], (uint16_t) imm);
9772 #if defined(TARGET_MIPS64)
9774 gen_st(ctx, OPC_SD, ry, rx, offset);
9778 gen_ld(env, ctx, OPC_LB, ry, rx, offset);
9781 gen_ld(env, ctx, OPC_LH, ry, rx, offset);
9784 gen_ld(env, ctx, OPC_LW, rx, 29, offset);
9787 gen_ld(env, ctx, OPC_LW, ry, rx, offset);
9790 gen_ld(env, ctx, OPC_LBU, ry, rx, offset);
9793 gen_ld(env, ctx, OPC_LHU, ry, rx, offset);
9796 gen_ld(env, ctx, OPC_LWPC, rx, 0, offset);
9798 #if defined(TARGET_MIPS64)
9800 gen_ld(env, ctx, OPC_LWU, ry, rx, offset);
9804 gen_st(ctx, OPC_SB, ry, rx, offset);
9807 gen_st(ctx, OPC_SH, ry, rx, offset);
9810 gen_st(ctx, OPC_SW, rx, 29, offset);
9813 gen_st(ctx, OPC_SW, ry, rx, offset);
9815 #if defined(TARGET_MIPS64)
9817 decode_i64_mips16(env, ctx, ry, funct, offset, 1);
9821 generate_exception(ctx, EXCP_RI);
9828 static int decode_mips16_opc (CPUMIPSState *env, DisasContext *ctx,
9833 int op, cnvt_op, op1, offset;
9837 op = (ctx->opcode >> 11) & 0x1f;
9838 sa = (ctx->opcode >> 2) & 0x7;
9839 sa = sa == 0 ? 8 : sa;
9840 rx = xlat((ctx->opcode >> 8) & 0x7);
9841 cnvt_op = (ctx->opcode >> 5) & 0x7;
9842 ry = xlat((ctx->opcode >> 5) & 0x7);
9843 op1 = offset = ctx->opcode & 0x1f;
9848 case M16_OPC_ADDIUSP:
9850 int16_t imm = ((uint8_t) ctx->opcode) << 2;
9852 gen_arith_imm(env, ctx, OPC_ADDIU, rx, 29, imm);
9855 case M16_OPC_ADDIUPC:
9856 gen_addiupc(ctx, rx, ((uint8_t) ctx->opcode) << 2, 0, 0);
9859 offset = (ctx->opcode & 0x7ff) << 1;
9860 offset = (int16_t)(offset << 4) >> 4;
9861 gen_compute_branch(ctx, OPC_BEQ, 2, 0, 0, offset);
9862 /* No delay slot, so just process as a normal instruction */
9865 offset = cpu_lduw_code(env, ctx->pc + 2);
9866 offset = (((ctx->opcode & 0x1f) << 21)
9867 | ((ctx->opcode >> 5) & 0x1f) << 16
9869 op = ((ctx->opcode >> 10) & 0x1) ? OPC_JALXS : OPC_JALS;
9870 gen_compute_branch(ctx, op, 4, rx, ry, offset);
9875 gen_compute_branch(ctx, OPC_BEQ, 2, rx, 0, ((int8_t)ctx->opcode) << 1);
9876 /* No delay slot, so just process as a normal instruction */
9879 gen_compute_branch(ctx, OPC_BNE, 2, rx, 0, ((int8_t)ctx->opcode) << 1);
9880 /* No delay slot, so just process as a normal instruction */
9883 switch (ctx->opcode & 0x3) {
9885 gen_shift_imm(env, ctx, OPC_SLL, rx, ry, sa);
9888 #if defined(TARGET_MIPS64)
9890 gen_shift_imm(env, ctx, OPC_DSLL, rx, ry, sa);
9892 generate_exception(ctx, EXCP_RI);
9896 gen_shift_imm(env, ctx, OPC_SRL, rx, ry, sa);
9899 gen_shift_imm(env, ctx, OPC_SRA, rx, ry, sa);
9903 #if defined(TARGET_MIPS64)
9906 gen_ld(env, ctx, OPC_LD, ry, rx, offset << 3);
9911 int16_t imm = (int8_t)((ctx->opcode & 0xf) << 4) >> 4;
9913 if ((ctx->opcode >> 4) & 1) {
9914 #if defined(TARGET_MIPS64)
9916 gen_arith_imm(env, ctx, OPC_DADDIU, ry, rx, imm);
9918 generate_exception(ctx, EXCP_RI);
9921 gen_arith_imm(env, ctx, OPC_ADDIU, ry, rx, imm);
9925 case M16_OPC_ADDIU8:
9927 int16_t imm = (int8_t) ctx->opcode;
9929 gen_arith_imm(env, ctx, OPC_ADDIU, rx, rx, imm);
9934 int16_t imm = (uint8_t) ctx->opcode;
9935 gen_slt_imm(env, ctx, OPC_SLTI, 24, rx, imm);
9940 int16_t imm = (uint8_t) ctx->opcode;
9941 gen_slt_imm(env, ctx, OPC_SLTIU, 24, rx, imm);
9948 funct = (ctx->opcode >> 8) & 0x7;
9951 gen_compute_branch(ctx, OPC_BEQ, 2, 24, 0,
9952 ((int8_t)ctx->opcode) << 1);
9955 gen_compute_branch(ctx, OPC_BNE, 2, 24, 0,
9956 ((int8_t)ctx->opcode) << 1);
9959 gen_st(ctx, OPC_SW, 31, 29, (ctx->opcode & 0xff) << 2);
9962 gen_arith_imm(env, ctx, OPC_ADDIU, 29, 29,
9963 ((int8_t)ctx->opcode) << 3);
9967 int do_ra = ctx->opcode & (1 << 6);
9968 int do_s0 = ctx->opcode & (1 << 5);
9969 int do_s1 = ctx->opcode & (1 << 4);
9970 int framesize = ctx->opcode & 0xf;
9972 if (framesize == 0) {
9975 framesize = framesize << 3;
9978 if (ctx->opcode & (1 << 7)) {
9979 gen_mips16_save(ctx, 0, 0,
9980 do_ra, do_s0, do_s1, framesize);
9982 gen_mips16_restore(ctx, 0, 0,
9983 do_ra, do_s0, do_s1, framesize);
9989 int rz = xlat(ctx->opcode & 0x7);
9991 reg32 = (((ctx->opcode >> 3) & 0x3) << 3) |
9992 ((ctx->opcode >> 5) & 0x7);
9993 gen_arith(env, ctx, OPC_ADDU, reg32, rz, 0);
9997 reg32 = ctx->opcode & 0x1f;
9998 gen_arith(env, ctx, OPC_ADDU, ry, reg32, 0);
10001 generate_exception(ctx, EXCP_RI);
10008 int16_t imm = (uint8_t) ctx->opcode;
10010 gen_arith_imm(env, ctx, OPC_ADDIU, rx, 0, imm);
10015 int16_t imm = (uint8_t) ctx->opcode;
10016 gen_logic_imm(env, ctx, OPC_XORI, 24, rx, imm);
10019 #if defined(TARGET_MIPS64)
10021 check_mips_64(ctx);
10022 gen_st(ctx, OPC_SD, ry, rx, offset << 3);
10026 gen_ld(env, ctx, OPC_LB, ry, rx, offset);
10029 gen_ld(env, ctx, OPC_LH, ry, rx, offset << 1);
10032 gen_ld(env, ctx, OPC_LW, rx, 29, ((uint8_t)ctx->opcode) << 2);
10035 gen_ld(env, ctx, OPC_LW, ry, rx, offset << 2);
10038 gen_ld(env, ctx, OPC_LBU, ry, rx, offset);
10041 gen_ld(env, ctx, OPC_LHU, ry, rx, offset << 1);
10044 gen_ld(env, ctx, OPC_LWPC, rx, 0, ((uint8_t)ctx->opcode) << 2);
10046 #if defined (TARGET_MIPS64)
10048 check_mips_64(ctx);
10049 gen_ld(env, ctx, OPC_LWU, ry, rx, offset << 2);
10053 gen_st(ctx, OPC_SB, ry, rx, offset);
10056 gen_st(ctx, OPC_SH, ry, rx, offset << 1);
10059 gen_st(ctx, OPC_SW, rx, 29, ((uint8_t)ctx->opcode) << 2);
10062 gen_st(ctx, OPC_SW, ry, rx, offset << 2);
10066 int rz = xlat((ctx->opcode >> 2) & 0x7);
10069 switch (ctx->opcode & 0x3) {
10071 mips32_op = OPC_ADDU;
10074 mips32_op = OPC_SUBU;
10076 #if defined(TARGET_MIPS64)
10078 mips32_op = OPC_DADDU;
10079 check_mips_64(ctx);
10082 mips32_op = OPC_DSUBU;
10083 check_mips_64(ctx);
10087 generate_exception(ctx, EXCP_RI);
10091 gen_arith(env, ctx, mips32_op, rz, rx, ry);
10100 int nd = (ctx->opcode >> 7) & 0x1;
10101 int link = (ctx->opcode >> 6) & 0x1;
10102 int ra = (ctx->opcode >> 5) & 0x1;
10105 op = nd ? OPC_JALRC : OPC_JALRS;
10110 gen_compute_branch(ctx, op, 2, ra ? 31 : rx, 31, 0);
10117 /* XXX: not clear which exception should be raised
10118 * when in debug mode...
10120 check_insn(env, ctx, ISA_MIPS32);
10121 if (!(ctx->hflags & MIPS_HFLAG_DM)) {
10122 generate_exception(ctx, EXCP_DBp);
10124 generate_exception(ctx, EXCP_DBp);
10128 gen_slt(env, ctx, OPC_SLT, 24, rx, ry);
10131 gen_slt(env, ctx, OPC_SLTU, 24, rx, ry);
10134 generate_exception(ctx, EXCP_BREAK);
10137 gen_shift(env, ctx, OPC_SLLV, ry, rx, ry);
10140 gen_shift(env, ctx, OPC_SRLV, ry, rx, ry);
10143 gen_shift(env, ctx, OPC_SRAV, ry, rx, ry);
10145 #if defined (TARGET_MIPS64)
10147 check_mips_64(ctx);
10148 gen_shift_imm(env, ctx, OPC_DSRL, ry, ry, sa);
10152 gen_logic(env, ctx, OPC_XOR, 24, rx, ry);
10155 gen_arith(env, ctx, OPC_SUBU, rx, 0, ry);
10158 gen_logic(env, ctx, OPC_AND, rx, rx, ry);
10161 gen_logic(env, ctx, OPC_OR, rx, rx, ry);
10164 gen_logic(env, ctx, OPC_XOR, rx, rx, ry);
10167 gen_logic(env, ctx, OPC_NOR, rx, ry, 0);
10170 gen_HILO(ctx, OPC_MFHI, rx);
10174 case RR_RY_CNVT_ZEB:
10175 tcg_gen_ext8u_tl(cpu_gpr[rx], cpu_gpr[rx]);
10177 case RR_RY_CNVT_ZEH:
10178 tcg_gen_ext16u_tl(cpu_gpr[rx], cpu_gpr[rx]);
10180 case RR_RY_CNVT_SEB:
10181 tcg_gen_ext8s_tl(cpu_gpr[rx], cpu_gpr[rx]);
10183 case RR_RY_CNVT_SEH:
10184 tcg_gen_ext16s_tl(cpu_gpr[rx], cpu_gpr[rx]);
10186 #if defined (TARGET_MIPS64)
10187 case RR_RY_CNVT_ZEW:
10188 check_mips_64(ctx);
10189 tcg_gen_ext32u_tl(cpu_gpr[rx], cpu_gpr[rx]);
10191 case RR_RY_CNVT_SEW:
10192 check_mips_64(ctx);
10193 tcg_gen_ext32s_tl(cpu_gpr[rx], cpu_gpr[rx]);
10197 generate_exception(ctx, EXCP_RI);
10202 gen_HILO(ctx, OPC_MFLO, rx);
10204 #if defined (TARGET_MIPS64)
10206 check_mips_64(ctx);
10207 gen_shift_imm(env, ctx, OPC_DSRA, ry, ry, sa);
10210 check_mips_64(ctx);
10211 gen_shift(env, ctx, OPC_DSLLV, ry, rx, ry);
10214 check_mips_64(ctx);
10215 gen_shift(env, ctx, OPC_DSRLV, ry, rx, ry);
10218 check_mips_64(ctx);
10219 gen_shift(env, ctx, OPC_DSRAV, ry, rx, ry);
10223 gen_muldiv(ctx, OPC_MULT, rx, ry);
10226 gen_muldiv(ctx, OPC_MULTU, rx, ry);
10229 gen_muldiv(ctx, OPC_DIV, rx, ry);
10232 gen_muldiv(ctx, OPC_DIVU, rx, ry);
10234 #if defined (TARGET_MIPS64)
10236 check_mips_64(ctx);
10237 gen_muldiv(ctx, OPC_DMULT, rx, ry);
10240 check_mips_64(ctx);
10241 gen_muldiv(ctx, OPC_DMULTU, rx, ry);
10244 check_mips_64(ctx);
10245 gen_muldiv(ctx, OPC_DDIV, rx, ry);
10248 check_mips_64(ctx);
10249 gen_muldiv(ctx, OPC_DDIVU, rx, ry);
10253 generate_exception(ctx, EXCP_RI);
10257 case M16_OPC_EXTEND:
10258 decode_extended_mips16_opc(env, ctx, is_branch);
10261 #if defined(TARGET_MIPS64)
10263 funct = (ctx->opcode >> 8) & 0x7;
10264 decode_i64_mips16(env, ctx, ry, funct, offset, 0);
10268 generate_exception(ctx, EXCP_RI);
10275 /* microMIPS extension to MIPS32 */
10277 /* microMIPS32 major opcodes */
10316 /* 0x20 is reserved */
10326 /* 0x28 and 0x29 are reserved */
10336 /* 0x30 and 0x31 are reserved */
10346 /* 0x38 and 0x39 are reserved */
10357 /* POOL32A encoding of minor opcode field */
10360 /* These opcodes are distinguished only by bits 9..6; those bits are
10361 * what are recorded below. */
10387 /* The following can be distinguished by their lower 6 bits. */
10393 /* POOL32AXF encoding of minor opcode field extension */
10407 /* bits 13..12 for 0x01 */
10413 /* bits 13..12 for 0x2a */
10419 /* bits 13..12 for 0x32 */
10423 /* bits 15..12 for 0x2c */
10439 /* bits 15..12 for 0x34 */
10447 /* bits 15..12 for 0x3c */
10449 JR = 0x0, /* alias */
10454 /* bits 15..12 for 0x05 */
10458 /* bits 15..12 for 0x0d */
10468 /* bits 15..12 for 0x15 */
10474 /* bits 15..12 for 0x1d */
10478 /* bits 15..12 for 0x2d */
10483 /* bits 15..12 for 0x35 */
10490 /* POOL32B encoding of minor opcode field (bits 15..12) */
10506 /* POOL32C encoding of minor opcode field (bits 15..12) */
10514 /* 0xa is reserved */
10521 /* 0x6 is reserved */
10527 /* POOL32F encoding of minor opcode field (bits 5..0) */
10530 /* These are the bit 7..6 values */
10541 /* These are the bit 8..6 values */
10585 CABS_COND_FMT = 0x1c, /* MIPS3D */
10589 /* POOL32Fxf encoding of minor opcode extension field */
10627 /* POOL32I encoding of minor opcode field (bits 25..21) */
10652 /* These overlap and are distinguished by bit16 of the instruction */
10661 /* POOL16A encoding of minor opcode field */
10668 /* POOL16B encoding of minor opcode field */
10675 /* POOL16C encoding of minor opcode field */
10695 /* POOL16D encoding of minor opcode field */
10702 /* POOL16E encoding of minor opcode field */
10709 static int mmreg (int r)
10711 static const int map[] = { 16, 17, 2, 3, 4, 5, 6, 7 };
10716 /* Used for 16-bit store instructions. */
10717 static int mmreg2 (int r)
10719 static const int map[] = { 0, 17, 2, 3, 4, 5, 6, 7 };
10724 #define uMIPS_RD(op) ((op >> 7) & 0x7)
10725 #define uMIPS_RS(op) ((op >> 4) & 0x7)
10726 #define uMIPS_RS2(op) uMIPS_RS(op)
10727 #define uMIPS_RS1(op) ((op >> 1) & 0x7)
10728 #define uMIPS_RD5(op) ((op >> 5) & 0x1f)
10729 #define uMIPS_RS5(op) (op & 0x1f)
10731 /* Signed immediate */
10732 #define SIMM(op, start, width) \
10733 ((int32_t)(((op >> start) & ((~0U) >> (32-width))) \
10736 /* Zero-extended immediate */
10737 #define ZIMM(op, start, width) ((op >> start) & ((~0U) >> (32-width)))
10739 static void gen_addiur1sp (CPUMIPSState *env, DisasContext *ctx)
10741 int rd = mmreg(uMIPS_RD(ctx->opcode));
10743 gen_arith_imm(env, ctx, OPC_ADDIU, rd, 29, ((ctx->opcode >> 1) & 0x3f) << 2);
10746 static void gen_addiur2 (CPUMIPSState *env, DisasContext *ctx)
10748 static const int decoded_imm[] = { 1, 4, 8, 12, 16, 20, 24, -1 };
10749 int rd = mmreg(uMIPS_RD(ctx->opcode));
10750 int rs = mmreg(uMIPS_RS(ctx->opcode));
10752 gen_arith_imm(env, ctx, OPC_ADDIU, rd, rs, decoded_imm[ZIMM(ctx->opcode, 1, 3)]);
10755 static void gen_addiusp (CPUMIPSState *env, DisasContext *ctx)
10757 int encoded = ZIMM(ctx->opcode, 1, 9);
10760 if (encoded <= 1) {
10761 decoded = 256 + encoded;
10762 } else if (encoded <= 255) {
10764 } else if (encoded <= 509) {
10765 decoded = encoded - 512;
10767 decoded = encoded - 768;
10770 gen_arith_imm(env, ctx, OPC_ADDIU, 29, 29, decoded << 2);
10773 static void gen_addius5 (CPUMIPSState *env, DisasContext *ctx)
10775 int imm = SIMM(ctx->opcode, 1, 4);
10776 int rd = (ctx->opcode >> 5) & 0x1f;
10778 gen_arith_imm(env, ctx, OPC_ADDIU, rd, rd, imm);
10781 static void gen_andi16 (CPUMIPSState *env, DisasContext *ctx)
10783 static const int decoded_imm[] = { 128, 1, 2, 3, 4, 7, 8, 15, 16,
10784 31, 32, 63, 64, 255, 32768, 65535 };
10785 int rd = mmreg(uMIPS_RD(ctx->opcode));
10786 int rs = mmreg(uMIPS_RS(ctx->opcode));
10787 int encoded = ZIMM(ctx->opcode, 0, 4);
10789 gen_logic_imm(env, ctx, OPC_ANDI, rd, rs, decoded_imm[encoded]);
10792 static void gen_ldst_multiple (DisasContext *ctx, uint32_t opc, int reglist,
10793 int base, int16_t offset)
10795 const char *opn = "ldst_multiple";
10799 if (ctx->hflags & MIPS_HFLAG_BMASK) {
10800 generate_exception(ctx, EXCP_RI);
10804 t0 = tcg_temp_new();
10806 gen_base_offset_addr(ctx, t0, base, offset);
10808 t1 = tcg_const_tl(reglist);
10809 t2 = tcg_const_i32(ctx->mem_idx);
10811 save_cpu_state(ctx, 1);
10814 gen_helper_lwm(cpu_env, t0, t1, t2);
10818 gen_helper_swm(cpu_env, t0, t1, t2);
10821 #ifdef TARGET_MIPS64
10823 gen_helper_ldm(cpu_env, t0, t1, t2);
10827 gen_helper_sdm(cpu_env, t0, t1, t2);
10833 MIPS_DEBUG("%s, %x, %d(%s)", opn, reglist, offset, regnames[base]);
10836 tcg_temp_free_i32(t2);
10840 static void gen_pool16c_insn (CPUMIPSState *env, DisasContext *ctx, int *is_branch)
10842 int rd = mmreg((ctx->opcode >> 3) & 0x7);
10843 int rs = mmreg(ctx->opcode & 0x7);
10846 switch (((ctx->opcode) >> 4) & 0x3f) {
10851 gen_logic(env, ctx, OPC_NOR, rd, rs, 0);
10857 gen_logic(env, ctx, OPC_XOR, rd, rd, rs);
10863 gen_logic(env, ctx, OPC_AND, rd, rd, rs);
10869 gen_logic(env, ctx, OPC_OR, rd, rd, rs);
10876 static const int lwm_convert[] = { 0x11, 0x12, 0x13, 0x14 };
10877 int offset = ZIMM(ctx->opcode, 0, 4);
10879 gen_ldst_multiple(ctx, LWM32, lwm_convert[(ctx->opcode >> 4) & 0x3],
10888 static const int swm_convert[] = { 0x11, 0x12, 0x13, 0x14 };
10889 int offset = ZIMM(ctx->opcode, 0, 4);
10891 gen_ldst_multiple(ctx, SWM32, swm_convert[(ctx->opcode >> 4) & 0x3],
10898 int reg = ctx->opcode & 0x1f;
10900 gen_compute_branch(ctx, OPC_JR, 2, reg, 0, 0);
10907 int reg = ctx->opcode & 0x1f;
10909 gen_compute_branch(ctx, OPC_JR, 2, reg, 0, 0);
10910 /* Let normal delay slot handling in our caller take us
10911 to the branch target. */
10923 int reg = ctx->opcode & 0x1f;
10925 gen_compute_branch(ctx, opc, 2, reg, 31, 0);
10931 gen_HILO(ctx, OPC_MFHI, uMIPS_RS5(ctx->opcode));
10935 gen_HILO(ctx, OPC_MFLO, uMIPS_RS5(ctx->opcode));
10938 generate_exception(ctx, EXCP_BREAK);
10941 /* XXX: not clear which exception should be raised
10942 * when in debug mode...
10944 check_insn(env, ctx, ISA_MIPS32);
10945 if (!(ctx->hflags & MIPS_HFLAG_DM)) {
10946 generate_exception(ctx, EXCP_DBp);
10948 generate_exception(ctx, EXCP_DBp);
10951 case JRADDIUSP + 0:
10952 case JRADDIUSP + 1:
10954 int imm = ZIMM(ctx->opcode, 0, 5);
10956 gen_compute_branch(ctx, OPC_JR, 2, 31, 0, 0);
10957 gen_arith_imm(env, ctx, OPC_ADDIU, 29, 29, imm << 2);
10958 /* Let normal delay slot handling in our caller take us
10959 to the branch target. */
10963 generate_exception(ctx, EXCP_RI);
10968 static void gen_ldxs (DisasContext *ctx, int base, int index, int rd)
10970 TCGv t0 = tcg_temp_new();
10971 TCGv t1 = tcg_temp_new();
10973 gen_load_gpr(t0, base);
10976 gen_load_gpr(t1, index);
10977 tcg_gen_shli_tl(t1, t1, 2);
10978 gen_op_addr_add(ctx, t0, t1, t0);
10981 tcg_gen_qemu_ld32s(t1, t0, ctx->mem_idx);
10982 gen_store_gpr(t1, rd);
10988 static void gen_ldst_pair (DisasContext *ctx, uint32_t opc, int rd,
10989 int base, int16_t offset)
10991 const char *opn = "ldst_pair";
10994 if (ctx->hflags & MIPS_HFLAG_BMASK || rd == 31) {
10995 generate_exception(ctx, EXCP_RI);
10999 t0 = tcg_temp_new();
11000 t1 = tcg_temp_new();
11002 gen_base_offset_addr(ctx, t0, base, offset);
11007 generate_exception(ctx, EXCP_RI);
11010 tcg_gen_qemu_ld32s(t1, t0, ctx->mem_idx);
11011 gen_store_gpr(t1, rd);
11012 tcg_gen_movi_tl(t1, 4);
11013 gen_op_addr_add(ctx, t0, t0, t1);
11014 tcg_gen_qemu_ld32s(t1, t0, ctx->mem_idx);
11015 gen_store_gpr(t1, rd+1);
11019 gen_load_gpr(t1, rd);
11020 tcg_gen_qemu_st32(t1, t0, ctx->mem_idx);
11021 tcg_gen_movi_tl(t1, 4);
11022 gen_op_addr_add(ctx, t0, t0, t1);
11023 gen_load_gpr(t1, rd+1);
11024 tcg_gen_qemu_st32(t1, t0, ctx->mem_idx);
11027 #ifdef TARGET_MIPS64
11030 generate_exception(ctx, EXCP_RI);
11033 tcg_gen_qemu_ld64(t1, t0, ctx->mem_idx);
11034 gen_store_gpr(t1, rd);
11035 tcg_gen_movi_tl(t1, 8);
11036 gen_op_addr_add(ctx, t0, t0, t1);
11037 tcg_gen_qemu_ld64(t1, t0, ctx->mem_idx);
11038 gen_store_gpr(t1, rd+1);
11042 gen_load_gpr(t1, rd);
11043 tcg_gen_qemu_st64(t1, t0, ctx->mem_idx);
11044 tcg_gen_movi_tl(t1, 8);
11045 gen_op_addr_add(ctx, t0, t0, t1);
11046 gen_load_gpr(t1, rd+1);
11047 tcg_gen_qemu_st64(t1, t0, ctx->mem_idx);
11052 (void)opn; /* avoid a compiler warning */
11053 MIPS_DEBUG("%s, %s, %d(%s)", opn, regnames[rd], offset, regnames[base]);
11058 static void gen_pool32axf (CPUMIPSState *env, DisasContext *ctx, int rt, int rs,
11061 int extension = (ctx->opcode >> 6) & 0x3f;
11062 int minor = (ctx->opcode >> 12) & 0xf;
11063 uint32_t mips32_op;
11065 switch (extension) {
11067 mips32_op = OPC_TEQ;
11070 mips32_op = OPC_TGE;
11073 mips32_op = OPC_TGEU;
11076 mips32_op = OPC_TLT;
11079 mips32_op = OPC_TLTU;
11082 mips32_op = OPC_TNE;
11084 gen_trap(ctx, mips32_op, rs, rt, -1);
11086 #ifndef CONFIG_USER_ONLY
11089 check_cp0_enabled(ctx);
11091 /* Treat as NOP. */
11094 gen_mfc0(env, ctx, cpu_gpr[rt], rs, (ctx->opcode >> 11) & 0x7);
11098 check_cp0_enabled(ctx);
11100 TCGv t0 = tcg_temp_new();
11102 gen_load_gpr(t0, rt);
11103 gen_mtc0(env, ctx, t0, rs, (ctx->opcode >> 11) & 0x7);
11111 gen_bshfl(ctx, OPC_SEB, rs, rt);
11114 gen_bshfl(ctx, OPC_SEH, rs, rt);
11117 mips32_op = OPC_CLO;
11120 mips32_op = OPC_CLZ;
11122 check_insn(env, ctx, ISA_MIPS32);
11123 gen_cl(ctx, mips32_op, rt, rs);
11126 gen_rdhwr(env, ctx, rt, rs);
11129 gen_bshfl(ctx, OPC_WSBH, rs, rt);
11132 mips32_op = OPC_MULT;
11135 mips32_op = OPC_MULTU;
11138 mips32_op = OPC_DIV;
11141 mips32_op = OPC_DIVU;
11144 mips32_op = OPC_MADD;
11147 mips32_op = OPC_MADDU;
11150 mips32_op = OPC_MSUB;
11153 mips32_op = OPC_MSUBU;
11155 check_insn(env, ctx, ISA_MIPS32);
11156 gen_muldiv(ctx, mips32_op, rs, rt);
11159 goto pool32axf_invalid;
11170 generate_exception_err(ctx, EXCP_CpU, 2);
11173 goto pool32axf_invalid;
11180 gen_compute_branch (ctx, OPC_JALR, 4, rs, rt, 0);
11185 gen_compute_branch (ctx, OPC_JALRS, 4, rs, rt, 0);
11189 goto pool32axf_invalid;
11195 check_cp0_enabled(ctx);
11196 check_insn(env, ctx, ISA_MIPS32R2);
11197 gen_load_srsgpr(rt, rs);
11200 check_cp0_enabled(ctx);
11201 check_insn(env, ctx, ISA_MIPS32R2);
11202 gen_store_srsgpr(rt, rs);
11205 goto pool32axf_invalid;
11208 #ifndef CONFIG_USER_ONLY
11212 mips32_op = OPC_TLBP;
11215 mips32_op = OPC_TLBR;
11218 mips32_op = OPC_TLBWI;
11221 mips32_op = OPC_TLBWR;
11224 mips32_op = OPC_WAIT;
11227 mips32_op = OPC_DERET;
11230 mips32_op = OPC_ERET;
11232 gen_cp0(env, ctx, mips32_op, rt, rs);
11235 goto pool32axf_invalid;
11241 check_cp0_enabled(ctx);
11243 TCGv t0 = tcg_temp_new();
11245 save_cpu_state(ctx, 1);
11246 gen_helper_di(t0, cpu_env);
11247 gen_store_gpr(t0, rs);
11248 /* Stop translation as we may have switched the execution mode */
11249 ctx->bstate = BS_STOP;
11254 check_cp0_enabled(ctx);
11256 TCGv t0 = tcg_temp_new();
11258 save_cpu_state(ctx, 1);
11259 gen_helper_ei(t0, cpu_env);
11260 gen_store_gpr(t0, rs);
11261 /* Stop translation as we may have switched the execution mode */
11262 ctx->bstate = BS_STOP;
11267 goto pool32axf_invalid;
11277 generate_exception(ctx, EXCP_SYSCALL);
11278 ctx->bstate = BS_STOP;
11281 check_insn(env, ctx, ISA_MIPS32);
11282 if (!(ctx->hflags & MIPS_HFLAG_DM)) {
11283 generate_exception(ctx, EXCP_DBp);
11285 generate_exception(ctx, EXCP_DBp);
11289 goto pool32axf_invalid;
11295 gen_HILO(ctx, OPC_MFHI, rs);
11298 gen_HILO(ctx, OPC_MFLO, rs);
11301 gen_HILO(ctx, OPC_MTHI, rs);
11304 gen_HILO(ctx, OPC_MTLO, rs);
11307 goto pool32axf_invalid;
11312 MIPS_INVAL("pool32axf");
11313 generate_exception(ctx, EXCP_RI);
11318 /* Values for microMIPS fmt field. Variable-width, depending on which
11319 formats the instruction supports. */
11338 static void gen_pool32fxf (CPUMIPSState *env, DisasContext *ctx, int rt, int rs)
11340 int extension = (ctx->opcode >> 6) & 0x3ff;
11341 uint32_t mips32_op;
11343 #define FLOAT_1BIT_FMT(opc, fmt) (fmt << 8) | opc
11344 #define FLOAT_2BIT_FMT(opc, fmt) (fmt << 7) | opc
11345 #define COND_FLOAT_MOV(opc, cond) (cond << 7) | opc
11347 switch (extension) {
11348 case FLOAT_1BIT_FMT(CFC1, 0):
11349 mips32_op = OPC_CFC1;
11351 case FLOAT_1BIT_FMT(CTC1, 0):
11352 mips32_op = OPC_CTC1;
11354 case FLOAT_1BIT_FMT(MFC1, 0):
11355 mips32_op = OPC_MFC1;
11357 case FLOAT_1BIT_FMT(MTC1, 0):
11358 mips32_op = OPC_MTC1;
11360 case FLOAT_1BIT_FMT(MFHC1, 0):
11361 mips32_op = OPC_MFHC1;
11363 case FLOAT_1BIT_FMT(MTHC1, 0):
11364 mips32_op = OPC_MTHC1;
11366 gen_cp1(ctx, mips32_op, rt, rs);
11369 /* Reciprocal square root */
11370 case FLOAT_1BIT_FMT(RSQRT_FMT, FMT_SD_S):
11371 mips32_op = OPC_RSQRT_S;
11373 case FLOAT_1BIT_FMT(RSQRT_FMT, FMT_SD_D):
11374 mips32_op = OPC_RSQRT_D;
11378 case FLOAT_1BIT_FMT(SQRT_FMT, FMT_SD_S):
11379 mips32_op = OPC_SQRT_S;
11381 case FLOAT_1BIT_FMT(SQRT_FMT, FMT_SD_D):
11382 mips32_op = OPC_SQRT_D;
11386 case FLOAT_1BIT_FMT(RECIP_FMT, FMT_SD_S):
11387 mips32_op = OPC_RECIP_S;
11389 case FLOAT_1BIT_FMT(RECIP_FMT, FMT_SD_D):
11390 mips32_op = OPC_RECIP_D;
11394 case FLOAT_1BIT_FMT(FLOOR_L, FMT_SD_S):
11395 mips32_op = OPC_FLOOR_L_S;
11397 case FLOAT_1BIT_FMT(FLOOR_L, FMT_SD_D):
11398 mips32_op = OPC_FLOOR_L_D;
11400 case FLOAT_1BIT_FMT(FLOOR_W, FMT_SD_S):
11401 mips32_op = OPC_FLOOR_W_S;
11403 case FLOAT_1BIT_FMT(FLOOR_W, FMT_SD_D):
11404 mips32_op = OPC_FLOOR_W_D;
11408 case FLOAT_1BIT_FMT(CEIL_L, FMT_SD_S):
11409 mips32_op = OPC_CEIL_L_S;
11411 case FLOAT_1BIT_FMT(CEIL_L, FMT_SD_D):
11412 mips32_op = OPC_CEIL_L_D;
11414 case FLOAT_1BIT_FMT(CEIL_W, FMT_SD_S):
11415 mips32_op = OPC_CEIL_W_S;
11417 case FLOAT_1BIT_FMT(CEIL_W, FMT_SD_D):
11418 mips32_op = OPC_CEIL_W_D;
11422 case FLOAT_1BIT_FMT(TRUNC_L, FMT_SD_S):
11423 mips32_op = OPC_TRUNC_L_S;
11425 case FLOAT_1BIT_FMT(TRUNC_L, FMT_SD_D):
11426 mips32_op = OPC_TRUNC_L_D;
11428 case FLOAT_1BIT_FMT(TRUNC_W, FMT_SD_S):
11429 mips32_op = OPC_TRUNC_W_S;
11431 case FLOAT_1BIT_FMT(TRUNC_W, FMT_SD_D):
11432 mips32_op = OPC_TRUNC_W_D;
11436 case FLOAT_1BIT_FMT(ROUND_L, FMT_SD_S):
11437 mips32_op = OPC_ROUND_L_S;
11439 case FLOAT_1BIT_FMT(ROUND_L, FMT_SD_D):
11440 mips32_op = OPC_ROUND_L_D;
11442 case FLOAT_1BIT_FMT(ROUND_W, FMT_SD_S):
11443 mips32_op = OPC_ROUND_W_S;
11445 case FLOAT_1BIT_FMT(ROUND_W, FMT_SD_D):
11446 mips32_op = OPC_ROUND_W_D;
11449 /* Integer to floating-point conversion */
11450 case FLOAT_1BIT_FMT(CVT_L, FMT_SD_S):
11451 mips32_op = OPC_CVT_L_S;
11453 case FLOAT_1BIT_FMT(CVT_L, FMT_SD_D):
11454 mips32_op = OPC_CVT_L_D;
11456 case FLOAT_1BIT_FMT(CVT_W, FMT_SD_S):
11457 mips32_op = OPC_CVT_W_S;
11459 case FLOAT_1BIT_FMT(CVT_W, FMT_SD_D):
11460 mips32_op = OPC_CVT_W_D;
11463 /* Paired-foo conversions */
11464 case FLOAT_1BIT_FMT(CVT_S_PL, 0):
11465 mips32_op = OPC_CVT_S_PL;
11467 case FLOAT_1BIT_FMT(CVT_S_PU, 0):
11468 mips32_op = OPC_CVT_S_PU;
11470 case FLOAT_1BIT_FMT(CVT_PW_PS, 0):
11471 mips32_op = OPC_CVT_PW_PS;
11473 case FLOAT_1BIT_FMT(CVT_PS_PW, 0):
11474 mips32_op = OPC_CVT_PS_PW;
11477 /* Floating-point moves */
11478 case FLOAT_2BIT_FMT(MOV_FMT, FMT_SDPS_S):
11479 mips32_op = OPC_MOV_S;
11481 case FLOAT_2BIT_FMT(MOV_FMT, FMT_SDPS_D):
11482 mips32_op = OPC_MOV_D;
11484 case FLOAT_2BIT_FMT(MOV_FMT, FMT_SDPS_PS):
11485 mips32_op = OPC_MOV_PS;
11488 /* Absolute value */
11489 case FLOAT_2BIT_FMT(ABS_FMT, FMT_SDPS_S):
11490 mips32_op = OPC_ABS_S;
11492 case FLOAT_2BIT_FMT(ABS_FMT, FMT_SDPS_D):
11493 mips32_op = OPC_ABS_D;
11495 case FLOAT_2BIT_FMT(ABS_FMT, FMT_SDPS_PS):
11496 mips32_op = OPC_ABS_PS;
11500 case FLOAT_2BIT_FMT(NEG_FMT, FMT_SDPS_S):
11501 mips32_op = OPC_NEG_S;
11503 case FLOAT_2BIT_FMT(NEG_FMT, FMT_SDPS_D):
11504 mips32_op = OPC_NEG_D;
11506 case FLOAT_2BIT_FMT(NEG_FMT, FMT_SDPS_PS):
11507 mips32_op = OPC_NEG_PS;
11510 /* Reciprocal square root step */
11511 case FLOAT_2BIT_FMT(RSQRT1_FMT, FMT_SDPS_S):
11512 mips32_op = OPC_RSQRT1_S;
11514 case FLOAT_2BIT_FMT(RSQRT1_FMT, FMT_SDPS_D):
11515 mips32_op = OPC_RSQRT1_D;
11517 case FLOAT_2BIT_FMT(RSQRT1_FMT, FMT_SDPS_PS):
11518 mips32_op = OPC_RSQRT1_PS;
11521 /* Reciprocal step */
11522 case FLOAT_2BIT_FMT(RECIP1_FMT, FMT_SDPS_S):
11523 mips32_op = OPC_RECIP1_S;
11525 case FLOAT_2BIT_FMT(RECIP1_FMT, FMT_SDPS_D):
11526 mips32_op = OPC_RECIP1_S;
11528 case FLOAT_2BIT_FMT(RECIP1_FMT, FMT_SDPS_PS):
11529 mips32_op = OPC_RECIP1_PS;
11532 /* Conversions from double */
11533 case FLOAT_2BIT_FMT(CVT_D, FMT_SWL_S):
11534 mips32_op = OPC_CVT_D_S;
11536 case FLOAT_2BIT_FMT(CVT_D, FMT_SWL_W):
11537 mips32_op = OPC_CVT_D_W;
11539 case FLOAT_2BIT_FMT(CVT_D, FMT_SWL_L):
11540 mips32_op = OPC_CVT_D_L;
11543 /* Conversions from single */
11544 case FLOAT_2BIT_FMT(CVT_S, FMT_DWL_D):
11545 mips32_op = OPC_CVT_S_D;
11547 case FLOAT_2BIT_FMT(CVT_S, FMT_DWL_W):
11548 mips32_op = OPC_CVT_S_W;
11550 case FLOAT_2BIT_FMT(CVT_S, FMT_DWL_L):
11551 mips32_op = OPC_CVT_S_L;
11553 gen_farith(ctx, mips32_op, -1, rs, rt, 0);
11556 /* Conditional moves on floating-point codes */
11557 case COND_FLOAT_MOV(MOVT, 0):
11558 case COND_FLOAT_MOV(MOVT, 1):
11559 case COND_FLOAT_MOV(MOVT, 2):
11560 case COND_FLOAT_MOV(MOVT, 3):
11561 case COND_FLOAT_MOV(MOVT, 4):
11562 case COND_FLOAT_MOV(MOVT, 5):
11563 case COND_FLOAT_MOV(MOVT, 6):
11564 case COND_FLOAT_MOV(MOVT, 7):
11565 gen_movci(ctx, rt, rs, (ctx->opcode >> 13) & 0x7, 1);
11567 case COND_FLOAT_MOV(MOVF, 0):
11568 case COND_FLOAT_MOV(MOVF, 1):
11569 case COND_FLOAT_MOV(MOVF, 2):
11570 case COND_FLOAT_MOV(MOVF, 3):
11571 case COND_FLOAT_MOV(MOVF, 4):
11572 case COND_FLOAT_MOV(MOVF, 5):
11573 case COND_FLOAT_MOV(MOVF, 6):
11574 case COND_FLOAT_MOV(MOVF, 7):
11575 gen_movci(ctx, rt, rs, (ctx->opcode >> 13) & 0x7, 0);
11578 MIPS_INVAL("pool32fxf");
11579 generate_exception(ctx, EXCP_RI);
11584 static void decode_micromips32_opc (CPUMIPSState *env, DisasContext *ctx,
11585 uint16_t insn_hw1, int *is_branch)
11589 int rt, rs, rd, rr;
11591 uint32_t op, minor, mips32_op;
11592 uint32_t cond, fmt, cc;
11594 insn = cpu_lduw_code(env, ctx->pc + 2);
11595 ctx->opcode = (ctx->opcode << 16) | insn;
11597 rt = (ctx->opcode >> 21) & 0x1f;
11598 rs = (ctx->opcode >> 16) & 0x1f;
11599 rd = (ctx->opcode >> 11) & 0x1f;
11600 rr = (ctx->opcode >> 6) & 0x1f;
11601 imm = (int16_t) ctx->opcode;
11603 op = (ctx->opcode >> 26) & 0x3f;
11606 minor = ctx->opcode & 0x3f;
11609 minor = (ctx->opcode >> 6) & 0xf;
11612 mips32_op = OPC_SLL;
11615 mips32_op = OPC_SRA;
11618 mips32_op = OPC_SRL;
11621 mips32_op = OPC_ROTR;
11623 gen_shift_imm(env, ctx, mips32_op, rt, rs, rd);
11626 goto pool32a_invalid;
11630 minor = (ctx->opcode >> 6) & 0xf;
11634 mips32_op = OPC_ADD;
11637 mips32_op = OPC_ADDU;
11640 mips32_op = OPC_SUB;
11643 mips32_op = OPC_SUBU;
11646 mips32_op = OPC_MUL;
11648 gen_arith(env, ctx, mips32_op, rd, rs, rt);
11652 mips32_op = OPC_SLLV;
11655 mips32_op = OPC_SRLV;
11658 mips32_op = OPC_SRAV;
11661 mips32_op = OPC_ROTRV;
11663 gen_shift(env, ctx, mips32_op, rd, rs, rt);
11665 /* Logical operations */
11667 mips32_op = OPC_AND;
11670 mips32_op = OPC_OR;
11673 mips32_op = OPC_NOR;
11676 mips32_op = OPC_XOR;
11678 gen_logic(env, ctx, mips32_op, rd, rs, rt);
11680 /* Set less than */
11682 mips32_op = OPC_SLT;
11685 mips32_op = OPC_SLTU;
11687 gen_slt(env, ctx, mips32_op, rd, rs, rt);
11690 goto pool32a_invalid;
11694 minor = (ctx->opcode >> 6) & 0xf;
11696 /* Conditional moves */
11698 mips32_op = OPC_MOVN;
11701 mips32_op = OPC_MOVZ;
11703 gen_cond_move(env, ctx, mips32_op, rd, rs, rt);
11706 gen_ldxs(ctx, rs, rt, rd);
11709 goto pool32a_invalid;
11713 gen_bitops(ctx, OPC_INS, rt, rs, rr, rd);
11716 gen_bitops(ctx, OPC_EXT, rt, rs, rr, rd);
11719 gen_pool32axf(env, ctx, rt, rs, is_branch);
11722 generate_exception(ctx, EXCP_BREAK);
11726 MIPS_INVAL("pool32a");
11727 generate_exception(ctx, EXCP_RI);
11732 minor = (ctx->opcode >> 12) & 0xf;
11735 check_cp0_enabled(ctx);
11736 /* Treat as no-op. */
11740 /* COP2: Not implemented. */
11741 generate_exception_err(ctx, EXCP_CpU, 2);
11745 #ifdef TARGET_MIPS64
11749 gen_ldst_pair(ctx, minor, rt, rs, SIMM(ctx->opcode, 0, 12));
11753 #ifdef TARGET_MIPS64
11757 gen_ldst_multiple(ctx, minor, rt, rs, SIMM(ctx->opcode, 0, 12));
11760 MIPS_INVAL("pool32b");
11761 generate_exception(ctx, EXCP_RI);
11766 if (env->CP0_Config1 & (1 << CP0C1_FP)) {
11767 minor = ctx->opcode & 0x3f;
11768 check_cp1_enabled(ctx);
11771 mips32_op = OPC_ALNV_PS;
11774 mips32_op = OPC_MADD_S;
11777 mips32_op = OPC_MADD_D;
11780 mips32_op = OPC_MADD_PS;
11783 mips32_op = OPC_MSUB_S;
11786 mips32_op = OPC_MSUB_D;
11789 mips32_op = OPC_MSUB_PS;
11792 mips32_op = OPC_NMADD_S;
11795 mips32_op = OPC_NMADD_D;
11798 mips32_op = OPC_NMADD_PS;
11801 mips32_op = OPC_NMSUB_S;
11804 mips32_op = OPC_NMSUB_D;
11807 mips32_op = OPC_NMSUB_PS;
11809 gen_flt3_arith(ctx, mips32_op, rd, rr, rs, rt);
11811 case CABS_COND_FMT:
11812 cond = (ctx->opcode >> 6) & 0xf;
11813 cc = (ctx->opcode >> 13) & 0x7;
11814 fmt = (ctx->opcode >> 10) & 0x3;
11817 gen_cmpabs_s(ctx, cond, rt, rs, cc);
11820 gen_cmpabs_d(ctx, cond, rt, rs, cc);
11823 gen_cmpabs_ps(ctx, cond, rt, rs, cc);
11826 goto pool32f_invalid;
11830 cond = (ctx->opcode >> 6) & 0xf;
11831 cc = (ctx->opcode >> 13) & 0x7;
11832 fmt = (ctx->opcode >> 10) & 0x3;
11835 gen_cmp_s(ctx, cond, rt, rs, cc);
11838 gen_cmp_d(ctx, cond, rt, rs, cc);
11841 gen_cmp_ps(ctx, cond, rt, rs, cc);
11844 goto pool32f_invalid;
11848 gen_pool32fxf(env, ctx, rt, rs);
11852 switch ((ctx->opcode >> 6) & 0x7) {
11854 mips32_op = OPC_PLL_PS;
11857 mips32_op = OPC_PLU_PS;
11860 mips32_op = OPC_PUL_PS;
11863 mips32_op = OPC_PUU_PS;
11866 mips32_op = OPC_CVT_PS_S;
11868 gen_farith(ctx, mips32_op, rt, rs, rd, 0);
11871 goto pool32f_invalid;
11876 switch ((ctx->opcode >> 6) & 0x7) {
11878 mips32_op = OPC_LWXC1;
11881 mips32_op = OPC_SWXC1;
11884 mips32_op = OPC_LDXC1;
11887 mips32_op = OPC_SDXC1;
11890 mips32_op = OPC_LUXC1;
11893 mips32_op = OPC_SUXC1;
11895 gen_flt3_ldst(ctx, mips32_op, rd, rd, rt, rs);
11898 goto pool32f_invalid;
11903 fmt = (ctx->opcode >> 9) & 0x3;
11904 switch ((ctx->opcode >> 6) & 0x7) {
11908 mips32_op = OPC_RSQRT2_S;
11911 mips32_op = OPC_RSQRT2_D;
11914 mips32_op = OPC_RSQRT2_PS;
11917 goto pool32f_invalid;
11923 mips32_op = OPC_RECIP2_S;
11926 mips32_op = OPC_RECIP2_D;
11929 mips32_op = OPC_RECIP2_PS;
11932 goto pool32f_invalid;
11936 mips32_op = OPC_ADDR_PS;
11939 mips32_op = OPC_MULR_PS;
11941 gen_farith(ctx, mips32_op, rt, rs, rd, 0);
11944 goto pool32f_invalid;
11948 /* MOV[FT].fmt and PREFX */
11949 cc = (ctx->opcode >> 13) & 0x7;
11950 fmt = (ctx->opcode >> 9) & 0x3;
11951 switch ((ctx->opcode >> 6) & 0x7) {
11955 gen_movcf_s(rs, rt, cc, 0);
11958 gen_movcf_d(ctx, rs, rt, cc, 0);
11961 gen_movcf_ps(rs, rt, cc, 0);
11964 goto pool32f_invalid;
11970 gen_movcf_s(rs, rt, cc, 1);
11973 gen_movcf_d(ctx, rs, rt, cc, 1);
11976 gen_movcf_ps(rs, rt, cc, 1);
11979 goto pool32f_invalid;
11985 goto pool32f_invalid;
11988 #define FINSN_3ARG_SDPS(prfx) \
11989 switch ((ctx->opcode >> 8) & 0x3) { \
11991 mips32_op = OPC_##prfx##_S; \
11994 mips32_op = OPC_##prfx##_D; \
11996 case FMT_SDPS_PS: \
11997 mips32_op = OPC_##prfx##_PS; \
12000 goto pool32f_invalid; \
12003 /* regular FP ops */
12004 switch ((ctx->opcode >> 6) & 0x3) {
12006 FINSN_3ARG_SDPS(ADD);
12009 FINSN_3ARG_SDPS(SUB);
12012 FINSN_3ARG_SDPS(MUL);
12015 fmt = (ctx->opcode >> 8) & 0x3;
12017 mips32_op = OPC_DIV_D;
12018 } else if (fmt == 0) {
12019 mips32_op = OPC_DIV_S;
12021 goto pool32f_invalid;
12025 goto pool32f_invalid;
12030 switch ((ctx->opcode >> 6) & 0x3) {
12032 FINSN_3ARG_SDPS(MOVN);
12035 FINSN_3ARG_SDPS(MOVZ);
12038 goto pool32f_invalid;
12042 gen_farith(ctx, mips32_op, rt, rs, rd, 0);
12046 MIPS_INVAL("pool32f");
12047 generate_exception(ctx, EXCP_RI);
12051 generate_exception_err(ctx, EXCP_CpU, 1);
12055 minor = (ctx->opcode >> 21) & 0x1f;
12058 mips32_op = OPC_BLTZ;
12061 mips32_op = OPC_BLTZAL;
12064 mips32_op = OPC_BLTZALS;
12067 mips32_op = OPC_BGEZ;
12070 mips32_op = OPC_BGEZAL;
12073 mips32_op = OPC_BGEZALS;
12076 mips32_op = OPC_BLEZ;
12079 mips32_op = OPC_BGTZ;
12081 gen_compute_branch(ctx, mips32_op, 4, rs, -1, imm << 1);
12087 mips32_op = OPC_TLTI;
12090 mips32_op = OPC_TGEI;
12093 mips32_op = OPC_TLTIU;
12096 mips32_op = OPC_TGEIU;
12099 mips32_op = OPC_TNEI;
12102 mips32_op = OPC_TEQI;
12104 gen_trap(ctx, mips32_op, rs, -1, imm);
12109 gen_compute_branch(ctx, minor == BNEZC ? OPC_BNE : OPC_BEQ,
12110 4, rs, 0, imm << 1);
12111 /* Compact branches don't have a delay slot, so just let
12112 the normal delay slot handling take us to the branch
12116 gen_logic_imm(env, ctx, OPC_LUI, rs, -1, imm);
12122 /* COP2: Not implemented. */
12123 generate_exception_err(ctx, EXCP_CpU, 2);
12126 mips32_op = (ctx->opcode & (1 << 16)) ? OPC_BC1FANY2 : OPC_BC1F;
12129 mips32_op = (ctx->opcode & (1 << 16)) ? OPC_BC1TANY2 : OPC_BC1T;
12132 mips32_op = OPC_BC1FANY4;
12135 mips32_op = OPC_BC1TANY4;
12138 check_insn(env, ctx, ASE_MIPS3D);
12141 gen_compute_branch1(env, ctx, mips32_op,
12142 (ctx->opcode >> 18) & 0x7, imm << 1);
12147 /* MIPS DSP: not implemented */
12150 MIPS_INVAL("pool32i");
12151 generate_exception(ctx, EXCP_RI);
12156 minor = (ctx->opcode >> 12) & 0xf;
12159 mips32_op = OPC_LWL;
12162 mips32_op = OPC_SWL;
12165 mips32_op = OPC_LWR;
12168 mips32_op = OPC_SWR;
12170 #if defined(TARGET_MIPS64)
12172 mips32_op = OPC_LDL;
12175 mips32_op = OPC_SDL;
12178 mips32_op = OPC_LDR;
12181 mips32_op = OPC_SDR;
12184 mips32_op = OPC_LWU;
12187 mips32_op = OPC_LLD;
12191 mips32_op = OPC_LL;
12194 gen_ld(env, ctx, mips32_op, rt, rs, SIMM(ctx->opcode, 0, 12));
12197 gen_st(ctx, mips32_op, rt, rs, SIMM(ctx->opcode, 0, 12));
12200 gen_st_cond(ctx, OPC_SC, rt, rs, SIMM(ctx->opcode, 0, 12));
12202 #if defined(TARGET_MIPS64)
12204 gen_st_cond(ctx, OPC_SCD, rt, rs, SIMM(ctx->opcode, 0, 12));
12208 /* Treat as no-op */
12211 MIPS_INVAL("pool32c");
12212 generate_exception(ctx, EXCP_RI);
12217 mips32_op = OPC_ADDI;
12220 mips32_op = OPC_ADDIU;
12222 gen_arith_imm(env, ctx, mips32_op, rt, rs, imm);
12225 /* Logical operations */
12227 mips32_op = OPC_ORI;
12230 mips32_op = OPC_XORI;
12233 mips32_op = OPC_ANDI;
12235 gen_logic_imm(env, ctx, mips32_op, rt, rs, imm);
12238 /* Set less than immediate */
12240 mips32_op = OPC_SLTI;
12243 mips32_op = OPC_SLTIU;
12245 gen_slt_imm(env, ctx, mips32_op, rt, rs, imm);
12248 offset = (int32_t)(ctx->opcode & 0x3FFFFFF) << 2;
12249 gen_compute_branch(ctx, OPC_JALX, 4, rt, rs, offset);
12253 offset = (int32_t)(ctx->opcode & 0x3FFFFFF) << 1;
12254 gen_compute_branch(ctx, OPC_JALS, 4, rt, rs, offset);
12258 gen_compute_branch(ctx, OPC_BEQ, 4, rt, rs, imm << 1);
12262 gen_compute_branch(ctx, OPC_BNE, 4, rt, rs, imm << 1);
12266 gen_compute_branch(ctx, OPC_J, 4, rt, rs,
12267 (int32_t)(ctx->opcode & 0x3FFFFFF) << 1);
12271 gen_compute_branch(ctx, OPC_JAL, 4, rt, rs,
12272 (int32_t)(ctx->opcode & 0x3FFFFFF) << 1);
12275 /* Floating point (COP1) */
12277 mips32_op = OPC_LWC1;
12280 mips32_op = OPC_LDC1;
12283 mips32_op = OPC_SWC1;
12286 mips32_op = OPC_SDC1;
12288 gen_cop1_ldst(env, ctx, mips32_op, rt, rs, imm);
12292 int reg = mmreg(ZIMM(ctx->opcode, 23, 3));
12293 int offset = SIMM(ctx->opcode, 0, 23) << 2;
12295 gen_addiupc(ctx, reg, offset, 0, 0);
12298 /* Loads and stores */
12300 mips32_op = OPC_LB;
12303 mips32_op = OPC_LBU;
12306 mips32_op = OPC_LH;
12309 mips32_op = OPC_LHU;
12312 mips32_op = OPC_LW;
12314 #ifdef TARGET_MIPS64
12316 mips32_op = OPC_LD;
12319 mips32_op = OPC_SD;
12323 mips32_op = OPC_SB;
12326 mips32_op = OPC_SH;
12329 mips32_op = OPC_SW;
12332 gen_ld(env, ctx, mips32_op, rt, rs, imm);
12335 gen_st(ctx, mips32_op, rt, rs, imm);
12338 generate_exception(ctx, EXCP_RI);
12343 static int decode_micromips_opc (CPUMIPSState *env, DisasContext *ctx, int *is_branch)
12347 /* make sure instructions are on a halfword boundary */
12348 if (ctx->pc & 0x1) {
12349 env->CP0_BadVAddr = ctx->pc;
12350 generate_exception(ctx, EXCP_AdEL);
12351 ctx->bstate = BS_STOP;
12355 op = (ctx->opcode >> 10) & 0x3f;
12356 /* Enforce properly-sized instructions in a delay slot */
12357 if (ctx->hflags & MIPS_HFLAG_BMASK) {
12358 int bits = ctx->hflags & MIPS_HFLAG_BMASK_EXT;
12392 case POOL48A: /* ??? */
12397 if (bits & MIPS_HFLAG_BDS16) {
12398 generate_exception(ctx, EXCP_RI);
12399 /* Just stop translation; the user is confused. */
12400 ctx->bstate = BS_STOP;
12425 if (bits & MIPS_HFLAG_BDS32) {
12426 generate_exception(ctx, EXCP_RI);
12427 /* Just stop translation; the user is confused. */
12428 ctx->bstate = BS_STOP;
12439 int rd = mmreg(uMIPS_RD(ctx->opcode));
12440 int rs1 = mmreg(uMIPS_RS1(ctx->opcode));
12441 int rs2 = mmreg(uMIPS_RS2(ctx->opcode));
12444 switch (ctx->opcode & 0x1) {
12453 gen_arith(env, ctx, opc, rd, rs1, rs2);
12458 int rd = mmreg(uMIPS_RD(ctx->opcode));
12459 int rs = mmreg(uMIPS_RS(ctx->opcode));
12460 int amount = (ctx->opcode >> 1) & 0x7;
12462 amount = amount == 0 ? 8 : amount;
12464 switch (ctx->opcode & 0x1) {
12473 gen_shift_imm(env, ctx, opc, rd, rs, amount);
12477 gen_pool16c_insn(env, ctx, is_branch);
12481 int rd = mmreg(uMIPS_RD(ctx->opcode));
12482 int rb = 28; /* GP */
12483 int16_t offset = SIMM(ctx->opcode, 0, 7) << 2;
12485 gen_ld(env, ctx, OPC_LW, rd, rb, offset);
12489 if (ctx->opcode & 1) {
12490 generate_exception(ctx, EXCP_RI);
12493 int enc_dest = uMIPS_RD(ctx->opcode);
12494 int enc_rt = uMIPS_RS2(ctx->opcode);
12495 int enc_rs = uMIPS_RS1(ctx->opcode);
12496 int rd, rs, re, rt;
12497 static const int rd_enc[] = { 5, 5, 6, 4, 4, 4, 4, 4 };
12498 static const int re_enc[] = { 6, 7, 7, 21, 22, 5, 6, 7 };
12499 static const int rs_rt_enc[] = { 0, 17, 2, 3, 16, 18, 19, 20 };
12501 rd = rd_enc[enc_dest];
12502 re = re_enc[enc_dest];
12503 rs = rs_rt_enc[enc_rs];
12504 rt = rs_rt_enc[enc_rt];
12506 gen_arith_imm(env, ctx, OPC_ADDIU, rd, rs, 0);
12507 gen_arith_imm(env, ctx, OPC_ADDIU, re, rt, 0);
12512 int rd = mmreg(uMIPS_RD(ctx->opcode));
12513 int rb = mmreg(uMIPS_RS(ctx->opcode));
12514 int16_t offset = ZIMM(ctx->opcode, 0, 4);
12515 offset = (offset == 0xf ? -1 : offset);
12517 gen_ld(env, ctx, OPC_LBU, rd, rb, offset);
12522 int rd = mmreg(uMIPS_RD(ctx->opcode));
12523 int rb = mmreg(uMIPS_RS(ctx->opcode));
12524 int16_t offset = ZIMM(ctx->opcode, 0, 4) << 1;
12526 gen_ld(env, ctx, OPC_LHU, rd, rb, offset);
12531 int rd = (ctx->opcode >> 5) & 0x1f;
12532 int rb = 29; /* SP */
12533 int16_t offset = ZIMM(ctx->opcode, 0, 5) << 2;
12535 gen_ld(env, ctx, OPC_LW, rd, rb, offset);
12540 int rd = mmreg(uMIPS_RD(ctx->opcode));
12541 int rb = mmreg(uMIPS_RS(ctx->opcode));
12542 int16_t offset = ZIMM(ctx->opcode, 0, 4) << 2;
12544 gen_ld(env, ctx, OPC_LW, rd, rb, offset);
12549 int rd = mmreg2(uMIPS_RD(ctx->opcode));
12550 int rb = mmreg(uMIPS_RS(ctx->opcode));
12551 int16_t offset = ZIMM(ctx->opcode, 0, 4);
12553 gen_st(ctx, OPC_SB, rd, rb, offset);
12558 int rd = mmreg2(uMIPS_RD(ctx->opcode));
12559 int rb = mmreg(uMIPS_RS(ctx->opcode));
12560 int16_t offset = ZIMM(ctx->opcode, 0, 4) << 1;
12562 gen_st(ctx, OPC_SH, rd, rb, offset);
12567 int rd = (ctx->opcode >> 5) & 0x1f;
12568 int rb = 29; /* SP */
12569 int16_t offset = ZIMM(ctx->opcode, 0, 5) << 2;
12571 gen_st(ctx, OPC_SW, rd, rb, offset);
12576 int rd = mmreg2(uMIPS_RD(ctx->opcode));
12577 int rb = mmreg(uMIPS_RS(ctx->opcode));
12578 int16_t offset = ZIMM(ctx->opcode, 0, 4) << 2;
12580 gen_st(ctx, OPC_SW, rd, rb, offset);
12585 int rd = uMIPS_RD5(ctx->opcode);
12586 int rs = uMIPS_RS5(ctx->opcode);
12588 gen_arith_imm(env, ctx, OPC_ADDIU, rd, rs, 0);
12592 gen_andi16(env, ctx);
12595 switch (ctx->opcode & 0x1) {
12597 gen_addius5(env, ctx);
12600 gen_addiusp(env, ctx);
12605 switch (ctx->opcode & 0x1) {
12607 gen_addiur2(env, ctx);
12610 gen_addiur1sp(env, ctx);
12615 gen_compute_branch(ctx, OPC_BEQ, 2, 0, 0,
12616 SIMM(ctx->opcode, 0, 10) << 1);
12621 gen_compute_branch(ctx, op == BNEZ16 ? OPC_BNE : OPC_BEQ, 2,
12622 mmreg(uMIPS_RD(ctx->opcode)),
12623 0, SIMM(ctx->opcode, 0, 7) << 1);
12628 int reg = mmreg(uMIPS_RD(ctx->opcode));
12629 int imm = ZIMM(ctx->opcode, 0, 7);
12631 imm = (imm == 0x7f ? -1 : imm);
12632 tcg_gen_movi_tl(cpu_gpr[reg], imm);
12642 generate_exception(ctx, EXCP_RI);
12645 decode_micromips32_opc (env, ctx, op, is_branch);
12652 /* SmartMIPS extension to MIPS32 */
12654 #if defined(TARGET_MIPS64)
12656 /* MDMX extension to MIPS64 */
12660 /* MIPSDSP functions. */
12661 static void gen_mipsdsp_ld(CPUMIPSState *env, DisasContext *ctx, uint32_t opc,
12662 int rd, int base, int offset)
12664 const char *opn = "ldx";
12673 t0 = tcg_temp_new();
12676 gen_load_gpr(t0, offset);
12677 } else if (offset == 0) {
12678 gen_load_gpr(t0, base);
12680 gen_op_addr_add(ctx, t0, cpu_gpr[base], cpu_gpr[offset]);
12685 tcg_gen_qemu_ld8u(t0, t0, ctx->mem_idx);
12686 gen_store_gpr(t0, rd);
12690 tcg_gen_qemu_ld16s(t0, t0, ctx->mem_idx);
12691 gen_store_gpr(t0, rd);
12695 tcg_gen_qemu_ld32s(t0, t0, ctx->mem_idx);
12696 gen_store_gpr(t0, rd);
12699 #if defined(TARGET_MIPS64)
12701 tcg_gen_qemu_ld64(t0, t0, ctx->mem_idx);
12702 gen_store_gpr(t0, rd);
12707 (void)opn; /* avoid a compiler warning */
12708 MIPS_DEBUG("%s %s, %s(%s)", opn,
12709 regnames[rd], regnames[offset], regnames[base]);
12713 static void gen_mipsdsp_arith(DisasContext *ctx, uint32_t op1, uint32_t op2,
12714 int ret, int v1, int v2)
12716 const char *opn = "mipsdsp arith";
12721 /* Treat as NOP. */
12726 v1_t = tcg_temp_new();
12727 v2_t = tcg_temp_new();
12729 gen_load_gpr(v1_t, v1);
12730 gen_load_gpr(v2_t, v2);
12733 /* OPC_MULT_G_2E is equal OPC_ADDUH_QB_DSP */
12734 case OPC_MULT_G_2E:
12738 gen_helper_adduh_qb(cpu_gpr[ret], v1_t, v2_t);
12740 case OPC_ADDUH_R_QB:
12741 gen_helper_adduh_r_qb(cpu_gpr[ret], v1_t, v2_t);
12744 gen_helper_addqh_ph(cpu_gpr[ret], v1_t, v2_t);
12746 case OPC_ADDQH_R_PH:
12747 gen_helper_addqh_r_ph(cpu_gpr[ret], v1_t, v2_t);
12750 gen_helper_addqh_w(cpu_gpr[ret], v1_t, v2_t);
12752 case OPC_ADDQH_R_W:
12753 gen_helper_addqh_r_w(cpu_gpr[ret], v1_t, v2_t);
12756 gen_helper_subuh_qb(cpu_gpr[ret], v1_t, v2_t);
12758 case OPC_SUBUH_R_QB:
12759 gen_helper_subuh_r_qb(cpu_gpr[ret], v1_t, v2_t);
12762 gen_helper_subqh_ph(cpu_gpr[ret], v1_t, v2_t);
12764 case OPC_SUBQH_R_PH:
12765 gen_helper_subqh_r_ph(cpu_gpr[ret], v1_t, v2_t);
12768 gen_helper_subqh_w(cpu_gpr[ret], v1_t, v2_t);
12770 case OPC_SUBQH_R_W:
12771 gen_helper_subqh_r_w(cpu_gpr[ret], v1_t, v2_t);
12775 case OPC_ABSQ_S_PH_DSP:
12777 case OPC_ABSQ_S_QB:
12779 gen_helper_absq_s_qb(cpu_gpr[ret], v2_t, cpu_env);
12781 case OPC_ABSQ_S_PH:
12783 gen_helper_absq_s_ph(cpu_gpr[ret], v2_t, cpu_env);
12787 gen_helper_absq_s_w(cpu_gpr[ret], v2_t, cpu_env);
12789 case OPC_PRECEQ_W_PHL:
12791 tcg_gen_andi_tl(cpu_gpr[ret], v2_t, 0xFFFF0000);
12792 tcg_gen_ext32s_tl(cpu_gpr[ret], cpu_gpr[ret]);
12794 case OPC_PRECEQ_W_PHR:
12796 tcg_gen_andi_tl(cpu_gpr[ret], v2_t, 0x0000FFFF);
12797 tcg_gen_shli_tl(cpu_gpr[ret], cpu_gpr[ret], 16);
12798 tcg_gen_ext32s_tl(cpu_gpr[ret], cpu_gpr[ret]);
12800 case OPC_PRECEQU_PH_QBL:
12802 gen_helper_precequ_ph_qbl(cpu_gpr[ret], v2_t);
12804 case OPC_PRECEQU_PH_QBR:
12806 gen_helper_precequ_ph_qbr(cpu_gpr[ret], v2_t);
12808 case OPC_PRECEQU_PH_QBLA:
12810 gen_helper_precequ_ph_qbla(cpu_gpr[ret], v2_t);
12812 case OPC_PRECEQU_PH_QBRA:
12814 gen_helper_precequ_ph_qbra(cpu_gpr[ret], v2_t);
12816 case OPC_PRECEU_PH_QBL:
12818 gen_helper_preceu_ph_qbl(cpu_gpr[ret], v2_t);
12820 case OPC_PRECEU_PH_QBR:
12822 gen_helper_preceu_ph_qbr(cpu_gpr[ret], v2_t);
12824 case OPC_PRECEU_PH_QBLA:
12826 gen_helper_preceu_ph_qbla(cpu_gpr[ret], v2_t);
12828 case OPC_PRECEU_PH_QBRA:
12830 gen_helper_preceu_ph_qbra(cpu_gpr[ret], v2_t);
12834 case OPC_ADDU_QB_DSP:
12838 gen_helper_addq_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12840 case OPC_ADDQ_S_PH:
12842 gen_helper_addq_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12846 gen_helper_addq_s_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12850 gen_helper_addu_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12852 case OPC_ADDU_S_QB:
12854 gen_helper_addu_s_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12858 gen_helper_addu_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12860 case OPC_ADDU_S_PH:
12862 gen_helper_addu_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12866 gen_helper_subq_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12868 case OPC_SUBQ_S_PH:
12870 gen_helper_subq_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12874 gen_helper_subq_s_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12878 gen_helper_subu_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12880 case OPC_SUBU_S_QB:
12882 gen_helper_subu_s_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12886 gen_helper_subu_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12888 case OPC_SUBU_S_PH:
12890 gen_helper_subu_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12894 gen_helper_addsc(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12898 gen_helper_addwc(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12902 gen_helper_modsub(cpu_gpr[ret], v1_t, v2_t);
12904 case OPC_RADDU_W_QB:
12906 gen_helper_raddu_w_qb(cpu_gpr[ret], v1_t);
12910 case OPC_CMPU_EQ_QB_DSP:
12912 case OPC_PRECR_QB_PH:
12914 gen_helper_precr_qb_ph(cpu_gpr[ret], v1_t, v2_t);
12916 case OPC_PRECRQ_QB_PH:
12918 gen_helper_precrq_qb_ph(cpu_gpr[ret], v1_t, v2_t);
12920 case OPC_PRECR_SRA_PH_W:
12923 TCGv_i32 sa_t = tcg_const_i32(v2);
12924 gen_helper_precr_sra_ph_w(cpu_gpr[ret], sa_t, v1_t,
12926 tcg_temp_free_i32(sa_t);
12929 case OPC_PRECR_SRA_R_PH_W:
12932 TCGv_i32 sa_t = tcg_const_i32(v2);
12933 gen_helper_precr_sra_r_ph_w(cpu_gpr[ret], sa_t, v1_t,
12935 tcg_temp_free_i32(sa_t);
12938 case OPC_PRECRQ_PH_W:
12940 gen_helper_precrq_ph_w(cpu_gpr[ret], v1_t, v2_t);
12942 case OPC_PRECRQ_RS_PH_W:
12944 gen_helper_precrq_rs_ph_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12946 case OPC_PRECRQU_S_QB_PH:
12948 gen_helper_precrqu_s_qb_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12952 #ifdef TARGET_MIPS64
12953 case OPC_ABSQ_S_QH_DSP:
12955 case OPC_PRECEQ_L_PWL:
12957 tcg_gen_andi_tl(cpu_gpr[ret], v2_t, 0xFFFFFFFF00000000ull);
12959 case OPC_PRECEQ_L_PWR:
12961 tcg_gen_shli_tl(cpu_gpr[ret], v2_t, 32);
12963 case OPC_PRECEQ_PW_QHL:
12965 gen_helper_preceq_pw_qhl(cpu_gpr[ret], v2_t);
12967 case OPC_PRECEQ_PW_QHR:
12969 gen_helper_preceq_pw_qhr(cpu_gpr[ret], v2_t);
12971 case OPC_PRECEQ_PW_QHLA:
12973 gen_helper_preceq_pw_qhla(cpu_gpr[ret], v2_t);
12975 case OPC_PRECEQ_PW_QHRA:
12977 gen_helper_preceq_pw_qhra(cpu_gpr[ret], v2_t);
12979 case OPC_PRECEQU_QH_OBL:
12981 gen_helper_precequ_qh_obl(cpu_gpr[ret], v2_t);
12983 case OPC_PRECEQU_QH_OBR:
12985 gen_helper_precequ_qh_obr(cpu_gpr[ret], v2_t);
12987 case OPC_PRECEQU_QH_OBLA:
12989 gen_helper_precequ_qh_obla(cpu_gpr[ret], v2_t);
12991 case OPC_PRECEQU_QH_OBRA:
12993 gen_helper_precequ_qh_obra(cpu_gpr[ret], v2_t);
12995 case OPC_PRECEU_QH_OBL:
12997 gen_helper_preceu_qh_obl(cpu_gpr[ret], v2_t);
12999 case OPC_PRECEU_QH_OBR:
13001 gen_helper_preceu_qh_obr(cpu_gpr[ret], v2_t);
13003 case OPC_PRECEU_QH_OBLA:
13005 gen_helper_preceu_qh_obla(cpu_gpr[ret], v2_t);
13007 case OPC_PRECEU_QH_OBRA:
13009 gen_helper_preceu_qh_obra(cpu_gpr[ret], v2_t);
13011 case OPC_ABSQ_S_OB:
13013 gen_helper_absq_s_ob(cpu_gpr[ret], v2_t, cpu_env);
13015 case OPC_ABSQ_S_PW:
13017 gen_helper_absq_s_pw(cpu_gpr[ret], v2_t, cpu_env);
13019 case OPC_ABSQ_S_QH:
13021 gen_helper_absq_s_qh(cpu_gpr[ret], v2_t, cpu_env);
13025 case OPC_ADDU_OB_DSP:
13027 case OPC_RADDU_L_OB:
13029 gen_helper_raddu_l_ob(cpu_gpr[ret], v1_t);
13033 gen_helper_subq_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13035 case OPC_SUBQ_S_PW:
13037 gen_helper_subq_s_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13041 gen_helper_subq_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13043 case OPC_SUBQ_S_QH:
13045 gen_helper_subq_s_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13049 gen_helper_subu_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13051 case OPC_SUBU_S_OB:
13053 gen_helper_subu_s_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13057 gen_helper_subu_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13059 case OPC_SUBU_S_QH:
13061 gen_helper_subu_s_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13065 gen_helper_subuh_ob(cpu_gpr[ret], v1_t, v2_t);
13067 case OPC_SUBUH_R_OB:
13069 gen_helper_subuh_r_ob(cpu_gpr[ret], v1_t, v2_t);
13073 gen_helper_addq_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13075 case OPC_ADDQ_S_PW:
13077 gen_helper_addq_s_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13081 gen_helper_addq_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13083 case OPC_ADDQ_S_QH:
13085 gen_helper_addq_s_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13089 gen_helper_addu_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13091 case OPC_ADDU_S_OB:
13093 gen_helper_addu_s_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13097 gen_helper_addu_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13099 case OPC_ADDU_S_QH:
13101 gen_helper_addu_s_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13105 gen_helper_adduh_ob(cpu_gpr[ret], v1_t, v2_t);
13107 case OPC_ADDUH_R_OB:
13109 gen_helper_adduh_r_ob(cpu_gpr[ret], v1_t, v2_t);
13113 case OPC_CMPU_EQ_OB_DSP:
13115 case OPC_PRECR_OB_QH:
13117 gen_helper_precr_ob_qh(cpu_gpr[ret], v1_t, v2_t);
13119 case OPC_PRECR_SRA_QH_PW:
13122 TCGv_i32 ret_t = tcg_const_i32(ret);
13123 gen_helper_precr_sra_qh_pw(v2_t, v1_t, v2_t, ret_t);
13124 tcg_temp_free_i32(ret_t);
13127 case OPC_PRECR_SRA_R_QH_PW:
13130 TCGv_i32 sa_v = tcg_const_i32(ret);
13131 gen_helper_precr_sra_r_qh_pw(v2_t, v1_t, v2_t, sa_v);
13132 tcg_temp_free_i32(sa_v);
13135 case OPC_PRECRQ_OB_QH:
13137 gen_helper_precrq_ob_qh(cpu_gpr[ret], v1_t, v2_t);
13139 case OPC_PRECRQ_PW_L:
13141 gen_helper_precrq_pw_l(cpu_gpr[ret], v1_t, v2_t);
13143 case OPC_PRECRQ_QH_PW:
13145 gen_helper_precrq_qh_pw(cpu_gpr[ret], v1_t, v2_t);
13147 case OPC_PRECRQ_RS_QH_PW:
13149 gen_helper_precrq_rs_qh_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13151 case OPC_PRECRQU_S_OB_QH:
13153 gen_helper_precrqu_s_ob_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13160 tcg_temp_free(v1_t);
13161 tcg_temp_free(v2_t);
13163 (void)opn; /* avoid a compiler warning */
13164 MIPS_DEBUG("%s", opn);
13167 static void gen_mipsdsp_shift(DisasContext *ctx, uint32_t opc,
13168 int ret, int v1, int v2)
13171 const char *opn = "mipsdsp shift";
13177 /* Treat as NOP. */
13182 t0 = tcg_temp_new();
13183 v1_t = tcg_temp_new();
13184 v2_t = tcg_temp_new();
13186 tcg_gen_movi_tl(t0, v1);
13187 gen_load_gpr(v1_t, v1);
13188 gen_load_gpr(v2_t, v2);
13191 case OPC_SHLL_QB_DSP:
13193 op2 = MASK_SHLL_QB(ctx->opcode);
13197 gen_helper_shll_qb(cpu_gpr[ret], t0, v2_t, cpu_env);
13201 gen_helper_shll_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13205 gen_helper_shll_ph(cpu_gpr[ret], t0, v2_t, cpu_env);
13209 gen_helper_shll_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13211 case OPC_SHLL_S_PH:
13213 gen_helper_shll_s_ph(cpu_gpr[ret], t0, v2_t, cpu_env);
13215 case OPC_SHLLV_S_PH:
13217 gen_helper_shll_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13221 gen_helper_shll_s_w(cpu_gpr[ret], t0, v2_t, cpu_env);
13223 case OPC_SHLLV_S_W:
13225 gen_helper_shll_s_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13229 gen_helper_shrl_qb(cpu_gpr[ret], t0, v2_t);
13233 gen_helper_shrl_qb(cpu_gpr[ret], v1_t, v2_t);
13237 gen_helper_shrl_ph(cpu_gpr[ret], t0, v2_t);
13241 gen_helper_shrl_ph(cpu_gpr[ret], v1_t, v2_t);
13245 gen_helper_shra_qb(cpu_gpr[ret], t0, v2_t);
13247 case OPC_SHRA_R_QB:
13249 gen_helper_shra_r_qb(cpu_gpr[ret], t0, v2_t);
13253 gen_helper_shra_qb(cpu_gpr[ret], v1_t, v2_t);
13255 case OPC_SHRAV_R_QB:
13257 gen_helper_shra_r_qb(cpu_gpr[ret], v1_t, v2_t);
13261 gen_helper_shra_ph(cpu_gpr[ret], t0, v2_t);
13263 case OPC_SHRA_R_PH:
13265 gen_helper_shra_r_ph(cpu_gpr[ret], t0, v2_t);
13269 gen_helper_shra_ph(cpu_gpr[ret], v1_t, v2_t);
13271 case OPC_SHRAV_R_PH:
13273 gen_helper_shra_r_ph(cpu_gpr[ret], v1_t, v2_t);
13277 gen_helper_shra_r_w(cpu_gpr[ret], t0, v2_t);
13279 case OPC_SHRAV_R_W:
13281 gen_helper_shra_r_w(cpu_gpr[ret], v1_t, v2_t);
13283 default: /* Invalid */
13284 MIPS_INVAL("MASK SHLL.QB");
13285 generate_exception(ctx, EXCP_RI);
13290 #ifdef TARGET_MIPS64
13291 case OPC_SHLL_OB_DSP:
13292 op2 = MASK_SHLL_OB(ctx->opcode);
13296 gen_helper_shll_pw(cpu_gpr[ret], v2_t, t0, cpu_env);
13300 gen_helper_shll_pw(cpu_gpr[ret], v2_t, v1_t, cpu_env);
13302 case OPC_SHLL_S_PW:
13304 gen_helper_shll_s_pw(cpu_gpr[ret], v2_t, t0, cpu_env);
13306 case OPC_SHLLV_S_PW:
13308 gen_helper_shll_s_pw(cpu_gpr[ret], v2_t, v1_t, cpu_env);
13312 gen_helper_shll_ob(cpu_gpr[ret], v2_t, t0, cpu_env);
13316 gen_helper_shll_ob(cpu_gpr[ret], v2_t, v1_t, cpu_env);
13320 gen_helper_shll_qh(cpu_gpr[ret], v2_t, t0, cpu_env);
13324 gen_helper_shll_qh(cpu_gpr[ret], v2_t, v1_t, cpu_env);
13326 case OPC_SHLL_S_QH:
13328 gen_helper_shll_s_qh(cpu_gpr[ret], v2_t, t0, cpu_env);
13330 case OPC_SHLLV_S_QH:
13332 gen_helper_shll_s_qh(cpu_gpr[ret], v2_t, v1_t, cpu_env);
13336 gen_helper_shra_ob(cpu_gpr[ret], v2_t, t0);
13340 gen_helper_shra_ob(cpu_gpr[ret], v2_t, v1_t);
13342 case OPC_SHRA_R_OB:
13344 gen_helper_shra_r_ob(cpu_gpr[ret], v2_t, t0);
13346 case OPC_SHRAV_R_OB:
13348 gen_helper_shra_r_ob(cpu_gpr[ret], v2_t, v1_t);
13352 gen_helper_shra_pw(cpu_gpr[ret], v2_t, t0);
13356 gen_helper_shra_pw(cpu_gpr[ret], v2_t, v1_t);
13358 case OPC_SHRA_R_PW:
13360 gen_helper_shra_r_pw(cpu_gpr[ret], v2_t, t0);
13362 case OPC_SHRAV_R_PW:
13364 gen_helper_shra_r_pw(cpu_gpr[ret], v2_t, v1_t);
13368 gen_helper_shra_qh(cpu_gpr[ret], v2_t, t0);
13372 gen_helper_shra_qh(cpu_gpr[ret], v2_t, v1_t);
13374 case OPC_SHRA_R_QH:
13376 gen_helper_shra_r_qh(cpu_gpr[ret], v2_t, t0);
13378 case OPC_SHRAV_R_QH:
13380 gen_helper_shra_r_qh(cpu_gpr[ret], v2_t, v1_t);
13384 gen_helper_shrl_ob(cpu_gpr[ret], v2_t, t0);
13388 gen_helper_shrl_ob(cpu_gpr[ret], v2_t, v1_t);
13392 gen_helper_shrl_qh(cpu_gpr[ret], v2_t, t0);
13396 gen_helper_shrl_qh(cpu_gpr[ret], v2_t, v1_t);
13398 default: /* Invalid */
13399 MIPS_INVAL("MASK SHLL.OB");
13400 generate_exception(ctx, EXCP_RI);
13408 tcg_temp_free(v1_t);
13409 tcg_temp_free(v2_t);
13410 (void)opn; /* avoid a compiler warning */
13411 MIPS_DEBUG("%s", opn);
13414 static void gen_mipsdsp_multiply(DisasContext *ctx, uint32_t op1, uint32_t op2,
13415 int ret, int v1, int v2, int check_ret)
13417 const char *opn = "mipsdsp multiply";
13422 if ((ret == 0) && (check_ret == 1)) {
13423 /* Treat as NOP. */
13428 t0 = tcg_temp_new_i32();
13429 v1_t = tcg_temp_new();
13430 v2_t = tcg_temp_new();
13432 tcg_gen_movi_i32(t0, ret);
13433 gen_load_gpr(v1_t, v1);
13434 gen_load_gpr(v2_t, v2);
13437 /* OPC_MULT_G_2E, OPC_ADDUH_QB_DSP, OPC_MUL_PH_DSP have
13438 * the same mask and op1. */
13439 case OPC_MULT_G_2E:
13442 gen_helper_mul_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13445 gen_helper_mul_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13448 gen_helper_mulq_s_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13450 case OPC_MULQ_RS_W:
13451 gen_helper_mulq_rs_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13455 case OPC_DPA_W_PH_DSP:
13457 case OPC_DPAU_H_QBL:
13459 gen_helper_dpau_h_qbl(t0, v1_t, v2_t, cpu_env);
13461 case OPC_DPAU_H_QBR:
13463 gen_helper_dpau_h_qbr(t0, v1_t, v2_t, cpu_env);
13465 case OPC_DPSU_H_QBL:
13467 gen_helper_dpsu_h_qbl(t0, v1_t, v2_t, cpu_env);
13469 case OPC_DPSU_H_QBR:
13471 gen_helper_dpsu_h_qbr(t0, v1_t, v2_t, cpu_env);
13475 gen_helper_dpa_w_ph(t0, v1_t, v2_t, cpu_env);
13477 case OPC_DPAX_W_PH:
13479 gen_helper_dpax_w_ph(t0, v1_t, v2_t, cpu_env);
13481 case OPC_DPAQ_S_W_PH:
13483 gen_helper_dpaq_s_w_ph(t0, v1_t, v2_t, cpu_env);
13485 case OPC_DPAQX_S_W_PH:
13487 gen_helper_dpaqx_s_w_ph(t0, v1_t, v2_t, cpu_env);
13489 case OPC_DPAQX_SA_W_PH:
13491 gen_helper_dpaqx_sa_w_ph(t0, v1_t, v2_t, cpu_env);
13495 gen_helper_dps_w_ph(t0, v1_t, v2_t, cpu_env);
13497 case OPC_DPSX_W_PH:
13499 gen_helper_dpsx_w_ph(t0, v1_t, v2_t, cpu_env);
13501 case OPC_DPSQ_S_W_PH:
13503 gen_helper_dpsq_s_w_ph(t0, v1_t, v2_t, cpu_env);
13505 case OPC_DPSQX_S_W_PH:
13507 gen_helper_dpsqx_s_w_ph(t0, v1_t, v2_t, cpu_env);
13509 case OPC_DPSQX_SA_W_PH:
13511 gen_helper_dpsqx_sa_w_ph(t0, v1_t, v2_t, cpu_env);
13513 case OPC_MULSAQ_S_W_PH:
13515 gen_helper_mulsaq_s_w_ph(t0, v1_t, v2_t, cpu_env);
13517 case OPC_DPAQ_SA_L_W:
13519 gen_helper_dpaq_sa_l_w(t0, v1_t, v2_t, cpu_env);
13521 case OPC_DPSQ_SA_L_W:
13523 gen_helper_dpsq_sa_l_w(t0, v1_t, v2_t, cpu_env);
13525 case OPC_MAQ_S_W_PHL:
13527 gen_helper_maq_s_w_phl(t0, v1_t, v2_t, cpu_env);
13529 case OPC_MAQ_S_W_PHR:
13531 gen_helper_maq_s_w_phr(t0, v1_t, v2_t, cpu_env);
13533 case OPC_MAQ_SA_W_PHL:
13535 gen_helper_maq_sa_w_phl(t0, v1_t, v2_t, cpu_env);
13537 case OPC_MAQ_SA_W_PHR:
13539 gen_helper_maq_sa_w_phr(t0, v1_t, v2_t, cpu_env);
13541 case OPC_MULSA_W_PH:
13543 gen_helper_mulsa_w_ph(t0, v1_t, v2_t, cpu_env);
13547 #ifdef TARGET_MIPS64
13548 case OPC_DPAQ_W_QH_DSP:
13550 int ac = ret & 0x03;
13551 tcg_gen_movi_i32(t0, ac);
13556 gen_helper_dmadd(v1_t, v2_t, t0, cpu_env);
13560 gen_helper_dmaddu(v1_t, v2_t, t0, cpu_env);
13564 gen_helper_dmsub(v1_t, v2_t, t0, cpu_env);
13568 gen_helper_dmsubu(v1_t, v2_t, t0, cpu_env);
13572 gen_helper_dpa_w_qh(v1_t, v2_t, t0, cpu_env);
13574 case OPC_DPAQ_S_W_QH:
13576 gen_helper_dpaq_s_w_qh(v1_t, v2_t, t0, cpu_env);
13578 case OPC_DPAQ_SA_L_PW:
13580 gen_helper_dpaq_sa_l_pw(v1_t, v2_t, t0, cpu_env);
13582 case OPC_DPAU_H_OBL:
13584 gen_helper_dpau_h_obl(v1_t, v2_t, t0, cpu_env);
13586 case OPC_DPAU_H_OBR:
13588 gen_helper_dpau_h_obr(v1_t, v2_t, t0, cpu_env);
13592 gen_helper_dps_w_qh(v1_t, v2_t, t0, cpu_env);
13594 case OPC_DPSQ_S_W_QH:
13596 gen_helper_dpsq_s_w_qh(v1_t, v2_t, t0, cpu_env);
13598 case OPC_DPSQ_SA_L_PW:
13600 gen_helper_dpsq_sa_l_pw(v1_t, v2_t, t0, cpu_env);
13602 case OPC_DPSU_H_OBL:
13604 gen_helper_dpsu_h_obl(v1_t, v2_t, t0, cpu_env);
13606 case OPC_DPSU_H_OBR:
13608 gen_helper_dpsu_h_obr(v1_t, v2_t, t0, cpu_env);
13610 case OPC_MAQ_S_L_PWL:
13612 gen_helper_maq_s_l_pwl(v1_t, v2_t, t0, cpu_env);
13614 case OPC_MAQ_S_L_PWR:
13616 gen_helper_maq_s_l_pwr(v1_t, v2_t, t0, cpu_env);
13618 case OPC_MAQ_S_W_QHLL:
13620 gen_helper_maq_s_w_qhll(v1_t, v2_t, t0, cpu_env);
13622 case OPC_MAQ_SA_W_QHLL:
13624 gen_helper_maq_sa_w_qhll(v1_t, v2_t, t0, cpu_env);
13626 case OPC_MAQ_S_W_QHLR:
13628 gen_helper_maq_s_w_qhlr(v1_t, v2_t, t0, cpu_env);
13630 case OPC_MAQ_SA_W_QHLR:
13632 gen_helper_maq_sa_w_qhlr(v1_t, v2_t, t0, cpu_env);
13634 case OPC_MAQ_S_W_QHRL:
13636 gen_helper_maq_s_w_qhrl(v1_t, v2_t, t0, cpu_env);
13638 case OPC_MAQ_SA_W_QHRL:
13640 gen_helper_maq_sa_w_qhrl(v1_t, v2_t, t0, cpu_env);
13642 case OPC_MAQ_S_W_QHRR:
13644 gen_helper_maq_s_w_qhrr(v1_t, v2_t, t0, cpu_env);
13646 case OPC_MAQ_SA_W_QHRR:
13648 gen_helper_maq_sa_w_qhrr(v1_t, v2_t, t0, cpu_env);
13650 case OPC_MULSAQ_S_L_PW:
13652 gen_helper_mulsaq_s_l_pw(v1_t, v2_t, t0, cpu_env);
13654 case OPC_MULSAQ_S_W_QH:
13656 gen_helper_mulsaq_s_w_qh(v1_t, v2_t, t0, cpu_env);
13662 case OPC_ADDU_QB_DSP:
13664 case OPC_MULEU_S_PH_QBL:
13666 gen_helper_muleu_s_ph_qbl(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13668 case OPC_MULEU_S_PH_QBR:
13670 gen_helper_muleu_s_ph_qbr(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13672 case OPC_MULQ_RS_PH:
13674 gen_helper_mulq_rs_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13676 case OPC_MULEQ_S_W_PHL:
13678 gen_helper_muleq_s_w_phl(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13680 case OPC_MULEQ_S_W_PHR:
13682 gen_helper_muleq_s_w_phr(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13684 case OPC_MULQ_S_PH:
13686 gen_helper_mulq_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13690 #ifdef TARGET_MIPS64
13691 case OPC_ADDU_OB_DSP:
13693 case OPC_MULEQ_S_PW_QHL:
13695 gen_helper_muleq_s_pw_qhl(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13697 case OPC_MULEQ_S_PW_QHR:
13699 gen_helper_muleq_s_pw_qhr(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13701 case OPC_MULEU_S_QH_OBL:
13703 gen_helper_muleu_s_qh_obl(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13705 case OPC_MULEU_S_QH_OBR:
13707 gen_helper_muleu_s_qh_obr(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13709 case OPC_MULQ_RS_QH:
13711 gen_helper_mulq_rs_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13718 tcg_temp_free_i32(t0);
13719 tcg_temp_free(v1_t);
13720 tcg_temp_free(v2_t);
13722 (void)opn; /* avoid a compiler warning */
13723 MIPS_DEBUG("%s", opn);
13727 static void gen_mipsdsp_bitinsn(CPUMIPSState *env, DisasContext *ctx,
13728 uint32_t op1, uint32_t op2,
13731 const char *opn = "mipsdsp Bit/ Manipulation";
13737 /* Treat as NOP. */
13742 t0 = tcg_temp_new();
13743 val_t = tcg_temp_new();
13744 gen_load_gpr(val_t, val);
13747 case OPC_ABSQ_S_PH_DSP:
13751 gen_helper_bitrev(cpu_gpr[ret], val_t);
13756 target_long result;
13757 imm = (ctx->opcode >> 16) & 0xFF;
13758 result = (uint32_t)imm << 24 |
13759 (uint32_t)imm << 16 |
13760 (uint32_t)imm << 8 |
13762 result = (int32_t)result;
13763 tcg_gen_movi_tl(cpu_gpr[ret], result);
13768 tcg_gen_ext8u_tl(cpu_gpr[ret], val_t);
13769 tcg_gen_shli_tl(t0, cpu_gpr[ret], 8);
13770 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
13771 tcg_gen_shli_tl(t0, cpu_gpr[ret], 16);
13772 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
13773 tcg_gen_ext32s_tl(cpu_gpr[ret], cpu_gpr[ret]);
13778 imm = (ctx->opcode >> 16) & 0x03FF;
13779 tcg_gen_movi_tl(cpu_gpr[ret], \
13780 (target_long)((int32_t)imm << 16 | \
13781 (uint32_t)(uint16_t)imm));
13786 tcg_gen_ext16u_tl(cpu_gpr[ret], val_t);
13787 tcg_gen_shli_tl(t0, cpu_gpr[ret], 16);
13788 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
13789 tcg_gen_ext32s_tl(cpu_gpr[ret], cpu_gpr[ret]);
13793 #ifdef TARGET_MIPS64
13794 case OPC_ABSQ_S_QH_DSP:
13801 imm = (ctx->opcode >> 16) & 0xFF;
13802 temp = ((uint64_t)imm << 8) | (uint64_t)imm;
13803 temp = (temp << 16) | temp;
13804 temp = (temp << 32) | temp;
13805 tcg_gen_movi_tl(cpu_gpr[ret], temp);
13813 imm = (ctx->opcode >> 16) & 0x03FF;
13814 imm = (int16_t)(imm << 6) >> 6;
13815 temp = ((target_long)imm << 32) \
13816 | ((target_long)imm & 0xFFFFFFFF);
13817 tcg_gen_movi_tl(cpu_gpr[ret], temp);
13825 imm = (ctx->opcode >> 16) & 0x03FF;
13826 imm = (int16_t)(imm << 6) >> 6;
13828 temp = ((uint64_t)(uint16_t)imm << 48) |
13829 ((uint64_t)(uint16_t)imm << 32) |
13830 ((uint64_t)(uint16_t)imm << 16) |
13831 (uint64_t)(uint16_t)imm;
13832 tcg_gen_movi_tl(cpu_gpr[ret], temp);
13837 tcg_gen_ext8u_tl(cpu_gpr[ret], val_t);
13838 tcg_gen_shli_tl(t0, cpu_gpr[ret], 8);
13839 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
13840 tcg_gen_shli_tl(t0, cpu_gpr[ret], 16);
13841 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
13842 tcg_gen_shli_tl(t0, cpu_gpr[ret], 32);
13843 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
13847 tcg_gen_ext32u_i64(cpu_gpr[ret], val_t);
13848 tcg_gen_shli_tl(t0, cpu_gpr[ret], 32);
13849 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
13853 tcg_gen_ext16u_tl(cpu_gpr[ret], val_t);
13854 tcg_gen_shli_tl(t0, cpu_gpr[ret], 16);
13855 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
13856 tcg_gen_shli_tl(t0, cpu_gpr[ret], 32);
13857 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
13864 tcg_temp_free(val_t);
13866 (void)opn; /* avoid a compiler warning */
13867 MIPS_DEBUG("%s", opn);
13870 static void gen_mipsdsp_add_cmp_pick(DisasContext *ctx,
13871 uint32_t op1, uint32_t op2,
13872 int ret, int v1, int v2, int check_ret)
13874 const char *opn = "mipsdsp add compare pick";
13880 if ((ret == 0) && (check_ret == 1)) {
13881 /* Treat as NOP. */
13886 t0 = tcg_temp_new_i32();
13887 t1 = tcg_temp_new();
13888 v1_t = tcg_temp_new();
13889 v2_t = tcg_temp_new();
13891 gen_load_gpr(v1_t, v1);
13892 gen_load_gpr(v2_t, v2);
13895 case OPC_APPEND_DSP:
13898 tcg_gen_movi_i32(t0, v2);
13899 gen_helper_append(cpu_gpr[ret], cpu_gpr[ret], v1_t, t0);
13902 tcg_gen_movi_i32(t0, v2);
13903 gen_helper_prepend(cpu_gpr[ret], v1_t, cpu_gpr[ret], t0);
13906 tcg_gen_movi_i32(t0, v2);
13907 gen_helper_balign(cpu_gpr[ret], v1_t, cpu_gpr[ret], t0);
13909 default: /* Invid */
13910 MIPS_INVAL("MASK APPEND");
13911 generate_exception(ctx, EXCP_RI);
13915 case OPC_CMPU_EQ_QB_DSP:
13917 case OPC_CMPU_EQ_QB:
13919 gen_helper_cmpu_eq_qb(v1_t, v2_t, cpu_env);
13921 case OPC_CMPU_LT_QB:
13923 gen_helper_cmpu_lt_qb(v1_t, v2_t, cpu_env);
13925 case OPC_CMPU_LE_QB:
13927 gen_helper_cmpu_le_qb(v1_t, v2_t, cpu_env);
13929 case OPC_CMPGU_EQ_QB:
13931 gen_helper_cmpgu_eq_qb(cpu_gpr[ret], v1_t, v2_t);
13933 case OPC_CMPGU_LT_QB:
13935 gen_helper_cmpgu_lt_qb(cpu_gpr[ret], v1_t, v2_t);
13937 case OPC_CMPGU_LE_QB:
13939 gen_helper_cmpgu_le_qb(cpu_gpr[ret], v1_t, v2_t);
13941 case OPC_CMPGDU_EQ_QB:
13943 gen_helper_cmpgu_eq_qb(t1, v1_t, v2_t);
13944 tcg_gen_mov_tl(cpu_gpr[ret], t1);
13945 tcg_gen_andi_tl(cpu_dspctrl, cpu_dspctrl, 0xF0FFFFFF);
13946 tcg_gen_shli_tl(t1, t1, 24);
13947 tcg_gen_or_tl(cpu_dspctrl, cpu_dspctrl, t1);
13949 case OPC_CMPGDU_LT_QB:
13951 gen_helper_cmpgu_lt_qb(t1, v1_t, v2_t);
13952 tcg_gen_mov_tl(cpu_gpr[ret], t1);
13953 tcg_gen_andi_tl(cpu_dspctrl, cpu_dspctrl, 0xF0FFFFFF);
13954 tcg_gen_shli_tl(t1, t1, 24);
13955 tcg_gen_or_tl(cpu_dspctrl, cpu_dspctrl, t1);
13957 case OPC_CMPGDU_LE_QB:
13959 gen_helper_cmpgu_le_qb(t1, v1_t, v2_t);
13960 tcg_gen_mov_tl(cpu_gpr[ret], t1);
13961 tcg_gen_andi_tl(cpu_dspctrl, cpu_dspctrl, 0xF0FFFFFF);
13962 tcg_gen_shli_tl(t1, t1, 24);
13963 tcg_gen_or_tl(cpu_dspctrl, cpu_dspctrl, t1);
13965 case OPC_CMP_EQ_PH:
13967 gen_helper_cmp_eq_ph(v1_t, v2_t, cpu_env);
13969 case OPC_CMP_LT_PH:
13971 gen_helper_cmp_lt_ph(v1_t, v2_t, cpu_env);
13973 case OPC_CMP_LE_PH:
13975 gen_helper_cmp_le_ph(v1_t, v2_t, cpu_env);
13979 gen_helper_pick_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13983 gen_helper_pick_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13985 case OPC_PACKRL_PH:
13987 gen_helper_packrl_ph(cpu_gpr[ret], v1_t, v2_t);
13991 #ifdef TARGET_MIPS64
13992 case OPC_CMPU_EQ_OB_DSP:
13994 case OPC_CMP_EQ_PW:
13996 gen_helper_cmp_eq_pw(v1_t, v2_t, cpu_env);
13998 case OPC_CMP_LT_PW:
14000 gen_helper_cmp_lt_pw(v1_t, v2_t, cpu_env);
14002 case OPC_CMP_LE_PW:
14004 gen_helper_cmp_le_pw(v1_t, v2_t, cpu_env);
14006 case OPC_CMP_EQ_QH:
14008 gen_helper_cmp_eq_qh(v1_t, v2_t, cpu_env);
14010 case OPC_CMP_LT_QH:
14012 gen_helper_cmp_lt_qh(v1_t, v2_t, cpu_env);
14014 case OPC_CMP_LE_QH:
14016 gen_helper_cmp_le_qh(v1_t, v2_t, cpu_env);
14018 case OPC_CMPGDU_EQ_OB:
14020 gen_helper_cmpgdu_eq_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
14022 case OPC_CMPGDU_LT_OB:
14024 gen_helper_cmpgdu_lt_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
14026 case OPC_CMPGDU_LE_OB:
14028 gen_helper_cmpgdu_le_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
14030 case OPC_CMPGU_EQ_OB:
14032 gen_helper_cmpgu_eq_ob(cpu_gpr[ret], v1_t, v2_t);
14034 case OPC_CMPGU_LT_OB:
14036 gen_helper_cmpgu_lt_ob(cpu_gpr[ret], v1_t, v2_t);
14038 case OPC_CMPGU_LE_OB:
14040 gen_helper_cmpgu_le_ob(cpu_gpr[ret], v1_t, v2_t);
14042 case OPC_CMPU_EQ_OB:
14044 gen_helper_cmpu_eq_ob(v1_t, v2_t, cpu_env);
14046 case OPC_CMPU_LT_OB:
14048 gen_helper_cmpu_lt_ob(v1_t, v2_t, cpu_env);
14050 case OPC_CMPU_LE_OB:
14052 gen_helper_cmpu_le_ob(v1_t, v2_t, cpu_env);
14054 case OPC_PACKRL_PW:
14056 gen_helper_packrl_pw(cpu_gpr[ret], v1_t, v2_t);
14060 gen_helper_pick_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
14064 gen_helper_pick_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
14068 gen_helper_pick_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
14072 case OPC_DAPPEND_DSP:
14075 tcg_gen_movi_i32(t0, v2);
14076 gen_helper_dappend(cpu_gpr[ret], v1_t, cpu_gpr[ret], t0);
14079 tcg_gen_movi_i32(t0, v2);
14080 gen_helper_prependd(cpu_gpr[ret], v1_t, cpu_gpr[ret], t0);
14083 tcg_gen_movi_i32(t0, v2);
14084 gen_helper_prependw(cpu_gpr[ret], v1_t, cpu_gpr[ret], t0);
14087 tcg_gen_movi_i32(t0, v2);
14088 gen_helper_dbalign(cpu_gpr[ret], v1_t, cpu_gpr[ret], t0);
14090 default: /* Invalid */
14091 MIPS_INVAL("MASK DAPPEND");
14092 generate_exception(ctx, EXCP_RI);
14099 tcg_temp_free_i32(t0);
14101 tcg_temp_free(v1_t);
14102 tcg_temp_free(v2_t);
14104 (void)opn; /* avoid a compiler warning */
14105 MIPS_DEBUG("%s", opn);
14108 static void gen_mipsdsp_accinsn(DisasContext *ctx, uint32_t op1, uint32_t op2,
14109 int ret, int v1, int v2, int check_ret)
14112 const char *opn = "mipsdsp accumulator";
14119 if ((ret == 0) && (check_ret == 1)) {
14120 /* Treat as NOP. */
14125 t0 = tcg_temp_new();
14126 t1 = tcg_temp_new();
14127 v1_t = tcg_temp_new();
14128 v2_t = tcg_temp_new();
14130 gen_load_gpr(v1_t, v1);
14131 gen_load_gpr(v2_t, v2);
14134 case OPC_EXTR_W_DSP:
14138 tcg_gen_movi_tl(t0, v2);
14139 tcg_gen_movi_tl(t1, v1);
14140 gen_helper_extr_w(cpu_gpr[ret], t0, t1, cpu_env);
14143 tcg_gen_movi_tl(t0, v2);
14144 tcg_gen_movi_tl(t1, v1);
14145 gen_helper_extr_r_w(cpu_gpr[ret], t0, t1, cpu_env);
14147 case OPC_EXTR_RS_W:
14148 tcg_gen_movi_tl(t0, v2);
14149 tcg_gen_movi_tl(t1, v1);
14150 gen_helper_extr_rs_w(cpu_gpr[ret], t0, t1, cpu_env);
14153 tcg_gen_movi_tl(t0, v2);
14154 tcg_gen_movi_tl(t1, v1);
14155 gen_helper_extr_s_h(cpu_gpr[ret], t0, t1, cpu_env);
14157 case OPC_EXTRV_S_H:
14158 tcg_gen_movi_tl(t0, v2);
14159 gen_helper_extr_s_h(cpu_gpr[ret], t0, v1_t, cpu_env);
14162 tcg_gen_movi_tl(t0, v2);
14163 gen_helper_extr_w(cpu_gpr[ret], t0, v1_t, cpu_env);
14165 case OPC_EXTRV_R_W:
14166 tcg_gen_movi_tl(t0, v2);
14167 gen_helper_extr_r_w(cpu_gpr[ret], t0, v1_t, cpu_env);
14169 case OPC_EXTRV_RS_W:
14170 tcg_gen_movi_tl(t0, v2);
14171 gen_helper_extr_rs_w(cpu_gpr[ret], t0, v1_t, cpu_env);
14174 tcg_gen_movi_tl(t0, v2);
14175 tcg_gen_movi_tl(t1, v1);
14176 gen_helper_extp(cpu_gpr[ret], t0, t1, cpu_env);
14179 tcg_gen_movi_tl(t0, v2);
14180 gen_helper_extp(cpu_gpr[ret], t0, v1_t, cpu_env);
14183 tcg_gen_movi_tl(t0, v2);
14184 tcg_gen_movi_tl(t1, v1);
14185 gen_helper_extpdp(cpu_gpr[ret], t0, t1, cpu_env);
14188 tcg_gen_movi_tl(t0, v2);
14189 gen_helper_extpdp(cpu_gpr[ret], t0, v1_t, cpu_env);
14192 imm = (ctx->opcode >> 20) & 0x3F;
14193 tcg_gen_movi_tl(t0, ret);
14194 tcg_gen_movi_tl(t1, imm);
14195 gen_helper_shilo(t0, t1, cpu_env);
14198 tcg_gen_movi_tl(t0, ret);
14199 gen_helper_shilo(t0, v1_t, cpu_env);
14202 tcg_gen_movi_tl(t0, ret);
14203 gen_helper_mthlip(t0, v1_t, cpu_env);
14206 imm = (ctx->opcode >> 11) & 0x3FF;
14207 tcg_gen_movi_tl(t0, imm);
14208 gen_helper_wrdsp(v1_t, t0, cpu_env);
14211 imm = (ctx->opcode >> 16) & 0x03FF;
14212 tcg_gen_movi_tl(t0, imm);
14213 gen_helper_rddsp(cpu_gpr[ret], t0, cpu_env);
14217 #ifdef TARGET_MIPS64
14218 case OPC_DEXTR_W_DSP:
14222 tcg_gen_movi_tl(t0, ret);
14223 gen_helper_dmthlip(v1_t, t0, cpu_env);
14227 int shift = (ctx->opcode >> 19) & 0x7F;
14228 int ac = (ctx->opcode >> 11) & 0x03;
14229 tcg_gen_movi_tl(t0, shift);
14230 tcg_gen_movi_tl(t1, ac);
14231 gen_helper_dshilo(t0, t1, cpu_env);
14236 int ac = (ctx->opcode >> 11) & 0x03;
14237 tcg_gen_movi_tl(t0, ac);
14238 gen_helper_dshilo(v1_t, t0, cpu_env);
14242 tcg_gen_movi_tl(t0, v2);
14243 tcg_gen_movi_tl(t1, v1);
14245 gen_helper_dextp(cpu_gpr[ret], t0, t1, cpu_env);
14248 tcg_gen_movi_tl(t0, v2);
14249 gen_helper_dextp(cpu_gpr[ret], t0, v1_t, cpu_env);
14252 tcg_gen_movi_tl(t0, v2);
14253 tcg_gen_movi_tl(t1, v1);
14254 gen_helper_dextpdp(cpu_gpr[ret], t0, t1, cpu_env);
14257 tcg_gen_movi_tl(t0, v2);
14258 gen_helper_dextpdp(cpu_gpr[ret], t0, v1_t, cpu_env);
14261 tcg_gen_movi_tl(t0, v2);
14262 tcg_gen_movi_tl(t1, v1);
14263 gen_helper_dextr_l(cpu_gpr[ret], t0, t1, cpu_env);
14265 case OPC_DEXTR_R_L:
14266 tcg_gen_movi_tl(t0, v2);
14267 tcg_gen_movi_tl(t1, v1);
14268 gen_helper_dextr_r_l(cpu_gpr[ret], t0, t1, cpu_env);
14270 case OPC_DEXTR_RS_L:
14271 tcg_gen_movi_tl(t0, v2);
14272 tcg_gen_movi_tl(t1, v1);
14273 gen_helper_dextr_rs_l(cpu_gpr[ret], t0, t1, cpu_env);
14276 tcg_gen_movi_tl(t0, v2);
14277 tcg_gen_movi_tl(t1, v1);
14278 gen_helper_dextr_w(cpu_gpr[ret], t0, t1, cpu_env);
14280 case OPC_DEXTR_R_W:
14281 tcg_gen_movi_tl(t0, v2);
14282 tcg_gen_movi_tl(t1, v1);
14283 gen_helper_dextr_r_w(cpu_gpr[ret], t0, t1, cpu_env);
14285 case OPC_DEXTR_RS_W:
14286 tcg_gen_movi_tl(t0, v2);
14287 tcg_gen_movi_tl(t1, v1);
14288 gen_helper_dextr_rs_w(cpu_gpr[ret], t0, t1, cpu_env);
14290 case OPC_DEXTR_S_H:
14291 tcg_gen_movi_tl(t0, v2);
14292 tcg_gen_movi_tl(t1, v1);
14293 gen_helper_dextr_s_h(cpu_gpr[ret], t0, t1, cpu_env);
14295 case OPC_DEXTRV_S_H:
14296 tcg_gen_movi_tl(t0, v2);
14297 tcg_gen_movi_tl(t1, v1);
14298 gen_helper_dextr_s_h(cpu_gpr[ret], t0, t1, cpu_env);
14301 tcg_gen_movi_tl(t0, v2);
14302 gen_helper_dextr_l(cpu_gpr[ret], t0, v1_t, cpu_env);
14304 case OPC_DEXTRV_R_L:
14305 tcg_gen_movi_tl(t0, v2);
14306 gen_helper_dextr_r_l(cpu_gpr[ret], t0, v1_t, cpu_env);
14308 case OPC_DEXTRV_RS_L:
14309 tcg_gen_movi_tl(t0, v2);
14310 gen_helper_dextr_rs_l(cpu_gpr[ret], t0, v1_t, cpu_env);
14313 tcg_gen_movi_tl(t0, v2);
14314 gen_helper_dextr_w(cpu_gpr[ret], t0, v1_t, cpu_env);
14316 case OPC_DEXTRV_R_W:
14317 tcg_gen_movi_tl(t0, v2);
14318 gen_helper_dextr_r_w(cpu_gpr[ret], t0, v1_t, cpu_env);
14320 case OPC_DEXTRV_RS_W:
14321 tcg_gen_movi_tl(t0, v2);
14322 gen_helper_dextr_rs_w(cpu_gpr[ret], t0, v1_t, cpu_env);
14331 tcg_temp_free(v1_t);
14332 tcg_temp_free(v2_t);
14334 (void)opn; /* avoid a compiler warning */
14335 MIPS_DEBUG("%s", opn);
14338 /* End MIPSDSP functions. */
14340 static void decode_opc (CPUMIPSState *env, DisasContext *ctx, int *is_branch)
14343 int rs, rt, rd, sa;
14344 uint32_t op, op1, op2;
14347 /* make sure instructions are on a word boundary */
14348 if (ctx->pc & 0x3) {
14349 env->CP0_BadVAddr = ctx->pc;
14350 generate_exception(ctx, EXCP_AdEL);
14354 /* Handle blikely not taken case */
14355 if ((ctx->hflags & MIPS_HFLAG_BMASK_BASE) == MIPS_HFLAG_BL) {
14356 int l1 = gen_new_label();
14358 MIPS_DEBUG("blikely condition (" TARGET_FMT_lx ")", ctx->pc + 4);
14359 tcg_gen_brcondi_tl(TCG_COND_NE, bcond, 0, l1);
14360 tcg_gen_movi_i32(hflags, ctx->hflags & ~MIPS_HFLAG_BMASK);
14361 gen_goto_tb(ctx, 1, ctx->pc + 4);
14365 if (unlikely(qemu_loglevel_mask(CPU_LOG_TB_OP | CPU_LOG_TB_OP_OPT))) {
14366 tcg_gen_debug_insn_start(ctx->pc);
14369 op = MASK_OP_MAJOR(ctx->opcode);
14370 rs = (ctx->opcode >> 21) & 0x1f;
14371 rt = (ctx->opcode >> 16) & 0x1f;
14372 rd = (ctx->opcode >> 11) & 0x1f;
14373 sa = (ctx->opcode >> 6) & 0x1f;
14374 imm = (int16_t)ctx->opcode;
14377 op1 = MASK_SPECIAL(ctx->opcode);
14379 case OPC_SLL: /* Shift with immediate */
14381 gen_shift_imm(env, ctx, op1, rd, rt, sa);
14384 switch ((ctx->opcode >> 21) & 0x1f) {
14386 /* rotr is decoded as srl on non-R2 CPUs */
14387 if (env->insn_flags & ISA_MIPS32R2) {
14392 gen_shift_imm(env, ctx, op1, rd, rt, sa);
14395 generate_exception(ctx, EXCP_RI);
14399 case OPC_MOVN: /* Conditional move */
14401 check_insn(env, ctx, ISA_MIPS4 | ISA_MIPS32 |
14402 INSN_LOONGSON2E | INSN_LOONGSON2F);
14403 gen_cond_move(env, ctx, op1, rd, rs, rt);
14405 case OPC_ADD ... OPC_SUBU:
14406 gen_arith(env, ctx, op1, rd, rs, rt);
14408 case OPC_SLLV: /* Shifts */
14410 gen_shift(env, ctx, op1, rd, rs, rt);
14413 switch ((ctx->opcode >> 6) & 0x1f) {
14415 /* rotrv is decoded as srlv on non-R2 CPUs */
14416 if (env->insn_flags & ISA_MIPS32R2) {
14421 gen_shift(env, ctx, op1, rd, rs, rt);
14424 generate_exception(ctx, EXCP_RI);
14428 case OPC_SLT: /* Set on less than */
14430 gen_slt(env, ctx, op1, rd, rs, rt);
14432 case OPC_AND: /* Logic*/
14436 gen_logic(env, ctx, op1, rd, rs, rt);
14438 case OPC_MULT ... OPC_DIVU:
14440 check_insn(env, ctx, INSN_VR54XX);
14441 op1 = MASK_MUL_VR54XX(ctx->opcode);
14442 gen_mul_vr54xx(ctx, op1, rd, rs, rt);
14444 gen_muldiv(ctx, op1, rs, rt);
14446 case OPC_JR ... OPC_JALR:
14447 gen_compute_branch(ctx, op1, 4, rs, rd, sa);
14450 case OPC_TGE ... OPC_TEQ: /* Traps */
14452 gen_trap(ctx, op1, rs, rt, -1);
14454 case OPC_MFHI: /* Move from HI/LO */
14456 gen_HILO(ctx, op1, rd);
14459 case OPC_MTLO: /* Move to HI/LO */
14460 gen_HILO(ctx, op1, rs);
14462 case OPC_PMON: /* Pmon entry point, also R4010 selsl */
14463 #ifdef MIPS_STRICT_STANDARD
14464 MIPS_INVAL("PMON / selsl");
14465 generate_exception(ctx, EXCP_RI);
14467 gen_helper_0e0i(pmon, sa);
14471 generate_exception(ctx, EXCP_SYSCALL);
14472 ctx->bstate = BS_STOP;
14475 generate_exception(ctx, EXCP_BREAK);
14478 #ifdef MIPS_STRICT_STANDARD
14479 MIPS_INVAL("SPIM");
14480 generate_exception(ctx, EXCP_RI);
14482 /* Implemented as RI exception for now. */
14483 MIPS_INVAL("spim (unofficial)");
14484 generate_exception(ctx, EXCP_RI);
14488 /* Treat as NOP. */
14492 check_insn(env, ctx, ISA_MIPS4 | ISA_MIPS32);
14493 if (env->CP0_Config1 & (1 << CP0C1_FP)) {
14494 check_cp1_enabled(ctx);
14495 gen_movci(ctx, rd, rs, (ctx->opcode >> 18) & 0x7,
14496 (ctx->opcode >> 16) & 1);
14498 generate_exception_err(ctx, EXCP_CpU, 1);
14502 #if defined(TARGET_MIPS64)
14503 /* MIPS64 specific opcodes */
14508 check_insn(env, ctx, ISA_MIPS3);
14509 check_mips_64(ctx);
14510 gen_shift_imm(env, ctx, op1, rd, rt, sa);
14513 switch ((ctx->opcode >> 21) & 0x1f) {
14515 /* drotr is decoded as dsrl on non-R2 CPUs */
14516 if (env->insn_flags & ISA_MIPS32R2) {
14521 check_insn(env, ctx, ISA_MIPS3);
14522 check_mips_64(ctx);
14523 gen_shift_imm(env, ctx, op1, rd, rt, sa);
14526 generate_exception(ctx, EXCP_RI);
14531 switch ((ctx->opcode >> 21) & 0x1f) {
14533 /* drotr32 is decoded as dsrl32 on non-R2 CPUs */
14534 if (env->insn_flags & ISA_MIPS32R2) {
14539 check_insn(env, ctx, ISA_MIPS3);
14540 check_mips_64(ctx);
14541 gen_shift_imm(env, ctx, op1, rd, rt, sa);
14544 generate_exception(ctx, EXCP_RI);
14548 case OPC_DADD ... OPC_DSUBU:
14549 check_insn(env, ctx, ISA_MIPS3);
14550 check_mips_64(ctx);
14551 gen_arith(env, ctx, op1, rd, rs, rt);
14555 check_insn(env, ctx, ISA_MIPS3);
14556 check_mips_64(ctx);
14557 gen_shift(env, ctx, op1, rd, rs, rt);
14560 switch ((ctx->opcode >> 6) & 0x1f) {
14562 /* drotrv is decoded as dsrlv on non-R2 CPUs */
14563 if (env->insn_flags & ISA_MIPS32R2) {
14568 check_insn(env, ctx, ISA_MIPS3);
14569 check_mips_64(ctx);
14570 gen_shift(env, ctx, op1, rd, rs, rt);
14573 generate_exception(ctx, EXCP_RI);
14577 case OPC_DMULT ... OPC_DDIVU:
14578 check_insn(env, ctx, ISA_MIPS3);
14579 check_mips_64(ctx);
14580 gen_muldiv(ctx, op1, rs, rt);
14583 default: /* Invalid */
14584 MIPS_INVAL("special");
14585 generate_exception(ctx, EXCP_RI);
14590 op1 = MASK_SPECIAL2(ctx->opcode);
14592 case OPC_MADD ... OPC_MADDU: /* Multiply and add/sub */
14593 case OPC_MSUB ... OPC_MSUBU:
14594 check_insn(env, ctx, ISA_MIPS32);
14595 gen_muldiv(ctx, op1, rs, rt);
14598 gen_arith(env, ctx, op1, rd, rs, rt);
14602 check_insn(env, ctx, ISA_MIPS32);
14603 gen_cl(ctx, op1, rd, rs);
14606 /* XXX: not clear which exception should be raised
14607 * when in debug mode...
14609 check_insn(env, ctx, ISA_MIPS32);
14610 if (!(ctx->hflags & MIPS_HFLAG_DM)) {
14611 generate_exception(ctx, EXCP_DBp);
14613 generate_exception(ctx, EXCP_DBp);
14615 /* Treat as NOP. */
14618 case OPC_DIVU_G_2F:
14619 case OPC_MULT_G_2F:
14620 case OPC_MULTU_G_2F:
14622 case OPC_MODU_G_2F:
14623 check_insn(env, ctx, INSN_LOONGSON2F);
14624 gen_loongson_integer(ctx, op1, rd, rs, rt);
14626 #if defined(TARGET_MIPS64)
14629 check_insn(env, ctx, ISA_MIPS64);
14630 check_mips_64(ctx);
14631 gen_cl(ctx, op1, rd, rs);
14633 case OPC_DMULT_G_2F:
14634 case OPC_DMULTU_G_2F:
14635 case OPC_DDIV_G_2F:
14636 case OPC_DDIVU_G_2F:
14637 case OPC_DMOD_G_2F:
14638 case OPC_DMODU_G_2F:
14639 check_insn(env, ctx, INSN_LOONGSON2F);
14640 gen_loongson_integer(ctx, op1, rd, rs, rt);
14643 default: /* Invalid */
14644 MIPS_INVAL("special2");
14645 generate_exception(ctx, EXCP_RI);
14650 op1 = MASK_SPECIAL3(ctx->opcode);
14654 check_insn(env, ctx, ISA_MIPS32R2);
14655 gen_bitops(ctx, op1, rt, rs, sa, rd);
14658 check_insn(env, ctx, ISA_MIPS32R2);
14659 op2 = MASK_BSHFL(ctx->opcode);
14660 gen_bshfl(ctx, op2, rt, rd);
14663 gen_rdhwr(env, ctx, rt, rd);
14666 check_insn(env, ctx, ASE_MT);
14668 TCGv t0 = tcg_temp_new();
14669 TCGv t1 = tcg_temp_new();
14671 gen_load_gpr(t0, rt);
14672 gen_load_gpr(t1, rs);
14673 gen_helper_fork(t0, t1);
14679 check_insn(env, ctx, ASE_MT);
14681 TCGv t0 = tcg_temp_new();
14683 save_cpu_state(ctx, 1);
14684 gen_load_gpr(t0, rs);
14685 gen_helper_yield(t0, cpu_env, t0);
14686 gen_store_gpr(t0, rd);
14690 case OPC_DIV_G_2E ... OPC_DIVU_G_2E:
14691 case OPC_MOD_G_2E ... OPC_MODU_G_2E:
14692 case OPC_MULT_G_2E ... OPC_MULTU_G_2E:
14693 /* OPC_MULT_G_2E, OPC_ADDUH_QB_DSP, OPC_MUL_PH_DSP have
14694 * the same mask and op1. */
14695 if ((env->insn_flags & ASE_DSPR2) && (op1 == OPC_MULT_G_2E)) {
14696 op2 = MASK_ADDUH_QB(ctx->opcode);
14699 case OPC_ADDUH_R_QB:
14701 case OPC_ADDQH_R_PH:
14703 case OPC_ADDQH_R_W:
14705 case OPC_SUBUH_R_QB:
14707 case OPC_SUBQH_R_PH:
14709 case OPC_SUBQH_R_W:
14710 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
14715 case OPC_MULQ_RS_W:
14716 gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 1);
14719 MIPS_INVAL("MASK ADDUH.QB");
14720 generate_exception(ctx, EXCP_RI);
14723 } else if (env->insn_flags & INSN_LOONGSON2E) {
14724 gen_loongson_integer(ctx, op1, rd, rs, rt);
14726 generate_exception(ctx, EXCP_RI);
14730 op2 = MASK_LX(ctx->opcode);
14732 #if defined(TARGET_MIPS64)
14738 gen_mipsdsp_ld(env, ctx, op2, rd, rs, rt);
14740 default: /* Invalid */
14741 MIPS_INVAL("MASK LX");
14742 generate_exception(ctx, EXCP_RI);
14746 case OPC_ABSQ_S_PH_DSP:
14747 op2 = MASK_ABSQ_S_PH(ctx->opcode);
14749 case OPC_ABSQ_S_QB:
14750 case OPC_ABSQ_S_PH:
14752 case OPC_PRECEQ_W_PHL:
14753 case OPC_PRECEQ_W_PHR:
14754 case OPC_PRECEQU_PH_QBL:
14755 case OPC_PRECEQU_PH_QBR:
14756 case OPC_PRECEQU_PH_QBLA:
14757 case OPC_PRECEQU_PH_QBRA:
14758 case OPC_PRECEU_PH_QBL:
14759 case OPC_PRECEU_PH_QBR:
14760 case OPC_PRECEU_PH_QBLA:
14761 case OPC_PRECEU_PH_QBRA:
14762 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
14769 gen_mipsdsp_bitinsn(env, ctx, op1, op2, rd, rt);
14772 MIPS_INVAL("MASK ABSQ_S.PH");
14773 generate_exception(ctx, EXCP_RI);
14777 case OPC_ADDU_QB_DSP:
14778 op2 = MASK_ADDU_QB(ctx->opcode);
14781 case OPC_ADDQ_S_PH:
14784 case OPC_ADDU_S_QB:
14786 case OPC_ADDU_S_PH:
14788 case OPC_SUBQ_S_PH:
14791 case OPC_SUBU_S_QB:
14793 case OPC_SUBU_S_PH:
14797 case OPC_RADDU_W_QB:
14798 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
14800 case OPC_MULEU_S_PH_QBL:
14801 case OPC_MULEU_S_PH_QBR:
14802 case OPC_MULQ_RS_PH:
14803 case OPC_MULEQ_S_W_PHL:
14804 case OPC_MULEQ_S_W_PHR:
14805 case OPC_MULQ_S_PH:
14806 gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 1);
14808 default: /* Invalid */
14809 MIPS_INVAL("MASK ADDU.QB");
14810 generate_exception(ctx, EXCP_RI);
14815 case OPC_CMPU_EQ_QB_DSP:
14816 op2 = MASK_CMPU_EQ_QB(ctx->opcode);
14818 case OPC_PRECR_SRA_PH_W:
14819 case OPC_PRECR_SRA_R_PH_W:
14820 gen_mipsdsp_arith(ctx, op1, op2, rt, rs, rd);
14822 case OPC_PRECR_QB_PH:
14823 case OPC_PRECRQ_QB_PH:
14824 case OPC_PRECRQ_PH_W:
14825 case OPC_PRECRQ_RS_PH_W:
14826 case OPC_PRECRQU_S_QB_PH:
14827 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
14829 case OPC_CMPU_EQ_QB:
14830 case OPC_CMPU_LT_QB:
14831 case OPC_CMPU_LE_QB:
14832 case OPC_CMP_EQ_PH:
14833 case OPC_CMP_LT_PH:
14834 case OPC_CMP_LE_PH:
14835 gen_mipsdsp_add_cmp_pick(ctx, op1, op2, rd, rs, rt, 0);
14837 case OPC_CMPGU_EQ_QB:
14838 case OPC_CMPGU_LT_QB:
14839 case OPC_CMPGU_LE_QB:
14840 case OPC_CMPGDU_EQ_QB:
14841 case OPC_CMPGDU_LT_QB:
14842 case OPC_CMPGDU_LE_QB:
14845 case OPC_PACKRL_PH:
14846 gen_mipsdsp_add_cmp_pick(ctx, op1, op2, rd, rs, rt, 1);
14848 default: /* Invalid */
14849 MIPS_INVAL("MASK CMPU.EQ.QB");
14850 generate_exception(ctx, EXCP_RI);
14854 case OPC_SHLL_QB_DSP:
14855 gen_mipsdsp_shift(ctx, op1, rd, rs, rt);
14857 case OPC_DPA_W_PH_DSP:
14858 op2 = MASK_DPA_W_PH(ctx->opcode);
14860 case OPC_DPAU_H_QBL:
14861 case OPC_DPAU_H_QBR:
14862 case OPC_DPSU_H_QBL:
14863 case OPC_DPSU_H_QBR:
14865 case OPC_DPAX_W_PH:
14866 case OPC_DPAQ_S_W_PH:
14867 case OPC_DPAQX_S_W_PH:
14868 case OPC_DPAQX_SA_W_PH:
14870 case OPC_DPSX_W_PH:
14871 case OPC_DPSQ_S_W_PH:
14872 case OPC_DPSQX_S_W_PH:
14873 case OPC_DPSQX_SA_W_PH:
14874 case OPC_MULSAQ_S_W_PH:
14875 case OPC_DPAQ_SA_L_W:
14876 case OPC_DPSQ_SA_L_W:
14877 case OPC_MAQ_S_W_PHL:
14878 case OPC_MAQ_S_W_PHR:
14879 case OPC_MAQ_SA_W_PHL:
14880 case OPC_MAQ_SA_W_PHR:
14881 case OPC_MULSA_W_PH:
14882 gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 0);
14884 default: /* Invalid */
14885 MIPS_INVAL("MASK DPAW.PH");
14886 generate_exception(ctx, EXCP_RI);
14891 op2 = MASK_INSV(ctx->opcode);
14903 t0 = tcg_temp_new();
14904 t1 = tcg_temp_new();
14906 gen_load_gpr(t0, rt);
14907 gen_load_gpr(t1, rs);
14909 gen_helper_insv(cpu_gpr[rt], cpu_env, t1, t0);
14915 default: /* Invalid */
14916 MIPS_INVAL("MASK INSV");
14917 generate_exception(ctx, EXCP_RI);
14921 case OPC_APPEND_DSP:
14923 op2 = MASK_APPEND(ctx->opcode);
14924 gen_mipsdsp_add_cmp_pick(ctx, op1, op2, rt, rs, rd, 1);
14926 case OPC_EXTR_W_DSP:
14927 op2 = MASK_EXTR_W(ctx->opcode);
14931 case OPC_EXTR_RS_W:
14933 case OPC_EXTRV_S_H:
14935 case OPC_EXTRV_R_W:
14936 case OPC_EXTRV_RS_W:
14941 gen_mipsdsp_accinsn(ctx, op1, op2, rt, rs, rd, 1);
14944 gen_mipsdsp_accinsn(ctx, op1, op2, rd, rs, rt, 1);
14950 gen_mipsdsp_accinsn(ctx, op1, op2, rd, rs, rt, 0);
14952 default: /* Invalid */
14953 MIPS_INVAL("MASK EXTR.W");
14954 generate_exception(ctx, EXCP_RI);
14958 #if defined(TARGET_MIPS64)
14959 case OPC_DEXTM ... OPC_DEXT:
14960 case OPC_DINSM ... OPC_DINS:
14961 check_insn(env, ctx, ISA_MIPS64R2);
14962 check_mips_64(ctx);
14963 gen_bitops(ctx, op1, rt, rs, sa, rd);
14966 check_insn(env, ctx, ISA_MIPS64R2);
14967 check_mips_64(ctx);
14968 op2 = MASK_DBSHFL(ctx->opcode);
14969 gen_bshfl(ctx, op2, rt, rd);
14971 case OPC_DDIV_G_2E ... OPC_DDIVU_G_2E:
14972 case OPC_DMULT_G_2E ... OPC_DMULTU_G_2E:
14973 case OPC_DMOD_G_2E ... OPC_DMODU_G_2E:
14974 check_insn(env, ctx, INSN_LOONGSON2E);
14975 gen_loongson_integer(ctx, op1, rd, rs, rt);
14977 case OPC_ABSQ_S_QH_DSP:
14978 op2 = MASK_ABSQ_S_QH(ctx->opcode);
14980 case OPC_PRECEQ_L_PWL:
14981 case OPC_PRECEQ_L_PWR:
14982 case OPC_PRECEQ_PW_QHL:
14983 case OPC_PRECEQ_PW_QHR:
14984 case OPC_PRECEQ_PW_QHLA:
14985 case OPC_PRECEQ_PW_QHRA:
14986 case OPC_PRECEQU_QH_OBL:
14987 case OPC_PRECEQU_QH_OBR:
14988 case OPC_PRECEQU_QH_OBLA:
14989 case OPC_PRECEQU_QH_OBRA:
14990 case OPC_PRECEU_QH_OBL:
14991 case OPC_PRECEU_QH_OBR:
14992 case OPC_PRECEU_QH_OBLA:
14993 case OPC_PRECEU_QH_OBRA:
14994 case OPC_ABSQ_S_OB:
14995 case OPC_ABSQ_S_PW:
14996 case OPC_ABSQ_S_QH:
14997 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
15005 gen_mipsdsp_bitinsn(env, ctx, op1, op2, rd, rt);
15007 default: /* Invalid */
15008 MIPS_INVAL("MASK ABSQ_S.QH");
15009 generate_exception(ctx, EXCP_RI);
15013 case OPC_ADDU_OB_DSP:
15014 op2 = MASK_ADDU_OB(ctx->opcode);
15016 case OPC_RADDU_L_OB:
15018 case OPC_SUBQ_S_PW:
15020 case OPC_SUBQ_S_QH:
15022 case OPC_SUBU_S_OB:
15024 case OPC_SUBU_S_QH:
15026 case OPC_SUBUH_R_OB:
15028 case OPC_ADDQ_S_PW:
15030 case OPC_ADDQ_S_QH:
15032 case OPC_ADDU_S_OB:
15034 case OPC_ADDU_S_QH:
15036 case OPC_ADDUH_R_OB:
15037 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
15039 case OPC_MULEQ_S_PW_QHL:
15040 case OPC_MULEQ_S_PW_QHR:
15041 case OPC_MULEU_S_QH_OBL:
15042 case OPC_MULEU_S_QH_OBR:
15043 case OPC_MULQ_RS_QH:
15044 gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 1);
15046 default: /* Invalid */
15047 MIPS_INVAL("MASK ADDU.OB");
15048 generate_exception(ctx, EXCP_RI);
15052 case OPC_CMPU_EQ_OB_DSP:
15053 op2 = MASK_CMPU_EQ_OB(ctx->opcode);
15055 case OPC_PRECR_SRA_QH_PW:
15056 case OPC_PRECR_SRA_R_QH_PW:
15057 /* Return value is rt. */
15058 gen_mipsdsp_arith(ctx, op1, op2, rt, rs, rd);
15060 case OPC_PRECR_OB_QH:
15061 case OPC_PRECRQ_OB_QH:
15062 case OPC_PRECRQ_PW_L:
15063 case OPC_PRECRQ_QH_PW:
15064 case OPC_PRECRQ_RS_QH_PW:
15065 case OPC_PRECRQU_S_OB_QH:
15066 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
15068 case OPC_CMPU_EQ_OB:
15069 case OPC_CMPU_LT_OB:
15070 case OPC_CMPU_LE_OB:
15071 case OPC_CMP_EQ_QH:
15072 case OPC_CMP_LT_QH:
15073 case OPC_CMP_LE_QH:
15074 case OPC_CMP_EQ_PW:
15075 case OPC_CMP_LT_PW:
15076 case OPC_CMP_LE_PW:
15077 gen_mipsdsp_add_cmp_pick(ctx, op1, op2, rd, rs, rt, 0);
15079 case OPC_CMPGDU_EQ_OB:
15080 case OPC_CMPGDU_LT_OB:
15081 case OPC_CMPGDU_LE_OB:
15082 case OPC_CMPGU_EQ_OB:
15083 case OPC_CMPGU_LT_OB:
15084 case OPC_CMPGU_LE_OB:
15085 case OPC_PACKRL_PW:
15089 gen_mipsdsp_add_cmp_pick(ctx, op1, op2, rd, rs, rt, 1);
15091 default: /* Invalid */
15092 MIPS_INVAL("MASK CMPU_EQ.OB");
15093 generate_exception(ctx, EXCP_RI);
15097 case OPC_DAPPEND_DSP:
15099 op2 = MASK_DAPPEND(ctx->opcode);
15100 gen_mipsdsp_add_cmp_pick(ctx, op1, op2, rt, rs, rd, 1);
15102 case OPC_DEXTR_W_DSP:
15103 op2 = MASK_DEXTR_W(ctx->opcode);
15110 case OPC_DEXTR_R_L:
15111 case OPC_DEXTR_RS_L:
15113 case OPC_DEXTR_R_W:
15114 case OPC_DEXTR_RS_W:
15115 case OPC_DEXTR_S_H:
15117 case OPC_DEXTRV_R_L:
15118 case OPC_DEXTRV_RS_L:
15119 case OPC_DEXTRV_S_H:
15121 case OPC_DEXTRV_R_W:
15122 case OPC_DEXTRV_RS_W:
15123 gen_mipsdsp_accinsn(ctx, op1, op2, rt, rs, rd, 1);
15128 gen_mipsdsp_accinsn(ctx, op1, op2, rd, rs, rt, 0);
15130 default: /* Invalid */
15131 MIPS_INVAL("MASK EXTR.W");
15132 generate_exception(ctx, EXCP_RI);
15136 case OPC_DPAQ_W_QH_DSP:
15137 op2 = MASK_DPAQ_W_QH(ctx->opcode);
15139 case OPC_DPAU_H_OBL:
15140 case OPC_DPAU_H_OBR:
15141 case OPC_DPSU_H_OBL:
15142 case OPC_DPSU_H_OBR:
15144 case OPC_DPAQ_S_W_QH:
15146 case OPC_DPSQ_S_W_QH:
15147 case OPC_MULSAQ_S_W_QH:
15148 case OPC_DPAQ_SA_L_PW:
15149 case OPC_DPSQ_SA_L_PW:
15150 case OPC_MULSAQ_S_L_PW:
15151 gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 0);
15153 case OPC_MAQ_S_W_QHLL:
15154 case OPC_MAQ_S_W_QHLR:
15155 case OPC_MAQ_S_W_QHRL:
15156 case OPC_MAQ_S_W_QHRR:
15157 case OPC_MAQ_SA_W_QHLL:
15158 case OPC_MAQ_SA_W_QHLR:
15159 case OPC_MAQ_SA_W_QHRL:
15160 case OPC_MAQ_SA_W_QHRR:
15161 case OPC_MAQ_S_L_PWL:
15162 case OPC_MAQ_S_L_PWR:
15167 gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 0);
15169 default: /* Invalid */
15170 MIPS_INVAL("MASK DPAQ.W.QH");
15171 generate_exception(ctx, EXCP_RI);
15175 case OPC_DINSV_DSP:
15176 op2 = MASK_INSV(ctx->opcode);
15188 t0 = tcg_temp_new();
15189 t1 = tcg_temp_new();
15191 gen_load_gpr(t0, rt);
15192 gen_load_gpr(t1, rs);
15194 gen_helper_dinsv(cpu_gpr[rt], cpu_env, t1, t0);
15197 default: /* Invalid */
15198 MIPS_INVAL("MASK DINSV");
15199 generate_exception(ctx, EXCP_RI);
15203 case OPC_SHLL_OB_DSP:
15204 gen_mipsdsp_shift(ctx, op1, rd, rs, rt);
15207 default: /* Invalid */
15208 MIPS_INVAL("special3");
15209 generate_exception(ctx, EXCP_RI);
15214 op1 = MASK_REGIMM(ctx->opcode);
15216 case OPC_BLTZ ... OPC_BGEZL: /* REGIMM branches */
15217 case OPC_BLTZAL ... OPC_BGEZALL:
15218 gen_compute_branch(ctx, op1, 4, rs, -1, imm << 2);
15221 case OPC_TGEI ... OPC_TEQI: /* REGIMM traps */
15223 gen_trap(ctx, op1, rs, -1, imm);
15226 check_insn(env, ctx, ISA_MIPS32R2);
15227 /* Treat as NOP. */
15229 case OPC_BPOSGE32: /* MIPS DSP branch */
15230 #if defined(TARGET_MIPS64)
15234 gen_compute_branch(ctx, op1, 4, -1, -2, (int32_t)imm << 2);
15237 default: /* Invalid */
15238 MIPS_INVAL("regimm");
15239 generate_exception(ctx, EXCP_RI);
15244 check_cp0_enabled(ctx);
15245 op1 = MASK_CP0(ctx->opcode);
15251 #if defined(TARGET_MIPS64)
15255 #ifndef CONFIG_USER_ONLY
15256 gen_cp0(env, ctx, op1, rt, rd);
15257 #endif /* !CONFIG_USER_ONLY */
15259 case OPC_C0_FIRST ... OPC_C0_LAST:
15260 #ifndef CONFIG_USER_ONLY
15261 gen_cp0(env, ctx, MASK_C0(ctx->opcode), rt, rd);
15262 #endif /* !CONFIG_USER_ONLY */
15265 #ifndef CONFIG_USER_ONLY
15267 TCGv t0 = tcg_temp_new();
15269 op2 = MASK_MFMC0(ctx->opcode);
15272 check_insn(env, ctx, ASE_MT);
15273 gen_helper_dmt(t0);
15274 gen_store_gpr(t0, rt);
15277 check_insn(env, ctx, ASE_MT);
15278 gen_helper_emt(t0);
15279 gen_store_gpr(t0, rt);
15282 check_insn(env, ctx, ASE_MT);
15283 gen_helper_dvpe(t0, cpu_env);
15284 gen_store_gpr(t0, rt);
15287 check_insn(env, ctx, ASE_MT);
15288 gen_helper_evpe(t0, cpu_env);
15289 gen_store_gpr(t0, rt);
15292 check_insn(env, ctx, ISA_MIPS32R2);
15293 save_cpu_state(ctx, 1);
15294 gen_helper_di(t0, cpu_env);
15295 gen_store_gpr(t0, rt);
15296 /* Stop translation as we may have switched the execution mode */
15297 ctx->bstate = BS_STOP;
15300 check_insn(env, ctx, ISA_MIPS32R2);
15301 save_cpu_state(ctx, 1);
15302 gen_helper_ei(t0, cpu_env);
15303 gen_store_gpr(t0, rt);
15304 /* Stop translation as we may have switched the execution mode */
15305 ctx->bstate = BS_STOP;
15307 default: /* Invalid */
15308 MIPS_INVAL("mfmc0");
15309 generate_exception(ctx, EXCP_RI);
15314 #endif /* !CONFIG_USER_ONLY */
15317 check_insn(env, ctx, ISA_MIPS32R2);
15318 gen_load_srsgpr(rt, rd);
15321 check_insn(env, ctx, ISA_MIPS32R2);
15322 gen_store_srsgpr(rt, rd);
15326 generate_exception(ctx, EXCP_RI);
15330 case OPC_ADDI: /* Arithmetic with immediate opcode */
15332 gen_arith_imm(env, ctx, op, rt, rs, imm);
15334 case OPC_SLTI: /* Set on less than with immediate opcode */
15336 gen_slt_imm(env, ctx, op, rt, rs, imm);
15338 case OPC_ANDI: /* Arithmetic with immediate opcode */
15342 gen_logic_imm(env, ctx, op, rt, rs, imm);
15344 case OPC_J ... OPC_JAL: /* Jump */
15345 offset = (int32_t)(ctx->opcode & 0x3FFFFFF) << 2;
15346 gen_compute_branch(ctx, op, 4, rs, rt, offset);
15349 case OPC_BEQ ... OPC_BGTZ: /* Branch */
15350 case OPC_BEQL ... OPC_BGTZL:
15351 gen_compute_branch(ctx, op, 4, rs, rt, imm << 2);
15354 case OPC_LB ... OPC_LWR: /* Load and stores */
15356 gen_ld(env, ctx, op, rt, rs, imm);
15358 case OPC_SB ... OPC_SW:
15360 gen_st(ctx, op, rt, rs, imm);
15363 gen_st_cond(ctx, op, rt, rs, imm);
15366 check_cp0_enabled(ctx);
15367 check_insn(env, ctx, ISA_MIPS3 | ISA_MIPS32);
15368 /* Treat as NOP. */
15371 check_insn(env, ctx, ISA_MIPS4 | ISA_MIPS32);
15372 /* Treat as NOP. */
15375 /* Floating point (COP1). */
15380 gen_cop1_ldst(env, ctx, op, rt, rs, imm);
15384 if (env->CP0_Config1 & (1 << CP0C1_FP)) {
15385 check_cp1_enabled(ctx);
15386 op1 = MASK_CP1(ctx->opcode);
15390 check_insn(env, ctx, ISA_MIPS32R2);
15395 gen_cp1(ctx, op1, rt, rd);
15397 #if defined(TARGET_MIPS64)
15400 check_insn(env, ctx, ISA_MIPS3);
15401 gen_cp1(ctx, op1, rt, rd);
15407 check_insn(env, ctx, ASE_MIPS3D);
15410 gen_compute_branch1(env, ctx, MASK_BC1(ctx->opcode),
15411 (rt >> 2) & 0x7, imm << 2);
15419 gen_farith(ctx, ctx->opcode & FOP(0x3f, 0x1f), rt, rd, sa,
15424 generate_exception (ctx, EXCP_RI);
15428 generate_exception_err(ctx, EXCP_CpU, 1);
15437 /* COP2: Not implemented. */
15438 generate_exception_err(ctx, EXCP_CpU, 2);
15441 check_insn(env, ctx, INSN_LOONGSON2F);
15442 /* Note that these instructions use different fields. */
15443 gen_loongson_multimedia(ctx, sa, rd, rt);
15447 if (env->CP0_Config1 & (1 << CP0C1_FP)) {
15448 check_cp1_enabled(ctx);
15449 op1 = MASK_CP3(ctx->opcode);
15457 gen_flt3_ldst(ctx, op1, sa, rd, rs, rt);
15460 /* Treat as NOP. */
15475 gen_flt3_arith(ctx, op1, sa, rs, rd, rt);
15479 generate_exception (ctx, EXCP_RI);
15483 generate_exception_err(ctx, EXCP_CpU, 1);
15487 #if defined(TARGET_MIPS64)
15488 /* MIPS64 opcodes */
15490 case OPC_LDL ... OPC_LDR:
15493 check_insn(env, ctx, ISA_MIPS3);
15494 check_mips_64(ctx);
15495 gen_ld(env, ctx, op, rt, rs, imm);
15497 case OPC_SDL ... OPC_SDR:
15499 check_insn(env, ctx, ISA_MIPS3);
15500 check_mips_64(ctx);
15501 gen_st(ctx, op, rt, rs, imm);
15504 check_insn(env, ctx, ISA_MIPS3);
15505 check_mips_64(ctx);
15506 gen_st_cond(ctx, op, rt, rs, imm);
15510 check_insn(env, ctx, ISA_MIPS3);
15511 check_mips_64(ctx);
15512 gen_arith_imm(env, ctx, op, rt, rs, imm);
15516 check_insn(env, ctx, ASE_MIPS16 | ASE_MICROMIPS);
15517 offset = (int32_t)(ctx->opcode & 0x3FFFFFF) << 2;
15518 gen_compute_branch(ctx, op, 4, rs, rt, offset);
15522 check_insn(env, ctx, ASE_MDMX);
15523 /* MDMX: Not implemented. */
15524 default: /* Invalid */
15525 MIPS_INVAL("major opcode");
15526 generate_exception(ctx, EXCP_RI);
15532 gen_intermediate_code_internal (CPUMIPSState *env, TranslationBlock *tb,
15536 target_ulong pc_start;
15537 uint16_t *gen_opc_end;
15546 qemu_log("search pc %d\n", search_pc);
15549 gen_opc_end = gen_opc_buf + OPC_MAX_SIZE;
15552 ctx.singlestep_enabled = env->singlestep_enabled;
15554 ctx.bstate = BS_NONE;
15555 /* Restore delay slot state from the tb context. */
15556 ctx.hflags = (uint32_t)tb->flags; /* FIXME: maybe use 64 bits here? */
15557 restore_cpu_state(env, &ctx);
15558 #ifdef CONFIG_USER_ONLY
15559 ctx.mem_idx = MIPS_HFLAG_UM;
15561 ctx.mem_idx = ctx.hflags & MIPS_HFLAG_KSU;
15564 max_insns = tb->cflags & CF_COUNT_MASK;
15565 if (max_insns == 0)
15566 max_insns = CF_COUNT_MASK;
15567 LOG_DISAS("\ntb %p idx %d hflags %04x\n", tb, ctx.mem_idx, ctx.hflags);
15568 gen_icount_start();
15569 while (ctx.bstate == BS_NONE) {
15570 if (unlikely(!QTAILQ_EMPTY(&env->breakpoints))) {
15571 QTAILQ_FOREACH(bp, &env->breakpoints, entry) {
15572 if (bp->pc == ctx.pc) {
15573 save_cpu_state(&ctx, 1);
15574 ctx.bstate = BS_BRANCH;
15575 gen_helper_0e0i(raise_exception, EXCP_DEBUG);
15576 /* Include the breakpoint location or the tb won't
15577 * be flushed when it must be. */
15579 goto done_generating;
15585 j = gen_opc_ptr - gen_opc_buf;
15589 gen_opc_instr_start[lj++] = 0;
15591 gen_opc_pc[lj] = ctx.pc;
15592 gen_opc_hflags[lj] = ctx.hflags & MIPS_HFLAG_BMASK;
15593 gen_opc_btarget[lj] = ctx.btarget;
15594 gen_opc_instr_start[lj] = 1;
15595 gen_opc_icount[lj] = num_insns;
15597 if (num_insns + 1 == max_insns && (tb->cflags & CF_LAST_IO))
15601 if (!(ctx.hflags & MIPS_HFLAG_M16)) {
15602 ctx.opcode = cpu_ldl_code(env, ctx.pc);
15604 decode_opc(env, &ctx, &is_branch);
15605 } else if (env->insn_flags & ASE_MICROMIPS) {
15606 ctx.opcode = cpu_lduw_code(env, ctx.pc);
15607 insn_bytes = decode_micromips_opc(env, &ctx, &is_branch);
15608 } else if (env->insn_flags & ASE_MIPS16) {
15609 ctx.opcode = cpu_lduw_code(env, ctx.pc);
15610 insn_bytes = decode_mips16_opc(env, &ctx, &is_branch);
15612 generate_exception(&ctx, EXCP_RI);
15613 ctx.bstate = BS_STOP;
15617 handle_delay_slot(env, &ctx, insn_bytes);
15619 ctx.pc += insn_bytes;
15623 /* Execute a branch and its delay slot as a single instruction.
15624 This is what GDB expects and is consistent with what the
15625 hardware does (e.g. if a delay slot instruction faults, the
15626 reported PC is the PC of the branch). */
15627 if (env->singlestep_enabled && (ctx.hflags & MIPS_HFLAG_BMASK) == 0)
15630 if ((ctx.pc & (TARGET_PAGE_SIZE - 1)) == 0)
15633 if (gen_opc_ptr >= gen_opc_end)
15636 if (num_insns >= max_insns)
15642 if (tb->cflags & CF_LAST_IO)
15644 if (env->singlestep_enabled && ctx.bstate != BS_BRANCH) {
15645 save_cpu_state(&ctx, ctx.bstate == BS_NONE);
15646 gen_helper_0e0i(raise_exception, EXCP_DEBUG);
15648 switch (ctx.bstate) {
15650 gen_goto_tb(&ctx, 0, ctx.pc);
15653 save_cpu_state(&ctx, 0);
15654 gen_goto_tb(&ctx, 0, ctx.pc);
15657 tcg_gen_exit_tb(0);
15665 gen_icount_end(tb, num_insns);
15666 *gen_opc_ptr = INDEX_op_end;
15668 j = gen_opc_ptr - gen_opc_buf;
15671 gen_opc_instr_start[lj++] = 0;
15673 tb->size = ctx.pc - pc_start;
15674 tb->icount = num_insns;
15678 if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM)) {
15679 qemu_log("IN: %s\n", lookup_symbol(pc_start));
15680 log_target_disas(pc_start, ctx.pc - pc_start, 0);
15686 void gen_intermediate_code (CPUMIPSState *env, struct TranslationBlock *tb)
15688 gen_intermediate_code_internal(env, tb, 0);
15691 void gen_intermediate_code_pc (CPUMIPSState *env, struct TranslationBlock *tb)
15693 gen_intermediate_code_internal(env, tb, 1);
15696 static void fpu_dump_state(CPUMIPSState *env, FILE *f, fprintf_function fpu_fprintf,
15700 int is_fpu64 = !!(env->hflags & MIPS_HFLAG_F64);
15702 #define printfpr(fp) \
15705 fpu_fprintf(f, "w:%08x d:%016" PRIx64 \
15706 " fd:%13g fs:%13g psu: %13g\n", \
15707 (fp)->w[FP_ENDIAN_IDX], (fp)->d, \
15708 (double)(fp)->fd, \
15709 (double)(fp)->fs[FP_ENDIAN_IDX], \
15710 (double)(fp)->fs[!FP_ENDIAN_IDX]); \
15713 tmp.w[FP_ENDIAN_IDX] = (fp)->w[FP_ENDIAN_IDX]; \
15714 tmp.w[!FP_ENDIAN_IDX] = ((fp) + 1)->w[FP_ENDIAN_IDX]; \
15715 fpu_fprintf(f, "w:%08x d:%016" PRIx64 \
15716 " fd:%13g fs:%13g psu:%13g\n", \
15717 tmp.w[FP_ENDIAN_IDX], tmp.d, \
15719 (double)tmp.fs[FP_ENDIAN_IDX], \
15720 (double)tmp.fs[!FP_ENDIAN_IDX]); \
15725 fpu_fprintf(f, "CP1 FCR0 0x%08x FCR31 0x%08x SR.FR %d fp_status 0x%02x\n",
15726 env->active_fpu.fcr0, env->active_fpu.fcr31, is_fpu64,
15727 get_float_exception_flags(&env->active_fpu.fp_status));
15728 for (i = 0; i < 32; (is_fpu64) ? i++ : (i += 2)) {
15729 fpu_fprintf(f, "%3s: ", fregnames[i]);
15730 printfpr(&env->active_fpu.fpr[i]);
15736 #if defined(TARGET_MIPS64) && defined(MIPS_DEBUG_SIGN_EXTENSIONS)
15737 /* Debug help: The architecture requires 32bit code to maintain proper
15738 sign-extended values on 64bit machines. */
15740 #define SIGN_EXT_P(val) ((((val) & ~0x7fffffff) == 0) || (((val) & ~0x7fffffff) == ~0x7fffffff))
15743 cpu_mips_check_sign_extensions (CPUMIPSState *env, FILE *f,
15744 fprintf_function cpu_fprintf,
15749 if (!SIGN_EXT_P(env->active_tc.PC))
15750 cpu_fprintf(f, "BROKEN: pc=0x" TARGET_FMT_lx "\n", env->active_tc.PC);
15751 if (!SIGN_EXT_P(env->active_tc.HI[0]))
15752 cpu_fprintf(f, "BROKEN: HI=0x" TARGET_FMT_lx "\n", env->active_tc.HI[0]);
15753 if (!SIGN_EXT_P(env->active_tc.LO[0]))
15754 cpu_fprintf(f, "BROKEN: LO=0x" TARGET_FMT_lx "\n", env->active_tc.LO[0]);
15755 if (!SIGN_EXT_P(env->btarget))
15756 cpu_fprintf(f, "BROKEN: btarget=0x" TARGET_FMT_lx "\n", env->btarget);
15758 for (i = 0; i < 32; i++) {
15759 if (!SIGN_EXT_P(env->active_tc.gpr[i]))
15760 cpu_fprintf(f, "BROKEN: %s=0x" TARGET_FMT_lx "\n", regnames[i], env->active_tc.gpr[i]);
15763 if (!SIGN_EXT_P(env->CP0_EPC))
15764 cpu_fprintf(f, "BROKEN: EPC=0x" TARGET_FMT_lx "\n", env->CP0_EPC);
15765 if (!SIGN_EXT_P(env->lladdr))
15766 cpu_fprintf(f, "BROKEN: LLAddr=0x" TARGET_FMT_lx "\n", env->lladdr);
15770 void cpu_dump_state (CPUMIPSState *env, FILE *f, fprintf_function cpu_fprintf,
15775 cpu_fprintf(f, "pc=0x" TARGET_FMT_lx " HI=0x" TARGET_FMT_lx
15776 " LO=0x" TARGET_FMT_lx " ds %04x "
15777 TARGET_FMT_lx " " TARGET_FMT_ld "\n",
15778 env->active_tc.PC, env->active_tc.HI[0], env->active_tc.LO[0],
15779 env->hflags, env->btarget, env->bcond);
15780 for (i = 0; i < 32; i++) {
15782 cpu_fprintf(f, "GPR%02d:", i);
15783 cpu_fprintf(f, " %s " TARGET_FMT_lx, regnames[i], env->active_tc.gpr[i]);
15785 cpu_fprintf(f, "\n");
15788 cpu_fprintf(f, "CP0 Status 0x%08x Cause 0x%08x EPC 0x" TARGET_FMT_lx "\n",
15789 env->CP0_Status, env->CP0_Cause, env->CP0_EPC);
15790 cpu_fprintf(f, " Config0 0x%08x Config1 0x%08x LLAddr 0x" TARGET_FMT_lx "\n",
15791 env->CP0_Config0, env->CP0_Config1, env->lladdr);
15792 if (env->hflags & MIPS_HFLAG_FPU)
15793 fpu_dump_state(env, f, cpu_fprintf, flags);
15794 #if defined(TARGET_MIPS64) && defined(MIPS_DEBUG_SIGN_EXTENSIONS)
15795 cpu_mips_check_sign_extensions(env, f, cpu_fprintf, flags);
15799 static void mips_tcg_init(void)
15804 /* Initialize various static tables. */
15808 cpu_env = tcg_global_reg_new_ptr(TCG_AREG0, "env");
15809 TCGV_UNUSED(cpu_gpr[0]);
15810 for (i = 1; i < 32; i++)
15811 cpu_gpr[i] = tcg_global_mem_new(TCG_AREG0,
15812 offsetof(CPUMIPSState, active_tc.gpr[i]),
15815 for (i = 0; i < 32; i++) {
15816 int off = offsetof(CPUMIPSState, active_fpu.fpr[i]);
15817 fpu_f64[i] = tcg_global_mem_new_i64(TCG_AREG0, off, fregnames[i]);
15820 cpu_PC = tcg_global_mem_new(TCG_AREG0,
15821 offsetof(CPUMIPSState, active_tc.PC), "PC");
15822 for (i = 0; i < MIPS_DSP_ACC; i++) {
15823 cpu_HI[i] = tcg_global_mem_new(TCG_AREG0,
15824 offsetof(CPUMIPSState, active_tc.HI[i]),
15826 cpu_LO[i] = tcg_global_mem_new(TCG_AREG0,
15827 offsetof(CPUMIPSState, active_tc.LO[i]),
15829 cpu_ACX[i] = tcg_global_mem_new(TCG_AREG0,
15830 offsetof(CPUMIPSState, active_tc.ACX[i]),
15833 cpu_dspctrl = tcg_global_mem_new(TCG_AREG0,
15834 offsetof(CPUMIPSState, active_tc.DSPControl),
15836 bcond = tcg_global_mem_new(TCG_AREG0,
15837 offsetof(CPUMIPSState, bcond), "bcond");
15838 btarget = tcg_global_mem_new(TCG_AREG0,
15839 offsetof(CPUMIPSState, btarget), "btarget");
15840 hflags = tcg_global_mem_new_i32(TCG_AREG0,
15841 offsetof(CPUMIPSState, hflags), "hflags");
15843 fpu_fcr0 = tcg_global_mem_new_i32(TCG_AREG0,
15844 offsetof(CPUMIPSState, active_fpu.fcr0),
15846 fpu_fcr31 = tcg_global_mem_new_i32(TCG_AREG0,
15847 offsetof(CPUMIPSState, active_fpu.fcr31),
15850 /* register helpers */
15851 #define GEN_HELPER 2
15852 #include "helper.h"
15857 #include "translate_init.c"
15859 MIPSCPU *cpu_mips_init(const char *cpu_model)
15863 const mips_def_t *def;
15865 def = cpu_mips_find_by_name(cpu_model);
15868 cpu = MIPS_CPU(object_new(TYPE_MIPS_CPU));
15870 env->cpu_model = def;
15871 env->cpu_model_str = cpu_model;
15873 #ifndef CONFIG_USER_ONLY
15874 mmu_init(env, def);
15876 fpu_init(env, def);
15877 mvp_init(env, def);
15879 cpu_reset(CPU(cpu));
15880 qemu_init_vcpu(env);
15884 void cpu_state_reset(CPUMIPSState *env)
15886 if (qemu_loglevel_mask(CPU_LOG_RESET)) {
15887 qemu_log("CPU Reset (CPU %d)\n", env->cpu_index);
15888 log_cpu_state(env, 0);
15891 memset(env, 0, offsetof(CPUMIPSState, breakpoints));
15894 /* Reset registers to their default values */
15895 env->CP0_PRid = env->cpu_model->CP0_PRid;
15896 env->CP0_Config0 = env->cpu_model->CP0_Config0;
15897 #ifdef TARGET_WORDS_BIGENDIAN
15898 env->CP0_Config0 |= (1 << CP0C0_BE);
15900 env->CP0_Config1 = env->cpu_model->CP0_Config1;
15901 env->CP0_Config2 = env->cpu_model->CP0_Config2;
15902 env->CP0_Config3 = env->cpu_model->CP0_Config3;
15903 env->CP0_Config6 = env->cpu_model->CP0_Config6;
15904 env->CP0_Config7 = env->cpu_model->CP0_Config7;
15905 env->CP0_LLAddr_rw_bitmask = env->cpu_model->CP0_LLAddr_rw_bitmask
15906 << env->cpu_model->CP0_LLAddr_shift;
15907 env->CP0_LLAddr_shift = env->cpu_model->CP0_LLAddr_shift;
15908 env->SYNCI_Step = env->cpu_model->SYNCI_Step;
15909 env->CCRes = env->cpu_model->CCRes;
15910 env->CP0_Status_rw_bitmask = env->cpu_model->CP0_Status_rw_bitmask;
15911 env->CP0_TCStatus_rw_bitmask = env->cpu_model->CP0_TCStatus_rw_bitmask;
15912 env->CP0_SRSCtl = env->cpu_model->CP0_SRSCtl;
15913 env->current_tc = 0;
15914 env->SEGBITS = env->cpu_model->SEGBITS;
15915 env->SEGMask = (target_ulong)((1ULL << env->cpu_model->SEGBITS) - 1);
15916 #if defined(TARGET_MIPS64)
15917 if (env->cpu_model->insn_flags & ISA_MIPS3) {
15918 env->SEGMask |= 3ULL << 62;
15921 env->PABITS = env->cpu_model->PABITS;
15922 env->PAMask = (target_ulong)((1ULL << env->cpu_model->PABITS) - 1);
15923 env->CP0_SRSConf0_rw_bitmask = env->cpu_model->CP0_SRSConf0_rw_bitmask;
15924 env->CP0_SRSConf0 = env->cpu_model->CP0_SRSConf0;
15925 env->CP0_SRSConf1_rw_bitmask = env->cpu_model->CP0_SRSConf1_rw_bitmask;
15926 env->CP0_SRSConf1 = env->cpu_model->CP0_SRSConf1;
15927 env->CP0_SRSConf2_rw_bitmask = env->cpu_model->CP0_SRSConf2_rw_bitmask;
15928 env->CP0_SRSConf2 = env->cpu_model->CP0_SRSConf2;
15929 env->CP0_SRSConf3_rw_bitmask = env->cpu_model->CP0_SRSConf3_rw_bitmask;
15930 env->CP0_SRSConf3 = env->cpu_model->CP0_SRSConf3;
15931 env->CP0_SRSConf4_rw_bitmask = env->cpu_model->CP0_SRSConf4_rw_bitmask;
15932 env->CP0_SRSConf4 = env->cpu_model->CP0_SRSConf4;
15933 env->active_fpu.fcr0 = env->cpu_model->CP1_fcr0;
15934 env->insn_flags = env->cpu_model->insn_flags;
15936 #if defined(CONFIG_USER_ONLY)
15937 env->CP0_Status = (MIPS_HFLAG_UM << CP0St_KSU);
15938 /* Enable access to the CPUNum, SYNCI_Step, CC, and CCRes RDHWR
15939 hardware registers. */
15940 env->CP0_HWREna |= 0x0000000F;
15941 if (env->CP0_Config1 & (1 << CP0C1_FP)) {
15942 env->CP0_Status |= (1 << CP0St_CU1);
15944 if (env->cpu_model->insn_flags & ASE_DSPR2) {
15945 env->hflags |= MIPS_HFLAG_DSP | MIPS_HFLAG_DSPR2;
15946 } else if (env->cpu_model->insn_flags & ASE_DSP) {
15947 env->hflags |= MIPS_HFLAG_DSP;
15950 if (env->hflags & MIPS_HFLAG_BMASK) {
15951 /* If the exception was raised from a delay slot,
15952 come back to the jump. */
15953 env->CP0_ErrorEPC = env->active_tc.PC - 4;
15955 env->CP0_ErrorEPC = env->active_tc.PC;
15957 env->active_tc.PC = (int32_t)0xBFC00000;
15958 env->CP0_Random = env->tlb->nb_tlb - 1;
15959 env->tlb->tlb_in_use = env->tlb->nb_tlb;
15960 env->CP0_Wired = 0;
15961 env->CP0_EBase = 0x80000000 | (env->cpu_index & 0x3FF);
15962 env->CP0_Status = (1 << CP0St_BEV) | (1 << CP0St_ERL);
15963 /* vectored interrupts not implemented, timer on int 7,
15964 no performance counters. */
15965 env->CP0_IntCtl = 0xe0000000;
15969 for (i = 0; i < 7; i++) {
15970 env->CP0_WatchLo[i] = 0;
15971 env->CP0_WatchHi[i] = 0x80000000;
15973 env->CP0_WatchLo[7] = 0;
15974 env->CP0_WatchHi[7] = 0;
15976 /* Count register increments in debug mode, EJTAG version 1 */
15977 env->CP0_Debug = (1 << CP0DB_CNT) | (0x1 << CP0DB_VER);
15979 if (env->CP0_Config3 & (1 << CP0C3_MT)) {
15982 /* Only TC0 on VPE 0 starts as active. */
15983 for (i = 0; i < ARRAY_SIZE(env->tcs); i++) {
15984 env->tcs[i].CP0_TCBind = env->cpu_index << CP0TCBd_CurVPE;
15985 env->tcs[i].CP0_TCHalt = 1;
15987 env->active_tc.CP0_TCHalt = 1;
15990 if (!env->cpu_index) {
15991 /* VPE0 starts up enabled. */
15992 env->mvp->CP0_MVPControl |= (1 << CP0MVPCo_EVP);
15993 env->CP0_VPEConf0 |= (1 << CP0VPEC0_MVP) | (1 << CP0VPEC0_VPA);
15995 /* TC0 starts up unhalted. */
15997 env->active_tc.CP0_TCHalt = 0;
15998 env->tcs[0].CP0_TCHalt = 0;
15999 /* With thread 0 active. */
16000 env->active_tc.CP0_TCStatus = (1 << CP0TCSt_A);
16001 env->tcs[0].CP0_TCStatus = (1 << CP0TCSt_A);
16005 compute_hflags(env);
16006 env->exception_index = EXCP_NONE;
16009 void restore_state_to_opc(CPUMIPSState *env, TranslationBlock *tb, int pc_pos)
16011 env->active_tc.PC = gen_opc_pc[pc_pos];
16012 env->hflags &= ~MIPS_HFLAG_BMASK;
16013 env->hflags |= gen_opc_hflags[pc_pos];
16014 switch (env->hflags & MIPS_HFLAG_BMASK_BASE) {
16015 case MIPS_HFLAG_BR:
16017 case MIPS_HFLAG_BC:
16018 case MIPS_HFLAG_BL:
16020 env->btarget = gen_opc_btarget[pc_pos];