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 #ifdef CONFIG_USER_ONLY
1818 t0 = tcg_temp_local_new();
1819 t1 = tcg_temp_local_new();
1821 t0 = tcg_temp_new();
1822 t1 = tcg_temp_new();
1824 gen_base_offset_addr(ctx, t0, base, offset);
1825 gen_load_gpr(t1, rt);
1827 #if defined(TARGET_MIPS64)
1829 save_cpu_state(ctx, 1);
1830 op_st_scd(t1, t0, rt, ctx);
1835 save_cpu_state(ctx, 1);
1836 op_st_sc(t1, t0, rt, ctx);
1840 (void)opn; /* avoid a compiler warning */
1841 MIPS_DEBUG("%s %s, %d(%s)", opn, regnames[rt], offset, regnames[base]);
1846 /* Load and store */
1847 static void gen_flt_ldst (DisasContext *ctx, uint32_t opc, int ft,
1848 int base, int16_t offset)
1850 const char *opn = "flt_ldst";
1851 TCGv t0 = tcg_temp_new();
1853 gen_base_offset_addr(ctx, t0, base, offset);
1854 /* Don't do NOP if destination is zero: we must perform the actual
1859 TCGv_i32 fp0 = tcg_temp_new_i32();
1861 tcg_gen_qemu_ld32s(t0, t0, ctx->mem_idx);
1862 tcg_gen_trunc_tl_i32(fp0, t0);
1863 gen_store_fpr32(fp0, ft);
1864 tcg_temp_free_i32(fp0);
1870 TCGv_i32 fp0 = tcg_temp_new_i32();
1871 TCGv t1 = tcg_temp_new();
1873 gen_load_fpr32(fp0, ft);
1874 tcg_gen_extu_i32_tl(t1, fp0);
1875 tcg_gen_qemu_st32(t1, t0, ctx->mem_idx);
1877 tcg_temp_free_i32(fp0);
1883 TCGv_i64 fp0 = tcg_temp_new_i64();
1885 tcg_gen_qemu_ld64(fp0, t0, ctx->mem_idx);
1886 gen_store_fpr64(ctx, fp0, ft);
1887 tcg_temp_free_i64(fp0);
1893 TCGv_i64 fp0 = tcg_temp_new_i64();
1895 gen_load_fpr64(ctx, fp0, ft);
1896 tcg_gen_qemu_st64(fp0, t0, ctx->mem_idx);
1897 tcg_temp_free_i64(fp0);
1903 generate_exception(ctx, EXCP_RI);
1906 (void)opn; /* avoid a compiler warning */
1907 MIPS_DEBUG("%s %s, %d(%s)", opn, fregnames[ft], offset, regnames[base]);
1912 static void gen_cop1_ldst(CPUMIPSState *env, DisasContext *ctx,
1913 uint32_t op, int rt, int rs, int16_t imm)
1915 if (env->CP0_Config1 & (1 << CP0C1_FP)) {
1916 check_cp1_enabled(ctx);
1917 gen_flt_ldst(ctx, op, rt, rs, imm);
1919 generate_exception_err(ctx, EXCP_CpU, 1);
1923 /* Arithmetic with immediate operand */
1924 static void gen_arith_imm (CPUMIPSState *env, DisasContext *ctx, uint32_t opc,
1925 int rt, int rs, int16_t imm)
1927 target_ulong uimm = (target_long)imm; /* Sign extend to 32/64 bits */
1928 const char *opn = "imm arith";
1930 if (rt == 0 && opc != OPC_ADDI && opc != OPC_DADDI) {
1931 /* If no destination, treat it as a NOP.
1932 For addi, we must generate the overflow exception when needed. */
1939 TCGv t0 = tcg_temp_local_new();
1940 TCGv t1 = tcg_temp_new();
1941 TCGv t2 = tcg_temp_new();
1942 int l1 = gen_new_label();
1944 gen_load_gpr(t1, rs);
1945 tcg_gen_addi_tl(t0, t1, uimm);
1946 tcg_gen_ext32s_tl(t0, t0);
1948 tcg_gen_xori_tl(t1, t1, ~uimm);
1949 tcg_gen_xori_tl(t2, t0, uimm);
1950 tcg_gen_and_tl(t1, t1, t2);
1952 tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
1954 /* operands of same sign, result different sign */
1955 generate_exception(ctx, EXCP_OVERFLOW);
1957 tcg_gen_ext32s_tl(t0, t0);
1958 gen_store_gpr(t0, rt);
1965 tcg_gen_addi_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
1966 tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]);
1968 tcg_gen_movi_tl(cpu_gpr[rt], uimm);
1972 #if defined(TARGET_MIPS64)
1975 TCGv t0 = tcg_temp_local_new();
1976 TCGv t1 = tcg_temp_new();
1977 TCGv t2 = tcg_temp_new();
1978 int l1 = gen_new_label();
1980 gen_load_gpr(t1, rs);
1981 tcg_gen_addi_tl(t0, t1, uimm);
1983 tcg_gen_xori_tl(t1, t1, ~uimm);
1984 tcg_gen_xori_tl(t2, t0, uimm);
1985 tcg_gen_and_tl(t1, t1, t2);
1987 tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
1989 /* operands of same sign, result different sign */
1990 generate_exception(ctx, EXCP_OVERFLOW);
1992 gen_store_gpr(t0, rt);
1999 tcg_gen_addi_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
2001 tcg_gen_movi_tl(cpu_gpr[rt], uimm);
2007 (void)opn; /* avoid a compiler warning */
2008 MIPS_DEBUG("%s %s, %s, " TARGET_FMT_lx, opn, regnames[rt], regnames[rs], uimm);
2011 /* Logic with immediate operand */
2012 static void gen_logic_imm(CPUMIPSState *env, DisasContext *ctx, uint32_t opc,
2013 int rt, int rs, int16_t imm)
2016 const char *opn = "imm logic";
2019 /* If no destination, treat it as a NOP. */
2023 uimm = (uint16_t)imm;
2026 if (likely(rs != 0))
2027 tcg_gen_andi_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
2029 tcg_gen_movi_tl(cpu_gpr[rt], 0);
2034 tcg_gen_ori_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
2036 tcg_gen_movi_tl(cpu_gpr[rt], uimm);
2040 if (likely(rs != 0))
2041 tcg_gen_xori_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
2043 tcg_gen_movi_tl(cpu_gpr[rt], uimm);
2047 tcg_gen_movi_tl(cpu_gpr[rt], imm << 16);
2051 (void)opn; /* avoid a compiler warning */
2052 MIPS_DEBUG("%s %s, %s, " TARGET_FMT_lx, opn, regnames[rt], regnames[rs], uimm);
2055 /* Set on less than with immediate operand */
2056 static void gen_slt_imm(CPUMIPSState *env, DisasContext *ctx, uint32_t opc,
2057 int rt, int rs, int16_t imm)
2059 target_ulong uimm = (target_long)imm; /* Sign extend to 32/64 bits */
2060 const char *opn = "imm arith";
2064 /* If no destination, treat it as a NOP. */
2068 t0 = tcg_temp_new();
2069 gen_load_gpr(t0, rs);
2072 tcg_gen_setcondi_tl(TCG_COND_LT, cpu_gpr[rt], t0, uimm);
2076 tcg_gen_setcondi_tl(TCG_COND_LTU, cpu_gpr[rt], t0, uimm);
2080 (void)opn; /* avoid a compiler warning */
2081 MIPS_DEBUG("%s %s, %s, " TARGET_FMT_lx, opn, regnames[rt], regnames[rs], uimm);
2085 /* Shifts with immediate operand */
2086 static void gen_shift_imm(CPUMIPSState *env, DisasContext *ctx, uint32_t opc,
2087 int rt, int rs, int16_t imm)
2089 target_ulong uimm = ((uint16_t)imm) & 0x1f;
2090 const char *opn = "imm shift";
2094 /* If no destination, treat it as a NOP. */
2099 t0 = tcg_temp_new();
2100 gen_load_gpr(t0, rs);
2103 tcg_gen_shli_tl(t0, t0, uimm);
2104 tcg_gen_ext32s_tl(cpu_gpr[rt], t0);
2108 tcg_gen_sari_tl(cpu_gpr[rt], t0, uimm);
2113 tcg_gen_ext32u_tl(t0, t0);
2114 tcg_gen_shri_tl(cpu_gpr[rt], t0, uimm);
2116 tcg_gen_ext32s_tl(cpu_gpr[rt], t0);
2122 TCGv_i32 t1 = tcg_temp_new_i32();
2124 tcg_gen_trunc_tl_i32(t1, t0);
2125 tcg_gen_rotri_i32(t1, t1, uimm);
2126 tcg_gen_ext_i32_tl(cpu_gpr[rt], t1);
2127 tcg_temp_free_i32(t1);
2129 tcg_gen_ext32s_tl(cpu_gpr[rt], t0);
2133 #if defined(TARGET_MIPS64)
2135 tcg_gen_shli_tl(cpu_gpr[rt], t0, uimm);
2139 tcg_gen_sari_tl(cpu_gpr[rt], t0, uimm);
2143 tcg_gen_shri_tl(cpu_gpr[rt], t0, uimm);
2148 tcg_gen_rotri_tl(cpu_gpr[rt], t0, uimm);
2150 tcg_gen_mov_tl(cpu_gpr[rt], t0);
2155 tcg_gen_shli_tl(cpu_gpr[rt], t0, uimm + 32);
2159 tcg_gen_sari_tl(cpu_gpr[rt], t0, uimm + 32);
2163 tcg_gen_shri_tl(cpu_gpr[rt], t0, uimm + 32);
2167 tcg_gen_rotri_tl(cpu_gpr[rt], t0, uimm + 32);
2172 (void)opn; /* avoid a compiler warning */
2173 MIPS_DEBUG("%s %s, %s, " TARGET_FMT_lx, opn, regnames[rt], regnames[rs], uimm);
2178 static void gen_arith (CPUMIPSState *env, DisasContext *ctx, uint32_t opc,
2179 int rd, int rs, int rt)
2181 const char *opn = "arith";
2183 if (rd == 0 && opc != OPC_ADD && opc != OPC_SUB
2184 && opc != OPC_DADD && opc != OPC_DSUB) {
2185 /* If no destination, treat it as a NOP.
2186 For add & sub, we must generate the overflow exception when needed. */
2194 TCGv t0 = tcg_temp_local_new();
2195 TCGv t1 = tcg_temp_new();
2196 TCGv t2 = tcg_temp_new();
2197 int l1 = gen_new_label();
2199 gen_load_gpr(t1, rs);
2200 gen_load_gpr(t2, rt);
2201 tcg_gen_add_tl(t0, t1, t2);
2202 tcg_gen_ext32s_tl(t0, t0);
2203 tcg_gen_xor_tl(t1, t1, t2);
2204 tcg_gen_xor_tl(t2, t0, t2);
2205 tcg_gen_andc_tl(t1, t2, t1);
2207 tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
2209 /* operands of same sign, result different sign */
2210 generate_exception(ctx, EXCP_OVERFLOW);
2212 gen_store_gpr(t0, rd);
2218 if (rs != 0 && rt != 0) {
2219 tcg_gen_add_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2220 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
2221 } else if (rs == 0 && rt != 0) {
2222 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rt]);
2223 } else if (rs != 0 && rt == 0) {
2224 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
2226 tcg_gen_movi_tl(cpu_gpr[rd], 0);
2232 TCGv t0 = tcg_temp_local_new();
2233 TCGv t1 = tcg_temp_new();
2234 TCGv t2 = tcg_temp_new();
2235 int l1 = gen_new_label();
2237 gen_load_gpr(t1, rs);
2238 gen_load_gpr(t2, rt);
2239 tcg_gen_sub_tl(t0, t1, t2);
2240 tcg_gen_ext32s_tl(t0, t0);
2241 tcg_gen_xor_tl(t2, t1, t2);
2242 tcg_gen_xor_tl(t1, t0, t1);
2243 tcg_gen_and_tl(t1, t1, t2);
2245 tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
2247 /* operands of different sign, first operand and result different sign */
2248 generate_exception(ctx, EXCP_OVERFLOW);
2250 gen_store_gpr(t0, rd);
2256 if (rs != 0 && rt != 0) {
2257 tcg_gen_sub_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2258 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
2259 } else if (rs == 0 && rt != 0) {
2260 tcg_gen_neg_tl(cpu_gpr[rd], cpu_gpr[rt]);
2261 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
2262 } else if (rs != 0 && rt == 0) {
2263 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
2265 tcg_gen_movi_tl(cpu_gpr[rd], 0);
2269 #if defined(TARGET_MIPS64)
2272 TCGv t0 = tcg_temp_local_new();
2273 TCGv t1 = tcg_temp_new();
2274 TCGv t2 = tcg_temp_new();
2275 int l1 = gen_new_label();
2277 gen_load_gpr(t1, rs);
2278 gen_load_gpr(t2, rt);
2279 tcg_gen_add_tl(t0, t1, t2);
2280 tcg_gen_xor_tl(t1, t1, t2);
2281 tcg_gen_xor_tl(t2, t0, t2);
2282 tcg_gen_andc_tl(t1, t2, t1);
2284 tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
2286 /* operands of same sign, result different sign */
2287 generate_exception(ctx, EXCP_OVERFLOW);
2289 gen_store_gpr(t0, rd);
2295 if (rs != 0 && rt != 0) {
2296 tcg_gen_add_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2297 } else if (rs == 0 && rt != 0) {
2298 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rt]);
2299 } else if (rs != 0 && rt == 0) {
2300 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
2302 tcg_gen_movi_tl(cpu_gpr[rd], 0);
2308 TCGv t0 = tcg_temp_local_new();
2309 TCGv t1 = tcg_temp_new();
2310 TCGv t2 = tcg_temp_new();
2311 int l1 = gen_new_label();
2313 gen_load_gpr(t1, rs);
2314 gen_load_gpr(t2, rt);
2315 tcg_gen_sub_tl(t0, t1, t2);
2316 tcg_gen_xor_tl(t2, t1, t2);
2317 tcg_gen_xor_tl(t1, t0, t1);
2318 tcg_gen_and_tl(t1, t1, t2);
2320 tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
2322 /* operands of different sign, first operand and result different sign */
2323 generate_exception(ctx, EXCP_OVERFLOW);
2325 gen_store_gpr(t0, rd);
2331 if (rs != 0 && rt != 0) {
2332 tcg_gen_sub_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2333 } else if (rs == 0 && rt != 0) {
2334 tcg_gen_neg_tl(cpu_gpr[rd], cpu_gpr[rt]);
2335 } else if (rs != 0 && rt == 0) {
2336 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
2338 tcg_gen_movi_tl(cpu_gpr[rd], 0);
2344 if (likely(rs != 0 && rt != 0)) {
2345 tcg_gen_mul_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2346 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
2348 tcg_gen_movi_tl(cpu_gpr[rd], 0);
2353 (void)opn; /* avoid a compiler warning */
2354 MIPS_DEBUG("%s %s, %s, %s", opn, regnames[rd], regnames[rs], regnames[rt]);
2357 /* Conditional move */
2358 static void gen_cond_move(CPUMIPSState *env, DisasContext *ctx, uint32_t opc,
2359 int rd, int rs, int rt)
2361 const char *opn = "cond move";
2365 /* If no destination, treat it as a NOP. */
2370 t0 = tcg_temp_new();
2371 gen_load_gpr(t0, rt);
2372 t1 = tcg_const_tl(0);
2373 t2 = tcg_temp_new();
2374 gen_load_gpr(t2, rs);
2377 tcg_gen_movcond_tl(TCG_COND_NE, cpu_gpr[rd], t0, t1, t2, cpu_gpr[rd]);
2381 tcg_gen_movcond_tl(TCG_COND_EQ, cpu_gpr[rd], t0, t1, t2, cpu_gpr[rd]);
2389 (void)opn; /* avoid a compiler warning */
2390 MIPS_DEBUG("%s %s, %s, %s", opn, regnames[rd], regnames[rs], regnames[rt]);
2394 static void gen_logic(CPUMIPSState *env, DisasContext *ctx, uint32_t opc,
2395 int rd, int rs, int rt)
2397 const char *opn = "logic";
2400 /* If no destination, treat it as a NOP. */
2407 if (likely(rs != 0 && rt != 0)) {
2408 tcg_gen_and_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2410 tcg_gen_movi_tl(cpu_gpr[rd], 0);
2415 if (rs != 0 && rt != 0) {
2416 tcg_gen_nor_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2417 } else if (rs == 0 && rt != 0) {
2418 tcg_gen_not_tl(cpu_gpr[rd], cpu_gpr[rt]);
2419 } else if (rs != 0 && rt == 0) {
2420 tcg_gen_not_tl(cpu_gpr[rd], cpu_gpr[rs]);
2422 tcg_gen_movi_tl(cpu_gpr[rd], ~((target_ulong)0));
2427 if (likely(rs != 0 && rt != 0)) {
2428 tcg_gen_or_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2429 } else if (rs == 0 && rt != 0) {
2430 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rt]);
2431 } else if (rs != 0 && rt == 0) {
2432 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
2434 tcg_gen_movi_tl(cpu_gpr[rd], 0);
2439 if (likely(rs != 0 && rt != 0)) {
2440 tcg_gen_xor_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2441 } else if (rs == 0 && rt != 0) {
2442 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rt]);
2443 } else if (rs != 0 && rt == 0) {
2444 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
2446 tcg_gen_movi_tl(cpu_gpr[rd], 0);
2451 (void)opn; /* avoid a compiler warning */
2452 MIPS_DEBUG("%s %s, %s, %s", opn, regnames[rd], regnames[rs], regnames[rt]);
2455 /* Set on lower than */
2456 static void gen_slt(CPUMIPSState *env, DisasContext *ctx, uint32_t opc,
2457 int rd, int rs, int rt)
2459 const char *opn = "slt";
2463 /* If no destination, treat it as a NOP. */
2468 t0 = tcg_temp_new();
2469 t1 = tcg_temp_new();
2470 gen_load_gpr(t0, rs);
2471 gen_load_gpr(t1, rt);
2474 tcg_gen_setcond_tl(TCG_COND_LT, cpu_gpr[rd], t0, t1);
2478 tcg_gen_setcond_tl(TCG_COND_LTU, cpu_gpr[rd], t0, t1);
2482 (void)opn; /* avoid a compiler warning */
2483 MIPS_DEBUG("%s %s, %s, %s", opn, regnames[rd], regnames[rs], regnames[rt]);
2489 static void gen_shift (CPUMIPSState *env, DisasContext *ctx, uint32_t opc,
2490 int rd, int rs, int rt)
2492 const char *opn = "shifts";
2496 /* If no destination, treat it as a NOP.
2497 For add & sub, we must generate the overflow exception when needed. */
2502 t0 = tcg_temp_new();
2503 t1 = tcg_temp_new();
2504 gen_load_gpr(t0, rs);
2505 gen_load_gpr(t1, rt);
2508 tcg_gen_andi_tl(t0, t0, 0x1f);
2509 tcg_gen_shl_tl(t0, t1, t0);
2510 tcg_gen_ext32s_tl(cpu_gpr[rd], t0);
2514 tcg_gen_andi_tl(t0, t0, 0x1f);
2515 tcg_gen_sar_tl(cpu_gpr[rd], t1, t0);
2519 tcg_gen_ext32u_tl(t1, t1);
2520 tcg_gen_andi_tl(t0, t0, 0x1f);
2521 tcg_gen_shr_tl(t0, t1, t0);
2522 tcg_gen_ext32s_tl(cpu_gpr[rd], t0);
2527 TCGv_i32 t2 = tcg_temp_new_i32();
2528 TCGv_i32 t3 = tcg_temp_new_i32();
2530 tcg_gen_trunc_tl_i32(t2, t0);
2531 tcg_gen_trunc_tl_i32(t3, t1);
2532 tcg_gen_andi_i32(t2, t2, 0x1f);
2533 tcg_gen_rotr_i32(t2, t3, t2);
2534 tcg_gen_ext_i32_tl(cpu_gpr[rd], t2);
2535 tcg_temp_free_i32(t2);
2536 tcg_temp_free_i32(t3);
2540 #if defined(TARGET_MIPS64)
2542 tcg_gen_andi_tl(t0, t0, 0x3f);
2543 tcg_gen_shl_tl(cpu_gpr[rd], t1, t0);
2547 tcg_gen_andi_tl(t0, t0, 0x3f);
2548 tcg_gen_sar_tl(cpu_gpr[rd], t1, t0);
2552 tcg_gen_andi_tl(t0, t0, 0x3f);
2553 tcg_gen_shr_tl(cpu_gpr[rd], t1, t0);
2557 tcg_gen_andi_tl(t0, t0, 0x3f);
2558 tcg_gen_rotr_tl(cpu_gpr[rd], t1, t0);
2563 (void)opn; /* avoid a compiler warning */
2564 MIPS_DEBUG("%s %s, %s, %s", opn, regnames[rd], regnames[rs], regnames[rt]);
2569 /* Arithmetic on HI/LO registers */
2570 static void gen_HILO (DisasContext *ctx, uint32_t opc, int reg)
2572 const char *opn = "hilo";
2575 if (reg == 0 && (opc == OPC_MFHI || opc == OPC_MFLO)) {
2581 if (opc == OPC_MFHI || opc == OPC_MFLO) {
2582 acc = ((ctx->opcode) >> 21) & 0x03;
2584 acc = ((ctx->opcode) >> 11) & 0x03;
2593 #if defined(TARGET_MIPS64)
2595 tcg_gen_ext32s_tl(cpu_gpr[reg], cpu_HI[acc]);
2599 tcg_gen_mov_tl(cpu_gpr[reg], cpu_HI[acc]);
2604 #if defined(TARGET_MIPS64)
2606 tcg_gen_ext32s_tl(cpu_gpr[reg], cpu_LO[acc]);
2610 tcg_gen_mov_tl(cpu_gpr[reg], cpu_LO[acc]);
2616 #if defined(TARGET_MIPS64)
2618 tcg_gen_ext32s_tl(cpu_HI[acc], cpu_gpr[reg]);
2622 tcg_gen_mov_tl(cpu_HI[acc], cpu_gpr[reg]);
2625 tcg_gen_movi_tl(cpu_HI[acc], 0);
2631 #if defined(TARGET_MIPS64)
2633 tcg_gen_ext32s_tl(cpu_LO[acc], cpu_gpr[reg]);
2637 tcg_gen_mov_tl(cpu_LO[acc], cpu_gpr[reg]);
2640 tcg_gen_movi_tl(cpu_LO[acc], 0);
2645 (void)opn; /* avoid a compiler warning */
2646 MIPS_DEBUG("%s %s", opn, regnames[reg]);
2649 static void gen_muldiv (DisasContext *ctx, uint32_t opc,
2652 const char *opn = "mul/div";
2656 t0 = tcg_temp_new();
2657 t1 = tcg_temp_new();
2659 gen_load_gpr(t0, rs);
2660 gen_load_gpr(t1, rt);
2665 TCGv t2 = tcg_temp_new();
2666 TCGv t3 = tcg_temp_new();
2667 tcg_gen_ext32s_tl(t0, t0);
2668 tcg_gen_ext32s_tl(t1, t1);
2669 tcg_gen_setcondi_tl(TCG_COND_EQ, t2, t0, INT_MIN);
2670 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, -1);
2671 tcg_gen_and_tl(t2, t2, t3);
2672 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, 0);
2673 tcg_gen_or_tl(t2, t2, t3);
2674 tcg_gen_movi_tl(t3, 0);
2675 tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, t3, t2, t1);
2676 tcg_gen_div_tl(cpu_LO[0], t0, t1);
2677 tcg_gen_rem_tl(cpu_HI[0], t0, t1);
2678 tcg_gen_ext32s_tl(cpu_LO[0], cpu_LO[0]);
2679 tcg_gen_ext32s_tl(cpu_HI[0], cpu_HI[0]);
2687 TCGv t2 = tcg_const_tl(0);
2688 TCGv t3 = tcg_const_tl(1);
2689 tcg_gen_ext32u_tl(t0, t0);
2690 tcg_gen_ext32u_tl(t1, t1);
2691 tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1, t2, t3, t1);
2692 tcg_gen_divu_tl(cpu_LO[0], t0, t1);
2693 tcg_gen_remu_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]);
2703 TCGv_i64 t2 = tcg_temp_new_i64();
2704 TCGv_i64 t3 = tcg_temp_new_i64();
2705 acc = ((ctx->opcode) >> 11) & 0x03;
2710 tcg_gen_ext_tl_i64(t2, t0);
2711 tcg_gen_ext_tl_i64(t3, t1);
2712 tcg_gen_mul_i64(t2, t2, t3);
2713 tcg_temp_free_i64(t3);
2714 tcg_gen_trunc_i64_tl(t0, t2);
2715 tcg_gen_shri_i64(t2, t2, 32);
2716 tcg_gen_trunc_i64_tl(t1, t2);
2717 tcg_temp_free_i64(t2);
2718 tcg_gen_ext32s_tl(cpu_LO[acc], t0);
2719 tcg_gen_ext32s_tl(cpu_HI[acc], t1);
2725 TCGv_i64 t2 = tcg_temp_new_i64();
2726 TCGv_i64 t3 = tcg_temp_new_i64();
2727 acc = ((ctx->opcode) >> 11) & 0x03;
2732 tcg_gen_ext32u_tl(t0, t0);
2733 tcg_gen_ext32u_tl(t1, t1);
2734 tcg_gen_extu_tl_i64(t2, t0);
2735 tcg_gen_extu_tl_i64(t3, t1);
2736 tcg_gen_mul_i64(t2, t2, t3);
2737 tcg_temp_free_i64(t3);
2738 tcg_gen_trunc_i64_tl(t0, t2);
2739 tcg_gen_shri_i64(t2, t2, 32);
2740 tcg_gen_trunc_i64_tl(t1, t2);
2741 tcg_temp_free_i64(t2);
2742 tcg_gen_ext32s_tl(cpu_LO[acc], t0);
2743 tcg_gen_ext32s_tl(cpu_HI[acc], t1);
2747 #if defined(TARGET_MIPS64)
2750 TCGv t2 = tcg_temp_new();
2751 TCGv t3 = tcg_temp_new();
2752 tcg_gen_setcondi_tl(TCG_COND_EQ, t2, t0, -1LL << 63);
2753 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, -1LL);
2754 tcg_gen_and_tl(t2, t2, t3);
2755 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, 0);
2756 tcg_gen_or_tl(t2, t2, t3);
2757 tcg_gen_movi_tl(t3, 0);
2758 tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, t3, t2, t1);
2759 tcg_gen_div_tl(cpu_LO[0], t0, t1);
2760 tcg_gen_rem_tl(cpu_HI[0], t0, t1);
2768 TCGv t2 = tcg_const_tl(0);
2769 TCGv t3 = tcg_const_tl(1);
2770 tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1, t2, t3, t1);
2771 tcg_gen_divu_i64(cpu_LO[0], t0, t1);
2772 tcg_gen_remu_i64(cpu_HI[0], t0, t1);
2779 gen_helper_dmult(cpu_env, t0, t1);
2783 gen_helper_dmultu(cpu_env, t0, t1);
2789 TCGv_i64 t2 = tcg_temp_new_i64();
2790 TCGv_i64 t3 = tcg_temp_new_i64();
2791 acc = ((ctx->opcode) >> 11) & 0x03;
2796 tcg_gen_ext_tl_i64(t2, t0);
2797 tcg_gen_ext_tl_i64(t3, t1);
2798 tcg_gen_mul_i64(t2, t2, t3);
2799 tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]);
2800 tcg_gen_add_i64(t2, t2, t3);
2801 tcg_temp_free_i64(t3);
2802 tcg_gen_trunc_i64_tl(t0, t2);
2803 tcg_gen_shri_i64(t2, t2, 32);
2804 tcg_gen_trunc_i64_tl(t1, t2);
2805 tcg_temp_free_i64(t2);
2806 tcg_gen_ext32s_tl(cpu_LO[acc], t0);
2807 tcg_gen_ext32s_tl(cpu_HI[acc], t1);
2813 TCGv_i64 t2 = tcg_temp_new_i64();
2814 TCGv_i64 t3 = tcg_temp_new_i64();
2815 acc = ((ctx->opcode) >> 11) & 0x03;
2820 tcg_gen_ext32u_tl(t0, t0);
2821 tcg_gen_ext32u_tl(t1, t1);
2822 tcg_gen_extu_tl_i64(t2, t0);
2823 tcg_gen_extu_tl_i64(t3, t1);
2824 tcg_gen_mul_i64(t2, t2, t3);
2825 tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]);
2826 tcg_gen_add_i64(t2, t2, t3);
2827 tcg_temp_free_i64(t3);
2828 tcg_gen_trunc_i64_tl(t0, t2);
2829 tcg_gen_shri_i64(t2, t2, 32);
2830 tcg_gen_trunc_i64_tl(t1, t2);
2831 tcg_temp_free_i64(t2);
2832 tcg_gen_ext32s_tl(cpu_LO[acc], t0);
2833 tcg_gen_ext32s_tl(cpu_HI[acc], t1);
2839 TCGv_i64 t2 = tcg_temp_new_i64();
2840 TCGv_i64 t3 = tcg_temp_new_i64();
2841 acc = ((ctx->opcode) >> 11) & 0x03;
2846 tcg_gen_ext_tl_i64(t2, t0);
2847 tcg_gen_ext_tl_i64(t3, t1);
2848 tcg_gen_mul_i64(t2, t2, t3);
2849 tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]);
2850 tcg_gen_sub_i64(t2, t3, t2);
2851 tcg_temp_free_i64(t3);
2852 tcg_gen_trunc_i64_tl(t0, t2);
2853 tcg_gen_shri_i64(t2, t2, 32);
2854 tcg_gen_trunc_i64_tl(t1, t2);
2855 tcg_temp_free_i64(t2);
2856 tcg_gen_ext32s_tl(cpu_LO[acc], t0);
2857 tcg_gen_ext32s_tl(cpu_HI[acc], t1);
2863 TCGv_i64 t2 = tcg_temp_new_i64();
2864 TCGv_i64 t3 = tcg_temp_new_i64();
2865 acc = ((ctx->opcode) >> 11) & 0x03;
2870 tcg_gen_ext32u_tl(t0, t0);
2871 tcg_gen_ext32u_tl(t1, t1);
2872 tcg_gen_extu_tl_i64(t2, t0);
2873 tcg_gen_extu_tl_i64(t3, t1);
2874 tcg_gen_mul_i64(t2, t2, t3);
2875 tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]);
2876 tcg_gen_sub_i64(t2, t3, t2);
2877 tcg_temp_free_i64(t3);
2878 tcg_gen_trunc_i64_tl(t0, t2);
2879 tcg_gen_shri_i64(t2, t2, 32);
2880 tcg_gen_trunc_i64_tl(t1, t2);
2881 tcg_temp_free_i64(t2);
2882 tcg_gen_ext32s_tl(cpu_LO[acc], t0);
2883 tcg_gen_ext32s_tl(cpu_HI[acc], t1);
2889 generate_exception(ctx, EXCP_RI);
2892 (void)opn; /* avoid a compiler warning */
2893 MIPS_DEBUG("%s %s %s", opn, regnames[rs], regnames[rt]);
2899 static void gen_mul_vr54xx (DisasContext *ctx, uint32_t opc,
2900 int rd, int rs, int rt)
2902 const char *opn = "mul vr54xx";
2903 TCGv t0 = tcg_temp_new();
2904 TCGv t1 = tcg_temp_new();
2906 gen_load_gpr(t0, rs);
2907 gen_load_gpr(t1, rt);
2910 case OPC_VR54XX_MULS:
2911 gen_helper_muls(t0, cpu_env, t0, t1);
2914 case OPC_VR54XX_MULSU:
2915 gen_helper_mulsu(t0, cpu_env, t0, t1);
2918 case OPC_VR54XX_MACC:
2919 gen_helper_macc(t0, cpu_env, t0, t1);
2922 case OPC_VR54XX_MACCU:
2923 gen_helper_maccu(t0, cpu_env, t0, t1);
2926 case OPC_VR54XX_MSAC:
2927 gen_helper_msac(t0, cpu_env, t0, t1);
2930 case OPC_VR54XX_MSACU:
2931 gen_helper_msacu(t0, cpu_env, t0, t1);
2934 case OPC_VR54XX_MULHI:
2935 gen_helper_mulhi(t0, cpu_env, t0, t1);
2938 case OPC_VR54XX_MULHIU:
2939 gen_helper_mulhiu(t0, cpu_env, t0, t1);
2942 case OPC_VR54XX_MULSHI:
2943 gen_helper_mulshi(t0, cpu_env, t0, t1);
2946 case OPC_VR54XX_MULSHIU:
2947 gen_helper_mulshiu(t0, cpu_env, t0, t1);
2950 case OPC_VR54XX_MACCHI:
2951 gen_helper_macchi(t0, cpu_env, t0, t1);
2954 case OPC_VR54XX_MACCHIU:
2955 gen_helper_macchiu(t0, cpu_env, t0, t1);
2958 case OPC_VR54XX_MSACHI:
2959 gen_helper_msachi(t0, cpu_env, t0, t1);
2962 case OPC_VR54XX_MSACHIU:
2963 gen_helper_msachiu(t0, cpu_env, t0, t1);
2967 MIPS_INVAL("mul vr54xx");
2968 generate_exception(ctx, EXCP_RI);
2971 gen_store_gpr(t0, rd);
2972 (void)opn; /* avoid a compiler warning */
2973 MIPS_DEBUG("%s %s, %s, %s", opn, regnames[rd], regnames[rs], regnames[rt]);
2980 static void gen_cl (DisasContext *ctx, uint32_t opc,
2983 const char *opn = "CLx";
2991 t0 = tcg_temp_new();
2992 gen_load_gpr(t0, rs);
2995 gen_helper_clo(cpu_gpr[rd], t0);
2999 gen_helper_clz(cpu_gpr[rd], t0);
3002 #if defined(TARGET_MIPS64)
3004 gen_helper_dclo(cpu_gpr[rd], t0);
3008 gen_helper_dclz(cpu_gpr[rd], t0);
3013 (void)opn; /* avoid a compiler warning */
3014 MIPS_DEBUG("%s %s, %s", opn, regnames[rd], regnames[rs]);
3018 /* Godson integer instructions */
3019 static void gen_loongson_integer(DisasContext *ctx, uint32_t opc,
3020 int rd, int rs, int rt)
3022 const char *opn = "loongson";
3034 case OPC_MULTU_G_2E:
3035 case OPC_MULTU_G_2F:
3036 #if defined(TARGET_MIPS64)
3037 case OPC_DMULT_G_2E:
3038 case OPC_DMULT_G_2F:
3039 case OPC_DMULTU_G_2E:
3040 case OPC_DMULTU_G_2F:
3042 t0 = tcg_temp_new();
3043 t1 = tcg_temp_new();
3046 t0 = tcg_temp_local_new();
3047 t1 = tcg_temp_local_new();
3051 gen_load_gpr(t0, rs);
3052 gen_load_gpr(t1, rt);
3057 tcg_gen_mul_tl(cpu_gpr[rd], t0, t1);
3058 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3061 case OPC_MULTU_G_2E:
3062 case OPC_MULTU_G_2F:
3063 tcg_gen_ext32u_tl(t0, t0);
3064 tcg_gen_ext32u_tl(t1, t1);
3065 tcg_gen_mul_tl(cpu_gpr[rd], t0, t1);
3066 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3072 int l1 = gen_new_label();
3073 int l2 = gen_new_label();
3074 int l3 = gen_new_label();
3075 tcg_gen_ext32s_tl(t0, t0);
3076 tcg_gen_ext32s_tl(t1, t1);
3077 tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
3078 tcg_gen_movi_tl(cpu_gpr[rd], 0);
3081 tcg_gen_brcondi_tl(TCG_COND_NE, t0, INT_MIN, l2);
3082 tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1, l2);
3083 tcg_gen_mov_tl(cpu_gpr[rd], t0);
3086 tcg_gen_div_tl(cpu_gpr[rd], t0, t1);
3087 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3095 int l1 = gen_new_label();
3096 int l2 = gen_new_label();
3097 tcg_gen_ext32u_tl(t0, t0);
3098 tcg_gen_ext32u_tl(t1, t1);
3099 tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
3100 tcg_gen_movi_tl(cpu_gpr[rd], 0);
3103 tcg_gen_divu_tl(cpu_gpr[rd], t0, t1);
3104 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3112 int l1 = gen_new_label();
3113 int l2 = gen_new_label();
3114 int l3 = gen_new_label();
3115 tcg_gen_ext32u_tl(t0, t0);
3116 tcg_gen_ext32u_tl(t1, t1);
3117 tcg_gen_brcondi_tl(TCG_COND_EQ, t1, 0, l1);
3118 tcg_gen_brcondi_tl(TCG_COND_NE, t0, INT_MIN, l2);
3119 tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1, l2);
3121 tcg_gen_movi_tl(cpu_gpr[rd], 0);
3124 tcg_gen_rem_tl(cpu_gpr[rd], t0, t1);
3125 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3133 int l1 = gen_new_label();
3134 int l2 = gen_new_label();
3135 tcg_gen_ext32u_tl(t0, t0);
3136 tcg_gen_ext32u_tl(t1, t1);
3137 tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
3138 tcg_gen_movi_tl(cpu_gpr[rd], 0);
3141 tcg_gen_remu_tl(cpu_gpr[rd], t0, t1);
3142 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3147 #if defined(TARGET_MIPS64)
3148 case OPC_DMULT_G_2E:
3149 case OPC_DMULT_G_2F:
3150 tcg_gen_mul_tl(cpu_gpr[rd], t0, t1);
3153 case OPC_DMULTU_G_2E:
3154 case OPC_DMULTU_G_2F:
3155 tcg_gen_mul_tl(cpu_gpr[rd], t0, t1);
3161 int l1 = gen_new_label();
3162 int l2 = gen_new_label();
3163 int l3 = gen_new_label();
3164 tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
3165 tcg_gen_movi_tl(cpu_gpr[rd], 0);
3168 tcg_gen_brcondi_tl(TCG_COND_NE, t0, -1LL << 63, l2);
3169 tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1LL, l2);
3170 tcg_gen_mov_tl(cpu_gpr[rd], t0);
3173 tcg_gen_div_tl(cpu_gpr[rd], t0, t1);
3178 case OPC_DDIVU_G_2E:
3179 case OPC_DDIVU_G_2F:
3181 int l1 = gen_new_label();
3182 int l2 = gen_new_label();
3183 tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
3184 tcg_gen_movi_tl(cpu_gpr[rd], 0);
3187 tcg_gen_divu_tl(cpu_gpr[rd], t0, t1);
3195 int l1 = gen_new_label();
3196 int l2 = gen_new_label();
3197 int l3 = gen_new_label();
3198 tcg_gen_brcondi_tl(TCG_COND_EQ, t1, 0, l1);
3199 tcg_gen_brcondi_tl(TCG_COND_NE, t0, -1LL << 63, l2);
3200 tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1LL, l2);
3202 tcg_gen_movi_tl(cpu_gpr[rd], 0);
3205 tcg_gen_rem_tl(cpu_gpr[rd], t0, t1);
3210 case OPC_DMODU_G_2E:
3211 case OPC_DMODU_G_2F:
3213 int l1 = gen_new_label();
3214 int l2 = gen_new_label();
3215 tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
3216 tcg_gen_movi_tl(cpu_gpr[rd], 0);
3219 tcg_gen_remu_tl(cpu_gpr[rd], t0, t1);
3227 (void)opn; /* avoid a compiler warning */
3228 MIPS_DEBUG("%s %s, %s", opn, regnames[rd], regnames[rs]);
3233 /* Loongson multimedia instructions */
3234 static void gen_loongson_multimedia(DisasContext *ctx, int rd, int rs, int rt)
3236 const char *opn = "loongson_cp2";
3237 uint32_t opc, shift_max;
3240 opc = MASK_LMI(ctx->opcode);
3246 t0 = tcg_temp_local_new_i64();
3247 t1 = tcg_temp_local_new_i64();
3250 t0 = tcg_temp_new_i64();
3251 t1 = tcg_temp_new_i64();
3255 gen_load_fpr64(ctx, t0, rs);
3256 gen_load_fpr64(ctx, t1, rt);
3258 #define LMI_HELPER(UP, LO) \
3259 case OPC_##UP: gen_helper_##LO(t0, t0, t1); opn = #LO; break
3260 #define LMI_HELPER_1(UP, LO) \
3261 case OPC_##UP: gen_helper_##LO(t0, t0); opn = #LO; break
3262 #define LMI_DIRECT(UP, LO, OP) \
3263 case OPC_##UP: tcg_gen_##OP##_i64(t0, t0, t1); opn = #LO; break
3266 LMI_HELPER(PADDSH, paddsh);
3267 LMI_HELPER(PADDUSH, paddush);
3268 LMI_HELPER(PADDH, paddh);
3269 LMI_HELPER(PADDW, paddw);
3270 LMI_HELPER(PADDSB, paddsb);
3271 LMI_HELPER(PADDUSB, paddusb);
3272 LMI_HELPER(PADDB, paddb);
3274 LMI_HELPER(PSUBSH, psubsh);
3275 LMI_HELPER(PSUBUSH, psubush);
3276 LMI_HELPER(PSUBH, psubh);
3277 LMI_HELPER(PSUBW, psubw);
3278 LMI_HELPER(PSUBSB, psubsb);
3279 LMI_HELPER(PSUBUSB, psubusb);
3280 LMI_HELPER(PSUBB, psubb);
3282 LMI_HELPER(PSHUFH, pshufh);
3283 LMI_HELPER(PACKSSWH, packsswh);
3284 LMI_HELPER(PACKSSHB, packsshb);
3285 LMI_HELPER(PACKUSHB, packushb);
3287 LMI_HELPER(PUNPCKLHW, punpcklhw);
3288 LMI_HELPER(PUNPCKHHW, punpckhhw);
3289 LMI_HELPER(PUNPCKLBH, punpcklbh);
3290 LMI_HELPER(PUNPCKHBH, punpckhbh);
3291 LMI_HELPER(PUNPCKLWD, punpcklwd);
3292 LMI_HELPER(PUNPCKHWD, punpckhwd);
3294 LMI_HELPER(PAVGH, pavgh);
3295 LMI_HELPER(PAVGB, pavgb);
3296 LMI_HELPER(PMAXSH, pmaxsh);
3297 LMI_HELPER(PMINSH, pminsh);
3298 LMI_HELPER(PMAXUB, pmaxub);
3299 LMI_HELPER(PMINUB, pminub);
3301 LMI_HELPER(PCMPEQW, pcmpeqw);
3302 LMI_HELPER(PCMPGTW, pcmpgtw);
3303 LMI_HELPER(PCMPEQH, pcmpeqh);
3304 LMI_HELPER(PCMPGTH, pcmpgth);
3305 LMI_HELPER(PCMPEQB, pcmpeqb);
3306 LMI_HELPER(PCMPGTB, pcmpgtb);
3308 LMI_HELPER(PSLLW, psllw);
3309 LMI_HELPER(PSLLH, psllh);
3310 LMI_HELPER(PSRLW, psrlw);
3311 LMI_HELPER(PSRLH, psrlh);
3312 LMI_HELPER(PSRAW, psraw);
3313 LMI_HELPER(PSRAH, psrah);
3315 LMI_HELPER(PMULLH, pmullh);
3316 LMI_HELPER(PMULHH, pmulhh);
3317 LMI_HELPER(PMULHUH, pmulhuh);
3318 LMI_HELPER(PMADDHW, pmaddhw);
3320 LMI_HELPER(PASUBUB, pasubub);
3321 LMI_HELPER_1(BIADD, biadd);
3322 LMI_HELPER_1(PMOVMSKB, pmovmskb);
3324 LMI_DIRECT(PADDD, paddd, add);
3325 LMI_DIRECT(PSUBD, psubd, sub);
3326 LMI_DIRECT(XOR_CP2, xor, xor);
3327 LMI_DIRECT(NOR_CP2, nor, nor);
3328 LMI_DIRECT(AND_CP2, and, and);
3329 LMI_DIRECT(PANDN, pandn, andc);
3330 LMI_DIRECT(OR, or, or);
3333 tcg_gen_deposit_i64(t0, t0, t1, 0, 16);
3337 tcg_gen_deposit_i64(t0, t0, t1, 16, 16);
3341 tcg_gen_deposit_i64(t0, t0, t1, 32, 16);
3345 tcg_gen_deposit_i64(t0, t0, t1, 48, 16);
3350 tcg_gen_andi_i64(t1, t1, 3);
3351 tcg_gen_shli_i64(t1, t1, 4);
3352 tcg_gen_shr_i64(t0, t0, t1);
3353 tcg_gen_ext16u_i64(t0, t0);
3358 tcg_gen_add_i64(t0, t0, t1);
3359 tcg_gen_ext32s_i64(t0, t0);
3363 tcg_gen_sub_i64(t0, t0, t1);
3364 tcg_gen_ext32s_i64(t0, t0);
3393 /* Make sure shift count isn't TCG undefined behaviour. */
3394 tcg_gen_andi_i64(t1, t1, shift_max - 1);
3399 tcg_gen_shl_i64(t0, t0, t1);
3403 /* Since SRA is UndefinedResult without sign-extended inputs,
3404 we can treat SRA and DSRA the same. */
3405 tcg_gen_sar_i64(t0, t0, t1);
3408 /* We want to shift in zeros for SRL; zero-extend first. */
3409 tcg_gen_ext32u_i64(t0, t0);
3412 tcg_gen_shr_i64(t0, t0, t1);
3416 if (shift_max == 32) {
3417 tcg_gen_ext32s_i64(t0, t0);
3420 /* Shifts larger than MAX produce zero. */
3421 tcg_gen_setcondi_i64(TCG_COND_LTU, t1, t1, shift_max);
3422 tcg_gen_neg_i64(t1, t1);
3423 tcg_gen_and_i64(t0, t0, t1);
3429 TCGv_i64 t2 = tcg_temp_new_i64();
3430 int lab = gen_new_label();
3432 tcg_gen_mov_i64(t2, t0);
3433 tcg_gen_add_i64(t0, t1, t2);
3434 if (opc == OPC_ADD_CP2) {
3435 tcg_gen_ext32s_i64(t0, t0);
3437 tcg_gen_xor_i64(t1, t1, t2);
3438 tcg_gen_xor_i64(t2, t2, t0);
3439 tcg_gen_andc_i64(t1, t2, t1);
3440 tcg_temp_free_i64(t2);
3441 tcg_gen_brcondi_i64(TCG_COND_GE, t1, 0, lab);
3442 generate_exception(ctx, EXCP_OVERFLOW);
3445 opn = (opc == OPC_ADD_CP2 ? "add" : "dadd");
3452 TCGv_i64 t2 = tcg_temp_new_i64();
3453 int lab = gen_new_label();
3455 tcg_gen_mov_i64(t2, t0);
3456 tcg_gen_sub_i64(t0, t1, t2);
3457 if (opc == OPC_SUB_CP2) {
3458 tcg_gen_ext32s_i64(t0, t0);
3460 tcg_gen_xor_i64(t1, t1, t2);
3461 tcg_gen_xor_i64(t2, t2, t0);
3462 tcg_gen_and_i64(t1, t1, t2);
3463 tcg_temp_free_i64(t2);
3464 tcg_gen_brcondi_i64(TCG_COND_GE, t1, 0, lab);
3465 generate_exception(ctx, EXCP_OVERFLOW);
3468 opn = (opc == OPC_SUB_CP2 ? "sub" : "dsub");
3473 tcg_gen_ext32u_i64(t0, t0);
3474 tcg_gen_ext32u_i64(t1, t1);
3475 tcg_gen_mul_i64(t0, t0, t1);
3485 /* ??? Document is unclear: Set FCC[CC]. Does that mean the
3486 FD field is the CC field? */
3489 generate_exception(ctx, EXCP_RI);
3496 gen_store_fpr64(ctx, t0, rd);
3498 (void)opn; /* avoid a compiler warning */
3499 MIPS_DEBUG("%s %s, %s, %s", opn,
3500 fregnames[rd], fregnames[rs], fregnames[rt]);
3501 tcg_temp_free_i64(t0);
3502 tcg_temp_free_i64(t1);
3506 static void gen_trap (DisasContext *ctx, uint32_t opc,
3507 int rs, int rt, int16_t imm)
3510 TCGv t0 = tcg_temp_new();
3511 TCGv t1 = tcg_temp_new();
3514 /* Load needed operands */
3522 /* Compare two registers */
3524 gen_load_gpr(t0, rs);
3525 gen_load_gpr(t1, rt);
3535 /* Compare register to immediate */
3536 if (rs != 0 || imm != 0) {
3537 gen_load_gpr(t0, rs);
3538 tcg_gen_movi_tl(t1, (int32_t)imm);
3545 case OPC_TEQ: /* rs == rs */
3546 case OPC_TEQI: /* r0 == 0 */
3547 case OPC_TGE: /* rs >= rs */
3548 case OPC_TGEI: /* r0 >= 0 */
3549 case OPC_TGEU: /* rs >= rs unsigned */
3550 case OPC_TGEIU: /* r0 >= 0 unsigned */
3552 generate_exception(ctx, EXCP_TRAP);
3554 case OPC_TLT: /* rs < rs */
3555 case OPC_TLTI: /* r0 < 0 */
3556 case OPC_TLTU: /* rs < rs unsigned */
3557 case OPC_TLTIU: /* r0 < 0 unsigned */
3558 case OPC_TNE: /* rs != rs */
3559 case OPC_TNEI: /* r0 != 0 */
3560 /* Never trap: treat as NOP. */
3564 int l1 = gen_new_label();
3569 tcg_gen_brcond_tl(TCG_COND_NE, t0, t1, l1);
3573 tcg_gen_brcond_tl(TCG_COND_LT, t0, t1, l1);
3577 tcg_gen_brcond_tl(TCG_COND_LTU, t0, t1, l1);
3581 tcg_gen_brcond_tl(TCG_COND_GE, t0, t1, l1);
3585 tcg_gen_brcond_tl(TCG_COND_GEU, t0, t1, l1);
3589 tcg_gen_brcond_tl(TCG_COND_EQ, t0, t1, l1);
3592 generate_exception(ctx, EXCP_TRAP);
3599 static inline void gen_goto_tb(DisasContext *ctx, int n, target_ulong dest)
3601 TranslationBlock *tb;
3603 if ((tb->pc & TARGET_PAGE_MASK) == (dest & TARGET_PAGE_MASK) &&
3604 likely(!ctx->singlestep_enabled)) {
3607 tcg_gen_exit_tb((tcg_target_long)tb + n);
3610 if (ctx->singlestep_enabled) {
3611 save_cpu_state(ctx, 0);
3612 gen_helper_0e0i(raise_exception, EXCP_DEBUG);
3618 /* Branches (before delay slot) */
3619 static void gen_compute_branch (DisasContext *ctx, uint32_t opc,
3621 int rs, int rt, int32_t offset)
3623 target_ulong btgt = -1;
3625 int bcond_compute = 0;
3626 TCGv t0 = tcg_temp_new();
3627 TCGv t1 = tcg_temp_new();
3629 if (ctx->hflags & MIPS_HFLAG_BMASK) {
3630 #ifdef MIPS_DEBUG_DISAS
3631 LOG_DISAS("Branch in delay slot at PC 0x" TARGET_FMT_lx "\n", ctx->pc);
3633 generate_exception(ctx, EXCP_RI);
3637 /* Load needed operands */
3643 /* Compare two registers */
3645 gen_load_gpr(t0, rs);
3646 gen_load_gpr(t1, rt);
3649 btgt = ctx->pc + insn_bytes + offset;
3665 /* Compare to zero */
3667 gen_load_gpr(t0, rs);
3670 btgt = ctx->pc + insn_bytes + offset;
3673 #if defined(TARGET_MIPS64)
3675 tcg_gen_andi_tl(t0, cpu_dspctrl, 0x7F);
3677 tcg_gen_andi_tl(t0, cpu_dspctrl, 0x3F);
3680 btgt = ctx->pc + insn_bytes + offset;
3687 /* Jump to immediate */
3688 btgt = ((ctx->pc + insn_bytes) & (int32_t)0xF0000000) | (uint32_t)offset;
3694 /* Jump to register */
3695 if (offset != 0 && offset != 16) {
3696 /* Hint = 0 is JR/JALR, hint 16 is JR.HB/JALR.HB, the
3697 others are reserved. */
3698 MIPS_INVAL("jump hint");
3699 generate_exception(ctx, EXCP_RI);
3702 gen_load_gpr(btarget, rs);
3705 MIPS_INVAL("branch/jump");
3706 generate_exception(ctx, EXCP_RI);
3709 if (bcond_compute == 0) {
3710 /* No condition to be computed */
3712 case OPC_BEQ: /* rx == rx */
3713 case OPC_BEQL: /* rx == rx likely */
3714 case OPC_BGEZ: /* 0 >= 0 */
3715 case OPC_BGEZL: /* 0 >= 0 likely */
3716 case OPC_BLEZ: /* 0 <= 0 */
3717 case OPC_BLEZL: /* 0 <= 0 likely */
3719 ctx->hflags |= MIPS_HFLAG_B;
3720 MIPS_DEBUG("balways");
3723 case OPC_BGEZAL: /* 0 >= 0 */
3724 case OPC_BGEZALL: /* 0 >= 0 likely */
3725 ctx->hflags |= (opc == OPC_BGEZALS
3727 : MIPS_HFLAG_BDS32);
3728 /* Always take and link */
3730 ctx->hflags |= MIPS_HFLAG_B;
3731 MIPS_DEBUG("balways and link");
3733 case OPC_BNE: /* rx != rx */
3734 case OPC_BGTZ: /* 0 > 0 */
3735 case OPC_BLTZ: /* 0 < 0 */
3737 MIPS_DEBUG("bnever (NOP)");
3740 case OPC_BLTZAL: /* 0 < 0 */
3741 ctx->hflags |= (opc == OPC_BLTZALS
3743 : MIPS_HFLAG_BDS32);
3744 /* Handle as an unconditional branch to get correct delay
3747 btgt = ctx->pc + (opc == OPC_BLTZALS ? 6 : 8);
3748 ctx->hflags |= MIPS_HFLAG_B;
3749 MIPS_DEBUG("bnever and link");
3751 case OPC_BLTZALL: /* 0 < 0 likely */
3752 tcg_gen_movi_tl(cpu_gpr[31], ctx->pc + 8);
3753 /* Skip the instruction in the delay slot */
3754 MIPS_DEBUG("bnever, link and skip");
3757 case OPC_BNEL: /* rx != rx likely */
3758 case OPC_BGTZL: /* 0 > 0 likely */
3759 case OPC_BLTZL: /* 0 < 0 likely */
3760 /* Skip the instruction in the delay slot */
3761 MIPS_DEBUG("bnever and skip");
3765 ctx->hflags |= MIPS_HFLAG_B;
3766 MIPS_DEBUG("j " TARGET_FMT_lx, btgt);
3770 ctx->hflags |= MIPS_HFLAG_BX;
3775 ctx->hflags |= MIPS_HFLAG_B;
3776 ctx->hflags |= ((opc == OPC_JALS || opc == OPC_JALXS)
3778 : MIPS_HFLAG_BDS32);
3779 MIPS_DEBUG("jal " TARGET_FMT_lx, btgt);
3782 ctx->hflags |= MIPS_HFLAG_BR;
3783 if (insn_bytes == 4)
3784 ctx->hflags |= MIPS_HFLAG_BDS32;
3785 MIPS_DEBUG("jr %s", regnames[rs]);
3791 ctx->hflags |= MIPS_HFLAG_BR;
3792 ctx->hflags |= (opc == OPC_JALRS
3794 : MIPS_HFLAG_BDS32);
3795 MIPS_DEBUG("jalr %s, %s", regnames[rt], regnames[rs]);
3798 MIPS_INVAL("branch/jump");
3799 generate_exception(ctx, EXCP_RI);
3805 tcg_gen_setcond_tl(TCG_COND_EQ, bcond, t0, t1);
3806 MIPS_DEBUG("beq %s, %s, " TARGET_FMT_lx,
3807 regnames[rs], regnames[rt], btgt);
3810 tcg_gen_setcond_tl(TCG_COND_EQ, bcond, t0, t1);
3811 MIPS_DEBUG("beql %s, %s, " TARGET_FMT_lx,
3812 regnames[rs], regnames[rt], btgt);
3815 tcg_gen_setcond_tl(TCG_COND_NE, bcond, t0, t1);
3816 MIPS_DEBUG("bne %s, %s, " TARGET_FMT_lx,
3817 regnames[rs], regnames[rt], btgt);
3820 tcg_gen_setcond_tl(TCG_COND_NE, bcond, t0, t1);
3821 MIPS_DEBUG("bnel %s, %s, " TARGET_FMT_lx,
3822 regnames[rs], regnames[rt], btgt);
3825 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 0);
3826 MIPS_DEBUG("bgez %s, " TARGET_FMT_lx, regnames[rs], btgt);
3829 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 0);
3830 MIPS_DEBUG("bgezl %s, " TARGET_FMT_lx, regnames[rs], btgt);
3834 ctx->hflags |= (opc == OPC_BGEZALS
3836 : MIPS_HFLAG_BDS32);
3837 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 0);
3838 MIPS_DEBUG("bgezal %s, " TARGET_FMT_lx, regnames[rs], btgt);
3842 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 0);
3844 MIPS_DEBUG("bgezall %s, " TARGET_FMT_lx, regnames[rs], btgt);
3847 tcg_gen_setcondi_tl(TCG_COND_GT, bcond, t0, 0);
3848 MIPS_DEBUG("bgtz %s, " TARGET_FMT_lx, regnames[rs], btgt);
3851 tcg_gen_setcondi_tl(TCG_COND_GT, bcond, t0, 0);
3852 MIPS_DEBUG("bgtzl %s, " TARGET_FMT_lx, regnames[rs], btgt);
3855 tcg_gen_setcondi_tl(TCG_COND_LE, bcond, t0, 0);
3856 MIPS_DEBUG("blez %s, " TARGET_FMT_lx, regnames[rs], btgt);
3859 tcg_gen_setcondi_tl(TCG_COND_LE, bcond, t0, 0);
3860 MIPS_DEBUG("blezl %s, " TARGET_FMT_lx, regnames[rs], btgt);
3863 tcg_gen_setcondi_tl(TCG_COND_LT, bcond, t0, 0);
3864 MIPS_DEBUG("bltz %s, " TARGET_FMT_lx, regnames[rs], btgt);
3867 tcg_gen_setcondi_tl(TCG_COND_LT, bcond, t0, 0);
3868 MIPS_DEBUG("bltzl %s, " TARGET_FMT_lx, regnames[rs], btgt);
3871 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 32);
3872 MIPS_DEBUG("bposge32 " TARGET_FMT_lx, btgt);
3874 #if defined(TARGET_MIPS64)
3876 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 64);
3877 MIPS_DEBUG("bposge64 " TARGET_FMT_lx, btgt);
3882 ctx->hflags |= (opc == OPC_BLTZALS
3884 : MIPS_HFLAG_BDS32);
3885 tcg_gen_setcondi_tl(TCG_COND_LT, bcond, t0, 0);
3887 MIPS_DEBUG("bltzal %s, " TARGET_FMT_lx, regnames[rs], btgt);
3889 ctx->hflags |= MIPS_HFLAG_BC;
3892 tcg_gen_setcondi_tl(TCG_COND_LT, bcond, t0, 0);
3894 MIPS_DEBUG("bltzall %s, " TARGET_FMT_lx, regnames[rs], btgt);
3896 ctx->hflags |= MIPS_HFLAG_BL;
3899 MIPS_INVAL("conditional branch/jump");
3900 generate_exception(ctx, EXCP_RI);
3904 MIPS_DEBUG("enter ds: link %d cond %02x target " TARGET_FMT_lx,
3905 blink, ctx->hflags, btgt);
3907 ctx->btarget = btgt;
3909 int post_delay = insn_bytes;
3910 int lowbit = !!(ctx->hflags & MIPS_HFLAG_M16);
3912 if (opc != OPC_JALRC)
3913 post_delay += ((ctx->hflags & MIPS_HFLAG_BDS16) ? 2 : 4);
3915 tcg_gen_movi_tl(cpu_gpr[blink], ctx->pc + post_delay + lowbit);
3919 if (insn_bytes == 2)
3920 ctx->hflags |= MIPS_HFLAG_B16;
3925 /* special3 bitfield operations */
3926 static void gen_bitops (DisasContext *ctx, uint32_t opc, int rt,
3927 int rs, int lsb, int msb)
3929 TCGv t0 = tcg_temp_new();
3930 TCGv t1 = tcg_temp_new();
3933 gen_load_gpr(t1, rs);
3938 tcg_gen_shri_tl(t0, t1, lsb);
3940 tcg_gen_andi_tl(t0, t0, (1 << (msb + 1)) - 1);
3942 tcg_gen_ext32s_tl(t0, t0);
3945 #if defined(TARGET_MIPS64)
3947 tcg_gen_shri_tl(t0, t1, lsb);
3949 tcg_gen_andi_tl(t0, t0, (1ULL << (msb + 1 + 32)) - 1);
3953 tcg_gen_shri_tl(t0, t1, lsb + 32);
3954 tcg_gen_andi_tl(t0, t0, (1ULL << (msb + 1)) - 1);
3957 tcg_gen_shri_tl(t0, t1, lsb);
3958 tcg_gen_andi_tl(t0, t0, (1ULL << (msb + 1)) - 1);
3964 mask = ((msb - lsb + 1 < 32) ? ((1 << (msb - lsb + 1)) - 1) : ~0) << lsb;
3965 gen_load_gpr(t0, rt);
3966 tcg_gen_andi_tl(t0, t0, ~mask);
3967 tcg_gen_shli_tl(t1, t1, lsb);
3968 tcg_gen_andi_tl(t1, t1, mask);
3969 tcg_gen_or_tl(t0, t0, t1);
3970 tcg_gen_ext32s_tl(t0, t0);
3972 #if defined(TARGET_MIPS64)
3976 mask = ((msb - lsb + 1 + 32 < 64) ? ((1ULL << (msb - lsb + 1 + 32)) - 1) : ~0ULL) << lsb;
3977 gen_load_gpr(t0, rt);
3978 tcg_gen_andi_tl(t0, t0, ~mask);
3979 tcg_gen_shli_tl(t1, t1, lsb);
3980 tcg_gen_andi_tl(t1, t1, mask);
3981 tcg_gen_or_tl(t0, t0, t1);
3986 mask = ((1ULL << (msb - lsb + 1)) - 1) << (lsb + 32);
3987 gen_load_gpr(t0, rt);
3988 tcg_gen_andi_tl(t0, t0, ~mask);
3989 tcg_gen_shli_tl(t1, t1, lsb + 32);
3990 tcg_gen_andi_tl(t1, t1, mask);
3991 tcg_gen_or_tl(t0, t0, t1);
3996 gen_load_gpr(t0, rt);
3997 mask = ((1ULL << (msb - lsb + 1)) - 1) << lsb;
3998 gen_load_gpr(t0, rt);
3999 tcg_gen_andi_tl(t0, t0, ~mask);
4000 tcg_gen_shli_tl(t1, t1, lsb);
4001 tcg_gen_andi_tl(t1, t1, mask);
4002 tcg_gen_or_tl(t0, t0, t1);
4007 MIPS_INVAL("bitops");
4008 generate_exception(ctx, EXCP_RI);
4013 gen_store_gpr(t0, rt);
4018 static void gen_bshfl (DisasContext *ctx, uint32_t op2, int rt, int rd)
4023 /* If no destination, treat it as a NOP. */
4028 t0 = tcg_temp_new();
4029 gen_load_gpr(t0, rt);
4033 TCGv t1 = tcg_temp_new();
4035 tcg_gen_shri_tl(t1, t0, 8);
4036 tcg_gen_andi_tl(t1, t1, 0x00FF00FF);
4037 tcg_gen_shli_tl(t0, t0, 8);
4038 tcg_gen_andi_tl(t0, t0, ~0x00FF00FF);
4039 tcg_gen_or_tl(t0, t0, t1);
4041 tcg_gen_ext32s_tl(cpu_gpr[rd], t0);
4045 tcg_gen_ext8s_tl(cpu_gpr[rd], t0);
4048 tcg_gen_ext16s_tl(cpu_gpr[rd], t0);
4050 #if defined(TARGET_MIPS64)
4053 TCGv t1 = tcg_temp_new();
4055 tcg_gen_shri_tl(t1, t0, 8);
4056 tcg_gen_andi_tl(t1, t1, 0x00FF00FF00FF00FFULL);
4057 tcg_gen_shli_tl(t0, t0, 8);
4058 tcg_gen_andi_tl(t0, t0, ~0x00FF00FF00FF00FFULL);
4059 tcg_gen_or_tl(cpu_gpr[rd], t0, t1);
4065 TCGv t1 = tcg_temp_new();
4067 tcg_gen_shri_tl(t1, t0, 16);
4068 tcg_gen_andi_tl(t1, t1, 0x0000FFFF0000FFFFULL);
4069 tcg_gen_shli_tl(t0, t0, 16);
4070 tcg_gen_andi_tl(t0, t0, ~0x0000FFFF0000FFFFULL);
4071 tcg_gen_or_tl(t0, t0, t1);
4072 tcg_gen_shri_tl(t1, t0, 32);
4073 tcg_gen_shli_tl(t0, t0, 32);
4074 tcg_gen_or_tl(cpu_gpr[rd], t0, t1);
4080 MIPS_INVAL("bsfhl");
4081 generate_exception(ctx, EXCP_RI);
4088 #ifndef CONFIG_USER_ONLY
4089 /* CP0 (MMU and control) */
4090 static inline void gen_mfc0_load32 (TCGv arg, target_ulong off)
4092 TCGv_i32 t0 = tcg_temp_new_i32();
4094 tcg_gen_ld_i32(t0, cpu_env, off);
4095 tcg_gen_ext_i32_tl(arg, t0);
4096 tcg_temp_free_i32(t0);
4099 static inline void gen_mfc0_load64 (TCGv arg, target_ulong off)
4101 tcg_gen_ld_tl(arg, cpu_env, off);
4102 tcg_gen_ext32s_tl(arg, arg);
4105 static inline void gen_mtc0_store32 (TCGv arg, target_ulong off)
4107 TCGv_i32 t0 = tcg_temp_new_i32();
4109 tcg_gen_trunc_tl_i32(t0, arg);
4110 tcg_gen_st_i32(t0, cpu_env, off);
4111 tcg_temp_free_i32(t0);
4114 static inline void gen_mtc0_store64 (TCGv arg, target_ulong off)
4116 tcg_gen_ext32s_tl(arg, arg);
4117 tcg_gen_st_tl(arg, cpu_env, off);
4120 static void gen_mfc0 (CPUMIPSState *env, DisasContext *ctx, TCGv arg, int reg, int sel)
4122 const char *rn = "invalid";
4125 check_insn(env, ctx, ISA_MIPS32);
4131 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Index));
4135 check_insn(env, ctx, ASE_MT);
4136 gen_helper_mfc0_mvpcontrol(arg, cpu_env);
4140 check_insn(env, ctx, ASE_MT);
4141 gen_helper_mfc0_mvpconf0(arg, cpu_env);
4145 check_insn(env, ctx, ASE_MT);
4146 gen_helper_mfc0_mvpconf1(arg, cpu_env);
4156 gen_helper_mfc0_random(arg, cpu_env);
4160 check_insn(env, ctx, ASE_MT);
4161 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEControl));
4165 check_insn(env, ctx, ASE_MT);
4166 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEConf0));
4170 check_insn(env, ctx, ASE_MT);
4171 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEConf1));
4175 check_insn(env, ctx, ASE_MT);
4176 gen_mfc0_load64(arg, offsetof(CPUMIPSState, CP0_YQMask));
4180 check_insn(env, ctx, ASE_MT);
4181 gen_mfc0_load64(arg, offsetof(CPUMIPSState, CP0_VPESchedule));
4185 check_insn(env, ctx, ASE_MT);
4186 gen_mfc0_load64(arg, offsetof(CPUMIPSState, CP0_VPEScheFBack));
4187 rn = "VPEScheFBack";
4190 check_insn(env, ctx, ASE_MT);
4191 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEOpt));
4201 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EntryLo0));
4202 tcg_gen_ext32s_tl(arg, arg);
4206 check_insn(env, ctx, ASE_MT);
4207 gen_helper_mfc0_tcstatus(arg, cpu_env);
4211 check_insn(env, ctx, ASE_MT);
4212 gen_helper_mfc0_tcbind(arg, cpu_env);
4216 check_insn(env, ctx, ASE_MT);
4217 gen_helper_mfc0_tcrestart(arg, cpu_env);
4221 check_insn(env, ctx, ASE_MT);
4222 gen_helper_mfc0_tchalt(arg, cpu_env);
4226 check_insn(env, ctx, ASE_MT);
4227 gen_helper_mfc0_tccontext(arg, cpu_env);
4231 check_insn(env, ctx, ASE_MT);
4232 gen_helper_mfc0_tcschedule(arg, cpu_env);
4236 check_insn(env, ctx, ASE_MT);
4237 gen_helper_mfc0_tcschefback(arg, cpu_env);
4247 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EntryLo1));
4248 tcg_gen_ext32s_tl(arg, arg);
4258 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_Context));
4259 tcg_gen_ext32s_tl(arg, arg);
4263 // gen_helper_mfc0_contextconfig(arg); /* SmartMIPS ASE */
4264 rn = "ContextConfig";
4273 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PageMask));
4277 check_insn(env, ctx, ISA_MIPS32R2);
4278 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PageGrain));
4288 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Wired));
4292 check_insn(env, ctx, ISA_MIPS32R2);
4293 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf0));
4297 check_insn(env, ctx, ISA_MIPS32R2);
4298 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf1));
4302 check_insn(env, ctx, ISA_MIPS32R2);
4303 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf2));
4307 check_insn(env, ctx, ISA_MIPS32R2);
4308 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf3));
4312 check_insn(env, ctx, ISA_MIPS32R2);
4313 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf4));
4323 check_insn(env, ctx, ISA_MIPS32R2);
4324 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_HWREna));
4334 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_BadVAddr));
4335 tcg_gen_ext32s_tl(arg, arg);
4345 /* Mark as an IO operation because we read the time. */
4348 gen_helper_mfc0_count(arg, cpu_env);
4352 /* Break the TB to be able to take timer interrupts immediately
4353 after reading count. */
4354 ctx->bstate = BS_STOP;
4357 /* 6,7 are implementation dependent */
4365 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EntryHi));
4366 tcg_gen_ext32s_tl(arg, arg);
4376 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Compare));
4379 /* 6,7 are implementation dependent */
4387 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Status));
4391 check_insn(env, ctx, ISA_MIPS32R2);
4392 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_IntCtl));
4396 check_insn(env, ctx, ISA_MIPS32R2);
4397 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSCtl));
4401 check_insn(env, ctx, ISA_MIPS32R2);
4402 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSMap));
4412 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Cause));
4422 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EPC));
4423 tcg_gen_ext32s_tl(arg, arg);
4433 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PRid));
4437 check_insn(env, ctx, ISA_MIPS32R2);
4438 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_EBase));
4448 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config0));
4452 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config1));
4456 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config2));
4460 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config3));
4463 /* 4,5 are reserved */
4464 /* 6,7 are implementation dependent */
4466 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config6));
4470 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config7));
4480 gen_helper_mfc0_lladdr(arg, cpu_env);
4490 gen_helper_1e0i(mfc0_watchlo, arg, sel);
4500 gen_helper_1e0i(mfc0_watchhi, arg, sel);
4510 #if defined(TARGET_MIPS64)
4511 check_insn(env, ctx, ISA_MIPS3);
4512 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_XContext));
4513 tcg_gen_ext32s_tl(arg, arg);
4522 /* Officially reserved, but sel 0 is used for R1x000 framemask */
4525 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Framemask));
4533 tcg_gen_movi_tl(arg, 0); /* unimplemented */
4534 rn = "'Diagnostic"; /* implementation dependent */
4539 gen_helper_mfc0_debug(arg, cpu_env); /* EJTAG support */
4543 // gen_helper_mfc0_tracecontrol(arg); /* PDtrace support */
4544 rn = "TraceControl";
4547 // gen_helper_mfc0_tracecontrol2(arg); /* PDtrace support */
4548 rn = "TraceControl2";
4551 // gen_helper_mfc0_usertracedata(arg); /* PDtrace support */
4552 rn = "UserTraceData";
4555 // gen_helper_mfc0_tracebpc(arg); /* PDtrace support */
4566 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_DEPC));
4567 tcg_gen_ext32s_tl(arg, arg);
4577 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Performance0));
4578 rn = "Performance0";
4581 // gen_helper_mfc0_performance1(arg);
4582 rn = "Performance1";
4585 // gen_helper_mfc0_performance2(arg);
4586 rn = "Performance2";
4589 // gen_helper_mfc0_performance3(arg);
4590 rn = "Performance3";
4593 // gen_helper_mfc0_performance4(arg);
4594 rn = "Performance4";
4597 // gen_helper_mfc0_performance5(arg);
4598 rn = "Performance5";
4601 // gen_helper_mfc0_performance6(arg);
4602 rn = "Performance6";
4605 // gen_helper_mfc0_performance7(arg);
4606 rn = "Performance7";
4613 tcg_gen_movi_tl(arg, 0); /* unimplemented */
4619 tcg_gen_movi_tl(arg, 0); /* unimplemented */
4632 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_TagLo));
4639 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DataLo));
4652 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_TagHi));
4659 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DataHi));
4669 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_ErrorEPC));
4670 tcg_gen_ext32s_tl(arg, arg);
4681 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DESAVE));
4691 (void)rn; /* avoid a compiler warning */
4692 LOG_DISAS("mfc0 %s (reg %d sel %d)\n", rn, reg, sel);
4696 LOG_DISAS("mfc0 %s (reg %d sel %d)\n", rn, reg, sel);
4697 generate_exception(ctx, EXCP_RI);
4700 static void gen_mtc0 (CPUMIPSState *env, DisasContext *ctx, TCGv arg, int reg, int sel)
4702 const char *rn = "invalid";
4705 check_insn(env, ctx, ISA_MIPS32);
4714 gen_helper_mtc0_index(cpu_env, arg);
4718 check_insn(env, ctx, ASE_MT);
4719 gen_helper_mtc0_mvpcontrol(cpu_env, arg);
4723 check_insn(env, ctx, ASE_MT);
4728 check_insn(env, ctx, ASE_MT);
4743 check_insn(env, ctx, ASE_MT);
4744 gen_helper_mtc0_vpecontrol(cpu_env, arg);
4748 check_insn(env, ctx, ASE_MT);
4749 gen_helper_mtc0_vpeconf0(cpu_env, arg);
4753 check_insn(env, ctx, ASE_MT);
4754 gen_helper_mtc0_vpeconf1(cpu_env, arg);
4758 check_insn(env, ctx, ASE_MT);
4759 gen_helper_mtc0_yqmask(cpu_env, arg);
4763 check_insn(env, ctx, ASE_MT);
4764 gen_mtc0_store64(arg, offsetof(CPUMIPSState, CP0_VPESchedule));
4768 check_insn(env, ctx, ASE_MT);
4769 gen_mtc0_store64(arg, offsetof(CPUMIPSState, CP0_VPEScheFBack));
4770 rn = "VPEScheFBack";
4773 check_insn(env, ctx, ASE_MT);
4774 gen_helper_mtc0_vpeopt(cpu_env, arg);
4784 gen_helper_mtc0_entrylo0(cpu_env, arg);
4788 check_insn(env, ctx, ASE_MT);
4789 gen_helper_mtc0_tcstatus(cpu_env, arg);
4793 check_insn(env, ctx, ASE_MT);
4794 gen_helper_mtc0_tcbind(cpu_env, arg);
4798 check_insn(env, ctx, ASE_MT);
4799 gen_helper_mtc0_tcrestart(cpu_env, arg);
4803 check_insn(env, ctx, ASE_MT);
4804 gen_helper_mtc0_tchalt(cpu_env, arg);
4808 check_insn(env, ctx, ASE_MT);
4809 gen_helper_mtc0_tccontext(cpu_env, arg);
4813 check_insn(env, ctx, ASE_MT);
4814 gen_helper_mtc0_tcschedule(cpu_env, arg);
4818 check_insn(env, ctx, ASE_MT);
4819 gen_helper_mtc0_tcschefback(cpu_env, arg);
4829 gen_helper_mtc0_entrylo1(cpu_env, arg);
4839 gen_helper_mtc0_context(cpu_env, arg);
4843 // gen_helper_mtc0_contextconfig(cpu_env, arg); /* SmartMIPS ASE */
4844 rn = "ContextConfig";
4853 gen_helper_mtc0_pagemask(cpu_env, arg);
4857 check_insn(env, ctx, ISA_MIPS32R2);
4858 gen_helper_mtc0_pagegrain(cpu_env, arg);
4868 gen_helper_mtc0_wired(cpu_env, arg);
4872 check_insn(env, ctx, ISA_MIPS32R2);
4873 gen_helper_mtc0_srsconf0(cpu_env, arg);
4877 check_insn(env, ctx, ISA_MIPS32R2);
4878 gen_helper_mtc0_srsconf1(cpu_env, arg);
4882 check_insn(env, ctx, ISA_MIPS32R2);
4883 gen_helper_mtc0_srsconf2(cpu_env, arg);
4887 check_insn(env, ctx, ISA_MIPS32R2);
4888 gen_helper_mtc0_srsconf3(cpu_env, arg);
4892 check_insn(env, ctx, ISA_MIPS32R2);
4893 gen_helper_mtc0_srsconf4(cpu_env, arg);
4903 check_insn(env, ctx, ISA_MIPS32R2);
4904 gen_helper_mtc0_hwrena(cpu_env, arg);
4918 gen_helper_mtc0_count(cpu_env, arg);
4921 /* 6,7 are implementation dependent */
4929 gen_helper_mtc0_entryhi(cpu_env, arg);
4939 gen_helper_mtc0_compare(cpu_env, arg);
4942 /* 6,7 are implementation dependent */
4950 save_cpu_state(ctx, 1);
4951 gen_helper_mtc0_status(cpu_env, arg);
4952 /* BS_STOP isn't good enough here, hflags may have changed. */
4953 gen_save_pc(ctx->pc + 4);
4954 ctx->bstate = BS_EXCP;
4958 check_insn(env, ctx, ISA_MIPS32R2);
4959 gen_helper_mtc0_intctl(cpu_env, arg);
4960 /* Stop translation as we may have switched the execution mode */
4961 ctx->bstate = BS_STOP;
4965 check_insn(env, ctx, ISA_MIPS32R2);
4966 gen_helper_mtc0_srsctl(cpu_env, arg);
4967 /* Stop translation as we may have switched the execution mode */
4968 ctx->bstate = BS_STOP;
4972 check_insn(env, ctx, ISA_MIPS32R2);
4973 gen_mtc0_store32(arg, offsetof(CPUMIPSState, CP0_SRSMap));
4974 /* Stop translation as we may have switched the execution mode */
4975 ctx->bstate = BS_STOP;
4985 save_cpu_state(ctx, 1);
4986 gen_helper_mtc0_cause(cpu_env, arg);
4996 gen_mtc0_store64(arg, offsetof(CPUMIPSState, CP0_EPC));
5010 check_insn(env, ctx, ISA_MIPS32R2);
5011 gen_helper_mtc0_ebase(cpu_env, arg);
5021 gen_helper_mtc0_config0(cpu_env, arg);
5023 /* Stop translation as we may have switched the execution mode */
5024 ctx->bstate = BS_STOP;
5027 /* ignored, read only */
5031 gen_helper_mtc0_config2(cpu_env, arg);
5033 /* Stop translation as we may have switched the execution mode */
5034 ctx->bstate = BS_STOP;
5037 /* ignored, read only */
5040 /* 4,5 are reserved */
5041 /* 6,7 are implementation dependent */
5051 rn = "Invalid config selector";
5058 gen_helper_mtc0_lladdr(cpu_env, arg);
5068 gen_helper_0e1i(mtc0_watchlo, arg, sel);
5078 gen_helper_0e1i(mtc0_watchhi, arg, sel);
5088 #if defined(TARGET_MIPS64)
5089 check_insn(env, ctx, ISA_MIPS3);
5090 gen_helper_mtc0_xcontext(cpu_env, arg);
5099 /* Officially reserved, but sel 0 is used for R1x000 framemask */
5102 gen_helper_mtc0_framemask(cpu_env, arg);
5111 rn = "Diagnostic"; /* implementation dependent */
5116 gen_helper_mtc0_debug(cpu_env, arg); /* EJTAG support */
5117 /* BS_STOP isn't good enough here, hflags may have changed. */
5118 gen_save_pc(ctx->pc + 4);
5119 ctx->bstate = BS_EXCP;
5123 // gen_helper_mtc0_tracecontrol(cpu_env, arg); /* PDtrace support */
5124 rn = "TraceControl";
5125 /* Stop translation as we may have switched the execution mode */
5126 ctx->bstate = BS_STOP;
5129 // gen_helper_mtc0_tracecontrol2(cpu_env, arg); /* PDtrace support */
5130 rn = "TraceControl2";
5131 /* Stop translation as we may have switched the execution mode */
5132 ctx->bstate = BS_STOP;
5135 /* Stop translation as we may have switched the execution mode */
5136 ctx->bstate = BS_STOP;
5137 // gen_helper_mtc0_usertracedata(cpu_env, arg); /* PDtrace support */
5138 rn = "UserTraceData";
5139 /* Stop translation as we may have switched the execution mode */
5140 ctx->bstate = BS_STOP;
5143 // gen_helper_mtc0_tracebpc(cpu_env, arg); /* PDtrace support */
5144 /* Stop translation as we may have switched the execution mode */
5145 ctx->bstate = BS_STOP;
5156 gen_mtc0_store64(arg, offsetof(CPUMIPSState, CP0_DEPC));
5166 gen_helper_mtc0_performance0(cpu_env, arg);
5167 rn = "Performance0";
5170 // gen_helper_mtc0_performance1(arg);
5171 rn = "Performance1";
5174 // gen_helper_mtc0_performance2(arg);
5175 rn = "Performance2";
5178 // gen_helper_mtc0_performance3(arg);
5179 rn = "Performance3";
5182 // gen_helper_mtc0_performance4(arg);
5183 rn = "Performance4";
5186 // gen_helper_mtc0_performance5(arg);
5187 rn = "Performance5";
5190 // gen_helper_mtc0_performance6(arg);
5191 rn = "Performance6";
5194 // gen_helper_mtc0_performance7(arg);
5195 rn = "Performance7";
5221 gen_helper_mtc0_taglo(cpu_env, arg);
5228 gen_helper_mtc0_datalo(cpu_env, arg);
5241 gen_helper_mtc0_taghi(cpu_env, arg);
5248 gen_helper_mtc0_datahi(cpu_env, arg);
5259 gen_mtc0_store64(arg, offsetof(CPUMIPSState, CP0_ErrorEPC));
5270 gen_mtc0_store32(arg, offsetof(CPUMIPSState, CP0_DESAVE));
5276 /* Stop translation as we may have switched the execution mode */
5277 ctx->bstate = BS_STOP;
5282 (void)rn; /* avoid a compiler warning */
5283 LOG_DISAS("mtc0 %s (reg %d sel %d)\n", rn, reg, sel);
5284 /* For simplicity assume that all writes can cause interrupts. */
5287 ctx->bstate = BS_STOP;
5292 LOG_DISAS("mtc0 %s (reg %d sel %d)\n", rn, reg, sel);
5293 generate_exception(ctx, EXCP_RI);
5296 #if defined(TARGET_MIPS64)
5297 static void gen_dmfc0 (CPUMIPSState *env, DisasContext *ctx, TCGv arg, int reg, int sel)
5299 const char *rn = "invalid";
5302 check_insn(env, ctx, ISA_MIPS64);
5308 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Index));
5312 check_insn(env, ctx, ASE_MT);
5313 gen_helper_mfc0_mvpcontrol(arg, cpu_env);
5317 check_insn(env, ctx, ASE_MT);
5318 gen_helper_mfc0_mvpconf0(arg, cpu_env);
5322 check_insn(env, ctx, ASE_MT);
5323 gen_helper_mfc0_mvpconf1(arg, cpu_env);
5333 gen_helper_mfc0_random(arg, cpu_env);
5337 check_insn(env, ctx, ASE_MT);
5338 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEControl));
5342 check_insn(env, ctx, ASE_MT);
5343 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEConf0));
5347 check_insn(env, ctx, ASE_MT);
5348 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEConf1));
5352 check_insn(env, ctx, ASE_MT);
5353 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_YQMask));
5357 check_insn(env, ctx, ASE_MT);
5358 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_VPESchedule));
5362 check_insn(env, ctx, ASE_MT);
5363 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_VPEScheFBack));
5364 rn = "VPEScheFBack";
5367 check_insn(env, ctx, ASE_MT);
5368 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEOpt));
5378 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EntryLo0));
5382 check_insn(env, ctx, ASE_MT);
5383 gen_helper_mfc0_tcstatus(arg, cpu_env);
5387 check_insn(env, ctx, ASE_MT);
5388 gen_helper_mfc0_tcbind(arg, cpu_env);
5392 check_insn(env, ctx, ASE_MT);
5393 gen_helper_dmfc0_tcrestart(arg, cpu_env);
5397 check_insn(env, ctx, ASE_MT);
5398 gen_helper_dmfc0_tchalt(arg, cpu_env);
5402 check_insn(env, ctx, ASE_MT);
5403 gen_helper_dmfc0_tccontext(arg, cpu_env);
5407 check_insn(env, ctx, ASE_MT);
5408 gen_helper_dmfc0_tcschedule(arg, cpu_env);
5412 check_insn(env, ctx, ASE_MT);
5413 gen_helper_dmfc0_tcschefback(arg, cpu_env);
5423 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EntryLo1));
5433 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_Context));
5437 // gen_helper_dmfc0_contextconfig(arg); /* SmartMIPS ASE */
5438 rn = "ContextConfig";
5447 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PageMask));
5451 check_insn(env, ctx, ISA_MIPS32R2);
5452 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PageGrain));
5462 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Wired));
5466 check_insn(env, ctx, ISA_MIPS32R2);
5467 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf0));
5471 check_insn(env, ctx, ISA_MIPS32R2);
5472 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf1));
5476 check_insn(env, ctx, ISA_MIPS32R2);
5477 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf2));
5481 check_insn(env, ctx, ISA_MIPS32R2);
5482 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf3));
5486 check_insn(env, ctx, ISA_MIPS32R2);
5487 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf4));
5497 check_insn(env, ctx, ISA_MIPS32R2);
5498 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_HWREna));
5508 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_BadVAddr));
5518 /* Mark as an IO operation because we read the time. */
5521 gen_helper_mfc0_count(arg, cpu_env);
5525 /* Break the TB to be able to take timer interrupts immediately
5526 after reading count. */
5527 ctx->bstate = BS_STOP;
5530 /* 6,7 are implementation dependent */
5538 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EntryHi));
5548 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Compare));
5551 /* 6,7 are implementation dependent */
5559 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Status));
5563 check_insn(env, ctx, ISA_MIPS32R2);
5564 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_IntCtl));
5568 check_insn(env, ctx, ISA_MIPS32R2);
5569 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSCtl));
5573 check_insn(env, ctx, ISA_MIPS32R2);
5574 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSMap));
5584 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Cause));
5594 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EPC));
5604 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PRid));
5608 check_insn(env, ctx, ISA_MIPS32R2);
5609 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_EBase));
5619 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config0));
5623 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config1));
5627 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config2));
5631 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config3));
5634 /* 6,7 are implementation dependent */
5636 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config6));
5640 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config7));
5650 gen_helper_dmfc0_lladdr(arg, cpu_env);
5660 gen_helper_1e0i(dmfc0_watchlo, arg, sel);
5670 gen_helper_1e0i(mfc0_watchhi, arg, sel);
5680 check_insn(env, ctx, ISA_MIPS3);
5681 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_XContext));
5689 /* Officially reserved, but sel 0 is used for R1x000 framemask */
5692 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Framemask));
5700 tcg_gen_movi_tl(arg, 0); /* unimplemented */
5701 rn = "'Diagnostic"; /* implementation dependent */
5706 gen_helper_mfc0_debug(arg, cpu_env); /* EJTAG support */
5710 // gen_helper_dmfc0_tracecontrol(arg, cpu_env); /* PDtrace support */
5711 rn = "TraceControl";
5714 // gen_helper_dmfc0_tracecontrol2(arg, cpu_env); /* PDtrace support */
5715 rn = "TraceControl2";
5718 // gen_helper_dmfc0_usertracedata(arg, cpu_env); /* PDtrace support */
5719 rn = "UserTraceData";
5722 // gen_helper_dmfc0_tracebpc(arg, cpu_env); /* PDtrace support */
5733 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_DEPC));
5743 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Performance0));
5744 rn = "Performance0";
5747 // gen_helper_dmfc0_performance1(arg);
5748 rn = "Performance1";
5751 // gen_helper_dmfc0_performance2(arg);
5752 rn = "Performance2";
5755 // gen_helper_dmfc0_performance3(arg);
5756 rn = "Performance3";
5759 // gen_helper_dmfc0_performance4(arg);
5760 rn = "Performance4";
5763 // gen_helper_dmfc0_performance5(arg);
5764 rn = "Performance5";
5767 // gen_helper_dmfc0_performance6(arg);
5768 rn = "Performance6";
5771 // gen_helper_dmfc0_performance7(arg);
5772 rn = "Performance7";
5779 tcg_gen_movi_tl(arg, 0); /* unimplemented */
5786 tcg_gen_movi_tl(arg, 0); /* unimplemented */
5799 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_TagLo));
5806 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DataLo));
5819 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_TagHi));
5826 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DataHi));
5836 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_ErrorEPC));
5847 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DESAVE));
5857 (void)rn; /* avoid a compiler warning */
5858 LOG_DISAS("dmfc0 %s (reg %d sel %d)\n", rn, reg, sel);
5862 LOG_DISAS("dmfc0 %s (reg %d sel %d)\n", rn, reg, sel);
5863 generate_exception(ctx, EXCP_RI);
5866 static void gen_dmtc0 (CPUMIPSState *env, DisasContext *ctx, TCGv arg, int reg, int sel)
5868 const char *rn = "invalid";
5871 check_insn(env, ctx, ISA_MIPS64);
5880 gen_helper_mtc0_index(cpu_env, arg);
5884 check_insn(env, ctx, ASE_MT);
5885 gen_helper_mtc0_mvpcontrol(cpu_env, arg);
5889 check_insn(env, ctx, ASE_MT);
5894 check_insn(env, ctx, ASE_MT);
5909 check_insn(env, ctx, ASE_MT);
5910 gen_helper_mtc0_vpecontrol(cpu_env, arg);
5914 check_insn(env, ctx, ASE_MT);
5915 gen_helper_mtc0_vpeconf0(cpu_env, arg);
5919 check_insn(env, ctx, ASE_MT);
5920 gen_helper_mtc0_vpeconf1(cpu_env, arg);
5924 check_insn(env, ctx, ASE_MT);
5925 gen_helper_mtc0_yqmask(cpu_env, arg);
5929 check_insn(env, ctx, ASE_MT);
5930 tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_VPESchedule));
5934 check_insn(env, ctx, ASE_MT);
5935 tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_VPEScheFBack));
5936 rn = "VPEScheFBack";
5939 check_insn(env, ctx, ASE_MT);
5940 gen_helper_mtc0_vpeopt(cpu_env, arg);
5950 gen_helper_mtc0_entrylo0(cpu_env, arg);
5954 check_insn(env, ctx, ASE_MT);
5955 gen_helper_mtc0_tcstatus(cpu_env, arg);
5959 check_insn(env, ctx, ASE_MT);
5960 gen_helper_mtc0_tcbind(cpu_env, arg);
5964 check_insn(env, ctx, ASE_MT);
5965 gen_helper_mtc0_tcrestart(cpu_env, arg);
5969 check_insn(env, ctx, ASE_MT);
5970 gen_helper_mtc0_tchalt(cpu_env, arg);
5974 check_insn(env, ctx, ASE_MT);
5975 gen_helper_mtc0_tccontext(cpu_env, arg);
5979 check_insn(env, ctx, ASE_MT);
5980 gen_helper_mtc0_tcschedule(cpu_env, arg);
5984 check_insn(env, ctx, ASE_MT);
5985 gen_helper_mtc0_tcschefback(cpu_env, arg);
5995 gen_helper_mtc0_entrylo1(cpu_env, arg);
6005 gen_helper_mtc0_context(cpu_env, arg);
6009 // gen_helper_mtc0_contextconfig(cpu_env, arg); /* SmartMIPS ASE */
6010 rn = "ContextConfig";
6019 gen_helper_mtc0_pagemask(cpu_env, arg);
6023 check_insn(env, ctx, ISA_MIPS32R2);
6024 gen_helper_mtc0_pagegrain(cpu_env, arg);
6034 gen_helper_mtc0_wired(cpu_env, arg);
6038 check_insn(env, ctx, ISA_MIPS32R2);
6039 gen_helper_mtc0_srsconf0(cpu_env, arg);
6043 check_insn(env, ctx, ISA_MIPS32R2);
6044 gen_helper_mtc0_srsconf1(cpu_env, arg);
6048 check_insn(env, ctx, ISA_MIPS32R2);
6049 gen_helper_mtc0_srsconf2(cpu_env, arg);
6053 check_insn(env, ctx, ISA_MIPS32R2);
6054 gen_helper_mtc0_srsconf3(cpu_env, arg);
6058 check_insn(env, ctx, ISA_MIPS32R2);
6059 gen_helper_mtc0_srsconf4(cpu_env, arg);
6069 check_insn(env, ctx, ISA_MIPS32R2);
6070 gen_helper_mtc0_hwrena(cpu_env, arg);
6084 gen_helper_mtc0_count(cpu_env, arg);
6087 /* 6,7 are implementation dependent */
6091 /* Stop translation as we may have switched the execution mode */
6092 ctx->bstate = BS_STOP;
6097 gen_helper_mtc0_entryhi(cpu_env, arg);
6107 gen_helper_mtc0_compare(cpu_env, arg);
6110 /* 6,7 are implementation dependent */
6114 /* Stop translation as we may have switched the execution mode */
6115 ctx->bstate = BS_STOP;
6120 save_cpu_state(ctx, 1);
6121 gen_helper_mtc0_status(cpu_env, arg);
6122 /* BS_STOP isn't good enough here, hflags may have changed. */
6123 gen_save_pc(ctx->pc + 4);
6124 ctx->bstate = BS_EXCP;
6128 check_insn(env, ctx, ISA_MIPS32R2);
6129 gen_helper_mtc0_intctl(cpu_env, arg);
6130 /* Stop translation as we may have switched the execution mode */
6131 ctx->bstate = BS_STOP;
6135 check_insn(env, ctx, ISA_MIPS32R2);
6136 gen_helper_mtc0_srsctl(cpu_env, arg);
6137 /* Stop translation as we may have switched the execution mode */
6138 ctx->bstate = BS_STOP;
6142 check_insn(env, ctx, ISA_MIPS32R2);
6143 gen_mtc0_store32(arg, offsetof(CPUMIPSState, CP0_SRSMap));
6144 /* Stop translation as we may have switched the execution mode */
6145 ctx->bstate = BS_STOP;
6155 save_cpu_state(ctx, 1);
6156 /* Mark as an IO operation because we may trigger a software
6161 gen_helper_mtc0_cause(cpu_env, arg);
6165 /* Stop translation as we may have triggered an intetrupt */
6166 ctx->bstate = BS_STOP;
6176 tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EPC));
6190 check_insn(env, ctx, ISA_MIPS32R2);
6191 gen_helper_mtc0_ebase(cpu_env, arg);
6201 gen_helper_mtc0_config0(cpu_env, arg);
6203 /* Stop translation as we may have switched the execution mode */
6204 ctx->bstate = BS_STOP;
6207 /* ignored, read only */
6211 gen_helper_mtc0_config2(cpu_env, arg);
6213 /* Stop translation as we may have switched the execution mode */
6214 ctx->bstate = BS_STOP;
6220 /* 6,7 are implementation dependent */
6222 rn = "Invalid config selector";
6229 gen_helper_mtc0_lladdr(cpu_env, arg);
6239 gen_helper_0e1i(mtc0_watchlo, arg, sel);
6249 gen_helper_0e1i(mtc0_watchhi, arg, sel);
6259 check_insn(env, ctx, ISA_MIPS3);
6260 gen_helper_mtc0_xcontext(cpu_env, arg);
6268 /* Officially reserved, but sel 0 is used for R1x000 framemask */
6271 gen_helper_mtc0_framemask(cpu_env, arg);
6280 rn = "Diagnostic"; /* implementation dependent */
6285 gen_helper_mtc0_debug(cpu_env, arg); /* EJTAG support */
6286 /* BS_STOP isn't good enough here, hflags may have changed. */
6287 gen_save_pc(ctx->pc + 4);
6288 ctx->bstate = BS_EXCP;
6292 // gen_helper_mtc0_tracecontrol(cpu_env, arg); /* PDtrace support */
6293 /* Stop translation as we may have switched the execution mode */
6294 ctx->bstate = BS_STOP;
6295 rn = "TraceControl";
6298 // gen_helper_mtc0_tracecontrol2(cpu_env, arg); /* PDtrace support */
6299 /* Stop translation as we may have switched the execution mode */
6300 ctx->bstate = BS_STOP;
6301 rn = "TraceControl2";
6304 // gen_helper_mtc0_usertracedata(cpu_env, arg); /* PDtrace support */
6305 /* Stop translation as we may have switched the execution mode */
6306 ctx->bstate = BS_STOP;
6307 rn = "UserTraceData";
6310 // gen_helper_mtc0_tracebpc(cpu_env, arg); /* PDtrace support */
6311 /* Stop translation as we may have switched the execution mode */
6312 ctx->bstate = BS_STOP;
6323 tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_DEPC));
6333 gen_helper_mtc0_performance0(cpu_env, arg);
6334 rn = "Performance0";
6337 // gen_helper_mtc0_performance1(cpu_env, arg);
6338 rn = "Performance1";
6341 // gen_helper_mtc0_performance2(cpu_env, arg);
6342 rn = "Performance2";
6345 // gen_helper_mtc0_performance3(cpu_env, arg);
6346 rn = "Performance3";
6349 // gen_helper_mtc0_performance4(cpu_env, arg);
6350 rn = "Performance4";
6353 // gen_helper_mtc0_performance5(cpu_env, arg);
6354 rn = "Performance5";
6357 // gen_helper_mtc0_performance6(cpu_env, arg);
6358 rn = "Performance6";
6361 // gen_helper_mtc0_performance7(cpu_env, arg);
6362 rn = "Performance7";
6388 gen_helper_mtc0_taglo(cpu_env, arg);
6395 gen_helper_mtc0_datalo(cpu_env, arg);
6408 gen_helper_mtc0_taghi(cpu_env, arg);
6415 gen_helper_mtc0_datahi(cpu_env, arg);
6426 tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_ErrorEPC));
6437 gen_mtc0_store32(arg, offsetof(CPUMIPSState, CP0_DESAVE));
6443 /* Stop translation as we may have switched the execution mode */
6444 ctx->bstate = BS_STOP;
6449 (void)rn; /* avoid a compiler warning */
6450 LOG_DISAS("dmtc0 %s (reg %d sel %d)\n", rn, reg, sel);
6451 /* For simplicity assume that all writes can cause interrupts. */
6454 ctx->bstate = BS_STOP;
6459 LOG_DISAS("dmtc0 %s (reg %d sel %d)\n", rn, reg, sel);
6460 generate_exception(ctx, EXCP_RI);
6462 #endif /* TARGET_MIPS64 */
6464 static void gen_mftr(CPUMIPSState *env, DisasContext *ctx, int rt, int rd,
6465 int u, int sel, int h)
6467 int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
6468 TCGv t0 = tcg_temp_local_new();
6470 if ((env->CP0_VPEConf0 & (1 << CP0VPEC0_MVP)) == 0 &&
6471 ((env->tcs[other_tc].CP0_TCBind & (0xf << CP0TCBd_CurVPE)) !=
6472 (env->active_tc.CP0_TCBind & (0xf << CP0TCBd_CurVPE))))
6473 tcg_gen_movi_tl(t0, -1);
6474 else if ((env->CP0_VPEControl & (0xff << CP0VPECo_TargTC)) >
6475 (env->mvp->CP0_MVPConf0 & (0xff << CP0MVPC0_PTC)))
6476 tcg_gen_movi_tl(t0, -1);
6482 gen_helper_mftc0_vpecontrol(t0, cpu_env);
6485 gen_helper_mftc0_vpeconf0(t0, cpu_env);
6495 gen_helper_mftc0_tcstatus(t0, cpu_env);
6498 gen_helper_mftc0_tcbind(t0, cpu_env);
6501 gen_helper_mftc0_tcrestart(t0, cpu_env);
6504 gen_helper_mftc0_tchalt(t0, cpu_env);
6507 gen_helper_mftc0_tccontext(t0, cpu_env);
6510 gen_helper_mftc0_tcschedule(t0, cpu_env);
6513 gen_helper_mftc0_tcschefback(t0, cpu_env);
6516 gen_mfc0(env, ctx, t0, rt, sel);
6523 gen_helper_mftc0_entryhi(t0, cpu_env);
6526 gen_mfc0(env, ctx, t0, rt, sel);
6532 gen_helper_mftc0_status(t0, cpu_env);
6535 gen_mfc0(env, ctx, t0, rt, sel);
6541 gen_helper_mftc0_cause(t0, cpu_env);
6551 gen_helper_mftc0_epc(t0, cpu_env);
6561 gen_helper_mftc0_ebase(t0, cpu_env);
6571 gen_helper_mftc0_configx(t0, cpu_env, tcg_const_tl(sel));
6581 gen_helper_mftc0_debug(t0, cpu_env);
6584 gen_mfc0(env, ctx, t0, rt, sel);
6589 gen_mfc0(env, ctx, t0, rt, sel);
6591 } else switch (sel) {
6592 /* GPR registers. */
6594 gen_helper_1e0i(mftgpr, t0, rt);
6596 /* Auxiliary CPU registers */
6600 gen_helper_1e0i(mftlo, t0, 0);
6603 gen_helper_1e0i(mfthi, t0, 0);
6606 gen_helper_1e0i(mftacx, t0, 0);
6609 gen_helper_1e0i(mftlo, t0, 1);
6612 gen_helper_1e0i(mfthi, t0, 1);
6615 gen_helper_1e0i(mftacx, t0, 1);
6618 gen_helper_1e0i(mftlo, t0, 2);
6621 gen_helper_1e0i(mfthi, t0, 2);
6624 gen_helper_1e0i(mftacx, t0, 2);
6627 gen_helper_1e0i(mftlo, t0, 3);
6630 gen_helper_1e0i(mfthi, t0, 3);
6633 gen_helper_1e0i(mftacx, t0, 3);
6636 gen_helper_mftdsp(t0, cpu_env);
6642 /* Floating point (COP1). */
6644 /* XXX: For now we support only a single FPU context. */
6646 TCGv_i32 fp0 = tcg_temp_new_i32();
6648 gen_load_fpr32(fp0, rt);
6649 tcg_gen_ext_i32_tl(t0, fp0);
6650 tcg_temp_free_i32(fp0);
6652 TCGv_i32 fp0 = tcg_temp_new_i32();
6654 gen_load_fpr32h(fp0, rt);
6655 tcg_gen_ext_i32_tl(t0, fp0);
6656 tcg_temp_free_i32(fp0);
6660 /* XXX: For now we support only a single FPU context. */
6661 gen_helper_1e0i(cfc1, t0, rt);
6663 /* COP2: Not implemented. */
6670 LOG_DISAS("mftr (reg %d u %d sel %d h %d)\n", rt, u, sel, h);
6671 gen_store_gpr(t0, rd);
6677 LOG_DISAS("mftr (reg %d u %d sel %d h %d)\n", rt, u, sel, h);
6678 generate_exception(ctx, EXCP_RI);
6681 static void gen_mttr(CPUMIPSState *env, DisasContext *ctx, int rd, int rt,
6682 int u, int sel, int h)
6684 int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
6685 TCGv t0 = tcg_temp_local_new();
6687 gen_load_gpr(t0, rt);
6688 if ((env->CP0_VPEConf0 & (1 << CP0VPEC0_MVP)) == 0 &&
6689 ((env->tcs[other_tc].CP0_TCBind & (0xf << CP0TCBd_CurVPE)) !=
6690 (env->active_tc.CP0_TCBind & (0xf << CP0TCBd_CurVPE))))
6692 else if ((env->CP0_VPEControl & (0xff << CP0VPECo_TargTC)) >
6693 (env->mvp->CP0_MVPConf0 & (0xff << CP0MVPC0_PTC)))
6700 gen_helper_mttc0_vpecontrol(cpu_env, t0);
6703 gen_helper_mttc0_vpeconf0(cpu_env, t0);
6713 gen_helper_mttc0_tcstatus(cpu_env, t0);
6716 gen_helper_mttc0_tcbind(cpu_env, t0);
6719 gen_helper_mttc0_tcrestart(cpu_env, t0);
6722 gen_helper_mttc0_tchalt(cpu_env, t0);
6725 gen_helper_mttc0_tccontext(cpu_env, t0);
6728 gen_helper_mttc0_tcschedule(cpu_env, t0);
6731 gen_helper_mttc0_tcschefback(cpu_env, t0);
6734 gen_mtc0(env, ctx, t0, rd, sel);
6741 gen_helper_mttc0_entryhi(cpu_env, t0);
6744 gen_mtc0(env, ctx, t0, rd, sel);
6750 gen_helper_mttc0_status(cpu_env, t0);
6753 gen_mtc0(env, ctx, t0, rd, sel);
6759 gen_helper_mttc0_cause(cpu_env, t0);
6769 gen_helper_mttc0_ebase(cpu_env, t0);
6779 gen_helper_mttc0_debug(cpu_env, t0);
6782 gen_mtc0(env, ctx, t0, rd, sel);
6787 gen_mtc0(env, ctx, t0, rd, sel);
6789 } else switch (sel) {
6790 /* GPR registers. */
6792 gen_helper_0e1i(mttgpr, t0, rd);
6794 /* Auxiliary CPU registers */
6798 gen_helper_0e1i(mttlo, t0, 0);
6801 gen_helper_0e1i(mtthi, t0, 0);
6804 gen_helper_0e1i(mttacx, t0, 0);
6807 gen_helper_0e1i(mttlo, t0, 1);
6810 gen_helper_0e1i(mtthi, t0, 1);
6813 gen_helper_0e1i(mttacx, t0, 1);
6816 gen_helper_0e1i(mttlo, t0, 2);
6819 gen_helper_0e1i(mtthi, t0, 2);
6822 gen_helper_0e1i(mttacx, t0, 2);
6825 gen_helper_0e1i(mttlo, t0, 3);
6828 gen_helper_0e1i(mtthi, t0, 3);
6831 gen_helper_0e1i(mttacx, t0, 3);
6834 gen_helper_mttdsp(cpu_env, t0);
6840 /* Floating point (COP1). */
6842 /* XXX: For now we support only a single FPU context. */
6844 TCGv_i32 fp0 = tcg_temp_new_i32();
6846 tcg_gen_trunc_tl_i32(fp0, t0);
6847 gen_store_fpr32(fp0, rd);
6848 tcg_temp_free_i32(fp0);
6850 TCGv_i32 fp0 = tcg_temp_new_i32();
6852 tcg_gen_trunc_tl_i32(fp0, t0);
6853 gen_store_fpr32h(fp0, rd);
6854 tcg_temp_free_i32(fp0);
6858 /* XXX: For now we support only a single FPU context. */
6859 gen_helper_0e1i(ctc1, t0, rd);
6861 /* COP2: Not implemented. */
6868 LOG_DISAS("mttr (reg %d u %d sel %d h %d)\n", rd, u, sel, h);
6874 LOG_DISAS("mttr (reg %d u %d sel %d h %d)\n", rd, u, sel, h);
6875 generate_exception(ctx, EXCP_RI);
6878 static void gen_cp0 (CPUMIPSState *env, DisasContext *ctx, uint32_t opc, int rt, int rd)
6880 const char *opn = "ldst";
6882 check_cp0_enabled(ctx);
6889 gen_mfc0(env, ctx, cpu_gpr[rt], rd, ctx->opcode & 0x7);
6894 TCGv t0 = tcg_temp_new();
6896 gen_load_gpr(t0, rt);
6897 gen_mtc0(env, ctx, t0, rd, ctx->opcode & 0x7);
6902 #if defined(TARGET_MIPS64)
6904 check_insn(env, ctx, ISA_MIPS3);
6909 gen_dmfc0(env, ctx, cpu_gpr[rt], rd, ctx->opcode & 0x7);
6913 check_insn(env, ctx, ISA_MIPS3);
6915 TCGv t0 = tcg_temp_new();
6917 gen_load_gpr(t0, rt);
6918 gen_dmtc0(env, ctx, t0, rd, ctx->opcode & 0x7);
6925 check_insn(env, ctx, ASE_MT);
6930 gen_mftr(env, ctx, rt, rd, (ctx->opcode >> 5) & 1,
6931 ctx->opcode & 0x7, (ctx->opcode >> 4) & 1);
6935 check_insn(env, ctx, ASE_MT);
6936 gen_mttr(env, ctx, rd, rt, (ctx->opcode >> 5) & 1,
6937 ctx->opcode & 0x7, (ctx->opcode >> 4) & 1);
6942 if (!env->tlb->helper_tlbwi)
6944 gen_helper_tlbwi(cpu_env);
6948 if (!env->tlb->helper_tlbwr)
6950 gen_helper_tlbwr(cpu_env);
6954 if (!env->tlb->helper_tlbp)
6956 gen_helper_tlbp(cpu_env);
6960 if (!env->tlb->helper_tlbr)
6962 gen_helper_tlbr(cpu_env);
6966 check_insn(env, ctx, ISA_MIPS2);
6967 gen_helper_eret(cpu_env);
6968 ctx->bstate = BS_EXCP;
6972 check_insn(env, ctx, ISA_MIPS32);
6973 if (!(ctx->hflags & MIPS_HFLAG_DM)) {
6975 generate_exception(ctx, EXCP_RI);
6977 gen_helper_deret(cpu_env);
6978 ctx->bstate = BS_EXCP;
6983 check_insn(env, ctx, ISA_MIPS3 | ISA_MIPS32);
6984 /* If we get an exception, we want to restart at next instruction */
6986 save_cpu_state(ctx, 1);
6988 gen_helper_wait(cpu_env);
6989 ctx->bstate = BS_EXCP;
6994 generate_exception(ctx, EXCP_RI);
6997 (void)opn; /* avoid a compiler warning */
6998 MIPS_DEBUG("%s %s %d", opn, regnames[rt], rd);
7000 #endif /* !CONFIG_USER_ONLY */
7002 /* CP1 Branches (before delay slot) */
7003 static void gen_compute_branch1 (CPUMIPSState *env, DisasContext *ctx, uint32_t op,
7004 int32_t cc, int32_t offset)
7006 target_ulong btarget;
7007 const char *opn = "cp1 cond branch";
7008 TCGv_i32 t0 = tcg_temp_new_i32();
7011 check_insn(env, ctx, ISA_MIPS4 | ISA_MIPS32);
7013 btarget = ctx->pc + 4 + offset;
7017 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
7018 tcg_gen_not_i32(t0, t0);
7019 tcg_gen_andi_i32(t0, t0, 1);
7020 tcg_gen_extu_i32_tl(bcond, t0);
7024 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
7025 tcg_gen_not_i32(t0, t0);
7026 tcg_gen_andi_i32(t0, t0, 1);
7027 tcg_gen_extu_i32_tl(bcond, t0);
7031 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
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_andi_i32(t0, t0, 1);
7039 tcg_gen_extu_i32_tl(bcond, t0);
7042 ctx->hflags |= MIPS_HFLAG_BL;
7046 TCGv_i32 t1 = tcg_temp_new_i32();
7047 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
7048 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+1));
7049 tcg_gen_nand_i32(t0, t0, t1);
7050 tcg_temp_free_i32(t1);
7051 tcg_gen_andi_i32(t0, t0, 1);
7052 tcg_gen_extu_i32_tl(bcond, t0);
7058 TCGv_i32 t1 = tcg_temp_new_i32();
7059 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
7060 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+1));
7061 tcg_gen_or_i32(t0, t0, t1);
7062 tcg_temp_free_i32(t1);
7063 tcg_gen_andi_i32(t0, t0, 1);
7064 tcg_gen_extu_i32_tl(bcond, t0);
7070 TCGv_i32 t1 = tcg_temp_new_i32();
7071 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
7072 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+1));
7073 tcg_gen_and_i32(t0, t0, t1);
7074 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+2));
7075 tcg_gen_and_i32(t0, t0, t1);
7076 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+3));
7077 tcg_gen_nand_i32(t0, t0, t1);
7078 tcg_temp_free_i32(t1);
7079 tcg_gen_andi_i32(t0, t0, 1);
7080 tcg_gen_extu_i32_tl(bcond, t0);
7086 TCGv_i32 t1 = tcg_temp_new_i32();
7087 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
7088 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+1));
7089 tcg_gen_or_i32(t0, t0, t1);
7090 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+2));
7091 tcg_gen_or_i32(t0, t0, t1);
7092 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+3));
7093 tcg_gen_or_i32(t0, t0, t1);
7094 tcg_temp_free_i32(t1);
7095 tcg_gen_andi_i32(t0, t0, 1);
7096 tcg_gen_extu_i32_tl(bcond, t0);
7100 ctx->hflags |= MIPS_HFLAG_BC;
7104 generate_exception (ctx, EXCP_RI);
7107 (void)opn; /* avoid a compiler warning */
7108 MIPS_DEBUG("%s: cond %02x target " TARGET_FMT_lx, opn,
7109 ctx->hflags, btarget);
7110 ctx->btarget = btarget;
7113 tcg_temp_free_i32(t0);
7116 /* Coprocessor 1 (FPU) */
7118 #define FOP(func, fmt) (((fmt) << 21) | (func))
7121 OPC_ADD_S = FOP(0, FMT_S),
7122 OPC_SUB_S = FOP(1, FMT_S),
7123 OPC_MUL_S = FOP(2, FMT_S),
7124 OPC_DIV_S = FOP(3, FMT_S),
7125 OPC_SQRT_S = FOP(4, FMT_S),
7126 OPC_ABS_S = FOP(5, FMT_S),
7127 OPC_MOV_S = FOP(6, FMT_S),
7128 OPC_NEG_S = FOP(7, FMT_S),
7129 OPC_ROUND_L_S = FOP(8, FMT_S),
7130 OPC_TRUNC_L_S = FOP(9, FMT_S),
7131 OPC_CEIL_L_S = FOP(10, FMT_S),
7132 OPC_FLOOR_L_S = FOP(11, FMT_S),
7133 OPC_ROUND_W_S = FOP(12, FMT_S),
7134 OPC_TRUNC_W_S = FOP(13, FMT_S),
7135 OPC_CEIL_W_S = FOP(14, FMT_S),
7136 OPC_FLOOR_W_S = FOP(15, FMT_S),
7137 OPC_MOVCF_S = FOP(17, FMT_S),
7138 OPC_MOVZ_S = FOP(18, FMT_S),
7139 OPC_MOVN_S = FOP(19, FMT_S),
7140 OPC_RECIP_S = FOP(21, FMT_S),
7141 OPC_RSQRT_S = FOP(22, FMT_S),
7142 OPC_RECIP2_S = FOP(28, FMT_S),
7143 OPC_RECIP1_S = FOP(29, FMT_S),
7144 OPC_RSQRT1_S = FOP(30, FMT_S),
7145 OPC_RSQRT2_S = FOP(31, FMT_S),
7146 OPC_CVT_D_S = FOP(33, FMT_S),
7147 OPC_CVT_W_S = FOP(36, FMT_S),
7148 OPC_CVT_L_S = FOP(37, FMT_S),
7149 OPC_CVT_PS_S = FOP(38, FMT_S),
7150 OPC_CMP_F_S = FOP (48, FMT_S),
7151 OPC_CMP_UN_S = FOP (49, FMT_S),
7152 OPC_CMP_EQ_S = FOP (50, FMT_S),
7153 OPC_CMP_UEQ_S = FOP (51, FMT_S),
7154 OPC_CMP_OLT_S = FOP (52, FMT_S),
7155 OPC_CMP_ULT_S = FOP (53, FMT_S),
7156 OPC_CMP_OLE_S = FOP (54, FMT_S),
7157 OPC_CMP_ULE_S = FOP (55, FMT_S),
7158 OPC_CMP_SF_S = FOP (56, FMT_S),
7159 OPC_CMP_NGLE_S = FOP (57, FMT_S),
7160 OPC_CMP_SEQ_S = FOP (58, FMT_S),
7161 OPC_CMP_NGL_S = FOP (59, FMT_S),
7162 OPC_CMP_LT_S = FOP (60, FMT_S),
7163 OPC_CMP_NGE_S = FOP (61, FMT_S),
7164 OPC_CMP_LE_S = FOP (62, FMT_S),
7165 OPC_CMP_NGT_S = FOP (63, FMT_S),
7167 OPC_ADD_D = FOP(0, FMT_D),
7168 OPC_SUB_D = FOP(1, FMT_D),
7169 OPC_MUL_D = FOP(2, FMT_D),
7170 OPC_DIV_D = FOP(3, FMT_D),
7171 OPC_SQRT_D = FOP(4, FMT_D),
7172 OPC_ABS_D = FOP(5, FMT_D),
7173 OPC_MOV_D = FOP(6, FMT_D),
7174 OPC_NEG_D = FOP(7, FMT_D),
7175 OPC_ROUND_L_D = FOP(8, FMT_D),
7176 OPC_TRUNC_L_D = FOP(9, FMT_D),
7177 OPC_CEIL_L_D = FOP(10, FMT_D),
7178 OPC_FLOOR_L_D = FOP(11, FMT_D),
7179 OPC_ROUND_W_D = FOP(12, FMT_D),
7180 OPC_TRUNC_W_D = FOP(13, FMT_D),
7181 OPC_CEIL_W_D = FOP(14, FMT_D),
7182 OPC_FLOOR_W_D = FOP(15, FMT_D),
7183 OPC_MOVCF_D = FOP(17, FMT_D),
7184 OPC_MOVZ_D = FOP(18, FMT_D),
7185 OPC_MOVN_D = FOP(19, FMT_D),
7186 OPC_RECIP_D = FOP(21, FMT_D),
7187 OPC_RSQRT_D = FOP(22, FMT_D),
7188 OPC_RECIP2_D = FOP(28, FMT_D),
7189 OPC_RECIP1_D = FOP(29, FMT_D),
7190 OPC_RSQRT1_D = FOP(30, FMT_D),
7191 OPC_RSQRT2_D = FOP(31, FMT_D),
7192 OPC_CVT_S_D = FOP(32, FMT_D),
7193 OPC_CVT_W_D = FOP(36, FMT_D),
7194 OPC_CVT_L_D = FOP(37, FMT_D),
7195 OPC_CMP_F_D = FOP (48, FMT_D),
7196 OPC_CMP_UN_D = FOP (49, FMT_D),
7197 OPC_CMP_EQ_D = FOP (50, FMT_D),
7198 OPC_CMP_UEQ_D = FOP (51, FMT_D),
7199 OPC_CMP_OLT_D = FOP (52, FMT_D),
7200 OPC_CMP_ULT_D = FOP (53, FMT_D),
7201 OPC_CMP_OLE_D = FOP (54, FMT_D),
7202 OPC_CMP_ULE_D = FOP (55, FMT_D),
7203 OPC_CMP_SF_D = FOP (56, FMT_D),
7204 OPC_CMP_NGLE_D = FOP (57, FMT_D),
7205 OPC_CMP_SEQ_D = FOP (58, FMT_D),
7206 OPC_CMP_NGL_D = FOP (59, FMT_D),
7207 OPC_CMP_LT_D = FOP (60, FMT_D),
7208 OPC_CMP_NGE_D = FOP (61, FMT_D),
7209 OPC_CMP_LE_D = FOP (62, FMT_D),
7210 OPC_CMP_NGT_D = FOP (63, FMT_D),
7212 OPC_CVT_S_W = FOP(32, FMT_W),
7213 OPC_CVT_D_W = FOP(33, FMT_W),
7214 OPC_CVT_S_L = FOP(32, FMT_L),
7215 OPC_CVT_D_L = FOP(33, FMT_L),
7216 OPC_CVT_PS_PW = FOP(38, FMT_W),
7218 OPC_ADD_PS = FOP(0, FMT_PS),
7219 OPC_SUB_PS = FOP(1, FMT_PS),
7220 OPC_MUL_PS = FOP(2, FMT_PS),
7221 OPC_DIV_PS = FOP(3, FMT_PS),
7222 OPC_ABS_PS = FOP(5, FMT_PS),
7223 OPC_MOV_PS = FOP(6, FMT_PS),
7224 OPC_NEG_PS = FOP(7, FMT_PS),
7225 OPC_MOVCF_PS = FOP(17, FMT_PS),
7226 OPC_MOVZ_PS = FOP(18, FMT_PS),
7227 OPC_MOVN_PS = FOP(19, FMT_PS),
7228 OPC_ADDR_PS = FOP(24, FMT_PS),
7229 OPC_MULR_PS = FOP(26, FMT_PS),
7230 OPC_RECIP2_PS = FOP(28, FMT_PS),
7231 OPC_RECIP1_PS = FOP(29, FMT_PS),
7232 OPC_RSQRT1_PS = FOP(30, FMT_PS),
7233 OPC_RSQRT2_PS = FOP(31, FMT_PS),
7235 OPC_CVT_S_PU = FOP(32, FMT_PS),
7236 OPC_CVT_PW_PS = FOP(36, FMT_PS),
7237 OPC_CVT_S_PL = FOP(40, FMT_PS),
7238 OPC_PLL_PS = FOP(44, FMT_PS),
7239 OPC_PLU_PS = FOP(45, FMT_PS),
7240 OPC_PUL_PS = FOP(46, FMT_PS),
7241 OPC_PUU_PS = FOP(47, FMT_PS),
7242 OPC_CMP_F_PS = FOP (48, FMT_PS),
7243 OPC_CMP_UN_PS = FOP (49, FMT_PS),
7244 OPC_CMP_EQ_PS = FOP (50, FMT_PS),
7245 OPC_CMP_UEQ_PS = FOP (51, FMT_PS),
7246 OPC_CMP_OLT_PS = FOP (52, FMT_PS),
7247 OPC_CMP_ULT_PS = FOP (53, FMT_PS),
7248 OPC_CMP_OLE_PS = FOP (54, FMT_PS),
7249 OPC_CMP_ULE_PS = FOP (55, FMT_PS),
7250 OPC_CMP_SF_PS = FOP (56, FMT_PS),
7251 OPC_CMP_NGLE_PS = FOP (57, FMT_PS),
7252 OPC_CMP_SEQ_PS = FOP (58, FMT_PS),
7253 OPC_CMP_NGL_PS = FOP (59, FMT_PS),
7254 OPC_CMP_LT_PS = FOP (60, FMT_PS),
7255 OPC_CMP_NGE_PS = FOP (61, FMT_PS),
7256 OPC_CMP_LE_PS = FOP (62, FMT_PS),
7257 OPC_CMP_NGT_PS = FOP (63, FMT_PS),
7260 static void gen_cp1 (DisasContext *ctx, uint32_t opc, int rt, int fs)
7262 const char *opn = "cp1 move";
7263 TCGv t0 = tcg_temp_new();
7268 TCGv_i32 fp0 = tcg_temp_new_i32();
7270 gen_load_fpr32(fp0, fs);
7271 tcg_gen_ext_i32_tl(t0, fp0);
7272 tcg_temp_free_i32(fp0);
7274 gen_store_gpr(t0, rt);
7278 gen_load_gpr(t0, rt);
7280 TCGv_i32 fp0 = tcg_temp_new_i32();
7282 tcg_gen_trunc_tl_i32(fp0, t0);
7283 gen_store_fpr32(fp0, fs);
7284 tcg_temp_free_i32(fp0);
7289 gen_helper_1e0i(cfc1, t0, fs);
7290 gen_store_gpr(t0, rt);
7294 gen_load_gpr(t0, rt);
7295 gen_helper_0e1i(ctc1, t0, fs);
7298 #if defined(TARGET_MIPS64)
7300 gen_load_fpr64(ctx, t0, fs);
7301 gen_store_gpr(t0, rt);
7305 gen_load_gpr(t0, rt);
7306 gen_store_fpr64(ctx, t0, fs);
7312 TCGv_i32 fp0 = tcg_temp_new_i32();
7314 gen_load_fpr32h(fp0, fs);
7315 tcg_gen_ext_i32_tl(t0, fp0);
7316 tcg_temp_free_i32(fp0);
7318 gen_store_gpr(t0, rt);
7322 gen_load_gpr(t0, rt);
7324 TCGv_i32 fp0 = tcg_temp_new_i32();
7326 tcg_gen_trunc_tl_i32(fp0, t0);
7327 gen_store_fpr32h(fp0, fs);
7328 tcg_temp_free_i32(fp0);
7334 generate_exception (ctx, EXCP_RI);
7337 (void)opn; /* avoid a compiler warning */
7338 MIPS_DEBUG("%s %s %s", opn, regnames[rt], fregnames[fs]);
7344 static void gen_movci (DisasContext *ctx, int rd, int rs, int cc, int tf)
7360 l1 = gen_new_label();
7361 t0 = tcg_temp_new_i32();
7362 tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc));
7363 tcg_gen_brcondi_i32(cond, t0, 0, l1);
7364 tcg_temp_free_i32(t0);
7366 tcg_gen_movi_tl(cpu_gpr[rd], 0);
7368 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
7373 static inline void gen_movcf_s (int fs, int fd, int cc, int tf)
7376 TCGv_i32 t0 = tcg_temp_new_i32();
7377 int l1 = gen_new_label();
7384 tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc));
7385 tcg_gen_brcondi_i32(cond, t0, 0, l1);
7386 gen_load_fpr32(t0, fs);
7387 gen_store_fpr32(t0, fd);
7389 tcg_temp_free_i32(t0);
7392 static inline void gen_movcf_d (DisasContext *ctx, int fs, int fd, int cc, int tf)
7395 TCGv_i32 t0 = tcg_temp_new_i32();
7397 int l1 = gen_new_label();
7404 tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc));
7405 tcg_gen_brcondi_i32(cond, t0, 0, l1);
7406 tcg_temp_free_i32(t0);
7407 fp0 = tcg_temp_new_i64();
7408 gen_load_fpr64(ctx, fp0, fs);
7409 gen_store_fpr64(ctx, fp0, fd);
7410 tcg_temp_free_i64(fp0);
7414 static inline void gen_movcf_ps (int fs, int fd, int cc, int tf)
7417 TCGv_i32 t0 = tcg_temp_new_i32();
7418 int l1 = gen_new_label();
7419 int l2 = gen_new_label();
7426 tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc));
7427 tcg_gen_brcondi_i32(cond, t0, 0, l1);
7428 gen_load_fpr32(t0, fs);
7429 gen_store_fpr32(t0, fd);
7432 tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc+1));
7433 tcg_gen_brcondi_i32(cond, t0, 0, l2);
7434 gen_load_fpr32h(t0, fs);
7435 gen_store_fpr32h(t0, fd);
7436 tcg_temp_free_i32(t0);
7441 static void gen_farith (DisasContext *ctx, enum fopcode op1,
7442 int ft, int fs, int fd, int cc)
7444 const char *opn = "farith";
7445 const char *condnames[] = {
7463 const char *condnames_abs[] = {
7481 enum { BINOP, CMPOP, OTHEROP } optype = OTHEROP;
7482 uint32_t func = ctx->opcode & 0x3f;
7487 TCGv_i32 fp0 = tcg_temp_new_i32();
7488 TCGv_i32 fp1 = tcg_temp_new_i32();
7490 gen_load_fpr32(fp0, fs);
7491 gen_load_fpr32(fp1, ft);
7492 gen_helper_float_add_s(fp0, cpu_env, fp0, fp1);
7493 tcg_temp_free_i32(fp1);
7494 gen_store_fpr32(fp0, fd);
7495 tcg_temp_free_i32(fp0);
7502 TCGv_i32 fp0 = tcg_temp_new_i32();
7503 TCGv_i32 fp1 = tcg_temp_new_i32();
7505 gen_load_fpr32(fp0, fs);
7506 gen_load_fpr32(fp1, ft);
7507 gen_helper_float_sub_s(fp0, cpu_env, fp0, fp1);
7508 tcg_temp_free_i32(fp1);
7509 gen_store_fpr32(fp0, fd);
7510 tcg_temp_free_i32(fp0);
7517 TCGv_i32 fp0 = tcg_temp_new_i32();
7518 TCGv_i32 fp1 = tcg_temp_new_i32();
7520 gen_load_fpr32(fp0, fs);
7521 gen_load_fpr32(fp1, ft);
7522 gen_helper_float_mul_s(fp0, cpu_env, fp0, fp1);
7523 tcg_temp_free_i32(fp1);
7524 gen_store_fpr32(fp0, fd);
7525 tcg_temp_free_i32(fp0);
7532 TCGv_i32 fp0 = tcg_temp_new_i32();
7533 TCGv_i32 fp1 = tcg_temp_new_i32();
7535 gen_load_fpr32(fp0, fs);
7536 gen_load_fpr32(fp1, ft);
7537 gen_helper_float_div_s(fp0, cpu_env, fp0, fp1);
7538 tcg_temp_free_i32(fp1);
7539 gen_store_fpr32(fp0, fd);
7540 tcg_temp_free_i32(fp0);
7547 TCGv_i32 fp0 = tcg_temp_new_i32();
7549 gen_load_fpr32(fp0, fs);
7550 gen_helper_float_sqrt_s(fp0, cpu_env, fp0);
7551 gen_store_fpr32(fp0, fd);
7552 tcg_temp_free_i32(fp0);
7558 TCGv_i32 fp0 = tcg_temp_new_i32();
7560 gen_load_fpr32(fp0, fs);
7561 gen_helper_float_abs_s(fp0, fp0);
7562 gen_store_fpr32(fp0, fd);
7563 tcg_temp_free_i32(fp0);
7569 TCGv_i32 fp0 = tcg_temp_new_i32();
7571 gen_load_fpr32(fp0, fs);
7572 gen_store_fpr32(fp0, fd);
7573 tcg_temp_free_i32(fp0);
7579 TCGv_i32 fp0 = tcg_temp_new_i32();
7581 gen_load_fpr32(fp0, fs);
7582 gen_helper_float_chs_s(fp0, fp0);
7583 gen_store_fpr32(fp0, fd);
7584 tcg_temp_free_i32(fp0);
7589 check_cp1_64bitmode(ctx);
7591 TCGv_i32 fp32 = tcg_temp_new_i32();
7592 TCGv_i64 fp64 = tcg_temp_new_i64();
7594 gen_load_fpr32(fp32, fs);
7595 gen_helper_float_roundl_s(fp64, cpu_env, fp32);
7596 tcg_temp_free_i32(fp32);
7597 gen_store_fpr64(ctx, fp64, fd);
7598 tcg_temp_free_i64(fp64);
7603 check_cp1_64bitmode(ctx);
7605 TCGv_i32 fp32 = tcg_temp_new_i32();
7606 TCGv_i64 fp64 = tcg_temp_new_i64();
7608 gen_load_fpr32(fp32, fs);
7609 gen_helper_float_truncl_s(fp64, cpu_env, fp32);
7610 tcg_temp_free_i32(fp32);
7611 gen_store_fpr64(ctx, fp64, fd);
7612 tcg_temp_free_i64(fp64);
7617 check_cp1_64bitmode(ctx);
7619 TCGv_i32 fp32 = tcg_temp_new_i32();
7620 TCGv_i64 fp64 = tcg_temp_new_i64();
7622 gen_load_fpr32(fp32, fs);
7623 gen_helper_float_ceill_s(fp64, cpu_env, fp32);
7624 tcg_temp_free_i32(fp32);
7625 gen_store_fpr64(ctx, fp64, fd);
7626 tcg_temp_free_i64(fp64);
7631 check_cp1_64bitmode(ctx);
7633 TCGv_i32 fp32 = tcg_temp_new_i32();
7634 TCGv_i64 fp64 = tcg_temp_new_i64();
7636 gen_load_fpr32(fp32, fs);
7637 gen_helper_float_floorl_s(fp64, cpu_env, fp32);
7638 tcg_temp_free_i32(fp32);
7639 gen_store_fpr64(ctx, fp64, fd);
7640 tcg_temp_free_i64(fp64);
7646 TCGv_i32 fp0 = tcg_temp_new_i32();
7648 gen_load_fpr32(fp0, fs);
7649 gen_helper_float_roundw_s(fp0, cpu_env, fp0);
7650 gen_store_fpr32(fp0, fd);
7651 tcg_temp_free_i32(fp0);
7657 TCGv_i32 fp0 = tcg_temp_new_i32();
7659 gen_load_fpr32(fp0, fs);
7660 gen_helper_float_truncw_s(fp0, cpu_env, fp0);
7661 gen_store_fpr32(fp0, fd);
7662 tcg_temp_free_i32(fp0);
7668 TCGv_i32 fp0 = tcg_temp_new_i32();
7670 gen_load_fpr32(fp0, fs);
7671 gen_helper_float_ceilw_s(fp0, cpu_env, fp0);
7672 gen_store_fpr32(fp0, fd);
7673 tcg_temp_free_i32(fp0);
7679 TCGv_i32 fp0 = tcg_temp_new_i32();
7681 gen_load_fpr32(fp0, fs);
7682 gen_helper_float_floorw_s(fp0, cpu_env, fp0);
7683 gen_store_fpr32(fp0, fd);
7684 tcg_temp_free_i32(fp0);
7689 gen_movcf_s(fs, fd, (ft >> 2) & 0x7, ft & 0x1);
7694 int l1 = gen_new_label();
7698 tcg_gen_brcondi_tl(TCG_COND_NE, cpu_gpr[ft], 0, l1);
7700 fp0 = tcg_temp_new_i32();
7701 gen_load_fpr32(fp0, fs);
7702 gen_store_fpr32(fp0, fd);
7703 tcg_temp_free_i32(fp0);
7710 int l1 = gen_new_label();
7714 tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_gpr[ft], 0, l1);
7715 fp0 = tcg_temp_new_i32();
7716 gen_load_fpr32(fp0, fs);
7717 gen_store_fpr32(fp0, fd);
7718 tcg_temp_free_i32(fp0);
7727 TCGv_i32 fp0 = tcg_temp_new_i32();
7729 gen_load_fpr32(fp0, fs);
7730 gen_helper_float_recip_s(fp0, cpu_env, fp0);
7731 gen_store_fpr32(fp0, fd);
7732 tcg_temp_free_i32(fp0);
7739 TCGv_i32 fp0 = tcg_temp_new_i32();
7741 gen_load_fpr32(fp0, fs);
7742 gen_helper_float_rsqrt_s(fp0, cpu_env, fp0);
7743 gen_store_fpr32(fp0, fd);
7744 tcg_temp_free_i32(fp0);
7749 check_cp1_64bitmode(ctx);
7751 TCGv_i32 fp0 = tcg_temp_new_i32();
7752 TCGv_i32 fp1 = tcg_temp_new_i32();
7754 gen_load_fpr32(fp0, fs);
7755 gen_load_fpr32(fp1, ft);
7756 gen_helper_float_recip2_s(fp0, cpu_env, fp0, fp1);
7757 tcg_temp_free_i32(fp1);
7758 gen_store_fpr32(fp0, fd);
7759 tcg_temp_free_i32(fp0);
7764 check_cp1_64bitmode(ctx);
7766 TCGv_i32 fp0 = tcg_temp_new_i32();
7768 gen_load_fpr32(fp0, fs);
7769 gen_helper_float_recip1_s(fp0, cpu_env, fp0);
7770 gen_store_fpr32(fp0, fd);
7771 tcg_temp_free_i32(fp0);
7776 check_cp1_64bitmode(ctx);
7778 TCGv_i32 fp0 = tcg_temp_new_i32();
7780 gen_load_fpr32(fp0, fs);
7781 gen_helper_float_rsqrt1_s(fp0, cpu_env, fp0);
7782 gen_store_fpr32(fp0, fd);
7783 tcg_temp_free_i32(fp0);
7788 check_cp1_64bitmode(ctx);
7790 TCGv_i32 fp0 = tcg_temp_new_i32();
7791 TCGv_i32 fp1 = tcg_temp_new_i32();
7793 gen_load_fpr32(fp0, fs);
7794 gen_load_fpr32(fp1, ft);
7795 gen_helper_float_rsqrt2_s(fp0, cpu_env, fp0, fp1);
7796 tcg_temp_free_i32(fp1);
7797 gen_store_fpr32(fp0, fd);
7798 tcg_temp_free_i32(fp0);
7803 check_cp1_registers(ctx, fd);
7805 TCGv_i32 fp32 = tcg_temp_new_i32();
7806 TCGv_i64 fp64 = tcg_temp_new_i64();
7808 gen_load_fpr32(fp32, fs);
7809 gen_helper_float_cvtd_s(fp64, cpu_env, fp32);
7810 tcg_temp_free_i32(fp32);
7811 gen_store_fpr64(ctx, fp64, fd);
7812 tcg_temp_free_i64(fp64);
7818 TCGv_i32 fp0 = tcg_temp_new_i32();
7820 gen_load_fpr32(fp0, fs);
7821 gen_helper_float_cvtw_s(fp0, cpu_env, fp0);
7822 gen_store_fpr32(fp0, fd);
7823 tcg_temp_free_i32(fp0);
7828 check_cp1_64bitmode(ctx);
7830 TCGv_i32 fp32 = tcg_temp_new_i32();
7831 TCGv_i64 fp64 = tcg_temp_new_i64();
7833 gen_load_fpr32(fp32, fs);
7834 gen_helper_float_cvtl_s(fp64, cpu_env, fp32);
7835 tcg_temp_free_i32(fp32);
7836 gen_store_fpr64(ctx, fp64, fd);
7837 tcg_temp_free_i64(fp64);
7842 check_cp1_64bitmode(ctx);
7844 TCGv_i64 fp64 = tcg_temp_new_i64();
7845 TCGv_i32 fp32_0 = tcg_temp_new_i32();
7846 TCGv_i32 fp32_1 = tcg_temp_new_i32();
7848 gen_load_fpr32(fp32_0, fs);
7849 gen_load_fpr32(fp32_1, ft);
7850 tcg_gen_concat_i32_i64(fp64, fp32_1, fp32_0);
7851 tcg_temp_free_i32(fp32_1);
7852 tcg_temp_free_i32(fp32_0);
7853 gen_store_fpr64(ctx, fp64, fd);
7854 tcg_temp_free_i64(fp64);
7867 case OPC_CMP_NGLE_S:
7874 if (ctx->opcode & (1 << 6)) {
7875 gen_cmpabs_s(ctx, func-48, ft, fs, cc);
7876 opn = condnames_abs[func-48];
7878 gen_cmp_s(ctx, func-48, ft, fs, cc);
7879 opn = condnames[func-48];
7883 check_cp1_registers(ctx, fs | ft | fd);
7885 TCGv_i64 fp0 = tcg_temp_new_i64();
7886 TCGv_i64 fp1 = tcg_temp_new_i64();
7888 gen_load_fpr64(ctx, fp0, fs);
7889 gen_load_fpr64(ctx, fp1, ft);
7890 gen_helper_float_add_d(fp0, cpu_env, fp0, fp1);
7891 tcg_temp_free_i64(fp1);
7892 gen_store_fpr64(ctx, fp0, fd);
7893 tcg_temp_free_i64(fp0);
7899 check_cp1_registers(ctx, fs | ft | fd);
7901 TCGv_i64 fp0 = tcg_temp_new_i64();
7902 TCGv_i64 fp1 = tcg_temp_new_i64();
7904 gen_load_fpr64(ctx, fp0, fs);
7905 gen_load_fpr64(ctx, fp1, ft);
7906 gen_helper_float_sub_d(fp0, cpu_env, fp0, fp1);
7907 tcg_temp_free_i64(fp1);
7908 gen_store_fpr64(ctx, fp0, fd);
7909 tcg_temp_free_i64(fp0);
7915 check_cp1_registers(ctx, fs | ft | fd);
7917 TCGv_i64 fp0 = tcg_temp_new_i64();
7918 TCGv_i64 fp1 = tcg_temp_new_i64();
7920 gen_load_fpr64(ctx, fp0, fs);
7921 gen_load_fpr64(ctx, fp1, ft);
7922 gen_helper_float_mul_d(fp0, cpu_env, fp0, fp1);
7923 tcg_temp_free_i64(fp1);
7924 gen_store_fpr64(ctx, fp0, fd);
7925 tcg_temp_free_i64(fp0);
7931 check_cp1_registers(ctx, fs | ft | fd);
7933 TCGv_i64 fp0 = tcg_temp_new_i64();
7934 TCGv_i64 fp1 = tcg_temp_new_i64();
7936 gen_load_fpr64(ctx, fp0, fs);
7937 gen_load_fpr64(ctx, fp1, ft);
7938 gen_helper_float_div_d(fp0, cpu_env, fp0, fp1);
7939 tcg_temp_free_i64(fp1);
7940 gen_store_fpr64(ctx, fp0, fd);
7941 tcg_temp_free_i64(fp0);
7947 check_cp1_registers(ctx, fs | fd);
7949 TCGv_i64 fp0 = tcg_temp_new_i64();
7951 gen_load_fpr64(ctx, fp0, fs);
7952 gen_helper_float_sqrt_d(fp0, cpu_env, fp0);
7953 gen_store_fpr64(ctx, fp0, fd);
7954 tcg_temp_free_i64(fp0);
7959 check_cp1_registers(ctx, fs | fd);
7961 TCGv_i64 fp0 = tcg_temp_new_i64();
7963 gen_load_fpr64(ctx, fp0, fs);
7964 gen_helper_float_abs_d(fp0, fp0);
7965 gen_store_fpr64(ctx, fp0, fd);
7966 tcg_temp_free_i64(fp0);
7971 check_cp1_registers(ctx, fs | fd);
7973 TCGv_i64 fp0 = tcg_temp_new_i64();
7975 gen_load_fpr64(ctx, fp0, fs);
7976 gen_store_fpr64(ctx, fp0, fd);
7977 tcg_temp_free_i64(fp0);
7982 check_cp1_registers(ctx, fs | fd);
7984 TCGv_i64 fp0 = tcg_temp_new_i64();
7986 gen_load_fpr64(ctx, fp0, fs);
7987 gen_helper_float_chs_d(fp0, fp0);
7988 gen_store_fpr64(ctx, fp0, fd);
7989 tcg_temp_free_i64(fp0);
7994 check_cp1_64bitmode(ctx);
7996 TCGv_i64 fp0 = tcg_temp_new_i64();
7998 gen_load_fpr64(ctx, fp0, fs);
7999 gen_helper_float_roundl_d(fp0, cpu_env, fp0);
8000 gen_store_fpr64(ctx, fp0, fd);
8001 tcg_temp_free_i64(fp0);
8006 check_cp1_64bitmode(ctx);
8008 TCGv_i64 fp0 = tcg_temp_new_i64();
8010 gen_load_fpr64(ctx, fp0, fs);
8011 gen_helper_float_truncl_d(fp0, cpu_env, fp0);
8012 gen_store_fpr64(ctx, fp0, fd);
8013 tcg_temp_free_i64(fp0);
8018 check_cp1_64bitmode(ctx);
8020 TCGv_i64 fp0 = tcg_temp_new_i64();
8022 gen_load_fpr64(ctx, fp0, fs);
8023 gen_helper_float_ceill_d(fp0, cpu_env, fp0);
8024 gen_store_fpr64(ctx, fp0, fd);
8025 tcg_temp_free_i64(fp0);
8030 check_cp1_64bitmode(ctx);
8032 TCGv_i64 fp0 = tcg_temp_new_i64();
8034 gen_load_fpr64(ctx, fp0, fs);
8035 gen_helper_float_floorl_d(fp0, cpu_env, fp0);
8036 gen_store_fpr64(ctx, fp0, fd);
8037 tcg_temp_free_i64(fp0);
8042 check_cp1_registers(ctx, fs);
8044 TCGv_i32 fp32 = tcg_temp_new_i32();
8045 TCGv_i64 fp64 = tcg_temp_new_i64();
8047 gen_load_fpr64(ctx, fp64, fs);
8048 gen_helper_float_roundw_d(fp32, cpu_env, fp64);
8049 tcg_temp_free_i64(fp64);
8050 gen_store_fpr32(fp32, fd);
8051 tcg_temp_free_i32(fp32);
8056 check_cp1_registers(ctx, fs);
8058 TCGv_i32 fp32 = tcg_temp_new_i32();
8059 TCGv_i64 fp64 = tcg_temp_new_i64();
8061 gen_load_fpr64(ctx, fp64, fs);
8062 gen_helper_float_truncw_d(fp32, cpu_env, fp64);
8063 tcg_temp_free_i64(fp64);
8064 gen_store_fpr32(fp32, fd);
8065 tcg_temp_free_i32(fp32);
8070 check_cp1_registers(ctx, fs);
8072 TCGv_i32 fp32 = tcg_temp_new_i32();
8073 TCGv_i64 fp64 = tcg_temp_new_i64();
8075 gen_load_fpr64(ctx, fp64, fs);
8076 gen_helper_float_ceilw_d(fp32, cpu_env, fp64);
8077 tcg_temp_free_i64(fp64);
8078 gen_store_fpr32(fp32, fd);
8079 tcg_temp_free_i32(fp32);
8084 check_cp1_registers(ctx, fs);
8086 TCGv_i32 fp32 = tcg_temp_new_i32();
8087 TCGv_i64 fp64 = tcg_temp_new_i64();
8089 gen_load_fpr64(ctx, fp64, fs);
8090 gen_helper_float_floorw_d(fp32, cpu_env, fp64);
8091 tcg_temp_free_i64(fp64);
8092 gen_store_fpr32(fp32, fd);
8093 tcg_temp_free_i32(fp32);
8098 gen_movcf_d(ctx, fs, fd, (ft >> 2) & 0x7, ft & 0x1);
8103 int l1 = gen_new_label();
8107 tcg_gen_brcondi_tl(TCG_COND_NE, cpu_gpr[ft], 0, l1);
8109 fp0 = tcg_temp_new_i64();
8110 gen_load_fpr64(ctx, fp0, fs);
8111 gen_store_fpr64(ctx, fp0, fd);
8112 tcg_temp_free_i64(fp0);
8119 int l1 = gen_new_label();
8123 tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_gpr[ft], 0, l1);
8124 fp0 = tcg_temp_new_i64();
8125 gen_load_fpr64(ctx, fp0, fs);
8126 gen_store_fpr64(ctx, fp0, fd);
8127 tcg_temp_free_i64(fp0);
8134 check_cp1_64bitmode(ctx);
8136 TCGv_i64 fp0 = tcg_temp_new_i64();
8138 gen_load_fpr64(ctx, fp0, fs);
8139 gen_helper_float_recip_d(fp0, cpu_env, fp0);
8140 gen_store_fpr64(ctx, fp0, fd);
8141 tcg_temp_free_i64(fp0);
8146 check_cp1_64bitmode(ctx);
8148 TCGv_i64 fp0 = tcg_temp_new_i64();
8150 gen_load_fpr64(ctx, fp0, fs);
8151 gen_helper_float_rsqrt_d(fp0, cpu_env, fp0);
8152 gen_store_fpr64(ctx, fp0, fd);
8153 tcg_temp_free_i64(fp0);
8158 check_cp1_64bitmode(ctx);
8160 TCGv_i64 fp0 = tcg_temp_new_i64();
8161 TCGv_i64 fp1 = tcg_temp_new_i64();
8163 gen_load_fpr64(ctx, fp0, fs);
8164 gen_load_fpr64(ctx, fp1, ft);
8165 gen_helper_float_recip2_d(fp0, cpu_env, fp0, fp1);
8166 tcg_temp_free_i64(fp1);
8167 gen_store_fpr64(ctx, fp0, fd);
8168 tcg_temp_free_i64(fp0);
8173 check_cp1_64bitmode(ctx);
8175 TCGv_i64 fp0 = tcg_temp_new_i64();
8177 gen_load_fpr64(ctx, fp0, fs);
8178 gen_helper_float_recip1_d(fp0, cpu_env, fp0);
8179 gen_store_fpr64(ctx, fp0, fd);
8180 tcg_temp_free_i64(fp0);
8185 check_cp1_64bitmode(ctx);
8187 TCGv_i64 fp0 = tcg_temp_new_i64();
8189 gen_load_fpr64(ctx, fp0, fs);
8190 gen_helper_float_rsqrt1_d(fp0, cpu_env, fp0);
8191 gen_store_fpr64(ctx, fp0, fd);
8192 tcg_temp_free_i64(fp0);
8197 check_cp1_64bitmode(ctx);
8199 TCGv_i64 fp0 = tcg_temp_new_i64();
8200 TCGv_i64 fp1 = tcg_temp_new_i64();
8202 gen_load_fpr64(ctx, fp0, fs);
8203 gen_load_fpr64(ctx, fp1, ft);
8204 gen_helper_float_rsqrt2_d(fp0, cpu_env, fp0, fp1);
8205 tcg_temp_free_i64(fp1);
8206 gen_store_fpr64(ctx, fp0, fd);
8207 tcg_temp_free_i64(fp0);
8220 case OPC_CMP_NGLE_D:
8227 if (ctx->opcode & (1 << 6)) {
8228 gen_cmpabs_d(ctx, func-48, ft, fs, cc);
8229 opn = condnames_abs[func-48];
8231 gen_cmp_d(ctx, func-48, ft, fs, cc);
8232 opn = condnames[func-48];
8236 check_cp1_registers(ctx, fs);
8238 TCGv_i32 fp32 = tcg_temp_new_i32();
8239 TCGv_i64 fp64 = tcg_temp_new_i64();
8241 gen_load_fpr64(ctx, fp64, fs);
8242 gen_helper_float_cvts_d(fp32, cpu_env, fp64);
8243 tcg_temp_free_i64(fp64);
8244 gen_store_fpr32(fp32, fd);
8245 tcg_temp_free_i32(fp32);
8250 check_cp1_registers(ctx, fs);
8252 TCGv_i32 fp32 = tcg_temp_new_i32();
8253 TCGv_i64 fp64 = tcg_temp_new_i64();
8255 gen_load_fpr64(ctx, fp64, fs);
8256 gen_helper_float_cvtw_d(fp32, cpu_env, fp64);
8257 tcg_temp_free_i64(fp64);
8258 gen_store_fpr32(fp32, fd);
8259 tcg_temp_free_i32(fp32);
8264 check_cp1_64bitmode(ctx);
8266 TCGv_i64 fp0 = tcg_temp_new_i64();
8268 gen_load_fpr64(ctx, fp0, fs);
8269 gen_helper_float_cvtl_d(fp0, cpu_env, fp0);
8270 gen_store_fpr64(ctx, fp0, fd);
8271 tcg_temp_free_i64(fp0);
8277 TCGv_i32 fp0 = tcg_temp_new_i32();
8279 gen_load_fpr32(fp0, fs);
8280 gen_helper_float_cvts_w(fp0, cpu_env, fp0);
8281 gen_store_fpr32(fp0, fd);
8282 tcg_temp_free_i32(fp0);
8287 check_cp1_registers(ctx, fd);
8289 TCGv_i32 fp32 = tcg_temp_new_i32();
8290 TCGv_i64 fp64 = tcg_temp_new_i64();
8292 gen_load_fpr32(fp32, fs);
8293 gen_helper_float_cvtd_w(fp64, cpu_env, fp32);
8294 tcg_temp_free_i32(fp32);
8295 gen_store_fpr64(ctx, fp64, fd);
8296 tcg_temp_free_i64(fp64);
8301 check_cp1_64bitmode(ctx);
8303 TCGv_i32 fp32 = tcg_temp_new_i32();
8304 TCGv_i64 fp64 = tcg_temp_new_i64();
8306 gen_load_fpr64(ctx, fp64, fs);
8307 gen_helper_float_cvts_l(fp32, cpu_env, fp64);
8308 tcg_temp_free_i64(fp64);
8309 gen_store_fpr32(fp32, fd);
8310 tcg_temp_free_i32(fp32);
8315 check_cp1_64bitmode(ctx);
8317 TCGv_i64 fp0 = tcg_temp_new_i64();
8319 gen_load_fpr64(ctx, fp0, fs);
8320 gen_helper_float_cvtd_l(fp0, cpu_env, fp0);
8321 gen_store_fpr64(ctx, fp0, fd);
8322 tcg_temp_free_i64(fp0);
8327 check_cp1_64bitmode(ctx);
8329 TCGv_i64 fp0 = tcg_temp_new_i64();
8331 gen_load_fpr64(ctx, fp0, fs);
8332 gen_helper_float_cvtps_pw(fp0, cpu_env, fp0);
8333 gen_store_fpr64(ctx, fp0, fd);
8334 tcg_temp_free_i64(fp0);
8339 check_cp1_64bitmode(ctx);
8341 TCGv_i64 fp0 = tcg_temp_new_i64();
8342 TCGv_i64 fp1 = tcg_temp_new_i64();
8344 gen_load_fpr64(ctx, fp0, fs);
8345 gen_load_fpr64(ctx, fp1, ft);
8346 gen_helper_float_add_ps(fp0, cpu_env, fp0, fp1);
8347 tcg_temp_free_i64(fp1);
8348 gen_store_fpr64(ctx, fp0, fd);
8349 tcg_temp_free_i64(fp0);
8354 check_cp1_64bitmode(ctx);
8356 TCGv_i64 fp0 = tcg_temp_new_i64();
8357 TCGv_i64 fp1 = tcg_temp_new_i64();
8359 gen_load_fpr64(ctx, fp0, fs);
8360 gen_load_fpr64(ctx, fp1, ft);
8361 gen_helper_float_sub_ps(fp0, cpu_env, fp0, fp1);
8362 tcg_temp_free_i64(fp1);
8363 gen_store_fpr64(ctx, fp0, fd);
8364 tcg_temp_free_i64(fp0);
8369 check_cp1_64bitmode(ctx);
8371 TCGv_i64 fp0 = tcg_temp_new_i64();
8372 TCGv_i64 fp1 = tcg_temp_new_i64();
8374 gen_load_fpr64(ctx, fp0, fs);
8375 gen_load_fpr64(ctx, fp1, ft);
8376 gen_helper_float_mul_ps(fp0, cpu_env, fp0, fp1);
8377 tcg_temp_free_i64(fp1);
8378 gen_store_fpr64(ctx, fp0, fd);
8379 tcg_temp_free_i64(fp0);
8384 check_cp1_64bitmode(ctx);
8386 TCGv_i64 fp0 = tcg_temp_new_i64();
8388 gen_load_fpr64(ctx, fp0, fs);
8389 gen_helper_float_abs_ps(fp0, fp0);
8390 gen_store_fpr64(ctx, fp0, fd);
8391 tcg_temp_free_i64(fp0);
8396 check_cp1_64bitmode(ctx);
8398 TCGv_i64 fp0 = tcg_temp_new_i64();
8400 gen_load_fpr64(ctx, fp0, fs);
8401 gen_store_fpr64(ctx, fp0, fd);
8402 tcg_temp_free_i64(fp0);
8407 check_cp1_64bitmode(ctx);
8409 TCGv_i64 fp0 = tcg_temp_new_i64();
8411 gen_load_fpr64(ctx, fp0, fs);
8412 gen_helper_float_chs_ps(fp0, fp0);
8413 gen_store_fpr64(ctx, fp0, fd);
8414 tcg_temp_free_i64(fp0);
8419 check_cp1_64bitmode(ctx);
8420 gen_movcf_ps(fs, fd, (ft >> 2) & 0x7, ft & 0x1);
8424 check_cp1_64bitmode(ctx);
8426 int l1 = gen_new_label();
8430 tcg_gen_brcondi_tl(TCG_COND_NE, cpu_gpr[ft], 0, l1);
8431 fp0 = tcg_temp_new_i64();
8432 gen_load_fpr64(ctx, fp0, fs);
8433 gen_store_fpr64(ctx, fp0, fd);
8434 tcg_temp_free_i64(fp0);
8440 check_cp1_64bitmode(ctx);
8442 int l1 = gen_new_label();
8446 tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_gpr[ft], 0, l1);
8447 fp0 = tcg_temp_new_i64();
8448 gen_load_fpr64(ctx, fp0, fs);
8449 gen_store_fpr64(ctx, fp0, fd);
8450 tcg_temp_free_i64(fp0);
8457 check_cp1_64bitmode(ctx);
8459 TCGv_i64 fp0 = tcg_temp_new_i64();
8460 TCGv_i64 fp1 = tcg_temp_new_i64();
8462 gen_load_fpr64(ctx, fp0, ft);
8463 gen_load_fpr64(ctx, fp1, fs);
8464 gen_helper_float_addr_ps(fp0, cpu_env, fp0, fp1);
8465 tcg_temp_free_i64(fp1);
8466 gen_store_fpr64(ctx, fp0, fd);
8467 tcg_temp_free_i64(fp0);
8472 check_cp1_64bitmode(ctx);
8474 TCGv_i64 fp0 = tcg_temp_new_i64();
8475 TCGv_i64 fp1 = tcg_temp_new_i64();
8477 gen_load_fpr64(ctx, fp0, ft);
8478 gen_load_fpr64(ctx, fp1, fs);
8479 gen_helper_float_mulr_ps(fp0, cpu_env, fp0, fp1);
8480 tcg_temp_free_i64(fp1);
8481 gen_store_fpr64(ctx, fp0, fd);
8482 tcg_temp_free_i64(fp0);
8487 check_cp1_64bitmode(ctx);
8489 TCGv_i64 fp0 = tcg_temp_new_i64();
8490 TCGv_i64 fp1 = tcg_temp_new_i64();
8492 gen_load_fpr64(ctx, fp0, fs);
8493 gen_load_fpr64(ctx, fp1, ft);
8494 gen_helper_float_recip2_ps(fp0, cpu_env, fp0, fp1);
8495 tcg_temp_free_i64(fp1);
8496 gen_store_fpr64(ctx, fp0, fd);
8497 tcg_temp_free_i64(fp0);
8502 check_cp1_64bitmode(ctx);
8504 TCGv_i64 fp0 = tcg_temp_new_i64();
8506 gen_load_fpr64(ctx, fp0, fs);
8507 gen_helper_float_recip1_ps(fp0, cpu_env, fp0);
8508 gen_store_fpr64(ctx, fp0, fd);
8509 tcg_temp_free_i64(fp0);
8514 check_cp1_64bitmode(ctx);
8516 TCGv_i64 fp0 = tcg_temp_new_i64();
8518 gen_load_fpr64(ctx, fp0, fs);
8519 gen_helper_float_rsqrt1_ps(fp0, cpu_env, fp0);
8520 gen_store_fpr64(ctx, fp0, fd);
8521 tcg_temp_free_i64(fp0);
8526 check_cp1_64bitmode(ctx);
8528 TCGv_i64 fp0 = tcg_temp_new_i64();
8529 TCGv_i64 fp1 = tcg_temp_new_i64();
8531 gen_load_fpr64(ctx, fp0, fs);
8532 gen_load_fpr64(ctx, fp1, ft);
8533 gen_helper_float_rsqrt2_ps(fp0, cpu_env, fp0, fp1);
8534 tcg_temp_free_i64(fp1);
8535 gen_store_fpr64(ctx, fp0, fd);
8536 tcg_temp_free_i64(fp0);
8541 check_cp1_64bitmode(ctx);
8543 TCGv_i32 fp0 = tcg_temp_new_i32();
8545 gen_load_fpr32h(fp0, fs);
8546 gen_helper_float_cvts_pu(fp0, cpu_env, fp0);
8547 gen_store_fpr32(fp0, fd);
8548 tcg_temp_free_i32(fp0);
8553 check_cp1_64bitmode(ctx);
8555 TCGv_i64 fp0 = tcg_temp_new_i64();
8557 gen_load_fpr64(ctx, fp0, fs);
8558 gen_helper_float_cvtpw_ps(fp0, cpu_env, fp0);
8559 gen_store_fpr64(ctx, fp0, fd);
8560 tcg_temp_free_i64(fp0);
8565 check_cp1_64bitmode(ctx);
8567 TCGv_i32 fp0 = tcg_temp_new_i32();
8569 gen_load_fpr32(fp0, fs);
8570 gen_helper_float_cvts_pl(fp0, cpu_env, fp0);
8571 gen_store_fpr32(fp0, fd);
8572 tcg_temp_free_i32(fp0);
8577 check_cp1_64bitmode(ctx);
8579 TCGv_i32 fp0 = tcg_temp_new_i32();
8580 TCGv_i32 fp1 = tcg_temp_new_i32();
8582 gen_load_fpr32(fp0, fs);
8583 gen_load_fpr32(fp1, ft);
8584 gen_store_fpr32h(fp0, fd);
8585 gen_store_fpr32(fp1, fd);
8586 tcg_temp_free_i32(fp0);
8587 tcg_temp_free_i32(fp1);
8592 check_cp1_64bitmode(ctx);
8594 TCGv_i32 fp0 = tcg_temp_new_i32();
8595 TCGv_i32 fp1 = tcg_temp_new_i32();
8597 gen_load_fpr32(fp0, fs);
8598 gen_load_fpr32h(fp1, ft);
8599 gen_store_fpr32(fp1, fd);
8600 gen_store_fpr32h(fp0, fd);
8601 tcg_temp_free_i32(fp0);
8602 tcg_temp_free_i32(fp1);
8607 check_cp1_64bitmode(ctx);
8609 TCGv_i32 fp0 = tcg_temp_new_i32();
8610 TCGv_i32 fp1 = tcg_temp_new_i32();
8612 gen_load_fpr32h(fp0, fs);
8613 gen_load_fpr32(fp1, ft);
8614 gen_store_fpr32(fp1, fd);
8615 gen_store_fpr32h(fp0, fd);
8616 tcg_temp_free_i32(fp0);
8617 tcg_temp_free_i32(fp1);
8622 check_cp1_64bitmode(ctx);
8624 TCGv_i32 fp0 = tcg_temp_new_i32();
8625 TCGv_i32 fp1 = tcg_temp_new_i32();
8627 gen_load_fpr32h(fp0, fs);
8628 gen_load_fpr32h(fp1, ft);
8629 gen_store_fpr32(fp1, fd);
8630 gen_store_fpr32h(fp0, fd);
8631 tcg_temp_free_i32(fp0);
8632 tcg_temp_free_i32(fp1);
8639 case OPC_CMP_UEQ_PS:
8640 case OPC_CMP_OLT_PS:
8641 case OPC_CMP_ULT_PS:
8642 case OPC_CMP_OLE_PS:
8643 case OPC_CMP_ULE_PS:
8645 case OPC_CMP_NGLE_PS:
8646 case OPC_CMP_SEQ_PS:
8647 case OPC_CMP_NGL_PS:
8649 case OPC_CMP_NGE_PS:
8651 case OPC_CMP_NGT_PS:
8652 if (ctx->opcode & (1 << 6)) {
8653 gen_cmpabs_ps(ctx, func-48, ft, fs, cc);
8654 opn = condnames_abs[func-48];
8656 gen_cmp_ps(ctx, func-48, ft, fs, cc);
8657 opn = condnames[func-48];
8662 generate_exception (ctx, EXCP_RI);
8665 (void)opn; /* avoid a compiler warning */
8668 MIPS_DEBUG("%s %s, %s, %s", opn, fregnames[fd], fregnames[fs], fregnames[ft]);
8671 MIPS_DEBUG("%s %s,%s", opn, fregnames[fs], fregnames[ft]);
8674 MIPS_DEBUG("%s %s,%s", opn, fregnames[fd], fregnames[fs]);
8679 /* Coprocessor 3 (FPU) */
8680 static void gen_flt3_ldst (DisasContext *ctx, uint32_t opc,
8681 int fd, int fs, int base, int index)
8683 const char *opn = "extended float load/store";
8685 TCGv t0 = tcg_temp_new();
8688 gen_load_gpr(t0, index);
8689 } else if (index == 0) {
8690 gen_load_gpr(t0, base);
8692 gen_op_addr_add(ctx, t0, cpu_gpr[base], cpu_gpr[index]);
8694 /* Don't do NOP if destination is zero: we must perform the actual
8700 TCGv_i32 fp0 = tcg_temp_new_i32();
8702 tcg_gen_qemu_ld32s(t0, t0, ctx->mem_idx);
8703 tcg_gen_trunc_tl_i32(fp0, t0);
8704 gen_store_fpr32(fp0, fd);
8705 tcg_temp_free_i32(fp0);
8711 check_cp1_registers(ctx, fd);
8713 TCGv_i64 fp0 = tcg_temp_new_i64();
8715 tcg_gen_qemu_ld64(fp0, t0, ctx->mem_idx);
8716 gen_store_fpr64(ctx, fp0, fd);
8717 tcg_temp_free_i64(fp0);
8722 check_cp1_64bitmode(ctx);
8723 tcg_gen_andi_tl(t0, t0, ~0x7);
8725 TCGv_i64 fp0 = tcg_temp_new_i64();
8727 tcg_gen_qemu_ld64(fp0, t0, ctx->mem_idx);
8728 gen_store_fpr64(ctx, fp0, fd);
8729 tcg_temp_free_i64(fp0);
8736 TCGv_i32 fp0 = tcg_temp_new_i32();
8737 TCGv t1 = tcg_temp_new();
8739 gen_load_fpr32(fp0, fs);
8740 tcg_gen_extu_i32_tl(t1, fp0);
8741 tcg_gen_qemu_st32(t1, t0, ctx->mem_idx);
8742 tcg_temp_free_i32(fp0);
8750 check_cp1_registers(ctx, fs);
8752 TCGv_i64 fp0 = tcg_temp_new_i64();
8754 gen_load_fpr64(ctx, fp0, fs);
8755 tcg_gen_qemu_st64(fp0, t0, ctx->mem_idx);
8756 tcg_temp_free_i64(fp0);
8762 check_cp1_64bitmode(ctx);
8763 tcg_gen_andi_tl(t0, t0, ~0x7);
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);
8776 (void)opn; (void)store; /* avoid compiler warnings */
8777 MIPS_DEBUG("%s %s, %s(%s)", opn, fregnames[store ? fs : fd],
8778 regnames[index], regnames[base]);
8781 static void gen_flt3_arith (DisasContext *ctx, uint32_t opc,
8782 int fd, int fr, int fs, int ft)
8784 const char *opn = "flt3_arith";
8788 check_cp1_64bitmode(ctx);
8790 TCGv t0 = tcg_temp_local_new();
8791 TCGv_i32 fp = tcg_temp_new_i32();
8792 TCGv_i32 fph = tcg_temp_new_i32();
8793 int l1 = gen_new_label();
8794 int l2 = gen_new_label();
8796 gen_load_gpr(t0, fr);
8797 tcg_gen_andi_tl(t0, t0, 0x7);
8799 tcg_gen_brcondi_tl(TCG_COND_NE, t0, 0, l1);
8800 gen_load_fpr32(fp, fs);
8801 gen_load_fpr32h(fph, fs);
8802 gen_store_fpr32(fp, fd);
8803 gen_store_fpr32h(fph, fd);
8806 tcg_gen_brcondi_tl(TCG_COND_NE, t0, 4, l2);
8808 #ifdef TARGET_WORDS_BIGENDIAN
8809 gen_load_fpr32(fp, fs);
8810 gen_load_fpr32h(fph, ft);
8811 gen_store_fpr32h(fp, fd);
8812 gen_store_fpr32(fph, fd);
8814 gen_load_fpr32h(fph, fs);
8815 gen_load_fpr32(fp, ft);
8816 gen_store_fpr32(fph, fd);
8817 gen_store_fpr32h(fp, fd);
8820 tcg_temp_free_i32(fp);
8821 tcg_temp_free_i32(fph);
8828 TCGv_i32 fp0 = tcg_temp_new_i32();
8829 TCGv_i32 fp1 = tcg_temp_new_i32();
8830 TCGv_i32 fp2 = tcg_temp_new_i32();
8832 gen_load_fpr32(fp0, fs);
8833 gen_load_fpr32(fp1, ft);
8834 gen_load_fpr32(fp2, fr);
8835 gen_helper_float_madd_s(fp2, cpu_env, fp0, fp1, fp2);
8836 tcg_temp_free_i32(fp0);
8837 tcg_temp_free_i32(fp1);
8838 gen_store_fpr32(fp2, fd);
8839 tcg_temp_free_i32(fp2);
8845 check_cp1_registers(ctx, fd | fs | ft | fr);
8847 TCGv_i64 fp0 = tcg_temp_new_i64();
8848 TCGv_i64 fp1 = tcg_temp_new_i64();
8849 TCGv_i64 fp2 = tcg_temp_new_i64();
8851 gen_load_fpr64(ctx, fp0, fs);
8852 gen_load_fpr64(ctx, fp1, ft);
8853 gen_load_fpr64(ctx, fp2, fr);
8854 gen_helper_float_madd_d(fp2, cpu_env, fp0, fp1, fp2);
8855 tcg_temp_free_i64(fp0);
8856 tcg_temp_free_i64(fp1);
8857 gen_store_fpr64(ctx, fp2, fd);
8858 tcg_temp_free_i64(fp2);
8863 check_cp1_64bitmode(ctx);
8865 TCGv_i64 fp0 = tcg_temp_new_i64();
8866 TCGv_i64 fp1 = tcg_temp_new_i64();
8867 TCGv_i64 fp2 = tcg_temp_new_i64();
8869 gen_load_fpr64(ctx, fp0, fs);
8870 gen_load_fpr64(ctx, fp1, ft);
8871 gen_load_fpr64(ctx, fp2, fr);
8872 gen_helper_float_madd_ps(fp2, cpu_env, fp0, fp1, fp2);
8873 tcg_temp_free_i64(fp0);
8874 tcg_temp_free_i64(fp1);
8875 gen_store_fpr64(ctx, fp2, fd);
8876 tcg_temp_free_i64(fp2);
8883 TCGv_i32 fp0 = tcg_temp_new_i32();
8884 TCGv_i32 fp1 = tcg_temp_new_i32();
8885 TCGv_i32 fp2 = tcg_temp_new_i32();
8887 gen_load_fpr32(fp0, fs);
8888 gen_load_fpr32(fp1, ft);
8889 gen_load_fpr32(fp2, fr);
8890 gen_helper_float_msub_s(fp2, cpu_env, fp0, fp1, fp2);
8891 tcg_temp_free_i32(fp0);
8892 tcg_temp_free_i32(fp1);
8893 gen_store_fpr32(fp2, fd);
8894 tcg_temp_free_i32(fp2);
8900 check_cp1_registers(ctx, fd | fs | ft | fr);
8902 TCGv_i64 fp0 = tcg_temp_new_i64();
8903 TCGv_i64 fp1 = tcg_temp_new_i64();
8904 TCGv_i64 fp2 = tcg_temp_new_i64();
8906 gen_load_fpr64(ctx, fp0, fs);
8907 gen_load_fpr64(ctx, fp1, ft);
8908 gen_load_fpr64(ctx, fp2, fr);
8909 gen_helper_float_msub_d(fp2, cpu_env, fp0, fp1, fp2);
8910 tcg_temp_free_i64(fp0);
8911 tcg_temp_free_i64(fp1);
8912 gen_store_fpr64(ctx, fp2, fd);
8913 tcg_temp_free_i64(fp2);
8918 check_cp1_64bitmode(ctx);
8920 TCGv_i64 fp0 = tcg_temp_new_i64();
8921 TCGv_i64 fp1 = tcg_temp_new_i64();
8922 TCGv_i64 fp2 = tcg_temp_new_i64();
8924 gen_load_fpr64(ctx, fp0, fs);
8925 gen_load_fpr64(ctx, fp1, ft);
8926 gen_load_fpr64(ctx, fp2, fr);
8927 gen_helper_float_msub_ps(fp2, cpu_env, fp0, fp1, fp2);
8928 tcg_temp_free_i64(fp0);
8929 tcg_temp_free_i64(fp1);
8930 gen_store_fpr64(ctx, fp2, fd);
8931 tcg_temp_free_i64(fp2);
8938 TCGv_i32 fp0 = tcg_temp_new_i32();
8939 TCGv_i32 fp1 = tcg_temp_new_i32();
8940 TCGv_i32 fp2 = tcg_temp_new_i32();
8942 gen_load_fpr32(fp0, fs);
8943 gen_load_fpr32(fp1, ft);
8944 gen_load_fpr32(fp2, fr);
8945 gen_helper_float_nmadd_s(fp2, cpu_env, fp0, fp1, fp2);
8946 tcg_temp_free_i32(fp0);
8947 tcg_temp_free_i32(fp1);
8948 gen_store_fpr32(fp2, fd);
8949 tcg_temp_free_i32(fp2);
8955 check_cp1_registers(ctx, fd | fs | ft | fr);
8957 TCGv_i64 fp0 = tcg_temp_new_i64();
8958 TCGv_i64 fp1 = tcg_temp_new_i64();
8959 TCGv_i64 fp2 = tcg_temp_new_i64();
8961 gen_load_fpr64(ctx, fp0, fs);
8962 gen_load_fpr64(ctx, fp1, ft);
8963 gen_load_fpr64(ctx, fp2, fr);
8964 gen_helper_float_nmadd_d(fp2, cpu_env, fp0, fp1, fp2);
8965 tcg_temp_free_i64(fp0);
8966 tcg_temp_free_i64(fp1);
8967 gen_store_fpr64(ctx, fp2, fd);
8968 tcg_temp_free_i64(fp2);
8973 check_cp1_64bitmode(ctx);
8975 TCGv_i64 fp0 = tcg_temp_new_i64();
8976 TCGv_i64 fp1 = tcg_temp_new_i64();
8977 TCGv_i64 fp2 = tcg_temp_new_i64();
8979 gen_load_fpr64(ctx, fp0, fs);
8980 gen_load_fpr64(ctx, fp1, ft);
8981 gen_load_fpr64(ctx, fp2, fr);
8982 gen_helper_float_nmadd_ps(fp2, cpu_env, fp0, fp1, fp2);
8983 tcg_temp_free_i64(fp0);
8984 tcg_temp_free_i64(fp1);
8985 gen_store_fpr64(ctx, fp2, fd);
8986 tcg_temp_free_i64(fp2);
8993 TCGv_i32 fp0 = tcg_temp_new_i32();
8994 TCGv_i32 fp1 = tcg_temp_new_i32();
8995 TCGv_i32 fp2 = tcg_temp_new_i32();
8997 gen_load_fpr32(fp0, fs);
8998 gen_load_fpr32(fp1, ft);
8999 gen_load_fpr32(fp2, fr);
9000 gen_helper_float_nmsub_s(fp2, cpu_env, fp0, fp1, fp2);
9001 tcg_temp_free_i32(fp0);
9002 tcg_temp_free_i32(fp1);
9003 gen_store_fpr32(fp2, fd);
9004 tcg_temp_free_i32(fp2);
9010 check_cp1_registers(ctx, fd | fs | ft | fr);
9012 TCGv_i64 fp0 = tcg_temp_new_i64();
9013 TCGv_i64 fp1 = tcg_temp_new_i64();
9014 TCGv_i64 fp2 = tcg_temp_new_i64();
9016 gen_load_fpr64(ctx, fp0, fs);
9017 gen_load_fpr64(ctx, fp1, ft);
9018 gen_load_fpr64(ctx, fp2, fr);
9019 gen_helper_float_nmsub_d(fp2, cpu_env, fp0, fp1, fp2);
9020 tcg_temp_free_i64(fp0);
9021 tcg_temp_free_i64(fp1);
9022 gen_store_fpr64(ctx, fp2, fd);
9023 tcg_temp_free_i64(fp2);
9028 check_cp1_64bitmode(ctx);
9030 TCGv_i64 fp0 = tcg_temp_new_i64();
9031 TCGv_i64 fp1 = tcg_temp_new_i64();
9032 TCGv_i64 fp2 = tcg_temp_new_i64();
9034 gen_load_fpr64(ctx, fp0, fs);
9035 gen_load_fpr64(ctx, fp1, ft);
9036 gen_load_fpr64(ctx, fp2, fr);
9037 gen_helper_float_nmsub_ps(fp2, cpu_env, fp0, fp1, fp2);
9038 tcg_temp_free_i64(fp0);
9039 tcg_temp_free_i64(fp1);
9040 gen_store_fpr64(ctx, fp2, fd);
9041 tcg_temp_free_i64(fp2);
9047 generate_exception (ctx, EXCP_RI);
9050 (void)opn; /* avoid a compiler warning */
9051 MIPS_DEBUG("%s %s, %s, %s, %s", opn, fregnames[fd], fregnames[fr],
9052 fregnames[fs], fregnames[ft]);
9056 gen_rdhwr (CPUMIPSState *env, DisasContext *ctx, int rt, int rd)
9060 #if !defined(CONFIG_USER_ONLY)
9061 /* The Linux kernel will emulate rdhwr if it's not supported natively.
9062 Therefore only check the ISA in system mode. */
9063 check_insn(env, ctx, ISA_MIPS32R2);
9065 t0 = tcg_temp_new();
9069 save_cpu_state(ctx, 1);
9070 gen_helper_rdhwr_cpunum(t0, cpu_env);
9071 gen_store_gpr(t0, rt);
9074 save_cpu_state(ctx, 1);
9075 gen_helper_rdhwr_synci_step(t0, cpu_env);
9076 gen_store_gpr(t0, rt);
9079 save_cpu_state(ctx, 1);
9080 gen_helper_rdhwr_cc(t0, cpu_env);
9081 gen_store_gpr(t0, rt);
9084 save_cpu_state(ctx, 1);
9085 gen_helper_rdhwr_ccres(t0, cpu_env);
9086 gen_store_gpr(t0, rt);
9089 #if defined(CONFIG_USER_ONLY)
9090 tcg_gen_ld_tl(t0, cpu_env, offsetof(CPUMIPSState, tls_value));
9091 gen_store_gpr(t0, rt);
9094 /* XXX: Some CPUs implement this in hardware.
9095 Not supported yet. */
9097 default: /* Invalid */
9098 MIPS_INVAL("rdhwr");
9099 generate_exception(ctx, EXCP_RI);
9105 static void handle_delay_slot (CPUMIPSState *env, DisasContext *ctx,
9108 if (ctx->hflags & MIPS_HFLAG_BMASK) {
9109 int proc_hflags = ctx->hflags & MIPS_HFLAG_BMASK;
9110 /* Branches completion */
9111 ctx->hflags &= ~MIPS_HFLAG_BMASK;
9112 ctx->bstate = BS_BRANCH;
9113 save_cpu_state(ctx, 0);
9114 /* FIXME: Need to clear can_do_io. */
9115 switch (proc_hflags & MIPS_HFLAG_BMASK_BASE) {
9117 /* unconditional branch */
9118 MIPS_DEBUG("unconditional branch");
9119 if (proc_hflags & MIPS_HFLAG_BX) {
9120 tcg_gen_xori_i32(hflags, hflags, MIPS_HFLAG_M16);
9122 gen_goto_tb(ctx, 0, ctx->btarget);
9125 /* blikely taken case */
9126 MIPS_DEBUG("blikely branch taken");
9127 gen_goto_tb(ctx, 0, ctx->btarget);
9130 /* Conditional branch */
9131 MIPS_DEBUG("conditional branch");
9133 int l1 = gen_new_label();
9135 tcg_gen_brcondi_tl(TCG_COND_NE, bcond, 0, l1);
9136 gen_goto_tb(ctx, 1, ctx->pc + insn_bytes);
9138 gen_goto_tb(ctx, 0, ctx->btarget);
9142 /* unconditional branch to register */
9143 MIPS_DEBUG("branch to register");
9144 if (env->insn_flags & (ASE_MIPS16 | ASE_MICROMIPS)) {
9145 TCGv t0 = tcg_temp_new();
9146 TCGv_i32 t1 = tcg_temp_new_i32();
9148 tcg_gen_andi_tl(t0, btarget, 0x1);
9149 tcg_gen_trunc_tl_i32(t1, t0);
9151 tcg_gen_andi_i32(hflags, hflags, ~(uint32_t)MIPS_HFLAG_M16);
9152 tcg_gen_shli_i32(t1, t1, MIPS_HFLAG_M16_SHIFT);
9153 tcg_gen_or_i32(hflags, hflags, t1);
9154 tcg_temp_free_i32(t1);
9156 tcg_gen_andi_tl(cpu_PC, btarget, ~(target_ulong)0x1);
9158 tcg_gen_mov_tl(cpu_PC, btarget);
9160 if (ctx->singlestep_enabled) {
9161 save_cpu_state(ctx, 0);
9162 gen_helper_0e0i(raise_exception, EXCP_DEBUG);
9167 MIPS_DEBUG("unknown branch");
9173 /* ISA extensions (ASEs) */
9174 /* MIPS16 extension to MIPS32 */
9176 /* MIPS16 major opcodes */
9178 M16_OPC_ADDIUSP = 0x00,
9179 M16_OPC_ADDIUPC = 0x01,
9182 M16_OPC_BEQZ = 0x04,
9183 M16_OPC_BNEQZ = 0x05,
9184 M16_OPC_SHIFT = 0x06,
9186 M16_OPC_RRIA = 0x08,
9187 M16_OPC_ADDIU8 = 0x09,
9188 M16_OPC_SLTI = 0x0a,
9189 M16_OPC_SLTIU = 0x0b,
9192 M16_OPC_CMPI = 0x0e,
9196 M16_OPC_LWSP = 0x12,
9200 M16_OPC_LWPC = 0x16,
9204 M16_OPC_SWSP = 0x1a,
9208 M16_OPC_EXTEND = 0x1e,
9212 /* I8 funct field */
9231 /* RR funct field */
9265 /* I64 funct field */
9277 /* RR ry field for CNVT */
9279 RR_RY_CNVT_ZEB = 0x0,
9280 RR_RY_CNVT_ZEH = 0x1,
9281 RR_RY_CNVT_ZEW = 0x2,
9282 RR_RY_CNVT_SEB = 0x4,
9283 RR_RY_CNVT_SEH = 0x5,
9284 RR_RY_CNVT_SEW = 0x6,
9287 static int xlat (int r)
9289 static int map[] = { 16, 17, 2, 3, 4, 5, 6, 7 };
9294 static void gen_mips16_save (DisasContext *ctx,
9295 int xsregs, int aregs,
9296 int do_ra, int do_s0, int do_s1,
9299 TCGv t0 = tcg_temp_new();
9300 TCGv t1 = tcg_temp_new();
9330 generate_exception(ctx, EXCP_RI);
9336 gen_base_offset_addr(ctx, t0, 29, 12);
9337 gen_load_gpr(t1, 7);
9338 tcg_gen_qemu_st32(t1, t0, ctx->mem_idx);
9341 gen_base_offset_addr(ctx, t0, 29, 8);
9342 gen_load_gpr(t1, 6);
9343 tcg_gen_qemu_st32(t1, t0, ctx->mem_idx);
9346 gen_base_offset_addr(ctx, t0, 29, 4);
9347 gen_load_gpr(t1, 5);
9348 tcg_gen_qemu_st32(t1, t0, ctx->mem_idx);
9351 gen_base_offset_addr(ctx, t0, 29, 0);
9352 gen_load_gpr(t1, 4);
9353 tcg_gen_qemu_st32(t1, t0, ctx->mem_idx);
9356 gen_load_gpr(t0, 29);
9358 #define DECR_AND_STORE(reg) do { \
9359 tcg_gen_subi_tl(t0, t0, 4); \
9360 gen_load_gpr(t1, reg); \
9361 tcg_gen_qemu_st32(t1, t0, ctx->mem_idx); \
9425 generate_exception(ctx, EXCP_RI);
9441 #undef DECR_AND_STORE
9443 tcg_gen_subi_tl(cpu_gpr[29], cpu_gpr[29], framesize);
9448 static void gen_mips16_restore (DisasContext *ctx,
9449 int xsregs, int aregs,
9450 int do_ra, int do_s0, int do_s1,
9454 TCGv t0 = tcg_temp_new();
9455 TCGv t1 = tcg_temp_new();
9457 tcg_gen_addi_tl(t0, cpu_gpr[29], framesize);
9459 #define DECR_AND_LOAD(reg) do { \
9460 tcg_gen_subi_tl(t0, t0, 4); \
9461 tcg_gen_qemu_ld32u(t1, t0, ctx->mem_idx); \
9462 gen_store_gpr(t1, reg); \
9526 generate_exception(ctx, EXCP_RI);
9542 #undef DECR_AND_LOAD
9544 tcg_gen_addi_tl(cpu_gpr[29], cpu_gpr[29], framesize);
9549 static void gen_addiupc (DisasContext *ctx, int rx, int imm,
9550 int is_64_bit, int extended)
9554 if (extended && (ctx->hflags & MIPS_HFLAG_BMASK)) {
9555 generate_exception(ctx, EXCP_RI);
9559 t0 = tcg_temp_new();
9561 tcg_gen_movi_tl(t0, pc_relative_pc(ctx));
9562 tcg_gen_addi_tl(cpu_gpr[rx], t0, imm);
9564 tcg_gen_ext32s_tl(cpu_gpr[rx], cpu_gpr[rx]);
9570 #if defined(TARGET_MIPS64)
9571 static void decode_i64_mips16 (CPUMIPSState *env, DisasContext *ctx,
9572 int ry, int funct, int16_t offset,
9578 offset = extended ? offset : offset << 3;
9579 gen_ld(env, ctx, OPC_LD, ry, 29, offset);
9583 offset = extended ? offset : offset << 3;
9584 gen_st(ctx, OPC_SD, ry, 29, offset);
9588 offset = extended ? offset : (ctx->opcode & 0xff) << 3;
9589 gen_st(ctx, OPC_SD, 31, 29, offset);
9593 offset = extended ? offset : ((int8_t)ctx->opcode) << 3;
9594 gen_arith_imm(env, ctx, OPC_DADDIU, 29, 29, offset);
9597 if (extended && (ctx->hflags & MIPS_HFLAG_BMASK)) {
9598 generate_exception(ctx, EXCP_RI);
9600 offset = extended ? offset : offset << 3;
9601 gen_ld(env, ctx, OPC_LDPC, ry, 0, offset);
9606 offset = extended ? offset : ((int8_t)(offset << 3)) >> 3;
9607 gen_arith_imm(env, ctx, OPC_DADDIU, ry, ry, offset);
9611 offset = extended ? offset : offset << 2;
9612 gen_addiupc(ctx, ry, offset, 1, extended);
9616 offset = extended ? offset : offset << 2;
9617 gen_arith_imm(env, ctx, OPC_DADDIU, ry, 29, offset);
9623 static int decode_extended_mips16_opc (CPUMIPSState *env, DisasContext *ctx,
9626 int extend = cpu_lduw_code(env, ctx->pc + 2);
9627 int op, rx, ry, funct, sa;
9628 int16_t imm, offset;
9630 ctx->opcode = (ctx->opcode << 16) | extend;
9631 op = (ctx->opcode >> 11) & 0x1f;
9632 sa = (ctx->opcode >> 22) & 0x1f;
9633 funct = (ctx->opcode >> 8) & 0x7;
9634 rx = xlat((ctx->opcode >> 8) & 0x7);
9635 ry = xlat((ctx->opcode >> 5) & 0x7);
9636 offset = imm = (int16_t) (((ctx->opcode >> 16) & 0x1f) << 11
9637 | ((ctx->opcode >> 21) & 0x3f) << 5
9638 | (ctx->opcode & 0x1f));
9640 /* The extended opcodes cleverly reuse the opcodes from their 16-bit
9643 case M16_OPC_ADDIUSP:
9644 gen_arith_imm(env, ctx, OPC_ADDIU, rx, 29, imm);
9646 case M16_OPC_ADDIUPC:
9647 gen_addiupc(ctx, rx, imm, 0, 1);
9650 gen_compute_branch(ctx, OPC_BEQ, 4, 0, 0, offset << 1);
9651 /* No delay slot, so just process as a normal instruction */
9654 gen_compute_branch(ctx, OPC_BEQ, 4, rx, 0, offset << 1);
9655 /* No delay slot, so just process as a normal instruction */
9658 gen_compute_branch(ctx, OPC_BNE, 4, rx, 0, offset << 1);
9659 /* No delay slot, so just process as a normal instruction */
9662 switch (ctx->opcode & 0x3) {
9664 gen_shift_imm(env, ctx, OPC_SLL, rx, ry, sa);
9667 #if defined(TARGET_MIPS64)
9669 gen_shift_imm(env, ctx, OPC_DSLL, rx, ry, sa);
9671 generate_exception(ctx, EXCP_RI);
9675 gen_shift_imm(env, ctx, OPC_SRL, rx, ry, sa);
9678 gen_shift_imm(env, ctx, OPC_SRA, rx, ry, sa);
9682 #if defined(TARGET_MIPS64)
9685 gen_ld(env, ctx, OPC_LD, ry, rx, offset);
9689 imm = ctx->opcode & 0xf;
9690 imm = imm | ((ctx->opcode >> 20) & 0x7f) << 4;
9691 imm = imm | ((ctx->opcode >> 16) & 0xf) << 11;
9692 imm = (int16_t) (imm << 1) >> 1;
9693 if ((ctx->opcode >> 4) & 0x1) {
9694 #if defined(TARGET_MIPS64)
9696 gen_arith_imm(env, ctx, OPC_DADDIU, ry, rx, imm);
9698 generate_exception(ctx, EXCP_RI);
9701 gen_arith_imm(env, ctx, OPC_ADDIU, ry, rx, imm);
9704 case M16_OPC_ADDIU8:
9705 gen_arith_imm(env, ctx, OPC_ADDIU, rx, rx, imm);
9708 gen_slt_imm(env, ctx, OPC_SLTI, 24, rx, imm);
9711 gen_slt_imm(env, ctx, OPC_SLTIU, 24, rx, imm);
9716 gen_compute_branch(ctx, OPC_BEQ, 4, 24, 0, offset << 1);
9719 gen_compute_branch(ctx, OPC_BNE, 4, 24, 0, offset << 1);
9722 gen_st(ctx, OPC_SW, 31, 29, imm);
9725 gen_arith_imm(env, ctx, OPC_ADDIU, 29, 29, imm);
9729 int xsregs = (ctx->opcode >> 24) & 0x7;
9730 int aregs = (ctx->opcode >> 16) & 0xf;
9731 int do_ra = (ctx->opcode >> 6) & 0x1;
9732 int do_s0 = (ctx->opcode >> 5) & 0x1;
9733 int do_s1 = (ctx->opcode >> 4) & 0x1;
9734 int framesize = (((ctx->opcode >> 20) & 0xf) << 4
9735 | (ctx->opcode & 0xf)) << 3;
9737 if (ctx->opcode & (1 << 7)) {
9738 gen_mips16_save(ctx, xsregs, aregs,
9739 do_ra, do_s0, do_s1,
9742 gen_mips16_restore(ctx, xsregs, aregs,
9743 do_ra, do_s0, do_s1,
9749 generate_exception(ctx, EXCP_RI);
9754 tcg_gen_movi_tl(cpu_gpr[rx], (uint16_t) imm);
9757 tcg_gen_xori_tl(cpu_gpr[24], cpu_gpr[rx], (uint16_t) imm);
9759 #if defined(TARGET_MIPS64)
9761 gen_st(ctx, OPC_SD, ry, rx, offset);
9765 gen_ld(env, ctx, OPC_LB, ry, rx, offset);
9768 gen_ld(env, ctx, OPC_LH, ry, rx, offset);
9771 gen_ld(env, ctx, OPC_LW, rx, 29, offset);
9774 gen_ld(env, ctx, OPC_LW, ry, rx, offset);
9777 gen_ld(env, ctx, OPC_LBU, ry, rx, offset);
9780 gen_ld(env, ctx, OPC_LHU, ry, rx, offset);
9783 gen_ld(env, ctx, OPC_LWPC, rx, 0, offset);
9785 #if defined(TARGET_MIPS64)
9787 gen_ld(env, ctx, OPC_LWU, ry, rx, offset);
9791 gen_st(ctx, OPC_SB, ry, rx, offset);
9794 gen_st(ctx, OPC_SH, ry, rx, offset);
9797 gen_st(ctx, OPC_SW, rx, 29, offset);
9800 gen_st(ctx, OPC_SW, ry, rx, offset);
9802 #if defined(TARGET_MIPS64)
9804 decode_i64_mips16(env, ctx, ry, funct, offset, 1);
9808 generate_exception(ctx, EXCP_RI);
9815 static int decode_mips16_opc (CPUMIPSState *env, DisasContext *ctx,
9820 int op, cnvt_op, op1, offset;
9824 op = (ctx->opcode >> 11) & 0x1f;
9825 sa = (ctx->opcode >> 2) & 0x7;
9826 sa = sa == 0 ? 8 : sa;
9827 rx = xlat((ctx->opcode >> 8) & 0x7);
9828 cnvt_op = (ctx->opcode >> 5) & 0x7;
9829 ry = xlat((ctx->opcode >> 5) & 0x7);
9830 op1 = offset = ctx->opcode & 0x1f;
9835 case M16_OPC_ADDIUSP:
9837 int16_t imm = ((uint8_t) ctx->opcode) << 2;
9839 gen_arith_imm(env, ctx, OPC_ADDIU, rx, 29, imm);
9842 case M16_OPC_ADDIUPC:
9843 gen_addiupc(ctx, rx, ((uint8_t) ctx->opcode) << 2, 0, 0);
9846 offset = (ctx->opcode & 0x7ff) << 1;
9847 offset = (int16_t)(offset << 4) >> 4;
9848 gen_compute_branch(ctx, OPC_BEQ, 2, 0, 0, offset);
9849 /* No delay slot, so just process as a normal instruction */
9852 offset = cpu_lduw_code(env, ctx->pc + 2);
9853 offset = (((ctx->opcode & 0x1f) << 21)
9854 | ((ctx->opcode >> 5) & 0x1f) << 16
9856 op = ((ctx->opcode >> 10) & 0x1) ? OPC_JALXS : OPC_JALS;
9857 gen_compute_branch(ctx, op, 4, rx, ry, offset);
9862 gen_compute_branch(ctx, OPC_BEQ, 2, rx, 0, ((int8_t)ctx->opcode) << 1);
9863 /* No delay slot, so just process as a normal instruction */
9866 gen_compute_branch(ctx, OPC_BNE, 2, rx, 0, ((int8_t)ctx->opcode) << 1);
9867 /* No delay slot, so just process as a normal instruction */
9870 switch (ctx->opcode & 0x3) {
9872 gen_shift_imm(env, ctx, OPC_SLL, rx, ry, sa);
9875 #if defined(TARGET_MIPS64)
9877 gen_shift_imm(env, ctx, OPC_DSLL, rx, ry, sa);
9879 generate_exception(ctx, EXCP_RI);
9883 gen_shift_imm(env, ctx, OPC_SRL, rx, ry, sa);
9886 gen_shift_imm(env, ctx, OPC_SRA, rx, ry, sa);
9890 #if defined(TARGET_MIPS64)
9893 gen_ld(env, ctx, OPC_LD, ry, rx, offset << 3);
9898 int16_t imm = (int8_t)((ctx->opcode & 0xf) << 4) >> 4;
9900 if ((ctx->opcode >> 4) & 1) {
9901 #if defined(TARGET_MIPS64)
9903 gen_arith_imm(env, ctx, OPC_DADDIU, ry, rx, imm);
9905 generate_exception(ctx, EXCP_RI);
9908 gen_arith_imm(env, ctx, OPC_ADDIU, ry, rx, imm);
9912 case M16_OPC_ADDIU8:
9914 int16_t imm = (int8_t) ctx->opcode;
9916 gen_arith_imm(env, ctx, OPC_ADDIU, rx, rx, imm);
9921 int16_t imm = (uint8_t) ctx->opcode;
9922 gen_slt_imm(env, ctx, OPC_SLTI, 24, rx, imm);
9927 int16_t imm = (uint8_t) ctx->opcode;
9928 gen_slt_imm(env, ctx, OPC_SLTIU, 24, rx, imm);
9935 funct = (ctx->opcode >> 8) & 0x7;
9938 gen_compute_branch(ctx, OPC_BEQ, 2, 24, 0,
9939 ((int8_t)ctx->opcode) << 1);
9942 gen_compute_branch(ctx, OPC_BNE, 2, 24, 0,
9943 ((int8_t)ctx->opcode) << 1);
9946 gen_st(ctx, OPC_SW, 31, 29, (ctx->opcode & 0xff) << 2);
9949 gen_arith_imm(env, ctx, OPC_ADDIU, 29, 29,
9950 ((int8_t)ctx->opcode) << 3);
9954 int do_ra = ctx->opcode & (1 << 6);
9955 int do_s0 = ctx->opcode & (1 << 5);
9956 int do_s1 = ctx->opcode & (1 << 4);
9957 int framesize = ctx->opcode & 0xf;
9959 if (framesize == 0) {
9962 framesize = framesize << 3;
9965 if (ctx->opcode & (1 << 7)) {
9966 gen_mips16_save(ctx, 0, 0,
9967 do_ra, do_s0, do_s1, framesize);
9969 gen_mips16_restore(ctx, 0, 0,
9970 do_ra, do_s0, do_s1, framesize);
9976 int rz = xlat(ctx->opcode & 0x7);
9978 reg32 = (((ctx->opcode >> 3) & 0x3) << 3) |
9979 ((ctx->opcode >> 5) & 0x7);
9980 gen_arith(env, ctx, OPC_ADDU, reg32, rz, 0);
9984 reg32 = ctx->opcode & 0x1f;
9985 gen_arith(env, ctx, OPC_ADDU, ry, reg32, 0);
9988 generate_exception(ctx, EXCP_RI);
9995 int16_t imm = (uint8_t) ctx->opcode;
9997 gen_arith_imm(env, ctx, OPC_ADDIU, rx, 0, imm);
10002 int16_t imm = (uint8_t) ctx->opcode;
10003 gen_logic_imm(env, ctx, OPC_XORI, 24, rx, imm);
10006 #if defined(TARGET_MIPS64)
10008 check_mips_64(ctx);
10009 gen_st(ctx, OPC_SD, ry, rx, offset << 3);
10013 gen_ld(env, ctx, OPC_LB, ry, rx, offset);
10016 gen_ld(env, ctx, OPC_LH, ry, rx, offset << 1);
10019 gen_ld(env, ctx, OPC_LW, rx, 29, ((uint8_t)ctx->opcode) << 2);
10022 gen_ld(env, ctx, OPC_LW, ry, rx, offset << 2);
10025 gen_ld(env, ctx, OPC_LBU, ry, rx, offset);
10028 gen_ld(env, ctx, OPC_LHU, ry, rx, offset << 1);
10031 gen_ld(env, ctx, OPC_LWPC, rx, 0, ((uint8_t)ctx->opcode) << 2);
10033 #if defined (TARGET_MIPS64)
10035 check_mips_64(ctx);
10036 gen_ld(env, ctx, OPC_LWU, ry, rx, offset << 2);
10040 gen_st(ctx, OPC_SB, ry, rx, offset);
10043 gen_st(ctx, OPC_SH, ry, rx, offset << 1);
10046 gen_st(ctx, OPC_SW, rx, 29, ((uint8_t)ctx->opcode) << 2);
10049 gen_st(ctx, OPC_SW, ry, rx, offset << 2);
10053 int rz = xlat((ctx->opcode >> 2) & 0x7);
10056 switch (ctx->opcode & 0x3) {
10058 mips32_op = OPC_ADDU;
10061 mips32_op = OPC_SUBU;
10063 #if defined(TARGET_MIPS64)
10065 mips32_op = OPC_DADDU;
10066 check_mips_64(ctx);
10069 mips32_op = OPC_DSUBU;
10070 check_mips_64(ctx);
10074 generate_exception(ctx, EXCP_RI);
10078 gen_arith(env, ctx, mips32_op, rz, rx, ry);
10087 int nd = (ctx->opcode >> 7) & 0x1;
10088 int link = (ctx->opcode >> 6) & 0x1;
10089 int ra = (ctx->opcode >> 5) & 0x1;
10092 op = nd ? OPC_JALRC : OPC_JALRS;
10097 gen_compute_branch(ctx, op, 2, ra ? 31 : rx, 31, 0);
10104 /* XXX: not clear which exception should be raised
10105 * when in debug mode...
10107 check_insn(env, ctx, ISA_MIPS32);
10108 if (!(ctx->hflags & MIPS_HFLAG_DM)) {
10109 generate_exception(ctx, EXCP_DBp);
10111 generate_exception(ctx, EXCP_DBp);
10115 gen_slt(env, ctx, OPC_SLT, 24, rx, ry);
10118 gen_slt(env, ctx, OPC_SLTU, 24, rx, ry);
10121 generate_exception(ctx, EXCP_BREAK);
10124 gen_shift(env, ctx, OPC_SLLV, ry, rx, ry);
10127 gen_shift(env, ctx, OPC_SRLV, ry, rx, ry);
10130 gen_shift(env, ctx, OPC_SRAV, ry, rx, ry);
10132 #if defined (TARGET_MIPS64)
10134 check_mips_64(ctx);
10135 gen_shift_imm(env, ctx, OPC_DSRL, ry, ry, sa);
10139 gen_logic(env, ctx, OPC_XOR, 24, rx, ry);
10142 gen_arith(env, ctx, OPC_SUBU, rx, 0, ry);
10145 gen_logic(env, ctx, OPC_AND, rx, rx, ry);
10148 gen_logic(env, ctx, OPC_OR, rx, rx, ry);
10151 gen_logic(env, ctx, OPC_XOR, rx, rx, ry);
10154 gen_logic(env, ctx, OPC_NOR, rx, ry, 0);
10157 gen_HILO(ctx, OPC_MFHI, rx);
10161 case RR_RY_CNVT_ZEB:
10162 tcg_gen_ext8u_tl(cpu_gpr[rx], cpu_gpr[rx]);
10164 case RR_RY_CNVT_ZEH:
10165 tcg_gen_ext16u_tl(cpu_gpr[rx], cpu_gpr[rx]);
10167 case RR_RY_CNVT_SEB:
10168 tcg_gen_ext8s_tl(cpu_gpr[rx], cpu_gpr[rx]);
10170 case RR_RY_CNVT_SEH:
10171 tcg_gen_ext16s_tl(cpu_gpr[rx], cpu_gpr[rx]);
10173 #if defined (TARGET_MIPS64)
10174 case RR_RY_CNVT_ZEW:
10175 check_mips_64(ctx);
10176 tcg_gen_ext32u_tl(cpu_gpr[rx], cpu_gpr[rx]);
10178 case RR_RY_CNVT_SEW:
10179 check_mips_64(ctx);
10180 tcg_gen_ext32s_tl(cpu_gpr[rx], cpu_gpr[rx]);
10184 generate_exception(ctx, EXCP_RI);
10189 gen_HILO(ctx, OPC_MFLO, rx);
10191 #if defined (TARGET_MIPS64)
10193 check_mips_64(ctx);
10194 gen_shift_imm(env, ctx, OPC_DSRA, ry, ry, sa);
10197 check_mips_64(ctx);
10198 gen_shift(env, ctx, OPC_DSLLV, ry, rx, ry);
10201 check_mips_64(ctx);
10202 gen_shift(env, ctx, OPC_DSRLV, ry, rx, ry);
10205 check_mips_64(ctx);
10206 gen_shift(env, ctx, OPC_DSRAV, ry, rx, ry);
10210 gen_muldiv(ctx, OPC_MULT, rx, ry);
10213 gen_muldiv(ctx, OPC_MULTU, rx, ry);
10216 gen_muldiv(ctx, OPC_DIV, rx, ry);
10219 gen_muldiv(ctx, OPC_DIVU, rx, ry);
10221 #if defined (TARGET_MIPS64)
10223 check_mips_64(ctx);
10224 gen_muldiv(ctx, OPC_DMULT, rx, ry);
10227 check_mips_64(ctx);
10228 gen_muldiv(ctx, OPC_DMULTU, rx, ry);
10231 check_mips_64(ctx);
10232 gen_muldiv(ctx, OPC_DDIV, rx, ry);
10235 check_mips_64(ctx);
10236 gen_muldiv(ctx, OPC_DDIVU, rx, ry);
10240 generate_exception(ctx, EXCP_RI);
10244 case M16_OPC_EXTEND:
10245 decode_extended_mips16_opc(env, ctx, is_branch);
10248 #if defined(TARGET_MIPS64)
10250 funct = (ctx->opcode >> 8) & 0x7;
10251 decode_i64_mips16(env, ctx, ry, funct, offset, 0);
10255 generate_exception(ctx, EXCP_RI);
10262 /* microMIPS extension to MIPS32 */
10264 /* microMIPS32 major opcodes */
10303 /* 0x20 is reserved */
10313 /* 0x28 and 0x29 are reserved */
10323 /* 0x30 and 0x31 are reserved */
10333 /* 0x38 and 0x39 are reserved */
10344 /* POOL32A encoding of minor opcode field */
10347 /* These opcodes are distinguished only by bits 9..6; those bits are
10348 * what are recorded below. */
10374 /* The following can be distinguished by their lower 6 bits. */
10380 /* POOL32AXF encoding of minor opcode field extension */
10394 /* bits 13..12 for 0x01 */
10400 /* bits 13..12 for 0x2a */
10406 /* bits 13..12 for 0x32 */
10410 /* bits 15..12 for 0x2c */
10426 /* bits 15..12 for 0x34 */
10434 /* bits 15..12 for 0x3c */
10436 JR = 0x0, /* alias */
10441 /* bits 15..12 for 0x05 */
10445 /* bits 15..12 for 0x0d */
10455 /* bits 15..12 for 0x15 */
10461 /* bits 15..12 for 0x1d */
10465 /* bits 15..12 for 0x2d */
10470 /* bits 15..12 for 0x35 */
10477 /* POOL32B encoding of minor opcode field (bits 15..12) */
10493 /* POOL32C encoding of minor opcode field (bits 15..12) */
10501 /* 0xa is reserved */
10508 /* 0x6 is reserved */
10514 /* POOL32F encoding of minor opcode field (bits 5..0) */
10517 /* These are the bit 7..6 values */
10528 /* These are the bit 8..6 values */
10572 CABS_COND_FMT = 0x1c, /* MIPS3D */
10576 /* POOL32Fxf encoding of minor opcode extension field */
10614 /* POOL32I encoding of minor opcode field (bits 25..21) */
10639 /* These overlap and are distinguished by bit16 of the instruction */
10648 /* POOL16A encoding of minor opcode field */
10655 /* POOL16B encoding of minor opcode field */
10662 /* POOL16C encoding of minor opcode field */
10682 /* POOL16D encoding of minor opcode field */
10689 /* POOL16E encoding of minor opcode field */
10696 static int mmreg (int r)
10698 static const int map[] = { 16, 17, 2, 3, 4, 5, 6, 7 };
10703 /* Used for 16-bit store instructions. */
10704 static int mmreg2 (int r)
10706 static const int map[] = { 0, 17, 2, 3, 4, 5, 6, 7 };
10711 #define uMIPS_RD(op) ((op >> 7) & 0x7)
10712 #define uMIPS_RS(op) ((op >> 4) & 0x7)
10713 #define uMIPS_RS2(op) uMIPS_RS(op)
10714 #define uMIPS_RS1(op) ((op >> 1) & 0x7)
10715 #define uMIPS_RD5(op) ((op >> 5) & 0x1f)
10716 #define uMIPS_RS5(op) (op & 0x1f)
10718 /* Signed immediate */
10719 #define SIMM(op, start, width) \
10720 ((int32_t)(((op >> start) & ((~0U) >> (32-width))) \
10723 /* Zero-extended immediate */
10724 #define ZIMM(op, start, width) ((op >> start) & ((~0U) >> (32-width)))
10726 static void gen_addiur1sp (CPUMIPSState *env, DisasContext *ctx)
10728 int rd = mmreg(uMIPS_RD(ctx->opcode));
10730 gen_arith_imm(env, ctx, OPC_ADDIU, rd, 29, ((ctx->opcode >> 1) & 0x3f) << 2);
10733 static void gen_addiur2 (CPUMIPSState *env, DisasContext *ctx)
10735 static const int decoded_imm[] = { 1, 4, 8, 12, 16, 20, 24, -1 };
10736 int rd = mmreg(uMIPS_RD(ctx->opcode));
10737 int rs = mmreg(uMIPS_RS(ctx->opcode));
10739 gen_arith_imm(env, ctx, OPC_ADDIU, rd, rs, decoded_imm[ZIMM(ctx->opcode, 1, 3)]);
10742 static void gen_addiusp (CPUMIPSState *env, DisasContext *ctx)
10744 int encoded = ZIMM(ctx->opcode, 1, 9);
10747 if (encoded <= 1) {
10748 decoded = 256 + encoded;
10749 } else if (encoded <= 255) {
10751 } else if (encoded <= 509) {
10752 decoded = encoded - 512;
10754 decoded = encoded - 768;
10757 gen_arith_imm(env, ctx, OPC_ADDIU, 29, 29, decoded << 2);
10760 static void gen_addius5 (CPUMIPSState *env, DisasContext *ctx)
10762 int imm = SIMM(ctx->opcode, 1, 4);
10763 int rd = (ctx->opcode >> 5) & 0x1f;
10765 gen_arith_imm(env, ctx, OPC_ADDIU, rd, rd, imm);
10768 static void gen_andi16 (CPUMIPSState *env, DisasContext *ctx)
10770 static const int decoded_imm[] = { 128, 1, 2, 3, 4, 7, 8, 15, 16,
10771 31, 32, 63, 64, 255, 32768, 65535 };
10772 int rd = mmreg(uMIPS_RD(ctx->opcode));
10773 int rs = mmreg(uMIPS_RS(ctx->opcode));
10774 int encoded = ZIMM(ctx->opcode, 0, 4);
10776 gen_logic_imm(env, ctx, OPC_ANDI, rd, rs, decoded_imm[encoded]);
10779 static void gen_ldst_multiple (DisasContext *ctx, uint32_t opc, int reglist,
10780 int base, int16_t offset)
10782 const char *opn = "ldst_multiple";
10786 if (ctx->hflags & MIPS_HFLAG_BMASK) {
10787 generate_exception(ctx, EXCP_RI);
10791 t0 = tcg_temp_new();
10793 gen_base_offset_addr(ctx, t0, base, offset);
10795 t1 = tcg_const_tl(reglist);
10796 t2 = tcg_const_i32(ctx->mem_idx);
10798 save_cpu_state(ctx, 1);
10801 gen_helper_lwm(cpu_env, t0, t1, t2);
10805 gen_helper_swm(cpu_env, t0, t1, t2);
10808 #ifdef TARGET_MIPS64
10810 gen_helper_ldm(cpu_env, t0, t1, t2);
10814 gen_helper_sdm(cpu_env, t0, t1, t2);
10820 MIPS_DEBUG("%s, %x, %d(%s)", opn, reglist, offset, regnames[base]);
10823 tcg_temp_free_i32(t2);
10827 static void gen_pool16c_insn (CPUMIPSState *env, DisasContext *ctx, int *is_branch)
10829 int rd = mmreg((ctx->opcode >> 3) & 0x7);
10830 int rs = mmreg(ctx->opcode & 0x7);
10833 switch (((ctx->opcode) >> 4) & 0x3f) {
10838 gen_logic(env, ctx, OPC_NOR, rd, rs, 0);
10844 gen_logic(env, ctx, OPC_XOR, rd, rd, rs);
10850 gen_logic(env, ctx, OPC_AND, rd, rd, rs);
10856 gen_logic(env, ctx, OPC_OR, rd, rd, rs);
10863 static const int lwm_convert[] = { 0x11, 0x12, 0x13, 0x14 };
10864 int offset = ZIMM(ctx->opcode, 0, 4);
10866 gen_ldst_multiple(ctx, LWM32, lwm_convert[(ctx->opcode >> 4) & 0x3],
10875 static const int swm_convert[] = { 0x11, 0x12, 0x13, 0x14 };
10876 int offset = ZIMM(ctx->opcode, 0, 4);
10878 gen_ldst_multiple(ctx, SWM32, swm_convert[(ctx->opcode >> 4) & 0x3],
10885 int reg = ctx->opcode & 0x1f;
10887 gen_compute_branch(ctx, OPC_JR, 2, reg, 0, 0);
10894 int reg = ctx->opcode & 0x1f;
10896 gen_compute_branch(ctx, OPC_JR, 2, reg, 0, 0);
10897 /* Let normal delay slot handling in our caller take us
10898 to the branch target. */
10910 int reg = ctx->opcode & 0x1f;
10912 gen_compute_branch(ctx, opc, 2, reg, 31, 0);
10918 gen_HILO(ctx, OPC_MFHI, uMIPS_RS5(ctx->opcode));
10922 gen_HILO(ctx, OPC_MFLO, uMIPS_RS5(ctx->opcode));
10925 generate_exception(ctx, EXCP_BREAK);
10928 /* XXX: not clear which exception should be raised
10929 * when in debug mode...
10931 check_insn(env, ctx, ISA_MIPS32);
10932 if (!(ctx->hflags & MIPS_HFLAG_DM)) {
10933 generate_exception(ctx, EXCP_DBp);
10935 generate_exception(ctx, EXCP_DBp);
10938 case JRADDIUSP + 0:
10939 case JRADDIUSP + 1:
10941 int imm = ZIMM(ctx->opcode, 0, 5);
10943 gen_compute_branch(ctx, OPC_JR, 2, 31, 0, 0);
10944 gen_arith_imm(env, ctx, OPC_ADDIU, 29, 29, imm << 2);
10945 /* Let normal delay slot handling in our caller take us
10946 to the branch target. */
10950 generate_exception(ctx, EXCP_RI);
10955 static void gen_ldxs (DisasContext *ctx, int base, int index, int rd)
10957 TCGv t0 = tcg_temp_new();
10958 TCGv t1 = tcg_temp_new();
10960 gen_load_gpr(t0, base);
10963 gen_load_gpr(t1, index);
10964 tcg_gen_shli_tl(t1, t1, 2);
10965 gen_op_addr_add(ctx, t0, t1, t0);
10968 tcg_gen_qemu_ld32s(t1, t0, ctx->mem_idx);
10969 gen_store_gpr(t1, rd);
10975 static void gen_ldst_pair (DisasContext *ctx, uint32_t opc, int rd,
10976 int base, int16_t offset)
10978 const char *opn = "ldst_pair";
10981 if (ctx->hflags & MIPS_HFLAG_BMASK || rd == 31) {
10982 generate_exception(ctx, EXCP_RI);
10986 t0 = tcg_temp_new();
10987 t1 = tcg_temp_new();
10989 gen_base_offset_addr(ctx, t0, base, offset);
10994 generate_exception(ctx, EXCP_RI);
10997 tcg_gen_qemu_ld32s(t1, t0, ctx->mem_idx);
10998 gen_store_gpr(t1, rd);
10999 tcg_gen_movi_tl(t1, 4);
11000 gen_op_addr_add(ctx, t0, t0, t1);
11001 tcg_gen_qemu_ld32s(t1, t0, ctx->mem_idx);
11002 gen_store_gpr(t1, rd+1);
11006 gen_load_gpr(t1, rd);
11007 tcg_gen_qemu_st32(t1, t0, ctx->mem_idx);
11008 tcg_gen_movi_tl(t1, 4);
11009 gen_op_addr_add(ctx, t0, t0, t1);
11010 gen_load_gpr(t1, rd+1);
11011 tcg_gen_qemu_st32(t1, t0, ctx->mem_idx);
11014 #ifdef TARGET_MIPS64
11017 generate_exception(ctx, EXCP_RI);
11020 tcg_gen_qemu_ld64(t1, t0, ctx->mem_idx);
11021 gen_store_gpr(t1, rd);
11022 tcg_gen_movi_tl(t1, 8);
11023 gen_op_addr_add(ctx, t0, t0, t1);
11024 tcg_gen_qemu_ld64(t1, t0, ctx->mem_idx);
11025 gen_store_gpr(t1, rd+1);
11029 gen_load_gpr(t1, rd);
11030 tcg_gen_qemu_st64(t1, t0, ctx->mem_idx);
11031 tcg_gen_movi_tl(t1, 8);
11032 gen_op_addr_add(ctx, t0, t0, t1);
11033 gen_load_gpr(t1, rd+1);
11034 tcg_gen_qemu_st64(t1, t0, ctx->mem_idx);
11039 (void)opn; /* avoid a compiler warning */
11040 MIPS_DEBUG("%s, %s, %d(%s)", opn, regnames[rd], offset, regnames[base]);
11045 static void gen_pool32axf (CPUMIPSState *env, DisasContext *ctx, int rt, int rs,
11048 int extension = (ctx->opcode >> 6) & 0x3f;
11049 int minor = (ctx->opcode >> 12) & 0xf;
11050 uint32_t mips32_op;
11052 switch (extension) {
11054 mips32_op = OPC_TEQ;
11057 mips32_op = OPC_TGE;
11060 mips32_op = OPC_TGEU;
11063 mips32_op = OPC_TLT;
11066 mips32_op = OPC_TLTU;
11069 mips32_op = OPC_TNE;
11071 gen_trap(ctx, mips32_op, rs, rt, -1);
11073 #ifndef CONFIG_USER_ONLY
11076 check_cp0_enabled(ctx);
11078 /* Treat as NOP. */
11081 gen_mfc0(env, ctx, cpu_gpr[rt], rs, (ctx->opcode >> 11) & 0x7);
11085 check_cp0_enabled(ctx);
11087 TCGv t0 = tcg_temp_new();
11089 gen_load_gpr(t0, rt);
11090 gen_mtc0(env, ctx, t0, rs, (ctx->opcode >> 11) & 0x7);
11098 gen_bshfl(ctx, OPC_SEB, rs, rt);
11101 gen_bshfl(ctx, OPC_SEH, rs, rt);
11104 mips32_op = OPC_CLO;
11107 mips32_op = OPC_CLZ;
11109 check_insn(env, ctx, ISA_MIPS32);
11110 gen_cl(ctx, mips32_op, rt, rs);
11113 gen_rdhwr(env, ctx, rt, rs);
11116 gen_bshfl(ctx, OPC_WSBH, rs, rt);
11119 mips32_op = OPC_MULT;
11122 mips32_op = OPC_MULTU;
11125 mips32_op = OPC_DIV;
11128 mips32_op = OPC_DIVU;
11131 mips32_op = OPC_MADD;
11134 mips32_op = OPC_MADDU;
11137 mips32_op = OPC_MSUB;
11140 mips32_op = OPC_MSUBU;
11142 check_insn(env, ctx, ISA_MIPS32);
11143 gen_muldiv(ctx, mips32_op, rs, rt);
11146 goto pool32axf_invalid;
11157 generate_exception_err(ctx, EXCP_CpU, 2);
11160 goto pool32axf_invalid;
11167 gen_compute_branch (ctx, OPC_JALR, 4, rs, rt, 0);
11172 gen_compute_branch (ctx, OPC_JALRS, 4, rs, rt, 0);
11176 goto pool32axf_invalid;
11182 check_cp0_enabled(ctx);
11183 check_insn(env, ctx, ISA_MIPS32R2);
11184 gen_load_srsgpr(rt, rs);
11187 check_cp0_enabled(ctx);
11188 check_insn(env, ctx, ISA_MIPS32R2);
11189 gen_store_srsgpr(rt, rs);
11192 goto pool32axf_invalid;
11195 #ifndef CONFIG_USER_ONLY
11199 mips32_op = OPC_TLBP;
11202 mips32_op = OPC_TLBR;
11205 mips32_op = OPC_TLBWI;
11208 mips32_op = OPC_TLBWR;
11211 mips32_op = OPC_WAIT;
11214 mips32_op = OPC_DERET;
11217 mips32_op = OPC_ERET;
11219 gen_cp0(env, ctx, mips32_op, rt, rs);
11222 goto pool32axf_invalid;
11228 check_cp0_enabled(ctx);
11230 TCGv t0 = tcg_temp_new();
11232 save_cpu_state(ctx, 1);
11233 gen_helper_di(t0, cpu_env);
11234 gen_store_gpr(t0, rs);
11235 /* Stop translation as we may have switched the execution mode */
11236 ctx->bstate = BS_STOP;
11241 check_cp0_enabled(ctx);
11243 TCGv t0 = tcg_temp_new();
11245 save_cpu_state(ctx, 1);
11246 gen_helper_ei(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 goto pool32axf_invalid;
11264 generate_exception(ctx, EXCP_SYSCALL);
11265 ctx->bstate = BS_STOP;
11268 check_insn(env, ctx, ISA_MIPS32);
11269 if (!(ctx->hflags & MIPS_HFLAG_DM)) {
11270 generate_exception(ctx, EXCP_DBp);
11272 generate_exception(ctx, EXCP_DBp);
11276 goto pool32axf_invalid;
11282 gen_HILO(ctx, OPC_MFHI, rs);
11285 gen_HILO(ctx, OPC_MFLO, rs);
11288 gen_HILO(ctx, OPC_MTHI, rs);
11291 gen_HILO(ctx, OPC_MTLO, rs);
11294 goto pool32axf_invalid;
11299 MIPS_INVAL("pool32axf");
11300 generate_exception(ctx, EXCP_RI);
11305 /* Values for microMIPS fmt field. Variable-width, depending on which
11306 formats the instruction supports. */
11325 static void gen_pool32fxf (CPUMIPSState *env, DisasContext *ctx, int rt, int rs)
11327 int extension = (ctx->opcode >> 6) & 0x3ff;
11328 uint32_t mips32_op;
11330 #define FLOAT_1BIT_FMT(opc, fmt) (fmt << 8) | opc
11331 #define FLOAT_2BIT_FMT(opc, fmt) (fmt << 7) | opc
11332 #define COND_FLOAT_MOV(opc, cond) (cond << 7) | opc
11334 switch (extension) {
11335 case FLOAT_1BIT_FMT(CFC1, 0):
11336 mips32_op = OPC_CFC1;
11338 case FLOAT_1BIT_FMT(CTC1, 0):
11339 mips32_op = OPC_CTC1;
11341 case FLOAT_1BIT_FMT(MFC1, 0):
11342 mips32_op = OPC_MFC1;
11344 case FLOAT_1BIT_FMT(MTC1, 0):
11345 mips32_op = OPC_MTC1;
11347 case FLOAT_1BIT_FMT(MFHC1, 0):
11348 mips32_op = OPC_MFHC1;
11350 case FLOAT_1BIT_FMT(MTHC1, 0):
11351 mips32_op = OPC_MTHC1;
11353 gen_cp1(ctx, mips32_op, rt, rs);
11356 /* Reciprocal square root */
11357 case FLOAT_1BIT_FMT(RSQRT_FMT, FMT_SD_S):
11358 mips32_op = OPC_RSQRT_S;
11360 case FLOAT_1BIT_FMT(RSQRT_FMT, FMT_SD_D):
11361 mips32_op = OPC_RSQRT_D;
11365 case FLOAT_1BIT_FMT(SQRT_FMT, FMT_SD_S):
11366 mips32_op = OPC_SQRT_S;
11368 case FLOAT_1BIT_FMT(SQRT_FMT, FMT_SD_D):
11369 mips32_op = OPC_SQRT_D;
11373 case FLOAT_1BIT_FMT(RECIP_FMT, FMT_SD_S):
11374 mips32_op = OPC_RECIP_S;
11376 case FLOAT_1BIT_FMT(RECIP_FMT, FMT_SD_D):
11377 mips32_op = OPC_RECIP_D;
11381 case FLOAT_1BIT_FMT(FLOOR_L, FMT_SD_S):
11382 mips32_op = OPC_FLOOR_L_S;
11384 case FLOAT_1BIT_FMT(FLOOR_L, FMT_SD_D):
11385 mips32_op = OPC_FLOOR_L_D;
11387 case FLOAT_1BIT_FMT(FLOOR_W, FMT_SD_S):
11388 mips32_op = OPC_FLOOR_W_S;
11390 case FLOAT_1BIT_FMT(FLOOR_W, FMT_SD_D):
11391 mips32_op = OPC_FLOOR_W_D;
11395 case FLOAT_1BIT_FMT(CEIL_L, FMT_SD_S):
11396 mips32_op = OPC_CEIL_L_S;
11398 case FLOAT_1BIT_FMT(CEIL_L, FMT_SD_D):
11399 mips32_op = OPC_CEIL_L_D;
11401 case FLOAT_1BIT_FMT(CEIL_W, FMT_SD_S):
11402 mips32_op = OPC_CEIL_W_S;
11404 case FLOAT_1BIT_FMT(CEIL_W, FMT_SD_D):
11405 mips32_op = OPC_CEIL_W_D;
11409 case FLOAT_1BIT_FMT(TRUNC_L, FMT_SD_S):
11410 mips32_op = OPC_TRUNC_L_S;
11412 case FLOAT_1BIT_FMT(TRUNC_L, FMT_SD_D):
11413 mips32_op = OPC_TRUNC_L_D;
11415 case FLOAT_1BIT_FMT(TRUNC_W, FMT_SD_S):
11416 mips32_op = OPC_TRUNC_W_S;
11418 case FLOAT_1BIT_FMT(TRUNC_W, FMT_SD_D):
11419 mips32_op = OPC_TRUNC_W_D;
11423 case FLOAT_1BIT_FMT(ROUND_L, FMT_SD_S):
11424 mips32_op = OPC_ROUND_L_S;
11426 case FLOAT_1BIT_FMT(ROUND_L, FMT_SD_D):
11427 mips32_op = OPC_ROUND_L_D;
11429 case FLOAT_1BIT_FMT(ROUND_W, FMT_SD_S):
11430 mips32_op = OPC_ROUND_W_S;
11432 case FLOAT_1BIT_FMT(ROUND_W, FMT_SD_D):
11433 mips32_op = OPC_ROUND_W_D;
11436 /* Integer to floating-point conversion */
11437 case FLOAT_1BIT_FMT(CVT_L, FMT_SD_S):
11438 mips32_op = OPC_CVT_L_S;
11440 case FLOAT_1BIT_FMT(CVT_L, FMT_SD_D):
11441 mips32_op = OPC_CVT_L_D;
11443 case FLOAT_1BIT_FMT(CVT_W, FMT_SD_S):
11444 mips32_op = OPC_CVT_W_S;
11446 case FLOAT_1BIT_FMT(CVT_W, FMT_SD_D):
11447 mips32_op = OPC_CVT_W_D;
11450 /* Paired-foo conversions */
11451 case FLOAT_1BIT_FMT(CVT_S_PL, 0):
11452 mips32_op = OPC_CVT_S_PL;
11454 case FLOAT_1BIT_FMT(CVT_S_PU, 0):
11455 mips32_op = OPC_CVT_S_PU;
11457 case FLOAT_1BIT_FMT(CVT_PW_PS, 0):
11458 mips32_op = OPC_CVT_PW_PS;
11460 case FLOAT_1BIT_FMT(CVT_PS_PW, 0):
11461 mips32_op = OPC_CVT_PS_PW;
11464 /* Floating-point moves */
11465 case FLOAT_2BIT_FMT(MOV_FMT, FMT_SDPS_S):
11466 mips32_op = OPC_MOV_S;
11468 case FLOAT_2BIT_FMT(MOV_FMT, FMT_SDPS_D):
11469 mips32_op = OPC_MOV_D;
11471 case FLOAT_2BIT_FMT(MOV_FMT, FMT_SDPS_PS):
11472 mips32_op = OPC_MOV_PS;
11475 /* Absolute value */
11476 case FLOAT_2BIT_FMT(ABS_FMT, FMT_SDPS_S):
11477 mips32_op = OPC_ABS_S;
11479 case FLOAT_2BIT_FMT(ABS_FMT, FMT_SDPS_D):
11480 mips32_op = OPC_ABS_D;
11482 case FLOAT_2BIT_FMT(ABS_FMT, FMT_SDPS_PS):
11483 mips32_op = OPC_ABS_PS;
11487 case FLOAT_2BIT_FMT(NEG_FMT, FMT_SDPS_S):
11488 mips32_op = OPC_NEG_S;
11490 case FLOAT_2BIT_FMT(NEG_FMT, FMT_SDPS_D):
11491 mips32_op = OPC_NEG_D;
11493 case FLOAT_2BIT_FMT(NEG_FMT, FMT_SDPS_PS):
11494 mips32_op = OPC_NEG_PS;
11497 /* Reciprocal square root step */
11498 case FLOAT_2BIT_FMT(RSQRT1_FMT, FMT_SDPS_S):
11499 mips32_op = OPC_RSQRT1_S;
11501 case FLOAT_2BIT_FMT(RSQRT1_FMT, FMT_SDPS_D):
11502 mips32_op = OPC_RSQRT1_D;
11504 case FLOAT_2BIT_FMT(RSQRT1_FMT, FMT_SDPS_PS):
11505 mips32_op = OPC_RSQRT1_PS;
11508 /* Reciprocal step */
11509 case FLOAT_2BIT_FMT(RECIP1_FMT, FMT_SDPS_S):
11510 mips32_op = OPC_RECIP1_S;
11512 case FLOAT_2BIT_FMT(RECIP1_FMT, FMT_SDPS_D):
11513 mips32_op = OPC_RECIP1_S;
11515 case FLOAT_2BIT_FMT(RECIP1_FMT, FMT_SDPS_PS):
11516 mips32_op = OPC_RECIP1_PS;
11519 /* Conversions from double */
11520 case FLOAT_2BIT_FMT(CVT_D, FMT_SWL_S):
11521 mips32_op = OPC_CVT_D_S;
11523 case FLOAT_2BIT_FMT(CVT_D, FMT_SWL_W):
11524 mips32_op = OPC_CVT_D_W;
11526 case FLOAT_2BIT_FMT(CVT_D, FMT_SWL_L):
11527 mips32_op = OPC_CVT_D_L;
11530 /* Conversions from single */
11531 case FLOAT_2BIT_FMT(CVT_S, FMT_DWL_D):
11532 mips32_op = OPC_CVT_S_D;
11534 case FLOAT_2BIT_FMT(CVT_S, FMT_DWL_W):
11535 mips32_op = OPC_CVT_S_W;
11537 case FLOAT_2BIT_FMT(CVT_S, FMT_DWL_L):
11538 mips32_op = OPC_CVT_S_L;
11540 gen_farith(ctx, mips32_op, -1, rs, rt, 0);
11543 /* Conditional moves on floating-point codes */
11544 case COND_FLOAT_MOV(MOVT, 0):
11545 case COND_FLOAT_MOV(MOVT, 1):
11546 case COND_FLOAT_MOV(MOVT, 2):
11547 case COND_FLOAT_MOV(MOVT, 3):
11548 case COND_FLOAT_MOV(MOVT, 4):
11549 case COND_FLOAT_MOV(MOVT, 5):
11550 case COND_FLOAT_MOV(MOVT, 6):
11551 case COND_FLOAT_MOV(MOVT, 7):
11552 gen_movci(ctx, rt, rs, (ctx->opcode >> 13) & 0x7, 1);
11554 case COND_FLOAT_MOV(MOVF, 0):
11555 case COND_FLOAT_MOV(MOVF, 1):
11556 case COND_FLOAT_MOV(MOVF, 2):
11557 case COND_FLOAT_MOV(MOVF, 3):
11558 case COND_FLOAT_MOV(MOVF, 4):
11559 case COND_FLOAT_MOV(MOVF, 5):
11560 case COND_FLOAT_MOV(MOVF, 6):
11561 case COND_FLOAT_MOV(MOVF, 7):
11562 gen_movci(ctx, rt, rs, (ctx->opcode >> 13) & 0x7, 0);
11565 MIPS_INVAL("pool32fxf");
11566 generate_exception(ctx, EXCP_RI);
11571 static void decode_micromips32_opc (CPUMIPSState *env, DisasContext *ctx,
11572 uint16_t insn_hw1, int *is_branch)
11576 int rt, rs, rd, rr;
11578 uint32_t op, minor, mips32_op;
11579 uint32_t cond, fmt, cc;
11581 insn = cpu_lduw_code(env, ctx->pc + 2);
11582 ctx->opcode = (ctx->opcode << 16) | insn;
11584 rt = (ctx->opcode >> 21) & 0x1f;
11585 rs = (ctx->opcode >> 16) & 0x1f;
11586 rd = (ctx->opcode >> 11) & 0x1f;
11587 rr = (ctx->opcode >> 6) & 0x1f;
11588 imm = (int16_t) ctx->opcode;
11590 op = (ctx->opcode >> 26) & 0x3f;
11593 minor = ctx->opcode & 0x3f;
11596 minor = (ctx->opcode >> 6) & 0xf;
11599 mips32_op = OPC_SLL;
11602 mips32_op = OPC_SRA;
11605 mips32_op = OPC_SRL;
11608 mips32_op = OPC_ROTR;
11610 gen_shift_imm(env, ctx, mips32_op, rt, rs, rd);
11613 goto pool32a_invalid;
11617 minor = (ctx->opcode >> 6) & 0xf;
11621 mips32_op = OPC_ADD;
11624 mips32_op = OPC_ADDU;
11627 mips32_op = OPC_SUB;
11630 mips32_op = OPC_SUBU;
11633 mips32_op = OPC_MUL;
11635 gen_arith(env, ctx, mips32_op, rd, rs, rt);
11639 mips32_op = OPC_SLLV;
11642 mips32_op = OPC_SRLV;
11645 mips32_op = OPC_SRAV;
11648 mips32_op = OPC_ROTRV;
11650 gen_shift(env, ctx, mips32_op, rd, rs, rt);
11652 /* Logical operations */
11654 mips32_op = OPC_AND;
11657 mips32_op = OPC_OR;
11660 mips32_op = OPC_NOR;
11663 mips32_op = OPC_XOR;
11665 gen_logic(env, ctx, mips32_op, rd, rs, rt);
11667 /* Set less than */
11669 mips32_op = OPC_SLT;
11672 mips32_op = OPC_SLTU;
11674 gen_slt(env, ctx, mips32_op, rd, rs, rt);
11677 goto pool32a_invalid;
11681 minor = (ctx->opcode >> 6) & 0xf;
11683 /* Conditional moves */
11685 mips32_op = OPC_MOVN;
11688 mips32_op = OPC_MOVZ;
11690 gen_cond_move(env, ctx, mips32_op, rd, rs, rt);
11693 gen_ldxs(ctx, rs, rt, rd);
11696 goto pool32a_invalid;
11700 gen_bitops(ctx, OPC_INS, rt, rs, rr, rd);
11703 gen_bitops(ctx, OPC_EXT, rt, rs, rr, rd);
11706 gen_pool32axf(env, ctx, rt, rs, is_branch);
11709 generate_exception(ctx, EXCP_BREAK);
11713 MIPS_INVAL("pool32a");
11714 generate_exception(ctx, EXCP_RI);
11719 minor = (ctx->opcode >> 12) & 0xf;
11722 check_cp0_enabled(ctx);
11723 /* Treat as no-op. */
11727 /* COP2: Not implemented. */
11728 generate_exception_err(ctx, EXCP_CpU, 2);
11732 #ifdef TARGET_MIPS64
11736 gen_ldst_pair(ctx, minor, rt, rs, SIMM(ctx->opcode, 0, 12));
11740 #ifdef TARGET_MIPS64
11744 gen_ldst_multiple(ctx, minor, rt, rs, SIMM(ctx->opcode, 0, 12));
11747 MIPS_INVAL("pool32b");
11748 generate_exception(ctx, EXCP_RI);
11753 if (env->CP0_Config1 & (1 << CP0C1_FP)) {
11754 minor = ctx->opcode & 0x3f;
11755 check_cp1_enabled(ctx);
11758 mips32_op = OPC_ALNV_PS;
11761 mips32_op = OPC_MADD_S;
11764 mips32_op = OPC_MADD_D;
11767 mips32_op = OPC_MADD_PS;
11770 mips32_op = OPC_MSUB_S;
11773 mips32_op = OPC_MSUB_D;
11776 mips32_op = OPC_MSUB_PS;
11779 mips32_op = OPC_NMADD_S;
11782 mips32_op = OPC_NMADD_D;
11785 mips32_op = OPC_NMADD_PS;
11788 mips32_op = OPC_NMSUB_S;
11791 mips32_op = OPC_NMSUB_D;
11794 mips32_op = OPC_NMSUB_PS;
11796 gen_flt3_arith(ctx, mips32_op, rd, rr, rs, rt);
11798 case CABS_COND_FMT:
11799 cond = (ctx->opcode >> 6) & 0xf;
11800 cc = (ctx->opcode >> 13) & 0x7;
11801 fmt = (ctx->opcode >> 10) & 0x3;
11804 gen_cmpabs_s(ctx, cond, rt, rs, cc);
11807 gen_cmpabs_d(ctx, cond, rt, rs, cc);
11810 gen_cmpabs_ps(ctx, cond, rt, rs, cc);
11813 goto pool32f_invalid;
11817 cond = (ctx->opcode >> 6) & 0xf;
11818 cc = (ctx->opcode >> 13) & 0x7;
11819 fmt = (ctx->opcode >> 10) & 0x3;
11822 gen_cmp_s(ctx, cond, rt, rs, cc);
11825 gen_cmp_d(ctx, cond, rt, rs, cc);
11828 gen_cmp_ps(ctx, cond, rt, rs, cc);
11831 goto pool32f_invalid;
11835 gen_pool32fxf(env, ctx, rt, rs);
11839 switch ((ctx->opcode >> 6) & 0x7) {
11841 mips32_op = OPC_PLL_PS;
11844 mips32_op = OPC_PLU_PS;
11847 mips32_op = OPC_PUL_PS;
11850 mips32_op = OPC_PUU_PS;
11853 mips32_op = OPC_CVT_PS_S;
11855 gen_farith(ctx, mips32_op, rt, rs, rd, 0);
11858 goto pool32f_invalid;
11863 switch ((ctx->opcode >> 6) & 0x7) {
11865 mips32_op = OPC_LWXC1;
11868 mips32_op = OPC_SWXC1;
11871 mips32_op = OPC_LDXC1;
11874 mips32_op = OPC_SDXC1;
11877 mips32_op = OPC_LUXC1;
11880 mips32_op = OPC_SUXC1;
11882 gen_flt3_ldst(ctx, mips32_op, rd, rd, rt, rs);
11885 goto pool32f_invalid;
11890 fmt = (ctx->opcode >> 9) & 0x3;
11891 switch ((ctx->opcode >> 6) & 0x7) {
11895 mips32_op = OPC_RSQRT2_S;
11898 mips32_op = OPC_RSQRT2_D;
11901 mips32_op = OPC_RSQRT2_PS;
11904 goto pool32f_invalid;
11910 mips32_op = OPC_RECIP2_S;
11913 mips32_op = OPC_RECIP2_D;
11916 mips32_op = OPC_RECIP2_PS;
11919 goto pool32f_invalid;
11923 mips32_op = OPC_ADDR_PS;
11926 mips32_op = OPC_MULR_PS;
11928 gen_farith(ctx, mips32_op, rt, rs, rd, 0);
11931 goto pool32f_invalid;
11935 /* MOV[FT].fmt and PREFX */
11936 cc = (ctx->opcode >> 13) & 0x7;
11937 fmt = (ctx->opcode >> 9) & 0x3;
11938 switch ((ctx->opcode >> 6) & 0x7) {
11942 gen_movcf_s(rs, rt, cc, 0);
11945 gen_movcf_d(ctx, rs, rt, cc, 0);
11948 gen_movcf_ps(rs, rt, cc, 0);
11951 goto pool32f_invalid;
11957 gen_movcf_s(rs, rt, cc, 1);
11960 gen_movcf_d(ctx, rs, rt, cc, 1);
11963 gen_movcf_ps(rs, rt, cc, 1);
11966 goto pool32f_invalid;
11972 goto pool32f_invalid;
11975 #define FINSN_3ARG_SDPS(prfx) \
11976 switch ((ctx->opcode >> 8) & 0x3) { \
11978 mips32_op = OPC_##prfx##_S; \
11981 mips32_op = OPC_##prfx##_D; \
11983 case FMT_SDPS_PS: \
11984 mips32_op = OPC_##prfx##_PS; \
11987 goto pool32f_invalid; \
11990 /* regular FP ops */
11991 switch ((ctx->opcode >> 6) & 0x3) {
11993 FINSN_3ARG_SDPS(ADD);
11996 FINSN_3ARG_SDPS(SUB);
11999 FINSN_3ARG_SDPS(MUL);
12002 fmt = (ctx->opcode >> 8) & 0x3;
12004 mips32_op = OPC_DIV_D;
12005 } else if (fmt == 0) {
12006 mips32_op = OPC_DIV_S;
12008 goto pool32f_invalid;
12012 goto pool32f_invalid;
12017 switch ((ctx->opcode >> 6) & 0x3) {
12019 FINSN_3ARG_SDPS(MOVN);
12022 FINSN_3ARG_SDPS(MOVZ);
12025 goto pool32f_invalid;
12029 gen_farith(ctx, mips32_op, rt, rs, rd, 0);
12033 MIPS_INVAL("pool32f");
12034 generate_exception(ctx, EXCP_RI);
12038 generate_exception_err(ctx, EXCP_CpU, 1);
12042 minor = (ctx->opcode >> 21) & 0x1f;
12045 mips32_op = OPC_BLTZ;
12048 mips32_op = OPC_BLTZAL;
12051 mips32_op = OPC_BLTZALS;
12054 mips32_op = OPC_BGEZ;
12057 mips32_op = OPC_BGEZAL;
12060 mips32_op = OPC_BGEZALS;
12063 mips32_op = OPC_BLEZ;
12066 mips32_op = OPC_BGTZ;
12068 gen_compute_branch(ctx, mips32_op, 4, rs, -1, imm << 1);
12074 mips32_op = OPC_TLTI;
12077 mips32_op = OPC_TGEI;
12080 mips32_op = OPC_TLTIU;
12083 mips32_op = OPC_TGEIU;
12086 mips32_op = OPC_TNEI;
12089 mips32_op = OPC_TEQI;
12091 gen_trap(ctx, mips32_op, rs, -1, imm);
12096 gen_compute_branch(ctx, minor == BNEZC ? OPC_BNE : OPC_BEQ,
12097 4, rs, 0, imm << 1);
12098 /* Compact branches don't have a delay slot, so just let
12099 the normal delay slot handling take us to the branch
12103 gen_logic_imm(env, ctx, OPC_LUI, rs, -1, imm);
12109 /* COP2: Not implemented. */
12110 generate_exception_err(ctx, EXCP_CpU, 2);
12113 mips32_op = (ctx->opcode & (1 << 16)) ? OPC_BC1FANY2 : OPC_BC1F;
12116 mips32_op = (ctx->opcode & (1 << 16)) ? OPC_BC1TANY2 : OPC_BC1T;
12119 mips32_op = OPC_BC1FANY4;
12122 mips32_op = OPC_BC1TANY4;
12125 check_insn(env, ctx, ASE_MIPS3D);
12128 gen_compute_branch1(env, ctx, mips32_op,
12129 (ctx->opcode >> 18) & 0x7, imm << 1);
12134 /* MIPS DSP: not implemented */
12137 MIPS_INVAL("pool32i");
12138 generate_exception(ctx, EXCP_RI);
12143 minor = (ctx->opcode >> 12) & 0xf;
12146 mips32_op = OPC_LWL;
12149 mips32_op = OPC_SWL;
12152 mips32_op = OPC_LWR;
12155 mips32_op = OPC_SWR;
12157 #if defined(TARGET_MIPS64)
12159 mips32_op = OPC_LDL;
12162 mips32_op = OPC_SDL;
12165 mips32_op = OPC_LDR;
12168 mips32_op = OPC_SDR;
12171 mips32_op = OPC_LWU;
12174 mips32_op = OPC_LLD;
12178 mips32_op = OPC_LL;
12181 gen_ld(env, ctx, mips32_op, rt, rs, SIMM(ctx->opcode, 0, 12));
12184 gen_st(ctx, mips32_op, rt, rs, SIMM(ctx->opcode, 0, 12));
12187 gen_st_cond(ctx, OPC_SC, rt, rs, SIMM(ctx->opcode, 0, 12));
12189 #if defined(TARGET_MIPS64)
12191 gen_st_cond(ctx, OPC_SCD, rt, rs, SIMM(ctx->opcode, 0, 12));
12195 /* Treat as no-op */
12198 MIPS_INVAL("pool32c");
12199 generate_exception(ctx, EXCP_RI);
12204 mips32_op = OPC_ADDI;
12207 mips32_op = OPC_ADDIU;
12209 gen_arith_imm(env, ctx, mips32_op, rt, rs, imm);
12212 /* Logical operations */
12214 mips32_op = OPC_ORI;
12217 mips32_op = OPC_XORI;
12220 mips32_op = OPC_ANDI;
12222 gen_logic_imm(env, ctx, mips32_op, rt, rs, imm);
12225 /* Set less than immediate */
12227 mips32_op = OPC_SLTI;
12230 mips32_op = OPC_SLTIU;
12232 gen_slt_imm(env, ctx, mips32_op, rt, rs, imm);
12235 offset = (int32_t)(ctx->opcode & 0x3FFFFFF) << 2;
12236 gen_compute_branch(ctx, OPC_JALX, 4, rt, rs, offset);
12240 offset = (int32_t)(ctx->opcode & 0x3FFFFFF) << 1;
12241 gen_compute_branch(ctx, OPC_JALS, 4, rt, rs, offset);
12245 gen_compute_branch(ctx, OPC_BEQ, 4, rt, rs, imm << 1);
12249 gen_compute_branch(ctx, OPC_BNE, 4, rt, rs, imm << 1);
12253 gen_compute_branch(ctx, OPC_J, 4, rt, rs,
12254 (int32_t)(ctx->opcode & 0x3FFFFFF) << 1);
12258 gen_compute_branch(ctx, OPC_JAL, 4, rt, rs,
12259 (int32_t)(ctx->opcode & 0x3FFFFFF) << 1);
12262 /* Floating point (COP1) */
12264 mips32_op = OPC_LWC1;
12267 mips32_op = OPC_LDC1;
12270 mips32_op = OPC_SWC1;
12273 mips32_op = OPC_SDC1;
12275 gen_cop1_ldst(env, ctx, mips32_op, rt, rs, imm);
12279 int reg = mmreg(ZIMM(ctx->opcode, 23, 3));
12280 int offset = SIMM(ctx->opcode, 0, 23) << 2;
12282 gen_addiupc(ctx, reg, offset, 0, 0);
12285 /* Loads and stores */
12287 mips32_op = OPC_LB;
12290 mips32_op = OPC_LBU;
12293 mips32_op = OPC_LH;
12296 mips32_op = OPC_LHU;
12299 mips32_op = OPC_LW;
12301 #ifdef TARGET_MIPS64
12303 mips32_op = OPC_LD;
12306 mips32_op = OPC_SD;
12310 mips32_op = OPC_SB;
12313 mips32_op = OPC_SH;
12316 mips32_op = OPC_SW;
12319 gen_ld(env, ctx, mips32_op, rt, rs, imm);
12322 gen_st(ctx, mips32_op, rt, rs, imm);
12325 generate_exception(ctx, EXCP_RI);
12330 static int decode_micromips_opc (CPUMIPSState *env, DisasContext *ctx, int *is_branch)
12334 /* make sure instructions are on a halfword boundary */
12335 if (ctx->pc & 0x1) {
12336 env->CP0_BadVAddr = ctx->pc;
12337 generate_exception(ctx, EXCP_AdEL);
12338 ctx->bstate = BS_STOP;
12342 op = (ctx->opcode >> 10) & 0x3f;
12343 /* Enforce properly-sized instructions in a delay slot */
12344 if (ctx->hflags & MIPS_HFLAG_BMASK) {
12345 int bits = ctx->hflags & MIPS_HFLAG_BMASK_EXT;
12379 case POOL48A: /* ??? */
12384 if (bits & MIPS_HFLAG_BDS16) {
12385 generate_exception(ctx, EXCP_RI);
12386 /* Just stop translation; the user is confused. */
12387 ctx->bstate = BS_STOP;
12412 if (bits & MIPS_HFLAG_BDS32) {
12413 generate_exception(ctx, EXCP_RI);
12414 /* Just stop translation; the user is confused. */
12415 ctx->bstate = BS_STOP;
12426 int rd = mmreg(uMIPS_RD(ctx->opcode));
12427 int rs1 = mmreg(uMIPS_RS1(ctx->opcode));
12428 int rs2 = mmreg(uMIPS_RS2(ctx->opcode));
12431 switch (ctx->opcode & 0x1) {
12440 gen_arith(env, ctx, opc, rd, rs1, rs2);
12445 int rd = mmreg(uMIPS_RD(ctx->opcode));
12446 int rs = mmreg(uMIPS_RS(ctx->opcode));
12447 int amount = (ctx->opcode >> 1) & 0x7;
12449 amount = amount == 0 ? 8 : amount;
12451 switch (ctx->opcode & 0x1) {
12460 gen_shift_imm(env, ctx, opc, rd, rs, amount);
12464 gen_pool16c_insn(env, ctx, is_branch);
12468 int rd = mmreg(uMIPS_RD(ctx->opcode));
12469 int rb = 28; /* GP */
12470 int16_t offset = SIMM(ctx->opcode, 0, 7) << 2;
12472 gen_ld(env, ctx, OPC_LW, rd, rb, offset);
12476 if (ctx->opcode & 1) {
12477 generate_exception(ctx, EXCP_RI);
12480 int enc_dest = uMIPS_RD(ctx->opcode);
12481 int enc_rt = uMIPS_RS2(ctx->opcode);
12482 int enc_rs = uMIPS_RS1(ctx->opcode);
12483 int rd, rs, re, rt;
12484 static const int rd_enc[] = { 5, 5, 6, 4, 4, 4, 4, 4 };
12485 static const int re_enc[] = { 6, 7, 7, 21, 22, 5, 6, 7 };
12486 static const int rs_rt_enc[] = { 0, 17, 2, 3, 16, 18, 19, 20 };
12488 rd = rd_enc[enc_dest];
12489 re = re_enc[enc_dest];
12490 rs = rs_rt_enc[enc_rs];
12491 rt = rs_rt_enc[enc_rt];
12493 gen_arith_imm(env, ctx, OPC_ADDIU, rd, rs, 0);
12494 gen_arith_imm(env, ctx, OPC_ADDIU, re, rt, 0);
12499 int rd = mmreg(uMIPS_RD(ctx->opcode));
12500 int rb = mmreg(uMIPS_RS(ctx->opcode));
12501 int16_t offset = ZIMM(ctx->opcode, 0, 4);
12502 offset = (offset == 0xf ? -1 : offset);
12504 gen_ld(env, ctx, OPC_LBU, rd, rb, offset);
12509 int rd = mmreg(uMIPS_RD(ctx->opcode));
12510 int rb = mmreg(uMIPS_RS(ctx->opcode));
12511 int16_t offset = ZIMM(ctx->opcode, 0, 4) << 1;
12513 gen_ld(env, ctx, OPC_LHU, rd, rb, offset);
12518 int rd = (ctx->opcode >> 5) & 0x1f;
12519 int rb = 29; /* SP */
12520 int16_t offset = ZIMM(ctx->opcode, 0, 5) << 2;
12522 gen_ld(env, ctx, OPC_LW, rd, rb, offset);
12527 int rd = mmreg(uMIPS_RD(ctx->opcode));
12528 int rb = mmreg(uMIPS_RS(ctx->opcode));
12529 int16_t offset = ZIMM(ctx->opcode, 0, 4) << 2;
12531 gen_ld(env, ctx, OPC_LW, rd, rb, offset);
12536 int rd = mmreg2(uMIPS_RD(ctx->opcode));
12537 int rb = mmreg(uMIPS_RS(ctx->opcode));
12538 int16_t offset = ZIMM(ctx->opcode, 0, 4);
12540 gen_st(ctx, OPC_SB, rd, rb, offset);
12545 int rd = mmreg2(uMIPS_RD(ctx->opcode));
12546 int rb = mmreg(uMIPS_RS(ctx->opcode));
12547 int16_t offset = ZIMM(ctx->opcode, 0, 4) << 1;
12549 gen_st(ctx, OPC_SH, rd, rb, offset);
12554 int rd = (ctx->opcode >> 5) & 0x1f;
12555 int rb = 29; /* SP */
12556 int16_t offset = ZIMM(ctx->opcode, 0, 5) << 2;
12558 gen_st(ctx, OPC_SW, rd, rb, offset);
12563 int rd = mmreg2(uMIPS_RD(ctx->opcode));
12564 int rb = mmreg(uMIPS_RS(ctx->opcode));
12565 int16_t offset = ZIMM(ctx->opcode, 0, 4) << 2;
12567 gen_st(ctx, OPC_SW, rd, rb, offset);
12572 int rd = uMIPS_RD5(ctx->opcode);
12573 int rs = uMIPS_RS5(ctx->opcode);
12575 gen_arith_imm(env, ctx, OPC_ADDIU, rd, rs, 0);
12579 gen_andi16(env, ctx);
12582 switch (ctx->opcode & 0x1) {
12584 gen_addius5(env, ctx);
12587 gen_addiusp(env, ctx);
12592 switch (ctx->opcode & 0x1) {
12594 gen_addiur2(env, ctx);
12597 gen_addiur1sp(env, ctx);
12602 gen_compute_branch(ctx, OPC_BEQ, 2, 0, 0,
12603 SIMM(ctx->opcode, 0, 10) << 1);
12608 gen_compute_branch(ctx, op == BNEZ16 ? OPC_BNE : OPC_BEQ, 2,
12609 mmreg(uMIPS_RD(ctx->opcode)),
12610 0, SIMM(ctx->opcode, 0, 7) << 1);
12615 int reg = mmreg(uMIPS_RD(ctx->opcode));
12616 int imm = ZIMM(ctx->opcode, 0, 7);
12618 imm = (imm == 0x7f ? -1 : imm);
12619 tcg_gen_movi_tl(cpu_gpr[reg], imm);
12629 generate_exception(ctx, EXCP_RI);
12632 decode_micromips32_opc (env, ctx, op, is_branch);
12639 /* SmartMIPS extension to MIPS32 */
12641 #if defined(TARGET_MIPS64)
12643 /* MDMX extension to MIPS64 */
12647 /* MIPSDSP functions. */
12648 static void gen_mipsdsp_ld(CPUMIPSState *env, DisasContext *ctx, uint32_t opc,
12649 int rd, int base, int offset)
12651 const char *opn = "ldx";
12660 t0 = tcg_temp_new();
12663 gen_load_gpr(t0, offset);
12664 } else if (offset == 0) {
12665 gen_load_gpr(t0, base);
12667 gen_op_addr_add(ctx, t0, cpu_gpr[base], cpu_gpr[offset]);
12672 tcg_gen_qemu_ld8u(t0, t0, ctx->mem_idx);
12673 gen_store_gpr(t0, rd);
12677 tcg_gen_qemu_ld16s(t0, t0, ctx->mem_idx);
12678 gen_store_gpr(t0, rd);
12682 tcg_gen_qemu_ld32s(t0, t0, ctx->mem_idx);
12683 gen_store_gpr(t0, rd);
12686 #if defined(TARGET_MIPS64)
12688 tcg_gen_qemu_ld64(t0, t0, ctx->mem_idx);
12689 gen_store_gpr(t0, rd);
12694 (void)opn; /* avoid a compiler warning */
12695 MIPS_DEBUG("%s %s, %s(%s)", opn,
12696 regnames[rd], regnames[offset], regnames[base]);
12700 static void gen_mipsdsp_arith(DisasContext *ctx, uint32_t op1, uint32_t op2,
12701 int ret, int v1, int v2)
12703 const char *opn = "mipsdsp arith";
12708 /* Treat as NOP. */
12713 v1_t = tcg_temp_new();
12714 v2_t = tcg_temp_new();
12716 gen_load_gpr(v1_t, v1);
12717 gen_load_gpr(v2_t, v2);
12720 /* OPC_MULT_G_2E is equal OPC_ADDUH_QB_DSP */
12721 case OPC_MULT_G_2E:
12725 gen_helper_adduh_qb(cpu_gpr[ret], v1_t, v2_t);
12727 case OPC_ADDUH_R_QB:
12728 gen_helper_adduh_r_qb(cpu_gpr[ret], v1_t, v2_t);
12731 gen_helper_addqh_ph(cpu_gpr[ret], v1_t, v2_t);
12733 case OPC_ADDQH_R_PH:
12734 gen_helper_addqh_r_ph(cpu_gpr[ret], v1_t, v2_t);
12737 gen_helper_addqh_w(cpu_gpr[ret], v1_t, v2_t);
12739 case OPC_ADDQH_R_W:
12740 gen_helper_addqh_r_w(cpu_gpr[ret], v1_t, v2_t);
12743 gen_helper_subuh_qb(cpu_gpr[ret], v1_t, v2_t);
12745 case OPC_SUBUH_R_QB:
12746 gen_helper_subuh_r_qb(cpu_gpr[ret], v1_t, v2_t);
12749 gen_helper_subqh_ph(cpu_gpr[ret], v1_t, v2_t);
12751 case OPC_SUBQH_R_PH:
12752 gen_helper_subqh_r_ph(cpu_gpr[ret], v1_t, v2_t);
12755 gen_helper_subqh_w(cpu_gpr[ret], v1_t, v2_t);
12757 case OPC_SUBQH_R_W:
12758 gen_helper_subqh_r_w(cpu_gpr[ret], v1_t, v2_t);
12762 case OPC_ABSQ_S_PH_DSP:
12764 case OPC_ABSQ_S_QB:
12766 gen_helper_absq_s_qb(cpu_gpr[ret], v2_t, cpu_env);
12768 case OPC_ABSQ_S_PH:
12770 gen_helper_absq_s_ph(cpu_gpr[ret], v2_t, cpu_env);
12774 gen_helper_absq_s_w(cpu_gpr[ret], v2_t, cpu_env);
12776 case OPC_PRECEQ_W_PHL:
12778 tcg_gen_andi_tl(cpu_gpr[ret], v2_t, 0xFFFF0000);
12779 tcg_gen_ext32s_tl(cpu_gpr[ret], cpu_gpr[ret]);
12781 case OPC_PRECEQ_W_PHR:
12783 tcg_gen_andi_tl(cpu_gpr[ret], v2_t, 0x0000FFFF);
12784 tcg_gen_shli_tl(cpu_gpr[ret], cpu_gpr[ret], 16);
12785 tcg_gen_ext32s_tl(cpu_gpr[ret], cpu_gpr[ret]);
12787 case OPC_PRECEQU_PH_QBL:
12789 gen_helper_precequ_ph_qbl(cpu_gpr[ret], v2_t);
12791 case OPC_PRECEQU_PH_QBR:
12793 gen_helper_precequ_ph_qbr(cpu_gpr[ret], v2_t);
12795 case OPC_PRECEQU_PH_QBLA:
12797 gen_helper_precequ_ph_qbla(cpu_gpr[ret], v2_t);
12799 case OPC_PRECEQU_PH_QBRA:
12801 gen_helper_precequ_ph_qbra(cpu_gpr[ret], v2_t);
12803 case OPC_PRECEU_PH_QBL:
12805 gen_helper_preceu_ph_qbl(cpu_gpr[ret], v2_t);
12807 case OPC_PRECEU_PH_QBR:
12809 gen_helper_preceu_ph_qbr(cpu_gpr[ret], v2_t);
12811 case OPC_PRECEU_PH_QBLA:
12813 gen_helper_preceu_ph_qbla(cpu_gpr[ret], v2_t);
12815 case OPC_PRECEU_PH_QBRA:
12817 gen_helper_preceu_ph_qbra(cpu_gpr[ret], v2_t);
12821 case OPC_ADDU_QB_DSP:
12825 gen_helper_addq_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12827 case OPC_ADDQ_S_PH:
12829 gen_helper_addq_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12833 gen_helper_addq_s_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12837 gen_helper_addu_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12839 case OPC_ADDU_S_QB:
12841 gen_helper_addu_s_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12845 gen_helper_addu_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12847 case OPC_ADDU_S_PH:
12849 gen_helper_addu_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12853 gen_helper_subq_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12855 case OPC_SUBQ_S_PH:
12857 gen_helper_subq_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12861 gen_helper_subq_s_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12865 gen_helper_subu_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12867 case OPC_SUBU_S_QB:
12869 gen_helper_subu_s_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12873 gen_helper_subu_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12875 case OPC_SUBU_S_PH:
12877 gen_helper_subu_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12881 gen_helper_addsc(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12885 gen_helper_addwc(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12889 gen_helper_modsub(cpu_gpr[ret], v1_t, v2_t);
12891 case OPC_RADDU_W_QB:
12893 gen_helper_raddu_w_qb(cpu_gpr[ret], v1_t);
12897 case OPC_CMPU_EQ_QB_DSP:
12899 case OPC_PRECR_QB_PH:
12901 gen_helper_precr_qb_ph(cpu_gpr[ret], v1_t, v2_t);
12903 case OPC_PRECRQ_QB_PH:
12905 gen_helper_precrq_qb_ph(cpu_gpr[ret], v1_t, v2_t);
12907 case OPC_PRECR_SRA_PH_W:
12910 TCGv_i32 sa_t = tcg_const_i32(v2);
12911 gen_helper_precr_sra_ph_w(cpu_gpr[ret], sa_t, v1_t,
12913 tcg_temp_free_i32(sa_t);
12916 case OPC_PRECR_SRA_R_PH_W:
12919 TCGv_i32 sa_t = tcg_const_i32(v2);
12920 gen_helper_precr_sra_r_ph_w(cpu_gpr[ret], sa_t, v1_t,
12922 tcg_temp_free_i32(sa_t);
12925 case OPC_PRECRQ_PH_W:
12927 gen_helper_precrq_ph_w(cpu_gpr[ret], v1_t, v2_t);
12929 case OPC_PRECRQ_RS_PH_W:
12931 gen_helper_precrq_rs_ph_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12933 case OPC_PRECRQU_S_QB_PH:
12935 gen_helper_precrqu_s_qb_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12939 #ifdef TARGET_MIPS64
12940 case OPC_ABSQ_S_QH_DSP:
12942 case OPC_PRECEQ_L_PWL:
12944 tcg_gen_andi_tl(cpu_gpr[ret], v2_t, 0xFFFFFFFF00000000ull);
12946 case OPC_PRECEQ_L_PWR:
12948 tcg_gen_shli_tl(cpu_gpr[ret], v2_t, 32);
12950 case OPC_PRECEQ_PW_QHL:
12952 gen_helper_preceq_pw_qhl(cpu_gpr[ret], v2_t);
12954 case OPC_PRECEQ_PW_QHR:
12956 gen_helper_preceq_pw_qhr(cpu_gpr[ret], v2_t);
12958 case OPC_PRECEQ_PW_QHLA:
12960 gen_helper_preceq_pw_qhla(cpu_gpr[ret], v2_t);
12962 case OPC_PRECEQ_PW_QHRA:
12964 gen_helper_preceq_pw_qhra(cpu_gpr[ret], v2_t);
12966 case OPC_PRECEQU_QH_OBL:
12968 gen_helper_precequ_qh_obl(cpu_gpr[ret], v2_t);
12970 case OPC_PRECEQU_QH_OBR:
12972 gen_helper_precequ_qh_obr(cpu_gpr[ret], v2_t);
12974 case OPC_PRECEQU_QH_OBLA:
12976 gen_helper_precequ_qh_obla(cpu_gpr[ret], v2_t);
12978 case OPC_PRECEQU_QH_OBRA:
12980 gen_helper_precequ_qh_obra(cpu_gpr[ret], v2_t);
12982 case OPC_PRECEU_QH_OBL:
12984 gen_helper_preceu_qh_obl(cpu_gpr[ret], v2_t);
12986 case OPC_PRECEU_QH_OBR:
12988 gen_helper_preceu_qh_obr(cpu_gpr[ret], v2_t);
12990 case OPC_PRECEU_QH_OBLA:
12992 gen_helper_preceu_qh_obla(cpu_gpr[ret], v2_t);
12994 case OPC_PRECEU_QH_OBRA:
12996 gen_helper_preceu_qh_obra(cpu_gpr[ret], v2_t);
12998 case OPC_ABSQ_S_OB:
13000 gen_helper_absq_s_ob(cpu_gpr[ret], v2_t, cpu_env);
13002 case OPC_ABSQ_S_PW:
13004 gen_helper_absq_s_pw(cpu_gpr[ret], v2_t, cpu_env);
13006 case OPC_ABSQ_S_QH:
13008 gen_helper_absq_s_qh(cpu_gpr[ret], v2_t, cpu_env);
13012 case OPC_ADDU_OB_DSP:
13014 case OPC_RADDU_L_OB:
13016 gen_helper_raddu_l_ob(cpu_gpr[ret], v1_t);
13020 gen_helper_subq_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13022 case OPC_SUBQ_S_PW:
13024 gen_helper_subq_s_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13028 gen_helper_subq_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13030 case OPC_SUBQ_S_QH:
13032 gen_helper_subq_s_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13036 gen_helper_subu_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13038 case OPC_SUBU_S_OB:
13040 gen_helper_subu_s_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13044 gen_helper_subu_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13046 case OPC_SUBU_S_QH:
13048 gen_helper_subu_s_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13052 gen_helper_subuh_ob(cpu_gpr[ret], v1_t, v2_t);
13054 case OPC_SUBUH_R_OB:
13056 gen_helper_subuh_r_ob(cpu_gpr[ret], v1_t, v2_t);
13060 gen_helper_addq_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13062 case OPC_ADDQ_S_PW:
13064 gen_helper_addq_s_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13068 gen_helper_addq_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13070 case OPC_ADDQ_S_QH:
13072 gen_helper_addq_s_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13076 gen_helper_addu_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13078 case OPC_ADDU_S_OB:
13080 gen_helper_addu_s_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13084 gen_helper_addu_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13086 case OPC_ADDU_S_QH:
13088 gen_helper_addu_s_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13092 gen_helper_adduh_ob(cpu_gpr[ret], v1_t, v2_t);
13094 case OPC_ADDUH_R_OB:
13096 gen_helper_adduh_r_ob(cpu_gpr[ret], v1_t, v2_t);
13100 case OPC_CMPU_EQ_OB_DSP:
13102 case OPC_PRECR_OB_QH:
13104 gen_helper_precr_ob_qh(cpu_gpr[ret], v1_t, v2_t);
13106 case OPC_PRECR_SRA_QH_PW:
13109 TCGv_i32 ret_t = tcg_const_i32(ret);
13110 gen_helper_precr_sra_qh_pw(v2_t, v1_t, v2_t, ret_t);
13111 tcg_temp_free_i32(ret_t);
13114 case OPC_PRECR_SRA_R_QH_PW:
13117 TCGv_i32 sa_v = tcg_const_i32(ret);
13118 gen_helper_precr_sra_r_qh_pw(v2_t, v1_t, v2_t, sa_v);
13119 tcg_temp_free_i32(sa_v);
13122 case OPC_PRECRQ_OB_QH:
13124 gen_helper_precrq_ob_qh(cpu_gpr[ret], v1_t, v2_t);
13126 case OPC_PRECRQ_PW_L:
13128 gen_helper_precrq_pw_l(cpu_gpr[ret], v1_t, v2_t);
13130 case OPC_PRECRQ_QH_PW:
13132 gen_helper_precrq_qh_pw(cpu_gpr[ret], v1_t, v2_t);
13134 case OPC_PRECRQ_RS_QH_PW:
13136 gen_helper_precrq_rs_qh_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13138 case OPC_PRECRQU_S_OB_QH:
13140 gen_helper_precrqu_s_ob_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13147 tcg_temp_free(v1_t);
13148 tcg_temp_free(v2_t);
13150 (void)opn; /* avoid a compiler warning */
13151 MIPS_DEBUG("%s", opn);
13154 static void gen_mipsdsp_shift(DisasContext *ctx, uint32_t opc,
13155 int ret, int v1, int v2)
13158 const char *opn = "mipsdsp shift";
13164 /* Treat as NOP. */
13169 t0 = tcg_temp_new();
13170 v1_t = tcg_temp_new();
13171 v2_t = tcg_temp_new();
13173 tcg_gen_movi_tl(t0, v1);
13174 gen_load_gpr(v1_t, v1);
13175 gen_load_gpr(v2_t, v2);
13178 case OPC_SHLL_QB_DSP:
13180 op2 = MASK_SHLL_QB(ctx->opcode);
13184 gen_helper_shll_qb(cpu_gpr[ret], t0, v2_t, cpu_env);
13188 gen_helper_shll_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13192 gen_helper_shll_ph(cpu_gpr[ret], t0, v2_t, cpu_env);
13196 gen_helper_shll_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13198 case OPC_SHLL_S_PH:
13200 gen_helper_shll_s_ph(cpu_gpr[ret], t0, v2_t, cpu_env);
13202 case OPC_SHLLV_S_PH:
13204 gen_helper_shll_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13208 gen_helper_shll_s_w(cpu_gpr[ret], t0, v2_t, cpu_env);
13210 case OPC_SHLLV_S_W:
13212 gen_helper_shll_s_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13216 gen_helper_shrl_qb(cpu_gpr[ret], t0, v2_t);
13220 gen_helper_shrl_qb(cpu_gpr[ret], v1_t, v2_t);
13224 gen_helper_shrl_ph(cpu_gpr[ret], t0, v2_t);
13228 gen_helper_shrl_ph(cpu_gpr[ret], v1_t, v2_t);
13232 gen_helper_shra_qb(cpu_gpr[ret], t0, v2_t);
13234 case OPC_SHRA_R_QB:
13236 gen_helper_shra_r_qb(cpu_gpr[ret], t0, v2_t);
13240 gen_helper_shra_qb(cpu_gpr[ret], v1_t, v2_t);
13242 case OPC_SHRAV_R_QB:
13244 gen_helper_shra_r_qb(cpu_gpr[ret], v1_t, v2_t);
13248 gen_helper_shra_ph(cpu_gpr[ret], t0, v2_t);
13250 case OPC_SHRA_R_PH:
13252 gen_helper_shra_r_ph(cpu_gpr[ret], t0, v2_t);
13256 gen_helper_shra_ph(cpu_gpr[ret], v1_t, v2_t);
13258 case OPC_SHRAV_R_PH:
13260 gen_helper_shra_r_ph(cpu_gpr[ret], v1_t, v2_t);
13264 gen_helper_shra_r_w(cpu_gpr[ret], t0, v2_t);
13266 case OPC_SHRAV_R_W:
13268 gen_helper_shra_r_w(cpu_gpr[ret], v1_t, v2_t);
13270 default: /* Invalid */
13271 MIPS_INVAL("MASK SHLL.QB");
13272 generate_exception(ctx, EXCP_RI);
13277 #ifdef TARGET_MIPS64
13278 case OPC_SHLL_OB_DSP:
13279 op2 = MASK_SHLL_OB(ctx->opcode);
13283 gen_helper_shll_pw(cpu_gpr[ret], v2_t, t0, cpu_env);
13287 gen_helper_shll_pw(cpu_gpr[ret], v2_t, v1_t, cpu_env);
13289 case OPC_SHLL_S_PW:
13291 gen_helper_shll_s_pw(cpu_gpr[ret], v2_t, t0, cpu_env);
13293 case OPC_SHLLV_S_PW:
13295 gen_helper_shll_s_pw(cpu_gpr[ret], v2_t, v1_t, cpu_env);
13299 gen_helper_shll_ob(cpu_gpr[ret], v2_t, t0, cpu_env);
13303 gen_helper_shll_ob(cpu_gpr[ret], v2_t, v1_t, cpu_env);
13307 gen_helper_shll_qh(cpu_gpr[ret], v2_t, t0, cpu_env);
13311 gen_helper_shll_qh(cpu_gpr[ret], v2_t, v1_t, cpu_env);
13313 case OPC_SHLL_S_QH:
13315 gen_helper_shll_s_qh(cpu_gpr[ret], v2_t, t0, cpu_env);
13317 case OPC_SHLLV_S_QH:
13319 gen_helper_shll_s_qh(cpu_gpr[ret], v2_t, v1_t, cpu_env);
13323 gen_helper_shra_ob(cpu_gpr[ret], v2_t, t0);
13327 gen_helper_shra_ob(cpu_gpr[ret], v2_t, v1_t);
13329 case OPC_SHRA_R_OB:
13331 gen_helper_shra_r_ob(cpu_gpr[ret], v2_t, t0);
13333 case OPC_SHRAV_R_OB:
13335 gen_helper_shra_r_ob(cpu_gpr[ret], v2_t, v1_t);
13339 gen_helper_shra_pw(cpu_gpr[ret], v2_t, t0);
13343 gen_helper_shra_pw(cpu_gpr[ret], v2_t, v1_t);
13345 case OPC_SHRA_R_PW:
13347 gen_helper_shra_r_pw(cpu_gpr[ret], v2_t, t0);
13349 case OPC_SHRAV_R_PW:
13351 gen_helper_shra_r_pw(cpu_gpr[ret], v2_t, v1_t);
13355 gen_helper_shra_qh(cpu_gpr[ret], v2_t, t0);
13359 gen_helper_shra_qh(cpu_gpr[ret], v2_t, v1_t);
13361 case OPC_SHRA_R_QH:
13363 gen_helper_shra_r_qh(cpu_gpr[ret], v2_t, t0);
13365 case OPC_SHRAV_R_QH:
13367 gen_helper_shra_r_qh(cpu_gpr[ret], v2_t, v1_t);
13371 gen_helper_shrl_ob(cpu_gpr[ret], v2_t, t0);
13375 gen_helper_shrl_ob(cpu_gpr[ret], v2_t, v1_t);
13379 gen_helper_shrl_qh(cpu_gpr[ret], v2_t, t0);
13383 gen_helper_shrl_qh(cpu_gpr[ret], v2_t, v1_t);
13385 default: /* Invalid */
13386 MIPS_INVAL("MASK SHLL.OB");
13387 generate_exception(ctx, EXCP_RI);
13395 tcg_temp_free(v1_t);
13396 tcg_temp_free(v2_t);
13397 (void)opn; /* avoid a compiler warning */
13398 MIPS_DEBUG("%s", opn);
13401 static void gen_mipsdsp_multiply(DisasContext *ctx, uint32_t op1, uint32_t op2,
13402 int ret, int v1, int v2, int check_ret)
13404 const char *opn = "mipsdsp multiply";
13409 if ((ret == 0) && (check_ret == 1)) {
13410 /* Treat as NOP. */
13415 t0 = tcg_temp_new_i32();
13416 v1_t = tcg_temp_new();
13417 v2_t = tcg_temp_new();
13419 tcg_gen_movi_i32(t0, ret);
13420 gen_load_gpr(v1_t, v1);
13421 gen_load_gpr(v2_t, v2);
13424 /* OPC_MULT_G_2E, OPC_ADDUH_QB_DSP, OPC_MUL_PH_DSP have
13425 * the same mask and op1. */
13426 case OPC_MULT_G_2E:
13429 gen_helper_mul_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13432 gen_helper_mul_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13435 gen_helper_mulq_s_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13437 case OPC_MULQ_RS_W:
13438 gen_helper_mulq_rs_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13442 case OPC_DPA_W_PH_DSP:
13444 case OPC_DPAU_H_QBL:
13446 gen_helper_dpau_h_qbl(t0, v1_t, v2_t, cpu_env);
13448 case OPC_DPAU_H_QBR:
13450 gen_helper_dpau_h_qbr(t0, v1_t, v2_t, cpu_env);
13452 case OPC_DPSU_H_QBL:
13454 gen_helper_dpsu_h_qbl(t0, v1_t, v2_t, cpu_env);
13456 case OPC_DPSU_H_QBR:
13458 gen_helper_dpsu_h_qbr(t0, v1_t, v2_t, cpu_env);
13462 gen_helper_dpa_w_ph(t0, v1_t, v2_t, cpu_env);
13464 case OPC_DPAX_W_PH:
13466 gen_helper_dpax_w_ph(t0, v1_t, v2_t, cpu_env);
13468 case OPC_DPAQ_S_W_PH:
13470 gen_helper_dpaq_s_w_ph(t0, v1_t, v2_t, cpu_env);
13472 case OPC_DPAQX_S_W_PH:
13474 gen_helper_dpaqx_s_w_ph(t0, v1_t, v2_t, cpu_env);
13476 case OPC_DPAQX_SA_W_PH:
13478 gen_helper_dpaqx_sa_w_ph(t0, v1_t, v2_t, cpu_env);
13482 gen_helper_dps_w_ph(t0, v1_t, v2_t, cpu_env);
13484 case OPC_DPSX_W_PH:
13486 gen_helper_dpsx_w_ph(t0, v1_t, v2_t, cpu_env);
13488 case OPC_DPSQ_S_W_PH:
13490 gen_helper_dpsq_s_w_ph(t0, v1_t, v2_t, cpu_env);
13492 case OPC_DPSQX_S_W_PH:
13494 gen_helper_dpsqx_s_w_ph(t0, v1_t, v2_t, cpu_env);
13496 case OPC_DPSQX_SA_W_PH:
13498 gen_helper_dpsqx_sa_w_ph(t0, v1_t, v2_t, cpu_env);
13500 case OPC_MULSAQ_S_W_PH:
13502 gen_helper_mulsaq_s_w_ph(t0, v1_t, v2_t, cpu_env);
13504 case OPC_DPAQ_SA_L_W:
13506 gen_helper_dpaq_sa_l_w(t0, v1_t, v2_t, cpu_env);
13508 case OPC_DPSQ_SA_L_W:
13510 gen_helper_dpsq_sa_l_w(t0, v1_t, v2_t, cpu_env);
13512 case OPC_MAQ_S_W_PHL:
13514 gen_helper_maq_s_w_phl(t0, v1_t, v2_t, cpu_env);
13516 case OPC_MAQ_S_W_PHR:
13518 gen_helper_maq_s_w_phr(t0, v1_t, v2_t, cpu_env);
13520 case OPC_MAQ_SA_W_PHL:
13522 gen_helper_maq_sa_w_phl(t0, v1_t, v2_t, cpu_env);
13524 case OPC_MAQ_SA_W_PHR:
13526 gen_helper_maq_sa_w_phr(t0, v1_t, v2_t, cpu_env);
13528 case OPC_MULSA_W_PH:
13530 gen_helper_mulsa_w_ph(t0, v1_t, v2_t, cpu_env);
13534 #ifdef TARGET_MIPS64
13535 case OPC_DPAQ_W_QH_DSP:
13537 int ac = ret & 0x03;
13538 tcg_gen_movi_i32(t0, ac);
13543 gen_helper_dmadd(v1_t, v2_t, t0, cpu_env);
13547 gen_helper_dmaddu(v1_t, v2_t, t0, cpu_env);
13551 gen_helper_dmsub(v1_t, v2_t, t0, cpu_env);
13555 gen_helper_dmsubu(v1_t, v2_t, t0, cpu_env);
13559 gen_helper_dpa_w_qh(v1_t, v2_t, t0, cpu_env);
13561 case OPC_DPAQ_S_W_QH:
13563 gen_helper_dpaq_s_w_qh(v1_t, v2_t, t0, cpu_env);
13565 case OPC_DPAQ_SA_L_PW:
13567 gen_helper_dpaq_sa_l_pw(v1_t, v2_t, t0, cpu_env);
13569 case OPC_DPAU_H_OBL:
13571 gen_helper_dpau_h_obl(v1_t, v2_t, t0, cpu_env);
13573 case OPC_DPAU_H_OBR:
13575 gen_helper_dpau_h_obr(v1_t, v2_t, t0, cpu_env);
13579 gen_helper_dps_w_qh(v1_t, v2_t, t0, cpu_env);
13581 case OPC_DPSQ_S_W_QH:
13583 gen_helper_dpsq_s_w_qh(v1_t, v2_t, t0, cpu_env);
13585 case OPC_DPSQ_SA_L_PW:
13587 gen_helper_dpsq_sa_l_pw(v1_t, v2_t, t0, cpu_env);
13589 case OPC_DPSU_H_OBL:
13591 gen_helper_dpsu_h_obl(v1_t, v2_t, t0, cpu_env);
13593 case OPC_DPSU_H_OBR:
13595 gen_helper_dpsu_h_obr(v1_t, v2_t, t0, cpu_env);
13597 case OPC_MAQ_S_L_PWL:
13599 gen_helper_maq_s_l_pwl(v1_t, v2_t, t0, cpu_env);
13601 case OPC_MAQ_S_L_PWR:
13603 gen_helper_maq_s_l_pwr(v1_t, v2_t, t0, cpu_env);
13605 case OPC_MAQ_S_W_QHLL:
13607 gen_helper_maq_s_w_qhll(v1_t, v2_t, t0, cpu_env);
13609 case OPC_MAQ_SA_W_QHLL:
13611 gen_helper_maq_sa_w_qhll(v1_t, v2_t, t0, cpu_env);
13613 case OPC_MAQ_S_W_QHLR:
13615 gen_helper_maq_s_w_qhlr(v1_t, v2_t, t0, cpu_env);
13617 case OPC_MAQ_SA_W_QHLR:
13619 gen_helper_maq_sa_w_qhlr(v1_t, v2_t, t0, cpu_env);
13621 case OPC_MAQ_S_W_QHRL:
13623 gen_helper_maq_s_w_qhrl(v1_t, v2_t, t0, cpu_env);
13625 case OPC_MAQ_SA_W_QHRL:
13627 gen_helper_maq_sa_w_qhrl(v1_t, v2_t, t0, cpu_env);
13629 case OPC_MAQ_S_W_QHRR:
13631 gen_helper_maq_s_w_qhrr(v1_t, v2_t, t0, cpu_env);
13633 case OPC_MAQ_SA_W_QHRR:
13635 gen_helper_maq_sa_w_qhrr(v1_t, v2_t, t0, cpu_env);
13637 case OPC_MULSAQ_S_L_PW:
13639 gen_helper_mulsaq_s_l_pw(v1_t, v2_t, t0, cpu_env);
13641 case OPC_MULSAQ_S_W_QH:
13643 gen_helper_mulsaq_s_w_qh(v1_t, v2_t, t0, cpu_env);
13649 case OPC_ADDU_QB_DSP:
13651 case OPC_MULEU_S_PH_QBL:
13653 gen_helper_muleu_s_ph_qbl(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13655 case OPC_MULEU_S_PH_QBR:
13657 gen_helper_muleu_s_ph_qbr(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13659 case OPC_MULQ_RS_PH:
13661 gen_helper_mulq_rs_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13663 case OPC_MULEQ_S_W_PHL:
13665 gen_helper_muleq_s_w_phl(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13667 case OPC_MULEQ_S_W_PHR:
13669 gen_helper_muleq_s_w_phr(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13671 case OPC_MULQ_S_PH:
13673 gen_helper_mulq_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13677 #ifdef TARGET_MIPS64
13678 case OPC_ADDU_OB_DSP:
13680 case OPC_MULEQ_S_PW_QHL:
13682 gen_helper_muleq_s_pw_qhl(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13684 case OPC_MULEQ_S_PW_QHR:
13686 gen_helper_muleq_s_pw_qhr(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13688 case OPC_MULEU_S_QH_OBL:
13690 gen_helper_muleu_s_qh_obl(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13692 case OPC_MULEU_S_QH_OBR:
13694 gen_helper_muleu_s_qh_obr(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13696 case OPC_MULQ_RS_QH:
13698 gen_helper_mulq_rs_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13705 tcg_temp_free_i32(t0);
13706 tcg_temp_free(v1_t);
13707 tcg_temp_free(v2_t);
13709 (void)opn; /* avoid a compiler warning */
13710 MIPS_DEBUG("%s", opn);
13714 static void gen_mipsdsp_bitinsn(CPUMIPSState *env, DisasContext *ctx,
13715 uint32_t op1, uint32_t op2,
13718 const char *opn = "mipsdsp Bit/ Manipulation";
13724 /* Treat as NOP. */
13729 t0 = tcg_temp_new();
13730 val_t = tcg_temp_new();
13731 gen_load_gpr(val_t, val);
13734 case OPC_ABSQ_S_PH_DSP:
13738 gen_helper_bitrev(cpu_gpr[ret], val_t);
13743 target_long result;
13744 imm = (ctx->opcode >> 16) & 0xFF;
13745 result = (uint32_t)imm << 24 |
13746 (uint32_t)imm << 16 |
13747 (uint32_t)imm << 8 |
13749 result = (int32_t)result;
13750 tcg_gen_movi_tl(cpu_gpr[ret], result);
13755 tcg_gen_ext8u_tl(cpu_gpr[ret], val_t);
13756 tcg_gen_shli_tl(t0, cpu_gpr[ret], 8);
13757 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
13758 tcg_gen_shli_tl(t0, cpu_gpr[ret], 16);
13759 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
13760 tcg_gen_ext32s_tl(cpu_gpr[ret], cpu_gpr[ret]);
13765 imm = (ctx->opcode >> 16) & 0x03FF;
13766 tcg_gen_movi_tl(cpu_gpr[ret], \
13767 (target_long)((int32_t)imm << 16 | \
13768 (uint32_t)(uint16_t)imm));
13773 tcg_gen_ext16u_tl(cpu_gpr[ret], val_t);
13774 tcg_gen_shli_tl(t0, cpu_gpr[ret], 16);
13775 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
13776 tcg_gen_ext32s_tl(cpu_gpr[ret], cpu_gpr[ret]);
13780 #ifdef TARGET_MIPS64
13781 case OPC_ABSQ_S_QH_DSP:
13788 imm = (ctx->opcode >> 16) & 0xFF;
13789 temp = ((uint64_t)imm << 8) | (uint64_t)imm;
13790 temp = (temp << 16) | temp;
13791 temp = (temp << 32) | temp;
13792 tcg_gen_movi_tl(cpu_gpr[ret], temp);
13800 imm = (ctx->opcode >> 16) & 0x03FF;
13801 imm = (int16_t)(imm << 6) >> 6;
13802 temp = ((target_long)imm << 32) \
13803 | ((target_long)imm & 0xFFFFFFFF);
13804 tcg_gen_movi_tl(cpu_gpr[ret], temp);
13812 imm = (ctx->opcode >> 16) & 0x03FF;
13813 imm = (int16_t)(imm << 6) >> 6;
13815 temp = ((uint64_t)(uint16_t)imm << 48) |
13816 ((uint64_t)(uint16_t)imm << 32) |
13817 ((uint64_t)(uint16_t)imm << 16) |
13818 (uint64_t)(uint16_t)imm;
13819 tcg_gen_movi_tl(cpu_gpr[ret], temp);
13824 tcg_gen_ext8u_tl(cpu_gpr[ret], val_t);
13825 tcg_gen_shli_tl(t0, cpu_gpr[ret], 8);
13826 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
13827 tcg_gen_shli_tl(t0, cpu_gpr[ret], 16);
13828 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
13829 tcg_gen_shli_tl(t0, cpu_gpr[ret], 32);
13830 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
13834 tcg_gen_ext32u_i64(cpu_gpr[ret], val_t);
13835 tcg_gen_shli_tl(t0, cpu_gpr[ret], 32);
13836 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
13840 tcg_gen_ext16u_tl(cpu_gpr[ret], val_t);
13841 tcg_gen_shli_tl(t0, cpu_gpr[ret], 16);
13842 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
13843 tcg_gen_shli_tl(t0, cpu_gpr[ret], 32);
13844 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
13851 tcg_temp_free(val_t);
13853 (void)opn; /* avoid a compiler warning */
13854 MIPS_DEBUG("%s", opn);
13857 static void gen_mipsdsp_add_cmp_pick(DisasContext *ctx,
13858 uint32_t op1, uint32_t op2,
13859 int ret, int v1, int v2, int check_ret)
13861 const char *opn = "mipsdsp add compare pick";
13867 if ((ret == 0) && (check_ret == 1)) {
13868 /* Treat as NOP. */
13873 t0 = tcg_temp_new_i32();
13874 t1 = tcg_temp_new();
13875 v1_t = tcg_temp_new();
13876 v2_t = tcg_temp_new();
13878 gen_load_gpr(v1_t, v1);
13879 gen_load_gpr(v2_t, v2);
13882 case OPC_APPEND_DSP:
13885 tcg_gen_movi_i32(t0, v2);
13886 gen_helper_append(cpu_gpr[ret], cpu_gpr[ret], v1_t, t0);
13889 tcg_gen_movi_i32(t0, v2);
13890 gen_helper_prepend(cpu_gpr[ret], v1_t, cpu_gpr[ret], t0);
13893 tcg_gen_movi_i32(t0, v2);
13894 gen_helper_balign(cpu_gpr[ret], v1_t, cpu_gpr[ret], t0);
13896 default: /* Invid */
13897 MIPS_INVAL("MASK APPEND");
13898 generate_exception(ctx, EXCP_RI);
13902 case OPC_CMPU_EQ_QB_DSP:
13904 case OPC_CMPU_EQ_QB:
13906 gen_helper_cmpu_eq_qb(v1_t, v2_t, cpu_env);
13908 case OPC_CMPU_LT_QB:
13910 gen_helper_cmpu_lt_qb(v1_t, v2_t, cpu_env);
13912 case OPC_CMPU_LE_QB:
13914 gen_helper_cmpu_le_qb(v1_t, v2_t, cpu_env);
13916 case OPC_CMPGU_EQ_QB:
13918 gen_helper_cmpgu_eq_qb(cpu_gpr[ret], v1_t, v2_t);
13920 case OPC_CMPGU_LT_QB:
13922 gen_helper_cmpgu_lt_qb(cpu_gpr[ret], v1_t, v2_t);
13924 case OPC_CMPGU_LE_QB:
13926 gen_helper_cmpgu_le_qb(cpu_gpr[ret], v1_t, v2_t);
13928 case OPC_CMPGDU_EQ_QB:
13930 gen_helper_cmpgu_eq_qb(t1, v1_t, v2_t);
13931 tcg_gen_mov_tl(cpu_gpr[ret], t1);
13932 tcg_gen_andi_tl(cpu_dspctrl, cpu_dspctrl, 0xF0FFFFFF);
13933 tcg_gen_shli_tl(t1, t1, 24);
13934 tcg_gen_or_tl(cpu_dspctrl, cpu_dspctrl, t1);
13936 case OPC_CMPGDU_LT_QB:
13938 gen_helper_cmpgu_lt_qb(t1, v1_t, v2_t);
13939 tcg_gen_mov_tl(cpu_gpr[ret], t1);
13940 tcg_gen_andi_tl(cpu_dspctrl, cpu_dspctrl, 0xF0FFFFFF);
13941 tcg_gen_shli_tl(t1, t1, 24);
13942 tcg_gen_or_tl(cpu_dspctrl, cpu_dspctrl, t1);
13944 case OPC_CMPGDU_LE_QB:
13946 gen_helper_cmpgu_le_qb(t1, v1_t, v2_t);
13947 tcg_gen_mov_tl(cpu_gpr[ret], t1);
13948 tcg_gen_andi_tl(cpu_dspctrl, cpu_dspctrl, 0xF0FFFFFF);
13949 tcg_gen_shli_tl(t1, t1, 24);
13950 tcg_gen_or_tl(cpu_dspctrl, cpu_dspctrl, t1);
13952 case OPC_CMP_EQ_PH:
13954 gen_helper_cmp_eq_ph(v1_t, v2_t, cpu_env);
13956 case OPC_CMP_LT_PH:
13958 gen_helper_cmp_lt_ph(v1_t, v2_t, cpu_env);
13960 case OPC_CMP_LE_PH:
13962 gen_helper_cmp_le_ph(v1_t, v2_t, cpu_env);
13966 gen_helper_pick_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13970 gen_helper_pick_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13972 case OPC_PACKRL_PH:
13974 gen_helper_packrl_ph(cpu_gpr[ret], v1_t, v2_t);
13978 #ifdef TARGET_MIPS64
13979 case OPC_CMPU_EQ_OB_DSP:
13981 case OPC_CMP_EQ_PW:
13983 gen_helper_cmp_eq_pw(v1_t, v2_t, cpu_env);
13985 case OPC_CMP_LT_PW:
13987 gen_helper_cmp_lt_pw(v1_t, v2_t, cpu_env);
13989 case OPC_CMP_LE_PW:
13991 gen_helper_cmp_le_pw(v1_t, v2_t, cpu_env);
13993 case OPC_CMP_EQ_QH:
13995 gen_helper_cmp_eq_qh(v1_t, v2_t, cpu_env);
13997 case OPC_CMP_LT_QH:
13999 gen_helper_cmp_lt_qh(v1_t, v2_t, cpu_env);
14001 case OPC_CMP_LE_QH:
14003 gen_helper_cmp_le_qh(v1_t, v2_t, cpu_env);
14005 case OPC_CMPGDU_EQ_OB:
14007 gen_helper_cmpgdu_eq_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
14009 case OPC_CMPGDU_LT_OB:
14011 gen_helper_cmpgdu_lt_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
14013 case OPC_CMPGDU_LE_OB:
14015 gen_helper_cmpgdu_le_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
14017 case OPC_CMPGU_EQ_OB:
14019 gen_helper_cmpgu_eq_ob(cpu_gpr[ret], v1_t, v2_t);
14021 case OPC_CMPGU_LT_OB:
14023 gen_helper_cmpgu_lt_ob(cpu_gpr[ret], v1_t, v2_t);
14025 case OPC_CMPGU_LE_OB:
14027 gen_helper_cmpgu_le_ob(cpu_gpr[ret], v1_t, v2_t);
14029 case OPC_CMPU_EQ_OB:
14031 gen_helper_cmpu_eq_ob(v1_t, v2_t, cpu_env);
14033 case OPC_CMPU_LT_OB:
14035 gen_helper_cmpu_lt_ob(v1_t, v2_t, cpu_env);
14037 case OPC_CMPU_LE_OB:
14039 gen_helper_cmpu_le_ob(v1_t, v2_t, cpu_env);
14041 case OPC_PACKRL_PW:
14043 gen_helper_packrl_pw(cpu_gpr[ret], v1_t, v2_t);
14047 gen_helper_pick_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
14051 gen_helper_pick_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
14055 gen_helper_pick_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
14059 case OPC_DAPPEND_DSP:
14062 tcg_gen_movi_i32(t0, v2);
14063 gen_helper_dappend(cpu_gpr[ret], v1_t, cpu_gpr[ret], t0);
14066 tcg_gen_movi_i32(t0, v2);
14067 gen_helper_prependd(cpu_gpr[ret], v1_t, cpu_gpr[ret], t0);
14070 tcg_gen_movi_i32(t0, v2);
14071 gen_helper_prependw(cpu_gpr[ret], v1_t, cpu_gpr[ret], t0);
14074 tcg_gen_movi_i32(t0, v2);
14075 gen_helper_dbalign(cpu_gpr[ret], v1_t, cpu_gpr[ret], t0);
14077 default: /* Invalid */
14078 MIPS_INVAL("MASK DAPPEND");
14079 generate_exception(ctx, EXCP_RI);
14086 tcg_temp_free_i32(t0);
14088 tcg_temp_free(v1_t);
14089 tcg_temp_free(v2_t);
14091 (void)opn; /* avoid a compiler warning */
14092 MIPS_DEBUG("%s", opn);
14095 static void gen_mipsdsp_accinsn(DisasContext *ctx, uint32_t op1, uint32_t op2,
14096 int ret, int v1, int v2, int check_ret)
14099 const char *opn = "mipsdsp accumulator";
14106 if ((ret == 0) && (check_ret == 1)) {
14107 /* Treat as NOP. */
14112 t0 = tcg_temp_new();
14113 t1 = tcg_temp_new();
14114 v1_t = tcg_temp_new();
14115 v2_t = tcg_temp_new();
14117 gen_load_gpr(v1_t, v1);
14118 gen_load_gpr(v2_t, v2);
14121 case OPC_EXTR_W_DSP:
14125 tcg_gen_movi_tl(t0, v2);
14126 tcg_gen_movi_tl(t1, v1);
14127 gen_helper_extr_w(cpu_gpr[ret], t0, t1, cpu_env);
14130 tcg_gen_movi_tl(t0, v2);
14131 tcg_gen_movi_tl(t1, v1);
14132 gen_helper_extr_r_w(cpu_gpr[ret], t0, t1, cpu_env);
14134 case OPC_EXTR_RS_W:
14135 tcg_gen_movi_tl(t0, v2);
14136 tcg_gen_movi_tl(t1, v1);
14137 gen_helper_extr_rs_w(cpu_gpr[ret], t0, t1, cpu_env);
14140 tcg_gen_movi_tl(t0, v2);
14141 tcg_gen_movi_tl(t1, v1);
14142 gen_helper_extr_s_h(cpu_gpr[ret], t0, t1, cpu_env);
14144 case OPC_EXTRV_S_H:
14145 tcg_gen_movi_tl(t0, v2);
14146 gen_helper_extr_s_h(cpu_gpr[ret], t0, v1_t, cpu_env);
14149 tcg_gen_movi_tl(t0, v2);
14150 gen_helper_extr_w(cpu_gpr[ret], t0, v1_t, cpu_env);
14152 case OPC_EXTRV_R_W:
14153 tcg_gen_movi_tl(t0, v2);
14154 gen_helper_extr_r_w(cpu_gpr[ret], t0, v1_t, cpu_env);
14156 case OPC_EXTRV_RS_W:
14157 tcg_gen_movi_tl(t0, v2);
14158 gen_helper_extr_rs_w(cpu_gpr[ret], t0, v1_t, cpu_env);
14161 tcg_gen_movi_tl(t0, v2);
14162 tcg_gen_movi_tl(t1, v1);
14163 gen_helper_extp(cpu_gpr[ret], t0, t1, cpu_env);
14166 tcg_gen_movi_tl(t0, v2);
14167 gen_helper_extp(cpu_gpr[ret], t0, v1_t, cpu_env);
14170 tcg_gen_movi_tl(t0, v2);
14171 tcg_gen_movi_tl(t1, v1);
14172 gen_helper_extpdp(cpu_gpr[ret], t0, t1, cpu_env);
14175 tcg_gen_movi_tl(t0, v2);
14176 gen_helper_extpdp(cpu_gpr[ret], t0, v1_t, cpu_env);
14179 imm = (ctx->opcode >> 20) & 0x3F;
14180 tcg_gen_movi_tl(t0, ret);
14181 tcg_gen_movi_tl(t1, imm);
14182 gen_helper_shilo(t0, t1, cpu_env);
14185 tcg_gen_movi_tl(t0, ret);
14186 gen_helper_shilo(t0, v1_t, cpu_env);
14189 tcg_gen_movi_tl(t0, ret);
14190 gen_helper_mthlip(t0, v1_t, cpu_env);
14193 imm = (ctx->opcode >> 11) & 0x3FF;
14194 tcg_gen_movi_tl(t0, imm);
14195 gen_helper_wrdsp(v1_t, t0, cpu_env);
14198 imm = (ctx->opcode >> 16) & 0x03FF;
14199 tcg_gen_movi_tl(t0, imm);
14200 gen_helper_rddsp(cpu_gpr[ret], t0, cpu_env);
14204 #ifdef TARGET_MIPS64
14205 case OPC_DEXTR_W_DSP:
14209 tcg_gen_movi_tl(t0, ret);
14210 gen_helper_dmthlip(v1_t, t0, cpu_env);
14214 int shift = (ctx->opcode >> 19) & 0x7F;
14215 int ac = (ctx->opcode >> 11) & 0x03;
14216 tcg_gen_movi_tl(t0, shift);
14217 tcg_gen_movi_tl(t1, ac);
14218 gen_helper_dshilo(t0, t1, cpu_env);
14223 int ac = (ctx->opcode >> 11) & 0x03;
14224 tcg_gen_movi_tl(t0, ac);
14225 gen_helper_dshilo(v1_t, t0, cpu_env);
14229 tcg_gen_movi_tl(t0, v2);
14230 tcg_gen_movi_tl(t1, v1);
14232 gen_helper_dextp(cpu_gpr[ret], t0, t1, cpu_env);
14235 tcg_gen_movi_tl(t0, v2);
14236 gen_helper_dextp(cpu_gpr[ret], t0, v1_t, cpu_env);
14239 tcg_gen_movi_tl(t0, v2);
14240 tcg_gen_movi_tl(t1, v1);
14241 gen_helper_dextpdp(cpu_gpr[ret], t0, t1, cpu_env);
14244 tcg_gen_movi_tl(t0, v2);
14245 gen_helper_dextpdp(cpu_gpr[ret], t0, v1_t, cpu_env);
14248 tcg_gen_movi_tl(t0, v2);
14249 tcg_gen_movi_tl(t1, v1);
14250 gen_helper_dextr_l(cpu_gpr[ret], t0, t1, cpu_env);
14252 case OPC_DEXTR_R_L:
14253 tcg_gen_movi_tl(t0, v2);
14254 tcg_gen_movi_tl(t1, v1);
14255 gen_helper_dextr_r_l(cpu_gpr[ret], t0, t1, cpu_env);
14257 case OPC_DEXTR_RS_L:
14258 tcg_gen_movi_tl(t0, v2);
14259 tcg_gen_movi_tl(t1, v1);
14260 gen_helper_dextr_rs_l(cpu_gpr[ret], t0, t1, cpu_env);
14263 tcg_gen_movi_tl(t0, v2);
14264 tcg_gen_movi_tl(t1, v1);
14265 gen_helper_dextr_w(cpu_gpr[ret], t0, t1, cpu_env);
14267 case OPC_DEXTR_R_W:
14268 tcg_gen_movi_tl(t0, v2);
14269 tcg_gen_movi_tl(t1, v1);
14270 gen_helper_dextr_r_w(cpu_gpr[ret], t0, t1, cpu_env);
14272 case OPC_DEXTR_RS_W:
14273 tcg_gen_movi_tl(t0, v2);
14274 tcg_gen_movi_tl(t1, v1);
14275 gen_helper_dextr_rs_w(cpu_gpr[ret], t0, t1, cpu_env);
14277 case OPC_DEXTR_S_H:
14278 tcg_gen_movi_tl(t0, v2);
14279 tcg_gen_movi_tl(t1, v1);
14280 gen_helper_dextr_s_h(cpu_gpr[ret], t0, t1, cpu_env);
14282 case OPC_DEXTRV_S_H:
14283 tcg_gen_movi_tl(t0, v2);
14284 tcg_gen_movi_tl(t1, v1);
14285 gen_helper_dextr_s_h(cpu_gpr[ret], t0, t1, cpu_env);
14288 tcg_gen_movi_tl(t0, v2);
14289 gen_helper_dextr_l(cpu_gpr[ret], t0, v1_t, cpu_env);
14291 case OPC_DEXTRV_R_L:
14292 tcg_gen_movi_tl(t0, v2);
14293 gen_helper_dextr_r_l(cpu_gpr[ret], t0, v1_t, cpu_env);
14295 case OPC_DEXTRV_RS_L:
14296 tcg_gen_movi_tl(t0, v2);
14297 gen_helper_dextr_rs_l(cpu_gpr[ret], t0, v1_t, cpu_env);
14300 tcg_gen_movi_tl(t0, v2);
14301 gen_helper_dextr_w(cpu_gpr[ret], t0, v1_t, cpu_env);
14303 case OPC_DEXTRV_R_W:
14304 tcg_gen_movi_tl(t0, v2);
14305 gen_helper_dextr_r_w(cpu_gpr[ret], t0, v1_t, cpu_env);
14307 case OPC_DEXTRV_RS_W:
14308 tcg_gen_movi_tl(t0, v2);
14309 gen_helper_dextr_rs_w(cpu_gpr[ret], t0, v1_t, cpu_env);
14318 tcg_temp_free(v1_t);
14319 tcg_temp_free(v2_t);
14321 (void)opn; /* avoid a compiler warning */
14322 MIPS_DEBUG("%s", opn);
14325 /* End MIPSDSP functions. */
14327 static void decode_opc (CPUMIPSState *env, DisasContext *ctx, int *is_branch)
14330 int rs, rt, rd, sa;
14331 uint32_t op, op1, op2;
14334 /* make sure instructions are on a word boundary */
14335 if (ctx->pc & 0x3) {
14336 env->CP0_BadVAddr = ctx->pc;
14337 generate_exception(ctx, EXCP_AdEL);
14341 /* Handle blikely not taken case */
14342 if ((ctx->hflags & MIPS_HFLAG_BMASK_BASE) == MIPS_HFLAG_BL) {
14343 int l1 = gen_new_label();
14345 MIPS_DEBUG("blikely condition (" TARGET_FMT_lx ")", ctx->pc + 4);
14346 tcg_gen_brcondi_tl(TCG_COND_NE, bcond, 0, l1);
14347 tcg_gen_movi_i32(hflags, ctx->hflags & ~MIPS_HFLAG_BMASK);
14348 gen_goto_tb(ctx, 1, ctx->pc + 4);
14352 if (unlikely(qemu_loglevel_mask(CPU_LOG_TB_OP | CPU_LOG_TB_OP_OPT))) {
14353 tcg_gen_debug_insn_start(ctx->pc);
14356 op = MASK_OP_MAJOR(ctx->opcode);
14357 rs = (ctx->opcode >> 21) & 0x1f;
14358 rt = (ctx->opcode >> 16) & 0x1f;
14359 rd = (ctx->opcode >> 11) & 0x1f;
14360 sa = (ctx->opcode >> 6) & 0x1f;
14361 imm = (int16_t)ctx->opcode;
14364 op1 = MASK_SPECIAL(ctx->opcode);
14366 case OPC_SLL: /* Shift with immediate */
14368 gen_shift_imm(env, ctx, op1, rd, rt, sa);
14371 switch ((ctx->opcode >> 21) & 0x1f) {
14373 /* rotr is decoded as srl on non-R2 CPUs */
14374 if (env->insn_flags & ISA_MIPS32R2) {
14379 gen_shift_imm(env, ctx, op1, rd, rt, sa);
14382 generate_exception(ctx, EXCP_RI);
14386 case OPC_MOVN: /* Conditional move */
14388 check_insn(env, ctx, ISA_MIPS4 | ISA_MIPS32 |
14389 INSN_LOONGSON2E | INSN_LOONGSON2F);
14390 gen_cond_move(env, ctx, op1, rd, rs, rt);
14392 case OPC_ADD ... OPC_SUBU:
14393 gen_arith(env, ctx, op1, rd, rs, rt);
14395 case OPC_SLLV: /* Shifts */
14397 gen_shift(env, ctx, op1, rd, rs, rt);
14400 switch ((ctx->opcode >> 6) & 0x1f) {
14402 /* rotrv is decoded as srlv on non-R2 CPUs */
14403 if (env->insn_flags & ISA_MIPS32R2) {
14408 gen_shift(env, ctx, op1, rd, rs, rt);
14411 generate_exception(ctx, EXCP_RI);
14415 case OPC_SLT: /* Set on less than */
14417 gen_slt(env, ctx, op1, rd, rs, rt);
14419 case OPC_AND: /* Logic*/
14423 gen_logic(env, ctx, op1, rd, rs, rt);
14425 case OPC_MULT ... OPC_DIVU:
14427 check_insn(env, ctx, INSN_VR54XX);
14428 op1 = MASK_MUL_VR54XX(ctx->opcode);
14429 gen_mul_vr54xx(ctx, op1, rd, rs, rt);
14431 gen_muldiv(ctx, op1, rs, rt);
14433 case OPC_JR ... OPC_JALR:
14434 gen_compute_branch(ctx, op1, 4, rs, rd, sa);
14437 case OPC_TGE ... OPC_TEQ: /* Traps */
14439 gen_trap(ctx, op1, rs, rt, -1);
14441 case OPC_MFHI: /* Move from HI/LO */
14443 gen_HILO(ctx, op1, rd);
14446 case OPC_MTLO: /* Move to HI/LO */
14447 gen_HILO(ctx, op1, rs);
14449 case OPC_PMON: /* Pmon entry point, also R4010 selsl */
14450 #ifdef MIPS_STRICT_STANDARD
14451 MIPS_INVAL("PMON / selsl");
14452 generate_exception(ctx, EXCP_RI);
14454 gen_helper_0e0i(pmon, sa);
14458 generate_exception(ctx, EXCP_SYSCALL);
14459 ctx->bstate = BS_STOP;
14462 generate_exception(ctx, EXCP_BREAK);
14465 #ifdef MIPS_STRICT_STANDARD
14466 MIPS_INVAL("SPIM");
14467 generate_exception(ctx, EXCP_RI);
14469 /* Implemented as RI exception for now. */
14470 MIPS_INVAL("spim (unofficial)");
14471 generate_exception(ctx, EXCP_RI);
14475 /* Treat as NOP. */
14479 check_insn(env, ctx, ISA_MIPS4 | ISA_MIPS32);
14480 if (env->CP0_Config1 & (1 << CP0C1_FP)) {
14481 check_cp1_enabled(ctx);
14482 gen_movci(ctx, rd, rs, (ctx->opcode >> 18) & 0x7,
14483 (ctx->opcode >> 16) & 1);
14485 generate_exception_err(ctx, EXCP_CpU, 1);
14489 #if defined(TARGET_MIPS64)
14490 /* MIPS64 specific opcodes */
14495 check_insn(env, ctx, ISA_MIPS3);
14496 check_mips_64(ctx);
14497 gen_shift_imm(env, ctx, op1, rd, rt, sa);
14500 switch ((ctx->opcode >> 21) & 0x1f) {
14502 /* drotr is decoded as dsrl on non-R2 CPUs */
14503 if (env->insn_flags & ISA_MIPS32R2) {
14508 check_insn(env, ctx, ISA_MIPS3);
14509 check_mips_64(ctx);
14510 gen_shift_imm(env, ctx, op1, rd, rt, sa);
14513 generate_exception(ctx, EXCP_RI);
14518 switch ((ctx->opcode >> 21) & 0x1f) {
14520 /* drotr32 is decoded as dsrl32 on non-R2 CPUs */
14521 if (env->insn_flags & ISA_MIPS32R2) {
14526 check_insn(env, ctx, ISA_MIPS3);
14527 check_mips_64(ctx);
14528 gen_shift_imm(env, ctx, op1, rd, rt, sa);
14531 generate_exception(ctx, EXCP_RI);
14535 case OPC_DADD ... OPC_DSUBU:
14536 check_insn(env, ctx, ISA_MIPS3);
14537 check_mips_64(ctx);
14538 gen_arith(env, ctx, op1, rd, rs, rt);
14542 check_insn(env, ctx, ISA_MIPS3);
14543 check_mips_64(ctx);
14544 gen_shift(env, ctx, op1, rd, rs, rt);
14547 switch ((ctx->opcode >> 6) & 0x1f) {
14549 /* drotrv is decoded as dsrlv on non-R2 CPUs */
14550 if (env->insn_flags & ISA_MIPS32R2) {
14555 check_insn(env, ctx, ISA_MIPS3);
14556 check_mips_64(ctx);
14557 gen_shift(env, ctx, op1, rd, rs, rt);
14560 generate_exception(ctx, EXCP_RI);
14564 case OPC_DMULT ... OPC_DDIVU:
14565 check_insn(env, ctx, ISA_MIPS3);
14566 check_mips_64(ctx);
14567 gen_muldiv(ctx, op1, rs, rt);
14570 default: /* Invalid */
14571 MIPS_INVAL("special");
14572 generate_exception(ctx, EXCP_RI);
14577 op1 = MASK_SPECIAL2(ctx->opcode);
14579 case OPC_MADD ... OPC_MADDU: /* Multiply and add/sub */
14580 case OPC_MSUB ... OPC_MSUBU:
14581 check_insn(env, ctx, ISA_MIPS32);
14582 gen_muldiv(ctx, op1, rs, rt);
14585 gen_arith(env, ctx, op1, rd, rs, rt);
14589 check_insn(env, ctx, ISA_MIPS32);
14590 gen_cl(ctx, op1, rd, rs);
14593 /* XXX: not clear which exception should be raised
14594 * when in debug mode...
14596 check_insn(env, ctx, ISA_MIPS32);
14597 if (!(ctx->hflags & MIPS_HFLAG_DM)) {
14598 generate_exception(ctx, EXCP_DBp);
14600 generate_exception(ctx, EXCP_DBp);
14602 /* Treat as NOP. */
14605 case OPC_DIVU_G_2F:
14606 case OPC_MULT_G_2F:
14607 case OPC_MULTU_G_2F:
14609 case OPC_MODU_G_2F:
14610 check_insn(env, ctx, INSN_LOONGSON2F);
14611 gen_loongson_integer(ctx, op1, rd, rs, rt);
14613 #if defined(TARGET_MIPS64)
14616 check_insn(env, ctx, ISA_MIPS64);
14617 check_mips_64(ctx);
14618 gen_cl(ctx, op1, rd, rs);
14620 case OPC_DMULT_G_2F:
14621 case OPC_DMULTU_G_2F:
14622 case OPC_DDIV_G_2F:
14623 case OPC_DDIVU_G_2F:
14624 case OPC_DMOD_G_2F:
14625 case OPC_DMODU_G_2F:
14626 check_insn(env, ctx, INSN_LOONGSON2F);
14627 gen_loongson_integer(ctx, op1, rd, rs, rt);
14630 default: /* Invalid */
14631 MIPS_INVAL("special2");
14632 generate_exception(ctx, EXCP_RI);
14637 op1 = MASK_SPECIAL3(ctx->opcode);
14641 check_insn(env, ctx, ISA_MIPS32R2);
14642 gen_bitops(ctx, op1, rt, rs, sa, rd);
14645 check_insn(env, ctx, ISA_MIPS32R2);
14646 op2 = MASK_BSHFL(ctx->opcode);
14647 gen_bshfl(ctx, op2, rt, rd);
14650 gen_rdhwr(env, ctx, rt, rd);
14653 check_insn(env, ctx, ASE_MT);
14655 TCGv t0 = tcg_temp_new();
14656 TCGv t1 = tcg_temp_new();
14658 gen_load_gpr(t0, rt);
14659 gen_load_gpr(t1, rs);
14660 gen_helper_fork(t0, t1);
14666 check_insn(env, ctx, ASE_MT);
14668 TCGv t0 = tcg_temp_new();
14670 save_cpu_state(ctx, 1);
14671 gen_load_gpr(t0, rs);
14672 gen_helper_yield(t0, cpu_env, t0);
14673 gen_store_gpr(t0, rd);
14677 case OPC_DIV_G_2E ... OPC_DIVU_G_2E:
14678 case OPC_MOD_G_2E ... OPC_MODU_G_2E:
14679 case OPC_MULT_G_2E ... OPC_MULTU_G_2E:
14680 /* OPC_MULT_G_2E, OPC_ADDUH_QB_DSP, OPC_MUL_PH_DSP have
14681 * the same mask and op1. */
14682 if ((env->insn_flags & ASE_DSPR2) && (op1 == OPC_MULT_G_2E)) {
14683 op2 = MASK_ADDUH_QB(ctx->opcode);
14686 case OPC_ADDUH_R_QB:
14688 case OPC_ADDQH_R_PH:
14690 case OPC_ADDQH_R_W:
14692 case OPC_SUBUH_R_QB:
14694 case OPC_SUBQH_R_PH:
14696 case OPC_SUBQH_R_W:
14697 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
14702 case OPC_MULQ_RS_W:
14703 gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 1);
14706 MIPS_INVAL("MASK ADDUH.QB");
14707 generate_exception(ctx, EXCP_RI);
14710 } else if (env->insn_flags & INSN_LOONGSON2E) {
14711 gen_loongson_integer(ctx, op1, rd, rs, rt);
14713 generate_exception(ctx, EXCP_RI);
14717 op2 = MASK_LX(ctx->opcode);
14719 #if defined(TARGET_MIPS64)
14725 gen_mipsdsp_ld(env, ctx, op2, rd, rs, rt);
14727 default: /* Invalid */
14728 MIPS_INVAL("MASK LX");
14729 generate_exception(ctx, EXCP_RI);
14733 case OPC_ABSQ_S_PH_DSP:
14734 op2 = MASK_ABSQ_S_PH(ctx->opcode);
14736 case OPC_ABSQ_S_QB:
14737 case OPC_ABSQ_S_PH:
14739 case OPC_PRECEQ_W_PHL:
14740 case OPC_PRECEQ_W_PHR:
14741 case OPC_PRECEQU_PH_QBL:
14742 case OPC_PRECEQU_PH_QBR:
14743 case OPC_PRECEQU_PH_QBLA:
14744 case OPC_PRECEQU_PH_QBRA:
14745 case OPC_PRECEU_PH_QBL:
14746 case OPC_PRECEU_PH_QBR:
14747 case OPC_PRECEU_PH_QBLA:
14748 case OPC_PRECEU_PH_QBRA:
14749 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
14756 gen_mipsdsp_bitinsn(env, ctx, op1, op2, rd, rt);
14759 MIPS_INVAL("MASK ABSQ_S.PH");
14760 generate_exception(ctx, EXCP_RI);
14764 case OPC_ADDU_QB_DSP:
14765 op2 = MASK_ADDU_QB(ctx->opcode);
14768 case OPC_ADDQ_S_PH:
14771 case OPC_ADDU_S_QB:
14773 case OPC_ADDU_S_PH:
14775 case OPC_SUBQ_S_PH:
14778 case OPC_SUBU_S_QB:
14780 case OPC_SUBU_S_PH:
14784 case OPC_RADDU_W_QB:
14785 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
14787 case OPC_MULEU_S_PH_QBL:
14788 case OPC_MULEU_S_PH_QBR:
14789 case OPC_MULQ_RS_PH:
14790 case OPC_MULEQ_S_W_PHL:
14791 case OPC_MULEQ_S_W_PHR:
14792 case OPC_MULQ_S_PH:
14793 gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 1);
14795 default: /* Invalid */
14796 MIPS_INVAL("MASK ADDU.QB");
14797 generate_exception(ctx, EXCP_RI);
14802 case OPC_CMPU_EQ_QB_DSP:
14803 op2 = MASK_CMPU_EQ_QB(ctx->opcode);
14805 case OPC_PRECR_SRA_PH_W:
14806 case OPC_PRECR_SRA_R_PH_W:
14807 gen_mipsdsp_arith(ctx, op1, op2, rt, rs, rd);
14809 case OPC_PRECR_QB_PH:
14810 case OPC_PRECRQ_QB_PH:
14811 case OPC_PRECRQ_PH_W:
14812 case OPC_PRECRQ_RS_PH_W:
14813 case OPC_PRECRQU_S_QB_PH:
14814 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
14816 case OPC_CMPU_EQ_QB:
14817 case OPC_CMPU_LT_QB:
14818 case OPC_CMPU_LE_QB:
14819 case OPC_CMP_EQ_PH:
14820 case OPC_CMP_LT_PH:
14821 case OPC_CMP_LE_PH:
14822 gen_mipsdsp_add_cmp_pick(ctx, op1, op2, rd, rs, rt, 0);
14824 case OPC_CMPGU_EQ_QB:
14825 case OPC_CMPGU_LT_QB:
14826 case OPC_CMPGU_LE_QB:
14827 case OPC_CMPGDU_EQ_QB:
14828 case OPC_CMPGDU_LT_QB:
14829 case OPC_CMPGDU_LE_QB:
14832 case OPC_PACKRL_PH:
14833 gen_mipsdsp_add_cmp_pick(ctx, op1, op2, rd, rs, rt, 1);
14835 default: /* Invalid */
14836 MIPS_INVAL("MASK CMPU.EQ.QB");
14837 generate_exception(ctx, EXCP_RI);
14841 case OPC_SHLL_QB_DSP:
14842 gen_mipsdsp_shift(ctx, op1, rd, rs, rt);
14844 case OPC_DPA_W_PH_DSP:
14845 op2 = MASK_DPA_W_PH(ctx->opcode);
14847 case OPC_DPAU_H_QBL:
14848 case OPC_DPAU_H_QBR:
14849 case OPC_DPSU_H_QBL:
14850 case OPC_DPSU_H_QBR:
14852 case OPC_DPAX_W_PH:
14853 case OPC_DPAQ_S_W_PH:
14854 case OPC_DPAQX_S_W_PH:
14855 case OPC_DPAQX_SA_W_PH:
14857 case OPC_DPSX_W_PH:
14858 case OPC_DPSQ_S_W_PH:
14859 case OPC_DPSQX_S_W_PH:
14860 case OPC_DPSQX_SA_W_PH:
14861 case OPC_MULSAQ_S_W_PH:
14862 case OPC_DPAQ_SA_L_W:
14863 case OPC_DPSQ_SA_L_W:
14864 case OPC_MAQ_S_W_PHL:
14865 case OPC_MAQ_S_W_PHR:
14866 case OPC_MAQ_SA_W_PHL:
14867 case OPC_MAQ_SA_W_PHR:
14868 case OPC_MULSA_W_PH:
14869 gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 0);
14871 default: /* Invalid */
14872 MIPS_INVAL("MASK DPAW.PH");
14873 generate_exception(ctx, EXCP_RI);
14878 op2 = MASK_INSV(ctx->opcode);
14890 t0 = tcg_temp_new();
14891 t1 = tcg_temp_new();
14893 gen_load_gpr(t0, rt);
14894 gen_load_gpr(t1, rs);
14896 gen_helper_insv(cpu_gpr[rt], cpu_env, t1, t0);
14902 default: /* Invalid */
14903 MIPS_INVAL("MASK INSV");
14904 generate_exception(ctx, EXCP_RI);
14908 case OPC_APPEND_DSP:
14910 op2 = MASK_APPEND(ctx->opcode);
14911 gen_mipsdsp_add_cmp_pick(ctx, op1, op2, rt, rs, rd, 1);
14913 case OPC_EXTR_W_DSP:
14914 op2 = MASK_EXTR_W(ctx->opcode);
14918 case OPC_EXTR_RS_W:
14920 case OPC_EXTRV_S_H:
14922 case OPC_EXTRV_R_W:
14923 case OPC_EXTRV_RS_W:
14928 gen_mipsdsp_accinsn(ctx, op1, op2, rt, rs, rd, 1);
14931 gen_mipsdsp_accinsn(ctx, op1, op2, rd, rs, rt, 1);
14937 gen_mipsdsp_accinsn(ctx, op1, op2, rd, rs, rt, 0);
14939 default: /* Invalid */
14940 MIPS_INVAL("MASK EXTR.W");
14941 generate_exception(ctx, EXCP_RI);
14945 #if defined(TARGET_MIPS64)
14946 case OPC_DEXTM ... OPC_DEXT:
14947 case OPC_DINSM ... OPC_DINS:
14948 check_insn(env, ctx, ISA_MIPS64R2);
14949 check_mips_64(ctx);
14950 gen_bitops(ctx, op1, rt, rs, sa, rd);
14953 check_insn(env, ctx, ISA_MIPS64R2);
14954 check_mips_64(ctx);
14955 op2 = MASK_DBSHFL(ctx->opcode);
14956 gen_bshfl(ctx, op2, rt, rd);
14958 case OPC_DDIV_G_2E ... OPC_DDIVU_G_2E:
14959 case OPC_DMULT_G_2E ... OPC_DMULTU_G_2E:
14960 case OPC_DMOD_G_2E ... OPC_DMODU_G_2E:
14961 check_insn(env, ctx, INSN_LOONGSON2E);
14962 gen_loongson_integer(ctx, op1, rd, rs, rt);
14964 case OPC_ABSQ_S_QH_DSP:
14965 op2 = MASK_ABSQ_S_QH(ctx->opcode);
14967 case OPC_PRECEQ_L_PWL:
14968 case OPC_PRECEQ_L_PWR:
14969 case OPC_PRECEQ_PW_QHL:
14970 case OPC_PRECEQ_PW_QHR:
14971 case OPC_PRECEQ_PW_QHLA:
14972 case OPC_PRECEQ_PW_QHRA:
14973 case OPC_PRECEQU_QH_OBL:
14974 case OPC_PRECEQU_QH_OBR:
14975 case OPC_PRECEQU_QH_OBLA:
14976 case OPC_PRECEQU_QH_OBRA:
14977 case OPC_PRECEU_QH_OBL:
14978 case OPC_PRECEU_QH_OBR:
14979 case OPC_PRECEU_QH_OBLA:
14980 case OPC_PRECEU_QH_OBRA:
14981 case OPC_ABSQ_S_OB:
14982 case OPC_ABSQ_S_PW:
14983 case OPC_ABSQ_S_QH:
14984 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
14992 gen_mipsdsp_bitinsn(env, ctx, op1, op2, rd, rt);
14994 default: /* Invalid */
14995 MIPS_INVAL("MASK ABSQ_S.QH");
14996 generate_exception(ctx, EXCP_RI);
15000 case OPC_ADDU_OB_DSP:
15001 op2 = MASK_ADDU_OB(ctx->opcode);
15003 case OPC_RADDU_L_OB:
15005 case OPC_SUBQ_S_PW:
15007 case OPC_SUBQ_S_QH:
15009 case OPC_SUBU_S_OB:
15011 case OPC_SUBU_S_QH:
15013 case OPC_SUBUH_R_OB:
15015 case OPC_ADDQ_S_PW:
15017 case OPC_ADDQ_S_QH:
15019 case OPC_ADDU_S_OB:
15021 case OPC_ADDU_S_QH:
15023 case OPC_ADDUH_R_OB:
15024 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
15026 case OPC_MULEQ_S_PW_QHL:
15027 case OPC_MULEQ_S_PW_QHR:
15028 case OPC_MULEU_S_QH_OBL:
15029 case OPC_MULEU_S_QH_OBR:
15030 case OPC_MULQ_RS_QH:
15031 gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 1);
15033 default: /* Invalid */
15034 MIPS_INVAL("MASK ADDU.OB");
15035 generate_exception(ctx, EXCP_RI);
15039 case OPC_CMPU_EQ_OB_DSP:
15040 op2 = MASK_CMPU_EQ_OB(ctx->opcode);
15042 case OPC_PRECR_SRA_QH_PW:
15043 case OPC_PRECR_SRA_R_QH_PW:
15044 /* Return value is rt. */
15045 gen_mipsdsp_arith(ctx, op1, op2, rt, rs, rd);
15047 case OPC_PRECR_OB_QH:
15048 case OPC_PRECRQ_OB_QH:
15049 case OPC_PRECRQ_PW_L:
15050 case OPC_PRECRQ_QH_PW:
15051 case OPC_PRECRQ_RS_QH_PW:
15052 case OPC_PRECRQU_S_OB_QH:
15053 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
15055 case OPC_CMPU_EQ_OB:
15056 case OPC_CMPU_LT_OB:
15057 case OPC_CMPU_LE_OB:
15058 case OPC_CMP_EQ_QH:
15059 case OPC_CMP_LT_QH:
15060 case OPC_CMP_LE_QH:
15061 case OPC_CMP_EQ_PW:
15062 case OPC_CMP_LT_PW:
15063 case OPC_CMP_LE_PW:
15064 gen_mipsdsp_add_cmp_pick(ctx, op1, op2, rd, rs, rt, 0);
15066 case OPC_CMPGDU_EQ_OB:
15067 case OPC_CMPGDU_LT_OB:
15068 case OPC_CMPGDU_LE_OB:
15069 case OPC_CMPGU_EQ_OB:
15070 case OPC_CMPGU_LT_OB:
15071 case OPC_CMPGU_LE_OB:
15072 case OPC_PACKRL_PW:
15076 gen_mipsdsp_add_cmp_pick(ctx, op1, op2, rd, rs, rt, 1);
15078 default: /* Invalid */
15079 MIPS_INVAL("MASK CMPU_EQ.OB");
15080 generate_exception(ctx, EXCP_RI);
15084 case OPC_DAPPEND_DSP:
15086 op2 = MASK_DAPPEND(ctx->opcode);
15087 gen_mipsdsp_add_cmp_pick(ctx, op1, op2, rt, rs, rd, 1);
15089 case OPC_DEXTR_W_DSP:
15090 op2 = MASK_DEXTR_W(ctx->opcode);
15097 case OPC_DEXTR_R_L:
15098 case OPC_DEXTR_RS_L:
15100 case OPC_DEXTR_R_W:
15101 case OPC_DEXTR_RS_W:
15102 case OPC_DEXTR_S_H:
15104 case OPC_DEXTRV_R_L:
15105 case OPC_DEXTRV_RS_L:
15106 case OPC_DEXTRV_S_H:
15108 case OPC_DEXTRV_R_W:
15109 case OPC_DEXTRV_RS_W:
15110 gen_mipsdsp_accinsn(ctx, op1, op2, rt, rs, rd, 1);
15115 gen_mipsdsp_accinsn(ctx, op1, op2, rd, rs, rt, 0);
15117 default: /* Invalid */
15118 MIPS_INVAL("MASK EXTR.W");
15119 generate_exception(ctx, EXCP_RI);
15123 case OPC_DPAQ_W_QH_DSP:
15124 op2 = MASK_DPAQ_W_QH(ctx->opcode);
15126 case OPC_DPAU_H_OBL:
15127 case OPC_DPAU_H_OBR:
15128 case OPC_DPSU_H_OBL:
15129 case OPC_DPSU_H_OBR:
15131 case OPC_DPAQ_S_W_QH:
15133 case OPC_DPSQ_S_W_QH:
15134 case OPC_MULSAQ_S_W_QH:
15135 case OPC_DPAQ_SA_L_PW:
15136 case OPC_DPSQ_SA_L_PW:
15137 case OPC_MULSAQ_S_L_PW:
15138 gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 0);
15140 case OPC_MAQ_S_W_QHLL:
15141 case OPC_MAQ_S_W_QHLR:
15142 case OPC_MAQ_S_W_QHRL:
15143 case OPC_MAQ_S_W_QHRR:
15144 case OPC_MAQ_SA_W_QHLL:
15145 case OPC_MAQ_SA_W_QHLR:
15146 case OPC_MAQ_SA_W_QHRL:
15147 case OPC_MAQ_SA_W_QHRR:
15148 case OPC_MAQ_S_L_PWL:
15149 case OPC_MAQ_S_L_PWR:
15154 gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 0);
15156 default: /* Invalid */
15157 MIPS_INVAL("MASK DPAQ.W.QH");
15158 generate_exception(ctx, EXCP_RI);
15162 case OPC_DINSV_DSP:
15163 op2 = MASK_INSV(ctx->opcode);
15175 t0 = tcg_temp_new();
15176 t1 = tcg_temp_new();
15178 gen_load_gpr(t0, rt);
15179 gen_load_gpr(t1, rs);
15181 gen_helper_dinsv(cpu_gpr[rt], cpu_env, t1, t0);
15184 default: /* Invalid */
15185 MIPS_INVAL("MASK DINSV");
15186 generate_exception(ctx, EXCP_RI);
15190 case OPC_SHLL_OB_DSP:
15191 gen_mipsdsp_shift(ctx, op1, rd, rs, rt);
15194 default: /* Invalid */
15195 MIPS_INVAL("special3");
15196 generate_exception(ctx, EXCP_RI);
15201 op1 = MASK_REGIMM(ctx->opcode);
15203 case OPC_BLTZ ... OPC_BGEZL: /* REGIMM branches */
15204 case OPC_BLTZAL ... OPC_BGEZALL:
15205 gen_compute_branch(ctx, op1, 4, rs, -1, imm << 2);
15208 case OPC_TGEI ... OPC_TEQI: /* REGIMM traps */
15210 gen_trap(ctx, op1, rs, -1, imm);
15213 check_insn(env, ctx, ISA_MIPS32R2);
15214 /* Treat as NOP. */
15216 case OPC_BPOSGE32: /* MIPS DSP branch */
15217 #if defined(TARGET_MIPS64)
15221 gen_compute_branch(ctx, op1, 4, -1, -2, (int32_t)imm << 2);
15224 default: /* Invalid */
15225 MIPS_INVAL("regimm");
15226 generate_exception(ctx, EXCP_RI);
15231 check_cp0_enabled(ctx);
15232 op1 = MASK_CP0(ctx->opcode);
15238 #if defined(TARGET_MIPS64)
15242 #ifndef CONFIG_USER_ONLY
15243 gen_cp0(env, ctx, op1, rt, rd);
15244 #endif /* !CONFIG_USER_ONLY */
15246 case OPC_C0_FIRST ... OPC_C0_LAST:
15247 #ifndef CONFIG_USER_ONLY
15248 gen_cp0(env, ctx, MASK_C0(ctx->opcode), rt, rd);
15249 #endif /* !CONFIG_USER_ONLY */
15252 #ifndef CONFIG_USER_ONLY
15254 TCGv t0 = tcg_temp_new();
15256 op2 = MASK_MFMC0(ctx->opcode);
15259 check_insn(env, ctx, ASE_MT);
15260 gen_helper_dmt(t0);
15261 gen_store_gpr(t0, rt);
15264 check_insn(env, ctx, ASE_MT);
15265 gen_helper_emt(t0);
15266 gen_store_gpr(t0, rt);
15269 check_insn(env, ctx, ASE_MT);
15270 gen_helper_dvpe(t0, cpu_env);
15271 gen_store_gpr(t0, rt);
15274 check_insn(env, ctx, ASE_MT);
15275 gen_helper_evpe(t0, cpu_env);
15276 gen_store_gpr(t0, rt);
15279 check_insn(env, ctx, ISA_MIPS32R2);
15280 save_cpu_state(ctx, 1);
15281 gen_helper_di(t0, cpu_env);
15282 gen_store_gpr(t0, rt);
15283 /* Stop translation as we may have switched the execution mode */
15284 ctx->bstate = BS_STOP;
15287 check_insn(env, ctx, ISA_MIPS32R2);
15288 save_cpu_state(ctx, 1);
15289 gen_helper_ei(t0, cpu_env);
15290 gen_store_gpr(t0, rt);
15291 /* Stop translation as we may have switched the execution mode */
15292 ctx->bstate = BS_STOP;
15294 default: /* Invalid */
15295 MIPS_INVAL("mfmc0");
15296 generate_exception(ctx, EXCP_RI);
15301 #endif /* !CONFIG_USER_ONLY */
15304 check_insn(env, ctx, ISA_MIPS32R2);
15305 gen_load_srsgpr(rt, rd);
15308 check_insn(env, ctx, ISA_MIPS32R2);
15309 gen_store_srsgpr(rt, rd);
15313 generate_exception(ctx, EXCP_RI);
15317 case OPC_ADDI: /* Arithmetic with immediate opcode */
15319 gen_arith_imm(env, ctx, op, rt, rs, imm);
15321 case OPC_SLTI: /* Set on less than with immediate opcode */
15323 gen_slt_imm(env, ctx, op, rt, rs, imm);
15325 case OPC_ANDI: /* Arithmetic with immediate opcode */
15329 gen_logic_imm(env, ctx, op, rt, rs, imm);
15331 case OPC_J ... OPC_JAL: /* Jump */
15332 offset = (int32_t)(ctx->opcode & 0x3FFFFFF) << 2;
15333 gen_compute_branch(ctx, op, 4, rs, rt, offset);
15336 case OPC_BEQ ... OPC_BGTZ: /* Branch */
15337 case OPC_BEQL ... OPC_BGTZL:
15338 gen_compute_branch(ctx, op, 4, rs, rt, imm << 2);
15341 case OPC_LB ... OPC_LWR: /* Load and stores */
15343 gen_ld(env, ctx, op, rt, rs, imm);
15345 case OPC_SB ... OPC_SW:
15347 gen_st(ctx, op, rt, rs, imm);
15350 gen_st_cond(ctx, op, rt, rs, imm);
15353 check_cp0_enabled(ctx);
15354 check_insn(env, ctx, ISA_MIPS3 | ISA_MIPS32);
15355 /* Treat as NOP. */
15358 check_insn(env, ctx, ISA_MIPS4 | ISA_MIPS32);
15359 /* Treat as NOP. */
15362 /* Floating point (COP1). */
15367 gen_cop1_ldst(env, ctx, op, rt, rs, imm);
15371 if (env->CP0_Config1 & (1 << CP0C1_FP)) {
15372 check_cp1_enabled(ctx);
15373 op1 = MASK_CP1(ctx->opcode);
15377 check_insn(env, ctx, ISA_MIPS32R2);
15382 gen_cp1(ctx, op1, rt, rd);
15384 #if defined(TARGET_MIPS64)
15387 check_insn(env, ctx, ISA_MIPS3);
15388 gen_cp1(ctx, op1, rt, rd);
15394 check_insn(env, ctx, ASE_MIPS3D);
15397 gen_compute_branch1(env, ctx, MASK_BC1(ctx->opcode),
15398 (rt >> 2) & 0x7, imm << 2);
15406 gen_farith(ctx, ctx->opcode & FOP(0x3f, 0x1f), rt, rd, sa,
15411 generate_exception (ctx, EXCP_RI);
15415 generate_exception_err(ctx, EXCP_CpU, 1);
15424 /* COP2: Not implemented. */
15425 generate_exception_err(ctx, EXCP_CpU, 2);
15428 check_insn(env, ctx, INSN_LOONGSON2F);
15429 /* Note that these instructions use different fields. */
15430 gen_loongson_multimedia(ctx, sa, rd, rt);
15434 if (env->CP0_Config1 & (1 << CP0C1_FP)) {
15435 check_cp1_enabled(ctx);
15436 op1 = MASK_CP3(ctx->opcode);
15444 gen_flt3_ldst(ctx, op1, sa, rd, rs, rt);
15447 /* Treat as NOP. */
15462 gen_flt3_arith(ctx, op1, sa, rs, rd, rt);
15466 generate_exception (ctx, EXCP_RI);
15470 generate_exception_err(ctx, EXCP_CpU, 1);
15474 #if defined(TARGET_MIPS64)
15475 /* MIPS64 opcodes */
15477 case OPC_LDL ... OPC_LDR:
15480 check_insn(env, ctx, ISA_MIPS3);
15481 check_mips_64(ctx);
15482 gen_ld(env, ctx, op, rt, rs, imm);
15484 case OPC_SDL ... OPC_SDR:
15486 check_insn(env, ctx, ISA_MIPS3);
15487 check_mips_64(ctx);
15488 gen_st(ctx, op, rt, rs, imm);
15491 check_insn(env, ctx, ISA_MIPS3);
15492 check_mips_64(ctx);
15493 gen_st_cond(ctx, op, rt, rs, imm);
15497 check_insn(env, ctx, ISA_MIPS3);
15498 check_mips_64(ctx);
15499 gen_arith_imm(env, ctx, op, rt, rs, imm);
15503 check_insn(env, ctx, ASE_MIPS16 | ASE_MICROMIPS);
15504 offset = (int32_t)(ctx->opcode & 0x3FFFFFF) << 2;
15505 gen_compute_branch(ctx, op, 4, rs, rt, offset);
15509 check_insn(env, ctx, ASE_MDMX);
15510 /* MDMX: Not implemented. */
15511 default: /* Invalid */
15512 MIPS_INVAL("major opcode");
15513 generate_exception(ctx, EXCP_RI);
15519 gen_intermediate_code_internal (CPUMIPSState *env, TranslationBlock *tb,
15523 target_ulong pc_start;
15524 uint16_t *gen_opc_end;
15533 qemu_log("search pc %d\n", search_pc);
15536 gen_opc_end = gen_opc_buf + OPC_MAX_SIZE;
15539 ctx.singlestep_enabled = env->singlestep_enabled;
15541 ctx.bstate = BS_NONE;
15542 /* Restore delay slot state from the tb context. */
15543 ctx.hflags = (uint32_t)tb->flags; /* FIXME: maybe use 64 bits here? */
15544 restore_cpu_state(env, &ctx);
15545 #ifdef CONFIG_USER_ONLY
15546 ctx.mem_idx = MIPS_HFLAG_UM;
15548 ctx.mem_idx = ctx.hflags & MIPS_HFLAG_KSU;
15551 max_insns = tb->cflags & CF_COUNT_MASK;
15552 if (max_insns == 0)
15553 max_insns = CF_COUNT_MASK;
15554 LOG_DISAS("\ntb %p idx %d hflags %04x\n", tb, ctx.mem_idx, ctx.hflags);
15555 gen_icount_start();
15556 while (ctx.bstate == BS_NONE) {
15557 if (unlikely(!QTAILQ_EMPTY(&env->breakpoints))) {
15558 QTAILQ_FOREACH(bp, &env->breakpoints, entry) {
15559 if (bp->pc == ctx.pc) {
15560 save_cpu_state(&ctx, 1);
15561 ctx.bstate = BS_BRANCH;
15562 gen_helper_0e0i(raise_exception, EXCP_DEBUG);
15563 /* Include the breakpoint location or the tb won't
15564 * be flushed when it must be. */
15566 goto done_generating;
15572 j = gen_opc_ptr - gen_opc_buf;
15576 gen_opc_instr_start[lj++] = 0;
15578 gen_opc_pc[lj] = ctx.pc;
15579 gen_opc_hflags[lj] = ctx.hflags & MIPS_HFLAG_BMASK;
15580 gen_opc_btarget[lj] = ctx.btarget;
15581 gen_opc_instr_start[lj] = 1;
15582 gen_opc_icount[lj] = num_insns;
15584 if (num_insns + 1 == max_insns && (tb->cflags & CF_LAST_IO))
15588 if (!(ctx.hflags & MIPS_HFLAG_M16)) {
15589 ctx.opcode = cpu_ldl_code(env, ctx.pc);
15591 decode_opc(env, &ctx, &is_branch);
15592 } else if (env->insn_flags & ASE_MICROMIPS) {
15593 ctx.opcode = cpu_lduw_code(env, ctx.pc);
15594 insn_bytes = decode_micromips_opc(env, &ctx, &is_branch);
15595 } else if (env->insn_flags & ASE_MIPS16) {
15596 ctx.opcode = cpu_lduw_code(env, ctx.pc);
15597 insn_bytes = decode_mips16_opc(env, &ctx, &is_branch);
15599 generate_exception(&ctx, EXCP_RI);
15600 ctx.bstate = BS_STOP;
15604 handle_delay_slot(env, &ctx, insn_bytes);
15606 ctx.pc += insn_bytes;
15610 /* Execute a branch and its delay slot as a single instruction.
15611 This is what GDB expects and is consistent with what the
15612 hardware does (e.g. if a delay slot instruction faults, the
15613 reported PC is the PC of the branch). */
15614 if (env->singlestep_enabled && (ctx.hflags & MIPS_HFLAG_BMASK) == 0)
15617 if ((ctx.pc & (TARGET_PAGE_SIZE - 1)) == 0)
15620 if (gen_opc_ptr >= gen_opc_end)
15623 if (num_insns >= max_insns)
15629 if (tb->cflags & CF_LAST_IO)
15631 if (env->singlestep_enabled && ctx.bstate != BS_BRANCH) {
15632 save_cpu_state(&ctx, ctx.bstate == BS_NONE);
15633 gen_helper_0e0i(raise_exception, EXCP_DEBUG);
15635 switch (ctx.bstate) {
15637 gen_goto_tb(&ctx, 0, ctx.pc);
15640 save_cpu_state(&ctx, 0);
15641 gen_goto_tb(&ctx, 0, ctx.pc);
15644 tcg_gen_exit_tb(0);
15652 gen_icount_end(tb, num_insns);
15653 *gen_opc_ptr = INDEX_op_end;
15655 j = gen_opc_ptr - gen_opc_buf;
15658 gen_opc_instr_start[lj++] = 0;
15660 tb->size = ctx.pc - pc_start;
15661 tb->icount = num_insns;
15665 if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM)) {
15666 qemu_log("IN: %s\n", lookup_symbol(pc_start));
15667 log_target_disas(pc_start, ctx.pc - pc_start, 0);
15673 void gen_intermediate_code (CPUMIPSState *env, struct TranslationBlock *tb)
15675 gen_intermediate_code_internal(env, tb, 0);
15678 void gen_intermediate_code_pc (CPUMIPSState *env, struct TranslationBlock *tb)
15680 gen_intermediate_code_internal(env, tb, 1);
15683 static void fpu_dump_state(CPUMIPSState *env, FILE *f, fprintf_function fpu_fprintf,
15687 int is_fpu64 = !!(env->hflags & MIPS_HFLAG_F64);
15689 #define printfpr(fp) \
15692 fpu_fprintf(f, "w:%08x d:%016" PRIx64 \
15693 " fd:%13g fs:%13g psu: %13g\n", \
15694 (fp)->w[FP_ENDIAN_IDX], (fp)->d, \
15695 (double)(fp)->fd, \
15696 (double)(fp)->fs[FP_ENDIAN_IDX], \
15697 (double)(fp)->fs[!FP_ENDIAN_IDX]); \
15700 tmp.w[FP_ENDIAN_IDX] = (fp)->w[FP_ENDIAN_IDX]; \
15701 tmp.w[!FP_ENDIAN_IDX] = ((fp) + 1)->w[FP_ENDIAN_IDX]; \
15702 fpu_fprintf(f, "w:%08x d:%016" PRIx64 \
15703 " fd:%13g fs:%13g psu:%13g\n", \
15704 tmp.w[FP_ENDIAN_IDX], tmp.d, \
15706 (double)tmp.fs[FP_ENDIAN_IDX], \
15707 (double)tmp.fs[!FP_ENDIAN_IDX]); \
15712 fpu_fprintf(f, "CP1 FCR0 0x%08x FCR31 0x%08x SR.FR %d fp_status 0x%02x\n",
15713 env->active_fpu.fcr0, env->active_fpu.fcr31, is_fpu64,
15714 get_float_exception_flags(&env->active_fpu.fp_status));
15715 for (i = 0; i < 32; (is_fpu64) ? i++ : (i += 2)) {
15716 fpu_fprintf(f, "%3s: ", fregnames[i]);
15717 printfpr(&env->active_fpu.fpr[i]);
15723 #if defined(TARGET_MIPS64) && defined(MIPS_DEBUG_SIGN_EXTENSIONS)
15724 /* Debug help: The architecture requires 32bit code to maintain proper
15725 sign-extended values on 64bit machines. */
15727 #define SIGN_EXT_P(val) ((((val) & ~0x7fffffff) == 0) || (((val) & ~0x7fffffff) == ~0x7fffffff))
15730 cpu_mips_check_sign_extensions (CPUMIPSState *env, FILE *f,
15731 fprintf_function cpu_fprintf,
15736 if (!SIGN_EXT_P(env->active_tc.PC))
15737 cpu_fprintf(f, "BROKEN: pc=0x" TARGET_FMT_lx "\n", env->active_tc.PC);
15738 if (!SIGN_EXT_P(env->active_tc.HI[0]))
15739 cpu_fprintf(f, "BROKEN: HI=0x" TARGET_FMT_lx "\n", env->active_tc.HI[0]);
15740 if (!SIGN_EXT_P(env->active_tc.LO[0]))
15741 cpu_fprintf(f, "BROKEN: LO=0x" TARGET_FMT_lx "\n", env->active_tc.LO[0]);
15742 if (!SIGN_EXT_P(env->btarget))
15743 cpu_fprintf(f, "BROKEN: btarget=0x" TARGET_FMT_lx "\n", env->btarget);
15745 for (i = 0; i < 32; i++) {
15746 if (!SIGN_EXT_P(env->active_tc.gpr[i]))
15747 cpu_fprintf(f, "BROKEN: %s=0x" TARGET_FMT_lx "\n", regnames[i], env->active_tc.gpr[i]);
15750 if (!SIGN_EXT_P(env->CP0_EPC))
15751 cpu_fprintf(f, "BROKEN: EPC=0x" TARGET_FMT_lx "\n", env->CP0_EPC);
15752 if (!SIGN_EXT_P(env->lladdr))
15753 cpu_fprintf(f, "BROKEN: LLAddr=0x" TARGET_FMT_lx "\n", env->lladdr);
15757 void cpu_dump_state (CPUMIPSState *env, FILE *f, fprintf_function cpu_fprintf,
15762 cpu_fprintf(f, "pc=0x" TARGET_FMT_lx " HI=0x" TARGET_FMT_lx
15763 " LO=0x" TARGET_FMT_lx " ds %04x "
15764 TARGET_FMT_lx " " TARGET_FMT_ld "\n",
15765 env->active_tc.PC, env->active_tc.HI[0], env->active_tc.LO[0],
15766 env->hflags, env->btarget, env->bcond);
15767 for (i = 0; i < 32; i++) {
15769 cpu_fprintf(f, "GPR%02d:", i);
15770 cpu_fprintf(f, " %s " TARGET_FMT_lx, regnames[i], env->active_tc.gpr[i]);
15772 cpu_fprintf(f, "\n");
15775 cpu_fprintf(f, "CP0 Status 0x%08x Cause 0x%08x EPC 0x" TARGET_FMT_lx "\n",
15776 env->CP0_Status, env->CP0_Cause, env->CP0_EPC);
15777 cpu_fprintf(f, " Config0 0x%08x Config1 0x%08x LLAddr 0x" TARGET_FMT_lx "\n",
15778 env->CP0_Config0, env->CP0_Config1, env->lladdr);
15779 if (env->hflags & MIPS_HFLAG_FPU)
15780 fpu_dump_state(env, f, cpu_fprintf, flags);
15781 #if defined(TARGET_MIPS64) && defined(MIPS_DEBUG_SIGN_EXTENSIONS)
15782 cpu_mips_check_sign_extensions(env, f, cpu_fprintf, flags);
15786 static void mips_tcg_init(void)
15791 /* Initialize various static tables. */
15795 cpu_env = tcg_global_reg_new_ptr(TCG_AREG0, "env");
15796 TCGV_UNUSED(cpu_gpr[0]);
15797 for (i = 1; i < 32; i++)
15798 cpu_gpr[i] = tcg_global_mem_new(TCG_AREG0,
15799 offsetof(CPUMIPSState, active_tc.gpr[i]),
15802 for (i = 0; i < 32; i++) {
15803 int off = offsetof(CPUMIPSState, active_fpu.fpr[i]);
15804 fpu_f64[i] = tcg_global_mem_new_i64(TCG_AREG0, off, fregnames[i]);
15807 cpu_PC = tcg_global_mem_new(TCG_AREG0,
15808 offsetof(CPUMIPSState, active_tc.PC), "PC");
15809 for (i = 0; i < MIPS_DSP_ACC; i++) {
15810 cpu_HI[i] = tcg_global_mem_new(TCG_AREG0,
15811 offsetof(CPUMIPSState, active_tc.HI[i]),
15813 cpu_LO[i] = tcg_global_mem_new(TCG_AREG0,
15814 offsetof(CPUMIPSState, active_tc.LO[i]),
15816 cpu_ACX[i] = tcg_global_mem_new(TCG_AREG0,
15817 offsetof(CPUMIPSState, active_tc.ACX[i]),
15820 cpu_dspctrl = tcg_global_mem_new(TCG_AREG0,
15821 offsetof(CPUMIPSState, active_tc.DSPControl),
15823 bcond = tcg_global_mem_new(TCG_AREG0,
15824 offsetof(CPUMIPSState, bcond), "bcond");
15825 btarget = tcg_global_mem_new(TCG_AREG0,
15826 offsetof(CPUMIPSState, btarget), "btarget");
15827 hflags = tcg_global_mem_new_i32(TCG_AREG0,
15828 offsetof(CPUMIPSState, hflags), "hflags");
15830 fpu_fcr0 = tcg_global_mem_new_i32(TCG_AREG0,
15831 offsetof(CPUMIPSState, active_fpu.fcr0),
15833 fpu_fcr31 = tcg_global_mem_new_i32(TCG_AREG0,
15834 offsetof(CPUMIPSState, active_fpu.fcr31),
15837 /* register helpers */
15838 #define GEN_HELPER 2
15839 #include "helper.h"
15844 #include "translate_init.c"
15846 MIPSCPU *cpu_mips_init(const char *cpu_model)
15850 const mips_def_t *def;
15852 def = cpu_mips_find_by_name(cpu_model);
15855 cpu = MIPS_CPU(object_new(TYPE_MIPS_CPU));
15857 env->cpu_model = def;
15858 env->cpu_model_str = cpu_model;
15860 #ifndef CONFIG_USER_ONLY
15861 mmu_init(env, def);
15863 fpu_init(env, def);
15864 mvp_init(env, def);
15866 cpu_reset(CPU(cpu));
15867 qemu_init_vcpu(env);
15871 void cpu_state_reset(CPUMIPSState *env)
15873 if (qemu_loglevel_mask(CPU_LOG_RESET)) {
15874 qemu_log("CPU Reset (CPU %d)\n", env->cpu_index);
15875 log_cpu_state(env, 0);
15878 memset(env, 0, offsetof(CPUMIPSState, breakpoints));
15881 /* Reset registers to their default values */
15882 env->CP0_PRid = env->cpu_model->CP0_PRid;
15883 env->CP0_Config0 = env->cpu_model->CP0_Config0;
15884 #ifdef TARGET_WORDS_BIGENDIAN
15885 env->CP0_Config0 |= (1 << CP0C0_BE);
15887 env->CP0_Config1 = env->cpu_model->CP0_Config1;
15888 env->CP0_Config2 = env->cpu_model->CP0_Config2;
15889 env->CP0_Config3 = env->cpu_model->CP0_Config3;
15890 env->CP0_Config6 = env->cpu_model->CP0_Config6;
15891 env->CP0_Config7 = env->cpu_model->CP0_Config7;
15892 env->CP0_LLAddr_rw_bitmask = env->cpu_model->CP0_LLAddr_rw_bitmask
15893 << env->cpu_model->CP0_LLAddr_shift;
15894 env->CP0_LLAddr_shift = env->cpu_model->CP0_LLAddr_shift;
15895 env->SYNCI_Step = env->cpu_model->SYNCI_Step;
15896 env->CCRes = env->cpu_model->CCRes;
15897 env->CP0_Status_rw_bitmask = env->cpu_model->CP0_Status_rw_bitmask;
15898 env->CP0_TCStatus_rw_bitmask = env->cpu_model->CP0_TCStatus_rw_bitmask;
15899 env->CP0_SRSCtl = env->cpu_model->CP0_SRSCtl;
15900 env->current_tc = 0;
15901 env->SEGBITS = env->cpu_model->SEGBITS;
15902 env->SEGMask = (target_ulong)((1ULL << env->cpu_model->SEGBITS) - 1);
15903 #if defined(TARGET_MIPS64)
15904 if (env->cpu_model->insn_flags & ISA_MIPS3) {
15905 env->SEGMask |= 3ULL << 62;
15908 env->PABITS = env->cpu_model->PABITS;
15909 env->PAMask = (target_ulong)((1ULL << env->cpu_model->PABITS) - 1);
15910 env->CP0_SRSConf0_rw_bitmask = env->cpu_model->CP0_SRSConf0_rw_bitmask;
15911 env->CP0_SRSConf0 = env->cpu_model->CP0_SRSConf0;
15912 env->CP0_SRSConf1_rw_bitmask = env->cpu_model->CP0_SRSConf1_rw_bitmask;
15913 env->CP0_SRSConf1 = env->cpu_model->CP0_SRSConf1;
15914 env->CP0_SRSConf2_rw_bitmask = env->cpu_model->CP0_SRSConf2_rw_bitmask;
15915 env->CP0_SRSConf2 = env->cpu_model->CP0_SRSConf2;
15916 env->CP0_SRSConf3_rw_bitmask = env->cpu_model->CP0_SRSConf3_rw_bitmask;
15917 env->CP0_SRSConf3 = env->cpu_model->CP0_SRSConf3;
15918 env->CP0_SRSConf4_rw_bitmask = env->cpu_model->CP0_SRSConf4_rw_bitmask;
15919 env->CP0_SRSConf4 = env->cpu_model->CP0_SRSConf4;
15920 env->active_fpu.fcr0 = env->cpu_model->CP1_fcr0;
15921 env->insn_flags = env->cpu_model->insn_flags;
15923 #if defined(CONFIG_USER_ONLY)
15924 env->CP0_Status = (MIPS_HFLAG_UM << CP0St_KSU);
15925 /* Enable access to the CPUNum, SYNCI_Step, CC, and CCRes RDHWR
15926 hardware registers. */
15927 env->CP0_HWREna |= 0x0000000F;
15928 if (env->CP0_Config1 & (1 << CP0C1_FP)) {
15929 env->CP0_Status |= (1 << CP0St_CU1);
15931 if (env->cpu_model->insn_flags & ASE_DSPR2) {
15932 env->hflags |= MIPS_HFLAG_DSP | MIPS_HFLAG_DSPR2;
15933 } else if (env->cpu_model->insn_flags & ASE_DSP) {
15934 env->hflags |= MIPS_HFLAG_DSP;
15937 if (env->hflags & MIPS_HFLAG_BMASK) {
15938 /* If the exception was raised from a delay slot,
15939 come back to the jump. */
15940 env->CP0_ErrorEPC = env->active_tc.PC - 4;
15942 env->CP0_ErrorEPC = env->active_tc.PC;
15944 env->active_tc.PC = (int32_t)0xBFC00000;
15945 env->CP0_Random = env->tlb->nb_tlb - 1;
15946 env->tlb->tlb_in_use = env->tlb->nb_tlb;
15947 env->CP0_Wired = 0;
15948 env->CP0_EBase = 0x80000000 | (env->cpu_index & 0x3FF);
15949 env->CP0_Status = (1 << CP0St_BEV) | (1 << CP0St_ERL);
15950 /* vectored interrupts not implemented, timer on int 7,
15951 no performance counters. */
15952 env->CP0_IntCtl = 0xe0000000;
15956 for (i = 0; i < 7; i++) {
15957 env->CP0_WatchLo[i] = 0;
15958 env->CP0_WatchHi[i] = 0x80000000;
15960 env->CP0_WatchLo[7] = 0;
15961 env->CP0_WatchHi[7] = 0;
15963 /* Count register increments in debug mode, EJTAG version 1 */
15964 env->CP0_Debug = (1 << CP0DB_CNT) | (0x1 << CP0DB_VER);
15966 if (env->CP0_Config3 & (1 << CP0C3_MT)) {
15969 /* Only TC0 on VPE 0 starts as active. */
15970 for (i = 0; i < ARRAY_SIZE(env->tcs); i++) {
15971 env->tcs[i].CP0_TCBind = env->cpu_index << CP0TCBd_CurVPE;
15972 env->tcs[i].CP0_TCHalt = 1;
15974 env->active_tc.CP0_TCHalt = 1;
15977 if (!env->cpu_index) {
15978 /* VPE0 starts up enabled. */
15979 env->mvp->CP0_MVPControl |= (1 << CP0MVPCo_EVP);
15980 env->CP0_VPEConf0 |= (1 << CP0VPEC0_MVP) | (1 << CP0VPEC0_VPA);
15982 /* TC0 starts up unhalted. */
15984 env->active_tc.CP0_TCHalt = 0;
15985 env->tcs[0].CP0_TCHalt = 0;
15986 /* With thread 0 active. */
15987 env->active_tc.CP0_TCStatus = (1 << CP0TCSt_A);
15988 env->tcs[0].CP0_TCStatus = (1 << CP0TCSt_A);
15992 compute_hflags(env);
15993 env->exception_index = EXCP_NONE;
15996 void restore_state_to_opc(CPUMIPSState *env, TranslationBlock *tb, int pc_pos)
15998 env->active_tc.PC = gen_opc_pc[pc_pos];
15999 env->hflags &= ~MIPS_HFLAG_BMASK;
16000 env->hflags |= gen_opc_hflags[pc_pos];
16001 switch (env->hflags & MIPS_HFLAG_BMASK_BASE) {
16002 case MIPS_HFLAG_BR:
16004 case MIPS_HFLAG_BC:
16005 case MIPS_HFLAG_BL:
16007 env->btarget = gen_opc_btarget[pc_pos];