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];
1019 #include "gen-icount.h"
1021 #define gen_helper_0e0i(name, arg) do { \
1022 TCGv_i32 helper_tmp = tcg_const_i32(arg); \
1023 gen_helper_##name(cpu_env, helper_tmp); \
1024 tcg_temp_free_i32(helper_tmp); \
1027 #define gen_helper_0e1i(name, arg1, arg2) do { \
1028 TCGv_i32 helper_tmp = tcg_const_i32(arg2); \
1029 gen_helper_##name(cpu_env, arg1, helper_tmp); \
1030 tcg_temp_free_i32(helper_tmp); \
1033 #define gen_helper_1e0i(name, ret, arg1) do { \
1034 TCGv_i32 helper_tmp = tcg_const_i32(arg1); \
1035 gen_helper_##name(ret, cpu_env, helper_tmp); \
1036 tcg_temp_free_i32(helper_tmp); \
1039 #define gen_helper_1e1i(name, ret, arg1, arg2) do { \
1040 TCGv_i32 helper_tmp = tcg_const_i32(arg2); \
1041 gen_helper_##name(ret, cpu_env, arg1, helper_tmp); \
1042 tcg_temp_free_i32(helper_tmp); \
1045 #define gen_helper_0e2i(name, arg1, arg2, arg3) do { \
1046 TCGv_i32 helper_tmp = tcg_const_i32(arg3); \
1047 gen_helper_##name(cpu_env, arg1, arg2, helper_tmp); \
1048 tcg_temp_free_i32(helper_tmp); \
1051 #define gen_helper_1e2i(name, ret, arg1, arg2, arg3) do { \
1052 TCGv_i32 helper_tmp = tcg_const_i32(arg3); \
1053 gen_helper_##name(ret, cpu_env, arg1, arg2, helper_tmp); \
1054 tcg_temp_free_i32(helper_tmp); \
1057 #define gen_helper_0e3i(name, arg1, arg2, arg3, arg4) do { \
1058 TCGv_i32 helper_tmp = tcg_const_i32(arg4); \
1059 gen_helper_##name(cpu_env, arg1, arg2, arg3, helper_tmp); \
1060 tcg_temp_free_i32(helper_tmp); \
1063 typedef struct DisasContext {
1064 struct TranslationBlock *tb;
1065 target_ulong pc, saved_pc;
1067 int singlestep_enabled;
1068 /* Routine used to access memory */
1070 uint32_t hflags, saved_hflags;
1072 target_ulong btarget;
1076 BS_NONE = 0, /* We go out of the TB without reaching a branch or an
1077 * exception condition */
1078 BS_STOP = 1, /* We want to stop translation for any reason */
1079 BS_BRANCH = 2, /* We reached a branch condition */
1080 BS_EXCP = 3, /* We reached an exception condition */
1083 static const char * const regnames[] = {
1084 "r0", "at", "v0", "v1", "a0", "a1", "a2", "a3",
1085 "t0", "t1", "t2", "t3", "t4", "t5", "t6", "t7",
1086 "s0", "s1", "s2", "s3", "s4", "s5", "s6", "s7",
1087 "t8", "t9", "k0", "k1", "gp", "sp", "s8", "ra",
1090 static const char * const regnames_HI[] = {
1091 "HI0", "HI1", "HI2", "HI3",
1094 static const char * const regnames_LO[] = {
1095 "LO0", "LO1", "LO2", "LO3",
1098 static const char * const regnames_ACX[] = {
1099 "ACX0", "ACX1", "ACX2", "ACX3",
1102 static const char * const fregnames[] = {
1103 "f0", "f1", "f2", "f3", "f4", "f5", "f6", "f7",
1104 "f8", "f9", "f10", "f11", "f12", "f13", "f14", "f15",
1105 "f16", "f17", "f18", "f19", "f20", "f21", "f22", "f23",
1106 "f24", "f25", "f26", "f27", "f28", "f29", "f30", "f31",
1109 #define MIPS_DEBUG(fmt, ...) \
1111 if (MIPS_DEBUG_DISAS) { \
1112 qemu_log_mask(CPU_LOG_TB_IN_ASM, \
1113 TARGET_FMT_lx ": %08x " fmt "\n", \
1114 ctx->pc, ctx->opcode , ## __VA_ARGS__); \
1118 #define LOG_DISAS(...) \
1120 if (MIPS_DEBUG_DISAS) { \
1121 qemu_log_mask(CPU_LOG_TB_IN_ASM, ## __VA_ARGS__); \
1125 #define MIPS_INVAL(op) \
1126 MIPS_DEBUG("Invalid %s %03x %03x %03x", op, ctx->opcode >> 26, \
1127 ctx->opcode & 0x3F, ((ctx->opcode >> 16) & 0x1F))
1129 /* General purpose registers moves. */
1130 static inline void gen_load_gpr (TCGv t, int reg)
1133 tcg_gen_movi_tl(t, 0);
1135 tcg_gen_mov_tl(t, cpu_gpr[reg]);
1138 static inline void gen_store_gpr (TCGv t, int reg)
1141 tcg_gen_mov_tl(cpu_gpr[reg], t);
1144 /* Moves to/from ACX register. */
1145 static inline void gen_load_ACX (TCGv t, int reg)
1147 tcg_gen_mov_tl(t, cpu_ACX[reg]);
1150 static inline void gen_store_ACX (TCGv t, int reg)
1152 tcg_gen_mov_tl(cpu_ACX[reg], t);
1155 /* Moves to/from shadow registers. */
1156 static inline void gen_load_srsgpr (int from, int to)
1158 TCGv t0 = tcg_temp_new();
1161 tcg_gen_movi_tl(t0, 0);
1163 TCGv_i32 t2 = tcg_temp_new_i32();
1164 TCGv_ptr addr = tcg_temp_new_ptr();
1166 tcg_gen_ld_i32(t2, cpu_env, offsetof(CPUMIPSState, CP0_SRSCtl));
1167 tcg_gen_shri_i32(t2, t2, CP0SRSCtl_PSS);
1168 tcg_gen_andi_i32(t2, t2, 0xf);
1169 tcg_gen_muli_i32(t2, t2, sizeof(target_ulong) * 32);
1170 tcg_gen_ext_i32_ptr(addr, t2);
1171 tcg_gen_add_ptr(addr, cpu_env, addr);
1173 tcg_gen_ld_tl(t0, addr, sizeof(target_ulong) * from);
1174 tcg_temp_free_ptr(addr);
1175 tcg_temp_free_i32(t2);
1177 gen_store_gpr(t0, to);
1181 static inline void gen_store_srsgpr (int from, int to)
1184 TCGv t0 = tcg_temp_new();
1185 TCGv_i32 t2 = tcg_temp_new_i32();
1186 TCGv_ptr addr = tcg_temp_new_ptr();
1188 gen_load_gpr(t0, from);
1189 tcg_gen_ld_i32(t2, cpu_env, offsetof(CPUMIPSState, CP0_SRSCtl));
1190 tcg_gen_shri_i32(t2, t2, CP0SRSCtl_PSS);
1191 tcg_gen_andi_i32(t2, t2, 0xf);
1192 tcg_gen_muli_i32(t2, t2, sizeof(target_ulong) * 32);
1193 tcg_gen_ext_i32_ptr(addr, t2);
1194 tcg_gen_add_ptr(addr, cpu_env, addr);
1196 tcg_gen_st_tl(t0, addr, sizeof(target_ulong) * to);
1197 tcg_temp_free_ptr(addr);
1198 tcg_temp_free_i32(t2);
1203 /* Floating point register moves. */
1204 static void gen_load_fpr32(TCGv_i32 t, int reg)
1206 tcg_gen_trunc_i64_i32(t, fpu_f64[reg]);
1209 static void gen_store_fpr32(TCGv_i32 t, int reg)
1211 TCGv_i64 t64 = tcg_temp_new_i64();
1212 tcg_gen_extu_i32_i64(t64, t);
1213 tcg_gen_deposit_i64(fpu_f64[reg], fpu_f64[reg], t64, 0, 32);
1214 tcg_temp_free_i64(t64);
1217 static void gen_load_fpr32h(TCGv_i32 t, int reg)
1219 TCGv_i64 t64 = tcg_temp_new_i64();
1220 tcg_gen_shri_i64(t64, fpu_f64[reg], 32);
1221 tcg_gen_trunc_i64_i32(t, t64);
1222 tcg_temp_free_i64(t64);
1225 static void gen_store_fpr32h(TCGv_i32 t, int reg)
1227 TCGv_i64 t64 = tcg_temp_new_i64();
1228 tcg_gen_extu_i32_i64(t64, t);
1229 tcg_gen_deposit_i64(fpu_f64[reg], fpu_f64[reg], t64, 32, 32);
1230 tcg_temp_free_i64(t64);
1233 static void gen_load_fpr64(DisasContext *ctx, TCGv_i64 t, int reg)
1235 if (ctx->hflags & MIPS_HFLAG_F64) {
1236 tcg_gen_mov_i64(t, fpu_f64[reg]);
1238 tcg_gen_concat32_i64(t, fpu_f64[reg & ~1], fpu_f64[reg | 1]);
1242 static void gen_store_fpr64(DisasContext *ctx, TCGv_i64 t, int reg)
1244 if (ctx->hflags & MIPS_HFLAG_F64) {
1245 tcg_gen_mov_i64(fpu_f64[reg], t);
1248 tcg_gen_deposit_i64(fpu_f64[reg & ~1], fpu_f64[reg & ~1], t, 0, 32);
1249 t0 = tcg_temp_new_i64();
1250 tcg_gen_shri_i64(t0, t, 32);
1251 tcg_gen_deposit_i64(fpu_f64[reg | 1], fpu_f64[reg | 1], t0, 0, 32);
1252 tcg_temp_free_i64(t0);
1256 static inline int get_fp_bit (int cc)
1265 static inline void gen_save_pc(target_ulong pc)
1267 tcg_gen_movi_tl(cpu_PC, pc);
1270 static inline void save_cpu_state (DisasContext *ctx, int do_save_pc)
1272 LOG_DISAS("hflags %08x saved %08x\n", ctx->hflags, ctx->saved_hflags);
1273 if (do_save_pc && ctx->pc != ctx->saved_pc) {
1274 gen_save_pc(ctx->pc);
1275 ctx->saved_pc = ctx->pc;
1277 if (ctx->hflags != ctx->saved_hflags) {
1278 tcg_gen_movi_i32(hflags, ctx->hflags);
1279 ctx->saved_hflags = ctx->hflags;
1280 switch (ctx->hflags & MIPS_HFLAG_BMASK_BASE) {
1286 tcg_gen_movi_tl(btarget, ctx->btarget);
1292 static inline void restore_cpu_state (CPUMIPSState *env, DisasContext *ctx)
1294 ctx->saved_hflags = ctx->hflags;
1295 switch (ctx->hflags & MIPS_HFLAG_BMASK_BASE) {
1301 ctx->btarget = env->btarget;
1307 generate_exception_err (DisasContext *ctx, int excp, int err)
1309 TCGv_i32 texcp = tcg_const_i32(excp);
1310 TCGv_i32 terr = tcg_const_i32(err);
1311 save_cpu_state(ctx, 1);
1312 gen_helper_raise_exception_err(cpu_env, texcp, terr);
1313 tcg_temp_free_i32(terr);
1314 tcg_temp_free_i32(texcp);
1318 generate_exception (DisasContext *ctx, int excp)
1320 save_cpu_state(ctx, 1);
1321 gen_helper_0e0i(raise_exception, excp);
1324 /* Addresses computation */
1325 static inline void gen_op_addr_add (DisasContext *ctx, TCGv ret, TCGv arg0, TCGv arg1)
1327 tcg_gen_add_tl(ret, arg0, arg1);
1329 #if defined(TARGET_MIPS64)
1330 /* For compatibility with 32-bit code, data reference in user mode
1331 with Status_UX = 0 should be casted to 32-bit and sign extended.
1332 See the MIPS64 PRA manual, section 4.10. */
1333 if (((ctx->hflags & MIPS_HFLAG_KSU) == MIPS_HFLAG_UM) &&
1334 !(ctx->hflags & MIPS_HFLAG_UX)) {
1335 tcg_gen_ext32s_i64(ret, ret);
1340 static inline void check_cp0_enabled(DisasContext *ctx)
1342 if (unlikely(!(ctx->hflags & MIPS_HFLAG_CP0)))
1343 generate_exception_err(ctx, EXCP_CpU, 0);
1346 static inline void check_cp1_enabled(DisasContext *ctx)
1348 if (unlikely(!(ctx->hflags & MIPS_HFLAG_FPU)))
1349 generate_exception_err(ctx, EXCP_CpU, 1);
1352 /* Verify that the processor is running with COP1X instructions enabled.
1353 This is associated with the nabla symbol in the MIPS32 and MIPS64
1356 static inline void check_cop1x(DisasContext *ctx)
1358 if (unlikely(!(ctx->hflags & MIPS_HFLAG_COP1X)))
1359 generate_exception(ctx, EXCP_RI);
1362 /* Verify that the processor is running with 64-bit floating-point
1363 operations enabled. */
1365 static inline void check_cp1_64bitmode(DisasContext *ctx)
1367 if (unlikely(~ctx->hflags & (MIPS_HFLAG_F64 | MIPS_HFLAG_COP1X)))
1368 generate_exception(ctx, EXCP_RI);
1372 * Verify if floating point register is valid; an operation is not defined
1373 * if bit 0 of any register specification is set and the FR bit in the
1374 * Status register equals zero, since the register numbers specify an
1375 * even-odd pair of adjacent coprocessor general registers. When the FR bit
1376 * in the Status register equals one, both even and odd register numbers
1377 * are valid. This limitation exists only for 64 bit wide (d,l,ps) registers.
1379 * Multiple 64 bit wide registers can be checked by calling
1380 * gen_op_cp1_registers(freg1 | freg2 | ... | fregN);
1382 static inline void check_cp1_registers(DisasContext *ctx, int regs)
1384 if (unlikely(!(ctx->hflags & MIPS_HFLAG_F64) && (regs & 1)))
1385 generate_exception(ctx, EXCP_RI);
1388 /* Verify that the processor is running with DSP instructions enabled.
1389 This is enabled by CP0 Status register MX(24) bit.
1392 static inline void check_dsp(DisasContext *ctx)
1394 if (unlikely(!(ctx->hflags & MIPS_HFLAG_DSP))) {
1395 generate_exception(ctx, EXCP_DSPDIS);
1399 static inline void check_dspr2(DisasContext *ctx)
1401 if (unlikely(!(ctx->hflags & MIPS_HFLAG_DSPR2))) {
1402 generate_exception(ctx, EXCP_DSPDIS);
1406 /* This code generates a "reserved instruction" exception if the
1407 CPU does not support the instruction set corresponding to flags. */
1408 static inline void check_insn(CPUMIPSState *env, DisasContext *ctx, int flags)
1410 if (unlikely(!(env->insn_flags & flags)))
1411 generate_exception(ctx, EXCP_RI);
1414 /* This code generates a "reserved instruction" exception if 64-bit
1415 instructions are not enabled. */
1416 static inline void check_mips_64(DisasContext *ctx)
1418 if (unlikely(!(ctx->hflags & MIPS_HFLAG_64)))
1419 generate_exception(ctx, EXCP_RI);
1422 /* Define small wrappers for gen_load_fpr* so that we have a uniform
1423 calling interface for 32 and 64-bit FPRs. No sense in changing
1424 all callers for gen_load_fpr32 when we need the CTX parameter for
1426 #define gen_ldcmp_fpr32(ctx, x, y) gen_load_fpr32(x, y)
1427 #define gen_ldcmp_fpr64(ctx, x, y) gen_load_fpr64(ctx, x, y)
1428 #define FOP_CONDS(type, abs, fmt, ifmt, bits) \
1429 static inline void gen_cmp ## type ## _ ## fmt(DisasContext *ctx, int n, \
1430 int ft, int fs, int cc) \
1432 TCGv_i##bits fp0 = tcg_temp_new_i##bits (); \
1433 TCGv_i##bits fp1 = tcg_temp_new_i##bits (); \
1436 check_cp1_64bitmode(ctx); \
1442 check_cp1_registers(ctx, fs | ft); \
1450 gen_ldcmp_fpr##bits (ctx, fp0, fs); \
1451 gen_ldcmp_fpr##bits (ctx, fp1, ft); \
1453 case 0: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _f, fp0, fp1, cc); break;\
1454 case 1: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _un, fp0, fp1, cc); break;\
1455 case 2: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _eq, fp0, fp1, cc); break;\
1456 case 3: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ueq, fp0, fp1, cc); break;\
1457 case 4: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _olt, fp0, fp1, cc); break;\
1458 case 5: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ult, fp0, fp1, cc); break;\
1459 case 6: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ole, fp0, fp1, cc); break;\
1460 case 7: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ule, fp0, fp1, cc); break;\
1461 case 8: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _sf, fp0, fp1, cc); break;\
1462 case 9: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ngle, fp0, fp1, cc); break;\
1463 case 10: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _seq, fp0, fp1, cc); break;\
1464 case 11: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ngl, fp0, fp1, cc); break;\
1465 case 12: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _lt, fp0, fp1, cc); break;\
1466 case 13: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _nge, fp0, fp1, cc); break;\
1467 case 14: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _le, fp0, fp1, cc); break;\
1468 case 15: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ngt, fp0, fp1, cc); break;\
1471 tcg_temp_free_i##bits (fp0); \
1472 tcg_temp_free_i##bits (fp1); \
1475 FOP_CONDS(, 0, d, FMT_D, 64)
1476 FOP_CONDS(abs, 1, d, FMT_D, 64)
1477 FOP_CONDS(, 0, s, FMT_S, 32)
1478 FOP_CONDS(abs, 1, s, FMT_S, 32)
1479 FOP_CONDS(, 0, ps, FMT_PS, 64)
1480 FOP_CONDS(abs, 1, ps, FMT_PS, 64)
1482 #undef gen_ldcmp_fpr32
1483 #undef gen_ldcmp_fpr64
1485 /* load/store instructions. */
1486 #define OP_LD(insn,fname) \
1487 static inline void op_ld_##insn(TCGv ret, TCGv arg1, DisasContext *ctx) \
1489 tcg_gen_qemu_##fname(ret, arg1, ctx->mem_idx); \
1496 #if defined(TARGET_MIPS64)
1502 #define OP_ST(insn,fname) \
1503 static inline void op_st_##insn(TCGv arg1, TCGv arg2, DisasContext *ctx) \
1505 tcg_gen_qemu_##fname(arg1, arg2, ctx->mem_idx); \
1510 #if defined(TARGET_MIPS64)
1515 #ifdef CONFIG_USER_ONLY
1516 #define OP_LD_ATOMIC(insn,fname) \
1517 static inline void op_ld_##insn(TCGv ret, TCGv arg1, DisasContext *ctx) \
1519 TCGv t0 = tcg_temp_new(); \
1520 tcg_gen_mov_tl(t0, arg1); \
1521 tcg_gen_qemu_##fname(ret, arg1, ctx->mem_idx); \
1522 tcg_gen_st_tl(t0, cpu_env, offsetof(CPUMIPSState, lladdr)); \
1523 tcg_gen_st_tl(ret, cpu_env, offsetof(CPUMIPSState, llval)); \
1524 tcg_temp_free(t0); \
1527 #define OP_LD_ATOMIC(insn,fname) \
1528 static inline void op_ld_##insn(TCGv ret, TCGv arg1, DisasContext *ctx) \
1530 gen_helper_1e1i(insn, ret, arg1, ctx->mem_idx); \
1533 OP_LD_ATOMIC(ll,ld32s);
1534 #if defined(TARGET_MIPS64)
1535 OP_LD_ATOMIC(lld,ld64);
1539 #ifdef CONFIG_USER_ONLY
1540 #define OP_ST_ATOMIC(insn,fname,ldname,almask) \
1541 static inline void op_st_##insn(TCGv arg1, TCGv arg2, int rt, DisasContext *ctx) \
1543 TCGv t0 = tcg_temp_new(); \
1544 int l1 = gen_new_label(); \
1545 int l2 = gen_new_label(); \
1547 tcg_gen_andi_tl(t0, arg2, almask); \
1548 tcg_gen_brcondi_tl(TCG_COND_EQ, t0, 0, l1); \
1549 tcg_gen_st_tl(arg2, cpu_env, offsetof(CPUMIPSState, CP0_BadVAddr)); \
1550 generate_exception(ctx, EXCP_AdES); \
1551 gen_set_label(l1); \
1552 tcg_gen_ld_tl(t0, cpu_env, offsetof(CPUMIPSState, lladdr)); \
1553 tcg_gen_brcond_tl(TCG_COND_NE, arg2, t0, l2); \
1554 tcg_gen_movi_tl(t0, rt | ((almask << 3) & 0x20)); \
1555 tcg_gen_st_tl(t0, cpu_env, offsetof(CPUMIPSState, llreg)); \
1556 tcg_gen_st_tl(arg1, cpu_env, offsetof(CPUMIPSState, llnewval)); \
1557 gen_helper_0e0i(raise_exception, EXCP_SC); \
1558 gen_set_label(l2); \
1559 tcg_gen_movi_tl(t0, 0); \
1560 gen_store_gpr(t0, rt); \
1561 tcg_temp_free(t0); \
1564 #define OP_ST_ATOMIC(insn,fname,ldname,almask) \
1565 static inline void op_st_##insn(TCGv arg1, TCGv arg2, int rt, DisasContext *ctx) \
1567 TCGv t0 = tcg_temp_new(); \
1568 gen_helper_1e2i(insn, t0, arg1, arg2, ctx->mem_idx); \
1569 gen_store_gpr(t0, rt); \
1570 tcg_temp_free(t0); \
1573 OP_ST_ATOMIC(sc,st32,ld32s,0x3);
1574 #if defined(TARGET_MIPS64)
1575 OP_ST_ATOMIC(scd,st64,ld64,0x7);
1579 static void gen_base_offset_addr (DisasContext *ctx, TCGv addr,
1580 int base, int16_t offset)
1583 tcg_gen_movi_tl(addr, offset);
1584 } else if (offset == 0) {
1585 gen_load_gpr(addr, base);
1587 tcg_gen_movi_tl(addr, offset);
1588 gen_op_addr_add(ctx, addr, cpu_gpr[base], addr);
1592 static target_ulong pc_relative_pc (DisasContext *ctx)
1594 target_ulong pc = ctx->pc;
1596 if (ctx->hflags & MIPS_HFLAG_BMASK) {
1597 int branch_bytes = ctx->hflags & MIPS_HFLAG_BDS16 ? 2 : 4;
1602 pc &= ~(target_ulong)3;
1607 static void gen_ld (CPUMIPSState *env, DisasContext *ctx, uint32_t opc,
1608 int rt, int base, int16_t offset)
1610 const char *opn = "ld";
1613 if (rt == 0 && env->insn_flags & (INSN_LOONGSON2E | INSN_LOONGSON2F)) {
1614 /* Loongson CPU uses a load to zero register for prefetch.
1615 We emulate it as a NOP. On other CPU we must perform the
1616 actual memory access. */
1621 t0 = tcg_temp_new();
1622 t1 = tcg_temp_new();
1623 gen_base_offset_addr(ctx, t0, base, offset);
1626 #if defined(TARGET_MIPS64)
1628 save_cpu_state(ctx, 0);
1629 op_ld_lwu(t0, t0, ctx);
1630 gen_store_gpr(t0, rt);
1634 save_cpu_state(ctx, 0);
1635 op_ld_ld(t0, t0, ctx);
1636 gen_store_gpr(t0, rt);
1640 save_cpu_state(ctx, 1);
1641 op_ld_lld(t0, t0, ctx);
1642 gen_store_gpr(t0, rt);
1646 save_cpu_state(ctx, 1);
1647 gen_load_gpr(t1, rt);
1648 gen_helper_1e2i(ldl, t1, t1, t0, ctx->mem_idx);
1649 gen_store_gpr(t1, rt);
1653 save_cpu_state(ctx, 1);
1654 gen_load_gpr(t1, rt);
1655 gen_helper_1e2i(ldr, t1, t1, t0, ctx->mem_idx);
1656 gen_store_gpr(t1, rt);
1660 save_cpu_state(ctx, 0);
1661 tcg_gen_movi_tl(t1, pc_relative_pc(ctx));
1662 gen_op_addr_add(ctx, t0, t0, t1);
1663 op_ld_ld(t0, t0, ctx);
1664 gen_store_gpr(t0, rt);
1669 save_cpu_state(ctx, 0);
1670 tcg_gen_movi_tl(t1, pc_relative_pc(ctx));
1671 gen_op_addr_add(ctx, t0, t0, t1);
1672 op_ld_lw(t0, t0, ctx);
1673 gen_store_gpr(t0, rt);
1677 save_cpu_state(ctx, 0);
1678 op_ld_lw(t0, t0, ctx);
1679 gen_store_gpr(t0, rt);
1683 save_cpu_state(ctx, 0);
1684 op_ld_lh(t0, t0, ctx);
1685 gen_store_gpr(t0, rt);
1689 save_cpu_state(ctx, 0);
1690 op_ld_lhu(t0, t0, ctx);
1691 gen_store_gpr(t0, rt);
1695 save_cpu_state(ctx, 0);
1696 op_ld_lb(t0, t0, ctx);
1697 gen_store_gpr(t0, rt);
1701 save_cpu_state(ctx, 0);
1702 op_ld_lbu(t0, t0, ctx);
1703 gen_store_gpr(t0, rt);
1707 save_cpu_state(ctx, 1);
1708 gen_load_gpr(t1, rt);
1709 gen_helper_1e2i(lwl, t1, t1, t0, ctx->mem_idx);
1710 gen_store_gpr(t1, rt);
1714 save_cpu_state(ctx, 1);
1715 gen_load_gpr(t1, rt);
1716 gen_helper_1e2i(lwr, t1, t1, t0, ctx->mem_idx);
1717 gen_store_gpr(t1, rt);
1721 save_cpu_state(ctx, 1);
1722 op_ld_ll(t0, t0, ctx);
1723 gen_store_gpr(t0, rt);
1727 (void)opn; /* avoid a compiler warning */
1728 MIPS_DEBUG("%s %s, %d(%s)", opn, regnames[rt], offset, regnames[base]);
1734 static void gen_st (DisasContext *ctx, uint32_t opc, int rt,
1735 int base, int16_t offset)
1737 const char *opn = "st";
1738 TCGv t0 = tcg_temp_new();
1739 TCGv t1 = tcg_temp_new();
1741 gen_base_offset_addr(ctx, t0, base, offset);
1742 gen_load_gpr(t1, rt);
1744 #if defined(TARGET_MIPS64)
1746 save_cpu_state(ctx, 0);
1747 op_st_sd(t1, t0, ctx);
1751 save_cpu_state(ctx, 1);
1752 gen_helper_0e2i(sdl, t1, t0, ctx->mem_idx);
1756 save_cpu_state(ctx, 1);
1757 gen_helper_0e2i(sdr, t1, t0, ctx->mem_idx);
1762 save_cpu_state(ctx, 0);
1763 op_st_sw(t1, t0, ctx);
1767 save_cpu_state(ctx, 0);
1768 op_st_sh(t1, t0, ctx);
1772 save_cpu_state(ctx, 0);
1773 op_st_sb(t1, t0, ctx);
1777 save_cpu_state(ctx, 1);
1778 gen_helper_0e2i(swl, t1, t0, ctx->mem_idx);
1782 save_cpu_state(ctx, 1);
1783 gen_helper_0e2i(swr, t1, t0, ctx->mem_idx);
1787 (void)opn; /* avoid a compiler warning */
1788 MIPS_DEBUG("%s %s, %d(%s)", opn, regnames[rt], offset, regnames[base]);
1794 /* Store conditional */
1795 static void gen_st_cond (DisasContext *ctx, uint32_t opc, int rt,
1796 int base, int16_t offset)
1798 const char *opn = "st_cond";
1801 t0 = tcg_temp_local_new();
1803 gen_base_offset_addr(ctx, t0, base, offset);
1804 /* Don't do NOP if destination is zero: we must perform the actual
1807 t1 = tcg_temp_local_new();
1808 gen_load_gpr(t1, rt);
1810 #if defined(TARGET_MIPS64)
1812 save_cpu_state(ctx, 1);
1813 op_st_scd(t1, t0, rt, ctx);
1818 save_cpu_state(ctx, 1);
1819 op_st_sc(t1, t0, rt, ctx);
1823 (void)opn; /* avoid a compiler warning */
1824 MIPS_DEBUG("%s %s, %d(%s)", opn, regnames[rt], offset, regnames[base]);
1829 /* Load and store */
1830 static void gen_flt_ldst (DisasContext *ctx, uint32_t opc, int ft,
1831 int base, int16_t offset)
1833 const char *opn = "flt_ldst";
1834 TCGv t0 = tcg_temp_new();
1836 gen_base_offset_addr(ctx, t0, base, offset);
1837 /* Don't do NOP if destination is zero: we must perform the actual
1842 TCGv_i32 fp0 = tcg_temp_new_i32();
1844 tcg_gen_qemu_ld32s(t0, t0, ctx->mem_idx);
1845 tcg_gen_trunc_tl_i32(fp0, t0);
1846 gen_store_fpr32(fp0, ft);
1847 tcg_temp_free_i32(fp0);
1853 TCGv_i32 fp0 = tcg_temp_new_i32();
1854 TCGv t1 = tcg_temp_new();
1856 gen_load_fpr32(fp0, ft);
1857 tcg_gen_extu_i32_tl(t1, fp0);
1858 tcg_gen_qemu_st32(t1, t0, ctx->mem_idx);
1860 tcg_temp_free_i32(fp0);
1866 TCGv_i64 fp0 = tcg_temp_new_i64();
1868 tcg_gen_qemu_ld64(fp0, t0, ctx->mem_idx);
1869 gen_store_fpr64(ctx, fp0, ft);
1870 tcg_temp_free_i64(fp0);
1876 TCGv_i64 fp0 = tcg_temp_new_i64();
1878 gen_load_fpr64(ctx, fp0, ft);
1879 tcg_gen_qemu_st64(fp0, t0, ctx->mem_idx);
1880 tcg_temp_free_i64(fp0);
1886 generate_exception(ctx, EXCP_RI);
1889 (void)opn; /* avoid a compiler warning */
1890 MIPS_DEBUG("%s %s, %d(%s)", opn, fregnames[ft], offset, regnames[base]);
1895 static void gen_cop1_ldst(CPUMIPSState *env, DisasContext *ctx,
1896 uint32_t op, int rt, int rs, int16_t imm)
1898 if (env->CP0_Config1 & (1 << CP0C1_FP)) {
1899 check_cp1_enabled(ctx);
1900 gen_flt_ldst(ctx, op, rt, rs, imm);
1902 generate_exception_err(ctx, EXCP_CpU, 1);
1906 /* Arithmetic with immediate operand */
1907 static void gen_arith_imm (CPUMIPSState *env, DisasContext *ctx, uint32_t opc,
1908 int rt, int rs, int16_t imm)
1910 target_ulong uimm = (target_long)imm; /* Sign extend to 32/64 bits */
1911 const char *opn = "imm arith";
1913 if (rt == 0 && opc != OPC_ADDI && opc != OPC_DADDI) {
1914 /* If no destination, treat it as a NOP.
1915 For addi, we must generate the overflow exception when needed. */
1922 TCGv t0 = tcg_temp_local_new();
1923 TCGv t1 = tcg_temp_new();
1924 TCGv t2 = tcg_temp_new();
1925 int l1 = gen_new_label();
1927 gen_load_gpr(t1, rs);
1928 tcg_gen_addi_tl(t0, t1, uimm);
1929 tcg_gen_ext32s_tl(t0, t0);
1931 tcg_gen_xori_tl(t1, t1, ~uimm);
1932 tcg_gen_xori_tl(t2, t0, uimm);
1933 tcg_gen_and_tl(t1, t1, t2);
1935 tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
1937 /* operands of same sign, result different sign */
1938 generate_exception(ctx, EXCP_OVERFLOW);
1940 tcg_gen_ext32s_tl(t0, t0);
1941 gen_store_gpr(t0, rt);
1948 tcg_gen_addi_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
1949 tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]);
1951 tcg_gen_movi_tl(cpu_gpr[rt], uimm);
1955 #if defined(TARGET_MIPS64)
1958 TCGv t0 = tcg_temp_local_new();
1959 TCGv t1 = tcg_temp_new();
1960 TCGv t2 = tcg_temp_new();
1961 int l1 = gen_new_label();
1963 gen_load_gpr(t1, rs);
1964 tcg_gen_addi_tl(t0, t1, uimm);
1966 tcg_gen_xori_tl(t1, t1, ~uimm);
1967 tcg_gen_xori_tl(t2, t0, uimm);
1968 tcg_gen_and_tl(t1, t1, t2);
1970 tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
1972 /* operands of same sign, result different sign */
1973 generate_exception(ctx, EXCP_OVERFLOW);
1975 gen_store_gpr(t0, rt);
1982 tcg_gen_addi_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
1984 tcg_gen_movi_tl(cpu_gpr[rt], uimm);
1990 (void)opn; /* avoid a compiler warning */
1991 MIPS_DEBUG("%s %s, %s, " TARGET_FMT_lx, opn, regnames[rt], regnames[rs], uimm);
1994 /* Logic with immediate operand */
1995 static void gen_logic_imm(CPUMIPSState *env, DisasContext *ctx, uint32_t opc,
1996 int rt, int rs, int16_t imm)
1999 const char *opn = "imm logic";
2002 /* If no destination, treat it as a NOP. */
2006 uimm = (uint16_t)imm;
2009 if (likely(rs != 0))
2010 tcg_gen_andi_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
2012 tcg_gen_movi_tl(cpu_gpr[rt], 0);
2017 tcg_gen_ori_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
2019 tcg_gen_movi_tl(cpu_gpr[rt], uimm);
2023 if (likely(rs != 0))
2024 tcg_gen_xori_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
2026 tcg_gen_movi_tl(cpu_gpr[rt], uimm);
2030 tcg_gen_movi_tl(cpu_gpr[rt], imm << 16);
2034 (void)opn; /* avoid a compiler warning */
2035 MIPS_DEBUG("%s %s, %s, " TARGET_FMT_lx, opn, regnames[rt], regnames[rs], uimm);
2038 /* Set on less than with immediate operand */
2039 static void gen_slt_imm(CPUMIPSState *env, DisasContext *ctx, uint32_t opc,
2040 int rt, int rs, int16_t imm)
2042 target_ulong uimm = (target_long)imm; /* Sign extend to 32/64 bits */
2043 const char *opn = "imm arith";
2047 /* If no destination, treat it as a NOP. */
2051 t0 = tcg_temp_new();
2052 gen_load_gpr(t0, rs);
2055 tcg_gen_setcondi_tl(TCG_COND_LT, cpu_gpr[rt], t0, uimm);
2059 tcg_gen_setcondi_tl(TCG_COND_LTU, cpu_gpr[rt], t0, uimm);
2063 (void)opn; /* avoid a compiler warning */
2064 MIPS_DEBUG("%s %s, %s, " TARGET_FMT_lx, opn, regnames[rt], regnames[rs], uimm);
2068 /* Shifts with immediate operand */
2069 static void gen_shift_imm(CPUMIPSState *env, DisasContext *ctx, uint32_t opc,
2070 int rt, int rs, int16_t imm)
2072 target_ulong uimm = ((uint16_t)imm) & 0x1f;
2073 const char *opn = "imm shift";
2077 /* If no destination, treat it as a NOP. */
2082 t0 = tcg_temp_new();
2083 gen_load_gpr(t0, rs);
2086 tcg_gen_shli_tl(t0, t0, uimm);
2087 tcg_gen_ext32s_tl(cpu_gpr[rt], t0);
2091 tcg_gen_sari_tl(cpu_gpr[rt], t0, uimm);
2096 tcg_gen_ext32u_tl(t0, t0);
2097 tcg_gen_shri_tl(cpu_gpr[rt], t0, uimm);
2099 tcg_gen_ext32s_tl(cpu_gpr[rt], t0);
2105 TCGv_i32 t1 = tcg_temp_new_i32();
2107 tcg_gen_trunc_tl_i32(t1, t0);
2108 tcg_gen_rotri_i32(t1, t1, uimm);
2109 tcg_gen_ext_i32_tl(cpu_gpr[rt], t1);
2110 tcg_temp_free_i32(t1);
2112 tcg_gen_ext32s_tl(cpu_gpr[rt], t0);
2116 #if defined(TARGET_MIPS64)
2118 tcg_gen_shli_tl(cpu_gpr[rt], t0, uimm);
2122 tcg_gen_sari_tl(cpu_gpr[rt], t0, uimm);
2126 tcg_gen_shri_tl(cpu_gpr[rt], t0, uimm);
2131 tcg_gen_rotri_tl(cpu_gpr[rt], t0, uimm);
2133 tcg_gen_mov_tl(cpu_gpr[rt], t0);
2138 tcg_gen_shli_tl(cpu_gpr[rt], t0, uimm + 32);
2142 tcg_gen_sari_tl(cpu_gpr[rt], t0, uimm + 32);
2146 tcg_gen_shri_tl(cpu_gpr[rt], t0, uimm + 32);
2150 tcg_gen_rotri_tl(cpu_gpr[rt], t0, uimm + 32);
2155 (void)opn; /* avoid a compiler warning */
2156 MIPS_DEBUG("%s %s, %s, " TARGET_FMT_lx, opn, regnames[rt], regnames[rs], uimm);
2161 static void gen_arith (CPUMIPSState *env, DisasContext *ctx, uint32_t opc,
2162 int rd, int rs, int rt)
2164 const char *opn = "arith";
2166 if (rd == 0 && opc != OPC_ADD && opc != OPC_SUB
2167 && opc != OPC_DADD && opc != OPC_DSUB) {
2168 /* If no destination, treat it as a NOP.
2169 For add & sub, we must generate the overflow exception when needed. */
2177 TCGv t0 = tcg_temp_local_new();
2178 TCGv t1 = tcg_temp_new();
2179 TCGv t2 = tcg_temp_new();
2180 int l1 = gen_new_label();
2182 gen_load_gpr(t1, rs);
2183 gen_load_gpr(t2, rt);
2184 tcg_gen_add_tl(t0, t1, t2);
2185 tcg_gen_ext32s_tl(t0, t0);
2186 tcg_gen_xor_tl(t1, t1, t2);
2187 tcg_gen_xor_tl(t2, t0, t2);
2188 tcg_gen_andc_tl(t1, t2, t1);
2190 tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
2192 /* operands of same sign, result different sign */
2193 generate_exception(ctx, EXCP_OVERFLOW);
2195 gen_store_gpr(t0, rd);
2201 if (rs != 0 && rt != 0) {
2202 tcg_gen_add_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2203 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
2204 } else if (rs == 0 && rt != 0) {
2205 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rt]);
2206 } else if (rs != 0 && rt == 0) {
2207 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
2209 tcg_gen_movi_tl(cpu_gpr[rd], 0);
2215 TCGv t0 = tcg_temp_local_new();
2216 TCGv t1 = tcg_temp_new();
2217 TCGv t2 = tcg_temp_new();
2218 int l1 = gen_new_label();
2220 gen_load_gpr(t1, rs);
2221 gen_load_gpr(t2, rt);
2222 tcg_gen_sub_tl(t0, t1, t2);
2223 tcg_gen_ext32s_tl(t0, t0);
2224 tcg_gen_xor_tl(t2, t1, t2);
2225 tcg_gen_xor_tl(t1, t0, t1);
2226 tcg_gen_and_tl(t1, t1, t2);
2228 tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
2230 /* operands of different sign, first operand and result different sign */
2231 generate_exception(ctx, EXCP_OVERFLOW);
2233 gen_store_gpr(t0, rd);
2239 if (rs != 0 && rt != 0) {
2240 tcg_gen_sub_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2241 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
2242 } else if (rs == 0 && rt != 0) {
2243 tcg_gen_neg_tl(cpu_gpr[rd], cpu_gpr[rt]);
2244 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
2245 } else if (rs != 0 && rt == 0) {
2246 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
2248 tcg_gen_movi_tl(cpu_gpr[rd], 0);
2252 #if defined(TARGET_MIPS64)
2255 TCGv t0 = tcg_temp_local_new();
2256 TCGv t1 = tcg_temp_new();
2257 TCGv t2 = tcg_temp_new();
2258 int l1 = gen_new_label();
2260 gen_load_gpr(t1, rs);
2261 gen_load_gpr(t2, rt);
2262 tcg_gen_add_tl(t0, t1, t2);
2263 tcg_gen_xor_tl(t1, t1, t2);
2264 tcg_gen_xor_tl(t2, t0, t2);
2265 tcg_gen_andc_tl(t1, t2, t1);
2267 tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
2269 /* operands of same sign, result different sign */
2270 generate_exception(ctx, EXCP_OVERFLOW);
2272 gen_store_gpr(t0, rd);
2278 if (rs != 0 && rt != 0) {
2279 tcg_gen_add_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2280 } else if (rs == 0 && rt != 0) {
2281 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rt]);
2282 } else if (rs != 0 && rt == 0) {
2283 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
2285 tcg_gen_movi_tl(cpu_gpr[rd], 0);
2291 TCGv t0 = tcg_temp_local_new();
2292 TCGv t1 = tcg_temp_new();
2293 TCGv t2 = tcg_temp_new();
2294 int l1 = gen_new_label();
2296 gen_load_gpr(t1, rs);
2297 gen_load_gpr(t2, rt);
2298 tcg_gen_sub_tl(t0, t1, t2);
2299 tcg_gen_xor_tl(t2, t1, t2);
2300 tcg_gen_xor_tl(t1, t0, t1);
2301 tcg_gen_and_tl(t1, t1, t2);
2303 tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
2305 /* operands of different sign, first operand and result different sign */
2306 generate_exception(ctx, EXCP_OVERFLOW);
2308 gen_store_gpr(t0, rd);
2314 if (rs != 0 && rt != 0) {
2315 tcg_gen_sub_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2316 } else if (rs == 0 && rt != 0) {
2317 tcg_gen_neg_tl(cpu_gpr[rd], cpu_gpr[rt]);
2318 } else if (rs != 0 && rt == 0) {
2319 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
2321 tcg_gen_movi_tl(cpu_gpr[rd], 0);
2327 if (likely(rs != 0 && rt != 0)) {
2328 tcg_gen_mul_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2329 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
2331 tcg_gen_movi_tl(cpu_gpr[rd], 0);
2336 (void)opn; /* avoid a compiler warning */
2337 MIPS_DEBUG("%s %s, %s, %s", opn, regnames[rd], regnames[rs], regnames[rt]);
2340 /* Conditional move */
2341 static void gen_cond_move(CPUMIPSState *env, DisasContext *ctx, uint32_t opc,
2342 int rd, int rs, int rt)
2344 const char *opn = "cond move";
2348 /* If no destination, treat it as a NOP.
2349 For add & sub, we must generate the overflow exception when needed. */
2354 l1 = gen_new_label();
2357 if (likely(rt != 0))
2358 tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_gpr[rt], 0, l1);
2364 if (likely(rt != 0))
2365 tcg_gen_brcondi_tl(TCG_COND_NE, cpu_gpr[rt], 0, l1);
2370 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
2372 tcg_gen_movi_tl(cpu_gpr[rd], 0);
2375 (void)opn; /* avoid a compiler warning */
2376 MIPS_DEBUG("%s %s, %s, %s", opn, regnames[rd], regnames[rs], regnames[rt]);
2380 static void gen_logic(CPUMIPSState *env, DisasContext *ctx, uint32_t opc,
2381 int rd, int rs, int rt)
2383 const char *opn = "logic";
2386 /* If no destination, treat it as a NOP. */
2393 if (likely(rs != 0 && rt != 0)) {
2394 tcg_gen_and_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2396 tcg_gen_movi_tl(cpu_gpr[rd], 0);
2401 if (rs != 0 && rt != 0) {
2402 tcg_gen_nor_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2403 } else if (rs == 0 && rt != 0) {
2404 tcg_gen_not_tl(cpu_gpr[rd], cpu_gpr[rt]);
2405 } else if (rs != 0 && rt == 0) {
2406 tcg_gen_not_tl(cpu_gpr[rd], cpu_gpr[rs]);
2408 tcg_gen_movi_tl(cpu_gpr[rd], ~((target_ulong)0));
2413 if (likely(rs != 0 && rt != 0)) {
2414 tcg_gen_or_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2415 } else if (rs == 0 && rt != 0) {
2416 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rt]);
2417 } else if (rs != 0 && rt == 0) {
2418 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
2420 tcg_gen_movi_tl(cpu_gpr[rd], 0);
2425 if (likely(rs != 0 && rt != 0)) {
2426 tcg_gen_xor_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2427 } else if (rs == 0 && rt != 0) {
2428 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rt]);
2429 } else if (rs != 0 && rt == 0) {
2430 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
2432 tcg_gen_movi_tl(cpu_gpr[rd], 0);
2437 (void)opn; /* avoid a compiler warning */
2438 MIPS_DEBUG("%s %s, %s, %s", opn, regnames[rd], regnames[rs], regnames[rt]);
2441 /* Set on lower than */
2442 static void gen_slt(CPUMIPSState *env, DisasContext *ctx, uint32_t opc,
2443 int rd, int rs, int rt)
2445 const char *opn = "slt";
2449 /* If no destination, treat it as a NOP. */
2454 t0 = tcg_temp_new();
2455 t1 = tcg_temp_new();
2456 gen_load_gpr(t0, rs);
2457 gen_load_gpr(t1, rt);
2460 tcg_gen_setcond_tl(TCG_COND_LT, cpu_gpr[rd], t0, t1);
2464 tcg_gen_setcond_tl(TCG_COND_LTU, cpu_gpr[rd], t0, t1);
2468 (void)opn; /* avoid a compiler warning */
2469 MIPS_DEBUG("%s %s, %s, %s", opn, regnames[rd], regnames[rs], regnames[rt]);
2475 static void gen_shift (CPUMIPSState *env, DisasContext *ctx, uint32_t opc,
2476 int rd, int rs, int rt)
2478 const char *opn = "shifts";
2482 /* If no destination, treat it as a NOP.
2483 For add & sub, we must generate the overflow exception when needed. */
2488 t0 = tcg_temp_new();
2489 t1 = tcg_temp_new();
2490 gen_load_gpr(t0, rs);
2491 gen_load_gpr(t1, rt);
2494 tcg_gen_andi_tl(t0, t0, 0x1f);
2495 tcg_gen_shl_tl(t0, t1, t0);
2496 tcg_gen_ext32s_tl(cpu_gpr[rd], t0);
2500 tcg_gen_andi_tl(t0, t0, 0x1f);
2501 tcg_gen_sar_tl(cpu_gpr[rd], t1, t0);
2505 tcg_gen_ext32u_tl(t1, t1);
2506 tcg_gen_andi_tl(t0, t0, 0x1f);
2507 tcg_gen_shr_tl(t0, t1, t0);
2508 tcg_gen_ext32s_tl(cpu_gpr[rd], t0);
2513 TCGv_i32 t2 = tcg_temp_new_i32();
2514 TCGv_i32 t3 = tcg_temp_new_i32();
2516 tcg_gen_trunc_tl_i32(t2, t0);
2517 tcg_gen_trunc_tl_i32(t3, t1);
2518 tcg_gen_andi_i32(t2, t2, 0x1f);
2519 tcg_gen_rotr_i32(t2, t3, t2);
2520 tcg_gen_ext_i32_tl(cpu_gpr[rd], t2);
2521 tcg_temp_free_i32(t2);
2522 tcg_temp_free_i32(t3);
2526 #if defined(TARGET_MIPS64)
2528 tcg_gen_andi_tl(t0, t0, 0x3f);
2529 tcg_gen_shl_tl(cpu_gpr[rd], t1, t0);
2533 tcg_gen_andi_tl(t0, t0, 0x3f);
2534 tcg_gen_sar_tl(cpu_gpr[rd], t1, t0);
2538 tcg_gen_andi_tl(t0, t0, 0x3f);
2539 tcg_gen_shr_tl(cpu_gpr[rd], t1, t0);
2543 tcg_gen_andi_tl(t0, t0, 0x3f);
2544 tcg_gen_rotr_tl(cpu_gpr[rd], t1, t0);
2549 (void)opn; /* avoid a compiler warning */
2550 MIPS_DEBUG("%s %s, %s, %s", opn, regnames[rd], regnames[rs], regnames[rt]);
2555 /* Arithmetic on HI/LO registers */
2556 static void gen_HILO (DisasContext *ctx, uint32_t opc, int reg)
2558 const char *opn = "hilo";
2561 if (reg == 0 && (opc == OPC_MFHI || opc == OPC_MFLO)) {
2567 if (opc == OPC_MFHI || opc == OPC_MFLO) {
2568 acc = ((ctx->opcode) >> 21) & 0x03;
2570 acc = ((ctx->opcode) >> 11) & 0x03;
2579 #if defined(TARGET_MIPS64)
2581 tcg_gen_ext32s_tl(cpu_gpr[reg], cpu_HI[acc]);
2585 tcg_gen_mov_tl(cpu_gpr[reg], cpu_HI[acc]);
2590 #if defined(TARGET_MIPS64)
2592 tcg_gen_ext32s_tl(cpu_gpr[reg], cpu_LO[acc]);
2596 tcg_gen_mov_tl(cpu_gpr[reg], cpu_LO[acc]);
2602 #if defined(TARGET_MIPS64)
2604 tcg_gen_ext32s_tl(cpu_HI[acc], cpu_gpr[reg]);
2608 tcg_gen_mov_tl(cpu_HI[acc], cpu_gpr[reg]);
2611 tcg_gen_movi_tl(cpu_HI[acc], 0);
2617 #if defined(TARGET_MIPS64)
2619 tcg_gen_ext32s_tl(cpu_LO[acc], cpu_gpr[reg]);
2623 tcg_gen_mov_tl(cpu_LO[acc], cpu_gpr[reg]);
2626 tcg_gen_movi_tl(cpu_LO[acc], 0);
2631 (void)opn; /* avoid a compiler warning */
2632 MIPS_DEBUG("%s %s", opn, regnames[reg]);
2635 static void gen_muldiv (DisasContext *ctx, uint32_t opc,
2638 const char *opn = "mul/div";
2645 #if defined(TARGET_MIPS64)
2649 t0 = tcg_temp_local_new();
2650 t1 = tcg_temp_local_new();
2653 t0 = tcg_temp_new();
2654 t1 = tcg_temp_new();
2658 gen_load_gpr(t0, rs);
2659 gen_load_gpr(t1, rt);
2663 int l1 = gen_new_label();
2664 int l2 = gen_new_label();
2666 tcg_gen_ext32s_tl(t0, t0);
2667 tcg_gen_ext32s_tl(t1, t1);
2668 tcg_gen_brcondi_tl(TCG_COND_EQ, t1, 0, l1);
2669 tcg_gen_brcondi_tl(TCG_COND_NE, t0, INT_MIN, l2);
2670 tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1, l2);
2672 tcg_gen_mov_tl(cpu_LO[0], t0);
2673 tcg_gen_movi_tl(cpu_HI[0], 0);
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]);
2686 int l1 = gen_new_label();
2688 tcg_gen_ext32u_tl(t0, t0);
2689 tcg_gen_ext32u_tl(t1, t1);
2690 tcg_gen_brcondi_tl(TCG_COND_EQ, t1, 0, l1);
2691 tcg_gen_divu_tl(cpu_LO[0], t0, t1);
2692 tcg_gen_remu_tl(cpu_HI[0], t0, t1);
2693 tcg_gen_ext32s_tl(cpu_LO[0], cpu_LO[0]);
2694 tcg_gen_ext32s_tl(cpu_HI[0], cpu_HI[0]);
2701 TCGv_i64 t2 = tcg_temp_new_i64();
2702 TCGv_i64 t3 = tcg_temp_new_i64();
2703 acc = ((ctx->opcode) >> 11) & 0x03;
2708 tcg_gen_ext_tl_i64(t2, t0);
2709 tcg_gen_ext_tl_i64(t3, t1);
2710 tcg_gen_mul_i64(t2, t2, t3);
2711 tcg_temp_free_i64(t3);
2712 tcg_gen_trunc_i64_tl(t0, t2);
2713 tcg_gen_shri_i64(t2, t2, 32);
2714 tcg_gen_trunc_i64_tl(t1, t2);
2715 tcg_temp_free_i64(t2);
2716 tcg_gen_ext32s_tl(cpu_LO[acc], t0);
2717 tcg_gen_ext32s_tl(cpu_HI[acc], t1);
2723 TCGv_i64 t2 = tcg_temp_new_i64();
2724 TCGv_i64 t3 = tcg_temp_new_i64();
2725 acc = ((ctx->opcode) >> 11) & 0x03;
2730 tcg_gen_ext32u_tl(t0, t0);
2731 tcg_gen_ext32u_tl(t1, t1);
2732 tcg_gen_extu_tl_i64(t2, t0);
2733 tcg_gen_extu_tl_i64(t3, t1);
2734 tcg_gen_mul_i64(t2, t2, t3);
2735 tcg_temp_free_i64(t3);
2736 tcg_gen_trunc_i64_tl(t0, t2);
2737 tcg_gen_shri_i64(t2, t2, 32);
2738 tcg_gen_trunc_i64_tl(t1, t2);
2739 tcg_temp_free_i64(t2);
2740 tcg_gen_ext32s_tl(cpu_LO[acc], t0);
2741 tcg_gen_ext32s_tl(cpu_HI[acc], t1);
2745 #if defined(TARGET_MIPS64)
2748 int l1 = gen_new_label();
2749 int l2 = gen_new_label();
2751 tcg_gen_brcondi_tl(TCG_COND_EQ, t1, 0, l1);
2752 tcg_gen_brcondi_tl(TCG_COND_NE, t0, -1LL << 63, l2);
2753 tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1LL, l2);
2754 tcg_gen_mov_tl(cpu_LO[0], t0);
2755 tcg_gen_movi_tl(cpu_HI[0], 0);
2758 tcg_gen_div_i64(cpu_LO[0], t0, t1);
2759 tcg_gen_rem_i64(cpu_HI[0], t0, t1);
2766 int l1 = gen_new_label();
2768 tcg_gen_brcondi_tl(TCG_COND_EQ, t1, 0, l1);
2769 tcg_gen_divu_i64(cpu_LO[0], t0, t1);
2770 tcg_gen_remu_i64(cpu_HI[0], t0, t1);
2776 gen_helper_dmult(cpu_env, t0, t1);
2780 gen_helper_dmultu(cpu_env, t0, t1);
2786 TCGv_i64 t2 = tcg_temp_new_i64();
2787 TCGv_i64 t3 = tcg_temp_new_i64();
2788 acc = ((ctx->opcode) >> 11) & 0x03;
2793 tcg_gen_ext_tl_i64(t2, t0);
2794 tcg_gen_ext_tl_i64(t3, t1);
2795 tcg_gen_mul_i64(t2, t2, t3);
2796 tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]);
2797 tcg_gen_add_i64(t2, t2, t3);
2798 tcg_temp_free_i64(t3);
2799 tcg_gen_trunc_i64_tl(t0, t2);
2800 tcg_gen_shri_i64(t2, t2, 32);
2801 tcg_gen_trunc_i64_tl(t1, t2);
2802 tcg_temp_free_i64(t2);
2803 tcg_gen_ext32s_tl(cpu_LO[acc], t0);
2804 tcg_gen_ext32s_tl(cpu_HI[acc], t1);
2810 TCGv_i64 t2 = tcg_temp_new_i64();
2811 TCGv_i64 t3 = tcg_temp_new_i64();
2812 acc = ((ctx->opcode) >> 11) & 0x03;
2817 tcg_gen_ext32u_tl(t0, t0);
2818 tcg_gen_ext32u_tl(t1, t1);
2819 tcg_gen_extu_tl_i64(t2, t0);
2820 tcg_gen_extu_tl_i64(t3, t1);
2821 tcg_gen_mul_i64(t2, t2, t3);
2822 tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]);
2823 tcg_gen_add_i64(t2, t2, t3);
2824 tcg_temp_free_i64(t3);
2825 tcg_gen_trunc_i64_tl(t0, t2);
2826 tcg_gen_shri_i64(t2, t2, 32);
2827 tcg_gen_trunc_i64_tl(t1, t2);
2828 tcg_temp_free_i64(t2);
2829 tcg_gen_ext32s_tl(cpu_LO[acc], t0);
2830 tcg_gen_ext32s_tl(cpu_HI[acc], t1);
2836 TCGv_i64 t2 = tcg_temp_new_i64();
2837 TCGv_i64 t3 = tcg_temp_new_i64();
2838 acc = ((ctx->opcode) >> 11) & 0x03;
2843 tcg_gen_ext_tl_i64(t2, t0);
2844 tcg_gen_ext_tl_i64(t3, t1);
2845 tcg_gen_mul_i64(t2, t2, t3);
2846 tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]);
2847 tcg_gen_sub_i64(t2, t3, t2);
2848 tcg_temp_free_i64(t3);
2849 tcg_gen_trunc_i64_tl(t0, t2);
2850 tcg_gen_shri_i64(t2, t2, 32);
2851 tcg_gen_trunc_i64_tl(t1, t2);
2852 tcg_temp_free_i64(t2);
2853 tcg_gen_ext32s_tl(cpu_LO[acc], t0);
2854 tcg_gen_ext32s_tl(cpu_HI[acc], t1);
2860 TCGv_i64 t2 = tcg_temp_new_i64();
2861 TCGv_i64 t3 = tcg_temp_new_i64();
2862 acc = ((ctx->opcode) >> 11) & 0x03;
2867 tcg_gen_ext32u_tl(t0, t0);
2868 tcg_gen_ext32u_tl(t1, t1);
2869 tcg_gen_extu_tl_i64(t2, t0);
2870 tcg_gen_extu_tl_i64(t3, t1);
2871 tcg_gen_mul_i64(t2, t2, t3);
2872 tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]);
2873 tcg_gen_sub_i64(t2, t3, t2);
2874 tcg_temp_free_i64(t3);
2875 tcg_gen_trunc_i64_tl(t0, t2);
2876 tcg_gen_shri_i64(t2, t2, 32);
2877 tcg_gen_trunc_i64_tl(t1, t2);
2878 tcg_temp_free_i64(t2);
2879 tcg_gen_ext32s_tl(cpu_LO[acc], t0);
2880 tcg_gen_ext32s_tl(cpu_HI[acc], t1);
2886 generate_exception(ctx, EXCP_RI);
2889 (void)opn; /* avoid a compiler warning */
2890 MIPS_DEBUG("%s %s %s", opn, regnames[rs], regnames[rt]);
2896 static void gen_mul_vr54xx (DisasContext *ctx, uint32_t opc,
2897 int rd, int rs, int rt)
2899 const char *opn = "mul vr54xx";
2900 TCGv t0 = tcg_temp_new();
2901 TCGv t1 = tcg_temp_new();
2903 gen_load_gpr(t0, rs);
2904 gen_load_gpr(t1, rt);
2907 case OPC_VR54XX_MULS:
2908 gen_helper_muls(t0, cpu_env, t0, t1);
2911 case OPC_VR54XX_MULSU:
2912 gen_helper_mulsu(t0, cpu_env, t0, t1);
2915 case OPC_VR54XX_MACC:
2916 gen_helper_macc(t0, cpu_env, t0, t1);
2919 case OPC_VR54XX_MACCU:
2920 gen_helper_maccu(t0, cpu_env, t0, t1);
2923 case OPC_VR54XX_MSAC:
2924 gen_helper_msac(t0, cpu_env, t0, t1);
2927 case OPC_VR54XX_MSACU:
2928 gen_helper_msacu(t0, cpu_env, t0, t1);
2931 case OPC_VR54XX_MULHI:
2932 gen_helper_mulhi(t0, cpu_env, t0, t1);
2935 case OPC_VR54XX_MULHIU:
2936 gen_helper_mulhiu(t0, cpu_env, t0, t1);
2939 case OPC_VR54XX_MULSHI:
2940 gen_helper_mulshi(t0, cpu_env, t0, t1);
2943 case OPC_VR54XX_MULSHIU:
2944 gen_helper_mulshiu(t0, cpu_env, t0, t1);
2947 case OPC_VR54XX_MACCHI:
2948 gen_helper_macchi(t0, cpu_env, t0, t1);
2951 case OPC_VR54XX_MACCHIU:
2952 gen_helper_macchiu(t0, cpu_env, t0, t1);
2955 case OPC_VR54XX_MSACHI:
2956 gen_helper_msachi(t0, cpu_env, t0, t1);
2959 case OPC_VR54XX_MSACHIU:
2960 gen_helper_msachiu(t0, cpu_env, t0, t1);
2964 MIPS_INVAL("mul vr54xx");
2965 generate_exception(ctx, EXCP_RI);
2968 gen_store_gpr(t0, rd);
2969 (void)opn; /* avoid a compiler warning */
2970 MIPS_DEBUG("%s %s, %s, %s", opn, regnames[rd], regnames[rs], regnames[rt]);
2977 static void gen_cl (DisasContext *ctx, uint32_t opc,
2980 const char *opn = "CLx";
2988 t0 = tcg_temp_new();
2989 gen_load_gpr(t0, rs);
2992 gen_helper_clo(cpu_gpr[rd], t0);
2996 gen_helper_clz(cpu_gpr[rd], t0);
2999 #if defined(TARGET_MIPS64)
3001 gen_helper_dclo(cpu_gpr[rd], t0);
3005 gen_helper_dclz(cpu_gpr[rd], t0);
3010 (void)opn; /* avoid a compiler warning */
3011 MIPS_DEBUG("%s %s, %s", opn, regnames[rd], regnames[rs]);
3015 /* Godson integer instructions */
3016 static void gen_loongson_integer(DisasContext *ctx, uint32_t opc,
3017 int rd, int rs, int rt)
3019 const char *opn = "loongson";
3031 case OPC_MULTU_G_2E:
3032 case OPC_MULTU_G_2F:
3033 #if defined(TARGET_MIPS64)
3034 case OPC_DMULT_G_2E:
3035 case OPC_DMULT_G_2F:
3036 case OPC_DMULTU_G_2E:
3037 case OPC_DMULTU_G_2F:
3039 t0 = tcg_temp_new();
3040 t1 = tcg_temp_new();
3043 t0 = tcg_temp_local_new();
3044 t1 = tcg_temp_local_new();
3048 gen_load_gpr(t0, rs);
3049 gen_load_gpr(t1, rt);
3054 tcg_gen_mul_tl(cpu_gpr[rd], t0, t1);
3055 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3058 case OPC_MULTU_G_2E:
3059 case OPC_MULTU_G_2F:
3060 tcg_gen_ext32u_tl(t0, t0);
3061 tcg_gen_ext32u_tl(t1, t1);
3062 tcg_gen_mul_tl(cpu_gpr[rd], t0, t1);
3063 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3069 int l1 = gen_new_label();
3070 int l2 = gen_new_label();
3071 int l3 = gen_new_label();
3072 tcg_gen_ext32s_tl(t0, t0);
3073 tcg_gen_ext32s_tl(t1, t1);
3074 tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
3075 tcg_gen_movi_tl(cpu_gpr[rd], 0);
3078 tcg_gen_brcondi_tl(TCG_COND_NE, t0, INT_MIN, l2);
3079 tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1, l2);
3080 tcg_gen_mov_tl(cpu_gpr[rd], t0);
3083 tcg_gen_div_tl(cpu_gpr[rd], t0, t1);
3084 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3092 int l1 = gen_new_label();
3093 int l2 = gen_new_label();
3094 tcg_gen_ext32u_tl(t0, t0);
3095 tcg_gen_ext32u_tl(t1, t1);
3096 tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
3097 tcg_gen_movi_tl(cpu_gpr[rd], 0);
3100 tcg_gen_divu_tl(cpu_gpr[rd], t0, t1);
3101 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3109 int l1 = gen_new_label();
3110 int l2 = gen_new_label();
3111 int l3 = gen_new_label();
3112 tcg_gen_ext32u_tl(t0, t0);
3113 tcg_gen_ext32u_tl(t1, t1);
3114 tcg_gen_brcondi_tl(TCG_COND_EQ, t1, 0, l1);
3115 tcg_gen_brcondi_tl(TCG_COND_NE, t0, INT_MIN, l2);
3116 tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1, l2);
3118 tcg_gen_movi_tl(cpu_gpr[rd], 0);
3121 tcg_gen_rem_tl(cpu_gpr[rd], t0, t1);
3122 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3130 int l1 = gen_new_label();
3131 int l2 = gen_new_label();
3132 tcg_gen_ext32u_tl(t0, t0);
3133 tcg_gen_ext32u_tl(t1, t1);
3134 tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
3135 tcg_gen_movi_tl(cpu_gpr[rd], 0);
3138 tcg_gen_remu_tl(cpu_gpr[rd], t0, t1);
3139 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3144 #if defined(TARGET_MIPS64)
3145 case OPC_DMULT_G_2E:
3146 case OPC_DMULT_G_2F:
3147 tcg_gen_mul_tl(cpu_gpr[rd], t0, t1);
3150 case OPC_DMULTU_G_2E:
3151 case OPC_DMULTU_G_2F:
3152 tcg_gen_mul_tl(cpu_gpr[rd], t0, t1);
3158 int l1 = gen_new_label();
3159 int l2 = gen_new_label();
3160 int l3 = gen_new_label();
3161 tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
3162 tcg_gen_movi_tl(cpu_gpr[rd], 0);
3165 tcg_gen_brcondi_tl(TCG_COND_NE, t0, -1LL << 63, l2);
3166 tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1LL, l2);
3167 tcg_gen_mov_tl(cpu_gpr[rd], t0);
3170 tcg_gen_div_tl(cpu_gpr[rd], t0, t1);
3175 case OPC_DDIVU_G_2E:
3176 case OPC_DDIVU_G_2F:
3178 int l1 = gen_new_label();
3179 int l2 = gen_new_label();
3180 tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
3181 tcg_gen_movi_tl(cpu_gpr[rd], 0);
3184 tcg_gen_divu_tl(cpu_gpr[rd], t0, t1);
3192 int l1 = gen_new_label();
3193 int l2 = gen_new_label();
3194 int l3 = gen_new_label();
3195 tcg_gen_brcondi_tl(TCG_COND_EQ, t1, 0, l1);
3196 tcg_gen_brcondi_tl(TCG_COND_NE, t0, -1LL << 63, l2);
3197 tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1LL, l2);
3199 tcg_gen_movi_tl(cpu_gpr[rd], 0);
3202 tcg_gen_rem_tl(cpu_gpr[rd], t0, t1);
3207 case OPC_DMODU_G_2E:
3208 case OPC_DMODU_G_2F:
3210 int l1 = gen_new_label();
3211 int l2 = gen_new_label();
3212 tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
3213 tcg_gen_movi_tl(cpu_gpr[rd], 0);
3216 tcg_gen_remu_tl(cpu_gpr[rd], t0, t1);
3224 (void)opn; /* avoid a compiler warning */
3225 MIPS_DEBUG("%s %s, %s", opn, regnames[rd], regnames[rs]);
3230 /* Loongson multimedia instructions */
3231 static void gen_loongson_multimedia(DisasContext *ctx, int rd, int rs, int rt)
3233 const char *opn = "loongson_cp2";
3234 uint32_t opc, shift_max;
3237 opc = MASK_LMI(ctx->opcode);
3243 t0 = tcg_temp_local_new_i64();
3244 t1 = tcg_temp_local_new_i64();
3247 t0 = tcg_temp_new_i64();
3248 t1 = tcg_temp_new_i64();
3252 gen_load_fpr64(ctx, t0, rs);
3253 gen_load_fpr64(ctx, t1, rt);
3255 #define LMI_HELPER(UP, LO) \
3256 case OPC_##UP: gen_helper_##LO(t0, t0, t1); opn = #LO; break
3257 #define LMI_HELPER_1(UP, LO) \
3258 case OPC_##UP: gen_helper_##LO(t0, t0); opn = #LO; break
3259 #define LMI_DIRECT(UP, LO, OP) \
3260 case OPC_##UP: tcg_gen_##OP##_i64(t0, t0, t1); opn = #LO; break
3263 LMI_HELPER(PADDSH, paddsh);
3264 LMI_HELPER(PADDUSH, paddush);
3265 LMI_HELPER(PADDH, paddh);
3266 LMI_HELPER(PADDW, paddw);
3267 LMI_HELPER(PADDSB, paddsb);
3268 LMI_HELPER(PADDUSB, paddusb);
3269 LMI_HELPER(PADDB, paddb);
3271 LMI_HELPER(PSUBSH, psubsh);
3272 LMI_HELPER(PSUBUSH, psubush);
3273 LMI_HELPER(PSUBH, psubh);
3274 LMI_HELPER(PSUBW, psubw);
3275 LMI_HELPER(PSUBSB, psubsb);
3276 LMI_HELPER(PSUBUSB, psubusb);
3277 LMI_HELPER(PSUBB, psubb);
3279 LMI_HELPER(PSHUFH, pshufh);
3280 LMI_HELPER(PACKSSWH, packsswh);
3281 LMI_HELPER(PACKSSHB, packsshb);
3282 LMI_HELPER(PACKUSHB, packushb);
3284 LMI_HELPER(PUNPCKLHW, punpcklhw);
3285 LMI_HELPER(PUNPCKHHW, punpckhhw);
3286 LMI_HELPER(PUNPCKLBH, punpcklbh);
3287 LMI_HELPER(PUNPCKHBH, punpckhbh);
3288 LMI_HELPER(PUNPCKLWD, punpcklwd);
3289 LMI_HELPER(PUNPCKHWD, punpckhwd);
3291 LMI_HELPER(PAVGH, pavgh);
3292 LMI_HELPER(PAVGB, pavgb);
3293 LMI_HELPER(PMAXSH, pmaxsh);
3294 LMI_HELPER(PMINSH, pminsh);
3295 LMI_HELPER(PMAXUB, pmaxub);
3296 LMI_HELPER(PMINUB, pminub);
3298 LMI_HELPER(PCMPEQW, pcmpeqw);
3299 LMI_HELPER(PCMPGTW, pcmpgtw);
3300 LMI_HELPER(PCMPEQH, pcmpeqh);
3301 LMI_HELPER(PCMPGTH, pcmpgth);
3302 LMI_HELPER(PCMPEQB, pcmpeqb);
3303 LMI_HELPER(PCMPGTB, pcmpgtb);
3305 LMI_HELPER(PSLLW, psllw);
3306 LMI_HELPER(PSLLH, psllh);
3307 LMI_HELPER(PSRLW, psrlw);
3308 LMI_HELPER(PSRLH, psrlh);
3309 LMI_HELPER(PSRAW, psraw);
3310 LMI_HELPER(PSRAH, psrah);
3312 LMI_HELPER(PMULLH, pmullh);
3313 LMI_HELPER(PMULHH, pmulhh);
3314 LMI_HELPER(PMULHUH, pmulhuh);
3315 LMI_HELPER(PMADDHW, pmaddhw);
3317 LMI_HELPER(PASUBUB, pasubub);
3318 LMI_HELPER_1(BIADD, biadd);
3319 LMI_HELPER_1(PMOVMSKB, pmovmskb);
3321 LMI_DIRECT(PADDD, paddd, add);
3322 LMI_DIRECT(PSUBD, psubd, sub);
3323 LMI_DIRECT(XOR_CP2, xor, xor);
3324 LMI_DIRECT(NOR_CP2, nor, nor);
3325 LMI_DIRECT(AND_CP2, and, and);
3326 LMI_DIRECT(PANDN, pandn, andc);
3327 LMI_DIRECT(OR, or, or);
3330 tcg_gen_deposit_i64(t0, t0, t1, 0, 16);
3334 tcg_gen_deposit_i64(t0, t0, t1, 16, 16);
3338 tcg_gen_deposit_i64(t0, t0, t1, 32, 16);
3342 tcg_gen_deposit_i64(t0, t0, t1, 48, 16);
3347 tcg_gen_andi_i64(t1, t1, 3);
3348 tcg_gen_shli_i64(t1, t1, 4);
3349 tcg_gen_shr_i64(t0, t0, t1);
3350 tcg_gen_ext16u_i64(t0, t0);
3355 tcg_gen_add_i64(t0, t0, t1);
3356 tcg_gen_ext32s_i64(t0, t0);
3360 tcg_gen_sub_i64(t0, t0, t1);
3361 tcg_gen_ext32s_i64(t0, t0);
3390 /* Make sure shift count isn't TCG undefined behaviour. */
3391 tcg_gen_andi_i64(t1, t1, shift_max - 1);
3396 tcg_gen_shl_i64(t0, t0, t1);
3400 /* Since SRA is UndefinedResult without sign-extended inputs,
3401 we can treat SRA and DSRA the same. */
3402 tcg_gen_sar_i64(t0, t0, t1);
3405 /* We want to shift in zeros for SRL; zero-extend first. */
3406 tcg_gen_ext32u_i64(t0, t0);
3409 tcg_gen_shr_i64(t0, t0, t1);
3413 if (shift_max == 32) {
3414 tcg_gen_ext32s_i64(t0, t0);
3417 /* Shifts larger than MAX produce zero. */
3418 tcg_gen_setcondi_i64(TCG_COND_LTU, t1, t1, shift_max);
3419 tcg_gen_neg_i64(t1, t1);
3420 tcg_gen_and_i64(t0, t0, t1);
3426 TCGv_i64 t2 = tcg_temp_new_i64();
3427 int lab = gen_new_label();
3429 tcg_gen_mov_i64(t2, t0);
3430 tcg_gen_add_i64(t0, t1, t2);
3431 if (opc == OPC_ADD_CP2) {
3432 tcg_gen_ext32s_i64(t0, t0);
3434 tcg_gen_xor_i64(t1, t1, t2);
3435 tcg_gen_xor_i64(t2, t2, t0);
3436 tcg_gen_andc_i64(t1, t2, t1);
3437 tcg_temp_free_i64(t2);
3438 tcg_gen_brcondi_i64(TCG_COND_GE, t1, 0, lab);
3439 generate_exception(ctx, EXCP_OVERFLOW);
3442 opn = (opc == OPC_ADD_CP2 ? "add" : "dadd");
3449 TCGv_i64 t2 = tcg_temp_new_i64();
3450 int lab = gen_new_label();
3452 tcg_gen_mov_i64(t2, t0);
3453 tcg_gen_sub_i64(t0, t1, t2);
3454 if (opc == OPC_SUB_CP2) {
3455 tcg_gen_ext32s_i64(t0, t0);
3457 tcg_gen_xor_i64(t1, t1, t2);
3458 tcg_gen_xor_i64(t2, t2, t0);
3459 tcg_gen_and_i64(t1, t1, t2);
3460 tcg_temp_free_i64(t2);
3461 tcg_gen_brcondi_i64(TCG_COND_GE, t1, 0, lab);
3462 generate_exception(ctx, EXCP_OVERFLOW);
3465 opn = (opc == OPC_SUB_CP2 ? "sub" : "dsub");
3470 tcg_gen_ext32u_i64(t0, t0);
3471 tcg_gen_ext32u_i64(t1, t1);
3472 tcg_gen_mul_i64(t0, t0, t1);
3482 /* ??? Document is unclear: Set FCC[CC]. Does that mean the
3483 FD field is the CC field? */
3486 generate_exception(ctx, EXCP_RI);
3493 gen_store_fpr64(ctx, t0, rd);
3495 (void)opn; /* avoid a compiler warning */
3496 MIPS_DEBUG("%s %s, %s, %s", opn,
3497 fregnames[rd], fregnames[rs], fregnames[rt]);
3498 tcg_temp_free_i64(t0);
3499 tcg_temp_free_i64(t1);
3503 static void gen_trap (DisasContext *ctx, uint32_t opc,
3504 int rs, int rt, int16_t imm)
3507 TCGv t0 = tcg_temp_new();
3508 TCGv t1 = tcg_temp_new();
3511 /* Load needed operands */
3519 /* Compare two registers */
3521 gen_load_gpr(t0, rs);
3522 gen_load_gpr(t1, rt);
3532 /* Compare register to immediate */
3533 if (rs != 0 || imm != 0) {
3534 gen_load_gpr(t0, rs);
3535 tcg_gen_movi_tl(t1, (int32_t)imm);
3542 case OPC_TEQ: /* rs == rs */
3543 case OPC_TEQI: /* r0 == 0 */
3544 case OPC_TGE: /* rs >= rs */
3545 case OPC_TGEI: /* r0 >= 0 */
3546 case OPC_TGEU: /* rs >= rs unsigned */
3547 case OPC_TGEIU: /* r0 >= 0 unsigned */
3549 generate_exception(ctx, EXCP_TRAP);
3551 case OPC_TLT: /* rs < rs */
3552 case OPC_TLTI: /* r0 < 0 */
3553 case OPC_TLTU: /* rs < rs unsigned */
3554 case OPC_TLTIU: /* r0 < 0 unsigned */
3555 case OPC_TNE: /* rs != rs */
3556 case OPC_TNEI: /* r0 != 0 */
3557 /* Never trap: treat as NOP. */
3561 int l1 = gen_new_label();
3566 tcg_gen_brcond_tl(TCG_COND_NE, t0, t1, l1);
3570 tcg_gen_brcond_tl(TCG_COND_LT, t0, t1, l1);
3574 tcg_gen_brcond_tl(TCG_COND_LTU, t0, t1, l1);
3578 tcg_gen_brcond_tl(TCG_COND_GE, t0, t1, l1);
3582 tcg_gen_brcond_tl(TCG_COND_GEU, t0, t1, l1);
3586 tcg_gen_brcond_tl(TCG_COND_EQ, t0, t1, l1);
3589 generate_exception(ctx, EXCP_TRAP);
3596 static inline void gen_goto_tb(DisasContext *ctx, int n, target_ulong dest)
3598 TranslationBlock *tb;
3600 if ((tb->pc & TARGET_PAGE_MASK) == (dest & TARGET_PAGE_MASK) &&
3601 likely(!ctx->singlestep_enabled)) {
3604 tcg_gen_exit_tb((tcg_target_long)tb + n);
3607 if (ctx->singlestep_enabled) {
3608 save_cpu_state(ctx, 0);
3609 gen_helper_0e0i(raise_exception, EXCP_DEBUG);
3615 /* Branches (before delay slot) */
3616 static void gen_compute_branch (DisasContext *ctx, uint32_t opc,
3618 int rs, int rt, int32_t offset)
3620 target_ulong btgt = -1;
3622 int bcond_compute = 0;
3623 TCGv t0 = tcg_temp_new();
3624 TCGv t1 = tcg_temp_new();
3626 if (ctx->hflags & MIPS_HFLAG_BMASK) {
3627 #ifdef MIPS_DEBUG_DISAS
3628 LOG_DISAS("Branch in delay slot at PC 0x" TARGET_FMT_lx "\n", ctx->pc);
3630 generate_exception(ctx, EXCP_RI);
3634 /* Load needed operands */
3640 /* Compare two registers */
3642 gen_load_gpr(t0, rs);
3643 gen_load_gpr(t1, rt);
3646 btgt = ctx->pc + insn_bytes + offset;
3662 /* Compare to zero */
3664 gen_load_gpr(t0, rs);
3667 btgt = ctx->pc + insn_bytes + offset;
3670 #if defined(TARGET_MIPS64)
3672 tcg_gen_andi_tl(t0, cpu_dspctrl, 0x7F);
3674 tcg_gen_andi_tl(t0, cpu_dspctrl, 0x3F);
3677 btgt = ctx->pc + insn_bytes + offset;
3684 /* Jump to immediate */
3685 btgt = ((ctx->pc + insn_bytes) & (int32_t)0xF0000000) | (uint32_t)offset;
3691 /* Jump to register */
3692 if (offset != 0 && offset != 16) {
3693 /* Hint = 0 is JR/JALR, hint 16 is JR.HB/JALR.HB, the
3694 others are reserved. */
3695 MIPS_INVAL("jump hint");
3696 generate_exception(ctx, EXCP_RI);
3699 gen_load_gpr(btarget, rs);
3702 MIPS_INVAL("branch/jump");
3703 generate_exception(ctx, EXCP_RI);
3706 if (bcond_compute == 0) {
3707 /* No condition to be computed */
3709 case OPC_BEQ: /* rx == rx */
3710 case OPC_BEQL: /* rx == rx likely */
3711 case OPC_BGEZ: /* 0 >= 0 */
3712 case OPC_BGEZL: /* 0 >= 0 likely */
3713 case OPC_BLEZ: /* 0 <= 0 */
3714 case OPC_BLEZL: /* 0 <= 0 likely */
3716 ctx->hflags |= MIPS_HFLAG_B;
3717 MIPS_DEBUG("balways");
3720 case OPC_BGEZAL: /* 0 >= 0 */
3721 case OPC_BGEZALL: /* 0 >= 0 likely */
3722 ctx->hflags |= (opc == OPC_BGEZALS
3724 : MIPS_HFLAG_BDS32);
3725 /* Always take and link */
3727 ctx->hflags |= MIPS_HFLAG_B;
3728 MIPS_DEBUG("balways and link");
3730 case OPC_BNE: /* rx != rx */
3731 case OPC_BGTZ: /* 0 > 0 */
3732 case OPC_BLTZ: /* 0 < 0 */
3734 MIPS_DEBUG("bnever (NOP)");
3737 case OPC_BLTZAL: /* 0 < 0 */
3738 ctx->hflags |= (opc == OPC_BLTZALS
3740 : MIPS_HFLAG_BDS32);
3741 /* Handle as an unconditional branch to get correct delay
3744 btgt = ctx->pc + (opc == OPC_BLTZALS ? 6 : 8);
3745 ctx->hflags |= MIPS_HFLAG_B;
3746 MIPS_DEBUG("bnever and link");
3748 case OPC_BLTZALL: /* 0 < 0 likely */
3749 tcg_gen_movi_tl(cpu_gpr[31], ctx->pc + 8);
3750 /* Skip the instruction in the delay slot */
3751 MIPS_DEBUG("bnever, link and skip");
3754 case OPC_BNEL: /* rx != rx likely */
3755 case OPC_BGTZL: /* 0 > 0 likely */
3756 case OPC_BLTZL: /* 0 < 0 likely */
3757 /* Skip the instruction in the delay slot */
3758 MIPS_DEBUG("bnever and skip");
3762 ctx->hflags |= MIPS_HFLAG_B;
3763 MIPS_DEBUG("j " TARGET_FMT_lx, btgt);
3767 ctx->hflags |= MIPS_HFLAG_BX;
3772 ctx->hflags |= MIPS_HFLAG_B;
3773 ctx->hflags |= ((opc == OPC_JALS || opc == OPC_JALXS)
3775 : MIPS_HFLAG_BDS32);
3776 MIPS_DEBUG("jal " TARGET_FMT_lx, btgt);
3779 ctx->hflags |= MIPS_HFLAG_BR;
3780 if (insn_bytes == 4)
3781 ctx->hflags |= MIPS_HFLAG_BDS32;
3782 MIPS_DEBUG("jr %s", regnames[rs]);
3788 ctx->hflags |= MIPS_HFLAG_BR;
3789 ctx->hflags |= (opc == OPC_JALRS
3791 : MIPS_HFLAG_BDS32);
3792 MIPS_DEBUG("jalr %s, %s", regnames[rt], regnames[rs]);
3795 MIPS_INVAL("branch/jump");
3796 generate_exception(ctx, EXCP_RI);
3802 tcg_gen_setcond_tl(TCG_COND_EQ, bcond, t0, t1);
3803 MIPS_DEBUG("beq %s, %s, " TARGET_FMT_lx,
3804 regnames[rs], regnames[rt], btgt);
3807 tcg_gen_setcond_tl(TCG_COND_EQ, bcond, t0, t1);
3808 MIPS_DEBUG("beql %s, %s, " TARGET_FMT_lx,
3809 regnames[rs], regnames[rt], btgt);
3812 tcg_gen_setcond_tl(TCG_COND_NE, bcond, t0, t1);
3813 MIPS_DEBUG("bne %s, %s, " TARGET_FMT_lx,
3814 regnames[rs], regnames[rt], btgt);
3817 tcg_gen_setcond_tl(TCG_COND_NE, bcond, t0, t1);
3818 MIPS_DEBUG("bnel %s, %s, " TARGET_FMT_lx,
3819 regnames[rs], regnames[rt], btgt);
3822 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 0);
3823 MIPS_DEBUG("bgez %s, " TARGET_FMT_lx, regnames[rs], btgt);
3826 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 0);
3827 MIPS_DEBUG("bgezl %s, " TARGET_FMT_lx, regnames[rs], btgt);
3831 ctx->hflags |= (opc == OPC_BGEZALS
3833 : MIPS_HFLAG_BDS32);
3834 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 0);
3835 MIPS_DEBUG("bgezal %s, " TARGET_FMT_lx, regnames[rs], btgt);
3839 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 0);
3841 MIPS_DEBUG("bgezall %s, " TARGET_FMT_lx, regnames[rs], btgt);
3844 tcg_gen_setcondi_tl(TCG_COND_GT, bcond, t0, 0);
3845 MIPS_DEBUG("bgtz %s, " TARGET_FMT_lx, regnames[rs], btgt);
3848 tcg_gen_setcondi_tl(TCG_COND_GT, bcond, t0, 0);
3849 MIPS_DEBUG("bgtzl %s, " TARGET_FMT_lx, regnames[rs], btgt);
3852 tcg_gen_setcondi_tl(TCG_COND_LE, bcond, t0, 0);
3853 MIPS_DEBUG("blez %s, " TARGET_FMT_lx, regnames[rs], btgt);
3856 tcg_gen_setcondi_tl(TCG_COND_LE, bcond, t0, 0);
3857 MIPS_DEBUG("blezl %s, " TARGET_FMT_lx, regnames[rs], btgt);
3860 tcg_gen_setcondi_tl(TCG_COND_LT, bcond, t0, 0);
3861 MIPS_DEBUG("bltz %s, " TARGET_FMT_lx, regnames[rs], btgt);
3864 tcg_gen_setcondi_tl(TCG_COND_LT, bcond, t0, 0);
3865 MIPS_DEBUG("bltzl %s, " TARGET_FMT_lx, regnames[rs], btgt);
3868 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 32);
3869 MIPS_DEBUG("bposge32 " TARGET_FMT_lx, btgt);
3871 #if defined(TARGET_MIPS64)
3873 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 64);
3874 MIPS_DEBUG("bposge64 " TARGET_FMT_lx, btgt);
3879 ctx->hflags |= (opc == OPC_BLTZALS
3881 : MIPS_HFLAG_BDS32);
3882 tcg_gen_setcondi_tl(TCG_COND_LT, bcond, t0, 0);
3884 MIPS_DEBUG("bltzal %s, " TARGET_FMT_lx, regnames[rs], btgt);
3886 ctx->hflags |= MIPS_HFLAG_BC;
3889 tcg_gen_setcondi_tl(TCG_COND_LT, bcond, t0, 0);
3891 MIPS_DEBUG("bltzall %s, " TARGET_FMT_lx, regnames[rs], btgt);
3893 ctx->hflags |= MIPS_HFLAG_BL;
3896 MIPS_INVAL("conditional branch/jump");
3897 generate_exception(ctx, EXCP_RI);
3901 MIPS_DEBUG("enter ds: link %d cond %02x target " TARGET_FMT_lx,
3902 blink, ctx->hflags, btgt);
3904 ctx->btarget = btgt;
3906 int post_delay = insn_bytes;
3907 int lowbit = !!(ctx->hflags & MIPS_HFLAG_M16);
3909 if (opc != OPC_JALRC)
3910 post_delay += ((ctx->hflags & MIPS_HFLAG_BDS16) ? 2 : 4);
3912 tcg_gen_movi_tl(cpu_gpr[blink], ctx->pc + post_delay + lowbit);
3916 if (insn_bytes == 2)
3917 ctx->hflags |= MIPS_HFLAG_B16;
3922 /* special3 bitfield operations */
3923 static void gen_bitops (DisasContext *ctx, uint32_t opc, int rt,
3924 int rs, int lsb, int msb)
3926 TCGv t0 = tcg_temp_new();
3927 TCGv t1 = tcg_temp_new();
3930 gen_load_gpr(t1, rs);
3935 tcg_gen_shri_tl(t0, t1, lsb);
3937 tcg_gen_andi_tl(t0, t0, (1 << (msb + 1)) - 1);
3939 tcg_gen_ext32s_tl(t0, t0);
3942 #if defined(TARGET_MIPS64)
3944 tcg_gen_shri_tl(t0, t1, lsb);
3946 tcg_gen_andi_tl(t0, t0, (1ULL << (msb + 1 + 32)) - 1);
3950 tcg_gen_shri_tl(t0, t1, lsb + 32);
3951 tcg_gen_andi_tl(t0, t0, (1ULL << (msb + 1)) - 1);
3954 tcg_gen_shri_tl(t0, t1, lsb);
3955 tcg_gen_andi_tl(t0, t0, (1ULL << (msb + 1)) - 1);
3961 mask = ((msb - lsb + 1 < 32) ? ((1 << (msb - lsb + 1)) - 1) : ~0) << lsb;
3962 gen_load_gpr(t0, rt);
3963 tcg_gen_andi_tl(t0, t0, ~mask);
3964 tcg_gen_shli_tl(t1, t1, lsb);
3965 tcg_gen_andi_tl(t1, t1, mask);
3966 tcg_gen_or_tl(t0, t0, t1);
3967 tcg_gen_ext32s_tl(t0, t0);
3969 #if defined(TARGET_MIPS64)
3973 mask = ((msb - lsb + 1 + 32 < 64) ? ((1ULL << (msb - lsb + 1 + 32)) - 1) : ~0ULL) << lsb;
3974 gen_load_gpr(t0, rt);
3975 tcg_gen_andi_tl(t0, t0, ~mask);
3976 tcg_gen_shli_tl(t1, t1, lsb);
3977 tcg_gen_andi_tl(t1, t1, mask);
3978 tcg_gen_or_tl(t0, t0, t1);
3983 mask = ((1ULL << (msb - lsb + 1)) - 1) << (lsb + 32);
3984 gen_load_gpr(t0, rt);
3985 tcg_gen_andi_tl(t0, t0, ~mask);
3986 tcg_gen_shli_tl(t1, t1, lsb + 32);
3987 tcg_gen_andi_tl(t1, t1, mask);
3988 tcg_gen_or_tl(t0, t0, t1);
3993 gen_load_gpr(t0, rt);
3994 mask = ((1ULL << (msb - lsb + 1)) - 1) << lsb;
3995 gen_load_gpr(t0, rt);
3996 tcg_gen_andi_tl(t0, t0, ~mask);
3997 tcg_gen_shli_tl(t1, t1, lsb);
3998 tcg_gen_andi_tl(t1, t1, mask);
3999 tcg_gen_or_tl(t0, t0, t1);
4004 MIPS_INVAL("bitops");
4005 generate_exception(ctx, EXCP_RI);
4010 gen_store_gpr(t0, rt);
4015 static void gen_bshfl (DisasContext *ctx, uint32_t op2, int rt, int rd)
4020 /* If no destination, treat it as a NOP. */
4025 t0 = tcg_temp_new();
4026 gen_load_gpr(t0, rt);
4030 TCGv t1 = tcg_temp_new();
4032 tcg_gen_shri_tl(t1, t0, 8);
4033 tcg_gen_andi_tl(t1, t1, 0x00FF00FF);
4034 tcg_gen_shli_tl(t0, t0, 8);
4035 tcg_gen_andi_tl(t0, t0, ~0x00FF00FF);
4036 tcg_gen_or_tl(t0, t0, t1);
4038 tcg_gen_ext32s_tl(cpu_gpr[rd], t0);
4042 tcg_gen_ext8s_tl(cpu_gpr[rd], t0);
4045 tcg_gen_ext16s_tl(cpu_gpr[rd], t0);
4047 #if defined(TARGET_MIPS64)
4050 TCGv t1 = tcg_temp_new();
4052 tcg_gen_shri_tl(t1, t0, 8);
4053 tcg_gen_andi_tl(t1, t1, 0x00FF00FF00FF00FFULL);
4054 tcg_gen_shli_tl(t0, t0, 8);
4055 tcg_gen_andi_tl(t0, t0, ~0x00FF00FF00FF00FFULL);
4056 tcg_gen_or_tl(cpu_gpr[rd], t0, t1);
4062 TCGv t1 = tcg_temp_new();
4064 tcg_gen_shri_tl(t1, t0, 16);
4065 tcg_gen_andi_tl(t1, t1, 0x0000FFFF0000FFFFULL);
4066 tcg_gen_shli_tl(t0, t0, 16);
4067 tcg_gen_andi_tl(t0, t0, ~0x0000FFFF0000FFFFULL);
4068 tcg_gen_or_tl(t0, t0, t1);
4069 tcg_gen_shri_tl(t1, t0, 32);
4070 tcg_gen_shli_tl(t0, t0, 32);
4071 tcg_gen_or_tl(cpu_gpr[rd], t0, t1);
4077 MIPS_INVAL("bsfhl");
4078 generate_exception(ctx, EXCP_RI);
4085 #ifndef CONFIG_USER_ONLY
4086 /* CP0 (MMU and control) */
4087 static inline void gen_mfc0_load32 (TCGv arg, target_ulong off)
4089 TCGv_i32 t0 = tcg_temp_new_i32();
4091 tcg_gen_ld_i32(t0, cpu_env, off);
4092 tcg_gen_ext_i32_tl(arg, t0);
4093 tcg_temp_free_i32(t0);
4096 static inline void gen_mfc0_load64 (TCGv arg, target_ulong off)
4098 tcg_gen_ld_tl(arg, cpu_env, off);
4099 tcg_gen_ext32s_tl(arg, arg);
4102 static inline void gen_mtc0_store32 (TCGv arg, target_ulong off)
4104 TCGv_i32 t0 = tcg_temp_new_i32();
4106 tcg_gen_trunc_tl_i32(t0, arg);
4107 tcg_gen_st_i32(t0, cpu_env, off);
4108 tcg_temp_free_i32(t0);
4111 static inline void gen_mtc0_store64 (TCGv arg, target_ulong off)
4113 tcg_gen_ext32s_tl(arg, arg);
4114 tcg_gen_st_tl(arg, cpu_env, off);
4117 static void gen_mfc0 (CPUMIPSState *env, DisasContext *ctx, TCGv arg, int reg, int sel)
4119 const char *rn = "invalid";
4122 check_insn(env, ctx, ISA_MIPS32);
4128 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Index));
4132 check_insn(env, ctx, ASE_MT);
4133 gen_helper_mfc0_mvpcontrol(arg, cpu_env);
4137 check_insn(env, ctx, ASE_MT);
4138 gen_helper_mfc0_mvpconf0(arg, cpu_env);
4142 check_insn(env, ctx, ASE_MT);
4143 gen_helper_mfc0_mvpconf1(arg, cpu_env);
4153 gen_helper_mfc0_random(arg, cpu_env);
4157 check_insn(env, ctx, ASE_MT);
4158 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEControl));
4162 check_insn(env, ctx, ASE_MT);
4163 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEConf0));
4167 check_insn(env, ctx, ASE_MT);
4168 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEConf1));
4172 check_insn(env, ctx, ASE_MT);
4173 gen_mfc0_load64(arg, offsetof(CPUMIPSState, CP0_YQMask));
4177 check_insn(env, ctx, ASE_MT);
4178 gen_mfc0_load64(arg, offsetof(CPUMIPSState, CP0_VPESchedule));
4182 check_insn(env, ctx, ASE_MT);
4183 gen_mfc0_load64(arg, offsetof(CPUMIPSState, CP0_VPEScheFBack));
4184 rn = "VPEScheFBack";
4187 check_insn(env, ctx, ASE_MT);
4188 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEOpt));
4198 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EntryLo0));
4199 tcg_gen_ext32s_tl(arg, arg);
4203 check_insn(env, ctx, ASE_MT);
4204 gen_helper_mfc0_tcstatus(arg, cpu_env);
4208 check_insn(env, ctx, ASE_MT);
4209 gen_helper_mfc0_tcbind(arg, cpu_env);
4213 check_insn(env, ctx, ASE_MT);
4214 gen_helper_mfc0_tcrestart(arg, cpu_env);
4218 check_insn(env, ctx, ASE_MT);
4219 gen_helper_mfc0_tchalt(arg, cpu_env);
4223 check_insn(env, ctx, ASE_MT);
4224 gen_helper_mfc0_tccontext(arg, cpu_env);
4228 check_insn(env, ctx, ASE_MT);
4229 gen_helper_mfc0_tcschedule(arg, cpu_env);
4233 check_insn(env, ctx, ASE_MT);
4234 gen_helper_mfc0_tcschefback(arg, cpu_env);
4244 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EntryLo1));
4245 tcg_gen_ext32s_tl(arg, arg);
4255 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_Context));
4256 tcg_gen_ext32s_tl(arg, arg);
4260 // gen_helper_mfc0_contextconfig(arg); /* SmartMIPS ASE */
4261 rn = "ContextConfig";
4270 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PageMask));
4274 check_insn(env, ctx, ISA_MIPS32R2);
4275 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PageGrain));
4285 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Wired));
4289 check_insn(env, ctx, ISA_MIPS32R2);
4290 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf0));
4294 check_insn(env, ctx, ISA_MIPS32R2);
4295 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf1));
4299 check_insn(env, ctx, ISA_MIPS32R2);
4300 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf2));
4304 check_insn(env, ctx, ISA_MIPS32R2);
4305 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf3));
4309 check_insn(env, ctx, ISA_MIPS32R2);
4310 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf4));
4320 check_insn(env, ctx, ISA_MIPS32R2);
4321 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_HWREna));
4331 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_BadVAddr));
4332 tcg_gen_ext32s_tl(arg, arg);
4342 /* Mark as an IO operation because we read the time. */
4345 gen_helper_mfc0_count(arg, cpu_env);
4349 /* Break the TB to be able to take timer interrupts immediately
4350 after reading count. */
4351 ctx->bstate = BS_STOP;
4354 /* 6,7 are implementation dependent */
4362 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EntryHi));
4363 tcg_gen_ext32s_tl(arg, arg);
4373 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Compare));
4376 /* 6,7 are implementation dependent */
4384 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Status));
4388 check_insn(env, ctx, ISA_MIPS32R2);
4389 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_IntCtl));
4393 check_insn(env, ctx, ISA_MIPS32R2);
4394 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSCtl));
4398 check_insn(env, ctx, ISA_MIPS32R2);
4399 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSMap));
4409 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Cause));
4419 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EPC));
4420 tcg_gen_ext32s_tl(arg, arg);
4430 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PRid));
4434 check_insn(env, ctx, ISA_MIPS32R2);
4435 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_EBase));
4445 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config0));
4449 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config1));
4453 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config2));
4457 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config3));
4460 /* 4,5 are reserved */
4461 /* 6,7 are implementation dependent */
4463 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config6));
4467 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config7));
4477 gen_helper_mfc0_lladdr(arg, cpu_env);
4487 gen_helper_1e0i(mfc0_watchlo, arg, sel);
4497 gen_helper_1e0i(mfc0_watchhi, arg, sel);
4507 #if defined(TARGET_MIPS64)
4508 check_insn(env, ctx, ISA_MIPS3);
4509 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_XContext));
4510 tcg_gen_ext32s_tl(arg, arg);
4519 /* Officially reserved, but sel 0 is used for R1x000 framemask */
4522 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Framemask));
4530 tcg_gen_movi_tl(arg, 0); /* unimplemented */
4531 rn = "'Diagnostic"; /* implementation dependent */
4536 gen_helper_mfc0_debug(arg, cpu_env); /* EJTAG support */
4540 // gen_helper_mfc0_tracecontrol(arg); /* PDtrace support */
4541 rn = "TraceControl";
4544 // gen_helper_mfc0_tracecontrol2(arg); /* PDtrace support */
4545 rn = "TraceControl2";
4548 // gen_helper_mfc0_usertracedata(arg); /* PDtrace support */
4549 rn = "UserTraceData";
4552 // gen_helper_mfc0_tracebpc(arg); /* PDtrace support */
4563 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_DEPC));
4564 tcg_gen_ext32s_tl(arg, arg);
4574 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Performance0));
4575 rn = "Performance0";
4578 // gen_helper_mfc0_performance1(arg);
4579 rn = "Performance1";
4582 // gen_helper_mfc0_performance2(arg);
4583 rn = "Performance2";
4586 // gen_helper_mfc0_performance3(arg);
4587 rn = "Performance3";
4590 // gen_helper_mfc0_performance4(arg);
4591 rn = "Performance4";
4594 // gen_helper_mfc0_performance5(arg);
4595 rn = "Performance5";
4598 // gen_helper_mfc0_performance6(arg);
4599 rn = "Performance6";
4602 // gen_helper_mfc0_performance7(arg);
4603 rn = "Performance7";
4610 tcg_gen_movi_tl(arg, 0); /* unimplemented */
4616 tcg_gen_movi_tl(arg, 0); /* unimplemented */
4629 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_TagLo));
4636 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DataLo));
4649 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_TagHi));
4656 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DataHi));
4666 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_ErrorEPC));
4667 tcg_gen_ext32s_tl(arg, arg);
4678 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DESAVE));
4688 (void)rn; /* avoid a compiler warning */
4689 LOG_DISAS("mfc0 %s (reg %d sel %d)\n", rn, reg, sel);
4693 LOG_DISAS("mfc0 %s (reg %d sel %d)\n", rn, reg, sel);
4694 generate_exception(ctx, EXCP_RI);
4697 static void gen_mtc0 (CPUMIPSState *env, DisasContext *ctx, TCGv arg, int reg, int sel)
4699 const char *rn = "invalid";
4702 check_insn(env, ctx, ISA_MIPS32);
4711 gen_helper_mtc0_index(cpu_env, arg);
4715 check_insn(env, ctx, ASE_MT);
4716 gen_helper_mtc0_mvpcontrol(cpu_env, arg);
4720 check_insn(env, ctx, ASE_MT);
4725 check_insn(env, ctx, ASE_MT);
4740 check_insn(env, ctx, ASE_MT);
4741 gen_helper_mtc0_vpecontrol(cpu_env, arg);
4745 check_insn(env, ctx, ASE_MT);
4746 gen_helper_mtc0_vpeconf0(cpu_env, arg);
4750 check_insn(env, ctx, ASE_MT);
4751 gen_helper_mtc0_vpeconf1(cpu_env, arg);
4755 check_insn(env, ctx, ASE_MT);
4756 gen_helper_mtc0_yqmask(cpu_env, arg);
4760 check_insn(env, ctx, ASE_MT);
4761 gen_mtc0_store64(arg, offsetof(CPUMIPSState, CP0_VPESchedule));
4765 check_insn(env, ctx, ASE_MT);
4766 gen_mtc0_store64(arg, offsetof(CPUMIPSState, CP0_VPEScheFBack));
4767 rn = "VPEScheFBack";
4770 check_insn(env, ctx, ASE_MT);
4771 gen_helper_mtc0_vpeopt(cpu_env, arg);
4781 gen_helper_mtc0_entrylo0(cpu_env, arg);
4785 check_insn(env, ctx, ASE_MT);
4786 gen_helper_mtc0_tcstatus(cpu_env, arg);
4790 check_insn(env, ctx, ASE_MT);
4791 gen_helper_mtc0_tcbind(cpu_env, arg);
4795 check_insn(env, ctx, ASE_MT);
4796 gen_helper_mtc0_tcrestart(cpu_env, arg);
4800 check_insn(env, ctx, ASE_MT);
4801 gen_helper_mtc0_tchalt(cpu_env, arg);
4805 check_insn(env, ctx, ASE_MT);
4806 gen_helper_mtc0_tccontext(cpu_env, arg);
4810 check_insn(env, ctx, ASE_MT);
4811 gen_helper_mtc0_tcschedule(cpu_env, arg);
4815 check_insn(env, ctx, ASE_MT);
4816 gen_helper_mtc0_tcschefback(cpu_env, arg);
4826 gen_helper_mtc0_entrylo1(cpu_env, arg);
4836 gen_helper_mtc0_context(cpu_env, arg);
4840 // gen_helper_mtc0_contextconfig(cpu_env, arg); /* SmartMIPS ASE */
4841 rn = "ContextConfig";
4850 gen_helper_mtc0_pagemask(cpu_env, arg);
4854 check_insn(env, ctx, ISA_MIPS32R2);
4855 gen_helper_mtc0_pagegrain(cpu_env, arg);
4865 gen_helper_mtc0_wired(cpu_env, arg);
4869 check_insn(env, ctx, ISA_MIPS32R2);
4870 gen_helper_mtc0_srsconf0(cpu_env, arg);
4874 check_insn(env, ctx, ISA_MIPS32R2);
4875 gen_helper_mtc0_srsconf1(cpu_env, arg);
4879 check_insn(env, ctx, ISA_MIPS32R2);
4880 gen_helper_mtc0_srsconf2(cpu_env, arg);
4884 check_insn(env, ctx, ISA_MIPS32R2);
4885 gen_helper_mtc0_srsconf3(cpu_env, arg);
4889 check_insn(env, ctx, ISA_MIPS32R2);
4890 gen_helper_mtc0_srsconf4(cpu_env, arg);
4900 check_insn(env, ctx, ISA_MIPS32R2);
4901 gen_helper_mtc0_hwrena(cpu_env, arg);
4915 gen_helper_mtc0_count(cpu_env, arg);
4918 /* 6,7 are implementation dependent */
4926 gen_helper_mtc0_entryhi(cpu_env, arg);
4936 gen_helper_mtc0_compare(cpu_env, arg);
4939 /* 6,7 are implementation dependent */
4947 save_cpu_state(ctx, 1);
4948 gen_helper_mtc0_status(cpu_env, arg);
4949 /* BS_STOP isn't good enough here, hflags may have changed. */
4950 gen_save_pc(ctx->pc + 4);
4951 ctx->bstate = BS_EXCP;
4955 check_insn(env, ctx, ISA_MIPS32R2);
4956 gen_helper_mtc0_intctl(cpu_env, arg);
4957 /* Stop translation as we may have switched the execution mode */
4958 ctx->bstate = BS_STOP;
4962 check_insn(env, ctx, ISA_MIPS32R2);
4963 gen_helper_mtc0_srsctl(cpu_env, arg);
4964 /* Stop translation as we may have switched the execution mode */
4965 ctx->bstate = BS_STOP;
4969 check_insn(env, ctx, ISA_MIPS32R2);
4970 gen_mtc0_store32(arg, offsetof(CPUMIPSState, CP0_SRSMap));
4971 /* Stop translation as we may have switched the execution mode */
4972 ctx->bstate = BS_STOP;
4982 save_cpu_state(ctx, 1);
4983 gen_helper_mtc0_cause(cpu_env, arg);
4993 gen_mtc0_store64(arg, offsetof(CPUMIPSState, CP0_EPC));
5007 check_insn(env, ctx, ISA_MIPS32R2);
5008 gen_helper_mtc0_ebase(cpu_env, arg);
5018 gen_helper_mtc0_config0(cpu_env, arg);
5020 /* Stop translation as we may have switched the execution mode */
5021 ctx->bstate = BS_STOP;
5024 /* ignored, read only */
5028 gen_helper_mtc0_config2(cpu_env, arg);
5030 /* Stop translation as we may have switched the execution mode */
5031 ctx->bstate = BS_STOP;
5034 /* ignored, read only */
5037 /* 4,5 are reserved */
5038 /* 6,7 are implementation dependent */
5048 rn = "Invalid config selector";
5055 gen_helper_mtc0_lladdr(cpu_env, arg);
5065 gen_helper_0e1i(mtc0_watchlo, arg, sel);
5075 gen_helper_0e1i(mtc0_watchhi, arg, sel);
5085 #if defined(TARGET_MIPS64)
5086 check_insn(env, ctx, ISA_MIPS3);
5087 gen_helper_mtc0_xcontext(cpu_env, arg);
5096 /* Officially reserved, but sel 0 is used for R1x000 framemask */
5099 gen_helper_mtc0_framemask(cpu_env, arg);
5108 rn = "Diagnostic"; /* implementation dependent */
5113 gen_helper_mtc0_debug(cpu_env, arg); /* EJTAG support */
5114 /* BS_STOP isn't good enough here, hflags may have changed. */
5115 gen_save_pc(ctx->pc + 4);
5116 ctx->bstate = BS_EXCP;
5120 // gen_helper_mtc0_tracecontrol(cpu_env, arg); /* PDtrace support */
5121 rn = "TraceControl";
5122 /* Stop translation as we may have switched the execution mode */
5123 ctx->bstate = BS_STOP;
5126 // gen_helper_mtc0_tracecontrol2(cpu_env, arg); /* PDtrace support */
5127 rn = "TraceControl2";
5128 /* Stop translation as we may have switched the execution mode */
5129 ctx->bstate = BS_STOP;
5132 /* Stop translation as we may have switched the execution mode */
5133 ctx->bstate = BS_STOP;
5134 // gen_helper_mtc0_usertracedata(cpu_env, arg); /* PDtrace support */
5135 rn = "UserTraceData";
5136 /* Stop translation as we may have switched the execution mode */
5137 ctx->bstate = BS_STOP;
5140 // gen_helper_mtc0_tracebpc(cpu_env, arg); /* PDtrace support */
5141 /* Stop translation as we may have switched the execution mode */
5142 ctx->bstate = BS_STOP;
5153 gen_mtc0_store64(arg, offsetof(CPUMIPSState, CP0_DEPC));
5163 gen_helper_mtc0_performance0(cpu_env, arg);
5164 rn = "Performance0";
5167 // gen_helper_mtc0_performance1(arg);
5168 rn = "Performance1";
5171 // gen_helper_mtc0_performance2(arg);
5172 rn = "Performance2";
5175 // gen_helper_mtc0_performance3(arg);
5176 rn = "Performance3";
5179 // gen_helper_mtc0_performance4(arg);
5180 rn = "Performance4";
5183 // gen_helper_mtc0_performance5(arg);
5184 rn = "Performance5";
5187 // gen_helper_mtc0_performance6(arg);
5188 rn = "Performance6";
5191 // gen_helper_mtc0_performance7(arg);
5192 rn = "Performance7";
5218 gen_helper_mtc0_taglo(cpu_env, arg);
5225 gen_helper_mtc0_datalo(cpu_env, arg);
5238 gen_helper_mtc0_taghi(cpu_env, arg);
5245 gen_helper_mtc0_datahi(cpu_env, arg);
5256 gen_mtc0_store64(arg, offsetof(CPUMIPSState, CP0_ErrorEPC));
5267 gen_mtc0_store32(arg, offsetof(CPUMIPSState, CP0_DESAVE));
5273 /* Stop translation as we may have switched the execution mode */
5274 ctx->bstate = BS_STOP;
5279 (void)rn; /* avoid a compiler warning */
5280 LOG_DISAS("mtc0 %s (reg %d sel %d)\n", rn, reg, sel);
5281 /* For simplicity assume that all writes can cause interrupts. */
5284 ctx->bstate = BS_STOP;
5289 LOG_DISAS("mtc0 %s (reg %d sel %d)\n", rn, reg, sel);
5290 generate_exception(ctx, EXCP_RI);
5293 #if defined(TARGET_MIPS64)
5294 static void gen_dmfc0 (CPUMIPSState *env, DisasContext *ctx, TCGv arg, int reg, int sel)
5296 const char *rn = "invalid";
5299 check_insn(env, ctx, ISA_MIPS64);
5305 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Index));
5309 check_insn(env, ctx, ASE_MT);
5310 gen_helper_mfc0_mvpcontrol(arg, cpu_env);
5314 check_insn(env, ctx, ASE_MT);
5315 gen_helper_mfc0_mvpconf0(arg, cpu_env);
5319 check_insn(env, ctx, ASE_MT);
5320 gen_helper_mfc0_mvpconf1(arg, cpu_env);
5330 gen_helper_mfc0_random(arg, cpu_env);
5334 check_insn(env, ctx, ASE_MT);
5335 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEControl));
5339 check_insn(env, ctx, ASE_MT);
5340 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEConf0));
5344 check_insn(env, ctx, ASE_MT);
5345 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEConf1));
5349 check_insn(env, ctx, ASE_MT);
5350 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_YQMask));
5354 check_insn(env, ctx, ASE_MT);
5355 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_VPESchedule));
5359 check_insn(env, ctx, ASE_MT);
5360 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_VPEScheFBack));
5361 rn = "VPEScheFBack";
5364 check_insn(env, ctx, ASE_MT);
5365 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEOpt));
5375 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EntryLo0));
5379 check_insn(env, ctx, ASE_MT);
5380 gen_helper_mfc0_tcstatus(arg, cpu_env);
5384 check_insn(env, ctx, ASE_MT);
5385 gen_helper_mfc0_tcbind(arg, cpu_env);
5389 check_insn(env, ctx, ASE_MT);
5390 gen_helper_dmfc0_tcrestart(arg, cpu_env);
5394 check_insn(env, ctx, ASE_MT);
5395 gen_helper_dmfc0_tchalt(arg, cpu_env);
5399 check_insn(env, ctx, ASE_MT);
5400 gen_helper_dmfc0_tccontext(arg, cpu_env);
5404 check_insn(env, ctx, ASE_MT);
5405 gen_helper_dmfc0_tcschedule(arg, cpu_env);
5409 check_insn(env, ctx, ASE_MT);
5410 gen_helper_dmfc0_tcschefback(arg, cpu_env);
5420 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EntryLo1));
5430 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_Context));
5434 // gen_helper_dmfc0_contextconfig(arg); /* SmartMIPS ASE */
5435 rn = "ContextConfig";
5444 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PageMask));
5448 check_insn(env, ctx, ISA_MIPS32R2);
5449 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PageGrain));
5459 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Wired));
5463 check_insn(env, ctx, ISA_MIPS32R2);
5464 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf0));
5468 check_insn(env, ctx, ISA_MIPS32R2);
5469 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf1));
5473 check_insn(env, ctx, ISA_MIPS32R2);
5474 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf2));
5478 check_insn(env, ctx, ISA_MIPS32R2);
5479 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf3));
5483 check_insn(env, ctx, ISA_MIPS32R2);
5484 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf4));
5494 check_insn(env, ctx, ISA_MIPS32R2);
5495 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_HWREna));
5505 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_BadVAddr));
5515 /* Mark as an IO operation because we read the time. */
5518 gen_helper_mfc0_count(arg, cpu_env);
5522 /* Break the TB to be able to take timer interrupts immediately
5523 after reading count. */
5524 ctx->bstate = BS_STOP;
5527 /* 6,7 are implementation dependent */
5535 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EntryHi));
5545 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Compare));
5548 /* 6,7 are implementation dependent */
5556 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Status));
5560 check_insn(env, ctx, ISA_MIPS32R2);
5561 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_IntCtl));
5565 check_insn(env, ctx, ISA_MIPS32R2);
5566 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSCtl));
5570 check_insn(env, ctx, ISA_MIPS32R2);
5571 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSMap));
5581 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Cause));
5591 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EPC));
5601 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PRid));
5605 check_insn(env, ctx, ISA_MIPS32R2);
5606 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_EBase));
5616 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config0));
5620 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config1));
5624 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config2));
5628 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config3));
5631 /* 6,7 are implementation dependent */
5633 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config6));
5637 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config7));
5647 gen_helper_dmfc0_lladdr(arg, cpu_env);
5657 gen_helper_1e0i(dmfc0_watchlo, arg, sel);
5667 gen_helper_1e0i(mfc0_watchhi, arg, sel);
5677 check_insn(env, ctx, ISA_MIPS3);
5678 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_XContext));
5686 /* Officially reserved, but sel 0 is used for R1x000 framemask */
5689 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Framemask));
5697 tcg_gen_movi_tl(arg, 0); /* unimplemented */
5698 rn = "'Diagnostic"; /* implementation dependent */
5703 gen_helper_mfc0_debug(arg, cpu_env); /* EJTAG support */
5707 // gen_helper_dmfc0_tracecontrol(arg, cpu_env); /* PDtrace support */
5708 rn = "TraceControl";
5711 // gen_helper_dmfc0_tracecontrol2(arg, cpu_env); /* PDtrace support */
5712 rn = "TraceControl2";
5715 // gen_helper_dmfc0_usertracedata(arg, cpu_env); /* PDtrace support */
5716 rn = "UserTraceData";
5719 // gen_helper_dmfc0_tracebpc(arg, cpu_env); /* PDtrace support */
5730 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_DEPC));
5740 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Performance0));
5741 rn = "Performance0";
5744 // gen_helper_dmfc0_performance1(arg);
5745 rn = "Performance1";
5748 // gen_helper_dmfc0_performance2(arg);
5749 rn = "Performance2";
5752 // gen_helper_dmfc0_performance3(arg);
5753 rn = "Performance3";
5756 // gen_helper_dmfc0_performance4(arg);
5757 rn = "Performance4";
5760 // gen_helper_dmfc0_performance5(arg);
5761 rn = "Performance5";
5764 // gen_helper_dmfc0_performance6(arg);
5765 rn = "Performance6";
5768 // gen_helper_dmfc0_performance7(arg);
5769 rn = "Performance7";
5776 tcg_gen_movi_tl(arg, 0); /* unimplemented */
5783 tcg_gen_movi_tl(arg, 0); /* unimplemented */
5796 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_TagLo));
5803 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DataLo));
5816 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_TagHi));
5823 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DataHi));
5833 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_ErrorEPC));
5844 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DESAVE));
5854 (void)rn; /* avoid a compiler warning */
5855 LOG_DISAS("dmfc0 %s (reg %d sel %d)\n", rn, reg, sel);
5859 LOG_DISAS("dmfc0 %s (reg %d sel %d)\n", rn, reg, sel);
5860 generate_exception(ctx, EXCP_RI);
5863 static void gen_dmtc0 (CPUMIPSState *env, DisasContext *ctx, TCGv arg, int reg, int sel)
5865 const char *rn = "invalid";
5868 check_insn(env, ctx, ISA_MIPS64);
5877 gen_helper_mtc0_index(cpu_env, arg);
5881 check_insn(env, ctx, ASE_MT);
5882 gen_helper_mtc0_mvpcontrol(cpu_env, arg);
5886 check_insn(env, ctx, ASE_MT);
5891 check_insn(env, ctx, ASE_MT);
5906 check_insn(env, ctx, ASE_MT);
5907 gen_helper_mtc0_vpecontrol(cpu_env, arg);
5911 check_insn(env, ctx, ASE_MT);
5912 gen_helper_mtc0_vpeconf0(cpu_env, arg);
5916 check_insn(env, ctx, ASE_MT);
5917 gen_helper_mtc0_vpeconf1(cpu_env, arg);
5921 check_insn(env, ctx, ASE_MT);
5922 gen_helper_mtc0_yqmask(cpu_env, arg);
5926 check_insn(env, ctx, ASE_MT);
5927 tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_VPESchedule));
5931 check_insn(env, ctx, ASE_MT);
5932 tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_VPEScheFBack));
5933 rn = "VPEScheFBack";
5936 check_insn(env, ctx, ASE_MT);
5937 gen_helper_mtc0_vpeopt(cpu_env, arg);
5947 gen_helper_mtc0_entrylo0(cpu_env, arg);
5951 check_insn(env, ctx, ASE_MT);
5952 gen_helper_mtc0_tcstatus(cpu_env, arg);
5956 check_insn(env, ctx, ASE_MT);
5957 gen_helper_mtc0_tcbind(cpu_env, arg);
5961 check_insn(env, ctx, ASE_MT);
5962 gen_helper_mtc0_tcrestart(cpu_env, arg);
5966 check_insn(env, ctx, ASE_MT);
5967 gen_helper_mtc0_tchalt(cpu_env, arg);
5971 check_insn(env, ctx, ASE_MT);
5972 gen_helper_mtc0_tccontext(cpu_env, arg);
5976 check_insn(env, ctx, ASE_MT);
5977 gen_helper_mtc0_tcschedule(cpu_env, arg);
5981 check_insn(env, ctx, ASE_MT);
5982 gen_helper_mtc0_tcschefback(cpu_env, arg);
5992 gen_helper_mtc0_entrylo1(cpu_env, arg);
6002 gen_helper_mtc0_context(cpu_env, arg);
6006 // gen_helper_mtc0_contextconfig(cpu_env, arg); /* SmartMIPS ASE */
6007 rn = "ContextConfig";
6016 gen_helper_mtc0_pagemask(cpu_env, arg);
6020 check_insn(env, ctx, ISA_MIPS32R2);
6021 gen_helper_mtc0_pagegrain(cpu_env, arg);
6031 gen_helper_mtc0_wired(cpu_env, arg);
6035 check_insn(env, ctx, ISA_MIPS32R2);
6036 gen_helper_mtc0_srsconf0(cpu_env, arg);
6040 check_insn(env, ctx, ISA_MIPS32R2);
6041 gen_helper_mtc0_srsconf1(cpu_env, arg);
6045 check_insn(env, ctx, ISA_MIPS32R2);
6046 gen_helper_mtc0_srsconf2(cpu_env, arg);
6050 check_insn(env, ctx, ISA_MIPS32R2);
6051 gen_helper_mtc0_srsconf3(cpu_env, arg);
6055 check_insn(env, ctx, ISA_MIPS32R2);
6056 gen_helper_mtc0_srsconf4(cpu_env, arg);
6066 check_insn(env, ctx, ISA_MIPS32R2);
6067 gen_helper_mtc0_hwrena(cpu_env, arg);
6081 gen_helper_mtc0_count(cpu_env, arg);
6084 /* 6,7 are implementation dependent */
6088 /* Stop translation as we may have switched the execution mode */
6089 ctx->bstate = BS_STOP;
6094 gen_helper_mtc0_entryhi(cpu_env, arg);
6104 gen_helper_mtc0_compare(cpu_env, arg);
6107 /* 6,7 are implementation dependent */
6111 /* Stop translation as we may have switched the execution mode */
6112 ctx->bstate = BS_STOP;
6117 save_cpu_state(ctx, 1);
6118 gen_helper_mtc0_status(cpu_env, arg);
6119 /* BS_STOP isn't good enough here, hflags may have changed. */
6120 gen_save_pc(ctx->pc + 4);
6121 ctx->bstate = BS_EXCP;
6125 check_insn(env, ctx, ISA_MIPS32R2);
6126 gen_helper_mtc0_intctl(cpu_env, arg);
6127 /* Stop translation as we may have switched the execution mode */
6128 ctx->bstate = BS_STOP;
6132 check_insn(env, ctx, ISA_MIPS32R2);
6133 gen_helper_mtc0_srsctl(cpu_env, arg);
6134 /* Stop translation as we may have switched the execution mode */
6135 ctx->bstate = BS_STOP;
6139 check_insn(env, ctx, ISA_MIPS32R2);
6140 gen_mtc0_store32(arg, offsetof(CPUMIPSState, CP0_SRSMap));
6141 /* Stop translation as we may have switched the execution mode */
6142 ctx->bstate = BS_STOP;
6152 save_cpu_state(ctx, 1);
6153 /* Mark as an IO operation because we may trigger a software
6158 gen_helper_mtc0_cause(cpu_env, arg);
6162 /* Stop translation as we may have triggered an intetrupt */
6163 ctx->bstate = BS_STOP;
6173 tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EPC));
6187 check_insn(env, ctx, ISA_MIPS32R2);
6188 gen_helper_mtc0_ebase(cpu_env, arg);
6198 gen_helper_mtc0_config0(cpu_env, arg);
6200 /* Stop translation as we may have switched the execution mode */
6201 ctx->bstate = BS_STOP;
6204 /* ignored, read only */
6208 gen_helper_mtc0_config2(cpu_env, arg);
6210 /* Stop translation as we may have switched the execution mode */
6211 ctx->bstate = BS_STOP;
6217 /* 6,7 are implementation dependent */
6219 rn = "Invalid config selector";
6226 gen_helper_mtc0_lladdr(cpu_env, arg);
6236 gen_helper_0e1i(mtc0_watchlo, arg, sel);
6246 gen_helper_0e1i(mtc0_watchhi, arg, sel);
6256 check_insn(env, ctx, ISA_MIPS3);
6257 gen_helper_mtc0_xcontext(cpu_env, arg);
6265 /* Officially reserved, but sel 0 is used for R1x000 framemask */
6268 gen_helper_mtc0_framemask(cpu_env, arg);
6277 rn = "Diagnostic"; /* implementation dependent */
6282 gen_helper_mtc0_debug(cpu_env, arg); /* EJTAG support */
6283 /* BS_STOP isn't good enough here, hflags may have changed. */
6284 gen_save_pc(ctx->pc + 4);
6285 ctx->bstate = BS_EXCP;
6289 // gen_helper_mtc0_tracecontrol(cpu_env, arg); /* PDtrace support */
6290 /* Stop translation as we may have switched the execution mode */
6291 ctx->bstate = BS_STOP;
6292 rn = "TraceControl";
6295 // gen_helper_mtc0_tracecontrol2(cpu_env, arg); /* PDtrace support */
6296 /* Stop translation as we may have switched the execution mode */
6297 ctx->bstate = BS_STOP;
6298 rn = "TraceControl2";
6301 // gen_helper_mtc0_usertracedata(cpu_env, arg); /* PDtrace support */
6302 /* Stop translation as we may have switched the execution mode */
6303 ctx->bstate = BS_STOP;
6304 rn = "UserTraceData";
6307 // gen_helper_mtc0_tracebpc(cpu_env, arg); /* PDtrace support */
6308 /* Stop translation as we may have switched the execution mode */
6309 ctx->bstate = BS_STOP;
6320 tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_DEPC));
6330 gen_helper_mtc0_performance0(cpu_env, arg);
6331 rn = "Performance0";
6334 // gen_helper_mtc0_performance1(cpu_env, arg);
6335 rn = "Performance1";
6338 // gen_helper_mtc0_performance2(cpu_env, arg);
6339 rn = "Performance2";
6342 // gen_helper_mtc0_performance3(cpu_env, arg);
6343 rn = "Performance3";
6346 // gen_helper_mtc0_performance4(cpu_env, arg);
6347 rn = "Performance4";
6350 // gen_helper_mtc0_performance5(cpu_env, arg);
6351 rn = "Performance5";
6354 // gen_helper_mtc0_performance6(cpu_env, arg);
6355 rn = "Performance6";
6358 // gen_helper_mtc0_performance7(cpu_env, arg);
6359 rn = "Performance7";
6385 gen_helper_mtc0_taglo(cpu_env, arg);
6392 gen_helper_mtc0_datalo(cpu_env, arg);
6405 gen_helper_mtc0_taghi(cpu_env, arg);
6412 gen_helper_mtc0_datahi(cpu_env, arg);
6423 tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_ErrorEPC));
6434 gen_mtc0_store32(arg, offsetof(CPUMIPSState, CP0_DESAVE));
6440 /* Stop translation as we may have switched the execution mode */
6441 ctx->bstate = BS_STOP;
6446 (void)rn; /* avoid a compiler warning */
6447 LOG_DISAS("dmtc0 %s (reg %d sel %d)\n", rn, reg, sel);
6448 /* For simplicity assume that all writes can cause interrupts. */
6451 ctx->bstate = BS_STOP;
6456 LOG_DISAS("dmtc0 %s (reg %d sel %d)\n", rn, reg, sel);
6457 generate_exception(ctx, EXCP_RI);
6459 #endif /* TARGET_MIPS64 */
6461 static void gen_mftr(CPUMIPSState *env, DisasContext *ctx, int rt, int rd,
6462 int u, int sel, int h)
6464 int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
6465 TCGv t0 = tcg_temp_local_new();
6467 if ((env->CP0_VPEConf0 & (1 << CP0VPEC0_MVP)) == 0 &&
6468 ((env->tcs[other_tc].CP0_TCBind & (0xf << CP0TCBd_CurVPE)) !=
6469 (env->active_tc.CP0_TCBind & (0xf << CP0TCBd_CurVPE))))
6470 tcg_gen_movi_tl(t0, -1);
6471 else if ((env->CP0_VPEControl & (0xff << CP0VPECo_TargTC)) >
6472 (env->mvp->CP0_MVPConf0 & (0xff << CP0MVPC0_PTC)))
6473 tcg_gen_movi_tl(t0, -1);
6479 gen_helper_mftc0_vpecontrol(t0, cpu_env);
6482 gen_helper_mftc0_vpeconf0(t0, cpu_env);
6492 gen_helper_mftc0_tcstatus(t0, cpu_env);
6495 gen_helper_mftc0_tcbind(t0, cpu_env);
6498 gen_helper_mftc0_tcrestart(t0, cpu_env);
6501 gen_helper_mftc0_tchalt(t0, cpu_env);
6504 gen_helper_mftc0_tccontext(t0, cpu_env);
6507 gen_helper_mftc0_tcschedule(t0, cpu_env);
6510 gen_helper_mftc0_tcschefback(t0, cpu_env);
6513 gen_mfc0(env, ctx, t0, rt, sel);
6520 gen_helper_mftc0_entryhi(t0, cpu_env);
6523 gen_mfc0(env, ctx, t0, rt, sel);
6529 gen_helper_mftc0_status(t0, cpu_env);
6532 gen_mfc0(env, ctx, t0, rt, sel);
6538 gen_helper_mftc0_cause(t0, cpu_env);
6548 gen_helper_mftc0_epc(t0, cpu_env);
6558 gen_helper_mftc0_ebase(t0, cpu_env);
6568 gen_helper_mftc0_configx(t0, cpu_env, tcg_const_tl(sel));
6578 gen_helper_mftc0_debug(t0, cpu_env);
6581 gen_mfc0(env, ctx, t0, rt, sel);
6586 gen_mfc0(env, ctx, t0, rt, sel);
6588 } else switch (sel) {
6589 /* GPR registers. */
6591 gen_helper_1e0i(mftgpr, t0, rt);
6593 /* Auxiliary CPU registers */
6597 gen_helper_1e0i(mftlo, t0, 0);
6600 gen_helper_1e0i(mfthi, t0, 0);
6603 gen_helper_1e0i(mftacx, t0, 0);
6606 gen_helper_1e0i(mftlo, t0, 1);
6609 gen_helper_1e0i(mfthi, t0, 1);
6612 gen_helper_1e0i(mftacx, t0, 1);
6615 gen_helper_1e0i(mftlo, t0, 2);
6618 gen_helper_1e0i(mfthi, t0, 2);
6621 gen_helper_1e0i(mftacx, t0, 2);
6624 gen_helper_1e0i(mftlo, t0, 3);
6627 gen_helper_1e0i(mfthi, t0, 3);
6630 gen_helper_1e0i(mftacx, t0, 3);
6633 gen_helper_mftdsp(t0, cpu_env);
6639 /* Floating point (COP1). */
6641 /* XXX: For now we support only a single FPU context. */
6643 TCGv_i32 fp0 = tcg_temp_new_i32();
6645 gen_load_fpr32(fp0, rt);
6646 tcg_gen_ext_i32_tl(t0, fp0);
6647 tcg_temp_free_i32(fp0);
6649 TCGv_i32 fp0 = tcg_temp_new_i32();
6651 gen_load_fpr32h(fp0, rt);
6652 tcg_gen_ext_i32_tl(t0, fp0);
6653 tcg_temp_free_i32(fp0);
6657 /* XXX: For now we support only a single FPU context. */
6658 gen_helper_1e0i(cfc1, t0, rt);
6660 /* COP2: Not implemented. */
6667 LOG_DISAS("mftr (reg %d u %d sel %d h %d)\n", rt, u, sel, h);
6668 gen_store_gpr(t0, rd);
6674 LOG_DISAS("mftr (reg %d u %d sel %d h %d)\n", rt, u, sel, h);
6675 generate_exception(ctx, EXCP_RI);
6678 static void gen_mttr(CPUMIPSState *env, DisasContext *ctx, int rd, int rt,
6679 int u, int sel, int h)
6681 int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
6682 TCGv t0 = tcg_temp_local_new();
6684 gen_load_gpr(t0, rt);
6685 if ((env->CP0_VPEConf0 & (1 << CP0VPEC0_MVP)) == 0 &&
6686 ((env->tcs[other_tc].CP0_TCBind & (0xf << CP0TCBd_CurVPE)) !=
6687 (env->active_tc.CP0_TCBind & (0xf << CP0TCBd_CurVPE))))
6689 else if ((env->CP0_VPEControl & (0xff << CP0VPECo_TargTC)) >
6690 (env->mvp->CP0_MVPConf0 & (0xff << CP0MVPC0_PTC)))
6697 gen_helper_mttc0_vpecontrol(cpu_env, t0);
6700 gen_helper_mttc0_vpeconf0(cpu_env, t0);
6710 gen_helper_mttc0_tcstatus(cpu_env, t0);
6713 gen_helper_mttc0_tcbind(cpu_env, t0);
6716 gen_helper_mttc0_tcrestart(cpu_env, t0);
6719 gen_helper_mttc0_tchalt(cpu_env, t0);
6722 gen_helper_mttc0_tccontext(cpu_env, t0);
6725 gen_helper_mttc0_tcschedule(cpu_env, t0);
6728 gen_helper_mttc0_tcschefback(cpu_env, t0);
6731 gen_mtc0(env, ctx, t0, rd, sel);
6738 gen_helper_mttc0_entryhi(cpu_env, t0);
6741 gen_mtc0(env, ctx, t0, rd, sel);
6747 gen_helper_mttc0_status(cpu_env, t0);
6750 gen_mtc0(env, ctx, t0, rd, sel);
6756 gen_helper_mttc0_cause(cpu_env, t0);
6766 gen_helper_mttc0_ebase(cpu_env, t0);
6776 gen_helper_mttc0_debug(cpu_env, t0);
6779 gen_mtc0(env, ctx, t0, rd, sel);
6784 gen_mtc0(env, ctx, t0, rd, sel);
6786 } else switch (sel) {
6787 /* GPR registers. */
6789 gen_helper_0e1i(mttgpr, t0, rd);
6791 /* Auxiliary CPU registers */
6795 gen_helper_0e1i(mttlo, t0, 0);
6798 gen_helper_0e1i(mtthi, t0, 0);
6801 gen_helper_0e1i(mttacx, t0, 0);
6804 gen_helper_0e1i(mttlo, t0, 1);
6807 gen_helper_0e1i(mtthi, t0, 1);
6810 gen_helper_0e1i(mttacx, t0, 1);
6813 gen_helper_0e1i(mttlo, t0, 2);
6816 gen_helper_0e1i(mtthi, t0, 2);
6819 gen_helper_0e1i(mttacx, t0, 2);
6822 gen_helper_0e1i(mttlo, t0, 3);
6825 gen_helper_0e1i(mtthi, t0, 3);
6828 gen_helper_0e1i(mttacx, t0, 3);
6831 gen_helper_mttdsp(cpu_env, t0);
6837 /* Floating point (COP1). */
6839 /* XXX: For now we support only a single FPU context. */
6841 TCGv_i32 fp0 = tcg_temp_new_i32();
6843 tcg_gen_trunc_tl_i32(fp0, t0);
6844 gen_store_fpr32(fp0, rd);
6845 tcg_temp_free_i32(fp0);
6847 TCGv_i32 fp0 = tcg_temp_new_i32();
6849 tcg_gen_trunc_tl_i32(fp0, t0);
6850 gen_store_fpr32h(fp0, rd);
6851 tcg_temp_free_i32(fp0);
6855 /* XXX: For now we support only a single FPU context. */
6856 gen_helper_0e1i(ctc1, t0, rd);
6858 /* COP2: Not implemented. */
6865 LOG_DISAS("mttr (reg %d u %d sel %d h %d)\n", rd, u, sel, h);
6871 LOG_DISAS("mttr (reg %d u %d sel %d h %d)\n", rd, u, sel, h);
6872 generate_exception(ctx, EXCP_RI);
6875 static void gen_cp0 (CPUMIPSState *env, DisasContext *ctx, uint32_t opc, int rt, int rd)
6877 const char *opn = "ldst";
6879 check_cp0_enabled(ctx);
6886 gen_mfc0(env, ctx, cpu_gpr[rt], rd, ctx->opcode & 0x7);
6891 TCGv t0 = tcg_temp_new();
6893 gen_load_gpr(t0, rt);
6894 gen_mtc0(env, ctx, t0, rd, ctx->opcode & 0x7);
6899 #if defined(TARGET_MIPS64)
6901 check_insn(env, ctx, ISA_MIPS3);
6906 gen_dmfc0(env, ctx, cpu_gpr[rt], rd, ctx->opcode & 0x7);
6910 check_insn(env, ctx, ISA_MIPS3);
6912 TCGv t0 = tcg_temp_new();
6914 gen_load_gpr(t0, rt);
6915 gen_dmtc0(env, ctx, t0, rd, ctx->opcode & 0x7);
6922 check_insn(env, ctx, ASE_MT);
6927 gen_mftr(env, ctx, rt, rd, (ctx->opcode >> 5) & 1,
6928 ctx->opcode & 0x7, (ctx->opcode >> 4) & 1);
6932 check_insn(env, ctx, ASE_MT);
6933 gen_mttr(env, ctx, rd, rt, (ctx->opcode >> 5) & 1,
6934 ctx->opcode & 0x7, (ctx->opcode >> 4) & 1);
6939 if (!env->tlb->helper_tlbwi)
6941 gen_helper_tlbwi(cpu_env);
6945 if (!env->tlb->helper_tlbwr)
6947 gen_helper_tlbwr(cpu_env);
6951 if (!env->tlb->helper_tlbp)
6953 gen_helper_tlbp(cpu_env);
6957 if (!env->tlb->helper_tlbr)
6959 gen_helper_tlbr(cpu_env);
6963 check_insn(env, ctx, ISA_MIPS2);
6964 gen_helper_eret(cpu_env);
6965 ctx->bstate = BS_EXCP;
6969 check_insn(env, ctx, ISA_MIPS32);
6970 if (!(ctx->hflags & MIPS_HFLAG_DM)) {
6972 generate_exception(ctx, EXCP_RI);
6974 gen_helper_deret(cpu_env);
6975 ctx->bstate = BS_EXCP;
6980 check_insn(env, ctx, ISA_MIPS3 | ISA_MIPS32);
6981 /* If we get an exception, we want to restart at next instruction */
6983 save_cpu_state(ctx, 1);
6985 gen_helper_wait(cpu_env);
6986 ctx->bstate = BS_EXCP;
6991 generate_exception(ctx, EXCP_RI);
6994 (void)opn; /* avoid a compiler warning */
6995 MIPS_DEBUG("%s %s %d", opn, regnames[rt], rd);
6997 #endif /* !CONFIG_USER_ONLY */
6999 /* CP1 Branches (before delay slot) */
7000 static void gen_compute_branch1 (CPUMIPSState *env, DisasContext *ctx, uint32_t op,
7001 int32_t cc, int32_t offset)
7003 target_ulong btarget;
7004 const char *opn = "cp1 cond branch";
7005 TCGv_i32 t0 = tcg_temp_new_i32();
7008 check_insn(env, ctx, ISA_MIPS4 | ISA_MIPS32);
7010 btarget = ctx->pc + 4 + offset;
7014 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
7015 tcg_gen_not_i32(t0, t0);
7016 tcg_gen_andi_i32(t0, t0, 1);
7017 tcg_gen_extu_i32_tl(bcond, t0);
7021 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
7022 tcg_gen_not_i32(t0, t0);
7023 tcg_gen_andi_i32(t0, t0, 1);
7024 tcg_gen_extu_i32_tl(bcond, t0);
7028 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
7029 tcg_gen_andi_i32(t0, t0, 1);
7030 tcg_gen_extu_i32_tl(bcond, t0);
7034 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
7035 tcg_gen_andi_i32(t0, t0, 1);
7036 tcg_gen_extu_i32_tl(bcond, t0);
7039 ctx->hflags |= MIPS_HFLAG_BL;
7043 TCGv_i32 t1 = tcg_temp_new_i32();
7044 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
7045 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+1));
7046 tcg_gen_nand_i32(t0, t0, t1);
7047 tcg_temp_free_i32(t1);
7048 tcg_gen_andi_i32(t0, t0, 1);
7049 tcg_gen_extu_i32_tl(bcond, t0);
7055 TCGv_i32 t1 = tcg_temp_new_i32();
7056 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
7057 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+1));
7058 tcg_gen_or_i32(t0, t0, t1);
7059 tcg_temp_free_i32(t1);
7060 tcg_gen_andi_i32(t0, t0, 1);
7061 tcg_gen_extu_i32_tl(bcond, t0);
7067 TCGv_i32 t1 = tcg_temp_new_i32();
7068 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
7069 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+1));
7070 tcg_gen_and_i32(t0, t0, t1);
7071 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+2));
7072 tcg_gen_and_i32(t0, t0, t1);
7073 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+3));
7074 tcg_gen_nand_i32(t0, t0, t1);
7075 tcg_temp_free_i32(t1);
7076 tcg_gen_andi_i32(t0, t0, 1);
7077 tcg_gen_extu_i32_tl(bcond, t0);
7083 TCGv_i32 t1 = tcg_temp_new_i32();
7084 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
7085 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+1));
7086 tcg_gen_or_i32(t0, t0, t1);
7087 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+2));
7088 tcg_gen_or_i32(t0, t0, t1);
7089 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+3));
7090 tcg_gen_or_i32(t0, t0, t1);
7091 tcg_temp_free_i32(t1);
7092 tcg_gen_andi_i32(t0, t0, 1);
7093 tcg_gen_extu_i32_tl(bcond, t0);
7097 ctx->hflags |= MIPS_HFLAG_BC;
7101 generate_exception (ctx, EXCP_RI);
7104 (void)opn; /* avoid a compiler warning */
7105 MIPS_DEBUG("%s: cond %02x target " TARGET_FMT_lx, opn,
7106 ctx->hflags, btarget);
7107 ctx->btarget = btarget;
7110 tcg_temp_free_i32(t0);
7113 /* Coprocessor 1 (FPU) */
7115 #define FOP(func, fmt) (((fmt) << 21) | (func))
7118 OPC_ADD_S = FOP(0, FMT_S),
7119 OPC_SUB_S = FOP(1, FMT_S),
7120 OPC_MUL_S = FOP(2, FMT_S),
7121 OPC_DIV_S = FOP(3, FMT_S),
7122 OPC_SQRT_S = FOP(4, FMT_S),
7123 OPC_ABS_S = FOP(5, FMT_S),
7124 OPC_MOV_S = FOP(6, FMT_S),
7125 OPC_NEG_S = FOP(7, FMT_S),
7126 OPC_ROUND_L_S = FOP(8, FMT_S),
7127 OPC_TRUNC_L_S = FOP(9, FMT_S),
7128 OPC_CEIL_L_S = FOP(10, FMT_S),
7129 OPC_FLOOR_L_S = FOP(11, FMT_S),
7130 OPC_ROUND_W_S = FOP(12, FMT_S),
7131 OPC_TRUNC_W_S = FOP(13, FMT_S),
7132 OPC_CEIL_W_S = FOP(14, FMT_S),
7133 OPC_FLOOR_W_S = FOP(15, FMT_S),
7134 OPC_MOVCF_S = FOP(17, FMT_S),
7135 OPC_MOVZ_S = FOP(18, FMT_S),
7136 OPC_MOVN_S = FOP(19, FMT_S),
7137 OPC_RECIP_S = FOP(21, FMT_S),
7138 OPC_RSQRT_S = FOP(22, FMT_S),
7139 OPC_RECIP2_S = FOP(28, FMT_S),
7140 OPC_RECIP1_S = FOP(29, FMT_S),
7141 OPC_RSQRT1_S = FOP(30, FMT_S),
7142 OPC_RSQRT2_S = FOP(31, FMT_S),
7143 OPC_CVT_D_S = FOP(33, FMT_S),
7144 OPC_CVT_W_S = FOP(36, FMT_S),
7145 OPC_CVT_L_S = FOP(37, FMT_S),
7146 OPC_CVT_PS_S = FOP(38, FMT_S),
7147 OPC_CMP_F_S = FOP (48, FMT_S),
7148 OPC_CMP_UN_S = FOP (49, FMT_S),
7149 OPC_CMP_EQ_S = FOP (50, FMT_S),
7150 OPC_CMP_UEQ_S = FOP (51, FMT_S),
7151 OPC_CMP_OLT_S = FOP (52, FMT_S),
7152 OPC_CMP_ULT_S = FOP (53, FMT_S),
7153 OPC_CMP_OLE_S = FOP (54, FMT_S),
7154 OPC_CMP_ULE_S = FOP (55, FMT_S),
7155 OPC_CMP_SF_S = FOP (56, FMT_S),
7156 OPC_CMP_NGLE_S = FOP (57, FMT_S),
7157 OPC_CMP_SEQ_S = FOP (58, FMT_S),
7158 OPC_CMP_NGL_S = FOP (59, FMT_S),
7159 OPC_CMP_LT_S = FOP (60, FMT_S),
7160 OPC_CMP_NGE_S = FOP (61, FMT_S),
7161 OPC_CMP_LE_S = FOP (62, FMT_S),
7162 OPC_CMP_NGT_S = FOP (63, FMT_S),
7164 OPC_ADD_D = FOP(0, FMT_D),
7165 OPC_SUB_D = FOP(1, FMT_D),
7166 OPC_MUL_D = FOP(2, FMT_D),
7167 OPC_DIV_D = FOP(3, FMT_D),
7168 OPC_SQRT_D = FOP(4, FMT_D),
7169 OPC_ABS_D = FOP(5, FMT_D),
7170 OPC_MOV_D = FOP(6, FMT_D),
7171 OPC_NEG_D = FOP(7, FMT_D),
7172 OPC_ROUND_L_D = FOP(8, FMT_D),
7173 OPC_TRUNC_L_D = FOP(9, FMT_D),
7174 OPC_CEIL_L_D = FOP(10, FMT_D),
7175 OPC_FLOOR_L_D = FOP(11, FMT_D),
7176 OPC_ROUND_W_D = FOP(12, FMT_D),
7177 OPC_TRUNC_W_D = FOP(13, FMT_D),
7178 OPC_CEIL_W_D = FOP(14, FMT_D),
7179 OPC_FLOOR_W_D = FOP(15, FMT_D),
7180 OPC_MOVCF_D = FOP(17, FMT_D),
7181 OPC_MOVZ_D = FOP(18, FMT_D),
7182 OPC_MOVN_D = FOP(19, FMT_D),
7183 OPC_RECIP_D = FOP(21, FMT_D),
7184 OPC_RSQRT_D = FOP(22, FMT_D),
7185 OPC_RECIP2_D = FOP(28, FMT_D),
7186 OPC_RECIP1_D = FOP(29, FMT_D),
7187 OPC_RSQRT1_D = FOP(30, FMT_D),
7188 OPC_RSQRT2_D = FOP(31, FMT_D),
7189 OPC_CVT_S_D = FOP(32, FMT_D),
7190 OPC_CVT_W_D = FOP(36, FMT_D),
7191 OPC_CVT_L_D = FOP(37, FMT_D),
7192 OPC_CMP_F_D = FOP (48, FMT_D),
7193 OPC_CMP_UN_D = FOP (49, FMT_D),
7194 OPC_CMP_EQ_D = FOP (50, FMT_D),
7195 OPC_CMP_UEQ_D = FOP (51, FMT_D),
7196 OPC_CMP_OLT_D = FOP (52, FMT_D),
7197 OPC_CMP_ULT_D = FOP (53, FMT_D),
7198 OPC_CMP_OLE_D = FOP (54, FMT_D),
7199 OPC_CMP_ULE_D = FOP (55, FMT_D),
7200 OPC_CMP_SF_D = FOP (56, FMT_D),
7201 OPC_CMP_NGLE_D = FOP (57, FMT_D),
7202 OPC_CMP_SEQ_D = FOP (58, FMT_D),
7203 OPC_CMP_NGL_D = FOP (59, FMT_D),
7204 OPC_CMP_LT_D = FOP (60, FMT_D),
7205 OPC_CMP_NGE_D = FOP (61, FMT_D),
7206 OPC_CMP_LE_D = FOP (62, FMT_D),
7207 OPC_CMP_NGT_D = FOP (63, FMT_D),
7209 OPC_CVT_S_W = FOP(32, FMT_W),
7210 OPC_CVT_D_W = FOP(33, FMT_W),
7211 OPC_CVT_S_L = FOP(32, FMT_L),
7212 OPC_CVT_D_L = FOP(33, FMT_L),
7213 OPC_CVT_PS_PW = FOP(38, FMT_W),
7215 OPC_ADD_PS = FOP(0, FMT_PS),
7216 OPC_SUB_PS = FOP(1, FMT_PS),
7217 OPC_MUL_PS = FOP(2, FMT_PS),
7218 OPC_DIV_PS = FOP(3, FMT_PS),
7219 OPC_ABS_PS = FOP(5, FMT_PS),
7220 OPC_MOV_PS = FOP(6, FMT_PS),
7221 OPC_NEG_PS = FOP(7, FMT_PS),
7222 OPC_MOVCF_PS = FOP(17, FMT_PS),
7223 OPC_MOVZ_PS = FOP(18, FMT_PS),
7224 OPC_MOVN_PS = FOP(19, FMT_PS),
7225 OPC_ADDR_PS = FOP(24, FMT_PS),
7226 OPC_MULR_PS = FOP(26, FMT_PS),
7227 OPC_RECIP2_PS = FOP(28, FMT_PS),
7228 OPC_RECIP1_PS = FOP(29, FMT_PS),
7229 OPC_RSQRT1_PS = FOP(30, FMT_PS),
7230 OPC_RSQRT2_PS = FOP(31, FMT_PS),
7232 OPC_CVT_S_PU = FOP(32, FMT_PS),
7233 OPC_CVT_PW_PS = FOP(36, FMT_PS),
7234 OPC_CVT_S_PL = FOP(40, FMT_PS),
7235 OPC_PLL_PS = FOP(44, FMT_PS),
7236 OPC_PLU_PS = FOP(45, FMT_PS),
7237 OPC_PUL_PS = FOP(46, FMT_PS),
7238 OPC_PUU_PS = FOP(47, FMT_PS),
7239 OPC_CMP_F_PS = FOP (48, FMT_PS),
7240 OPC_CMP_UN_PS = FOP (49, FMT_PS),
7241 OPC_CMP_EQ_PS = FOP (50, FMT_PS),
7242 OPC_CMP_UEQ_PS = FOP (51, FMT_PS),
7243 OPC_CMP_OLT_PS = FOP (52, FMT_PS),
7244 OPC_CMP_ULT_PS = FOP (53, FMT_PS),
7245 OPC_CMP_OLE_PS = FOP (54, FMT_PS),
7246 OPC_CMP_ULE_PS = FOP (55, FMT_PS),
7247 OPC_CMP_SF_PS = FOP (56, FMT_PS),
7248 OPC_CMP_NGLE_PS = FOP (57, FMT_PS),
7249 OPC_CMP_SEQ_PS = FOP (58, FMT_PS),
7250 OPC_CMP_NGL_PS = FOP (59, FMT_PS),
7251 OPC_CMP_LT_PS = FOP (60, FMT_PS),
7252 OPC_CMP_NGE_PS = FOP (61, FMT_PS),
7253 OPC_CMP_LE_PS = FOP (62, FMT_PS),
7254 OPC_CMP_NGT_PS = FOP (63, FMT_PS),
7257 static void gen_cp1 (DisasContext *ctx, uint32_t opc, int rt, int fs)
7259 const char *opn = "cp1 move";
7260 TCGv t0 = tcg_temp_new();
7265 TCGv_i32 fp0 = tcg_temp_new_i32();
7267 gen_load_fpr32(fp0, fs);
7268 tcg_gen_ext_i32_tl(t0, fp0);
7269 tcg_temp_free_i32(fp0);
7271 gen_store_gpr(t0, rt);
7275 gen_load_gpr(t0, rt);
7277 TCGv_i32 fp0 = tcg_temp_new_i32();
7279 tcg_gen_trunc_tl_i32(fp0, t0);
7280 gen_store_fpr32(fp0, fs);
7281 tcg_temp_free_i32(fp0);
7286 gen_helper_1e0i(cfc1, t0, fs);
7287 gen_store_gpr(t0, rt);
7291 gen_load_gpr(t0, rt);
7292 gen_helper_0e1i(ctc1, t0, fs);
7295 #if defined(TARGET_MIPS64)
7297 gen_load_fpr64(ctx, t0, fs);
7298 gen_store_gpr(t0, rt);
7302 gen_load_gpr(t0, rt);
7303 gen_store_fpr64(ctx, t0, fs);
7309 TCGv_i32 fp0 = tcg_temp_new_i32();
7311 gen_load_fpr32h(fp0, fs);
7312 tcg_gen_ext_i32_tl(t0, fp0);
7313 tcg_temp_free_i32(fp0);
7315 gen_store_gpr(t0, rt);
7319 gen_load_gpr(t0, rt);
7321 TCGv_i32 fp0 = tcg_temp_new_i32();
7323 tcg_gen_trunc_tl_i32(fp0, t0);
7324 gen_store_fpr32h(fp0, fs);
7325 tcg_temp_free_i32(fp0);
7331 generate_exception (ctx, EXCP_RI);
7334 (void)opn; /* avoid a compiler warning */
7335 MIPS_DEBUG("%s %s %s", opn, regnames[rt], fregnames[fs]);
7341 static void gen_movci (DisasContext *ctx, int rd, int rs, int cc, int tf)
7357 l1 = gen_new_label();
7358 t0 = tcg_temp_new_i32();
7359 tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc));
7360 tcg_gen_brcondi_i32(cond, t0, 0, l1);
7361 tcg_temp_free_i32(t0);
7363 tcg_gen_movi_tl(cpu_gpr[rd], 0);
7365 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
7370 static inline void gen_movcf_s (int fs, int fd, int cc, int tf)
7373 TCGv_i32 t0 = tcg_temp_new_i32();
7374 int l1 = gen_new_label();
7381 tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc));
7382 tcg_gen_brcondi_i32(cond, t0, 0, l1);
7383 gen_load_fpr32(t0, fs);
7384 gen_store_fpr32(t0, fd);
7386 tcg_temp_free_i32(t0);
7389 static inline void gen_movcf_d (DisasContext *ctx, int fs, int fd, int cc, int tf)
7392 TCGv_i32 t0 = tcg_temp_new_i32();
7394 int l1 = gen_new_label();
7401 tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc));
7402 tcg_gen_brcondi_i32(cond, t0, 0, l1);
7403 tcg_temp_free_i32(t0);
7404 fp0 = tcg_temp_new_i64();
7405 gen_load_fpr64(ctx, fp0, fs);
7406 gen_store_fpr64(ctx, fp0, fd);
7407 tcg_temp_free_i64(fp0);
7411 static inline void gen_movcf_ps (int fs, int fd, int cc, int tf)
7414 TCGv_i32 t0 = tcg_temp_new_i32();
7415 int l1 = gen_new_label();
7416 int l2 = gen_new_label();
7423 tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc));
7424 tcg_gen_brcondi_i32(cond, t0, 0, l1);
7425 gen_load_fpr32(t0, fs);
7426 gen_store_fpr32(t0, fd);
7429 tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc+1));
7430 tcg_gen_brcondi_i32(cond, t0, 0, l2);
7431 gen_load_fpr32h(t0, fs);
7432 gen_store_fpr32h(t0, fd);
7433 tcg_temp_free_i32(t0);
7438 static void gen_farith (DisasContext *ctx, enum fopcode op1,
7439 int ft, int fs, int fd, int cc)
7441 const char *opn = "farith";
7442 const char *condnames[] = {
7460 const char *condnames_abs[] = {
7478 enum { BINOP, CMPOP, OTHEROP } optype = OTHEROP;
7479 uint32_t func = ctx->opcode & 0x3f;
7484 TCGv_i32 fp0 = tcg_temp_new_i32();
7485 TCGv_i32 fp1 = tcg_temp_new_i32();
7487 gen_load_fpr32(fp0, fs);
7488 gen_load_fpr32(fp1, ft);
7489 gen_helper_float_add_s(fp0, cpu_env, fp0, fp1);
7490 tcg_temp_free_i32(fp1);
7491 gen_store_fpr32(fp0, fd);
7492 tcg_temp_free_i32(fp0);
7499 TCGv_i32 fp0 = tcg_temp_new_i32();
7500 TCGv_i32 fp1 = tcg_temp_new_i32();
7502 gen_load_fpr32(fp0, fs);
7503 gen_load_fpr32(fp1, ft);
7504 gen_helper_float_sub_s(fp0, cpu_env, fp0, fp1);
7505 tcg_temp_free_i32(fp1);
7506 gen_store_fpr32(fp0, fd);
7507 tcg_temp_free_i32(fp0);
7514 TCGv_i32 fp0 = tcg_temp_new_i32();
7515 TCGv_i32 fp1 = tcg_temp_new_i32();
7517 gen_load_fpr32(fp0, fs);
7518 gen_load_fpr32(fp1, ft);
7519 gen_helper_float_mul_s(fp0, cpu_env, fp0, fp1);
7520 tcg_temp_free_i32(fp1);
7521 gen_store_fpr32(fp0, fd);
7522 tcg_temp_free_i32(fp0);
7529 TCGv_i32 fp0 = tcg_temp_new_i32();
7530 TCGv_i32 fp1 = tcg_temp_new_i32();
7532 gen_load_fpr32(fp0, fs);
7533 gen_load_fpr32(fp1, ft);
7534 gen_helper_float_div_s(fp0, cpu_env, fp0, fp1);
7535 tcg_temp_free_i32(fp1);
7536 gen_store_fpr32(fp0, fd);
7537 tcg_temp_free_i32(fp0);
7544 TCGv_i32 fp0 = tcg_temp_new_i32();
7546 gen_load_fpr32(fp0, fs);
7547 gen_helper_float_sqrt_s(fp0, cpu_env, fp0);
7548 gen_store_fpr32(fp0, fd);
7549 tcg_temp_free_i32(fp0);
7555 TCGv_i32 fp0 = tcg_temp_new_i32();
7557 gen_load_fpr32(fp0, fs);
7558 gen_helper_float_abs_s(fp0, fp0);
7559 gen_store_fpr32(fp0, fd);
7560 tcg_temp_free_i32(fp0);
7566 TCGv_i32 fp0 = tcg_temp_new_i32();
7568 gen_load_fpr32(fp0, fs);
7569 gen_store_fpr32(fp0, fd);
7570 tcg_temp_free_i32(fp0);
7576 TCGv_i32 fp0 = tcg_temp_new_i32();
7578 gen_load_fpr32(fp0, fs);
7579 gen_helper_float_chs_s(fp0, fp0);
7580 gen_store_fpr32(fp0, fd);
7581 tcg_temp_free_i32(fp0);
7586 check_cp1_64bitmode(ctx);
7588 TCGv_i32 fp32 = tcg_temp_new_i32();
7589 TCGv_i64 fp64 = tcg_temp_new_i64();
7591 gen_load_fpr32(fp32, fs);
7592 gen_helper_float_roundl_s(fp64, cpu_env, fp32);
7593 tcg_temp_free_i32(fp32);
7594 gen_store_fpr64(ctx, fp64, fd);
7595 tcg_temp_free_i64(fp64);
7600 check_cp1_64bitmode(ctx);
7602 TCGv_i32 fp32 = tcg_temp_new_i32();
7603 TCGv_i64 fp64 = tcg_temp_new_i64();
7605 gen_load_fpr32(fp32, fs);
7606 gen_helper_float_truncl_s(fp64, cpu_env, fp32);
7607 tcg_temp_free_i32(fp32);
7608 gen_store_fpr64(ctx, fp64, fd);
7609 tcg_temp_free_i64(fp64);
7614 check_cp1_64bitmode(ctx);
7616 TCGv_i32 fp32 = tcg_temp_new_i32();
7617 TCGv_i64 fp64 = tcg_temp_new_i64();
7619 gen_load_fpr32(fp32, fs);
7620 gen_helper_float_ceill_s(fp64, cpu_env, fp32);
7621 tcg_temp_free_i32(fp32);
7622 gen_store_fpr64(ctx, fp64, fd);
7623 tcg_temp_free_i64(fp64);
7628 check_cp1_64bitmode(ctx);
7630 TCGv_i32 fp32 = tcg_temp_new_i32();
7631 TCGv_i64 fp64 = tcg_temp_new_i64();
7633 gen_load_fpr32(fp32, fs);
7634 gen_helper_float_floorl_s(fp64, cpu_env, fp32);
7635 tcg_temp_free_i32(fp32);
7636 gen_store_fpr64(ctx, fp64, fd);
7637 tcg_temp_free_i64(fp64);
7643 TCGv_i32 fp0 = tcg_temp_new_i32();
7645 gen_load_fpr32(fp0, fs);
7646 gen_helper_float_roundw_s(fp0, cpu_env, fp0);
7647 gen_store_fpr32(fp0, fd);
7648 tcg_temp_free_i32(fp0);
7654 TCGv_i32 fp0 = tcg_temp_new_i32();
7656 gen_load_fpr32(fp0, fs);
7657 gen_helper_float_truncw_s(fp0, cpu_env, fp0);
7658 gen_store_fpr32(fp0, fd);
7659 tcg_temp_free_i32(fp0);
7665 TCGv_i32 fp0 = tcg_temp_new_i32();
7667 gen_load_fpr32(fp0, fs);
7668 gen_helper_float_ceilw_s(fp0, cpu_env, fp0);
7669 gen_store_fpr32(fp0, fd);
7670 tcg_temp_free_i32(fp0);
7676 TCGv_i32 fp0 = tcg_temp_new_i32();
7678 gen_load_fpr32(fp0, fs);
7679 gen_helper_float_floorw_s(fp0, cpu_env, fp0);
7680 gen_store_fpr32(fp0, fd);
7681 tcg_temp_free_i32(fp0);
7686 gen_movcf_s(fs, fd, (ft >> 2) & 0x7, ft & 0x1);
7691 int l1 = gen_new_label();
7695 tcg_gen_brcondi_tl(TCG_COND_NE, cpu_gpr[ft], 0, l1);
7697 fp0 = tcg_temp_new_i32();
7698 gen_load_fpr32(fp0, fs);
7699 gen_store_fpr32(fp0, fd);
7700 tcg_temp_free_i32(fp0);
7707 int l1 = gen_new_label();
7711 tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_gpr[ft], 0, l1);
7712 fp0 = tcg_temp_new_i32();
7713 gen_load_fpr32(fp0, fs);
7714 gen_store_fpr32(fp0, fd);
7715 tcg_temp_free_i32(fp0);
7724 TCGv_i32 fp0 = tcg_temp_new_i32();
7726 gen_load_fpr32(fp0, fs);
7727 gen_helper_float_recip_s(fp0, cpu_env, fp0);
7728 gen_store_fpr32(fp0, fd);
7729 tcg_temp_free_i32(fp0);
7736 TCGv_i32 fp0 = tcg_temp_new_i32();
7738 gen_load_fpr32(fp0, fs);
7739 gen_helper_float_rsqrt_s(fp0, cpu_env, fp0);
7740 gen_store_fpr32(fp0, fd);
7741 tcg_temp_free_i32(fp0);
7746 check_cp1_64bitmode(ctx);
7748 TCGv_i32 fp0 = tcg_temp_new_i32();
7749 TCGv_i32 fp1 = tcg_temp_new_i32();
7751 gen_load_fpr32(fp0, fs);
7752 gen_load_fpr32(fp1, ft);
7753 gen_helper_float_recip2_s(fp0, cpu_env, fp0, fp1);
7754 tcg_temp_free_i32(fp1);
7755 gen_store_fpr32(fp0, fd);
7756 tcg_temp_free_i32(fp0);
7761 check_cp1_64bitmode(ctx);
7763 TCGv_i32 fp0 = tcg_temp_new_i32();
7765 gen_load_fpr32(fp0, fs);
7766 gen_helper_float_recip1_s(fp0, cpu_env, fp0);
7767 gen_store_fpr32(fp0, fd);
7768 tcg_temp_free_i32(fp0);
7773 check_cp1_64bitmode(ctx);
7775 TCGv_i32 fp0 = tcg_temp_new_i32();
7777 gen_load_fpr32(fp0, fs);
7778 gen_helper_float_rsqrt1_s(fp0, cpu_env, fp0);
7779 gen_store_fpr32(fp0, fd);
7780 tcg_temp_free_i32(fp0);
7785 check_cp1_64bitmode(ctx);
7787 TCGv_i32 fp0 = tcg_temp_new_i32();
7788 TCGv_i32 fp1 = tcg_temp_new_i32();
7790 gen_load_fpr32(fp0, fs);
7791 gen_load_fpr32(fp1, ft);
7792 gen_helper_float_rsqrt2_s(fp0, cpu_env, fp0, fp1);
7793 tcg_temp_free_i32(fp1);
7794 gen_store_fpr32(fp0, fd);
7795 tcg_temp_free_i32(fp0);
7800 check_cp1_registers(ctx, fd);
7802 TCGv_i32 fp32 = tcg_temp_new_i32();
7803 TCGv_i64 fp64 = tcg_temp_new_i64();
7805 gen_load_fpr32(fp32, fs);
7806 gen_helper_float_cvtd_s(fp64, cpu_env, fp32);
7807 tcg_temp_free_i32(fp32);
7808 gen_store_fpr64(ctx, fp64, fd);
7809 tcg_temp_free_i64(fp64);
7815 TCGv_i32 fp0 = tcg_temp_new_i32();
7817 gen_load_fpr32(fp0, fs);
7818 gen_helper_float_cvtw_s(fp0, cpu_env, fp0);
7819 gen_store_fpr32(fp0, fd);
7820 tcg_temp_free_i32(fp0);
7825 check_cp1_64bitmode(ctx);
7827 TCGv_i32 fp32 = tcg_temp_new_i32();
7828 TCGv_i64 fp64 = tcg_temp_new_i64();
7830 gen_load_fpr32(fp32, fs);
7831 gen_helper_float_cvtl_s(fp64, cpu_env, fp32);
7832 tcg_temp_free_i32(fp32);
7833 gen_store_fpr64(ctx, fp64, fd);
7834 tcg_temp_free_i64(fp64);
7839 check_cp1_64bitmode(ctx);
7841 TCGv_i64 fp64 = tcg_temp_new_i64();
7842 TCGv_i32 fp32_0 = tcg_temp_new_i32();
7843 TCGv_i32 fp32_1 = tcg_temp_new_i32();
7845 gen_load_fpr32(fp32_0, fs);
7846 gen_load_fpr32(fp32_1, ft);
7847 tcg_gen_concat_i32_i64(fp64, fp32_1, fp32_0);
7848 tcg_temp_free_i32(fp32_1);
7849 tcg_temp_free_i32(fp32_0);
7850 gen_store_fpr64(ctx, fp64, fd);
7851 tcg_temp_free_i64(fp64);
7864 case OPC_CMP_NGLE_S:
7871 if (ctx->opcode & (1 << 6)) {
7872 gen_cmpabs_s(ctx, func-48, ft, fs, cc);
7873 opn = condnames_abs[func-48];
7875 gen_cmp_s(ctx, func-48, ft, fs, cc);
7876 opn = condnames[func-48];
7880 check_cp1_registers(ctx, fs | ft | fd);
7882 TCGv_i64 fp0 = tcg_temp_new_i64();
7883 TCGv_i64 fp1 = tcg_temp_new_i64();
7885 gen_load_fpr64(ctx, fp0, fs);
7886 gen_load_fpr64(ctx, fp1, ft);
7887 gen_helper_float_add_d(fp0, cpu_env, fp0, fp1);
7888 tcg_temp_free_i64(fp1);
7889 gen_store_fpr64(ctx, fp0, fd);
7890 tcg_temp_free_i64(fp0);
7896 check_cp1_registers(ctx, fs | ft | fd);
7898 TCGv_i64 fp0 = tcg_temp_new_i64();
7899 TCGv_i64 fp1 = tcg_temp_new_i64();
7901 gen_load_fpr64(ctx, fp0, fs);
7902 gen_load_fpr64(ctx, fp1, ft);
7903 gen_helper_float_sub_d(fp0, cpu_env, fp0, fp1);
7904 tcg_temp_free_i64(fp1);
7905 gen_store_fpr64(ctx, fp0, fd);
7906 tcg_temp_free_i64(fp0);
7912 check_cp1_registers(ctx, fs | ft | fd);
7914 TCGv_i64 fp0 = tcg_temp_new_i64();
7915 TCGv_i64 fp1 = tcg_temp_new_i64();
7917 gen_load_fpr64(ctx, fp0, fs);
7918 gen_load_fpr64(ctx, fp1, ft);
7919 gen_helper_float_mul_d(fp0, cpu_env, fp0, fp1);
7920 tcg_temp_free_i64(fp1);
7921 gen_store_fpr64(ctx, fp0, fd);
7922 tcg_temp_free_i64(fp0);
7928 check_cp1_registers(ctx, fs | ft | fd);
7930 TCGv_i64 fp0 = tcg_temp_new_i64();
7931 TCGv_i64 fp1 = tcg_temp_new_i64();
7933 gen_load_fpr64(ctx, fp0, fs);
7934 gen_load_fpr64(ctx, fp1, ft);
7935 gen_helper_float_div_d(fp0, cpu_env, fp0, fp1);
7936 tcg_temp_free_i64(fp1);
7937 gen_store_fpr64(ctx, fp0, fd);
7938 tcg_temp_free_i64(fp0);
7944 check_cp1_registers(ctx, fs | fd);
7946 TCGv_i64 fp0 = tcg_temp_new_i64();
7948 gen_load_fpr64(ctx, fp0, fs);
7949 gen_helper_float_sqrt_d(fp0, cpu_env, fp0);
7950 gen_store_fpr64(ctx, fp0, fd);
7951 tcg_temp_free_i64(fp0);
7956 check_cp1_registers(ctx, fs | fd);
7958 TCGv_i64 fp0 = tcg_temp_new_i64();
7960 gen_load_fpr64(ctx, fp0, fs);
7961 gen_helper_float_abs_d(fp0, fp0);
7962 gen_store_fpr64(ctx, fp0, fd);
7963 tcg_temp_free_i64(fp0);
7968 check_cp1_registers(ctx, fs | fd);
7970 TCGv_i64 fp0 = tcg_temp_new_i64();
7972 gen_load_fpr64(ctx, fp0, fs);
7973 gen_store_fpr64(ctx, fp0, fd);
7974 tcg_temp_free_i64(fp0);
7979 check_cp1_registers(ctx, fs | fd);
7981 TCGv_i64 fp0 = tcg_temp_new_i64();
7983 gen_load_fpr64(ctx, fp0, fs);
7984 gen_helper_float_chs_d(fp0, fp0);
7985 gen_store_fpr64(ctx, fp0, fd);
7986 tcg_temp_free_i64(fp0);
7991 check_cp1_64bitmode(ctx);
7993 TCGv_i64 fp0 = tcg_temp_new_i64();
7995 gen_load_fpr64(ctx, fp0, fs);
7996 gen_helper_float_roundl_d(fp0, cpu_env, fp0);
7997 gen_store_fpr64(ctx, fp0, fd);
7998 tcg_temp_free_i64(fp0);
8003 check_cp1_64bitmode(ctx);
8005 TCGv_i64 fp0 = tcg_temp_new_i64();
8007 gen_load_fpr64(ctx, fp0, fs);
8008 gen_helper_float_truncl_d(fp0, cpu_env, fp0);
8009 gen_store_fpr64(ctx, fp0, fd);
8010 tcg_temp_free_i64(fp0);
8015 check_cp1_64bitmode(ctx);
8017 TCGv_i64 fp0 = tcg_temp_new_i64();
8019 gen_load_fpr64(ctx, fp0, fs);
8020 gen_helper_float_ceill_d(fp0, cpu_env, fp0);
8021 gen_store_fpr64(ctx, fp0, fd);
8022 tcg_temp_free_i64(fp0);
8027 check_cp1_64bitmode(ctx);
8029 TCGv_i64 fp0 = tcg_temp_new_i64();
8031 gen_load_fpr64(ctx, fp0, fs);
8032 gen_helper_float_floorl_d(fp0, cpu_env, fp0);
8033 gen_store_fpr64(ctx, fp0, fd);
8034 tcg_temp_free_i64(fp0);
8039 check_cp1_registers(ctx, fs);
8041 TCGv_i32 fp32 = tcg_temp_new_i32();
8042 TCGv_i64 fp64 = tcg_temp_new_i64();
8044 gen_load_fpr64(ctx, fp64, fs);
8045 gen_helper_float_roundw_d(fp32, cpu_env, fp64);
8046 tcg_temp_free_i64(fp64);
8047 gen_store_fpr32(fp32, fd);
8048 tcg_temp_free_i32(fp32);
8053 check_cp1_registers(ctx, fs);
8055 TCGv_i32 fp32 = tcg_temp_new_i32();
8056 TCGv_i64 fp64 = tcg_temp_new_i64();
8058 gen_load_fpr64(ctx, fp64, fs);
8059 gen_helper_float_truncw_d(fp32, cpu_env, fp64);
8060 tcg_temp_free_i64(fp64);
8061 gen_store_fpr32(fp32, fd);
8062 tcg_temp_free_i32(fp32);
8067 check_cp1_registers(ctx, fs);
8069 TCGv_i32 fp32 = tcg_temp_new_i32();
8070 TCGv_i64 fp64 = tcg_temp_new_i64();
8072 gen_load_fpr64(ctx, fp64, fs);
8073 gen_helper_float_ceilw_d(fp32, cpu_env, fp64);
8074 tcg_temp_free_i64(fp64);
8075 gen_store_fpr32(fp32, fd);
8076 tcg_temp_free_i32(fp32);
8081 check_cp1_registers(ctx, fs);
8083 TCGv_i32 fp32 = tcg_temp_new_i32();
8084 TCGv_i64 fp64 = tcg_temp_new_i64();
8086 gen_load_fpr64(ctx, fp64, fs);
8087 gen_helper_float_floorw_d(fp32, cpu_env, fp64);
8088 tcg_temp_free_i64(fp64);
8089 gen_store_fpr32(fp32, fd);
8090 tcg_temp_free_i32(fp32);
8095 gen_movcf_d(ctx, fs, fd, (ft >> 2) & 0x7, ft & 0x1);
8100 int l1 = gen_new_label();
8104 tcg_gen_brcondi_tl(TCG_COND_NE, cpu_gpr[ft], 0, l1);
8106 fp0 = tcg_temp_new_i64();
8107 gen_load_fpr64(ctx, fp0, fs);
8108 gen_store_fpr64(ctx, fp0, fd);
8109 tcg_temp_free_i64(fp0);
8116 int l1 = gen_new_label();
8120 tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_gpr[ft], 0, l1);
8121 fp0 = tcg_temp_new_i64();
8122 gen_load_fpr64(ctx, fp0, fs);
8123 gen_store_fpr64(ctx, fp0, fd);
8124 tcg_temp_free_i64(fp0);
8131 check_cp1_64bitmode(ctx);
8133 TCGv_i64 fp0 = tcg_temp_new_i64();
8135 gen_load_fpr64(ctx, fp0, fs);
8136 gen_helper_float_recip_d(fp0, cpu_env, fp0);
8137 gen_store_fpr64(ctx, fp0, fd);
8138 tcg_temp_free_i64(fp0);
8143 check_cp1_64bitmode(ctx);
8145 TCGv_i64 fp0 = tcg_temp_new_i64();
8147 gen_load_fpr64(ctx, fp0, fs);
8148 gen_helper_float_rsqrt_d(fp0, cpu_env, fp0);
8149 gen_store_fpr64(ctx, fp0, fd);
8150 tcg_temp_free_i64(fp0);
8155 check_cp1_64bitmode(ctx);
8157 TCGv_i64 fp0 = tcg_temp_new_i64();
8158 TCGv_i64 fp1 = tcg_temp_new_i64();
8160 gen_load_fpr64(ctx, fp0, fs);
8161 gen_load_fpr64(ctx, fp1, ft);
8162 gen_helper_float_recip2_d(fp0, cpu_env, fp0, fp1);
8163 tcg_temp_free_i64(fp1);
8164 gen_store_fpr64(ctx, fp0, fd);
8165 tcg_temp_free_i64(fp0);
8170 check_cp1_64bitmode(ctx);
8172 TCGv_i64 fp0 = tcg_temp_new_i64();
8174 gen_load_fpr64(ctx, fp0, fs);
8175 gen_helper_float_recip1_d(fp0, cpu_env, fp0);
8176 gen_store_fpr64(ctx, fp0, fd);
8177 tcg_temp_free_i64(fp0);
8182 check_cp1_64bitmode(ctx);
8184 TCGv_i64 fp0 = tcg_temp_new_i64();
8186 gen_load_fpr64(ctx, fp0, fs);
8187 gen_helper_float_rsqrt1_d(fp0, cpu_env, fp0);
8188 gen_store_fpr64(ctx, fp0, fd);
8189 tcg_temp_free_i64(fp0);
8194 check_cp1_64bitmode(ctx);
8196 TCGv_i64 fp0 = tcg_temp_new_i64();
8197 TCGv_i64 fp1 = tcg_temp_new_i64();
8199 gen_load_fpr64(ctx, fp0, fs);
8200 gen_load_fpr64(ctx, fp1, ft);
8201 gen_helper_float_rsqrt2_d(fp0, cpu_env, fp0, fp1);
8202 tcg_temp_free_i64(fp1);
8203 gen_store_fpr64(ctx, fp0, fd);
8204 tcg_temp_free_i64(fp0);
8217 case OPC_CMP_NGLE_D:
8224 if (ctx->opcode & (1 << 6)) {
8225 gen_cmpabs_d(ctx, func-48, ft, fs, cc);
8226 opn = condnames_abs[func-48];
8228 gen_cmp_d(ctx, func-48, ft, fs, cc);
8229 opn = condnames[func-48];
8233 check_cp1_registers(ctx, fs);
8235 TCGv_i32 fp32 = tcg_temp_new_i32();
8236 TCGv_i64 fp64 = tcg_temp_new_i64();
8238 gen_load_fpr64(ctx, fp64, fs);
8239 gen_helper_float_cvts_d(fp32, cpu_env, fp64);
8240 tcg_temp_free_i64(fp64);
8241 gen_store_fpr32(fp32, fd);
8242 tcg_temp_free_i32(fp32);
8247 check_cp1_registers(ctx, fs);
8249 TCGv_i32 fp32 = tcg_temp_new_i32();
8250 TCGv_i64 fp64 = tcg_temp_new_i64();
8252 gen_load_fpr64(ctx, fp64, fs);
8253 gen_helper_float_cvtw_d(fp32, cpu_env, fp64);
8254 tcg_temp_free_i64(fp64);
8255 gen_store_fpr32(fp32, fd);
8256 tcg_temp_free_i32(fp32);
8261 check_cp1_64bitmode(ctx);
8263 TCGv_i64 fp0 = tcg_temp_new_i64();
8265 gen_load_fpr64(ctx, fp0, fs);
8266 gen_helper_float_cvtl_d(fp0, cpu_env, fp0);
8267 gen_store_fpr64(ctx, fp0, fd);
8268 tcg_temp_free_i64(fp0);
8274 TCGv_i32 fp0 = tcg_temp_new_i32();
8276 gen_load_fpr32(fp0, fs);
8277 gen_helper_float_cvts_w(fp0, cpu_env, fp0);
8278 gen_store_fpr32(fp0, fd);
8279 tcg_temp_free_i32(fp0);
8284 check_cp1_registers(ctx, fd);
8286 TCGv_i32 fp32 = tcg_temp_new_i32();
8287 TCGv_i64 fp64 = tcg_temp_new_i64();
8289 gen_load_fpr32(fp32, fs);
8290 gen_helper_float_cvtd_w(fp64, cpu_env, fp32);
8291 tcg_temp_free_i32(fp32);
8292 gen_store_fpr64(ctx, fp64, fd);
8293 tcg_temp_free_i64(fp64);
8298 check_cp1_64bitmode(ctx);
8300 TCGv_i32 fp32 = tcg_temp_new_i32();
8301 TCGv_i64 fp64 = tcg_temp_new_i64();
8303 gen_load_fpr64(ctx, fp64, fs);
8304 gen_helper_float_cvts_l(fp32, cpu_env, fp64);
8305 tcg_temp_free_i64(fp64);
8306 gen_store_fpr32(fp32, fd);
8307 tcg_temp_free_i32(fp32);
8312 check_cp1_64bitmode(ctx);
8314 TCGv_i64 fp0 = tcg_temp_new_i64();
8316 gen_load_fpr64(ctx, fp0, fs);
8317 gen_helper_float_cvtd_l(fp0, cpu_env, fp0);
8318 gen_store_fpr64(ctx, fp0, fd);
8319 tcg_temp_free_i64(fp0);
8324 check_cp1_64bitmode(ctx);
8326 TCGv_i64 fp0 = tcg_temp_new_i64();
8328 gen_load_fpr64(ctx, fp0, fs);
8329 gen_helper_float_cvtps_pw(fp0, cpu_env, fp0);
8330 gen_store_fpr64(ctx, fp0, fd);
8331 tcg_temp_free_i64(fp0);
8336 check_cp1_64bitmode(ctx);
8338 TCGv_i64 fp0 = tcg_temp_new_i64();
8339 TCGv_i64 fp1 = tcg_temp_new_i64();
8341 gen_load_fpr64(ctx, fp0, fs);
8342 gen_load_fpr64(ctx, fp1, ft);
8343 gen_helper_float_add_ps(fp0, cpu_env, fp0, fp1);
8344 tcg_temp_free_i64(fp1);
8345 gen_store_fpr64(ctx, fp0, fd);
8346 tcg_temp_free_i64(fp0);
8351 check_cp1_64bitmode(ctx);
8353 TCGv_i64 fp0 = tcg_temp_new_i64();
8354 TCGv_i64 fp1 = tcg_temp_new_i64();
8356 gen_load_fpr64(ctx, fp0, fs);
8357 gen_load_fpr64(ctx, fp1, ft);
8358 gen_helper_float_sub_ps(fp0, cpu_env, fp0, fp1);
8359 tcg_temp_free_i64(fp1);
8360 gen_store_fpr64(ctx, fp0, fd);
8361 tcg_temp_free_i64(fp0);
8366 check_cp1_64bitmode(ctx);
8368 TCGv_i64 fp0 = tcg_temp_new_i64();
8369 TCGv_i64 fp1 = tcg_temp_new_i64();
8371 gen_load_fpr64(ctx, fp0, fs);
8372 gen_load_fpr64(ctx, fp1, ft);
8373 gen_helper_float_mul_ps(fp0, cpu_env, fp0, fp1);
8374 tcg_temp_free_i64(fp1);
8375 gen_store_fpr64(ctx, fp0, fd);
8376 tcg_temp_free_i64(fp0);
8381 check_cp1_64bitmode(ctx);
8383 TCGv_i64 fp0 = tcg_temp_new_i64();
8385 gen_load_fpr64(ctx, fp0, fs);
8386 gen_helper_float_abs_ps(fp0, fp0);
8387 gen_store_fpr64(ctx, fp0, fd);
8388 tcg_temp_free_i64(fp0);
8393 check_cp1_64bitmode(ctx);
8395 TCGv_i64 fp0 = tcg_temp_new_i64();
8397 gen_load_fpr64(ctx, fp0, fs);
8398 gen_store_fpr64(ctx, fp0, fd);
8399 tcg_temp_free_i64(fp0);
8404 check_cp1_64bitmode(ctx);
8406 TCGv_i64 fp0 = tcg_temp_new_i64();
8408 gen_load_fpr64(ctx, fp0, fs);
8409 gen_helper_float_chs_ps(fp0, fp0);
8410 gen_store_fpr64(ctx, fp0, fd);
8411 tcg_temp_free_i64(fp0);
8416 check_cp1_64bitmode(ctx);
8417 gen_movcf_ps(fs, fd, (ft >> 2) & 0x7, ft & 0x1);
8421 check_cp1_64bitmode(ctx);
8423 int l1 = gen_new_label();
8427 tcg_gen_brcondi_tl(TCG_COND_NE, cpu_gpr[ft], 0, l1);
8428 fp0 = tcg_temp_new_i64();
8429 gen_load_fpr64(ctx, fp0, fs);
8430 gen_store_fpr64(ctx, fp0, fd);
8431 tcg_temp_free_i64(fp0);
8437 check_cp1_64bitmode(ctx);
8439 int l1 = gen_new_label();
8443 tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_gpr[ft], 0, l1);
8444 fp0 = tcg_temp_new_i64();
8445 gen_load_fpr64(ctx, fp0, fs);
8446 gen_store_fpr64(ctx, fp0, fd);
8447 tcg_temp_free_i64(fp0);
8454 check_cp1_64bitmode(ctx);
8456 TCGv_i64 fp0 = tcg_temp_new_i64();
8457 TCGv_i64 fp1 = tcg_temp_new_i64();
8459 gen_load_fpr64(ctx, fp0, ft);
8460 gen_load_fpr64(ctx, fp1, fs);
8461 gen_helper_float_addr_ps(fp0, cpu_env, fp0, fp1);
8462 tcg_temp_free_i64(fp1);
8463 gen_store_fpr64(ctx, fp0, fd);
8464 tcg_temp_free_i64(fp0);
8469 check_cp1_64bitmode(ctx);
8471 TCGv_i64 fp0 = tcg_temp_new_i64();
8472 TCGv_i64 fp1 = tcg_temp_new_i64();
8474 gen_load_fpr64(ctx, fp0, ft);
8475 gen_load_fpr64(ctx, fp1, fs);
8476 gen_helper_float_mulr_ps(fp0, cpu_env, fp0, fp1);
8477 tcg_temp_free_i64(fp1);
8478 gen_store_fpr64(ctx, fp0, fd);
8479 tcg_temp_free_i64(fp0);
8484 check_cp1_64bitmode(ctx);
8486 TCGv_i64 fp0 = tcg_temp_new_i64();
8487 TCGv_i64 fp1 = tcg_temp_new_i64();
8489 gen_load_fpr64(ctx, fp0, fs);
8490 gen_load_fpr64(ctx, fp1, ft);
8491 gen_helper_float_recip2_ps(fp0, cpu_env, fp0, fp1);
8492 tcg_temp_free_i64(fp1);
8493 gen_store_fpr64(ctx, fp0, fd);
8494 tcg_temp_free_i64(fp0);
8499 check_cp1_64bitmode(ctx);
8501 TCGv_i64 fp0 = tcg_temp_new_i64();
8503 gen_load_fpr64(ctx, fp0, fs);
8504 gen_helper_float_recip1_ps(fp0, cpu_env, fp0);
8505 gen_store_fpr64(ctx, fp0, fd);
8506 tcg_temp_free_i64(fp0);
8511 check_cp1_64bitmode(ctx);
8513 TCGv_i64 fp0 = tcg_temp_new_i64();
8515 gen_load_fpr64(ctx, fp0, fs);
8516 gen_helper_float_rsqrt1_ps(fp0, cpu_env, fp0);
8517 gen_store_fpr64(ctx, fp0, fd);
8518 tcg_temp_free_i64(fp0);
8523 check_cp1_64bitmode(ctx);
8525 TCGv_i64 fp0 = tcg_temp_new_i64();
8526 TCGv_i64 fp1 = tcg_temp_new_i64();
8528 gen_load_fpr64(ctx, fp0, fs);
8529 gen_load_fpr64(ctx, fp1, ft);
8530 gen_helper_float_rsqrt2_ps(fp0, cpu_env, fp0, fp1);
8531 tcg_temp_free_i64(fp1);
8532 gen_store_fpr64(ctx, fp0, fd);
8533 tcg_temp_free_i64(fp0);
8538 check_cp1_64bitmode(ctx);
8540 TCGv_i32 fp0 = tcg_temp_new_i32();
8542 gen_load_fpr32h(fp0, fs);
8543 gen_helper_float_cvts_pu(fp0, cpu_env, fp0);
8544 gen_store_fpr32(fp0, fd);
8545 tcg_temp_free_i32(fp0);
8550 check_cp1_64bitmode(ctx);
8552 TCGv_i64 fp0 = tcg_temp_new_i64();
8554 gen_load_fpr64(ctx, fp0, fs);
8555 gen_helper_float_cvtpw_ps(fp0, cpu_env, fp0);
8556 gen_store_fpr64(ctx, fp0, fd);
8557 tcg_temp_free_i64(fp0);
8562 check_cp1_64bitmode(ctx);
8564 TCGv_i32 fp0 = tcg_temp_new_i32();
8566 gen_load_fpr32(fp0, fs);
8567 gen_helper_float_cvts_pl(fp0, cpu_env, fp0);
8568 gen_store_fpr32(fp0, fd);
8569 tcg_temp_free_i32(fp0);
8574 check_cp1_64bitmode(ctx);
8576 TCGv_i32 fp0 = tcg_temp_new_i32();
8577 TCGv_i32 fp1 = tcg_temp_new_i32();
8579 gen_load_fpr32(fp0, fs);
8580 gen_load_fpr32(fp1, ft);
8581 gen_store_fpr32h(fp0, fd);
8582 gen_store_fpr32(fp1, fd);
8583 tcg_temp_free_i32(fp0);
8584 tcg_temp_free_i32(fp1);
8589 check_cp1_64bitmode(ctx);
8591 TCGv_i32 fp0 = tcg_temp_new_i32();
8592 TCGv_i32 fp1 = tcg_temp_new_i32();
8594 gen_load_fpr32(fp0, fs);
8595 gen_load_fpr32h(fp1, ft);
8596 gen_store_fpr32(fp1, fd);
8597 gen_store_fpr32h(fp0, fd);
8598 tcg_temp_free_i32(fp0);
8599 tcg_temp_free_i32(fp1);
8604 check_cp1_64bitmode(ctx);
8606 TCGv_i32 fp0 = tcg_temp_new_i32();
8607 TCGv_i32 fp1 = tcg_temp_new_i32();
8609 gen_load_fpr32h(fp0, fs);
8610 gen_load_fpr32(fp1, ft);
8611 gen_store_fpr32(fp1, fd);
8612 gen_store_fpr32h(fp0, fd);
8613 tcg_temp_free_i32(fp0);
8614 tcg_temp_free_i32(fp1);
8619 check_cp1_64bitmode(ctx);
8621 TCGv_i32 fp0 = tcg_temp_new_i32();
8622 TCGv_i32 fp1 = tcg_temp_new_i32();
8624 gen_load_fpr32h(fp0, fs);
8625 gen_load_fpr32h(fp1, ft);
8626 gen_store_fpr32(fp1, fd);
8627 gen_store_fpr32h(fp0, fd);
8628 tcg_temp_free_i32(fp0);
8629 tcg_temp_free_i32(fp1);
8636 case OPC_CMP_UEQ_PS:
8637 case OPC_CMP_OLT_PS:
8638 case OPC_CMP_ULT_PS:
8639 case OPC_CMP_OLE_PS:
8640 case OPC_CMP_ULE_PS:
8642 case OPC_CMP_NGLE_PS:
8643 case OPC_CMP_SEQ_PS:
8644 case OPC_CMP_NGL_PS:
8646 case OPC_CMP_NGE_PS:
8648 case OPC_CMP_NGT_PS:
8649 if (ctx->opcode & (1 << 6)) {
8650 gen_cmpabs_ps(ctx, func-48, ft, fs, cc);
8651 opn = condnames_abs[func-48];
8653 gen_cmp_ps(ctx, func-48, ft, fs, cc);
8654 opn = condnames[func-48];
8659 generate_exception (ctx, EXCP_RI);
8662 (void)opn; /* avoid a compiler warning */
8665 MIPS_DEBUG("%s %s, %s, %s", opn, fregnames[fd], fregnames[fs], fregnames[ft]);
8668 MIPS_DEBUG("%s %s,%s", opn, fregnames[fs], fregnames[ft]);
8671 MIPS_DEBUG("%s %s,%s", opn, fregnames[fd], fregnames[fs]);
8676 /* Coprocessor 3 (FPU) */
8677 static void gen_flt3_ldst (DisasContext *ctx, uint32_t opc,
8678 int fd, int fs, int base, int index)
8680 const char *opn = "extended float load/store";
8682 TCGv t0 = tcg_temp_new();
8685 gen_load_gpr(t0, index);
8686 } else if (index == 0) {
8687 gen_load_gpr(t0, base);
8689 gen_op_addr_add(ctx, t0, cpu_gpr[base], cpu_gpr[index]);
8691 /* Don't do NOP if destination is zero: we must perform the actual
8693 save_cpu_state(ctx, 0);
8698 TCGv_i32 fp0 = tcg_temp_new_i32();
8700 tcg_gen_qemu_ld32s(t0, t0, ctx->mem_idx);
8701 tcg_gen_trunc_tl_i32(fp0, t0);
8702 gen_store_fpr32(fp0, fd);
8703 tcg_temp_free_i32(fp0);
8709 check_cp1_registers(ctx, fd);
8711 TCGv_i64 fp0 = tcg_temp_new_i64();
8713 tcg_gen_qemu_ld64(fp0, t0, ctx->mem_idx);
8714 gen_store_fpr64(ctx, fp0, fd);
8715 tcg_temp_free_i64(fp0);
8720 check_cp1_64bitmode(ctx);
8721 tcg_gen_andi_tl(t0, t0, ~0x7);
8723 TCGv_i64 fp0 = tcg_temp_new_i64();
8725 tcg_gen_qemu_ld64(fp0, t0, ctx->mem_idx);
8726 gen_store_fpr64(ctx, fp0, fd);
8727 tcg_temp_free_i64(fp0);
8734 TCGv_i32 fp0 = tcg_temp_new_i32();
8735 TCGv t1 = tcg_temp_new();
8737 gen_load_fpr32(fp0, fs);
8738 tcg_gen_extu_i32_tl(t1, fp0);
8739 tcg_gen_qemu_st32(t1, t0, ctx->mem_idx);
8740 tcg_temp_free_i32(fp0);
8748 check_cp1_registers(ctx, fs);
8750 TCGv_i64 fp0 = tcg_temp_new_i64();
8752 gen_load_fpr64(ctx, fp0, fs);
8753 tcg_gen_qemu_st64(fp0, t0, ctx->mem_idx);
8754 tcg_temp_free_i64(fp0);
8760 check_cp1_64bitmode(ctx);
8761 tcg_gen_andi_tl(t0, t0, ~0x7);
8763 TCGv_i64 fp0 = tcg_temp_new_i64();
8765 gen_load_fpr64(ctx, fp0, fs);
8766 tcg_gen_qemu_st64(fp0, t0, ctx->mem_idx);
8767 tcg_temp_free_i64(fp0);
8774 (void)opn; (void)store; /* avoid compiler warnings */
8775 MIPS_DEBUG("%s %s, %s(%s)", opn, fregnames[store ? fs : fd],
8776 regnames[index], regnames[base]);
8779 static void gen_flt3_arith (DisasContext *ctx, uint32_t opc,
8780 int fd, int fr, int fs, int ft)
8782 const char *opn = "flt3_arith";
8786 check_cp1_64bitmode(ctx);
8788 TCGv t0 = tcg_temp_local_new();
8789 TCGv_i32 fp = tcg_temp_new_i32();
8790 TCGv_i32 fph = tcg_temp_new_i32();
8791 int l1 = gen_new_label();
8792 int l2 = gen_new_label();
8794 gen_load_gpr(t0, fr);
8795 tcg_gen_andi_tl(t0, t0, 0x7);
8797 tcg_gen_brcondi_tl(TCG_COND_NE, t0, 0, l1);
8798 gen_load_fpr32(fp, fs);
8799 gen_load_fpr32h(fph, fs);
8800 gen_store_fpr32(fp, fd);
8801 gen_store_fpr32h(fph, fd);
8804 tcg_gen_brcondi_tl(TCG_COND_NE, t0, 4, l2);
8806 #ifdef TARGET_WORDS_BIGENDIAN
8807 gen_load_fpr32(fp, fs);
8808 gen_load_fpr32h(fph, ft);
8809 gen_store_fpr32h(fp, fd);
8810 gen_store_fpr32(fph, fd);
8812 gen_load_fpr32h(fph, fs);
8813 gen_load_fpr32(fp, ft);
8814 gen_store_fpr32(fph, fd);
8815 gen_store_fpr32h(fp, fd);
8818 tcg_temp_free_i32(fp);
8819 tcg_temp_free_i32(fph);
8826 TCGv_i32 fp0 = tcg_temp_new_i32();
8827 TCGv_i32 fp1 = tcg_temp_new_i32();
8828 TCGv_i32 fp2 = tcg_temp_new_i32();
8830 gen_load_fpr32(fp0, fs);
8831 gen_load_fpr32(fp1, ft);
8832 gen_load_fpr32(fp2, fr);
8833 gen_helper_float_muladd_s(fp2, cpu_env, fp0, fp1, fp2);
8834 tcg_temp_free_i32(fp0);
8835 tcg_temp_free_i32(fp1);
8836 gen_store_fpr32(fp2, fd);
8837 tcg_temp_free_i32(fp2);
8843 check_cp1_registers(ctx, fd | fs | ft | fr);
8845 TCGv_i64 fp0 = tcg_temp_new_i64();
8846 TCGv_i64 fp1 = tcg_temp_new_i64();
8847 TCGv_i64 fp2 = tcg_temp_new_i64();
8849 gen_load_fpr64(ctx, fp0, fs);
8850 gen_load_fpr64(ctx, fp1, ft);
8851 gen_load_fpr64(ctx, fp2, fr);
8852 gen_helper_float_muladd_d(fp2, cpu_env, fp0, fp1, fp2);
8853 tcg_temp_free_i64(fp0);
8854 tcg_temp_free_i64(fp1);
8855 gen_store_fpr64(ctx, fp2, fd);
8856 tcg_temp_free_i64(fp2);
8861 check_cp1_64bitmode(ctx);
8863 TCGv_i64 fp0 = tcg_temp_new_i64();
8864 TCGv_i64 fp1 = tcg_temp_new_i64();
8865 TCGv_i64 fp2 = tcg_temp_new_i64();
8867 gen_load_fpr64(ctx, fp0, fs);
8868 gen_load_fpr64(ctx, fp1, ft);
8869 gen_load_fpr64(ctx, fp2, fr);
8870 gen_helper_float_muladd_ps(fp2, cpu_env, fp0, fp1, fp2);
8871 tcg_temp_free_i64(fp0);
8872 tcg_temp_free_i64(fp1);
8873 gen_store_fpr64(ctx, fp2, fd);
8874 tcg_temp_free_i64(fp2);
8881 TCGv_i32 fp0 = tcg_temp_new_i32();
8882 TCGv_i32 fp1 = tcg_temp_new_i32();
8883 TCGv_i32 fp2 = tcg_temp_new_i32();
8885 gen_load_fpr32(fp0, fs);
8886 gen_load_fpr32(fp1, ft);
8887 gen_load_fpr32(fp2, fr);
8888 gen_helper_float_mulsub_s(fp2, cpu_env, fp0, fp1, fp2);
8889 tcg_temp_free_i32(fp0);
8890 tcg_temp_free_i32(fp1);
8891 gen_store_fpr32(fp2, fd);
8892 tcg_temp_free_i32(fp2);
8898 check_cp1_registers(ctx, fd | fs | ft | fr);
8900 TCGv_i64 fp0 = tcg_temp_new_i64();
8901 TCGv_i64 fp1 = tcg_temp_new_i64();
8902 TCGv_i64 fp2 = tcg_temp_new_i64();
8904 gen_load_fpr64(ctx, fp0, fs);
8905 gen_load_fpr64(ctx, fp1, ft);
8906 gen_load_fpr64(ctx, fp2, fr);
8907 gen_helper_float_mulsub_d(fp2, cpu_env, fp0, fp1, fp2);
8908 tcg_temp_free_i64(fp0);
8909 tcg_temp_free_i64(fp1);
8910 gen_store_fpr64(ctx, fp2, fd);
8911 tcg_temp_free_i64(fp2);
8916 check_cp1_64bitmode(ctx);
8918 TCGv_i64 fp0 = tcg_temp_new_i64();
8919 TCGv_i64 fp1 = tcg_temp_new_i64();
8920 TCGv_i64 fp2 = tcg_temp_new_i64();
8922 gen_load_fpr64(ctx, fp0, fs);
8923 gen_load_fpr64(ctx, fp1, ft);
8924 gen_load_fpr64(ctx, fp2, fr);
8925 gen_helper_float_mulsub_ps(fp2, cpu_env, fp0, fp1, fp2);
8926 tcg_temp_free_i64(fp0);
8927 tcg_temp_free_i64(fp1);
8928 gen_store_fpr64(ctx, fp2, fd);
8929 tcg_temp_free_i64(fp2);
8936 TCGv_i32 fp0 = tcg_temp_new_i32();
8937 TCGv_i32 fp1 = tcg_temp_new_i32();
8938 TCGv_i32 fp2 = tcg_temp_new_i32();
8940 gen_load_fpr32(fp0, fs);
8941 gen_load_fpr32(fp1, ft);
8942 gen_load_fpr32(fp2, fr);
8943 gen_helper_float_nmuladd_s(fp2, cpu_env, fp0, fp1, fp2);
8944 tcg_temp_free_i32(fp0);
8945 tcg_temp_free_i32(fp1);
8946 gen_store_fpr32(fp2, fd);
8947 tcg_temp_free_i32(fp2);
8953 check_cp1_registers(ctx, fd | fs | ft | fr);
8955 TCGv_i64 fp0 = tcg_temp_new_i64();
8956 TCGv_i64 fp1 = tcg_temp_new_i64();
8957 TCGv_i64 fp2 = tcg_temp_new_i64();
8959 gen_load_fpr64(ctx, fp0, fs);
8960 gen_load_fpr64(ctx, fp1, ft);
8961 gen_load_fpr64(ctx, fp2, fr);
8962 gen_helper_float_nmuladd_d(fp2, cpu_env, fp0, fp1, fp2);
8963 tcg_temp_free_i64(fp0);
8964 tcg_temp_free_i64(fp1);
8965 gen_store_fpr64(ctx, fp2, fd);
8966 tcg_temp_free_i64(fp2);
8971 check_cp1_64bitmode(ctx);
8973 TCGv_i64 fp0 = tcg_temp_new_i64();
8974 TCGv_i64 fp1 = tcg_temp_new_i64();
8975 TCGv_i64 fp2 = tcg_temp_new_i64();
8977 gen_load_fpr64(ctx, fp0, fs);
8978 gen_load_fpr64(ctx, fp1, ft);
8979 gen_load_fpr64(ctx, fp2, fr);
8980 gen_helper_float_nmuladd_ps(fp2, cpu_env, fp0, fp1, fp2);
8981 tcg_temp_free_i64(fp0);
8982 tcg_temp_free_i64(fp1);
8983 gen_store_fpr64(ctx, fp2, fd);
8984 tcg_temp_free_i64(fp2);
8991 TCGv_i32 fp0 = tcg_temp_new_i32();
8992 TCGv_i32 fp1 = tcg_temp_new_i32();
8993 TCGv_i32 fp2 = tcg_temp_new_i32();
8995 gen_load_fpr32(fp0, fs);
8996 gen_load_fpr32(fp1, ft);
8997 gen_load_fpr32(fp2, fr);
8998 gen_helper_float_nmulsub_s(fp2, cpu_env, fp0, fp1, fp2);
8999 tcg_temp_free_i32(fp0);
9000 tcg_temp_free_i32(fp1);
9001 gen_store_fpr32(fp2, fd);
9002 tcg_temp_free_i32(fp2);
9008 check_cp1_registers(ctx, fd | fs | ft | fr);
9010 TCGv_i64 fp0 = tcg_temp_new_i64();
9011 TCGv_i64 fp1 = tcg_temp_new_i64();
9012 TCGv_i64 fp2 = tcg_temp_new_i64();
9014 gen_load_fpr64(ctx, fp0, fs);
9015 gen_load_fpr64(ctx, fp1, ft);
9016 gen_load_fpr64(ctx, fp2, fr);
9017 gen_helper_float_nmulsub_d(fp2, cpu_env, fp0, fp1, fp2);
9018 tcg_temp_free_i64(fp0);
9019 tcg_temp_free_i64(fp1);
9020 gen_store_fpr64(ctx, fp2, fd);
9021 tcg_temp_free_i64(fp2);
9026 check_cp1_64bitmode(ctx);
9028 TCGv_i64 fp0 = tcg_temp_new_i64();
9029 TCGv_i64 fp1 = tcg_temp_new_i64();
9030 TCGv_i64 fp2 = tcg_temp_new_i64();
9032 gen_load_fpr64(ctx, fp0, fs);
9033 gen_load_fpr64(ctx, fp1, ft);
9034 gen_load_fpr64(ctx, fp2, fr);
9035 gen_helper_float_nmulsub_ps(fp2, cpu_env, fp0, fp1, fp2);
9036 tcg_temp_free_i64(fp0);
9037 tcg_temp_free_i64(fp1);
9038 gen_store_fpr64(ctx, fp2, fd);
9039 tcg_temp_free_i64(fp2);
9045 generate_exception (ctx, EXCP_RI);
9048 (void)opn; /* avoid a compiler warning */
9049 MIPS_DEBUG("%s %s, %s, %s, %s", opn, fregnames[fd], fregnames[fr],
9050 fregnames[fs], fregnames[ft]);
9054 gen_rdhwr (CPUMIPSState *env, DisasContext *ctx, int rt, int rd)
9058 #if !defined(CONFIG_USER_ONLY)
9059 /* The Linux kernel will emulate rdhwr if it's not supported natively.
9060 Therefore only check the ISA in system mode. */
9061 check_insn(env, ctx, ISA_MIPS32R2);
9063 t0 = tcg_temp_new();
9067 save_cpu_state(ctx, 1);
9068 gen_helper_rdhwr_cpunum(t0, cpu_env);
9069 gen_store_gpr(t0, rt);
9072 save_cpu_state(ctx, 1);
9073 gen_helper_rdhwr_synci_step(t0, cpu_env);
9074 gen_store_gpr(t0, rt);
9077 save_cpu_state(ctx, 1);
9078 gen_helper_rdhwr_cc(t0, cpu_env);
9079 gen_store_gpr(t0, rt);
9082 save_cpu_state(ctx, 1);
9083 gen_helper_rdhwr_ccres(t0, cpu_env);
9084 gen_store_gpr(t0, rt);
9087 #if defined(CONFIG_USER_ONLY)
9088 tcg_gen_ld_tl(t0, cpu_env, offsetof(CPUMIPSState, tls_value));
9089 gen_store_gpr(t0, rt);
9092 /* XXX: Some CPUs implement this in hardware.
9093 Not supported yet. */
9095 default: /* Invalid */
9096 MIPS_INVAL("rdhwr");
9097 generate_exception(ctx, EXCP_RI);
9103 static void handle_delay_slot (CPUMIPSState *env, DisasContext *ctx,
9106 if (ctx->hflags & MIPS_HFLAG_BMASK) {
9107 int proc_hflags = ctx->hflags & MIPS_HFLAG_BMASK;
9108 /* Branches completion */
9109 ctx->hflags &= ~MIPS_HFLAG_BMASK;
9110 ctx->bstate = BS_BRANCH;
9111 save_cpu_state(ctx, 0);
9112 /* FIXME: Need to clear can_do_io. */
9113 switch (proc_hflags & MIPS_HFLAG_BMASK_BASE) {
9115 /* unconditional branch */
9116 MIPS_DEBUG("unconditional branch");
9117 if (proc_hflags & MIPS_HFLAG_BX) {
9118 tcg_gen_xori_i32(hflags, hflags, MIPS_HFLAG_M16);
9120 gen_goto_tb(ctx, 0, ctx->btarget);
9123 /* blikely taken case */
9124 MIPS_DEBUG("blikely branch taken");
9125 gen_goto_tb(ctx, 0, ctx->btarget);
9128 /* Conditional branch */
9129 MIPS_DEBUG("conditional branch");
9131 int l1 = gen_new_label();
9133 tcg_gen_brcondi_tl(TCG_COND_NE, bcond, 0, l1);
9134 gen_goto_tb(ctx, 1, ctx->pc + insn_bytes);
9136 gen_goto_tb(ctx, 0, ctx->btarget);
9140 /* unconditional branch to register */
9141 MIPS_DEBUG("branch to register");
9142 if (env->insn_flags & (ASE_MIPS16 | ASE_MICROMIPS)) {
9143 TCGv t0 = tcg_temp_new();
9144 TCGv_i32 t1 = tcg_temp_new_i32();
9146 tcg_gen_andi_tl(t0, btarget, 0x1);
9147 tcg_gen_trunc_tl_i32(t1, t0);
9149 tcg_gen_andi_i32(hflags, hflags, ~(uint32_t)MIPS_HFLAG_M16);
9150 tcg_gen_shli_i32(t1, t1, MIPS_HFLAG_M16_SHIFT);
9151 tcg_gen_or_i32(hflags, hflags, t1);
9152 tcg_temp_free_i32(t1);
9154 tcg_gen_andi_tl(cpu_PC, btarget, ~(target_ulong)0x1);
9156 tcg_gen_mov_tl(cpu_PC, btarget);
9158 if (ctx->singlestep_enabled) {
9159 save_cpu_state(ctx, 0);
9160 gen_helper_0e0i(raise_exception, EXCP_DEBUG);
9165 MIPS_DEBUG("unknown branch");
9171 /* ISA extensions (ASEs) */
9172 /* MIPS16 extension to MIPS32 */
9174 /* MIPS16 major opcodes */
9176 M16_OPC_ADDIUSP = 0x00,
9177 M16_OPC_ADDIUPC = 0x01,
9180 M16_OPC_BEQZ = 0x04,
9181 M16_OPC_BNEQZ = 0x05,
9182 M16_OPC_SHIFT = 0x06,
9184 M16_OPC_RRIA = 0x08,
9185 M16_OPC_ADDIU8 = 0x09,
9186 M16_OPC_SLTI = 0x0a,
9187 M16_OPC_SLTIU = 0x0b,
9190 M16_OPC_CMPI = 0x0e,
9194 M16_OPC_LWSP = 0x12,
9198 M16_OPC_LWPC = 0x16,
9202 M16_OPC_SWSP = 0x1a,
9206 M16_OPC_EXTEND = 0x1e,
9210 /* I8 funct field */
9229 /* RR funct field */
9263 /* I64 funct field */
9275 /* RR ry field for CNVT */
9277 RR_RY_CNVT_ZEB = 0x0,
9278 RR_RY_CNVT_ZEH = 0x1,
9279 RR_RY_CNVT_ZEW = 0x2,
9280 RR_RY_CNVT_SEB = 0x4,
9281 RR_RY_CNVT_SEH = 0x5,
9282 RR_RY_CNVT_SEW = 0x6,
9285 static int xlat (int r)
9287 static int map[] = { 16, 17, 2, 3, 4, 5, 6, 7 };
9292 static void gen_mips16_save (DisasContext *ctx,
9293 int xsregs, int aregs,
9294 int do_ra, int do_s0, int do_s1,
9297 TCGv t0 = tcg_temp_new();
9298 TCGv t1 = tcg_temp_new();
9328 generate_exception(ctx, EXCP_RI);
9334 gen_base_offset_addr(ctx, t0, 29, 12);
9335 gen_load_gpr(t1, 7);
9336 op_st_sw(t1, t0, ctx);
9339 gen_base_offset_addr(ctx, t0, 29, 8);
9340 gen_load_gpr(t1, 6);
9341 op_st_sw(t1, t0, ctx);
9344 gen_base_offset_addr(ctx, t0, 29, 4);
9345 gen_load_gpr(t1, 5);
9346 op_st_sw(t1, t0, ctx);
9349 gen_base_offset_addr(ctx, t0, 29, 0);
9350 gen_load_gpr(t1, 4);
9351 op_st_sw(t1, t0, ctx);
9354 gen_load_gpr(t0, 29);
9356 #define DECR_AND_STORE(reg) do { \
9357 tcg_gen_subi_tl(t0, t0, 4); \
9358 gen_load_gpr(t1, reg); \
9359 op_st_sw(t1, t0, ctx); \
9423 generate_exception(ctx, EXCP_RI);
9439 #undef DECR_AND_STORE
9441 tcg_gen_subi_tl(cpu_gpr[29], cpu_gpr[29], framesize);
9446 static void gen_mips16_restore (DisasContext *ctx,
9447 int xsregs, int aregs,
9448 int do_ra, int do_s0, int do_s1,
9452 TCGv t0 = tcg_temp_new();
9453 TCGv t1 = tcg_temp_new();
9455 tcg_gen_addi_tl(t0, cpu_gpr[29], framesize);
9457 #define DECR_AND_LOAD(reg) do { \
9458 tcg_gen_subi_tl(t0, t0, 4); \
9459 op_ld_lw(t1, t0, ctx); \
9460 gen_store_gpr(t1, reg); \
9524 generate_exception(ctx, EXCP_RI);
9540 #undef DECR_AND_LOAD
9542 tcg_gen_addi_tl(cpu_gpr[29], cpu_gpr[29], framesize);
9547 static void gen_addiupc (DisasContext *ctx, int rx, int imm,
9548 int is_64_bit, int extended)
9552 if (extended && (ctx->hflags & MIPS_HFLAG_BMASK)) {
9553 generate_exception(ctx, EXCP_RI);
9557 t0 = tcg_temp_new();
9559 tcg_gen_movi_tl(t0, pc_relative_pc(ctx));
9560 tcg_gen_addi_tl(cpu_gpr[rx], t0, imm);
9562 tcg_gen_ext32s_tl(cpu_gpr[rx], cpu_gpr[rx]);
9568 #if defined(TARGET_MIPS64)
9569 static void decode_i64_mips16 (CPUMIPSState *env, DisasContext *ctx,
9570 int ry, int funct, int16_t offset,
9576 offset = extended ? offset : offset << 3;
9577 gen_ld(env, ctx, OPC_LD, ry, 29, offset);
9581 offset = extended ? offset : offset << 3;
9582 gen_st(ctx, OPC_SD, ry, 29, offset);
9586 offset = extended ? offset : (ctx->opcode & 0xff) << 3;
9587 gen_st(ctx, OPC_SD, 31, 29, offset);
9591 offset = extended ? offset : ((int8_t)ctx->opcode) << 3;
9592 gen_arith_imm(env, ctx, OPC_DADDIU, 29, 29, offset);
9595 if (extended && (ctx->hflags & MIPS_HFLAG_BMASK)) {
9596 generate_exception(ctx, EXCP_RI);
9598 offset = extended ? offset : offset << 3;
9599 gen_ld(env, ctx, OPC_LDPC, ry, 0, offset);
9604 offset = extended ? offset : ((int8_t)(offset << 3)) >> 3;
9605 gen_arith_imm(env, ctx, OPC_DADDIU, ry, ry, offset);
9609 offset = extended ? offset : offset << 2;
9610 gen_addiupc(ctx, ry, offset, 1, extended);
9614 offset = extended ? offset : offset << 2;
9615 gen_arith_imm(env, ctx, OPC_DADDIU, ry, 29, offset);
9621 static int decode_extended_mips16_opc (CPUMIPSState *env, DisasContext *ctx,
9624 int extend = cpu_lduw_code(env, ctx->pc + 2);
9625 int op, rx, ry, funct, sa;
9626 int16_t imm, offset;
9628 ctx->opcode = (ctx->opcode << 16) | extend;
9629 op = (ctx->opcode >> 11) & 0x1f;
9630 sa = (ctx->opcode >> 22) & 0x1f;
9631 funct = (ctx->opcode >> 8) & 0x7;
9632 rx = xlat((ctx->opcode >> 8) & 0x7);
9633 ry = xlat((ctx->opcode >> 5) & 0x7);
9634 offset = imm = (int16_t) (((ctx->opcode >> 16) & 0x1f) << 11
9635 | ((ctx->opcode >> 21) & 0x3f) << 5
9636 | (ctx->opcode & 0x1f));
9638 /* The extended opcodes cleverly reuse the opcodes from their 16-bit
9641 case M16_OPC_ADDIUSP:
9642 gen_arith_imm(env, ctx, OPC_ADDIU, rx, 29, imm);
9644 case M16_OPC_ADDIUPC:
9645 gen_addiupc(ctx, rx, imm, 0, 1);
9648 gen_compute_branch(ctx, OPC_BEQ, 4, 0, 0, offset << 1);
9649 /* No delay slot, so just process as a normal instruction */
9652 gen_compute_branch(ctx, OPC_BEQ, 4, rx, 0, offset << 1);
9653 /* No delay slot, so just process as a normal instruction */
9656 gen_compute_branch(ctx, OPC_BNE, 4, rx, 0, offset << 1);
9657 /* No delay slot, so just process as a normal instruction */
9660 switch (ctx->opcode & 0x3) {
9662 gen_shift_imm(env, ctx, OPC_SLL, rx, ry, sa);
9665 #if defined(TARGET_MIPS64)
9667 gen_shift_imm(env, ctx, OPC_DSLL, rx, ry, sa);
9669 generate_exception(ctx, EXCP_RI);
9673 gen_shift_imm(env, ctx, OPC_SRL, rx, ry, sa);
9676 gen_shift_imm(env, ctx, OPC_SRA, rx, ry, sa);
9680 #if defined(TARGET_MIPS64)
9683 gen_ld(env, ctx, OPC_LD, ry, rx, offset);
9687 imm = ctx->opcode & 0xf;
9688 imm = imm | ((ctx->opcode >> 20) & 0x7f) << 4;
9689 imm = imm | ((ctx->opcode >> 16) & 0xf) << 11;
9690 imm = (int16_t) (imm << 1) >> 1;
9691 if ((ctx->opcode >> 4) & 0x1) {
9692 #if defined(TARGET_MIPS64)
9694 gen_arith_imm(env, ctx, OPC_DADDIU, ry, rx, imm);
9696 generate_exception(ctx, EXCP_RI);
9699 gen_arith_imm(env, ctx, OPC_ADDIU, ry, rx, imm);
9702 case M16_OPC_ADDIU8:
9703 gen_arith_imm(env, ctx, OPC_ADDIU, rx, rx, imm);
9706 gen_slt_imm(env, ctx, OPC_SLTI, 24, rx, imm);
9709 gen_slt_imm(env, ctx, OPC_SLTIU, 24, rx, imm);
9714 gen_compute_branch(ctx, OPC_BEQ, 4, 24, 0, offset << 1);
9717 gen_compute_branch(ctx, OPC_BNE, 4, 24, 0, offset << 1);
9720 gen_st(ctx, OPC_SW, 31, 29, imm);
9723 gen_arith_imm(env, ctx, OPC_ADDIU, 29, 29, imm);
9727 int xsregs = (ctx->opcode >> 24) & 0x7;
9728 int aregs = (ctx->opcode >> 16) & 0xf;
9729 int do_ra = (ctx->opcode >> 6) & 0x1;
9730 int do_s0 = (ctx->opcode >> 5) & 0x1;
9731 int do_s1 = (ctx->opcode >> 4) & 0x1;
9732 int framesize = (((ctx->opcode >> 20) & 0xf) << 4
9733 | (ctx->opcode & 0xf)) << 3;
9735 if (ctx->opcode & (1 << 7)) {
9736 gen_mips16_save(ctx, xsregs, aregs,
9737 do_ra, do_s0, do_s1,
9740 gen_mips16_restore(ctx, xsregs, aregs,
9741 do_ra, do_s0, do_s1,
9747 generate_exception(ctx, EXCP_RI);
9752 tcg_gen_movi_tl(cpu_gpr[rx], (uint16_t) imm);
9755 tcg_gen_xori_tl(cpu_gpr[24], cpu_gpr[rx], (uint16_t) imm);
9757 #if defined(TARGET_MIPS64)
9759 gen_st(ctx, OPC_SD, ry, rx, offset);
9763 gen_ld(env, ctx, OPC_LB, ry, rx, offset);
9766 gen_ld(env, ctx, OPC_LH, ry, rx, offset);
9769 gen_ld(env, ctx, OPC_LW, rx, 29, offset);
9772 gen_ld(env, ctx, OPC_LW, ry, rx, offset);
9775 gen_ld(env, ctx, OPC_LBU, ry, rx, offset);
9778 gen_ld(env, ctx, OPC_LHU, ry, rx, offset);
9781 gen_ld(env, ctx, OPC_LWPC, rx, 0, offset);
9783 #if defined(TARGET_MIPS64)
9785 gen_ld(env, ctx, OPC_LWU, ry, rx, offset);
9789 gen_st(ctx, OPC_SB, ry, rx, offset);
9792 gen_st(ctx, OPC_SH, ry, rx, offset);
9795 gen_st(ctx, OPC_SW, rx, 29, offset);
9798 gen_st(ctx, OPC_SW, ry, rx, offset);
9800 #if defined(TARGET_MIPS64)
9802 decode_i64_mips16(env, ctx, ry, funct, offset, 1);
9806 generate_exception(ctx, EXCP_RI);
9813 static int decode_mips16_opc (CPUMIPSState *env, DisasContext *ctx,
9818 int op, cnvt_op, op1, offset;
9822 op = (ctx->opcode >> 11) & 0x1f;
9823 sa = (ctx->opcode >> 2) & 0x7;
9824 sa = sa == 0 ? 8 : sa;
9825 rx = xlat((ctx->opcode >> 8) & 0x7);
9826 cnvt_op = (ctx->opcode >> 5) & 0x7;
9827 ry = xlat((ctx->opcode >> 5) & 0x7);
9828 op1 = offset = ctx->opcode & 0x1f;
9833 case M16_OPC_ADDIUSP:
9835 int16_t imm = ((uint8_t) ctx->opcode) << 2;
9837 gen_arith_imm(env, ctx, OPC_ADDIU, rx, 29, imm);
9840 case M16_OPC_ADDIUPC:
9841 gen_addiupc(ctx, rx, ((uint8_t) ctx->opcode) << 2, 0, 0);
9844 offset = (ctx->opcode & 0x7ff) << 1;
9845 offset = (int16_t)(offset << 4) >> 4;
9846 gen_compute_branch(ctx, OPC_BEQ, 2, 0, 0, offset);
9847 /* No delay slot, so just process as a normal instruction */
9850 offset = cpu_lduw_code(env, ctx->pc + 2);
9851 offset = (((ctx->opcode & 0x1f) << 21)
9852 | ((ctx->opcode >> 5) & 0x1f) << 16
9854 op = ((ctx->opcode >> 10) & 0x1) ? OPC_JALXS : OPC_JALS;
9855 gen_compute_branch(ctx, op, 4, rx, ry, offset);
9860 gen_compute_branch(ctx, OPC_BEQ, 2, rx, 0, ((int8_t)ctx->opcode) << 1);
9861 /* No delay slot, so just process as a normal instruction */
9864 gen_compute_branch(ctx, OPC_BNE, 2, rx, 0, ((int8_t)ctx->opcode) << 1);
9865 /* No delay slot, so just process as a normal instruction */
9868 switch (ctx->opcode & 0x3) {
9870 gen_shift_imm(env, ctx, OPC_SLL, rx, ry, sa);
9873 #if defined(TARGET_MIPS64)
9875 gen_shift_imm(env, ctx, OPC_DSLL, rx, ry, sa);
9877 generate_exception(ctx, EXCP_RI);
9881 gen_shift_imm(env, ctx, OPC_SRL, rx, ry, sa);
9884 gen_shift_imm(env, ctx, OPC_SRA, rx, ry, sa);
9888 #if defined(TARGET_MIPS64)
9891 gen_ld(env, ctx, OPC_LD, ry, rx, offset << 3);
9896 int16_t imm = (int8_t)((ctx->opcode & 0xf) << 4) >> 4;
9898 if ((ctx->opcode >> 4) & 1) {
9899 #if defined(TARGET_MIPS64)
9901 gen_arith_imm(env, ctx, OPC_DADDIU, ry, rx, imm);
9903 generate_exception(ctx, EXCP_RI);
9906 gen_arith_imm(env, ctx, OPC_ADDIU, ry, rx, imm);
9910 case M16_OPC_ADDIU8:
9912 int16_t imm = (int8_t) ctx->opcode;
9914 gen_arith_imm(env, ctx, OPC_ADDIU, rx, rx, imm);
9919 int16_t imm = (uint8_t) ctx->opcode;
9920 gen_slt_imm(env, ctx, OPC_SLTI, 24, rx, imm);
9925 int16_t imm = (uint8_t) ctx->opcode;
9926 gen_slt_imm(env, ctx, OPC_SLTIU, 24, rx, imm);
9933 funct = (ctx->opcode >> 8) & 0x7;
9936 gen_compute_branch(ctx, OPC_BEQ, 2, 24, 0,
9937 ((int8_t)ctx->opcode) << 1);
9940 gen_compute_branch(ctx, OPC_BNE, 2, 24, 0,
9941 ((int8_t)ctx->opcode) << 1);
9944 gen_st(ctx, OPC_SW, 31, 29, (ctx->opcode & 0xff) << 2);
9947 gen_arith_imm(env, ctx, OPC_ADDIU, 29, 29,
9948 ((int8_t)ctx->opcode) << 3);
9952 int do_ra = ctx->opcode & (1 << 6);
9953 int do_s0 = ctx->opcode & (1 << 5);
9954 int do_s1 = ctx->opcode & (1 << 4);
9955 int framesize = ctx->opcode & 0xf;
9957 if (framesize == 0) {
9960 framesize = framesize << 3;
9963 if (ctx->opcode & (1 << 7)) {
9964 gen_mips16_save(ctx, 0, 0,
9965 do_ra, do_s0, do_s1, framesize);
9967 gen_mips16_restore(ctx, 0, 0,
9968 do_ra, do_s0, do_s1, framesize);
9974 int rz = xlat(ctx->opcode & 0x7);
9976 reg32 = (((ctx->opcode >> 3) & 0x3) << 3) |
9977 ((ctx->opcode >> 5) & 0x7);
9978 gen_arith(env, ctx, OPC_ADDU, reg32, rz, 0);
9982 reg32 = ctx->opcode & 0x1f;
9983 gen_arith(env, ctx, OPC_ADDU, ry, reg32, 0);
9986 generate_exception(ctx, EXCP_RI);
9993 int16_t imm = (uint8_t) ctx->opcode;
9995 gen_arith_imm(env, ctx, OPC_ADDIU, rx, 0, imm);
10000 int16_t imm = (uint8_t) ctx->opcode;
10001 gen_logic_imm(env, ctx, OPC_XORI, 24, rx, imm);
10004 #if defined(TARGET_MIPS64)
10006 check_mips_64(ctx);
10007 gen_st(ctx, OPC_SD, ry, rx, offset << 3);
10011 gen_ld(env, ctx, OPC_LB, ry, rx, offset);
10014 gen_ld(env, ctx, OPC_LH, ry, rx, offset << 1);
10017 gen_ld(env, ctx, OPC_LW, rx, 29, ((uint8_t)ctx->opcode) << 2);
10020 gen_ld(env, ctx, OPC_LW, ry, rx, offset << 2);
10023 gen_ld(env, ctx, OPC_LBU, ry, rx, offset);
10026 gen_ld(env, ctx, OPC_LHU, ry, rx, offset << 1);
10029 gen_ld(env, ctx, OPC_LWPC, rx, 0, ((uint8_t)ctx->opcode) << 2);
10031 #if defined (TARGET_MIPS64)
10033 check_mips_64(ctx);
10034 gen_ld(env, ctx, OPC_LWU, ry, rx, offset << 2);
10038 gen_st(ctx, OPC_SB, ry, rx, offset);
10041 gen_st(ctx, OPC_SH, ry, rx, offset << 1);
10044 gen_st(ctx, OPC_SW, rx, 29, ((uint8_t)ctx->opcode) << 2);
10047 gen_st(ctx, OPC_SW, ry, rx, offset << 2);
10051 int rz = xlat((ctx->opcode >> 2) & 0x7);
10054 switch (ctx->opcode & 0x3) {
10056 mips32_op = OPC_ADDU;
10059 mips32_op = OPC_SUBU;
10061 #if defined(TARGET_MIPS64)
10063 mips32_op = OPC_DADDU;
10064 check_mips_64(ctx);
10067 mips32_op = OPC_DSUBU;
10068 check_mips_64(ctx);
10072 generate_exception(ctx, EXCP_RI);
10076 gen_arith(env, ctx, mips32_op, rz, rx, ry);
10085 int nd = (ctx->opcode >> 7) & 0x1;
10086 int link = (ctx->opcode >> 6) & 0x1;
10087 int ra = (ctx->opcode >> 5) & 0x1;
10090 op = nd ? OPC_JALRC : OPC_JALRS;
10095 gen_compute_branch(ctx, op, 2, ra ? 31 : rx, 31, 0);
10102 /* XXX: not clear which exception should be raised
10103 * when in debug mode...
10105 check_insn(env, ctx, ISA_MIPS32);
10106 if (!(ctx->hflags & MIPS_HFLAG_DM)) {
10107 generate_exception(ctx, EXCP_DBp);
10109 generate_exception(ctx, EXCP_DBp);
10113 gen_slt(env, ctx, OPC_SLT, 24, rx, ry);
10116 gen_slt(env, ctx, OPC_SLTU, 24, rx, ry);
10119 generate_exception(ctx, EXCP_BREAK);
10122 gen_shift(env, ctx, OPC_SLLV, ry, rx, ry);
10125 gen_shift(env, ctx, OPC_SRLV, ry, rx, ry);
10128 gen_shift(env, ctx, OPC_SRAV, ry, rx, ry);
10130 #if defined (TARGET_MIPS64)
10132 check_mips_64(ctx);
10133 gen_shift_imm(env, ctx, OPC_DSRL, ry, ry, sa);
10137 gen_logic(env, ctx, OPC_XOR, 24, rx, ry);
10140 gen_arith(env, ctx, OPC_SUBU, rx, 0, ry);
10143 gen_logic(env, ctx, OPC_AND, rx, rx, ry);
10146 gen_logic(env, ctx, OPC_OR, rx, rx, ry);
10149 gen_logic(env, ctx, OPC_XOR, rx, rx, ry);
10152 gen_logic(env, ctx, OPC_NOR, rx, ry, 0);
10155 gen_HILO(ctx, OPC_MFHI, rx);
10159 case RR_RY_CNVT_ZEB:
10160 tcg_gen_ext8u_tl(cpu_gpr[rx], cpu_gpr[rx]);
10162 case RR_RY_CNVT_ZEH:
10163 tcg_gen_ext16u_tl(cpu_gpr[rx], cpu_gpr[rx]);
10165 case RR_RY_CNVT_SEB:
10166 tcg_gen_ext8s_tl(cpu_gpr[rx], cpu_gpr[rx]);
10168 case RR_RY_CNVT_SEH:
10169 tcg_gen_ext16s_tl(cpu_gpr[rx], cpu_gpr[rx]);
10171 #if defined (TARGET_MIPS64)
10172 case RR_RY_CNVT_ZEW:
10173 check_mips_64(ctx);
10174 tcg_gen_ext32u_tl(cpu_gpr[rx], cpu_gpr[rx]);
10176 case RR_RY_CNVT_SEW:
10177 check_mips_64(ctx);
10178 tcg_gen_ext32s_tl(cpu_gpr[rx], cpu_gpr[rx]);
10182 generate_exception(ctx, EXCP_RI);
10187 gen_HILO(ctx, OPC_MFLO, rx);
10189 #if defined (TARGET_MIPS64)
10191 check_mips_64(ctx);
10192 gen_shift_imm(env, ctx, OPC_DSRA, ry, ry, sa);
10195 check_mips_64(ctx);
10196 gen_shift(env, ctx, OPC_DSLLV, ry, rx, ry);
10199 check_mips_64(ctx);
10200 gen_shift(env, ctx, OPC_DSRLV, ry, rx, ry);
10203 check_mips_64(ctx);
10204 gen_shift(env, ctx, OPC_DSRAV, ry, rx, ry);
10208 gen_muldiv(ctx, OPC_MULT, rx, ry);
10211 gen_muldiv(ctx, OPC_MULTU, rx, ry);
10214 gen_muldiv(ctx, OPC_DIV, rx, ry);
10217 gen_muldiv(ctx, OPC_DIVU, rx, ry);
10219 #if defined (TARGET_MIPS64)
10221 check_mips_64(ctx);
10222 gen_muldiv(ctx, OPC_DMULT, rx, ry);
10225 check_mips_64(ctx);
10226 gen_muldiv(ctx, OPC_DMULTU, rx, ry);
10229 check_mips_64(ctx);
10230 gen_muldiv(ctx, OPC_DDIV, rx, ry);
10233 check_mips_64(ctx);
10234 gen_muldiv(ctx, OPC_DDIVU, rx, ry);
10238 generate_exception(ctx, EXCP_RI);
10242 case M16_OPC_EXTEND:
10243 decode_extended_mips16_opc(env, ctx, is_branch);
10246 #if defined(TARGET_MIPS64)
10248 funct = (ctx->opcode >> 8) & 0x7;
10249 decode_i64_mips16(env, ctx, ry, funct, offset, 0);
10253 generate_exception(ctx, EXCP_RI);
10260 /* microMIPS extension to MIPS32 */
10262 /* microMIPS32 major opcodes */
10301 /* 0x20 is reserved */
10311 /* 0x28 and 0x29 are reserved */
10321 /* 0x30 and 0x31 are reserved */
10331 /* 0x38 and 0x39 are reserved */
10342 /* POOL32A encoding of minor opcode field */
10345 /* These opcodes are distinguished only by bits 9..6; those bits are
10346 * what are recorded below. */
10372 /* The following can be distinguished by their lower 6 bits. */
10378 /* POOL32AXF encoding of minor opcode field extension */
10392 /* bits 13..12 for 0x01 */
10398 /* bits 13..12 for 0x2a */
10404 /* bits 13..12 for 0x32 */
10408 /* bits 15..12 for 0x2c */
10424 /* bits 15..12 for 0x34 */
10432 /* bits 15..12 for 0x3c */
10434 JR = 0x0, /* alias */
10439 /* bits 15..12 for 0x05 */
10443 /* bits 15..12 for 0x0d */
10453 /* bits 15..12 for 0x15 */
10459 /* bits 15..12 for 0x1d */
10463 /* bits 15..12 for 0x2d */
10468 /* bits 15..12 for 0x35 */
10475 /* POOL32B encoding of minor opcode field (bits 15..12) */
10491 /* POOL32C encoding of minor opcode field (bits 15..12) */
10499 /* 0xa is reserved */
10506 /* 0x6 is reserved */
10512 /* POOL32F encoding of minor opcode field (bits 5..0) */
10515 /* These are the bit 7..6 values */
10526 /* These are the bit 8..6 values */
10570 CABS_COND_FMT = 0x1c, /* MIPS3D */
10574 /* POOL32Fxf encoding of minor opcode extension field */
10612 /* POOL32I encoding of minor opcode field (bits 25..21) */
10637 /* These overlap and are distinguished by bit16 of the instruction */
10646 /* POOL16A encoding of minor opcode field */
10653 /* POOL16B encoding of minor opcode field */
10660 /* POOL16C encoding of minor opcode field */
10680 /* POOL16D encoding of minor opcode field */
10687 /* POOL16E encoding of minor opcode field */
10694 static int mmreg (int r)
10696 static const int map[] = { 16, 17, 2, 3, 4, 5, 6, 7 };
10701 /* Used for 16-bit store instructions. */
10702 static int mmreg2 (int r)
10704 static const int map[] = { 0, 17, 2, 3, 4, 5, 6, 7 };
10709 #define uMIPS_RD(op) ((op >> 7) & 0x7)
10710 #define uMIPS_RS(op) ((op >> 4) & 0x7)
10711 #define uMIPS_RS2(op) uMIPS_RS(op)
10712 #define uMIPS_RS1(op) ((op >> 1) & 0x7)
10713 #define uMIPS_RD5(op) ((op >> 5) & 0x1f)
10714 #define uMIPS_RS5(op) (op & 0x1f)
10716 /* Signed immediate */
10717 #define SIMM(op, start, width) \
10718 ((int32_t)(((op >> start) & ((~0U) >> (32-width))) \
10721 /* Zero-extended immediate */
10722 #define ZIMM(op, start, width) ((op >> start) & ((~0U) >> (32-width)))
10724 static void gen_addiur1sp (CPUMIPSState *env, DisasContext *ctx)
10726 int rd = mmreg(uMIPS_RD(ctx->opcode));
10728 gen_arith_imm(env, ctx, OPC_ADDIU, rd, 29, ((ctx->opcode >> 1) & 0x3f) << 2);
10731 static void gen_addiur2 (CPUMIPSState *env, DisasContext *ctx)
10733 static const int decoded_imm[] = { 1, 4, 8, 12, 16, 20, 24, -1 };
10734 int rd = mmreg(uMIPS_RD(ctx->opcode));
10735 int rs = mmreg(uMIPS_RS(ctx->opcode));
10737 gen_arith_imm(env, ctx, OPC_ADDIU, rd, rs, decoded_imm[ZIMM(ctx->opcode, 1, 3)]);
10740 static void gen_addiusp (CPUMIPSState *env, DisasContext *ctx)
10742 int encoded = ZIMM(ctx->opcode, 1, 9);
10745 if (encoded <= 1) {
10746 decoded = 256 + encoded;
10747 } else if (encoded <= 255) {
10749 } else if (encoded <= 509) {
10750 decoded = encoded - 512;
10752 decoded = encoded - 768;
10755 gen_arith_imm(env, ctx, OPC_ADDIU, 29, 29, decoded << 2);
10758 static void gen_addius5 (CPUMIPSState *env, DisasContext *ctx)
10760 int imm = SIMM(ctx->opcode, 1, 4);
10761 int rd = (ctx->opcode >> 5) & 0x1f;
10763 gen_arith_imm(env, ctx, OPC_ADDIU, rd, rd, imm);
10766 static void gen_andi16 (CPUMIPSState *env, DisasContext *ctx)
10768 static const int decoded_imm[] = { 128, 1, 2, 3, 4, 7, 8, 15, 16,
10769 31, 32, 63, 64, 255, 32768, 65535 };
10770 int rd = mmreg(uMIPS_RD(ctx->opcode));
10771 int rs = mmreg(uMIPS_RS(ctx->opcode));
10772 int encoded = ZIMM(ctx->opcode, 0, 4);
10774 gen_logic_imm(env, ctx, OPC_ANDI, rd, rs, decoded_imm[encoded]);
10777 static void gen_ldst_multiple (DisasContext *ctx, uint32_t opc, int reglist,
10778 int base, int16_t offset)
10780 const char *opn = "ldst_multiple";
10784 if (ctx->hflags & MIPS_HFLAG_BMASK) {
10785 generate_exception(ctx, EXCP_RI);
10789 t0 = tcg_temp_new();
10791 gen_base_offset_addr(ctx, t0, base, offset);
10793 t1 = tcg_const_tl(reglist);
10794 t2 = tcg_const_i32(ctx->mem_idx);
10796 save_cpu_state(ctx, 1);
10799 gen_helper_lwm(cpu_env, t0, t1, t2);
10803 gen_helper_swm(cpu_env, t0, t1, t2);
10806 #ifdef TARGET_MIPS64
10808 gen_helper_ldm(cpu_env, t0, t1, t2);
10812 gen_helper_sdm(cpu_env, t0, t1, t2);
10818 MIPS_DEBUG("%s, %x, %d(%s)", opn, reglist, offset, regnames[base]);
10821 tcg_temp_free_i32(t2);
10825 static void gen_pool16c_insn (CPUMIPSState *env, DisasContext *ctx, int *is_branch)
10827 int rd = mmreg((ctx->opcode >> 3) & 0x7);
10828 int rs = mmreg(ctx->opcode & 0x7);
10831 switch (((ctx->opcode) >> 4) & 0x3f) {
10836 gen_logic(env, ctx, OPC_NOR, rd, rs, 0);
10842 gen_logic(env, ctx, OPC_XOR, rd, rd, rs);
10848 gen_logic(env, ctx, OPC_AND, rd, rd, rs);
10854 gen_logic(env, ctx, OPC_OR, rd, rd, rs);
10861 static const int lwm_convert[] = { 0x11, 0x12, 0x13, 0x14 };
10862 int offset = ZIMM(ctx->opcode, 0, 4);
10864 gen_ldst_multiple(ctx, LWM32, lwm_convert[(ctx->opcode >> 4) & 0x3],
10873 static const int swm_convert[] = { 0x11, 0x12, 0x13, 0x14 };
10874 int offset = ZIMM(ctx->opcode, 0, 4);
10876 gen_ldst_multiple(ctx, SWM32, swm_convert[(ctx->opcode >> 4) & 0x3],
10883 int reg = ctx->opcode & 0x1f;
10885 gen_compute_branch(ctx, OPC_JR, 2, reg, 0, 0);
10892 int reg = ctx->opcode & 0x1f;
10894 gen_compute_branch(ctx, OPC_JR, 2, reg, 0, 0);
10895 /* Let normal delay slot handling in our caller take us
10896 to the branch target. */
10908 int reg = ctx->opcode & 0x1f;
10910 gen_compute_branch(ctx, opc, 2, reg, 31, 0);
10916 gen_HILO(ctx, OPC_MFHI, uMIPS_RS5(ctx->opcode));
10920 gen_HILO(ctx, OPC_MFLO, uMIPS_RS5(ctx->opcode));
10923 generate_exception(ctx, EXCP_BREAK);
10926 /* XXX: not clear which exception should be raised
10927 * when in debug mode...
10929 check_insn(env, ctx, ISA_MIPS32);
10930 if (!(ctx->hflags & MIPS_HFLAG_DM)) {
10931 generate_exception(ctx, EXCP_DBp);
10933 generate_exception(ctx, EXCP_DBp);
10936 case JRADDIUSP + 0:
10937 case JRADDIUSP + 1:
10939 int imm = ZIMM(ctx->opcode, 0, 5);
10941 gen_compute_branch(ctx, OPC_JR, 2, 31, 0, 0);
10942 gen_arith_imm(env, ctx, OPC_ADDIU, 29, 29, imm << 2);
10943 /* Let normal delay slot handling in our caller take us
10944 to the branch target. */
10948 generate_exception(ctx, EXCP_RI);
10953 static void gen_ldxs (DisasContext *ctx, int base, int index, int rd)
10955 TCGv t0 = tcg_temp_new();
10956 TCGv t1 = tcg_temp_new();
10958 gen_load_gpr(t0, base);
10961 gen_load_gpr(t1, index);
10962 tcg_gen_shli_tl(t1, t1, 2);
10963 gen_op_addr_add(ctx, t0, t1, t0);
10966 save_cpu_state(ctx, 0);
10967 op_ld_lw(t1, t0, ctx);
10968 gen_store_gpr(t1, rd);
10974 static void gen_ldst_pair (DisasContext *ctx, uint32_t opc, int rd,
10975 int base, int16_t offset)
10977 const char *opn = "ldst_pair";
10980 if (ctx->hflags & MIPS_HFLAG_BMASK || rd == 31) {
10981 generate_exception(ctx, EXCP_RI);
10985 t0 = tcg_temp_new();
10986 t1 = tcg_temp_new();
10988 gen_base_offset_addr(ctx, t0, base, offset);
10993 generate_exception(ctx, EXCP_RI);
10996 save_cpu_state(ctx, 0);
10997 op_ld_lw(t1, t0, ctx);
10998 gen_store_gpr(t1, rd);
10999 tcg_gen_movi_tl(t1, 4);
11000 gen_op_addr_add(ctx, t0, t0, t1);
11001 op_ld_lw(t1, t0, ctx);
11002 gen_store_gpr(t1, rd+1);
11006 save_cpu_state(ctx, 0);
11007 gen_load_gpr(t1, rd);
11008 op_st_sw(t1, t0, ctx);
11009 tcg_gen_movi_tl(t1, 4);
11010 gen_op_addr_add(ctx, t0, t0, t1);
11011 gen_load_gpr(t1, rd+1);
11012 op_st_sw(t1, t0, ctx);
11015 #ifdef TARGET_MIPS64
11018 generate_exception(ctx, EXCP_RI);
11021 save_cpu_state(ctx, 0);
11022 op_ld_ld(t1, t0, ctx);
11023 gen_store_gpr(t1, rd);
11024 tcg_gen_movi_tl(t1, 8);
11025 gen_op_addr_add(ctx, t0, t0, t1);
11026 op_ld_ld(t1, t0, ctx);
11027 gen_store_gpr(t1, rd+1);
11031 save_cpu_state(ctx, 0);
11032 gen_load_gpr(t1, rd);
11033 op_st_sd(t1, t0, ctx);
11034 tcg_gen_movi_tl(t1, 8);
11035 gen_op_addr_add(ctx, t0, t0, t1);
11036 gen_load_gpr(t1, rd+1);
11037 op_st_sd(t1, t0, ctx);
11042 (void)opn; /* avoid a compiler warning */
11043 MIPS_DEBUG("%s, %s, %d(%s)", opn, regnames[rd], offset, regnames[base]);
11048 static void gen_pool32axf (CPUMIPSState *env, DisasContext *ctx, int rt, int rs,
11051 int extension = (ctx->opcode >> 6) & 0x3f;
11052 int minor = (ctx->opcode >> 12) & 0xf;
11053 uint32_t mips32_op;
11055 switch (extension) {
11057 mips32_op = OPC_TEQ;
11060 mips32_op = OPC_TGE;
11063 mips32_op = OPC_TGEU;
11066 mips32_op = OPC_TLT;
11069 mips32_op = OPC_TLTU;
11072 mips32_op = OPC_TNE;
11074 gen_trap(ctx, mips32_op, rs, rt, -1);
11076 #ifndef CONFIG_USER_ONLY
11079 check_cp0_enabled(ctx);
11081 /* Treat as NOP. */
11084 gen_mfc0(env, ctx, cpu_gpr[rt], rs, (ctx->opcode >> 11) & 0x7);
11088 check_cp0_enabled(ctx);
11090 TCGv t0 = tcg_temp_new();
11092 gen_load_gpr(t0, rt);
11093 gen_mtc0(env, ctx, t0, rs, (ctx->opcode >> 11) & 0x7);
11101 gen_bshfl(ctx, OPC_SEB, rs, rt);
11104 gen_bshfl(ctx, OPC_SEH, rs, rt);
11107 mips32_op = OPC_CLO;
11110 mips32_op = OPC_CLZ;
11112 check_insn(env, ctx, ISA_MIPS32);
11113 gen_cl(ctx, mips32_op, rt, rs);
11116 gen_rdhwr(env, ctx, rt, rs);
11119 gen_bshfl(ctx, OPC_WSBH, rs, rt);
11122 mips32_op = OPC_MULT;
11125 mips32_op = OPC_MULTU;
11128 mips32_op = OPC_DIV;
11131 mips32_op = OPC_DIVU;
11134 mips32_op = OPC_MADD;
11137 mips32_op = OPC_MADDU;
11140 mips32_op = OPC_MSUB;
11143 mips32_op = OPC_MSUBU;
11145 check_insn(env, ctx, ISA_MIPS32);
11146 gen_muldiv(ctx, mips32_op, rs, rt);
11149 goto pool32axf_invalid;
11160 generate_exception_err(ctx, EXCP_CpU, 2);
11163 goto pool32axf_invalid;
11170 gen_compute_branch (ctx, OPC_JALR, 4, rs, rt, 0);
11175 gen_compute_branch (ctx, OPC_JALRS, 4, rs, rt, 0);
11179 goto pool32axf_invalid;
11185 check_cp0_enabled(ctx);
11186 check_insn(env, ctx, ISA_MIPS32R2);
11187 gen_load_srsgpr(rt, rs);
11190 check_cp0_enabled(ctx);
11191 check_insn(env, ctx, ISA_MIPS32R2);
11192 gen_store_srsgpr(rt, rs);
11195 goto pool32axf_invalid;
11198 #ifndef CONFIG_USER_ONLY
11202 mips32_op = OPC_TLBP;
11205 mips32_op = OPC_TLBR;
11208 mips32_op = OPC_TLBWI;
11211 mips32_op = OPC_TLBWR;
11214 mips32_op = OPC_WAIT;
11217 mips32_op = OPC_DERET;
11220 mips32_op = OPC_ERET;
11222 gen_cp0(env, ctx, mips32_op, rt, rs);
11225 goto pool32axf_invalid;
11231 check_cp0_enabled(ctx);
11233 TCGv t0 = tcg_temp_new();
11235 save_cpu_state(ctx, 1);
11236 gen_helper_di(t0, cpu_env);
11237 gen_store_gpr(t0, rs);
11238 /* Stop translation as we may have switched the execution mode */
11239 ctx->bstate = BS_STOP;
11244 check_cp0_enabled(ctx);
11246 TCGv t0 = tcg_temp_new();
11248 save_cpu_state(ctx, 1);
11249 gen_helper_ei(t0, cpu_env);
11250 gen_store_gpr(t0, rs);
11251 /* Stop translation as we may have switched the execution mode */
11252 ctx->bstate = BS_STOP;
11257 goto pool32axf_invalid;
11267 generate_exception(ctx, EXCP_SYSCALL);
11268 ctx->bstate = BS_STOP;
11271 check_insn(env, ctx, ISA_MIPS32);
11272 if (!(ctx->hflags & MIPS_HFLAG_DM)) {
11273 generate_exception(ctx, EXCP_DBp);
11275 generate_exception(ctx, EXCP_DBp);
11279 goto pool32axf_invalid;
11285 gen_HILO(ctx, OPC_MFHI, rs);
11288 gen_HILO(ctx, OPC_MFLO, rs);
11291 gen_HILO(ctx, OPC_MTHI, rs);
11294 gen_HILO(ctx, OPC_MTLO, rs);
11297 goto pool32axf_invalid;
11302 MIPS_INVAL("pool32axf");
11303 generate_exception(ctx, EXCP_RI);
11308 /* Values for microMIPS fmt field. Variable-width, depending on which
11309 formats the instruction supports. */
11328 static void gen_pool32fxf (CPUMIPSState *env, DisasContext *ctx, int rt, int rs)
11330 int extension = (ctx->opcode >> 6) & 0x3ff;
11331 uint32_t mips32_op;
11333 #define FLOAT_1BIT_FMT(opc, fmt) (fmt << 8) | opc
11334 #define FLOAT_2BIT_FMT(opc, fmt) (fmt << 7) | opc
11335 #define COND_FLOAT_MOV(opc, cond) (cond << 7) | opc
11337 switch (extension) {
11338 case FLOAT_1BIT_FMT(CFC1, 0):
11339 mips32_op = OPC_CFC1;
11341 case FLOAT_1BIT_FMT(CTC1, 0):
11342 mips32_op = OPC_CTC1;
11344 case FLOAT_1BIT_FMT(MFC1, 0):
11345 mips32_op = OPC_MFC1;
11347 case FLOAT_1BIT_FMT(MTC1, 0):
11348 mips32_op = OPC_MTC1;
11350 case FLOAT_1BIT_FMT(MFHC1, 0):
11351 mips32_op = OPC_MFHC1;
11353 case FLOAT_1BIT_FMT(MTHC1, 0):
11354 mips32_op = OPC_MTHC1;
11356 gen_cp1(ctx, mips32_op, rt, rs);
11359 /* Reciprocal square root */
11360 case FLOAT_1BIT_FMT(RSQRT_FMT, FMT_SD_S):
11361 mips32_op = OPC_RSQRT_S;
11363 case FLOAT_1BIT_FMT(RSQRT_FMT, FMT_SD_D):
11364 mips32_op = OPC_RSQRT_D;
11368 case FLOAT_1BIT_FMT(SQRT_FMT, FMT_SD_S):
11369 mips32_op = OPC_SQRT_S;
11371 case FLOAT_1BIT_FMT(SQRT_FMT, FMT_SD_D):
11372 mips32_op = OPC_SQRT_D;
11376 case FLOAT_1BIT_FMT(RECIP_FMT, FMT_SD_S):
11377 mips32_op = OPC_RECIP_S;
11379 case FLOAT_1BIT_FMT(RECIP_FMT, FMT_SD_D):
11380 mips32_op = OPC_RECIP_D;
11384 case FLOAT_1BIT_FMT(FLOOR_L, FMT_SD_S):
11385 mips32_op = OPC_FLOOR_L_S;
11387 case FLOAT_1BIT_FMT(FLOOR_L, FMT_SD_D):
11388 mips32_op = OPC_FLOOR_L_D;
11390 case FLOAT_1BIT_FMT(FLOOR_W, FMT_SD_S):
11391 mips32_op = OPC_FLOOR_W_S;
11393 case FLOAT_1BIT_FMT(FLOOR_W, FMT_SD_D):
11394 mips32_op = OPC_FLOOR_W_D;
11398 case FLOAT_1BIT_FMT(CEIL_L, FMT_SD_S):
11399 mips32_op = OPC_CEIL_L_S;
11401 case FLOAT_1BIT_FMT(CEIL_L, FMT_SD_D):
11402 mips32_op = OPC_CEIL_L_D;
11404 case FLOAT_1BIT_FMT(CEIL_W, FMT_SD_S):
11405 mips32_op = OPC_CEIL_W_S;
11407 case FLOAT_1BIT_FMT(CEIL_W, FMT_SD_D):
11408 mips32_op = OPC_CEIL_W_D;
11412 case FLOAT_1BIT_FMT(TRUNC_L, FMT_SD_S):
11413 mips32_op = OPC_TRUNC_L_S;
11415 case FLOAT_1BIT_FMT(TRUNC_L, FMT_SD_D):
11416 mips32_op = OPC_TRUNC_L_D;
11418 case FLOAT_1BIT_FMT(TRUNC_W, FMT_SD_S):
11419 mips32_op = OPC_TRUNC_W_S;
11421 case FLOAT_1BIT_FMT(TRUNC_W, FMT_SD_D):
11422 mips32_op = OPC_TRUNC_W_D;
11426 case FLOAT_1BIT_FMT(ROUND_L, FMT_SD_S):
11427 mips32_op = OPC_ROUND_L_S;
11429 case FLOAT_1BIT_FMT(ROUND_L, FMT_SD_D):
11430 mips32_op = OPC_ROUND_L_D;
11432 case FLOAT_1BIT_FMT(ROUND_W, FMT_SD_S):
11433 mips32_op = OPC_ROUND_W_S;
11435 case FLOAT_1BIT_FMT(ROUND_W, FMT_SD_D):
11436 mips32_op = OPC_ROUND_W_D;
11439 /* Integer to floating-point conversion */
11440 case FLOAT_1BIT_FMT(CVT_L, FMT_SD_S):
11441 mips32_op = OPC_CVT_L_S;
11443 case FLOAT_1BIT_FMT(CVT_L, FMT_SD_D):
11444 mips32_op = OPC_CVT_L_D;
11446 case FLOAT_1BIT_FMT(CVT_W, FMT_SD_S):
11447 mips32_op = OPC_CVT_W_S;
11449 case FLOAT_1BIT_FMT(CVT_W, FMT_SD_D):
11450 mips32_op = OPC_CVT_W_D;
11453 /* Paired-foo conversions */
11454 case FLOAT_1BIT_FMT(CVT_S_PL, 0):
11455 mips32_op = OPC_CVT_S_PL;
11457 case FLOAT_1BIT_FMT(CVT_S_PU, 0):
11458 mips32_op = OPC_CVT_S_PU;
11460 case FLOAT_1BIT_FMT(CVT_PW_PS, 0):
11461 mips32_op = OPC_CVT_PW_PS;
11463 case FLOAT_1BIT_FMT(CVT_PS_PW, 0):
11464 mips32_op = OPC_CVT_PS_PW;
11467 /* Floating-point moves */
11468 case FLOAT_2BIT_FMT(MOV_FMT, FMT_SDPS_S):
11469 mips32_op = OPC_MOV_S;
11471 case FLOAT_2BIT_FMT(MOV_FMT, FMT_SDPS_D):
11472 mips32_op = OPC_MOV_D;
11474 case FLOAT_2BIT_FMT(MOV_FMT, FMT_SDPS_PS):
11475 mips32_op = OPC_MOV_PS;
11478 /* Absolute value */
11479 case FLOAT_2BIT_FMT(ABS_FMT, FMT_SDPS_S):
11480 mips32_op = OPC_ABS_S;
11482 case FLOAT_2BIT_FMT(ABS_FMT, FMT_SDPS_D):
11483 mips32_op = OPC_ABS_D;
11485 case FLOAT_2BIT_FMT(ABS_FMT, FMT_SDPS_PS):
11486 mips32_op = OPC_ABS_PS;
11490 case FLOAT_2BIT_FMT(NEG_FMT, FMT_SDPS_S):
11491 mips32_op = OPC_NEG_S;
11493 case FLOAT_2BIT_FMT(NEG_FMT, FMT_SDPS_D):
11494 mips32_op = OPC_NEG_D;
11496 case FLOAT_2BIT_FMT(NEG_FMT, FMT_SDPS_PS):
11497 mips32_op = OPC_NEG_PS;
11500 /* Reciprocal square root step */
11501 case FLOAT_2BIT_FMT(RSQRT1_FMT, FMT_SDPS_S):
11502 mips32_op = OPC_RSQRT1_S;
11504 case FLOAT_2BIT_FMT(RSQRT1_FMT, FMT_SDPS_D):
11505 mips32_op = OPC_RSQRT1_D;
11507 case FLOAT_2BIT_FMT(RSQRT1_FMT, FMT_SDPS_PS):
11508 mips32_op = OPC_RSQRT1_PS;
11511 /* Reciprocal step */
11512 case FLOAT_2BIT_FMT(RECIP1_FMT, FMT_SDPS_S):
11513 mips32_op = OPC_RECIP1_S;
11515 case FLOAT_2BIT_FMT(RECIP1_FMT, FMT_SDPS_D):
11516 mips32_op = OPC_RECIP1_S;
11518 case FLOAT_2BIT_FMT(RECIP1_FMT, FMT_SDPS_PS):
11519 mips32_op = OPC_RECIP1_PS;
11522 /* Conversions from double */
11523 case FLOAT_2BIT_FMT(CVT_D, FMT_SWL_S):
11524 mips32_op = OPC_CVT_D_S;
11526 case FLOAT_2BIT_FMT(CVT_D, FMT_SWL_W):
11527 mips32_op = OPC_CVT_D_W;
11529 case FLOAT_2BIT_FMT(CVT_D, FMT_SWL_L):
11530 mips32_op = OPC_CVT_D_L;
11533 /* Conversions from single */
11534 case FLOAT_2BIT_FMT(CVT_S, FMT_DWL_D):
11535 mips32_op = OPC_CVT_S_D;
11537 case FLOAT_2BIT_FMT(CVT_S, FMT_DWL_W):
11538 mips32_op = OPC_CVT_S_W;
11540 case FLOAT_2BIT_FMT(CVT_S, FMT_DWL_L):
11541 mips32_op = OPC_CVT_S_L;
11543 gen_farith(ctx, mips32_op, -1, rs, rt, 0);
11546 /* Conditional moves on floating-point codes */
11547 case COND_FLOAT_MOV(MOVT, 0):
11548 case COND_FLOAT_MOV(MOVT, 1):
11549 case COND_FLOAT_MOV(MOVT, 2):
11550 case COND_FLOAT_MOV(MOVT, 3):
11551 case COND_FLOAT_MOV(MOVT, 4):
11552 case COND_FLOAT_MOV(MOVT, 5):
11553 case COND_FLOAT_MOV(MOVT, 6):
11554 case COND_FLOAT_MOV(MOVT, 7):
11555 gen_movci(ctx, rt, rs, (ctx->opcode >> 13) & 0x7, 1);
11557 case COND_FLOAT_MOV(MOVF, 0):
11558 case COND_FLOAT_MOV(MOVF, 1):
11559 case COND_FLOAT_MOV(MOVF, 2):
11560 case COND_FLOAT_MOV(MOVF, 3):
11561 case COND_FLOAT_MOV(MOVF, 4):
11562 case COND_FLOAT_MOV(MOVF, 5):
11563 case COND_FLOAT_MOV(MOVF, 6):
11564 case COND_FLOAT_MOV(MOVF, 7):
11565 gen_movci(ctx, rt, rs, (ctx->opcode >> 13) & 0x7, 0);
11568 MIPS_INVAL("pool32fxf");
11569 generate_exception(ctx, EXCP_RI);
11574 static void decode_micromips32_opc (CPUMIPSState *env, DisasContext *ctx,
11575 uint16_t insn_hw1, int *is_branch)
11579 int rt, rs, rd, rr;
11581 uint32_t op, minor, mips32_op;
11582 uint32_t cond, fmt, cc;
11584 insn = cpu_lduw_code(env, ctx->pc + 2);
11585 ctx->opcode = (ctx->opcode << 16) | insn;
11587 rt = (ctx->opcode >> 21) & 0x1f;
11588 rs = (ctx->opcode >> 16) & 0x1f;
11589 rd = (ctx->opcode >> 11) & 0x1f;
11590 rr = (ctx->opcode >> 6) & 0x1f;
11591 imm = (int16_t) ctx->opcode;
11593 op = (ctx->opcode >> 26) & 0x3f;
11596 minor = ctx->opcode & 0x3f;
11599 minor = (ctx->opcode >> 6) & 0xf;
11602 mips32_op = OPC_SLL;
11605 mips32_op = OPC_SRA;
11608 mips32_op = OPC_SRL;
11611 mips32_op = OPC_ROTR;
11613 gen_shift_imm(env, ctx, mips32_op, rt, rs, rd);
11616 goto pool32a_invalid;
11620 minor = (ctx->opcode >> 6) & 0xf;
11624 mips32_op = OPC_ADD;
11627 mips32_op = OPC_ADDU;
11630 mips32_op = OPC_SUB;
11633 mips32_op = OPC_SUBU;
11636 mips32_op = OPC_MUL;
11638 gen_arith(env, ctx, mips32_op, rd, rs, rt);
11642 mips32_op = OPC_SLLV;
11645 mips32_op = OPC_SRLV;
11648 mips32_op = OPC_SRAV;
11651 mips32_op = OPC_ROTRV;
11653 gen_shift(env, ctx, mips32_op, rd, rs, rt);
11655 /* Logical operations */
11657 mips32_op = OPC_AND;
11660 mips32_op = OPC_OR;
11663 mips32_op = OPC_NOR;
11666 mips32_op = OPC_XOR;
11668 gen_logic(env, ctx, mips32_op, rd, rs, rt);
11670 /* Set less than */
11672 mips32_op = OPC_SLT;
11675 mips32_op = OPC_SLTU;
11677 gen_slt(env, ctx, mips32_op, rd, rs, rt);
11680 goto pool32a_invalid;
11684 minor = (ctx->opcode >> 6) & 0xf;
11686 /* Conditional moves */
11688 mips32_op = OPC_MOVN;
11691 mips32_op = OPC_MOVZ;
11693 gen_cond_move(env, ctx, mips32_op, rd, rs, rt);
11696 gen_ldxs(ctx, rs, rt, rd);
11699 goto pool32a_invalid;
11703 gen_bitops(ctx, OPC_INS, rt, rs, rr, rd);
11706 gen_bitops(ctx, OPC_EXT, rt, rs, rr, rd);
11709 gen_pool32axf(env, ctx, rt, rs, is_branch);
11712 generate_exception(ctx, EXCP_BREAK);
11716 MIPS_INVAL("pool32a");
11717 generate_exception(ctx, EXCP_RI);
11722 minor = (ctx->opcode >> 12) & 0xf;
11725 check_cp0_enabled(ctx);
11726 /* Treat as no-op. */
11730 /* COP2: Not implemented. */
11731 generate_exception_err(ctx, EXCP_CpU, 2);
11735 #ifdef TARGET_MIPS64
11739 gen_ldst_pair(ctx, minor, rt, rs, SIMM(ctx->opcode, 0, 12));
11743 #ifdef TARGET_MIPS64
11747 gen_ldst_multiple(ctx, minor, rt, rs, SIMM(ctx->opcode, 0, 12));
11750 MIPS_INVAL("pool32b");
11751 generate_exception(ctx, EXCP_RI);
11756 if (env->CP0_Config1 & (1 << CP0C1_FP)) {
11757 minor = ctx->opcode & 0x3f;
11758 check_cp1_enabled(ctx);
11761 mips32_op = OPC_ALNV_PS;
11764 mips32_op = OPC_MADD_S;
11767 mips32_op = OPC_MADD_D;
11770 mips32_op = OPC_MADD_PS;
11773 mips32_op = OPC_MSUB_S;
11776 mips32_op = OPC_MSUB_D;
11779 mips32_op = OPC_MSUB_PS;
11782 mips32_op = OPC_NMADD_S;
11785 mips32_op = OPC_NMADD_D;
11788 mips32_op = OPC_NMADD_PS;
11791 mips32_op = OPC_NMSUB_S;
11794 mips32_op = OPC_NMSUB_D;
11797 mips32_op = OPC_NMSUB_PS;
11799 gen_flt3_arith(ctx, mips32_op, rd, rr, rs, rt);
11801 case CABS_COND_FMT:
11802 cond = (ctx->opcode >> 6) & 0xf;
11803 cc = (ctx->opcode >> 13) & 0x7;
11804 fmt = (ctx->opcode >> 10) & 0x3;
11807 gen_cmpabs_s(ctx, cond, rt, rs, cc);
11810 gen_cmpabs_d(ctx, cond, rt, rs, cc);
11813 gen_cmpabs_ps(ctx, cond, rt, rs, cc);
11816 goto pool32f_invalid;
11820 cond = (ctx->opcode >> 6) & 0xf;
11821 cc = (ctx->opcode >> 13) & 0x7;
11822 fmt = (ctx->opcode >> 10) & 0x3;
11825 gen_cmp_s(ctx, cond, rt, rs, cc);
11828 gen_cmp_d(ctx, cond, rt, rs, cc);
11831 gen_cmp_ps(ctx, cond, rt, rs, cc);
11834 goto pool32f_invalid;
11838 gen_pool32fxf(env, ctx, rt, rs);
11842 switch ((ctx->opcode >> 6) & 0x7) {
11844 mips32_op = OPC_PLL_PS;
11847 mips32_op = OPC_PLU_PS;
11850 mips32_op = OPC_PUL_PS;
11853 mips32_op = OPC_PUU_PS;
11856 mips32_op = OPC_CVT_PS_S;
11858 gen_farith(ctx, mips32_op, rt, rs, rd, 0);
11861 goto pool32f_invalid;
11866 switch ((ctx->opcode >> 6) & 0x7) {
11868 mips32_op = OPC_LWXC1;
11871 mips32_op = OPC_SWXC1;
11874 mips32_op = OPC_LDXC1;
11877 mips32_op = OPC_SDXC1;
11880 mips32_op = OPC_LUXC1;
11883 mips32_op = OPC_SUXC1;
11885 gen_flt3_ldst(ctx, mips32_op, rd, rd, rt, rs);
11888 goto pool32f_invalid;
11893 fmt = (ctx->opcode >> 9) & 0x3;
11894 switch ((ctx->opcode >> 6) & 0x7) {
11898 mips32_op = OPC_RSQRT2_S;
11901 mips32_op = OPC_RSQRT2_D;
11904 mips32_op = OPC_RSQRT2_PS;
11907 goto pool32f_invalid;
11913 mips32_op = OPC_RECIP2_S;
11916 mips32_op = OPC_RECIP2_D;
11919 mips32_op = OPC_RECIP2_PS;
11922 goto pool32f_invalid;
11926 mips32_op = OPC_ADDR_PS;
11929 mips32_op = OPC_MULR_PS;
11931 gen_farith(ctx, mips32_op, rt, rs, rd, 0);
11934 goto pool32f_invalid;
11938 /* MOV[FT].fmt and PREFX */
11939 cc = (ctx->opcode >> 13) & 0x7;
11940 fmt = (ctx->opcode >> 9) & 0x3;
11941 switch ((ctx->opcode >> 6) & 0x7) {
11945 gen_movcf_s(rs, rt, cc, 0);
11948 gen_movcf_d(ctx, rs, rt, cc, 0);
11951 gen_movcf_ps(rs, rt, cc, 0);
11954 goto pool32f_invalid;
11960 gen_movcf_s(rs, rt, cc, 1);
11963 gen_movcf_d(ctx, rs, rt, cc, 1);
11966 gen_movcf_ps(rs, rt, cc, 1);
11969 goto pool32f_invalid;
11975 goto pool32f_invalid;
11978 #define FINSN_3ARG_SDPS(prfx) \
11979 switch ((ctx->opcode >> 8) & 0x3) { \
11981 mips32_op = OPC_##prfx##_S; \
11984 mips32_op = OPC_##prfx##_D; \
11986 case FMT_SDPS_PS: \
11987 mips32_op = OPC_##prfx##_PS; \
11990 goto pool32f_invalid; \
11993 /* regular FP ops */
11994 switch ((ctx->opcode >> 6) & 0x3) {
11996 FINSN_3ARG_SDPS(ADD);
11999 FINSN_3ARG_SDPS(SUB);
12002 FINSN_3ARG_SDPS(MUL);
12005 fmt = (ctx->opcode >> 8) & 0x3;
12007 mips32_op = OPC_DIV_D;
12008 } else if (fmt == 0) {
12009 mips32_op = OPC_DIV_S;
12011 goto pool32f_invalid;
12015 goto pool32f_invalid;
12020 switch ((ctx->opcode >> 6) & 0x3) {
12022 FINSN_3ARG_SDPS(MOVN);
12025 FINSN_3ARG_SDPS(MOVZ);
12028 goto pool32f_invalid;
12032 gen_farith(ctx, mips32_op, rt, rs, rd, 0);
12036 MIPS_INVAL("pool32f");
12037 generate_exception(ctx, EXCP_RI);
12041 generate_exception_err(ctx, EXCP_CpU, 1);
12045 minor = (ctx->opcode >> 21) & 0x1f;
12048 mips32_op = OPC_BLTZ;
12051 mips32_op = OPC_BLTZAL;
12054 mips32_op = OPC_BLTZALS;
12057 mips32_op = OPC_BGEZ;
12060 mips32_op = OPC_BGEZAL;
12063 mips32_op = OPC_BGEZALS;
12066 mips32_op = OPC_BLEZ;
12069 mips32_op = OPC_BGTZ;
12071 gen_compute_branch(ctx, mips32_op, 4, rs, -1, imm << 1);
12077 mips32_op = OPC_TLTI;
12080 mips32_op = OPC_TGEI;
12083 mips32_op = OPC_TLTIU;
12086 mips32_op = OPC_TGEIU;
12089 mips32_op = OPC_TNEI;
12092 mips32_op = OPC_TEQI;
12094 gen_trap(ctx, mips32_op, rs, -1, imm);
12099 gen_compute_branch(ctx, minor == BNEZC ? OPC_BNE : OPC_BEQ,
12100 4, rs, 0, imm << 1);
12101 /* Compact branches don't have a delay slot, so just let
12102 the normal delay slot handling take us to the branch
12106 gen_logic_imm(env, ctx, OPC_LUI, rs, -1, imm);
12112 /* COP2: Not implemented. */
12113 generate_exception_err(ctx, EXCP_CpU, 2);
12116 mips32_op = (ctx->opcode & (1 << 16)) ? OPC_BC1FANY2 : OPC_BC1F;
12119 mips32_op = (ctx->opcode & (1 << 16)) ? OPC_BC1TANY2 : OPC_BC1T;
12122 mips32_op = OPC_BC1FANY4;
12125 mips32_op = OPC_BC1TANY4;
12128 check_insn(env, ctx, ASE_MIPS3D);
12131 gen_compute_branch1(env, ctx, mips32_op,
12132 (ctx->opcode >> 18) & 0x7, imm << 1);
12137 /* MIPS DSP: not implemented */
12140 MIPS_INVAL("pool32i");
12141 generate_exception(ctx, EXCP_RI);
12146 minor = (ctx->opcode >> 12) & 0xf;
12149 mips32_op = OPC_LWL;
12152 mips32_op = OPC_SWL;
12155 mips32_op = OPC_LWR;
12158 mips32_op = OPC_SWR;
12160 #if defined(TARGET_MIPS64)
12162 mips32_op = OPC_LDL;
12165 mips32_op = OPC_SDL;
12168 mips32_op = OPC_LDR;
12171 mips32_op = OPC_SDR;
12174 mips32_op = OPC_LWU;
12177 mips32_op = OPC_LLD;
12181 mips32_op = OPC_LL;
12184 gen_ld(env, ctx, mips32_op, rt, rs, SIMM(ctx->opcode, 0, 12));
12187 gen_st(ctx, mips32_op, rt, rs, SIMM(ctx->opcode, 0, 12));
12190 gen_st_cond(ctx, OPC_SC, rt, rs, SIMM(ctx->opcode, 0, 12));
12192 #if defined(TARGET_MIPS64)
12194 gen_st_cond(ctx, OPC_SCD, rt, rs, SIMM(ctx->opcode, 0, 12));
12198 /* Treat as no-op */
12201 MIPS_INVAL("pool32c");
12202 generate_exception(ctx, EXCP_RI);
12207 mips32_op = OPC_ADDI;
12210 mips32_op = OPC_ADDIU;
12212 gen_arith_imm(env, ctx, mips32_op, rt, rs, imm);
12215 /* Logical operations */
12217 mips32_op = OPC_ORI;
12220 mips32_op = OPC_XORI;
12223 mips32_op = OPC_ANDI;
12225 gen_logic_imm(env, ctx, mips32_op, rt, rs, imm);
12228 /* Set less than immediate */
12230 mips32_op = OPC_SLTI;
12233 mips32_op = OPC_SLTIU;
12235 gen_slt_imm(env, ctx, mips32_op, rt, rs, imm);
12238 offset = (int32_t)(ctx->opcode & 0x3FFFFFF) << 2;
12239 gen_compute_branch(ctx, OPC_JALX, 4, rt, rs, offset);
12243 offset = (int32_t)(ctx->opcode & 0x3FFFFFF) << 1;
12244 gen_compute_branch(ctx, OPC_JALS, 4, rt, rs, offset);
12248 gen_compute_branch(ctx, OPC_BEQ, 4, rt, rs, imm << 1);
12252 gen_compute_branch(ctx, OPC_BNE, 4, rt, rs, imm << 1);
12256 gen_compute_branch(ctx, OPC_J, 4, rt, rs,
12257 (int32_t)(ctx->opcode & 0x3FFFFFF) << 1);
12261 gen_compute_branch(ctx, OPC_JAL, 4, rt, rs,
12262 (int32_t)(ctx->opcode & 0x3FFFFFF) << 1);
12265 /* Floating point (COP1) */
12267 mips32_op = OPC_LWC1;
12270 mips32_op = OPC_LDC1;
12273 mips32_op = OPC_SWC1;
12276 mips32_op = OPC_SDC1;
12278 gen_cop1_ldst(env, ctx, mips32_op, rt, rs, imm);
12282 int reg = mmreg(ZIMM(ctx->opcode, 23, 3));
12283 int offset = SIMM(ctx->opcode, 0, 23) << 2;
12285 gen_addiupc(ctx, reg, offset, 0, 0);
12288 /* Loads and stores */
12290 mips32_op = OPC_LB;
12293 mips32_op = OPC_LBU;
12296 mips32_op = OPC_LH;
12299 mips32_op = OPC_LHU;
12302 mips32_op = OPC_LW;
12304 #ifdef TARGET_MIPS64
12306 mips32_op = OPC_LD;
12309 mips32_op = OPC_SD;
12313 mips32_op = OPC_SB;
12316 mips32_op = OPC_SH;
12319 mips32_op = OPC_SW;
12322 gen_ld(env, ctx, mips32_op, rt, rs, imm);
12325 gen_st(ctx, mips32_op, rt, rs, imm);
12328 generate_exception(ctx, EXCP_RI);
12333 static int decode_micromips_opc (CPUMIPSState *env, DisasContext *ctx, int *is_branch)
12337 /* make sure instructions are on a halfword boundary */
12338 if (ctx->pc & 0x1) {
12339 env->CP0_BadVAddr = ctx->pc;
12340 generate_exception(ctx, EXCP_AdEL);
12341 ctx->bstate = BS_STOP;
12345 op = (ctx->opcode >> 10) & 0x3f;
12346 /* Enforce properly-sized instructions in a delay slot */
12347 if (ctx->hflags & MIPS_HFLAG_BMASK) {
12348 int bits = ctx->hflags & MIPS_HFLAG_BMASK_EXT;
12382 case POOL48A: /* ??? */
12387 if (bits & MIPS_HFLAG_BDS16) {
12388 generate_exception(ctx, EXCP_RI);
12389 /* Just stop translation; the user is confused. */
12390 ctx->bstate = BS_STOP;
12415 if (bits & MIPS_HFLAG_BDS32) {
12416 generate_exception(ctx, EXCP_RI);
12417 /* Just stop translation; the user is confused. */
12418 ctx->bstate = BS_STOP;
12429 int rd = mmreg(uMIPS_RD(ctx->opcode));
12430 int rs1 = mmreg(uMIPS_RS1(ctx->opcode));
12431 int rs2 = mmreg(uMIPS_RS2(ctx->opcode));
12434 switch (ctx->opcode & 0x1) {
12443 gen_arith(env, ctx, opc, rd, rs1, rs2);
12448 int rd = mmreg(uMIPS_RD(ctx->opcode));
12449 int rs = mmreg(uMIPS_RS(ctx->opcode));
12450 int amount = (ctx->opcode >> 1) & 0x7;
12452 amount = amount == 0 ? 8 : amount;
12454 switch (ctx->opcode & 0x1) {
12463 gen_shift_imm(env, ctx, opc, rd, rs, amount);
12467 gen_pool16c_insn(env, ctx, is_branch);
12471 int rd = mmreg(uMIPS_RD(ctx->opcode));
12472 int rb = 28; /* GP */
12473 int16_t offset = SIMM(ctx->opcode, 0, 7) << 2;
12475 gen_ld(env, ctx, OPC_LW, rd, rb, offset);
12479 if (ctx->opcode & 1) {
12480 generate_exception(ctx, EXCP_RI);
12483 int enc_dest = uMIPS_RD(ctx->opcode);
12484 int enc_rt = uMIPS_RS2(ctx->opcode);
12485 int enc_rs = uMIPS_RS1(ctx->opcode);
12486 int rd, rs, re, rt;
12487 static const int rd_enc[] = { 5, 5, 6, 4, 4, 4, 4, 4 };
12488 static const int re_enc[] = { 6, 7, 7, 21, 22, 5, 6, 7 };
12489 static const int rs_rt_enc[] = { 0, 17, 2, 3, 16, 18, 19, 20 };
12491 rd = rd_enc[enc_dest];
12492 re = re_enc[enc_dest];
12493 rs = rs_rt_enc[enc_rs];
12494 rt = rs_rt_enc[enc_rt];
12496 gen_arith_imm(env, ctx, OPC_ADDIU, rd, rs, 0);
12497 gen_arith_imm(env, ctx, OPC_ADDIU, re, rt, 0);
12502 int rd = mmreg(uMIPS_RD(ctx->opcode));
12503 int rb = mmreg(uMIPS_RS(ctx->opcode));
12504 int16_t offset = ZIMM(ctx->opcode, 0, 4);
12505 offset = (offset == 0xf ? -1 : offset);
12507 gen_ld(env, ctx, OPC_LBU, rd, rb, offset);
12512 int rd = mmreg(uMIPS_RD(ctx->opcode));
12513 int rb = mmreg(uMIPS_RS(ctx->opcode));
12514 int16_t offset = ZIMM(ctx->opcode, 0, 4) << 1;
12516 gen_ld(env, ctx, OPC_LHU, rd, rb, offset);
12521 int rd = (ctx->opcode >> 5) & 0x1f;
12522 int rb = 29; /* SP */
12523 int16_t offset = ZIMM(ctx->opcode, 0, 5) << 2;
12525 gen_ld(env, ctx, OPC_LW, rd, rb, offset);
12530 int rd = mmreg(uMIPS_RD(ctx->opcode));
12531 int rb = mmreg(uMIPS_RS(ctx->opcode));
12532 int16_t offset = ZIMM(ctx->opcode, 0, 4) << 2;
12534 gen_ld(env, ctx, OPC_LW, rd, rb, offset);
12539 int rd = mmreg2(uMIPS_RD(ctx->opcode));
12540 int rb = mmreg(uMIPS_RS(ctx->opcode));
12541 int16_t offset = ZIMM(ctx->opcode, 0, 4);
12543 gen_st(ctx, OPC_SB, rd, rb, offset);
12548 int rd = mmreg2(uMIPS_RD(ctx->opcode));
12549 int rb = mmreg(uMIPS_RS(ctx->opcode));
12550 int16_t offset = ZIMM(ctx->opcode, 0, 4) << 1;
12552 gen_st(ctx, OPC_SH, rd, rb, offset);
12557 int rd = (ctx->opcode >> 5) & 0x1f;
12558 int rb = 29; /* SP */
12559 int16_t offset = ZIMM(ctx->opcode, 0, 5) << 2;
12561 gen_st(ctx, OPC_SW, rd, rb, offset);
12566 int rd = mmreg2(uMIPS_RD(ctx->opcode));
12567 int rb = mmreg(uMIPS_RS(ctx->opcode));
12568 int16_t offset = ZIMM(ctx->opcode, 0, 4) << 2;
12570 gen_st(ctx, OPC_SW, rd, rb, offset);
12575 int rd = uMIPS_RD5(ctx->opcode);
12576 int rs = uMIPS_RS5(ctx->opcode);
12578 gen_arith_imm(env, ctx, OPC_ADDIU, rd, rs, 0);
12582 gen_andi16(env, ctx);
12585 switch (ctx->opcode & 0x1) {
12587 gen_addius5(env, ctx);
12590 gen_addiusp(env, ctx);
12595 switch (ctx->opcode & 0x1) {
12597 gen_addiur2(env, ctx);
12600 gen_addiur1sp(env, ctx);
12605 gen_compute_branch(ctx, OPC_BEQ, 2, 0, 0,
12606 SIMM(ctx->opcode, 0, 10) << 1);
12611 gen_compute_branch(ctx, op == BNEZ16 ? OPC_BNE : OPC_BEQ, 2,
12612 mmreg(uMIPS_RD(ctx->opcode)),
12613 0, SIMM(ctx->opcode, 0, 7) << 1);
12618 int reg = mmreg(uMIPS_RD(ctx->opcode));
12619 int imm = ZIMM(ctx->opcode, 0, 7);
12621 imm = (imm == 0x7f ? -1 : imm);
12622 tcg_gen_movi_tl(cpu_gpr[reg], imm);
12632 generate_exception(ctx, EXCP_RI);
12635 decode_micromips32_opc (env, ctx, op, is_branch);
12642 /* SmartMIPS extension to MIPS32 */
12644 #if defined(TARGET_MIPS64)
12646 /* MDMX extension to MIPS64 */
12650 /* MIPSDSP functions. */
12651 static void gen_mipsdsp_ld(CPUMIPSState *env, DisasContext *ctx, uint32_t opc,
12652 int rd, int base, int offset)
12654 const char *opn = "ldx";
12663 t0 = tcg_temp_new();
12666 gen_load_gpr(t0, offset);
12667 } else if (offset == 0) {
12668 gen_load_gpr(t0, base);
12670 gen_op_addr_add(ctx, t0, cpu_gpr[base], cpu_gpr[offset]);
12673 save_cpu_state(ctx, 0);
12676 op_ld_lbu(t0, t0, ctx);
12677 gen_store_gpr(t0, rd);
12681 op_ld_lh(t0, t0, ctx);
12682 gen_store_gpr(t0, rd);
12686 op_ld_lw(t0, t0, ctx);
12687 gen_store_gpr(t0, rd);
12690 #if defined(TARGET_MIPS64)
12692 op_ld_ld(t0, t0, ctx);
12693 gen_store_gpr(t0, rd);
12698 (void)opn; /* avoid a compiler warning */
12699 MIPS_DEBUG("%s %s, %s(%s)", opn,
12700 regnames[rd], regnames[offset], regnames[base]);
12704 static void gen_mipsdsp_arith(DisasContext *ctx, uint32_t op1, uint32_t op2,
12705 int ret, int v1, int v2)
12707 const char *opn = "mipsdsp arith";
12712 /* Treat as NOP. */
12717 v1_t = tcg_temp_new();
12718 v2_t = tcg_temp_new();
12720 gen_load_gpr(v1_t, v1);
12721 gen_load_gpr(v2_t, v2);
12724 /* OPC_MULT_G_2E is equal OPC_ADDUH_QB_DSP */
12725 case OPC_MULT_G_2E:
12729 gen_helper_adduh_qb(cpu_gpr[ret], v1_t, v2_t);
12731 case OPC_ADDUH_R_QB:
12732 gen_helper_adduh_r_qb(cpu_gpr[ret], v1_t, v2_t);
12735 gen_helper_addqh_ph(cpu_gpr[ret], v1_t, v2_t);
12737 case OPC_ADDQH_R_PH:
12738 gen_helper_addqh_r_ph(cpu_gpr[ret], v1_t, v2_t);
12741 gen_helper_addqh_w(cpu_gpr[ret], v1_t, v2_t);
12743 case OPC_ADDQH_R_W:
12744 gen_helper_addqh_r_w(cpu_gpr[ret], v1_t, v2_t);
12747 gen_helper_subuh_qb(cpu_gpr[ret], v1_t, v2_t);
12749 case OPC_SUBUH_R_QB:
12750 gen_helper_subuh_r_qb(cpu_gpr[ret], v1_t, v2_t);
12753 gen_helper_subqh_ph(cpu_gpr[ret], v1_t, v2_t);
12755 case OPC_SUBQH_R_PH:
12756 gen_helper_subqh_r_ph(cpu_gpr[ret], v1_t, v2_t);
12759 gen_helper_subqh_w(cpu_gpr[ret], v1_t, v2_t);
12761 case OPC_SUBQH_R_W:
12762 gen_helper_subqh_r_w(cpu_gpr[ret], v1_t, v2_t);
12766 case OPC_ABSQ_S_PH_DSP:
12768 case OPC_ABSQ_S_QB:
12770 gen_helper_absq_s_qb(cpu_gpr[ret], v2_t, cpu_env);
12772 case OPC_ABSQ_S_PH:
12774 gen_helper_absq_s_ph(cpu_gpr[ret], v2_t, cpu_env);
12778 gen_helper_absq_s_w(cpu_gpr[ret], v2_t, cpu_env);
12780 case OPC_PRECEQ_W_PHL:
12782 tcg_gen_andi_tl(cpu_gpr[ret], v2_t, 0xFFFF0000);
12783 tcg_gen_ext32s_tl(cpu_gpr[ret], cpu_gpr[ret]);
12785 case OPC_PRECEQ_W_PHR:
12787 tcg_gen_andi_tl(cpu_gpr[ret], v2_t, 0x0000FFFF);
12788 tcg_gen_shli_tl(cpu_gpr[ret], cpu_gpr[ret], 16);
12789 tcg_gen_ext32s_tl(cpu_gpr[ret], cpu_gpr[ret]);
12791 case OPC_PRECEQU_PH_QBL:
12793 gen_helper_precequ_ph_qbl(cpu_gpr[ret], v2_t);
12795 case OPC_PRECEQU_PH_QBR:
12797 gen_helper_precequ_ph_qbr(cpu_gpr[ret], v2_t);
12799 case OPC_PRECEQU_PH_QBLA:
12801 gen_helper_precequ_ph_qbla(cpu_gpr[ret], v2_t);
12803 case OPC_PRECEQU_PH_QBRA:
12805 gen_helper_precequ_ph_qbra(cpu_gpr[ret], v2_t);
12807 case OPC_PRECEU_PH_QBL:
12809 gen_helper_preceu_ph_qbl(cpu_gpr[ret], v2_t);
12811 case OPC_PRECEU_PH_QBR:
12813 gen_helper_preceu_ph_qbr(cpu_gpr[ret], v2_t);
12815 case OPC_PRECEU_PH_QBLA:
12817 gen_helper_preceu_ph_qbla(cpu_gpr[ret], v2_t);
12819 case OPC_PRECEU_PH_QBRA:
12821 gen_helper_preceu_ph_qbra(cpu_gpr[ret], v2_t);
12825 case OPC_ADDU_QB_DSP:
12829 gen_helper_addq_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12831 case OPC_ADDQ_S_PH:
12833 gen_helper_addq_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12837 gen_helper_addq_s_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12841 gen_helper_addu_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12843 case OPC_ADDU_S_QB:
12845 gen_helper_addu_s_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12849 gen_helper_addu_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12851 case OPC_ADDU_S_PH:
12853 gen_helper_addu_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12857 gen_helper_subq_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12859 case OPC_SUBQ_S_PH:
12861 gen_helper_subq_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12865 gen_helper_subq_s_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12869 gen_helper_subu_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12871 case OPC_SUBU_S_QB:
12873 gen_helper_subu_s_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12877 gen_helper_subu_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12879 case OPC_SUBU_S_PH:
12881 gen_helper_subu_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12885 gen_helper_addsc(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12889 gen_helper_addwc(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12893 gen_helper_modsub(cpu_gpr[ret], v1_t, v2_t);
12895 case OPC_RADDU_W_QB:
12897 gen_helper_raddu_w_qb(cpu_gpr[ret], v1_t);
12901 case OPC_CMPU_EQ_QB_DSP:
12903 case OPC_PRECR_QB_PH:
12905 gen_helper_precr_qb_ph(cpu_gpr[ret], v1_t, v2_t);
12907 case OPC_PRECRQ_QB_PH:
12909 gen_helper_precrq_qb_ph(cpu_gpr[ret], v1_t, v2_t);
12911 case OPC_PRECR_SRA_PH_W:
12914 TCGv_i32 sa_t = tcg_const_i32(v2);
12915 gen_helper_precr_sra_ph_w(cpu_gpr[ret], sa_t, v1_t,
12917 tcg_temp_free_i32(sa_t);
12920 case OPC_PRECR_SRA_R_PH_W:
12923 TCGv_i32 sa_t = tcg_const_i32(v2);
12924 gen_helper_precr_sra_r_ph_w(cpu_gpr[ret], sa_t, v1_t,
12926 tcg_temp_free_i32(sa_t);
12929 case OPC_PRECRQ_PH_W:
12931 gen_helper_precrq_ph_w(cpu_gpr[ret], v1_t, v2_t);
12933 case OPC_PRECRQ_RS_PH_W:
12935 gen_helper_precrq_rs_ph_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12937 case OPC_PRECRQU_S_QB_PH:
12939 gen_helper_precrqu_s_qb_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12943 #ifdef TARGET_MIPS64
12944 case OPC_ABSQ_S_QH_DSP:
12946 case OPC_PRECEQ_L_PWL:
12948 tcg_gen_andi_tl(cpu_gpr[ret], v2_t, 0xFFFFFFFF00000000ull);
12950 case OPC_PRECEQ_L_PWR:
12952 tcg_gen_shli_tl(cpu_gpr[ret], v2_t, 32);
12954 case OPC_PRECEQ_PW_QHL:
12956 gen_helper_preceq_pw_qhl(cpu_gpr[ret], v2_t);
12958 case OPC_PRECEQ_PW_QHR:
12960 gen_helper_preceq_pw_qhr(cpu_gpr[ret], v2_t);
12962 case OPC_PRECEQ_PW_QHLA:
12964 gen_helper_preceq_pw_qhla(cpu_gpr[ret], v2_t);
12966 case OPC_PRECEQ_PW_QHRA:
12968 gen_helper_preceq_pw_qhra(cpu_gpr[ret], v2_t);
12970 case OPC_PRECEQU_QH_OBL:
12972 gen_helper_precequ_qh_obl(cpu_gpr[ret], v2_t);
12974 case OPC_PRECEQU_QH_OBR:
12976 gen_helper_precequ_qh_obr(cpu_gpr[ret], v2_t);
12978 case OPC_PRECEQU_QH_OBLA:
12980 gen_helper_precequ_qh_obla(cpu_gpr[ret], v2_t);
12982 case OPC_PRECEQU_QH_OBRA:
12984 gen_helper_precequ_qh_obra(cpu_gpr[ret], v2_t);
12986 case OPC_PRECEU_QH_OBL:
12988 gen_helper_preceu_qh_obl(cpu_gpr[ret], v2_t);
12990 case OPC_PRECEU_QH_OBR:
12992 gen_helper_preceu_qh_obr(cpu_gpr[ret], v2_t);
12994 case OPC_PRECEU_QH_OBLA:
12996 gen_helper_preceu_qh_obla(cpu_gpr[ret], v2_t);
12998 case OPC_PRECEU_QH_OBRA:
13000 gen_helper_preceu_qh_obra(cpu_gpr[ret], v2_t);
13002 case OPC_ABSQ_S_OB:
13004 gen_helper_absq_s_ob(cpu_gpr[ret], v2_t, cpu_env);
13006 case OPC_ABSQ_S_PW:
13008 gen_helper_absq_s_pw(cpu_gpr[ret], v2_t, cpu_env);
13010 case OPC_ABSQ_S_QH:
13012 gen_helper_absq_s_qh(cpu_gpr[ret], v2_t, cpu_env);
13016 case OPC_ADDU_OB_DSP:
13018 case OPC_RADDU_L_OB:
13020 gen_helper_raddu_l_ob(cpu_gpr[ret], v1_t);
13024 gen_helper_subq_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13026 case OPC_SUBQ_S_PW:
13028 gen_helper_subq_s_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13032 gen_helper_subq_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13034 case OPC_SUBQ_S_QH:
13036 gen_helper_subq_s_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13040 gen_helper_subu_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13042 case OPC_SUBU_S_OB:
13044 gen_helper_subu_s_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13048 gen_helper_subu_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13050 case OPC_SUBU_S_QH:
13052 gen_helper_subu_s_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13056 gen_helper_subuh_ob(cpu_gpr[ret], v1_t, v2_t);
13058 case OPC_SUBUH_R_OB:
13060 gen_helper_subuh_r_ob(cpu_gpr[ret], v1_t, v2_t);
13064 gen_helper_addq_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13066 case OPC_ADDQ_S_PW:
13068 gen_helper_addq_s_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13072 gen_helper_addq_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13074 case OPC_ADDQ_S_QH:
13076 gen_helper_addq_s_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13080 gen_helper_addu_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13082 case OPC_ADDU_S_OB:
13084 gen_helper_addu_s_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13088 gen_helper_addu_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13090 case OPC_ADDU_S_QH:
13092 gen_helper_addu_s_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13096 gen_helper_adduh_ob(cpu_gpr[ret], v1_t, v2_t);
13098 case OPC_ADDUH_R_OB:
13100 gen_helper_adduh_r_ob(cpu_gpr[ret], v1_t, v2_t);
13104 case OPC_CMPU_EQ_OB_DSP:
13106 case OPC_PRECR_OB_QH:
13108 gen_helper_precr_ob_qh(cpu_gpr[ret], v1_t, v2_t);
13110 case OPC_PRECR_SRA_QH_PW:
13113 TCGv_i32 ret_t = tcg_const_i32(ret);
13114 gen_helper_precr_sra_qh_pw(v2_t, v1_t, v2_t, ret_t);
13115 tcg_temp_free_i32(ret_t);
13118 case OPC_PRECR_SRA_R_QH_PW:
13121 TCGv_i32 sa_v = tcg_const_i32(ret);
13122 gen_helper_precr_sra_r_qh_pw(v2_t, v1_t, v2_t, sa_v);
13123 tcg_temp_free_i32(sa_v);
13126 case OPC_PRECRQ_OB_QH:
13128 gen_helper_precrq_ob_qh(cpu_gpr[ret], v1_t, v2_t);
13130 case OPC_PRECRQ_PW_L:
13132 gen_helper_precrq_pw_l(cpu_gpr[ret], v1_t, v2_t);
13134 case OPC_PRECRQ_QH_PW:
13136 gen_helper_precrq_qh_pw(cpu_gpr[ret], v1_t, v2_t);
13138 case OPC_PRECRQ_RS_QH_PW:
13140 gen_helper_precrq_rs_qh_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13142 case OPC_PRECRQU_S_OB_QH:
13144 gen_helper_precrqu_s_ob_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13151 tcg_temp_free(v1_t);
13152 tcg_temp_free(v2_t);
13154 (void)opn; /* avoid a compiler warning */
13155 MIPS_DEBUG("%s", opn);
13158 static void gen_mipsdsp_shift(DisasContext *ctx, uint32_t opc,
13159 int ret, int v1, int v2)
13162 const char *opn = "mipsdsp shift";
13168 /* Treat as NOP. */
13173 t0 = tcg_temp_new();
13174 v1_t = tcg_temp_new();
13175 v2_t = tcg_temp_new();
13177 tcg_gen_movi_tl(t0, v1);
13178 gen_load_gpr(v1_t, v1);
13179 gen_load_gpr(v2_t, v2);
13182 case OPC_SHLL_QB_DSP:
13184 op2 = MASK_SHLL_QB(ctx->opcode);
13188 gen_helper_shll_qb(cpu_gpr[ret], t0, v2_t, cpu_env);
13192 gen_helper_shll_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13196 gen_helper_shll_ph(cpu_gpr[ret], t0, v2_t, cpu_env);
13200 gen_helper_shll_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13202 case OPC_SHLL_S_PH:
13204 gen_helper_shll_s_ph(cpu_gpr[ret], t0, v2_t, cpu_env);
13206 case OPC_SHLLV_S_PH:
13208 gen_helper_shll_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13212 gen_helper_shll_s_w(cpu_gpr[ret], t0, v2_t, cpu_env);
13214 case OPC_SHLLV_S_W:
13216 gen_helper_shll_s_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13220 gen_helper_shrl_qb(cpu_gpr[ret], t0, v2_t);
13224 gen_helper_shrl_qb(cpu_gpr[ret], v1_t, v2_t);
13228 gen_helper_shrl_ph(cpu_gpr[ret], t0, v2_t);
13232 gen_helper_shrl_ph(cpu_gpr[ret], v1_t, v2_t);
13236 gen_helper_shra_qb(cpu_gpr[ret], t0, v2_t);
13238 case OPC_SHRA_R_QB:
13240 gen_helper_shra_r_qb(cpu_gpr[ret], t0, v2_t);
13244 gen_helper_shra_qb(cpu_gpr[ret], v1_t, v2_t);
13246 case OPC_SHRAV_R_QB:
13248 gen_helper_shra_r_qb(cpu_gpr[ret], v1_t, v2_t);
13252 gen_helper_shra_ph(cpu_gpr[ret], t0, v2_t);
13254 case OPC_SHRA_R_PH:
13256 gen_helper_shra_r_ph(cpu_gpr[ret], t0, v2_t);
13260 gen_helper_shra_ph(cpu_gpr[ret], v1_t, v2_t);
13262 case OPC_SHRAV_R_PH:
13264 gen_helper_shra_r_ph(cpu_gpr[ret], v1_t, v2_t);
13268 gen_helper_shra_r_w(cpu_gpr[ret], t0, v2_t);
13270 case OPC_SHRAV_R_W:
13272 gen_helper_shra_r_w(cpu_gpr[ret], v1_t, v2_t);
13274 default: /* Invalid */
13275 MIPS_INVAL("MASK SHLL.QB");
13276 generate_exception(ctx, EXCP_RI);
13281 #ifdef TARGET_MIPS64
13282 case OPC_SHLL_OB_DSP:
13283 op2 = MASK_SHLL_OB(ctx->opcode);
13287 gen_helper_shll_pw(cpu_gpr[ret], v2_t, t0, cpu_env);
13291 gen_helper_shll_pw(cpu_gpr[ret], v2_t, v1_t, cpu_env);
13293 case OPC_SHLL_S_PW:
13295 gen_helper_shll_s_pw(cpu_gpr[ret], v2_t, t0, cpu_env);
13297 case OPC_SHLLV_S_PW:
13299 gen_helper_shll_s_pw(cpu_gpr[ret], v2_t, v1_t, cpu_env);
13303 gen_helper_shll_ob(cpu_gpr[ret], v2_t, t0, cpu_env);
13307 gen_helper_shll_ob(cpu_gpr[ret], v2_t, v1_t, cpu_env);
13311 gen_helper_shll_qh(cpu_gpr[ret], v2_t, t0, cpu_env);
13315 gen_helper_shll_qh(cpu_gpr[ret], v2_t, v1_t, cpu_env);
13317 case OPC_SHLL_S_QH:
13319 gen_helper_shll_s_qh(cpu_gpr[ret], v2_t, t0, cpu_env);
13321 case OPC_SHLLV_S_QH:
13323 gen_helper_shll_s_qh(cpu_gpr[ret], v2_t, v1_t, cpu_env);
13327 gen_helper_shra_ob(cpu_gpr[ret], v2_t, t0);
13331 gen_helper_shra_ob(cpu_gpr[ret], v2_t, v1_t);
13333 case OPC_SHRA_R_OB:
13335 gen_helper_shra_r_ob(cpu_gpr[ret], v2_t, t0);
13337 case OPC_SHRAV_R_OB:
13339 gen_helper_shra_r_ob(cpu_gpr[ret], v2_t, v1_t);
13343 gen_helper_shra_pw(cpu_gpr[ret], v2_t, t0);
13347 gen_helper_shra_pw(cpu_gpr[ret], v2_t, v1_t);
13349 case OPC_SHRA_R_PW:
13351 gen_helper_shra_r_pw(cpu_gpr[ret], v2_t, t0);
13353 case OPC_SHRAV_R_PW:
13355 gen_helper_shra_r_pw(cpu_gpr[ret], v2_t, v1_t);
13359 gen_helper_shra_qh(cpu_gpr[ret], v2_t, t0);
13363 gen_helper_shra_qh(cpu_gpr[ret], v2_t, v1_t);
13365 case OPC_SHRA_R_QH:
13367 gen_helper_shra_r_qh(cpu_gpr[ret], v2_t, t0);
13369 case OPC_SHRAV_R_QH:
13371 gen_helper_shra_r_qh(cpu_gpr[ret], v2_t, v1_t);
13375 gen_helper_shrl_ob(cpu_gpr[ret], v2_t, t0);
13379 gen_helper_shrl_ob(cpu_gpr[ret], v2_t, v1_t);
13383 gen_helper_shrl_qh(cpu_gpr[ret], v2_t, t0);
13387 gen_helper_shrl_qh(cpu_gpr[ret], v2_t, v1_t);
13389 default: /* Invalid */
13390 MIPS_INVAL("MASK SHLL.OB");
13391 generate_exception(ctx, EXCP_RI);
13399 tcg_temp_free(v1_t);
13400 tcg_temp_free(v2_t);
13401 (void)opn; /* avoid a compiler warning */
13402 MIPS_DEBUG("%s", opn);
13405 static void gen_mipsdsp_multiply(DisasContext *ctx, uint32_t op1, uint32_t op2,
13406 int ret, int v1, int v2, int check_ret)
13408 const char *opn = "mipsdsp multiply";
13413 if ((ret == 0) && (check_ret == 1)) {
13414 /* Treat as NOP. */
13419 t0 = tcg_temp_new_i32();
13420 v1_t = tcg_temp_new();
13421 v2_t = tcg_temp_new();
13423 tcg_gen_movi_i32(t0, ret);
13424 gen_load_gpr(v1_t, v1);
13425 gen_load_gpr(v2_t, v2);
13428 /* OPC_MULT_G_2E, OPC_ADDUH_QB_DSP, OPC_MUL_PH_DSP have
13429 * the same mask and op1. */
13430 case OPC_MULT_G_2E:
13433 gen_helper_mul_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13436 gen_helper_mul_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13439 gen_helper_mulq_s_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13441 case OPC_MULQ_RS_W:
13442 gen_helper_mulq_rs_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13446 case OPC_DPA_W_PH_DSP:
13448 case OPC_DPAU_H_QBL:
13450 gen_helper_dpau_h_qbl(t0, v1_t, v2_t, cpu_env);
13452 case OPC_DPAU_H_QBR:
13454 gen_helper_dpau_h_qbr(t0, v1_t, v2_t, cpu_env);
13456 case OPC_DPSU_H_QBL:
13458 gen_helper_dpsu_h_qbl(t0, v1_t, v2_t, cpu_env);
13460 case OPC_DPSU_H_QBR:
13462 gen_helper_dpsu_h_qbr(t0, v1_t, v2_t, cpu_env);
13466 gen_helper_dpa_w_ph(t0, v1_t, v2_t, cpu_env);
13468 case OPC_DPAX_W_PH:
13470 gen_helper_dpax_w_ph(t0, v1_t, v2_t, cpu_env);
13472 case OPC_DPAQ_S_W_PH:
13474 gen_helper_dpaq_s_w_ph(t0, v1_t, v2_t, cpu_env);
13476 case OPC_DPAQX_S_W_PH:
13478 gen_helper_dpaqx_s_w_ph(t0, v1_t, v2_t, cpu_env);
13480 case OPC_DPAQX_SA_W_PH:
13482 gen_helper_dpaqx_sa_w_ph(t0, v1_t, v2_t, cpu_env);
13486 gen_helper_dps_w_ph(t0, v1_t, v2_t, cpu_env);
13488 case OPC_DPSX_W_PH:
13490 gen_helper_dpsx_w_ph(t0, v1_t, v2_t, cpu_env);
13492 case OPC_DPSQ_S_W_PH:
13494 gen_helper_dpsq_s_w_ph(t0, v1_t, v2_t, cpu_env);
13496 case OPC_DPSQX_S_W_PH:
13498 gen_helper_dpsqx_s_w_ph(t0, v1_t, v2_t, cpu_env);
13500 case OPC_DPSQX_SA_W_PH:
13502 gen_helper_dpsqx_sa_w_ph(t0, v1_t, v2_t, cpu_env);
13504 case OPC_MULSAQ_S_W_PH:
13506 gen_helper_mulsaq_s_w_ph(t0, v1_t, v2_t, cpu_env);
13508 case OPC_DPAQ_SA_L_W:
13510 gen_helper_dpaq_sa_l_w(t0, v1_t, v2_t, cpu_env);
13512 case OPC_DPSQ_SA_L_W:
13514 gen_helper_dpsq_sa_l_w(t0, v1_t, v2_t, cpu_env);
13516 case OPC_MAQ_S_W_PHL:
13518 gen_helper_maq_s_w_phl(t0, v1_t, v2_t, cpu_env);
13520 case OPC_MAQ_S_W_PHR:
13522 gen_helper_maq_s_w_phr(t0, v1_t, v2_t, cpu_env);
13524 case OPC_MAQ_SA_W_PHL:
13526 gen_helper_maq_sa_w_phl(t0, v1_t, v2_t, cpu_env);
13528 case OPC_MAQ_SA_W_PHR:
13530 gen_helper_maq_sa_w_phr(t0, v1_t, v2_t, cpu_env);
13532 case OPC_MULSA_W_PH:
13534 gen_helper_mulsa_w_ph(t0, v1_t, v2_t, cpu_env);
13538 #ifdef TARGET_MIPS64
13539 case OPC_DPAQ_W_QH_DSP:
13541 int ac = ret & 0x03;
13542 tcg_gen_movi_i32(t0, ac);
13547 gen_helper_dmadd(v1_t, v2_t, t0, cpu_env);
13551 gen_helper_dmaddu(v1_t, v2_t, t0, cpu_env);
13555 gen_helper_dmsub(v1_t, v2_t, t0, cpu_env);
13559 gen_helper_dmsubu(v1_t, v2_t, t0, cpu_env);
13563 gen_helper_dpa_w_qh(v1_t, v2_t, t0, cpu_env);
13565 case OPC_DPAQ_S_W_QH:
13567 gen_helper_dpaq_s_w_qh(v1_t, v2_t, t0, cpu_env);
13569 case OPC_DPAQ_SA_L_PW:
13571 gen_helper_dpaq_sa_l_pw(v1_t, v2_t, t0, cpu_env);
13573 case OPC_DPAU_H_OBL:
13575 gen_helper_dpau_h_obl(v1_t, v2_t, t0, cpu_env);
13577 case OPC_DPAU_H_OBR:
13579 gen_helper_dpau_h_obr(v1_t, v2_t, t0, cpu_env);
13583 gen_helper_dps_w_qh(v1_t, v2_t, t0, cpu_env);
13585 case OPC_DPSQ_S_W_QH:
13587 gen_helper_dpsq_s_w_qh(v1_t, v2_t, t0, cpu_env);
13589 case OPC_DPSQ_SA_L_PW:
13591 gen_helper_dpsq_sa_l_pw(v1_t, v2_t, t0, cpu_env);
13593 case OPC_DPSU_H_OBL:
13595 gen_helper_dpsu_h_obl(v1_t, v2_t, t0, cpu_env);
13597 case OPC_DPSU_H_OBR:
13599 gen_helper_dpsu_h_obr(v1_t, v2_t, t0, cpu_env);
13601 case OPC_MAQ_S_L_PWL:
13603 gen_helper_maq_s_l_pwl(v1_t, v2_t, t0, cpu_env);
13605 case OPC_MAQ_S_L_PWR:
13607 gen_helper_maq_s_l_pwr(v1_t, v2_t, t0, cpu_env);
13609 case OPC_MAQ_S_W_QHLL:
13611 gen_helper_maq_s_w_qhll(v1_t, v2_t, t0, cpu_env);
13613 case OPC_MAQ_SA_W_QHLL:
13615 gen_helper_maq_sa_w_qhll(v1_t, v2_t, t0, cpu_env);
13617 case OPC_MAQ_S_W_QHLR:
13619 gen_helper_maq_s_w_qhlr(v1_t, v2_t, t0, cpu_env);
13621 case OPC_MAQ_SA_W_QHLR:
13623 gen_helper_maq_sa_w_qhlr(v1_t, v2_t, t0, cpu_env);
13625 case OPC_MAQ_S_W_QHRL:
13627 gen_helper_maq_s_w_qhrl(v1_t, v2_t, t0, cpu_env);
13629 case OPC_MAQ_SA_W_QHRL:
13631 gen_helper_maq_sa_w_qhrl(v1_t, v2_t, t0, cpu_env);
13633 case OPC_MAQ_S_W_QHRR:
13635 gen_helper_maq_s_w_qhrr(v1_t, v2_t, t0, cpu_env);
13637 case OPC_MAQ_SA_W_QHRR:
13639 gen_helper_maq_sa_w_qhrr(v1_t, v2_t, t0, cpu_env);
13641 case OPC_MULSAQ_S_L_PW:
13643 gen_helper_mulsaq_s_l_pw(v1_t, v2_t, t0, cpu_env);
13645 case OPC_MULSAQ_S_W_QH:
13647 gen_helper_mulsaq_s_w_qh(v1_t, v2_t, t0, cpu_env);
13653 case OPC_ADDU_QB_DSP:
13655 case OPC_MULEU_S_PH_QBL:
13657 gen_helper_muleu_s_ph_qbl(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13659 case OPC_MULEU_S_PH_QBR:
13661 gen_helper_muleu_s_ph_qbr(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13663 case OPC_MULQ_RS_PH:
13665 gen_helper_mulq_rs_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13667 case OPC_MULEQ_S_W_PHL:
13669 gen_helper_muleq_s_w_phl(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13671 case OPC_MULEQ_S_W_PHR:
13673 gen_helper_muleq_s_w_phr(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13675 case OPC_MULQ_S_PH:
13677 gen_helper_mulq_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13681 #ifdef TARGET_MIPS64
13682 case OPC_ADDU_OB_DSP:
13684 case OPC_MULEQ_S_PW_QHL:
13686 gen_helper_muleq_s_pw_qhl(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13688 case OPC_MULEQ_S_PW_QHR:
13690 gen_helper_muleq_s_pw_qhr(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13692 case OPC_MULEU_S_QH_OBL:
13694 gen_helper_muleu_s_qh_obl(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13696 case OPC_MULEU_S_QH_OBR:
13698 gen_helper_muleu_s_qh_obr(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13700 case OPC_MULQ_RS_QH:
13702 gen_helper_mulq_rs_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13709 tcg_temp_free_i32(t0);
13710 tcg_temp_free(v1_t);
13711 tcg_temp_free(v2_t);
13713 (void)opn; /* avoid a compiler warning */
13714 MIPS_DEBUG("%s", opn);
13718 static void gen_mipsdsp_bitinsn(CPUMIPSState *env, DisasContext *ctx,
13719 uint32_t op1, uint32_t op2,
13722 const char *opn = "mipsdsp Bit/ Manipulation";
13728 /* Treat as NOP. */
13733 t0 = tcg_temp_new();
13734 val_t = tcg_temp_new();
13735 gen_load_gpr(val_t, val);
13738 case OPC_ABSQ_S_PH_DSP:
13742 gen_helper_bitrev(cpu_gpr[ret], val_t);
13747 target_long result;
13748 imm = (ctx->opcode >> 16) & 0xFF;
13749 result = (uint32_t)imm << 24 |
13750 (uint32_t)imm << 16 |
13751 (uint32_t)imm << 8 |
13753 result = (int32_t)result;
13754 tcg_gen_movi_tl(cpu_gpr[ret], result);
13759 tcg_gen_ext8u_tl(cpu_gpr[ret], val_t);
13760 tcg_gen_shli_tl(t0, cpu_gpr[ret], 8);
13761 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
13762 tcg_gen_shli_tl(t0, cpu_gpr[ret], 16);
13763 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
13764 tcg_gen_ext32s_tl(cpu_gpr[ret], cpu_gpr[ret]);
13769 imm = (ctx->opcode >> 16) & 0x03FF;
13770 tcg_gen_movi_tl(cpu_gpr[ret], \
13771 (target_long)((int32_t)imm << 16 | \
13772 (uint32_t)(uint16_t)imm));
13777 tcg_gen_ext16u_tl(cpu_gpr[ret], val_t);
13778 tcg_gen_shli_tl(t0, cpu_gpr[ret], 16);
13779 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
13780 tcg_gen_ext32s_tl(cpu_gpr[ret], cpu_gpr[ret]);
13784 #ifdef TARGET_MIPS64
13785 case OPC_ABSQ_S_QH_DSP:
13792 imm = (ctx->opcode >> 16) & 0xFF;
13793 temp = ((uint64_t)imm << 8) | (uint64_t)imm;
13794 temp = (temp << 16) | temp;
13795 temp = (temp << 32) | temp;
13796 tcg_gen_movi_tl(cpu_gpr[ret], temp);
13804 imm = (ctx->opcode >> 16) & 0x03FF;
13805 imm = (int16_t)(imm << 6) >> 6;
13806 temp = ((target_long)imm << 32) \
13807 | ((target_long)imm & 0xFFFFFFFF);
13808 tcg_gen_movi_tl(cpu_gpr[ret], temp);
13816 imm = (ctx->opcode >> 16) & 0x03FF;
13817 imm = (int16_t)(imm << 6) >> 6;
13819 temp = ((uint64_t)(uint16_t)imm << 48) |
13820 ((uint64_t)(uint16_t)imm << 32) |
13821 ((uint64_t)(uint16_t)imm << 16) |
13822 (uint64_t)(uint16_t)imm;
13823 tcg_gen_movi_tl(cpu_gpr[ret], temp);
13828 tcg_gen_ext8u_tl(cpu_gpr[ret], val_t);
13829 tcg_gen_shli_tl(t0, cpu_gpr[ret], 8);
13830 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
13831 tcg_gen_shli_tl(t0, cpu_gpr[ret], 16);
13832 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
13833 tcg_gen_shli_tl(t0, cpu_gpr[ret], 32);
13834 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
13838 tcg_gen_ext32u_i64(cpu_gpr[ret], val_t);
13839 tcg_gen_shli_tl(t0, cpu_gpr[ret], 32);
13840 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
13844 tcg_gen_ext16u_tl(cpu_gpr[ret], val_t);
13845 tcg_gen_shli_tl(t0, cpu_gpr[ret], 16);
13846 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
13847 tcg_gen_shli_tl(t0, cpu_gpr[ret], 32);
13848 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
13855 tcg_temp_free(val_t);
13857 (void)opn; /* avoid a compiler warning */
13858 MIPS_DEBUG("%s", opn);
13861 static void gen_mipsdsp_add_cmp_pick(DisasContext *ctx,
13862 uint32_t op1, uint32_t op2,
13863 int ret, int v1, int v2, int check_ret)
13865 const char *opn = "mipsdsp add compare pick";
13871 if ((ret == 0) && (check_ret == 1)) {
13872 /* Treat as NOP. */
13877 t0 = tcg_temp_new_i32();
13878 t1 = tcg_temp_new();
13879 v1_t = tcg_temp_new();
13880 v2_t = tcg_temp_new();
13882 gen_load_gpr(v1_t, v1);
13883 gen_load_gpr(v2_t, v2);
13886 case OPC_APPEND_DSP:
13889 tcg_gen_movi_i32(t0, v2);
13890 gen_helper_append(cpu_gpr[ret], cpu_gpr[ret], v1_t, t0);
13893 tcg_gen_movi_i32(t0, v2);
13894 gen_helper_prepend(cpu_gpr[ret], v1_t, cpu_gpr[ret], t0);
13897 tcg_gen_movi_i32(t0, v2);
13898 gen_helper_balign(cpu_gpr[ret], v1_t, cpu_gpr[ret], t0);
13900 default: /* Invid */
13901 MIPS_INVAL("MASK APPEND");
13902 generate_exception(ctx, EXCP_RI);
13906 case OPC_CMPU_EQ_QB_DSP:
13908 case OPC_CMPU_EQ_QB:
13910 gen_helper_cmpu_eq_qb(v1_t, v2_t, cpu_env);
13912 case OPC_CMPU_LT_QB:
13914 gen_helper_cmpu_lt_qb(v1_t, v2_t, cpu_env);
13916 case OPC_CMPU_LE_QB:
13918 gen_helper_cmpu_le_qb(v1_t, v2_t, cpu_env);
13920 case OPC_CMPGU_EQ_QB:
13922 gen_helper_cmpgu_eq_qb(cpu_gpr[ret], v1_t, v2_t);
13924 case OPC_CMPGU_LT_QB:
13926 gen_helper_cmpgu_lt_qb(cpu_gpr[ret], v1_t, v2_t);
13928 case OPC_CMPGU_LE_QB:
13930 gen_helper_cmpgu_le_qb(cpu_gpr[ret], v1_t, v2_t);
13932 case OPC_CMPGDU_EQ_QB:
13934 gen_helper_cmpgu_eq_qb(t1, v1_t, v2_t);
13935 tcg_gen_mov_tl(cpu_gpr[ret], t1);
13936 tcg_gen_andi_tl(cpu_dspctrl, cpu_dspctrl, 0xF0FFFFFF);
13937 tcg_gen_shli_tl(t1, t1, 24);
13938 tcg_gen_or_tl(cpu_dspctrl, cpu_dspctrl, t1);
13940 case OPC_CMPGDU_LT_QB:
13942 gen_helper_cmpgu_lt_qb(t1, v1_t, v2_t);
13943 tcg_gen_mov_tl(cpu_gpr[ret], t1);
13944 tcg_gen_andi_tl(cpu_dspctrl, cpu_dspctrl, 0xF0FFFFFF);
13945 tcg_gen_shli_tl(t1, t1, 24);
13946 tcg_gen_or_tl(cpu_dspctrl, cpu_dspctrl, t1);
13948 case OPC_CMPGDU_LE_QB:
13950 gen_helper_cmpgu_le_qb(t1, v1_t, v2_t);
13951 tcg_gen_mov_tl(cpu_gpr[ret], t1);
13952 tcg_gen_andi_tl(cpu_dspctrl, cpu_dspctrl, 0xF0FFFFFF);
13953 tcg_gen_shli_tl(t1, t1, 24);
13954 tcg_gen_or_tl(cpu_dspctrl, cpu_dspctrl, t1);
13956 case OPC_CMP_EQ_PH:
13958 gen_helper_cmp_eq_ph(v1_t, v2_t, cpu_env);
13960 case OPC_CMP_LT_PH:
13962 gen_helper_cmp_lt_ph(v1_t, v2_t, cpu_env);
13964 case OPC_CMP_LE_PH:
13966 gen_helper_cmp_le_ph(v1_t, v2_t, cpu_env);
13970 gen_helper_pick_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13974 gen_helper_pick_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13976 case OPC_PACKRL_PH:
13978 gen_helper_packrl_ph(cpu_gpr[ret], v1_t, v2_t);
13982 #ifdef TARGET_MIPS64
13983 case OPC_CMPU_EQ_OB_DSP:
13985 case OPC_CMP_EQ_PW:
13987 gen_helper_cmp_eq_pw(v1_t, v2_t, cpu_env);
13989 case OPC_CMP_LT_PW:
13991 gen_helper_cmp_lt_pw(v1_t, v2_t, cpu_env);
13993 case OPC_CMP_LE_PW:
13995 gen_helper_cmp_le_pw(v1_t, v2_t, cpu_env);
13997 case OPC_CMP_EQ_QH:
13999 gen_helper_cmp_eq_qh(v1_t, v2_t, cpu_env);
14001 case OPC_CMP_LT_QH:
14003 gen_helper_cmp_lt_qh(v1_t, v2_t, cpu_env);
14005 case OPC_CMP_LE_QH:
14007 gen_helper_cmp_le_qh(v1_t, v2_t, cpu_env);
14009 case OPC_CMPGDU_EQ_OB:
14011 gen_helper_cmpgdu_eq_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
14013 case OPC_CMPGDU_LT_OB:
14015 gen_helper_cmpgdu_lt_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
14017 case OPC_CMPGDU_LE_OB:
14019 gen_helper_cmpgdu_le_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
14021 case OPC_CMPGU_EQ_OB:
14023 gen_helper_cmpgu_eq_ob(cpu_gpr[ret], v1_t, v2_t);
14025 case OPC_CMPGU_LT_OB:
14027 gen_helper_cmpgu_lt_ob(cpu_gpr[ret], v1_t, v2_t);
14029 case OPC_CMPGU_LE_OB:
14031 gen_helper_cmpgu_le_ob(cpu_gpr[ret], v1_t, v2_t);
14033 case OPC_CMPU_EQ_OB:
14035 gen_helper_cmpu_eq_ob(v1_t, v2_t, cpu_env);
14037 case OPC_CMPU_LT_OB:
14039 gen_helper_cmpu_lt_ob(v1_t, v2_t, cpu_env);
14041 case OPC_CMPU_LE_OB:
14043 gen_helper_cmpu_le_ob(v1_t, v2_t, cpu_env);
14045 case OPC_PACKRL_PW:
14047 gen_helper_packrl_pw(cpu_gpr[ret], v1_t, v2_t);
14051 gen_helper_pick_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
14055 gen_helper_pick_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
14059 gen_helper_pick_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
14063 case OPC_DAPPEND_DSP:
14066 tcg_gen_movi_i32(t0, v2);
14067 gen_helper_dappend(cpu_gpr[ret], v1_t, cpu_gpr[ret], t0);
14070 tcg_gen_movi_i32(t0, v2);
14071 gen_helper_prependd(cpu_gpr[ret], v1_t, cpu_gpr[ret], t0);
14074 tcg_gen_movi_i32(t0, v2);
14075 gen_helper_prependw(cpu_gpr[ret], v1_t, cpu_gpr[ret], t0);
14078 tcg_gen_movi_i32(t0, v2);
14079 gen_helper_dbalign(cpu_gpr[ret], v1_t, cpu_gpr[ret], t0);
14081 default: /* Invalid */
14082 MIPS_INVAL("MASK DAPPEND");
14083 generate_exception(ctx, EXCP_RI);
14090 tcg_temp_free_i32(t0);
14092 tcg_temp_free(v1_t);
14093 tcg_temp_free(v2_t);
14095 (void)opn; /* avoid a compiler warning */
14096 MIPS_DEBUG("%s", opn);
14099 static void gen_mipsdsp_accinsn(DisasContext *ctx, uint32_t op1, uint32_t op2,
14100 int ret, int v1, int v2, int check_ret)
14103 const char *opn = "mipsdsp accumulator";
14110 if ((ret == 0) && (check_ret == 1)) {
14111 /* Treat as NOP. */
14116 t0 = tcg_temp_new();
14117 t1 = tcg_temp_new();
14118 v1_t = tcg_temp_new();
14119 v2_t = tcg_temp_new();
14121 gen_load_gpr(v1_t, v1);
14122 gen_load_gpr(v2_t, v2);
14125 case OPC_EXTR_W_DSP:
14129 tcg_gen_movi_tl(t0, v2);
14130 tcg_gen_movi_tl(t1, v1);
14131 gen_helper_extr_w(cpu_gpr[ret], t0, t1, cpu_env);
14134 tcg_gen_movi_tl(t0, v2);
14135 tcg_gen_movi_tl(t1, v1);
14136 gen_helper_extr_r_w(cpu_gpr[ret], t0, t1, cpu_env);
14138 case OPC_EXTR_RS_W:
14139 tcg_gen_movi_tl(t0, v2);
14140 tcg_gen_movi_tl(t1, v1);
14141 gen_helper_extr_rs_w(cpu_gpr[ret], t0, t1, cpu_env);
14144 tcg_gen_movi_tl(t0, v2);
14145 tcg_gen_movi_tl(t1, v1);
14146 gen_helper_extr_s_h(cpu_gpr[ret], t0, t1, cpu_env);
14148 case OPC_EXTRV_S_H:
14149 tcg_gen_movi_tl(t0, v2);
14150 gen_helper_extr_s_h(cpu_gpr[ret], t0, v1_t, cpu_env);
14153 tcg_gen_movi_tl(t0, v2);
14154 gen_helper_extr_w(cpu_gpr[ret], t0, v1_t, cpu_env);
14156 case OPC_EXTRV_R_W:
14157 tcg_gen_movi_tl(t0, v2);
14158 gen_helper_extr_r_w(cpu_gpr[ret], t0, v1_t, cpu_env);
14160 case OPC_EXTRV_RS_W:
14161 tcg_gen_movi_tl(t0, v2);
14162 gen_helper_extr_rs_w(cpu_gpr[ret], t0, v1_t, cpu_env);
14165 tcg_gen_movi_tl(t0, v2);
14166 tcg_gen_movi_tl(t1, v1);
14167 gen_helper_extp(cpu_gpr[ret], t0, t1, cpu_env);
14170 tcg_gen_movi_tl(t0, v2);
14171 gen_helper_extp(cpu_gpr[ret], t0, v1_t, cpu_env);
14174 tcg_gen_movi_tl(t0, v2);
14175 tcg_gen_movi_tl(t1, v1);
14176 gen_helper_extpdp(cpu_gpr[ret], t0, t1, cpu_env);
14179 tcg_gen_movi_tl(t0, v2);
14180 gen_helper_extpdp(cpu_gpr[ret], t0, v1_t, cpu_env);
14183 imm = (ctx->opcode >> 20) & 0x3F;
14184 tcg_gen_movi_tl(t0, ret);
14185 tcg_gen_movi_tl(t1, imm);
14186 gen_helper_shilo(t0, t1, cpu_env);
14189 tcg_gen_movi_tl(t0, ret);
14190 gen_helper_shilo(t0, v1_t, cpu_env);
14193 tcg_gen_movi_tl(t0, ret);
14194 gen_helper_mthlip(t0, v1_t, cpu_env);
14197 imm = (ctx->opcode >> 11) & 0x3FF;
14198 tcg_gen_movi_tl(t0, imm);
14199 gen_helper_wrdsp(v1_t, t0, cpu_env);
14202 imm = (ctx->opcode >> 16) & 0x03FF;
14203 tcg_gen_movi_tl(t0, imm);
14204 gen_helper_rddsp(cpu_gpr[ret], t0, cpu_env);
14208 #ifdef TARGET_MIPS64
14209 case OPC_DEXTR_W_DSP:
14213 tcg_gen_movi_tl(t0, ret);
14214 gen_helper_dmthlip(v1_t, t0, cpu_env);
14218 int shift = (ctx->opcode >> 19) & 0x7F;
14219 int ac = (ctx->opcode >> 11) & 0x03;
14220 tcg_gen_movi_tl(t0, shift);
14221 tcg_gen_movi_tl(t1, ac);
14222 gen_helper_dshilo(t0, t1, cpu_env);
14227 int ac = (ctx->opcode >> 11) & 0x03;
14228 tcg_gen_movi_tl(t0, ac);
14229 gen_helper_dshilo(v1_t, t0, cpu_env);
14233 tcg_gen_movi_tl(t0, v2);
14234 tcg_gen_movi_tl(t1, v1);
14236 gen_helper_dextp(cpu_gpr[ret], t0, t1, cpu_env);
14239 tcg_gen_movi_tl(t0, v2);
14240 gen_helper_dextp(cpu_gpr[ret], t0, v1_t, cpu_env);
14243 tcg_gen_movi_tl(t0, v2);
14244 tcg_gen_movi_tl(t1, v1);
14245 gen_helper_dextpdp(cpu_gpr[ret], t0, t1, cpu_env);
14248 tcg_gen_movi_tl(t0, v2);
14249 gen_helper_dextpdp(cpu_gpr[ret], t0, v1_t, cpu_env);
14252 tcg_gen_movi_tl(t0, v2);
14253 tcg_gen_movi_tl(t1, v1);
14254 gen_helper_dextr_l(cpu_gpr[ret], t0, t1, cpu_env);
14256 case OPC_DEXTR_R_L:
14257 tcg_gen_movi_tl(t0, v2);
14258 tcg_gen_movi_tl(t1, v1);
14259 gen_helper_dextr_r_l(cpu_gpr[ret], t0, t1, cpu_env);
14261 case OPC_DEXTR_RS_L:
14262 tcg_gen_movi_tl(t0, v2);
14263 tcg_gen_movi_tl(t1, v1);
14264 gen_helper_dextr_rs_l(cpu_gpr[ret], t0, t1, cpu_env);
14267 tcg_gen_movi_tl(t0, v2);
14268 tcg_gen_movi_tl(t1, v1);
14269 gen_helper_dextr_w(cpu_gpr[ret], t0, t1, cpu_env);
14271 case OPC_DEXTR_R_W:
14272 tcg_gen_movi_tl(t0, v2);
14273 tcg_gen_movi_tl(t1, v1);
14274 gen_helper_dextr_r_w(cpu_gpr[ret], t0, t1, cpu_env);
14276 case OPC_DEXTR_RS_W:
14277 tcg_gen_movi_tl(t0, v2);
14278 tcg_gen_movi_tl(t1, v1);
14279 gen_helper_dextr_rs_w(cpu_gpr[ret], t0, t1, cpu_env);
14281 case OPC_DEXTR_S_H:
14282 tcg_gen_movi_tl(t0, v2);
14283 tcg_gen_movi_tl(t1, v1);
14284 gen_helper_dextr_s_h(cpu_gpr[ret], t0, t1, cpu_env);
14286 case OPC_DEXTRV_S_H:
14287 tcg_gen_movi_tl(t0, v2);
14288 tcg_gen_movi_tl(t1, v1);
14289 gen_helper_dextr_s_h(cpu_gpr[ret], t0, t1, cpu_env);
14292 tcg_gen_movi_tl(t0, v2);
14293 gen_helper_dextr_l(cpu_gpr[ret], t0, v1_t, cpu_env);
14295 case OPC_DEXTRV_R_L:
14296 tcg_gen_movi_tl(t0, v2);
14297 gen_helper_dextr_r_l(cpu_gpr[ret], t0, v1_t, cpu_env);
14299 case OPC_DEXTRV_RS_L:
14300 tcg_gen_movi_tl(t0, v2);
14301 gen_helper_dextr_rs_l(cpu_gpr[ret], t0, v1_t, cpu_env);
14304 tcg_gen_movi_tl(t0, v2);
14305 gen_helper_dextr_w(cpu_gpr[ret], t0, v1_t, cpu_env);
14307 case OPC_DEXTRV_R_W:
14308 tcg_gen_movi_tl(t0, v2);
14309 gen_helper_dextr_r_w(cpu_gpr[ret], t0, v1_t, cpu_env);
14311 case OPC_DEXTRV_RS_W:
14312 tcg_gen_movi_tl(t0, v2);
14313 gen_helper_dextr_rs_w(cpu_gpr[ret], t0, v1_t, cpu_env);
14322 tcg_temp_free(v1_t);
14323 tcg_temp_free(v2_t);
14325 (void)opn; /* avoid a compiler warning */
14326 MIPS_DEBUG("%s", opn);
14329 /* End MIPSDSP functions. */
14331 static void decode_opc (CPUMIPSState *env, DisasContext *ctx, int *is_branch)
14334 int rs, rt, rd, sa;
14335 uint32_t op, op1, op2;
14338 /* make sure instructions are on a word boundary */
14339 if (ctx->pc & 0x3) {
14340 env->CP0_BadVAddr = ctx->pc;
14341 generate_exception(ctx, EXCP_AdEL);
14345 /* Handle blikely not taken case */
14346 if ((ctx->hflags & MIPS_HFLAG_BMASK_BASE) == MIPS_HFLAG_BL) {
14347 int l1 = gen_new_label();
14349 MIPS_DEBUG("blikely condition (" TARGET_FMT_lx ")", ctx->pc + 4);
14350 tcg_gen_brcondi_tl(TCG_COND_NE, bcond, 0, l1);
14351 tcg_gen_movi_i32(hflags, ctx->hflags & ~MIPS_HFLAG_BMASK);
14352 gen_goto_tb(ctx, 1, ctx->pc + 4);
14356 if (unlikely(qemu_loglevel_mask(CPU_LOG_TB_OP | CPU_LOG_TB_OP_OPT))) {
14357 tcg_gen_debug_insn_start(ctx->pc);
14360 op = MASK_OP_MAJOR(ctx->opcode);
14361 rs = (ctx->opcode >> 21) & 0x1f;
14362 rt = (ctx->opcode >> 16) & 0x1f;
14363 rd = (ctx->opcode >> 11) & 0x1f;
14364 sa = (ctx->opcode >> 6) & 0x1f;
14365 imm = (int16_t)ctx->opcode;
14368 op1 = MASK_SPECIAL(ctx->opcode);
14370 case OPC_SLL: /* Shift with immediate */
14372 gen_shift_imm(env, ctx, op1, rd, rt, sa);
14375 switch ((ctx->opcode >> 21) & 0x1f) {
14377 /* rotr is decoded as srl on non-R2 CPUs */
14378 if (env->insn_flags & ISA_MIPS32R2) {
14383 gen_shift_imm(env, ctx, op1, rd, rt, sa);
14386 generate_exception(ctx, EXCP_RI);
14390 case OPC_MOVN: /* Conditional move */
14392 check_insn(env, ctx, ISA_MIPS4 | ISA_MIPS32 |
14393 INSN_LOONGSON2E | INSN_LOONGSON2F);
14394 gen_cond_move(env, ctx, op1, rd, rs, rt);
14396 case OPC_ADD ... OPC_SUBU:
14397 gen_arith(env, ctx, op1, rd, rs, rt);
14399 case OPC_SLLV: /* Shifts */
14401 gen_shift(env, ctx, op1, rd, rs, rt);
14404 switch ((ctx->opcode >> 6) & 0x1f) {
14406 /* rotrv is decoded as srlv on non-R2 CPUs */
14407 if (env->insn_flags & ISA_MIPS32R2) {
14412 gen_shift(env, ctx, op1, rd, rs, rt);
14415 generate_exception(ctx, EXCP_RI);
14419 case OPC_SLT: /* Set on less than */
14421 gen_slt(env, ctx, op1, rd, rs, rt);
14423 case OPC_AND: /* Logic*/
14427 gen_logic(env, ctx, op1, rd, rs, rt);
14429 case OPC_MULT ... OPC_DIVU:
14431 check_insn(env, ctx, INSN_VR54XX);
14432 op1 = MASK_MUL_VR54XX(ctx->opcode);
14433 gen_mul_vr54xx(ctx, op1, rd, rs, rt);
14435 gen_muldiv(ctx, op1, rs, rt);
14437 case OPC_JR ... OPC_JALR:
14438 gen_compute_branch(ctx, op1, 4, rs, rd, sa);
14441 case OPC_TGE ... OPC_TEQ: /* Traps */
14443 gen_trap(ctx, op1, rs, rt, -1);
14445 case OPC_MFHI: /* Move from HI/LO */
14447 gen_HILO(ctx, op1, rd);
14450 case OPC_MTLO: /* Move to HI/LO */
14451 gen_HILO(ctx, op1, rs);
14453 case OPC_PMON: /* Pmon entry point, also R4010 selsl */
14454 #ifdef MIPS_STRICT_STANDARD
14455 MIPS_INVAL("PMON / selsl");
14456 generate_exception(ctx, EXCP_RI);
14458 gen_helper_0e0i(pmon, sa);
14462 generate_exception(ctx, EXCP_SYSCALL);
14463 ctx->bstate = BS_STOP;
14466 generate_exception(ctx, EXCP_BREAK);
14469 #ifdef MIPS_STRICT_STANDARD
14470 MIPS_INVAL("SPIM");
14471 generate_exception(ctx, EXCP_RI);
14473 /* Implemented as RI exception for now. */
14474 MIPS_INVAL("spim (unofficial)");
14475 generate_exception(ctx, EXCP_RI);
14479 /* Treat as NOP. */
14483 check_insn(env, ctx, ISA_MIPS4 | ISA_MIPS32);
14484 if (env->CP0_Config1 & (1 << CP0C1_FP)) {
14485 check_cp1_enabled(ctx);
14486 gen_movci(ctx, rd, rs, (ctx->opcode >> 18) & 0x7,
14487 (ctx->opcode >> 16) & 1);
14489 generate_exception_err(ctx, EXCP_CpU, 1);
14493 #if defined(TARGET_MIPS64)
14494 /* MIPS64 specific opcodes */
14499 check_insn(env, ctx, ISA_MIPS3);
14500 check_mips_64(ctx);
14501 gen_shift_imm(env, ctx, op1, rd, rt, sa);
14504 switch ((ctx->opcode >> 21) & 0x1f) {
14506 /* drotr is decoded as dsrl on non-R2 CPUs */
14507 if (env->insn_flags & ISA_MIPS32R2) {
14512 check_insn(env, ctx, ISA_MIPS3);
14513 check_mips_64(ctx);
14514 gen_shift_imm(env, ctx, op1, rd, rt, sa);
14517 generate_exception(ctx, EXCP_RI);
14522 switch ((ctx->opcode >> 21) & 0x1f) {
14524 /* drotr32 is decoded as dsrl32 on non-R2 CPUs */
14525 if (env->insn_flags & ISA_MIPS32R2) {
14530 check_insn(env, ctx, ISA_MIPS3);
14531 check_mips_64(ctx);
14532 gen_shift_imm(env, ctx, op1, rd, rt, sa);
14535 generate_exception(ctx, EXCP_RI);
14539 case OPC_DADD ... OPC_DSUBU:
14540 check_insn(env, ctx, ISA_MIPS3);
14541 check_mips_64(ctx);
14542 gen_arith(env, ctx, op1, rd, rs, rt);
14546 check_insn(env, ctx, ISA_MIPS3);
14547 check_mips_64(ctx);
14548 gen_shift(env, ctx, op1, rd, rs, rt);
14551 switch ((ctx->opcode >> 6) & 0x1f) {
14553 /* drotrv is decoded as dsrlv on non-R2 CPUs */
14554 if (env->insn_flags & ISA_MIPS32R2) {
14559 check_insn(env, ctx, ISA_MIPS3);
14560 check_mips_64(ctx);
14561 gen_shift(env, ctx, op1, rd, rs, rt);
14564 generate_exception(ctx, EXCP_RI);
14568 case OPC_DMULT ... OPC_DDIVU:
14569 check_insn(env, ctx, ISA_MIPS3);
14570 check_mips_64(ctx);
14571 gen_muldiv(ctx, op1, rs, rt);
14574 default: /* Invalid */
14575 MIPS_INVAL("special");
14576 generate_exception(ctx, EXCP_RI);
14581 op1 = MASK_SPECIAL2(ctx->opcode);
14583 case OPC_MADD ... OPC_MADDU: /* Multiply and add/sub */
14584 case OPC_MSUB ... OPC_MSUBU:
14585 check_insn(env, ctx, ISA_MIPS32);
14586 gen_muldiv(ctx, op1, rs, rt);
14589 gen_arith(env, ctx, op1, rd, rs, rt);
14593 check_insn(env, ctx, ISA_MIPS32);
14594 gen_cl(ctx, op1, rd, rs);
14597 /* XXX: not clear which exception should be raised
14598 * when in debug mode...
14600 check_insn(env, ctx, ISA_MIPS32);
14601 if (!(ctx->hflags & MIPS_HFLAG_DM)) {
14602 generate_exception(ctx, EXCP_DBp);
14604 generate_exception(ctx, EXCP_DBp);
14606 /* Treat as NOP. */
14609 case OPC_DIVU_G_2F:
14610 case OPC_MULT_G_2F:
14611 case OPC_MULTU_G_2F:
14613 case OPC_MODU_G_2F:
14614 check_insn(env, ctx, INSN_LOONGSON2F);
14615 gen_loongson_integer(ctx, op1, rd, rs, rt);
14617 #if defined(TARGET_MIPS64)
14620 check_insn(env, ctx, ISA_MIPS64);
14621 check_mips_64(ctx);
14622 gen_cl(ctx, op1, rd, rs);
14624 case OPC_DMULT_G_2F:
14625 case OPC_DMULTU_G_2F:
14626 case OPC_DDIV_G_2F:
14627 case OPC_DDIVU_G_2F:
14628 case OPC_DMOD_G_2F:
14629 case OPC_DMODU_G_2F:
14630 check_insn(env, ctx, INSN_LOONGSON2F);
14631 gen_loongson_integer(ctx, op1, rd, rs, rt);
14634 default: /* Invalid */
14635 MIPS_INVAL("special2");
14636 generate_exception(ctx, EXCP_RI);
14641 op1 = MASK_SPECIAL3(ctx->opcode);
14645 check_insn(env, ctx, ISA_MIPS32R2);
14646 gen_bitops(ctx, op1, rt, rs, sa, rd);
14649 check_insn(env, ctx, ISA_MIPS32R2);
14650 op2 = MASK_BSHFL(ctx->opcode);
14651 gen_bshfl(ctx, op2, rt, rd);
14654 gen_rdhwr(env, ctx, rt, rd);
14657 check_insn(env, ctx, ASE_MT);
14659 TCGv t0 = tcg_temp_new();
14660 TCGv t1 = tcg_temp_new();
14662 gen_load_gpr(t0, rt);
14663 gen_load_gpr(t1, rs);
14664 gen_helper_fork(t0, t1);
14670 check_insn(env, ctx, ASE_MT);
14672 TCGv t0 = tcg_temp_new();
14674 save_cpu_state(ctx, 1);
14675 gen_load_gpr(t0, rs);
14676 gen_helper_yield(t0, cpu_env, t0);
14677 gen_store_gpr(t0, rd);
14681 case OPC_DIV_G_2E ... OPC_DIVU_G_2E:
14682 case OPC_MOD_G_2E ... OPC_MODU_G_2E:
14683 case OPC_MULT_G_2E ... OPC_MULTU_G_2E:
14684 /* OPC_MULT_G_2E, OPC_ADDUH_QB_DSP, OPC_MUL_PH_DSP have
14685 * the same mask and op1. */
14686 if ((env->insn_flags & ASE_DSPR2) && (op1 == OPC_MULT_G_2E)) {
14687 op2 = MASK_ADDUH_QB(ctx->opcode);
14690 case OPC_ADDUH_R_QB:
14692 case OPC_ADDQH_R_PH:
14694 case OPC_ADDQH_R_W:
14696 case OPC_SUBUH_R_QB:
14698 case OPC_SUBQH_R_PH:
14700 case OPC_SUBQH_R_W:
14701 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
14706 case OPC_MULQ_RS_W:
14707 gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 1);
14710 MIPS_INVAL("MASK ADDUH.QB");
14711 generate_exception(ctx, EXCP_RI);
14714 } else if (env->insn_flags & INSN_LOONGSON2E) {
14715 gen_loongson_integer(ctx, op1, rd, rs, rt);
14717 generate_exception(ctx, EXCP_RI);
14721 op2 = MASK_LX(ctx->opcode);
14723 #if defined(TARGET_MIPS64)
14729 gen_mipsdsp_ld(env, ctx, op2, rd, rs, rt);
14731 default: /* Invalid */
14732 MIPS_INVAL("MASK LX");
14733 generate_exception(ctx, EXCP_RI);
14737 case OPC_ABSQ_S_PH_DSP:
14738 op2 = MASK_ABSQ_S_PH(ctx->opcode);
14740 case OPC_ABSQ_S_QB:
14741 case OPC_ABSQ_S_PH:
14743 case OPC_PRECEQ_W_PHL:
14744 case OPC_PRECEQ_W_PHR:
14745 case OPC_PRECEQU_PH_QBL:
14746 case OPC_PRECEQU_PH_QBR:
14747 case OPC_PRECEQU_PH_QBLA:
14748 case OPC_PRECEQU_PH_QBRA:
14749 case OPC_PRECEU_PH_QBL:
14750 case OPC_PRECEU_PH_QBR:
14751 case OPC_PRECEU_PH_QBLA:
14752 case OPC_PRECEU_PH_QBRA:
14753 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
14760 gen_mipsdsp_bitinsn(env, ctx, op1, op2, rd, rt);
14763 MIPS_INVAL("MASK ABSQ_S.PH");
14764 generate_exception(ctx, EXCP_RI);
14768 case OPC_ADDU_QB_DSP:
14769 op2 = MASK_ADDU_QB(ctx->opcode);
14772 case OPC_ADDQ_S_PH:
14775 case OPC_ADDU_S_QB:
14777 case OPC_ADDU_S_PH:
14779 case OPC_SUBQ_S_PH:
14782 case OPC_SUBU_S_QB:
14784 case OPC_SUBU_S_PH:
14788 case OPC_RADDU_W_QB:
14789 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
14791 case OPC_MULEU_S_PH_QBL:
14792 case OPC_MULEU_S_PH_QBR:
14793 case OPC_MULQ_RS_PH:
14794 case OPC_MULEQ_S_W_PHL:
14795 case OPC_MULEQ_S_W_PHR:
14796 case OPC_MULQ_S_PH:
14797 gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 1);
14799 default: /* Invalid */
14800 MIPS_INVAL("MASK ADDU.QB");
14801 generate_exception(ctx, EXCP_RI);
14806 case OPC_CMPU_EQ_QB_DSP:
14807 op2 = MASK_CMPU_EQ_QB(ctx->opcode);
14809 case OPC_PRECR_SRA_PH_W:
14810 case OPC_PRECR_SRA_R_PH_W:
14811 gen_mipsdsp_arith(ctx, op1, op2, rt, rs, rd);
14813 case OPC_PRECR_QB_PH:
14814 case OPC_PRECRQ_QB_PH:
14815 case OPC_PRECRQ_PH_W:
14816 case OPC_PRECRQ_RS_PH_W:
14817 case OPC_PRECRQU_S_QB_PH:
14818 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
14820 case OPC_CMPU_EQ_QB:
14821 case OPC_CMPU_LT_QB:
14822 case OPC_CMPU_LE_QB:
14823 case OPC_CMP_EQ_PH:
14824 case OPC_CMP_LT_PH:
14825 case OPC_CMP_LE_PH:
14826 gen_mipsdsp_add_cmp_pick(ctx, op1, op2, rd, rs, rt, 0);
14828 case OPC_CMPGU_EQ_QB:
14829 case OPC_CMPGU_LT_QB:
14830 case OPC_CMPGU_LE_QB:
14831 case OPC_CMPGDU_EQ_QB:
14832 case OPC_CMPGDU_LT_QB:
14833 case OPC_CMPGDU_LE_QB:
14836 case OPC_PACKRL_PH:
14837 gen_mipsdsp_add_cmp_pick(ctx, op1, op2, rd, rs, rt, 1);
14839 default: /* Invalid */
14840 MIPS_INVAL("MASK CMPU.EQ.QB");
14841 generate_exception(ctx, EXCP_RI);
14845 case OPC_SHLL_QB_DSP:
14846 gen_mipsdsp_shift(ctx, op1, rd, rs, rt);
14848 case OPC_DPA_W_PH_DSP:
14849 op2 = MASK_DPA_W_PH(ctx->opcode);
14851 case OPC_DPAU_H_QBL:
14852 case OPC_DPAU_H_QBR:
14853 case OPC_DPSU_H_QBL:
14854 case OPC_DPSU_H_QBR:
14856 case OPC_DPAX_W_PH:
14857 case OPC_DPAQ_S_W_PH:
14858 case OPC_DPAQX_S_W_PH:
14859 case OPC_DPAQX_SA_W_PH:
14861 case OPC_DPSX_W_PH:
14862 case OPC_DPSQ_S_W_PH:
14863 case OPC_DPSQX_S_W_PH:
14864 case OPC_DPSQX_SA_W_PH:
14865 case OPC_MULSAQ_S_W_PH:
14866 case OPC_DPAQ_SA_L_W:
14867 case OPC_DPSQ_SA_L_W:
14868 case OPC_MAQ_S_W_PHL:
14869 case OPC_MAQ_S_W_PHR:
14870 case OPC_MAQ_SA_W_PHL:
14871 case OPC_MAQ_SA_W_PHR:
14872 case OPC_MULSA_W_PH:
14873 gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 0);
14875 default: /* Invalid */
14876 MIPS_INVAL("MASK DPAW.PH");
14877 generate_exception(ctx, EXCP_RI);
14882 op2 = MASK_INSV(ctx->opcode);
14894 t0 = tcg_temp_new();
14895 t1 = tcg_temp_new();
14897 gen_load_gpr(t0, rt);
14898 gen_load_gpr(t1, rs);
14900 gen_helper_insv(cpu_gpr[rt], cpu_env, t1, t0);
14906 default: /* Invalid */
14907 MIPS_INVAL("MASK INSV");
14908 generate_exception(ctx, EXCP_RI);
14912 case OPC_APPEND_DSP:
14914 op2 = MASK_APPEND(ctx->opcode);
14915 gen_mipsdsp_add_cmp_pick(ctx, op1, op2, rt, rs, rd, 1);
14917 case OPC_EXTR_W_DSP:
14918 op2 = MASK_EXTR_W(ctx->opcode);
14922 case OPC_EXTR_RS_W:
14924 case OPC_EXTRV_S_H:
14926 case OPC_EXTRV_R_W:
14927 case OPC_EXTRV_RS_W:
14932 gen_mipsdsp_accinsn(ctx, op1, op2, rt, rs, rd, 1);
14935 gen_mipsdsp_accinsn(ctx, op1, op2, rd, rs, rt, 1);
14941 gen_mipsdsp_accinsn(ctx, op1, op2, rd, rs, rt, 0);
14943 default: /* Invalid */
14944 MIPS_INVAL("MASK EXTR.W");
14945 generate_exception(ctx, EXCP_RI);
14949 #if defined(TARGET_MIPS64)
14950 case OPC_DEXTM ... OPC_DEXT:
14951 case OPC_DINSM ... OPC_DINS:
14952 check_insn(env, ctx, ISA_MIPS64R2);
14953 check_mips_64(ctx);
14954 gen_bitops(ctx, op1, rt, rs, sa, rd);
14957 check_insn(env, ctx, ISA_MIPS64R2);
14958 check_mips_64(ctx);
14959 op2 = MASK_DBSHFL(ctx->opcode);
14960 gen_bshfl(ctx, op2, rt, rd);
14962 case OPC_DDIV_G_2E ... OPC_DDIVU_G_2E:
14963 case OPC_DMULT_G_2E ... OPC_DMULTU_G_2E:
14964 case OPC_DMOD_G_2E ... OPC_DMODU_G_2E:
14965 check_insn(env, ctx, INSN_LOONGSON2E);
14966 gen_loongson_integer(ctx, op1, rd, rs, rt);
14968 case OPC_ABSQ_S_QH_DSP:
14969 op2 = MASK_ABSQ_S_QH(ctx->opcode);
14971 case OPC_PRECEQ_L_PWL:
14972 case OPC_PRECEQ_L_PWR:
14973 case OPC_PRECEQ_PW_QHL:
14974 case OPC_PRECEQ_PW_QHR:
14975 case OPC_PRECEQ_PW_QHLA:
14976 case OPC_PRECEQ_PW_QHRA:
14977 case OPC_PRECEQU_QH_OBL:
14978 case OPC_PRECEQU_QH_OBR:
14979 case OPC_PRECEQU_QH_OBLA:
14980 case OPC_PRECEQU_QH_OBRA:
14981 case OPC_PRECEU_QH_OBL:
14982 case OPC_PRECEU_QH_OBR:
14983 case OPC_PRECEU_QH_OBLA:
14984 case OPC_PRECEU_QH_OBRA:
14985 case OPC_ABSQ_S_OB:
14986 case OPC_ABSQ_S_PW:
14987 case OPC_ABSQ_S_QH:
14988 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
14996 gen_mipsdsp_bitinsn(env, ctx, op1, op2, rd, rt);
14998 default: /* Invalid */
14999 MIPS_INVAL("MASK ABSQ_S.QH");
15000 generate_exception(ctx, EXCP_RI);
15004 case OPC_ADDU_OB_DSP:
15005 op2 = MASK_ADDU_OB(ctx->opcode);
15007 case OPC_RADDU_L_OB:
15009 case OPC_SUBQ_S_PW:
15011 case OPC_SUBQ_S_QH:
15013 case OPC_SUBU_S_OB:
15015 case OPC_SUBU_S_QH:
15017 case OPC_SUBUH_R_OB:
15019 case OPC_ADDQ_S_PW:
15021 case OPC_ADDQ_S_QH:
15023 case OPC_ADDU_S_OB:
15025 case OPC_ADDU_S_QH:
15027 case OPC_ADDUH_R_OB:
15028 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
15030 case OPC_MULEQ_S_PW_QHL:
15031 case OPC_MULEQ_S_PW_QHR:
15032 case OPC_MULEU_S_QH_OBL:
15033 case OPC_MULEU_S_QH_OBR:
15034 case OPC_MULQ_RS_QH:
15035 gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 1);
15037 default: /* Invalid */
15038 MIPS_INVAL("MASK ADDU.OB");
15039 generate_exception(ctx, EXCP_RI);
15043 case OPC_CMPU_EQ_OB_DSP:
15044 op2 = MASK_CMPU_EQ_OB(ctx->opcode);
15046 case OPC_PRECR_SRA_QH_PW:
15047 case OPC_PRECR_SRA_R_QH_PW:
15048 /* Return value is rt. */
15049 gen_mipsdsp_arith(ctx, op1, op2, rt, rs, rd);
15051 case OPC_PRECR_OB_QH:
15052 case OPC_PRECRQ_OB_QH:
15053 case OPC_PRECRQ_PW_L:
15054 case OPC_PRECRQ_QH_PW:
15055 case OPC_PRECRQ_RS_QH_PW:
15056 case OPC_PRECRQU_S_OB_QH:
15057 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
15059 case OPC_CMPU_EQ_OB:
15060 case OPC_CMPU_LT_OB:
15061 case OPC_CMPU_LE_OB:
15062 case OPC_CMP_EQ_QH:
15063 case OPC_CMP_LT_QH:
15064 case OPC_CMP_LE_QH:
15065 case OPC_CMP_EQ_PW:
15066 case OPC_CMP_LT_PW:
15067 case OPC_CMP_LE_PW:
15068 gen_mipsdsp_add_cmp_pick(ctx, op1, op2, rd, rs, rt, 0);
15070 case OPC_CMPGDU_EQ_OB:
15071 case OPC_CMPGDU_LT_OB:
15072 case OPC_CMPGDU_LE_OB:
15073 case OPC_CMPGU_EQ_OB:
15074 case OPC_CMPGU_LT_OB:
15075 case OPC_CMPGU_LE_OB:
15076 case OPC_PACKRL_PW:
15080 gen_mipsdsp_add_cmp_pick(ctx, op1, op2, rd, rs, rt, 1);
15082 default: /* Invalid */
15083 MIPS_INVAL("MASK CMPU_EQ.OB");
15084 generate_exception(ctx, EXCP_RI);
15088 case OPC_DAPPEND_DSP:
15090 op2 = MASK_DAPPEND(ctx->opcode);
15091 gen_mipsdsp_add_cmp_pick(ctx, op1, op2, rt, rs, rd, 1);
15093 case OPC_DEXTR_W_DSP:
15094 op2 = MASK_DEXTR_W(ctx->opcode);
15101 case OPC_DEXTR_R_L:
15102 case OPC_DEXTR_RS_L:
15104 case OPC_DEXTR_R_W:
15105 case OPC_DEXTR_RS_W:
15106 case OPC_DEXTR_S_H:
15108 case OPC_DEXTRV_R_L:
15109 case OPC_DEXTRV_RS_L:
15110 case OPC_DEXTRV_S_H:
15112 case OPC_DEXTRV_R_W:
15113 case OPC_DEXTRV_RS_W:
15114 gen_mipsdsp_accinsn(ctx, op1, op2, rt, rs, rd, 1);
15119 gen_mipsdsp_accinsn(ctx, op1, op2, rd, rs, rt, 0);
15121 default: /* Invalid */
15122 MIPS_INVAL("MASK EXTR.W");
15123 generate_exception(ctx, EXCP_RI);
15127 case OPC_DPAQ_W_QH_DSP:
15128 op2 = MASK_DPAQ_W_QH(ctx->opcode);
15130 case OPC_DPAU_H_OBL:
15131 case OPC_DPAU_H_OBR:
15132 case OPC_DPSU_H_OBL:
15133 case OPC_DPSU_H_OBR:
15135 case OPC_DPAQ_S_W_QH:
15137 case OPC_DPSQ_S_W_QH:
15138 case OPC_MULSAQ_S_W_QH:
15139 case OPC_DPAQ_SA_L_PW:
15140 case OPC_DPSQ_SA_L_PW:
15141 case OPC_MULSAQ_S_L_PW:
15142 gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 0);
15144 case OPC_MAQ_S_W_QHLL:
15145 case OPC_MAQ_S_W_QHLR:
15146 case OPC_MAQ_S_W_QHRL:
15147 case OPC_MAQ_S_W_QHRR:
15148 case OPC_MAQ_SA_W_QHLL:
15149 case OPC_MAQ_SA_W_QHLR:
15150 case OPC_MAQ_SA_W_QHRL:
15151 case OPC_MAQ_SA_W_QHRR:
15152 case OPC_MAQ_S_L_PWL:
15153 case OPC_MAQ_S_L_PWR:
15158 gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 0);
15160 default: /* Invalid */
15161 MIPS_INVAL("MASK DPAQ.W.QH");
15162 generate_exception(ctx, EXCP_RI);
15166 case OPC_DINSV_DSP:
15167 op2 = MASK_INSV(ctx->opcode);
15179 t0 = tcg_temp_new();
15180 t1 = tcg_temp_new();
15182 gen_load_gpr(t0, rt);
15183 gen_load_gpr(t1, rs);
15185 gen_helper_dinsv(cpu_gpr[rt], cpu_env, t1, t0);
15188 default: /* Invalid */
15189 MIPS_INVAL("MASK DINSV");
15190 generate_exception(ctx, EXCP_RI);
15194 case OPC_SHLL_OB_DSP:
15195 gen_mipsdsp_shift(ctx, op1, rd, rs, rt);
15198 default: /* Invalid */
15199 MIPS_INVAL("special3");
15200 generate_exception(ctx, EXCP_RI);
15205 op1 = MASK_REGIMM(ctx->opcode);
15207 case OPC_BLTZ ... OPC_BGEZL: /* REGIMM branches */
15208 case OPC_BLTZAL ... OPC_BGEZALL:
15209 gen_compute_branch(ctx, op1, 4, rs, -1, imm << 2);
15212 case OPC_TGEI ... OPC_TEQI: /* REGIMM traps */
15214 gen_trap(ctx, op1, rs, -1, imm);
15217 check_insn(env, ctx, ISA_MIPS32R2);
15218 /* Treat as NOP. */
15220 case OPC_BPOSGE32: /* MIPS DSP branch */
15221 #if defined(TARGET_MIPS64)
15225 gen_compute_branch(ctx, op1, 4, -1, -2, (int32_t)imm << 2);
15228 default: /* Invalid */
15229 MIPS_INVAL("regimm");
15230 generate_exception(ctx, EXCP_RI);
15235 check_cp0_enabled(ctx);
15236 op1 = MASK_CP0(ctx->opcode);
15242 #if defined(TARGET_MIPS64)
15246 #ifndef CONFIG_USER_ONLY
15247 gen_cp0(env, ctx, op1, rt, rd);
15248 #endif /* !CONFIG_USER_ONLY */
15250 case OPC_C0_FIRST ... OPC_C0_LAST:
15251 #ifndef CONFIG_USER_ONLY
15252 gen_cp0(env, ctx, MASK_C0(ctx->opcode), rt, rd);
15253 #endif /* !CONFIG_USER_ONLY */
15256 #ifndef CONFIG_USER_ONLY
15258 TCGv t0 = tcg_temp_new();
15260 op2 = MASK_MFMC0(ctx->opcode);
15263 check_insn(env, ctx, ASE_MT);
15264 gen_helper_dmt(t0);
15265 gen_store_gpr(t0, rt);
15268 check_insn(env, ctx, ASE_MT);
15269 gen_helper_emt(t0);
15270 gen_store_gpr(t0, rt);
15273 check_insn(env, ctx, ASE_MT);
15274 gen_helper_dvpe(t0, cpu_env);
15275 gen_store_gpr(t0, rt);
15278 check_insn(env, ctx, ASE_MT);
15279 gen_helper_evpe(t0, cpu_env);
15280 gen_store_gpr(t0, rt);
15283 check_insn(env, ctx, ISA_MIPS32R2);
15284 save_cpu_state(ctx, 1);
15285 gen_helper_di(t0, cpu_env);
15286 gen_store_gpr(t0, rt);
15287 /* Stop translation as we may have switched the execution mode */
15288 ctx->bstate = BS_STOP;
15291 check_insn(env, ctx, ISA_MIPS32R2);
15292 save_cpu_state(ctx, 1);
15293 gen_helper_ei(t0, cpu_env);
15294 gen_store_gpr(t0, rt);
15295 /* Stop translation as we may have switched the execution mode */
15296 ctx->bstate = BS_STOP;
15298 default: /* Invalid */
15299 MIPS_INVAL("mfmc0");
15300 generate_exception(ctx, EXCP_RI);
15305 #endif /* !CONFIG_USER_ONLY */
15308 check_insn(env, ctx, ISA_MIPS32R2);
15309 gen_load_srsgpr(rt, rd);
15312 check_insn(env, ctx, ISA_MIPS32R2);
15313 gen_store_srsgpr(rt, rd);
15317 generate_exception(ctx, EXCP_RI);
15321 case OPC_ADDI: /* Arithmetic with immediate opcode */
15323 gen_arith_imm(env, ctx, op, rt, rs, imm);
15325 case OPC_SLTI: /* Set on less than with immediate opcode */
15327 gen_slt_imm(env, ctx, op, rt, rs, imm);
15329 case OPC_ANDI: /* Arithmetic with immediate opcode */
15333 gen_logic_imm(env, ctx, op, rt, rs, imm);
15335 case OPC_J ... OPC_JAL: /* Jump */
15336 offset = (int32_t)(ctx->opcode & 0x3FFFFFF) << 2;
15337 gen_compute_branch(ctx, op, 4, rs, rt, offset);
15340 case OPC_BEQ ... OPC_BGTZ: /* Branch */
15341 case OPC_BEQL ... OPC_BGTZL:
15342 gen_compute_branch(ctx, op, 4, rs, rt, imm << 2);
15345 case OPC_LB ... OPC_LWR: /* Load and stores */
15347 gen_ld(env, ctx, op, rt, rs, imm);
15349 case OPC_SB ... OPC_SW:
15351 gen_st(ctx, op, rt, rs, imm);
15354 gen_st_cond(ctx, op, rt, rs, imm);
15357 check_cp0_enabled(ctx);
15358 check_insn(env, ctx, ISA_MIPS3 | ISA_MIPS32);
15359 /* Treat as NOP. */
15362 check_insn(env, ctx, ISA_MIPS4 | ISA_MIPS32);
15363 /* Treat as NOP. */
15366 /* Floating point (COP1). */
15371 gen_cop1_ldst(env, ctx, op, rt, rs, imm);
15375 if (env->CP0_Config1 & (1 << CP0C1_FP)) {
15376 check_cp1_enabled(ctx);
15377 op1 = MASK_CP1(ctx->opcode);
15381 check_insn(env, ctx, ISA_MIPS32R2);
15386 gen_cp1(ctx, op1, rt, rd);
15388 #if defined(TARGET_MIPS64)
15391 check_insn(env, ctx, ISA_MIPS3);
15392 gen_cp1(ctx, op1, rt, rd);
15398 check_insn(env, ctx, ASE_MIPS3D);
15401 gen_compute_branch1(env, ctx, MASK_BC1(ctx->opcode),
15402 (rt >> 2) & 0x7, imm << 2);
15410 gen_farith(ctx, ctx->opcode & FOP(0x3f, 0x1f), rt, rd, sa,
15415 generate_exception (ctx, EXCP_RI);
15419 generate_exception_err(ctx, EXCP_CpU, 1);
15428 /* COP2: Not implemented. */
15429 generate_exception_err(ctx, EXCP_CpU, 2);
15432 check_insn(env, ctx, INSN_LOONGSON2F);
15433 /* Note that these instructions use different fields. */
15434 gen_loongson_multimedia(ctx, sa, rd, rt);
15438 if (env->CP0_Config1 & (1 << CP0C1_FP)) {
15439 check_cp1_enabled(ctx);
15440 op1 = MASK_CP3(ctx->opcode);
15448 gen_flt3_ldst(ctx, op1, sa, rd, rs, rt);
15451 /* Treat as NOP. */
15466 gen_flt3_arith(ctx, op1, sa, rs, rd, rt);
15470 generate_exception (ctx, EXCP_RI);
15474 generate_exception_err(ctx, EXCP_CpU, 1);
15478 #if defined(TARGET_MIPS64)
15479 /* MIPS64 opcodes */
15481 case OPC_LDL ... OPC_LDR:
15484 check_insn(env, ctx, ISA_MIPS3);
15485 check_mips_64(ctx);
15486 gen_ld(env, ctx, op, rt, rs, imm);
15488 case OPC_SDL ... OPC_SDR:
15490 check_insn(env, ctx, ISA_MIPS3);
15491 check_mips_64(ctx);
15492 gen_st(ctx, op, rt, rs, imm);
15495 check_insn(env, ctx, ISA_MIPS3);
15496 check_mips_64(ctx);
15497 gen_st_cond(ctx, op, rt, rs, imm);
15501 check_insn(env, ctx, ISA_MIPS3);
15502 check_mips_64(ctx);
15503 gen_arith_imm(env, ctx, op, rt, rs, imm);
15507 check_insn(env, ctx, ASE_MIPS16 | ASE_MICROMIPS);
15508 offset = (int32_t)(ctx->opcode & 0x3FFFFFF) << 2;
15509 gen_compute_branch(ctx, op, 4, rs, rt, offset);
15513 check_insn(env, ctx, ASE_MDMX);
15514 /* MDMX: Not implemented. */
15515 default: /* Invalid */
15516 MIPS_INVAL("major opcode");
15517 generate_exception(ctx, EXCP_RI);
15523 gen_intermediate_code_internal (CPUMIPSState *env, TranslationBlock *tb,
15527 target_ulong pc_start;
15528 uint16_t *gen_opc_end;
15537 qemu_log("search pc %d\n", search_pc);
15540 gen_opc_end = gen_opc_buf + OPC_MAX_SIZE;
15543 ctx.singlestep_enabled = env->singlestep_enabled;
15545 ctx.bstate = BS_NONE;
15546 /* Restore delay slot state from the tb context. */
15547 ctx.hflags = (uint32_t)tb->flags; /* FIXME: maybe use 64 bits here? */
15548 restore_cpu_state(env, &ctx);
15549 #ifdef CONFIG_USER_ONLY
15550 ctx.mem_idx = MIPS_HFLAG_UM;
15552 ctx.mem_idx = ctx.hflags & MIPS_HFLAG_KSU;
15555 max_insns = tb->cflags & CF_COUNT_MASK;
15556 if (max_insns == 0)
15557 max_insns = CF_COUNT_MASK;
15558 LOG_DISAS("\ntb %p idx %d hflags %04x\n", tb, ctx.mem_idx, ctx.hflags);
15559 gen_icount_start();
15560 while (ctx.bstate == BS_NONE) {
15561 if (unlikely(!QTAILQ_EMPTY(&env->breakpoints))) {
15562 QTAILQ_FOREACH(bp, &env->breakpoints, entry) {
15563 if (bp->pc == ctx.pc) {
15564 save_cpu_state(&ctx, 1);
15565 ctx.bstate = BS_BRANCH;
15566 gen_helper_0e0i(raise_exception, EXCP_DEBUG);
15567 /* Include the breakpoint location or the tb won't
15568 * be flushed when it must be. */
15570 goto done_generating;
15576 j = gen_opc_ptr - gen_opc_buf;
15580 gen_opc_instr_start[lj++] = 0;
15582 gen_opc_pc[lj] = ctx.pc;
15583 gen_opc_hflags[lj] = ctx.hflags & MIPS_HFLAG_BMASK;
15584 gen_opc_instr_start[lj] = 1;
15585 gen_opc_icount[lj] = num_insns;
15587 if (num_insns + 1 == max_insns && (tb->cflags & CF_LAST_IO))
15591 if (!(ctx.hflags & MIPS_HFLAG_M16)) {
15592 ctx.opcode = cpu_ldl_code(env, ctx.pc);
15594 decode_opc(env, &ctx, &is_branch);
15595 } else if (env->insn_flags & ASE_MICROMIPS) {
15596 ctx.opcode = cpu_lduw_code(env, ctx.pc);
15597 insn_bytes = decode_micromips_opc(env, &ctx, &is_branch);
15598 } else if (env->insn_flags & ASE_MIPS16) {
15599 ctx.opcode = cpu_lduw_code(env, ctx.pc);
15600 insn_bytes = decode_mips16_opc(env, &ctx, &is_branch);
15602 generate_exception(&ctx, EXCP_RI);
15603 ctx.bstate = BS_STOP;
15607 handle_delay_slot(env, &ctx, insn_bytes);
15609 ctx.pc += insn_bytes;
15613 /* Execute a branch and its delay slot as a single instruction.
15614 This is what GDB expects and is consistent with what the
15615 hardware does (e.g. if a delay slot instruction faults, the
15616 reported PC is the PC of the branch). */
15617 if (env->singlestep_enabled && (ctx.hflags & MIPS_HFLAG_BMASK) == 0)
15620 if ((ctx.pc & (TARGET_PAGE_SIZE - 1)) == 0)
15623 if (gen_opc_ptr >= gen_opc_end)
15626 if (num_insns >= max_insns)
15632 if (tb->cflags & CF_LAST_IO)
15634 if (env->singlestep_enabled && ctx.bstate != BS_BRANCH) {
15635 save_cpu_state(&ctx, ctx.bstate == BS_NONE);
15636 gen_helper_0e0i(raise_exception, EXCP_DEBUG);
15638 switch (ctx.bstate) {
15640 gen_goto_tb(&ctx, 0, ctx.pc);
15643 save_cpu_state(&ctx, 0);
15644 gen_goto_tb(&ctx, 0, ctx.pc);
15647 tcg_gen_exit_tb(0);
15655 gen_icount_end(tb, num_insns);
15656 *gen_opc_ptr = INDEX_op_end;
15658 j = gen_opc_ptr - gen_opc_buf;
15661 gen_opc_instr_start[lj++] = 0;
15663 tb->size = ctx.pc - pc_start;
15664 tb->icount = num_insns;
15668 if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM)) {
15669 qemu_log("IN: %s\n", lookup_symbol(pc_start));
15670 log_target_disas(pc_start, ctx.pc - pc_start, 0);
15676 void gen_intermediate_code (CPUMIPSState *env, struct TranslationBlock *tb)
15678 gen_intermediate_code_internal(env, tb, 0);
15681 void gen_intermediate_code_pc (CPUMIPSState *env, struct TranslationBlock *tb)
15683 gen_intermediate_code_internal(env, tb, 1);
15686 static void fpu_dump_state(CPUMIPSState *env, FILE *f, fprintf_function fpu_fprintf,
15690 int is_fpu64 = !!(env->hflags & MIPS_HFLAG_F64);
15692 #define printfpr(fp) \
15695 fpu_fprintf(f, "w:%08x d:%016" PRIx64 \
15696 " fd:%13g fs:%13g psu: %13g\n", \
15697 (fp)->w[FP_ENDIAN_IDX], (fp)->d, \
15698 (double)(fp)->fd, \
15699 (double)(fp)->fs[FP_ENDIAN_IDX], \
15700 (double)(fp)->fs[!FP_ENDIAN_IDX]); \
15703 tmp.w[FP_ENDIAN_IDX] = (fp)->w[FP_ENDIAN_IDX]; \
15704 tmp.w[!FP_ENDIAN_IDX] = ((fp) + 1)->w[FP_ENDIAN_IDX]; \
15705 fpu_fprintf(f, "w:%08x d:%016" PRIx64 \
15706 " fd:%13g fs:%13g psu:%13g\n", \
15707 tmp.w[FP_ENDIAN_IDX], tmp.d, \
15709 (double)tmp.fs[FP_ENDIAN_IDX], \
15710 (double)tmp.fs[!FP_ENDIAN_IDX]); \
15715 fpu_fprintf(f, "CP1 FCR0 0x%08x FCR31 0x%08x SR.FR %d fp_status 0x%02x\n",
15716 env->active_fpu.fcr0, env->active_fpu.fcr31, is_fpu64,
15717 get_float_exception_flags(&env->active_fpu.fp_status));
15718 for (i = 0; i < 32; (is_fpu64) ? i++ : (i += 2)) {
15719 fpu_fprintf(f, "%3s: ", fregnames[i]);
15720 printfpr(&env->active_fpu.fpr[i]);
15726 #if defined(TARGET_MIPS64) && defined(MIPS_DEBUG_SIGN_EXTENSIONS)
15727 /* Debug help: The architecture requires 32bit code to maintain proper
15728 sign-extended values on 64bit machines. */
15730 #define SIGN_EXT_P(val) ((((val) & ~0x7fffffff) == 0) || (((val) & ~0x7fffffff) == ~0x7fffffff))
15733 cpu_mips_check_sign_extensions (CPUMIPSState *env, FILE *f,
15734 fprintf_function cpu_fprintf,
15739 if (!SIGN_EXT_P(env->active_tc.PC))
15740 cpu_fprintf(f, "BROKEN: pc=0x" TARGET_FMT_lx "\n", env->active_tc.PC);
15741 if (!SIGN_EXT_P(env->active_tc.HI[0]))
15742 cpu_fprintf(f, "BROKEN: HI=0x" TARGET_FMT_lx "\n", env->active_tc.HI[0]);
15743 if (!SIGN_EXT_P(env->active_tc.LO[0]))
15744 cpu_fprintf(f, "BROKEN: LO=0x" TARGET_FMT_lx "\n", env->active_tc.LO[0]);
15745 if (!SIGN_EXT_P(env->btarget))
15746 cpu_fprintf(f, "BROKEN: btarget=0x" TARGET_FMT_lx "\n", env->btarget);
15748 for (i = 0; i < 32; i++) {
15749 if (!SIGN_EXT_P(env->active_tc.gpr[i]))
15750 cpu_fprintf(f, "BROKEN: %s=0x" TARGET_FMT_lx "\n", regnames[i], env->active_tc.gpr[i]);
15753 if (!SIGN_EXT_P(env->CP0_EPC))
15754 cpu_fprintf(f, "BROKEN: EPC=0x" TARGET_FMT_lx "\n", env->CP0_EPC);
15755 if (!SIGN_EXT_P(env->lladdr))
15756 cpu_fprintf(f, "BROKEN: LLAddr=0x" TARGET_FMT_lx "\n", env->lladdr);
15760 void cpu_dump_state (CPUMIPSState *env, FILE *f, fprintf_function cpu_fprintf,
15765 cpu_fprintf(f, "pc=0x" TARGET_FMT_lx " HI=0x" TARGET_FMT_lx
15766 " LO=0x" TARGET_FMT_lx " ds %04x "
15767 TARGET_FMT_lx " " TARGET_FMT_ld "\n",
15768 env->active_tc.PC, env->active_tc.HI[0], env->active_tc.LO[0],
15769 env->hflags, env->btarget, env->bcond);
15770 for (i = 0; i < 32; i++) {
15772 cpu_fprintf(f, "GPR%02d:", i);
15773 cpu_fprintf(f, " %s " TARGET_FMT_lx, regnames[i], env->active_tc.gpr[i]);
15775 cpu_fprintf(f, "\n");
15778 cpu_fprintf(f, "CP0 Status 0x%08x Cause 0x%08x EPC 0x" TARGET_FMT_lx "\n",
15779 env->CP0_Status, env->CP0_Cause, env->CP0_EPC);
15780 cpu_fprintf(f, " Config0 0x%08x Config1 0x%08x LLAddr 0x" TARGET_FMT_lx "\n",
15781 env->CP0_Config0, env->CP0_Config1, env->lladdr);
15782 if (env->hflags & MIPS_HFLAG_FPU)
15783 fpu_dump_state(env, f, cpu_fprintf, flags);
15784 #if defined(TARGET_MIPS64) && defined(MIPS_DEBUG_SIGN_EXTENSIONS)
15785 cpu_mips_check_sign_extensions(env, f, cpu_fprintf, flags);
15789 static void mips_tcg_init(void)
15794 /* Initialize various static tables. */
15798 cpu_env = tcg_global_reg_new_ptr(TCG_AREG0, "env");
15799 TCGV_UNUSED(cpu_gpr[0]);
15800 for (i = 1; i < 32; i++)
15801 cpu_gpr[i] = tcg_global_mem_new(TCG_AREG0,
15802 offsetof(CPUMIPSState, active_tc.gpr[i]),
15805 for (i = 0; i < 32; i++) {
15806 int off = offsetof(CPUMIPSState, active_fpu.fpr[i]);
15807 fpu_f64[i] = tcg_global_mem_new_i64(TCG_AREG0, off, fregnames[i]);
15810 cpu_PC = tcg_global_mem_new(TCG_AREG0,
15811 offsetof(CPUMIPSState, active_tc.PC), "PC");
15812 for (i = 0; i < MIPS_DSP_ACC; i++) {
15813 cpu_HI[i] = tcg_global_mem_new(TCG_AREG0,
15814 offsetof(CPUMIPSState, active_tc.HI[i]),
15816 cpu_LO[i] = tcg_global_mem_new(TCG_AREG0,
15817 offsetof(CPUMIPSState, active_tc.LO[i]),
15819 cpu_ACX[i] = tcg_global_mem_new(TCG_AREG0,
15820 offsetof(CPUMIPSState, active_tc.ACX[i]),
15823 cpu_dspctrl = tcg_global_mem_new(TCG_AREG0,
15824 offsetof(CPUMIPSState, active_tc.DSPControl),
15826 bcond = tcg_global_mem_new(TCG_AREG0,
15827 offsetof(CPUMIPSState, bcond), "bcond");
15828 btarget = tcg_global_mem_new(TCG_AREG0,
15829 offsetof(CPUMIPSState, btarget), "btarget");
15830 hflags = tcg_global_mem_new_i32(TCG_AREG0,
15831 offsetof(CPUMIPSState, hflags), "hflags");
15833 fpu_fcr0 = tcg_global_mem_new_i32(TCG_AREG0,
15834 offsetof(CPUMIPSState, active_fpu.fcr0),
15836 fpu_fcr31 = tcg_global_mem_new_i32(TCG_AREG0,
15837 offsetof(CPUMIPSState, active_fpu.fcr31),
15840 /* register helpers */
15841 #define GEN_HELPER 2
15842 #include "helper.h"
15847 #include "translate_init.c"
15849 MIPSCPU *cpu_mips_init(const char *cpu_model)
15853 const mips_def_t *def;
15855 def = cpu_mips_find_by_name(cpu_model);
15858 cpu = MIPS_CPU(object_new(TYPE_MIPS_CPU));
15860 env->cpu_model = def;
15861 env->cpu_model_str = cpu_model;
15863 #ifndef CONFIG_USER_ONLY
15864 mmu_init(env, def);
15866 fpu_init(env, def);
15867 mvp_init(env, def);
15869 cpu_reset(CPU(cpu));
15870 qemu_init_vcpu(env);
15874 void cpu_state_reset(CPUMIPSState *env)
15876 if (qemu_loglevel_mask(CPU_LOG_RESET)) {
15877 qemu_log("CPU Reset (CPU %d)\n", env->cpu_index);
15878 log_cpu_state(env, 0);
15881 memset(env, 0, offsetof(CPUMIPSState, breakpoints));
15884 /* Reset registers to their default values */
15885 env->CP0_PRid = env->cpu_model->CP0_PRid;
15886 env->CP0_Config0 = env->cpu_model->CP0_Config0;
15887 #ifdef TARGET_WORDS_BIGENDIAN
15888 env->CP0_Config0 |= (1 << CP0C0_BE);
15890 env->CP0_Config1 = env->cpu_model->CP0_Config1;
15891 env->CP0_Config2 = env->cpu_model->CP0_Config2;
15892 env->CP0_Config3 = env->cpu_model->CP0_Config3;
15893 env->CP0_Config6 = env->cpu_model->CP0_Config6;
15894 env->CP0_Config7 = env->cpu_model->CP0_Config7;
15895 env->CP0_LLAddr_rw_bitmask = env->cpu_model->CP0_LLAddr_rw_bitmask
15896 << env->cpu_model->CP0_LLAddr_shift;
15897 env->CP0_LLAddr_shift = env->cpu_model->CP0_LLAddr_shift;
15898 env->SYNCI_Step = env->cpu_model->SYNCI_Step;
15899 env->CCRes = env->cpu_model->CCRes;
15900 env->CP0_Status_rw_bitmask = env->cpu_model->CP0_Status_rw_bitmask;
15901 env->CP0_TCStatus_rw_bitmask = env->cpu_model->CP0_TCStatus_rw_bitmask;
15902 env->CP0_SRSCtl = env->cpu_model->CP0_SRSCtl;
15903 env->current_tc = 0;
15904 env->SEGBITS = env->cpu_model->SEGBITS;
15905 env->SEGMask = (target_ulong)((1ULL << env->cpu_model->SEGBITS) - 1);
15906 #if defined(TARGET_MIPS64)
15907 if (env->cpu_model->insn_flags & ISA_MIPS3) {
15908 env->SEGMask |= 3ULL << 62;
15911 env->PABITS = env->cpu_model->PABITS;
15912 env->PAMask = (target_ulong)((1ULL << env->cpu_model->PABITS) - 1);
15913 env->CP0_SRSConf0_rw_bitmask = env->cpu_model->CP0_SRSConf0_rw_bitmask;
15914 env->CP0_SRSConf0 = env->cpu_model->CP0_SRSConf0;
15915 env->CP0_SRSConf1_rw_bitmask = env->cpu_model->CP0_SRSConf1_rw_bitmask;
15916 env->CP0_SRSConf1 = env->cpu_model->CP0_SRSConf1;
15917 env->CP0_SRSConf2_rw_bitmask = env->cpu_model->CP0_SRSConf2_rw_bitmask;
15918 env->CP0_SRSConf2 = env->cpu_model->CP0_SRSConf2;
15919 env->CP0_SRSConf3_rw_bitmask = env->cpu_model->CP0_SRSConf3_rw_bitmask;
15920 env->CP0_SRSConf3 = env->cpu_model->CP0_SRSConf3;
15921 env->CP0_SRSConf4_rw_bitmask = env->cpu_model->CP0_SRSConf4_rw_bitmask;
15922 env->CP0_SRSConf4 = env->cpu_model->CP0_SRSConf4;
15923 env->active_fpu.fcr0 = env->cpu_model->CP1_fcr0;
15924 env->insn_flags = env->cpu_model->insn_flags;
15926 #if defined(CONFIG_USER_ONLY)
15927 env->CP0_Status = (MIPS_HFLAG_UM << CP0St_KSU);
15928 /* Enable access to the CPUNum, SYNCI_Step, CC, and CCRes RDHWR
15929 hardware registers. */
15930 env->CP0_HWREna |= 0x0000000F;
15931 if (env->CP0_Config1 & (1 << CP0C1_FP)) {
15932 env->CP0_Status |= (1 << CP0St_CU1);
15934 if (env->cpu_model->insn_flags & ASE_DSPR2) {
15935 env->hflags |= MIPS_HFLAG_DSP | MIPS_HFLAG_DSPR2;
15936 } else if (env->cpu_model->insn_flags & ASE_DSP) {
15937 env->hflags |= MIPS_HFLAG_DSP;
15940 if (env->hflags & MIPS_HFLAG_BMASK) {
15941 /* If the exception was raised from a delay slot,
15942 come back to the jump. */
15943 env->CP0_ErrorEPC = env->active_tc.PC - 4;
15945 env->CP0_ErrorEPC = env->active_tc.PC;
15947 env->active_tc.PC = (int32_t)0xBFC00000;
15948 env->CP0_Random = env->tlb->nb_tlb - 1;
15949 env->tlb->tlb_in_use = env->tlb->nb_tlb;
15950 env->CP0_Wired = 0;
15951 env->CP0_EBase = 0x80000000 | (env->cpu_index & 0x3FF);
15952 env->CP0_Status = (1 << CP0St_BEV) | (1 << CP0St_ERL);
15953 /* vectored interrupts not implemented, timer on int 7,
15954 no performance counters. */
15955 env->CP0_IntCtl = 0xe0000000;
15959 for (i = 0; i < 7; i++) {
15960 env->CP0_WatchLo[i] = 0;
15961 env->CP0_WatchHi[i] = 0x80000000;
15963 env->CP0_WatchLo[7] = 0;
15964 env->CP0_WatchHi[7] = 0;
15966 /* Count register increments in debug mode, EJTAG version 1 */
15967 env->CP0_Debug = (1 << CP0DB_CNT) | (0x1 << CP0DB_VER);
15969 if (env->CP0_Config3 & (1 << CP0C3_MT)) {
15972 /* Only TC0 on VPE 0 starts as active. */
15973 for (i = 0; i < ARRAY_SIZE(env->tcs); i++) {
15974 env->tcs[i].CP0_TCBind = env->cpu_index << CP0TCBd_CurVPE;
15975 env->tcs[i].CP0_TCHalt = 1;
15977 env->active_tc.CP0_TCHalt = 1;
15980 if (!env->cpu_index) {
15981 /* VPE0 starts up enabled. */
15982 env->mvp->CP0_MVPControl |= (1 << CP0MVPCo_EVP);
15983 env->CP0_VPEConf0 |= (1 << CP0VPEC0_MVP) | (1 << CP0VPEC0_VPA);
15985 /* TC0 starts up unhalted. */
15987 env->active_tc.CP0_TCHalt = 0;
15988 env->tcs[0].CP0_TCHalt = 0;
15989 /* With thread 0 active. */
15990 env->active_tc.CP0_TCStatus = (1 << CP0TCSt_A);
15991 env->tcs[0].CP0_TCStatus = (1 << CP0TCSt_A);
15995 compute_hflags(env);
15996 env->exception_index = EXCP_NONE;
15999 void restore_state_to_opc(CPUMIPSState *env, TranslationBlock *tb, int pc_pos)
16001 env->active_tc.PC = gen_opc_pc[pc_pos];
16002 env->hflags &= ~MIPS_HFLAG_BMASK;
16003 env->hflags |= gen_opc_hflags[pc_pos];