2 * MIPS32 emulation for qemu: main translation routines.
4 * Copyright (c) 2004-2005 Jocelyn Mayer
5 * Copyright (c) 2006 Marius Groeger (FPU operations)
6 * Copyright (c) 2006 Thiemo Seufer (MIPS32R2 support)
7 * Copyright (c) 2009 CodeSourcery (MIPS16 and microMIPS support)
8 * Copyright (c) 2012 Jia Liu & Dongxue Zhang (MIPS ASE DSP support)
10 * This library is free software; you can redistribute it and/or
11 * modify it under the terms of the GNU Lesser General Public
12 * License as published by the Free Software Foundation; either
13 * version 2 of the License, or (at your option) any later version.
15 * This library is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
18 * Lesser General Public License for more details.
20 * You should have received a copy of the GNU Lesser General Public
21 * License along with this library; if not, see <http://www.gnu.org/licenses/>.
32 #define MIPS_DEBUG_DISAS 0
33 //#define MIPS_DEBUG_SIGN_EXTENSIONS
35 /* MIPS major opcodes */
36 #define MASK_OP_MAJOR(op) (op & (0x3F << 26))
39 /* indirect opcode tables */
40 OPC_SPECIAL = (0x00 << 26),
41 OPC_REGIMM = (0x01 << 26),
42 OPC_CP0 = (0x10 << 26),
43 OPC_CP1 = (0x11 << 26),
44 OPC_CP2 = (0x12 << 26),
45 OPC_CP3 = (0x13 << 26),
46 OPC_SPECIAL2 = (0x1C << 26),
47 OPC_SPECIAL3 = (0x1F << 26),
48 /* arithmetic with immediate */
49 OPC_ADDI = (0x08 << 26),
50 OPC_ADDIU = (0x09 << 26),
51 OPC_SLTI = (0x0A << 26),
52 OPC_SLTIU = (0x0B << 26),
53 /* logic with immediate */
54 OPC_ANDI = (0x0C << 26),
55 OPC_ORI = (0x0D << 26),
56 OPC_XORI = (0x0E << 26),
57 OPC_LUI = (0x0F << 26),
58 /* arithmetic with immediate */
59 OPC_DADDI = (0x18 << 26),
60 OPC_DADDIU = (0x19 << 26),
61 /* Jump and branches */
63 OPC_JAL = (0x03 << 26),
64 OPC_JALS = OPC_JAL | 0x5,
65 OPC_BEQ = (0x04 << 26), /* Unconditional if rs = rt = 0 (B) */
66 OPC_BEQL = (0x14 << 26),
67 OPC_BNE = (0x05 << 26),
68 OPC_BNEL = (0x15 << 26),
69 OPC_BLEZ = (0x06 << 26),
70 OPC_BLEZL = (0x16 << 26),
71 OPC_BGTZ = (0x07 << 26),
72 OPC_BGTZL = (0x17 << 26),
73 OPC_JALX = (0x1D << 26), /* MIPS 16 only */
74 OPC_JALXS = OPC_JALX | 0x5,
76 OPC_LDL = (0x1A << 26),
77 OPC_LDR = (0x1B << 26),
78 OPC_LB = (0x20 << 26),
79 OPC_LH = (0x21 << 26),
80 OPC_LWL = (0x22 << 26),
81 OPC_LW = (0x23 << 26),
82 OPC_LWPC = OPC_LW | 0x5,
83 OPC_LBU = (0x24 << 26),
84 OPC_LHU = (0x25 << 26),
85 OPC_LWR = (0x26 << 26),
86 OPC_LWU = (0x27 << 26),
87 OPC_SB = (0x28 << 26),
88 OPC_SH = (0x29 << 26),
89 OPC_SWL = (0x2A << 26),
90 OPC_SW = (0x2B << 26),
91 OPC_SDL = (0x2C << 26),
92 OPC_SDR = (0x2D << 26),
93 OPC_SWR = (0x2E << 26),
94 OPC_LL = (0x30 << 26),
95 OPC_LLD = (0x34 << 26),
96 OPC_LD = (0x37 << 26),
97 OPC_LDPC = OPC_LD | 0x5,
98 OPC_SC = (0x38 << 26),
99 OPC_SCD = (0x3C << 26),
100 OPC_SD = (0x3F << 26),
101 /* Floating point load/store */
102 OPC_LWC1 = (0x31 << 26),
103 OPC_LWC2 = (0x32 << 26),
104 OPC_LDC1 = (0x35 << 26),
105 OPC_LDC2 = (0x36 << 26),
106 OPC_SWC1 = (0x39 << 26),
107 OPC_SWC2 = (0x3A << 26),
108 OPC_SDC1 = (0x3D << 26),
109 OPC_SDC2 = (0x3E << 26),
110 /* MDMX ASE specific */
111 OPC_MDMX = (0x1E << 26),
112 /* Cache and prefetch */
113 OPC_CACHE = (0x2F << 26),
114 OPC_PREF = (0x33 << 26),
115 /* Reserved major opcode */
116 OPC_MAJOR3B_RESERVED = (0x3B << 26),
119 /* MIPS special opcodes */
120 #define MASK_SPECIAL(op) MASK_OP_MAJOR(op) | (op & 0x3F)
124 OPC_SLL = 0x00 | OPC_SPECIAL,
125 /* NOP is SLL r0, r0, 0 */
126 /* SSNOP is SLL r0, r0, 1 */
127 /* EHB is SLL r0, r0, 3 */
128 OPC_SRL = 0x02 | OPC_SPECIAL, /* also ROTR */
129 OPC_ROTR = OPC_SRL | (1 << 21),
130 OPC_SRA = 0x03 | OPC_SPECIAL,
131 OPC_SLLV = 0x04 | OPC_SPECIAL,
132 OPC_SRLV = 0x06 | OPC_SPECIAL, /* also ROTRV */
133 OPC_ROTRV = OPC_SRLV | (1 << 6),
134 OPC_SRAV = 0x07 | OPC_SPECIAL,
135 OPC_DSLLV = 0x14 | OPC_SPECIAL,
136 OPC_DSRLV = 0x16 | OPC_SPECIAL, /* also DROTRV */
137 OPC_DROTRV = OPC_DSRLV | (1 << 6),
138 OPC_DSRAV = 0x17 | OPC_SPECIAL,
139 OPC_DSLL = 0x38 | OPC_SPECIAL,
140 OPC_DSRL = 0x3A | OPC_SPECIAL, /* also DROTR */
141 OPC_DROTR = OPC_DSRL | (1 << 21),
142 OPC_DSRA = 0x3B | OPC_SPECIAL,
143 OPC_DSLL32 = 0x3C | OPC_SPECIAL,
144 OPC_DSRL32 = 0x3E | OPC_SPECIAL, /* also DROTR32 */
145 OPC_DROTR32 = OPC_DSRL32 | (1 << 21),
146 OPC_DSRA32 = 0x3F | OPC_SPECIAL,
147 /* Multiplication / division */
148 OPC_MULT = 0x18 | OPC_SPECIAL,
149 OPC_MULTU = 0x19 | OPC_SPECIAL,
150 OPC_DIV = 0x1A | OPC_SPECIAL,
151 OPC_DIVU = 0x1B | OPC_SPECIAL,
152 OPC_DMULT = 0x1C | OPC_SPECIAL,
153 OPC_DMULTU = 0x1D | OPC_SPECIAL,
154 OPC_DDIV = 0x1E | OPC_SPECIAL,
155 OPC_DDIVU = 0x1F | OPC_SPECIAL,
156 /* 2 registers arithmetic / logic */
157 OPC_ADD = 0x20 | OPC_SPECIAL,
158 OPC_ADDU = 0x21 | OPC_SPECIAL,
159 OPC_SUB = 0x22 | OPC_SPECIAL,
160 OPC_SUBU = 0x23 | OPC_SPECIAL,
161 OPC_AND = 0x24 | OPC_SPECIAL,
162 OPC_OR = 0x25 | OPC_SPECIAL,
163 OPC_XOR = 0x26 | OPC_SPECIAL,
164 OPC_NOR = 0x27 | OPC_SPECIAL,
165 OPC_SLT = 0x2A | OPC_SPECIAL,
166 OPC_SLTU = 0x2B | OPC_SPECIAL,
167 OPC_DADD = 0x2C | OPC_SPECIAL,
168 OPC_DADDU = 0x2D | OPC_SPECIAL,
169 OPC_DSUB = 0x2E | OPC_SPECIAL,
170 OPC_DSUBU = 0x2F | OPC_SPECIAL,
172 OPC_JR = 0x08 | OPC_SPECIAL, /* Also JR.HB */
173 OPC_JALR = 0x09 | OPC_SPECIAL, /* Also JALR.HB */
174 OPC_JALRC = OPC_JALR | (0x5 << 6),
175 OPC_JALRS = 0x10 | OPC_SPECIAL | (0x5 << 6),
177 OPC_TGE = 0x30 | OPC_SPECIAL,
178 OPC_TGEU = 0x31 | OPC_SPECIAL,
179 OPC_TLT = 0x32 | OPC_SPECIAL,
180 OPC_TLTU = 0x33 | OPC_SPECIAL,
181 OPC_TEQ = 0x34 | OPC_SPECIAL,
182 OPC_TNE = 0x36 | OPC_SPECIAL,
183 /* HI / LO registers load & stores */
184 OPC_MFHI = 0x10 | OPC_SPECIAL,
185 OPC_MTHI = 0x11 | OPC_SPECIAL,
186 OPC_MFLO = 0x12 | OPC_SPECIAL,
187 OPC_MTLO = 0x13 | OPC_SPECIAL,
188 /* Conditional moves */
189 OPC_MOVZ = 0x0A | OPC_SPECIAL,
190 OPC_MOVN = 0x0B | OPC_SPECIAL,
192 OPC_MOVCI = 0x01 | OPC_SPECIAL,
195 OPC_PMON = 0x05 | OPC_SPECIAL, /* unofficial */
196 OPC_SYSCALL = 0x0C | OPC_SPECIAL,
197 OPC_BREAK = 0x0D | OPC_SPECIAL,
198 OPC_SPIM = 0x0E | OPC_SPECIAL, /* unofficial */
199 OPC_SYNC = 0x0F | OPC_SPECIAL,
201 OPC_SPECIAL15_RESERVED = 0x15 | OPC_SPECIAL,
202 OPC_SPECIAL28_RESERVED = 0x28 | OPC_SPECIAL,
203 OPC_SPECIAL29_RESERVED = 0x29 | OPC_SPECIAL,
204 OPC_SPECIAL35_RESERVED = 0x35 | OPC_SPECIAL,
205 OPC_SPECIAL37_RESERVED = 0x37 | OPC_SPECIAL,
206 OPC_SPECIAL39_RESERVED = 0x39 | OPC_SPECIAL,
207 OPC_SPECIAL3D_RESERVED = 0x3D | OPC_SPECIAL,
210 /* Multiplication variants of the vr54xx. */
211 #define MASK_MUL_VR54XX(op) MASK_SPECIAL(op) | (op & (0x1F << 6))
214 OPC_VR54XX_MULS = (0x03 << 6) | OPC_MULT,
215 OPC_VR54XX_MULSU = (0x03 << 6) | OPC_MULTU,
216 OPC_VR54XX_MACC = (0x05 << 6) | OPC_MULT,
217 OPC_VR54XX_MACCU = (0x05 << 6) | OPC_MULTU,
218 OPC_VR54XX_MSAC = (0x07 << 6) | OPC_MULT,
219 OPC_VR54XX_MSACU = (0x07 << 6) | OPC_MULTU,
220 OPC_VR54XX_MULHI = (0x09 << 6) | OPC_MULT,
221 OPC_VR54XX_MULHIU = (0x09 << 6) | OPC_MULTU,
222 OPC_VR54XX_MULSHI = (0x0B << 6) | OPC_MULT,
223 OPC_VR54XX_MULSHIU = (0x0B << 6) | OPC_MULTU,
224 OPC_VR54XX_MACCHI = (0x0D << 6) | OPC_MULT,
225 OPC_VR54XX_MACCHIU = (0x0D << 6) | OPC_MULTU,
226 OPC_VR54XX_MSACHI = (0x0F << 6) | OPC_MULT,
227 OPC_VR54XX_MSACHIU = (0x0F << 6) | OPC_MULTU,
230 /* REGIMM (rt field) opcodes */
231 #define MASK_REGIMM(op) MASK_OP_MAJOR(op) | (op & (0x1F << 16))
234 OPC_BLTZ = (0x00 << 16) | OPC_REGIMM,
235 OPC_BLTZL = (0x02 << 16) | OPC_REGIMM,
236 OPC_BGEZ = (0x01 << 16) | OPC_REGIMM,
237 OPC_BGEZL = (0x03 << 16) | OPC_REGIMM,
238 OPC_BLTZAL = (0x10 << 16) | OPC_REGIMM,
239 OPC_BLTZALS = OPC_BLTZAL | 0x5, /* microMIPS */
240 OPC_BLTZALL = (0x12 << 16) | OPC_REGIMM,
241 OPC_BGEZAL = (0x11 << 16) | OPC_REGIMM,
242 OPC_BGEZALS = OPC_BGEZAL | 0x5, /* microMIPS */
243 OPC_BGEZALL = (0x13 << 16) | OPC_REGIMM,
244 OPC_TGEI = (0x08 << 16) | OPC_REGIMM,
245 OPC_TGEIU = (0x09 << 16) | OPC_REGIMM,
246 OPC_TLTI = (0x0A << 16) | OPC_REGIMM,
247 OPC_TLTIU = (0x0B << 16) | OPC_REGIMM,
248 OPC_TEQI = (0x0C << 16) | OPC_REGIMM,
249 OPC_TNEI = (0x0E << 16) | OPC_REGIMM,
250 OPC_SYNCI = (0x1F << 16) | OPC_REGIMM,
253 /* Special2 opcodes */
254 #define MASK_SPECIAL2(op) MASK_OP_MAJOR(op) | (op & 0x3F)
257 /* Multiply & xxx operations */
258 OPC_MADD = 0x00 | OPC_SPECIAL2,
259 OPC_MADDU = 0x01 | OPC_SPECIAL2,
260 OPC_MUL = 0x02 | OPC_SPECIAL2,
261 OPC_MSUB = 0x04 | OPC_SPECIAL2,
262 OPC_MSUBU = 0x05 | OPC_SPECIAL2,
264 OPC_MULT_G_2F = 0x10 | OPC_SPECIAL2,
265 OPC_DMULT_G_2F = 0x11 | OPC_SPECIAL2,
266 OPC_MULTU_G_2F = 0x12 | OPC_SPECIAL2,
267 OPC_DMULTU_G_2F = 0x13 | OPC_SPECIAL2,
268 OPC_DIV_G_2F = 0x14 | OPC_SPECIAL2,
269 OPC_DDIV_G_2F = 0x15 | OPC_SPECIAL2,
270 OPC_DIVU_G_2F = 0x16 | OPC_SPECIAL2,
271 OPC_DDIVU_G_2F = 0x17 | OPC_SPECIAL2,
272 OPC_MOD_G_2F = 0x1c | OPC_SPECIAL2,
273 OPC_DMOD_G_2F = 0x1d | OPC_SPECIAL2,
274 OPC_MODU_G_2F = 0x1e | OPC_SPECIAL2,
275 OPC_DMODU_G_2F = 0x1f | OPC_SPECIAL2,
277 OPC_CLZ = 0x20 | OPC_SPECIAL2,
278 OPC_CLO = 0x21 | OPC_SPECIAL2,
279 OPC_DCLZ = 0x24 | OPC_SPECIAL2,
280 OPC_DCLO = 0x25 | OPC_SPECIAL2,
282 OPC_SDBBP = 0x3F | OPC_SPECIAL2,
285 /* Special3 opcodes */
286 #define MASK_SPECIAL3(op) MASK_OP_MAJOR(op) | (op & 0x3F)
289 OPC_EXT = 0x00 | OPC_SPECIAL3,
290 OPC_DEXTM = 0x01 | OPC_SPECIAL3,
291 OPC_DEXTU = 0x02 | OPC_SPECIAL3,
292 OPC_DEXT = 0x03 | OPC_SPECIAL3,
293 OPC_INS = 0x04 | OPC_SPECIAL3,
294 OPC_DINSM = 0x05 | OPC_SPECIAL3,
295 OPC_DINSU = 0x06 | OPC_SPECIAL3,
296 OPC_DINS = 0x07 | OPC_SPECIAL3,
297 OPC_FORK = 0x08 | OPC_SPECIAL3,
298 OPC_YIELD = 0x09 | OPC_SPECIAL3,
299 OPC_BSHFL = 0x20 | OPC_SPECIAL3,
300 OPC_DBSHFL = 0x24 | OPC_SPECIAL3,
301 OPC_RDHWR = 0x3B | OPC_SPECIAL3,
304 OPC_MULT_G_2E = 0x18 | OPC_SPECIAL3,
305 OPC_MULTU_G_2E = 0x19 | OPC_SPECIAL3,
306 OPC_DIV_G_2E = 0x1A | OPC_SPECIAL3,
307 OPC_DIVU_G_2E = 0x1B | OPC_SPECIAL3,
308 OPC_DMULT_G_2E = 0x1C | OPC_SPECIAL3,
309 OPC_DMULTU_G_2E = 0x1D | OPC_SPECIAL3,
310 OPC_DDIV_G_2E = 0x1E | OPC_SPECIAL3,
311 OPC_DDIVU_G_2E = 0x1F | OPC_SPECIAL3,
312 OPC_MOD_G_2E = 0x22 | OPC_SPECIAL3,
313 OPC_MODU_G_2E = 0x23 | OPC_SPECIAL3,
314 OPC_DMOD_G_2E = 0x26 | OPC_SPECIAL3,
315 OPC_DMODU_G_2E = 0x27 | OPC_SPECIAL3,
318 OPC_LX_DSP = 0x0A | OPC_SPECIAL3,
319 /* MIPS DSP Arithmetic */
320 OPC_ADDU_QB_DSP = 0x10 | OPC_SPECIAL3,
321 OPC_ADDU_OB_DSP = 0x14 | OPC_SPECIAL3,
322 OPC_ABSQ_S_PH_DSP = 0x12 | OPC_SPECIAL3,
323 OPC_ABSQ_S_QH_DSP = 0x16 | OPC_SPECIAL3,
324 /* OPC_ADDUH_QB_DSP is same as OPC_MULT_G_2E. */
325 /* OPC_ADDUH_QB_DSP = 0x18 | OPC_SPECIAL3, */
326 OPC_CMPU_EQ_QB_DSP = 0x11 | OPC_SPECIAL3,
327 OPC_CMPU_EQ_OB_DSP = 0x15 | OPC_SPECIAL3,
328 /* MIPS DSP GPR-Based Shift Sub-class */
329 OPC_SHLL_QB_DSP = 0x13 | OPC_SPECIAL3,
330 OPC_SHLL_OB_DSP = 0x17 | OPC_SPECIAL3,
331 /* MIPS DSP Multiply Sub-class insns */
332 /* OPC_MUL_PH_DSP is same as OPC_ADDUH_QB_DSP. */
333 /* OPC_MUL_PH_DSP = 0x18 | OPC_SPECIAL3, */
334 OPC_DPA_W_PH_DSP = 0x30 | OPC_SPECIAL3,
335 OPC_DPAQ_W_QH_DSP = 0x34 | OPC_SPECIAL3,
336 /* DSP Bit/Manipulation Sub-class */
337 OPC_INSV_DSP = 0x0C | OPC_SPECIAL3,
338 OPC_DINSV_DSP = 0x0D | OPC_SPECIAL3,
339 /* MIPS DSP Compare-Pick Sub-class */
340 OPC_APPEND_DSP = 0x31 | OPC_SPECIAL3,
341 OPC_DAPPEND_DSP = 0x35 | OPC_SPECIAL3,
342 /* MIPS DSP Accumulator and DSPControl Access Sub-class */
343 OPC_EXTR_W_DSP = 0x38 | OPC_SPECIAL3,
344 OPC_DEXTR_W_DSP = 0x3C | OPC_SPECIAL3,
348 #define MASK_BSHFL(op) MASK_SPECIAL3(op) | (op & (0x1F << 6))
351 OPC_WSBH = (0x02 << 6) | OPC_BSHFL,
352 OPC_SEB = (0x10 << 6) | OPC_BSHFL,
353 OPC_SEH = (0x18 << 6) | OPC_BSHFL,
357 #define MASK_DBSHFL(op) MASK_SPECIAL3(op) | (op & (0x1F << 6))
360 OPC_DSBH = (0x02 << 6) | OPC_DBSHFL,
361 OPC_DSHD = (0x05 << 6) | OPC_DBSHFL,
364 /* MIPS DSP REGIMM opcodes */
366 OPC_BPOSGE32 = (0x1C << 16) | OPC_REGIMM,
367 OPC_BPOSGE64 = (0x1D << 16) | OPC_REGIMM,
370 #define MASK_LX(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
373 OPC_LBUX = (0x06 << 6) | OPC_LX_DSP,
374 OPC_LHX = (0x04 << 6) | OPC_LX_DSP,
375 OPC_LWX = (0x00 << 6) | OPC_LX_DSP,
376 OPC_LDX = (0x08 << 6) | OPC_LX_DSP,
379 #define MASK_ADDU_QB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
381 /* MIPS DSP Arithmetic Sub-class */
382 OPC_ADDQ_PH = (0x0A << 6) | OPC_ADDU_QB_DSP,
383 OPC_ADDQ_S_PH = (0x0E << 6) | OPC_ADDU_QB_DSP,
384 OPC_ADDQ_S_W = (0x16 << 6) | OPC_ADDU_QB_DSP,
385 OPC_ADDU_QB = (0x00 << 6) | OPC_ADDU_QB_DSP,
386 OPC_ADDU_S_QB = (0x04 << 6) | OPC_ADDU_QB_DSP,
387 OPC_ADDU_PH = (0x08 << 6) | OPC_ADDU_QB_DSP,
388 OPC_ADDU_S_PH = (0x0C << 6) | OPC_ADDU_QB_DSP,
389 OPC_SUBQ_PH = (0x0B << 6) | OPC_ADDU_QB_DSP,
390 OPC_SUBQ_S_PH = (0x0F << 6) | OPC_ADDU_QB_DSP,
391 OPC_SUBQ_S_W = (0x17 << 6) | OPC_ADDU_QB_DSP,
392 OPC_SUBU_QB = (0x01 << 6) | OPC_ADDU_QB_DSP,
393 OPC_SUBU_S_QB = (0x05 << 6) | OPC_ADDU_QB_DSP,
394 OPC_SUBU_PH = (0x09 << 6) | OPC_ADDU_QB_DSP,
395 OPC_SUBU_S_PH = (0x0D << 6) | OPC_ADDU_QB_DSP,
396 OPC_ADDSC = (0x10 << 6) | OPC_ADDU_QB_DSP,
397 OPC_ADDWC = (0x11 << 6) | OPC_ADDU_QB_DSP,
398 OPC_MODSUB = (0x12 << 6) | OPC_ADDU_QB_DSP,
399 OPC_RADDU_W_QB = (0x14 << 6) | OPC_ADDU_QB_DSP,
400 /* MIPS DSP Multiply Sub-class insns */
401 OPC_MULEU_S_PH_QBL = (0x06 << 6) | OPC_ADDU_QB_DSP,
402 OPC_MULEU_S_PH_QBR = (0x07 << 6) | OPC_ADDU_QB_DSP,
403 OPC_MULQ_RS_PH = (0x1F << 6) | OPC_ADDU_QB_DSP,
404 OPC_MULEQ_S_W_PHL = (0x1C << 6) | OPC_ADDU_QB_DSP,
405 OPC_MULEQ_S_W_PHR = (0x1D << 6) | OPC_ADDU_QB_DSP,
406 OPC_MULQ_S_PH = (0x1E << 6) | OPC_ADDU_QB_DSP,
409 #define OPC_ADDUH_QB_DSP OPC_MULT_G_2E
410 #define MASK_ADDUH_QB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
412 /* MIPS DSP Arithmetic Sub-class */
413 OPC_ADDUH_QB = (0x00 << 6) | OPC_ADDUH_QB_DSP,
414 OPC_ADDUH_R_QB = (0x02 << 6) | OPC_ADDUH_QB_DSP,
415 OPC_ADDQH_PH = (0x08 << 6) | OPC_ADDUH_QB_DSP,
416 OPC_ADDQH_R_PH = (0x0A << 6) | OPC_ADDUH_QB_DSP,
417 OPC_ADDQH_W = (0x10 << 6) | OPC_ADDUH_QB_DSP,
418 OPC_ADDQH_R_W = (0x12 << 6) | OPC_ADDUH_QB_DSP,
419 OPC_SUBUH_QB = (0x01 << 6) | OPC_ADDUH_QB_DSP,
420 OPC_SUBUH_R_QB = (0x03 << 6) | OPC_ADDUH_QB_DSP,
421 OPC_SUBQH_PH = (0x09 << 6) | OPC_ADDUH_QB_DSP,
422 OPC_SUBQH_R_PH = (0x0B << 6) | OPC_ADDUH_QB_DSP,
423 OPC_SUBQH_W = (0x11 << 6) | OPC_ADDUH_QB_DSP,
424 OPC_SUBQH_R_W = (0x13 << 6) | OPC_ADDUH_QB_DSP,
425 /* MIPS DSP Multiply Sub-class insns */
426 OPC_MUL_PH = (0x0C << 6) | OPC_ADDUH_QB_DSP,
427 OPC_MUL_S_PH = (0x0E << 6) | OPC_ADDUH_QB_DSP,
428 OPC_MULQ_S_W = (0x16 << 6) | OPC_ADDUH_QB_DSP,
429 OPC_MULQ_RS_W = (0x17 << 6) | OPC_ADDUH_QB_DSP,
432 #define MASK_ABSQ_S_PH(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
434 /* MIPS DSP Arithmetic Sub-class */
435 OPC_ABSQ_S_QB = (0x01 << 6) | OPC_ABSQ_S_PH_DSP,
436 OPC_ABSQ_S_PH = (0x09 << 6) | OPC_ABSQ_S_PH_DSP,
437 OPC_ABSQ_S_W = (0x11 << 6) | OPC_ABSQ_S_PH_DSP,
438 OPC_PRECEQ_W_PHL = (0x0C << 6) | OPC_ABSQ_S_PH_DSP,
439 OPC_PRECEQ_W_PHR = (0x0D << 6) | OPC_ABSQ_S_PH_DSP,
440 OPC_PRECEQU_PH_QBL = (0x04 << 6) | OPC_ABSQ_S_PH_DSP,
441 OPC_PRECEQU_PH_QBR = (0x05 << 6) | OPC_ABSQ_S_PH_DSP,
442 OPC_PRECEQU_PH_QBLA = (0x06 << 6) | OPC_ABSQ_S_PH_DSP,
443 OPC_PRECEQU_PH_QBRA = (0x07 << 6) | OPC_ABSQ_S_PH_DSP,
444 OPC_PRECEU_PH_QBL = (0x1C << 6) | OPC_ABSQ_S_PH_DSP,
445 OPC_PRECEU_PH_QBR = (0x1D << 6) | OPC_ABSQ_S_PH_DSP,
446 OPC_PRECEU_PH_QBLA = (0x1E << 6) | OPC_ABSQ_S_PH_DSP,
447 OPC_PRECEU_PH_QBRA = (0x1F << 6) | OPC_ABSQ_S_PH_DSP,
448 /* DSP Bit/Manipulation Sub-class */
449 OPC_BITREV = (0x1B << 6) | OPC_ABSQ_S_PH_DSP,
450 OPC_REPL_QB = (0x02 << 6) | OPC_ABSQ_S_PH_DSP,
451 OPC_REPLV_QB = (0x03 << 6) | OPC_ABSQ_S_PH_DSP,
452 OPC_REPL_PH = (0x0A << 6) | OPC_ABSQ_S_PH_DSP,
453 OPC_REPLV_PH = (0x0B << 6) | OPC_ABSQ_S_PH_DSP,
456 #define MASK_CMPU_EQ_QB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
458 /* MIPS DSP Arithmetic Sub-class */
459 OPC_PRECR_QB_PH = (0x0D << 6) | OPC_CMPU_EQ_QB_DSP,
460 OPC_PRECRQ_QB_PH = (0x0C << 6) | OPC_CMPU_EQ_QB_DSP,
461 OPC_PRECR_SRA_PH_W = (0x1E << 6) | OPC_CMPU_EQ_QB_DSP,
462 OPC_PRECR_SRA_R_PH_W = (0x1F << 6) | OPC_CMPU_EQ_QB_DSP,
463 OPC_PRECRQ_PH_W = (0x14 << 6) | OPC_CMPU_EQ_QB_DSP,
464 OPC_PRECRQ_RS_PH_W = (0x15 << 6) | OPC_CMPU_EQ_QB_DSP,
465 OPC_PRECRQU_S_QB_PH = (0x0F << 6) | OPC_CMPU_EQ_QB_DSP,
466 /* DSP Compare-Pick Sub-class */
467 OPC_CMPU_EQ_QB = (0x00 << 6) | OPC_CMPU_EQ_QB_DSP,
468 OPC_CMPU_LT_QB = (0x01 << 6) | OPC_CMPU_EQ_QB_DSP,
469 OPC_CMPU_LE_QB = (0x02 << 6) | OPC_CMPU_EQ_QB_DSP,
470 OPC_CMPGU_EQ_QB = (0x04 << 6) | OPC_CMPU_EQ_QB_DSP,
471 OPC_CMPGU_LT_QB = (0x05 << 6) | OPC_CMPU_EQ_QB_DSP,
472 OPC_CMPGU_LE_QB = (0x06 << 6) | OPC_CMPU_EQ_QB_DSP,
473 OPC_CMPGDU_EQ_QB = (0x18 << 6) | OPC_CMPU_EQ_QB_DSP,
474 OPC_CMPGDU_LT_QB = (0x19 << 6) | OPC_CMPU_EQ_QB_DSP,
475 OPC_CMPGDU_LE_QB = (0x1A << 6) | OPC_CMPU_EQ_QB_DSP,
476 OPC_CMP_EQ_PH = (0x08 << 6) | OPC_CMPU_EQ_QB_DSP,
477 OPC_CMP_LT_PH = (0x09 << 6) | OPC_CMPU_EQ_QB_DSP,
478 OPC_CMP_LE_PH = (0x0A << 6) | OPC_CMPU_EQ_QB_DSP,
479 OPC_PICK_QB = (0x03 << 6) | OPC_CMPU_EQ_QB_DSP,
480 OPC_PICK_PH = (0x0B << 6) | OPC_CMPU_EQ_QB_DSP,
481 OPC_PACKRL_PH = (0x0E << 6) | OPC_CMPU_EQ_QB_DSP,
484 #define MASK_SHLL_QB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
486 /* MIPS DSP GPR-Based Shift Sub-class */
487 OPC_SHLL_QB = (0x00 << 6) | OPC_SHLL_QB_DSP,
488 OPC_SHLLV_QB = (0x02 << 6) | OPC_SHLL_QB_DSP,
489 OPC_SHLL_PH = (0x08 << 6) | OPC_SHLL_QB_DSP,
490 OPC_SHLLV_PH = (0x0A << 6) | OPC_SHLL_QB_DSP,
491 OPC_SHLL_S_PH = (0x0C << 6) | OPC_SHLL_QB_DSP,
492 OPC_SHLLV_S_PH = (0x0E << 6) | OPC_SHLL_QB_DSP,
493 OPC_SHLL_S_W = (0x14 << 6) | OPC_SHLL_QB_DSP,
494 OPC_SHLLV_S_W = (0x16 << 6) | OPC_SHLL_QB_DSP,
495 OPC_SHRL_QB = (0x01 << 6) | OPC_SHLL_QB_DSP,
496 OPC_SHRLV_QB = (0x03 << 6) | OPC_SHLL_QB_DSP,
497 OPC_SHRL_PH = (0x19 << 6) | OPC_SHLL_QB_DSP,
498 OPC_SHRLV_PH = (0x1B << 6) | OPC_SHLL_QB_DSP,
499 OPC_SHRA_QB = (0x04 << 6) | OPC_SHLL_QB_DSP,
500 OPC_SHRA_R_QB = (0x05 << 6) | OPC_SHLL_QB_DSP,
501 OPC_SHRAV_QB = (0x06 << 6) | OPC_SHLL_QB_DSP,
502 OPC_SHRAV_R_QB = (0x07 << 6) | OPC_SHLL_QB_DSP,
503 OPC_SHRA_PH = (0x09 << 6) | OPC_SHLL_QB_DSP,
504 OPC_SHRAV_PH = (0x0B << 6) | OPC_SHLL_QB_DSP,
505 OPC_SHRA_R_PH = (0x0D << 6) | OPC_SHLL_QB_DSP,
506 OPC_SHRAV_R_PH = (0x0F << 6) | OPC_SHLL_QB_DSP,
507 OPC_SHRA_R_W = (0x15 << 6) | OPC_SHLL_QB_DSP,
508 OPC_SHRAV_R_W = (0x17 << 6) | OPC_SHLL_QB_DSP,
511 #define MASK_DPA_W_PH(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
513 /* MIPS DSP Multiply Sub-class insns */
514 OPC_DPAU_H_QBL = (0x03 << 6) | OPC_DPA_W_PH_DSP,
515 OPC_DPAU_H_QBR = (0x07 << 6) | OPC_DPA_W_PH_DSP,
516 OPC_DPSU_H_QBL = (0x0B << 6) | OPC_DPA_W_PH_DSP,
517 OPC_DPSU_H_QBR = (0x0F << 6) | OPC_DPA_W_PH_DSP,
518 OPC_DPA_W_PH = (0x00 << 6) | OPC_DPA_W_PH_DSP,
519 OPC_DPAX_W_PH = (0x08 << 6) | OPC_DPA_W_PH_DSP,
520 OPC_DPAQ_S_W_PH = (0x04 << 6) | OPC_DPA_W_PH_DSP,
521 OPC_DPAQX_S_W_PH = (0x18 << 6) | OPC_DPA_W_PH_DSP,
522 OPC_DPAQX_SA_W_PH = (0x1A << 6) | OPC_DPA_W_PH_DSP,
523 OPC_DPS_W_PH = (0x01 << 6) | OPC_DPA_W_PH_DSP,
524 OPC_DPSX_W_PH = (0x09 << 6) | OPC_DPA_W_PH_DSP,
525 OPC_DPSQ_S_W_PH = (0x05 << 6) | OPC_DPA_W_PH_DSP,
526 OPC_DPSQX_S_W_PH = (0x19 << 6) | OPC_DPA_W_PH_DSP,
527 OPC_DPSQX_SA_W_PH = (0x1B << 6) | OPC_DPA_W_PH_DSP,
528 OPC_MULSAQ_S_W_PH = (0x06 << 6) | OPC_DPA_W_PH_DSP,
529 OPC_DPAQ_SA_L_W = (0x0C << 6) | OPC_DPA_W_PH_DSP,
530 OPC_DPSQ_SA_L_W = (0x0D << 6) | OPC_DPA_W_PH_DSP,
531 OPC_MAQ_S_W_PHL = (0x14 << 6) | OPC_DPA_W_PH_DSP,
532 OPC_MAQ_S_W_PHR = (0x16 << 6) | OPC_DPA_W_PH_DSP,
533 OPC_MAQ_SA_W_PHL = (0x10 << 6) | OPC_DPA_W_PH_DSP,
534 OPC_MAQ_SA_W_PHR = (0x12 << 6) | OPC_DPA_W_PH_DSP,
535 OPC_MULSA_W_PH = (0x02 << 6) | OPC_DPA_W_PH_DSP,
538 #define MASK_INSV(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
540 /* DSP Bit/Manipulation Sub-class */
541 OPC_INSV = (0x00 << 6) | OPC_INSV_DSP,
544 #define MASK_APPEND(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
546 /* MIPS DSP Compare-Pick Sub-class */
547 OPC_APPEND = (0x00 << 6) | OPC_APPEND_DSP,
548 OPC_PREPEND = (0x01 << 6) | OPC_APPEND_DSP,
549 OPC_BALIGN = (0x10 << 6) | OPC_APPEND_DSP,
552 #define MASK_EXTR_W(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
554 /* MIPS DSP Accumulator and DSPControl Access Sub-class */
555 OPC_EXTR_W = (0x00 << 6) | OPC_EXTR_W_DSP,
556 OPC_EXTR_R_W = (0x04 << 6) | OPC_EXTR_W_DSP,
557 OPC_EXTR_RS_W = (0x06 << 6) | OPC_EXTR_W_DSP,
558 OPC_EXTR_S_H = (0x0E << 6) | OPC_EXTR_W_DSP,
559 OPC_EXTRV_S_H = (0x0F << 6) | OPC_EXTR_W_DSP,
560 OPC_EXTRV_W = (0x01 << 6) | OPC_EXTR_W_DSP,
561 OPC_EXTRV_R_W = (0x05 << 6) | OPC_EXTR_W_DSP,
562 OPC_EXTRV_RS_W = (0x07 << 6) | OPC_EXTR_W_DSP,
563 OPC_EXTP = (0x02 << 6) | OPC_EXTR_W_DSP,
564 OPC_EXTPV = (0x03 << 6) | OPC_EXTR_W_DSP,
565 OPC_EXTPDP = (0x0A << 6) | OPC_EXTR_W_DSP,
566 OPC_EXTPDPV = (0x0B << 6) | OPC_EXTR_W_DSP,
567 OPC_SHILO = (0x1A << 6) | OPC_EXTR_W_DSP,
568 OPC_SHILOV = (0x1B << 6) | OPC_EXTR_W_DSP,
569 OPC_MTHLIP = (0x1F << 6) | OPC_EXTR_W_DSP,
570 OPC_WRDSP = (0x13 << 6) | OPC_EXTR_W_DSP,
571 OPC_RDDSP = (0x12 << 6) | OPC_EXTR_W_DSP,
574 #define MASK_ABSQ_S_QH(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
576 /* MIPS DSP Arithmetic Sub-class */
577 OPC_PRECEQ_L_PWL = (0x14 << 6) | OPC_ABSQ_S_QH_DSP,
578 OPC_PRECEQ_L_PWR = (0x15 << 6) | OPC_ABSQ_S_QH_DSP,
579 OPC_PRECEQ_PW_QHL = (0x0C << 6) | OPC_ABSQ_S_QH_DSP,
580 OPC_PRECEQ_PW_QHR = (0x0D << 6) | OPC_ABSQ_S_QH_DSP,
581 OPC_PRECEQ_PW_QHLA = (0x0E << 6) | OPC_ABSQ_S_QH_DSP,
582 OPC_PRECEQ_PW_QHRA = (0x0F << 6) | OPC_ABSQ_S_QH_DSP,
583 OPC_PRECEQU_QH_OBL = (0x04 << 6) | OPC_ABSQ_S_QH_DSP,
584 OPC_PRECEQU_QH_OBR = (0x05 << 6) | OPC_ABSQ_S_QH_DSP,
585 OPC_PRECEQU_QH_OBLA = (0x06 << 6) | OPC_ABSQ_S_QH_DSP,
586 OPC_PRECEQU_QH_OBRA = (0x07 << 6) | OPC_ABSQ_S_QH_DSP,
587 OPC_PRECEU_QH_OBL = (0x1C << 6) | OPC_ABSQ_S_QH_DSP,
588 OPC_PRECEU_QH_OBR = (0x1D << 6) | OPC_ABSQ_S_QH_DSP,
589 OPC_PRECEU_QH_OBLA = (0x1E << 6) | OPC_ABSQ_S_QH_DSP,
590 OPC_PRECEU_QH_OBRA = (0x1F << 6) | OPC_ABSQ_S_QH_DSP,
591 OPC_ABSQ_S_OB = (0x01 << 6) | OPC_ABSQ_S_QH_DSP,
592 OPC_ABSQ_S_PW = (0x11 << 6) | OPC_ABSQ_S_QH_DSP,
593 OPC_ABSQ_S_QH = (0x09 << 6) | OPC_ABSQ_S_QH_DSP,
594 /* DSP Bit/Manipulation Sub-class */
595 OPC_REPL_OB = (0x02 << 6) | OPC_ABSQ_S_QH_DSP,
596 OPC_REPL_PW = (0x12 << 6) | OPC_ABSQ_S_QH_DSP,
597 OPC_REPL_QH = (0x0A << 6) | OPC_ABSQ_S_QH_DSP,
598 OPC_REPLV_OB = (0x03 << 6) | OPC_ABSQ_S_QH_DSP,
599 OPC_REPLV_PW = (0x13 << 6) | OPC_ABSQ_S_QH_DSP,
600 OPC_REPLV_QH = (0x0B << 6) | OPC_ABSQ_S_QH_DSP,
603 #define MASK_ADDU_OB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
605 /* MIPS DSP Multiply Sub-class insns */
606 OPC_MULEQ_S_PW_QHL = (0x1C << 6) | OPC_ADDU_OB_DSP,
607 OPC_MULEQ_S_PW_QHR = (0x1D << 6) | OPC_ADDU_OB_DSP,
608 OPC_MULEU_S_QH_OBL = (0x06 << 6) | OPC_ADDU_OB_DSP,
609 OPC_MULEU_S_QH_OBR = (0x07 << 6) | OPC_ADDU_OB_DSP,
610 OPC_MULQ_RS_QH = (0x1F << 6) | OPC_ADDU_OB_DSP,
611 /* MIPS DSP Arithmetic Sub-class */
612 OPC_RADDU_L_OB = (0x14 << 6) | OPC_ADDU_OB_DSP,
613 OPC_SUBQ_PW = (0x13 << 6) | OPC_ADDU_OB_DSP,
614 OPC_SUBQ_S_PW = (0x17 << 6) | OPC_ADDU_OB_DSP,
615 OPC_SUBQ_QH = (0x0B << 6) | OPC_ADDU_OB_DSP,
616 OPC_SUBQ_S_QH = (0x0F << 6) | OPC_ADDU_OB_DSP,
617 OPC_SUBU_OB = (0x01 << 6) | OPC_ADDU_OB_DSP,
618 OPC_SUBU_S_OB = (0x05 << 6) | OPC_ADDU_OB_DSP,
619 OPC_SUBU_QH = (0x09 << 6) | OPC_ADDU_OB_DSP,
620 OPC_SUBU_S_QH = (0x0D << 6) | OPC_ADDU_OB_DSP,
621 OPC_SUBUH_OB = (0x19 << 6) | OPC_ADDU_OB_DSP,
622 OPC_SUBUH_R_OB = (0x1B << 6) | OPC_ADDU_OB_DSP,
623 OPC_ADDQ_PW = (0x12 << 6) | OPC_ADDU_OB_DSP,
624 OPC_ADDQ_S_PW = (0x16 << 6) | OPC_ADDU_OB_DSP,
625 OPC_ADDQ_QH = (0x0A << 6) | OPC_ADDU_OB_DSP,
626 OPC_ADDQ_S_QH = (0x0E << 6) | OPC_ADDU_OB_DSP,
627 OPC_ADDU_OB = (0x00 << 6) | OPC_ADDU_OB_DSP,
628 OPC_ADDU_S_OB = (0x04 << 6) | OPC_ADDU_OB_DSP,
629 OPC_ADDU_QH = (0x08 << 6) | OPC_ADDU_OB_DSP,
630 OPC_ADDU_S_QH = (0x0C << 6) | OPC_ADDU_OB_DSP,
631 OPC_ADDUH_OB = (0x18 << 6) | OPC_ADDU_OB_DSP,
632 OPC_ADDUH_R_OB = (0x1A << 6) | OPC_ADDU_OB_DSP,
635 #define MASK_CMPU_EQ_OB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
637 /* DSP Compare-Pick Sub-class */
638 OPC_CMP_EQ_PW = (0x10 << 6) | OPC_CMPU_EQ_OB_DSP,
639 OPC_CMP_LT_PW = (0x11 << 6) | OPC_CMPU_EQ_OB_DSP,
640 OPC_CMP_LE_PW = (0x12 << 6) | OPC_CMPU_EQ_OB_DSP,
641 OPC_CMP_EQ_QH = (0x08 << 6) | OPC_CMPU_EQ_OB_DSP,
642 OPC_CMP_LT_QH = (0x09 << 6) | OPC_CMPU_EQ_OB_DSP,
643 OPC_CMP_LE_QH = (0x0A << 6) | OPC_CMPU_EQ_OB_DSP,
644 OPC_CMPGDU_EQ_OB = (0x18 << 6) | OPC_CMPU_EQ_OB_DSP,
645 OPC_CMPGDU_LT_OB = (0x19 << 6) | OPC_CMPU_EQ_OB_DSP,
646 OPC_CMPGDU_LE_OB = (0x1A << 6) | OPC_CMPU_EQ_OB_DSP,
647 OPC_CMPGU_EQ_OB = (0x04 << 6) | OPC_CMPU_EQ_OB_DSP,
648 OPC_CMPGU_LT_OB = (0x05 << 6) | OPC_CMPU_EQ_OB_DSP,
649 OPC_CMPGU_LE_OB = (0x06 << 6) | OPC_CMPU_EQ_OB_DSP,
650 OPC_CMPU_EQ_OB = (0x00 << 6) | OPC_CMPU_EQ_OB_DSP,
651 OPC_CMPU_LT_OB = (0x01 << 6) | OPC_CMPU_EQ_OB_DSP,
652 OPC_CMPU_LE_OB = (0x02 << 6) | OPC_CMPU_EQ_OB_DSP,
653 OPC_PACKRL_PW = (0x0E << 6) | OPC_CMPU_EQ_OB_DSP,
654 OPC_PICK_OB = (0x03 << 6) | OPC_CMPU_EQ_OB_DSP,
655 OPC_PICK_PW = (0x13 << 6) | OPC_CMPU_EQ_OB_DSP,
656 OPC_PICK_QH = (0x0B << 6) | OPC_CMPU_EQ_OB_DSP,
657 /* MIPS DSP Arithmetic Sub-class */
658 OPC_PRECR_OB_QH = (0x0D << 6) | OPC_CMPU_EQ_OB_DSP,
659 OPC_PRECR_SRA_QH_PW = (0x1E << 6) | OPC_CMPU_EQ_OB_DSP,
660 OPC_PRECR_SRA_R_QH_PW = (0x1F << 6) | OPC_CMPU_EQ_OB_DSP,
661 OPC_PRECRQ_OB_QH = (0x0C << 6) | OPC_CMPU_EQ_OB_DSP,
662 OPC_PRECRQ_PW_L = (0x1C << 6) | OPC_CMPU_EQ_OB_DSP,
663 OPC_PRECRQ_QH_PW = (0x14 << 6) | OPC_CMPU_EQ_OB_DSP,
664 OPC_PRECRQ_RS_QH_PW = (0x15 << 6) | OPC_CMPU_EQ_OB_DSP,
665 OPC_PRECRQU_S_OB_QH = (0x0F << 6) | OPC_CMPU_EQ_OB_DSP,
668 #define MASK_DAPPEND(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
670 /* DSP Compare-Pick Sub-class */
671 OPC_DAPPEND = (0x00 << 6) | OPC_DAPPEND_DSP,
672 OPC_PREPENDD = (0x03 << 6) | OPC_DAPPEND_DSP,
673 OPC_PREPENDW = (0x01 << 6) | OPC_DAPPEND_DSP,
674 OPC_DBALIGN = (0x10 << 6) | OPC_DAPPEND_DSP,
677 #define MASK_DEXTR_W(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
679 /* MIPS DSP Accumulator and DSPControl Access Sub-class */
680 OPC_DMTHLIP = (0x1F << 6) | OPC_DEXTR_W_DSP,
681 OPC_DSHILO = (0x1A << 6) | OPC_DEXTR_W_DSP,
682 OPC_DEXTP = (0x02 << 6) | OPC_DEXTR_W_DSP,
683 OPC_DEXTPDP = (0x0A << 6) | OPC_DEXTR_W_DSP,
684 OPC_DEXTPDPV = (0x0B << 6) | OPC_DEXTR_W_DSP,
685 OPC_DEXTPV = (0x03 << 6) | OPC_DEXTR_W_DSP,
686 OPC_DEXTR_L = (0x10 << 6) | OPC_DEXTR_W_DSP,
687 OPC_DEXTR_R_L = (0x14 << 6) | OPC_DEXTR_W_DSP,
688 OPC_DEXTR_RS_L = (0x16 << 6) | OPC_DEXTR_W_DSP,
689 OPC_DEXTR_W = (0x00 << 6) | OPC_DEXTR_W_DSP,
690 OPC_DEXTR_R_W = (0x04 << 6) | OPC_DEXTR_W_DSP,
691 OPC_DEXTR_RS_W = (0x06 << 6) | OPC_DEXTR_W_DSP,
692 OPC_DEXTR_S_H = (0x0E << 6) | OPC_DEXTR_W_DSP,
693 OPC_DEXTRV_L = (0x11 << 6) | OPC_DEXTR_W_DSP,
694 OPC_DEXTRV_R_L = (0x15 << 6) | OPC_DEXTR_W_DSP,
695 OPC_DEXTRV_RS_L = (0x17 << 6) | OPC_DEXTR_W_DSP,
696 OPC_DEXTRV_S_H = (0x0F << 6) | OPC_DEXTR_W_DSP,
697 OPC_DEXTRV_W = (0x01 << 6) | OPC_DEXTR_W_DSP,
698 OPC_DEXTRV_R_W = (0x05 << 6) | OPC_DEXTR_W_DSP,
699 OPC_DEXTRV_RS_W = (0x07 << 6) | OPC_DEXTR_W_DSP,
700 OPC_DSHILOV = (0x1B << 6) | OPC_DEXTR_W_DSP,
703 #define MASK_DINSV(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
705 /* DSP Bit/Manipulation Sub-class */
706 OPC_DINSV = (0x00 << 6) | OPC_DINSV_DSP,
709 #define MASK_DPAQ_W_QH(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
711 /* MIPS DSP Multiply Sub-class insns */
712 OPC_DMADD = (0x19 << 6) | OPC_DPAQ_W_QH_DSP,
713 OPC_DMADDU = (0x1D << 6) | OPC_DPAQ_W_QH_DSP,
714 OPC_DMSUB = (0x1B << 6) | OPC_DPAQ_W_QH_DSP,
715 OPC_DMSUBU = (0x1F << 6) | OPC_DPAQ_W_QH_DSP,
716 OPC_DPA_W_QH = (0x00 << 6) | OPC_DPAQ_W_QH_DSP,
717 OPC_DPAQ_S_W_QH = (0x04 << 6) | OPC_DPAQ_W_QH_DSP,
718 OPC_DPAQ_SA_L_PW = (0x0C << 6) | OPC_DPAQ_W_QH_DSP,
719 OPC_DPAU_H_OBL = (0x03 << 6) | OPC_DPAQ_W_QH_DSP,
720 OPC_DPAU_H_OBR = (0x07 << 6) | OPC_DPAQ_W_QH_DSP,
721 OPC_DPS_W_QH = (0x01 << 6) | OPC_DPAQ_W_QH_DSP,
722 OPC_DPSQ_S_W_QH = (0x05 << 6) | OPC_DPAQ_W_QH_DSP,
723 OPC_DPSQ_SA_L_PW = (0x0D << 6) | OPC_DPAQ_W_QH_DSP,
724 OPC_DPSU_H_OBL = (0x0B << 6) | OPC_DPAQ_W_QH_DSP,
725 OPC_DPSU_H_OBR = (0x0F << 6) | OPC_DPAQ_W_QH_DSP,
726 OPC_MAQ_S_L_PWL = (0x1C << 6) | OPC_DPAQ_W_QH_DSP,
727 OPC_MAQ_S_L_PWR = (0x1E << 6) | OPC_DPAQ_W_QH_DSP,
728 OPC_MAQ_S_W_QHLL = (0x14 << 6) | OPC_DPAQ_W_QH_DSP,
729 OPC_MAQ_SA_W_QHLL = (0x10 << 6) | OPC_DPAQ_W_QH_DSP,
730 OPC_MAQ_S_W_QHLR = (0x15 << 6) | OPC_DPAQ_W_QH_DSP,
731 OPC_MAQ_SA_W_QHLR = (0x11 << 6) | OPC_DPAQ_W_QH_DSP,
732 OPC_MAQ_S_W_QHRL = (0x16 << 6) | OPC_DPAQ_W_QH_DSP,
733 OPC_MAQ_SA_W_QHRL = (0x12 << 6) | OPC_DPAQ_W_QH_DSP,
734 OPC_MAQ_S_W_QHRR = (0x17 << 6) | OPC_DPAQ_W_QH_DSP,
735 OPC_MAQ_SA_W_QHRR = (0x13 << 6) | OPC_DPAQ_W_QH_DSP,
736 OPC_MULSAQ_S_L_PW = (0x0E << 6) | OPC_DPAQ_W_QH_DSP,
737 OPC_MULSAQ_S_W_QH = (0x06 << 6) | OPC_DPAQ_W_QH_DSP,
740 #define MASK_SHLL_OB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
742 /* MIPS DSP GPR-Based Shift Sub-class */
743 OPC_SHLL_PW = (0x10 << 6) | OPC_SHLL_OB_DSP,
744 OPC_SHLL_S_PW = (0x14 << 6) | OPC_SHLL_OB_DSP,
745 OPC_SHLLV_OB = (0x02 << 6) | OPC_SHLL_OB_DSP,
746 OPC_SHLLV_PW = (0x12 << 6) | OPC_SHLL_OB_DSP,
747 OPC_SHLLV_S_PW = (0x16 << 6) | OPC_SHLL_OB_DSP,
748 OPC_SHLLV_QH = (0x0A << 6) | OPC_SHLL_OB_DSP,
749 OPC_SHLLV_S_QH = (0x0E << 6) | OPC_SHLL_OB_DSP,
750 OPC_SHRA_PW = (0x11 << 6) | OPC_SHLL_OB_DSP,
751 OPC_SHRA_R_PW = (0x15 << 6) | OPC_SHLL_OB_DSP,
752 OPC_SHRAV_OB = (0x06 << 6) | OPC_SHLL_OB_DSP,
753 OPC_SHRAV_R_OB = (0x07 << 6) | OPC_SHLL_OB_DSP,
754 OPC_SHRAV_PW = (0x13 << 6) | OPC_SHLL_OB_DSP,
755 OPC_SHRAV_R_PW = (0x17 << 6) | OPC_SHLL_OB_DSP,
756 OPC_SHRAV_QH = (0x0B << 6) | OPC_SHLL_OB_DSP,
757 OPC_SHRAV_R_QH = (0x0F << 6) | OPC_SHLL_OB_DSP,
758 OPC_SHRLV_OB = (0x03 << 6) | OPC_SHLL_OB_DSP,
759 OPC_SHRLV_QH = (0x1B << 6) | OPC_SHLL_OB_DSP,
760 OPC_SHLL_OB = (0x00 << 6) | OPC_SHLL_OB_DSP,
761 OPC_SHLL_QH = (0x08 << 6) | OPC_SHLL_OB_DSP,
762 OPC_SHLL_S_QH = (0x0C << 6) | OPC_SHLL_OB_DSP,
763 OPC_SHRA_OB = (0x04 << 6) | OPC_SHLL_OB_DSP,
764 OPC_SHRA_R_OB = (0x05 << 6) | OPC_SHLL_OB_DSP,
765 OPC_SHRA_QH = (0x09 << 6) | OPC_SHLL_OB_DSP,
766 OPC_SHRA_R_QH = (0x0D << 6) | OPC_SHLL_OB_DSP,
767 OPC_SHRL_OB = (0x01 << 6) | OPC_SHLL_OB_DSP,
768 OPC_SHRL_QH = (0x19 << 6) | OPC_SHLL_OB_DSP,
771 /* Coprocessor 0 (rs field) */
772 #define MASK_CP0(op) MASK_OP_MAJOR(op) | (op & (0x1F << 21))
775 OPC_MFC0 = (0x00 << 21) | OPC_CP0,
776 OPC_DMFC0 = (0x01 << 21) | OPC_CP0,
777 OPC_MTC0 = (0x04 << 21) | OPC_CP0,
778 OPC_DMTC0 = (0x05 << 21) | OPC_CP0,
779 OPC_MFTR = (0x08 << 21) | OPC_CP0,
780 OPC_RDPGPR = (0x0A << 21) | OPC_CP0,
781 OPC_MFMC0 = (0x0B << 21) | OPC_CP0,
782 OPC_MTTR = (0x0C << 21) | OPC_CP0,
783 OPC_WRPGPR = (0x0E << 21) | OPC_CP0,
784 OPC_C0 = (0x10 << 21) | OPC_CP0,
785 OPC_C0_FIRST = (0x10 << 21) | OPC_CP0,
786 OPC_C0_LAST = (0x1F << 21) | OPC_CP0,
790 #define MASK_MFMC0(op) MASK_CP0(op) | (op & 0xFFFF)
793 OPC_DMT = 0x01 | (0 << 5) | (0x0F << 6) | (0x01 << 11) | OPC_MFMC0,
794 OPC_EMT = 0x01 | (1 << 5) | (0x0F << 6) | (0x01 << 11) | OPC_MFMC0,
795 OPC_DVPE = 0x01 | (0 << 5) | OPC_MFMC0,
796 OPC_EVPE = 0x01 | (1 << 5) | OPC_MFMC0,
797 OPC_DI = (0 << 5) | (0x0C << 11) | OPC_MFMC0,
798 OPC_EI = (1 << 5) | (0x0C << 11) | OPC_MFMC0,
801 /* Coprocessor 0 (with rs == C0) */
802 #define MASK_C0(op) MASK_CP0(op) | (op & 0x3F)
805 OPC_TLBR = 0x01 | OPC_C0,
806 OPC_TLBWI = 0x02 | OPC_C0,
807 OPC_TLBWR = 0x06 | OPC_C0,
808 OPC_TLBP = 0x08 | OPC_C0,
809 OPC_RFE = 0x10 | OPC_C0,
810 OPC_ERET = 0x18 | OPC_C0,
811 OPC_DERET = 0x1F | OPC_C0,
812 OPC_WAIT = 0x20 | OPC_C0,
815 /* Coprocessor 1 (rs field) */
816 #define MASK_CP1(op) MASK_OP_MAJOR(op) | (op & (0x1F << 21))
818 /* Values for the fmt field in FP instructions */
820 /* 0 - 15 are reserved */
821 FMT_S = 16, /* single fp */
822 FMT_D = 17, /* double fp */
823 FMT_E = 18, /* extended fp */
824 FMT_Q = 19, /* quad fp */
825 FMT_W = 20, /* 32-bit fixed */
826 FMT_L = 21, /* 64-bit fixed */
827 FMT_PS = 22, /* paired single fp */
828 /* 23 - 31 are reserved */
832 OPC_MFC1 = (0x00 << 21) | OPC_CP1,
833 OPC_DMFC1 = (0x01 << 21) | OPC_CP1,
834 OPC_CFC1 = (0x02 << 21) | OPC_CP1,
835 OPC_MFHC1 = (0x03 << 21) | OPC_CP1,
836 OPC_MTC1 = (0x04 << 21) | OPC_CP1,
837 OPC_DMTC1 = (0x05 << 21) | OPC_CP1,
838 OPC_CTC1 = (0x06 << 21) | OPC_CP1,
839 OPC_MTHC1 = (0x07 << 21) | OPC_CP1,
840 OPC_BC1 = (0x08 << 21) | OPC_CP1, /* bc */
841 OPC_BC1ANY2 = (0x09 << 21) | OPC_CP1,
842 OPC_BC1ANY4 = (0x0A << 21) | OPC_CP1,
843 OPC_S_FMT = (FMT_S << 21) | OPC_CP1,
844 OPC_D_FMT = (FMT_D << 21) | OPC_CP1,
845 OPC_E_FMT = (FMT_E << 21) | OPC_CP1,
846 OPC_Q_FMT = (FMT_Q << 21) | OPC_CP1,
847 OPC_W_FMT = (FMT_W << 21) | OPC_CP1,
848 OPC_L_FMT = (FMT_L << 21) | OPC_CP1,
849 OPC_PS_FMT = (FMT_PS << 21) | OPC_CP1,
852 #define MASK_CP1_FUNC(op) MASK_CP1(op) | (op & 0x3F)
853 #define MASK_BC1(op) MASK_CP1(op) | (op & (0x3 << 16))
856 OPC_BC1F = (0x00 << 16) | OPC_BC1,
857 OPC_BC1T = (0x01 << 16) | OPC_BC1,
858 OPC_BC1FL = (0x02 << 16) | OPC_BC1,
859 OPC_BC1TL = (0x03 << 16) | OPC_BC1,
863 OPC_BC1FANY2 = (0x00 << 16) | OPC_BC1ANY2,
864 OPC_BC1TANY2 = (0x01 << 16) | OPC_BC1ANY2,
868 OPC_BC1FANY4 = (0x00 << 16) | OPC_BC1ANY4,
869 OPC_BC1TANY4 = (0x01 << 16) | OPC_BC1ANY4,
872 #define MASK_CP2(op) MASK_OP_MAJOR(op) | (op & (0x1F << 21))
875 OPC_MFC2 = (0x00 << 21) | OPC_CP2,
876 OPC_DMFC2 = (0x01 << 21) | OPC_CP2,
877 OPC_CFC2 = (0x02 << 21) | OPC_CP2,
878 OPC_MFHC2 = (0x03 << 21) | OPC_CP2,
879 OPC_MTC2 = (0x04 << 21) | OPC_CP2,
880 OPC_DMTC2 = (0x05 << 21) | OPC_CP2,
881 OPC_CTC2 = (0x06 << 21) | OPC_CP2,
882 OPC_MTHC2 = (0x07 << 21) | OPC_CP2,
883 OPC_BC2 = (0x08 << 21) | OPC_CP2,
886 #define MASK_LMI(op) (MASK_OP_MAJOR(op) | (op & (0x1F << 21)) | (op & 0x1F))
889 OPC_PADDSH = (24 << 21) | (0x00) | OPC_CP2,
890 OPC_PADDUSH = (25 << 21) | (0x00) | OPC_CP2,
891 OPC_PADDH = (26 << 21) | (0x00) | OPC_CP2,
892 OPC_PADDW = (27 << 21) | (0x00) | OPC_CP2,
893 OPC_PADDSB = (28 << 21) | (0x00) | OPC_CP2,
894 OPC_PADDUSB = (29 << 21) | (0x00) | OPC_CP2,
895 OPC_PADDB = (30 << 21) | (0x00) | OPC_CP2,
896 OPC_PADDD = (31 << 21) | (0x00) | OPC_CP2,
898 OPC_PSUBSH = (24 << 21) | (0x01) | OPC_CP2,
899 OPC_PSUBUSH = (25 << 21) | (0x01) | OPC_CP2,
900 OPC_PSUBH = (26 << 21) | (0x01) | OPC_CP2,
901 OPC_PSUBW = (27 << 21) | (0x01) | OPC_CP2,
902 OPC_PSUBSB = (28 << 21) | (0x01) | OPC_CP2,
903 OPC_PSUBUSB = (29 << 21) | (0x01) | OPC_CP2,
904 OPC_PSUBB = (30 << 21) | (0x01) | OPC_CP2,
905 OPC_PSUBD = (31 << 21) | (0x01) | OPC_CP2,
907 OPC_PSHUFH = (24 << 21) | (0x02) | OPC_CP2,
908 OPC_PACKSSWH = (25 << 21) | (0x02) | OPC_CP2,
909 OPC_PACKSSHB = (26 << 21) | (0x02) | OPC_CP2,
910 OPC_PACKUSHB = (27 << 21) | (0x02) | OPC_CP2,
911 OPC_XOR_CP2 = (28 << 21) | (0x02) | OPC_CP2,
912 OPC_NOR_CP2 = (29 << 21) | (0x02) | OPC_CP2,
913 OPC_AND_CP2 = (30 << 21) | (0x02) | OPC_CP2,
914 OPC_PANDN = (31 << 21) | (0x02) | OPC_CP2,
916 OPC_PUNPCKLHW = (24 << 21) | (0x03) | OPC_CP2,
917 OPC_PUNPCKHHW = (25 << 21) | (0x03) | OPC_CP2,
918 OPC_PUNPCKLBH = (26 << 21) | (0x03) | OPC_CP2,
919 OPC_PUNPCKHBH = (27 << 21) | (0x03) | OPC_CP2,
920 OPC_PINSRH_0 = (28 << 21) | (0x03) | OPC_CP2,
921 OPC_PINSRH_1 = (29 << 21) | (0x03) | OPC_CP2,
922 OPC_PINSRH_2 = (30 << 21) | (0x03) | OPC_CP2,
923 OPC_PINSRH_3 = (31 << 21) | (0x03) | OPC_CP2,
925 OPC_PAVGH = (24 << 21) | (0x08) | OPC_CP2,
926 OPC_PAVGB = (25 << 21) | (0x08) | OPC_CP2,
927 OPC_PMAXSH = (26 << 21) | (0x08) | OPC_CP2,
928 OPC_PMINSH = (27 << 21) | (0x08) | OPC_CP2,
929 OPC_PMAXUB = (28 << 21) | (0x08) | OPC_CP2,
930 OPC_PMINUB = (29 << 21) | (0x08) | OPC_CP2,
932 OPC_PCMPEQW = (24 << 21) | (0x09) | OPC_CP2,
933 OPC_PCMPGTW = (25 << 21) | (0x09) | OPC_CP2,
934 OPC_PCMPEQH = (26 << 21) | (0x09) | OPC_CP2,
935 OPC_PCMPGTH = (27 << 21) | (0x09) | OPC_CP2,
936 OPC_PCMPEQB = (28 << 21) | (0x09) | OPC_CP2,
937 OPC_PCMPGTB = (29 << 21) | (0x09) | OPC_CP2,
939 OPC_PSLLW = (24 << 21) | (0x0A) | OPC_CP2,
940 OPC_PSLLH = (25 << 21) | (0x0A) | OPC_CP2,
941 OPC_PMULLH = (26 << 21) | (0x0A) | OPC_CP2,
942 OPC_PMULHH = (27 << 21) | (0x0A) | OPC_CP2,
943 OPC_PMULUW = (28 << 21) | (0x0A) | OPC_CP2,
944 OPC_PMULHUH = (29 << 21) | (0x0A) | OPC_CP2,
946 OPC_PSRLW = (24 << 21) | (0x0B) | OPC_CP2,
947 OPC_PSRLH = (25 << 21) | (0x0B) | OPC_CP2,
948 OPC_PSRAW = (26 << 21) | (0x0B) | OPC_CP2,
949 OPC_PSRAH = (27 << 21) | (0x0B) | OPC_CP2,
950 OPC_PUNPCKLWD = (28 << 21) | (0x0B) | OPC_CP2,
951 OPC_PUNPCKHWD = (29 << 21) | (0x0B) | OPC_CP2,
953 OPC_ADDU_CP2 = (24 << 21) | (0x0C) | OPC_CP2,
954 OPC_OR_CP2 = (25 << 21) | (0x0C) | OPC_CP2,
955 OPC_ADD_CP2 = (26 << 21) | (0x0C) | OPC_CP2,
956 OPC_DADD_CP2 = (27 << 21) | (0x0C) | OPC_CP2,
957 OPC_SEQU_CP2 = (28 << 21) | (0x0C) | OPC_CP2,
958 OPC_SEQ_CP2 = (29 << 21) | (0x0C) | OPC_CP2,
960 OPC_SUBU_CP2 = (24 << 21) | (0x0D) | OPC_CP2,
961 OPC_PASUBUB = (25 << 21) | (0x0D) | OPC_CP2,
962 OPC_SUB_CP2 = (26 << 21) | (0x0D) | OPC_CP2,
963 OPC_DSUB_CP2 = (27 << 21) | (0x0D) | OPC_CP2,
964 OPC_SLTU_CP2 = (28 << 21) | (0x0D) | OPC_CP2,
965 OPC_SLT_CP2 = (29 << 21) | (0x0D) | OPC_CP2,
967 OPC_SLL_CP2 = (24 << 21) | (0x0E) | OPC_CP2,
968 OPC_DSLL_CP2 = (25 << 21) | (0x0E) | OPC_CP2,
969 OPC_PEXTRH = (26 << 21) | (0x0E) | OPC_CP2,
970 OPC_PMADDHW = (27 << 21) | (0x0E) | OPC_CP2,
971 OPC_SLEU_CP2 = (28 << 21) | (0x0E) | OPC_CP2,
972 OPC_SLE_CP2 = (29 << 21) | (0x0E) | OPC_CP2,
974 OPC_SRL_CP2 = (24 << 21) | (0x0F) | OPC_CP2,
975 OPC_DSRL_CP2 = (25 << 21) | (0x0F) | OPC_CP2,
976 OPC_SRA_CP2 = (26 << 21) | (0x0F) | OPC_CP2,
977 OPC_DSRA_CP2 = (27 << 21) | (0x0F) | OPC_CP2,
978 OPC_BIADD = (28 << 21) | (0x0F) | OPC_CP2,
979 OPC_PMOVMSKB = (29 << 21) | (0x0F) | OPC_CP2,
983 #define MASK_CP3(op) MASK_OP_MAJOR(op) | (op & 0x3F)
986 OPC_LWXC1 = 0x00 | OPC_CP3,
987 OPC_LDXC1 = 0x01 | OPC_CP3,
988 OPC_LUXC1 = 0x05 | OPC_CP3,
989 OPC_SWXC1 = 0x08 | OPC_CP3,
990 OPC_SDXC1 = 0x09 | OPC_CP3,
991 OPC_SUXC1 = 0x0D | OPC_CP3,
992 OPC_PREFX = 0x0F | OPC_CP3,
993 OPC_ALNV_PS = 0x1E | OPC_CP3,
994 OPC_MADD_S = 0x20 | OPC_CP3,
995 OPC_MADD_D = 0x21 | OPC_CP3,
996 OPC_MADD_PS = 0x26 | OPC_CP3,
997 OPC_MSUB_S = 0x28 | OPC_CP3,
998 OPC_MSUB_D = 0x29 | OPC_CP3,
999 OPC_MSUB_PS = 0x2E | OPC_CP3,
1000 OPC_NMADD_S = 0x30 | OPC_CP3,
1001 OPC_NMADD_D = 0x31 | OPC_CP3,
1002 OPC_NMADD_PS= 0x36 | OPC_CP3,
1003 OPC_NMSUB_S = 0x38 | OPC_CP3,
1004 OPC_NMSUB_D = 0x39 | OPC_CP3,
1005 OPC_NMSUB_PS= 0x3E | OPC_CP3,
1008 /* global register indices */
1009 static TCGv_ptr cpu_env;
1010 static TCGv cpu_gpr[32], cpu_PC;
1011 static TCGv cpu_HI[MIPS_DSP_ACC], cpu_LO[MIPS_DSP_ACC], cpu_ACX[MIPS_DSP_ACC];
1012 static TCGv cpu_dspctrl, btarget, bcond;
1013 static TCGv_i32 hflags;
1014 static TCGv_i32 fpu_fcr0, fpu_fcr31;
1015 static TCGv_i64 fpu_f64[32];
1017 static uint32_t gen_opc_hflags[OPC_BUF_SIZE];
1018 static target_ulong gen_opc_btarget[OPC_BUF_SIZE];
1020 #include "gen-icount.h"
1022 #define gen_helper_0e0i(name, arg) do { \
1023 TCGv_i32 helper_tmp = tcg_const_i32(arg); \
1024 gen_helper_##name(cpu_env, helper_tmp); \
1025 tcg_temp_free_i32(helper_tmp); \
1028 #define gen_helper_0e1i(name, arg1, arg2) do { \
1029 TCGv_i32 helper_tmp = tcg_const_i32(arg2); \
1030 gen_helper_##name(cpu_env, arg1, helper_tmp); \
1031 tcg_temp_free_i32(helper_tmp); \
1034 #define gen_helper_1e0i(name, ret, arg1) do { \
1035 TCGv_i32 helper_tmp = tcg_const_i32(arg1); \
1036 gen_helper_##name(ret, cpu_env, helper_tmp); \
1037 tcg_temp_free_i32(helper_tmp); \
1040 #define gen_helper_1e1i(name, ret, arg1, arg2) do { \
1041 TCGv_i32 helper_tmp = tcg_const_i32(arg2); \
1042 gen_helper_##name(ret, cpu_env, arg1, helper_tmp); \
1043 tcg_temp_free_i32(helper_tmp); \
1046 #define gen_helper_0e2i(name, arg1, arg2, arg3) do { \
1047 TCGv_i32 helper_tmp = tcg_const_i32(arg3); \
1048 gen_helper_##name(cpu_env, arg1, arg2, helper_tmp); \
1049 tcg_temp_free_i32(helper_tmp); \
1052 #define gen_helper_1e2i(name, ret, arg1, arg2, arg3) do { \
1053 TCGv_i32 helper_tmp = tcg_const_i32(arg3); \
1054 gen_helper_##name(ret, cpu_env, arg1, arg2, helper_tmp); \
1055 tcg_temp_free_i32(helper_tmp); \
1058 #define gen_helper_0e3i(name, arg1, arg2, arg3, arg4) do { \
1059 TCGv_i32 helper_tmp = tcg_const_i32(arg4); \
1060 gen_helper_##name(cpu_env, arg1, arg2, arg3, helper_tmp); \
1061 tcg_temp_free_i32(helper_tmp); \
1064 typedef struct DisasContext {
1065 struct TranslationBlock *tb;
1066 target_ulong pc, saved_pc;
1068 int singlestep_enabled;
1069 /* Routine used to access memory */
1071 uint32_t hflags, saved_hflags;
1073 target_ulong btarget;
1077 BS_NONE = 0, /* We go out of the TB without reaching a branch or an
1078 * exception condition */
1079 BS_STOP = 1, /* We want to stop translation for any reason */
1080 BS_BRANCH = 2, /* We reached a branch condition */
1081 BS_EXCP = 3, /* We reached an exception condition */
1084 static const char * const regnames[] = {
1085 "r0", "at", "v0", "v1", "a0", "a1", "a2", "a3",
1086 "t0", "t1", "t2", "t3", "t4", "t5", "t6", "t7",
1087 "s0", "s1", "s2", "s3", "s4", "s5", "s6", "s7",
1088 "t8", "t9", "k0", "k1", "gp", "sp", "s8", "ra",
1091 static const char * const regnames_HI[] = {
1092 "HI0", "HI1", "HI2", "HI3",
1095 static const char * const regnames_LO[] = {
1096 "LO0", "LO1", "LO2", "LO3",
1099 static const char * const regnames_ACX[] = {
1100 "ACX0", "ACX1", "ACX2", "ACX3",
1103 static const char * const fregnames[] = {
1104 "f0", "f1", "f2", "f3", "f4", "f5", "f6", "f7",
1105 "f8", "f9", "f10", "f11", "f12", "f13", "f14", "f15",
1106 "f16", "f17", "f18", "f19", "f20", "f21", "f22", "f23",
1107 "f24", "f25", "f26", "f27", "f28", "f29", "f30", "f31",
1110 #define MIPS_DEBUG(fmt, ...) \
1112 if (MIPS_DEBUG_DISAS) { \
1113 qemu_log_mask(CPU_LOG_TB_IN_ASM, \
1114 TARGET_FMT_lx ": %08x " fmt "\n", \
1115 ctx->pc, ctx->opcode , ## __VA_ARGS__); \
1119 #define LOG_DISAS(...) \
1121 if (MIPS_DEBUG_DISAS) { \
1122 qemu_log_mask(CPU_LOG_TB_IN_ASM, ## __VA_ARGS__); \
1126 #define MIPS_INVAL(op) \
1127 MIPS_DEBUG("Invalid %s %03x %03x %03x", op, ctx->opcode >> 26, \
1128 ctx->opcode & 0x3F, ((ctx->opcode >> 16) & 0x1F))
1130 /* General purpose registers moves. */
1131 static inline void gen_load_gpr (TCGv t, int reg)
1134 tcg_gen_movi_tl(t, 0);
1136 tcg_gen_mov_tl(t, cpu_gpr[reg]);
1139 static inline void gen_store_gpr (TCGv t, int reg)
1142 tcg_gen_mov_tl(cpu_gpr[reg], t);
1145 /* Moves to/from ACX register. */
1146 static inline void gen_load_ACX (TCGv t, int reg)
1148 tcg_gen_mov_tl(t, cpu_ACX[reg]);
1151 static inline void gen_store_ACX (TCGv t, int reg)
1153 tcg_gen_mov_tl(cpu_ACX[reg], t);
1156 /* Moves to/from shadow registers. */
1157 static inline void gen_load_srsgpr (int from, int to)
1159 TCGv t0 = tcg_temp_new();
1162 tcg_gen_movi_tl(t0, 0);
1164 TCGv_i32 t2 = tcg_temp_new_i32();
1165 TCGv_ptr addr = tcg_temp_new_ptr();
1167 tcg_gen_ld_i32(t2, cpu_env, offsetof(CPUMIPSState, CP0_SRSCtl));
1168 tcg_gen_shri_i32(t2, t2, CP0SRSCtl_PSS);
1169 tcg_gen_andi_i32(t2, t2, 0xf);
1170 tcg_gen_muli_i32(t2, t2, sizeof(target_ulong) * 32);
1171 tcg_gen_ext_i32_ptr(addr, t2);
1172 tcg_gen_add_ptr(addr, cpu_env, addr);
1174 tcg_gen_ld_tl(t0, addr, sizeof(target_ulong) * from);
1175 tcg_temp_free_ptr(addr);
1176 tcg_temp_free_i32(t2);
1178 gen_store_gpr(t0, to);
1182 static inline void gen_store_srsgpr (int from, int to)
1185 TCGv t0 = tcg_temp_new();
1186 TCGv_i32 t2 = tcg_temp_new_i32();
1187 TCGv_ptr addr = tcg_temp_new_ptr();
1189 gen_load_gpr(t0, from);
1190 tcg_gen_ld_i32(t2, cpu_env, offsetof(CPUMIPSState, CP0_SRSCtl));
1191 tcg_gen_shri_i32(t2, t2, CP0SRSCtl_PSS);
1192 tcg_gen_andi_i32(t2, t2, 0xf);
1193 tcg_gen_muli_i32(t2, t2, sizeof(target_ulong) * 32);
1194 tcg_gen_ext_i32_ptr(addr, t2);
1195 tcg_gen_add_ptr(addr, cpu_env, addr);
1197 tcg_gen_st_tl(t0, addr, sizeof(target_ulong) * to);
1198 tcg_temp_free_ptr(addr);
1199 tcg_temp_free_i32(t2);
1204 /* Floating point register moves. */
1205 static void gen_load_fpr32(TCGv_i32 t, int reg)
1207 tcg_gen_trunc_i64_i32(t, fpu_f64[reg]);
1210 static void gen_store_fpr32(TCGv_i32 t, int reg)
1212 TCGv_i64 t64 = tcg_temp_new_i64();
1213 tcg_gen_extu_i32_i64(t64, t);
1214 tcg_gen_deposit_i64(fpu_f64[reg], fpu_f64[reg], t64, 0, 32);
1215 tcg_temp_free_i64(t64);
1218 static void gen_load_fpr32h(TCGv_i32 t, int reg)
1220 TCGv_i64 t64 = tcg_temp_new_i64();
1221 tcg_gen_shri_i64(t64, fpu_f64[reg], 32);
1222 tcg_gen_trunc_i64_i32(t, t64);
1223 tcg_temp_free_i64(t64);
1226 static void gen_store_fpr32h(TCGv_i32 t, int reg)
1228 TCGv_i64 t64 = tcg_temp_new_i64();
1229 tcg_gen_extu_i32_i64(t64, t);
1230 tcg_gen_deposit_i64(fpu_f64[reg], fpu_f64[reg], t64, 32, 32);
1231 tcg_temp_free_i64(t64);
1234 static void gen_load_fpr64(DisasContext *ctx, TCGv_i64 t, int reg)
1236 if (ctx->hflags & MIPS_HFLAG_F64) {
1237 tcg_gen_mov_i64(t, fpu_f64[reg]);
1239 tcg_gen_concat32_i64(t, fpu_f64[reg & ~1], fpu_f64[reg | 1]);
1243 static void gen_store_fpr64(DisasContext *ctx, TCGv_i64 t, int reg)
1245 if (ctx->hflags & MIPS_HFLAG_F64) {
1246 tcg_gen_mov_i64(fpu_f64[reg], t);
1249 tcg_gen_deposit_i64(fpu_f64[reg & ~1], fpu_f64[reg & ~1], t, 0, 32);
1250 t0 = tcg_temp_new_i64();
1251 tcg_gen_shri_i64(t0, t, 32);
1252 tcg_gen_deposit_i64(fpu_f64[reg | 1], fpu_f64[reg | 1], t0, 0, 32);
1253 tcg_temp_free_i64(t0);
1257 static inline int get_fp_bit (int cc)
1266 static inline void gen_save_pc(target_ulong pc)
1268 tcg_gen_movi_tl(cpu_PC, pc);
1271 static inline void save_cpu_state (DisasContext *ctx, int do_save_pc)
1273 LOG_DISAS("hflags %08x saved %08x\n", ctx->hflags, ctx->saved_hflags);
1274 if (do_save_pc && ctx->pc != ctx->saved_pc) {
1275 gen_save_pc(ctx->pc);
1276 ctx->saved_pc = ctx->pc;
1278 if (ctx->hflags != ctx->saved_hflags) {
1279 tcg_gen_movi_i32(hflags, ctx->hflags);
1280 ctx->saved_hflags = ctx->hflags;
1281 switch (ctx->hflags & MIPS_HFLAG_BMASK_BASE) {
1287 tcg_gen_movi_tl(btarget, ctx->btarget);
1293 static inline void restore_cpu_state (CPUMIPSState *env, DisasContext *ctx)
1295 ctx->saved_hflags = ctx->hflags;
1296 switch (ctx->hflags & MIPS_HFLAG_BMASK_BASE) {
1302 ctx->btarget = env->btarget;
1308 generate_exception_err (DisasContext *ctx, int excp, int err)
1310 TCGv_i32 texcp = tcg_const_i32(excp);
1311 TCGv_i32 terr = tcg_const_i32(err);
1312 save_cpu_state(ctx, 1);
1313 gen_helper_raise_exception_err(cpu_env, texcp, terr);
1314 tcg_temp_free_i32(terr);
1315 tcg_temp_free_i32(texcp);
1319 generate_exception (DisasContext *ctx, int excp)
1321 save_cpu_state(ctx, 1);
1322 gen_helper_0e0i(raise_exception, excp);
1325 /* Addresses computation */
1326 static inline void gen_op_addr_add (DisasContext *ctx, TCGv ret, TCGv arg0, TCGv arg1)
1328 tcg_gen_add_tl(ret, arg0, arg1);
1330 #if defined(TARGET_MIPS64)
1331 /* For compatibility with 32-bit code, data reference in user mode
1332 with Status_UX = 0 should be casted to 32-bit and sign extended.
1333 See the MIPS64 PRA manual, section 4.10. */
1334 if (((ctx->hflags & MIPS_HFLAG_KSU) == MIPS_HFLAG_UM) &&
1335 !(ctx->hflags & MIPS_HFLAG_UX)) {
1336 tcg_gen_ext32s_i64(ret, ret);
1341 static inline void check_cp0_enabled(DisasContext *ctx)
1343 if (unlikely(!(ctx->hflags & MIPS_HFLAG_CP0)))
1344 generate_exception_err(ctx, EXCP_CpU, 0);
1347 static inline void check_cp1_enabled(DisasContext *ctx)
1349 if (unlikely(!(ctx->hflags & MIPS_HFLAG_FPU)))
1350 generate_exception_err(ctx, EXCP_CpU, 1);
1353 /* Verify that the processor is running with COP1X instructions enabled.
1354 This is associated with the nabla symbol in the MIPS32 and MIPS64
1357 static inline void check_cop1x(DisasContext *ctx)
1359 if (unlikely(!(ctx->hflags & MIPS_HFLAG_COP1X)))
1360 generate_exception(ctx, EXCP_RI);
1363 /* Verify that the processor is running with 64-bit floating-point
1364 operations enabled. */
1366 static inline void check_cp1_64bitmode(DisasContext *ctx)
1368 if (unlikely(~ctx->hflags & (MIPS_HFLAG_F64 | MIPS_HFLAG_COP1X)))
1369 generate_exception(ctx, EXCP_RI);
1373 * Verify if floating point register is valid; an operation is not defined
1374 * if bit 0 of any register specification is set and the FR bit in the
1375 * Status register equals zero, since the register numbers specify an
1376 * even-odd pair of adjacent coprocessor general registers. When the FR bit
1377 * in the Status register equals one, both even and odd register numbers
1378 * are valid. This limitation exists only for 64 bit wide (d,l,ps) registers.
1380 * Multiple 64 bit wide registers can be checked by calling
1381 * gen_op_cp1_registers(freg1 | freg2 | ... | fregN);
1383 static inline void check_cp1_registers(DisasContext *ctx, int regs)
1385 if (unlikely(!(ctx->hflags & MIPS_HFLAG_F64) && (regs & 1)))
1386 generate_exception(ctx, EXCP_RI);
1389 /* Verify that the processor is running with DSP instructions enabled.
1390 This is enabled by CP0 Status register MX(24) bit.
1393 static inline void check_dsp(DisasContext *ctx)
1395 if (unlikely(!(ctx->hflags & MIPS_HFLAG_DSP))) {
1396 generate_exception(ctx, EXCP_DSPDIS);
1400 static inline void check_dspr2(DisasContext *ctx)
1402 if (unlikely(!(ctx->hflags & MIPS_HFLAG_DSPR2))) {
1403 generate_exception(ctx, EXCP_DSPDIS);
1407 /* This code generates a "reserved instruction" exception if the
1408 CPU does not support the instruction set corresponding to flags. */
1409 static inline void check_insn(CPUMIPSState *env, DisasContext *ctx, int flags)
1411 if (unlikely(!(env->insn_flags & flags)))
1412 generate_exception(ctx, EXCP_RI);
1415 /* This code generates a "reserved instruction" exception if 64-bit
1416 instructions are not enabled. */
1417 static inline void check_mips_64(DisasContext *ctx)
1419 if (unlikely(!(ctx->hflags & MIPS_HFLAG_64)))
1420 generate_exception(ctx, EXCP_RI);
1423 /* Define small wrappers for gen_load_fpr* so that we have a uniform
1424 calling interface for 32 and 64-bit FPRs. No sense in changing
1425 all callers for gen_load_fpr32 when we need the CTX parameter for
1427 #define gen_ldcmp_fpr32(ctx, x, y) gen_load_fpr32(x, y)
1428 #define gen_ldcmp_fpr64(ctx, x, y) gen_load_fpr64(ctx, x, y)
1429 #define FOP_CONDS(type, abs, fmt, ifmt, bits) \
1430 static inline void gen_cmp ## type ## _ ## fmt(DisasContext *ctx, int n, \
1431 int ft, int fs, int cc) \
1433 TCGv_i##bits fp0 = tcg_temp_new_i##bits (); \
1434 TCGv_i##bits fp1 = tcg_temp_new_i##bits (); \
1437 check_cp1_64bitmode(ctx); \
1443 check_cp1_registers(ctx, fs | ft); \
1451 gen_ldcmp_fpr##bits (ctx, fp0, fs); \
1452 gen_ldcmp_fpr##bits (ctx, fp1, ft); \
1454 case 0: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _f, fp0, fp1, cc); break;\
1455 case 1: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _un, fp0, fp1, cc); break;\
1456 case 2: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _eq, fp0, fp1, cc); break;\
1457 case 3: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ueq, fp0, fp1, cc); break;\
1458 case 4: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _olt, fp0, fp1, cc); break;\
1459 case 5: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ult, fp0, fp1, cc); break;\
1460 case 6: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ole, fp0, fp1, cc); break;\
1461 case 7: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ule, fp0, fp1, cc); break;\
1462 case 8: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _sf, fp0, fp1, cc); break;\
1463 case 9: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ngle, fp0, fp1, cc); break;\
1464 case 10: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _seq, fp0, fp1, cc); break;\
1465 case 11: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ngl, fp0, fp1, cc); break;\
1466 case 12: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _lt, fp0, fp1, cc); break;\
1467 case 13: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _nge, fp0, fp1, cc); break;\
1468 case 14: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _le, fp0, fp1, cc); break;\
1469 case 15: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ngt, fp0, fp1, cc); break;\
1472 tcg_temp_free_i##bits (fp0); \
1473 tcg_temp_free_i##bits (fp1); \
1476 FOP_CONDS(, 0, d, FMT_D, 64)
1477 FOP_CONDS(abs, 1, d, FMT_D, 64)
1478 FOP_CONDS(, 0, s, FMT_S, 32)
1479 FOP_CONDS(abs, 1, s, FMT_S, 32)
1480 FOP_CONDS(, 0, ps, FMT_PS, 64)
1481 FOP_CONDS(abs, 1, ps, FMT_PS, 64)
1483 #undef gen_ldcmp_fpr32
1484 #undef gen_ldcmp_fpr64
1486 /* load/store instructions. */
1487 #ifdef CONFIG_USER_ONLY
1488 #define OP_LD_ATOMIC(insn,fname) \
1489 static inline void op_ld_##insn(TCGv ret, TCGv arg1, DisasContext *ctx) \
1491 TCGv t0 = tcg_temp_new(); \
1492 tcg_gen_mov_tl(t0, arg1); \
1493 tcg_gen_qemu_##fname(ret, arg1, ctx->mem_idx); \
1494 tcg_gen_st_tl(t0, cpu_env, offsetof(CPUMIPSState, lladdr)); \
1495 tcg_gen_st_tl(ret, cpu_env, offsetof(CPUMIPSState, llval)); \
1496 tcg_temp_free(t0); \
1499 #define OP_LD_ATOMIC(insn,fname) \
1500 static inline void op_ld_##insn(TCGv ret, TCGv arg1, DisasContext *ctx) \
1502 gen_helper_1e1i(insn, ret, arg1, ctx->mem_idx); \
1505 OP_LD_ATOMIC(ll,ld32s);
1506 #if defined(TARGET_MIPS64)
1507 OP_LD_ATOMIC(lld,ld64);
1511 #ifdef CONFIG_USER_ONLY
1512 #define OP_ST_ATOMIC(insn,fname,ldname,almask) \
1513 static inline void op_st_##insn(TCGv arg1, TCGv arg2, int rt, DisasContext *ctx) \
1515 TCGv t0 = tcg_temp_new(); \
1516 int l1 = gen_new_label(); \
1517 int l2 = gen_new_label(); \
1519 tcg_gen_andi_tl(t0, arg2, almask); \
1520 tcg_gen_brcondi_tl(TCG_COND_EQ, t0, 0, l1); \
1521 tcg_gen_st_tl(arg2, cpu_env, offsetof(CPUMIPSState, CP0_BadVAddr)); \
1522 generate_exception(ctx, EXCP_AdES); \
1523 gen_set_label(l1); \
1524 tcg_gen_ld_tl(t0, cpu_env, offsetof(CPUMIPSState, lladdr)); \
1525 tcg_gen_brcond_tl(TCG_COND_NE, arg2, t0, l2); \
1526 tcg_gen_movi_tl(t0, rt | ((almask << 3) & 0x20)); \
1527 tcg_gen_st_tl(t0, cpu_env, offsetof(CPUMIPSState, llreg)); \
1528 tcg_gen_st_tl(arg1, cpu_env, offsetof(CPUMIPSState, llnewval)); \
1529 gen_helper_0e0i(raise_exception, EXCP_SC); \
1530 gen_set_label(l2); \
1531 tcg_gen_movi_tl(t0, 0); \
1532 gen_store_gpr(t0, rt); \
1533 tcg_temp_free(t0); \
1536 #define OP_ST_ATOMIC(insn,fname,ldname,almask) \
1537 static inline void op_st_##insn(TCGv arg1, TCGv arg2, int rt, DisasContext *ctx) \
1539 TCGv t0 = tcg_temp_new(); \
1540 gen_helper_1e2i(insn, t0, arg1, arg2, ctx->mem_idx); \
1541 gen_store_gpr(t0, rt); \
1542 tcg_temp_free(t0); \
1545 OP_ST_ATOMIC(sc,st32,ld32s,0x3);
1546 #if defined(TARGET_MIPS64)
1547 OP_ST_ATOMIC(scd,st64,ld64,0x7);
1551 static void gen_base_offset_addr (DisasContext *ctx, TCGv addr,
1552 int base, int16_t offset)
1555 tcg_gen_movi_tl(addr, offset);
1556 } else if (offset == 0) {
1557 gen_load_gpr(addr, base);
1559 tcg_gen_movi_tl(addr, offset);
1560 gen_op_addr_add(ctx, addr, cpu_gpr[base], addr);
1564 static target_ulong pc_relative_pc (DisasContext *ctx)
1566 target_ulong pc = ctx->pc;
1568 if (ctx->hflags & MIPS_HFLAG_BMASK) {
1569 int branch_bytes = ctx->hflags & MIPS_HFLAG_BDS16 ? 2 : 4;
1574 pc &= ~(target_ulong)3;
1579 static void gen_ld (CPUMIPSState *env, DisasContext *ctx, uint32_t opc,
1580 int rt, int base, int16_t offset)
1582 const char *opn = "ld";
1585 if (rt == 0 && env->insn_flags & (INSN_LOONGSON2E | INSN_LOONGSON2F)) {
1586 /* Loongson CPU uses a load to zero register for prefetch.
1587 We emulate it as a NOP. On other CPU we must perform the
1588 actual memory access. */
1593 t0 = tcg_temp_new();
1594 gen_base_offset_addr(ctx, t0, base, offset);
1597 #if defined(TARGET_MIPS64)
1599 tcg_gen_qemu_ld32u(t0, t0, ctx->mem_idx);
1600 gen_store_gpr(t0, rt);
1604 tcg_gen_qemu_ld64(t0, t0, ctx->mem_idx);
1605 gen_store_gpr(t0, rt);
1609 save_cpu_state(ctx, 1);
1610 op_ld_lld(t0, t0, ctx);
1611 gen_store_gpr(t0, rt);
1615 save_cpu_state(ctx, 1);
1616 t1 = tcg_temp_new();
1617 gen_load_gpr(t1, rt);
1618 gen_helper_1e2i(ldl, t1, t1, t0, ctx->mem_idx);
1619 gen_store_gpr(t1, rt);
1624 save_cpu_state(ctx, 1);
1625 t1 = tcg_temp_new();
1626 gen_load_gpr(t1, rt);
1627 gen_helper_1e2i(ldr, t1, t1, t0, ctx->mem_idx);
1628 gen_store_gpr(t1, rt);
1633 t1 = tcg_const_tl(pc_relative_pc(ctx));
1634 gen_op_addr_add(ctx, t0, t0, t1);
1636 tcg_gen_qemu_ld64(t0, t0, ctx->mem_idx);
1637 gen_store_gpr(t0, rt);
1642 t1 = tcg_const_tl(pc_relative_pc(ctx));
1643 gen_op_addr_add(ctx, t0, t0, t1);
1645 tcg_gen_qemu_ld32s(t0, t0, ctx->mem_idx);
1646 gen_store_gpr(t0, rt);
1650 tcg_gen_qemu_ld32s(t0, t0, ctx->mem_idx);
1651 gen_store_gpr(t0, rt);
1655 tcg_gen_qemu_ld16s(t0, t0, ctx->mem_idx);
1656 gen_store_gpr(t0, rt);
1660 tcg_gen_qemu_ld16u(t0, t0, ctx->mem_idx);
1661 gen_store_gpr(t0, rt);
1665 tcg_gen_qemu_ld8s(t0, t0, ctx->mem_idx);
1666 gen_store_gpr(t0, rt);
1670 tcg_gen_qemu_ld8u(t0, t0, ctx->mem_idx);
1671 gen_store_gpr(t0, rt);
1675 save_cpu_state(ctx, 1);
1676 t1 = tcg_temp_new();
1677 gen_load_gpr(t1, rt);
1678 gen_helper_1e2i(lwl, t1, t1, t0, ctx->mem_idx);
1679 gen_store_gpr(t1, rt);
1684 save_cpu_state(ctx, 1);
1685 t1 = tcg_temp_new();
1686 gen_load_gpr(t1, rt);
1687 gen_helper_1e2i(lwr, t1, t1, t0, ctx->mem_idx);
1688 gen_store_gpr(t1, rt);
1693 save_cpu_state(ctx, 1);
1694 op_ld_ll(t0, t0, ctx);
1695 gen_store_gpr(t0, rt);
1699 (void)opn; /* avoid a compiler warning */
1700 MIPS_DEBUG("%s %s, %d(%s)", opn, regnames[rt], offset, regnames[base]);
1705 static void gen_st (DisasContext *ctx, uint32_t opc, int rt,
1706 int base, int16_t offset)
1708 const char *opn = "st";
1709 TCGv t0 = tcg_temp_new();
1710 TCGv t1 = tcg_temp_new();
1712 gen_base_offset_addr(ctx, t0, base, offset);
1713 gen_load_gpr(t1, rt);
1715 #if defined(TARGET_MIPS64)
1717 tcg_gen_qemu_st64(t1, t0, ctx->mem_idx);
1721 save_cpu_state(ctx, 1);
1722 gen_helper_0e2i(sdl, t1, t0, ctx->mem_idx);
1726 save_cpu_state(ctx, 1);
1727 gen_helper_0e2i(sdr, t1, t0, ctx->mem_idx);
1732 tcg_gen_qemu_st32(t1, t0, ctx->mem_idx);
1736 tcg_gen_qemu_st16(t1, t0, ctx->mem_idx);
1740 tcg_gen_qemu_st8(t1, t0, ctx->mem_idx);
1744 save_cpu_state(ctx, 1);
1745 gen_helper_0e2i(swl, t1, t0, ctx->mem_idx);
1749 save_cpu_state(ctx, 1);
1750 gen_helper_0e2i(swr, t1, t0, ctx->mem_idx);
1754 (void)opn; /* avoid a compiler warning */
1755 MIPS_DEBUG("%s %s, %d(%s)", opn, regnames[rt], offset, regnames[base]);
1761 /* Store conditional */
1762 static void gen_st_cond (DisasContext *ctx, uint32_t opc, int rt,
1763 int base, int16_t offset)
1765 const char *opn = "st_cond";
1768 t0 = tcg_temp_local_new();
1770 gen_base_offset_addr(ctx, t0, base, offset);
1771 /* Don't do NOP if destination is zero: we must perform the actual
1774 t1 = tcg_temp_local_new();
1775 gen_load_gpr(t1, rt);
1777 #if defined(TARGET_MIPS64)
1779 save_cpu_state(ctx, 1);
1780 op_st_scd(t1, t0, rt, ctx);
1785 save_cpu_state(ctx, 1);
1786 op_st_sc(t1, t0, rt, ctx);
1790 (void)opn; /* avoid a compiler warning */
1791 MIPS_DEBUG("%s %s, %d(%s)", opn, regnames[rt], offset, regnames[base]);
1796 /* Load and store */
1797 static void gen_flt_ldst (DisasContext *ctx, uint32_t opc, int ft,
1798 int base, int16_t offset)
1800 const char *opn = "flt_ldst";
1801 TCGv t0 = tcg_temp_new();
1803 gen_base_offset_addr(ctx, t0, base, offset);
1804 /* Don't do NOP if destination is zero: we must perform the actual
1809 TCGv_i32 fp0 = tcg_temp_new_i32();
1811 tcg_gen_qemu_ld32s(t0, t0, ctx->mem_idx);
1812 tcg_gen_trunc_tl_i32(fp0, t0);
1813 gen_store_fpr32(fp0, ft);
1814 tcg_temp_free_i32(fp0);
1820 TCGv_i32 fp0 = tcg_temp_new_i32();
1821 TCGv t1 = tcg_temp_new();
1823 gen_load_fpr32(fp0, ft);
1824 tcg_gen_extu_i32_tl(t1, fp0);
1825 tcg_gen_qemu_st32(t1, t0, ctx->mem_idx);
1827 tcg_temp_free_i32(fp0);
1833 TCGv_i64 fp0 = tcg_temp_new_i64();
1835 tcg_gen_qemu_ld64(fp0, t0, ctx->mem_idx);
1836 gen_store_fpr64(ctx, fp0, ft);
1837 tcg_temp_free_i64(fp0);
1843 TCGv_i64 fp0 = tcg_temp_new_i64();
1845 gen_load_fpr64(ctx, fp0, ft);
1846 tcg_gen_qemu_st64(fp0, t0, ctx->mem_idx);
1847 tcg_temp_free_i64(fp0);
1853 generate_exception(ctx, EXCP_RI);
1856 (void)opn; /* avoid a compiler warning */
1857 MIPS_DEBUG("%s %s, %d(%s)", opn, fregnames[ft], offset, regnames[base]);
1862 static void gen_cop1_ldst(CPUMIPSState *env, DisasContext *ctx,
1863 uint32_t op, int rt, int rs, int16_t imm)
1865 if (env->CP0_Config1 & (1 << CP0C1_FP)) {
1866 check_cp1_enabled(ctx);
1867 gen_flt_ldst(ctx, op, rt, rs, imm);
1869 generate_exception_err(ctx, EXCP_CpU, 1);
1873 /* Arithmetic with immediate operand */
1874 static void gen_arith_imm (CPUMIPSState *env, DisasContext *ctx, uint32_t opc,
1875 int rt, int rs, int16_t imm)
1877 target_ulong uimm = (target_long)imm; /* Sign extend to 32/64 bits */
1878 const char *opn = "imm arith";
1880 if (rt == 0 && opc != OPC_ADDI && opc != OPC_DADDI) {
1881 /* If no destination, treat it as a NOP.
1882 For addi, we must generate the overflow exception when needed. */
1889 TCGv t0 = tcg_temp_local_new();
1890 TCGv t1 = tcg_temp_new();
1891 TCGv t2 = tcg_temp_new();
1892 int l1 = gen_new_label();
1894 gen_load_gpr(t1, rs);
1895 tcg_gen_addi_tl(t0, t1, uimm);
1896 tcg_gen_ext32s_tl(t0, t0);
1898 tcg_gen_xori_tl(t1, t1, ~uimm);
1899 tcg_gen_xori_tl(t2, t0, uimm);
1900 tcg_gen_and_tl(t1, t1, t2);
1902 tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
1904 /* operands of same sign, result different sign */
1905 generate_exception(ctx, EXCP_OVERFLOW);
1907 tcg_gen_ext32s_tl(t0, t0);
1908 gen_store_gpr(t0, rt);
1915 tcg_gen_addi_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
1916 tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]);
1918 tcg_gen_movi_tl(cpu_gpr[rt], uimm);
1922 #if defined(TARGET_MIPS64)
1925 TCGv t0 = tcg_temp_local_new();
1926 TCGv t1 = tcg_temp_new();
1927 TCGv t2 = tcg_temp_new();
1928 int l1 = gen_new_label();
1930 gen_load_gpr(t1, rs);
1931 tcg_gen_addi_tl(t0, t1, uimm);
1933 tcg_gen_xori_tl(t1, t1, ~uimm);
1934 tcg_gen_xori_tl(t2, t0, uimm);
1935 tcg_gen_and_tl(t1, t1, t2);
1937 tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
1939 /* operands of same sign, result different sign */
1940 generate_exception(ctx, EXCP_OVERFLOW);
1942 gen_store_gpr(t0, rt);
1949 tcg_gen_addi_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
1951 tcg_gen_movi_tl(cpu_gpr[rt], uimm);
1957 (void)opn; /* avoid a compiler warning */
1958 MIPS_DEBUG("%s %s, %s, " TARGET_FMT_lx, opn, regnames[rt], regnames[rs], uimm);
1961 /* Logic with immediate operand */
1962 static void gen_logic_imm(CPUMIPSState *env, DisasContext *ctx, uint32_t opc,
1963 int rt, int rs, int16_t imm)
1966 const char *opn = "imm logic";
1969 /* If no destination, treat it as a NOP. */
1973 uimm = (uint16_t)imm;
1976 if (likely(rs != 0))
1977 tcg_gen_andi_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
1979 tcg_gen_movi_tl(cpu_gpr[rt], 0);
1984 tcg_gen_ori_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
1986 tcg_gen_movi_tl(cpu_gpr[rt], uimm);
1990 if (likely(rs != 0))
1991 tcg_gen_xori_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
1993 tcg_gen_movi_tl(cpu_gpr[rt], uimm);
1997 tcg_gen_movi_tl(cpu_gpr[rt], imm << 16);
2001 (void)opn; /* avoid a compiler warning */
2002 MIPS_DEBUG("%s %s, %s, " TARGET_FMT_lx, opn, regnames[rt], regnames[rs], uimm);
2005 /* Set on less than with immediate operand */
2006 static void gen_slt_imm(CPUMIPSState *env, DisasContext *ctx, uint32_t opc,
2007 int rt, int rs, int16_t imm)
2009 target_ulong uimm = (target_long)imm; /* Sign extend to 32/64 bits */
2010 const char *opn = "imm arith";
2014 /* If no destination, treat it as a NOP. */
2018 t0 = tcg_temp_new();
2019 gen_load_gpr(t0, rs);
2022 tcg_gen_setcondi_tl(TCG_COND_LT, cpu_gpr[rt], t0, uimm);
2026 tcg_gen_setcondi_tl(TCG_COND_LTU, cpu_gpr[rt], t0, uimm);
2030 (void)opn; /* avoid a compiler warning */
2031 MIPS_DEBUG("%s %s, %s, " TARGET_FMT_lx, opn, regnames[rt], regnames[rs], uimm);
2035 /* Shifts with immediate operand */
2036 static void gen_shift_imm(CPUMIPSState *env, DisasContext *ctx, uint32_t opc,
2037 int rt, int rs, int16_t imm)
2039 target_ulong uimm = ((uint16_t)imm) & 0x1f;
2040 const char *opn = "imm shift";
2044 /* If no destination, treat it as a NOP. */
2049 t0 = tcg_temp_new();
2050 gen_load_gpr(t0, rs);
2053 tcg_gen_shli_tl(t0, t0, uimm);
2054 tcg_gen_ext32s_tl(cpu_gpr[rt], t0);
2058 tcg_gen_sari_tl(cpu_gpr[rt], t0, uimm);
2063 tcg_gen_ext32u_tl(t0, t0);
2064 tcg_gen_shri_tl(cpu_gpr[rt], t0, uimm);
2066 tcg_gen_ext32s_tl(cpu_gpr[rt], t0);
2072 TCGv_i32 t1 = tcg_temp_new_i32();
2074 tcg_gen_trunc_tl_i32(t1, t0);
2075 tcg_gen_rotri_i32(t1, t1, uimm);
2076 tcg_gen_ext_i32_tl(cpu_gpr[rt], t1);
2077 tcg_temp_free_i32(t1);
2079 tcg_gen_ext32s_tl(cpu_gpr[rt], t0);
2083 #if defined(TARGET_MIPS64)
2085 tcg_gen_shli_tl(cpu_gpr[rt], t0, uimm);
2089 tcg_gen_sari_tl(cpu_gpr[rt], t0, uimm);
2093 tcg_gen_shri_tl(cpu_gpr[rt], t0, uimm);
2098 tcg_gen_rotri_tl(cpu_gpr[rt], t0, uimm);
2100 tcg_gen_mov_tl(cpu_gpr[rt], t0);
2105 tcg_gen_shli_tl(cpu_gpr[rt], t0, uimm + 32);
2109 tcg_gen_sari_tl(cpu_gpr[rt], t0, uimm + 32);
2113 tcg_gen_shri_tl(cpu_gpr[rt], t0, uimm + 32);
2117 tcg_gen_rotri_tl(cpu_gpr[rt], t0, uimm + 32);
2122 (void)opn; /* avoid a compiler warning */
2123 MIPS_DEBUG("%s %s, %s, " TARGET_FMT_lx, opn, regnames[rt], regnames[rs], uimm);
2128 static void gen_arith (CPUMIPSState *env, DisasContext *ctx, uint32_t opc,
2129 int rd, int rs, int rt)
2131 const char *opn = "arith";
2133 if (rd == 0 && opc != OPC_ADD && opc != OPC_SUB
2134 && opc != OPC_DADD && opc != OPC_DSUB) {
2135 /* If no destination, treat it as a NOP.
2136 For add & sub, we must generate the overflow exception when needed. */
2144 TCGv t0 = tcg_temp_local_new();
2145 TCGv t1 = tcg_temp_new();
2146 TCGv t2 = tcg_temp_new();
2147 int l1 = gen_new_label();
2149 gen_load_gpr(t1, rs);
2150 gen_load_gpr(t2, rt);
2151 tcg_gen_add_tl(t0, t1, t2);
2152 tcg_gen_ext32s_tl(t0, t0);
2153 tcg_gen_xor_tl(t1, t1, t2);
2154 tcg_gen_xor_tl(t2, t0, t2);
2155 tcg_gen_andc_tl(t1, t2, t1);
2157 tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
2159 /* operands of same sign, result different sign */
2160 generate_exception(ctx, EXCP_OVERFLOW);
2162 gen_store_gpr(t0, rd);
2168 if (rs != 0 && rt != 0) {
2169 tcg_gen_add_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2170 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
2171 } else if (rs == 0 && rt != 0) {
2172 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rt]);
2173 } else if (rs != 0 && rt == 0) {
2174 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
2176 tcg_gen_movi_tl(cpu_gpr[rd], 0);
2182 TCGv t0 = tcg_temp_local_new();
2183 TCGv t1 = tcg_temp_new();
2184 TCGv t2 = tcg_temp_new();
2185 int l1 = gen_new_label();
2187 gen_load_gpr(t1, rs);
2188 gen_load_gpr(t2, rt);
2189 tcg_gen_sub_tl(t0, t1, t2);
2190 tcg_gen_ext32s_tl(t0, t0);
2191 tcg_gen_xor_tl(t2, t1, t2);
2192 tcg_gen_xor_tl(t1, t0, t1);
2193 tcg_gen_and_tl(t1, t1, t2);
2195 tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
2197 /* operands of different sign, first operand and result different sign */
2198 generate_exception(ctx, EXCP_OVERFLOW);
2200 gen_store_gpr(t0, rd);
2206 if (rs != 0 && rt != 0) {
2207 tcg_gen_sub_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2208 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
2209 } else if (rs == 0 && rt != 0) {
2210 tcg_gen_neg_tl(cpu_gpr[rd], cpu_gpr[rt]);
2211 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
2212 } else if (rs != 0 && rt == 0) {
2213 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
2215 tcg_gen_movi_tl(cpu_gpr[rd], 0);
2219 #if defined(TARGET_MIPS64)
2222 TCGv t0 = tcg_temp_local_new();
2223 TCGv t1 = tcg_temp_new();
2224 TCGv t2 = tcg_temp_new();
2225 int l1 = gen_new_label();
2227 gen_load_gpr(t1, rs);
2228 gen_load_gpr(t2, rt);
2229 tcg_gen_add_tl(t0, t1, t2);
2230 tcg_gen_xor_tl(t1, t1, t2);
2231 tcg_gen_xor_tl(t2, t0, t2);
2232 tcg_gen_andc_tl(t1, t2, t1);
2234 tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
2236 /* operands of same sign, result different sign */
2237 generate_exception(ctx, EXCP_OVERFLOW);
2239 gen_store_gpr(t0, rd);
2245 if (rs != 0 && rt != 0) {
2246 tcg_gen_add_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2247 } else if (rs == 0 && rt != 0) {
2248 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rt]);
2249 } else if (rs != 0 && rt == 0) {
2250 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
2252 tcg_gen_movi_tl(cpu_gpr[rd], 0);
2258 TCGv t0 = tcg_temp_local_new();
2259 TCGv t1 = tcg_temp_new();
2260 TCGv t2 = tcg_temp_new();
2261 int l1 = gen_new_label();
2263 gen_load_gpr(t1, rs);
2264 gen_load_gpr(t2, rt);
2265 tcg_gen_sub_tl(t0, t1, t2);
2266 tcg_gen_xor_tl(t2, t1, t2);
2267 tcg_gen_xor_tl(t1, t0, t1);
2268 tcg_gen_and_tl(t1, t1, t2);
2270 tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
2272 /* operands of different sign, first operand and result different sign */
2273 generate_exception(ctx, EXCP_OVERFLOW);
2275 gen_store_gpr(t0, rd);
2281 if (rs != 0 && rt != 0) {
2282 tcg_gen_sub_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2283 } else if (rs == 0 && rt != 0) {
2284 tcg_gen_neg_tl(cpu_gpr[rd], cpu_gpr[rt]);
2285 } else if (rs != 0 && rt == 0) {
2286 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
2288 tcg_gen_movi_tl(cpu_gpr[rd], 0);
2294 if (likely(rs != 0 && rt != 0)) {
2295 tcg_gen_mul_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2296 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
2298 tcg_gen_movi_tl(cpu_gpr[rd], 0);
2303 (void)opn; /* avoid a compiler warning */
2304 MIPS_DEBUG("%s %s, %s, %s", opn, regnames[rd], regnames[rs], regnames[rt]);
2307 /* Conditional move */
2308 static void gen_cond_move(CPUMIPSState *env, DisasContext *ctx, uint32_t opc,
2309 int rd, int rs, int rt)
2311 const char *opn = "cond move";
2315 /* If no destination, treat it as a NOP.
2316 For add & sub, we must generate the overflow exception when needed. */
2321 l1 = gen_new_label();
2324 if (likely(rt != 0))
2325 tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_gpr[rt], 0, l1);
2331 if (likely(rt != 0))
2332 tcg_gen_brcondi_tl(TCG_COND_NE, cpu_gpr[rt], 0, l1);
2337 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
2339 tcg_gen_movi_tl(cpu_gpr[rd], 0);
2342 (void)opn; /* avoid a compiler warning */
2343 MIPS_DEBUG("%s %s, %s, %s", opn, regnames[rd], regnames[rs], regnames[rt]);
2347 static void gen_logic(CPUMIPSState *env, DisasContext *ctx, uint32_t opc,
2348 int rd, int rs, int rt)
2350 const char *opn = "logic";
2353 /* If no destination, treat it as a NOP. */
2360 if (likely(rs != 0 && rt != 0)) {
2361 tcg_gen_and_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2363 tcg_gen_movi_tl(cpu_gpr[rd], 0);
2368 if (rs != 0 && rt != 0) {
2369 tcg_gen_nor_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2370 } else if (rs == 0 && rt != 0) {
2371 tcg_gen_not_tl(cpu_gpr[rd], cpu_gpr[rt]);
2372 } else if (rs != 0 && rt == 0) {
2373 tcg_gen_not_tl(cpu_gpr[rd], cpu_gpr[rs]);
2375 tcg_gen_movi_tl(cpu_gpr[rd], ~((target_ulong)0));
2380 if (likely(rs != 0 && rt != 0)) {
2381 tcg_gen_or_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2382 } else if (rs == 0 && rt != 0) {
2383 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rt]);
2384 } else if (rs != 0 && rt == 0) {
2385 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
2387 tcg_gen_movi_tl(cpu_gpr[rd], 0);
2392 if (likely(rs != 0 && rt != 0)) {
2393 tcg_gen_xor_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2394 } else if (rs == 0 && rt != 0) {
2395 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rt]);
2396 } else if (rs != 0 && rt == 0) {
2397 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
2399 tcg_gen_movi_tl(cpu_gpr[rd], 0);
2404 (void)opn; /* avoid a compiler warning */
2405 MIPS_DEBUG("%s %s, %s, %s", opn, regnames[rd], regnames[rs], regnames[rt]);
2408 /* Set on lower than */
2409 static void gen_slt(CPUMIPSState *env, DisasContext *ctx, uint32_t opc,
2410 int rd, int rs, int rt)
2412 const char *opn = "slt";
2416 /* If no destination, treat it as a NOP. */
2421 t0 = tcg_temp_new();
2422 t1 = tcg_temp_new();
2423 gen_load_gpr(t0, rs);
2424 gen_load_gpr(t1, rt);
2427 tcg_gen_setcond_tl(TCG_COND_LT, cpu_gpr[rd], t0, t1);
2431 tcg_gen_setcond_tl(TCG_COND_LTU, cpu_gpr[rd], t0, t1);
2435 (void)opn; /* avoid a compiler warning */
2436 MIPS_DEBUG("%s %s, %s, %s", opn, regnames[rd], regnames[rs], regnames[rt]);
2442 static void gen_shift (CPUMIPSState *env, DisasContext *ctx, uint32_t opc,
2443 int rd, int rs, int rt)
2445 const char *opn = "shifts";
2449 /* If no destination, treat it as a NOP.
2450 For add & sub, we must generate the overflow exception when needed. */
2455 t0 = tcg_temp_new();
2456 t1 = tcg_temp_new();
2457 gen_load_gpr(t0, rs);
2458 gen_load_gpr(t1, rt);
2461 tcg_gen_andi_tl(t0, t0, 0x1f);
2462 tcg_gen_shl_tl(t0, t1, t0);
2463 tcg_gen_ext32s_tl(cpu_gpr[rd], t0);
2467 tcg_gen_andi_tl(t0, t0, 0x1f);
2468 tcg_gen_sar_tl(cpu_gpr[rd], t1, t0);
2472 tcg_gen_ext32u_tl(t1, t1);
2473 tcg_gen_andi_tl(t0, t0, 0x1f);
2474 tcg_gen_shr_tl(t0, t1, t0);
2475 tcg_gen_ext32s_tl(cpu_gpr[rd], t0);
2480 TCGv_i32 t2 = tcg_temp_new_i32();
2481 TCGv_i32 t3 = tcg_temp_new_i32();
2483 tcg_gen_trunc_tl_i32(t2, t0);
2484 tcg_gen_trunc_tl_i32(t3, t1);
2485 tcg_gen_andi_i32(t2, t2, 0x1f);
2486 tcg_gen_rotr_i32(t2, t3, t2);
2487 tcg_gen_ext_i32_tl(cpu_gpr[rd], t2);
2488 tcg_temp_free_i32(t2);
2489 tcg_temp_free_i32(t3);
2493 #if defined(TARGET_MIPS64)
2495 tcg_gen_andi_tl(t0, t0, 0x3f);
2496 tcg_gen_shl_tl(cpu_gpr[rd], t1, t0);
2500 tcg_gen_andi_tl(t0, t0, 0x3f);
2501 tcg_gen_sar_tl(cpu_gpr[rd], t1, t0);
2505 tcg_gen_andi_tl(t0, t0, 0x3f);
2506 tcg_gen_shr_tl(cpu_gpr[rd], t1, t0);
2510 tcg_gen_andi_tl(t0, t0, 0x3f);
2511 tcg_gen_rotr_tl(cpu_gpr[rd], t1, t0);
2516 (void)opn; /* avoid a compiler warning */
2517 MIPS_DEBUG("%s %s, %s, %s", opn, regnames[rd], regnames[rs], regnames[rt]);
2522 /* Arithmetic on HI/LO registers */
2523 static void gen_HILO (DisasContext *ctx, uint32_t opc, int reg)
2525 const char *opn = "hilo";
2528 if (reg == 0 && (opc == OPC_MFHI || opc == OPC_MFLO)) {
2534 if (opc == OPC_MFHI || opc == OPC_MFLO) {
2535 acc = ((ctx->opcode) >> 21) & 0x03;
2537 acc = ((ctx->opcode) >> 11) & 0x03;
2546 #if defined(TARGET_MIPS64)
2548 tcg_gen_ext32s_tl(cpu_gpr[reg], cpu_HI[acc]);
2552 tcg_gen_mov_tl(cpu_gpr[reg], cpu_HI[acc]);
2557 #if defined(TARGET_MIPS64)
2559 tcg_gen_ext32s_tl(cpu_gpr[reg], cpu_LO[acc]);
2563 tcg_gen_mov_tl(cpu_gpr[reg], cpu_LO[acc]);
2569 #if defined(TARGET_MIPS64)
2571 tcg_gen_ext32s_tl(cpu_HI[acc], cpu_gpr[reg]);
2575 tcg_gen_mov_tl(cpu_HI[acc], cpu_gpr[reg]);
2578 tcg_gen_movi_tl(cpu_HI[acc], 0);
2584 #if defined(TARGET_MIPS64)
2586 tcg_gen_ext32s_tl(cpu_LO[acc], cpu_gpr[reg]);
2590 tcg_gen_mov_tl(cpu_LO[acc], cpu_gpr[reg]);
2593 tcg_gen_movi_tl(cpu_LO[acc], 0);
2598 (void)opn; /* avoid a compiler warning */
2599 MIPS_DEBUG("%s %s", opn, regnames[reg]);
2602 static void gen_muldiv (DisasContext *ctx, uint32_t opc,
2605 const char *opn = "mul/div";
2612 #if defined(TARGET_MIPS64)
2616 t0 = tcg_temp_local_new();
2617 t1 = tcg_temp_local_new();
2620 t0 = tcg_temp_new();
2621 t1 = tcg_temp_new();
2625 gen_load_gpr(t0, rs);
2626 gen_load_gpr(t1, rt);
2630 int l1 = gen_new_label();
2631 int l2 = gen_new_label();
2633 tcg_gen_ext32s_tl(t0, t0);
2634 tcg_gen_ext32s_tl(t1, t1);
2635 tcg_gen_brcondi_tl(TCG_COND_EQ, t1, 0, l1);
2636 tcg_gen_brcondi_tl(TCG_COND_NE, t0, INT_MIN, l2);
2637 tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1, l2);
2639 tcg_gen_mov_tl(cpu_LO[0], t0);
2640 tcg_gen_movi_tl(cpu_HI[0], 0);
2643 tcg_gen_div_tl(cpu_LO[0], t0, t1);
2644 tcg_gen_rem_tl(cpu_HI[0], t0, t1);
2645 tcg_gen_ext32s_tl(cpu_LO[0], cpu_LO[0]);
2646 tcg_gen_ext32s_tl(cpu_HI[0], cpu_HI[0]);
2653 int l1 = gen_new_label();
2655 tcg_gen_ext32u_tl(t0, t0);
2656 tcg_gen_ext32u_tl(t1, t1);
2657 tcg_gen_brcondi_tl(TCG_COND_EQ, t1, 0, l1);
2658 tcg_gen_divu_tl(cpu_LO[0], t0, t1);
2659 tcg_gen_remu_tl(cpu_HI[0], t0, t1);
2660 tcg_gen_ext32s_tl(cpu_LO[0], cpu_LO[0]);
2661 tcg_gen_ext32s_tl(cpu_HI[0], cpu_HI[0]);
2668 TCGv_i64 t2 = tcg_temp_new_i64();
2669 TCGv_i64 t3 = tcg_temp_new_i64();
2670 acc = ((ctx->opcode) >> 11) & 0x03;
2675 tcg_gen_ext_tl_i64(t2, t0);
2676 tcg_gen_ext_tl_i64(t3, t1);
2677 tcg_gen_mul_i64(t2, t2, t3);
2678 tcg_temp_free_i64(t3);
2679 tcg_gen_trunc_i64_tl(t0, t2);
2680 tcg_gen_shri_i64(t2, t2, 32);
2681 tcg_gen_trunc_i64_tl(t1, t2);
2682 tcg_temp_free_i64(t2);
2683 tcg_gen_ext32s_tl(cpu_LO[acc], t0);
2684 tcg_gen_ext32s_tl(cpu_HI[acc], t1);
2690 TCGv_i64 t2 = tcg_temp_new_i64();
2691 TCGv_i64 t3 = tcg_temp_new_i64();
2692 acc = ((ctx->opcode) >> 11) & 0x03;
2697 tcg_gen_ext32u_tl(t0, t0);
2698 tcg_gen_ext32u_tl(t1, t1);
2699 tcg_gen_extu_tl_i64(t2, t0);
2700 tcg_gen_extu_tl_i64(t3, t1);
2701 tcg_gen_mul_i64(t2, t2, t3);
2702 tcg_temp_free_i64(t3);
2703 tcg_gen_trunc_i64_tl(t0, t2);
2704 tcg_gen_shri_i64(t2, t2, 32);
2705 tcg_gen_trunc_i64_tl(t1, t2);
2706 tcg_temp_free_i64(t2);
2707 tcg_gen_ext32s_tl(cpu_LO[acc], t0);
2708 tcg_gen_ext32s_tl(cpu_HI[acc], t1);
2712 #if defined(TARGET_MIPS64)
2715 int l1 = gen_new_label();
2716 int l2 = gen_new_label();
2718 tcg_gen_brcondi_tl(TCG_COND_EQ, t1, 0, l1);
2719 tcg_gen_brcondi_tl(TCG_COND_NE, t0, -1LL << 63, l2);
2720 tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1LL, l2);
2721 tcg_gen_mov_tl(cpu_LO[0], t0);
2722 tcg_gen_movi_tl(cpu_HI[0], 0);
2725 tcg_gen_div_i64(cpu_LO[0], t0, t1);
2726 tcg_gen_rem_i64(cpu_HI[0], t0, t1);
2733 int l1 = gen_new_label();
2735 tcg_gen_brcondi_tl(TCG_COND_EQ, t1, 0, l1);
2736 tcg_gen_divu_i64(cpu_LO[0], t0, t1);
2737 tcg_gen_remu_i64(cpu_HI[0], t0, t1);
2743 gen_helper_dmult(cpu_env, t0, t1);
2747 gen_helper_dmultu(cpu_env, t0, t1);
2753 TCGv_i64 t2 = tcg_temp_new_i64();
2754 TCGv_i64 t3 = tcg_temp_new_i64();
2755 acc = ((ctx->opcode) >> 11) & 0x03;
2760 tcg_gen_ext_tl_i64(t2, t0);
2761 tcg_gen_ext_tl_i64(t3, t1);
2762 tcg_gen_mul_i64(t2, t2, t3);
2763 tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]);
2764 tcg_gen_add_i64(t2, t2, t3);
2765 tcg_temp_free_i64(t3);
2766 tcg_gen_trunc_i64_tl(t0, t2);
2767 tcg_gen_shri_i64(t2, t2, 32);
2768 tcg_gen_trunc_i64_tl(t1, t2);
2769 tcg_temp_free_i64(t2);
2770 tcg_gen_ext32s_tl(cpu_LO[acc], t0);
2771 tcg_gen_ext32s_tl(cpu_HI[acc], t1);
2777 TCGv_i64 t2 = tcg_temp_new_i64();
2778 TCGv_i64 t3 = tcg_temp_new_i64();
2779 acc = ((ctx->opcode) >> 11) & 0x03;
2784 tcg_gen_ext32u_tl(t0, t0);
2785 tcg_gen_ext32u_tl(t1, t1);
2786 tcg_gen_extu_tl_i64(t2, t0);
2787 tcg_gen_extu_tl_i64(t3, t1);
2788 tcg_gen_mul_i64(t2, t2, t3);
2789 tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]);
2790 tcg_gen_add_i64(t2, t2, t3);
2791 tcg_temp_free_i64(t3);
2792 tcg_gen_trunc_i64_tl(t0, t2);
2793 tcg_gen_shri_i64(t2, t2, 32);
2794 tcg_gen_trunc_i64_tl(t1, t2);
2795 tcg_temp_free_i64(t2);
2796 tcg_gen_ext32s_tl(cpu_LO[acc], t0);
2797 tcg_gen_ext32s_tl(cpu_HI[acc], t1);
2803 TCGv_i64 t2 = tcg_temp_new_i64();
2804 TCGv_i64 t3 = tcg_temp_new_i64();
2805 acc = ((ctx->opcode) >> 11) & 0x03;
2810 tcg_gen_ext_tl_i64(t2, t0);
2811 tcg_gen_ext_tl_i64(t3, t1);
2812 tcg_gen_mul_i64(t2, t2, t3);
2813 tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]);
2814 tcg_gen_sub_i64(t2, t3, t2);
2815 tcg_temp_free_i64(t3);
2816 tcg_gen_trunc_i64_tl(t0, t2);
2817 tcg_gen_shri_i64(t2, t2, 32);
2818 tcg_gen_trunc_i64_tl(t1, t2);
2819 tcg_temp_free_i64(t2);
2820 tcg_gen_ext32s_tl(cpu_LO[acc], t0);
2821 tcg_gen_ext32s_tl(cpu_HI[acc], t1);
2827 TCGv_i64 t2 = tcg_temp_new_i64();
2828 TCGv_i64 t3 = tcg_temp_new_i64();
2829 acc = ((ctx->opcode) >> 11) & 0x03;
2834 tcg_gen_ext32u_tl(t0, t0);
2835 tcg_gen_ext32u_tl(t1, t1);
2836 tcg_gen_extu_tl_i64(t2, t0);
2837 tcg_gen_extu_tl_i64(t3, t1);
2838 tcg_gen_mul_i64(t2, t2, t3);
2839 tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]);
2840 tcg_gen_sub_i64(t2, t3, t2);
2841 tcg_temp_free_i64(t3);
2842 tcg_gen_trunc_i64_tl(t0, t2);
2843 tcg_gen_shri_i64(t2, t2, 32);
2844 tcg_gen_trunc_i64_tl(t1, t2);
2845 tcg_temp_free_i64(t2);
2846 tcg_gen_ext32s_tl(cpu_LO[acc], t0);
2847 tcg_gen_ext32s_tl(cpu_HI[acc], t1);
2853 generate_exception(ctx, EXCP_RI);
2856 (void)opn; /* avoid a compiler warning */
2857 MIPS_DEBUG("%s %s %s", opn, regnames[rs], regnames[rt]);
2863 static void gen_mul_vr54xx (DisasContext *ctx, uint32_t opc,
2864 int rd, int rs, int rt)
2866 const char *opn = "mul vr54xx";
2867 TCGv t0 = tcg_temp_new();
2868 TCGv t1 = tcg_temp_new();
2870 gen_load_gpr(t0, rs);
2871 gen_load_gpr(t1, rt);
2874 case OPC_VR54XX_MULS:
2875 gen_helper_muls(t0, cpu_env, t0, t1);
2878 case OPC_VR54XX_MULSU:
2879 gen_helper_mulsu(t0, cpu_env, t0, t1);
2882 case OPC_VR54XX_MACC:
2883 gen_helper_macc(t0, cpu_env, t0, t1);
2886 case OPC_VR54XX_MACCU:
2887 gen_helper_maccu(t0, cpu_env, t0, t1);
2890 case OPC_VR54XX_MSAC:
2891 gen_helper_msac(t0, cpu_env, t0, t1);
2894 case OPC_VR54XX_MSACU:
2895 gen_helper_msacu(t0, cpu_env, t0, t1);
2898 case OPC_VR54XX_MULHI:
2899 gen_helper_mulhi(t0, cpu_env, t0, t1);
2902 case OPC_VR54XX_MULHIU:
2903 gen_helper_mulhiu(t0, cpu_env, t0, t1);
2906 case OPC_VR54XX_MULSHI:
2907 gen_helper_mulshi(t0, cpu_env, t0, t1);
2910 case OPC_VR54XX_MULSHIU:
2911 gen_helper_mulshiu(t0, cpu_env, t0, t1);
2914 case OPC_VR54XX_MACCHI:
2915 gen_helper_macchi(t0, cpu_env, t0, t1);
2918 case OPC_VR54XX_MACCHIU:
2919 gen_helper_macchiu(t0, cpu_env, t0, t1);
2922 case OPC_VR54XX_MSACHI:
2923 gen_helper_msachi(t0, cpu_env, t0, t1);
2926 case OPC_VR54XX_MSACHIU:
2927 gen_helper_msachiu(t0, cpu_env, t0, t1);
2931 MIPS_INVAL("mul vr54xx");
2932 generate_exception(ctx, EXCP_RI);
2935 gen_store_gpr(t0, rd);
2936 (void)opn; /* avoid a compiler warning */
2937 MIPS_DEBUG("%s %s, %s, %s", opn, regnames[rd], regnames[rs], regnames[rt]);
2944 static void gen_cl (DisasContext *ctx, uint32_t opc,
2947 const char *opn = "CLx";
2955 t0 = tcg_temp_new();
2956 gen_load_gpr(t0, rs);
2959 gen_helper_clo(cpu_gpr[rd], t0);
2963 gen_helper_clz(cpu_gpr[rd], t0);
2966 #if defined(TARGET_MIPS64)
2968 gen_helper_dclo(cpu_gpr[rd], t0);
2972 gen_helper_dclz(cpu_gpr[rd], t0);
2977 (void)opn; /* avoid a compiler warning */
2978 MIPS_DEBUG("%s %s, %s", opn, regnames[rd], regnames[rs]);
2982 /* Godson integer instructions */
2983 static void gen_loongson_integer(DisasContext *ctx, uint32_t opc,
2984 int rd, int rs, int rt)
2986 const char *opn = "loongson";
2998 case OPC_MULTU_G_2E:
2999 case OPC_MULTU_G_2F:
3000 #if defined(TARGET_MIPS64)
3001 case OPC_DMULT_G_2E:
3002 case OPC_DMULT_G_2F:
3003 case OPC_DMULTU_G_2E:
3004 case OPC_DMULTU_G_2F:
3006 t0 = tcg_temp_new();
3007 t1 = tcg_temp_new();
3010 t0 = tcg_temp_local_new();
3011 t1 = tcg_temp_local_new();
3015 gen_load_gpr(t0, rs);
3016 gen_load_gpr(t1, rt);
3021 tcg_gen_mul_tl(cpu_gpr[rd], t0, t1);
3022 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3025 case OPC_MULTU_G_2E:
3026 case OPC_MULTU_G_2F:
3027 tcg_gen_ext32u_tl(t0, t0);
3028 tcg_gen_ext32u_tl(t1, t1);
3029 tcg_gen_mul_tl(cpu_gpr[rd], t0, t1);
3030 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3036 int l1 = gen_new_label();
3037 int l2 = gen_new_label();
3038 int l3 = gen_new_label();
3039 tcg_gen_ext32s_tl(t0, t0);
3040 tcg_gen_ext32s_tl(t1, t1);
3041 tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
3042 tcg_gen_movi_tl(cpu_gpr[rd], 0);
3045 tcg_gen_brcondi_tl(TCG_COND_NE, t0, INT_MIN, l2);
3046 tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1, l2);
3047 tcg_gen_mov_tl(cpu_gpr[rd], t0);
3050 tcg_gen_div_tl(cpu_gpr[rd], t0, t1);
3051 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3059 int l1 = gen_new_label();
3060 int l2 = gen_new_label();
3061 tcg_gen_ext32u_tl(t0, t0);
3062 tcg_gen_ext32u_tl(t1, t1);
3063 tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
3064 tcg_gen_movi_tl(cpu_gpr[rd], 0);
3067 tcg_gen_divu_tl(cpu_gpr[rd], t0, t1);
3068 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3076 int l1 = gen_new_label();
3077 int l2 = gen_new_label();
3078 int l3 = gen_new_label();
3079 tcg_gen_ext32u_tl(t0, t0);
3080 tcg_gen_ext32u_tl(t1, t1);
3081 tcg_gen_brcondi_tl(TCG_COND_EQ, t1, 0, l1);
3082 tcg_gen_brcondi_tl(TCG_COND_NE, t0, INT_MIN, l2);
3083 tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1, l2);
3085 tcg_gen_movi_tl(cpu_gpr[rd], 0);
3088 tcg_gen_rem_tl(cpu_gpr[rd], t0, t1);
3089 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3097 int l1 = gen_new_label();
3098 int l2 = gen_new_label();
3099 tcg_gen_ext32u_tl(t0, t0);
3100 tcg_gen_ext32u_tl(t1, t1);
3101 tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
3102 tcg_gen_movi_tl(cpu_gpr[rd], 0);
3105 tcg_gen_remu_tl(cpu_gpr[rd], t0, t1);
3106 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3111 #if defined(TARGET_MIPS64)
3112 case OPC_DMULT_G_2E:
3113 case OPC_DMULT_G_2F:
3114 tcg_gen_mul_tl(cpu_gpr[rd], t0, t1);
3117 case OPC_DMULTU_G_2E:
3118 case OPC_DMULTU_G_2F:
3119 tcg_gen_mul_tl(cpu_gpr[rd], t0, t1);
3125 int l1 = gen_new_label();
3126 int l2 = gen_new_label();
3127 int l3 = gen_new_label();
3128 tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
3129 tcg_gen_movi_tl(cpu_gpr[rd], 0);
3132 tcg_gen_brcondi_tl(TCG_COND_NE, t0, -1LL << 63, l2);
3133 tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1LL, l2);
3134 tcg_gen_mov_tl(cpu_gpr[rd], t0);
3137 tcg_gen_div_tl(cpu_gpr[rd], t0, t1);
3142 case OPC_DDIVU_G_2E:
3143 case OPC_DDIVU_G_2F:
3145 int l1 = gen_new_label();
3146 int l2 = gen_new_label();
3147 tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
3148 tcg_gen_movi_tl(cpu_gpr[rd], 0);
3151 tcg_gen_divu_tl(cpu_gpr[rd], t0, t1);
3159 int l1 = gen_new_label();
3160 int l2 = gen_new_label();
3161 int l3 = gen_new_label();
3162 tcg_gen_brcondi_tl(TCG_COND_EQ, t1, 0, l1);
3163 tcg_gen_brcondi_tl(TCG_COND_NE, t0, -1LL << 63, l2);
3164 tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1LL, l2);
3166 tcg_gen_movi_tl(cpu_gpr[rd], 0);
3169 tcg_gen_rem_tl(cpu_gpr[rd], t0, t1);
3174 case OPC_DMODU_G_2E:
3175 case OPC_DMODU_G_2F:
3177 int l1 = gen_new_label();
3178 int l2 = gen_new_label();
3179 tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
3180 tcg_gen_movi_tl(cpu_gpr[rd], 0);
3183 tcg_gen_remu_tl(cpu_gpr[rd], t0, t1);
3191 (void)opn; /* avoid a compiler warning */
3192 MIPS_DEBUG("%s %s, %s", opn, regnames[rd], regnames[rs]);
3197 /* Loongson multimedia instructions */
3198 static void gen_loongson_multimedia(DisasContext *ctx, int rd, int rs, int rt)
3200 const char *opn = "loongson_cp2";
3201 uint32_t opc, shift_max;
3204 opc = MASK_LMI(ctx->opcode);
3210 t0 = tcg_temp_local_new_i64();
3211 t1 = tcg_temp_local_new_i64();
3214 t0 = tcg_temp_new_i64();
3215 t1 = tcg_temp_new_i64();
3219 gen_load_fpr64(ctx, t0, rs);
3220 gen_load_fpr64(ctx, t1, rt);
3222 #define LMI_HELPER(UP, LO) \
3223 case OPC_##UP: gen_helper_##LO(t0, t0, t1); opn = #LO; break
3224 #define LMI_HELPER_1(UP, LO) \
3225 case OPC_##UP: gen_helper_##LO(t0, t0); opn = #LO; break
3226 #define LMI_DIRECT(UP, LO, OP) \
3227 case OPC_##UP: tcg_gen_##OP##_i64(t0, t0, t1); opn = #LO; break
3230 LMI_HELPER(PADDSH, paddsh);
3231 LMI_HELPER(PADDUSH, paddush);
3232 LMI_HELPER(PADDH, paddh);
3233 LMI_HELPER(PADDW, paddw);
3234 LMI_HELPER(PADDSB, paddsb);
3235 LMI_HELPER(PADDUSB, paddusb);
3236 LMI_HELPER(PADDB, paddb);
3238 LMI_HELPER(PSUBSH, psubsh);
3239 LMI_HELPER(PSUBUSH, psubush);
3240 LMI_HELPER(PSUBH, psubh);
3241 LMI_HELPER(PSUBW, psubw);
3242 LMI_HELPER(PSUBSB, psubsb);
3243 LMI_HELPER(PSUBUSB, psubusb);
3244 LMI_HELPER(PSUBB, psubb);
3246 LMI_HELPER(PSHUFH, pshufh);
3247 LMI_HELPER(PACKSSWH, packsswh);
3248 LMI_HELPER(PACKSSHB, packsshb);
3249 LMI_HELPER(PACKUSHB, packushb);
3251 LMI_HELPER(PUNPCKLHW, punpcklhw);
3252 LMI_HELPER(PUNPCKHHW, punpckhhw);
3253 LMI_HELPER(PUNPCKLBH, punpcklbh);
3254 LMI_HELPER(PUNPCKHBH, punpckhbh);
3255 LMI_HELPER(PUNPCKLWD, punpcklwd);
3256 LMI_HELPER(PUNPCKHWD, punpckhwd);
3258 LMI_HELPER(PAVGH, pavgh);
3259 LMI_HELPER(PAVGB, pavgb);
3260 LMI_HELPER(PMAXSH, pmaxsh);
3261 LMI_HELPER(PMINSH, pminsh);
3262 LMI_HELPER(PMAXUB, pmaxub);
3263 LMI_HELPER(PMINUB, pminub);
3265 LMI_HELPER(PCMPEQW, pcmpeqw);
3266 LMI_HELPER(PCMPGTW, pcmpgtw);
3267 LMI_HELPER(PCMPEQH, pcmpeqh);
3268 LMI_HELPER(PCMPGTH, pcmpgth);
3269 LMI_HELPER(PCMPEQB, pcmpeqb);
3270 LMI_HELPER(PCMPGTB, pcmpgtb);
3272 LMI_HELPER(PSLLW, psllw);
3273 LMI_HELPER(PSLLH, psllh);
3274 LMI_HELPER(PSRLW, psrlw);
3275 LMI_HELPER(PSRLH, psrlh);
3276 LMI_HELPER(PSRAW, psraw);
3277 LMI_HELPER(PSRAH, psrah);
3279 LMI_HELPER(PMULLH, pmullh);
3280 LMI_HELPER(PMULHH, pmulhh);
3281 LMI_HELPER(PMULHUH, pmulhuh);
3282 LMI_HELPER(PMADDHW, pmaddhw);
3284 LMI_HELPER(PASUBUB, pasubub);
3285 LMI_HELPER_1(BIADD, biadd);
3286 LMI_HELPER_1(PMOVMSKB, pmovmskb);
3288 LMI_DIRECT(PADDD, paddd, add);
3289 LMI_DIRECT(PSUBD, psubd, sub);
3290 LMI_DIRECT(XOR_CP2, xor, xor);
3291 LMI_DIRECT(NOR_CP2, nor, nor);
3292 LMI_DIRECT(AND_CP2, and, and);
3293 LMI_DIRECT(PANDN, pandn, andc);
3294 LMI_DIRECT(OR, or, or);
3297 tcg_gen_deposit_i64(t0, t0, t1, 0, 16);
3301 tcg_gen_deposit_i64(t0, t0, t1, 16, 16);
3305 tcg_gen_deposit_i64(t0, t0, t1, 32, 16);
3309 tcg_gen_deposit_i64(t0, t0, t1, 48, 16);
3314 tcg_gen_andi_i64(t1, t1, 3);
3315 tcg_gen_shli_i64(t1, t1, 4);
3316 tcg_gen_shr_i64(t0, t0, t1);
3317 tcg_gen_ext16u_i64(t0, t0);
3322 tcg_gen_add_i64(t0, t0, t1);
3323 tcg_gen_ext32s_i64(t0, t0);
3327 tcg_gen_sub_i64(t0, t0, t1);
3328 tcg_gen_ext32s_i64(t0, t0);
3357 /* Make sure shift count isn't TCG undefined behaviour. */
3358 tcg_gen_andi_i64(t1, t1, shift_max - 1);
3363 tcg_gen_shl_i64(t0, t0, t1);
3367 /* Since SRA is UndefinedResult without sign-extended inputs,
3368 we can treat SRA and DSRA the same. */
3369 tcg_gen_sar_i64(t0, t0, t1);
3372 /* We want to shift in zeros for SRL; zero-extend first. */
3373 tcg_gen_ext32u_i64(t0, t0);
3376 tcg_gen_shr_i64(t0, t0, t1);
3380 if (shift_max == 32) {
3381 tcg_gen_ext32s_i64(t0, t0);
3384 /* Shifts larger than MAX produce zero. */
3385 tcg_gen_setcondi_i64(TCG_COND_LTU, t1, t1, shift_max);
3386 tcg_gen_neg_i64(t1, t1);
3387 tcg_gen_and_i64(t0, t0, t1);
3393 TCGv_i64 t2 = tcg_temp_new_i64();
3394 int lab = gen_new_label();
3396 tcg_gen_mov_i64(t2, t0);
3397 tcg_gen_add_i64(t0, t1, t2);
3398 if (opc == OPC_ADD_CP2) {
3399 tcg_gen_ext32s_i64(t0, t0);
3401 tcg_gen_xor_i64(t1, t1, t2);
3402 tcg_gen_xor_i64(t2, t2, t0);
3403 tcg_gen_andc_i64(t1, t2, t1);
3404 tcg_temp_free_i64(t2);
3405 tcg_gen_brcondi_i64(TCG_COND_GE, t1, 0, lab);
3406 generate_exception(ctx, EXCP_OVERFLOW);
3409 opn = (opc == OPC_ADD_CP2 ? "add" : "dadd");
3416 TCGv_i64 t2 = tcg_temp_new_i64();
3417 int lab = gen_new_label();
3419 tcg_gen_mov_i64(t2, t0);
3420 tcg_gen_sub_i64(t0, t1, t2);
3421 if (opc == OPC_SUB_CP2) {
3422 tcg_gen_ext32s_i64(t0, t0);
3424 tcg_gen_xor_i64(t1, t1, t2);
3425 tcg_gen_xor_i64(t2, t2, t0);
3426 tcg_gen_and_i64(t1, t1, t2);
3427 tcg_temp_free_i64(t2);
3428 tcg_gen_brcondi_i64(TCG_COND_GE, t1, 0, lab);
3429 generate_exception(ctx, EXCP_OVERFLOW);
3432 opn = (opc == OPC_SUB_CP2 ? "sub" : "dsub");
3437 tcg_gen_ext32u_i64(t0, t0);
3438 tcg_gen_ext32u_i64(t1, t1);
3439 tcg_gen_mul_i64(t0, t0, t1);
3449 /* ??? Document is unclear: Set FCC[CC]. Does that mean the
3450 FD field is the CC field? */
3453 generate_exception(ctx, EXCP_RI);
3460 gen_store_fpr64(ctx, t0, rd);
3462 (void)opn; /* avoid a compiler warning */
3463 MIPS_DEBUG("%s %s, %s, %s", opn,
3464 fregnames[rd], fregnames[rs], fregnames[rt]);
3465 tcg_temp_free_i64(t0);
3466 tcg_temp_free_i64(t1);
3470 static void gen_trap (DisasContext *ctx, uint32_t opc,
3471 int rs, int rt, int16_t imm)
3474 TCGv t0 = tcg_temp_new();
3475 TCGv t1 = tcg_temp_new();
3478 /* Load needed operands */
3486 /* Compare two registers */
3488 gen_load_gpr(t0, rs);
3489 gen_load_gpr(t1, rt);
3499 /* Compare register to immediate */
3500 if (rs != 0 || imm != 0) {
3501 gen_load_gpr(t0, rs);
3502 tcg_gen_movi_tl(t1, (int32_t)imm);
3509 case OPC_TEQ: /* rs == rs */
3510 case OPC_TEQI: /* r0 == 0 */
3511 case OPC_TGE: /* rs >= rs */
3512 case OPC_TGEI: /* r0 >= 0 */
3513 case OPC_TGEU: /* rs >= rs unsigned */
3514 case OPC_TGEIU: /* r0 >= 0 unsigned */
3516 generate_exception(ctx, EXCP_TRAP);
3518 case OPC_TLT: /* rs < rs */
3519 case OPC_TLTI: /* r0 < 0 */
3520 case OPC_TLTU: /* rs < rs unsigned */
3521 case OPC_TLTIU: /* r0 < 0 unsigned */
3522 case OPC_TNE: /* rs != rs */
3523 case OPC_TNEI: /* r0 != 0 */
3524 /* Never trap: treat as NOP. */
3528 int l1 = gen_new_label();
3533 tcg_gen_brcond_tl(TCG_COND_NE, t0, t1, l1);
3537 tcg_gen_brcond_tl(TCG_COND_LT, t0, t1, l1);
3541 tcg_gen_brcond_tl(TCG_COND_LTU, t0, t1, l1);
3545 tcg_gen_brcond_tl(TCG_COND_GE, t0, t1, l1);
3549 tcg_gen_brcond_tl(TCG_COND_GEU, t0, t1, l1);
3553 tcg_gen_brcond_tl(TCG_COND_EQ, t0, t1, l1);
3556 generate_exception(ctx, EXCP_TRAP);
3563 static inline void gen_goto_tb(DisasContext *ctx, int n, target_ulong dest)
3565 TranslationBlock *tb;
3567 if ((tb->pc & TARGET_PAGE_MASK) == (dest & TARGET_PAGE_MASK) &&
3568 likely(!ctx->singlestep_enabled)) {
3571 tcg_gen_exit_tb((tcg_target_long)tb + n);
3574 if (ctx->singlestep_enabled) {
3575 save_cpu_state(ctx, 0);
3576 gen_helper_0e0i(raise_exception, EXCP_DEBUG);
3582 /* Branches (before delay slot) */
3583 static void gen_compute_branch (DisasContext *ctx, uint32_t opc,
3585 int rs, int rt, int32_t offset)
3587 target_ulong btgt = -1;
3589 int bcond_compute = 0;
3590 TCGv t0 = tcg_temp_new();
3591 TCGv t1 = tcg_temp_new();
3593 if (ctx->hflags & MIPS_HFLAG_BMASK) {
3594 #ifdef MIPS_DEBUG_DISAS
3595 LOG_DISAS("Branch in delay slot at PC 0x" TARGET_FMT_lx "\n", ctx->pc);
3597 generate_exception(ctx, EXCP_RI);
3601 /* Load needed operands */
3607 /* Compare two registers */
3609 gen_load_gpr(t0, rs);
3610 gen_load_gpr(t1, rt);
3613 btgt = ctx->pc + insn_bytes + offset;
3629 /* Compare to zero */
3631 gen_load_gpr(t0, rs);
3634 btgt = ctx->pc + insn_bytes + offset;
3637 #if defined(TARGET_MIPS64)
3639 tcg_gen_andi_tl(t0, cpu_dspctrl, 0x7F);
3641 tcg_gen_andi_tl(t0, cpu_dspctrl, 0x3F);
3644 btgt = ctx->pc + insn_bytes + offset;
3651 /* Jump to immediate */
3652 btgt = ((ctx->pc + insn_bytes) & (int32_t)0xF0000000) | (uint32_t)offset;
3658 /* Jump to register */
3659 if (offset != 0 && offset != 16) {
3660 /* Hint = 0 is JR/JALR, hint 16 is JR.HB/JALR.HB, the
3661 others are reserved. */
3662 MIPS_INVAL("jump hint");
3663 generate_exception(ctx, EXCP_RI);
3666 gen_load_gpr(btarget, rs);
3669 MIPS_INVAL("branch/jump");
3670 generate_exception(ctx, EXCP_RI);
3673 if (bcond_compute == 0) {
3674 /* No condition to be computed */
3676 case OPC_BEQ: /* rx == rx */
3677 case OPC_BEQL: /* rx == rx likely */
3678 case OPC_BGEZ: /* 0 >= 0 */
3679 case OPC_BGEZL: /* 0 >= 0 likely */
3680 case OPC_BLEZ: /* 0 <= 0 */
3681 case OPC_BLEZL: /* 0 <= 0 likely */
3683 ctx->hflags |= MIPS_HFLAG_B;
3684 MIPS_DEBUG("balways");
3687 case OPC_BGEZAL: /* 0 >= 0 */
3688 case OPC_BGEZALL: /* 0 >= 0 likely */
3689 ctx->hflags |= (opc == OPC_BGEZALS
3691 : MIPS_HFLAG_BDS32);
3692 /* Always take and link */
3694 ctx->hflags |= MIPS_HFLAG_B;
3695 MIPS_DEBUG("balways and link");
3697 case OPC_BNE: /* rx != rx */
3698 case OPC_BGTZ: /* 0 > 0 */
3699 case OPC_BLTZ: /* 0 < 0 */
3701 MIPS_DEBUG("bnever (NOP)");
3704 case OPC_BLTZAL: /* 0 < 0 */
3705 ctx->hflags |= (opc == OPC_BLTZALS
3707 : MIPS_HFLAG_BDS32);
3708 /* Handle as an unconditional branch to get correct delay
3711 btgt = ctx->pc + (opc == OPC_BLTZALS ? 6 : 8);
3712 ctx->hflags |= MIPS_HFLAG_B;
3713 MIPS_DEBUG("bnever and link");
3715 case OPC_BLTZALL: /* 0 < 0 likely */
3716 tcg_gen_movi_tl(cpu_gpr[31], ctx->pc + 8);
3717 /* Skip the instruction in the delay slot */
3718 MIPS_DEBUG("bnever, link and skip");
3721 case OPC_BNEL: /* rx != rx likely */
3722 case OPC_BGTZL: /* 0 > 0 likely */
3723 case OPC_BLTZL: /* 0 < 0 likely */
3724 /* Skip the instruction in the delay slot */
3725 MIPS_DEBUG("bnever and skip");
3729 ctx->hflags |= MIPS_HFLAG_B;
3730 MIPS_DEBUG("j " TARGET_FMT_lx, btgt);
3734 ctx->hflags |= MIPS_HFLAG_BX;
3739 ctx->hflags |= MIPS_HFLAG_B;
3740 ctx->hflags |= ((opc == OPC_JALS || opc == OPC_JALXS)
3742 : MIPS_HFLAG_BDS32);
3743 MIPS_DEBUG("jal " TARGET_FMT_lx, btgt);
3746 ctx->hflags |= MIPS_HFLAG_BR;
3747 if (insn_bytes == 4)
3748 ctx->hflags |= MIPS_HFLAG_BDS32;
3749 MIPS_DEBUG("jr %s", regnames[rs]);
3755 ctx->hflags |= MIPS_HFLAG_BR;
3756 ctx->hflags |= (opc == OPC_JALRS
3758 : MIPS_HFLAG_BDS32);
3759 MIPS_DEBUG("jalr %s, %s", regnames[rt], regnames[rs]);
3762 MIPS_INVAL("branch/jump");
3763 generate_exception(ctx, EXCP_RI);
3769 tcg_gen_setcond_tl(TCG_COND_EQ, bcond, t0, t1);
3770 MIPS_DEBUG("beq %s, %s, " TARGET_FMT_lx,
3771 regnames[rs], regnames[rt], btgt);
3774 tcg_gen_setcond_tl(TCG_COND_EQ, bcond, t0, t1);
3775 MIPS_DEBUG("beql %s, %s, " TARGET_FMT_lx,
3776 regnames[rs], regnames[rt], btgt);
3779 tcg_gen_setcond_tl(TCG_COND_NE, bcond, t0, t1);
3780 MIPS_DEBUG("bne %s, %s, " TARGET_FMT_lx,
3781 regnames[rs], regnames[rt], btgt);
3784 tcg_gen_setcond_tl(TCG_COND_NE, bcond, t0, t1);
3785 MIPS_DEBUG("bnel %s, %s, " TARGET_FMT_lx,
3786 regnames[rs], regnames[rt], btgt);
3789 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 0);
3790 MIPS_DEBUG("bgez %s, " TARGET_FMT_lx, regnames[rs], btgt);
3793 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 0);
3794 MIPS_DEBUG("bgezl %s, " TARGET_FMT_lx, regnames[rs], btgt);
3798 ctx->hflags |= (opc == OPC_BGEZALS
3800 : MIPS_HFLAG_BDS32);
3801 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 0);
3802 MIPS_DEBUG("bgezal %s, " TARGET_FMT_lx, regnames[rs], btgt);
3806 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 0);
3808 MIPS_DEBUG("bgezall %s, " TARGET_FMT_lx, regnames[rs], btgt);
3811 tcg_gen_setcondi_tl(TCG_COND_GT, bcond, t0, 0);
3812 MIPS_DEBUG("bgtz %s, " TARGET_FMT_lx, regnames[rs], btgt);
3815 tcg_gen_setcondi_tl(TCG_COND_GT, bcond, t0, 0);
3816 MIPS_DEBUG("bgtzl %s, " TARGET_FMT_lx, regnames[rs], btgt);
3819 tcg_gen_setcondi_tl(TCG_COND_LE, bcond, t0, 0);
3820 MIPS_DEBUG("blez %s, " TARGET_FMT_lx, regnames[rs], btgt);
3823 tcg_gen_setcondi_tl(TCG_COND_LE, bcond, t0, 0);
3824 MIPS_DEBUG("blezl %s, " TARGET_FMT_lx, regnames[rs], btgt);
3827 tcg_gen_setcondi_tl(TCG_COND_LT, bcond, t0, 0);
3828 MIPS_DEBUG("bltz %s, " TARGET_FMT_lx, regnames[rs], btgt);
3831 tcg_gen_setcondi_tl(TCG_COND_LT, bcond, t0, 0);
3832 MIPS_DEBUG("bltzl %s, " TARGET_FMT_lx, regnames[rs], btgt);
3835 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 32);
3836 MIPS_DEBUG("bposge32 " TARGET_FMT_lx, btgt);
3838 #if defined(TARGET_MIPS64)
3840 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 64);
3841 MIPS_DEBUG("bposge64 " TARGET_FMT_lx, btgt);
3846 ctx->hflags |= (opc == OPC_BLTZALS
3848 : MIPS_HFLAG_BDS32);
3849 tcg_gen_setcondi_tl(TCG_COND_LT, bcond, t0, 0);
3851 MIPS_DEBUG("bltzal %s, " TARGET_FMT_lx, regnames[rs], btgt);
3853 ctx->hflags |= MIPS_HFLAG_BC;
3856 tcg_gen_setcondi_tl(TCG_COND_LT, bcond, t0, 0);
3858 MIPS_DEBUG("bltzall %s, " TARGET_FMT_lx, regnames[rs], btgt);
3860 ctx->hflags |= MIPS_HFLAG_BL;
3863 MIPS_INVAL("conditional branch/jump");
3864 generate_exception(ctx, EXCP_RI);
3868 MIPS_DEBUG("enter ds: link %d cond %02x target " TARGET_FMT_lx,
3869 blink, ctx->hflags, btgt);
3871 ctx->btarget = btgt;
3873 int post_delay = insn_bytes;
3874 int lowbit = !!(ctx->hflags & MIPS_HFLAG_M16);
3876 if (opc != OPC_JALRC)
3877 post_delay += ((ctx->hflags & MIPS_HFLAG_BDS16) ? 2 : 4);
3879 tcg_gen_movi_tl(cpu_gpr[blink], ctx->pc + post_delay + lowbit);
3883 if (insn_bytes == 2)
3884 ctx->hflags |= MIPS_HFLAG_B16;
3889 /* special3 bitfield operations */
3890 static void gen_bitops (DisasContext *ctx, uint32_t opc, int rt,
3891 int rs, int lsb, int msb)
3893 TCGv t0 = tcg_temp_new();
3894 TCGv t1 = tcg_temp_new();
3897 gen_load_gpr(t1, rs);
3902 tcg_gen_shri_tl(t0, t1, lsb);
3904 tcg_gen_andi_tl(t0, t0, (1 << (msb + 1)) - 1);
3906 tcg_gen_ext32s_tl(t0, t0);
3909 #if defined(TARGET_MIPS64)
3911 tcg_gen_shri_tl(t0, t1, lsb);
3913 tcg_gen_andi_tl(t0, t0, (1ULL << (msb + 1 + 32)) - 1);
3917 tcg_gen_shri_tl(t0, t1, lsb + 32);
3918 tcg_gen_andi_tl(t0, t0, (1ULL << (msb + 1)) - 1);
3921 tcg_gen_shri_tl(t0, t1, lsb);
3922 tcg_gen_andi_tl(t0, t0, (1ULL << (msb + 1)) - 1);
3928 mask = ((msb - lsb + 1 < 32) ? ((1 << (msb - lsb + 1)) - 1) : ~0) << lsb;
3929 gen_load_gpr(t0, rt);
3930 tcg_gen_andi_tl(t0, t0, ~mask);
3931 tcg_gen_shli_tl(t1, t1, lsb);
3932 tcg_gen_andi_tl(t1, t1, mask);
3933 tcg_gen_or_tl(t0, t0, t1);
3934 tcg_gen_ext32s_tl(t0, t0);
3936 #if defined(TARGET_MIPS64)
3940 mask = ((msb - lsb + 1 + 32 < 64) ? ((1ULL << (msb - lsb + 1 + 32)) - 1) : ~0ULL) << lsb;
3941 gen_load_gpr(t0, rt);
3942 tcg_gen_andi_tl(t0, t0, ~mask);
3943 tcg_gen_shli_tl(t1, t1, lsb);
3944 tcg_gen_andi_tl(t1, t1, mask);
3945 tcg_gen_or_tl(t0, t0, t1);
3950 mask = ((1ULL << (msb - lsb + 1)) - 1) << (lsb + 32);
3951 gen_load_gpr(t0, rt);
3952 tcg_gen_andi_tl(t0, t0, ~mask);
3953 tcg_gen_shli_tl(t1, t1, lsb + 32);
3954 tcg_gen_andi_tl(t1, t1, mask);
3955 tcg_gen_or_tl(t0, t0, t1);
3960 gen_load_gpr(t0, rt);
3961 mask = ((1ULL << (msb - lsb + 1)) - 1) << 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);
3971 MIPS_INVAL("bitops");
3972 generate_exception(ctx, EXCP_RI);
3977 gen_store_gpr(t0, rt);
3982 static void gen_bshfl (DisasContext *ctx, uint32_t op2, int rt, int rd)
3987 /* If no destination, treat it as a NOP. */
3992 t0 = tcg_temp_new();
3993 gen_load_gpr(t0, rt);
3997 TCGv t1 = tcg_temp_new();
3999 tcg_gen_shri_tl(t1, t0, 8);
4000 tcg_gen_andi_tl(t1, t1, 0x00FF00FF);
4001 tcg_gen_shli_tl(t0, t0, 8);
4002 tcg_gen_andi_tl(t0, t0, ~0x00FF00FF);
4003 tcg_gen_or_tl(t0, t0, t1);
4005 tcg_gen_ext32s_tl(cpu_gpr[rd], t0);
4009 tcg_gen_ext8s_tl(cpu_gpr[rd], t0);
4012 tcg_gen_ext16s_tl(cpu_gpr[rd], t0);
4014 #if defined(TARGET_MIPS64)
4017 TCGv t1 = tcg_temp_new();
4019 tcg_gen_shri_tl(t1, t0, 8);
4020 tcg_gen_andi_tl(t1, t1, 0x00FF00FF00FF00FFULL);
4021 tcg_gen_shli_tl(t0, t0, 8);
4022 tcg_gen_andi_tl(t0, t0, ~0x00FF00FF00FF00FFULL);
4023 tcg_gen_or_tl(cpu_gpr[rd], t0, t1);
4029 TCGv t1 = tcg_temp_new();
4031 tcg_gen_shri_tl(t1, t0, 16);
4032 tcg_gen_andi_tl(t1, t1, 0x0000FFFF0000FFFFULL);
4033 tcg_gen_shli_tl(t0, t0, 16);
4034 tcg_gen_andi_tl(t0, t0, ~0x0000FFFF0000FFFFULL);
4035 tcg_gen_or_tl(t0, t0, t1);
4036 tcg_gen_shri_tl(t1, t0, 32);
4037 tcg_gen_shli_tl(t0, t0, 32);
4038 tcg_gen_or_tl(cpu_gpr[rd], t0, t1);
4044 MIPS_INVAL("bsfhl");
4045 generate_exception(ctx, EXCP_RI);
4052 #ifndef CONFIG_USER_ONLY
4053 /* CP0 (MMU and control) */
4054 static inline void gen_mfc0_load32 (TCGv arg, target_ulong off)
4056 TCGv_i32 t0 = tcg_temp_new_i32();
4058 tcg_gen_ld_i32(t0, cpu_env, off);
4059 tcg_gen_ext_i32_tl(arg, t0);
4060 tcg_temp_free_i32(t0);
4063 static inline void gen_mfc0_load64 (TCGv arg, target_ulong off)
4065 tcg_gen_ld_tl(arg, cpu_env, off);
4066 tcg_gen_ext32s_tl(arg, arg);
4069 static inline void gen_mtc0_store32 (TCGv arg, target_ulong off)
4071 TCGv_i32 t0 = tcg_temp_new_i32();
4073 tcg_gen_trunc_tl_i32(t0, arg);
4074 tcg_gen_st_i32(t0, cpu_env, off);
4075 tcg_temp_free_i32(t0);
4078 static inline void gen_mtc0_store64 (TCGv arg, target_ulong off)
4080 tcg_gen_ext32s_tl(arg, arg);
4081 tcg_gen_st_tl(arg, cpu_env, off);
4084 static void gen_mfc0 (CPUMIPSState *env, DisasContext *ctx, TCGv arg, int reg, int sel)
4086 const char *rn = "invalid";
4089 check_insn(env, ctx, ISA_MIPS32);
4095 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Index));
4099 check_insn(env, ctx, ASE_MT);
4100 gen_helper_mfc0_mvpcontrol(arg, cpu_env);
4104 check_insn(env, ctx, ASE_MT);
4105 gen_helper_mfc0_mvpconf0(arg, cpu_env);
4109 check_insn(env, ctx, ASE_MT);
4110 gen_helper_mfc0_mvpconf1(arg, cpu_env);
4120 gen_helper_mfc0_random(arg, cpu_env);
4124 check_insn(env, ctx, ASE_MT);
4125 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEControl));
4129 check_insn(env, ctx, ASE_MT);
4130 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEConf0));
4134 check_insn(env, ctx, ASE_MT);
4135 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEConf1));
4139 check_insn(env, ctx, ASE_MT);
4140 gen_mfc0_load64(arg, offsetof(CPUMIPSState, CP0_YQMask));
4144 check_insn(env, ctx, ASE_MT);
4145 gen_mfc0_load64(arg, offsetof(CPUMIPSState, CP0_VPESchedule));
4149 check_insn(env, ctx, ASE_MT);
4150 gen_mfc0_load64(arg, offsetof(CPUMIPSState, CP0_VPEScheFBack));
4151 rn = "VPEScheFBack";
4154 check_insn(env, ctx, ASE_MT);
4155 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEOpt));
4165 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EntryLo0));
4166 tcg_gen_ext32s_tl(arg, arg);
4170 check_insn(env, ctx, ASE_MT);
4171 gen_helper_mfc0_tcstatus(arg, cpu_env);
4175 check_insn(env, ctx, ASE_MT);
4176 gen_helper_mfc0_tcbind(arg, cpu_env);
4180 check_insn(env, ctx, ASE_MT);
4181 gen_helper_mfc0_tcrestart(arg, cpu_env);
4185 check_insn(env, ctx, ASE_MT);
4186 gen_helper_mfc0_tchalt(arg, cpu_env);
4190 check_insn(env, ctx, ASE_MT);
4191 gen_helper_mfc0_tccontext(arg, cpu_env);
4195 check_insn(env, ctx, ASE_MT);
4196 gen_helper_mfc0_tcschedule(arg, cpu_env);
4200 check_insn(env, ctx, ASE_MT);
4201 gen_helper_mfc0_tcschefback(arg, cpu_env);
4211 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EntryLo1));
4212 tcg_gen_ext32s_tl(arg, arg);
4222 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_Context));
4223 tcg_gen_ext32s_tl(arg, arg);
4227 // gen_helper_mfc0_contextconfig(arg); /* SmartMIPS ASE */
4228 rn = "ContextConfig";
4237 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PageMask));
4241 check_insn(env, ctx, ISA_MIPS32R2);
4242 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PageGrain));
4252 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Wired));
4256 check_insn(env, ctx, ISA_MIPS32R2);
4257 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf0));
4261 check_insn(env, ctx, ISA_MIPS32R2);
4262 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf1));
4266 check_insn(env, ctx, ISA_MIPS32R2);
4267 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf2));
4271 check_insn(env, ctx, ISA_MIPS32R2);
4272 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf3));
4276 check_insn(env, ctx, ISA_MIPS32R2);
4277 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf4));
4287 check_insn(env, ctx, ISA_MIPS32R2);
4288 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_HWREna));
4298 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_BadVAddr));
4299 tcg_gen_ext32s_tl(arg, arg);
4309 /* Mark as an IO operation because we read the time. */
4312 gen_helper_mfc0_count(arg, cpu_env);
4316 /* Break the TB to be able to take timer interrupts immediately
4317 after reading count. */
4318 ctx->bstate = BS_STOP;
4321 /* 6,7 are implementation dependent */
4329 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EntryHi));
4330 tcg_gen_ext32s_tl(arg, arg);
4340 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Compare));
4343 /* 6,7 are implementation dependent */
4351 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Status));
4355 check_insn(env, ctx, ISA_MIPS32R2);
4356 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_IntCtl));
4360 check_insn(env, ctx, ISA_MIPS32R2);
4361 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSCtl));
4365 check_insn(env, ctx, ISA_MIPS32R2);
4366 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSMap));
4376 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Cause));
4386 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EPC));
4387 tcg_gen_ext32s_tl(arg, arg);
4397 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PRid));
4401 check_insn(env, ctx, ISA_MIPS32R2);
4402 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_EBase));
4412 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config0));
4416 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config1));
4420 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config2));
4424 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config3));
4427 /* 4,5 are reserved */
4428 /* 6,7 are implementation dependent */
4430 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config6));
4434 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config7));
4444 gen_helper_mfc0_lladdr(arg, cpu_env);
4454 gen_helper_1e0i(mfc0_watchlo, arg, sel);
4464 gen_helper_1e0i(mfc0_watchhi, arg, sel);
4474 #if defined(TARGET_MIPS64)
4475 check_insn(env, ctx, ISA_MIPS3);
4476 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_XContext));
4477 tcg_gen_ext32s_tl(arg, arg);
4486 /* Officially reserved, but sel 0 is used for R1x000 framemask */
4489 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Framemask));
4497 tcg_gen_movi_tl(arg, 0); /* unimplemented */
4498 rn = "'Diagnostic"; /* implementation dependent */
4503 gen_helper_mfc0_debug(arg, cpu_env); /* EJTAG support */
4507 // gen_helper_mfc0_tracecontrol(arg); /* PDtrace support */
4508 rn = "TraceControl";
4511 // gen_helper_mfc0_tracecontrol2(arg); /* PDtrace support */
4512 rn = "TraceControl2";
4515 // gen_helper_mfc0_usertracedata(arg); /* PDtrace support */
4516 rn = "UserTraceData";
4519 // gen_helper_mfc0_tracebpc(arg); /* PDtrace support */
4530 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_DEPC));
4531 tcg_gen_ext32s_tl(arg, arg);
4541 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Performance0));
4542 rn = "Performance0";
4545 // gen_helper_mfc0_performance1(arg);
4546 rn = "Performance1";
4549 // gen_helper_mfc0_performance2(arg);
4550 rn = "Performance2";
4553 // gen_helper_mfc0_performance3(arg);
4554 rn = "Performance3";
4557 // gen_helper_mfc0_performance4(arg);
4558 rn = "Performance4";
4561 // gen_helper_mfc0_performance5(arg);
4562 rn = "Performance5";
4565 // gen_helper_mfc0_performance6(arg);
4566 rn = "Performance6";
4569 // gen_helper_mfc0_performance7(arg);
4570 rn = "Performance7";
4577 tcg_gen_movi_tl(arg, 0); /* unimplemented */
4583 tcg_gen_movi_tl(arg, 0); /* unimplemented */
4596 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_TagLo));
4603 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DataLo));
4616 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_TagHi));
4623 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DataHi));
4633 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_ErrorEPC));
4634 tcg_gen_ext32s_tl(arg, arg);
4645 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DESAVE));
4655 (void)rn; /* avoid a compiler warning */
4656 LOG_DISAS("mfc0 %s (reg %d sel %d)\n", rn, reg, sel);
4660 LOG_DISAS("mfc0 %s (reg %d sel %d)\n", rn, reg, sel);
4661 generate_exception(ctx, EXCP_RI);
4664 static void gen_mtc0 (CPUMIPSState *env, DisasContext *ctx, TCGv arg, int reg, int sel)
4666 const char *rn = "invalid";
4669 check_insn(env, ctx, ISA_MIPS32);
4678 gen_helper_mtc0_index(cpu_env, arg);
4682 check_insn(env, ctx, ASE_MT);
4683 gen_helper_mtc0_mvpcontrol(cpu_env, arg);
4687 check_insn(env, ctx, ASE_MT);
4692 check_insn(env, ctx, ASE_MT);
4707 check_insn(env, ctx, ASE_MT);
4708 gen_helper_mtc0_vpecontrol(cpu_env, arg);
4712 check_insn(env, ctx, ASE_MT);
4713 gen_helper_mtc0_vpeconf0(cpu_env, arg);
4717 check_insn(env, ctx, ASE_MT);
4718 gen_helper_mtc0_vpeconf1(cpu_env, arg);
4722 check_insn(env, ctx, ASE_MT);
4723 gen_helper_mtc0_yqmask(cpu_env, arg);
4727 check_insn(env, ctx, ASE_MT);
4728 gen_mtc0_store64(arg, offsetof(CPUMIPSState, CP0_VPESchedule));
4732 check_insn(env, ctx, ASE_MT);
4733 gen_mtc0_store64(arg, offsetof(CPUMIPSState, CP0_VPEScheFBack));
4734 rn = "VPEScheFBack";
4737 check_insn(env, ctx, ASE_MT);
4738 gen_helper_mtc0_vpeopt(cpu_env, arg);
4748 gen_helper_mtc0_entrylo0(cpu_env, arg);
4752 check_insn(env, ctx, ASE_MT);
4753 gen_helper_mtc0_tcstatus(cpu_env, arg);
4757 check_insn(env, ctx, ASE_MT);
4758 gen_helper_mtc0_tcbind(cpu_env, arg);
4762 check_insn(env, ctx, ASE_MT);
4763 gen_helper_mtc0_tcrestart(cpu_env, arg);
4767 check_insn(env, ctx, ASE_MT);
4768 gen_helper_mtc0_tchalt(cpu_env, arg);
4772 check_insn(env, ctx, ASE_MT);
4773 gen_helper_mtc0_tccontext(cpu_env, arg);
4777 check_insn(env, ctx, ASE_MT);
4778 gen_helper_mtc0_tcschedule(cpu_env, arg);
4782 check_insn(env, ctx, ASE_MT);
4783 gen_helper_mtc0_tcschefback(cpu_env, arg);
4793 gen_helper_mtc0_entrylo1(cpu_env, arg);
4803 gen_helper_mtc0_context(cpu_env, arg);
4807 // gen_helper_mtc0_contextconfig(cpu_env, arg); /* SmartMIPS ASE */
4808 rn = "ContextConfig";
4817 gen_helper_mtc0_pagemask(cpu_env, arg);
4821 check_insn(env, ctx, ISA_MIPS32R2);
4822 gen_helper_mtc0_pagegrain(cpu_env, arg);
4832 gen_helper_mtc0_wired(cpu_env, arg);
4836 check_insn(env, ctx, ISA_MIPS32R2);
4837 gen_helper_mtc0_srsconf0(cpu_env, arg);
4841 check_insn(env, ctx, ISA_MIPS32R2);
4842 gen_helper_mtc0_srsconf1(cpu_env, arg);
4846 check_insn(env, ctx, ISA_MIPS32R2);
4847 gen_helper_mtc0_srsconf2(cpu_env, arg);
4851 check_insn(env, ctx, ISA_MIPS32R2);
4852 gen_helper_mtc0_srsconf3(cpu_env, arg);
4856 check_insn(env, ctx, ISA_MIPS32R2);
4857 gen_helper_mtc0_srsconf4(cpu_env, arg);
4867 check_insn(env, ctx, ISA_MIPS32R2);
4868 gen_helper_mtc0_hwrena(cpu_env, arg);
4882 gen_helper_mtc0_count(cpu_env, arg);
4885 /* 6,7 are implementation dependent */
4893 gen_helper_mtc0_entryhi(cpu_env, arg);
4903 gen_helper_mtc0_compare(cpu_env, arg);
4906 /* 6,7 are implementation dependent */
4914 save_cpu_state(ctx, 1);
4915 gen_helper_mtc0_status(cpu_env, arg);
4916 /* BS_STOP isn't good enough here, hflags may have changed. */
4917 gen_save_pc(ctx->pc + 4);
4918 ctx->bstate = BS_EXCP;
4922 check_insn(env, ctx, ISA_MIPS32R2);
4923 gen_helper_mtc0_intctl(cpu_env, arg);
4924 /* Stop translation as we may have switched the execution mode */
4925 ctx->bstate = BS_STOP;
4929 check_insn(env, ctx, ISA_MIPS32R2);
4930 gen_helper_mtc0_srsctl(cpu_env, arg);
4931 /* Stop translation as we may have switched the execution mode */
4932 ctx->bstate = BS_STOP;
4936 check_insn(env, ctx, ISA_MIPS32R2);
4937 gen_mtc0_store32(arg, offsetof(CPUMIPSState, CP0_SRSMap));
4938 /* Stop translation as we may have switched the execution mode */
4939 ctx->bstate = BS_STOP;
4949 save_cpu_state(ctx, 1);
4950 gen_helper_mtc0_cause(cpu_env, arg);
4960 gen_mtc0_store64(arg, offsetof(CPUMIPSState, CP0_EPC));
4974 check_insn(env, ctx, ISA_MIPS32R2);
4975 gen_helper_mtc0_ebase(cpu_env, arg);
4985 gen_helper_mtc0_config0(cpu_env, arg);
4987 /* Stop translation as we may have switched the execution mode */
4988 ctx->bstate = BS_STOP;
4991 /* ignored, read only */
4995 gen_helper_mtc0_config2(cpu_env, arg);
4997 /* Stop translation as we may have switched the execution mode */
4998 ctx->bstate = BS_STOP;
5001 /* ignored, read only */
5004 /* 4,5 are reserved */
5005 /* 6,7 are implementation dependent */
5015 rn = "Invalid config selector";
5022 gen_helper_mtc0_lladdr(cpu_env, arg);
5032 gen_helper_0e1i(mtc0_watchlo, arg, sel);
5042 gen_helper_0e1i(mtc0_watchhi, arg, sel);
5052 #if defined(TARGET_MIPS64)
5053 check_insn(env, ctx, ISA_MIPS3);
5054 gen_helper_mtc0_xcontext(cpu_env, arg);
5063 /* Officially reserved, but sel 0 is used for R1x000 framemask */
5066 gen_helper_mtc0_framemask(cpu_env, arg);
5075 rn = "Diagnostic"; /* implementation dependent */
5080 gen_helper_mtc0_debug(cpu_env, arg); /* EJTAG support */
5081 /* BS_STOP isn't good enough here, hflags may have changed. */
5082 gen_save_pc(ctx->pc + 4);
5083 ctx->bstate = BS_EXCP;
5087 // gen_helper_mtc0_tracecontrol(cpu_env, arg); /* PDtrace support */
5088 rn = "TraceControl";
5089 /* Stop translation as we may have switched the execution mode */
5090 ctx->bstate = BS_STOP;
5093 // gen_helper_mtc0_tracecontrol2(cpu_env, arg); /* PDtrace support */
5094 rn = "TraceControl2";
5095 /* Stop translation as we may have switched the execution mode */
5096 ctx->bstate = BS_STOP;
5099 /* Stop translation as we may have switched the execution mode */
5100 ctx->bstate = BS_STOP;
5101 // gen_helper_mtc0_usertracedata(cpu_env, arg); /* PDtrace support */
5102 rn = "UserTraceData";
5103 /* Stop translation as we may have switched the execution mode */
5104 ctx->bstate = BS_STOP;
5107 // gen_helper_mtc0_tracebpc(cpu_env, arg); /* PDtrace support */
5108 /* Stop translation as we may have switched the execution mode */
5109 ctx->bstate = BS_STOP;
5120 gen_mtc0_store64(arg, offsetof(CPUMIPSState, CP0_DEPC));
5130 gen_helper_mtc0_performance0(cpu_env, arg);
5131 rn = "Performance0";
5134 // gen_helper_mtc0_performance1(arg);
5135 rn = "Performance1";
5138 // gen_helper_mtc0_performance2(arg);
5139 rn = "Performance2";
5142 // gen_helper_mtc0_performance3(arg);
5143 rn = "Performance3";
5146 // gen_helper_mtc0_performance4(arg);
5147 rn = "Performance4";
5150 // gen_helper_mtc0_performance5(arg);
5151 rn = "Performance5";
5154 // gen_helper_mtc0_performance6(arg);
5155 rn = "Performance6";
5158 // gen_helper_mtc0_performance7(arg);
5159 rn = "Performance7";
5185 gen_helper_mtc0_taglo(cpu_env, arg);
5192 gen_helper_mtc0_datalo(cpu_env, arg);
5205 gen_helper_mtc0_taghi(cpu_env, arg);
5212 gen_helper_mtc0_datahi(cpu_env, arg);
5223 gen_mtc0_store64(arg, offsetof(CPUMIPSState, CP0_ErrorEPC));
5234 gen_mtc0_store32(arg, offsetof(CPUMIPSState, CP0_DESAVE));
5240 /* Stop translation as we may have switched the execution mode */
5241 ctx->bstate = BS_STOP;
5246 (void)rn; /* avoid a compiler warning */
5247 LOG_DISAS("mtc0 %s (reg %d sel %d)\n", rn, reg, sel);
5248 /* For simplicity assume that all writes can cause interrupts. */
5251 ctx->bstate = BS_STOP;
5256 LOG_DISAS("mtc0 %s (reg %d sel %d)\n", rn, reg, sel);
5257 generate_exception(ctx, EXCP_RI);
5260 #if defined(TARGET_MIPS64)
5261 static void gen_dmfc0 (CPUMIPSState *env, DisasContext *ctx, TCGv arg, int reg, int sel)
5263 const char *rn = "invalid";
5266 check_insn(env, ctx, ISA_MIPS64);
5272 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Index));
5276 check_insn(env, ctx, ASE_MT);
5277 gen_helper_mfc0_mvpcontrol(arg, cpu_env);
5281 check_insn(env, ctx, ASE_MT);
5282 gen_helper_mfc0_mvpconf0(arg, cpu_env);
5286 check_insn(env, ctx, ASE_MT);
5287 gen_helper_mfc0_mvpconf1(arg, cpu_env);
5297 gen_helper_mfc0_random(arg, cpu_env);
5301 check_insn(env, ctx, ASE_MT);
5302 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEControl));
5306 check_insn(env, ctx, ASE_MT);
5307 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEConf0));
5311 check_insn(env, ctx, ASE_MT);
5312 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEConf1));
5316 check_insn(env, ctx, ASE_MT);
5317 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_YQMask));
5321 check_insn(env, ctx, ASE_MT);
5322 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_VPESchedule));
5326 check_insn(env, ctx, ASE_MT);
5327 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_VPEScheFBack));
5328 rn = "VPEScheFBack";
5331 check_insn(env, ctx, ASE_MT);
5332 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEOpt));
5342 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EntryLo0));
5346 check_insn(env, ctx, ASE_MT);
5347 gen_helper_mfc0_tcstatus(arg, cpu_env);
5351 check_insn(env, ctx, ASE_MT);
5352 gen_helper_mfc0_tcbind(arg, cpu_env);
5356 check_insn(env, ctx, ASE_MT);
5357 gen_helper_dmfc0_tcrestart(arg, cpu_env);
5361 check_insn(env, ctx, ASE_MT);
5362 gen_helper_dmfc0_tchalt(arg, cpu_env);
5366 check_insn(env, ctx, ASE_MT);
5367 gen_helper_dmfc0_tccontext(arg, cpu_env);
5371 check_insn(env, ctx, ASE_MT);
5372 gen_helper_dmfc0_tcschedule(arg, cpu_env);
5376 check_insn(env, ctx, ASE_MT);
5377 gen_helper_dmfc0_tcschefback(arg, cpu_env);
5387 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EntryLo1));
5397 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_Context));
5401 // gen_helper_dmfc0_contextconfig(arg); /* SmartMIPS ASE */
5402 rn = "ContextConfig";
5411 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PageMask));
5415 check_insn(env, ctx, ISA_MIPS32R2);
5416 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PageGrain));
5426 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Wired));
5430 check_insn(env, ctx, ISA_MIPS32R2);
5431 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf0));
5435 check_insn(env, ctx, ISA_MIPS32R2);
5436 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf1));
5440 check_insn(env, ctx, ISA_MIPS32R2);
5441 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf2));
5445 check_insn(env, ctx, ISA_MIPS32R2);
5446 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf3));
5450 check_insn(env, ctx, ISA_MIPS32R2);
5451 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf4));
5461 check_insn(env, ctx, ISA_MIPS32R2);
5462 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_HWREna));
5472 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_BadVAddr));
5482 /* Mark as an IO operation because we read the time. */
5485 gen_helper_mfc0_count(arg, cpu_env);
5489 /* Break the TB to be able to take timer interrupts immediately
5490 after reading count. */
5491 ctx->bstate = BS_STOP;
5494 /* 6,7 are implementation dependent */
5502 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EntryHi));
5512 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Compare));
5515 /* 6,7 are implementation dependent */
5523 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Status));
5527 check_insn(env, ctx, ISA_MIPS32R2);
5528 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_IntCtl));
5532 check_insn(env, ctx, ISA_MIPS32R2);
5533 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSCtl));
5537 check_insn(env, ctx, ISA_MIPS32R2);
5538 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSMap));
5548 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Cause));
5558 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EPC));
5568 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PRid));
5572 check_insn(env, ctx, ISA_MIPS32R2);
5573 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_EBase));
5583 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config0));
5587 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config1));
5591 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config2));
5595 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config3));
5598 /* 6,7 are implementation dependent */
5600 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config6));
5604 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config7));
5614 gen_helper_dmfc0_lladdr(arg, cpu_env);
5624 gen_helper_1e0i(dmfc0_watchlo, arg, sel);
5634 gen_helper_1e0i(mfc0_watchhi, arg, sel);
5644 check_insn(env, ctx, ISA_MIPS3);
5645 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_XContext));
5653 /* Officially reserved, but sel 0 is used for R1x000 framemask */
5656 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Framemask));
5664 tcg_gen_movi_tl(arg, 0); /* unimplemented */
5665 rn = "'Diagnostic"; /* implementation dependent */
5670 gen_helper_mfc0_debug(arg, cpu_env); /* EJTAG support */
5674 // gen_helper_dmfc0_tracecontrol(arg, cpu_env); /* PDtrace support */
5675 rn = "TraceControl";
5678 // gen_helper_dmfc0_tracecontrol2(arg, cpu_env); /* PDtrace support */
5679 rn = "TraceControl2";
5682 // gen_helper_dmfc0_usertracedata(arg, cpu_env); /* PDtrace support */
5683 rn = "UserTraceData";
5686 // gen_helper_dmfc0_tracebpc(arg, cpu_env); /* PDtrace support */
5697 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_DEPC));
5707 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Performance0));
5708 rn = "Performance0";
5711 // gen_helper_dmfc0_performance1(arg);
5712 rn = "Performance1";
5715 // gen_helper_dmfc0_performance2(arg);
5716 rn = "Performance2";
5719 // gen_helper_dmfc0_performance3(arg);
5720 rn = "Performance3";
5723 // gen_helper_dmfc0_performance4(arg);
5724 rn = "Performance4";
5727 // gen_helper_dmfc0_performance5(arg);
5728 rn = "Performance5";
5731 // gen_helper_dmfc0_performance6(arg);
5732 rn = "Performance6";
5735 // gen_helper_dmfc0_performance7(arg);
5736 rn = "Performance7";
5743 tcg_gen_movi_tl(arg, 0); /* unimplemented */
5750 tcg_gen_movi_tl(arg, 0); /* unimplemented */
5763 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_TagLo));
5770 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DataLo));
5783 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_TagHi));
5790 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DataHi));
5800 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_ErrorEPC));
5811 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DESAVE));
5821 (void)rn; /* avoid a compiler warning */
5822 LOG_DISAS("dmfc0 %s (reg %d sel %d)\n", rn, reg, sel);
5826 LOG_DISAS("dmfc0 %s (reg %d sel %d)\n", rn, reg, sel);
5827 generate_exception(ctx, EXCP_RI);
5830 static void gen_dmtc0 (CPUMIPSState *env, DisasContext *ctx, TCGv arg, int reg, int sel)
5832 const char *rn = "invalid";
5835 check_insn(env, ctx, ISA_MIPS64);
5844 gen_helper_mtc0_index(cpu_env, arg);
5848 check_insn(env, ctx, ASE_MT);
5849 gen_helper_mtc0_mvpcontrol(cpu_env, arg);
5853 check_insn(env, ctx, ASE_MT);
5858 check_insn(env, ctx, ASE_MT);
5873 check_insn(env, ctx, ASE_MT);
5874 gen_helper_mtc0_vpecontrol(cpu_env, arg);
5878 check_insn(env, ctx, ASE_MT);
5879 gen_helper_mtc0_vpeconf0(cpu_env, arg);
5883 check_insn(env, ctx, ASE_MT);
5884 gen_helper_mtc0_vpeconf1(cpu_env, arg);
5888 check_insn(env, ctx, ASE_MT);
5889 gen_helper_mtc0_yqmask(cpu_env, arg);
5893 check_insn(env, ctx, ASE_MT);
5894 tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_VPESchedule));
5898 check_insn(env, ctx, ASE_MT);
5899 tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_VPEScheFBack));
5900 rn = "VPEScheFBack";
5903 check_insn(env, ctx, ASE_MT);
5904 gen_helper_mtc0_vpeopt(cpu_env, arg);
5914 gen_helper_mtc0_entrylo0(cpu_env, arg);
5918 check_insn(env, ctx, ASE_MT);
5919 gen_helper_mtc0_tcstatus(cpu_env, arg);
5923 check_insn(env, ctx, ASE_MT);
5924 gen_helper_mtc0_tcbind(cpu_env, arg);
5928 check_insn(env, ctx, ASE_MT);
5929 gen_helper_mtc0_tcrestart(cpu_env, arg);
5933 check_insn(env, ctx, ASE_MT);
5934 gen_helper_mtc0_tchalt(cpu_env, arg);
5938 check_insn(env, ctx, ASE_MT);
5939 gen_helper_mtc0_tccontext(cpu_env, arg);
5943 check_insn(env, ctx, ASE_MT);
5944 gen_helper_mtc0_tcschedule(cpu_env, arg);
5948 check_insn(env, ctx, ASE_MT);
5949 gen_helper_mtc0_tcschefback(cpu_env, arg);
5959 gen_helper_mtc0_entrylo1(cpu_env, arg);
5969 gen_helper_mtc0_context(cpu_env, arg);
5973 // gen_helper_mtc0_contextconfig(cpu_env, arg); /* SmartMIPS ASE */
5974 rn = "ContextConfig";
5983 gen_helper_mtc0_pagemask(cpu_env, arg);
5987 check_insn(env, ctx, ISA_MIPS32R2);
5988 gen_helper_mtc0_pagegrain(cpu_env, arg);
5998 gen_helper_mtc0_wired(cpu_env, arg);
6002 check_insn(env, ctx, ISA_MIPS32R2);
6003 gen_helper_mtc0_srsconf0(cpu_env, arg);
6007 check_insn(env, ctx, ISA_MIPS32R2);
6008 gen_helper_mtc0_srsconf1(cpu_env, arg);
6012 check_insn(env, ctx, ISA_MIPS32R2);
6013 gen_helper_mtc0_srsconf2(cpu_env, arg);
6017 check_insn(env, ctx, ISA_MIPS32R2);
6018 gen_helper_mtc0_srsconf3(cpu_env, arg);
6022 check_insn(env, ctx, ISA_MIPS32R2);
6023 gen_helper_mtc0_srsconf4(cpu_env, arg);
6033 check_insn(env, ctx, ISA_MIPS32R2);
6034 gen_helper_mtc0_hwrena(cpu_env, arg);
6048 gen_helper_mtc0_count(cpu_env, arg);
6051 /* 6,7 are implementation dependent */
6055 /* Stop translation as we may have switched the execution mode */
6056 ctx->bstate = BS_STOP;
6061 gen_helper_mtc0_entryhi(cpu_env, arg);
6071 gen_helper_mtc0_compare(cpu_env, arg);
6074 /* 6,7 are implementation dependent */
6078 /* Stop translation as we may have switched the execution mode */
6079 ctx->bstate = BS_STOP;
6084 save_cpu_state(ctx, 1);
6085 gen_helper_mtc0_status(cpu_env, arg);
6086 /* BS_STOP isn't good enough here, hflags may have changed. */
6087 gen_save_pc(ctx->pc + 4);
6088 ctx->bstate = BS_EXCP;
6092 check_insn(env, ctx, ISA_MIPS32R2);
6093 gen_helper_mtc0_intctl(cpu_env, arg);
6094 /* Stop translation as we may have switched the execution mode */
6095 ctx->bstate = BS_STOP;
6099 check_insn(env, ctx, ISA_MIPS32R2);
6100 gen_helper_mtc0_srsctl(cpu_env, arg);
6101 /* Stop translation as we may have switched the execution mode */
6102 ctx->bstate = BS_STOP;
6106 check_insn(env, ctx, ISA_MIPS32R2);
6107 gen_mtc0_store32(arg, offsetof(CPUMIPSState, CP0_SRSMap));
6108 /* Stop translation as we may have switched the execution mode */
6109 ctx->bstate = BS_STOP;
6119 save_cpu_state(ctx, 1);
6120 /* Mark as an IO operation because we may trigger a software
6125 gen_helper_mtc0_cause(cpu_env, arg);
6129 /* Stop translation as we may have triggered an intetrupt */
6130 ctx->bstate = BS_STOP;
6140 tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EPC));
6154 check_insn(env, ctx, ISA_MIPS32R2);
6155 gen_helper_mtc0_ebase(cpu_env, arg);
6165 gen_helper_mtc0_config0(cpu_env, arg);
6167 /* Stop translation as we may have switched the execution mode */
6168 ctx->bstate = BS_STOP;
6171 /* ignored, read only */
6175 gen_helper_mtc0_config2(cpu_env, arg);
6177 /* Stop translation as we may have switched the execution mode */
6178 ctx->bstate = BS_STOP;
6184 /* 6,7 are implementation dependent */
6186 rn = "Invalid config selector";
6193 gen_helper_mtc0_lladdr(cpu_env, arg);
6203 gen_helper_0e1i(mtc0_watchlo, arg, sel);
6213 gen_helper_0e1i(mtc0_watchhi, arg, sel);
6223 check_insn(env, ctx, ISA_MIPS3);
6224 gen_helper_mtc0_xcontext(cpu_env, arg);
6232 /* Officially reserved, but sel 0 is used for R1x000 framemask */
6235 gen_helper_mtc0_framemask(cpu_env, arg);
6244 rn = "Diagnostic"; /* implementation dependent */
6249 gen_helper_mtc0_debug(cpu_env, arg); /* EJTAG support */
6250 /* BS_STOP isn't good enough here, hflags may have changed. */
6251 gen_save_pc(ctx->pc + 4);
6252 ctx->bstate = BS_EXCP;
6256 // gen_helper_mtc0_tracecontrol(cpu_env, arg); /* PDtrace support */
6257 /* Stop translation as we may have switched the execution mode */
6258 ctx->bstate = BS_STOP;
6259 rn = "TraceControl";
6262 // gen_helper_mtc0_tracecontrol2(cpu_env, arg); /* PDtrace support */
6263 /* Stop translation as we may have switched the execution mode */
6264 ctx->bstate = BS_STOP;
6265 rn = "TraceControl2";
6268 // gen_helper_mtc0_usertracedata(cpu_env, arg); /* PDtrace support */
6269 /* Stop translation as we may have switched the execution mode */
6270 ctx->bstate = BS_STOP;
6271 rn = "UserTraceData";
6274 // gen_helper_mtc0_tracebpc(cpu_env, arg); /* PDtrace support */
6275 /* Stop translation as we may have switched the execution mode */
6276 ctx->bstate = BS_STOP;
6287 tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_DEPC));
6297 gen_helper_mtc0_performance0(cpu_env, arg);
6298 rn = "Performance0";
6301 // gen_helper_mtc0_performance1(cpu_env, arg);
6302 rn = "Performance1";
6305 // gen_helper_mtc0_performance2(cpu_env, arg);
6306 rn = "Performance2";
6309 // gen_helper_mtc0_performance3(cpu_env, arg);
6310 rn = "Performance3";
6313 // gen_helper_mtc0_performance4(cpu_env, arg);
6314 rn = "Performance4";
6317 // gen_helper_mtc0_performance5(cpu_env, arg);
6318 rn = "Performance5";
6321 // gen_helper_mtc0_performance6(cpu_env, arg);
6322 rn = "Performance6";
6325 // gen_helper_mtc0_performance7(cpu_env, arg);
6326 rn = "Performance7";
6352 gen_helper_mtc0_taglo(cpu_env, arg);
6359 gen_helper_mtc0_datalo(cpu_env, arg);
6372 gen_helper_mtc0_taghi(cpu_env, arg);
6379 gen_helper_mtc0_datahi(cpu_env, arg);
6390 tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_ErrorEPC));
6401 gen_mtc0_store32(arg, offsetof(CPUMIPSState, CP0_DESAVE));
6407 /* Stop translation as we may have switched the execution mode */
6408 ctx->bstate = BS_STOP;
6413 (void)rn; /* avoid a compiler warning */
6414 LOG_DISAS("dmtc0 %s (reg %d sel %d)\n", rn, reg, sel);
6415 /* For simplicity assume that all writes can cause interrupts. */
6418 ctx->bstate = BS_STOP;
6423 LOG_DISAS("dmtc0 %s (reg %d sel %d)\n", rn, reg, sel);
6424 generate_exception(ctx, EXCP_RI);
6426 #endif /* TARGET_MIPS64 */
6428 static void gen_mftr(CPUMIPSState *env, DisasContext *ctx, int rt, int rd,
6429 int u, int sel, int h)
6431 int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
6432 TCGv t0 = tcg_temp_local_new();
6434 if ((env->CP0_VPEConf0 & (1 << CP0VPEC0_MVP)) == 0 &&
6435 ((env->tcs[other_tc].CP0_TCBind & (0xf << CP0TCBd_CurVPE)) !=
6436 (env->active_tc.CP0_TCBind & (0xf << CP0TCBd_CurVPE))))
6437 tcg_gen_movi_tl(t0, -1);
6438 else if ((env->CP0_VPEControl & (0xff << CP0VPECo_TargTC)) >
6439 (env->mvp->CP0_MVPConf0 & (0xff << CP0MVPC0_PTC)))
6440 tcg_gen_movi_tl(t0, -1);
6446 gen_helper_mftc0_vpecontrol(t0, cpu_env);
6449 gen_helper_mftc0_vpeconf0(t0, cpu_env);
6459 gen_helper_mftc0_tcstatus(t0, cpu_env);
6462 gen_helper_mftc0_tcbind(t0, cpu_env);
6465 gen_helper_mftc0_tcrestart(t0, cpu_env);
6468 gen_helper_mftc0_tchalt(t0, cpu_env);
6471 gen_helper_mftc0_tccontext(t0, cpu_env);
6474 gen_helper_mftc0_tcschedule(t0, cpu_env);
6477 gen_helper_mftc0_tcschefback(t0, cpu_env);
6480 gen_mfc0(env, ctx, t0, rt, sel);
6487 gen_helper_mftc0_entryhi(t0, cpu_env);
6490 gen_mfc0(env, ctx, t0, rt, sel);
6496 gen_helper_mftc0_status(t0, cpu_env);
6499 gen_mfc0(env, ctx, t0, rt, sel);
6505 gen_helper_mftc0_cause(t0, cpu_env);
6515 gen_helper_mftc0_epc(t0, cpu_env);
6525 gen_helper_mftc0_ebase(t0, cpu_env);
6535 gen_helper_mftc0_configx(t0, cpu_env, tcg_const_tl(sel));
6545 gen_helper_mftc0_debug(t0, cpu_env);
6548 gen_mfc0(env, ctx, t0, rt, sel);
6553 gen_mfc0(env, ctx, t0, rt, sel);
6555 } else switch (sel) {
6556 /* GPR registers. */
6558 gen_helper_1e0i(mftgpr, t0, rt);
6560 /* Auxiliary CPU registers */
6564 gen_helper_1e0i(mftlo, t0, 0);
6567 gen_helper_1e0i(mfthi, t0, 0);
6570 gen_helper_1e0i(mftacx, t0, 0);
6573 gen_helper_1e0i(mftlo, t0, 1);
6576 gen_helper_1e0i(mfthi, t0, 1);
6579 gen_helper_1e0i(mftacx, t0, 1);
6582 gen_helper_1e0i(mftlo, t0, 2);
6585 gen_helper_1e0i(mfthi, t0, 2);
6588 gen_helper_1e0i(mftacx, t0, 2);
6591 gen_helper_1e0i(mftlo, t0, 3);
6594 gen_helper_1e0i(mfthi, t0, 3);
6597 gen_helper_1e0i(mftacx, t0, 3);
6600 gen_helper_mftdsp(t0, cpu_env);
6606 /* Floating point (COP1). */
6608 /* XXX: For now we support only a single FPU context. */
6610 TCGv_i32 fp0 = tcg_temp_new_i32();
6612 gen_load_fpr32(fp0, rt);
6613 tcg_gen_ext_i32_tl(t0, fp0);
6614 tcg_temp_free_i32(fp0);
6616 TCGv_i32 fp0 = tcg_temp_new_i32();
6618 gen_load_fpr32h(fp0, rt);
6619 tcg_gen_ext_i32_tl(t0, fp0);
6620 tcg_temp_free_i32(fp0);
6624 /* XXX: For now we support only a single FPU context. */
6625 gen_helper_1e0i(cfc1, t0, rt);
6627 /* COP2: Not implemented. */
6634 LOG_DISAS("mftr (reg %d u %d sel %d h %d)\n", rt, u, sel, h);
6635 gen_store_gpr(t0, rd);
6641 LOG_DISAS("mftr (reg %d u %d sel %d h %d)\n", rt, u, sel, h);
6642 generate_exception(ctx, EXCP_RI);
6645 static void gen_mttr(CPUMIPSState *env, DisasContext *ctx, int rd, int rt,
6646 int u, int sel, int h)
6648 int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
6649 TCGv t0 = tcg_temp_local_new();
6651 gen_load_gpr(t0, rt);
6652 if ((env->CP0_VPEConf0 & (1 << CP0VPEC0_MVP)) == 0 &&
6653 ((env->tcs[other_tc].CP0_TCBind & (0xf << CP0TCBd_CurVPE)) !=
6654 (env->active_tc.CP0_TCBind & (0xf << CP0TCBd_CurVPE))))
6656 else if ((env->CP0_VPEControl & (0xff << CP0VPECo_TargTC)) >
6657 (env->mvp->CP0_MVPConf0 & (0xff << CP0MVPC0_PTC)))
6664 gen_helper_mttc0_vpecontrol(cpu_env, t0);
6667 gen_helper_mttc0_vpeconf0(cpu_env, t0);
6677 gen_helper_mttc0_tcstatus(cpu_env, t0);
6680 gen_helper_mttc0_tcbind(cpu_env, t0);
6683 gen_helper_mttc0_tcrestart(cpu_env, t0);
6686 gen_helper_mttc0_tchalt(cpu_env, t0);
6689 gen_helper_mttc0_tccontext(cpu_env, t0);
6692 gen_helper_mttc0_tcschedule(cpu_env, t0);
6695 gen_helper_mttc0_tcschefback(cpu_env, t0);
6698 gen_mtc0(env, ctx, t0, rd, sel);
6705 gen_helper_mttc0_entryhi(cpu_env, t0);
6708 gen_mtc0(env, ctx, t0, rd, sel);
6714 gen_helper_mttc0_status(cpu_env, t0);
6717 gen_mtc0(env, ctx, t0, rd, sel);
6723 gen_helper_mttc0_cause(cpu_env, t0);
6733 gen_helper_mttc0_ebase(cpu_env, t0);
6743 gen_helper_mttc0_debug(cpu_env, t0);
6746 gen_mtc0(env, ctx, t0, rd, sel);
6751 gen_mtc0(env, ctx, t0, rd, sel);
6753 } else switch (sel) {
6754 /* GPR registers. */
6756 gen_helper_0e1i(mttgpr, t0, rd);
6758 /* Auxiliary CPU registers */
6762 gen_helper_0e1i(mttlo, t0, 0);
6765 gen_helper_0e1i(mtthi, t0, 0);
6768 gen_helper_0e1i(mttacx, t0, 0);
6771 gen_helper_0e1i(mttlo, t0, 1);
6774 gen_helper_0e1i(mtthi, t0, 1);
6777 gen_helper_0e1i(mttacx, t0, 1);
6780 gen_helper_0e1i(mttlo, t0, 2);
6783 gen_helper_0e1i(mtthi, t0, 2);
6786 gen_helper_0e1i(mttacx, t0, 2);
6789 gen_helper_0e1i(mttlo, t0, 3);
6792 gen_helper_0e1i(mtthi, t0, 3);
6795 gen_helper_0e1i(mttacx, t0, 3);
6798 gen_helper_mttdsp(cpu_env, t0);
6804 /* Floating point (COP1). */
6806 /* XXX: For now we support only a single FPU context. */
6808 TCGv_i32 fp0 = tcg_temp_new_i32();
6810 tcg_gen_trunc_tl_i32(fp0, t0);
6811 gen_store_fpr32(fp0, rd);
6812 tcg_temp_free_i32(fp0);
6814 TCGv_i32 fp0 = tcg_temp_new_i32();
6816 tcg_gen_trunc_tl_i32(fp0, t0);
6817 gen_store_fpr32h(fp0, rd);
6818 tcg_temp_free_i32(fp0);
6822 /* XXX: For now we support only a single FPU context. */
6823 gen_helper_0e1i(ctc1, t0, rd);
6825 /* COP2: Not implemented. */
6832 LOG_DISAS("mttr (reg %d u %d sel %d h %d)\n", rd, u, sel, h);
6838 LOG_DISAS("mttr (reg %d u %d sel %d h %d)\n", rd, u, sel, h);
6839 generate_exception(ctx, EXCP_RI);
6842 static void gen_cp0 (CPUMIPSState *env, DisasContext *ctx, uint32_t opc, int rt, int rd)
6844 const char *opn = "ldst";
6846 check_cp0_enabled(ctx);
6853 gen_mfc0(env, ctx, cpu_gpr[rt], rd, ctx->opcode & 0x7);
6858 TCGv t0 = tcg_temp_new();
6860 gen_load_gpr(t0, rt);
6861 gen_mtc0(env, ctx, t0, rd, ctx->opcode & 0x7);
6866 #if defined(TARGET_MIPS64)
6868 check_insn(env, ctx, ISA_MIPS3);
6873 gen_dmfc0(env, ctx, cpu_gpr[rt], rd, ctx->opcode & 0x7);
6877 check_insn(env, ctx, ISA_MIPS3);
6879 TCGv t0 = tcg_temp_new();
6881 gen_load_gpr(t0, rt);
6882 gen_dmtc0(env, ctx, t0, rd, ctx->opcode & 0x7);
6889 check_insn(env, ctx, ASE_MT);
6894 gen_mftr(env, ctx, rt, rd, (ctx->opcode >> 5) & 1,
6895 ctx->opcode & 0x7, (ctx->opcode >> 4) & 1);
6899 check_insn(env, ctx, ASE_MT);
6900 gen_mttr(env, ctx, rd, rt, (ctx->opcode >> 5) & 1,
6901 ctx->opcode & 0x7, (ctx->opcode >> 4) & 1);
6906 if (!env->tlb->helper_tlbwi)
6908 gen_helper_tlbwi(cpu_env);
6912 if (!env->tlb->helper_tlbwr)
6914 gen_helper_tlbwr(cpu_env);
6918 if (!env->tlb->helper_tlbp)
6920 gen_helper_tlbp(cpu_env);
6924 if (!env->tlb->helper_tlbr)
6926 gen_helper_tlbr(cpu_env);
6930 check_insn(env, ctx, ISA_MIPS2);
6931 gen_helper_eret(cpu_env);
6932 ctx->bstate = BS_EXCP;
6936 check_insn(env, ctx, ISA_MIPS32);
6937 if (!(ctx->hflags & MIPS_HFLAG_DM)) {
6939 generate_exception(ctx, EXCP_RI);
6941 gen_helper_deret(cpu_env);
6942 ctx->bstate = BS_EXCP;
6947 check_insn(env, ctx, ISA_MIPS3 | ISA_MIPS32);
6948 /* If we get an exception, we want to restart at next instruction */
6950 save_cpu_state(ctx, 1);
6952 gen_helper_wait(cpu_env);
6953 ctx->bstate = BS_EXCP;
6958 generate_exception(ctx, EXCP_RI);
6961 (void)opn; /* avoid a compiler warning */
6962 MIPS_DEBUG("%s %s %d", opn, regnames[rt], rd);
6964 #endif /* !CONFIG_USER_ONLY */
6966 /* CP1 Branches (before delay slot) */
6967 static void gen_compute_branch1 (CPUMIPSState *env, DisasContext *ctx, uint32_t op,
6968 int32_t cc, int32_t offset)
6970 target_ulong btarget;
6971 const char *opn = "cp1 cond branch";
6972 TCGv_i32 t0 = tcg_temp_new_i32();
6975 check_insn(env, ctx, ISA_MIPS4 | ISA_MIPS32);
6977 btarget = ctx->pc + 4 + offset;
6981 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
6982 tcg_gen_not_i32(t0, t0);
6983 tcg_gen_andi_i32(t0, t0, 1);
6984 tcg_gen_extu_i32_tl(bcond, t0);
6988 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
6989 tcg_gen_not_i32(t0, t0);
6990 tcg_gen_andi_i32(t0, t0, 1);
6991 tcg_gen_extu_i32_tl(bcond, t0);
6995 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
6996 tcg_gen_andi_i32(t0, t0, 1);
6997 tcg_gen_extu_i32_tl(bcond, t0);
7001 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
7002 tcg_gen_andi_i32(t0, t0, 1);
7003 tcg_gen_extu_i32_tl(bcond, t0);
7006 ctx->hflags |= MIPS_HFLAG_BL;
7010 TCGv_i32 t1 = tcg_temp_new_i32();
7011 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
7012 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+1));
7013 tcg_gen_nand_i32(t0, t0, t1);
7014 tcg_temp_free_i32(t1);
7015 tcg_gen_andi_i32(t0, t0, 1);
7016 tcg_gen_extu_i32_tl(bcond, t0);
7022 TCGv_i32 t1 = tcg_temp_new_i32();
7023 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
7024 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+1));
7025 tcg_gen_or_i32(t0, t0, t1);
7026 tcg_temp_free_i32(t1);
7027 tcg_gen_andi_i32(t0, t0, 1);
7028 tcg_gen_extu_i32_tl(bcond, t0);
7034 TCGv_i32 t1 = tcg_temp_new_i32();
7035 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
7036 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+1));
7037 tcg_gen_and_i32(t0, t0, t1);
7038 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+2));
7039 tcg_gen_and_i32(t0, t0, t1);
7040 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+3));
7041 tcg_gen_nand_i32(t0, t0, t1);
7042 tcg_temp_free_i32(t1);
7043 tcg_gen_andi_i32(t0, t0, 1);
7044 tcg_gen_extu_i32_tl(bcond, t0);
7050 TCGv_i32 t1 = tcg_temp_new_i32();
7051 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
7052 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+1));
7053 tcg_gen_or_i32(t0, t0, t1);
7054 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+2));
7055 tcg_gen_or_i32(t0, t0, t1);
7056 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+3));
7057 tcg_gen_or_i32(t0, t0, t1);
7058 tcg_temp_free_i32(t1);
7059 tcg_gen_andi_i32(t0, t0, 1);
7060 tcg_gen_extu_i32_tl(bcond, t0);
7064 ctx->hflags |= MIPS_HFLAG_BC;
7068 generate_exception (ctx, EXCP_RI);
7071 (void)opn; /* avoid a compiler warning */
7072 MIPS_DEBUG("%s: cond %02x target " TARGET_FMT_lx, opn,
7073 ctx->hflags, btarget);
7074 ctx->btarget = btarget;
7077 tcg_temp_free_i32(t0);
7080 /* Coprocessor 1 (FPU) */
7082 #define FOP(func, fmt) (((fmt) << 21) | (func))
7085 OPC_ADD_S = FOP(0, FMT_S),
7086 OPC_SUB_S = FOP(1, FMT_S),
7087 OPC_MUL_S = FOP(2, FMT_S),
7088 OPC_DIV_S = FOP(3, FMT_S),
7089 OPC_SQRT_S = FOP(4, FMT_S),
7090 OPC_ABS_S = FOP(5, FMT_S),
7091 OPC_MOV_S = FOP(6, FMT_S),
7092 OPC_NEG_S = FOP(7, FMT_S),
7093 OPC_ROUND_L_S = FOP(8, FMT_S),
7094 OPC_TRUNC_L_S = FOP(9, FMT_S),
7095 OPC_CEIL_L_S = FOP(10, FMT_S),
7096 OPC_FLOOR_L_S = FOP(11, FMT_S),
7097 OPC_ROUND_W_S = FOP(12, FMT_S),
7098 OPC_TRUNC_W_S = FOP(13, FMT_S),
7099 OPC_CEIL_W_S = FOP(14, FMT_S),
7100 OPC_FLOOR_W_S = FOP(15, FMT_S),
7101 OPC_MOVCF_S = FOP(17, FMT_S),
7102 OPC_MOVZ_S = FOP(18, FMT_S),
7103 OPC_MOVN_S = FOP(19, FMT_S),
7104 OPC_RECIP_S = FOP(21, FMT_S),
7105 OPC_RSQRT_S = FOP(22, FMT_S),
7106 OPC_RECIP2_S = FOP(28, FMT_S),
7107 OPC_RECIP1_S = FOP(29, FMT_S),
7108 OPC_RSQRT1_S = FOP(30, FMT_S),
7109 OPC_RSQRT2_S = FOP(31, FMT_S),
7110 OPC_CVT_D_S = FOP(33, FMT_S),
7111 OPC_CVT_W_S = FOP(36, FMT_S),
7112 OPC_CVT_L_S = FOP(37, FMT_S),
7113 OPC_CVT_PS_S = FOP(38, FMT_S),
7114 OPC_CMP_F_S = FOP (48, FMT_S),
7115 OPC_CMP_UN_S = FOP (49, FMT_S),
7116 OPC_CMP_EQ_S = FOP (50, FMT_S),
7117 OPC_CMP_UEQ_S = FOP (51, FMT_S),
7118 OPC_CMP_OLT_S = FOP (52, FMT_S),
7119 OPC_CMP_ULT_S = FOP (53, FMT_S),
7120 OPC_CMP_OLE_S = FOP (54, FMT_S),
7121 OPC_CMP_ULE_S = FOP (55, FMT_S),
7122 OPC_CMP_SF_S = FOP (56, FMT_S),
7123 OPC_CMP_NGLE_S = FOP (57, FMT_S),
7124 OPC_CMP_SEQ_S = FOP (58, FMT_S),
7125 OPC_CMP_NGL_S = FOP (59, FMT_S),
7126 OPC_CMP_LT_S = FOP (60, FMT_S),
7127 OPC_CMP_NGE_S = FOP (61, FMT_S),
7128 OPC_CMP_LE_S = FOP (62, FMT_S),
7129 OPC_CMP_NGT_S = FOP (63, FMT_S),
7131 OPC_ADD_D = FOP(0, FMT_D),
7132 OPC_SUB_D = FOP(1, FMT_D),
7133 OPC_MUL_D = FOP(2, FMT_D),
7134 OPC_DIV_D = FOP(3, FMT_D),
7135 OPC_SQRT_D = FOP(4, FMT_D),
7136 OPC_ABS_D = FOP(5, FMT_D),
7137 OPC_MOV_D = FOP(6, FMT_D),
7138 OPC_NEG_D = FOP(7, FMT_D),
7139 OPC_ROUND_L_D = FOP(8, FMT_D),
7140 OPC_TRUNC_L_D = FOP(9, FMT_D),
7141 OPC_CEIL_L_D = FOP(10, FMT_D),
7142 OPC_FLOOR_L_D = FOP(11, FMT_D),
7143 OPC_ROUND_W_D = FOP(12, FMT_D),
7144 OPC_TRUNC_W_D = FOP(13, FMT_D),
7145 OPC_CEIL_W_D = FOP(14, FMT_D),
7146 OPC_FLOOR_W_D = FOP(15, FMT_D),
7147 OPC_MOVCF_D = FOP(17, FMT_D),
7148 OPC_MOVZ_D = FOP(18, FMT_D),
7149 OPC_MOVN_D = FOP(19, FMT_D),
7150 OPC_RECIP_D = FOP(21, FMT_D),
7151 OPC_RSQRT_D = FOP(22, FMT_D),
7152 OPC_RECIP2_D = FOP(28, FMT_D),
7153 OPC_RECIP1_D = FOP(29, FMT_D),
7154 OPC_RSQRT1_D = FOP(30, FMT_D),
7155 OPC_RSQRT2_D = FOP(31, FMT_D),
7156 OPC_CVT_S_D = FOP(32, FMT_D),
7157 OPC_CVT_W_D = FOP(36, FMT_D),
7158 OPC_CVT_L_D = FOP(37, FMT_D),
7159 OPC_CMP_F_D = FOP (48, FMT_D),
7160 OPC_CMP_UN_D = FOP (49, FMT_D),
7161 OPC_CMP_EQ_D = FOP (50, FMT_D),
7162 OPC_CMP_UEQ_D = FOP (51, FMT_D),
7163 OPC_CMP_OLT_D = FOP (52, FMT_D),
7164 OPC_CMP_ULT_D = FOP (53, FMT_D),
7165 OPC_CMP_OLE_D = FOP (54, FMT_D),
7166 OPC_CMP_ULE_D = FOP (55, FMT_D),
7167 OPC_CMP_SF_D = FOP (56, FMT_D),
7168 OPC_CMP_NGLE_D = FOP (57, FMT_D),
7169 OPC_CMP_SEQ_D = FOP (58, FMT_D),
7170 OPC_CMP_NGL_D = FOP (59, FMT_D),
7171 OPC_CMP_LT_D = FOP (60, FMT_D),
7172 OPC_CMP_NGE_D = FOP (61, FMT_D),
7173 OPC_CMP_LE_D = FOP (62, FMT_D),
7174 OPC_CMP_NGT_D = FOP (63, FMT_D),
7176 OPC_CVT_S_W = FOP(32, FMT_W),
7177 OPC_CVT_D_W = FOP(33, FMT_W),
7178 OPC_CVT_S_L = FOP(32, FMT_L),
7179 OPC_CVT_D_L = FOP(33, FMT_L),
7180 OPC_CVT_PS_PW = FOP(38, FMT_W),
7182 OPC_ADD_PS = FOP(0, FMT_PS),
7183 OPC_SUB_PS = FOP(1, FMT_PS),
7184 OPC_MUL_PS = FOP(2, FMT_PS),
7185 OPC_DIV_PS = FOP(3, FMT_PS),
7186 OPC_ABS_PS = FOP(5, FMT_PS),
7187 OPC_MOV_PS = FOP(6, FMT_PS),
7188 OPC_NEG_PS = FOP(7, FMT_PS),
7189 OPC_MOVCF_PS = FOP(17, FMT_PS),
7190 OPC_MOVZ_PS = FOP(18, FMT_PS),
7191 OPC_MOVN_PS = FOP(19, FMT_PS),
7192 OPC_ADDR_PS = FOP(24, FMT_PS),
7193 OPC_MULR_PS = FOP(26, FMT_PS),
7194 OPC_RECIP2_PS = FOP(28, FMT_PS),
7195 OPC_RECIP1_PS = FOP(29, FMT_PS),
7196 OPC_RSQRT1_PS = FOP(30, FMT_PS),
7197 OPC_RSQRT2_PS = FOP(31, FMT_PS),
7199 OPC_CVT_S_PU = FOP(32, FMT_PS),
7200 OPC_CVT_PW_PS = FOP(36, FMT_PS),
7201 OPC_CVT_S_PL = FOP(40, FMT_PS),
7202 OPC_PLL_PS = FOP(44, FMT_PS),
7203 OPC_PLU_PS = FOP(45, FMT_PS),
7204 OPC_PUL_PS = FOP(46, FMT_PS),
7205 OPC_PUU_PS = FOP(47, FMT_PS),
7206 OPC_CMP_F_PS = FOP (48, FMT_PS),
7207 OPC_CMP_UN_PS = FOP (49, FMT_PS),
7208 OPC_CMP_EQ_PS = FOP (50, FMT_PS),
7209 OPC_CMP_UEQ_PS = FOP (51, FMT_PS),
7210 OPC_CMP_OLT_PS = FOP (52, FMT_PS),
7211 OPC_CMP_ULT_PS = FOP (53, FMT_PS),
7212 OPC_CMP_OLE_PS = FOP (54, FMT_PS),
7213 OPC_CMP_ULE_PS = FOP (55, FMT_PS),
7214 OPC_CMP_SF_PS = FOP (56, FMT_PS),
7215 OPC_CMP_NGLE_PS = FOP (57, FMT_PS),
7216 OPC_CMP_SEQ_PS = FOP (58, FMT_PS),
7217 OPC_CMP_NGL_PS = FOP (59, FMT_PS),
7218 OPC_CMP_LT_PS = FOP (60, FMT_PS),
7219 OPC_CMP_NGE_PS = FOP (61, FMT_PS),
7220 OPC_CMP_LE_PS = FOP (62, FMT_PS),
7221 OPC_CMP_NGT_PS = FOP (63, FMT_PS),
7224 static void gen_cp1 (DisasContext *ctx, uint32_t opc, int rt, int fs)
7226 const char *opn = "cp1 move";
7227 TCGv t0 = tcg_temp_new();
7232 TCGv_i32 fp0 = tcg_temp_new_i32();
7234 gen_load_fpr32(fp0, fs);
7235 tcg_gen_ext_i32_tl(t0, fp0);
7236 tcg_temp_free_i32(fp0);
7238 gen_store_gpr(t0, rt);
7242 gen_load_gpr(t0, rt);
7244 TCGv_i32 fp0 = tcg_temp_new_i32();
7246 tcg_gen_trunc_tl_i32(fp0, t0);
7247 gen_store_fpr32(fp0, fs);
7248 tcg_temp_free_i32(fp0);
7253 gen_helper_1e0i(cfc1, t0, fs);
7254 gen_store_gpr(t0, rt);
7258 gen_load_gpr(t0, rt);
7259 gen_helper_0e1i(ctc1, t0, fs);
7262 #if defined(TARGET_MIPS64)
7264 gen_load_fpr64(ctx, t0, fs);
7265 gen_store_gpr(t0, rt);
7269 gen_load_gpr(t0, rt);
7270 gen_store_fpr64(ctx, t0, fs);
7276 TCGv_i32 fp0 = tcg_temp_new_i32();
7278 gen_load_fpr32h(fp0, fs);
7279 tcg_gen_ext_i32_tl(t0, fp0);
7280 tcg_temp_free_i32(fp0);
7282 gen_store_gpr(t0, rt);
7286 gen_load_gpr(t0, rt);
7288 TCGv_i32 fp0 = tcg_temp_new_i32();
7290 tcg_gen_trunc_tl_i32(fp0, t0);
7291 gen_store_fpr32h(fp0, fs);
7292 tcg_temp_free_i32(fp0);
7298 generate_exception (ctx, EXCP_RI);
7301 (void)opn; /* avoid a compiler warning */
7302 MIPS_DEBUG("%s %s %s", opn, regnames[rt], fregnames[fs]);
7308 static void gen_movci (DisasContext *ctx, int rd, int rs, int cc, int tf)
7324 l1 = gen_new_label();
7325 t0 = tcg_temp_new_i32();
7326 tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc));
7327 tcg_gen_brcondi_i32(cond, t0, 0, l1);
7328 tcg_temp_free_i32(t0);
7330 tcg_gen_movi_tl(cpu_gpr[rd], 0);
7332 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
7337 static inline void gen_movcf_s (int fs, int fd, int cc, int tf)
7340 TCGv_i32 t0 = tcg_temp_new_i32();
7341 int l1 = gen_new_label();
7348 tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc));
7349 tcg_gen_brcondi_i32(cond, t0, 0, l1);
7350 gen_load_fpr32(t0, fs);
7351 gen_store_fpr32(t0, fd);
7353 tcg_temp_free_i32(t0);
7356 static inline void gen_movcf_d (DisasContext *ctx, int fs, int fd, int cc, int tf)
7359 TCGv_i32 t0 = tcg_temp_new_i32();
7361 int l1 = gen_new_label();
7368 tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc));
7369 tcg_gen_brcondi_i32(cond, t0, 0, l1);
7370 tcg_temp_free_i32(t0);
7371 fp0 = tcg_temp_new_i64();
7372 gen_load_fpr64(ctx, fp0, fs);
7373 gen_store_fpr64(ctx, fp0, fd);
7374 tcg_temp_free_i64(fp0);
7378 static inline void gen_movcf_ps (int fs, int fd, int cc, int tf)
7381 TCGv_i32 t0 = tcg_temp_new_i32();
7382 int l1 = gen_new_label();
7383 int l2 = gen_new_label();
7390 tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc));
7391 tcg_gen_brcondi_i32(cond, t0, 0, l1);
7392 gen_load_fpr32(t0, fs);
7393 gen_store_fpr32(t0, fd);
7396 tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc+1));
7397 tcg_gen_brcondi_i32(cond, t0, 0, l2);
7398 gen_load_fpr32h(t0, fs);
7399 gen_store_fpr32h(t0, fd);
7400 tcg_temp_free_i32(t0);
7405 static void gen_farith (DisasContext *ctx, enum fopcode op1,
7406 int ft, int fs, int fd, int cc)
7408 const char *opn = "farith";
7409 const char *condnames[] = {
7427 const char *condnames_abs[] = {
7445 enum { BINOP, CMPOP, OTHEROP } optype = OTHEROP;
7446 uint32_t func = ctx->opcode & 0x3f;
7451 TCGv_i32 fp0 = tcg_temp_new_i32();
7452 TCGv_i32 fp1 = tcg_temp_new_i32();
7454 gen_load_fpr32(fp0, fs);
7455 gen_load_fpr32(fp1, ft);
7456 gen_helper_float_add_s(fp0, cpu_env, fp0, fp1);
7457 tcg_temp_free_i32(fp1);
7458 gen_store_fpr32(fp0, fd);
7459 tcg_temp_free_i32(fp0);
7466 TCGv_i32 fp0 = tcg_temp_new_i32();
7467 TCGv_i32 fp1 = tcg_temp_new_i32();
7469 gen_load_fpr32(fp0, fs);
7470 gen_load_fpr32(fp1, ft);
7471 gen_helper_float_sub_s(fp0, cpu_env, fp0, fp1);
7472 tcg_temp_free_i32(fp1);
7473 gen_store_fpr32(fp0, fd);
7474 tcg_temp_free_i32(fp0);
7481 TCGv_i32 fp0 = tcg_temp_new_i32();
7482 TCGv_i32 fp1 = tcg_temp_new_i32();
7484 gen_load_fpr32(fp0, fs);
7485 gen_load_fpr32(fp1, ft);
7486 gen_helper_float_mul_s(fp0, cpu_env, fp0, fp1);
7487 tcg_temp_free_i32(fp1);
7488 gen_store_fpr32(fp0, fd);
7489 tcg_temp_free_i32(fp0);
7496 TCGv_i32 fp0 = tcg_temp_new_i32();
7497 TCGv_i32 fp1 = tcg_temp_new_i32();
7499 gen_load_fpr32(fp0, fs);
7500 gen_load_fpr32(fp1, ft);
7501 gen_helper_float_div_s(fp0, cpu_env, fp0, fp1);
7502 tcg_temp_free_i32(fp1);
7503 gen_store_fpr32(fp0, fd);
7504 tcg_temp_free_i32(fp0);
7511 TCGv_i32 fp0 = tcg_temp_new_i32();
7513 gen_load_fpr32(fp0, fs);
7514 gen_helper_float_sqrt_s(fp0, cpu_env, fp0);
7515 gen_store_fpr32(fp0, fd);
7516 tcg_temp_free_i32(fp0);
7522 TCGv_i32 fp0 = tcg_temp_new_i32();
7524 gen_load_fpr32(fp0, fs);
7525 gen_helper_float_abs_s(fp0, fp0);
7526 gen_store_fpr32(fp0, fd);
7527 tcg_temp_free_i32(fp0);
7533 TCGv_i32 fp0 = tcg_temp_new_i32();
7535 gen_load_fpr32(fp0, fs);
7536 gen_store_fpr32(fp0, fd);
7537 tcg_temp_free_i32(fp0);
7543 TCGv_i32 fp0 = tcg_temp_new_i32();
7545 gen_load_fpr32(fp0, fs);
7546 gen_helper_float_chs_s(fp0, fp0);
7547 gen_store_fpr32(fp0, fd);
7548 tcg_temp_free_i32(fp0);
7553 check_cp1_64bitmode(ctx);
7555 TCGv_i32 fp32 = tcg_temp_new_i32();
7556 TCGv_i64 fp64 = tcg_temp_new_i64();
7558 gen_load_fpr32(fp32, fs);
7559 gen_helper_float_roundl_s(fp64, cpu_env, fp32);
7560 tcg_temp_free_i32(fp32);
7561 gen_store_fpr64(ctx, fp64, fd);
7562 tcg_temp_free_i64(fp64);
7567 check_cp1_64bitmode(ctx);
7569 TCGv_i32 fp32 = tcg_temp_new_i32();
7570 TCGv_i64 fp64 = tcg_temp_new_i64();
7572 gen_load_fpr32(fp32, fs);
7573 gen_helper_float_truncl_s(fp64, cpu_env, fp32);
7574 tcg_temp_free_i32(fp32);
7575 gen_store_fpr64(ctx, fp64, fd);
7576 tcg_temp_free_i64(fp64);
7581 check_cp1_64bitmode(ctx);
7583 TCGv_i32 fp32 = tcg_temp_new_i32();
7584 TCGv_i64 fp64 = tcg_temp_new_i64();
7586 gen_load_fpr32(fp32, fs);
7587 gen_helper_float_ceill_s(fp64, cpu_env, fp32);
7588 tcg_temp_free_i32(fp32);
7589 gen_store_fpr64(ctx, fp64, fd);
7590 tcg_temp_free_i64(fp64);
7595 check_cp1_64bitmode(ctx);
7597 TCGv_i32 fp32 = tcg_temp_new_i32();
7598 TCGv_i64 fp64 = tcg_temp_new_i64();
7600 gen_load_fpr32(fp32, fs);
7601 gen_helper_float_floorl_s(fp64, cpu_env, fp32);
7602 tcg_temp_free_i32(fp32);
7603 gen_store_fpr64(ctx, fp64, fd);
7604 tcg_temp_free_i64(fp64);
7610 TCGv_i32 fp0 = tcg_temp_new_i32();
7612 gen_load_fpr32(fp0, fs);
7613 gen_helper_float_roundw_s(fp0, cpu_env, fp0);
7614 gen_store_fpr32(fp0, fd);
7615 tcg_temp_free_i32(fp0);
7621 TCGv_i32 fp0 = tcg_temp_new_i32();
7623 gen_load_fpr32(fp0, fs);
7624 gen_helper_float_truncw_s(fp0, cpu_env, fp0);
7625 gen_store_fpr32(fp0, fd);
7626 tcg_temp_free_i32(fp0);
7632 TCGv_i32 fp0 = tcg_temp_new_i32();
7634 gen_load_fpr32(fp0, fs);
7635 gen_helper_float_ceilw_s(fp0, cpu_env, fp0);
7636 gen_store_fpr32(fp0, fd);
7637 tcg_temp_free_i32(fp0);
7643 TCGv_i32 fp0 = tcg_temp_new_i32();
7645 gen_load_fpr32(fp0, fs);
7646 gen_helper_float_floorw_s(fp0, cpu_env, fp0);
7647 gen_store_fpr32(fp0, fd);
7648 tcg_temp_free_i32(fp0);
7653 gen_movcf_s(fs, fd, (ft >> 2) & 0x7, ft & 0x1);
7658 int l1 = gen_new_label();
7662 tcg_gen_brcondi_tl(TCG_COND_NE, cpu_gpr[ft], 0, l1);
7664 fp0 = tcg_temp_new_i32();
7665 gen_load_fpr32(fp0, fs);
7666 gen_store_fpr32(fp0, fd);
7667 tcg_temp_free_i32(fp0);
7674 int l1 = gen_new_label();
7678 tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_gpr[ft], 0, l1);
7679 fp0 = tcg_temp_new_i32();
7680 gen_load_fpr32(fp0, fs);
7681 gen_store_fpr32(fp0, fd);
7682 tcg_temp_free_i32(fp0);
7691 TCGv_i32 fp0 = tcg_temp_new_i32();
7693 gen_load_fpr32(fp0, fs);
7694 gen_helper_float_recip_s(fp0, cpu_env, fp0);
7695 gen_store_fpr32(fp0, fd);
7696 tcg_temp_free_i32(fp0);
7703 TCGv_i32 fp0 = tcg_temp_new_i32();
7705 gen_load_fpr32(fp0, fs);
7706 gen_helper_float_rsqrt_s(fp0, cpu_env, fp0);
7707 gen_store_fpr32(fp0, fd);
7708 tcg_temp_free_i32(fp0);
7713 check_cp1_64bitmode(ctx);
7715 TCGv_i32 fp0 = tcg_temp_new_i32();
7716 TCGv_i32 fp1 = tcg_temp_new_i32();
7718 gen_load_fpr32(fp0, fs);
7719 gen_load_fpr32(fp1, ft);
7720 gen_helper_float_recip2_s(fp0, cpu_env, fp0, fp1);
7721 tcg_temp_free_i32(fp1);
7722 gen_store_fpr32(fp0, fd);
7723 tcg_temp_free_i32(fp0);
7728 check_cp1_64bitmode(ctx);
7730 TCGv_i32 fp0 = tcg_temp_new_i32();
7732 gen_load_fpr32(fp0, fs);
7733 gen_helper_float_recip1_s(fp0, cpu_env, fp0);
7734 gen_store_fpr32(fp0, fd);
7735 tcg_temp_free_i32(fp0);
7740 check_cp1_64bitmode(ctx);
7742 TCGv_i32 fp0 = tcg_temp_new_i32();
7744 gen_load_fpr32(fp0, fs);
7745 gen_helper_float_rsqrt1_s(fp0, cpu_env, fp0);
7746 gen_store_fpr32(fp0, fd);
7747 tcg_temp_free_i32(fp0);
7752 check_cp1_64bitmode(ctx);
7754 TCGv_i32 fp0 = tcg_temp_new_i32();
7755 TCGv_i32 fp1 = tcg_temp_new_i32();
7757 gen_load_fpr32(fp0, fs);
7758 gen_load_fpr32(fp1, ft);
7759 gen_helper_float_rsqrt2_s(fp0, cpu_env, fp0, fp1);
7760 tcg_temp_free_i32(fp1);
7761 gen_store_fpr32(fp0, fd);
7762 tcg_temp_free_i32(fp0);
7767 check_cp1_registers(ctx, fd);
7769 TCGv_i32 fp32 = tcg_temp_new_i32();
7770 TCGv_i64 fp64 = tcg_temp_new_i64();
7772 gen_load_fpr32(fp32, fs);
7773 gen_helper_float_cvtd_s(fp64, cpu_env, fp32);
7774 tcg_temp_free_i32(fp32);
7775 gen_store_fpr64(ctx, fp64, fd);
7776 tcg_temp_free_i64(fp64);
7782 TCGv_i32 fp0 = tcg_temp_new_i32();
7784 gen_load_fpr32(fp0, fs);
7785 gen_helper_float_cvtw_s(fp0, cpu_env, fp0);
7786 gen_store_fpr32(fp0, fd);
7787 tcg_temp_free_i32(fp0);
7792 check_cp1_64bitmode(ctx);
7794 TCGv_i32 fp32 = tcg_temp_new_i32();
7795 TCGv_i64 fp64 = tcg_temp_new_i64();
7797 gen_load_fpr32(fp32, fs);
7798 gen_helper_float_cvtl_s(fp64, cpu_env, fp32);
7799 tcg_temp_free_i32(fp32);
7800 gen_store_fpr64(ctx, fp64, fd);
7801 tcg_temp_free_i64(fp64);
7806 check_cp1_64bitmode(ctx);
7808 TCGv_i64 fp64 = tcg_temp_new_i64();
7809 TCGv_i32 fp32_0 = tcg_temp_new_i32();
7810 TCGv_i32 fp32_1 = tcg_temp_new_i32();
7812 gen_load_fpr32(fp32_0, fs);
7813 gen_load_fpr32(fp32_1, ft);
7814 tcg_gen_concat_i32_i64(fp64, fp32_1, fp32_0);
7815 tcg_temp_free_i32(fp32_1);
7816 tcg_temp_free_i32(fp32_0);
7817 gen_store_fpr64(ctx, fp64, fd);
7818 tcg_temp_free_i64(fp64);
7831 case OPC_CMP_NGLE_S:
7838 if (ctx->opcode & (1 << 6)) {
7839 gen_cmpabs_s(ctx, func-48, ft, fs, cc);
7840 opn = condnames_abs[func-48];
7842 gen_cmp_s(ctx, func-48, ft, fs, cc);
7843 opn = condnames[func-48];
7847 check_cp1_registers(ctx, fs | ft | fd);
7849 TCGv_i64 fp0 = tcg_temp_new_i64();
7850 TCGv_i64 fp1 = tcg_temp_new_i64();
7852 gen_load_fpr64(ctx, fp0, fs);
7853 gen_load_fpr64(ctx, fp1, ft);
7854 gen_helper_float_add_d(fp0, cpu_env, fp0, fp1);
7855 tcg_temp_free_i64(fp1);
7856 gen_store_fpr64(ctx, fp0, fd);
7857 tcg_temp_free_i64(fp0);
7863 check_cp1_registers(ctx, fs | ft | fd);
7865 TCGv_i64 fp0 = tcg_temp_new_i64();
7866 TCGv_i64 fp1 = tcg_temp_new_i64();
7868 gen_load_fpr64(ctx, fp0, fs);
7869 gen_load_fpr64(ctx, fp1, ft);
7870 gen_helper_float_sub_d(fp0, cpu_env, fp0, fp1);
7871 tcg_temp_free_i64(fp1);
7872 gen_store_fpr64(ctx, fp0, fd);
7873 tcg_temp_free_i64(fp0);
7879 check_cp1_registers(ctx, fs | ft | fd);
7881 TCGv_i64 fp0 = tcg_temp_new_i64();
7882 TCGv_i64 fp1 = tcg_temp_new_i64();
7884 gen_load_fpr64(ctx, fp0, fs);
7885 gen_load_fpr64(ctx, fp1, ft);
7886 gen_helper_float_mul_d(fp0, cpu_env, fp0, fp1);
7887 tcg_temp_free_i64(fp1);
7888 gen_store_fpr64(ctx, fp0, fd);
7889 tcg_temp_free_i64(fp0);
7895 check_cp1_registers(ctx, fs | ft | fd);
7897 TCGv_i64 fp0 = tcg_temp_new_i64();
7898 TCGv_i64 fp1 = tcg_temp_new_i64();
7900 gen_load_fpr64(ctx, fp0, fs);
7901 gen_load_fpr64(ctx, fp1, ft);
7902 gen_helper_float_div_d(fp0, cpu_env, fp0, fp1);
7903 tcg_temp_free_i64(fp1);
7904 gen_store_fpr64(ctx, fp0, fd);
7905 tcg_temp_free_i64(fp0);
7911 check_cp1_registers(ctx, fs | fd);
7913 TCGv_i64 fp0 = tcg_temp_new_i64();
7915 gen_load_fpr64(ctx, fp0, fs);
7916 gen_helper_float_sqrt_d(fp0, cpu_env, fp0);
7917 gen_store_fpr64(ctx, fp0, fd);
7918 tcg_temp_free_i64(fp0);
7923 check_cp1_registers(ctx, fs | fd);
7925 TCGv_i64 fp0 = tcg_temp_new_i64();
7927 gen_load_fpr64(ctx, fp0, fs);
7928 gen_helper_float_abs_d(fp0, fp0);
7929 gen_store_fpr64(ctx, fp0, fd);
7930 tcg_temp_free_i64(fp0);
7935 check_cp1_registers(ctx, fs | fd);
7937 TCGv_i64 fp0 = tcg_temp_new_i64();
7939 gen_load_fpr64(ctx, fp0, fs);
7940 gen_store_fpr64(ctx, fp0, fd);
7941 tcg_temp_free_i64(fp0);
7946 check_cp1_registers(ctx, fs | fd);
7948 TCGv_i64 fp0 = tcg_temp_new_i64();
7950 gen_load_fpr64(ctx, fp0, fs);
7951 gen_helper_float_chs_d(fp0, fp0);
7952 gen_store_fpr64(ctx, fp0, fd);
7953 tcg_temp_free_i64(fp0);
7958 check_cp1_64bitmode(ctx);
7960 TCGv_i64 fp0 = tcg_temp_new_i64();
7962 gen_load_fpr64(ctx, fp0, fs);
7963 gen_helper_float_roundl_d(fp0, cpu_env, fp0);
7964 gen_store_fpr64(ctx, fp0, fd);
7965 tcg_temp_free_i64(fp0);
7970 check_cp1_64bitmode(ctx);
7972 TCGv_i64 fp0 = tcg_temp_new_i64();
7974 gen_load_fpr64(ctx, fp0, fs);
7975 gen_helper_float_truncl_d(fp0, cpu_env, fp0);
7976 gen_store_fpr64(ctx, fp0, fd);
7977 tcg_temp_free_i64(fp0);
7982 check_cp1_64bitmode(ctx);
7984 TCGv_i64 fp0 = tcg_temp_new_i64();
7986 gen_load_fpr64(ctx, fp0, fs);
7987 gen_helper_float_ceill_d(fp0, cpu_env, fp0);
7988 gen_store_fpr64(ctx, fp0, fd);
7989 tcg_temp_free_i64(fp0);
7994 check_cp1_64bitmode(ctx);
7996 TCGv_i64 fp0 = tcg_temp_new_i64();
7998 gen_load_fpr64(ctx, fp0, fs);
7999 gen_helper_float_floorl_d(fp0, cpu_env, fp0);
8000 gen_store_fpr64(ctx, fp0, fd);
8001 tcg_temp_free_i64(fp0);
8006 check_cp1_registers(ctx, fs);
8008 TCGv_i32 fp32 = tcg_temp_new_i32();
8009 TCGv_i64 fp64 = tcg_temp_new_i64();
8011 gen_load_fpr64(ctx, fp64, fs);
8012 gen_helper_float_roundw_d(fp32, cpu_env, fp64);
8013 tcg_temp_free_i64(fp64);
8014 gen_store_fpr32(fp32, fd);
8015 tcg_temp_free_i32(fp32);
8020 check_cp1_registers(ctx, fs);
8022 TCGv_i32 fp32 = tcg_temp_new_i32();
8023 TCGv_i64 fp64 = tcg_temp_new_i64();
8025 gen_load_fpr64(ctx, fp64, fs);
8026 gen_helper_float_truncw_d(fp32, cpu_env, fp64);
8027 tcg_temp_free_i64(fp64);
8028 gen_store_fpr32(fp32, fd);
8029 tcg_temp_free_i32(fp32);
8034 check_cp1_registers(ctx, fs);
8036 TCGv_i32 fp32 = tcg_temp_new_i32();
8037 TCGv_i64 fp64 = tcg_temp_new_i64();
8039 gen_load_fpr64(ctx, fp64, fs);
8040 gen_helper_float_ceilw_d(fp32, cpu_env, fp64);
8041 tcg_temp_free_i64(fp64);
8042 gen_store_fpr32(fp32, fd);
8043 tcg_temp_free_i32(fp32);
8048 check_cp1_registers(ctx, fs);
8050 TCGv_i32 fp32 = tcg_temp_new_i32();
8051 TCGv_i64 fp64 = tcg_temp_new_i64();
8053 gen_load_fpr64(ctx, fp64, fs);
8054 gen_helper_float_floorw_d(fp32, cpu_env, fp64);
8055 tcg_temp_free_i64(fp64);
8056 gen_store_fpr32(fp32, fd);
8057 tcg_temp_free_i32(fp32);
8062 gen_movcf_d(ctx, fs, fd, (ft >> 2) & 0x7, ft & 0x1);
8067 int l1 = gen_new_label();
8071 tcg_gen_brcondi_tl(TCG_COND_NE, cpu_gpr[ft], 0, l1);
8073 fp0 = tcg_temp_new_i64();
8074 gen_load_fpr64(ctx, fp0, fs);
8075 gen_store_fpr64(ctx, fp0, fd);
8076 tcg_temp_free_i64(fp0);
8083 int l1 = gen_new_label();
8087 tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_gpr[ft], 0, l1);
8088 fp0 = tcg_temp_new_i64();
8089 gen_load_fpr64(ctx, fp0, fs);
8090 gen_store_fpr64(ctx, fp0, fd);
8091 tcg_temp_free_i64(fp0);
8098 check_cp1_64bitmode(ctx);
8100 TCGv_i64 fp0 = tcg_temp_new_i64();
8102 gen_load_fpr64(ctx, fp0, fs);
8103 gen_helper_float_recip_d(fp0, cpu_env, fp0);
8104 gen_store_fpr64(ctx, fp0, fd);
8105 tcg_temp_free_i64(fp0);
8110 check_cp1_64bitmode(ctx);
8112 TCGv_i64 fp0 = tcg_temp_new_i64();
8114 gen_load_fpr64(ctx, fp0, fs);
8115 gen_helper_float_rsqrt_d(fp0, cpu_env, fp0);
8116 gen_store_fpr64(ctx, fp0, fd);
8117 tcg_temp_free_i64(fp0);
8122 check_cp1_64bitmode(ctx);
8124 TCGv_i64 fp0 = tcg_temp_new_i64();
8125 TCGv_i64 fp1 = tcg_temp_new_i64();
8127 gen_load_fpr64(ctx, fp0, fs);
8128 gen_load_fpr64(ctx, fp1, ft);
8129 gen_helper_float_recip2_d(fp0, cpu_env, fp0, fp1);
8130 tcg_temp_free_i64(fp1);
8131 gen_store_fpr64(ctx, fp0, fd);
8132 tcg_temp_free_i64(fp0);
8137 check_cp1_64bitmode(ctx);
8139 TCGv_i64 fp0 = tcg_temp_new_i64();
8141 gen_load_fpr64(ctx, fp0, fs);
8142 gen_helper_float_recip1_d(fp0, cpu_env, fp0);
8143 gen_store_fpr64(ctx, fp0, fd);
8144 tcg_temp_free_i64(fp0);
8149 check_cp1_64bitmode(ctx);
8151 TCGv_i64 fp0 = tcg_temp_new_i64();
8153 gen_load_fpr64(ctx, fp0, fs);
8154 gen_helper_float_rsqrt1_d(fp0, cpu_env, fp0);
8155 gen_store_fpr64(ctx, fp0, fd);
8156 tcg_temp_free_i64(fp0);
8161 check_cp1_64bitmode(ctx);
8163 TCGv_i64 fp0 = tcg_temp_new_i64();
8164 TCGv_i64 fp1 = tcg_temp_new_i64();
8166 gen_load_fpr64(ctx, fp0, fs);
8167 gen_load_fpr64(ctx, fp1, ft);
8168 gen_helper_float_rsqrt2_d(fp0, cpu_env, fp0, fp1);
8169 tcg_temp_free_i64(fp1);
8170 gen_store_fpr64(ctx, fp0, fd);
8171 tcg_temp_free_i64(fp0);
8184 case OPC_CMP_NGLE_D:
8191 if (ctx->opcode & (1 << 6)) {
8192 gen_cmpabs_d(ctx, func-48, ft, fs, cc);
8193 opn = condnames_abs[func-48];
8195 gen_cmp_d(ctx, func-48, ft, fs, cc);
8196 opn = condnames[func-48];
8200 check_cp1_registers(ctx, fs);
8202 TCGv_i32 fp32 = tcg_temp_new_i32();
8203 TCGv_i64 fp64 = tcg_temp_new_i64();
8205 gen_load_fpr64(ctx, fp64, fs);
8206 gen_helper_float_cvts_d(fp32, cpu_env, fp64);
8207 tcg_temp_free_i64(fp64);
8208 gen_store_fpr32(fp32, fd);
8209 tcg_temp_free_i32(fp32);
8214 check_cp1_registers(ctx, fs);
8216 TCGv_i32 fp32 = tcg_temp_new_i32();
8217 TCGv_i64 fp64 = tcg_temp_new_i64();
8219 gen_load_fpr64(ctx, fp64, fs);
8220 gen_helper_float_cvtw_d(fp32, cpu_env, fp64);
8221 tcg_temp_free_i64(fp64);
8222 gen_store_fpr32(fp32, fd);
8223 tcg_temp_free_i32(fp32);
8228 check_cp1_64bitmode(ctx);
8230 TCGv_i64 fp0 = tcg_temp_new_i64();
8232 gen_load_fpr64(ctx, fp0, fs);
8233 gen_helper_float_cvtl_d(fp0, cpu_env, fp0);
8234 gen_store_fpr64(ctx, fp0, fd);
8235 tcg_temp_free_i64(fp0);
8241 TCGv_i32 fp0 = tcg_temp_new_i32();
8243 gen_load_fpr32(fp0, fs);
8244 gen_helper_float_cvts_w(fp0, cpu_env, fp0);
8245 gen_store_fpr32(fp0, fd);
8246 tcg_temp_free_i32(fp0);
8251 check_cp1_registers(ctx, fd);
8253 TCGv_i32 fp32 = tcg_temp_new_i32();
8254 TCGv_i64 fp64 = tcg_temp_new_i64();
8256 gen_load_fpr32(fp32, fs);
8257 gen_helper_float_cvtd_w(fp64, cpu_env, fp32);
8258 tcg_temp_free_i32(fp32);
8259 gen_store_fpr64(ctx, fp64, fd);
8260 tcg_temp_free_i64(fp64);
8265 check_cp1_64bitmode(ctx);
8267 TCGv_i32 fp32 = tcg_temp_new_i32();
8268 TCGv_i64 fp64 = tcg_temp_new_i64();
8270 gen_load_fpr64(ctx, fp64, fs);
8271 gen_helper_float_cvts_l(fp32, cpu_env, fp64);
8272 tcg_temp_free_i64(fp64);
8273 gen_store_fpr32(fp32, fd);
8274 tcg_temp_free_i32(fp32);
8279 check_cp1_64bitmode(ctx);
8281 TCGv_i64 fp0 = tcg_temp_new_i64();
8283 gen_load_fpr64(ctx, fp0, fs);
8284 gen_helper_float_cvtd_l(fp0, cpu_env, fp0);
8285 gen_store_fpr64(ctx, fp0, fd);
8286 tcg_temp_free_i64(fp0);
8291 check_cp1_64bitmode(ctx);
8293 TCGv_i64 fp0 = tcg_temp_new_i64();
8295 gen_load_fpr64(ctx, fp0, fs);
8296 gen_helper_float_cvtps_pw(fp0, cpu_env, fp0);
8297 gen_store_fpr64(ctx, fp0, fd);
8298 tcg_temp_free_i64(fp0);
8303 check_cp1_64bitmode(ctx);
8305 TCGv_i64 fp0 = tcg_temp_new_i64();
8306 TCGv_i64 fp1 = tcg_temp_new_i64();
8308 gen_load_fpr64(ctx, fp0, fs);
8309 gen_load_fpr64(ctx, fp1, ft);
8310 gen_helper_float_add_ps(fp0, cpu_env, fp0, fp1);
8311 tcg_temp_free_i64(fp1);
8312 gen_store_fpr64(ctx, fp0, fd);
8313 tcg_temp_free_i64(fp0);
8318 check_cp1_64bitmode(ctx);
8320 TCGv_i64 fp0 = tcg_temp_new_i64();
8321 TCGv_i64 fp1 = tcg_temp_new_i64();
8323 gen_load_fpr64(ctx, fp0, fs);
8324 gen_load_fpr64(ctx, fp1, ft);
8325 gen_helper_float_sub_ps(fp0, cpu_env, fp0, fp1);
8326 tcg_temp_free_i64(fp1);
8327 gen_store_fpr64(ctx, fp0, fd);
8328 tcg_temp_free_i64(fp0);
8333 check_cp1_64bitmode(ctx);
8335 TCGv_i64 fp0 = tcg_temp_new_i64();
8336 TCGv_i64 fp1 = tcg_temp_new_i64();
8338 gen_load_fpr64(ctx, fp0, fs);
8339 gen_load_fpr64(ctx, fp1, ft);
8340 gen_helper_float_mul_ps(fp0, cpu_env, fp0, fp1);
8341 tcg_temp_free_i64(fp1);
8342 gen_store_fpr64(ctx, fp0, fd);
8343 tcg_temp_free_i64(fp0);
8348 check_cp1_64bitmode(ctx);
8350 TCGv_i64 fp0 = tcg_temp_new_i64();
8352 gen_load_fpr64(ctx, fp0, fs);
8353 gen_helper_float_abs_ps(fp0, fp0);
8354 gen_store_fpr64(ctx, fp0, fd);
8355 tcg_temp_free_i64(fp0);
8360 check_cp1_64bitmode(ctx);
8362 TCGv_i64 fp0 = tcg_temp_new_i64();
8364 gen_load_fpr64(ctx, fp0, fs);
8365 gen_store_fpr64(ctx, fp0, fd);
8366 tcg_temp_free_i64(fp0);
8371 check_cp1_64bitmode(ctx);
8373 TCGv_i64 fp0 = tcg_temp_new_i64();
8375 gen_load_fpr64(ctx, fp0, fs);
8376 gen_helper_float_chs_ps(fp0, fp0);
8377 gen_store_fpr64(ctx, fp0, fd);
8378 tcg_temp_free_i64(fp0);
8383 check_cp1_64bitmode(ctx);
8384 gen_movcf_ps(fs, fd, (ft >> 2) & 0x7, ft & 0x1);
8388 check_cp1_64bitmode(ctx);
8390 int l1 = gen_new_label();
8394 tcg_gen_brcondi_tl(TCG_COND_NE, cpu_gpr[ft], 0, l1);
8395 fp0 = tcg_temp_new_i64();
8396 gen_load_fpr64(ctx, fp0, fs);
8397 gen_store_fpr64(ctx, fp0, fd);
8398 tcg_temp_free_i64(fp0);
8404 check_cp1_64bitmode(ctx);
8406 int l1 = gen_new_label();
8410 tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_gpr[ft], 0, l1);
8411 fp0 = tcg_temp_new_i64();
8412 gen_load_fpr64(ctx, fp0, fs);
8413 gen_store_fpr64(ctx, fp0, fd);
8414 tcg_temp_free_i64(fp0);
8421 check_cp1_64bitmode(ctx);
8423 TCGv_i64 fp0 = tcg_temp_new_i64();
8424 TCGv_i64 fp1 = tcg_temp_new_i64();
8426 gen_load_fpr64(ctx, fp0, ft);
8427 gen_load_fpr64(ctx, fp1, fs);
8428 gen_helper_float_addr_ps(fp0, cpu_env, fp0, fp1);
8429 tcg_temp_free_i64(fp1);
8430 gen_store_fpr64(ctx, fp0, fd);
8431 tcg_temp_free_i64(fp0);
8436 check_cp1_64bitmode(ctx);
8438 TCGv_i64 fp0 = tcg_temp_new_i64();
8439 TCGv_i64 fp1 = tcg_temp_new_i64();
8441 gen_load_fpr64(ctx, fp0, ft);
8442 gen_load_fpr64(ctx, fp1, fs);
8443 gen_helper_float_mulr_ps(fp0, cpu_env, fp0, fp1);
8444 tcg_temp_free_i64(fp1);
8445 gen_store_fpr64(ctx, fp0, fd);
8446 tcg_temp_free_i64(fp0);
8451 check_cp1_64bitmode(ctx);
8453 TCGv_i64 fp0 = tcg_temp_new_i64();
8454 TCGv_i64 fp1 = tcg_temp_new_i64();
8456 gen_load_fpr64(ctx, fp0, fs);
8457 gen_load_fpr64(ctx, fp1, ft);
8458 gen_helper_float_recip2_ps(fp0, cpu_env, fp0, fp1);
8459 tcg_temp_free_i64(fp1);
8460 gen_store_fpr64(ctx, fp0, fd);
8461 tcg_temp_free_i64(fp0);
8466 check_cp1_64bitmode(ctx);
8468 TCGv_i64 fp0 = tcg_temp_new_i64();
8470 gen_load_fpr64(ctx, fp0, fs);
8471 gen_helper_float_recip1_ps(fp0, cpu_env, fp0);
8472 gen_store_fpr64(ctx, fp0, fd);
8473 tcg_temp_free_i64(fp0);
8478 check_cp1_64bitmode(ctx);
8480 TCGv_i64 fp0 = tcg_temp_new_i64();
8482 gen_load_fpr64(ctx, fp0, fs);
8483 gen_helper_float_rsqrt1_ps(fp0, cpu_env, fp0);
8484 gen_store_fpr64(ctx, fp0, fd);
8485 tcg_temp_free_i64(fp0);
8490 check_cp1_64bitmode(ctx);
8492 TCGv_i64 fp0 = tcg_temp_new_i64();
8493 TCGv_i64 fp1 = tcg_temp_new_i64();
8495 gen_load_fpr64(ctx, fp0, fs);
8496 gen_load_fpr64(ctx, fp1, ft);
8497 gen_helper_float_rsqrt2_ps(fp0, cpu_env, fp0, fp1);
8498 tcg_temp_free_i64(fp1);
8499 gen_store_fpr64(ctx, fp0, fd);
8500 tcg_temp_free_i64(fp0);
8505 check_cp1_64bitmode(ctx);
8507 TCGv_i32 fp0 = tcg_temp_new_i32();
8509 gen_load_fpr32h(fp0, fs);
8510 gen_helper_float_cvts_pu(fp0, cpu_env, fp0);
8511 gen_store_fpr32(fp0, fd);
8512 tcg_temp_free_i32(fp0);
8517 check_cp1_64bitmode(ctx);
8519 TCGv_i64 fp0 = tcg_temp_new_i64();
8521 gen_load_fpr64(ctx, fp0, fs);
8522 gen_helper_float_cvtpw_ps(fp0, cpu_env, fp0);
8523 gen_store_fpr64(ctx, fp0, fd);
8524 tcg_temp_free_i64(fp0);
8529 check_cp1_64bitmode(ctx);
8531 TCGv_i32 fp0 = tcg_temp_new_i32();
8533 gen_load_fpr32(fp0, fs);
8534 gen_helper_float_cvts_pl(fp0, cpu_env, fp0);
8535 gen_store_fpr32(fp0, fd);
8536 tcg_temp_free_i32(fp0);
8541 check_cp1_64bitmode(ctx);
8543 TCGv_i32 fp0 = tcg_temp_new_i32();
8544 TCGv_i32 fp1 = tcg_temp_new_i32();
8546 gen_load_fpr32(fp0, fs);
8547 gen_load_fpr32(fp1, ft);
8548 gen_store_fpr32h(fp0, fd);
8549 gen_store_fpr32(fp1, fd);
8550 tcg_temp_free_i32(fp0);
8551 tcg_temp_free_i32(fp1);
8556 check_cp1_64bitmode(ctx);
8558 TCGv_i32 fp0 = tcg_temp_new_i32();
8559 TCGv_i32 fp1 = tcg_temp_new_i32();
8561 gen_load_fpr32(fp0, fs);
8562 gen_load_fpr32h(fp1, ft);
8563 gen_store_fpr32(fp1, fd);
8564 gen_store_fpr32h(fp0, fd);
8565 tcg_temp_free_i32(fp0);
8566 tcg_temp_free_i32(fp1);
8571 check_cp1_64bitmode(ctx);
8573 TCGv_i32 fp0 = tcg_temp_new_i32();
8574 TCGv_i32 fp1 = tcg_temp_new_i32();
8576 gen_load_fpr32h(fp0, fs);
8577 gen_load_fpr32(fp1, ft);
8578 gen_store_fpr32(fp1, fd);
8579 gen_store_fpr32h(fp0, fd);
8580 tcg_temp_free_i32(fp0);
8581 tcg_temp_free_i32(fp1);
8586 check_cp1_64bitmode(ctx);
8588 TCGv_i32 fp0 = tcg_temp_new_i32();
8589 TCGv_i32 fp1 = tcg_temp_new_i32();
8591 gen_load_fpr32h(fp0, fs);
8592 gen_load_fpr32h(fp1, ft);
8593 gen_store_fpr32(fp1, fd);
8594 gen_store_fpr32h(fp0, fd);
8595 tcg_temp_free_i32(fp0);
8596 tcg_temp_free_i32(fp1);
8603 case OPC_CMP_UEQ_PS:
8604 case OPC_CMP_OLT_PS:
8605 case OPC_CMP_ULT_PS:
8606 case OPC_CMP_OLE_PS:
8607 case OPC_CMP_ULE_PS:
8609 case OPC_CMP_NGLE_PS:
8610 case OPC_CMP_SEQ_PS:
8611 case OPC_CMP_NGL_PS:
8613 case OPC_CMP_NGE_PS:
8615 case OPC_CMP_NGT_PS:
8616 if (ctx->opcode & (1 << 6)) {
8617 gen_cmpabs_ps(ctx, func-48, ft, fs, cc);
8618 opn = condnames_abs[func-48];
8620 gen_cmp_ps(ctx, func-48, ft, fs, cc);
8621 opn = condnames[func-48];
8626 generate_exception (ctx, EXCP_RI);
8629 (void)opn; /* avoid a compiler warning */
8632 MIPS_DEBUG("%s %s, %s, %s", opn, fregnames[fd], fregnames[fs], fregnames[ft]);
8635 MIPS_DEBUG("%s %s,%s", opn, fregnames[fs], fregnames[ft]);
8638 MIPS_DEBUG("%s %s,%s", opn, fregnames[fd], fregnames[fs]);
8643 /* Coprocessor 3 (FPU) */
8644 static void gen_flt3_ldst (DisasContext *ctx, uint32_t opc,
8645 int fd, int fs, int base, int index)
8647 const char *opn = "extended float load/store";
8649 TCGv t0 = tcg_temp_new();
8652 gen_load_gpr(t0, index);
8653 } else if (index == 0) {
8654 gen_load_gpr(t0, base);
8656 gen_op_addr_add(ctx, t0, cpu_gpr[base], cpu_gpr[index]);
8658 /* Don't do NOP if destination is zero: we must perform the actual
8664 TCGv_i32 fp0 = tcg_temp_new_i32();
8666 tcg_gen_qemu_ld32s(t0, t0, ctx->mem_idx);
8667 tcg_gen_trunc_tl_i32(fp0, t0);
8668 gen_store_fpr32(fp0, fd);
8669 tcg_temp_free_i32(fp0);
8675 check_cp1_registers(ctx, fd);
8677 TCGv_i64 fp0 = tcg_temp_new_i64();
8679 tcg_gen_qemu_ld64(fp0, t0, ctx->mem_idx);
8680 gen_store_fpr64(ctx, fp0, fd);
8681 tcg_temp_free_i64(fp0);
8686 check_cp1_64bitmode(ctx);
8687 tcg_gen_andi_tl(t0, t0, ~0x7);
8689 TCGv_i64 fp0 = tcg_temp_new_i64();
8691 tcg_gen_qemu_ld64(fp0, t0, ctx->mem_idx);
8692 gen_store_fpr64(ctx, fp0, fd);
8693 tcg_temp_free_i64(fp0);
8700 TCGv_i32 fp0 = tcg_temp_new_i32();
8701 TCGv t1 = tcg_temp_new();
8703 gen_load_fpr32(fp0, fs);
8704 tcg_gen_extu_i32_tl(t1, fp0);
8705 tcg_gen_qemu_st32(t1, t0, ctx->mem_idx);
8706 tcg_temp_free_i32(fp0);
8714 check_cp1_registers(ctx, fs);
8716 TCGv_i64 fp0 = tcg_temp_new_i64();
8718 gen_load_fpr64(ctx, fp0, fs);
8719 tcg_gen_qemu_st64(fp0, t0, ctx->mem_idx);
8720 tcg_temp_free_i64(fp0);
8726 check_cp1_64bitmode(ctx);
8727 tcg_gen_andi_tl(t0, t0, ~0x7);
8729 TCGv_i64 fp0 = tcg_temp_new_i64();
8731 gen_load_fpr64(ctx, fp0, fs);
8732 tcg_gen_qemu_st64(fp0, t0, ctx->mem_idx);
8733 tcg_temp_free_i64(fp0);
8740 (void)opn; (void)store; /* avoid compiler warnings */
8741 MIPS_DEBUG("%s %s, %s(%s)", opn, fregnames[store ? fs : fd],
8742 regnames[index], regnames[base]);
8745 static void gen_flt3_arith (DisasContext *ctx, uint32_t opc,
8746 int fd, int fr, int fs, int ft)
8748 const char *opn = "flt3_arith";
8752 check_cp1_64bitmode(ctx);
8754 TCGv t0 = tcg_temp_local_new();
8755 TCGv_i32 fp = tcg_temp_new_i32();
8756 TCGv_i32 fph = tcg_temp_new_i32();
8757 int l1 = gen_new_label();
8758 int l2 = gen_new_label();
8760 gen_load_gpr(t0, fr);
8761 tcg_gen_andi_tl(t0, t0, 0x7);
8763 tcg_gen_brcondi_tl(TCG_COND_NE, t0, 0, l1);
8764 gen_load_fpr32(fp, fs);
8765 gen_load_fpr32h(fph, fs);
8766 gen_store_fpr32(fp, fd);
8767 gen_store_fpr32h(fph, fd);
8770 tcg_gen_brcondi_tl(TCG_COND_NE, t0, 4, l2);
8772 #ifdef TARGET_WORDS_BIGENDIAN
8773 gen_load_fpr32(fp, fs);
8774 gen_load_fpr32h(fph, ft);
8775 gen_store_fpr32h(fp, fd);
8776 gen_store_fpr32(fph, fd);
8778 gen_load_fpr32h(fph, fs);
8779 gen_load_fpr32(fp, ft);
8780 gen_store_fpr32(fph, fd);
8781 gen_store_fpr32h(fp, fd);
8784 tcg_temp_free_i32(fp);
8785 tcg_temp_free_i32(fph);
8792 TCGv_i32 fp0 = tcg_temp_new_i32();
8793 TCGv_i32 fp1 = tcg_temp_new_i32();
8794 TCGv_i32 fp2 = tcg_temp_new_i32();
8796 gen_load_fpr32(fp0, fs);
8797 gen_load_fpr32(fp1, ft);
8798 gen_load_fpr32(fp2, fr);
8799 gen_helper_float_madd_s(fp2, cpu_env, fp0, fp1, fp2);
8800 tcg_temp_free_i32(fp0);
8801 tcg_temp_free_i32(fp1);
8802 gen_store_fpr32(fp2, fd);
8803 tcg_temp_free_i32(fp2);
8809 check_cp1_registers(ctx, fd | fs | ft | fr);
8811 TCGv_i64 fp0 = tcg_temp_new_i64();
8812 TCGv_i64 fp1 = tcg_temp_new_i64();
8813 TCGv_i64 fp2 = tcg_temp_new_i64();
8815 gen_load_fpr64(ctx, fp0, fs);
8816 gen_load_fpr64(ctx, fp1, ft);
8817 gen_load_fpr64(ctx, fp2, fr);
8818 gen_helper_float_madd_d(fp2, cpu_env, fp0, fp1, fp2);
8819 tcg_temp_free_i64(fp0);
8820 tcg_temp_free_i64(fp1);
8821 gen_store_fpr64(ctx, fp2, fd);
8822 tcg_temp_free_i64(fp2);
8827 check_cp1_64bitmode(ctx);
8829 TCGv_i64 fp0 = tcg_temp_new_i64();
8830 TCGv_i64 fp1 = tcg_temp_new_i64();
8831 TCGv_i64 fp2 = tcg_temp_new_i64();
8833 gen_load_fpr64(ctx, fp0, fs);
8834 gen_load_fpr64(ctx, fp1, ft);
8835 gen_load_fpr64(ctx, fp2, fr);
8836 gen_helper_float_madd_ps(fp2, cpu_env, fp0, fp1, fp2);
8837 tcg_temp_free_i64(fp0);
8838 tcg_temp_free_i64(fp1);
8839 gen_store_fpr64(ctx, fp2, fd);
8840 tcg_temp_free_i64(fp2);
8847 TCGv_i32 fp0 = tcg_temp_new_i32();
8848 TCGv_i32 fp1 = tcg_temp_new_i32();
8849 TCGv_i32 fp2 = tcg_temp_new_i32();
8851 gen_load_fpr32(fp0, fs);
8852 gen_load_fpr32(fp1, ft);
8853 gen_load_fpr32(fp2, fr);
8854 gen_helper_float_msub_s(fp2, cpu_env, fp0, fp1, fp2);
8855 tcg_temp_free_i32(fp0);
8856 tcg_temp_free_i32(fp1);
8857 gen_store_fpr32(fp2, fd);
8858 tcg_temp_free_i32(fp2);
8864 check_cp1_registers(ctx, fd | fs | ft | fr);
8866 TCGv_i64 fp0 = tcg_temp_new_i64();
8867 TCGv_i64 fp1 = tcg_temp_new_i64();
8868 TCGv_i64 fp2 = tcg_temp_new_i64();
8870 gen_load_fpr64(ctx, fp0, fs);
8871 gen_load_fpr64(ctx, fp1, ft);
8872 gen_load_fpr64(ctx, fp2, fr);
8873 gen_helper_float_msub_d(fp2, cpu_env, fp0, fp1, fp2);
8874 tcg_temp_free_i64(fp0);
8875 tcg_temp_free_i64(fp1);
8876 gen_store_fpr64(ctx, fp2, fd);
8877 tcg_temp_free_i64(fp2);
8882 check_cp1_64bitmode(ctx);
8884 TCGv_i64 fp0 = tcg_temp_new_i64();
8885 TCGv_i64 fp1 = tcg_temp_new_i64();
8886 TCGv_i64 fp2 = tcg_temp_new_i64();
8888 gen_load_fpr64(ctx, fp0, fs);
8889 gen_load_fpr64(ctx, fp1, ft);
8890 gen_load_fpr64(ctx, fp2, fr);
8891 gen_helper_float_msub_ps(fp2, cpu_env, fp0, fp1, fp2);
8892 tcg_temp_free_i64(fp0);
8893 tcg_temp_free_i64(fp1);
8894 gen_store_fpr64(ctx, fp2, fd);
8895 tcg_temp_free_i64(fp2);
8902 TCGv_i32 fp0 = tcg_temp_new_i32();
8903 TCGv_i32 fp1 = tcg_temp_new_i32();
8904 TCGv_i32 fp2 = tcg_temp_new_i32();
8906 gen_load_fpr32(fp0, fs);
8907 gen_load_fpr32(fp1, ft);
8908 gen_load_fpr32(fp2, fr);
8909 gen_helper_float_nmadd_s(fp2, cpu_env, fp0, fp1, fp2);
8910 tcg_temp_free_i32(fp0);
8911 tcg_temp_free_i32(fp1);
8912 gen_store_fpr32(fp2, fd);
8913 tcg_temp_free_i32(fp2);
8919 check_cp1_registers(ctx, fd | fs | ft | fr);
8921 TCGv_i64 fp0 = tcg_temp_new_i64();
8922 TCGv_i64 fp1 = tcg_temp_new_i64();
8923 TCGv_i64 fp2 = tcg_temp_new_i64();
8925 gen_load_fpr64(ctx, fp0, fs);
8926 gen_load_fpr64(ctx, fp1, ft);
8927 gen_load_fpr64(ctx, fp2, fr);
8928 gen_helper_float_nmadd_d(fp2, cpu_env, fp0, fp1, fp2);
8929 tcg_temp_free_i64(fp0);
8930 tcg_temp_free_i64(fp1);
8931 gen_store_fpr64(ctx, fp2, fd);
8932 tcg_temp_free_i64(fp2);
8937 check_cp1_64bitmode(ctx);
8939 TCGv_i64 fp0 = tcg_temp_new_i64();
8940 TCGv_i64 fp1 = tcg_temp_new_i64();
8941 TCGv_i64 fp2 = tcg_temp_new_i64();
8943 gen_load_fpr64(ctx, fp0, fs);
8944 gen_load_fpr64(ctx, fp1, ft);
8945 gen_load_fpr64(ctx, fp2, fr);
8946 gen_helper_float_nmadd_ps(fp2, cpu_env, fp0, fp1, fp2);
8947 tcg_temp_free_i64(fp0);
8948 tcg_temp_free_i64(fp1);
8949 gen_store_fpr64(ctx, fp2, fd);
8950 tcg_temp_free_i64(fp2);
8957 TCGv_i32 fp0 = tcg_temp_new_i32();
8958 TCGv_i32 fp1 = tcg_temp_new_i32();
8959 TCGv_i32 fp2 = tcg_temp_new_i32();
8961 gen_load_fpr32(fp0, fs);
8962 gen_load_fpr32(fp1, ft);
8963 gen_load_fpr32(fp2, fr);
8964 gen_helper_float_nmsub_s(fp2, cpu_env, fp0, fp1, fp2);
8965 tcg_temp_free_i32(fp0);
8966 tcg_temp_free_i32(fp1);
8967 gen_store_fpr32(fp2, fd);
8968 tcg_temp_free_i32(fp2);
8974 check_cp1_registers(ctx, fd | fs | ft | fr);
8976 TCGv_i64 fp0 = tcg_temp_new_i64();
8977 TCGv_i64 fp1 = tcg_temp_new_i64();
8978 TCGv_i64 fp2 = tcg_temp_new_i64();
8980 gen_load_fpr64(ctx, fp0, fs);
8981 gen_load_fpr64(ctx, fp1, ft);
8982 gen_load_fpr64(ctx, fp2, fr);
8983 gen_helper_float_nmsub_d(fp2, cpu_env, fp0, fp1, fp2);
8984 tcg_temp_free_i64(fp0);
8985 tcg_temp_free_i64(fp1);
8986 gen_store_fpr64(ctx, fp2, fd);
8987 tcg_temp_free_i64(fp2);
8992 check_cp1_64bitmode(ctx);
8994 TCGv_i64 fp0 = tcg_temp_new_i64();
8995 TCGv_i64 fp1 = tcg_temp_new_i64();
8996 TCGv_i64 fp2 = tcg_temp_new_i64();
8998 gen_load_fpr64(ctx, fp0, fs);
8999 gen_load_fpr64(ctx, fp1, ft);
9000 gen_load_fpr64(ctx, fp2, fr);
9001 gen_helper_float_nmsub_ps(fp2, cpu_env, fp0, fp1, fp2);
9002 tcg_temp_free_i64(fp0);
9003 tcg_temp_free_i64(fp1);
9004 gen_store_fpr64(ctx, fp2, fd);
9005 tcg_temp_free_i64(fp2);
9011 generate_exception (ctx, EXCP_RI);
9014 (void)opn; /* avoid a compiler warning */
9015 MIPS_DEBUG("%s %s, %s, %s, %s", opn, fregnames[fd], fregnames[fr],
9016 fregnames[fs], fregnames[ft]);
9020 gen_rdhwr (CPUMIPSState *env, DisasContext *ctx, int rt, int rd)
9024 #if !defined(CONFIG_USER_ONLY)
9025 /* The Linux kernel will emulate rdhwr if it's not supported natively.
9026 Therefore only check the ISA in system mode. */
9027 check_insn(env, ctx, ISA_MIPS32R2);
9029 t0 = tcg_temp_new();
9033 save_cpu_state(ctx, 1);
9034 gen_helper_rdhwr_cpunum(t0, cpu_env);
9035 gen_store_gpr(t0, rt);
9038 save_cpu_state(ctx, 1);
9039 gen_helper_rdhwr_synci_step(t0, cpu_env);
9040 gen_store_gpr(t0, rt);
9043 save_cpu_state(ctx, 1);
9044 gen_helper_rdhwr_cc(t0, cpu_env);
9045 gen_store_gpr(t0, rt);
9048 save_cpu_state(ctx, 1);
9049 gen_helper_rdhwr_ccres(t0, cpu_env);
9050 gen_store_gpr(t0, rt);
9053 #if defined(CONFIG_USER_ONLY)
9054 tcg_gen_ld_tl(t0, cpu_env, offsetof(CPUMIPSState, tls_value));
9055 gen_store_gpr(t0, rt);
9058 /* XXX: Some CPUs implement this in hardware.
9059 Not supported yet. */
9061 default: /* Invalid */
9062 MIPS_INVAL("rdhwr");
9063 generate_exception(ctx, EXCP_RI);
9069 static void handle_delay_slot (CPUMIPSState *env, DisasContext *ctx,
9072 if (ctx->hflags & MIPS_HFLAG_BMASK) {
9073 int proc_hflags = ctx->hflags & MIPS_HFLAG_BMASK;
9074 /* Branches completion */
9075 ctx->hflags &= ~MIPS_HFLAG_BMASK;
9076 ctx->bstate = BS_BRANCH;
9077 save_cpu_state(ctx, 0);
9078 /* FIXME: Need to clear can_do_io. */
9079 switch (proc_hflags & MIPS_HFLAG_BMASK_BASE) {
9081 /* unconditional branch */
9082 MIPS_DEBUG("unconditional branch");
9083 if (proc_hflags & MIPS_HFLAG_BX) {
9084 tcg_gen_xori_i32(hflags, hflags, MIPS_HFLAG_M16);
9086 gen_goto_tb(ctx, 0, ctx->btarget);
9089 /* blikely taken case */
9090 MIPS_DEBUG("blikely branch taken");
9091 gen_goto_tb(ctx, 0, ctx->btarget);
9094 /* Conditional branch */
9095 MIPS_DEBUG("conditional branch");
9097 int l1 = gen_new_label();
9099 tcg_gen_brcondi_tl(TCG_COND_NE, bcond, 0, l1);
9100 gen_goto_tb(ctx, 1, ctx->pc + insn_bytes);
9102 gen_goto_tb(ctx, 0, ctx->btarget);
9106 /* unconditional branch to register */
9107 MIPS_DEBUG("branch to register");
9108 if (env->insn_flags & (ASE_MIPS16 | ASE_MICROMIPS)) {
9109 TCGv t0 = tcg_temp_new();
9110 TCGv_i32 t1 = tcg_temp_new_i32();
9112 tcg_gen_andi_tl(t0, btarget, 0x1);
9113 tcg_gen_trunc_tl_i32(t1, t0);
9115 tcg_gen_andi_i32(hflags, hflags, ~(uint32_t)MIPS_HFLAG_M16);
9116 tcg_gen_shli_i32(t1, t1, MIPS_HFLAG_M16_SHIFT);
9117 tcg_gen_or_i32(hflags, hflags, t1);
9118 tcg_temp_free_i32(t1);
9120 tcg_gen_andi_tl(cpu_PC, btarget, ~(target_ulong)0x1);
9122 tcg_gen_mov_tl(cpu_PC, btarget);
9124 if (ctx->singlestep_enabled) {
9125 save_cpu_state(ctx, 0);
9126 gen_helper_0e0i(raise_exception, EXCP_DEBUG);
9131 MIPS_DEBUG("unknown branch");
9137 /* ISA extensions (ASEs) */
9138 /* MIPS16 extension to MIPS32 */
9140 /* MIPS16 major opcodes */
9142 M16_OPC_ADDIUSP = 0x00,
9143 M16_OPC_ADDIUPC = 0x01,
9146 M16_OPC_BEQZ = 0x04,
9147 M16_OPC_BNEQZ = 0x05,
9148 M16_OPC_SHIFT = 0x06,
9150 M16_OPC_RRIA = 0x08,
9151 M16_OPC_ADDIU8 = 0x09,
9152 M16_OPC_SLTI = 0x0a,
9153 M16_OPC_SLTIU = 0x0b,
9156 M16_OPC_CMPI = 0x0e,
9160 M16_OPC_LWSP = 0x12,
9164 M16_OPC_LWPC = 0x16,
9168 M16_OPC_SWSP = 0x1a,
9172 M16_OPC_EXTEND = 0x1e,
9176 /* I8 funct field */
9195 /* RR funct field */
9229 /* I64 funct field */
9241 /* RR ry field for CNVT */
9243 RR_RY_CNVT_ZEB = 0x0,
9244 RR_RY_CNVT_ZEH = 0x1,
9245 RR_RY_CNVT_ZEW = 0x2,
9246 RR_RY_CNVT_SEB = 0x4,
9247 RR_RY_CNVT_SEH = 0x5,
9248 RR_RY_CNVT_SEW = 0x6,
9251 static int xlat (int r)
9253 static int map[] = { 16, 17, 2, 3, 4, 5, 6, 7 };
9258 static void gen_mips16_save (DisasContext *ctx,
9259 int xsregs, int aregs,
9260 int do_ra, int do_s0, int do_s1,
9263 TCGv t0 = tcg_temp_new();
9264 TCGv t1 = tcg_temp_new();
9294 generate_exception(ctx, EXCP_RI);
9300 gen_base_offset_addr(ctx, t0, 29, 12);
9301 gen_load_gpr(t1, 7);
9302 tcg_gen_qemu_st32(t1, t0, ctx->mem_idx);
9305 gen_base_offset_addr(ctx, t0, 29, 8);
9306 gen_load_gpr(t1, 6);
9307 tcg_gen_qemu_st32(t1, t0, ctx->mem_idx);
9310 gen_base_offset_addr(ctx, t0, 29, 4);
9311 gen_load_gpr(t1, 5);
9312 tcg_gen_qemu_st32(t1, t0, ctx->mem_idx);
9315 gen_base_offset_addr(ctx, t0, 29, 0);
9316 gen_load_gpr(t1, 4);
9317 tcg_gen_qemu_st32(t1, t0, ctx->mem_idx);
9320 gen_load_gpr(t0, 29);
9322 #define DECR_AND_STORE(reg) do { \
9323 tcg_gen_subi_tl(t0, t0, 4); \
9324 gen_load_gpr(t1, reg); \
9325 tcg_gen_qemu_st32(t1, t0, ctx->mem_idx); \
9389 generate_exception(ctx, EXCP_RI);
9405 #undef DECR_AND_STORE
9407 tcg_gen_subi_tl(cpu_gpr[29], cpu_gpr[29], framesize);
9412 static void gen_mips16_restore (DisasContext *ctx,
9413 int xsregs, int aregs,
9414 int do_ra, int do_s0, int do_s1,
9418 TCGv t0 = tcg_temp_new();
9419 TCGv t1 = tcg_temp_new();
9421 tcg_gen_addi_tl(t0, cpu_gpr[29], framesize);
9423 #define DECR_AND_LOAD(reg) do { \
9424 tcg_gen_subi_tl(t0, t0, 4); \
9425 tcg_gen_qemu_ld32u(t1, t0, ctx->mem_idx); \
9426 gen_store_gpr(t1, reg); \
9490 generate_exception(ctx, EXCP_RI);
9506 #undef DECR_AND_LOAD
9508 tcg_gen_addi_tl(cpu_gpr[29], cpu_gpr[29], framesize);
9513 static void gen_addiupc (DisasContext *ctx, int rx, int imm,
9514 int is_64_bit, int extended)
9518 if (extended && (ctx->hflags & MIPS_HFLAG_BMASK)) {
9519 generate_exception(ctx, EXCP_RI);
9523 t0 = tcg_temp_new();
9525 tcg_gen_movi_tl(t0, pc_relative_pc(ctx));
9526 tcg_gen_addi_tl(cpu_gpr[rx], t0, imm);
9528 tcg_gen_ext32s_tl(cpu_gpr[rx], cpu_gpr[rx]);
9534 #if defined(TARGET_MIPS64)
9535 static void decode_i64_mips16 (CPUMIPSState *env, DisasContext *ctx,
9536 int ry, int funct, int16_t offset,
9542 offset = extended ? offset : offset << 3;
9543 gen_ld(env, ctx, OPC_LD, ry, 29, offset);
9547 offset = extended ? offset : offset << 3;
9548 gen_st(ctx, OPC_SD, ry, 29, offset);
9552 offset = extended ? offset : (ctx->opcode & 0xff) << 3;
9553 gen_st(ctx, OPC_SD, 31, 29, offset);
9557 offset = extended ? offset : ((int8_t)ctx->opcode) << 3;
9558 gen_arith_imm(env, ctx, OPC_DADDIU, 29, 29, offset);
9561 if (extended && (ctx->hflags & MIPS_HFLAG_BMASK)) {
9562 generate_exception(ctx, EXCP_RI);
9564 offset = extended ? offset : offset << 3;
9565 gen_ld(env, ctx, OPC_LDPC, ry, 0, offset);
9570 offset = extended ? offset : ((int8_t)(offset << 3)) >> 3;
9571 gen_arith_imm(env, ctx, OPC_DADDIU, ry, ry, offset);
9575 offset = extended ? offset : offset << 2;
9576 gen_addiupc(ctx, ry, offset, 1, extended);
9580 offset = extended ? offset : offset << 2;
9581 gen_arith_imm(env, ctx, OPC_DADDIU, ry, 29, offset);
9587 static int decode_extended_mips16_opc (CPUMIPSState *env, DisasContext *ctx,
9590 int extend = cpu_lduw_code(env, ctx->pc + 2);
9591 int op, rx, ry, funct, sa;
9592 int16_t imm, offset;
9594 ctx->opcode = (ctx->opcode << 16) | extend;
9595 op = (ctx->opcode >> 11) & 0x1f;
9596 sa = (ctx->opcode >> 22) & 0x1f;
9597 funct = (ctx->opcode >> 8) & 0x7;
9598 rx = xlat((ctx->opcode >> 8) & 0x7);
9599 ry = xlat((ctx->opcode >> 5) & 0x7);
9600 offset = imm = (int16_t) (((ctx->opcode >> 16) & 0x1f) << 11
9601 | ((ctx->opcode >> 21) & 0x3f) << 5
9602 | (ctx->opcode & 0x1f));
9604 /* The extended opcodes cleverly reuse the opcodes from their 16-bit
9607 case M16_OPC_ADDIUSP:
9608 gen_arith_imm(env, ctx, OPC_ADDIU, rx, 29, imm);
9610 case M16_OPC_ADDIUPC:
9611 gen_addiupc(ctx, rx, imm, 0, 1);
9614 gen_compute_branch(ctx, OPC_BEQ, 4, 0, 0, offset << 1);
9615 /* No delay slot, so just process as a normal instruction */
9618 gen_compute_branch(ctx, OPC_BEQ, 4, rx, 0, offset << 1);
9619 /* No delay slot, so just process as a normal instruction */
9622 gen_compute_branch(ctx, OPC_BNE, 4, rx, 0, offset << 1);
9623 /* No delay slot, so just process as a normal instruction */
9626 switch (ctx->opcode & 0x3) {
9628 gen_shift_imm(env, ctx, OPC_SLL, rx, ry, sa);
9631 #if defined(TARGET_MIPS64)
9633 gen_shift_imm(env, ctx, OPC_DSLL, rx, ry, sa);
9635 generate_exception(ctx, EXCP_RI);
9639 gen_shift_imm(env, ctx, OPC_SRL, rx, ry, sa);
9642 gen_shift_imm(env, ctx, OPC_SRA, rx, ry, sa);
9646 #if defined(TARGET_MIPS64)
9649 gen_ld(env, ctx, OPC_LD, ry, rx, offset);
9653 imm = ctx->opcode & 0xf;
9654 imm = imm | ((ctx->opcode >> 20) & 0x7f) << 4;
9655 imm = imm | ((ctx->opcode >> 16) & 0xf) << 11;
9656 imm = (int16_t) (imm << 1) >> 1;
9657 if ((ctx->opcode >> 4) & 0x1) {
9658 #if defined(TARGET_MIPS64)
9660 gen_arith_imm(env, ctx, OPC_DADDIU, ry, rx, imm);
9662 generate_exception(ctx, EXCP_RI);
9665 gen_arith_imm(env, ctx, OPC_ADDIU, ry, rx, imm);
9668 case M16_OPC_ADDIU8:
9669 gen_arith_imm(env, ctx, OPC_ADDIU, rx, rx, imm);
9672 gen_slt_imm(env, ctx, OPC_SLTI, 24, rx, imm);
9675 gen_slt_imm(env, ctx, OPC_SLTIU, 24, rx, imm);
9680 gen_compute_branch(ctx, OPC_BEQ, 4, 24, 0, offset << 1);
9683 gen_compute_branch(ctx, OPC_BNE, 4, 24, 0, offset << 1);
9686 gen_st(ctx, OPC_SW, 31, 29, imm);
9689 gen_arith_imm(env, ctx, OPC_ADDIU, 29, 29, imm);
9693 int xsregs = (ctx->opcode >> 24) & 0x7;
9694 int aregs = (ctx->opcode >> 16) & 0xf;
9695 int do_ra = (ctx->opcode >> 6) & 0x1;
9696 int do_s0 = (ctx->opcode >> 5) & 0x1;
9697 int do_s1 = (ctx->opcode >> 4) & 0x1;
9698 int framesize = (((ctx->opcode >> 20) & 0xf) << 4
9699 | (ctx->opcode & 0xf)) << 3;
9701 if (ctx->opcode & (1 << 7)) {
9702 gen_mips16_save(ctx, xsregs, aregs,
9703 do_ra, do_s0, do_s1,
9706 gen_mips16_restore(ctx, xsregs, aregs,
9707 do_ra, do_s0, do_s1,
9713 generate_exception(ctx, EXCP_RI);
9718 tcg_gen_movi_tl(cpu_gpr[rx], (uint16_t) imm);
9721 tcg_gen_xori_tl(cpu_gpr[24], cpu_gpr[rx], (uint16_t) imm);
9723 #if defined(TARGET_MIPS64)
9725 gen_st(ctx, OPC_SD, ry, rx, offset);
9729 gen_ld(env, ctx, OPC_LB, ry, rx, offset);
9732 gen_ld(env, ctx, OPC_LH, ry, rx, offset);
9735 gen_ld(env, ctx, OPC_LW, rx, 29, offset);
9738 gen_ld(env, ctx, OPC_LW, ry, rx, offset);
9741 gen_ld(env, ctx, OPC_LBU, ry, rx, offset);
9744 gen_ld(env, ctx, OPC_LHU, ry, rx, offset);
9747 gen_ld(env, ctx, OPC_LWPC, rx, 0, offset);
9749 #if defined(TARGET_MIPS64)
9751 gen_ld(env, ctx, OPC_LWU, ry, rx, offset);
9755 gen_st(ctx, OPC_SB, ry, rx, offset);
9758 gen_st(ctx, OPC_SH, ry, rx, offset);
9761 gen_st(ctx, OPC_SW, rx, 29, offset);
9764 gen_st(ctx, OPC_SW, ry, rx, offset);
9766 #if defined(TARGET_MIPS64)
9768 decode_i64_mips16(env, ctx, ry, funct, offset, 1);
9772 generate_exception(ctx, EXCP_RI);
9779 static int decode_mips16_opc (CPUMIPSState *env, DisasContext *ctx,
9784 int op, cnvt_op, op1, offset;
9788 op = (ctx->opcode >> 11) & 0x1f;
9789 sa = (ctx->opcode >> 2) & 0x7;
9790 sa = sa == 0 ? 8 : sa;
9791 rx = xlat((ctx->opcode >> 8) & 0x7);
9792 cnvt_op = (ctx->opcode >> 5) & 0x7;
9793 ry = xlat((ctx->opcode >> 5) & 0x7);
9794 op1 = offset = ctx->opcode & 0x1f;
9799 case M16_OPC_ADDIUSP:
9801 int16_t imm = ((uint8_t) ctx->opcode) << 2;
9803 gen_arith_imm(env, ctx, OPC_ADDIU, rx, 29, imm);
9806 case M16_OPC_ADDIUPC:
9807 gen_addiupc(ctx, rx, ((uint8_t) ctx->opcode) << 2, 0, 0);
9810 offset = (ctx->opcode & 0x7ff) << 1;
9811 offset = (int16_t)(offset << 4) >> 4;
9812 gen_compute_branch(ctx, OPC_BEQ, 2, 0, 0, offset);
9813 /* No delay slot, so just process as a normal instruction */
9816 offset = cpu_lduw_code(env, ctx->pc + 2);
9817 offset = (((ctx->opcode & 0x1f) << 21)
9818 | ((ctx->opcode >> 5) & 0x1f) << 16
9820 op = ((ctx->opcode >> 10) & 0x1) ? OPC_JALXS : OPC_JALS;
9821 gen_compute_branch(ctx, op, 4, rx, ry, offset);
9826 gen_compute_branch(ctx, OPC_BEQ, 2, rx, 0, ((int8_t)ctx->opcode) << 1);
9827 /* No delay slot, so just process as a normal instruction */
9830 gen_compute_branch(ctx, OPC_BNE, 2, rx, 0, ((int8_t)ctx->opcode) << 1);
9831 /* No delay slot, so just process as a normal instruction */
9834 switch (ctx->opcode & 0x3) {
9836 gen_shift_imm(env, ctx, OPC_SLL, rx, ry, sa);
9839 #if defined(TARGET_MIPS64)
9841 gen_shift_imm(env, ctx, OPC_DSLL, rx, ry, sa);
9843 generate_exception(ctx, EXCP_RI);
9847 gen_shift_imm(env, ctx, OPC_SRL, rx, ry, sa);
9850 gen_shift_imm(env, ctx, OPC_SRA, rx, ry, sa);
9854 #if defined(TARGET_MIPS64)
9857 gen_ld(env, ctx, OPC_LD, ry, rx, offset << 3);
9862 int16_t imm = (int8_t)((ctx->opcode & 0xf) << 4) >> 4;
9864 if ((ctx->opcode >> 4) & 1) {
9865 #if defined(TARGET_MIPS64)
9867 gen_arith_imm(env, ctx, OPC_DADDIU, ry, rx, imm);
9869 generate_exception(ctx, EXCP_RI);
9872 gen_arith_imm(env, ctx, OPC_ADDIU, ry, rx, imm);
9876 case M16_OPC_ADDIU8:
9878 int16_t imm = (int8_t) ctx->opcode;
9880 gen_arith_imm(env, ctx, OPC_ADDIU, rx, rx, imm);
9885 int16_t imm = (uint8_t) ctx->opcode;
9886 gen_slt_imm(env, ctx, OPC_SLTI, 24, rx, imm);
9891 int16_t imm = (uint8_t) ctx->opcode;
9892 gen_slt_imm(env, ctx, OPC_SLTIU, 24, rx, imm);
9899 funct = (ctx->opcode >> 8) & 0x7;
9902 gen_compute_branch(ctx, OPC_BEQ, 2, 24, 0,
9903 ((int8_t)ctx->opcode) << 1);
9906 gen_compute_branch(ctx, OPC_BNE, 2, 24, 0,
9907 ((int8_t)ctx->opcode) << 1);
9910 gen_st(ctx, OPC_SW, 31, 29, (ctx->opcode & 0xff) << 2);
9913 gen_arith_imm(env, ctx, OPC_ADDIU, 29, 29,
9914 ((int8_t)ctx->opcode) << 3);
9918 int do_ra = ctx->opcode & (1 << 6);
9919 int do_s0 = ctx->opcode & (1 << 5);
9920 int do_s1 = ctx->opcode & (1 << 4);
9921 int framesize = ctx->opcode & 0xf;
9923 if (framesize == 0) {
9926 framesize = framesize << 3;
9929 if (ctx->opcode & (1 << 7)) {
9930 gen_mips16_save(ctx, 0, 0,
9931 do_ra, do_s0, do_s1, framesize);
9933 gen_mips16_restore(ctx, 0, 0,
9934 do_ra, do_s0, do_s1, framesize);
9940 int rz = xlat(ctx->opcode & 0x7);
9942 reg32 = (((ctx->opcode >> 3) & 0x3) << 3) |
9943 ((ctx->opcode >> 5) & 0x7);
9944 gen_arith(env, ctx, OPC_ADDU, reg32, rz, 0);
9948 reg32 = ctx->opcode & 0x1f;
9949 gen_arith(env, ctx, OPC_ADDU, ry, reg32, 0);
9952 generate_exception(ctx, EXCP_RI);
9959 int16_t imm = (uint8_t) ctx->opcode;
9961 gen_arith_imm(env, ctx, OPC_ADDIU, rx, 0, imm);
9966 int16_t imm = (uint8_t) ctx->opcode;
9967 gen_logic_imm(env, ctx, OPC_XORI, 24, rx, imm);
9970 #if defined(TARGET_MIPS64)
9973 gen_st(ctx, OPC_SD, ry, rx, offset << 3);
9977 gen_ld(env, ctx, OPC_LB, ry, rx, offset);
9980 gen_ld(env, ctx, OPC_LH, ry, rx, offset << 1);
9983 gen_ld(env, ctx, OPC_LW, rx, 29, ((uint8_t)ctx->opcode) << 2);
9986 gen_ld(env, ctx, OPC_LW, ry, rx, offset << 2);
9989 gen_ld(env, ctx, OPC_LBU, ry, rx, offset);
9992 gen_ld(env, ctx, OPC_LHU, ry, rx, offset << 1);
9995 gen_ld(env, ctx, OPC_LWPC, rx, 0, ((uint8_t)ctx->opcode) << 2);
9997 #if defined (TARGET_MIPS64)
10000 gen_ld(env, ctx, OPC_LWU, ry, rx, offset << 2);
10004 gen_st(ctx, OPC_SB, ry, rx, offset);
10007 gen_st(ctx, OPC_SH, ry, rx, offset << 1);
10010 gen_st(ctx, OPC_SW, rx, 29, ((uint8_t)ctx->opcode) << 2);
10013 gen_st(ctx, OPC_SW, ry, rx, offset << 2);
10017 int rz = xlat((ctx->opcode >> 2) & 0x7);
10020 switch (ctx->opcode & 0x3) {
10022 mips32_op = OPC_ADDU;
10025 mips32_op = OPC_SUBU;
10027 #if defined(TARGET_MIPS64)
10029 mips32_op = OPC_DADDU;
10030 check_mips_64(ctx);
10033 mips32_op = OPC_DSUBU;
10034 check_mips_64(ctx);
10038 generate_exception(ctx, EXCP_RI);
10042 gen_arith(env, ctx, mips32_op, rz, rx, ry);
10051 int nd = (ctx->opcode >> 7) & 0x1;
10052 int link = (ctx->opcode >> 6) & 0x1;
10053 int ra = (ctx->opcode >> 5) & 0x1;
10056 op = nd ? OPC_JALRC : OPC_JALRS;
10061 gen_compute_branch(ctx, op, 2, ra ? 31 : rx, 31, 0);
10068 /* XXX: not clear which exception should be raised
10069 * when in debug mode...
10071 check_insn(env, ctx, ISA_MIPS32);
10072 if (!(ctx->hflags & MIPS_HFLAG_DM)) {
10073 generate_exception(ctx, EXCP_DBp);
10075 generate_exception(ctx, EXCP_DBp);
10079 gen_slt(env, ctx, OPC_SLT, 24, rx, ry);
10082 gen_slt(env, ctx, OPC_SLTU, 24, rx, ry);
10085 generate_exception(ctx, EXCP_BREAK);
10088 gen_shift(env, ctx, OPC_SLLV, ry, rx, ry);
10091 gen_shift(env, ctx, OPC_SRLV, ry, rx, ry);
10094 gen_shift(env, ctx, OPC_SRAV, ry, rx, ry);
10096 #if defined (TARGET_MIPS64)
10098 check_mips_64(ctx);
10099 gen_shift_imm(env, ctx, OPC_DSRL, ry, ry, sa);
10103 gen_logic(env, ctx, OPC_XOR, 24, rx, ry);
10106 gen_arith(env, ctx, OPC_SUBU, rx, 0, ry);
10109 gen_logic(env, ctx, OPC_AND, rx, rx, ry);
10112 gen_logic(env, ctx, OPC_OR, rx, rx, ry);
10115 gen_logic(env, ctx, OPC_XOR, rx, rx, ry);
10118 gen_logic(env, ctx, OPC_NOR, rx, ry, 0);
10121 gen_HILO(ctx, OPC_MFHI, rx);
10125 case RR_RY_CNVT_ZEB:
10126 tcg_gen_ext8u_tl(cpu_gpr[rx], cpu_gpr[rx]);
10128 case RR_RY_CNVT_ZEH:
10129 tcg_gen_ext16u_tl(cpu_gpr[rx], cpu_gpr[rx]);
10131 case RR_RY_CNVT_SEB:
10132 tcg_gen_ext8s_tl(cpu_gpr[rx], cpu_gpr[rx]);
10134 case RR_RY_CNVT_SEH:
10135 tcg_gen_ext16s_tl(cpu_gpr[rx], cpu_gpr[rx]);
10137 #if defined (TARGET_MIPS64)
10138 case RR_RY_CNVT_ZEW:
10139 check_mips_64(ctx);
10140 tcg_gen_ext32u_tl(cpu_gpr[rx], cpu_gpr[rx]);
10142 case RR_RY_CNVT_SEW:
10143 check_mips_64(ctx);
10144 tcg_gen_ext32s_tl(cpu_gpr[rx], cpu_gpr[rx]);
10148 generate_exception(ctx, EXCP_RI);
10153 gen_HILO(ctx, OPC_MFLO, rx);
10155 #if defined (TARGET_MIPS64)
10157 check_mips_64(ctx);
10158 gen_shift_imm(env, ctx, OPC_DSRA, ry, ry, sa);
10161 check_mips_64(ctx);
10162 gen_shift(env, ctx, OPC_DSLLV, ry, rx, ry);
10165 check_mips_64(ctx);
10166 gen_shift(env, ctx, OPC_DSRLV, ry, rx, ry);
10169 check_mips_64(ctx);
10170 gen_shift(env, ctx, OPC_DSRAV, ry, rx, ry);
10174 gen_muldiv(ctx, OPC_MULT, rx, ry);
10177 gen_muldiv(ctx, OPC_MULTU, rx, ry);
10180 gen_muldiv(ctx, OPC_DIV, rx, ry);
10183 gen_muldiv(ctx, OPC_DIVU, rx, ry);
10185 #if defined (TARGET_MIPS64)
10187 check_mips_64(ctx);
10188 gen_muldiv(ctx, OPC_DMULT, rx, ry);
10191 check_mips_64(ctx);
10192 gen_muldiv(ctx, OPC_DMULTU, rx, ry);
10195 check_mips_64(ctx);
10196 gen_muldiv(ctx, OPC_DDIV, rx, ry);
10199 check_mips_64(ctx);
10200 gen_muldiv(ctx, OPC_DDIVU, rx, ry);
10204 generate_exception(ctx, EXCP_RI);
10208 case M16_OPC_EXTEND:
10209 decode_extended_mips16_opc(env, ctx, is_branch);
10212 #if defined(TARGET_MIPS64)
10214 funct = (ctx->opcode >> 8) & 0x7;
10215 decode_i64_mips16(env, ctx, ry, funct, offset, 0);
10219 generate_exception(ctx, EXCP_RI);
10226 /* microMIPS extension to MIPS32 */
10228 /* microMIPS32 major opcodes */
10267 /* 0x20 is reserved */
10277 /* 0x28 and 0x29 are reserved */
10287 /* 0x30 and 0x31 are reserved */
10297 /* 0x38 and 0x39 are reserved */
10308 /* POOL32A encoding of minor opcode field */
10311 /* These opcodes are distinguished only by bits 9..6; those bits are
10312 * what are recorded below. */
10338 /* The following can be distinguished by their lower 6 bits. */
10344 /* POOL32AXF encoding of minor opcode field extension */
10358 /* bits 13..12 for 0x01 */
10364 /* bits 13..12 for 0x2a */
10370 /* bits 13..12 for 0x32 */
10374 /* bits 15..12 for 0x2c */
10390 /* bits 15..12 for 0x34 */
10398 /* bits 15..12 for 0x3c */
10400 JR = 0x0, /* alias */
10405 /* bits 15..12 for 0x05 */
10409 /* bits 15..12 for 0x0d */
10419 /* bits 15..12 for 0x15 */
10425 /* bits 15..12 for 0x1d */
10429 /* bits 15..12 for 0x2d */
10434 /* bits 15..12 for 0x35 */
10441 /* POOL32B encoding of minor opcode field (bits 15..12) */
10457 /* POOL32C encoding of minor opcode field (bits 15..12) */
10465 /* 0xa is reserved */
10472 /* 0x6 is reserved */
10478 /* POOL32F encoding of minor opcode field (bits 5..0) */
10481 /* These are the bit 7..6 values */
10492 /* These are the bit 8..6 values */
10536 CABS_COND_FMT = 0x1c, /* MIPS3D */
10540 /* POOL32Fxf encoding of minor opcode extension field */
10578 /* POOL32I encoding of minor opcode field (bits 25..21) */
10603 /* These overlap and are distinguished by bit16 of the instruction */
10612 /* POOL16A encoding of minor opcode field */
10619 /* POOL16B encoding of minor opcode field */
10626 /* POOL16C encoding of minor opcode field */
10646 /* POOL16D encoding of minor opcode field */
10653 /* POOL16E encoding of minor opcode field */
10660 static int mmreg (int r)
10662 static const int map[] = { 16, 17, 2, 3, 4, 5, 6, 7 };
10667 /* Used for 16-bit store instructions. */
10668 static int mmreg2 (int r)
10670 static const int map[] = { 0, 17, 2, 3, 4, 5, 6, 7 };
10675 #define uMIPS_RD(op) ((op >> 7) & 0x7)
10676 #define uMIPS_RS(op) ((op >> 4) & 0x7)
10677 #define uMIPS_RS2(op) uMIPS_RS(op)
10678 #define uMIPS_RS1(op) ((op >> 1) & 0x7)
10679 #define uMIPS_RD5(op) ((op >> 5) & 0x1f)
10680 #define uMIPS_RS5(op) (op & 0x1f)
10682 /* Signed immediate */
10683 #define SIMM(op, start, width) \
10684 ((int32_t)(((op >> start) & ((~0U) >> (32-width))) \
10687 /* Zero-extended immediate */
10688 #define ZIMM(op, start, width) ((op >> start) & ((~0U) >> (32-width)))
10690 static void gen_addiur1sp (CPUMIPSState *env, DisasContext *ctx)
10692 int rd = mmreg(uMIPS_RD(ctx->opcode));
10694 gen_arith_imm(env, ctx, OPC_ADDIU, rd, 29, ((ctx->opcode >> 1) & 0x3f) << 2);
10697 static void gen_addiur2 (CPUMIPSState *env, DisasContext *ctx)
10699 static const int decoded_imm[] = { 1, 4, 8, 12, 16, 20, 24, -1 };
10700 int rd = mmreg(uMIPS_RD(ctx->opcode));
10701 int rs = mmreg(uMIPS_RS(ctx->opcode));
10703 gen_arith_imm(env, ctx, OPC_ADDIU, rd, rs, decoded_imm[ZIMM(ctx->opcode, 1, 3)]);
10706 static void gen_addiusp (CPUMIPSState *env, DisasContext *ctx)
10708 int encoded = ZIMM(ctx->opcode, 1, 9);
10711 if (encoded <= 1) {
10712 decoded = 256 + encoded;
10713 } else if (encoded <= 255) {
10715 } else if (encoded <= 509) {
10716 decoded = encoded - 512;
10718 decoded = encoded - 768;
10721 gen_arith_imm(env, ctx, OPC_ADDIU, 29, 29, decoded << 2);
10724 static void gen_addius5 (CPUMIPSState *env, DisasContext *ctx)
10726 int imm = SIMM(ctx->opcode, 1, 4);
10727 int rd = (ctx->opcode >> 5) & 0x1f;
10729 gen_arith_imm(env, ctx, OPC_ADDIU, rd, rd, imm);
10732 static void gen_andi16 (CPUMIPSState *env, DisasContext *ctx)
10734 static const int decoded_imm[] = { 128, 1, 2, 3, 4, 7, 8, 15, 16,
10735 31, 32, 63, 64, 255, 32768, 65535 };
10736 int rd = mmreg(uMIPS_RD(ctx->opcode));
10737 int rs = mmreg(uMIPS_RS(ctx->opcode));
10738 int encoded = ZIMM(ctx->opcode, 0, 4);
10740 gen_logic_imm(env, ctx, OPC_ANDI, rd, rs, decoded_imm[encoded]);
10743 static void gen_ldst_multiple (DisasContext *ctx, uint32_t opc, int reglist,
10744 int base, int16_t offset)
10746 const char *opn = "ldst_multiple";
10750 if (ctx->hflags & MIPS_HFLAG_BMASK) {
10751 generate_exception(ctx, EXCP_RI);
10755 t0 = tcg_temp_new();
10757 gen_base_offset_addr(ctx, t0, base, offset);
10759 t1 = tcg_const_tl(reglist);
10760 t2 = tcg_const_i32(ctx->mem_idx);
10762 save_cpu_state(ctx, 1);
10765 gen_helper_lwm(cpu_env, t0, t1, t2);
10769 gen_helper_swm(cpu_env, t0, t1, t2);
10772 #ifdef TARGET_MIPS64
10774 gen_helper_ldm(cpu_env, t0, t1, t2);
10778 gen_helper_sdm(cpu_env, t0, t1, t2);
10784 MIPS_DEBUG("%s, %x, %d(%s)", opn, reglist, offset, regnames[base]);
10787 tcg_temp_free_i32(t2);
10791 static void gen_pool16c_insn (CPUMIPSState *env, DisasContext *ctx, int *is_branch)
10793 int rd = mmreg((ctx->opcode >> 3) & 0x7);
10794 int rs = mmreg(ctx->opcode & 0x7);
10797 switch (((ctx->opcode) >> 4) & 0x3f) {
10802 gen_logic(env, ctx, OPC_NOR, rd, rs, 0);
10808 gen_logic(env, ctx, OPC_XOR, rd, rd, rs);
10814 gen_logic(env, ctx, OPC_AND, rd, rd, rs);
10820 gen_logic(env, ctx, OPC_OR, rd, rd, rs);
10827 static const int lwm_convert[] = { 0x11, 0x12, 0x13, 0x14 };
10828 int offset = ZIMM(ctx->opcode, 0, 4);
10830 gen_ldst_multiple(ctx, LWM32, lwm_convert[(ctx->opcode >> 4) & 0x3],
10839 static const int swm_convert[] = { 0x11, 0x12, 0x13, 0x14 };
10840 int offset = ZIMM(ctx->opcode, 0, 4);
10842 gen_ldst_multiple(ctx, SWM32, swm_convert[(ctx->opcode >> 4) & 0x3],
10849 int reg = ctx->opcode & 0x1f;
10851 gen_compute_branch(ctx, OPC_JR, 2, reg, 0, 0);
10858 int reg = ctx->opcode & 0x1f;
10860 gen_compute_branch(ctx, OPC_JR, 2, reg, 0, 0);
10861 /* Let normal delay slot handling in our caller take us
10862 to the branch target. */
10874 int reg = ctx->opcode & 0x1f;
10876 gen_compute_branch(ctx, opc, 2, reg, 31, 0);
10882 gen_HILO(ctx, OPC_MFHI, uMIPS_RS5(ctx->opcode));
10886 gen_HILO(ctx, OPC_MFLO, uMIPS_RS5(ctx->opcode));
10889 generate_exception(ctx, EXCP_BREAK);
10892 /* XXX: not clear which exception should be raised
10893 * when in debug mode...
10895 check_insn(env, ctx, ISA_MIPS32);
10896 if (!(ctx->hflags & MIPS_HFLAG_DM)) {
10897 generate_exception(ctx, EXCP_DBp);
10899 generate_exception(ctx, EXCP_DBp);
10902 case JRADDIUSP + 0:
10903 case JRADDIUSP + 1:
10905 int imm = ZIMM(ctx->opcode, 0, 5);
10907 gen_compute_branch(ctx, OPC_JR, 2, 31, 0, 0);
10908 gen_arith_imm(env, ctx, OPC_ADDIU, 29, 29, imm << 2);
10909 /* Let normal delay slot handling in our caller take us
10910 to the branch target. */
10914 generate_exception(ctx, EXCP_RI);
10919 static void gen_ldxs (DisasContext *ctx, int base, int index, int rd)
10921 TCGv t0 = tcg_temp_new();
10922 TCGv t1 = tcg_temp_new();
10924 gen_load_gpr(t0, base);
10927 gen_load_gpr(t1, index);
10928 tcg_gen_shli_tl(t1, t1, 2);
10929 gen_op_addr_add(ctx, t0, t1, t0);
10932 tcg_gen_qemu_ld32s(t1, t0, ctx->mem_idx);
10933 gen_store_gpr(t1, rd);
10939 static void gen_ldst_pair (DisasContext *ctx, uint32_t opc, int rd,
10940 int base, int16_t offset)
10942 const char *opn = "ldst_pair";
10945 if (ctx->hflags & MIPS_HFLAG_BMASK || rd == 31) {
10946 generate_exception(ctx, EXCP_RI);
10950 t0 = tcg_temp_new();
10951 t1 = tcg_temp_new();
10953 gen_base_offset_addr(ctx, t0, base, offset);
10958 generate_exception(ctx, EXCP_RI);
10961 tcg_gen_qemu_ld32s(t1, t0, ctx->mem_idx);
10962 gen_store_gpr(t1, rd);
10963 tcg_gen_movi_tl(t1, 4);
10964 gen_op_addr_add(ctx, t0, t0, t1);
10965 tcg_gen_qemu_ld32s(t1, t0, ctx->mem_idx);
10966 gen_store_gpr(t1, rd+1);
10970 gen_load_gpr(t1, rd);
10971 tcg_gen_qemu_st32(t1, t0, ctx->mem_idx);
10972 tcg_gen_movi_tl(t1, 4);
10973 gen_op_addr_add(ctx, t0, t0, t1);
10974 gen_load_gpr(t1, rd+1);
10975 tcg_gen_qemu_st32(t1, t0, ctx->mem_idx);
10978 #ifdef TARGET_MIPS64
10981 generate_exception(ctx, EXCP_RI);
10984 tcg_gen_qemu_ld64(t1, t0, ctx->mem_idx);
10985 gen_store_gpr(t1, rd);
10986 tcg_gen_movi_tl(t1, 8);
10987 gen_op_addr_add(ctx, t0, t0, t1);
10988 tcg_gen_qemu_ld64(t1, t0, ctx->mem_idx);
10989 gen_store_gpr(t1, rd+1);
10993 gen_load_gpr(t1, rd);
10994 tcg_gen_qemu_st64(t1, t0, ctx->mem_idx);
10995 tcg_gen_movi_tl(t1, 8);
10996 gen_op_addr_add(ctx, t0, t0, t1);
10997 gen_load_gpr(t1, rd+1);
10998 tcg_gen_qemu_st64(t1, t0, ctx->mem_idx);
11003 (void)opn; /* avoid a compiler warning */
11004 MIPS_DEBUG("%s, %s, %d(%s)", opn, regnames[rd], offset, regnames[base]);
11009 static void gen_pool32axf (CPUMIPSState *env, DisasContext *ctx, int rt, int rs,
11012 int extension = (ctx->opcode >> 6) & 0x3f;
11013 int minor = (ctx->opcode >> 12) & 0xf;
11014 uint32_t mips32_op;
11016 switch (extension) {
11018 mips32_op = OPC_TEQ;
11021 mips32_op = OPC_TGE;
11024 mips32_op = OPC_TGEU;
11027 mips32_op = OPC_TLT;
11030 mips32_op = OPC_TLTU;
11033 mips32_op = OPC_TNE;
11035 gen_trap(ctx, mips32_op, rs, rt, -1);
11037 #ifndef CONFIG_USER_ONLY
11040 check_cp0_enabled(ctx);
11042 /* Treat as NOP. */
11045 gen_mfc0(env, ctx, cpu_gpr[rt], rs, (ctx->opcode >> 11) & 0x7);
11049 check_cp0_enabled(ctx);
11051 TCGv t0 = tcg_temp_new();
11053 gen_load_gpr(t0, rt);
11054 gen_mtc0(env, ctx, t0, rs, (ctx->opcode >> 11) & 0x7);
11062 gen_bshfl(ctx, OPC_SEB, rs, rt);
11065 gen_bshfl(ctx, OPC_SEH, rs, rt);
11068 mips32_op = OPC_CLO;
11071 mips32_op = OPC_CLZ;
11073 check_insn(env, ctx, ISA_MIPS32);
11074 gen_cl(ctx, mips32_op, rt, rs);
11077 gen_rdhwr(env, ctx, rt, rs);
11080 gen_bshfl(ctx, OPC_WSBH, rs, rt);
11083 mips32_op = OPC_MULT;
11086 mips32_op = OPC_MULTU;
11089 mips32_op = OPC_DIV;
11092 mips32_op = OPC_DIVU;
11095 mips32_op = OPC_MADD;
11098 mips32_op = OPC_MADDU;
11101 mips32_op = OPC_MSUB;
11104 mips32_op = OPC_MSUBU;
11106 check_insn(env, ctx, ISA_MIPS32);
11107 gen_muldiv(ctx, mips32_op, rs, rt);
11110 goto pool32axf_invalid;
11121 generate_exception_err(ctx, EXCP_CpU, 2);
11124 goto pool32axf_invalid;
11131 gen_compute_branch (ctx, OPC_JALR, 4, rs, rt, 0);
11136 gen_compute_branch (ctx, OPC_JALRS, 4, rs, rt, 0);
11140 goto pool32axf_invalid;
11146 check_cp0_enabled(ctx);
11147 check_insn(env, ctx, ISA_MIPS32R2);
11148 gen_load_srsgpr(rt, rs);
11151 check_cp0_enabled(ctx);
11152 check_insn(env, ctx, ISA_MIPS32R2);
11153 gen_store_srsgpr(rt, rs);
11156 goto pool32axf_invalid;
11159 #ifndef CONFIG_USER_ONLY
11163 mips32_op = OPC_TLBP;
11166 mips32_op = OPC_TLBR;
11169 mips32_op = OPC_TLBWI;
11172 mips32_op = OPC_TLBWR;
11175 mips32_op = OPC_WAIT;
11178 mips32_op = OPC_DERET;
11181 mips32_op = OPC_ERET;
11183 gen_cp0(env, ctx, mips32_op, rt, rs);
11186 goto pool32axf_invalid;
11192 check_cp0_enabled(ctx);
11194 TCGv t0 = tcg_temp_new();
11196 save_cpu_state(ctx, 1);
11197 gen_helper_di(t0, cpu_env);
11198 gen_store_gpr(t0, rs);
11199 /* Stop translation as we may have switched the execution mode */
11200 ctx->bstate = BS_STOP;
11205 check_cp0_enabled(ctx);
11207 TCGv t0 = tcg_temp_new();
11209 save_cpu_state(ctx, 1);
11210 gen_helper_ei(t0, cpu_env);
11211 gen_store_gpr(t0, rs);
11212 /* Stop translation as we may have switched the execution mode */
11213 ctx->bstate = BS_STOP;
11218 goto pool32axf_invalid;
11228 generate_exception(ctx, EXCP_SYSCALL);
11229 ctx->bstate = BS_STOP;
11232 check_insn(env, ctx, ISA_MIPS32);
11233 if (!(ctx->hflags & MIPS_HFLAG_DM)) {
11234 generate_exception(ctx, EXCP_DBp);
11236 generate_exception(ctx, EXCP_DBp);
11240 goto pool32axf_invalid;
11246 gen_HILO(ctx, OPC_MFHI, rs);
11249 gen_HILO(ctx, OPC_MFLO, rs);
11252 gen_HILO(ctx, OPC_MTHI, rs);
11255 gen_HILO(ctx, OPC_MTLO, rs);
11258 goto pool32axf_invalid;
11263 MIPS_INVAL("pool32axf");
11264 generate_exception(ctx, EXCP_RI);
11269 /* Values for microMIPS fmt field. Variable-width, depending on which
11270 formats the instruction supports. */
11289 static void gen_pool32fxf (CPUMIPSState *env, DisasContext *ctx, int rt, int rs)
11291 int extension = (ctx->opcode >> 6) & 0x3ff;
11292 uint32_t mips32_op;
11294 #define FLOAT_1BIT_FMT(opc, fmt) (fmt << 8) | opc
11295 #define FLOAT_2BIT_FMT(opc, fmt) (fmt << 7) | opc
11296 #define COND_FLOAT_MOV(opc, cond) (cond << 7) | opc
11298 switch (extension) {
11299 case FLOAT_1BIT_FMT(CFC1, 0):
11300 mips32_op = OPC_CFC1;
11302 case FLOAT_1BIT_FMT(CTC1, 0):
11303 mips32_op = OPC_CTC1;
11305 case FLOAT_1BIT_FMT(MFC1, 0):
11306 mips32_op = OPC_MFC1;
11308 case FLOAT_1BIT_FMT(MTC1, 0):
11309 mips32_op = OPC_MTC1;
11311 case FLOAT_1BIT_FMT(MFHC1, 0):
11312 mips32_op = OPC_MFHC1;
11314 case FLOAT_1BIT_FMT(MTHC1, 0):
11315 mips32_op = OPC_MTHC1;
11317 gen_cp1(ctx, mips32_op, rt, rs);
11320 /* Reciprocal square root */
11321 case FLOAT_1BIT_FMT(RSQRT_FMT, FMT_SD_S):
11322 mips32_op = OPC_RSQRT_S;
11324 case FLOAT_1BIT_FMT(RSQRT_FMT, FMT_SD_D):
11325 mips32_op = OPC_RSQRT_D;
11329 case FLOAT_1BIT_FMT(SQRT_FMT, FMT_SD_S):
11330 mips32_op = OPC_SQRT_S;
11332 case FLOAT_1BIT_FMT(SQRT_FMT, FMT_SD_D):
11333 mips32_op = OPC_SQRT_D;
11337 case FLOAT_1BIT_FMT(RECIP_FMT, FMT_SD_S):
11338 mips32_op = OPC_RECIP_S;
11340 case FLOAT_1BIT_FMT(RECIP_FMT, FMT_SD_D):
11341 mips32_op = OPC_RECIP_D;
11345 case FLOAT_1BIT_FMT(FLOOR_L, FMT_SD_S):
11346 mips32_op = OPC_FLOOR_L_S;
11348 case FLOAT_1BIT_FMT(FLOOR_L, FMT_SD_D):
11349 mips32_op = OPC_FLOOR_L_D;
11351 case FLOAT_1BIT_FMT(FLOOR_W, FMT_SD_S):
11352 mips32_op = OPC_FLOOR_W_S;
11354 case FLOAT_1BIT_FMT(FLOOR_W, FMT_SD_D):
11355 mips32_op = OPC_FLOOR_W_D;
11359 case FLOAT_1BIT_FMT(CEIL_L, FMT_SD_S):
11360 mips32_op = OPC_CEIL_L_S;
11362 case FLOAT_1BIT_FMT(CEIL_L, FMT_SD_D):
11363 mips32_op = OPC_CEIL_L_D;
11365 case FLOAT_1BIT_FMT(CEIL_W, FMT_SD_S):
11366 mips32_op = OPC_CEIL_W_S;
11368 case FLOAT_1BIT_FMT(CEIL_W, FMT_SD_D):
11369 mips32_op = OPC_CEIL_W_D;
11373 case FLOAT_1BIT_FMT(TRUNC_L, FMT_SD_S):
11374 mips32_op = OPC_TRUNC_L_S;
11376 case FLOAT_1BIT_FMT(TRUNC_L, FMT_SD_D):
11377 mips32_op = OPC_TRUNC_L_D;
11379 case FLOAT_1BIT_FMT(TRUNC_W, FMT_SD_S):
11380 mips32_op = OPC_TRUNC_W_S;
11382 case FLOAT_1BIT_FMT(TRUNC_W, FMT_SD_D):
11383 mips32_op = OPC_TRUNC_W_D;
11387 case FLOAT_1BIT_FMT(ROUND_L, FMT_SD_S):
11388 mips32_op = OPC_ROUND_L_S;
11390 case FLOAT_1BIT_FMT(ROUND_L, FMT_SD_D):
11391 mips32_op = OPC_ROUND_L_D;
11393 case FLOAT_1BIT_FMT(ROUND_W, FMT_SD_S):
11394 mips32_op = OPC_ROUND_W_S;
11396 case FLOAT_1BIT_FMT(ROUND_W, FMT_SD_D):
11397 mips32_op = OPC_ROUND_W_D;
11400 /* Integer to floating-point conversion */
11401 case FLOAT_1BIT_FMT(CVT_L, FMT_SD_S):
11402 mips32_op = OPC_CVT_L_S;
11404 case FLOAT_1BIT_FMT(CVT_L, FMT_SD_D):
11405 mips32_op = OPC_CVT_L_D;
11407 case FLOAT_1BIT_FMT(CVT_W, FMT_SD_S):
11408 mips32_op = OPC_CVT_W_S;
11410 case FLOAT_1BIT_FMT(CVT_W, FMT_SD_D):
11411 mips32_op = OPC_CVT_W_D;
11414 /* Paired-foo conversions */
11415 case FLOAT_1BIT_FMT(CVT_S_PL, 0):
11416 mips32_op = OPC_CVT_S_PL;
11418 case FLOAT_1BIT_FMT(CVT_S_PU, 0):
11419 mips32_op = OPC_CVT_S_PU;
11421 case FLOAT_1BIT_FMT(CVT_PW_PS, 0):
11422 mips32_op = OPC_CVT_PW_PS;
11424 case FLOAT_1BIT_FMT(CVT_PS_PW, 0):
11425 mips32_op = OPC_CVT_PS_PW;
11428 /* Floating-point moves */
11429 case FLOAT_2BIT_FMT(MOV_FMT, FMT_SDPS_S):
11430 mips32_op = OPC_MOV_S;
11432 case FLOAT_2BIT_FMT(MOV_FMT, FMT_SDPS_D):
11433 mips32_op = OPC_MOV_D;
11435 case FLOAT_2BIT_FMT(MOV_FMT, FMT_SDPS_PS):
11436 mips32_op = OPC_MOV_PS;
11439 /* Absolute value */
11440 case FLOAT_2BIT_FMT(ABS_FMT, FMT_SDPS_S):
11441 mips32_op = OPC_ABS_S;
11443 case FLOAT_2BIT_FMT(ABS_FMT, FMT_SDPS_D):
11444 mips32_op = OPC_ABS_D;
11446 case FLOAT_2BIT_FMT(ABS_FMT, FMT_SDPS_PS):
11447 mips32_op = OPC_ABS_PS;
11451 case FLOAT_2BIT_FMT(NEG_FMT, FMT_SDPS_S):
11452 mips32_op = OPC_NEG_S;
11454 case FLOAT_2BIT_FMT(NEG_FMT, FMT_SDPS_D):
11455 mips32_op = OPC_NEG_D;
11457 case FLOAT_2BIT_FMT(NEG_FMT, FMT_SDPS_PS):
11458 mips32_op = OPC_NEG_PS;
11461 /* Reciprocal square root step */
11462 case FLOAT_2BIT_FMT(RSQRT1_FMT, FMT_SDPS_S):
11463 mips32_op = OPC_RSQRT1_S;
11465 case FLOAT_2BIT_FMT(RSQRT1_FMT, FMT_SDPS_D):
11466 mips32_op = OPC_RSQRT1_D;
11468 case FLOAT_2BIT_FMT(RSQRT1_FMT, FMT_SDPS_PS):
11469 mips32_op = OPC_RSQRT1_PS;
11472 /* Reciprocal step */
11473 case FLOAT_2BIT_FMT(RECIP1_FMT, FMT_SDPS_S):
11474 mips32_op = OPC_RECIP1_S;
11476 case FLOAT_2BIT_FMT(RECIP1_FMT, FMT_SDPS_D):
11477 mips32_op = OPC_RECIP1_S;
11479 case FLOAT_2BIT_FMT(RECIP1_FMT, FMT_SDPS_PS):
11480 mips32_op = OPC_RECIP1_PS;
11483 /* Conversions from double */
11484 case FLOAT_2BIT_FMT(CVT_D, FMT_SWL_S):
11485 mips32_op = OPC_CVT_D_S;
11487 case FLOAT_2BIT_FMT(CVT_D, FMT_SWL_W):
11488 mips32_op = OPC_CVT_D_W;
11490 case FLOAT_2BIT_FMT(CVT_D, FMT_SWL_L):
11491 mips32_op = OPC_CVT_D_L;
11494 /* Conversions from single */
11495 case FLOAT_2BIT_FMT(CVT_S, FMT_DWL_D):
11496 mips32_op = OPC_CVT_S_D;
11498 case FLOAT_2BIT_FMT(CVT_S, FMT_DWL_W):
11499 mips32_op = OPC_CVT_S_W;
11501 case FLOAT_2BIT_FMT(CVT_S, FMT_DWL_L):
11502 mips32_op = OPC_CVT_S_L;
11504 gen_farith(ctx, mips32_op, -1, rs, rt, 0);
11507 /* Conditional moves on floating-point codes */
11508 case COND_FLOAT_MOV(MOVT, 0):
11509 case COND_FLOAT_MOV(MOVT, 1):
11510 case COND_FLOAT_MOV(MOVT, 2):
11511 case COND_FLOAT_MOV(MOVT, 3):
11512 case COND_FLOAT_MOV(MOVT, 4):
11513 case COND_FLOAT_MOV(MOVT, 5):
11514 case COND_FLOAT_MOV(MOVT, 6):
11515 case COND_FLOAT_MOV(MOVT, 7):
11516 gen_movci(ctx, rt, rs, (ctx->opcode >> 13) & 0x7, 1);
11518 case COND_FLOAT_MOV(MOVF, 0):
11519 case COND_FLOAT_MOV(MOVF, 1):
11520 case COND_FLOAT_MOV(MOVF, 2):
11521 case COND_FLOAT_MOV(MOVF, 3):
11522 case COND_FLOAT_MOV(MOVF, 4):
11523 case COND_FLOAT_MOV(MOVF, 5):
11524 case COND_FLOAT_MOV(MOVF, 6):
11525 case COND_FLOAT_MOV(MOVF, 7):
11526 gen_movci(ctx, rt, rs, (ctx->opcode >> 13) & 0x7, 0);
11529 MIPS_INVAL("pool32fxf");
11530 generate_exception(ctx, EXCP_RI);
11535 static void decode_micromips32_opc (CPUMIPSState *env, DisasContext *ctx,
11536 uint16_t insn_hw1, int *is_branch)
11540 int rt, rs, rd, rr;
11542 uint32_t op, minor, mips32_op;
11543 uint32_t cond, fmt, cc;
11545 insn = cpu_lduw_code(env, ctx->pc + 2);
11546 ctx->opcode = (ctx->opcode << 16) | insn;
11548 rt = (ctx->opcode >> 21) & 0x1f;
11549 rs = (ctx->opcode >> 16) & 0x1f;
11550 rd = (ctx->opcode >> 11) & 0x1f;
11551 rr = (ctx->opcode >> 6) & 0x1f;
11552 imm = (int16_t) ctx->opcode;
11554 op = (ctx->opcode >> 26) & 0x3f;
11557 minor = ctx->opcode & 0x3f;
11560 minor = (ctx->opcode >> 6) & 0xf;
11563 mips32_op = OPC_SLL;
11566 mips32_op = OPC_SRA;
11569 mips32_op = OPC_SRL;
11572 mips32_op = OPC_ROTR;
11574 gen_shift_imm(env, ctx, mips32_op, rt, rs, rd);
11577 goto pool32a_invalid;
11581 minor = (ctx->opcode >> 6) & 0xf;
11585 mips32_op = OPC_ADD;
11588 mips32_op = OPC_ADDU;
11591 mips32_op = OPC_SUB;
11594 mips32_op = OPC_SUBU;
11597 mips32_op = OPC_MUL;
11599 gen_arith(env, ctx, mips32_op, rd, rs, rt);
11603 mips32_op = OPC_SLLV;
11606 mips32_op = OPC_SRLV;
11609 mips32_op = OPC_SRAV;
11612 mips32_op = OPC_ROTRV;
11614 gen_shift(env, ctx, mips32_op, rd, rs, rt);
11616 /* Logical operations */
11618 mips32_op = OPC_AND;
11621 mips32_op = OPC_OR;
11624 mips32_op = OPC_NOR;
11627 mips32_op = OPC_XOR;
11629 gen_logic(env, ctx, mips32_op, rd, rs, rt);
11631 /* Set less than */
11633 mips32_op = OPC_SLT;
11636 mips32_op = OPC_SLTU;
11638 gen_slt(env, ctx, mips32_op, rd, rs, rt);
11641 goto pool32a_invalid;
11645 minor = (ctx->opcode >> 6) & 0xf;
11647 /* Conditional moves */
11649 mips32_op = OPC_MOVN;
11652 mips32_op = OPC_MOVZ;
11654 gen_cond_move(env, ctx, mips32_op, rd, rs, rt);
11657 gen_ldxs(ctx, rs, rt, rd);
11660 goto pool32a_invalid;
11664 gen_bitops(ctx, OPC_INS, rt, rs, rr, rd);
11667 gen_bitops(ctx, OPC_EXT, rt, rs, rr, rd);
11670 gen_pool32axf(env, ctx, rt, rs, is_branch);
11673 generate_exception(ctx, EXCP_BREAK);
11677 MIPS_INVAL("pool32a");
11678 generate_exception(ctx, EXCP_RI);
11683 minor = (ctx->opcode >> 12) & 0xf;
11686 check_cp0_enabled(ctx);
11687 /* Treat as no-op. */
11691 /* COP2: Not implemented. */
11692 generate_exception_err(ctx, EXCP_CpU, 2);
11696 #ifdef TARGET_MIPS64
11700 gen_ldst_pair(ctx, minor, rt, rs, SIMM(ctx->opcode, 0, 12));
11704 #ifdef TARGET_MIPS64
11708 gen_ldst_multiple(ctx, minor, rt, rs, SIMM(ctx->opcode, 0, 12));
11711 MIPS_INVAL("pool32b");
11712 generate_exception(ctx, EXCP_RI);
11717 if (env->CP0_Config1 & (1 << CP0C1_FP)) {
11718 minor = ctx->opcode & 0x3f;
11719 check_cp1_enabled(ctx);
11722 mips32_op = OPC_ALNV_PS;
11725 mips32_op = OPC_MADD_S;
11728 mips32_op = OPC_MADD_D;
11731 mips32_op = OPC_MADD_PS;
11734 mips32_op = OPC_MSUB_S;
11737 mips32_op = OPC_MSUB_D;
11740 mips32_op = OPC_MSUB_PS;
11743 mips32_op = OPC_NMADD_S;
11746 mips32_op = OPC_NMADD_D;
11749 mips32_op = OPC_NMADD_PS;
11752 mips32_op = OPC_NMSUB_S;
11755 mips32_op = OPC_NMSUB_D;
11758 mips32_op = OPC_NMSUB_PS;
11760 gen_flt3_arith(ctx, mips32_op, rd, rr, rs, rt);
11762 case CABS_COND_FMT:
11763 cond = (ctx->opcode >> 6) & 0xf;
11764 cc = (ctx->opcode >> 13) & 0x7;
11765 fmt = (ctx->opcode >> 10) & 0x3;
11768 gen_cmpabs_s(ctx, cond, rt, rs, cc);
11771 gen_cmpabs_d(ctx, cond, rt, rs, cc);
11774 gen_cmpabs_ps(ctx, cond, rt, rs, cc);
11777 goto pool32f_invalid;
11781 cond = (ctx->opcode >> 6) & 0xf;
11782 cc = (ctx->opcode >> 13) & 0x7;
11783 fmt = (ctx->opcode >> 10) & 0x3;
11786 gen_cmp_s(ctx, cond, rt, rs, cc);
11789 gen_cmp_d(ctx, cond, rt, rs, cc);
11792 gen_cmp_ps(ctx, cond, rt, rs, cc);
11795 goto pool32f_invalid;
11799 gen_pool32fxf(env, ctx, rt, rs);
11803 switch ((ctx->opcode >> 6) & 0x7) {
11805 mips32_op = OPC_PLL_PS;
11808 mips32_op = OPC_PLU_PS;
11811 mips32_op = OPC_PUL_PS;
11814 mips32_op = OPC_PUU_PS;
11817 mips32_op = OPC_CVT_PS_S;
11819 gen_farith(ctx, mips32_op, rt, rs, rd, 0);
11822 goto pool32f_invalid;
11827 switch ((ctx->opcode >> 6) & 0x7) {
11829 mips32_op = OPC_LWXC1;
11832 mips32_op = OPC_SWXC1;
11835 mips32_op = OPC_LDXC1;
11838 mips32_op = OPC_SDXC1;
11841 mips32_op = OPC_LUXC1;
11844 mips32_op = OPC_SUXC1;
11846 gen_flt3_ldst(ctx, mips32_op, rd, rd, rt, rs);
11849 goto pool32f_invalid;
11854 fmt = (ctx->opcode >> 9) & 0x3;
11855 switch ((ctx->opcode >> 6) & 0x7) {
11859 mips32_op = OPC_RSQRT2_S;
11862 mips32_op = OPC_RSQRT2_D;
11865 mips32_op = OPC_RSQRT2_PS;
11868 goto pool32f_invalid;
11874 mips32_op = OPC_RECIP2_S;
11877 mips32_op = OPC_RECIP2_D;
11880 mips32_op = OPC_RECIP2_PS;
11883 goto pool32f_invalid;
11887 mips32_op = OPC_ADDR_PS;
11890 mips32_op = OPC_MULR_PS;
11892 gen_farith(ctx, mips32_op, rt, rs, rd, 0);
11895 goto pool32f_invalid;
11899 /* MOV[FT].fmt and PREFX */
11900 cc = (ctx->opcode >> 13) & 0x7;
11901 fmt = (ctx->opcode >> 9) & 0x3;
11902 switch ((ctx->opcode >> 6) & 0x7) {
11906 gen_movcf_s(rs, rt, cc, 0);
11909 gen_movcf_d(ctx, rs, rt, cc, 0);
11912 gen_movcf_ps(rs, rt, cc, 0);
11915 goto pool32f_invalid;
11921 gen_movcf_s(rs, rt, cc, 1);
11924 gen_movcf_d(ctx, rs, rt, cc, 1);
11927 gen_movcf_ps(rs, rt, cc, 1);
11930 goto pool32f_invalid;
11936 goto pool32f_invalid;
11939 #define FINSN_3ARG_SDPS(prfx) \
11940 switch ((ctx->opcode >> 8) & 0x3) { \
11942 mips32_op = OPC_##prfx##_S; \
11945 mips32_op = OPC_##prfx##_D; \
11947 case FMT_SDPS_PS: \
11948 mips32_op = OPC_##prfx##_PS; \
11951 goto pool32f_invalid; \
11954 /* regular FP ops */
11955 switch ((ctx->opcode >> 6) & 0x3) {
11957 FINSN_3ARG_SDPS(ADD);
11960 FINSN_3ARG_SDPS(SUB);
11963 FINSN_3ARG_SDPS(MUL);
11966 fmt = (ctx->opcode >> 8) & 0x3;
11968 mips32_op = OPC_DIV_D;
11969 } else if (fmt == 0) {
11970 mips32_op = OPC_DIV_S;
11972 goto pool32f_invalid;
11976 goto pool32f_invalid;
11981 switch ((ctx->opcode >> 6) & 0x3) {
11983 FINSN_3ARG_SDPS(MOVN);
11986 FINSN_3ARG_SDPS(MOVZ);
11989 goto pool32f_invalid;
11993 gen_farith(ctx, mips32_op, rt, rs, rd, 0);
11997 MIPS_INVAL("pool32f");
11998 generate_exception(ctx, EXCP_RI);
12002 generate_exception_err(ctx, EXCP_CpU, 1);
12006 minor = (ctx->opcode >> 21) & 0x1f;
12009 mips32_op = OPC_BLTZ;
12012 mips32_op = OPC_BLTZAL;
12015 mips32_op = OPC_BLTZALS;
12018 mips32_op = OPC_BGEZ;
12021 mips32_op = OPC_BGEZAL;
12024 mips32_op = OPC_BGEZALS;
12027 mips32_op = OPC_BLEZ;
12030 mips32_op = OPC_BGTZ;
12032 gen_compute_branch(ctx, mips32_op, 4, rs, -1, imm << 1);
12038 mips32_op = OPC_TLTI;
12041 mips32_op = OPC_TGEI;
12044 mips32_op = OPC_TLTIU;
12047 mips32_op = OPC_TGEIU;
12050 mips32_op = OPC_TNEI;
12053 mips32_op = OPC_TEQI;
12055 gen_trap(ctx, mips32_op, rs, -1, imm);
12060 gen_compute_branch(ctx, minor == BNEZC ? OPC_BNE : OPC_BEQ,
12061 4, rs, 0, imm << 1);
12062 /* Compact branches don't have a delay slot, so just let
12063 the normal delay slot handling take us to the branch
12067 gen_logic_imm(env, ctx, OPC_LUI, rs, -1, imm);
12073 /* COP2: Not implemented. */
12074 generate_exception_err(ctx, EXCP_CpU, 2);
12077 mips32_op = (ctx->opcode & (1 << 16)) ? OPC_BC1FANY2 : OPC_BC1F;
12080 mips32_op = (ctx->opcode & (1 << 16)) ? OPC_BC1TANY2 : OPC_BC1T;
12083 mips32_op = OPC_BC1FANY4;
12086 mips32_op = OPC_BC1TANY4;
12089 check_insn(env, ctx, ASE_MIPS3D);
12092 gen_compute_branch1(env, ctx, mips32_op,
12093 (ctx->opcode >> 18) & 0x7, imm << 1);
12098 /* MIPS DSP: not implemented */
12101 MIPS_INVAL("pool32i");
12102 generate_exception(ctx, EXCP_RI);
12107 minor = (ctx->opcode >> 12) & 0xf;
12110 mips32_op = OPC_LWL;
12113 mips32_op = OPC_SWL;
12116 mips32_op = OPC_LWR;
12119 mips32_op = OPC_SWR;
12121 #if defined(TARGET_MIPS64)
12123 mips32_op = OPC_LDL;
12126 mips32_op = OPC_SDL;
12129 mips32_op = OPC_LDR;
12132 mips32_op = OPC_SDR;
12135 mips32_op = OPC_LWU;
12138 mips32_op = OPC_LLD;
12142 mips32_op = OPC_LL;
12145 gen_ld(env, ctx, mips32_op, rt, rs, SIMM(ctx->opcode, 0, 12));
12148 gen_st(ctx, mips32_op, rt, rs, SIMM(ctx->opcode, 0, 12));
12151 gen_st_cond(ctx, OPC_SC, rt, rs, SIMM(ctx->opcode, 0, 12));
12153 #if defined(TARGET_MIPS64)
12155 gen_st_cond(ctx, OPC_SCD, rt, rs, SIMM(ctx->opcode, 0, 12));
12159 /* Treat as no-op */
12162 MIPS_INVAL("pool32c");
12163 generate_exception(ctx, EXCP_RI);
12168 mips32_op = OPC_ADDI;
12171 mips32_op = OPC_ADDIU;
12173 gen_arith_imm(env, ctx, mips32_op, rt, rs, imm);
12176 /* Logical operations */
12178 mips32_op = OPC_ORI;
12181 mips32_op = OPC_XORI;
12184 mips32_op = OPC_ANDI;
12186 gen_logic_imm(env, ctx, mips32_op, rt, rs, imm);
12189 /* Set less than immediate */
12191 mips32_op = OPC_SLTI;
12194 mips32_op = OPC_SLTIU;
12196 gen_slt_imm(env, ctx, mips32_op, rt, rs, imm);
12199 offset = (int32_t)(ctx->opcode & 0x3FFFFFF) << 2;
12200 gen_compute_branch(ctx, OPC_JALX, 4, rt, rs, offset);
12204 offset = (int32_t)(ctx->opcode & 0x3FFFFFF) << 1;
12205 gen_compute_branch(ctx, OPC_JALS, 4, rt, rs, offset);
12209 gen_compute_branch(ctx, OPC_BEQ, 4, rt, rs, imm << 1);
12213 gen_compute_branch(ctx, OPC_BNE, 4, rt, rs, imm << 1);
12217 gen_compute_branch(ctx, OPC_J, 4, rt, rs,
12218 (int32_t)(ctx->opcode & 0x3FFFFFF) << 1);
12222 gen_compute_branch(ctx, OPC_JAL, 4, rt, rs,
12223 (int32_t)(ctx->opcode & 0x3FFFFFF) << 1);
12226 /* Floating point (COP1) */
12228 mips32_op = OPC_LWC1;
12231 mips32_op = OPC_LDC1;
12234 mips32_op = OPC_SWC1;
12237 mips32_op = OPC_SDC1;
12239 gen_cop1_ldst(env, ctx, mips32_op, rt, rs, imm);
12243 int reg = mmreg(ZIMM(ctx->opcode, 23, 3));
12244 int offset = SIMM(ctx->opcode, 0, 23) << 2;
12246 gen_addiupc(ctx, reg, offset, 0, 0);
12249 /* Loads and stores */
12251 mips32_op = OPC_LB;
12254 mips32_op = OPC_LBU;
12257 mips32_op = OPC_LH;
12260 mips32_op = OPC_LHU;
12263 mips32_op = OPC_LW;
12265 #ifdef TARGET_MIPS64
12267 mips32_op = OPC_LD;
12270 mips32_op = OPC_SD;
12274 mips32_op = OPC_SB;
12277 mips32_op = OPC_SH;
12280 mips32_op = OPC_SW;
12283 gen_ld(env, ctx, mips32_op, rt, rs, imm);
12286 gen_st(ctx, mips32_op, rt, rs, imm);
12289 generate_exception(ctx, EXCP_RI);
12294 static int decode_micromips_opc (CPUMIPSState *env, DisasContext *ctx, int *is_branch)
12298 /* make sure instructions are on a halfword boundary */
12299 if (ctx->pc & 0x1) {
12300 env->CP0_BadVAddr = ctx->pc;
12301 generate_exception(ctx, EXCP_AdEL);
12302 ctx->bstate = BS_STOP;
12306 op = (ctx->opcode >> 10) & 0x3f;
12307 /* Enforce properly-sized instructions in a delay slot */
12308 if (ctx->hflags & MIPS_HFLAG_BMASK) {
12309 int bits = ctx->hflags & MIPS_HFLAG_BMASK_EXT;
12343 case POOL48A: /* ??? */
12348 if (bits & MIPS_HFLAG_BDS16) {
12349 generate_exception(ctx, EXCP_RI);
12350 /* Just stop translation; the user is confused. */
12351 ctx->bstate = BS_STOP;
12376 if (bits & MIPS_HFLAG_BDS32) {
12377 generate_exception(ctx, EXCP_RI);
12378 /* Just stop translation; the user is confused. */
12379 ctx->bstate = BS_STOP;
12390 int rd = mmreg(uMIPS_RD(ctx->opcode));
12391 int rs1 = mmreg(uMIPS_RS1(ctx->opcode));
12392 int rs2 = mmreg(uMIPS_RS2(ctx->opcode));
12395 switch (ctx->opcode & 0x1) {
12404 gen_arith(env, ctx, opc, rd, rs1, rs2);
12409 int rd = mmreg(uMIPS_RD(ctx->opcode));
12410 int rs = mmreg(uMIPS_RS(ctx->opcode));
12411 int amount = (ctx->opcode >> 1) & 0x7;
12413 amount = amount == 0 ? 8 : amount;
12415 switch (ctx->opcode & 0x1) {
12424 gen_shift_imm(env, ctx, opc, rd, rs, amount);
12428 gen_pool16c_insn(env, ctx, is_branch);
12432 int rd = mmreg(uMIPS_RD(ctx->opcode));
12433 int rb = 28; /* GP */
12434 int16_t offset = SIMM(ctx->opcode, 0, 7) << 2;
12436 gen_ld(env, ctx, OPC_LW, rd, rb, offset);
12440 if (ctx->opcode & 1) {
12441 generate_exception(ctx, EXCP_RI);
12444 int enc_dest = uMIPS_RD(ctx->opcode);
12445 int enc_rt = uMIPS_RS2(ctx->opcode);
12446 int enc_rs = uMIPS_RS1(ctx->opcode);
12447 int rd, rs, re, rt;
12448 static const int rd_enc[] = { 5, 5, 6, 4, 4, 4, 4, 4 };
12449 static const int re_enc[] = { 6, 7, 7, 21, 22, 5, 6, 7 };
12450 static const int rs_rt_enc[] = { 0, 17, 2, 3, 16, 18, 19, 20 };
12452 rd = rd_enc[enc_dest];
12453 re = re_enc[enc_dest];
12454 rs = rs_rt_enc[enc_rs];
12455 rt = rs_rt_enc[enc_rt];
12457 gen_arith_imm(env, ctx, OPC_ADDIU, rd, rs, 0);
12458 gen_arith_imm(env, ctx, OPC_ADDIU, re, rt, 0);
12463 int rd = mmreg(uMIPS_RD(ctx->opcode));
12464 int rb = mmreg(uMIPS_RS(ctx->opcode));
12465 int16_t offset = ZIMM(ctx->opcode, 0, 4);
12466 offset = (offset == 0xf ? -1 : offset);
12468 gen_ld(env, ctx, OPC_LBU, rd, rb, offset);
12473 int rd = mmreg(uMIPS_RD(ctx->opcode));
12474 int rb = mmreg(uMIPS_RS(ctx->opcode));
12475 int16_t offset = ZIMM(ctx->opcode, 0, 4) << 1;
12477 gen_ld(env, ctx, OPC_LHU, rd, rb, offset);
12482 int rd = (ctx->opcode >> 5) & 0x1f;
12483 int rb = 29; /* SP */
12484 int16_t offset = ZIMM(ctx->opcode, 0, 5) << 2;
12486 gen_ld(env, ctx, OPC_LW, rd, rb, offset);
12491 int rd = mmreg(uMIPS_RD(ctx->opcode));
12492 int rb = mmreg(uMIPS_RS(ctx->opcode));
12493 int16_t offset = ZIMM(ctx->opcode, 0, 4) << 2;
12495 gen_ld(env, ctx, OPC_LW, rd, rb, offset);
12500 int rd = mmreg2(uMIPS_RD(ctx->opcode));
12501 int rb = mmreg(uMIPS_RS(ctx->opcode));
12502 int16_t offset = ZIMM(ctx->opcode, 0, 4);
12504 gen_st(ctx, OPC_SB, rd, rb, offset);
12509 int rd = mmreg2(uMIPS_RD(ctx->opcode));
12510 int rb = mmreg(uMIPS_RS(ctx->opcode));
12511 int16_t offset = ZIMM(ctx->opcode, 0, 4) << 1;
12513 gen_st(ctx, OPC_SH, rd, rb, offset);
12518 int rd = (ctx->opcode >> 5) & 0x1f;
12519 int rb = 29; /* SP */
12520 int16_t offset = ZIMM(ctx->opcode, 0, 5) << 2;
12522 gen_st(ctx, OPC_SW, rd, rb, offset);
12527 int rd = mmreg2(uMIPS_RD(ctx->opcode));
12528 int rb = mmreg(uMIPS_RS(ctx->opcode));
12529 int16_t offset = ZIMM(ctx->opcode, 0, 4) << 2;
12531 gen_st(ctx, OPC_SW, rd, rb, offset);
12536 int rd = uMIPS_RD5(ctx->opcode);
12537 int rs = uMIPS_RS5(ctx->opcode);
12539 gen_arith_imm(env, ctx, OPC_ADDIU, rd, rs, 0);
12543 gen_andi16(env, ctx);
12546 switch (ctx->opcode & 0x1) {
12548 gen_addius5(env, ctx);
12551 gen_addiusp(env, ctx);
12556 switch (ctx->opcode & 0x1) {
12558 gen_addiur2(env, ctx);
12561 gen_addiur1sp(env, ctx);
12566 gen_compute_branch(ctx, OPC_BEQ, 2, 0, 0,
12567 SIMM(ctx->opcode, 0, 10) << 1);
12572 gen_compute_branch(ctx, op == BNEZ16 ? OPC_BNE : OPC_BEQ, 2,
12573 mmreg(uMIPS_RD(ctx->opcode)),
12574 0, SIMM(ctx->opcode, 0, 7) << 1);
12579 int reg = mmreg(uMIPS_RD(ctx->opcode));
12580 int imm = ZIMM(ctx->opcode, 0, 7);
12582 imm = (imm == 0x7f ? -1 : imm);
12583 tcg_gen_movi_tl(cpu_gpr[reg], imm);
12593 generate_exception(ctx, EXCP_RI);
12596 decode_micromips32_opc (env, ctx, op, is_branch);
12603 /* SmartMIPS extension to MIPS32 */
12605 #if defined(TARGET_MIPS64)
12607 /* MDMX extension to MIPS64 */
12611 /* MIPSDSP functions. */
12612 static void gen_mipsdsp_ld(CPUMIPSState *env, DisasContext *ctx, uint32_t opc,
12613 int rd, int base, int offset)
12615 const char *opn = "ldx";
12624 t0 = tcg_temp_new();
12627 gen_load_gpr(t0, offset);
12628 } else if (offset == 0) {
12629 gen_load_gpr(t0, base);
12631 gen_op_addr_add(ctx, t0, cpu_gpr[base], cpu_gpr[offset]);
12636 tcg_gen_qemu_ld8u(t0, t0, ctx->mem_idx);
12637 gen_store_gpr(t0, rd);
12641 tcg_gen_qemu_ld16s(t0, t0, ctx->mem_idx);
12642 gen_store_gpr(t0, rd);
12646 tcg_gen_qemu_ld32s(t0, t0, ctx->mem_idx);
12647 gen_store_gpr(t0, rd);
12650 #if defined(TARGET_MIPS64)
12652 tcg_gen_qemu_ld64(t0, t0, ctx->mem_idx);
12653 gen_store_gpr(t0, rd);
12658 (void)opn; /* avoid a compiler warning */
12659 MIPS_DEBUG("%s %s, %s(%s)", opn,
12660 regnames[rd], regnames[offset], regnames[base]);
12664 static void gen_mipsdsp_arith(DisasContext *ctx, uint32_t op1, uint32_t op2,
12665 int ret, int v1, int v2)
12667 const char *opn = "mipsdsp arith";
12672 /* Treat as NOP. */
12677 v1_t = tcg_temp_new();
12678 v2_t = tcg_temp_new();
12680 gen_load_gpr(v1_t, v1);
12681 gen_load_gpr(v2_t, v2);
12684 /* OPC_MULT_G_2E is equal OPC_ADDUH_QB_DSP */
12685 case OPC_MULT_G_2E:
12689 gen_helper_adduh_qb(cpu_gpr[ret], v1_t, v2_t);
12691 case OPC_ADDUH_R_QB:
12692 gen_helper_adduh_r_qb(cpu_gpr[ret], v1_t, v2_t);
12695 gen_helper_addqh_ph(cpu_gpr[ret], v1_t, v2_t);
12697 case OPC_ADDQH_R_PH:
12698 gen_helper_addqh_r_ph(cpu_gpr[ret], v1_t, v2_t);
12701 gen_helper_addqh_w(cpu_gpr[ret], v1_t, v2_t);
12703 case OPC_ADDQH_R_W:
12704 gen_helper_addqh_r_w(cpu_gpr[ret], v1_t, v2_t);
12707 gen_helper_subuh_qb(cpu_gpr[ret], v1_t, v2_t);
12709 case OPC_SUBUH_R_QB:
12710 gen_helper_subuh_r_qb(cpu_gpr[ret], v1_t, v2_t);
12713 gen_helper_subqh_ph(cpu_gpr[ret], v1_t, v2_t);
12715 case OPC_SUBQH_R_PH:
12716 gen_helper_subqh_r_ph(cpu_gpr[ret], v1_t, v2_t);
12719 gen_helper_subqh_w(cpu_gpr[ret], v1_t, v2_t);
12721 case OPC_SUBQH_R_W:
12722 gen_helper_subqh_r_w(cpu_gpr[ret], v1_t, v2_t);
12726 case OPC_ABSQ_S_PH_DSP:
12728 case OPC_ABSQ_S_QB:
12730 gen_helper_absq_s_qb(cpu_gpr[ret], v2_t, cpu_env);
12732 case OPC_ABSQ_S_PH:
12734 gen_helper_absq_s_ph(cpu_gpr[ret], v2_t, cpu_env);
12738 gen_helper_absq_s_w(cpu_gpr[ret], v2_t, cpu_env);
12740 case OPC_PRECEQ_W_PHL:
12742 tcg_gen_andi_tl(cpu_gpr[ret], v2_t, 0xFFFF0000);
12743 tcg_gen_ext32s_tl(cpu_gpr[ret], cpu_gpr[ret]);
12745 case OPC_PRECEQ_W_PHR:
12747 tcg_gen_andi_tl(cpu_gpr[ret], v2_t, 0x0000FFFF);
12748 tcg_gen_shli_tl(cpu_gpr[ret], cpu_gpr[ret], 16);
12749 tcg_gen_ext32s_tl(cpu_gpr[ret], cpu_gpr[ret]);
12751 case OPC_PRECEQU_PH_QBL:
12753 gen_helper_precequ_ph_qbl(cpu_gpr[ret], v2_t);
12755 case OPC_PRECEQU_PH_QBR:
12757 gen_helper_precequ_ph_qbr(cpu_gpr[ret], v2_t);
12759 case OPC_PRECEQU_PH_QBLA:
12761 gen_helper_precequ_ph_qbla(cpu_gpr[ret], v2_t);
12763 case OPC_PRECEQU_PH_QBRA:
12765 gen_helper_precequ_ph_qbra(cpu_gpr[ret], v2_t);
12767 case OPC_PRECEU_PH_QBL:
12769 gen_helper_preceu_ph_qbl(cpu_gpr[ret], v2_t);
12771 case OPC_PRECEU_PH_QBR:
12773 gen_helper_preceu_ph_qbr(cpu_gpr[ret], v2_t);
12775 case OPC_PRECEU_PH_QBLA:
12777 gen_helper_preceu_ph_qbla(cpu_gpr[ret], v2_t);
12779 case OPC_PRECEU_PH_QBRA:
12781 gen_helper_preceu_ph_qbra(cpu_gpr[ret], v2_t);
12785 case OPC_ADDU_QB_DSP:
12789 gen_helper_addq_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12791 case OPC_ADDQ_S_PH:
12793 gen_helper_addq_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12797 gen_helper_addq_s_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12801 gen_helper_addu_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12803 case OPC_ADDU_S_QB:
12805 gen_helper_addu_s_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12809 gen_helper_addu_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12811 case OPC_ADDU_S_PH:
12813 gen_helper_addu_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12817 gen_helper_subq_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12819 case OPC_SUBQ_S_PH:
12821 gen_helper_subq_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12825 gen_helper_subq_s_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12829 gen_helper_subu_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12831 case OPC_SUBU_S_QB:
12833 gen_helper_subu_s_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12837 gen_helper_subu_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12839 case OPC_SUBU_S_PH:
12841 gen_helper_subu_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12845 gen_helper_addsc(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12849 gen_helper_addwc(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12853 gen_helper_modsub(cpu_gpr[ret], v1_t, v2_t);
12855 case OPC_RADDU_W_QB:
12857 gen_helper_raddu_w_qb(cpu_gpr[ret], v1_t);
12861 case OPC_CMPU_EQ_QB_DSP:
12863 case OPC_PRECR_QB_PH:
12865 gen_helper_precr_qb_ph(cpu_gpr[ret], v1_t, v2_t);
12867 case OPC_PRECRQ_QB_PH:
12869 gen_helper_precrq_qb_ph(cpu_gpr[ret], v1_t, v2_t);
12871 case OPC_PRECR_SRA_PH_W:
12874 TCGv_i32 sa_t = tcg_const_i32(v2);
12875 gen_helper_precr_sra_ph_w(cpu_gpr[ret], sa_t, v1_t,
12877 tcg_temp_free_i32(sa_t);
12880 case OPC_PRECR_SRA_R_PH_W:
12883 TCGv_i32 sa_t = tcg_const_i32(v2);
12884 gen_helper_precr_sra_r_ph_w(cpu_gpr[ret], sa_t, v1_t,
12886 tcg_temp_free_i32(sa_t);
12889 case OPC_PRECRQ_PH_W:
12891 gen_helper_precrq_ph_w(cpu_gpr[ret], v1_t, v2_t);
12893 case OPC_PRECRQ_RS_PH_W:
12895 gen_helper_precrq_rs_ph_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12897 case OPC_PRECRQU_S_QB_PH:
12899 gen_helper_precrqu_s_qb_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12903 #ifdef TARGET_MIPS64
12904 case OPC_ABSQ_S_QH_DSP:
12906 case OPC_PRECEQ_L_PWL:
12908 tcg_gen_andi_tl(cpu_gpr[ret], v2_t, 0xFFFFFFFF00000000ull);
12910 case OPC_PRECEQ_L_PWR:
12912 tcg_gen_shli_tl(cpu_gpr[ret], v2_t, 32);
12914 case OPC_PRECEQ_PW_QHL:
12916 gen_helper_preceq_pw_qhl(cpu_gpr[ret], v2_t);
12918 case OPC_PRECEQ_PW_QHR:
12920 gen_helper_preceq_pw_qhr(cpu_gpr[ret], v2_t);
12922 case OPC_PRECEQ_PW_QHLA:
12924 gen_helper_preceq_pw_qhla(cpu_gpr[ret], v2_t);
12926 case OPC_PRECEQ_PW_QHRA:
12928 gen_helper_preceq_pw_qhra(cpu_gpr[ret], v2_t);
12930 case OPC_PRECEQU_QH_OBL:
12932 gen_helper_precequ_qh_obl(cpu_gpr[ret], v2_t);
12934 case OPC_PRECEQU_QH_OBR:
12936 gen_helper_precequ_qh_obr(cpu_gpr[ret], v2_t);
12938 case OPC_PRECEQU_QH_OBLA:
12940 gen_helper_precequ_qh_obla(cpu_gpr[ret], v2_t);
12942 case OPC_PRECEQU_QH_OBRA:
12944 gen_helper_precequ_qh_obra(cpu_gpr[ret], v2_t);
12946 case OPC_PRECEU_QH_OBL:
12948 gen_helper_preceu_qh_obl(cpu_gpr[ret], v2_t);
12950 case OPC_PRECEU_QH_OBR:
12952 gen_helper_preceu_qh_obr(cpu_gpr[ret], v2_t);
12954 case OPC_PRECEU_QH_OBLA:
12956 gen_helper_preceu_qh_obla(cpu_gpr[ret], v2_t);
12958 case OPC_PRECEU_QH_OBRA:
12960 gen_helper_preceu_qh_obra(cpu_gpr[ret], v2_t);
12962 case OPC_ABSQ_S_OB:
12964 gen_helper_absq_s_ob(cpu_gpr[ret], v2_t, cpu_env);
12966 case OPC_ABSQ_S_PW:
12968 gen_helper_absq_s_pw(cpu_gpr[ret], v2_t, cpu_env);
12970 case OPC_ABSQ_S_QH:
12972 gen_helper_absq_s_qh(cpu_gpr[ret], v2_t, cpu_env);
12976 case OPC_ADDU_OB_DSP:
12978 case OPC_RADDU_L_OB:
12980 gen_helper_raddu_l_ob(cpu_gpr[ret], v1_t);
12984 gen_helper_subq_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12986 case OPC_SUBQ_S_PW:
12988 gen_helper_subq_s_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12992 gen_helper_subq_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12994 case OPC_SUBQ_S_QH:
12996 gen_helper_subq_s_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13000 gen_helper_subu_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13002 case OPC_SUBU_S_OB:
13004 gen_helper_subu_s_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13008 gen_helper_subu_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13010 case OPC_SUBU_S_QH:
13012 gen_helper_subu_s_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13016 gen_helper_subuh_ob(cpu_gpr[ret], v1_t, v2_t);
13018 case OPC_SUBUH_R_OB:
13020 gen_helper_subuh_r_ob(cpu_gpr[ret], v1_t, v2_t);
13024 gen_helper_addq_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13026 case OPC_ADDQ_S_PW:
13028 gen_helper_addq_s_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13032 gen_helper_addq_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13034 case OPC_ADDQ_S_QH:
13036 gen_helper_addq_s_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13040 gen_helper_addu_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13042 case OPC_ADDU_S_OB:
13044 gen_helper_addu_s_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13048 gen_helper_addu_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13050 case OPC_ADDU_S_QH:
13052 gen_helper_addu_s_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13056 gen_helper_adduh_ob(cpu_gpr[ret], v1_t, v2_t);
13058 case OPC_ADDUH_R_OB:
13060 gen_helper_adduh_r_ob(cpu_gpr[ret], v1_t, v2_t);
13064 case OPC_CMPU_EQ_OB_DSP:
13066 case OPC_PRECR_OB_QH:
13068 gen_helper_precr_ob_qh(cpu_gpr[ret], v1_t, v2_t);
13070 case OPC_PRECR_SRA_QH_PW:
13073 TCGv_i32 ret_t = tcg_const_i32(ret);
13074 gen_helper_precr_sra_qh_pw(v2_t, v1_t, v2_t, ret_t);
13075 tcg_temp_free_i32(ret_t);
13078 case OPC_PRECR_SRA_R_QH_PW:
13081 TCGv_i32 sa_v = tcg_const_i32(ret);
13082 gen_helper_precr_sra_r_qh_pw(v2_t, v1_t, v2_t, sa_v);
13083 tcg_temp_free_i32(sa_v);
13086 case OPC_PRECRQ_OB_QH:
13088 gen_helper_precrq_ob_qh(cpu_gpr[ret], v1_t, v2_t);
13090 case OPC_PRECRQ_PW_L:
13092 gen_helper_precrq_pw_l(cpu_gpr[ret], v1_t, v2_t);
13094 case OPC_PRECRQ_QH_PW:
13096 gen_helper_precrq_qh_pw(cpu_gpr[ret], v1_t, v2_t);
13098 case OPC_PRECRQ_RS_QH_PW:
13100 gen_helper_precrq_rs_qh_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13102 case OPC_PRECRQU_S_OB_QH:
13104 gen_helper_precrqu_s_ob_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13111 tcg_temp_free(v1_t);
13112 tcg_temp_free(v2_t);
13114 (void)opn; /* avoid a compiler warning */
13115 MIPS_DEBUG("%s", opn);
13118 static void gen_mipsdsp_shift(DisasContext *ctx, uint32_t opc,
13119 int ret, int v1, int v2)
13122 const char *opn = "mipsdsp shift";
13128 /* Treat as NOP. */
13133 t0 = tcg_temp_new();
13134 v1_t = tcg_temp_new();
13135 v2_t = tcg_temp_new();
13137 tcg_gen_movi_tl(t0, v1);
13138 gen_load_gpr(v1_t, v1);
13139 gen_load_gpr(v2_t, v2);
13142 case OPC_SHLL_QB_DSP:
13144 op2 = MASK_SHLL_QB(ctx->opcode);
13148 gen_helper_shll_qb(cpu_gpr[ret], t0, v2_t, cpu_env);
13152 gen_helper_shll_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13156 gen_helper_shll_ph(cpu_gpr[ret], t0, v2_t, cpu_env);
13160 gen_helper_shll_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13162 case OPC_SHLL_S_PH:
13164 gen_helper_shll_s_ph(cpu_gpr[ret], t0, v2_t, cpu_env);
13166 case OPC_SHLLV_S_PH:
13168 gen_helper_shll_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13172 gen_helper_shll_s_w(cpu_gpr[ret], t0, v2_t, cpu_env);
13174 case OPC_SHLLV_S_W:
13176 gen_helper_shll_s_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13180 gen_helper_shrl_qb(cpu_gpr[ret], t0, v2_t);
13184 gen_helper_shrl_qb(cpu_gpr[ret], v1_t, v2_t);
13188 gen_helper_shrl_ph(cpu_gpr[ret], t0, v2_t);
13192 gen_helper_shrl_ph(cpu_gpr[ret], v1_t, v2_t);
13196 gen_helper_shra_qb(cpu_gpr[ret], t0, v2_t);
13198 case OPC_SHRA_R_QB:
13200 gen_helper_shra_r_qb(cpu_gpr[ret], t0, v2_t);
13204 gen_helper_shra_qb(cpu_gpr[ret], v1_t, v2_t);
13206 case OPC_SHRAV_R_QB:
13208 gen_helper_shra_r_qb(cpu_gpr[ret], v1_t, v2_t);
13212 gen_helper_shra_ph(cpu_gpr[ret], t0, v2_t);
13214 case OPC_SHRA_R_PH:
13216 gen_helper_shra_r_ph(cpu_gpr[ret], t0, v2_t);
13220 gen_helper_shra_ph(cpu_gpr[ret], v1_t, v2_t);
13222 case OPC_SHRAV_R_PH:
13224 gen_helper_shra_r_ph(cpu_gpr[ret], v1_t, v2_t);
13228 gen_helper_shra_r_w(cpu_gpr[ret], t0, v2_t);
13230 case OPC_SHRAV_R_W:
13232 gen_helper_shra_r_w(cpu_gpr[ret], v1_t, v2_t);
13234 default: /* Invalid */
13235 MIPS_INVAL("MASK SHLL.QB");
13236 generate_exception(ctx, EXCP_RI);
13241 #ifdef TARGET_MIPS64
13242 case OPC_SHLL_OB_DSP:
13243 op2 = MASK_SHLL_OB(ctx->opcode);
13247 gen_helper_shll_pw(cpu_gpr[ret], v2_t, t0, cpu_env);
13251 gen_helper_shll_pw(cpu_gpr[ret], v2_t, v1_t, cpu_env);
13253 case OPC_SHLL_S_PW:
13255 gen_helper_shll_s_pw(cpu_gpr[ret], v2_t, t0, cpu_env);
13257 case OPC_SHLLV_S_PW:
13259 gen_helper_shll_s_pw(cpu_gpr[ret], v2_t, v1_t, cpu_env);
13263 gen_helper_shll_ob(cpu_gpr[ret], v2_t, t0, cpu_env);
13267 gen_helper_shll_ob(cpu_gpr[ret], v2_t, v1_t, cpu_env);
13271 gen_helper_shll_qh(cpu_gpr[ret], v2_t, t0, cpu_env);
13275 gen_helper_shll_qh(cpu_gpr[ret], v2_t, v1_t, cpu_env);
13277 case OPC_SHLL_S_QH:
13279 gen_helper_shll_s_qh(cpu_gpr[ret], v2_t, t0, cpu_env);
13281 case OPC_SHLLV_S_QH:
13283 gen_helper_shll_s_qh(cpu_gpr[ret], v2_t, v1_t, cpu_env);
13287 gen_helper_shra_ob(cpu_gpr[ret], v2_t, t0);
13291 gen_helper_shra_ob(cpu_gpr[ret], v2_t, v1_t);
13293 case OPC_SHRA_R_OB:
13295 gen_helper_shra_r_ob(cpu_gpr[ret], v2_t, t0);
13297 case OPC_SHRAV_R_OB:
13299 gen_helper_shra_r_ob(cpu_gpr[ret], v2_t, v1_t);
13303 gen_helper_shra_pw(cpu_gpr[ret], v2_t, t0);
13307 gen_helper_shra_pw(cpu_gpr[ret], v2_t, v1_t);
13309 case OPC_SHRA_R_PW:
13311 gen_helper_shra_r_pw(cpu_gpr[ret], v2_t, t0);
13313 case OPC_SHRAV_R_PW:
13315 gen_helper_shra_r_pw(cpu_gpr[ret], v2_t, v1_t);
13319 gen_helper_shra_qh(cpu_gpr[ret], v2_t, t0);
13323 gen_helper_shra_qh(cpu_gpr[ret], v2_t, v1_t);
13325 case OPC_SHRA_R_QH:
13327 gen_helper_shra_r_qh(cpu_gpr[ret], v2_t, t0);
13329 case OPC_SHRAV_R_QH:
13331 gen_helper_shra_r_qh(cpu_gpr[ret], v2_t, v1_t);
13335 gen_helper_shrl_ob(cpu_gpr[ret], v2_t, t0);
13339 gen_helper_shrl_ob(cpu_gpr[ret], v2_t, v1_t);
13343 gen_helper_shrl_qh(cpu_gpr[ret], v2_t, t0);
13347 gen_helper_shrl_qh(cpu_gpr[ret], v2_t, v1_t);
13349 default: /* Invalid */
13350 MIPS_INVAL("MASK SHLL.OB");
13351 generate_exception(ctx, EXCP_RI);
13359 tcg_temp_free(v1_t);
13360 tcg_temp_free(v2_t);
13361 (void)opn; /* avoid a compiler warning */
13362 MIPS_DEBUG("%s", opn);
13365 static void gen_mipsdsp_multiply(DisasContext *ctx, uint32_t op1, uint32_t op2,
13366 int ret, int v1, int v2, int check_ret)
13368 const char *opn = "mipsdsp multiply";
13373 if ((ret == 0) && (check_ret == 1)) {
13374 /* Treat as NOP. */
13379 t0 = tcg_temp_new_i32();
13380 v1_t = tcg_temp_new();
13381 v2_t = tcg_temp_new();
13383 tcg_gen_movi_i32(t0, ret);
13384 gen_load_gpr(v1_t, v1);
13385 gen_load_gpr(v2_t, v2);
13388 /* OPC_MULT_G_2E, OPC_ADDUH_QB_DSP, OPC_MUL_PH_DSP have
13389 * the same mask and op1. */
13390 case OPC_MULT_G_2E:
13393 gen_helper_mul_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13396 gen_helper_mul_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13399 gen_helper_mulq_s_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13401 case OPC_MULQ_RS_W:
13402 gen_helper_mulq_rs_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13406 case OPC_DPA_W_PH_DSP:
13408 case OPC_DPAU_H_QBL:
13410 gen_helper_dpau_h_qbl(t0, v1_t, v2_t, cpu_env);
13412 case OPC_DPAU_H_QBR:
13414 gen_helper_dpau_h_qbr(t0, v1_t, v2_t, cpu_env);
13416 case OPC_DPSU_H_QBL:
13418 gen_helper_dpsu_h_qbl(t0, v1_t, v2_t, cpu_env);
13420 case OPC_DPSU_H_QBR:
13422 gen_helper_dpsu_h_qbr(t0, v1_t, v2_t, cpu_env);
13426 gen_helper_dpa_w_ph(t0, v1_t, v2_t, cpu_env);
13428 case OPC_DPAX_W_PH:
13430 gen_helper_dpax_w_ph(t0, v1_t, v2_t, cpu_env);
13432 case OPC_DPAQ_S_W_PH:
13434 gen_helper_dpaq_s_w_ph(t0, v1_t, v2_t, cpu_env);
13436 case OPC_DPAQX_S_W_PH:
13438 gen_helper_dpaqx_s_w_ph(t0, v1_t, v2_t, cpu_env);
13440 case OPC_DPAQX_SA_W_PH:
13442 gen_helper_dpaqx_sa_w_ph(t0, v1_t, v2_t, cpu_env);
13446 gen_helper_dps_w_ph(t0, v1_t, v2_t, cpu_env);
13448 case OPC_DPSX_W_PH:
13450 gen_helper_dpsx_w_ph(t0, v1_t, v2_t, cpu_env);
13452 case OPC_DPSQ_S_W_PH:
13454 gen_helper_dpsq_s_w_ph(t0, v1_t, v2_t, cpu_env);
13456 case OPC_DPSQX_S_W_PH:
13458 gen_helper_dpsqx_s_w_ph(t0, v1_t, v2_t, cpu_env);
13460 case OPC_DPSQX_SA_W_PH:
13462 gen_helper_dpsqx_sa_w_ph(t0, v1_t, v2_t, cpu_env);
13464 case OPC_MULSAQ_S_W_PH:
13466 gen_helper_mulsaq_s_w_ph(t0, v1_t, v2_t, cpu_env);
13468 case OPC_DPAQ_SA_L_W:
13470 gen_helper_dpaq_sa_l_w(t0, v1_t, v2_t, cpu_env);
13472 case OPC_DPSQ_SA_L_W:
13474 gen_helper_dpsq_sa_l_w(t0, v1_t, v2_t, cpu_env);
13476 case OPC_MAQ_S_W_PHL:
13478 gen_helper_maq_s_w_phl(t0, v1_t, v2_t, cpu_env);
13480 case OPC_MAQ_S_W_PHR:
13482 gen_helper_maq_s_w_phr(t0, v1_t, v2_t, cpu_env);
13484 case OPC_MAQ_SA_W_PHL:
13486 gen_helper_maq_sa_w_phl(t0, v1_t, v2_t, cpu_env);
13488 case OPC_MAQ_SA_W_PHR:
13490 gen_helper_maq_sa_w_phr(t0, v1_t, v2_t, cpu_env);
13492 case OPC_MULSA_W_PH:
13494 gen_helper_mulsa_w_ph(t0, v1_t, v2_t, cpu_env);
13498 #ifdef TARGET_MIPS64
13499 case OPC_DPAQ_W_QH_DSP:
13501 int ac = ret & 0x03;
13502 tcg_gen_movi_i32(t0, ac);
13507 gen_helper_dmadd(v1_t, v2_t, t0, cpu_env);
13511 gen_helper_dmaddu(v1_t, v2_t, t0, cpu_env);
13515 gen_helper_dmsub(v1_t, v2_t, t0, cpu_env);
13519 gen_helper_dmsubu(v1_t, v2_t, t0, cpu_env);
13523 gen_helper_dpa_w_qh(v1_t, v2_t, t0, cpu_env);
13525 case OPC_DPAQ_S_W_QH:
13527 gen_helper_dpaq_s_w_qh(v1_t, v2_t, t0, cpu_env);
13529 case OPC_DPAQ_SA_L_PW:
13531 gen_helper_dpaq_sa_l_pw(v1_t, v2_t, t0, cpu_env);
13533 case OPC_DPAU_H_OBL:
13535 gen_helper_dpau_h_obl(v1_t, v2_t, t0, cpu_env);
13537 case OPC_DPAU_H_OBR:
13539 gen_helper_dpau_h_obr(v1_t, v2_t, t0, cpu_env);
13543 gen_helper_dps_w_qh(v1_t, v2_t, t0, cpu_env);
13545 case OPC_DPSQ_S_W_QH:
13547 gen_helper_dpsq_s_w_qh(v1_t, v2_t, t0, cpu_env);
13549 case OPC_DPSQ_SA_L_PW:
13551 gen_helper_dpsq_sa_l_pw(v1_t, v2_t, t0, cpu_env);
13553 case OPC_DPSU_H_OBL:
13555 gen_helper_dpsu_h_obl(v1_t, v2_t, t0, cpu_env);
13557 case OPC_DPSU_H_OBR:
13559 gen_helper_dpsu_h_obr(v1_t, v2_t, t0, cpu_env);
13561 case OPC_MAQ_S_L_PWL:
13563 gen_helper_maq_s_l_pwl(v1_t, v2_t, t0, cpu_env);
13565 case OPC_MAQ_S_L_PWR:
13567 gen_helper_maq_s_l_pwr(v1_t, v2_t, t0, cpu_env);
13569 case OPC_MAQ_S_W_QHLL:
13571 gen_helper_maq_s_w_qhll(v1_t, v2_t, t0, cpu_env);
13573 case OPC_MAQ_SA_W_QHLL:
13575 gen_helper_maq_sa_w_qhll(v1_t, v2_t, t0, cpu_env);
13577 case OPC_MAQ_S_W_QHLR:
13579 gen_helper_maq_s_w_qhlr(v1_t, v2_t, t0, cpu_env);
13581 case OPC_MAQ_SA_W_QHLR:
13583 gen_helper_maq_sa_w_qhlr(v1_t, v2_t, t0, cpu_env);
13585 case OPC_MAQ_S_W_QHRL:
13587 gen_helper_maq_s_w_qhrl(v1_t, v2_t, t0, cpu_env);
13589 case OPC_MAQ_SA_W_QHRL:
13591 gen_helper_maq_sa_w_qhrl(v1_t, v2_t, t0, cpu_env);
13593 case OPC_MAQ_S_W_QHRR:
13595 gen_helper_maq_s_w_qhrr(v1_t, v2_t, t0, cpu_env);
13597 case OPC_MAQ_SA_W_QHRR:
13599 gen_helper_maq_sa_w_qhrr(v1_t, v2_t, t0, cpu_env);
13601 case OPC_MULSAQ_S_L_PW:
13603 gen_helper_mulsaq_s_l_pw(v1_t, v2_t, t0, cpu_env);
13605 case OPC_MULSAQ_S_W_QH:
13607 gen_helper_mulsaq_s_w_qh(v1_t, v2_t, t0, cpu_env);
13613 case OPC_ADDU_QB_DSP:
13615 case OPC_MULEU_S_PH_QBL:
13617 gen_helper_muleu_s_ph_qbl(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13619 case OPC_MULEU_S_PH_QBR:
13621 gen_helper_muleu_s_ph_qbr(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13623 case OPC_MULQ_RS_PH:
13625 gen_helper_mulq_rs_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13627 case OPC_MULEQ_S_W_PHL:
13629 gen_helper_muleq_s_w_phl(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13631 case OPC_MULEQ_S_W_PHR:
13633 gen_helper_muleq_s_w_phr(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13635 case OPC_MULQ_S_PH:
13637 gen_helper_mulq_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13641 #ifdef TARGET_MIPS64
13642 case OPC_ADDU_OB_DSP:
13644 case OPC_MULEQ_S_PW_QHL:
13646 gen_helper_muleq_s_pw_qhl(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13648 case OPC_MULEQ_S_PW_QHR:
13650 gen_helper_muleq_s_pw_qhr(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13652 case OPC_MULEU_S_QH_OBL:
13654 gen_helper_muleu_s_qh_obl(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13656 case OPC_MULEU_S_QH_OBR:
13658 gen_helper_muleu_s_qh_obr(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13660 case OPC_MULQ_RS_QH:
13662 gen_helper_mulq_rs_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13669 tcg_temp_free_i32(t0);
13670 tcg_temp_free(v1_t);
13671 tcg_temp_free(v2_t);
13673 (void)opn; /* avoid a compiler warning */
13674 MIPS_DEBUG("%s", opn);
13678 static void gen_mipsdsp_bitinsn(CPUMIPSState *env, DisasContext *ctx,
13679 uint32_t op1, uint32_t op2,
13682 const char *opn = "mipsdsp Bit/ Manipulation";
13688 /* Treat as NOP. */
13693 t0 = tcg_temp_new();
13694 val_t = tcg_temp_new();
13695 gen_load_gpr(val_t, val);
13698 case OPC_ABSQ_S_PH_DSP:
13702 gen_helper_bitrev(cpu_gpr[ret], val_t);
13707 target_long result;
13708 imm = (ctx->opcode >> 16) & 0xFF;
13709 result = (uint32_t)imm << 24 |
13710 (uint32_t)imm << 16 |
13711 (uint32_t)imm << 8 |
13713 result = (int32_t)result;
13714 tcg_gen_movi_tl(cpu_gpr[ret], result);
13719 tcg_gen_ext8u_tl(cpu_gpr[ret], val_t);
13720 tcg_gen_shli_tl(t0, cpu_gpr[ret], 8);
13721 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
13722 tcg_gen_shli_tl(t0, cpu_gpr[ret], 16);
13723 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
13724 tcg_gen_ext32s_tl(cpu_gpr[ret], cpu_gpr[ret]);
13729 imm = (ctx->opcode >> 16) & 0x03FF;
13730 tcg_gen_movi_tl(cpu_gpr[ret], \
13731 (target_long)((int32_t)imm << 16 | \
13732 (uint32_t)(uint16_t)imm));
13737 tcg_gen_ext16u_tl(cpu_gpr[ret], val_t);
13738 tcg_gen_shli_tl(t0, cpu_gpr[ret], 16);
13739 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
13740 tcg_gen_ext32s_tl(cpu_gpr[ret], cpu_gpr[ret]);
13744 #ifdef TARGET_MIPS64
13745 case OPC_ABSQ_S_QH_DSP:
13752 imm = (ctx->opcode >> 16) & 0xFF;
13753 temp = ((uint64_t)imm << 8) | (uint64_t)imm;
13754 temp = (temp << 16) | temp;
13755 temp = (temp << 32) | temp;
13756 tcg_gen_movi_tl(cpu_gpr[ret], temp);
13764 imm = (ctx->opcode >> 16) & 0x03FF;
13765 imm = (int16_t)(imm << 6) >> 6;
13766 temp = ((target_long)imm << 32) \
13767 | ((target_long)imm & 0xFFFFFFFF);
13768 tcg_gen_movi_tl(cpu_gpr[ret], temp);
13776 imm = (ctx->opcode >> 16) & 0x03FF;
13777 imm = (int16_t)(imm << 6) >> 6;
13779 temp = ((uint64_t)(uint16_t)imm << 48) |
13780 ((uint64_t)(uint16_t)imm << 32) |
13781 ((uint64_t)(uint16_t)imm << 16) |
13782 (uint64_t)(uint16_t)imm;
13783 tcg_gen_movi_tl(cpu_gpr[ret], temp);
13788 tcg_gen_ext8u_tl(cpu_gpr[ret], val_t);
13789 tcg_gen_shli_tl(t0, cpu_gpr[ret], 8);
13790 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
13791 tcg_gen_shli_tl(t0, cpu_gpr[ret], 16);
13792 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
13793 tcg_gen_shli_tl(t0, cpu_gpr[ret], 32);
13794 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
13798 tcg_gen_ext32u_i64(cpu_gpr[ret], val_t);
13799 tcg_gen_shli_tl(t0, cpu_gpr[ret], 32);
13800 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
13804 tcg_gen_ext16u_tl(cpu_gpr[ret], val_t);
13805 tcg_gen_shli_tl(t0, cpu_gpr[ret], 16);
13806 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
13807 tcg_gen_shli_tl(t0, cpu_gpr[ret], 32);
13808 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
13815 tcg_temp_free(val_t);
13817 (void)opn; /* avoid a compiler warning */
13818 MIPS_DEBUG("%s", opn);
13821 static void gen_mipsdsp_add_cmp_pick(DisasContext *ctx,
13822 uint32_t op1, uint32_t op2,
13823 int ret, int v1, int v2, int check_ret)
13825 const char *opn = "mipsdsp add compare pick";
13831 if ((ret == 0) && (check_ret == 1)) {
13832 /* Treat as NOP. */
13837 t0 = tcg_temp_new_i32();
13838 t1 = tcg_temp_new();
13839 v1_t = tcg_temp_new();
13840 v2_t = tcg_temp_new();
13842 gen_load_gpr(v1_t, v1);
13843 gen_load_gpr(v2_t, v2);
13846 case OPC_APPEND_DSP:
13849 tcg_gen_movi_i32(t0, v2);
13850 gen_helper_append(cpu_gpr[ret], cpu_gpr[ret], v1_t, t0);
13853 tcg_gen_movi_i32(t0, v2);
13854 gen_helper_prepend(cpu_gpr[ret], v1_t, cpu_gpr[ret], t0);
13857 tcg_gen_movi_i32(t0, v2);
13858 gen_helper_balign(cpu_gpr[ret], v1_t, cpu_gpr[ret], t0);
13860 default: /* Invid */
13861 MIPS_INVAL("MASK APPEND");
13862 generate_exception(ctx, EXCP_RI);
13866 case OPC_CMPU_EQ_QB_DSP:
13868 case OPC_CMPU_EQ_QB:
13870 gen_helper_cmpu_eq_qb(v1_t, v2_t, cpu_env);
13872 case OPC_CMPU_LT_QB:
13874 gen_helper_cmpu_lt_qb(v1_t, v2_t, cpu_env);
13876 case OPC_CMPU_LE_QB:
13878 gen_helper_cmpu_le_qb(v1_t, v2_t, cpu_env);
13880 case OPC_CMPGU_EQ_QB:
13882 gen_helper_cmpgu_eq_qb(cpu_gpr[ret], v1_t, v2_t);
13884 case OPC_CMPGU_LT_QB:
13886 gen_helper_cmpgu_lt_qb(cpu_gpr[ret], v1_t, v2_t);
13888 case OPC_CMPGU_LE_QB:
13890 gen_helper_cmpgu_le_qb(cpu_gpr[ret], v1_t, v2_t);
13892 case OPC_CMPGDU_EQ_QB:
13894 gen_helper_cmpgu_eq_qb(t1, v1_t, v2_t);
13895 tcg_gen_mov_tl(cpu_gpr[ret], t1);
13896 tcg_gen_andi_tl(cpu_dspctrl, cpu_dspctrl, 0xF0FFFFFF);
13897 tcg_gen_shli_tl(t1, t1, 24);
13898 tcg_gen_or_tl(cpu_dspctrl, cpu_dspctrl, t1);
13900 case OPC_CMPGDU_LT_QB:
13902 gen_helper_cmpgu_lt_qb(t1, v1_t, v2_t);
13903 tcg_gen_mov_tl(cpu_gpr[ret], t1);
13904 tcg_gen_andi_tl(cpu_dspctrl, cpu_dspctrl, 0xF0FFFFFF);
13905 tcg_gen_shli_tl(t1, t1, 24);
13906 tcg_gen_or_tl(cpu_dspctrl, cpu_dspctrl, t1);
13908 case OPC_CMPGDU_LE_QB:
13910 gen_helper_cmpgu_le_qb(t1, v1_t, v2_t);
13911 tcg_gen_mov_tl(cpu_gpr[ret], t1);
13912 tcg_gen_andi_tl(cpu_dspctrl, cpu_dspctrl, 0xF0FFFFFF);
13913 tcg_gen_shli_tl(t1, t1, 24);
13914 tcg_gen_or_tl(cpu_dspctrl, cpu_dspctrl, t1);
13916 case OPC_CMP_EQ_PH:
13918 gen_helper_cmp_eq_ph(v1_t, v2_t, cpu_env);
13920 case OPC_CMP_LT_PH:
13922 gen_helper_cmp_lt_ph(v1_t, v2_t, cpu_env);
13924 case OPC_CMP_LE_PH:
13926 gen_helper_cmp_le_ph(v1_t, v2_t, cpu_env);
13930 gen_helper_pick_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13934 gen_helper_pick_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13936 case OPC_PACKRL_PH:
13938 gen_helper_packrl_ph(cpu_gpr[ret], v1_t, v2_t);
13942 #ifdef TARGET_MIPS64
13943 case OPC_CMPU_EQ_OB_DSP:
13945 case OPC_CMP_EQ_PW:
13947 gen_helper_cmp_eq_pw(v1_t, v2_t, cpu_env);
13949 case OPC_CMP_LT_PW:
13951 gen_helper_cmp_lt_pw(v1_t, v2_t, cpu_env);
13953 case OPC_CMP_LE_PW:
13955 gen_helper_cmp_le_pw(v1_t, v2_t, cpu_env);
13957 case OPC_CMP_EQ_QH:
13959 gen_helper_cmp_eq_qh(v1_t, v2_t, cpu_env);
13961 case OPC_CMP_LT_QH:
13963 gen_helper_cmp_lt_qh(v1_t, v2_t, cpu_env);
13965 case OPC_CMP_LE_QH:
13967 gen_helper_cmp_le_qh(v1_t, v2_t, cpu_env);
13969 case OPC_CMPGDU_EQ_OB:
13971 gen_helper_cmpgdu_eq_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13973 case OPC_CMPGDU_LT_OB:
13975 gen_helper_cmpgdu_lt_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13977 case OPC_CMPGDU_LE_OB:
13979 gen_helper_cmpgdu_le_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13981 case OPC_CMPGU_EQ_OB:
13983 gen_helper_cmpgu_eq_ob(cpu_gpr[ret], v1_t, v2_t);
13985 case OPC_CMPGU_LT_OB:
13987 gen_helper_cmpgu_lt_ob(cpu_gpr[ret], v1_t, v2_t);
13989 case OPC_CMPGU_LE_OB:
13991 gen_helper_cmpgu_le_ob(cpu_gpr[ret], v1_t, v2_t);
13993 case OPC_CMPU_EQ_OB:
13995 gen_helper_cmpu_eq_ob(v1_t, v2_t, cpu_env);
13997 case OPC_CMPU_LT_OB:
13999 gen_helper_cmpu_lt_ob(v1_t, v2_t, cpu_env);
14001 case OPC_CMPU_LE_OB:
14003 gen_helper_cmpu_le_ob(v1_t, v2_t, cpu_env);
14005 case OPC_PACKRL_PW:
14007 gen_helper_packrl_pw(cpu_gpr[ret], v1_t, v2_t);
14011 gen_helper_pick_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
14015 gen_helper_pick_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
14019 gen_helper_pick_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
14023 case OPC_DAPPEND_DSP:
14026 tcg_gen_movi_i32(t0, v2);
14027 gen_helper_dappend(cpu_gpr[ret], v1_t, cpu_gpr[ret], t0);
14030 tcg_gen_movi_i32(t0, v2);
14031 gen_helper_prependd(cpu_gpr[ret], v1_t, cpu_gpr[ret], t0);
14034 tcg_gen_movi_i32(t0, v2);
14035 gen_helper_prependw(cpu_gpr[ret], v1_t, cpu_gpr[ret], t0);
14038 tcg_gen_movi_i32(t0, v2);
14039 gen_helper_dbalign(cpu_gpr[ret], v1_t, cpu_gpr[ret], t0);
14041 default: /* Invalid */
14042 MIPS_INVAL("MASK DAPPEND");
14043 generate_exception(ctx, EXCP_RI);
14050 tcg_temp_free_i32(t0);
14052 tcg_temp_free(v1_t);
14053 tcg_temp_free(v2_t);
14055 (void)opn; /* avoid a compiler warning */
14056 MIPS_DEBUG("%s", opn);
14059 static void gen_mipsdsp_accinsn(DisasContext *ctx, uint32_t op1, uint32_t op2,
14060 int ret, int v1, int v2, int check_ret)
14063 const char *opn = "mipsdsp accumulator";
14070 if ((ret == 0) && (check_ret == 1)) {
14071 /* Treat as NOP. */
14076 t0 = tcg_temp_new();
14077 t1 = tcg_temp_new();
14078 v1_t = tcg_temp_new();
14079 v2_t = tcg_temp_new();
14081 gen_load_gpr(v1_t, v1);
14082 gen_load_gpr(v2_t, v2);
14085 case OPC_EXTR_W_DSP:
14089 tcg_gen_movi_tl(t0, v2);
14090 tcg_gen_movi_tl(t1, v1);
14091 gen_helper_extr_w(cpu_gpr[ret], t0, t1, cpu_env);
14094 tcg_gen_movi_tl(t0, v2);
14095 tcg_gen_movi_tl(t1, v1);
14096 gen_helper_extr_r_w(cpu_gpr[ret], t0, t1, cpu_env);
14098 case OPC_EXTR_RS_W:
14099 tcg_gen_movi_tl(t0, v2);
14100 tcg_gen_movi_tl(t1, v1);
14101 gen_helper_extr_rs_w(cpu_gpr[ret], t0, t1, cpu_env);
14104 tcg_gen_movi_tl(t0, v2);
14105 tcg_gen_movi_tl(t1, v1);
14106 gen_helper_extr_s_h(cpu_gpr[ret], t0, t1, cpu_env);
14108 case OPC_EXTRV_S_H:
14109 tcg_gen_movi_tl(t0, v2);
14110 gen_helper_extr_s_h(cpu_gpr[ret], t0, v1_t, cpu_env);
14113 tcg_gen_movi_tl(t0, v2);
14114 gen_helper_extr_w(cpu_gpr[ret], t0, v1_t, cpu_env);
14116 case OPC_EXTRV_R_W:
14117 tcg_gen_movi_tl(t0, v2);
14118 gen_helper_extr_r_w(cpu_gpr[ret], t0, v1_t, cpu_env);
14120 case OPC_EXTRV_RS_W:
14121 tcg_gen_movi_tl(t0, v2);
14122 gen_helper_extr_rs_w(cpu_gpr[ret], t0, v1_t, cpu_env);
14125 tcg_gen_movi_tl(t0, v2);
14126 tcg_gen_movi_tl(t1, v1);
14127 gen_helper_extp(cpu_gpr[ret], t0, t1, cpu_env);
14130 tcg_gen_movi_tl(t0, v2);
14131 gen_helper_extp(cpu_gpr[ret], t0, v1_t, cpu_env);
14134 tcg_gen_movi_tl(t0, v2);
14135 tcg_gen_movi_tl(t1, v1);
14136 gen_helper_extpdp(cpu_gpr[ret], t0, t1, cpu_env);
14139 tcg_gen_movi_tl(t0, v2);
14140 gen_helper_extpdp(cpu_gpr[ret], t0, v1_t, cpu_env);
14143 imm = (ctx->opcode >> 20) & 0x3F;
14144 tcg_gen_movi_tl(t0, ret);
14145 tcg_gen_movi_tl(t1, imm);
14146 gen_helper_shilo(t0, t1, cpu_env);
14149 tcg_gen_movi_tl(t0, ret);
14150 gen_helper_shilo(t0, v1_t, cpu_env);
14153 tcg_gen_movi_tl(t0, ret);
14154 gen_helper_mthlip(t0, v1_t, cpu_env);
14157 imm = (ctx->opcode >> 11) & 0x3FF;
14158 tcg_gen_movi_tl(t0, imm);
14159 gen_helper_wrdsp(v1_t, t0, cpu_env);
14162 imm = (ctx->opcode >> 16) & 0x03FF;
14163 tcg_gen_movi_tl(t0, imm);
14164 gen_helper_rddsp(cpu_gpr[ret], t0, cpu_env);
14168 #ifdef TARGET_MIPS64
14169 case OPC_DEXTR_W_DSP:
14173 tcg_gen_movi_tl(t0, ret);
14174 gen_helper_dmthlip(v1_t, t0, cpu_env);
14178 int shift = (ctx->opcode >> 19) & 0x7F;
14179 int ac = (ctx->opcode >> 11) & 0x03;
14180 tcg_gen_movi_tl(t0, shift);
14181 tcg_gen_movi_tl(t1, ac);
14182 gen_helper_dshilo(t0, t1, cpu_env);
14187 int ac = (ctx->opcode >> 11) & 0x03;
14188 tcg_gen_movi_tl(t0, ac);
14189 gen_helper_dshilo(v1_t, t0, cpu_env);
14193 tcg_gen_movi_tl(t0, v2);
14194 tcg_gen_movi_tl(t1, v1);
14196 gen_helper_dextp(cpu_gpr[ret], t0, t1, cpu_env);
14199 tcg_gen_movi_tl(t0, v2);
14200 gen_helper_dextp(cpu_gpr[ret], t0, v1_t, cpu_env);
14203 tcg_gen_movi_tl(t0, v2);
14204 tcg_gen_movi_tl(t1, v1);
14205 gen_helper_dextpdp(cpu_gpr[ret], t0, t1, cpu_env);
14208 tcg_gen_movi_tl(t0, v2);
14209 gen_helper_dextpdp(cpu_gpr[ret], t0, v1_t, cpu_env);
14212 tcg_gen_movi_tl(t0, v2);
14213 tcg_gen_movi_tl(t1, v1);
14214 gen_helper_dextr_l(cpu_gpr[ret], t0, t1, cpu_env);
14216 case OPC_DEXTR_R_L:
14217 tcg_gen_movi_tl(t0, v2);
14218 tcg_gen_movi_tl(t1, v1);
14219 gen_helper_dextr_r_l(cpu_gpr[ret], t0, t1, cpu_env);
14221 case OPC_DEXTR_RS_L:
14222 tcg_gen_movi_tl(t0, v2);
14223 tcg_gen_movi_tl(t1, v1);
14224 gen_helper_dextr_rs_l(cpu_gpr[ret], t0, t1, cpu_env);
14227 tcg_gen_movi_tl(t0, v2);
14228 tcg_gen_movi_tl(t1, v1);
14229 gen_helper_dextr_w(cpu_gpr[ret], t0, t1, cpu_env);
14231 case OPC_DEXTR_R_W:
14232 tcg_gen_movi_tl(t0, v2);
14233 tcg_gen_movi_tl(t1, v1);
14234 gen_helper_dextr_r_w(cpu_gpr[ret], t0, t1, cpu_env);
14236 case OPC_DEXTR_RS_W:
14237 tcg_gen_movi_tl(t0, v2);
14238 tcg_gen_movi_tl(t1, v1);
14239 gen_helper_dextr_rs_w(cpu_gpr[ret], t0, t1, cpu_env);
14241 case OPC_DEXTR_S_H:
14242 tcg_gen_movi_tl(t0, v2);
14243 tcg_gen_movi_tl(t1, v1);
14244 gen_helper_dextr_s_h(cpu_gpr[ret], t0, t1, cpu_env);
14246 case OPC_DEXTRV_S_H:
14247 tcg_gen_movi_tl(t0, v2);
14248 tcg_gen_movi_tl(t1, v1);
14249 gen_helper_dextr_s_h(cpu_gpr[ret], t0, t1, cpu_env);
14252 tcg_gen_movi_tl(t0, v2);
14253 gen_helper_dextr_l(cpu_gpr[ret], t0, v1_t, cpu_env);
14255 case OPC_DEXTRV_R_L:
14256 tcg_gen_movi_tl(t0, v2);
14257 gen_helper_dextr_r_l(cpu_gpr[ret], t0, v1_t, cpu_env);
14259 case OPC_DEXTRV_RS_L:
14260 tcg_gen_movi_tl(t0, v2);
14261 gen_helper_dextr_rs_l(cpu_gpr[ret], t0, v1_t, cpu_env);
14264 tcg_gen_movi_tl(t0, v2);
14265 gen_helper_dextr_w(cpu_gpr[ret], t0, v1_t, cpu_env);
14267 case OPC_DEXTRV_R_W:
14268 tcg_gen_movi_tl(t0, v2);
14269 gen_helper_dextr_r_w(cpu_gpr[ret], t0, v1_t, cpu_env);
14271 case OPC_DEXTRV_RS_W:
14272 tcg_gen_movi_tl(t0, v2);
14273 gen_helper_dextr_rs_w(cpu_gpr[ret], t0, v1_t, cpu_env);
14282 tcg_temp_free(v1_t);
14283 tcg_temp_free(v2_t);
14285 (void)opn; /* avoid a compiler warning */
14286 MIPS_DEBUG("%s", opn);
14289 /* End MIPSDSP functions. */
14291 static void decode_opc (CPUMIPSState *env, DisasContext *ctx, int *is_branch)
14294 int rs, rt, rd, sa;
14295 uint32_t op, op1, op2;
14298 /* make sure instructions are on a word boundary */
14299 if (ctx->pc & 0x3) {
14300 env->CP0_BadVAddr = ctx->pc;
14301 generate_exception(ctx, EXCP_AdEL);
14305 /* Handle blikely not taken case */
14306 if ((ctx->hflags & MIPS_HFLAG_BMASK_BASE) == MIPS_HFLAG_BL) {
14307 int l1 = gen_new_label();
14309 MIPS_DEBUG("blikely condition (" TARGET_FMT_lx ")", ctx->pc + 4);
14310 tcg_gen_brcondi_tl(TCG_COND_NE, bcond, 0, l1);
14311 tcg_gen_movi_i32(hflags, ctx->hflags & ~MIPS_HFLAG_BMASK);
14312 gen_goto_tb(ctx, 1, ctx->pc + 4);
14316 if (unlikely(qemu_loglevel_mask(CPU_LOG_TB_OP | CPU_LOG_TB_OP_OPT))) {
14317 tcg_gen_debug_insn_start(ctx->pc);
14320 op = MASK_OP_MAJOR(ctx->opcode);
14321 rs = (ctx->opcode >> 21) & 0x1f;
14322 rt = (ctx->opcode >> 16) & 0x1f;
14323 rd = (ctx->opcode >> 11) & 0x1f;
14324 sa = (ctx->opcode >> 6) & 0x1f;
14325 imm = (int16_t)ctx->opcode;
14328 op1 = MASK_SPECIAL(ctx->opcode);
14330 case OPC_SLL: /* Shift with immediate */
14332 gen_shift_imm(env, ctx, op1, rd, rt, sa);
14335 switch ((ctx->opcode >> 21) & 0x1f) {
14337 /* rotr is decoded as srl on non-R2 CPUs */
14338 if (env->insn_flags & ISA_MIPS32R2) {
14343 gen_shift_imm(env, ctx, op1, rd, rt, sa);
14346 generate_exception(ctx, EXCP_RI);
14350 case OPC_MOVN: /* Conditional move */
14352 check_insn(env, ctx, ISA_MIPS4 | ISA_MIPS32 |
14353 INSN_LOONGSON2E | INSN_LOONGSON2F);
14354 gen_cond_move(env, ctx, op1, rd, rs, rt);
14356 case OPC_ADD ... OPC_SUBU:
14357 gen_arith(env, ctx, op1, rd, rs, rt);
14359 case OPC_SLLV: /* Shifts */
14361 gen_shift(env, ctx, op1, rd, rs, rt);
14364 switch ((ctx->opcode >> 6) & 0x1f) {
14366 /* rotrv is decoded as srlv on non-R2 CPUs */
14367 if (env->insn_flags & ISA_MIPS32R2) {
14372 gen_shift(env, ctx, op1, rd, rs, rt);
14375 generate_exception(ctx, EXCP_RI);
14379 case OPC_SLT: /* Set on less than */
14381 gen_slt(env, ctx, op1, rd, rs, rt);
14383 case OPC_AND: /* Logic*/
14387 gen_logic(env, ctx, op1, rd, rs, rt);
14389 case OPC_MULT ... OPC_DIVU:
14391 check_insn(env, ctx, INSN_VR54XX);
14392 op1 = MASK_MUL_VR54XX(ctx->opcode);
14393 gen_mul_vr54xx(ctx, op1, rd, rs, rt);
14395 gen_muldiv(ctx, op1, rs, rt);
14397 case OPC_JR ... OPC_JALR:
14398 gen_compute_branch(ctx, op1, 4, rs, rd, sa);
14401 case OPC_TGE ... OPC_TEQ: /* Traps */
14403 gen_trap(ctx, op1, rs, rt, -1);
14405 case OPC_MFHI: /* Move from HI/LO */
14407 gen_HILO(ctx, op1, rd);
14410 case OPC_MTLO: /* Move to HI/LO */
14411 gen_HILO(ctx, op1, rs);
14413 case OPC_PMON: /* Pmon entry point, also R4010 selsl */
14414 #ifdef MIPS_STRICT_STANDARD
14415 MIPS_INVAL("PMON / selsl");
14416 generate_exception(ctx, EXCP_RI);
14418 gen_helper_0e0i(pmon, sa);
14422 generate_exception(ctx, EXCP_SYSCALL);
14423 ctx->bstate = BS_STOP;
14426 generate_exception(ctx, EXCP_BREAK);
14429 #ifdef MIPS_STRICT_STANDARD
14430 MIPS_INVAL("SPIM");
14431 generate_exception(ctx, EXCP_RI);
14433 /* Implemented as RI exception for now. */
14434 MIPS_INVAL("spim (unofficial)");
14435 generate_exception(ctx, EXCP_RI);
14439 /* Treat as NOP. */
14443 check_insn(env, ctx, ISA_MIPS4 | ISA_MIPS32);
14444 if (env->CP0_Config1 & (1 << CP0C1_FP)) {
14445 check_cp1_enabled(ctx);
14446 gen_movci(ctx, rd, rs, (ctx->opcode >> 18) & 0x7,
14447 (ctx->opcode >> 16) & 1);
14449 generate_exception_err(ctx, EXCP_CpU, 1);
14453 #if defined(TARGET_MIPS64)
14454 /* MIPS64 specific opcodes */
14459 check_insn(env, ctx, ISA_MIPS3);
14460 check_mips_64(ctx);
14461 gen_shift_imm(env, ctx, op1, rd, rt, sa);
14464 switch ((ctx->opcode >> 21) & 0x1f) {
14466 /* drotr is decoded as dsrl on non-R2 CPUs */
14467 if (env->insn_flags & ISA_MIPS32R2) {
14472 check_insn(env, ctx, ISA_MIPS3);
14473 check_mips_64(ctx);
14474 gen_shift_imm(env, ctx, op1, rd, rt, sa);
14477 generate_exception(ctx, EXCP_RI);
14482 switch ((ctx->opcode >> 21) & 0x1f) {
14484 /* drotr32 is decoded as dsrl32 on non-R2 CPUs */
14485 if (env->insn_flags & ISA_MIPS32R2) {
14490 check_insn(env, ctx, ISA_MIPS3);
14491 check_mips_64(ctx);
14492 gen_shift_imm(env, ctx, op1, rd, rt, sa);
14495 generate_exception(ctx, EXCP_RI);
14499 case OPC_DADD ... OPC_DSUBU:
14500 check_insn(env, ctx, ISA_MIPS3);
14501 check_mips_64(ctx);
14502 gen_arith(env, ctx, op1, rd, rs, rt);
14506 check_insn(env, ctx, ISA_MIPS3);
14507 check_mips_64(ctx);
14508 gen_shift(env, ctx, op1, rd, rs, rt);
14511 switch ((ctx->opcode >> 6) & 0x1f) {
14513 /* drotrv is decoded as dsrlv on non-R2 CPUs */
14514 if (env->insn_flags & ISA_MIPS32R2) {
14519 check_insn(env, ctx, ISA_MIPS3);
14520 check_mips_64(ctx);
14521 gen_shift(env, ctx, op1, rd, rs, rt);
14524 generate_exception(ctx, EXCP_RI);
14528 case OPC_DMULT ... OPC_DDIVU:
14529 check_insn(env, ctx, ISA_MIPS3);
14530 check_mips_64(ctx);
14531 gen_muldiv(ctx, op1, rs, rt);
14534 default: /* Invalid */
14535 MIPS_INVAL("special");
14536 generate_exception(ctx, EXCP_RI);
14541 op1 = MASK_SPECIAL2(ctx->opcode);
14543 case OPC_MADD ... OPC_MADDU: /* Multiply and add/sub */
14544 case OPC_MSUB ... OPC_MSUBU:
14545 check_insn(env, ctx, ISA_MIPS32);
14546 gen_muldiv(ctx, op1, rs, rt);
14549 gen_arith(env, ctx, op1, rd, rs, rt);
14553 check_insn(env, ctx, ISA_MIPS32);
14554 gen_cl(ctx, op1, rd, rs);
14557 /* XXX: not clear which exception should be raised
14558 * when in debug mode...
14560 check_insn(env, ctx, ISA_MIPS32);
14561 if (!(ctx->hflags & MIPS_HFLAG_DM)) {
14562 generate_exception(ctx, EXCP_DBp);
14564 generate_exception(ctx, EXCP_DBp);
14566 /* Treat as NOP. */
14569 case OPC_DIVU_G_2F:
14570 case OPC_MULT_G_2F:
14571 case OPC_MULTU_G_2F:
14573 case OPC_MODU_G_2F:
14574 check_insn(env, ctx, INSN_LOONGSON2F);
14575 gen_loongson_integer(ctx, op1, rd, rs, rt);
14577 #if defined(TARGET_MIPS64)
14580 check_insn(env, ctx, ISA_MIPS64);
14581 check_mips_64(ctx);
14582 gen_cl(ctx, op1, rd, rs);
14584 case OPC_DMULT_G_2F:
14585 case OPC_DMULTU_G_2F:
14586 case OPC_DDIV_G_2F:
14587 case OPC_DDIVU_G_2F:
14588 case OPC_DMOD_G_2F:
14589 case OPC_DMODU_G_2F:
14590 check_insn(env, ctx, INSN_LOONGSON2F);
14591 gen_loongson_integer(ctx, op1, rd, rs, rt);
14594 default: /* Invalid */
14595 MIPS_INVAL("special2");
14596 generate_exception(ctx, EXCP_RI);
14601 op1 = MASK_SPECIAL3(ctx->opcode);
14605 check_insn(env, ctx, ISA_MIPS32R2);
14606 gen_bitops(ctx, op1, rt, rs, sa, rd);
14609 check_insn(env, ctx, ISA_MIPS32R2);
14610 op2 = MASK_BSHFL(ctx->opcode);
14611 gen_bshfl(ctx, op2, rt, rd);
14614 gen_rdhwr(env, ctx, rt, rd);
14617 check_insn(env, ctx, ASE_MT);
14619 TCGv t0 = tcg_temp_new();
14620 TCGv t1 = tcg_temp_new();
14622 gen_load_gpr(t0, rt);
14623 gen_load_gpr(t1, rs);
14624 gen_helper_fork(t0, t1);
14630 check_insn(env, ctx, ASE_MT);
14632 TCGv t0 = tcg_temp_new();
14634 save_cpu_state(ctx, 1);
14635 gen_load_gpr(t0, rs);
14636 gen_helper_yield(t0, cpu_env, t0);
14637 gen_store_gpr(t0, rd);
14641 case OPC_DIV_G_2E ... OPC_DIVU_G_2E:
14642 case OPC_MOD_G_2E ... OPC_MODU_G_2E:
14643 case OPC_MULT_G_2E ... OPC_MULTU_G_2E:
14644 /* OPC_MULT_G_2E, OPC_ADDUH_QB_DSP, OPC_MUL_PH_DSP have
14645 * the same mask and op1. */
14646 if ((env->insn_flags & ASE_DSPR2) && (op1 == OPC_MULT_G_2E)) {
14647 op2 = MASK_ADDUH_QB(ctx->opcode);
14650 case OPC_ADDUH_R_QB:
14652 case OPC_ADDQH_R_PH:
14654 case OPC_ADDQH_R_W:
14656 case OPC_SUBUH_R_QB:
14658 case OPC_SUBQH_R_PH:
14660 case OPC_SUBQH_R_W:
14661 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
14666 case OPC_MULQ_RS_W:
14667 gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 1);
14670 MIPS_INVAL("MASK ADDUH.QB");
14671 generate_exception(ctx, EXCP_RI);
14674 } else if (env->insn_flags & INSN_LOONGSON2E) {
14675 gen_loongson_integer(ctx, op1, rd, rs, rt);
14677 generate_exception(ctx, EXCP_RI);
14681 op2 = MASK_LX(ctx->opcode);
14683 #if defined(TARGET_MIPS64)
14689 gen_mipsdsp_ld(env, ctx, op2, rd, rs, rt);
14691 default: /* Invalid */
14692 MIPS_INVAL("MASK LX");
14693 generate_exception(ctx, EXCP_RI);
14697 case OPC_ABSQ_S_PH_DSP:
14698 op2 = MASK_ABSQ_S_PH(ctx->opcode);
14700 case OPC_ABSQ_S_QB:
14701 case OPC_ABSQ_S_PH:
14703 case OPC_PRECEQ_W_PHL:
14704 case OPC_PRECEQ_W_PHR:
14705 case OPC_PRECEQU_PH_QBL:
14706 case OPC_PRECEQU_PH_QBR:
14707 case OPC_PRECEQU_PH_QBLA:
14708 case OPC_PRECEQU_PH_QBRA:
14709 case OPC_PRECEU_PH_QBL:
14710 case OPC_PRECEU_PH_QBR:
14711 case OPC_PRECEU_PH_QBLA:
14712 case OPC_PRECEU_PH_QBRA:
14713 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
14720 gen_mipsdsp_bitinsn(env, ctx, op1, op2, rd, rt);
14723 MIPS_INVAL("MASK ABSQ_S.PH");
14724 generate_exception(ctx, EXCP_RI);
14728 case OPC_ADDU_QB_DSP:
14729 op2 = MASK_ADDU_QB(ctx->opcode);
14732 case OPC_ADDQ_S_PH:
14735 case OPC_ADDU_S_QB:
14737 case OPC_ADDU_S_PH:
14739 case OPC_SUBQ_S_PH:
14742 case OPC_SUBU_S_QB:
14744 case OPC_SUBU_S_PH:
14748 case OPC_RADDU_W_QB:
14749 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
14751 case OPC_MULEU_S_PH_QBL:
14752 case OPC_MULEU_S_PH_QBR:
14753 case OPC_MULQ_RS_PH:
14754 case OPC_MULEQ_S_W_PHL:
14755 case OPC_MULEQ_S_W_PHR:
14756 case OPC_MULQ_S_PH:
14757 gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 1);
14759 default: /* Invalid */
14760 MIPS_INVAL("MASK ADDU.QB");
14761 generate_exception(ctx, EXCP_RI);
14766 case OPC_CMPU_EQ_QB_DSP:
14767 op2 = MASK_CMPU_EQ_QB(ctx->opcode);
14769 case OPC_PRECR_SRA_PH_W:
14770 case OPC_PRECR_SRA_R_PH_W:
14771 gen_mipsdsp_arith(ctx, op1, op2, rt, rs, rd);
14773 case OPC_PRECR_QB_PH:
14774 case OPC_PRECRQ_QB_PH:
14775 case OPC_PRECRQ_PH_W:
14776 case OPC_PRECRQ_RS_PH_W:
14777 case OPC_PRECRQU_S_QB_PH:
14778 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
14780 case OPC_CMPU_EQ_QB:
14781 case OPC_CMPU_LT_QB:
14782 case OPC_CMPU_LE_QB:
14783 case OPC_CMP_EQ_PH:
14784 case OPC_CMP_LT_PH:
14785 case OPC_CMP_LE_PH:
14786 gen_mipsdsp_add_cmp_pick(ctx, op1, op2, rd, rs, rt, 0);
14788 case OPC_CMPGU_EQ_QB:
14789 case OPC_CMPGU_LT_QB:
14790 case OPC_CMPGU_LE_QB:
14791 case OPC_CMPGDU_EQ_QB:
14792 case OPC_CMPGDU_LT_QB:
14793 case OPC_CMPGDU_LE_QB:
14796 case OPC_PACKRL_PH:
14797 gen_mipsdsp_add_cmp_pick(ctx, op1, op2, rd, rs, rt, 1);
14799 default: /* Invalid */
14800 MIPS_INVAL("MASK CMPU.EQ.QB");
14801 generate_exception(ctx, EXCP_RI);
14805 case OPC_SHLL_QB_DSP:
14806 gen_mipsdsp_shift(ctx, op1, rd, rs, rt);
14808 case OPC_DPA_W_PH_DSP:
14809 op2 = MASK_DPA_W_PH(ctx->opcode);
14811 case OPC_DPAU_H_QBL:
14812 case OPC_DPAU_H_QBR:
14813 case OPC_DPSU_H_QBL:
14814 case OPC_DPSU_H_QBR:
14816 case OPC_DPAX_W_PH:
14817 case OPC_DPAQ_S_W_PH:
14818 case OPC_DPAQX_S_W_PH:
14819 case OPC_DPAQX_SA_W_PH:
14821 case OPC_DPSX_W_PH:
14822 case OPC_DPSQ_S_W_PH:
14823 case OPC_DPSQX_S_W_PH:
14824 case OPC_DPSQX_SA_W_PH:
14825 case OPC_MULSAQ_S_W_PH:
14826 case OPC_DPAQ_SA_L_W:
14827 case OPC_DPSQ_SA_L_W:
14828 case OPC_MAQ_S_W_PHL:
14829 case OPC_MAQ_S_W_PHR:
14830 case OPC_MAQ_SA_W_PHL:
14831 case OPC_MAQ_SA_W_PHR:
14832 case OPC_MULSA_W_PH:
14833 gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 0);
14835 default: /* Invalid */
14836 MIPS_INVAL("MASK DPAW.PH");
14837 generate_exception(ctx, EXCP_RI);
14842 op2 = MASK_INSV(ctx->opcode);
14854 t0 = tcg_temp_new();
14855 t1 = tcg_temp_new();
14857 gen_load_gpr(t0, rt);
14858 gen_load_gpr(t1, rs);
14860 gen_helper_insv(cpu_gpr[rt], cpu_env, t1, t0);
14866 default: /* Invalid */
14867 MIPS_INVAL("MASK INSV");
14868 generate_exception(ctx, EXCP_RI);
14872 case OPC_APPEND_DSP:
14874 op2 = MASK_APPEND(ctx->opcode);
14875 gen_mipsdsp_add_cmp_pick(ctx, op1, op2, rt, rs, rd, 1);
14877 case OPC_EXTR_W_DSP:
14878 op2 = MASK_EXTR_W(ctx->opcode);
14882 case OPC_EXTR_RS_W:
14884 case OPC_EXTRV_S_H:
14886 case OPC_EXTRV_R_W:
14887 case OPC_EXTRV_RS_W:
14892 gen_mipsdsp_accinsn(ctx, op1, op2, rt, rs, rd, 1);
14895 gen_mipsdsp_accinsn(ctx, op1, op2, rd, rs, rt, 1);
14901 gen_mipsdsp_accinsn(ctx, op1, op2, rd, rs, rt, 0);
14903 default: /* Invalid */
14904 MIPS_INVAL("MASK EXTR.W");
14905 generate_exception(ctx, EXCP_RI);
14909 #if defined(TARGET_MIPS64)
14910 case OPC_DEXTM ... OPC_DEXT:
14911 case OPC_DINSM ... OPC_DINS:
14912 check_insn(env, ctx, ISA_MIPS64R2);
14913 check_mips_64(ctx);
14914 gen_bitops(ctx, op1, rt, rs, sa, rd);
14917 check_insn(env, ctx, ISA_MIPS64R2);
14918 check_mips_64(ctx);
14919 op2 = MASK_DBSHFL(ctx->opcode);
14920 gen_bshfl(ctx, op2, rt, rd);
14922 case OPC_DDIV_G_2E ... OPC_DDIVU_G_2E:
14923 case OPC_DMULT_G_2E ... OPC_DMULTU_G_2E:
14924 case OPC_DMOD_G_2E ... OPC_DMODU_G_2E:
14925 check_insn(env, ctx, INSN_LOONGSON2E);
14926 gen_loongson_integer(ctx, op1, rd, rs, rt);
14928 case OPC_ABSQ_S_QH_DSP:
14929 op2 = MASK_ABSQ_S_QH(ctx->opcode);
14931 case OPC_PRECEQ_L_PWL:
14932 case OPC_PRECEQ_L_PWR:
14933 case OPC_PRECEQ_PW_QHL:
14934 case OPC_PRECEQ_PW_QHR:
14935 case OPC_PRECEQ_PW_QHLA:
14936 case OPC_PRECEQ_PW_QHRA:
14937 case OPC_PRECEQU_QH_OBL:
14938 case OPC_PRECEQU_QH_OBR:
14939 case OPC_PRECEQU_QH_OBLA:
14940 case OPC_PRECEQU_QH_OBRA:
14941 case OPC_PRECEU_QH_OBL:
14942 case OPC_PRECEU_QH_OBR:
14943 case OPC_PRECEU_QH_OBLA:
14944 case OPC_PRECEU_QH_OBRA:
14945 case OPC_ABSQ_S_OB:
14946 case OPC_ABSQ_S_PW:
14947 case OPC_ABSQ_S_QH:
14948 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
14956 gen_mipsdsp_bitinsn(env, ctx, op1, op2, rd, rt);
14958 default: /* Invalid */
14959 MIPS_INVAL("MASK ABSQ_S.QH");
14960 generate_exception(ctx, EXCP_RI);
14964 case OPC_ADDU_OB_DSP:
14965 op2 = MASK_ADDU_OB(ctx->opcode);
14967 case OPC_RADDU_L_OB:
14969 case OPC_SUBQ_S_PW:
14971 case OPC_SUBQ_S_QH:
14973 case OPC_SUBU_S_OB:
14975 case OPC_SUBU_S_QH:
14977 case OPC_SUBUH_R_OB:
14979 case OPC_ADDQ_S_PW:
14981 case OPC_ADDQ_S_QH:
14983 case OPC_ADDU_S_OB:
14985 case OPC_ADDU_S_QH:
14987 case OPC_ADDUH_R_OB:
14988 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
14990 case OPC_MULEQ_S_PW_QHL:
14991 case OPC_MULEQ_S_PW_QHR:
14992 case OPC_MULEU_S_QH_OBL:
14993 case OPC_MULEU_S_QH_OBR:
14994 case OPC_MULQ_RS_QH:
14995 gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 1);
14997 default: /* Invalid */
14998 MIPS_INVAL("MASK ADDU.OB");
14999 generate_exception(ctx, EXCP_RI);
15003 case OPC_CMPU_EQ_OB_DSP:
15004 op2 = MASK_CMPU_EQ_OB(ctx->opcode);
15006 case OPC_PRECR_SRA_QH_PW:
15007 case OPC_PRECR_SRA_R_QH_PW:
15008 /* Return value is rt. */
15009 gen_mipsdsp_arith(ctx, op1, op2, rt, rs, rd);
15011 case OPC_PRECR_OB_QH:
15012 case OPC_PRECRQ_OB_QH:
15013 case OPC_PRECRQ_PW_L:
15014 case OPC_PRECRQ_QH_PW:
15015 case OPC_PRECRQ_RS_QH_PW:
15016 case OPC_PRECRQU_S_OB_QH:
15017 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
15019 case OPC_CMPU_EQ_OB:
15020 case OPC_CMPU_LT_OB:
15021 case OPC_CMPU_LE_OB:
15022 case OPC_CMP_EQ_QH:
15023 case OPC_CMP_LT_QH:
15024 case OPC_CMP_LE_QH:
15025 case OPC_CMP_EQ_PW:
15026 case OPC_CMP_LT_PW:
15027 case OPC_CMP_LE_PW:
15028 gen_mipsdsp_add_cmp_pick(ctx, op1, op2, rd, rs, rt, 0);
15030 case OPC_CMPGDU_EQ_OB:
15031 case OPC_CMPGDU_LT_OB:
15032 case OPC_CMPGDU_LE_OB:
15033 case OPC_CMPGU_EQ_OB:
15034 case OPC_CMPGU_LT_OB:
15035 case OPC_CMPGU_LE_OB:
15036 case OPC_PACKRL_PW:
15040 gen_mipsdsp_add_cmp_pick(ctx, op1, op2, rd, rs, rt, 1);
15042 default: /* Invalid */
15043 MIPS_INVAL("MASK CMPU_EQ.OB");
15044 generate_exception(ctx, EXCP_RI);
15048 case OPC_DAPPEND_DSP:
15050 op2 = MASK_DAPPEND(ctx->opcode);
15051 gen_mipsdsp_add_cmp_pick(ctx, op1, op2, rt, rs, rd, 1);
15053 case OPC_DEXTR_W_DSP:
15054 op2 = MASK_DEXTR_W(ctx->opcode);
15061 case OPC_DEXTR_R_L:
15062 case OPC_DEXTR_RS_L:
15064 case OPC_DEXTR_R_W:
15065 case OPC_DEXTR_RS_W:
15066 case OPC_DEXTR_S_H:
15068 case OPC_DEXTRV_R_L:
15069 case OPC_DEXTRV_RS_L:
15070 case OPC_DEXTRV_S_H:
15072 case OPC_DEXTRV_R_W:
15073 case OPC_DEXTRV_RS_W:
15074 gen_mipsdsp_accinsn(ctx, op1, op2, rt, rs, rd, 1);
15079 gen_mipsdsp_accinsn(ctx, op1, op2, rd, rs, rt, 0);
15081 default: /* Invalid */
15082 MIPS_INVAL("MASK EXTR.W");
15083 generate_exception(ctx, EXCP_RI);
15087 case OPC_DPAQ_W_QH_DSP:
15088 op2 = MASK_DPAQ_W_QH(ctx->opcode);
15090 case OPC_DPAU_H_OBL:
15091 case OPC_DPAU_H_OBR:
15092 case OPC_DPSU_H_OBL:
15093 case OPC_DPSU_H_OBR:
15095 case OPC_DPAQ_S_W_QH:
15097 case OPC_DPSQ_S_W_QH:
15098 case OPC_MULSAQ_S_W_QH:
15099 case OPC_DPAQ_SA_L_PW:
15100 case OPC_DPSQ_SA_L_PW:
15101 case OPC_MULSAQ_S_L_PW:
15102 gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 0);
15104 case OPC_MAQ_S_W_QHLL:
15105 case OPC_MAQ_S_W_QHLR:
15106 case OPC_MAQ_S_W_QHRL:
15107 case OPC_MAQ_S_W_QHRR:
15108 case OPC_MAQ_SA_W_QHLL:
15109 case OPC_MAQ_SA_W_QHLR:
15110 case OPC_MAQ_SA_W_QHRL:
15111 case OPC_MAQ_SA_W_QHRR:
15112 case OPC_MAQ_S_L_PWL:
15113 case OPC_MAQ_S_L_PWR:
15118 gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 0);
15120 default: /* Invalid */
15121 MIPS_INVAL("MASK DPAQ.W.QH");
15122 generate_exception(ctx, EXCP_RI);
15126 case OPC_DINSV_DSP:
15127 op2 = MASK_INSV(ctx->opcode);
15139 t0 = tcg_temp_new();
15140 t1 = tcg_temp_new();
15142 gen_load_gpr(t0, rt);
15143 gen_load_gpr(t1, rs);
15145 gen_helper_dinsv(cpu_gpr[rt], cpu_env, t1, t0);
15148 default: /* Invalid */
15149 MIPS_INVAL("MASK DINSV");
15150 generate_exception(ctx, EXCP_RI);
15154 case OPC_SHLL_OB_DSP:
15155 gen_mipsdsp_shift(ctx, op1, rd, rs, rt);
15158 default: /* Invalid */
15159 MIPS_INVAL("special3");
15160 generate_exception(ctx, EXCP_RI);
15165 op1 = MASK_REGIMM(ctx->opcode);
15167 case OPC_BLTZ ... OPC_BGEZL: /* REGIMM branches */
15168 case OPC_BLTZAL ... OPC_BGEZALL:
15169 gen_compute_branch(ctx, op1, 4, rs, -1, imm << 2);
15172 case OPC_TGEI ... OPC_TEQI: /* REGIMM traps */
15174 gen_trap(ctx, op1, rs, -1, imm);
15177 check_insn(env, ctx, ISA_MIPS32R2);
15178 /* Treat as NOP. */
15180 case OPC_BPOSGE32: /* MIPS DSP branch */
15181 #if defined(TARGET_MIPS64)
15185 gen_compute_branch(ctx, op1, 4, -1, -2, (int32_t)imm << 2);
15188 default: /* Invalid */
15189 MIPS_INVAL("regimm");
15190 generate_exception(ctx, EXCP_RI);
15195 check_cp0_enabled(ctx);
15196 op1 = MASK_CP0(ctx->opcode);
15202 #if defined(TARGET_MIPS64)
15206 #ifndef CONFIG_USER_ONLY
15207 gen_cp0(env, ctx, op1, rt, rd);
15208 #endif /* !CONFIG_USER_ONLY */
15210 case OPC_C0_FIRST ... OPC_C0_LAST:
15211 #ifndef CONFIG_USER_ONLY
15212 gen_cp0(env, ctx, MASK_C0(ctx->opcode), rt, rd);
15213 #endif /* !CONFIG_USER_ONLY */
15216 #ifndef CONFIG_USER_ONLY
15218 TCGv t0 = tcg_temp_new();
15220 op2 = MASK_MFMC0(ctx->opcode);
15223 check_insn(env, ctx, ASE_MT);
15224 gen_helper_dmt(t0);
15225 gen_store_gpr(t0, rt);
15228 check_insn(env, ctx, ASE_MT);
15229 gen_helper_emt(t0);
15230 gen_store_gpr(t0, rt);
15233 check_insn(env, ctx, ASE_MT);
15234 gen_helper_dvpe(t0, cpu_env);
15235 gen_store_gpr(t0, rt);
15238 check_insn(env, ctx, ASE_MT);
15239 gen_helper_evpe(t0, cpu_env);
15240 gen_store_gpr(t0, rt);
15243 check_insn(env, ctx, ISA_MIPS32R2);
15244 save_cpu_state(ctx, 1);
15245 gen_helper_di(t0, cpu_env);
15246 gen_store_gpr(t0, rt);
15247 /* Stop translation as we may have switched the execution mode */
15248 ctx->bstate = BS_STOP;
15251 check_insn(env, ctx, ISA_MIPS32R2);
15252 save_cpu_state(ctx, 1);
15253 gen_helper_ei(t0, cpu_env);
15254 gen_store_gpr(t0, rt);
15255 /* Stop translation as we may have switched the execution mode */
15256 ctx->bstate = BS_STOP;
15258 default: /* Invalid */
15259 MIPS_INVAL("mfmc0");
15260 generate_exception(ctx, EXCP_RI);
15265 #endif /* !CONFIG_USER_ONLY */
15268 check_insn(env, ctx, ISA_MIPS32R2);
15269 gen_load_srsgpr(rt, rd);
15272 check_insn(env, ctx, ISA_MIPS32R2);
15273 gen_store_srsgpr(rt, rd);
15277 generate_exception(ctx, EXCP_RI);
15281 case OPC_ADDI: /* Arithmetic with immediate opcode */
15283 gen_arith_imm(env, ctx, op, rt, rs, imm);
15285 case OPC_SLTI: /* Set on less than with immediate opcode */
15287 gen_slt_imm(env, ctx, op, rt, rs, imm);
15289 case OPC_ANDI: /* Arithmetic with immediate opcode */
15293 gen_logic_imm(env, ctx, op, rt, rs, imm);
15295 case OPC_J ... OPC_JAL: /* Jump */
15296 offset = (int32_t)(ctx->opcode & 0x3FFFFFF) << 2;
15297 gen_compute_branch(ctx, op, 4, rs, rt, offset);
15300 case OPC_BEQ ... OPC_BGTZ: /* Branch */
15301 case OPC_BEQL ... OPC_BGTZL:
15302 gen_compute_branch(ctx, op, 4, rs, rt, imm << 2);
15305 case OPC_LB ... OPC_LWR: /* Load and stores */
15307 gen_ld(env, ctx, op, rt, rs, imm);
15309 case OPC_SB ... OPC_SW:
15311 gen_st(ctx, op, rt, rs, imm);
15314 gen_st_cond(ctx, op, rt, rs, imm);
15317 check_cp0_enabled(ctx);
15318 check_insn(env, ctx, ISA_MIPS3 | ISA_MIPS32);
15319 /* Treat as NOP. */
15322 check_insn(env, ctx, ISA_MIPS4 | ISA_MIPS32);
15323 /* Treat as NOP. */
15326 /* Floating point (COP1). */
15331 gen_cop1_ldst(env, ctx, op, rt, rs, imm);
15335 if (env->CP0_Config1 & (1 << CP0C1_FP)) {
15336 check_cp1_enabled(ctx);
15337 op1 = MASK_CP1(ctx->opcode);
15341 check_insn(env, ctx, ISA_MIPS32R2);
15346 gen_cp1(ctx, op1, rt, rd);
15348 #if defined(TARGET_MIPS64)
15351 check_insn(env, ctx, ISA_MIPS3);
15352 gen_cp1(ctx, op1, rt, rd);
15358 check_insn(env, ctx, ASE_MIPS3D);
15361 gen_compute_branch1(env, ctx, MASK_BC1(ctx->opcode),
15362 (rt >> 2) & 0x7, imm << 2);
15370 gen_farith(ctx, ctx->opcode & FOP(0x3f, 0x1f), rt, rd, sa,
15375 generate_exception (ctx, EXCP_RI);
15379 generate_exception_err(ctx, EXCP_CpU, 1);
15388 /* COP2: Not implemented. */
15389 generate_exception_err(ctx, EXCP_CpU, 2);
15392 check_insn(env, ctx, INSN_LOONGSON2F);
15393 /* Note that these instructions use different fields. */
15394 gen_loongson_multimedia(ctx, sa, rd, rt);
15398 if (env->CP0_Config1 & (1 << CP0C1_FP)) {
15399 check_cp1_enabled(ctx);
15400 op1 = MASK_CP3(ctx->opcode);
15408 gen_flt3_ldst(ctx, op1, sa, rd, rs, rt);
15411 /* Treat as NOP. */
15426 gen_flt3_arith(ctx, op1, sa, rs, rd, rt);
15430 generate_exception (ctx, EXCP_RI);
15434 generate_exception_err(ctx, EXCP_CpU, 1);
15438 #if defined(TARGET_MIPS64)
15439 /* MIPS64 opcodes */
15441 case OPC_LDL ... OPC_LDR:
15444 check_insn(env, ctx, ISA_MIPS3);
15445 check_mips_64(ctx);
15446 gen_ld(env, ctx, op, rt, rs, imm);
15448 case OPC_SDL ... OPC_SDR:
15450 check_insn(env, ctx, ISA_MIPS3);
15451 check_mips_64(ctx);
15452 gen_st(ctx, op, rt, rs, imm);
15455 check_insn(env, ctx, ISA_MIPS3);
15456 check_mips_64(ctx);
15457 gen_st_cond(ctx, op, rt, rs, imm);
15461 check_insn(env, ctx, ISA_MIPS3);
15462 check_mips_64(ctx);
15463 gen_arith_imm(env, ctx, op, rt, rs, imm);
15467 check_insn(env, ctx, ASE_MIPS16 | ASE_MICROMIPS);
15468 offset = (int32_t)(ctx->opcode & 0x3FFFFFF) << 2;
15469 gen_compute_branch(ctx, op, 4, rs, rt, offset);
15473 check_insn(env, ctx, ASE_MDMX);
15474 /* MDMX: Not implemented. */
15475 default: /* Invalid */
15476 MIPS_INVAL("major opcode");
15477 generate_exception(ctx, EXCP_RI);
15483 gen_intermediate_code_internal (CPUMIPSState *env, TranslationBlock *tb,
15487 target_ulong pc_start;
15488 uint16_t *gen_opc_end;
15497 qemu_log("search pc %d\n", search_pc);
15500 gen_opc_end = gen_opc_buf + OPC_MAX_SIZE;
15503 ctx.singlestep_enabled = env->singlestep_enabled;
15505 ctx.bstate = BS_NONE;
15506 /* Restore delay slot state from the tb context. */
15507 ctx.hflags = (uint32_t)tb->flags; /* FIXME: maybe use 64 bits here? */
15508 restore_cpu_state(env, &ctx);
15509 #ifdef CONFIG_USER_ONLY
15510 ctx.mem_idx = MIPS_HFLAG_UM;
15512 ctx.mem_idx = ctx.hflags & MIPS_HFLAG_KSU;
15515 max_insns = tb->cflags & CF_COUNT_MASK;
15516 if (max_insns == 0)
15517 max_insns = CF_COUNT_MASK;
15518 LOG_DISAS("\ntb %p idx %d hflags %04x\n", tb, ctx.mem_idx, ctx.hflags);
15519 gen_icount_start();
15520 while (ctx.bstate == BS_NONE) {
15521 if (unlikely(!QTAILQ_EMPTY(&env->breakpoints))) {
15522 QTAILQ_FOREACH(bp, &env->breakpoints, entry) {
15523 if (bp->pc == ctx.pc) {
15524 save_cpu_state(&ctx, 1);
15525 ctx.bstate = BS_BRANCH;
15526 gen_helper_0e0i(raise_exception, EXCP_DEBUG);
15527 /* Include the breakpoint location or the tb won't
15528 * be flushed when it must be. */
15530 goto done_generating;
15536 j = gen_opc_ptr - gen_opc_buf;
15540 gen_opc_instr_start[lj++] = 0;
15542 gen_opc_pc[lj] = ctx.pc;
15543 gen_opc_hflags[lj] = ctx.hflags & MIPS_HFLAG_BMASK;
15544 gen_opc_btarget[lj] = ctx.btarget;
15545 gen_opc_instr_start[lj] = 1;
15546 gen_opc_icount[lj] = num_insns;
15548 if (num_insns + 1 == max_insns && (tb->cflags & CF_LAST_IO))
15552 if (!(ctx.hflags & MIPS_HFLAG_M16)) {
15553 ctx.opcode = cpu_ldl_code(env, ctx.pc);
15555 decode_opc(env, &ctx, &is_branch);
15556 } else if (env->insn_flags & ASE_MICROMIPS) {
15557 ctx.opcode = cpu_lduw_code(env, ctx.pc);
15558 insn_bytes = decode_micromips_opc(env, &ctx, &is_branch);
15559 } else if (env->insn_flags & ASE_MIPS16) {
15560 ctx.opcode = cpu_lduw_code(env, ctx.pc);
15561 insn_bytes = decode_mips16_opc(env, &ctx, &is_branch);
15563 generate_exception(&ctx, EXCP_RI);
15564 ctx.bstate = BS_STOP;
15568 handle_delay_slot(env, &ctx, insn_bytes);
15570 ctx.pc += insn_bytes;
15574 /* Execute a branch and its delay slot as a single instruction.
15575 This is what GDB expects and is consistent with what the
15576 hardware does (e.g. if a delay slot instruction faults, the
15577 reported PC is the PC of the branch). */
15578 if (env->singlestep_enabled && (ctx.hflags & MIPS_HFLAG_BMASK) == 0)
15581 if ((ctx.pc & (TARGET_PAGE_SIZE - 1)) == 0)
15584 if (gen_opc_ptr >= gen_opc_end)
15587 if (num_insns >= max_insns)
15593 if (tb->cflags & CF_LAST_IO)
15595 if (env->singlestep_enabled && ctx.bstate != BS_BRANCH) {
15596 save_cpu_state(&ctx, ctx.bstate == BS_NONE);
15597 gen_helper_0e0i(raise_exception, EXCP_DEBUG);
15599 switch (ctx.bstate) {
15601 gen_goto_tb(&ctx, 0, ctx.pc);
15604 save_cpu_state(&ctx, 0);
15605 gen_goto_tb(&ctx, 0, ctx.pc);
15608 tcg_gen_exit_tb(0);
15616 gen_icount_end(tb, num_insns);
15617 *gen_opc_ptr = INDEX_op_end;
15619 j = gen_opc_ptr - gen_opc_buf;
15622 gen_opc_instr_start[lj++] = 0;
15624 tb->size = ctx.pc - pc_start;
15625 tb->icount = num_insns;
15629 if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM)) {
15630 qemu_log("IN: %s\n", lookup_symbol(pc_start));
15631 log_target_disas(pc_start, ctx.pc - pc_start, 0);
15637 void gen_intermediate_code (CPUMIPSState *env, struct TranslationBlock *tb)
15639 gen_intermediate_code_internal(env, tb, 0);
15642 void gen_intermediate_code_pc (CPUMIPSState *env, struct TranslationBlock *tb)
15644 gen_intermediate_code_internal(env, tb, 1);
15647 static void fpu_dump_state(CPUMIPSState *env, FILE *f, fprintf_function fpu_fprintf,
15651 int is_fpu64 = !!(env->hflags & MIPS_HFLAG_F64);
15653 #define printfpr(fp) \
15656 fpu_fprintf(f, "w:%08x d:%016" PRIx64 \
15657 " fd:%13g fs:%13g psu: %13g\n", \
15658 (fp)->w[FP_ENDIAN_IDX], (fp)->d, \
15659 (double)(fp)->fd, \
15660 (double)(fp)->fs[FP_ENDIAN_IDX], \
15661 (double)(fp)->fs[!FP_ENDIAN_IDX]); \
15664 tmp.w[FP_ENDIAN_IDX] = (fp)->w[FP_ENDIAN_IDX]; \
15665 tmp.w[!FP_ENDIAN_IDX] = ((fp) + 1)->w[FP_ENDIAN_IDX]; \
15666 fpu_fprintf(f, "w:%08x d:%016" PRIx64 \
15667 " fd:%13g fs:%13g psu:%13g\n", \
15668 tmp.w[FP_ENDIAN_IDX], tmp.d, \
15670 (double)tmp.fs[FP_ENDIAN_IDX], \
15671 (double)tmp.fs[!FP_ENDIAN_IDX]); \
15676 fpu_fprintf(f, "CP1 FCR0 0x%08x FCR31 0x%08x SR.FR %d fp_status 0x%02x\n",
15677 env->active_fpu.fcr0, env->active_fpu.fcr31, is_fpu64,
15678 get_float_exception_flags(&env->active_fpu.fp_status));
15679 for (i = 0; i < 32; (is_fpu64) ? i++ : (i += 2)) {
15680 fpu_fprintf(f, "%3s: ", fregnames[i]);
15681 printfpr(&env->active_fpu.fpr[i]);
15687 #if defined(TARGET_MIPS64) && defined(MIPS_DEBUG_SIGN_EXTENSIONS)
15688 /* Debug help: The architecture requires 32bit code to maintain proper
15689 sign-extended values on 64bit machines. */
15691 #define SIGN_EXT_P(val) ((((val) & ~0x7fffffff) == 0) || (((val) & ~0x7fffffff) == ~0x7fffffff))
15694 cpu_mips_check_sign_extensions (CPUMIPSState *env, FILE *f,
15695 fprintf_function cpu_fprintf,
15700 if (!SIGN_EXT_P(env->active_tc.PC))
15701 cpu_fprintf(f, "BROKEN: pc=0x" TARGET_FMT_lx "\n", env->active_tc.PC);
15702 if (!SIGN_EXT_P(env->active_tc.HI[0]))
15703 cpu_fprintf(f, "BROKEN: HI=0x" TARGET_FMT_lx "\n", env->active_tc.HI[0]);
15704 if (!SIGN_EXT_P(env->active_tc.LO[0]))
15705 cpu_fprintf(f, "BROKEN: LO=0x" TARGET_FMT_lx "\n", env->active_tc.LO[0]);
15706 if (!SIGN_EXT_P(env->btarget))
15707 cpu_fprintf(f, "BROKEN: btarget=0x" TARGET_FMT_lx "\n", env->btarget);
15709 for (i = 0; i < 32; i++) {
15710 if (!SIGN_EXT_P(env->active_tc.gpr[i]))
15711 cpu_fprintf(f, "BROKEN: %s=0x" TARGET_FMT_lx "\n", regnames[i], env->active_tc.gpr[i]);
15714 if (!SIGN_EXT_P(env->CP0_EPC))
15715 cpu_fprintf(f, "BROKEN: EPC=0x" TARGET_FMT_lx "\n", env->CP0_EPC);
15716 if (!SIGN_EXT_P(env->lladdr))
15717 cpu_fprintf(f, "BROKEN: LLAddr=0x" TARGET_FMT_lx "\n", env->lladdr);
15721 void cpu_dump_state (CPUMIPSState *env, FILE *f, fprintf_function cpu_fprintf,
15726 cpu_fprintf(f, "pc=0x" TARGET_FMT_lx " HI=0x" TARGET_FMT_lx
15727 " LO=0x" TARGET_FMT_lx " ds %04x "
15728 TARGET_FMT_lx " " TARGET_FMT_ld "\n",
15729 env->active_tc.PC, env->active_tc.HI[0], env->active_tc.LO[0],
15730 env->hflags, env->btarget, env->bcond);
15731 for (i = 0; i < 32; i++) {
15733 cpu_fprintf(f, "GPR%02d:", i);
15734 cpu_fprintf(f, " %s " TARGET_FMT_lx, regnames[i], env->active_tc.gpr[i]);
15736 cpu_fprintf(f, "\n");
15739 cpu_fprintf(f, "CP0 Status 0x%08x Cause 0x%08x EPC 0x" TARGET_FMT_lx "\n",
15740 env->CP0_Status, env->CP0_Cause, env->CP0_EPC);
15741 cpu_fprintf(f, " Config0 0x%08x Config1 0x%08x LLAddr 0x" TARGET_FMT_lx "\n",
15742 env->CP0_Config0, env->CP0_Config1, env->lladdr);
15743 if (env->hflags & MIPS_HFLAG_FPU)
15744 fpu_dump_state(env, f, cpu_fprintf, flags);
15745 #if defined(TARGET_MIPS64) && defined(MIPS_DEBUG_SIGN_EXTENSIONS)
15746 cpu_mips_check_sign_extensions(env, f, cpu_fprintf, flags);
15750 static void mips_tcg_init(void)
15755 /* Initialize various static tables. */
15759 cpu_env = tcg_global_reg_new_ptr(TCG_AREG0, "env");
15760 TCGV_UNUSED(cpu_gpr[0]);
15761 for (i = 1; i < 32; i++)
15762 cpu_gpr[i] = tcg_global_mem_new(TCG_AREG0,
15763 offsetof(CPUMIPSState, active_tc.gpr[i]),
15766 for (i = 0; i < 32; i++) {
15767 int off = offsetof(CPUMIPSState, active_fpu.fpr[i]);
15768 fpu_f64[i] = tcg_global_mem_new_i64(TCG_AREG0, off, fregnames[i]);
15771 cpu_PC = tcg_global_mem_new(TCG_AREG0,
15772 offsetof(CPUMIPSState, active_tc.PC), "PC");
15773 for (i = 0; i < MIPS_DSP_ACC; i++) {
15774 cpu_HI[i] = tcg_global_mem_new(TCG_AREG0,
15775 offsetof(CPUMIPSState, active_tc.HI[i]),
15777 cpu_LO[i] = tcg_global_mem_new(TCG_AREG0,
15778 offsetof(CPUMIPSState, active_tc.LO[i]),
15780 cpu_ACX[i] = tcg_global_mem_new(TCG_AREG0,
15781 offsetof(CPUMIPSState, active_tc.ACX[i]),
15784 cpu_dspctrl = tcg_global_mem_new(TCG_AREG0,
15785 offsetof(CPUMIPSState, active_tc.DSPControl),
15787 bcond = tcg_global_mem_new(TCG_AREG0,
15788 offsetof(CPUMIPSState, bcond), "bcond");
15789 btarget = tcg_global_mem_new(TCG_AREG0,
15790 offsetof(CPUMIPSState, btarget), "btarget");
15791 hflags = tcg_global_mem_new_i32(TCG_AREG0,
15792 offsetof(CPUMIPSState, hflags), "hflags");
15794 fpu_fcr0 = tcg_global_mem_new_i32(TCG_AREG0,
15795 offsetof(CPUMIPSState, active_fpu.fcr0),
15797 fpu_fcr31 = tcg_global_mem_new_i32(TCG_AREG0,
15798 offsetof(CPUMIPSState, active_fpu.fcr31),
15801 /* register helpers */
15802 #define GEN_HELPER 2
15803 #include "helper.h"
15808 #include "translate_init.c"
15810 MIPSCPU *cpu_mips_init(const char *cpu_model)
15814 const mips_def_t *def;
15816 def = cpu_mips_find_by_name(cpu_model);
15819 cpu = MIPS_CPU(object_new(TYPE_MIPS_CPU));
15821 env->cpu_model = def;
15822 env->cpu_model_str = cpu_model;
15824 #ifndef CONFIG_USER_ONLY
15825 mmu_init(env, def);
15827 fpu_init(env, def);
15828 mvp_init(env, def);
15830 cpu_reset(CPU(cpu));
15831 qemu_init_vcpu(env);
15835 void cpu_state_reset(CPUMIPSState *env)
15837 if (qemu_loglevel_mask(CPU_LOG_RESET)) {
15838 qemu_log("CPU Reset (CPU %d)\n", env->cpu_index);
15839 log_cpu_state(env, 0);
15842 memset(env, 0, offsetof(CPUMIPSState, breakpoints));
15845 /* Reset registers to their default values */
15846 env->CP0_PRid = env->cpu_model->CP0_PRid;
15847 env->CP0_Config0 = env->cpu_model->CP0_Config0;
15848 #ifdef TARGET_WORDS_BIGENDIAN
15849 env->CP0_Config0 |= (1 << CP0C0_BE);
15851 env->CP0_Config1 = env->cpu_model->CP0_Config1;
15852 env->CP0_Config2 = env->cpu_model->CP0_Config2;
15853 env->CP0_Config3 = env->cpu_model->CP0_Config3;
15854 env->CP0_Config6 = env->cpu_model->CP0_Config6;
15855 env->CP0_Config7 = env->cpu_model->CP0_Config7;
15856 env->CP0_LLAddr_rw_bitmask = env->cpu_model->CP0_LLAddr_rw_bitmask
15857 << env->cpu_model->CP0_LLAddr_shift;
15858 env->CP0_LLAddr_shift = env->cpu_model->CP0_LLAddr_shift;
15859 env->SYNCI_Step = env->cpu_model->SYNCI_Step;
15860 env->CCRes = env->cpu_model->CCRes;
15861 env->CP0_Status_rw_bitmask = env->cpu_model->CP0_Status_rw_bitmask;
15862 env->CP0_TCStatus_rw_bitmask = env->cpu_model->CP0_TCStatus_rw_bitmask;
15863 env->CP0_SRSCtl = env->cpu_model->CP0_SRSCtl;
15864 env->current_tc = 0;
15865 env->SEGBITS = env->cpu_model->SEGBITS;
15866 env->SEGMask = (target_ulong)((1ULL << env->cpu_model->SEGBITS) - 1);
15867 #if defined(TARGET_MIPS64)
15868 if (env->cpu_model->insn_flags & ISA_MIPS3) {
15869 env->SEGMask |= 3ULL << 62;
15872 env->PABITS = env->cpu_model->PABITS;
15873 env->PAMask = (target_ulong)((1ULL << env->cpu_model->PABITS) - 1);
15874 env->CP0_SRSConf0_rw_bitmask = env->cpu_model->CP0_SRSConf0_rw_bitmask;
15875 env->CP0_SRSConf0 = env->cpu_model->CP0_SRSConf0;
15876 env->CP0_SRSConf1_rw_bitmask = env->cpu_model->CP0_SRSConf1_rw_bitmask;
15877 env->CP0_SRSConf1 = env->cpu_model->CP0_SRSConf1;
15878 env->CP0_SRSConf2_rw_bitmask = env->cpu_model->CP0_SRSConf2_rw_bitmask;
15879 env->CP0_SRSConf2 = env->cpu_model->CP0_SRSConf2;
15880 env->CP0_SRSConf3_rw_bitmask = env->cpu_model->CP0_SRSConf3_rw_bitmask;
15881 env->CP0_SRSConf3 = env->cpu_model->CP0_SRSConf3;
15882 env->CP0_SRSConf4_rw_bitmask = env->cpu_model->CP0_SRSConf4_rw_bitmask;
15883 env->CP0_SRSConf4 = env->cpu_model->CP0_SRSConf4;
15884 env->active_fpu.fcr0 = env->cpu_model->CP1_fcr0;
15885 env->insn_flags = env->cpu_model->insn_flags;
15887 #if defined(CONFIG_USER_ONLY)
15888 env->CP0_Status = (MIPS_HFLAG_UM << CP0St_KSU);
15889 /* Enable access to the CPUNum, SYNCI_Step, CC, and CCRes RDHWR
15890 hardware registers. */
15891 env->CP0_HWREna |= 0x0000000F;
15892 if (env->CP0_Config1 & (1 << CP0C1_FP)) {
15893 env->CP0_Status |= (1 << CP0St_CU1);
15895 if (env->cpu_model->insn_flags & ASE_DSPR2) {
15896 env->hflags |= MIPS_HFLAG_DSP | MIPS_HFLAG_DSPR2;
15897 } else if (env->cpu_model->insn_flags & ASE_DSP) {
15898 env->hflags |= MIPS_HFLAG_DSP;
15901 if (env->hflags & MIPS_HFLAG_BMASK) {
15902 /* If the exception was raised from a delay slot,
15903 come back to the jump. */
15904 env->CP0_ErrorEPC = env->active_tc.PC - 4;
15906 env->CP0_ErrorEPC = env->active_tc.PC;
15908 env->active_tc.PC = (int32_t)0xBFC00000;
15909 env->CP0_Random = env->tlb->nb_tlb - 1;
15910 env->tlb->tlb_in_use = env->tlb->nb_tlb;
15911 env->CP0_Wired = 0;
15912 env->CP0_EBase = 0x80000000 | (env->cpu_index & 0x3FF);
15913 env->CP0_Status = (1 << CP0St_BEV) | (1 << CP0St_ERL);
15914 /* vectored interrupts not implemented, timer on int 7,
15915 no performance counters. */
15916 env->CP0_IntCtl = 0xe0000000;
15920 for (i = 0; i < 7; i++) {
15921 env->CP0_WatchLo[i] = 0;
15922 env->CP0_WatchHi[i] = 0x80000000;
15924 env->CP0_WatchLo[7] = 0;
15925 env->CP0_WatchHi[7] = 0;
15927 /* Count register increments in debug mode, EJTAG version 1 */
15928 env->CP0_Debug = (1 << CP0DB_CNT) | (0x1 << CP0DB_VER);
15930 if (env->CP0_Config3 & (1 << CP0C3_MT)) {
15933 /* Only TC0 on VPE 0 starts as active. */
15934 for (i = 0; i < ARRAY_SIZE(env->tcs); i++) {
15935 env->tcs[i].CP0_TCBind = env->cpu_index << CP0TCBd_CurVPE;
15936 env->tcs[i].CP0_TCHalt = 1;
15938 env->active_tc.CP0_TCHalt = 1;
15941 if (!env->cpu_index) {
15942 /* VPE0 starts up enabled. */
15943 env->mvp->CP0_MVPControl |= (1 << CP0MVPCo_EVP);
15944 env->CP0_VPEConf0 |= (1 << CP0VPEC0_MVP) | (1 << CP0VPEC0_VPA);
15946 /* TC0 starts up unhalted. */
15948 env->active_tc.CP0_TCHalt = 0;
15949 env->tcs[0].CP0_TCHalt = 0;
15950 /* With thread 0 active. */
15951 env->active_tc.CP0_TCStatus = (1 << CP0TCSt_A);
15952 env->tcs[0].CP0_TCStatus = (1 << CP0TCSt_A);
15956 compute_hflags(env);
15957 env->exception_index = EXCP_NONE;
15960 void restore_state_to_opc(CPUMIPSState *env, TranslationBlock *tb, int pc_pos)
15962 env->active_tc.PC = gen_opc_pc[pc_pos];
15963 env->hflags &= ~MIPS_HFLAG_BMASK;
15964 env->hflags |= gen_opc_hflags[pc_pos];
15965 switch (env->hflags & MIPS_HFLAG_BMASK_BASE) {
15966 case MIPS_HFLAG_BR:
15968 case MIPS_HFLAG_BC:
15969 case MIPS_HFLAG_BL:
15971 env->btarget = gen_opc_btarget[pc_pos];