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 #define OP_LD(insn,fname) \
1488 static inline void op_ld_##insn(TCGv ret, TCGv arg1, DisasContext *ctx) \
1490 tcg_gen_qemu_##fname(ret, arg1, ctx->mem_idx); \
1497 #if defined(TARGET_MIPS64)
1503 #define OP_ST(insn,fname) \
1504 static inline void op_st_##insn(TCGv arg1, TCGv arg2, DisasContext *ctx) \
1506 tcg_gen_qemu_##fname(arg1, arg2, ctx->mem_idx); \
1511 #if defined(TARGET_MIPS64)
1516 #ifdef CONFIG_USER_ONLY
1517 #define OP_LD_ATOMIC(insn,fname) \
1518 static inline void op_ld_##insn(TCGv ret, TCGv arg1, DisasContext *ctx) \
1520 TCGv t0 = tcg_temp_new(); \
1521 tcg_gen_mov_tl(t0, arg1); \
1522 tcg_gen_qemu_##fname(ret, arg1, ctx->mem_idx); \
1523 tcg_gen_st_tl(t0, cpu_env, offsetof(CPUMIPSState, lladdr)); \
1524 tcg_gen_st_tl(ret, cpu_env, offsetof(CPUMIPSState, llval)); \
1525 tcg_temp_free(t0); \
1528 #define OP_LD_ATOMIC(insn,fname) \
1529 static inline void op_ld_##insn(TCGv ret, TCGv arg1, DisasContext *ctx) \
1531 gen_helper_1e1i(insn, ret, arg1, ctx->mem_idx); \
1534 OP_LD_ATOMIC(ll,ld32s);
1535 #if defined(TARGET_MIPS64)
1536 OP_LD_ATOMIC(lld,ld64);
1540 #ifdef CONFIG_USER_ONLY
1541 #define OP_ST_ATOMIC(insn,fname,ldname,almask) \
1542 static inline void op_st_##insn(TCGv arg1, TCGv arg2, int rt, DisasContext *ctx) \
1544 TCGv t0 = tcg_temp_new(); \
1545 int l1 = gen_new_label(); \
1546 int l2 = gen_new_label(); \
1548 tcg_gen_andi_tl(t0, arg2, almask); \
1549 tcg_gen_brcondi_tl(TCG_COND_EQ, t0, 0, l1); \
1550 tcg_gen_st_tl(arg2, cpu_env, offsetof(CPUMIPSState, CP0_BadVAddr)); \
1551 generate_exception(ctx, EXCP_AdES); \
1552 gen_set_label(l1); \
1553 tcg_gen_ld_tl(t0, cpu_env, offsetof(CPUMIPSState, lladdr)); \
1554 tcg_gen_brcond_tl(TCG_COND_NE, arg2, t0, l2); \
1555 tcg_gen_movi_tl(t0, rt | ((almask << 3) & 0x20)); \
1556 tcg_gen_st_tl(t0, cpu_env, offsetof(CPUMIPSState, llreg)); \
1557 tcg_gen_st_tl(arg1, cpu_env, offsetof(CPUMIPSState, llnewval)); \
1558 gen_helper_0e0i(raise_exception, EXCP_SC); \
1559 gen_set_label(l2); \
1560 tcg_gen_movi_tl(t0, 0); \
1561 gen_store_gpr(t0, rt); \
1562 tcg_temp_free(t0); \
1565 #define OP_ST_ATOMIC(insn,fname,ldname,almask) \
1566 static inline void op_st_##insn(TCGv arg1, TCGv arg2, int rt, DisasContext *ctx) \
1568 TCGv t0 = tcg_temp_new(); \
1569 gen_helper_1e2i(insn, t0, arg1, arg2, ctx->mem_idx); \
1570 gen_store_gpr(t0, rt); \
1571 tcg_temp_free(t0); \
1574 OP_ST_ATOMIC(sc,st32,ld32s,0x3);
1575 #if defined(TARGET_MIPS64)
1576 OP_ST_ATOMIC(scd,st64,ld64,0x7);
1580 static void gen_base_offset_addr (DisasContext *ctx, TCGv addr,
1581 int base, int16_t offset)
1584 tcg_gen_movi_tl(addr, offset);
1585 } else if (offset == 0) {
1586 gen_load_gpr(addr, base);
1588 tcg_gen_movi_tl(addr, offset);
1589 gen_op_addr_add(ctx, addr, cpu_gpr[base], addr);
1593 static target_ulong pc_relative_pc (DisasContext *ctx)
1595 target_ulong pc = ctx->pc;
1597 if (ctx->hflags & MIPS_HFLAG_BMASK) {
1598 int branch_bytes = ctx->hflags & MIPS_HFLAG_BDS16 ? 2 : 4;
1603 pc &= ~(target_ulong)3;
1608 static void gen_ld (CPUMIPSState *env, DisasContext *ctx, uint32_t opc,
1609 int rt, int base, int16_t offset)
1611 const char *opn = "ld";
1614 if (rt == 0 && env->insn_flags & (INSN_LOONGSON2E | INSN_LOONGSON2F)) {
1615 /* Loongson CPU uses a load to zero register for prefetch.
1616 We emulate it as a NOP. On other CPU we must perform the
1617 actual memory access. */
1622 t0 = tcg_temp_new();
1623 t1 = tcg_temp_new();
1624 gen_base_offset_addr(ctx, t0, base, offset);
1627 #if defined(TARGET_MIPS64)
1629 op_ld_lwu(t0, t0, ctx);
1630 gen_store_gpr(t0, rt);
1634 op_ld_ld(t0, t0, ctx);
1635 gen_store_gpr(t0, rt);
1639 save_cpu_state(ctx, 1);
1640 op_ld_lld(t0, t0, ctx);
1641 gen_store_gpr(t0, rt);
1645 save_cpu_state(ctx, 1);
1646 gen_load_gpr(t1, rt);
1647 gen_helper_1e2i(ldl, t1, t1, t0, ctx->mem_idx);
1648 gen_store_gpr(t1, rt);
1652 save_cpu_state(ctx, 1);
1653 gen_load_gpr(t1, rt);
1654 gen_helper_1e2i(ldr, t1, t1, t0, ctx->mem_idx);
1655 gen_store_gpr(t1, rt);
1659 tcg_gen_movi_tl(t1, pc_relative_pc(ctx));
1660 gen_op_addr_add(ctx, t0, t0, t1);
1661 op_ld_ld(t0, t0, ctx);
1662 gen_store_gpr(t0, rt);
1667 tcg_gen_movi_tl(t1, pc_relative_pc(ctx));
1668 gen_op_addr_add(ctx, t0, t0, t1);
1669 op_ld_lw(t0, t0, ctx);
1670 gen_store_gpr(t0, rt);
1674 op_ld_lw(t0, t0, ctx);
1675 gen_store_gpr(t0, rt);
1679 op_ld_lh(t0, t0, ctx);
1680 gen_store_gpr(t0, rt);
1684 op_ld_lhu(t0, t0, ctx);
1685 gen_store_gpr(t0, rt);
1689 op_ld_lb(t0, t0, ctx);
1690 gen_store_gpr(t0, rt);
1694 op_ld_lbu(t0, t0, ctx);
1695 gen_store_gpr(t0, rt);
1699 save_cpu_state(ctx, 1);
1700 gen_load_gpr(t1, rt);
1701 gen_helper_1e2i(lwl, t1, t1, t0, ctx->mem_idx);
1702 gen_store_gpr(t1, rt);
1706 save_cpu_state(ctx, 1);
1707 gen_load_gpr(t1, rt);
1708 gen_helper_1e2i(lwr, t1, t1, t0, ctx->mem_idx);
1709 gen_store_gpr(t1, rt);
1713 save_cpu_state(ctx, 1);
1714 op_ld_ll(t0, t0, ctx);
1715 gen_store_gpr(t0, rt);
1719 (void)opn; /* avoid a compiler warning */
1720 MIPS_DEBUG("%s %s, %d(%s)", opn, regnames[rt], offset, regnames[base]);
1726 static void gen_st (DisasContext *ctx, uint32_t opc, int rt,
1727 int base, int16_t offset)
1729 const char *opn = "st";
1730 TCGv t0 = tcg_temp_new();
1731 TCGv t1 = tcg_temp_new();
1733 gen_base_offset_addr(ctx, t0, base, offset);
1734 gen_load_gpr(t1, rt);
1736 #if defined(TARGET_MIPS64)
1738 op_st_sd(t1, t0, ctx);
1742 save_cpu_state(ctx, 1);
1743 gen_helper_0e2i(sdl, t1, t0, ctx->mem_idx);
1747 save_cpu_state(ctx, 1);
1748 gen_helper_0e2i(sdr, t1, t0, ctx->mem_idx);
1753 op_st_sw(t1, t0, ctx);
1757 op_st_sh(t1, t0, ctx);
1761 op_st_sb(t1, t0, ctx);
1765 save_cpu_state(ctx, 1);
1766 gen_helper_0e2i(swl, t1, t0, ctx->mem_idx);
1770 save_cpu_state(ctx, 1);
1771 gen_helper_0e2i(swr, t1, t0, ctx->mem_idx);
1775 (void)opn; /* avoid a compiler warning */
1776 MIPS_DEBUG("%s %s, %d(%s)", opn, regnames[rt], offset, regnames[base]);
1782 /* Store conditional */
1783 static void gen_st_cond (DisasContext *ctx, uint32_t opc, int rt,
1784 int base, int16_t offset)
1786 const char *opn = "st_cond";
1789 t0 = tcg_temp_local_new();
1791 gen_base_offset_addr(ctx, t0, base, offset);
1792 /* Don't do NOP if destination is zero: we must perform the actual
1795 t1 = tcg_temp_local_new();
1796 gen_load_gpr(t1, rt);
1798 #if defined(TARGET_MIPS64)
1800 save_cpu_state(ctx, 1);
1801 op_st_scd(t1, t0, rt, ctx);
1806 save_cpu_state(ctx, 1);
1807 op_st_sc(t1, t0, rt, ctx);
1811 (void)opn; /* avoid a compiler warning */
1812 MIPS_DEBUG("%s %s, %d(%s)", opn, regnames[rt], offset, regnames[base]);
1817 /* Load and store */
1818 static void gen_flt_ldst (DisasContext *ctx, uint32_t opc, int ft,
1819 int base, int16_t offset)
1821 const char *opn = "flt_ldst";
1822 TCGv t0 = tcg_temp_new();
1824 gen_base_offset_addr(ctx, t0, base, offset);
1825 /* Don't do NOP if destination is zero: we must perform the actual
1830 TCGv_i32 fp0 = tcg_temp_new_i32();
1832 tcg_gen_qemu_ld32s(t0, t0, ctx->mem_idx);
1833 tcg_gen_trunc_tl_i32(fp0, t0);
1834 gen_store_fpr32(fp0, ft);
1835 tcg_temp_free_i32(fp0);
1841 TCGv_i32 fp0 = tcg_temp_new_i32();
1842 TCGv t1 = tcg_temp_new();
1844 gen_load_fpr32(fp0, ft);
1845 tcg_gen_extu_i32_tl(t1, fp0);
1846 tcg_gen_qemu_st32(t1, t0, ctx->mem_idx);
1848 tcg_temp_free_i32(fp0);
1854 TCGv_i64 fp0 = tcg_temp_new_i64();
1856 tcg_gen_qemu_ld64(fp0, t0, ctx->mem_idx);
1857 gen_store_fpr64(ctx, fp0, ft);
1858 tcg_temp_free_i64(fp0);
1864 TCGv_i64 fp0 = tcg_temp_new_i64();
1866 gen_load_fpr64(ctx, fp0, ft);
1867 tcg_gen_qemu_st64(fp0, t0, ctx->mem_idx);
1868 tcg_temp_free_i64(fp0);
1874 generate_exception(ctx, EXCP_RI);
1877 (void)opn; /* avoid a compiler warning */
1878 MIPS_DEBUG("%s %s, %d(%s)", opn, fregnames[ft], offset, regnames[base]);
1883 static void gen_cop1_ldst(CPUMIPSState *env, DisasContext *ctx,
1884 uint32_t op, int rt, int rs, int16_t imm)
1886 if (env->CP0_Config1 & (1 << CP0C1_FP)) {
1887 check_cp1_enabled(ctx);
1888 gen_flt_ldst(ctx, op, rt, rs, imm);
1890 generate_exception_err(ctx, EXCP_CpU, 1);
1894 /* Arithmetic with immediate operand */
1895 static void gen_arith_imm (CPUMIPSState *env, DisasContext *ctx, uint32_t opc,
1896 int rt, int rs, int16_t imm)
1898 target_ulong uimm = (target_long)imm; /* Sign extend to 32/64 bits */
1899 const char *opn = "imm arith";
1901 if (rt == 0 && opc != OPC_ADDI && opc != OPC_DADDI) {
1902 /* If no destination, treat it as a NOP.
1903 For addi, we must generate the overflow exception when needed. */
1910 TCGv t0 = tcg_temp_local_new();
1911 TCGv t1 = tcg_temp_new();
1912 TCGv t2 = tcg_temp_new();
1913 int l1 = gen_new_label();
1915 gen_load_gpr(t1, rs);
1916 tcg_gen_addi_tl(t0, t1, uimm);
1917 tcg_gen_ext32s_tl(t0, t0);
1919 tcg_gen_xori_tl(t1, t1, ~uimm);
1920 tcg_gen_xori_tl(t2, t0, uimm);
1921 tcg_gen_and_tl(t1, t1, t2);
1923 tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
1925 /* operands of same sign, result different sign */
1926 generate_exception(ctx, EXCP_OVERFLOW);
1928 tcg_gen_ext32s_tl(t0, t0);
1929 gen_store_gpr(t0, rt);
1936 tcg_gen_addi_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
1937 tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]);
1939 tcg_gen_movi_tl(cpu_gpr[rt], uimm);
1943 #if defined(TARGET_MIPS64)
1946 TCGv t0 = tcg_temp_local_new();
1947 TCGv t1 = tcg_temp_new();
1948 TCGv t2 = tcg_temp_new();
1949 int l1 = gen_new_label();
1951 gen_load_gpr(t1, rs);
1952 tcg_gen_addi_tl(t0, t1, uimm);
1954 tcg_gen_xori_tl(t1, t1, ~uimm);
1955 tcg_gen_xori_tl(t2, t0, uimm);
1956 tcg_gen_and_tl(t1, t1, t2);
1958 tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
1960 /* operands of same sign, result different sign */
1961 generate_exception(ctx, EXCP_OVERFLOW);
1963 gen_store_gpr(t0, rt);
1970 tcg_gen_addi_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
1972 tcg_gen_movi_tl(cpu_gpr[rt], uimm);
1978 (void)opn; /* avoid a compiler warning */
1979 MIPS_DEBUG("%s %s, %s, " TARGET_FMT_lx, opn, regnames[rt], regnames[rs], uimm);
1982 /* Logic with immediate operand */
1983 static void gen_logic_imm(CPUMIPSState *env, DisasContext *ctx, uint32_t opc,
1984 int rt, int rs, int16_t imm)
1987 const char *opn = "imm logic";
1990 /* If no destination, treat it as a NOP. */
1994 uimm = (uint16_t)imm;
1997 if (likely(rs != 0))
1998 tcg_gen_andi_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
2000 tcg_gen_movi_tl(cpu_gpr[rt], 0);
2005 tcg_gen_ori_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
2007 tcg_gen_movi_tl(cpu_gpr[rt], uimm);
2011 if (likely(rs != 0))
2012 tcg_gen_xori_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
2014 tcg_gen_movi_tl(cpu_gpr[rt], uimm);
2018 tcg_gen_movi_tl(cpu_gpr[rt], imm << 16);
2022 (void)opn; /* avoid a compiler warning */
2023 MIPS_DEBUG("%s %s, %s, " TARGET_FMT_lx, opn, regnames[rt], regnames[rs], uimm);
2026 /* Set on less than with immediate operand */
2027 static void gen_slt_imm(CPUMIPSState *env, DisasContext *ctx, uint32_t opc,
2028 int rt, int rs, int16_t imm)
2030 target_ulong uimm = (target_long)imm; /* Sign extend to 32/64 bits */
2031 const char *opn = "imm arith";
2035 /* If no destination, treat it as a NOP. */
2039 t0 = tcg_temp_new();
2040 gen_load_gpr(t0, rs);
2043 tcg_gen_setcondi_tl(TCG_COND_LT, cpu_gpr[rt], t0, uimm);
2047 tcg_gen_setcondi_tl(TCG_COND_LTU, cpu_gpr[rt], t0, uimm);
2051 (void)opn; /* avoid a compiler warning */
2052 MIPS_DEBUG("%s %s, %s, " TARGET_FMT_lx, opn, regnames[rt], regnames[rs], uimm);
2056 /* Shifts with immediate operand */
2057 static void gen_shift_imm(CPUMIPSState *env, DisasContext *ctx, uint32_t opc,
2058 int rt, int rs, int16_t imm)
2060 target_ulong uimm = ((uint16_t)imm) & 0x1f;
2061 const char *opn = "imm shift";
2065 /* If no destination, treat it as a NOP. */
2070 t0 = tcg_temp_new();
2071 gen_load_gpr(t0, rs);
2074 tcg_gen_shli_tl(t0, t0, uimm);
2075 tcg_gen_ext32s_tl(cpu_gpr[rt], t0);
2079 tcg_gen_sari_tl(cpu_gpr[rt], t0, uimm);
2084 tcg_gen_ext32u_tl(t0, t0);
2085 tcg_gen_shri_tl(cpu_gpr[rt], t0, uimm);
2087 tcg_gen_ext32s_tl(cpu_gpr[rt], t0);
2093 TCGv_i32 t1 = tcg_temp_new_i32();
2095 tcg_gen_trunc_tl_i32(t1, t0);
2096 tcg_gen_rotri_i32(t1, t1, uimm);
2097 tcg_gen_ext_i32_tl(cpu_gpr[rt], t1);
2098 tcg_temp_free_i32(t1);
2100 tcg_gen_ext32s_tl(cpu_gpr[rt], t0);
2104 #if defined(TARGET_MIPS64)
2106 tcg_gen_shli_tl(cpu_gpr[rt], t0, uimm);
2110 tcg_gen_sari_tl(cpu_gpr[rt], t0, uimm);
2114 tcg_gen_shri_tl(cpu_gpr[rt], t0, uimm);
2119 tcg_gen_rotri_tl(cpu_gpr[rt], t0, uimm);
2121 tcg_gen_mov_tl(cpu_gpr[rt], t0);
2126 tcg_gen_shli_tl(cpu_gpr[rt], t0, uimm + 32);
2130 tcg_gen_sari_tl(cpu_gpr[rt], t0, uimm + 32);
2134 tcg_gen_shri_tl(cpu_gpr[rt], t0, uimm + 32);
2138 tcg_gen_rotri_tl(cpu_gpr[rt], t0, uimm + 32);
2143 (void)opn; /* avoid a compiler warning */
2144 MIPS_DEBUG("%s %s, %s, " TARGET_FMT_lx, opn, regnames[rt], regnames[rs], uimm);
2149 static void gen_arith (CPUMIPSState *env, DisasContext *ctx, uint32_t opc,
2150 int rd, int rs, int rt)
2152 const char *opn = "arith";
2154 if (rd == 0 && opc != OPC_ADD && opc != OPC_SUB
2155 && opc != OPC_DADD && opc != OPC_DSUB) {
2156 /* If no destination, treat it as a NOP.
2157 For add & sub, we must generate the overflow exception when needed. */
2165 TCGv t0 = tcg_temp_local_new();
2166 TCGv t1 = tcg_temp_new();
2167 TCGv t2 = tcg_temp_new();
2168 int l1 = gen_new_label();
2170 gen_load_gpr(t1, rs);
2171 gen_load_gpr(t2, rt);
2172 tcg_gen_add_tl(t0, t1, t2);
2173 tcg_gen_ext32s_tl(t0, t0);
2174 tcg_gen_xor_tl(t1, t1, t2);
2175 tcg_gen_xor_tl(t2, t0, t2);
2176 tcg_gen_andc_tl(t1, t2, t1);
2178 tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
2180 /* operands of same sign, result different sign */
2181 generate_exception(ctx, EXCP_OVERFLOW);
2183 gen_store_gpr(t0, rd);
2189 if (rs != 0 && rt != 0) {
2190 tcg_gen_add_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2191 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
2192 } else if (rs == 0 && rt != 0) {
2193 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rt]);
2194 } else if (rs != 0 && rt == 0) {
2195 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
2197 tcg_gen_movi_tl(cpu_gpr[rd], 0);
2203 TCGv t0 = tcg_temp_local_new();
2204 TCGv t1 = tcg_temp_new();
2205 TCGv t2 = tcg_temp_new();
2206 int l1 = gen_new_label();
2208 gen_load_gpr(t1, rs);
2209 gen_load_gpr(t2, rt);
2210 tcg_gen_sub_tl(t0, t1, t2);
2211 tcg_gen_ext32s_tl(t0, t0);
2212 tcg_gen_xor_tl(t2, t1, t2);
2213 tcg_gen_xor_tl(t1, t0, t1);
2214 tcg_gen_and_tl(t1, t1, t2);
2216 tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
2218 /* operands of different sign, first operand and result different sign */
2219 generate_exception(ctx, EXCP_OVERFLOW);
2221 gen_store_gpr(t0, rd);
2227 if (rs != 0 && rt != 0) {
2228 tcg_gen_sub_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2229 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
2230 } else if (rs == 0 && rt != 0) {
2231 tcg_gen_neg_tl(cpu_gpr[rd], cpu_gpr[rt]);
2232 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
2233 } else if (rs != 0 && rt == 0) {
2234 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
2236 tcg_gen_movi_tl(cpu_gpr[rd], 0);
2240 #if defined(TARGET_MIPS64)
2243 TCGv t0 = tcg_temp_local_new();
2244 TCGv t1 = tcg_temp_new();
2245 TCGv t2 = tcg_temp_new();
2246 int l1 = gen_new_label();
2248 gen_load_gpr(t1, rs);
2249 gen_load_gpr(t2, rt);
2250 tcg_gen_add_tl(t0, t1, t2);
2251 tcg_gen_xor_tl(t1, t1, t2);
2252 tcg_gen_xor_tl(t2, t0, t2);
2253 tcg_gen_andc_tl(t1, t2, t1);
2255 tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
2257 /* operands of same sign, result different sign */
2258 generate_exception(ctx, EXCP_OVERFLOW);
2260 gen_store_gpr(t0, rd);
2266 if (rs != 0 && rt != 0) {
2267 tcg_gen_add_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2268 } else if (rs == 0 && rt != 0) {
2269 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rt]);
2270 } else if (rs != 0 && rt == 0) {
2271 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
2273 tcg_gen_movi_tl(cpu_gpr[rd], 0);
2279 TCGv t0 = tcg_temp_local_new();
2280 TCGv t1 = tcg_temp_new();
2281 TCGv t2 = tcg_temp_new();
2282 int l1 = gen_new_label();
2284 gen_load_gpr(t1, rs);
2285 gen_load_gpr(t2, rt);
2286 tcg_gen_sub_tl(t0, t1, t2);
2287 tcg_gen_xor_tl(t2, t1, t2);
2288 tcg_gen_xor_tl(t1, t0, t1);
2289 tcg_gen_and_tl(t1, t1, t2);
2291 tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
2293 /* operands of different sign, first operand and result different sign */
2294 generate_exception(ctx, EXCP_OVERFLOW);
2296 gen_store_gpr(t0, rd);
2302 if (rs != 0 && rt != 0) {
2303 tcg_gen_sub_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2304 } else if (rs == 0 && rt != 0) {
2305 tcg_gen_neg_tl(cpu_gpr[rd], cpu_gpr[rt]);
2306 } else if (rs != 0 && rt == 0) {
2307 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
2309 tcg_gen_movi_tl(cpu_gpr[rd], 0);
2315 if (likely(rs != 0 && rt != 0)) {
2316 tcg_gen_mul_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2317 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
2319 tcg_gen_movi_tl(cpu_gpr[rd], 0);
2324 (void)opn; /* avoid a compiler warning */
2325 MIPS_DEBUG("%s %s, %s, %s", opn, regnames[rd], regnames[rs], regnames[rt]);
2328 /* Conditional move */
2329 static void gen_cond_move(CPUMIPSState *env, DisasContext *ctx, uint32_t opc,
2330 int rd, int rs, int rt)
2332 const char *opn = "cond move";
2336 /* If no destination, treat it as a NOP.
2337 For add & sub, we must generate the overflow exception when needed. */
2342 l1 = gen_new_label();
2345 if (likely(rt != 0))
2346 tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_gpr[rt], 0, l1);
2352 if (likely(rt != 0))
2353 tcg_gen_brcondi_tl(TCG_COND_NE, cpu_gpr[rt], 0, l1);
2358 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
2360 tcg_gen_movi_tl(cpu_gpr[rd], 0);
2363 (void)opn; /* avoid a compiler warning */
2364 MIPS_DEBUG("%s %s, %s, %s", opn, regnames[rd], regnames[rs], regnames[rt]);
2368 static void gen_logic(CPUMIPSState *env, DisasContext *ctx, uint32_t opc,
2369 int rd, int rs, int rt)
2371 const char *opn = "logic";
2374 /* If no destination, treat it as a NOP. */
2381 if (likely(rs != 0 && rt != 0)) {
2382 tcg_gen_and_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2384 tcg_gen_movi_tl(cpu_gpr[rd], 0);
2389 if (rs != 0 && rt != 0) {
2390 tcg_gen_nor_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2391 } else if (rs == 0 && rt != 0) {
2392 tcg_gen_not_tl(cpu_gpr[rd], cpu_gpr[rt]);
2393 } else if (rs != 0 && rt == 0) {
2394 tcg_gen_not_tl(cpu_gpr[rd], cpu_gpr[rs]);
2396 tcg_gen_movi_tl(cpu_gpr[rd], ~((target_ulong)0));
2401 if (likely(rs != 0 && rt != 0)) {
2402 tcg_gen_or_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2403 } else if (rs == 0 && rt != 0) {
2404 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rt]);
2405 } else if (rs != 0 && rt == 0) {
2406 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
2408 tcg_gen_movi_tl(cpu_gpr[rd], 0);
2413 if (likely(rs != 0 && rt != 0)) {
2414 tcg_gen_xor_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2415 } else if (rs == 0 && rt != 0) {
2416 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rt]);
2417 } else if (rs != 0 && rt == 0) {
2418 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
2420 tcg_gen_movi_tl(cpu_gpr[rd], 0);
2425 (void)opn; /* avoid a compiler warning */
2426 MIPS_DEBUG("%s %s, %s, %s", opn, regnames[rd], regnames[rs], regnames[rt]);
2429 /* Set on lower than */
2430 static void gen_slt(CPUMIPSState *env, DisasContext *ctx, uint32_t opc,
2431 int rd, int rs, int rt)
2433 const char *opn = "slt";
2437 /* If no destination, treat it as a NOP. */
2442 t0 = tcg_temp_new();
2443 t1 = tcg_temp_new();
2444 gen_load_gpr(t0, rs);
2445 gen_load_gpr(t1, rt);
2448 tcg_gen_setcond_tl(TCG_COND_LT, cpu_gpr[rd], t0, t1);
2452 tcg_gen_setcond_tl(TCG_COND_LTU, cpu_gpr[rd], t0, t1);
2456 (void)opn; /* avoid a compiler warning */
2457 MIPS_DEBUG("%s %s, %s, %s", opn, regnames[rd], regnames[rs], regnames[rt]);
2463 static void gen_shift (CPUMIPSState *env, DisasContext *ctx, uint32_t opc,
2464 int rd, int rs, int rt)
2466 const char *opn = "shifts";
2470 /* If no destination, treat it as a NOP.
2471 For add & sub, we must generate the overflow exception when needed. */
2476 t0 = tcg_temp_new();
2477 t1 = tcg_temp_new();
2478 gen_load_gpr(t0, rs);
2479 gen_load_gpr(t1, rt);
2482 tcg_gen_andi_tl(t0, t0, 0x1f);
2483 tcg_gen_shl_tl(t0, t1, t0);
2484 tcg_gen_ext32s_tl(cpu_gpr[rd], t0);
2488 tcg_gen_andi_tl(t0, t0, 0x1f);
2489 tcg_gen_sar_tl(cpu_gpr[rd], t1, t0);
2493 tcg_gen_ext32u_tl(t1, t1);
2494 tcg_gen_andi_tl(t0, t0, 0x1f);
2495 tcg_gen_shr_tl(t0, t1, t0);
2496 tcg_gen_ext32s_tl(cpu_gpr[rd], t0);
2501 TCGv_i32 t2 = tcg_temp_new_i32();
2502 TCGv_i32 t3 = tcg_temp_new_i32();
2504 tcg_gen_trunc_tl_i32(t2, t0);
2505 tcg_gen_trunc_tl_i32(t3, t1);
2506 tcg_gen_andi_i32(t2, t2, 0x1f);
2507 tcg_gen_rotr_i32(t2, t3, t2);
2508 tcg_gen_ext_i32_tl(cpu_gpr[rd], t2);
2509 tcg_temp_free_i32(t2);
2510 tcg_temp_free_i32(t3);
2514 #if defined(TARGET_MIPS64)
2516 tcg_gen_andi_tl(t0, t0, 0x3f);
2517 tcg_gen_shl_tl(cpu_gpr[rd], t1, t0);
2521 tcg_gen_andi_tl(t0, t0, 0x3f);
2522 tcg_gen_sar_tl(cpu_gpr[rd], t1, t0);
2526 tcg_gen_andi_tl(t0, t0, 0x3f);
2527 tcg_gen_shr_tl(cpu_gpr[rd], t1, t0);
2531 tcg_gen_andi_tl(t0, t0, 0x3f);
2532 tcg_gen_rotr_tl(cpu_gpr[rd], t1, t0);
2537 (void)opn; /* avoid a compiler warning */
2538 MIPS_DEBUG("%s %s, %s, %s", opn, regnames[rd], regnames[rs], regnames[rt]);
2543 /* Arithmetic on HI/LO registers */
2544 static void gen_HILO (DisasContext *ctx, uint32_t opc, int reg)
2546 const char *opn = "hilo";
2549 if (reg == 0 && (opc == OPC_MFHI || opc == OPC_MFLO)) {
2555 if (opc == OPC_MFHI || opc == OPC_MFLO) {
2556 acc = ((ctx->opcode) >> 21) & 0x03;
2558 acc = ((ctx->opcode) >> 11) & 0x03;
2567 #if defined(TARGET_MIPS64)
2569 tcg_gen_ext32s_tl(cpu_gpr[reg], cpu_HI[acc]);
2573 tcg_gen_mov_tl(cpu_gpr[reg], cpu_HI[acc]);
2578 #if defined(TARGET_MIPS64)
2580 tcg_gen_ext32s_tl(cpu_gpr[reg], cpu_LO[acc]);
2584 tcg_gen_mov_tl(cpu_gpr[reg], cpu_LO[acc]);
2590 #if defined(TARGET_MIPS64)
2592 tcg_gen_ext32s_tl(cpu_HI[acc], cpu_gpr[reg]);
2596 tcg_gen_mov_tl(cpu_HI[acc], cpu_gpr[reg]);
2599 tcg_gen_movi_tl(cpu_HI[acc], 0);
2605 #if defined(TARGET_MIPS64)
2607 tcg_gen_ext32s_tl(cpu_LO[acc], cpu_gpr[reg]);
2611 tcg_gen_mov_tl(cpu_LO[acc], cpu_gpr[reg]);
2614 tcg_gen_movi_tl(cpu_LO[acc], 0);
2619 (void)opn; /* avoid a compiler warning */
2620 MIPS_DEBUG("%s %s", opn, regnames[reg]);
2623 static void gen_muldiv (DisasContext *ctx, uint32_t opc,
2626 const char *opn = "mul/div";
2633 #if defined(TARGET_MIPS64)
2637 t0 = tcg_temp_local_new();
2638 t1 = tcg_temp_local_new();
2641 t0 = tcg_temp_new();
2642 t1 = tcg_temp_new();
2646 gen_load_gpr(t0, rs);
2647 gen_load_gpr(t1, rt);
2651 int l1 = gen_new_label();
2652 int l2 = gen_new_label();
2654 tcg_gen_ext32s_tl(t0, t0);
2655 tcg_gen_ext32s_tl(t1, t1);
2656 tcg_gen_brcondi_tl(TCG_COND_EQ, t1, 0, l1);
2657 tcg_gen_brcondi_tl(TCG_COND_NE, t0, INT_MIN, l2);
2658 tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1, l2);
2660 tcg_gen_mov_tl(cpu_LO[0], t0);
2661 tcg_gen_movi_tl(cpu_HI[0], 0);
2664 tcg_gen_div_tl(cpu_LO[0], t0, t1);
2665 tcg_gen_rem_tl(cpu_HI[0], t0, t1);
2666 tcg_gen_ext32s_tl(cpu_LO[0], cpu_LO[0]);
2667 tcg_gen_ext32s_tl(cpu_HI[0], cpu_HI[0]);
2674 int l1 = gen_new_label();
2676 tcg_gen_ext32u_tl(t0, t0);
2677 tcg_gen_ext32u_tl(t1, t1);
2678 tcg_gen_brcondi_tl(TCG_COND_EQ, t1, 0, l1);
2679 tcg_gen_divu_tl(cpu_LO[0], t0, t1);
2680 tcg_gen_remu_tl(cpu_HI[0], t0, t1);
2681 tcg_gen_ext32s_tl(cpu_LO[0], cpu_LO[0]);
2682 tcg_gen_ext32s_tl(cpu_HI[0], cpu_HI[0]);
2689 TCGv_i64 t2 = tcg_temp_new_i64();
2690 TCGv_i64 t3 = tcg_temp_new_i64();
2691 acc = ((ctx->opcode) >> 11) & 0x03;
2696 tcg_gen_ext_tl_i64(t2, t0);
2697 tcg_gen_ext_tl_i64(t3, t1);
2698 tcg_gen_mul_i64(t2, t2, t3);
2699 tcg_temp_free_i64(t3);
2700 tcg_gen_trunc_i64_tl(t0, t2);
2701 tcg_gen_shri_i64(t2, t2, 32);
2702 tcg_gen_trunc_i64_tl(t1, t2);
2703 tcg_temp_free_i64(t2);
2704 tcg_gen_ext32s_tl(cpu_LO[acc], t0);
2705 tcg_gen_ext32s_tl(cpu_HI[acc], t1);
2711 TCGv_i64 t2 = tcg_temp_new_i64();
2712 TCGv_i64 t3 = tcg_temp_new_i64();
2713 acc = ((ctx->opcode) >> 11) & 0x03;
2718 tcg_gen_ext32u_tl(t0, t0);
2719 tcg_gen_ext32u_tl(t1, t1);
2720 tcg_gen_extu_tl_i64(t2, t0);
2721 tcg_gen_extu_tl_i64(t3, t1);
2722 tcg_gen_mul_i64(t2, t2, t3);
2723 tcg_temp_free_i64(t3);
2724 tcg_gen_trunc_i64_tl(t0, t2);
2725 tcg_gen_shri_i64(t2, t2, 32);
2726 tcg_gen_trunc_i64_tl(t1, t2);
2727 tcg_temp_free_i64(t2);
2728 tcg_gen_ext32s_tl(cpu_LO[acc], t0);
2729 tcg_gen_ext32s_tl(cpu_HI[acc], t1);
2733 #if defined(TARGET_MIPS64)
2736 int l1 = gen_new_label();
2737 int l2 = gen_new_label();
2739 tcg_gen_brcondi_tl(TCG_COND_EQ, t1, 0, l1);
2740 tcg_gen_brcondi_tl(TCG_COND_NE, t0, -1LL << 63, l2);
2741 tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1LL, l2);
2742 tcg_gen_mov_tl(cpu_LO[0], t0);
2743 tcg_gen_movi_tl(cpu_HI[0], 0);
2746 tcg_gen_div_i64(cpu_LO[0], t0, t1);
2747 tcg_gen_rem_i64(cpu_HI[0], t0, t1);
2754 int l1 = gen_new_label();
2756 tcg_gen_brcondi_tl(TCG_COND_EQ, t1, 0, l1);
2757 tcg_gen_divu_i64(cpu_LO[0], t0, t1);
2758 tcg_gen_remu_i64(cpu_HI[0], t0, t1);
2764 gen_helper_dmult(cpu_env, t0, t1);
2768 gen_helper_dmultu(cpu_env, t0, t1);
2774 TCGv_i64 t2 = tcg_temp_new_i64();
2775 TCGv_i64 t3 = tcg_temp_new_i64();
2776 acc = ((ctx->opcode) >> 11) & 0x03;
2781 tcg_gen_ext_tl_i64(t2, t0);
2782 tcg_gen_ext_tl_i64(t3, t1);
2783 tcg_gen_mul_i64(t2, t2, t3);
2784 tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]);
2785 tcg_gen_add_i64(t2, t2, t3);
2786 tcg_temp_free_i64(t3);
2787 tcg_gen_trunc_i64_tl(t0, t2);
2788 tcg_gen_shri_i64(t2, t2, 32);
2789 tcg_gen_trunc_i64_tl(t1, t2);
2790 tcg_temp_free_i64(t2);
2791 tcg_gen_ext32s_tl(cpu_LO[acc], t0);
2792 tcg_gen_ext32s_tl(cpu_HI[acc], t1);
2798 TCGv_i64 t2 = tcg_temp_new_i64();
2799 TCGv_i64 t3 = tcg_temp_new_i64();
2800 acc = ((ctx->opcode) >> 11) & 0x03;
2805 tcg_gen_ext32u_tl(t0, t0);
2806 tcg_gen_ext32u_tl(t1, t1);
2807 tcg_gen_extu_tl_i64(t2, t0);
2808 tcg_gen_extu_tl_i64(t3, t1);
2809 tcg_gen_mul_i64(t2, t2, t3);
2810 tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]);
2811 tcg_gen_add_i64(t2, t2, t3);
2812 tcg_temp_free_i64(t3);
2813 tcg_gen_trunc_i64_tl(t0, t2);
2814 tcg_gen_shri_i64(t2, t2, 32);
2815 tcg_gen_trunc_i64_tl(t1, t2);
2816 tcg_temp_free_i64(t2);
2817 tcg_gen_ext32s_tl(cpu_LO[acc], t0);
2818 tcg_gen_ext32s_tl(cpu_HI[acc], t1);
2824 TCGv_i64 t2 = tcg_temp_new_i64();
2825 TCGv_i64 t3 = tcg_temp_new_i64();
2826 acc = ((ctx->opcode) >> 11) & 0x03;
2831 tcg_gen_ext_tl_i64(t2, t0);
2832 tcg_gen_ext_tl_i64(t3, t1);
2833 tcg_gen_mul_i64(t2, t2, t3);
2834 tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]);
2835 tcg_gen_sub_i64(t2, t3, t2);
2836 tcg_temp_free_i64(t3);
2837 tcg_gen_trunc_i64_tl(t0, t2);
2838 tcg_gen_shri_i64(t2, t2, 32);
2839 tcg_gen_trunc_i64_tl(t1, t2);
2840 tcg_temp_free_i64(t2);
2841 tcg_gen_ext32s_tl(cpu_LO[acc], t0);
2842 tcg_gen_ext32s_tl(cpu_HI[acc], t1);
2848 TCGv_i64 t2 = tcg_temp_new_i64();
2849 TCGv_i64 t3 = tcg_temp_new_i64();
2850 acc = ((ctx->opcode) >> 11) & 0x03;
2855 tcg_gen_ext32u_tl(t0, t0);
2856 tcg_gen_ext32u_tl(t1, t1);
2857 tcg_gen_extu_tl_i64(t2, t0);
2858 tcg_gen_extu_tl_i64(t3, t1);
2859 tcg_gen_mul_i64(t2, t2, t3);
2860 tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]);
2861 tcg_gen_sub_i64(t2, t3, t2);
2862 tcg_temp_free_i64(t3);
2863 tcg_gen_trunc_i64_tl(t0, t2);
2864 tcg_gen_shri_i64(t2, t2, 32);
2865 tcg_gen_trunc_i64_tl(t1, t2);
2866 tcg_temp_free_i64(t2);
2867 tcg_gen_ext32s_tl(cpu_LO[acc], t0);
2868 tcg_gen_ext32s_tl(cpu_HI[acc], t1);
2874 generate_exception(ctx, EXCP_RI);
2877 (void)opn; /* avoid a compiler warning */
2878 MIPS_DEBUG("%s %s %s", opn, regnames[rs], regnames[rt]);
2884 static void gen_mul_vr54xx (DisasContext *ctx, uint32_t opc,
2885 int rd, int rs, int rt)
2887 const char *opn = "mul vr54xx";
2888 TCGv t0 = tcg_temp_new();
2889 TCGv t1 = tcg_temp_new();
2891 gen_load_gpr(t0, rs);
2892 gen_load_gpr(t1, rt);
2895 case OPC_VR54XX_MULS:
2896 gen_helper_muls(t0, cpu_env, t0, t1);
2899 case OPC_VR54XX_MULSU:
2900 gen_helper_mulsu(t0, cpu_env, t0, t1);
2903 case OPC_VR54XX_MACC:
2904 gen_helper_macc(t0, cpu_env, t0, t1);
2907 case OPC_VR54XX_MACCU:
2908 gen_helper_maccu(t0, cpu_env, t0, t1);
2911 case OPC_VR54XX_MSAC:
2912 gen_helper_msac(t0, cpu_env, t0, t1);
2915 case OPC_VR54XX_MSACU:
2916 gen_helper_msacu(t0, cpu_env, t0, t1);
2919 case OPC_VR54XX_MULHI:
2920 gen_helper_mulhi(t0, cpu_env, t0, t1);
2923 case OPC_VR54XX_MULHIU:
2924 gen_helper_mulhiu(t0, cpu_env, t0, t1);
2927 case OPC_VR54XX_MULSHI:
2928 gen_helper_mulshi(t0, cpu_env, t0, t1);
2931 case OPC_VR54XX_MULSHIU:
2932 gen_helper_mulshiu(t0, cpu_env, t0, t1);
2935 case OPC_VR54XX_MACCHI:
2936 gen_helper_macchi(t0, cpu_env, t0, t1);
2939 case OPC_VR54XX_MACCHIU:
2940 gen_helper_macchiu(t0, cpu_env, t0, t1);
2943 case OPC_VR54XX_MSACHI:
2944 gen_helper_msachi(t0, cpu_env, t0, t1);
2947 case OPC_VR54XX_MSACHIU:
2948 gen_helper_msachiu(t0, cpu_env, t0, t1);
2952 MIPS_INVAL("mul vr54xx");
2953 generate_exception(ctx, EXCP_RI);
2956 gen_store_gpr(t0, rd);
2957 (void)opn; /* avoid a compiler warning */
2958 MIPS_DEBUG("%s %s, %s, %s", opn, regnames[rd], regnames[rs], regnames[rt]);
2965 static void gen_cl (DisasContext *ctx, uint32_t opc,
2968 const char *opn = "CLx";
2976 t0 = tcg_temp_new();
2977 gen_load_gpr(t0, rs);
2980 gen_helper_clo(cpu_gpr[rd], t0);
2984 gen_helper_clz(cpu_gpr[rd], t0);
2987 #if defined(TARGET_MIPS64)
2989 gen_helper_dclo(cpu_gpr[rd], t0);
2993 gen_helper_dclz(cpu_gpr[rd], t0);
2998 (void)opn; /* avoid a compiler warning */
2999 MIPS_DEBUG("%s %s, %s", opn, regnames[rd], regnames[rs]);
3003 /* Godson integer instructions */
3004 static void gen_loongson_integer(DisasContext *ctx, uint32_t opc,
3005 int rd, int rs, int rt)
3007 const char *opn = "loongson";
3019 case OPC_MULTU_G_2E:
3020 case OPC_MULTU_G_2F:
3021 #if defined(TARGET_MIPS64)
3022 case OPC_DMULT_G_2E:
3023 case OPC_DMULT_G_2F:
3024 case OPC_DMULTU_G_2E:
3025 case OPC_DMULTU_G_2F:
3027 t0 = tcg_temp_new();
3028 t1 = tcg_temp_new();
3031 t0 = tcg_temp_local_new();
3032 t1 = tcg_temp_local_new();
3036 gen_load_gpr(t0, rs);
3037 gen_load_gpr(t1, rt);
3042 tcg_gen_mul_tl(cpu_gpr[rd], t0, t1);
3043 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3046 case OPC_MULTU_G_2E:
3047 case OPC_MULTU_G_2F:
3048 tcg_gen_ext32u_tl(t0, t0);
3049 tcg_gen_ext32u_tl(t1, t1);
3050 tcg_gen_mul_tl(cpu_gpr[rd], t0, t1);
3051 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3057 int l1 = gen_new_label();
3058 int l2 = gen_new_label();
3059 int l3 = gen_new_label();
3060 tcg_gen_ext32s_tl(t0, t0);
3061 tcg_gen_ext32s_tl(t1, t1);
3062 tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
3063 tcg_gen_movi_tl(cpu_gpr[rd], 0);
3066 tcg_gen_brcondi_tl(TCG_COND_NE, t0, INT_MIN, l2);
3067 tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1, l2);
3068 tcg_gen_mov_tl(cpu_gpr[rd], t0);
3071 tcg_gen_div_tl(cpu_gpr[rd], t0, t1);
3072 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3080 int l1 = gen_new_label();
3081 int l2 = gen_new_label();
3082 tcg_gen_ext32u_tl(t0, t0);
3083 tcg_gen_ext32u_tl(t1, t1);
3084 tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
3085 tcg_gen_movi_tl(cpu_gpr[rd], 0);
3088 tcg_gen_divu_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 int l3 = gen_new_label();
3100 tcg_gen_ext32u_tl(t0, t0);
3101 tcg_gen_ext32u_tl(t1, t1);
3102 tcg_gen_brcondi_tl(TCG_COND_EQ, t1, 0, l1);
3103 tcg_gen_brcondi_tl(TCG_COND_NE, t0, INT_MIN, l2);
3104 tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1, l2);
3106 tcg_gen_movi_tl(cpu_gpr[rd], 0);
3109 tcg_gen_rem_tl(cpu_gpr[rd], t0, t1);
3110 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3118 int l1 = gen_new_label();
3119 int l2 = gen_new_label();
3120 tcg_gen_ext32u_tl(t0, t0);
3121 tcg_gen_ext32u_tl(t1, t1);
3122 tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
3123 tcg_gen_movi_tl(cpu_gpr[rd], 0);
3126 tcg_gen_remu_tl(cpu_gpr[rd], t0, t1);
3127 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3132 #if defined(TARGET_MIPS64)
3133 case OPC_DMULT_G_2E:
3134 case OPC_DMULT_G_2F:
3135 tcg_gen_mul_tl(cpu_gpr[rd], t0, t1);
3138 case OPC_DMULTU_G_2E:
3139 case OPC_DMULTU_G_2F:
3140 tcg_gen_mul_tl(cpu_gpr[rd], t0, t1);
3146 int l1 = gen_new_label();
3147 int l2 = gen_new_label();
3148 int l3 = gen_new_label();
3149 tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
3150 tcg_gen_movi_tl(cpu_gpr[rd], 0);
3153 tcg_gen_brcondi_tl(TCG_COND_NE, t0, -1LL << 63, l2);
3154 tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1LL, l2);
3155 tcg_gen_mov_tl(cpu_gpr[rd], t0);
3158 tcg_gen_div_tl(cpu_gpr[rd], t0, t1);
3163 case OPC_DDIVU_G_2E:
3164 case OPC_DDIVU_G_2F:
3166 int l1 = gen_new_label();
3167 int l2 = gen_new_label();
3168 tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
3169 tcg_gen_movi_tl(cpu_gpr[rd], 0);
3172 tcg_gen_divu_tl(cpu_gpr[rd], t0, t1);
3180 int l1 = gen_new_label();
3181 int l2 = gen_new_label();
3182 int l3 = gen_new_label();
3183 tcg_gen_brcondi_tl(TCG_COND_EQ, t1, 0, l1);
3184 tcg_gen_brcondi_tl(TCG_COND_NE, t0, -1LL << 63, l2);
3185 tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1LL, l2);
3187 tcg_gen_movi_tl(cpu_gpr[rd], 0);
3190 tcg_gen_rem_tl(cpu_gpr[rd], t0, t1);
3195 case OPC_DMODU_G_2E:
3196 case OPC_DMODU_G_2F:
3198 int l1 = gen_new_label();
3199 int l2 = gen_new_label();
3200 tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
3201 tcg_gen_movi_tl(cpu_gpr[rd], 0);
3204 tcg_gen_remu_tl(cpu_gpr[rd], t0, t1);
3212 (void)opn; /* avoid a compiler warning */
3213 MIPS_DEBUG("%s %s, %s", opn, regnames[rd], regnames[rs]);
3218 /* Loongson multimedia instructions */
3219 static void gen_loongson_multimedia(DisasContext *ctx, int rd, int rs, int rt)
3221 const char *opn = "loongson_cp2";
3222 uint32_t opc, shift_max;
3225 opc = MASK_LMI(ctx->opcode);
3231 t0 = tcg_temp_local_new_i64();
3232 t1 = tcg_temp_local_new_i64();
3235 t0 = tcg_temp_new_i64();
3236 t1 = tcg_temp_new_i64();
3240 gen_load_fpr64(ctx, t0, rs);
3241 gen_load_fpr64(ctx, t1, rt);
3243 #define LMI_HELPER(UP, LO) \
3244 case OPC_##UP: gen_helper_##LO(t0, t0, t1); opn = #LO; break
3245 #define LMI_HELPER_1(UP, LO) \
3246 case OPC_##UP: gen_helper_##LO(t0, t0); opn = #LO; break
3247 #define LMI_DIRECT(UP, LO, OP) \
3248 case OPC_##UP: tcg_gen_##OP##_i64(t0, t0, t1); opn = #LO; break
3251 LMI_HELPER(PADDSH, paddsh);
3252 LMI_HELPER(PADDUSH, paddush);
3253 LMI_HELPER(PADDH, paddh);
3254 LMI_HELPER(PADDW, paddw);
3255 LMI_HELPER(PADDSB, paddsb);
3256 LMI_HELPER(PADDUSB, paddusb);
3257 LMI_HELPER(PADDB, paddb);
3259 LMI_HELPER(PSUBSH, psubsh);
3260 LMI_HELPER(PSUBUSH, psubush);
3261 LMI_HELPER(PSUBH, psubh);
3262 LMI_HELPER(PSUBW, psubw);
3263 LMI_HELPER(PSUBSB, psubsb);
3264 LMI_HELPER(PSUBUSB, psubusb);
3265 LMI_HELPER(PSUBB, psubb);
3267 LMI_HELPER(PSHUFH, pshufh);
3268 LMI_HELPER(PACKSSWH, packsswh);
3269 LMI_HELPER(PACKSSHB, packsshb);
3270 LMI_HELPER(PACKUSHB, packushb);
3272 LMI_HELPER(PUNPCKLHW, punpcklhw);
3273 LMI_HELPER(PUNPCKHHW, punpckhhw);
3274 LMI_HELPER(PUNPCKLBH, punpcklbh);
3275 LMI_HELPER(PUNPCKHBH, punpckhbh);
3276 LMI_HELPER(PUNPCKLWD, punpcklwd);
3277 LMI_HELPER(PUNPCKHWD, punpckhwd);
3279 LMI_HELPER(PAVGH, pavgh);
3280 LMI_HELPER(PAVGB, pavgb);
3281 LMI_HELPER(PMAXSH, pmaxsh);
3282 LMI_HELPER(PMINSH, pminsh);
3283 LMI_HELPER(PMAXUB, pmaxub);
3284 LMI_HELPER(PMINUB, pminub);
3286 LMI_HELPER(PCMPEQW, pcmpeqw);
3287 LMI_HELPER(PCMPGTW, pcmpgtw);
3288 LMI_HELPER(PCMPEQH, pcmpeqh);
3289 LMI_HELPER(PCMPGTH, pcmpgth);
3290 LMI_HELPER(PCMPEQB, pcmpeqb);
3291 LMI_HELPER(PCMPGTB, pcmpgtb);
3293 LMI_HELPER(PSLLW, psllw);
3294 LMI_HELPER(PSLLH, psllh);
3295 LMI_HELPER(PSRLW, psrlw);
3296 LMI_HELPER(PSRLH, psrlh);
3297 LMI_HELPER(PSRAW, psraw);
3298 LMI_HELPER(PSRAH, psrah);
3300 LMI_HELPER(PMULLH, pmullh);
3301 LMI_HELPER(PMULHH, pmulhh);
3302 LMI_HELPER(PMULHUH, pmulhuh);
3303 LMI_HELPER(PMADDHW, pmaddhw);
3305 LMI_HELPER(PASUBUB, pasubub);
3306 LMI_HELPER_1(BIADD, biadd);
3307 LMI_HELPER_1(PMOVMSKB, pmovmskb);
3309 LMI_DIRECT(PADDD, paddd, add);
3310 LMI_DIRECT(PSUBD, psubd, sub);
3311 LMI_DIRECT(XOR_CP2, xor, xor);
3312 LMI_DIRECT(NOR_CP2, nor, nor);
3313 LMI_DIRECT(AND_CP2, and, and);
3314 LMI_DIRECT(PANDN, pandn, andc);
3315 LMI_DIRECT(OR, or, or);
3318 tcg_gen_deposit_i64(t0, t0, t1, 0, 16);
3322 tcg_gen_deposit_i64(t0, t0, t1, 16, 16);
3326 tcg_gen_deposit_i64(t0, t0, t1, 32, 16);
3330 tcg_gen_deposit_i64(t0, t0, t1, 48, 16);
3335 tcg_gen_andi_i64(t1, t1, 3);
3336 tcg_gen_shli_i64(t1, t1, 4);
3337 tcg_gen_shr_i64(t0, t0, t1);
3338 tcg_gen_ext16u_i64(t0, t0);
3343 tcg_gen_add_i64(t0, t0, t1);
3344 tcg_gen_ext32s_i64(t0, t0);
3348 tcg_gen_sub_i64(t0, t0, t1);
3349 tcg_gen_ext32s_i64(t0, t0);
3378 /* Make sure shift count isn't TCG undefined behaviour. */
3379 tcg_gen_andi_i64(t1, t1, shift_max - 1);
3384 tcg_gen_shl_i64(t0, t0, t1);
3388 /* Since SRA is UndefinedResult without sign-extended inputs,
3389 we can treat SRA and DSRA the same. */
3390 tcg_gen_sar_i64(t0, t0, t1);
3393 /* We want to shift in zeros for SRL; zero-extend first. */
3394 tcg_gen_ext32u_i64(t0, t0);
3397 tcg_gen_shr_i64(t0, t0, t1);
3401 if (shift_max == 32) {
3402 tcg_gen_ext32s_i64(t0, t0);
3405 /* Shifts larger than MAX produce zero. */
3406 tcg_gen_setcondi_i64(TCG_COND_LTU, t1, t1, shift_max);
3407 tcg_gen_neg_i64(t1, t1);
3408 tcg_gen_and_i64(t0, t0, t1);
3414 TCGv_i64 t2 = tcg_temp_new_i64();
3415 int lab = gen_new_label();
3417 tcg_gen_mov_i64(t2, t0);
3418 tcg_gen_add_i64(t0, t1, t2);
3419 if (opc == OPC_ADD_CP2) {
3420 tcg_gen_ext32s_i64(t0, t0);
3422 tcg_gen_xor_i64(t1, t1, t2);
3423 tcg_gen_xor_i64(t2, t2, t0);
3424 tcg_gen_andc_i64(t1, t2, t1);
3425 tcg_temp_free_i64(t2);
3426 tcg_gen_brcondi_i64(TCG_COND_GE, t1, 0, lab);
3427 generate_exception(ctx, EXCP_OVERFLOW);
3430 opn = (opc == OPC_ADD_CP2 ? "add" : "dadd");
3437 TCGv_i64 t2 = tcg_temp_new_i64();
3438 int lab = gen_new_label();
3440 tcg_gen_mov_i64(t2, t0);
3441 tcg_gen_sub_i64(t0, t1, t2);
3442 if (opc == OPC_SUB_CP2) {
3443 tcg_gen_ext32s_i64(t0, t0);
3445 tcg_gen_xor_i64(t1, t1, t2);
3446 tcg_gen_xor_i64(t2, t2, t0);
3447 tcg_gen_and_i64(t1, t1, t2);
3448 tcg_temp_free_i64(t2);
3449 tcg_gen_brcondi_i64(TCG_COND_GE, t1, 0, lab);
3450 generate_exception(ctx, EXCP_OVERFLOW);
3453 opn = (opc == OPC_SUB_CP2 ? "sub" : "dsub");
3458 tcg_gen_ext32u_i64(t0, t0);
3459 tcg_gen_ext32u_i64(t1, t1);
3460 tcg_gen_mul_i64(t0, t0, t1);
3470 /* ??? Document is unclear: Set FCC[CC]. Does that mean the
3471 FD field is the CC field? */
3474 generate_exception(ctx, EXCP_RI);
3481 gen_store_fpr64(ctx, t0, rd);
3483 (void)opn; /* avoid a compiler warning */
3484 MIPS_DEBUG("%s %s, %s, %s", opn,
3485 fregnames[rd], fregnames[rs], fregnames[rt]);
3486 tcg_temp_free_i64(t0);
3487 tcg_temp_free_i64(t1);
3491 static void gen_trap (DisasContext *ctx, uint32_t opc,
3492 int rs, int rt, int16_t imm)
3495 TCGv t0 = tcg_temp_new();
3496 TCGv t1 = tcg_temp_new();
3499 /* Load needed operands */
3507 /* Compare two registers */
3509 gen_load_gpr(t0, rs);
3510 gen_load_gpr(t1, rt);
3520 /* Compare register to immediate */
3521 if (rs != 0 || imm != 0) {
3522 gen_load_gpr(t0, rs);
3523 tcg_gen_movi_tl(t1, (int32_t)imm);
3530 case OPC_TEQ: /* rs == rs */
3531 case OPC_TEQI: /* r0 == 0 */
3532 case OPC_TGE: /* rs >= rs */
3533 case OPC_TGEI: /* r0 >= 0 */
3534 case OPC_TGEU: /* rs >= rs unsigned */
3535 case OPC_TGEIU: /* r0 >= 0 unsigned */
3537 generate_exception(ctx, EXCP_TRAP);
3539 case OPC_TLT: /* rs < rs */
3540 case OPC_TLTI: /* r0 < 0 */
3541 case OPC_TLTU: /* rs < rs unsigned */
3542 case OPC_TLTIU: /* r0 < 0 unsigned */
3543 case OPC_TNE: /* rs != rs */
3544 case OPC_TNEI: /* r0 != 0 */
3545 /* Never trap: treat as NOP. */
3549 int l1 = gen_new_label();
3554 tcg_gen_brcond_tl(TCG_COND_NE, t0, t1, l1);
3558 tcg_gen_brcond_tl(TCG_COND_LT, t0, t1, l1);
3562 tcg_gen_brcond_tl(TCG_COND_LTU, t0, t1, l1);
3566 tcg_gen_brcond_tl(TCG_COND_GE, t0, t1, l1);
3570 tcg_gen_brcond_tl(TCG_COND_GEU, t0, t1, l1);
3574 tcg_gen_brcond_tl(TCG_COND_EQ, t0, t1, l1);
3577 generate_exception(ctx, EXCP_TRAP);
3584 static inline void gen_goto_tb(DisasContext *ctx, int n, target_ulong dest)
3586 TranslationBlock *tb;
3588 if ((tb->pc & TARGET_PAGE_MASK) == (dest & TARGET_PAGE_MASK) &&
3589 likely(!ctx->singlestep_enabled)) {
3592 tcg_gen_exit_tb((tcg_target_long)tb + n);
3595 if (ctx->singlestep_enabled) {
3596 save_cpu_state(ctx, 0);
3597 gen_helper_0e0i(raise_exception, EXCP_DEBUG);
3603 /* Branches (before delay slot) */
3604 static void gen_compute_branch (DisasContext *ctx, uint32_t opc,
3606 int rs, int rt, int32_t offset)
3608 target_ulong btgt = -1;
3610 int bcond_compute = 0;
3611 TCGv t0 = tcg_temp_new();
3612 TCGv t1 = tcg_temp_new();
3614 if (ctx->hflags & MIPS_HFLAG_BMASK) {
3615 #ifdef MIPS_DEBUG_DISAS
3616 LOG_DISAS("Branch in delay slot at PC 0x" TARGET_FMT_lx "\n", ctx->pc);
3618 generate_exception(ctx, EXCP_RI);
3622 /* Load needed operands */
3628 /* Compare two registers */
3630 gen_load_gpr(t0, rs);
3631 gen_load_gpr(t1, rt);
3634 btgt = ctx->pc + insn_bytes + offset;
3650 /* Compare to zero */
3652 gen_load_gpr(t0, rs);
3655 btgt = ctx->pc + insn_bytes + offset;
3658 #if defined(TARGET_MIPS64)
3660 tcg_gen_andi_tl(t0, cpu_dspctrl, 0x7F);
3662 tcg_gen_andi_tl(t0, cpu_dspctrl, 0x3F);
3665 btgt = ctx->pc + insn_bytes + offset;
3672 /* Jump to immediate */
3673 btgt = ((ctx->pc + insn_bytes) & (int32_t)0xF0000000) | (uint32_t)offset;
3679 /* Jump to register */
3680 if (offset != 0 && offset != 16) {
3681 /* Hint = 0 is JR/JALR, hint 16 is JR.HB/JALR.HB, the
3682 others are reserved. */
3683 MIPS_INVAL("jump hint");
3684 generate_exception(ctx, EXCP_RI);
3687 gen_load_gpr(btarget, rs);
3690 MIPS_INVAL("branch/jump");
3691 generate_exception(ctx, EXCP_RI);
3694 if (bcond_compute == 0) {
3695 /* No condition to be computed */
3697 case OPC_BEQ: /* rx == rx */
3698 case OPC_BEQL: /* rx == rx likely */
3699 case OPC_BGEZ: /* 0 >= 0 */
3700 case OPC_BGEZL: /* 0 >= 0 likely */
3701 case OPC_BLEZ: /* 0 <= 0 */
3702 case OPC_BLEZL: /* 0 <= 0 likely */
3704 ctx->hflags |= MIPS_HFLAG_B;
3705 MIPS_DEBUG("balways");
3708 case OPC_BGEZAL: /* 0 >= 0 */
3709 case OPC_BGEZALL: /* 0 >= 0 likely */
3710 ctx->hflags |= (opc == OPC_BGEZALS
3712 : MIPS_HFLAG_BDS32);
3713 /* Always take and link */
3715 ctx->hflags |= MIPS_HFLAG_B;
3716 MIPS_DEBUG("balways and link");
3718 case OPC_BNE: /* rx != rx */
3719 case OPC_BGTZ: /* 0 > 0 */
3720 case OPC_BLTZ: /* 0 < 0 */
3722 MIPS_DEBUG("bnever (NOP)");
3725 case OPC_BLTZAL: /* 0 < 0 */
3726 ctx->hflags |= (opc == OPC_BLTZALS
3728 : MIPS_HFLAG_BDS32);
3729 /* Handle as an unconditional branch to get correct delay
3732 btgt = ctx->pc + (opc == OPC_BLTZALS ? 6 : 8);
3733 ctx->hflags |= MIPS_HFLAG_B;
3734 MIPS_DEBUG("bnever and link");
3736 case OPC_BLTZALL: /* 0 < 0 likely */
3737 tcg_gen_movi_tl(cpu_gpr[31], ctx->pc + 8);
3738 /* Skip the instruction in the delay slot */
3739 MIPS_DEBUG("bnever, link and skip");
3742 case OPC_BNEL: /* rx != rx likely */
3743 case OPC_BGTZL: /* 0 > 0 likely */
3744 case OPC_BLTZL: /* 0 < 0 likely */
3745 /* Skip the instruction in the delay slot */
3746 MIPS_DEBUG("bnever and skip");
3750 ctx->hflags |= MIPS_HFLAG_B;
3751 MIPS_DEBUG("j " TARGET_FMT_lx, btgt);
3755 ctx->hflags |= MIPS_HFLAG_BX;
3760 ctx->hflags |= MIPS_HFLAG_B;
3761 ctx->hflags |= ((opc == OPC_JALS || opc == OPC_JALXS)
3763 : MIPS_HFLAG_BDS32);
3764 MIPS_DEBUG("jal " TARGET_FMT_lx, btgt);
3767 ctx->hflags |= MIPS_HFLAG_BR;
3768 if (insn_bytes == 4)
3769 ctx->hflags |= MIPS_HFLAG_BDS32;
3770 MIPS_DEBUG("jr %s", regnames[rs]);
3776 ctx->hflags |= MIPS_HFLAG_BR;
3777 ctx->hflags |= (opc == OPC_JALRS
3779 : MIPS_HFLAG_BDS32);
3780 MIPS_DEBUG("jalr %s, %s", regnames[rt], regnames[rs]);
3783 MIPS_INVAL("branch/jump");
3784 generate_exception(ctx, EXCP_RI);
3790 tcg_gen_setcond_tl(TCG_COND_EQ, bcond, t0, t1);
3791 MIPS_DEBUG("beq %s, %s, " TARGET_FMT_lx,
3792 regnames[rs], regnames[rt], btgt);
3795 tcg_gen_setcond_tl(TCG_COND_EQ, bcond, t0, t1);
3796 MIPS_DEBUG("beql %s, %s, " TARGET_FMT_lx,
3797 regnames[rs], regnames[rt], btgt);
3800 tcg_gen_setcond_tl(TCG_COND_NE, bcond, t0, t1);
3801 MIPS_DEBUG("bne %s, %s, " TARGET_FMT_lx,
3802 regnames[rs], regnames[rt], btgt);
3805 tcg_gen_setcond_tl(TCG_COND_NE, bcond, t0, t1);
3806 MIPS_DEBUG("bnel %s, %s, " TARGET_FMT_lx,
3807 regnames[rs], regnames[rt], btgt);
3810 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 0);
3811 MIPS_DEBUG("bgez %s, " TARGET_FMT_lx, regnames[rs], btgt);
3814 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 0);
3815 MIPS_DEBUG("bgezl %s, " TARGET_FMT_lx, regnames[rs], btgt);
3819 ctx->hflags |= (opc == OPC_BGEZALS
3821 : MIPS_HFLAG_BDS32);
3822 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 0);
3823 MIPS_DEBUG("bgezal %s, " TARGET_FMT_lx, regnames[rs], btgt);
3827 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 0);
3829 MIPS_DEBUG("bgezall %s, " TARGET_FMT_lx, regnames[rs], btgt);
3832 tcg_gen_setcondi_tl(TCG_COND_GT, bcond, t0, 0);
3833 MIPS_DEBUG("bgtz %s, " TARGET_FMT_lx, regnames[rs], btgt);
3836 tcg_gen_setcondi_tl(TCG_COND_GT, bcond, t0, 0);
3837 MIPS_DEBUG("bgtzl %s, " TARGET_FMT_lx, regnames[rs], btgt);
3840 tcg_gen_setcondi_tl(TCG_COND_LE, bcond, t0, 0);
3841 MIPS_DEBUG("blez %s, " TARGET_FMT_lx, regnames[rs], btgt);
3844 tcg_gen_setcondi_tl(TCG_COND_LE, bcond, t0, 0);
3845 MIPS_DEBUG("blezl %s, " TARGET_FMT_lx, regnames[rs], btgt);
3848 tcg_gen_setcondi_tl(TCG_COND_LT, bcond, t0, 0);
3849 MIPS_DEBUG("bltz %s, " TARGET_FMT_lx, regnames[rs], btgt);
3852 tcg_gen_setcondi_tl(TCG_COND_LT, bcond, t0, 0);
3853 MIPS_DEBUG("bltzl %s, " TARGET_FMT_lx, regnames[rs], btgt);
3856 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 32);
3857 MIPS_DEBUG("bposge32 " TARGET_FMT_lx, btgt);
3859 #if defined(TARGET_MIPS64)
3861 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 64);
3862 MIPS_DEBUG("bposge64 " TARGET_FMT_lx, btgt);
3867 ctx->hflags |= (opc == OPC_BLTZALS
3869 : MIPS_HFLAG_BDS32);
3870 tcg_gen_setcondi_tl(TCG_COND_LT, bcond, t0, 0);
3872 MIPS_DEBUG("bltzal %s, " TARGET_FMT_lx, regnames[rs], btgt);
3874 ctx->hflags |= MIPS_HFLAG_BC;
3877 tcg_gen_setcondi_tl(TCG_COND_LT, bcond, t0, 0);
3879 MIPS_DEBUG("bltzall %s, " TARGET_FMT_lx, regnames[rs], btgt);
3881 ctx->hflags |= MIPS_HFLAG_BL;
3884 MIPS_INVAL("conditional branch/jump");
3885 generate_exception(ctx, EXCP_RI);
3889 MIPS_DEBUG("enter ds: link %d cond %02x target " TARGET_FMT_lx,
3890 blink, ctx->hflags, btgt);
3892 ctx->btarget = btgt;
3894 int post_delay = insn_bytes;
3895 int lowbit = !!(ctx->hflags & MIPS_HFLAG_M16);
3897 if (opc != OPC_JALRC)
3898 post_delay += ((ctx->hflags & MIPS_HFLAG_BDS16) ? 2 : 4);
3900 tcg_gen_movi_tl(cpu_gpr[blink], ctx->pc + post_delay + lowbit);
3904 if (insn_bytes == 2)
3905 ctx->hflags |= MIPS_HFLAG_B16;
3910 /* special3 bitfield operations */
3911 static void gen_bitops (DisasContext *ctx, uint32_t opc, int rt,
3912 int rs, int lsb, int msb)
3914 TCGv t0 = tcg_temp_new();
3915 TCGv t1 = tcg_temp_new();
3918 gen_load_gpr(t1, rs);
3923 tcg_gen_shri_tl(t0, t1, lsb);
3925 tcg_gen_andi_tl(t0, t0, (1 << (msb + 1)) - 1);
3927 tcg_gen_ext32s_tl(t0, t0);
3930 #if defined(TARGET_MIPS64)
3932 tcg_gen_shri_tl(t0, t1, lsb);
3934 tcg_gen_andi_tl(t0, t0, (1ULL << (msb + 1 + 32)) - 1);
3938 tcg_gen_shri_tl(t0, t1, lsb + 32);
3939 tcg_gen_andi_tl(t0, t0, (1ULL << (msb + 1)) - 1);
3942 tcg_gen_shri_tl(t0, t1, lsb);
3943 tcg_gen_andi_tl(t0, t0, (1ULL << (msb + 1)) - 1);
3949 mask = ((msb - lsb + 1 < 32) ? ((1 << (msb - lsb + 1)) - 1) : ~0) << lsb;
3950 gen_load_gpr(t0, rt);
3951 tcg_gen_andi_tl(t0, t0, ~mask);
3952 tcg_gen_shli_tl(t1, t1, lsb);
3953 tcg_gen_andi_tl(t1, t1, mask);
3954 tcg_gen_or_tl(t0, t0, t1);
3955 tcg_gen_ext32s_tl(t0, t0);
3957 #if defined(TARGET_MIPS64)
3961 mask = ((msb - lsb + 1 + 32 < 64) ? ((1ULL << (msb - lsb + 1 + 32)) - 1) : ~0ULL) << 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 mask = ((1ULL << (msb - lsb + 1)) - 1) << (lsb + 32);
3972 gen_load_gpr(t0, rt);
3973 tcg_gen_andi_tl(t0, t0, ~mask);
3974 tcg_gen_shli_tl(t1, t1, lsb + 32);
3975 tcg_gen_andi_tl(t1, t1, mask);
3976 tcg_gen_or_tl(t0, t0, t1);
3981 gen_load_gpr(t0, rt);
3982 mask = ((1ULL << (msb - lsb + 1)) - 1) << lsb;
3983 gen_load_gpr(t0, rt);
3984 tcg_gen_andi_tl(t0, t0, ~mask);
3985 tcg_gen_shli_tl(t1, t1, lsb);
3986 tcg_gen_andi_tl(t1, t1, mask);
3987 tcg_gen_or_tl(t0, t0, t1);
3992 MIPS_INVAL("bitops");
3993 generate_exception(ctx, EXCP_RI);
3998 gen_store_gpr(t0, rt);
4003 static void gen_bshfl (DisasContext *ctx, uint32_t op2, int rt, int rd)
4008 /* If no destination, treat it as a NOP. */
4013 t0 = tcg_temp_new();
4014 gen_load_gpr(t0, rt);
4018 TCGv t1 = tcg_temp_new();
4020 tcg_gen_shri_tl(t1, t0, 8);
4021 tcg_gen_andi_tl(t1, t1, 0x00FF00FF);
4022 tcg_gen_shli_tl(t0, t0, 8);
4023 tcg_gen_andi_tl(t0, t0, ~0x00FF00FF);
4024 tcg_gen_or_tl(t0, t0, t1);
4026 tcg_gen_ext32s_tl(cpu_gpr[rd], t0);
4030 tcg_gen_ext8s_tl(cpu_gpr[rd], t0);
4033 tcg_gen_ext16s_tl(cpu_gpr[rd], t0);
4035 #if defined(TARGET_MIPS64)
4038 TCGv t1 = tcg_temp_new();
4040 tcg_gen_shri_tl(t1, t0, 8);
4041 tcg_gen_andi_tl(t1, t1, 0x00FF00FF00FF00FFULL);
4042 tcg_gen_shli_tl(t0, t0, 8);
4043 tcg_gen_andi_tl(t0, t0, ~0x00FF00FF00FF00FFULL);
4044 tcg_gen_or_tl(cpu_gpr[rd], t0, t1);
4050 TCGv t1 = tcg_temp_new();
4052 tcg_gen_shri_tl(t1, t0, 16);
4053 tcg_gen_andi_tl(t1, t1, 0x0000FFFF0000FFFFULL);
4054 tcg_gen_shli_tl(t0, t0, 16);
4055 tcg_gen_andi_tl(t0, t0, ~0x0000FFFF0000FFFFULL);
4056 tcg_gen_or_tl(t0, t0, t1);
4057 tcg_gen_shri_tl(t1, t0, 32);
4058 tcg_gen_shli_tl(t0, t0, 32);
4059 tcg_gen_or_tl(cpu_gpr[rd], t0, t1);
4065 MIPS_INVAL("bsfhl");
4066 generate_exception(ctx, EXCP_RI);
4073 #ifndef CONFIG_USER_ONLY
4074 /* CP0 (MMU and control) */
4075 static inline void gen_mfc0_load32 (TCGv arg, target_ulong off)
4077 TCGv_i32 t0 = tcg_temp_new_i32();
4079 tcg_gen_ld_i32(t0, cpu_env, off);
4080 tcg_gen_ext_i32_tl(arg, t0);
4081 tcg_temp_free_i32(t0);
4084 static inline void gen_mfc0_load64 (TCGv arg, target_ulong off)
4086 tcg_gen_ld_tl(arg, cpu_env, off);
4087 tcg_gen_ext32s_tl(arg, arg);
4090 static inline void gen_mtc0_store32 (TCGv arg, target_ulong off)
4092 TCGv_i32 t0 = tcg_temp_new_i32();
4094 tcg_gen_trunc_tl_i32(t0, arg);
4095 tcg_gen_st_i32(t0, cpu_env, off);
4096 tcg_temp_free_i32(t0);
4099 static inline void gen_mtc0_store64 (TCGv arg, target_ulong off)
4101 tcg_gen_ext32s_tl(arg, arg);
4102 tcg_gen_st_tl(arg, cpu_env, off);
4105 static void gen_mfc0 (CPUMIPSState *env, DisasContext *ctx, TCGv arg, int reg, int sel)
4107 const char *rn = "invalid";
4110 check_insn(env, ctx, ISA_MIPS32);
4116 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Index));
4120 check_insn(env, ctx, ASE_MT);
4121 gen_helper_mfc0_mvpcontrol(arg, cpu_env);
4125 check_insn(env, ctx, ASE_MT);
4126 gen_helper_mfc0_mvpconf0(arg, cpu_env);
4130 check_insn(env, ctx, ASE_MT);
4131 gen_helper_mfc0_mvpconf1(arg, cpu_env);
4141 gen_helper_mfc0_random(arg, cpu_env);
4145 check_insn(env, ctx, ASE_MT);
4146 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEControl));
4150 check_insn(env, ctx, ASE_MT);
4151 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEConf0));
4155 check_insn(env, ctx, ASE_MT);
4156 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEConf1));
4160 check_insn(env, ctx, ASE_MT);
4161 gen_mfc0_load64(arg, offsetof(CPUMIPSState, CP0_YQMask));
4165 check_insn(env, ctx, ASE_MT);
4166 gen_mfc0_load64(arg, offsetof(CPUMIPSState, CP0_VPESchedule));
4170 check_insn(env, ctx, ASE_MT);
4171 gen_mfc0_load64(arg, offsetof(CPUMIPSState, CP0_VPEScheFBack));
4172 rn = "VPEScheFBack";
4175 check_insn(env, ctx, ASE_MT);
4176 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEOpt));
4186 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EntryLo0));
4187 tcg_gen_ext32s_tl(arg, arg);
4191 check_insn(env, ctx, ASE_MT);
4192 gen_helper_mfc0_tcstatus(arg, cpu_env);
4196 check_insn(env, ctx, ASE_MT);
4197 gen_helper_mfc0_tcbind(arg, cpu_env);
4201 check_insn(env, ctx, ASE_MT);
4202 gen_helper_mfc0_tcrestart(arg, cpu_env);
4206 check_insn(env, ctx, ASE_MT);
4207 gen_helper_mfc0_tchalt(arg, cpu_env);
4211 check_insn(env, ctx, ASE_MT);
4212 gen_helper_mfc0_tccontext(arg, cpu_env);
4216 check_insn(env, ctx, ASE_MT);
4217 gen_helper_mfc0_tcschedule(arg, cpu_env);
4221 check_insn(env, ctx, ASE_MT);
4222 gen_helper_mfc0_tcschefback(arg, cpu_env);
4232 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EntryLo1));
4233 tcg_gen_ext32s_tl(arg, arg);
4243 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_Context));
4244 tcg_gen_ext32s_tl(arg, arg);
4248 // gen_helper_mfc0_contextconfig(arg); /* SmartMIPS ASE */
4249 rn = "ContextConfig";
4258 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PageMask));
4262 check_insn(env, ctx, ISA_MIPS32R2);
4263 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PageGrain));
4273 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Wired));
4277 check_insn(env, ctx, ISA_MIPS32R2);
4278 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf0));
4282 check_insn(env, ctx, ISA_MIPS32R2);
4283 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf1));
4287 check_insn(env, ctx, ISA_MIPS32R2);
4288 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf2));
4292 check_insn(env, ctx, ISA_MIPS32R2);
4293 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf3));
4297 check_insn(env, ctx, ISA_MIPS32R2);
4298 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf4));
4308 check_insn(env, ctx, ISA_MIPS32R2);
4309 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_HWREna));
4319 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_BadVAddr));
4320 tcg_gen_ext32s_tl(arg, arg);
4330 /* Mark as an IO operation because we read the time. */
4333 gen_helper_mfc0_count(arg, cpu_env);
4337 /* Break the TB to be able to take timer interrupts immediately
4338 after reading count. */
4339 ctx->bstate = BS_STOP;
4342 /* 6,7 are implementation dependent */
4350 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EntryHi));
4351 tcg_gen_ext32s_tl(arg, arg);
4361 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Compare));
4364 /* 6,7 are implementation dependent */
4372 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Status));
4376 check_insn(env, ctx, ISA_MIPS32R2);
4377 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_IntCtl));
4381 check_insn(env, ctx, ISA_MIPS32R2);
4382 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSCtl));
4386 check_insn(env, ctx, ISA_MIPS32R2);
4387 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSMap));
4397 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Cause));
4407 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EPC));
4408 tcg_gen_ext32s_tl(arg, arg);
4418 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PRid));
4422 check_insn(env, ctx, ISA_MIPS32R2);
4423 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_EBase));
4433 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config0));
4437 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config1));
4441 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config2));
4445 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config3));
4448 /* 4,5 are reserved */
4449 /* 6,7 are implementation dependent */
4451 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config6));
4455 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config7));
4465 gen_helper_mfc0_lladdr(arg, cpu_env);
4475 gen_helper_1e0i(mfc0_watchlo, arg, sel);
4485 gen_helper_1e0i(mfc0_watchhi, arg, sel);
4495 #if defined(TARGET_MIPS64)
4496 check_insn(env, ctx, ISA_MIPS3);
4497 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_XContext));
4498 tcg_gen_ext32s_tl(arg, arg);
4507 /* Officially reserved, but sel 0 is used for R1x000 framemask */
4510 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Framemask));
4518 tcg_gen_movi_tl(arg, 0); /* unimplemented */
4519 rn = "'Diagnostic"; /* implementation dependent */
4524 gen_helper_mfc0_debug(arg, cpu_env); /* EJTAG support */
4528 // gen_helper_mfc0_tracecontrol(arg); /* PDtrace support */
4529 rn = "TraceControl";
4532 // gen_helper_mfc0_tracecontrol2(arg); /* PDtrace support */
4533 rn = "TraceControl2";
4536 // gen_helper_mfc0_usertracedata(arg); /* PDtrace support */
4537 rn = "UserTraceData";
4540 // gen_helper_mfc0_tracebpc(arg); /* PDtrace support */
4551 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_DEPC));
4552 tcg_gen_ext32s_tl(arg, arg);
4562 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Performance0));
4563 rn = "Performance0";
4566 // gen_helper_mfc0_performance1(arg);
4567 rn = "Performance1";
4570 // gen_helper_mfc0_performance2(arg);
4571 rn = "Performance2";
4574 // gen_helper_mfc0_performance3(arg);
4575 rn = "Performance3";
4578 // gen_helper_mfc0_performance4(arg);
4579 rn = "Performance4";
4582 // gen_helper_mfc0_performance5(arg);
4583 rn = "Performance5";
4586 // gen_helper_mfc0_performance6(arg);
4587 rn = "Performance6";
4590 // gen_helper_mfc0_performance7(arg);
4591 rn = "Performance7";
4598 tcg_gen_movi_tl(arg, 0); /* unimplemented */
4604 tcg_gen_movi_tl(arg, 0); /* unimplemented */
4617 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_TagLo));
4624 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DataLo));
4637 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_TagHi));
4644 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DataHi));
4654 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_ErrorEPC));
4655 tcg_gen_ext32s_tl(arg, arg);
4666 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DESAVE));
4676 (void)rn; /* avoid a compiler warning */
4677 LOG_DISAS("mfc0 %s (reg %d sel %d)\n", rn, reg, sel);
4681 LOG_DISAS("mfc0 %s (reg %d sel %d)\n", rn, reg, sel);
4682 generate_exception(ctx, EXCP_RI);
4685 static void gen_mtc0 (CPUMIPSState *env, DisasContext *ctx, TCGv arg, int reg, int sel)
4687 const char *rn = "invalid";
4690 check_insn(env, ctx, ISA_MIPS32);
4699 gen_helper_mtc0_index(cpu_env, arg);
4703 check_insn(env, ctx, ASE_MT);
4704 gen_helper_mtc0_mvpcontrol(cpu_env, arg);
4708 check_insn(env, ctx, ASE_MT);
4713 check_insn(env, ctx, ASE_MT);
4728 check_insn(env, ctx, ASE_MT);
4729 gen_helper_mtc0_vpecontrol(cpu_env, arg);
4733 check_insn(env, ctx, ASE_MT);
4734 gen_helper_mtc0_vpeconf0(cpu_env, arg);
4738 check_insn(env, ctx, ASE_MT);
4739 gen_helper_mtc0_vpeconf1(cpu_env, arg);
4743 check_insn(env, ctx, ASE_MT);
4744 gen_helper_mtc0_yqmask(cpu_env, arg);
4748 check_insn(env, ctx, ASE_MT);
4749 gen_mtc0_store64(arg, offsetof(CPUMIPSState, CP0_VPESchedule));
4753 check_insn(env, ctx, ASE_MT);
4754 gen_mtc0_store64(arg, offsetof(CPUMIPSState, CP0_VPEScheFBack));
4755 rn = "VPEScheFBack";
4758 check_insn(env, ctx, ASE_MT);
4759 gen_helper_mtc0_vpeopt(cpu_env, arg);
4769 gen_helper_mtc0_entrylo0(cpu_env, arg);
4773 check_insn(env, ctx, ASE_MT);
4774 gen_helper_mtc0_tcstatus(cpu_env, arg);
4778 check_insn(env, ctx, ASE_MT);
4779 gen_helper_mtc0_tcbind(cpu_env, arg);
4783 check_insn(env, ctx, ASE_MT);
4784 gen_helper_mtc0_tcrestart(cpu_env, arg);
4788 check_insn(env, ctx, ASE_MT);
4789 gen_helper_mtc0_tchalt(cpu_env, arg);
4793 check_insn(env, ctx, ASE_MT);
4794 gen_helper_mtc0_tccontext(cpu_env, arg);
4798 check_insn(env, ctx, ASE_MT);
4799 gen_helper_mtc0_tcschedule(cpu_env, arg);
4803 check_insn(env, ctx, ASE_MT);
4804 gen_helper_mtc0_tcschefback(cpu_env, arg);
4814 gen_helper_mtc0_entrylo1(cpu_env, arg);
4824 gen_helper_mtc0_context(cpu_env, arg);
4828 // gen_helper_mtc0_contextconfig(cpu_env, arg); /* SmartMIPS ASE */
4829 rn = "ContextConfig";
4838 gen_helper_mtc0_pagemask(cpu_env, arg);
4842 check_insn(env, ctx, ISA_MIPS32R2);
4843 gen_helper_mtc0_pagegrain(cpu_env, arg);
4853 gen_helper_mtc0_wired(cpu_env, arg);
4857 check_insn(env, ctx, ISA_MIPS32R2);
4858 gen_helper_mtc0_srsconf0(cpu_env, arg);
4862 check_insn(env, ctx, ISA_MIPS32R2);
4863 gen_helper_mtc0_srsconf1(cpu_env, arg);
4867 check_insn(env, ctx, ISA_MIPS32R2);
4868 gen_helper_mtc0_srsconf2(cpu_env, arg);
4872 check_insn(env, ctx, ISA_MIPS32R2);
4873 gen_helper_mtc0_srsconf3(cpu_env, arg);
4877 check_insn(env, ctx, ISA_MIPS32R2);
4878 gen_helper_mtc0_srsconf4(cpu_env, arg);
4888 check_insn(env, ctx, ISA_MIPS32R2);
4889 gen_helper_mtc0_hwrena(cpu_env, arg);
4903 gen_helper_mtc0_count(cpu_env, arg);
4906 /* 6,7 are implementation dependent */
4914 gen_helper_mtc0_entryhi(cpu_env, arg);
4924 gen_helper_mtc0_compare(cpu_env, arg);
4927 /* 6,7 are implementation dependent */
4935 save_cpu_state(ctx, 1);
4936 gen_helper_mtc0_status(cpu_env, arg);
4937 /* BS_STOP isn't good enough here, hflags may have changed. */
4938 gen_save_pc(ctx->pc + 4);
4939 ctx->bstate = BS_EXCP;
4943 check_insn(env, ctx, ISA_MIPS32R2);
4944 gen_helper_mtc0_intctl(cpu_env, arg);
4945 /* Stop translation as we may have switched the execution mode */
4946 ctx->bstate = BS_STOP;
4950 check_insn(env, ctx, ISA_MIPS32R2);
4951 gen_helper_mtc0_srsctl(cpu_env, arg);
4952 /* Stop translation as we may have switched the execution mode */
4953 ctx->bstate = BS_STOP;
4957 check_insn(env, ctx, ISA_MIPS32R2);
4958 gen_mtc0_store32(arg, offsetof(CPUMIPSState, CP0_SRSMap));
4959 /* Stop translation as we may have switched the execution mode */
4960 ctx->bstate = BS_STOP;
4970 save_cpu_state(ctx, 1);
4971 gen_helper_mtc0_cause(cpu_env, arg);
4981 gen_mtc0_store64(arg, offsetof(CPUMIPSState, CP0_EPC));
4995 check_insn(env, ctx, ISA_MIPS32R2);
4996 gen_helper_mtc0_ebase(cpu_env, arg);
5006 gen_helper_mtc0_config0(cpu_env, arg);
5008 /* Stop translation as we may have switched the execution mode */
5009 ctx->bstate = BS_STOP;
5012 /* ignored, read only */
5016 gen_helper_mtc0_config2(cpu_env, arg);
5018 /* Stop translation as we may have switched the execution mode */
5019 ctx->bstate = BS_STOP;
5022 /* ignored, read only */
5025 /* 4,5 are reserved */
5026 /* 6,7 are implementation dependent */
5036 rn = "Invalid config selector";
5043 gen_helper_mtc0_lladdr(cpu_env, arg);
5053 gen_helper_0e1i(mtc0_watchlo, arg, sel);
5063 gen_helper_0e1i(mtc0_watchhi, arg, sel);
5073 #if defined(TARGET_MIPS64)
5074 check_insn(env, ctx, ISA_MIPS3);
5075 gen_helper_mtc0_xcontext(cpu_env, arg);
5084 /* Officially reserved, but sel 0 is used for R1x000 framemask */
5087 gen_helper_mtc0_framemask(cpu_env, arg);
5096 rn = "Diagnostic"; /* implementation dependent */
5101 gen_helper_mtc0_debug(cpu_env, arg); /* EJTAG support */
5102 /* BS_STOP isn't good enough here, hflags may have changed. */
5103 gen_save_pc(ctx->pc + 4);
5104 ctx->bstate = BS_EXCP;
5108 // gen_helper_mtc0_tracecontrol(cpu_env, arg); /* PDtrace support */
5109 rn = "TraceControl";
5110 /* Stop translation as we may have switched the execution mode */
5111 ctx->bstate = BS_STOP;
5114 // gen_helper_mtc0_tracecontrol2(cpu_env, arg); /* PDtrace support */
5115 rn = "TraceControl2";
5116 /* Stop translation as we may have switched the execution mode */
5117 ctx->bstate = BS_STOP;
5120 /* Stop translation as we may have switched the execution mode */
5121 ctx->bstate = BS_STOP;
5122 // gen_helper_mtc0_usertracedata(cpu_env, arg); /* PDtrace support */
5123 rn = "UserTraceData";
5124 /* Stop translation as we may have switched the execution mode */
5125 ctx->bstate = BS_STOP;
5128 // gen_helper_mtc0_tracebpc(cpu_env, arg); /* PDtrace support */
5129 /* Stop translation as we may have switched the execution mode */
5130 ctx->bstate = BS_STOP;
5141 gen_mtc0_store64(arg, offsetof(CPUMIPSState, CP0_DEPC));
5151 gen_helper_mtc0_performance0(cpu_env, arg);
5152 rn = "Performance0";
5155 // gen_helper_mtc0_performance1(arg);
5156 rn = "Performance1";
5159 // gen_helper_mtc0_performance2(arg);
5160 rn = "Performance2";
5163 // gen_helper_mtc0_performance3(arg);
5164 rn = "Performance3";
5167 // gen_helper_mtc0_performance4(arg);
5168 rn = "Performance4";
5171 // gen_helper_mtc0_performance5(arg);
5172 rn = "Performance5";
5175 // gen_helper_mtc0_performance6(arg);
5176 rn = "Performance6";
5179 // gen_helper_mtc0_performance7(arg);
5180 rn = "Performance7";
5206 gen_helper_mtc0_taglo(cpu_env, arg);
5213 gen_helper_mtc0_datalo(cpu_env, arg);
5226 gen_helper_mtc0_taghi(cpu_env, arg);
5233 gen_helper_mtc0_datahi(cpu_env, arg);
5244 gen_mtc0_store64(arg, offsetof(CPUMIPSState, CP0_ErrorEPC));
5255 gen_mtc0_store32(arg, offsetof(CPUMIPSState, CP0_DESAVE));
5261 /* Stop translation as we may have switched the execution mode */
5262 ctx->bstate = BS_STOP;
5267 (void)rn; /* avoid a compiler warning */
5268 LOG_DISAS("mtc0 %s (reg %d sel %d)\n", rn, reg, sel);
5269 /* For simplicity assume that all writes can cause interrupts. */
5272 ctx->bstate = BS_STOP;
5277 LOG_DISAS("mtc0 %s (reg %d sel %d)\n", rn, reg, sel);
5278 generate_exception(ctx, EXCP_RI);
5281 #if defined(TARGET_MIPS64)
5282 static void gen_dmfc0 (CPUMIPSState *env, DisasContext *ctx, TCGv arg, int reg, int sel)
5284 const char *rn = "invalid";
5287 check_insn(env, ctx, ISA_MIPS64);
5293 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Index));
5297 check_insn(env, ctx, ASE_MT);
5298 gen_helper_mfc0_mvpcontrol(arg, cpu_env);
5302 check_insn(env, ctx, ASE_MT);
5303 gen_helper_mfc0_mvpconf0(arg, cpu_env);
5307 check_insn(env, ctx, ASE_MT);
5308 gen_helper_mfc0_mvpconf1(arg, cpu_env);
5318 gen_helper_mfc0_random(arg, cpu_env);
5322 check_insn(env, ctx, ASE_MT);
5323 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEControl));
5327 check_insn(env, ctx, ASE_MT);
5328 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEConf0));
5332 check_insn(env, ctx, ASE_MT);
5333 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEConf1));
5337 check_insn(env, ctx, ASE_MT);
5338 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_YQMask));
5342 check_insn(env, ctx, ASE_MT);
5343 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_VPESchedule));
5347 check_insn(env, ctx, ASE_MT);
5348 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_VPEScheFBack));
5349 rn = "VPEScheFBack";
5352 check_insn(env, ctx, ASE_MT);
5353 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEOpt));
5363 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EntryLo0));
5367 check_insn(env, ctx, ASE_MT);
5368 gen_helper_mfc0_tcstatus(arg, cpu_env);
5372 check_insn(env, ctx, ASE_MT);
5373 gen_helper_mfc0_tcbind(arg, cpu_env);
5377 check_insn(env, ctx, ASE_MT);
5378 gen_helper_dmfc0_tcrestart(arg, cpu_env);
5382 check_insn(env, ctx, ASE_MT);
5383 gen_helper_dmfc0_tchalt(arg, cpu_env);
5387 check_insn(env, ctx, ASE_MT);
5388 gen_helper_dmfc0_tccontext(arg, cpu_env);
5392 check_insn(env, ctx, ASE_MT);
5393 gen_helper_dmfc0_tcschedule(arg, cpu_env);
5397 check_insn(env, ctx, ASE_MT);
5398 gen_helper_dmfc0_tcschefback(arg, cpu_env);
5408 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EntryLo1));
5418 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_Context));
5422 // gen_helper_dmfc0_contextconfig(arg); /* SmartMIPS ASE */
5423 rn = "ContextConfig";
5432 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PageMask));
5436 check_insn(env, ctx, ISA_MIPS32R2);
5437 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PageGrain));
5447 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Wired));
5451 check_insn(env, ctx, ISA_MIPS32R2);
5452 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf0));
5456 check_insn(env, ctx, ISA_MIPS32R2);
5457 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf1));
5461 check_insn(env, ctx, ISA_MIPS32R2);
5462 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf2));
5466 check_insn(env, ctx, ISA_MIPS32R2);
5467 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf3));
5471 check_insn(env, ctx, ISA_MIPS32R2);
5472 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf4));
5482 check_insn(env, ctx, ISA_MIPS32R2);
5483 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_HWREna));
5493 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_BadVAddr));
5503 /* Mark as an IO operation because we read the time. */
5506 gen_helper_mfc0_count(arg, cpu_env);
5510 /* Break the TB to be able to take timer interrupts immediately
5511 after reading count. */
5512 ctx->bstate = BS_STOP;
5515 /* 6,7 are implementation dependent */
5523 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EntryHi));
5533 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Compare));
5536 /* 6,7 are implementation dependent */
5544 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Status));
5548 check_insn(env, ctx, ISA_MIPS32R2);
5549 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_IntCtl));
5553 check_insn(env, ctx, ISA_MIPS32R2);
5554 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSCtl));
5558 check_insn(env, ctx, ISA_MIPS32R2);
5559 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSMap));
5569 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Cause));
5579 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EPC));
5589 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PRid));
5593 check_insn(env, ctx, ISA_MIPS32R2);
5594 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_EBase));
5604 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config0));
5608 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config1));
5612 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config2));
5616 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config3));
5619 /* 6,7 are implementation dependent */
5621 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config6));
5625 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config7));
5635 gen_helper_dmfc0_lladdr(arg, cpu_env);
5645 gen_helper_1e0i(dmfc0_watchlo, arg, sel);
5655 gen_helper_1e0i(mfc0_watchhi, arg, sel);
5665 check_insn(env, ctx, ISA_MIPS3);
5666 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_XContext));
5674 /* Officially reserved, but sel 0 is used for R1x000 framemask */
5677 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Framemask));
5685 tcg_gen_movi_tl(arg, 0); /* unimplemented */
5686 rn = "'Diagnostic"; /* implementation dependent */
5691 gen_helper_mfc0_debug(arg, cpu_env); /* EJTAG support */
5695 // gen_helper_dmfc0_tracecontrol(arg, cpu_env); /* PDtrace support */
5696 rn = "TraceControl";
5699 // gen_helper_dmfc0_tracecontrol2(arg, cpu_env); /* PDtrace support */
5700 rn = "TraceControl2";
5703 // gen_helper_dmfc0_usertracedata(arg, cpu_env); /* PDtrace support */
5704 rn = "UserTraceData";
5707 // gen_helper_dmfc0_tracebpc(arg, cpu_env); /* PDtrace support */
5718 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_DEPC));
5728 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Performance0));
5729 rn = "Performance0";
5732 // gen_helper_dmfc0_performance1(arg);
5733 rn = "Performance1";
5736 // gen_helper_dmfc0_performance2(arg);
5737 rn = "Performance2";
5740 // gen_helper_dmfc0_performance3(arg);
5741 rn = "Performance3";
5744 // gen_helper_dmfc0_performance4(arg);
5745 rn = "Performance4";
5748 // gen_helper_dmfc0_performance5(arg);
5749 rn = "Performance5";
5752 // gen_helper_dmfc0_performance6(arg);
5753 rn = "Performance6";
5756 // gen_helper_dmfc0_performance7(arg);
5757 rn = "Performance7";
5764 tcg_gen_movi_tl(arg, 0); /* unimplemented */
5771 tcg_gen_movi_tl(arg, 0); /* unimplemented */
5784 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_TagLo));
5791 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DataLo));
5804 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_TagHi));
5811 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DataHi));
5821 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_ErrorEPC));
5832 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DESAVE));
5842 (void)rn; /* avoid a compiler warning */
5843 LOG_DISAS("dmfc0 %s (reg %d sel %d)\n", rn, reg, sel);
5847 LOG_DISAS("dmfc0 %s (reg %d sel %d)\n", rn, reg, sel);
5848 generate_exception(ctx, EXCP_RI);
5851 static void gen_dmtc0 (CPUMIPSState *env, DisasContext *ctx, TCGv arg, int reg, int sel)
5853 const char *rn = "invalid";
5856 check_insn(env, ctx, ISA_MIPS64);
5865 gen_helper_mtc0_index(cpu_env, arg);
5869 check_insn(env, ctx, ASE_MT);
5870 gen_helper_mtc0_mvpcontrol(cpu_env, arg);
5874 check_insn(env, ctx, ASE_MT);
5879 check_insn(env, ctx, ASE_MT);
5894 check_insn(env, ctx, ASE_MT);
5895 gen_helper_mtc0_vpecontrol(cpu_env, arg);
5899 check_insn(env, ctx, ASE_MT);
5900 gen_helper_mtc0_vpeconf0(cpu_env, arg);
5904 check_insn(env, ctx, ASE_MT);
5905 gen_helper_mtc0_vpeconf1(cpu_env, arg);
5909 check_insn(env, ctx, ASE_MT);
5910 gen_helper_mtc0_yqmask(cpu_env, arg);
5914 check_insn(env, ctx, ASE_MT);
5915 tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_VPESchedule));
5919 check_insn(env, ctx, ASE_MT);
5920 tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_VPEScheFBack));
5921 rn = "VPEScheFBack";
5924 check_insn(env, ctx, ASE_MT);
5925 gen_helper_mtc0_vpeopt(cpu_env, arg);
5935 gen_helper_mtc0_entrylo0(cpu_env, arg);
5939 check_insn(env, ctx, ASE_MT);
5940 gen_helper_mtc0_tcstatus(cpu_env, arg);
5944 check_insn(env, ctx, ASE_MT);
5945 gen_helper_mtc0_tcbind(cpu_env, arg);
5949 check_insn(env, ctx, ASE_MT);
5950 gen_helper_mtc0_tcrestart(cpu_env, arg);
5954 check_insn(env, ctx, ASE_MT);
5955 gen_helper_mtc0_tchalt(cpu_env, arg);
5959 check_insn(env, ctx, ASE_MT);
5960 gen_helper_mtc0_tccontext(cpu_env, arg);
5964 check_insn(env, ctx, ASE_MT);
5965 gen_helper_mtc0_tcschedule(cpu_env, arg);
5969 check_insn(env, ctx, ASE_MT);
5970 gen_helper_mtc0_tcschefback(cpu_env, arg);
5980 gen_helper_mtc0_entrylo1(cpu_env, arg);
5990 gen_helper_mtc0_context(cpu_env, arg);
5994 // gen_helper_mtc0_contextconfig(cpu_env, arg); /* SmartMIPS ASE */
5995 rn = "ContextConfig";
6004 gen_helper_mtc0_pagemask(cpu_env, arg);
6008 check_insn(env, ctx, ISA_MIPS32R2);
6009 gen_helper_mtc0_pagegrain(cpu_env, arg);
6019 gen_helper_mtc0_wired(cpu_env, arg);
6023 check_insn(env, ctx, ISA_MIPS32R2);
6024 gen_helper_mtc0_srsconf0(cpu_env, arg);
6028 check_insn(env, ctx, ISA_MIPS32R2);
6029 gen_helper_mtc0_srsconf1(cpu_env, arg);
6033 check_insn(env, ctx, ISA_MIPS32R2);
6034 gen_helper_mtc0_srsconf2(cpu_env, arg);
6038 check_insn(env, ctx, ISA_MIPS32R2);
6039 gen_helper_mtc0_srsconf3(cpu_env, arg);
6043 check_insn(env, ctx, ISA_MIPS32R2);
6044 gen_helper_mtc0_srsconf4(cpu_env, arg);
6054 check_insn(env, ctx, ISA_MIPS32R2);
6055 gen_helper_mtc0_hwrena(cpu_env, arg);
6069 gen_helper_mtc0_count(cpu_env, arg);
6072 /* 6,7 are implementation dependent */
6076 /* Stop translation as we may have switched the execution mode */
6077 ctx->bstate = BS_STOP;
6082 gen_helper_mtc0_entryhi(cpu_env, arg);
6092 gen_helper_mtc0_compare(cpu_env, arg);
6095 /* 6,7 are implementation dependent */
6099 /* Stop translation as we may have switched the execution mode */
6100 ctx->bstate = BS_STOP;
6105 save_cpu_state(ctx, 1);
6106 gen_helper_mtc0_status(cpu_env, arg);
6107 /* BS_STOP isn't good enough here, hflags may have changed. */
6108 gen_save_pc(ctx->pc + 4);
6109 ctx->bstate = BS_EXCP;
6113 check_insn(env, ctx, ISA_MIPS32R2);
6114 gen_helper_mtc0_intctl(cpu_env, arg);
6115 /* Stop translation as we may have switched the execution mode */
6116 ctx->bstate = BS_STOP;
6120 check_insn(env, ctx, ISA_MIPS32R2);
6121 gen_helper_mtc0_srsctl(cpu_env, arg);
6122 /* Stop translation as we may have switched the execution mode */
6123 ctx->bstate = BS_STOP;
6127 check_insn(env, ctx, ISA_MIPS32R2);
6128 gen_mtc0_store32(arg, offsetof(CPUMIPSState, CP0_SRSMap));
6129 /* Stop translation as we may have switched the execution mode */
6130 ctx->bstate = BS_STOP;
6140 save_cpu_state(ctx, 1);
6141 /* Mark as an IO operation because we may trigger a software
6146 gen_helper_mtc0_cause(cpu_env, arg);
6150 /* Stop translation as we may have triggered an intetrupt */
6151 ctx->bstate = BS_STOP;
6161 tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EPC));
6175 check_insn(env, ctx, ISA_MIPS32R2);
6176 gen_helper_mtc0_ebase(cpu_env, arg);
6186 gen_helper_mtc0_config0(cpu_env, arg);
6188 /* Stop translation as we may have switched the execution mode */
6189 ctx->bstate = BS_STOP;
6192 /* ignored, read only */
6196 gen_helper_mtc0_config2(cpu_env, arg);
6198 /* Stop translation as we may have switched the execution mode */
6199 ctx->bstate = BS_STOP;
6205 /* 6,7 are implementation dependent */
6207 rn = "Invalid config selector";
6214 gen_helper_mtc0_lladdr(cpu_env, arg);
6224 gen_helper_0e1i(mtc0_watchlo, arg, sel);
6234 gen_helper_0e1i(mtc0_watchhi, arg, sel);
6244 check_insn(env, ctx, ISA_MIPS3);
6245 gen_helper_mtc0_xcontext(cpu_env, arg);
6253 /* Officially reserved, but sel 0 is used for R1x000 framemask */
6256 gen_helper_mtc0_framemask(cpu_env, arg);
6265 rn = "Diagnostic"; /* implementation dependent */
6270 gen_helper_mtc0_debug(cpu_env, arg); /* EJTAG support */
6271 /* BS_STOP isn't good enough here, hflags may have changed. */
6272 gen_save_pc(ctx->pc + 4);
6273 ctx->bstate = BS_EXCP;
6277 // gen_helper_mtc0_tracecontrol(cpu_env, arg); /* PDtrace support */
6278 /* Stop translation as we may have switched the execution mode */
6279 ctx->bstate = BS_STOP;
6280 rn = "TraceControl";
6283 // gen_helper_mtc0_tracecontrol2(cpu_env, arg); /* PDtrace support */
6284 /* Stop translation as we may have switched the execution mode */
6285 ctx->bstate = BS_STOP;
6286 rn = "TraceControl2";
6289 // gen_helper_mtc0_usertracedata(cpu_env, arg); /* PDtrace support */
6290 /* Stop translation as we may have switched the execution mode */
6291 ctx->bstate = BS_STOP;
6292 rn = "UserTraceData";
6295 // gen_helper_mtc0_tracebpc(cpu_env, arg); /* PDtrace support */
6296 /* Stop translation as we may have switched the execution mode */
6297 ctx->bstate = BS_STOP;
6308 tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_DEPC));
6318 gen_helper_mtc0_performance0(cpu_env, arg);
6319 rn = "Performance0";
6322 // gen_helper_mtc0_performance1(cpu_env, arg);
6323 rn = "Performance1";
6326 // gen_helper_mtc0_performance2(cpu_env, arg);
6327 rn = "Performance2";
6330 // gen_helper_mtc0_performance3(cpu_env, arg);
6331 rn = "Performance3";
6334 // gen_helper_mtc0_performance4(cpu_env, arg);
6335 rn = "Performance4";
6338 // gen_helper_mtc0_performance5(cpu_env, arg);
6339 rn = "Performance5";
6342 // gen_helper_mtc0_performance6(cpu_env, arg);
6343 rn = "Performance6";
6346 // gen_helper_mtc0_performance7(cpu_env, arg);
6347 rn = "Performance7";
6373 gen_helper_mtc0_taglo(cpu_env, arg);
6380 gen_helper_mtc0_datalo(cpu_env, arg);
6393 gen_helper_mtc0_taghi(cpu_env, arg);
6400 gen_helper_mtc0_datahi(cpu_env, arg);
6411 tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_ErrorEPC));
6422 gen_mtc0_store32(arg, offsetof(CPUMIPSState, CP0_DESAVE));
6428 /* Stop translation as we may have switched the execution mode */
6429 ctx->bstate = BS_STOP;
6434 (void)rn; /* avoid a compiler warning */
6435 LOG_DISAS("dmtc0 %s (reg %d sel %d)\n", rn, reg, sel);
6436 /* For simplicity assume that all writes can cause interrupts. */
6439 ctx->bstate = BS_STOP;
6444 LOG_DISAS("dmtc0 %s (reg %d sel %d)\n", rn, reg, sel);
6445 generate_exception(ctx, EXCP_RI);
6447 #endif /* TARGET_MIPS64 */
6449 static void gen_mftr(CPUMIPSState *env, DisasContext *ctx, int rt, int rd,
6450 int u, int sel, int h)
6452 int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
6453 TCGv t0 = tcg_temp_local_new();
6455 if ((env->CP0_VPEConf0 & (1 << CP0VPEC0_MVP)) == 0 &&
6456 ((env->tcs[other_tc].CP0_TCBind & (0xf << CP0TCBd_CurVPE)) !=
6457 (env->active_tc.CP0_TCBind & (0xf << CP0TCBd_CurVPE))))
6458 tcg_gen_movi_tl(t0, -1);
6459 else if ((env->CP0_VPEControl & (0xff << CP0VPECo_TargTC)) >
6460 (env->mvp->CP0_MVPConf0 & (0xff << CP0MVPC0_PTC)))
6461 tcg_gen_movi_tl(t0, -1);
6467 gen_helper_mftc0_vpecontrol(t0, cpu_env);
6470 gen_helper_mftc0_vpeconf0(t0, cpu_env);
6480 gen_helper_mftc0_tcstatus(t0, cpu_env);
6483 gen_helper_mftc0_tcbind(t0, cpu_env);
6486 gen_helper_mftc0_tcrestart(t0, cpu_env);
6489 gen_helper_mftc0_tchalt(t0, cpu_env);
6492 gen_helper_mftc0_tccontext(t0, cpu_env);
6495 gen_helper_mftc0_tcschedule(t0, cpu_env);
6498 gen_helper_mftc0_tcschefback(t0, cpu_env);
6501 gen_mfc0(env, ctx, t0, rt, sel);
6508 gen_helper_mftc0_entryhi(t0, cpu_env);
6511 gen_mfc0(env, ctx, t0, rt, sel);
6517 gen_helper_mftc0_status(t0, cpu_env);
6520 gen_mfc0(env, ctx, t0, rt, sel);
6526 gen_helper_mftc0_cause(t0, cpu_env);
6536 gen_helper_mftc0_epc(t0, cpu_env);
6546 gen_helper_mftc0_ebase(t0, cpu_env);
6556 gen_helper_mftc0_configx(t0, cpu_env, tcg_const_tl(sel));
6566 gen_helper_mftc0_debug(t0, cpu_env);
6569 gen_mfc0(env, ctx, t0, rt, sel);
6574 gen_mfc0(env, ctx, t0, rt, sel);
6576 } else switch (sel) {
6577 /* GPR registers. */
6579 gen_helper_1e0i(mftgpr, t0, rt);
6581 /* Auxiliary CPU registers */
6585 gen_helper_1e0i(mftlo, t0, 0);
6588 gen_helper_1e0i(mfthi, t0, 0);
6591 gen_helper_1e0i(mftacx, t0, 0);
6594 gen_helper_1e0i(mftlo, t0, 1);
6597 gen_helper_1e0i(mfthi, t0, 1);
6600 gen_helper_1e0i(mftacx, t0, 1);
6603 gen_helper_1e0i(mftlo, t0, 2);
6606 gen_helper_1e0i(mfthi, t0, 2);
6609 gen_helper_1e0i(mftacx, t0, 2);
6612 gen_helper_1e0i(mftlo, t0, 3);
6615 gen_helper_1e0i(mfthi, t0, 3);
6618 gen_helper_1e0i(mftacx, t0, 3);
6621 gen_helper_mftdsp(t0, cpu_env);
6627 /* Floating point (COP1). */
6629 /* XXX: For now we support only a single FPU context. */
6631 TCGv_i32 fp0 = tcg_temp_new_i32();
6633 gen_load_fpr32(fp0, rt);
6634 tcg_gen_ext_i32_tl(t0, fp0);
6635 tcg_temp_free_i32(fp0);
6637 TCGv_i32 fp0 = tcg_temp_new_i32();
6639 gen_load_fpr32h(fp0, rt);
6640 tcg_gen_ext_i32_tl(t0, fp0);
6641 tcg_temp_free_i32(fp0);
6645 /* XXX: For now we support only a single FPU context. */
6646 gen_helper_1e0i(cfc1, t0, rt);
6648 /* COP2: Not implemented. */
6655 LOG_DISAS("mftr (reg %d u %d sel %d h %d)\n", rt, u, sel, h);
6656 gen_store_gpr(t0, rd);
6662 LOG_DISAS("mftr (reg %d u %d sel %d h %d)\n", rt, u, sel, h);
6663 generate_exception(ctx, EXCP_RI);
6666 static void gen_mttr(CPUMIPSState *env, DisasContext *ctx, int rd, int rt,
6667 int u, int sel, int h)
6669 int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
6670 TCGv t0 = tcg_temp_local_new();
6672 gen_load_gpr(t0, rt);
6673 if ((env->CP0_VPEConf0 & (1 << CP0VPEC0_MVP)) == 0 &&
6674 ((env->tcs[other_tc].CP0_TCBind & (0xf << CP0TCBd_CurVPE)) !=
6675 (env->active_tc.CP0_TCBind & (0xf << CP0TCBd_CurVPE))))
6677 else if ((env->CP0_VPEControl & (0xff << CP0VPECo_TargTC)) >
6678 (env->mvp->CP0_MVPConf0 & (0xff << CP0MVPC0_PTC)))
6685 gen_helper_mttc0_vpecontrol(cpu_env, t0);
6688 gen_helper_mttc0_vpeconf0(cpu_env, t0);
6698 gen_helper_mttc0_tcstatus(cpu_env, t0);
6701 gen_helper_mttc0_tcbind(cpu_env, t0);
6704 gen_helper_mttc0_tcrestart(cpu_env, t0);
6707 gen_helper_mttc0_tchalt(cpu_env, t0);
6710 gen_helper_mttc0_tccontext(cpu_env, t0);
6713 gen_helper_mttc0_tcschedule(cpu_env, t0);
6716 gen_helper_mttc0_tcschefback(cpu_env, t0);
6719 gen_mtc0(env, ctx, t0, rd, sel);
6726 gen_helper_mttc0_entryhi(cpu_env, t0);
6729 gen_mtc0(env, ctx, t0, rd, sel);
6735 gen_helper_mttc0_status(cpu_env, t0);
6738 gen_mtc0(env, ctx, t0, rd, sel);
6744 gen_helper_mttc0_cause(cpu_env, t0);
6754 gen_helper_mttc0_ebase(cpu_env, t0);
6764 gen_helper_mttc0_debug(cpu_env, t0);
6767 gen_mtc0(env, ctx, t0, rd, sel);
6772 gen_mtc0(env, ctx, t0, rd, sel);
6774 } else switch (sel) {
6775 /* GPR registers. */
6777 gen_helper_0e1i(mttgpr, t0, rd);
6779 /* Auxiliary CPU registers */
6783 gen_helper_0e1i(mttlo, t0, 0);
6786 gen_helper_0e1i(mtthi, t0, 0);
6789 gen_helper_0e1i(mttacx, t0, 0);
6792 gen_helper_0e1i(mttlo, t0, 1);
6795 gen_helper_0e1i(mtthi, t0, 1);
6798 gen_helper_0e1i(mttacx, t0, 1);
6801 gen_helper_0e1i(mttlo, t0, 2);
6804 gen_helper_0e1i(mtthi, t0, 2);
6807 gen_helper_0e1i(mttacx, t0, 2);
6810 gen_helper_0e1i(mttlo, t0, 3);
6813 gen_helper_0e1i(mtthi, t0, 3);
6816 gen_helper_0e1i(mttacx, t0, 3);
6819 gen_helper_mttdsp(cpu_env, t0);
6825 /* Floating point (COP1). */
6827 /* XXX: For now we support only a single FPU context. */
6829 TCGv_i32 fp0 = tcg_temp_new_i32();
6831 tcg_gen_trunc_tl_i32(fp0, t0);
6832 gen_store_fpr32(fp0, rd);
6833 tcg_temp_free_i32(fp0);
6835 TCGv_i32 fp0 = tcg_temp_new_i32();
6837 tcg_gen_trunc_tl_i32(fp0, t0);
6838 gen_store_fpr32h(fp0, rd);
6839 tcg_temp_free_i32(fp0);
6843 /* XXX: For now we support only a single FPU context. */
6844 gen_helper_0e1i(ctc1, t0, rd);
6846 /* COP2: Not implemented. */
6853 LOG_DISAS("mttr (reg %d u %d sel %d h %d)\n", rd, u, sel, h);
6859 LOG_DISAS("mttr (reg %d u %d sel %d h %d)\n", rd, u, sel, h);
6860 generate_exception(ctx, EXCP_RI);
6863 static void gen_cp0 (CPUMIPSState *env, DisasContext *ctx, uint32_t opc, int rt, int rd)
6865 const char *opn = "ldst";
6867 check_cp0_enabled(ctx);
6874 gen_mfc0(env, ctx, cpu_gpr[rt], rd, ctx->opcode & 0x7);
6879 TCGv t0 = tcg_temp_new();
6881 gen_load_gpr(t0, rt);
6882 gen_mtc0(env, ctx, t0, rd, ctx->opcode & 0x7);
6887 #if defined(TARGET_MIPS64)
6889 check_insn(env, ctx, ISA_MIPS3);
6894 gen_dmfc0(env, ctx, cpu_gpr[rt], rd, ctx->opcode & 0x7);
6898 check_insn(env, ctx, ISA_MIPS3);
6900 TCGv t0 = tcg_temp_new();
6902 gen_load_gpr(t0, rt);
6903 gen_dmtc0(env, ctx, t0, rd, ctx->opcode & 0x7);
6910 check_insn(env, ctx, ASE_MT);
6915 gen_mftr(env, ctx, rt, rd, (ctx->opcode >> 5) & 1,
6916 ctx->opcode & 0x7, (ctx->opcode >> 4) & 1);
6920 check_insn(env, ctx, ASE_MT);
6921 gen_mttr(env, ctx, rd, rt, (ctx->opcode >> 5) & 1,
6922 ctx->opcode & 0x7, (ctx->opcode >> 4) & 1);
6927 if (!env->tlb->helper_tlbwi)
6929 gen_helper_tlbwi(cpu_env);
6933 if (!env->tlb->helper_tlbwr)
6935 gen_helper_tlbwr(cpu_env);
6939 if (!env->tlb->helper_tlbp)
6941 gen_helper_tlbp(cpu_env);
6945 if (!env->tlb->helper_tlbr)
6947 gen_helper_tlbr(cpu_env);
6951 check_insn(env, ctx, ISA_MIPS2);
6952 gen_helper_eret(cpu_env);
6953 ctx->bstate = BS_EXCP;
6957 check_insn(env, ctx, ISA_MIPS32);
6958 if (!(ctx->hflags & MIPS_HFLAG_DM)) {
6960 generate_exception(ctx, EXCP_RI);
6962 gen_helper_deret(cpu_env);
6963 ctx->bstate = BS_EXCP;
6968 check_insn(env, ctx, ISA_MIPS3 | ISA_MIPS32);
6969 /* If we get an exception, we want to restart at next instruction */
6971 save_cpu_state(ctx, 1);
6973 gen_helper_wait(cpu_env);
6974 ctx->bstate = BS_EXCP;
6979 generate_exception(ctx, EXCP_RI);
6982 (void)opn; /* avoid a compiler warning */
6983 MIPS_DEBUG("%s %s %d", opn, regnames[rt], rd);
6985 #endif /* !CONFIG_USER_ONLY */
6987 /* CP1 Branches (before delay slot) */
6988 static void gen_compute_branch1 (CPUMIPSState *env, DisasContext *ctx, uint32_t op,
6989 int32_t cc, int32_t offset)
6991 target_ulong btarget;
6992 const char *opn = "cp1 cond branch";
6993 TCGv_i32 t0 = tcg_temp_new_i32();
6996 check_insn(env, ctx, ISA_MIPS4 | ISA_MIPS32);
6998 btarget = ctx->pc + 4 + offset;
7002 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
7003 tcg_gen_not_i32(t0, t0);
7004 tcg_gen_andi_i32(t0, t0, 1);
7005 tcg_gen_extu_i32_tl(bcond, t0);
7009 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
7010 tcg_gen_not_i32(t0, t0);
7011 tcg_gen_andi_i32(t0, t0, 1);
7012 tcg_gen_extu_i32_tl(bcond, t0);
7016 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
7017 tcg_gen_andi_i32(t0, t0, 1);
7018 tcg_gen_extu_i32_tl(bcond, t0);
7022 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
7023 tcg_gen_andi_i32(t0, t0, 1);
7024 tcg_gen_extu_i32_tl(bcond, t0);
7027 ctx->hflags |= MIPS_HFLAG_BL;
7031 TCGv_i32 t1 = tcg_temp_new_i32();
7032 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
7033 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+1));
7034 tcg_gen_nand_i32(t0, t0, t1);
7035 tcg_temp_free_i32(t1);
7036 tcg_gen_andi_i32(t0, t0, 1);
7037 tcg_gen_extu_i32_tl(bcond, t0);
7043 TCGv_i32 t1 = tcg_temp_new_i32();
7044 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
7045 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+1));
7046 tcg_gen_or_i32(t0, t0, t1);
7047 tcg_temp_free_i32(t1);
7048 tcg_gen_andi_i32(t0, t0, 1);
7049 tcg_gen_extu_i32_tl(bcond, t0);
7055 TCGv_i32 t1 = tcg_temp_new_i32();
7056 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
7057 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+1));
7058 tcg_gen_and_i32(t0, t0, t1);
7059 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+2));
7060 tcg_gen_and_i32(t0, t0, t1);
7061 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+3));
7062 tcg_gen_nand_i32(t0, t0, t1);
7063 tcg_temp_free_i32(t1);
7064 tcg_gen_andi_i32(t0, t0, 1);
7065 tcg_gen_extu_i32_tl(bcond, t0);
7071 TCGv_i32 t1 = tcg_temp_new_i32();
7072 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
7073 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+1));
7074 tcg_gen_or_i32(t0, t0, t1);
7075 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+2));
7076 tcg_gen_or_i32(t0, t0, t1);
7077 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+3));
7078 tcg_gen_or_i32(t0, t0, t1);
7079 tcg_temp_free_i32(t1);
7080 tcg_gen_andi_i32(t0, t0, 1);
7081 tcg_gen_extu_i32_tl(bcond, t0);
7085 ctx->hflags |= MIPS_HFLAG_BC;
7089 generate_exception (ctx, EXCP_RI);
7092 (void)opn; /* avoid a compiler warning */
7093 MIPS_DEBUG("%s: cond %02x target " TARGET_FMT_lx, opn,
7094 ctx->hflags, btarget);
7095 ctx->btarget = btarget;
7098 tcg_temp_free_i32(t0);
7101 /* Coprocessor 1 (FPU) */
7103 #define FOP(func, fmt) (((fmt) << 21) | (func))
7106 OPC_ADD_S = FOP(0, FMT_S),
7107 OPC_SUB_S = FOP(1, FMT_S),
7108 OPC_MUL_S = FOP(2, FMT_S),
7109 OPC_DIV_S = FOP(3, FMT_S),
7110 OPC_SQRT_S = FOP(4, FMT_S),
7111 OPC_ABS_S = FOP(5, FMT_S),
7112 OPC_MOV_S = FOP(6, FMT_S),
7113 OPC_NEG_S = FOP(7, FMT_S),
7114 OPC_ROUND_L_S = FOP(8, FMT_S),
7115 OPC_TRUNC_L_S = FOP(9, FMT_S),
7116 OPC_CEIL_L_S = FOP(10, FMT_S),
7117 OPC_FLOOR_L_S = FOP(11, FMT_S),
7118 OPC_ROUND_W_S = FOP(12, FMT_S),
7119 OPC_TRUNC_W_S = FOP(13, FMT_S),
7120 OPC_CEIL_W_S = FOP(14, FMT_S),
7121 OPC_FLOOR_W_S = FOP(15, FMT_S),
7122 OPC_MOVCF_S = FOP(17, FMT_S),
7123 OPC_MOVZ_S = FOP(18, FMT_S),
7124 OPC_MOVN_S = FOP(19, FMT_S),
7125 OPC_RECIP_S = FOP(21, FMT_S),
7126 OPC_RSQRT_S = FOP(22, FMT_S),
7127 OPC_RECIP2_S = FOP(28, FMT_S),
7128 OPC_RECIP1_S = FOP(29, FMT_S),
7129 OPC_RSQRT1_S = FOP(30, FMT_S),
7130 OPC_RSQRT2_S = FOP(31, FMT_S),
7131 OPC_CVT_D_S = FOP(33, FMT_S),
7132 OPC_CVT_W_S = FOP(36, FMT_S),
7133 OPC_CVT_L_S = FOP(37, FMT_S),
7134 OPC_CVT_PS_S = FOP(38, FMT_S),
7135 OPC_CMP_F_S = FOP (48, FMT_S),
7136 OPC_CMP_UN_S = FOP (49, FMT_S),
7137 OPC_CMP_EQ_S = FOP (50, FMT_S),
7138 OPC_CMP_UEQ_S = FOP (51, FMT_S),
7139 OPC_CMP_OLT_S = FOP (52, FMT_S),
7140 OPC_CMP_ULT_S = FOP (53, FMT_S),
7141 OPC_CMP_OLE_S = FOP (54, FMT_S),
7142 OPC_CMP_ULE_S = FOP (55, FMT_S),
7143 OPC_CMP_SF_S = FOP (56, FMT_S),
7144 OPC_CMP_NGLE_S = FOP (57, FMT_S),
7145 OPC_CMP_SEQ_S = FOP (58, FMT_S),
7146 OPC_CMP_NGL_S = FOP (59, FMT_S),
7147 OPC_CMP_LT_S = FOP (60, FMT_S),
7148 OPC_CMP_NGE_S = FOP (61, FMT_S),
7149 OPC_CMP_LE_S = FOP (62, FMT_S),
7150 OPC_CMP_NGT_S = FOP (63, FMT_S),
7152 OPC_ADD_D = FOP(0, FMT_D),
7153 OPC_SUB_D = FOP(1, FMT_D),
7154 OPC_MUL_D = FOP(2, FMT_D),
7155 OPC_DIV_D = FOP(3, FMT_D),
7156 OPC_SQRT_D = FOP(4, FMT_D),
7157 OPC_ABS_D = FOP(5, FMT_D),
7158 OPC_MOV_D = FOP(6, FMT_D),
7159 OPC_NEG_D = FOP(7, FMT_D),
7160 OPC_ROUND_L_D = FOP(8, FMT_D),
7161 OPC_TRUNC_L_D = FOP(9, FMT_D),
7162 OPC_CEIL_L_D = FOP(10, FMT_D),
7163 OPC_FLOOR_L_D = FOP(11, FMT_D),
7164 OPC_ROUND_W_D = FOP(12, FMT_D),
7165 OPC_TRUNC_W_D = FOP(13, FMT_D),
7166 OPC_CEIL_W_D = FOP(14, FMT_D),
7167 OPC_FLOOR_W_D = FOP(15, FMT_D),
7168 OPC_MOVCF_D = FOP(17, FMT_D),
7169 OPC_MOVZ_D = FOP(18, FMT_D),
7170 OPC_MOVN_D = FOP(19, FMT_D),
7171 OPC_RECIP_D = FOP(21, FMT_D),
7172 OPC_RSQRT_D = FOP(22, FMT_D),
7173 OPC_RECIP2_D = FOP(28, FMT_D),
7174 OPC_RECIP1_D = FOP(29, FMT_D),
7175 OPC_RSQRT1_D = FOP(30, FMT_D),
7176 OPC_RSQRT2_D = FOP(31, FMT_D),
7177 OPC_CVT_S_D = FOP(32, FMT_D),
7178 OPC_CVT_W_D = FOP(36, FMT_D),
7179 OPC_CVT_L_D = FOP(37, FMT_D),
7180 OPC_CMP_F_D = FOP (48, FMT_D),
7181 OPC_CMP_UN_D = FOP (49, FMT_D),
7182 OPC_CMP_EQ_D = FOP (50, FMT_D),
7183 OPC_CMP_UEQ_D = FOP (51, FMT_D),
7184 OPC_CMP_OLT_D = FOP (52, FMT_D),
7185 OPC_CMP_ULT_D = FOP (53, FMT_D),
7186 OPC_CMP_OLE_D = FOP (54, FMT_D),
7187 OPC_CMP_ULE_D = FOP (55, FMT_D),
7188 OPC_CMP_SF_D = FOP (56, FMT_D),
7189 OPC_CMP_NGLE_D = FOP (57, FMT_D),
7190 OPC_CMP_SEQ_D = FOP (58, FMT_D),
7191 OPC_CMP_NGL_D = FOP (59, FMT_D),
7192 OPC_CMP_LT_D = FOP (60, FMT_D),
7193 OPC_CMP_NGE_D = FOP (61, FMT_D),
7194 OPC_CMP_LE_D = FOP (62, FMT_D),
7195 OPC_CMP_NGT_D = FOP (63, FMT_D),
7197 OPC_CVT_S_W = FOP(32, FMT_W),
7198 OPC_CVT_D_W = FOP(33, FMT_W),
7199 OPC_CVT_S_L = FOP(32, FMT_L),
7200 OPC_CVT_D_L = FOP(33, FMT_L),
7201 OPC_CVT_PS_PW = FOP(38, FMT_W),
7203 OPC_ADD_PS = FOP(0, FMT_PS),
7204 OPC_SUB_PS = FOP(1, FMT_PS),
7205 OPC_MUL_PS = FOP(2, FMT_PS),
7206 OPC_DIV_PS = FOP(3, FMT_PS),
7207 OPC_ABS_PS = FOP(5, FMT_PS),
7208 OPC_MOV_PS = FOP(6, FMT_PS),
7209 OPC_NEG_PS = FOP(7, FMT_PS),
7210 OPC_MOVCF_PS = FOP(17, FMT_PS),
7211 OPC_MOVZ_PS = FOP(18, FMT_PS),
7212 OPC_MOVN_PS = FOP(19, FMT_PS),
7213 OPC_ADDR_PS = FOP(24, FMT_PS),
7214 OPC_MULR_PS = FOP(26, FMT_PS),
7215 OPC_RECIP2_PS = FOP(28, FMT_PS),
7216 OPC_RECIP1_PS = FOP(29, FMT_PS),
7217 OPC_RSQRT1_PS = FOP(30, FMT_PS),
7218 OPC_RSQRT2_PS = FOP(31, FMT_PS),
7220 OPC_CVT_S_PU = FOP(32, FMT_PS),
7221 OPC_CVT_PW_PS = FOP(36, FMT_PS),
7222 OPC_CVT_S_PL = FOP(40, FMT_PS),
7223 OPC_PLL_PS = FOP(44, FMT_PS),
7224 OPC_PLU_PS = FOP(45, FMT_PS),
7225 OPC_PUL_PS = FOP(46, FMT_PS),
7226 OPC_PUU_PS = FOP(47, FMT_PS),
7227 OPC_CMP_F_PS = FOP (48, FMT_PS),
7228 OPC_CMP_UN_PS = FOP (49, FMT_PS),
7229 OPC_CMP_EQ_PS = FOP (50, FMT_PS),
7230 OPC_CMP_UEQ_PS = FOP (51, FMT_PS),
7231 OPC_CMP_OLT_PS = FOP (52, FMT_PS),
7232 OPC_CMP_ULT_PS = FOP (53, FMT_PS),
7233 OPC_CMP_OLE_PS = FOP (54, FMT_PS),
7234 OPC_CMP_ULE_PS = FOP (55, FMT_PS),
7235 OPC_CMP_SF_PS = FOP (56, FMT_PS),
7236 OPC_CMP_NGLE_PS = FOP (57, FMT_PS),
7237 OPC_CMP_SEQ_PS = FOP (58, FMT_PS),
7238 OPC_CMP_NGL_PS = FOP (59, FMT_PS),
7239 OPC_CMP_LT_PS = FOP (60, FMT_PS),
7240 OPC_CMP_NGE_PS = FOP (61, FMT_PS),
7241 OPC_CMP_LE_PS = FOP (62, FMT_PS),
7242 OPC_CMP_NGT_PS = FOP (63, FMT_PS),
7245 static void gen_cp1 (DisasContext *ctx, uint32_t opc, int rt, int fs)
7247 const char *opn = "cp1 move";
7248 TCGv t0 = tcg_temp_new();
7253 TCGv_i32 fp0 = tcg_temp_new_i32();
7255 gen_load_fpr32(fp0, fs);
7256 tcg_gen_ext_i32_tl(t0, fp0);
7257 tcg_temp_free_i32(fp0);
7259 gen_store_gpr(t0, rt);
7263 gen_load_gpr(t0, rt);
7265 TCGv_i32 fp0 = tcg_temp_new_i32();
7267 tcg_gen_trunc_tl_i32(fp0, t0);
7268 gen_store_fpr32(fp0, fs);
7269 tcg_temp_free_i32(fp0);
7274 gen_helper_1e0i(cfc1, t0, fs);
7275 gen_store_gpr(t0, rt);
7279 gen_load_gpr(t0, rt);
7280 gen_helper_0e1i(ctc1, t0, fs);
7283 #if defined(TARGET_MIPS64)
7285 gen_load_fpr64(ctx, t0, fs);
7286 gen_store_gpr(t0, rt);
7290 gen_load_gpr(t0, rt);
7291 gen_store_fpr64(ctx, t0, fs);
7297 TCGv_i32 fp0 = tcg_temp_new_i32();
7299 gen_load_fpr32h(fp0, fs);
7300 tcg_gen_ext_i32_tl(t0, fp0);
7301 tcg_temp_free_i32(fp0);
7303 gen_store_gpr(t0, rt);
7307 gen_load_gpr(t0, rt);
7309 TCGv_i32 fp0 = tcg_temp_new_i32();
7311 tcg_gen_trunc_tl_i32(fp0, t0);
7312 gen_store_fpr32h(fp0, fs);
7313 tcg_temp_free_i32(fp0);
7319 generate_exception (ctx, EXCP_RI);
7322 (void)opn; /* avoid a compiler warning */
7323 MIPS_DEBUG("%s %s %s", opn, regnames[rt], fregnames[fs]);
7329 static void gen_movci (DisasContext *ctx, int rd, int rs, int cc, int tf)
7345 l1 = gen_new_label();
7346 t0 = tcg_temp_new_i32();
7347 tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc));
7348 tcg_gen_brcondi_i32(cond, t0, 0, l1);
7349 tcg_temp_free_i32(t0);
7351 tcg_gen_movi_tl(cpu_gpr[rd], 0);
7353 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
7358 static inline void gen_movcf_s (int fs, int fd, int cc, int tf)
7361 TCGv_i32 t0 = tcg_temp_new_i32();
7362 int l1 = gen_new_label();
7369 tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc));
7370 tcg_gen_brcondi_i32(cond, t0, 0, l1);
7371 gen_load_fpr32(t0, fs);
7372 gen_store_fpr32(t0, fd);
7374 tcg_temp_free_i32(t0);
7377 static inline void gen_movcf_d (DisasContext *ctx, int fs, int fd, int cc, int tf)
7380 TCGv_i32 t0 = tcg_temp_new_i32();
7382 int l1 = gen_new_label();
7389 tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc));
7390 tcg_gen_brcondi_i32(cond, t0, 0, l1);
7391 tcg_temp_free_i32(t0);
7392 fp0 = tcg_temp_new_i64();
7393 gen_load_fpr64(ctx, fp0, fs);
7394 gen_store_fpr64(ctx, fp0, fd);
7395 tcg_temp_free_i64(fp0);
7399 static inline void gen_movcf_ps (int fs, int fd, int cc, int tf)
7402 TCGv_i32 t0 = tcg_temp_new_i32();
7403 int l1 = gen_new_label();
7404 int l2 = gen_new_label();
7411 tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc));
7412 tcg_gen_brcondi_i32(cond, t0, 0, l1);
7413 gen_load_fpr32(t0, fs);
7414 gen_store_fpr32(t0, fd);
7417 tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc+1));
7418 tcg_gen_brcondi_i32(cond, t0, 0, l2);
7419 gen_load_fpr32h(t0, fs);
7420 gen_store_fpr32h(t0, fd);
7421 tcg_temp_free_i32(t0);
7426 static void gen_farith (DisasContext *ctx, enum fopcode op1,
7427 int ft, int fs, int fd, int cc)
7429 const char *opn = "farith";
7430 const char *condnames[] = {
7448 const char *condnames_abs[] = {
7466 enum { BINOP, CMPOP, OTHEROP } optype = OTHEROP;
7467 uint32_t func = ctx->opcode & 0x3f;
7472 TCGv_i32 fp0 = tcg_temp_new_i32();
7473 TCGv_i32 fp1 = tcg_temp_new_i32();
7475 gen_load_fpr32(fp0, fs);
7476 gen_load_fpr32(fp1, ft);
7477 gen_helper_float_add_s(fp0, cpu_env, fp0, fp1);
7478 tcg_temp_free_i32(fp1);
7479 gen_store_fpr32(fp0, fd);
7480 tcg_temp_free_i32(fp0);
7487 TCGv_i32 fp0 = tcg_temp_new_i32();
7488 TCGv_i32 fp1 = tcg_temp_new_i32();
7490 gen_load_fpr32(fp0, fs);
7491 gen_load_fpr32(fp1, ft);
7492 gen_helper_float_sub_s(fp0, cpu_env, fp0, fp1);
7493 tcg_temp_free_i32(fp1);
7494 gen_store_fpr32(fp0, fd);
7495 tcg_temp_free_i32(fp0);
7502 TCGv_i32 fp0 = tcg_temp_new_i32();
7503 TCGv_i32 fp1 = tcg_temp_new_i32();
7505 gen_load_fpr32(fp0, fs);
7506 gen_load_fpr32(fp1, ft);
7507 gen_helper_float_mul_s(fp0, cpu_env, fp0, fp1);
7508 tcg_temp_free_i32(fp1);
7509 gen_store_fpr32(fp0, fd);
7510 tcg_temp_free_i32(fp0);
7517 TCGv_i32 fp0 = tcg_temp_new_i32();
7518 TCGv_i32 fp1 = tcg_temp_new_i32();
7520 gen_load_fpr32(fp0, fs);
7521 gen_load_fpr32(fp1, ft);
7522 gen_helper_float_div_s(fp0, cpu_env, fp0, fp1);
7523 tcg_temp_free_i32(fp1);
7524 gen_store_fpr32(fp0, fd);
7525 tcg_temp_free_i32(fp0);
7532 TCGv_i32 fp0 = tcg_temp_new_i32();
7534 gen_load_fpr32(fp0, fs);
7535 gen_helper_float_sqrt_s(fp0, cpu_env, fp0);
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_abs_s(fp0, fp0);
7547 gen_store_fpr32(fp0, fd);
7548 tcg_temp_free_i32(fp0);
7554 TCGv_i32 fp0 = tcg_temp_new_i32();
7556 gen_load_fpr32(fp0, fs);
7557 gen_store_fpr32(fp0, fd);
7558 tcg_temp_free_i32(fp0);
7564 TCGv_i32 fp0 = tcg_temp_new_i32();
7566 gen_load_fpr32(fp0, fs);
7567 gen_helper_float_chs_s(fp0, fp0);
7568 gen_store_fpr32(fp0, fd);
7569 tcg_temp_free_i32(fp0);
7574 check_cp1_64bitmode(ctx);
7576 TCGv_i32 fp32 = tcg_temp_new_i32();
7577 TCGv_i64 fp64 = tcg_temp_new_i64();
7579 gen_load_fpr32(fp32, fs);
7580 gen_helper_float_roundl_s(fp64, cpu_env, fp32);
7581 tcg_temp_free_i32(fp32);
7582 gen_store_fpr64(ctx, fp64, fd);
7583 tcg_temp_free_i64(fp64);
7588 check_cp1_64bitmode(ctx);
7590 TCGv_i32 fp32 = tcg_temp_new_i32();
7591 TCGv_i64 fp64 = tcg_temp_new_i64();
7593 gen_load_fpr32(fp32, fs);
7594 gen_helper_float_truncl_s(fp64, cpu_env, fp32);
7595 tcg_temp_free_i32(fp32);
7596 gen_store_fpr64(ctx, fp64, fd);
7597 tcg_temp_free_i64(fp64);
7602 check_cp1_64bitmode(ctx);
7604 TCGv_i32 fp32 = tcg_temp_new_i32();
7605 TCGv_i64 fp64 = tcg_temp_new_i64();
7607 gen_load_fpr32(fp32, fs);
7608 gen_helper_float_ceill_s(fp64, cpu_env, fp32);
7609 tcg_temp_free_i32(fp32);
7610 gen_store_fpr64(ctx, fp64, fd);
7611 tcg_temp_free_i64(fp64);
7616 check_cp1_64bitmode(ctx);
7618 TCGv_i32 fp32 = tcg_temp_new_i32();
7619 TCGv_i64 fp64 = tcg_temp_new_i64();
7621 gen_load_fpr32(fp32, fs);
7622 gen_helper_float_floorl_s(fp64, cpu_env, fp32);
7623 tcg_temp_free_i32(fp32);
7624 gen_store_fpr64(ctx, fp64, fd);
7625 tcg_temp_free_i64(fp64);
7631 TCGv_i32 fp0 = tcg_temp_new_i32();
7633 gen_load_fpr32(fp0, fs);
7634 gen_helper_float_roundw_s(fp0, cpu_env, fp0);
7635 gen_store_fpr32(fp0, fd);
7636 tcg_temp_free_i32(fp0);
7642 TCGv_i32 fp0 = tcg_temp_new_i32();
7644 gen_load_fpr32(fp0, fs);
7645 gen_helper_float_truncw_s(fp0, cpu_env, fp0);
7646 gen_store_fpr32(fp0, fd);
7647 tcg_temp_free_i32(fp0);
7653 TCGv_i32 fp0 = tcg_temp_new_i32();
7655 gen_load_fpr32(fp0, fs);
7656 gen_helper_float_ceilw_s(fp0, cpu_env, fp0);
7657 gen_store_fpr32(fp0, fd);
7658 tcg_temp_free_i32(fp0);
7664 TCGv_i32 fp0 = tcg_temp_new_i32();
7666 gen_load_fpr32(fp0, fs);
7667 gen_helper_float_floorw_s(fp0, cpu_env, fp0);
7668 gen_store_fpr32(fp0, fd);
7669 tcg_temp_free_i32(fp0);
7674 gen_movcf_s(fs, fd, (ft >> 2) & 0x7, ft & 0x1);
7679 int l1 = gen_new_label();
7683 tcg_gen_brcondi_tl(TCG_COND_NE, cpu_gpr[ft], 0, l1);
7685 fp0 = tcg_temp_new_i32();
7686 gen_load_fpr32(fp0, fs);
7687 gen_store_fpr32(fp0, fd);
7688 tcg_temp_free_i32(fp0);
7695 int l1 = gen_new_label();
7699 tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_gpr[ft], 0, l1);
7700 fp0 = tcg_temp_new_i32();
7701 gen_load_fpr32(fp0, fs);
7702 gen_store_fpr32(fp0, fd);
7703 tcg_temp_free_i32(fp0);
7712 TCGv_i32 fp0 = tcg_temp_new_i32();
7714 gen_load_fpr32(fp0, fs);
7715 gen_helper_float_recip_s(fp0, cpu_env, fp0);
7716 gen_store_fpr32(fp0, fd);
7717 tcg_temp_free_i32(fp0);
7724 TCGv_i32 fp0 = tcg_temp_new_i32();
7726 gen_load_fpr32(fp0, fs);
7727 gen_helper_float_rsqrt_s(fp0, cpu_env, fp0);
7728 gen_store_fpr32(fp0, fd);
7729 tcg_temp_free_i32(fp0);
7734 check_cp1_64bitmode(ctx);
7736 TCGv_i32 fp0 = tcg_temp_new_i32();
7737 TCGv_i32 fp1 = tcg_temp_new_i32();
7739 gen_load_fpr32(fp0, fs);
7740 gen_load_fpr32(fp1, ft);
7741 gen_helper_float_recip2_s(fp0, cpu_env, fp0, fp1);
7742 tcg_temp_free_i32(fp1);
7743 gen_store_fpr32(fp0, fd);
7744 tcg_temp_free_i32(fp0);
7749 check_cp1_64bitmode(ctx);
7751 TCGv_i32 fp0 = tcg_temp_new_i32();
7753 gen_load_fpr32(fp0, fs);
7754 gen_helper_float_recip1_s(fp0, cpu_env, fp0);
7755 gen_store_fpr32(fp0, fd);
7756 tcg_temp_free_i32(fp0);
7761 check_cp1_64bitmode(ctx);
7763 TCGv_i32 fp0 = tcg_temp_new_i32();
7765 gen_load_fpr32(fp0, fs);
7766 gen_helper_float_rsqrt1_s(fp0, cpu_env, fp0);
7767 gen_store_fpr32(fp0, fd);
7768 tcg_temp_free_i32(fp0);
7773 check_cp1_64bitmode(ctx);
7775 TCGv_i32 fp0 = tcg_temp_new_i32();
7776 TCGv_i32 fp1 = tcg_temp_new_i32();
7778 gen_load_fpr32(fp0, fs);
7779 gen_load_fpr32(fp1, ft);
7780 gen_helper_float_rsqrt2_s(fp0, cpu_env, fp0, fp1);
7781 tcg_temp_free_i32(fp1);
7782 gen_store_fpr32(fp0, fd);
7783 tcg_temp_free_i32(fp0);
7788 check_cp1_registers(ctx, fd);
7790 TCGv_i32 fp32 = tcg_temp_new_i32();
7791 TCGv_i64 fp64 = tcg_temp_new_i64();
7793 gen_load_fpr32(fp32, fs);
7794 gen_helper_float_cvtd_s(fp64, cpu_env, fp32);
7795 tcg_temp_free_i32(fp32);
7796 gen_store_fpr64(ctx, fp64, fd);
7797 tcg_temp_free_i64(fp64);
7803 TCGv_i32 fp0 = tcg_temp_new_i32();
7805 gen_load_fpr32(fp0, fs);
7806 gen_helper_float_cvtw_s(fp0, cpu_env, fp0);
7807 gen_store_fpr32(fp0, fd);
7808 tcg_temp_free_i32(fp0);
7813 check_cp1_64bitmode(ctx);
7815 TCGv_i32 fp32 = tcg_temp_new_i32();
7816 TCGv_i64 fp64 = tcg_temp_new_i64();
7818 gen_load_fpr32(fp32, fs);
7819 gen_helper_float_cvtl_s(fp64, cpu_env, fp32);
7820 tcg_temp_free_i32(fp32);
7821 gen_store_fpr64(ctx, fp64, fd);
7822 tcg_temp_free_i64(fp64);
7827 check_cp1_64bitmode(ctx);
7829 TCGv_i64 fp64 = tcg_temp_new_i64();
7830 TCGv_i32 fp32_0 = tcg_temp_new_i32();
7831 TCGv_i32 fp32_1 = tcg_temp_new_i32();
7833 gen_load_fpr32(fp32_0, fs);
7834 gen_load_fpr32(fp32_1, ft);
7835 tcg_gen_concat_i32_i64(fp64, fp32_1, fp32_0);
7836 tcg_temp_free_i32(fp32_1);
7837 tcg_temp_free_i32(fp32_0);
7838 gen_store_fpr64(ctx, fp64, fd);
7839 tcg_temp_free_i64(fp64);
7852 case OPC_CMP_NGLE_S:
7859 if (ctx->opcode & (1 << 6)) {
7860 gen_cmpabs_s(ctx, func-48, ft, fs, cc);
7861 opn = condnames_abs[func-48];
7863 gen_cmp_s(ctx, func-48, ft, fs, cc);
7864 opn = condnames[func-48];
7868 check_cp1_registers(ctx, fs | ft | fd);
7870 TCGv_i64 fp0 = tcg_temp_new_i64();
7871 TCGv_i64 fp1 = tcg_temp_new_i64();
7873 gen_load_fpr64(ctx, fp0, fs);
7874 gen_load_fpr64(ctx, fp1, ft);
7875 gen_helper_float_add_d(fp0, cpu_env, fp0, fp1);
7876 tcg_temp_free_i64(fp1);
7877 gen_store_fpr64(ctx, fp0, fd);
7878 tcg_temp_free_i64(fp0);
7884 check_cp1_registers(ctx, fs | ft | fd);
7886 TCGv_i64 fp0 = tcg_temp_new_i64();
7887 TCGv_i64 fp1 = tcg_temp_new_i64();
7889 gen_load_fpr64(ctx, fp0, fs);
7890 gen_load_fpr64(ctx, fp1, ft);
7891 gen_helper_float_sub_d(fp0, cpu_env, fp0, fp1);
7892 tcg_temp_free_i64(fp1);
7893 gen_store_fpr64(ctx, fp0, fd);
7894 tcg_temp_free_i64(fp0);
7900 check_cp1_registers(ctx, fs | ft | fd);
7902 TCGv_i64 fp0 = tcg_temp_new_i64();
7903 TCGv_i64 fp1 = tcg_temp_new_i64();
7905 gen_load_fpr64(ctx, fp0, fs);
7906 gen_load_fpr64(ctx, fp1, ft);
7907 gen_helper_float_mul_d(fp0, cpu_env, fp0, fp1);
7908 tcg_temp_free_i64(fp1);
7909 gen_store_fpr64(ctx, fp0, fd);
7910 tcg_temp_free_i64(fp0);
7916 check_cp1_registers(ctx, fs | ft | fd);
7918 TCGv_i64 fp0 = tcg_temp_new_i64();
7919 TCGv_i64 fp1 = tcg_temp_new_i64();
7921 gen_load_fpr64(ctx, fp0, fs);
7922 gen_load_fpr64(ctx, fp1, ft);
7923 gen_helper_float_div_d(fp0, cpu_env, fp0, fp1);
7924 tcg_temp_free_i64(fp1);
7925 gen_store_fpr64(ctx, fp0, fd);
7926 tcg_temp_free_i64(fp0);
7932 check_cp1_registers(ctx, fs | fd);
7934 TCGv_i64 fp0 = tcg_temp_new_i64();
7936 gen_load_fpr64(ctx, fp0, fs);
7937 gen_helper_float_sqrt_d(fp0, cpu_env, fp0);
7938 gen_store_fpr64(ctx, fp0, fd);
7939 tcg_temp_free_i64(fp0);
7944 check_cp1_registers(ctx, fs | fd);
7946 TCGv_i64 fp0 = tcg_temp_new_i64();
7948 gen_load_fpr64(ctx, fp0, fs);
7949 gen_helper_float_abs_d(fp0, fp0);
7950 gen_store_fpr64(ctx, fp0, fd);
7951 tcg_temp_free_i64(fp0);
7956 check_cp1_registers(ctx, fs | fd);
7958 TCGv_i64 fp0 = tcg_temp_new_i64();
7960 gen_load_fpr64(ctx, fp0, fs);
7961 gen_store_fpr64(ctx, fp0, fd);
7962 tcg_temp_free_i64(fp0);
7967 check_cp1_registers(ctx, fs | fd);
7969 TCGv_i64 fp0 = tcg_temp_new_i64();
7971 gen_load_fpr64(ctx, fp0, fs);
7972 gen_helper_float_chs_d(fp0, fp0);
7973 gen_store_fpr64(ctx, fp0, fd);
7974 tcg_temp_free_i64(fp0);
7979 check_cp1_64bitmode(ctx);
7981 TCGv_i64 fp0 = tcg_temp_new_i64();
7983 gen_load_fpr64(ctx, fp0, fs);
7984 gen_helper_float_roundl_d(fp0, cpu_env, fp0);
7985 gen_store_fpr64(ctx, fp0, fd);
7986 tcg_temp_free_i64(fp0);
7991 check_cp1_64bitmode(ctx);
7993 TCGv_i64 fp0 = tcg_temp_new_i64();
7995 gen_load_fpr64(ctx, fp0, fs);
7996 gen_helper_float_truncl_d(fp0, cpu_env, fp0);
7997 gen_store_fpr64(ctx, fp0, fd);
7998 tcg_temp_free_i64(fp0);
8003 check_cp1_64bitmode(ctx);
8005 TCGv_i64 fp0 = tcg_temp_new_i64();
8007 gen_load_fpr64(ctx, fp0, fs);
8008 gen_helper_float_ceill_d(fp0, cpu_env, fp0);
8009 gen_store_fpr64(ctx, fp0, fd);
8010 tcg_temp_free_i64(fp0);
8015 check_cp1_64bitmode(ctx);
8017 TCGv_i64 fp0 = tcg_temp_new_i64();
8019 gen_load_fpr64(ctx, fp0, fs);
8020 gen_helper_float_floorl_d(fp0, cpu_env, fp0);
8021 gen_store_fpr64(ctx, fp0, fd);
8022 tcg_temp_free_i64(fp0);
8027 check_cp1_registers(ctx, fs);
8029 TCGv_i32 fp32 = tcg_temp_new_i32();
8030 TCGv_i64 fp64 = tcg_temp_new_i64();
8032 gen_load_fpr64(ctx, fp64, fs);
8033 gen_helper_float_roundw_d(fp32, cpu_env, fp64);
8034 tcg_temp_free_i64(fp64);
8035 gen_store_fpr32(fp32, fd);
8036 tcg_temp_free_i32(fp32);
8041 check_cp1_registers(ctx, fs);
8043 TCGv_i32 fp32 = tcg_temp_new_i32();
8044 TCGv_i64 fp64 = tcg_temp_new_i64();
8046 gen_load_fpr64(ctx, fp64, fs);
8047 gen_helper_float_truncw_d(fp32, cpu_env, fp64);
8048 tcg_temp_free_i64(fp64);
8049 gen_store_fpr32(fp32, fd);
8050 tcg_temp_free_i32(fp32);
8055 check_cp1_registers(ctx, fs);
8057 TCGv_i32 fp32 = tcg_temp_new_i32();
8058 TCGv_i64 fp64 = tcg_temp_new_i64();
8060 gen_load_fpr64(ctx, fp64, fs);
8061 gen_helper_float_ceilw_d(fp32, cpu_env, fp64);
8062 tcg_temp_free_i64(fp64);
8063 gen_store_fpr32(fp32, fd);
8064 tcg_temp_free_i32(fp32);
8069 check_cp1_registers(ctx, fs);
8071 TCGv_i32 fp32 = tcg_temp_new_i32();
8072 TCGv_i64 fp64 = tcg_temp_new_i64();
8074 gen_load_fpr64(ctx, fp64, fs);
8075 gen_helper_float_floorw_d(fp32, cpu_env, fp64);
8076 tcg_temp_free_i64(fp64);
8077 gen_store_fpr32(fp32, fd);
8078 tcg_temp_free_i32(fp32);
8083 gen_movcf_d(ctx, fs, fd, (ft >> 2) & 0x7, ft & 0x1);
8088 int l1 = gen_new_label();
8092 tcg_gen_brcondi_tl(TCG_COND_NE, cpu_gpr[ft], 0, l1);
8094 fp0 = tcg_temp_new_i64();
8095 gen_load_fpr64(ctx, fp0, fs);
8096 gen_store_fpr64(ctx, fp0, fd);
8097 tcg_temp_free_i64(fp0);
8104 int l1 = gen_new_label();
8108 tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_gpr[ft], 0, l1);
8109 fp0 = tcg_temp_new_i64();
8110 gen_load_fpr64(ctx, fp0, fs);
8111 gen_store_fpr64(ctx, fp0, fd);
8112 tcg_temp_free_i64(fp0);
8119 check_cp1_64bitmode(ctx);
8121 TCGv_i64 fp0 = tcg_temp_new_i64();
8123 gen_load_fpr64(ctx, fp0, fs);
8124 gen_helper_float_recip_d(fp0, cpu_env, fp0);
8125 gen_store_fpr64(ctx, fp0, fd);
8126 tcg_temp_free_i64(fp0);
8131 check_cp1_64bitmode(ctx);
8133 TCGv_i64 fp0 = tcg_temp_new_i64();
8135 gen_load_fpr64(ctx, fp0, fs);
8136 gen_helper_float_rsqrt_d(fp0, cpu_env, fp0);
8137 gen_store_fpr64(ctx, fp0, fd);
8138 tcg_temp_free_i64(fp0);
8143 check_cp1_64bitmode(ctx);
8145 TCGv_i64 fp0 = tcg_temp_new_i64();
8146 TCGv_i64 fp1 = tcg_temp_new_i64();
8148 gen_load_fpr64(ctx, fp0, fs);
8149 gen_load_fpr64(ctx, fp1, ft);
8150 gen_helper_float_recip2_d(fp0, cpu_env, fp0, fp1);
8151 tcg_temp_free_i64(fp1);
8152 gen_store_fpr64(ctx, fp0, fd);
8153 tcg_temp_free_i64(fp0);
8158 check_cp1_64bitmode(ctx);
8160 TCGv_i64 fp0 = tcg_temp_new_i64();
8162 gen_load_fpr64(ctx, fp0, fs);
8163 gen_helper_float_recip1_d(fp0, cpu_env, fp0);
8164 gen_store_fpr64(ctx, fp0, fd);
8165 tcg_temp_free_i64(fp0);
8170 check_cp1_64bitmode(ctx);
8172 TCGv_i64 fp0 = tcg_temp_new_i64();
8174 gen_load_fpr64(ctx, fp0, fs);
8175 gen_helper_float_rsqrt1_d(fp0, cpu_env, fp0);
8176 gen_store_fpr64(ctx, fp0, fd);
8177 tcg_temp_free_i64(fp0);
8182 check_cp1_64bitmode(ctx);
8184 TCGv_i64 fp0 = tcg_temp_new_i64();
8185 TCGv_i64 fp1 = tcg_temp_new_i64();
8187 gen_load_fpr64(ctx, fp0, fs);
8188 gen_load_fpr64(ctx, fp1, ft);
8189 gen_helper_float_rsqrt2_d(fp0, cpu_env, fp0, fp1);
8190 tcg_temp_free_i64(fp1);
8191 gen_store_fpr64(ctx, fp0, fd);
8192 tcg_temp_free_i64(fp0);
8205 case OPC_CMP_NGLE_D:
8212 if (ctx->opcode & (1 << 6)) {
8213 gen_cmpabs_d(ctx, func-48, ft, fs, cc);
8214 opn = condnames_abs[func-48];
8216 gen_cmp_d(ctx, func-48, ft, fs, cc);
8217 opn = condnames[func-48];
8221 check_cp1_registers(ctx, fs);
8223 TCGv_i32 fp32 = tcg_temp_new_i32();
8224 TCGv_i64 fp64 = tcg_temp_new_i64();
8226 gen_load_fpr64(ctx, fp64, fs);
8227 gen_helper_float_cvts_d(fp32, cpu_env, fp64);
8228 tcg_temp_free_i64(fp64);
8229 gen_store_fpr32(fp32, fd);
8230 tcg_temp_free_i32(fp32);
8235 check_cp1_registers(ctx, fs);
8237 TCGv_i32 fp32 = tcg_temp_new_i32();
8238 TCGv_i64 fp64 = tcg_temp_new_i64();
8240 gen_load_fpr64(ctx, fp64, fs);
8241 gen_helper_float_cvtw_d(fp32, cpu_env, fp64);
8242 tcg_temp_free_i64(fp64);
8243 gen_store_fpr32(fp32, fd);
8244 tcg_temp_free_i32(fp32);
8249 check_cp1_64bitmode(ctx);
8251 TCGv_i64 fp0 = tcg_temp_new_i64();
8253 gen_load_fpr64(ctx, fp0, fs);
8254 gen_helper_float_cvtl_d(fp0, cpu_env, fp0);
8255 gen_store_fpr64(ctx, fp0, fd);
8256 tcg_temp_free_i64(fp0);
8262 TCGv_i32 fp0 = tcg_temp_new_i32();
8264 gen_load_fpr32(fp0, fs);
8265 gen_helper_float_cvts_w(fp0, cpu_env, fp0);
8266 gen_store_fpr32(fp0, fd);
8267 tcg_temp_free_i32(fp0);
8272 check_cp1_registers(ctx, fd);
8274 TCGv_i32 fp32 = tcg_temp_new_i32();
8275 TCGv_i64 fp64 = tcg_temp_new_i64();
8277 gen_load_fpr32(fp32, fs);
8278 gen_helper_float_cvtd_w(fp64, cpu_env, fp32);
8279 tcg_temp_free_i32(fp32);
8280 gen_store_fpr64(ctx, fp64, fd);
8281 tcg_temp_free_i64(fp64);
8286 check_cp1_64bitmode(ctx);
8288 TCGv_i32 fp32 = tcg_temp_new_i32();
8289 TCGv_i64 fp64 = tcg_temp_new_i64();
8291 gen_load_fpr64(ctx, fp64, fs);
8292 gen_helper_float_cvts_l(fp32, cpu_env, fp64);
8293 tcg_temp_free_i64(fp64);
8294 gen_store_fpr32(fp32, fd);
8295 tcg_temp_free_i32(fp32);
8300 check_cp1_64bitmode(ctx);
8302 TCGv_i64 fp0 = tcg_temp_new_i64();
8304 gen_load_fpr64(ctx, fp0, fs);
8305 gen_helper_float_cvtd_l(fp0, cpu_env, fp0);
8306 gen_store_fpr64(ctx, fp0, fd);
8307 tcg_temp_free_i64(fp0);
8312 check_cp1_64bitmode(ctx);
8314 TCGv_i64 fp0 = tcg_temp_new_i64();
8316 gen_load_fpr64(ctx, fp0, fs);
8317 gen_helper_float_cvtps_pw(fp0, cpu_env, fp0);
8318 gen_store_fpr64(ctx, fp0, fd);
8319 tcg_temp_free_i64(fp0);
8324 check_cp1_64bitmode(ctx);
8326 TCGv_i64 fp0 = tcg_temp_new_i64();
8327 TCGv_i64 fp1 = tcg_temp_new_i64();
8329 gen_load_fpr64(ctx, fp0, fs);
8330 gen_load_fpr64(ctx, fp1, ft);
8331 gen_helper_float_add_ps(fp0, cpu_env, fp0, fp1);
8332 tcg_temp_free_i64(fp1);
8333 gen_store_fpr64(ctx, fp0, fd);
8334 tcg_temp_free_i64(fp0);
8339 check_cp1_64bitmode(ctx);
8341 TCGv_i64 fp0 = tcg_temp_new_i64();
8342 TCGv_i64 fp1 = tcg_temp_new_i64();
8344 gen_load_fpr64(ctx, fp0, fs);
8345 gen_load_fpr64(ctx, fp1, ft);
8346 gen_helper_float_sub_ps(fp0, cpu_env, fp0, fp1);
8347 tcg_temp_free_i64(fp1);
8348 gen_store_fpr64(ctx, fp0, fd);
8349 tcg_temp_free_i64(fp0);
8354 check_cp1_64bitmode(ctx);
8356 TCGv_i64 fp0 = tcg_temp_new_i64();
8357 TCGv_i64 fp1 = tcg_temp_new_i64();
8359 gen_load_fpr64(ctx, fp0, fs);
8360 gen_load_fpr64(ctx, fp1, ft);
8361 gen_helper_float_mul_ps(fp0, cpu_env, fp0, fp1);
8362 tcg_temp_free_i64(fp1);
8363 gen_store_fpr64(ctx, fp0, fd);
8364 tcg_temp_free_i64(fp0);
8369 check_cp1_64bitmode(ctx);
8371 TCGv_i64 fp0 = tcg_temp_new_i64();
8373 gen_load_fpr64(ctx, fp0, fs);
8374 gen_helper_float_abs_ps(fp0, fp0);
8375 gen_store_fpr64(ctx, fp0, fd);
8376 tcg_temp_free_i64(fp0);
8381 check_cp1_64bitmode(ctx);
8383 TCGv_i64 fp0 = tcg_temp_new_i64();
8385 gen_load_fpr64(ctx, fp0, fs);
8386 gen_store_fpr64(ctx, fp0, fd);
8387 tcg_temp_free_i64(fp0);
8392 check_cp1_64bitmode(ctx);
8394 TCGv_i64 fp0 = tcg_temp_new_i64();
8396 gen_load_fpr64(ctx, fp0, fs);
8397 gen_helper_float_chs_ps(fp0, fp0);
8398 gen_store_fpr64(ctx, fp0, fd);
8399 tcg_temp_free_i64(fp0);
8404 check_cp1_64bitmode(ctx);
8405 gen_movcf_ps(fs, fd, (ft >> 2) & 0x7, ft & 0x1);
8409 check_cp1_64bitmode(ctx);
8411 int l1 = gen_new_label();
8415 tcg_gen_brcondi_tl(TCG_COND_NE, cpu_gpr[ft], 0, l1);
8416 fp0 = tcg_temp_new_i64();
8417 gen_load_fpr64(ctx, fp0, fs);
8418 gen_store_fpr64(ctx, fp0, fd);
8419 tcg_temp_free_i64(fp0);
8425 check_cp1_64bitmode(ctx);
8427 int l1 = gen_new_label();
8431 tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_gpr[ft], 0, l1);
8432 fp0 = tcg_temp_new_i64();
8433 gen_load_fpr64(ctx, fp0, fs);
8434 gen_store_fpr64(ctx, fp0, fd);
8435 tcg_temp_free_i64(fp0);
8442 check_cp1_64bitmode(ctx);
8444 TCGv_i64 fp0 = tcg_temp_new_i64();
8445 TCGv_i64 fp1 = tcg_temp_new_i64();
8447 gen_load_fpr64(ctx, fp0, ft);
8448 gen_load_fpr64(ctx, fp1, fs);
8449 gen_helper_float_addr_ps(fp0, cpu_env, fp0, fp1);
8450 tcg_temp_free_i64(fp1);
8451 gen_store_fpr64(ctx, fp0, fd);
8452 tcg_temp_free_i64(fp0);
8457 check_cp1_64bitmode(ctx);
8459 TCGv_i64 fp0 = tcg_temp_new_i64();
8460 TCGv_i64 fp1 = tcg_temp_new_i64();
8462 gen_load_fpr64(ctx, fp0, ft);
8463 gen_load_fpr64(ctx, fp1, fs);
8464 gen_helper_float_mulr_ps(fp0, cpu_env, fp0, fp1);
8465 tcg_temp_free_i64(fp1);
8466 gen_store_fpr64(ctx, fp0, fd);
8467 tcg_temp_free_i64(fp0);
8472 check_cp1_64bitmode(ctx);
8474 TCGv_i64 fp0 = tcg_temp_new_i64();
8475 TCGv_i64 fp1 = tcg_temp_new_i64();
8477 gen_load_fpr64(ctx, fp0, fs);
8478 gen_load_fpr64(ctx, fp1, ft);
8479 gen_helper_float_recip2_ps(fp0, cpu_env, fp0, fp1);
8480 tcg_temp_free_i64(fp1);
8481 gen_store_fpr64(ctx, fp0, fd);
8482 tcg_temp_free_i64(fp0);
8487 check_cp1_64bitmode(ctx);
8489 TCGv_i64 fp0 = tcg_temp_new_i64();
8491 gen_load_fpr64(ctx, fp0, fs);
8492 gen_helper_float_recip1_ps(fp0, cpu_env, fp0);
8493 gen_store_fpr64(ctx, fp0, fd);
8494 tcg_temp_free_i64(fp0);
8499 check_cp1_64bitmode(ctx);
8501 TCGv_i64 fp0 = tcg_temp_new_i64();
8503 gen_load_fpr64(ctx, fp0, fs);
8504 gen_helper_float_rsqrt1_ps(fp0, cpu_env, fp0);
8505 gen_store_fpr64(ctx, fp0, fd);
8506 tcg_temp_free_i64(fp0);
8511 check_cp1_64bitmode(ctx);
8513 TCGv_i64 fp0 = tcg_temp_new_i64();
8514 TCGv_i64 fp1 = tcg_temp_new_i64();
8516 gen_load_fpr64(ctx, fp0, fs);
8517 gen_load_fpr64(ctx, fp1, ft);
8518 gen_helper_float_rsqrt2_ps(fp0, cpu_env, fp0, fp1);
8519 tcg_temp_free_i64(fp1);
8520 gen_store_fpr64(ctx, fp0, fd);
8521 tcg_temp_free_i64(fp0);
8526 check_cp1_64bitmode(ctx);
8528 TCGv_i32 fp0 = tcg_temp_new_i32();
8530 gen_load_fpr32h(fp0, fs);
8531 gen_helper_float_cvts_pu(fp0, cpu_env, fp0);
8532 gen_store_fpr32(fp0, fd);
8533 tcg_temp_free_i32(fp0);
8538 check_cp1_64bitmode(ctx);
8540 TCGv_i64 fp0 = tcg_temp_new_i64();
8542 gen_load_fpr64(ctx, fp0, fs);
8543 gen_helper_float_cvtpw_ps(fp0, cpu_env, fp0);
8544 gen_store_fpr64(ctx, fp0, fd);
8545 tcg_temp_free_i64(fp0);
8550 check_cp1_64bitmode(ctx);
8552 TCGv_i32 fp0 = tcg_temp_new_i32();
8554 gen_load_fpr32(fp0, fs);
8555 gen_helper_float_cvts_pl(fp0, cpu_env, fp0);
8556 gen_store_fpr32(fp0, fd);
8557 tcg_temp_free_i32(fp0);
8562 check_cp1_64bitmode(ctx);
8564 TCGv_i32 fp0 = tcg_temp_new_i32();
8565 TCGv_i32 fp1 = tcg_temp_new_i32();
8567 gen_load_fpr32(fp0, fs);
8568 gen_load_fpr32(fp1, ft);
8569 gen_store_fpr32h(fp0, fd);
8570 gen_store_fpr32(fp1, fd);
8571 tcg_temp_free_i32(fp0);
8572 tcg_temp_free_i32(fp1);
8577 check_cp1_64bitmode(ctx);
8579 TCGv_i32 fp0 = tcg_temp_new_i32();
8580 TCGv_i32 fp1 = tcg_temp_new_i32();
8582 gen_load_fpr32(fp0, fs);
8583 gen_load_fpr32h(fp1, ft);
8584 gen_store_fpr32(fp1, fd);
8585 gen_store_fpr32h(fp0, fd);
8586 tcg_temp_free_i32(fp0);
8587 tcg_temp_free_i32(fp1);
8592 check_cp1_64bitmode(ctx);
8594 TCGv_i32 fp0 = tcg_temp_new_i32();
8595 TCGv_i32 fp1 = tcg_temp_new_i32();
8597 gen_load_fpr32h(fp0, fs);
8598 gen_load_fpr32(fp1, ft);
8599 gen_store_fpr32(fp1, fd);
8600 gen_store_fpr32h(fp0, fd);
8601 tcg_temp_free_i32(fp0);
8602 tcg_temp_free_i32(fp1);
8607 check_cp1_64bitmode(ctx);
8609 TCGv_i32 fp0 = tcg_temp_new_i32();
8610 TCGv_i32 fp1 = tcg_temp_new_i32();
8612 gen_load_fpr32h(fp0, fs);
8613 gen_load_fpr32h(fp1, ft);
8614 gen_store_fpr32(fp1, fd);
8615 gen_store_fpr32h(fp0, fd);
8616 tcg_temp_free_i32(fp0);
8617 tcg_temp_free_i32(fp1);
8624 case OPC_CMP_UEQ_PS:
8625 case OPC_CMP_OLT_PS:
8626 case OPC_CMP_ULT_PS:
8627 case OPC_CMP_OLE_PS:
8628 case OPC_CMP_ULE_PS:
8630 case OPC_CMP_NGLE_PS:
8631 case OPC_CMP_SEQ_PS:
8632 case OPC_CMP_NGL_PS:
8634 case OPC_CMP_NGE_PS:
8636 case OPC_CMP_NGT_PS:
8637 if (ctx->opcode & (1 << 6)) {
8638 gen_cmpabs_ps(ctx, func-48, ft, fs, cc);
8639 opn = condnames_abs[func-48];
8641 gen_cmp_ps(ctx, func-48, ft, fs, cc);
8642 opn = condnames[func-48];
8647 generate_exception (ctx, EXCP_RI);
8650 (void)opn; /* avoid a compiler warning */
8653 MIPS_DEBUG("%s %s, %s, %s", opn, fregnames[fd], fregnames[fs], fregnames[ft]);
8656 MIPS_DEBUG("%s %s,%s", opn, fregnames[fs], fregnames[ft]);
8659 MIPS_DEBUG("%s %s,%s", opn, fregnames[fd], fregnames[fs]);
8664 /* Coprocessor 3 (FPU) */
8665 static void gen_flt3_ldst (DisasContext *ctx, uint32_t opc,
8666 int fd, int fs, int base, int index)
8668 const char *opn = "extended float load/store";
8670 TCGv t0 = tcg_temp_new();
8673 gen_load_gpr(t0, index);
8674 } else if (index == 0) {
8675 gen_load_gpr(t0, base);
8677 gen_op_addr_add(ctx, t0, cpu_gpr[base], cpu_gpr[index]);
8679 /* Don't do NOP if destination is zero: we must perform the actual
8685 TCGv_i32 fp0 = tcg_temp_new_i32();
8687 tcg_gen_qemu_ld32s(t0, t0, ctx->mem_idx);
8688 tcg_gen_trunc_tl_i32(fp0, t0);
8689 gen_store_fpr32(fp0, fd);
8690 tcg_temp_free_i32(fp0);
8696 check_cp1_registers(ctx, fd);
8698 TCGv_i64 fp0 = tcg_temp_new_i64();
8700 tcg_gen_qemu_ld64(fp0, t0, ctx->mem_idx);
8701 gen_store_fpr64(ctx, fp0, fd);
8702 tcg_temp_free_i64(fp0);
8707 check_cp1_64bitmode(ctx);
8708 tcg_gen_andi_tl(t0, t0, ~0x7);
8710 TCGv_i64 fp0 = tcg_temp_new_i64();
8712 tcg_gen_qemu_ld64(fp0, t0, ctx->mem_idx);
8713 gen_store_fpr64(ctx, fp0, fd);
8714 tcg_temp_free_i64(fp0);
8721 TCGv_i32 fp0 = tcg_temp_new_i32();
8722 TCGv t1 = tcg_temp_new();
8724 gen_load_fpr32(fp0, fs);
8725 tcg_gen_extu_i32_tl(t1, fp0);
8726 tcg_gen_qemu_st32(t1, t0, ctx->mem_idx);
8727 tcg_temp_free_i32(fp0);
8735 check_cp1_registers(ctx, fs);
8737 TCGv_i64 fp0 = tcg_temp_new_i64();
8739 gen_load_fpr64(ctx, fp0, fs);
8740 tcg_gen_qemu_st64(fp0, t0, ctx->mem_idx);
8741 tcg_temp_free_i64(fp0);
8747 check_cp1_64bitmode(ctx);
8748 tcg_gen_andi_tl(t0, t0, ~0x7);
8750 TCGv_i64 fp0 = tcg_temp_new_i64();
8752 gen_load_fpr64(ctx, fp0, fs);
8753 tcg_gen_qemu_st64(fp0, t0, ctx->mem_idx);
8754 tcg_temp_free_i64(fp0);
8761 (void)opn; (void)store; /* avoid compiler warnings */
8762 MIPS_DEBUG("%s %s, %s(%s)", opn, fregnames[store ? fs : fd],
8763 regnames[index], regnames[base]);
8766 static void gen_flt3_arith (DisasContext *ctx, uint32_t opc,
8767 int fd, int fr, int fs, int ft)
8769 const char *opn = "flt3_arith";
8773 check_cp1_64bitmode(ctx);
8775 TCGv t0 = tcg_temp_local_new();
8776 TCGv_i32 fp = tcg_temp_new_i32();
8777 TCGv_i32 fph = tcg_temp_new_i32();
8778 int l1 = gen_new_label();
8779 int l2 = gen_new_label();
8781 gen_load_gpr(t0, fr);
8782 tcg_gen_andi_tl(t0, t0, 0x7);
8784 tcg_gen_brcondi_tl(TCG_COND_NE, t0, 0, l1);
8785 gen_load_fpr32(fp, fs);
8786 gen_load_fpr32h(fph, fs);
8787 gen_store_fpr32(fp, fd);
8788 gen_store_fpr32h(fph, fd);
8791 tcg_gen_brcondi_tl(TCG_COND_NE, t0, 4, l2);
8793 #ifdef TARGET_WORDS_BIGENDIAN
8794 gen_load_fpr32(fp, fs);
8795 gen_load_fpr32h(fph, ft);
8796 gen_store_fpr32h(fp, fd);
8797 gen_store_fpr32(fph, fd);
8799 gen_load_fpr32h(fph, fs);
8800 gen_load_fpr32(fp, ft);
8801 gen_store_fpr32(fph, fd);
8802 gen_store_fpr32h(fp, fd);
8805 tcg_temp_free_i32(fp);
8806 tcg_temp_free_i32(fph);
8813 TCGv_i32 fp0 = tcg_temp_new_i32();
8814 TCGv_i32 fp1 = tcg_temp_new_i32();
8815 TCGv_i32 fp2 = tcg_temp_new_i32();
8817 gen_load_fpr32(fp0, fs);
8818 gen_load_fpr32(fp1, ft);
8819 gen_load_fpr32(fp2, fr);
8820 gen_helper_float_madd_s(fp2, cpu_env, fp0, fp1, fp2);
8821 tcg_temp_free_i32(fp0);
8822 tcg_temp_free_i32(fp1);
8823 gen_store_fpr32(fp2, fd);
8824 tcg_temp_free_i32(fp2);
8830 check_cp1_registers(ctx, fd | fs | ft | fr);
8832 TCGv_i64 fp0 = tcg_temp_new_i64();
8833 TCGv_i64 fp1 = tcg_temp_new_i64();
8834 TCGv_i64 fp2 = tcg_temp_new_i64();
8836 gen_load_fpr64(ctx, fp0, fs);
8837 gen_load_fpr64(ctx, fp1, ft);
8838 gen_load_fpr64(ctx, fp2, fr);
8839 gen_helper_float_madd_d(fp2, cpu_env, fp0, fp1, fp2);
8840 tcg_temp_free_i64(fp0);
8841 tcg_temp_free_i64(fp1);
8842 gen_store_fpr64(ctx, fp2, fd);
8843 tcg_temp_free_i64(fp2);
8848 check_cp1_64bitmode(ctx);
8850 TCGv_i64 fp0 = tcg_temp_new_i64();
8851 TCGv_i64 fp1 = tcg_temp_new_i64();
8852 TCGv_i64 fp2 = tcg_temp_new_i64();
8854 gen_load_fpr64(ctx, fp0, fs);
8855 gen_load_fpr64(ctx, fp1, ft);
8856 gen_load_fpr64(ctx, fp2, fr);
8857 gen_helper_float_madd_ps(fp2, cpu_env, fp0, fp1, fp2);
8858 tcg_temp_free_i64(fp0);
8859 tcg_temp_free_i64(fp1);
8860 gen_store_fpr64(ctx, fp2, fd);
8861 tcg_temp_free_i64(fp2);
8868 TCGv_i32 fp0 = tcg_temp_new_i32();
8869 TCGv_i32 fp1 = tcg_temp_new_i32();
8870 TCGv_i32 fp2 = tcg_temp_new_i32();
8872 gen_load_fpr32(fp0, fs);
8873 gen_load_fpr32(fp1, ft);
8874 gen_load_fpr32(fp2, fr);
8875 gen_helper_float_msub_s(fp2, cpu_env, fp0, fp1, fp2);
8876 tcg_temp_free_i32(fp0);
8877 tcg_temp_free_i32(fp1);
8878 gen_store_fpr32(fp2, fd);
8879 tcg_temp_free_i32(fp2);
8885 check_cp1_registers(ctx, fd | fs | ft | fr);
8887 TCGv_i64 fp0 = tcg_temp_new_i64();
8888 TCGv_i64 fp1 = tcg_temp_new_i64();
8889 TCGv_i64 fp2 = tcg_temp_new_i64();
8891 gen_load_fpr64(ctx, fp0, fs);
8892 gen_load_fpr64(ctx, fp1, ft);
8893 gen_load_fpr64(ctx, fp2, fr);
8894 gen_helper_float_msub_d(fp2, cpu_env, fp0, fp1, fp2);
8895 tcg_temp_free_i64(fp0);
8896 tcg_temp_free_i64(fp1);
8897 gen_store_fpr64(ctx, fp2, fd);
8898 tcg_temp_free_i64(fp2);
8903 check_cp1_64bitmode(ctx);
8905 TCGv_i64 fp0 = tcg_temp_new_i64();
8906 TCGv_i64 fp1 = tcg_temp_new_i64();
8907 TCGv_i64 fp2 = tcg_temp_new_i64();
8909 gen_load_fpr64(ctx, fp0, fs);
8910 gen_load_fpr64(ctx, fp1, ft);
8911 gen_load_fpr64(ctx, fp2, fr);
8912 gen_helper_float_msub_ps(fp2, cpu_env, fp0, fp1, fp2);
8913 tcg_temp_free_i64(fp0);
8914 tcg_temp_free_i64(fp1);
8915 gen_store_fpr64(ctx, fp2, fd);
8916 tcg_temp_free_i64(fp2);
8923 TCGv_i32 fp0 = tcg_temp_new_i32();
8924 TCGv_i32 fp1 = tcg_temp_new_i32();
8925 TCGv_i32 fp2 = tcg_temp_new_i32();
8927 gen_load_fpr32(fp0, fs);
8928 gen_load_fpr32(fp1, ft);
8929 gen_load_fpr32(fp2, fr);
8930 gen_helper_float_nmadd_s(fp2, cpu_env, fp0, fp1, fp2);
8931 tcg_temp_free_i32(fp0);
8932 tcg_temp_free_i32(fp1);
8933 gen_store_fpr32(fp2, fd);
8934 tcg_temp_free_i32(fp2);
8940 check_cp1_registers(ctx, fd | fs | ft | fr);
8942 TCGv_i64 fp0 = tcg_temp_new_i64();
8943 TCGv_i64 fp1 = tcg_temp_new_i64();
8944 TCGv_i64 fp2 = tcg_temp_new_i64();
8946 gen_load_fpr64(ctx, fp0, fs);
8947 gen_load_fpr64(ctx, fp1, ft);
8948 gen_load_fpr64(ctx, fp2, fr);
8949 gen_helper_float_nmadd_d(fp2, cpu_env, fp0, fp1, fp2);
8950 tcg_temp_free_i64(fp0);
8951 tcg_temp_free_i64(fp1);
8952 gen_store_fpr64(ctx, fp2, fd);
8953 tcg_temp_free_i64(fp2);
8958 check_cp1_64bitmode(ctx);
8960 TCGv_i64 fp0 = tcg_temp_new_i64();
8961 TCGv_i64 fp1 = tcg_temp_new_i64();
8962 TCGv_i64 fp2 = tcg_temp_new_i64();
8964 gen_load_fpr64(ctx, fp0, fs);
8965 gen_load_fpr64(ctx, fp1, ft);
8966 gen_load_fpr64(ctx, fp2, fr);
8967 gen_helper_float_nmadd_ps(fp2, cpu_env, fp0, fp1, fp2);
8968 tcg_temp_free_i64(fp0);
8969 tcg_temp_free_i64(fp1);
8970 gen_store_fpr64(ctx, fp2, fd);
8971 tcg_temp_free_i64(fp2);
8978 TCGv_i32 fp0 = tcg_temp_new_i32();
8979 TCGv_i32 fp1 = tcg_temp_new_i32();
8980 TCGv_i32 fp2 = tcg_temp_new_i32();
8982 gen_load_fpr32(fp0, fs);
8983 gen_load_fpr32(fp1, ft);
8984 gen_load_fpr32(fp2, fr);
8985 gen_helper_float_nmsub_s(fp2, cpu_env, fp0, fp1, fp2);
8986 tcg_temp_free_i32(fp0);
8987 tcg_temp_free_i32(fp1);
8988 gen_store_fpr32(fp2, fd);
8989 tcg_temp_free_i32(fp2);
8995 check_cp1_registers(ctx, fd | fs | ft | fr);
8997 TCGv_i64 fp0 = tcg_temp_new_i64();
8998 TCGv_i64 fp1 = tcg_temp_new_i64();
8999 TCGv_i64 fp2 = tcg_temp_new_i64();
9001 gen_load_fpr64(ctx, fp0, fs);
9002 gen_load_fpr64(ctx, fp1, ft);
9003 gen_load_fpr64(ctx, fp2, fr);
9004 gen_helper_float_nmsub_d(fp2, cpu_env, fp0, fp1, fp2);
9005 tcg_temp_free_i64(fp0);
9006 tcg_temp_free_i64(fp1);
9007 gen_store_fpr64(ctx, fp2, fd);
9008 tcg_temp_free_i64(fp2);
9013 check_cp1_64bitmode(ctx);
9015 TCGv_i64 fp0 = tcg_temp_new_i64();
9016 TCGv_i64 fp1 = tcg_temp_new_i64();
9017 TCGv_i64 fp2 = tcg_temp_new_i64();
9019 gen_load_fpr64(ctx, fp0, fs);
9020 gen_load_fpr64(ctx, fp1, ft);
9021 gen_load_fpr64(ctx, fp2, fr);
9022 gen_helper_float_nmsub_ps(fp2, cpu_env, fp0, fp1, fp2);
9023 tcg_temp_free_i64(fp0);
9024 tcg_temp_free_i64(fp1);
9025 gen_store_fpr64(ctx, fp2, fd);
9026 tcg_temp_free_i64(fp2);
9032 generate_exception (ctx, EXCP_RI);
9035 (void)opn; /* avoid a compiler warning */
9036 MIPS_DEBUG("%s %s, %s, %s, %s", opn, fregnames[fd], fregnames[fr],
9037 fregnames[fs], fregnames[ft]);
9041 gen_rdhwr (CPUMIPSState *env, DisasContext *ctx, int rt, int rd)
9045 #if !defined(CONFIG_USER_ONLY)
9046 /* The Linux kernel will emulate rdhwr if it's not supported natively.
9047 Therefore only check the ISA in system mode. */
9048 check_insn(env, ctx, ISA_MIPS32R2);
9050 t0 = tcg_temp_new();
9054 save_cpu_state(ctx, 1);
9055 gen_helper_rdhwr_cpunum(t0, cpu_env);
9056 gen_store_gpr(t0, rt);
9059 save_cpu_state(ctx, 1);
9060 gen_helper_rdhwr_synci_step(t0, cpu_env);
9061 gen_store_gpr(t0, rt);
9064 save_cpu_state(ctx, 1);
9065 gen_helper_rdhwr_cc(t0, cpu_env);
9066 gen_store_gpr(t0, rt);
9069 save_cpu_state(ctx, 1);
9070 gen_helper_rdhwr_ccres(t0, cpu_env);
9071 gen_store_gpr(t0, rt);
9074 #if defined(CONFIG_USER_ONLY)
9075 tcg_gen_ld_tl(t0, cpu_env, offsetof(CPUMIPSState, tls_value));
9076 gen_store_gpr(t0, rt);
9079 /* XXX: Some CPUs implement this in hardware.
9080 Not supported yet. */
9082 default: /* Invalid */
9083 MIPS_INVAL("rdhwr");
9084 generate_exception(ctx, EXCP_RI);
9090 static void handle_delay_slot (CPUMIPSState *env, DisasContext *ctx,
9093 if (ctx->hflags & MIPS_HFLAG_BMASK) {
9094 int proc_hflags = ctx->hflags & MIPS_HFLAG_BMASK;
9095 /* Branches completion */
9096 ctx->hflags &= ~MIPS_HFLAG_BMASK;
9097 ctx->bstate = BS_BRANCH;
9098 save_cpu_state(ctx, 0);
9099 /* FIXME: Need to clear can_do_io. */
9100 switch (proc_hflags & MIPS_HFLAG_BMASK_BASE) {
9102 /* unconditional branch */
9103 MIPS_DEBUG("unconditional branch");
9104 if (proc_hflags & MIPS_HFLAG_BX) {
9105 tcg_gen_xori_i32(hflags, hflags, MIPS_HFLAG_M16);
9107 gen_goto_tb(ctx, 0, ctx->btarget);
9110 /* blikely taken case */
9111 MIPS_DEBUG("blikely branch taken");
9112 gen_goto_tb(ctx, 0, ctx->btarget);
9115 /* Conditional branch */
9116 MIPS_DEBUG("conditional branch");
9118 int l1 = gen_new_label();
9120 tcg_gen_brcondi_tl(TCG_COND_NE, bcond, 0, l1);
9121 gen_goto_tb(ctx, 1, ctx->pc + insn_bytes);
9123 gen_goto_tb(ctx, 0, ctx->btarget);
9127 /* unconditional branch to register */
9128 MIPS_DEBUG("branch to register");
9129 if (env->insn_flags & (ASE_MIPS16 | ASE_MICROMIPS)) {
9130 TCGv t0 = tcg_temp_new();
9131 TCGv_i32 t1 = tcg_temp_new_i32();
9133 tcg_gen_andi_tl(t0, btarget, 0x1);
9134 tcg_gen_trunc_tl_i32(t1, t0);
9136 tcg_gen_andi_i32(hflags, hflags, ~(uint32_t)MIPS_HFLAG_M16);
9137 tcg_gen_shli_i32(t1, t1, MIPS_HFLAG_M16_SHIFT);
9138 tcg_gen_or_i32(hflags, hflags, t1);
9139 tcg_temp_free_i32(t1);
9141 tcg_gen_andi_tl(cpu_PC, btarget, ~(target_ulong)0x1);
9143 tcg_gen_mov_tl(cpu_PC, btarget);
9145 if (ctx->singlestep_enabled) {
9146 save_cpu_state(ctx, 0);
9147 gen_helper_0e0i(raise_exception, EXCP_DEBUG);
9152 MIPS_DEBUG("unknown branch");
9158 /* ISA extensions (ASEs) */
9159 /* MIPS16 extension to MIPS32 */
9161 /* MIPS16 major opcodes */
9163 M16_OPC_ADDIUSP = 0x00,
9164 M16_OPC_ADDIUPC = 0x01,
9167 M16_OPC_BEQZ = 0x04,
9168 M16_OPC_BNEQZ = 0x05,
9169 M16_OPC_SHIFT = 0x06,
9171 M16_OPC_RRIA = 0x08,
9172 M16_OPC_ADDIU8 = 0x09,
9173 M16_OPC_SLTI = 0x0a,
9174 M16_OPC_SLTIU = 0x0b,
9177 M16_OPC_CMPI = 0x0e,
9181 M16_OPC_LWSP = 0x12,
9185 M16_OPC_LWPC = 0x16,
9189 M16_OPC_SWSP = 0x1a,
9193 M16_OPC_EXTEND = 0x1e,
9197 /* I8 funct field */
9216 /* RR funct field */
9250 /* I64 funct field */
9262 /* RR ry field for CNVT */
9264 RR_RY_CNVT_ZEB = 0x0,
9265 RR_RY_CNVT_ZEH = 0x1,
9266 RR_RY_CNVT_ZEW = 0x2,
9267 RR_RY_CNVT_SEB = 0x4,
9268 RR_RY_CNVT_SEH = 0x5,
9269 RR_RY_CNVT_SEW = 0x6,
9272 static int xlat (int r)
9274 static int map[] = { 16, 17, 2, 3, 4, 5, 6, 7 };
9279 static void gen_mips16_save (DisasContext *ctx,
9280 int xsregs, int aregs,
9281 int do_ra, int do_s0, int do_s1,
9284 TCGv t0 = tcg_temp_new();
9285 TCGv t1 = tcg_temp_new();
9315 generate_exception(ctx, EXCP_RI);
9321 gen_base_offset_addr(ctx, t0, 29, 12);
9322 gen_load_gpr(t1, 7);
9323 op_st_sw(t1, t0, ctx);
9326 gen_base_offset_addr(ctx, t0, 29, 8);
9327 gen_load_gpr(t1, 6);
9328 op_st_sw(t1, t0, ctx);
9331 gen_base_offset_addr(ctx, t0, 29, 4);
9332 gen_load_gpr(t1, 5);
9333 op_st_sw(t1, t0, ctx);
9336 gen_base_offset_addr(ctx, t0, 29, 0);
9337 gen_load_gpr(t1, 4);
9338 op_st_sw(t1, t0, ctx);
9341 gen_load_gpr(t0, 29);
9343 #define DECR_AND_STORE(reg) do { \
9344 tcg_gen_subi_tl(t0, t0, 4); \
9345 gen_load_gpr(t1, reg); \
9346 op_st_sw(t1, t0, ctx); \
9410 generate_exception(ctx, EXCP_RI);
9426 #undef DECR_AND_STORE
9428 tcg_gen_subi_tl(cpu_gpr[29], cpu_gpr[29], framesize);
9433 static void gen_mips16_restore (DisasContext *ctx,
9434 int xsregs, int aregs,
9435 int do_ra, int do_s0, int do_s1,
9439 TCGv t0 = tcg_temp_new();
9440 TCGv t1 = tcg_temp_new();
9442 tcg_gen_addi_tl(t0, cpu_gpr[29], framesize);
9444 #define DECR_AND_LOAD(reg) do { \
9445 tcg_gen_subi_tl(t0, t0, 4); \
9446 op_ld_lw(t1, t0, ctx); \
9447 gen_store_gpr(t1, reg); \
9511 generate_exception(ctx, EXCP_RI);
9527 #undef DECR_AND_LOAD
9529 tcg_gen_addi_tl(cpu_gpr[29], cpu_gpr[29], framesize);
9534 static void gen_addiupc (DisasContext *ctx, int rx, int imm,
9535 int is_64_bit, int extended)
9539 if (extended && (ctx->hflags & MIPS_HFLAG_BMASK)) {
9540 generate_exception(ctx, EXCP_RI);
9544 t0 = tcg_temp_new();
9546 tcg_gen_movi_tl(t0, pc_relative_pc(ctx));
9547 tcg_gen_addi_tl(cpu_gpr[rx], t0, imm);
9549 tcg_gen_ext32s_tl(cpu_gpr[rx], cpu_gpr[rx]);
9555 #if defined(TARGET_MIPS64)
9556 static void decode_i64_mips16 (CPUMIPSState *env, DisasContext *ctx,
9557 int ry, int funct, int16_t offset,
9563 offset = extended ? offset : offset << 3;
9564 gen_ld(env, ctx, OPC_LD, ry, 29, offset);
9568 offset = extended ? offset : offset << 3;
9569 gen_st(ctx, OPC_SD, ry, 29, offset);
9573 offset = extended ? offset : (ctx->opcode & 0xff) << 3;
9574 gen_st(ctx, OPC_SD, 31, 29, offset);
9578 offset = extended ? offset : ((int8_t)ctx->opcode) << 3;
9579 gen_arith_imm(env, ctx, OPC_DADDIU, 29, 29, offset);
9582 if (extended && (ctx->hflags & MIPS_HFLAG_BMASK)) {
9583 generate_exception(ctx, EXCP_RI);
9585 offset = extended ? offset : offset << 3;
9586 gen_ld(env, ctx, OPC_LDPC, ry, 0, offset);
9591 offset = extended ? offset : ((int8_t)(offset << 3)) >> 3;
9592 gen_arith_imm(env, ctx, OPC_DADDIU, ry, ry, offset);
9596 offset = extended ? offset : offset << 2;
9597 gen_addiupc(ctx, ry, offset, 1, extended);
9601 offset = extended ? offset : offset << 2;
9602 gen_arith_imm(env, ctx, OPC_DADDIU, ry, 29, offset);
9608 static int decode_extended_mips16_opc (CPUMIPSState *env, DisasContext *ctx,
9611 int extend = cpu_lduw_code(env, ctx->pc + 2);
9612 int op, rx, ry, funct, sa;
9613 int16_t imm, offset;
9615 ctx->opcode = (ctx->opcode << 16) | extend;
9616 op = (ctx->opcode >> 11) & 0x1f;
9617 sa = (ctx->opcode >> 22) & 0x1f;
9618 funct = (ctx->opcode >> 8) & 0x7;
9619 rx = xlat((ctx->opcode >> 8) & 0x7);
9620 ry = xlat((ctx->opcode >> 5) & 0x7);
9621 offset = imm = (int16_t) (((ctx->opcode >> 16) & 0x1f) << 11
9622 | ((ctx->opcode >> 21) & 0x3f) << 5
9623 | (ctx->opcode & 0x1f));
9625 /* The extended opcodes cleverly reuse the opcodes from their 16-bit
9628 case M16_OPC_ADDIUSP:
9629 gen_arith_imm(env, ctx, OPC_ADDIU, rx, 29, imm);
9631 case M16_OPC_ADDIUPC:
9632 gen_addiupc(ctx, rx, imm, 0, 1);
9635 gen_compute_branch(ctx, OPC_BEQ, 4, 0, 0, offset << 1);
9636 /* No delay slot, so just process as a normal instruction */
9639 gen_compute_branch(ctx, OPC_BEQ, 4, rx, 0, offset << 1);
9640 /* No delay slot, so just process as a normal instruction */
9643 gen_compute_branch(ctx, OPC_BNE, 4, rx, 0, offset << 1);
9644 /* No delay slot, so just process as a normal instruction */
9647 switch (ctx->opcode & 0x3) {
9649 gen_shift_imm(env, ctx, OPC_SLL, rx, ry, sa);
9652 #if defined(TARGET_MIPS64)
9654 gen_shift_imm(env, ctx, OPC_DSLL, rx, ry, sa);
9656 generate_exception(ctx, EXCP_RI);
9660 gen_shift_imm(env, ctx, OPC_SRL, rx, ry, sa);
9663 gen_shift_imm(env, ctx, OPC_SRA, rx, ry, sa);
9667 #if defined(TARGET_MIPS64)
9670 gen_ld(env, ctx, OPC_LD, ry, rx, offset);
9674 imm = ctx->opcode & 0xf;
9675 imm = imm | ((ctx->opcode >> 20) & 0x7f) << 4;
9676 imm = imm | ((ctx->opcode >> 16) & 0xf) << 11;
9677 imm = (int16_t) (imm << 1) >> 1;
9678 if ((ctx->opcode >> 4) & 0x1) {
9679 #if defined(TARGET_MIPS64)
9681 gen_arith_imm(env, ctx, OPC_DADDIU, ry, rx, imm);
9683 generate_exception(ctx, EXCP_RI);
9686 gen_arith_imm(env, ctx, OPC_ADDIU, ry, rx, imm);
9689 case M16_OPC_ADDIU8:
9690 gen_arith_imm(env, ctx, OPC_ADDIU, rx, rx, imm);
9693 gen_slt_imm(env, ctx, OPC_SLTI, 24, rx, imm);
9696 gen_slt_imm(env, ctx, OPC_SLTIU, 24, rx, imm);
9701 gen_compute_branch(ctx, OPC_BEQ, 4, 24, 0, offset << 1);
9704 gen_compute_branch(ctx, OPC_BNE, 4, 24, 0, offset << 1);
9707 gen_st(ctx, OPC_SW, 31, 29, imm);
9710 gen_arith_imm(env, ctx, OPC_ADDIU, 29, 29, imm);
9714 int xsregs = (ctx->opcode >> 24) & 0x7;
9715 int aregs = (ctx->opcode >> 16) & 0xf;
9716 int do_ra = (ctx->opcode >> 6) & 0x1;
9717 int do_s0 = (ctx->opcode >> 5) & 0x1;
9718 int do_s1 = (ctx->opcode >> 4) & 0x1;
9719 int framesize = (((ctx->opcode >> 20) & 0xf) << 4
9720 | (ctx->opcode & 0xf)) << 3;
9722 if (ctx->opcode & (1 << 7)) {
9723 gen_mips16_save(ctx, xsregs, aregs,
9724 do_ra, do_s0, do_s1,
9727 gen_mips16_restore(ctx, xsregs, aregs,
9728 do_ra, do_s0, do_s1,
9734 generate_exception(ctx, EXCP_RI);
9739 tcg_gen_movi_tl(cpu_gpr[rx], (uint16_t) imm);
9742 tcg_gen_xori_tl(cpu_gpr[24], cpu_gpr[rx], (uint16_t) imm);
9744 #if defined(TARGET_MIPS64)
9746 gen_st(ctx, OPC_SD, ry, rx, offset);
9750 gen_ld(env, ctx, OPC_LB, ry, rx, offset);
9753 gen_ld(env, ctx, OPC_LH, ry, rx, offset);
9756 gen_ld(env, ctx, OPC_LW, rx, 29, offset);
9759 gen_ld(env, ctx, OPC_LW, ry, rx, offset);
9762 gen_ld(env, ctx, OPC_LBU, ry, rx, offset);
9765 gen_ld(env, ctx, OPC_LHU, ry, rx, offset);
9768 gen_ld(env, ctx, OPC_LWPC, rx, 0, offset);
9770 #if defined(TARGET_MIPS64)
9772 gen_ld(env, ctx, OPC_LWU, ry, rx, offset);
9776 gen_st(ctx, OPC_SB, ry, rx, offset);
9779 gen_st(ctx, OPC_SH, ry, rx, offset);
9782 gen_st(ctx, OPC_SW, rx, 29, offset);
9785 gen_st(ctx, OPC_SW, ry, rx, offset);
9787 #if defined(TARGET_MIPS64)
9789 decode_i64_mips16(env, ctx, ry, funct, offset, 1);
9793 generate_exception(ctx, EXCP_RI);
9800 static int decode_mips16_opc (CPUMIPSState *env, DisasContext *ctx,
9805 int op, cnvt_op, op1, offset;
9809 op = (ctx->opcode >> 11) & 0x1f;
9810 sa = (ctx->opcode >> 2) & 0x7;
9811 sa = sa == 0 ? 8 : sa;
9812 rx = xlat((ctx->opcode >> 8) & 0x7);
9813 cnvt_op = (ctx->opcode >> 5) & 0x7;
9814 ry = xlat((ctx->opcode >> 5) & 0x7);
9815 op1 = offset = ctx->opcode & 0x1f;
9820 case M16_OPC_ADDIUSP:
9822 int16_t imm = ((uint8_t) ctx->opcode) << 2;
9824 gen_arith_imm(env, ctx, OPC_ADDIU, rx, 29, imm);
9827 case M16_OPC_ADDIUPC:
9828 gen_addiupc(ctx, rx, ((uint8_t) ctx->opcode) << 2, 0, 0);
9831 offset = (ctx->opcode & 0x7ff) << 1;
9832 offset = (int16_t)(offset << 4) >> 4;
9833 gen_compute_branch(ctx, OPC_BEQ, 2, 0, 0, offset);
9834 /* No delay slot, so just process as a normal instruction */
9837 offset = cpu_lduw_code(env, ctx->pc + 2);
9838 offset = (((ctx->opcode & 0x1f) << 21)
9839 | ((ctx->opcode >> 5) & 0x1f) << 16
9841 op = ((ctx->opcode >> 10) & 0x1) ? OPC_JALXS : OPC_JALS;
9842 gen_compute_branch(ctx, op, 4, rx, ry, offset);
9847 gen_compute_branch(ctx, OPC_BEQ, 2, rx, 0, ((int8_t)ctx->opcode) << 1);
9848 /* No delay slot, so just process as a normal instruction */
9851 gen_compute_branch(ctx, OPC_BNE, 2, rx, 0, ((int8_t)ctx->opcode) << 1);
9852 /* No delay slot, so just process as a normal instruction */
9855 switch (ctx->opcode & 0x3) {
9857 gen_shift_imm(env, ctx, OPC_SLL, rx, ry, sa);
9860 #if defined(TARGET_MIPS64)
9862 gen_shift_imm(env, ctx, OPC_DSLL, rx, ry, sa);
9864 generate_exception(ctx, EXCP_RI);
9868 gen_shift_imm(env, ctx, OPC_SRL, rx, ry, sa);
9871 gen_shift_imm(env, ctx, OPC_SRA, rx, ry, sa);
9875 #if defined(TARGET_MIPS64)
9878 gen_ld(env, ctx, OPC_LD, ry, rx, offset << 3);
9883 int16_t imm = (int8_t)((ctx->opcode & 0xf) << 4) >> 4;
9885 if ((ctx->opcode >> 4) & 1) {
9886 #if defined(TARGET_MIPS64)
9888 gen_arith_imm(env, ctx, OPC_DADDIU, ry, rx, imm);
9890 generate_exception(ctx, EXCP_RI);
9893 gen_arith_imm(env, ctx, OPC_ADDIU, ry, rx, imm);
9897 case M16_OPC_ADDIU8:
9899 int16_t imm = (int8_t) ctx->opcode;
9901 gen_arith_imm(env, ctx, OPC_ADDIU, rx, rx, imm);
9906 int16_t imm = (uint8_t) ctx->opcode;
9907 gen_slt_imm(env, ctx, OPC_SLTI, 24, rx, imm);
9912 int16_t imm = (uint8_t) ctx->opcode;
9913 gen_slt_imm(env, ctx, OPC_SLTIU, 24, rx, imm);
9920 funct = (ctx->opcode >> 8) & 0x7;
9923 gen_compute_branch(ctx, OPC_BEQ, 2, 24, 0,
9924 ((int8_t)ctx->opcode) << 1);
9927 gen_compute_branch(ctx, OPC_BNE, 2, 24, 0,
9928 ((int8_t)ctx->opcode) << 1);
9931 gen_st(ctx, OPC_SW, 31, 29, (ctx->opcode & 0xff) << 2);
9934 gen_arith_imm(env, ctx, OPC_ADDIU, 29, 29,
9935 ((int8_t)ctx->opcode) << 3);
9939 int do_ra = ctx->opcode & (1 << 6);
9940 int do_s0 = ctx->opcode & (1 << 5);
9941 int do_s1 = ctx->opcode & (1 << 4);
9942 int framesize = ctx->opcode & 0xf;
9944 if (framesize == 0) {
9947 framesize = framesize << 3;
9950 if (ctx->opcode & (1 << 7)) {
9951 gen_mips16_save(ctx, 0, 0,
9952 do_ra, do_s0, do_s1, framesize);
9954 gen_mips16_restore(ctx, 0, 0,
9955 do_ra, do_s0, do_s1, framesize);
9961 int rz = xlat(ctx->opcode & 0x7);
9963 reg32 = (((ctx->opcode >> 3) & 0x3) << 3) |
9964 ((ctx->opcode >> 5) & 0x7);
9965 gen_arith(env, ctx, OPC_ADDU, reg32, rz, 0);
9969 reg32 = ctx->opcode & 0x1f;
9970 gen_arith(env, ctx, OPC_ADDU, ry, reg32, 0);
9973 generate_exception(ctx, EXCP_RI);
9980 int16_t imm = (uint8_t) ctx->opcode;
9982 gen_arith_imm(env, ctx, OPC_ADDIU, rx, 0, imm);
9987 int16_t imm = (uint8_t) ctx->opcode;
9988 gen_logic_imm(env, ctx, OPC_XORI, 24, rx, imm);
9991 #if defined(TARGET_MIPS64)
9994 gen_st(ctx, OPC_SD, ry, rx, offset << 3);
9998 gen_ld(env, ctx, OPC_LB, ry, rx, offset);
10001 gen_ld(env, ctx, OPC_LH, ry, rx, offset << 1);
10004 gen_ld(env, ctx, OPC_LW, rx, 29, ((uint8_t)ctx->opcode) << 2);
10007 gen_ld(env, ctx, OPC_LW, ry, rx, offset << 2);
10010 gen_ld(env, ctx, OPC_LBU, ry, rx, offset);
10013 gen_ld(env, ctx, OPC_LHU, ry, rx, offset << 1);
10016 gen_ld(env, ctx, OPC_LWPC, rx, 0, ((uint8_t)ctx->opcode) << 2);
10018 #if defined (TARGET_MIPS64)
10020 check_mips_64(ctx);
10021 gen_ld(env, ctx, OPC_LWU, ry, rx, offset << 2);
10025 gen_st(ctx, OPC_SB, ry, rx, offset);
10028 gen_st(ctx, OPC_SH, ry, rx, offset << 1);
10031 gen_st(ctx, OPC_SW, rx, 29, ((uint8_t)ctx->opcode) << 2);
10034 gen_st(ctx, OPC_SW, ry, rx, offset << 2);
10038 int rz = xlat((ctx->opcode >> 2) & 0x7);
10041 switch (ctx->opcode & 0x3) {
10043 mips32_op = OPC_ADDU;
10046 mips32_op = OPC_SUBU;
10048 #if defined(TARGET_MIPS64)
10050 mips32_op = OPC_DADDU;
10051 check_mips_64(ctx);
10054 mips32_op = OPC_DSUBU;
10055 check_mips_64(ctx);
10059 generate_exception(ctx, EXCP_RI);
10063 gen_arith(env, ctx, mips32_op, rz, rx, ry);
10072 int nd = (ctx->opcode >> 7) & 0x1;
10073 int link = (ctx->opcode >> 6) & 0x1;
10074 int ra = (ctx->opcode >> 5) & 0x1;
10077 op = nd ? OPC_JALRC : OPC_JALRS;
10082 gen_compute_branch(ctx, op, 2, ra ? 31 : rx, 31, 0);
10089 /* XXX: not clear which exception should be raised
10090 * when in debug mode...
10092 check_insn(env, ctx, ISA_MIPS32);
10093 if (!(ctx->hflags & MIPS_HFLAG_DM)) {
10094 generate_exception(ctx, EXCP_DBp);
10096 generate_exception(ctx, EXCP_DBp);
10100 gen_slt(env, ctx, OPC_SLT, 24, rx, ry);
10103 gen_slt(env, ctx, OPC_SLTU, 24, rx, ry);
10106 generate_exception(ctx, EXCP_BREAK);
10109 gen_shift(env, ctx, OPC_SLLV, ry, rx, ry);
10112 gen_shift(env, ctx, OPC_SRLV, ry, rx, ry);
10115 gen_shift(env, ctx, OPC_SRAV, ry, rx, ry);
10117 #if defined (TARGET_MIPS64)
10119 check_mips_64(ctx);
10120 gen_shift_imm(env, ctx, OPC_DSRL, ry, ry, sa);
10124 gen_logic(env, ctx, OPC_XOR, 24, rx, ry);
10127 gen_arith(env, ctx, OPC_SUBU, rx, 0, ry);
10130 gen_logic(env, ctx, OPC_AND, rx, rx, ry);
10133 gen_logic(env, ctx, OPC_OR, rx, rx, ry);
10136 gen_logic(env, ctx, OPC_XOR, rx, rx, ry);
10139 gen_logic(env, ctx, OPC_NOR, rx, ry, 0);
10142 gen_HILO(ctx, OPC_MFHI, rx);
10146 case RR_RY_CNVT_ZEB:
10147 tcg_gen_ext8u_tl(cpu_gpr[rx], cpu_gpr[rx]);
10149 case RR_RY_CNVT_ZEH:
10150 tcg_gen_ext16u_tl(cpu_gpr[rx], cpu_gpr[rx]);
10152 case RR_RY_CNVT_SEB:
10153 tcg_gen_ext8s_tl(cpu_gpr[rx], cpu_gpr[rx]);
10155 case RR_RY_CNVT_SEH:
10156 tcg_gen_ext16s_tl(cpu_gpr[rx], cpu_gpr[rx]);
10158 #if defined (TARGET_MIPS64)
10159 case RR_RY_CNVT_ZEW:
10160 check_mips_64(ctx);
10161 tcg_gen_ext32u_tl(cpu_gpr[rx], cpu_gpr[rx]);
10163 case RR_RY_CNVT_SEW:
10164 check_mips_64(ctx);
10165 tcg_gen_ext32s_tl(cpu_gpr[rx], cpu_gpr[rx]);
10169 generate_exception(ctx, EXCP_RI);
10174 gen_HILO(ctx, OPC_MFLO, rx);
10176 #if defined (TARGET_MIPS64)
10178 check_mips_64(ctx);
10179 gen_shift_imm(env, ctx, OPC_DSRA, ry, ry, sa);
10182 check_mips_64(ctx);
10183 gen_shift(env, ctx, OPC_DSLLV, ry, rx, ry);
10186 check_mips_64(ctx);
10187 gen_shift(env, ctx, OPC_DSRLV, ry, rx, ry);
10190 check_mips_64(ctx);
10191 gen_shift(env, ctx, OPC_DSRAV, ry, rx, ry);
10195 gen_muldiv(ctx, OPC_MULT, rx, ry);
10198 gen_muldiv(ctx, OPC_MULTU, rx, ry);
10201 gen_muldiv(ctx, OPC_DIV, rx, ry);
10204 gen_muldiv(ctx, OPC_DIVU, rx, ry);
10206 #if defined (TARGET_MIPS64)
10208 check_mips_64(ctx);
10209 gen_muldiv(ctx, OPC_DMULT, rx, ry);
10212 check_mips_64(ctx);
10213 gen_muldiv(ctx, OPC_DMULTU, rx, ry);
10216 check_mips_64(ctx);
10217 gen_muldiv(ctx, OPC_DDIV, rx, ry);
10220 check_mips_64(ctx);
10221 gen_muldiv(ctx, OPC_DDIVU, rx, ry);
10225 generate_exception(ctx, EXCP_RI);
10229 case M16_OPC_EXTEND:
10230 decode_extended_mips16_opc(env, ctx, is_branch);
10233 #if defined(TARGET_MIPS64)
10235 funct = (ctx->opcode >> 8) & 0x7;
10236 decode_i64_mips16(env, ctx, ry, funct, offset, 0);
10240 generate_exception(ctx, EXCP_RI);
10247 /* microMIPS extension to MIPS32 */
10249 /* microMIPS32 major opcodes */
10288 /* 0x20 is reserved */
10298 /* 0x28 and 0x29 are reserved */
10308 /* 0x30 and 0x31 are reserved */
10318 /* 0x38 and 0x39 are reserved */
10329 /* POOL32A encoding of minor opcode field */
10332 /* These opcodes are distinguished only by bits 9..6; those bits are
10333 * what are recorded below. */
10359 /* The following can be distinguished by their lower 6 bits. */
10365 /* POOL32AXF encoding of minor opcode field extension */
10379 /* bits 13..12 for 0x01 */
10385 /* bits 13..12 for 0x2a */
10391 /* bits 13..12 for 0x32 */
10395 /* bits 15..12 for 0x2c */
10411 /* bits 15..12 for 0x34 */
10419 /* bits 15..12 for 0x3c */
10421 JR = 0x0, /* alias */
10426 /* bits 15..12 for 0x05 */
10430 /* bits 15..12 for 0x0d */
10440 /* bits 15..12 for 0x15 */
10446 /* bits 15..12 for 0x1d */
10450 /* bits 15..12 for 0x2d */
10455 /* bits 15..12 for 0x35 */
10462 /* POOL32B encoding of minor opcode field (bits 15..12) */
10478 /* POOL32C encoding of minor opcode field (bits 15..12) */
10486 /* 0xa is reserved */
10493 /* 0x6 is reserved */
10499 /* POOL32F encoding of minor opcode field (bits 5..0) */
10502 /* These are the bit 7..6 values */
10513 /* These are the bit 8..6 values */
10557 CABS_COND_FMT = 0x1c, /* MIPS3D */
10561 /* POOL32Fxf encoding of minor opcode extension field */
10599 /* POOL32I encoding of minor opcode field (bits 25..21) */
10624 /* These overlap and are distinguished by bit16 of the instruction */
10633 /* POOL16A encoding of minor opcode field */
10640 /* POOL16B encoding of minor opcode field */
10647 /* POOL16C encoding of minor opcode field */
10667 /* POOL16D encoding of minor opcode field */
10674 /* POOL16E encoding of minor opcode field */
10681 static int mmreg (int r)
10683 static const int map[] = { 16, 17, 2, 3, 4, 5, 6, 7 };
10688 /* Used for 16-bit store instructions. */
10689 static int mmreg2 (int r)
10691 static const int map[] = { 0, 17, 2, 3, 4, 5, 6, 7 };
10696 #define uMIPS_RD(op) ((op >> 7) & 0x7)
10697 #define uMIPS_RS(op) ((op >> 4) & 0x7)
10698 #define uMIPS_RS2(op) uMIPS_RS(op)
10699 #define uMIPS_RS1(op) ((op >> 1) & 0x7)
10700 #define uMIPS_RD5(op) ((op >> 5) & 0x1f)
10701 #define uMIPS_RS5(op) (op & 0x1f)
10703 /* Signed immediate */
10704 #define SIMM(op, start, width) \
10705 ((int32_t)(((op >> start) & ((~0U) >> (32-width))) \
10708 /* Zero-extended immediate */
10709 #define ZIMM(op, start, width) ((op >> start) & ((~0U) >> (32-width)))
10711 static void gen_addiur1sp (CPUMIPSState *env, DisasContext *ctx)
10713 int rd = mmreg(uMIPS_RD(ctx->opcode));
10715 gen_arith_imm(env, ctx, OPC_ADDIU, rd, 29, ((ctx->opcode >> 1) & 0x3f) << 2);
10718 static void gen_addiur2 (CPUMIPSState *env, DisasContext *ctx)
10720 static const int decoded_imm[] = { 1, 4, 8, 12, 16, 20, 24, -1 };
10721 int rd = mmreg(uMIPS_RD(ctx->opcode));
10722 int rs = mmreg(uMIPS_RS(ctx->opcode));
10724 gen_arith_imm(env, ctx, OPC_ADDIU, rd, rs, decoded_imm[ZIMM(ctx->opcode, 1, 3)]);
10727 static void gen_addiusp (CPUMIPSState *env, DisasContext *ctx)
10729 int encoded = ZIMM(ctx->opcode, 1, 9);
10732 if (encoded <= 1) {
10733 decoded = 256 + encoded;
10734 } else if (encoded <= 255) {
10736 } else if (encoded <= 509) {
10737 decoded = encoded - 512;
10739 decoded = encoded - 768;
10742 gen_arith_imm(env, ctx, OPC_ADDIU, 29, 29, decoded << 2);
10745 static void gen_addius5 (CPUMIPSState *env, DisasContext *ctx)
10747 int imm = SIMM(ctx->opcode, 1, 4);
10748 int rd = (ctx->opcode >> 5) & 0x1f;
10750 gen_arith_imm(env, ctx, OPC_ADDIU, rd, rd, imm);
10753 static void gen_andi16 (CPUMIPSState *env, DisasContext *ctx)
10755 static const int decoded_imm[] = { 128, 1, 2, 3, 4, 7, 8, 15, 16,
10756 31, 32, 63, 64, 255, 32768, 65535 };
10757 int rd = mmreg(uMIPS_RD(ctx->opcode));
10758 int rs = mmreg(uMIPS_RS(ctx->opcode));
10759 int encoded = ZIMM(ctx->opcode, 0, 4);
10761 gen_logic_imm(env, ctx, OPC_ANDI, rd, rs, decoded_imm[encoded]);
10764 static void gen_ldst_multiple (DisasContext *ctx, uint32_t opc, int reglist,
10765 int base, int16_t offset)
10767 const char *opn = "ldst_multiple";
10771 if (ctx->hflags & MIPS_HFLAG_BMASK) {
10772 generate_exception(ctx, EXCP_RI);
10776 t0 = tcg_temp_new();
10778 gen_base_offset_addr(ctx, t0, base, offset);
10780 t1 = tcg_const_tl(reglist);
10781 t2 = tcg_const_i32(ctx->mem_idx);
10783 save_cpu_state(ctx, 1);
10786 gen_helper_lwm(cpu_env, t0, t1, t2);
10790 gen_helper_swm(cpu_env, t0, t1, t2);
10793 #ifdef TARGET_MIPS64
10795 gen_helper_ldm(cpu_env, t0, t1, t2);
10799 gen_helper_sdm(cpu_env, t0, t1, t2);
10805 MIPS_DEBUG("%s, %x, %d(%s)", opn, reglist, offset, regnames[base]);
10808 tcg_temp_free_i32(t2);
10812 static void gen_pool16c_insn (CPUMIPSState *env, DisasContext *ctx, int *is_branch)
10814 int rd = mmreg((ctx->opcode >> 3) & 0x7);
10815 int rs = mmreg(ctx->opcode & 0x7);
10818 switch (((ctx->opcode) >> 4) & 0x3f) {
10823 gen_logic(env, ctx, OPC_NOR, rd, rs, 0);
10829 gen_logic(env, ctx, OPC_XOR, rd, rd, rs);
10835 gen_logic(env, ctx, OPC_AND, rd, rd, rs);
10841 gen_logic(env, ctx, OPC_OR, rd, rd, rs);
10848 static const int lwm_convert[] = { 0x11, 0x12, 0x13, 0x14 };
10849 int offset = ZIMM(ctx->opcode, 0, 4);
10851 gen_ldst_multiple(ctx, LWM32, lwm_convert[(ctx->opcode >> 4) & 0x3],
10860 static const int swm_convert[] = { 0x11, 0x12, 0x13, 0x14 };
10861 int offset = ZIMM(ctx->opcode, 0, 4);
10863 gen_ldst_multiple(ctx, SWM32, swm_convert[(ctx->opcode >> 4) & 0x3],
10870 int reg = ctx->opcode & 0x1f;
10872 gen_compute_branch(ctx, OPC_JR, 2, reg, 0, 0);
10879 int reg = ctx->opcode & 0x1f;
10881 gen_compute_branch(ctx, OPC_JR, 2, reg, 0, 0);
10882 /* Let normal delay slot handling in our caller take us
10883 to the branch target. */
10895 int reg = ctx->opcode & 0x1f;
10897 gen_compute_branch(ctx, opc, 2, reg, 31, 0);
10903 gen_HILO(ctx, OPC_MFHI, uMIPS_RS5(ctx->opcode));
10907 gen_HILO(ctx, OPC_MFLO, uMIPS_RS5(ctx->opcode));
10910 generate_exception(ctx, EXCP_BREAK);
10913 /* XXX: not clear which exception should be raised
10914 * when in debug mode...
10916 check_insn(env, ctx, ISA_MIPS32);
10917 if (!(ctx->hflags & MIPS_HFLAG_DM)) {
10918 generate_exception(ctx, EXCP_DBp);
10920 generate_exception(ctx, EXCP_DBp);
10923 case JRADDIUSP + 0:
10924 case JRADDIUSP + 1:
10926 int imm = ZIMM(ctx->opcode, 0, 5);
10928 gen_compute_branch(ctx, OPC_JR, 2, 31, 0, 0);
10929 gen_arith_imm(env, ctx, OPC_ADDIU, 29, 29, imm << 2);
10930 /* Let normal delay slot handling in our caller take us
10931 to the branch target. */
10935 generate_exception(ctx, EXCP_RI);
10940 static void gen_ldxs (DisasContext *ctx, int base, int index, int rd)
10942 TCGv t0 = tcg_temp_new();
10943 TCGv t1 = tcg_temp_new();
10945 gen_load_gpr(t0, base);
10948 gen_load_gpr(t1, index);
10949 tcg_gen_shli_tl(t1, t1, 2);
10950 gen_op_addr_add(ctx, t0, t1, t0);
10953 op_ld_lw(t1, t0, ctx);
10954 gen_store_gpr(t1, rd);
10960 static void gen_ldst_pair (DisasContext *ctx, uint32_t opc, int rd,
10961 int base, int16_t offset)
10963 const char *opn = "ldst_pair";
10966 if (ctx->hflags & MIPS_HFLAG_BMASK || rd == 31) {
10967 generate_exception(ctx, EXCP_RI);
10971 t0 = tcg_temp_new();
10972 t1 = tcg_temp_new();
10974 gen_base_offset_addr(ctx, t0, base, offset);
10979 generate_exception(ctx, EXCP_RI);
10982 op_ld_lw(t1, t0, ctx);
10983 gen_store_gpr(t1, rd);
10984 tcg_gen_movi_tl(t1, 4);
10985 gen_op_addr_add(ctx, t0, t0, t1);
10986 op_ld_lw(t1, t0, ctx);
10987 gen_store_gpr(t1, rd+1);
10991 gen_load_gpr(t1, rd);
10992 op_st_sw(t1, t0, ctx);
10993 tcg_gen_movi_tl(t1, 4);
10994 gen_op_addr_add(ctx, t0, t0, t1);
10995 gen_load_gpr(t1, rd+1);
10996 op_st_sw(t1, t0, ctx);
10999 #ifdef TARGET_MIPS64
11002 generate_exception(ctx, EXCP_RI);
11005 op_ld_ld(t1, t0, ctx);
11006 gen_store_gpr(t1, rd);
11007 tcg_gen_movi_tl(t1, 8);
11008 gen_op_addr_add(ctx, t0, t0, t1);
11009 op_ld_ld(t1, t0, ctx);
11010 gen_store_gpr(t1, rd+1);
11014 gen_load_gpr(t1, rd);
11015 op_st_sd(t1, t0, ctx);
11016 tcg_gen_movi_tl(t1, 8);
11017 gen_op_addr_add(ctx, t0, t0, t1);
11018 gen_load_gpr(t1, rd+1);
11019 op_st_sd(t1, t0, ctx);
11024 (void)opn; /* avoid a compiler warning */
11025 MIPS_DEBUG("%s, %s, %d(%s)", opn, regnames[rd], offset, regnames[base]);
11030 static void gen_pool32axf (CPUMIPSState *env, DisasContext *ctx, int rt, int rs,
11033 int extension = (ctx->opcode >> 6) & 0x3f;
11034 int minor = (ctx->opcode >> 12) & 0xf;
11035 uint32_t mips32_op;
11037 switch (extension) {
11039 mips32_op = OPC_TEQ;
11042 mips32_op = OPC_TGE;
11045 mips32_op = OPC_TGEU;
11048 mips32_op = OPC_TLT;
11051 mips32_op = OPC_TLTU;
11054 mips32_op = OPC_TNE;
11056 gen_trap(ctx, mips32_op, rs, rt, -1);
11058 #ifndef CONFIG_USER_ONLY
11061 check_cp0_enabled(ctx);
11063 /* Treat as NOP. */
11066 gen_mfc0(env, ctx, cpu_gpr[rt], rs, (ctx->opcode >> 11) & 0x7);
11070 check_cp0_enabled(ctx);
11072 TCGv t0 = tcg_temp_new();
11074 gen_load_gpr(t0, rt);
11075 gen_mtc0(env, ctx, t0, rs, (ctx->opcode >> 11) & 0x7);
11083 gen_bshfl(ctx, OPC_SEB, rs, rt);
11086 gen_bshfl(ctx, OPC_SEH, rs, rt);
11089 mips32_op = OPC_CLO;
11092 mips32_op = OPC_CLZ;
11094 check_insn(env, ctx, ISA_MIPS32);
11095 gen_cl(ctx, mips32_op, rt, rs);
11098 gen_rdhwr(env, ctx, rt, rs);
11101 gen_bshfl(ctx, OPC_WSBH, rs, rt);
11104 mips32_op = OPC_MULT;
11107 mips32_op = OPC_MULTU;
11110 mips32_op = OPC_DIV;
11113 mips32_op = OPC_DIVU;
11116 mips32_op = OPC_MADD;
11119 mips32_op = OPC_MADDU;
11122 mips32_op = OPC_MSUB;
11125 mips32_op = OPC_MSUBU;
11127 check_insn(env, ctx, ISA_MIPS32);
11128 gen_muldiv(ctx, mips32_op, rs, rt);
11131 goto pool32axf_invalid;
11142 generate_exception_err(ctx, EXCP_CpU, 2);
11145 goto pool32axf_invalid;
11152 gen_compute_branch (ctx, OPC_JALR, 4, rs, rt, 0);
11157 gen_compute_branch (ctx, OPC_JALRS, 4, rs, rt, 0);
11161 goto pool32axf_invalid;
11167 check_cp0_enabled(ctx);
11168 check_insn(env, ctx, ISA_MIPS32R2);
11169 gen_load_srsgpr(rt, rs);
11172 check_cp0_enabled(ctx);
11173 check_insn(env, ctx, ISA_MIPS32R2);
11174 gen_store_srsgpr(rt, rs);
11177 goto pool32axf_invalid;
11180 #ifndef CONFIG_USER_ONLY
11184 mips32_op = OPC_TLBP;
11187 mips32_op = OPC_TLBR;
11190 mips32_op = OPC_TLBWI;
11193 mips32_op = OPC_TLBWR;
11196 mips32_op = OPC_WAIT;
11199 mips32_op = OPC_DERET;
11202 mips32_op = OPC_ERET;
11204 gen_cp0(env, ctx, mips32_op, rt, rs);
11207 goto pool32axf_invalid;
11213 check_cp0_enabled(ctx);
11215 TCGv t0 = tcg_temp_new();
11217 save_cpu_state(ctx, 1);
11218 gen_helper_di(t0, cpu_env);
11219 gen_store_gpr(t0, rs);
11220 /* Stop translation as we may have switched the execution mode */
11221 ctx->bstate = BS_STOP;
11226 check_cp0_enabled(ctx);
11228 TCGv t0 = tcg_temp_new();
11230 save_cpu_state(ctx, 1);
11231 gen_helper_ei(t0, cpu_env);
11232 gen_store_gpr(t0, rs);
11233 /* Stop translation as we may have switched the execution mode */
11234 ctx->bstate = BS_STOP;
11239 goto pool32axf_invalid;
11249 generate_exception(ctx, EXCP_SYSCALL);
11250 ctx->bstate = BS_STOP;
11253 check_insn(env, ctx, ISA_MIPS32);
11254 if (!(ctx->hflags & MIPS_HFLAG_DM)) {
11255 generate_exception(ctx, EXCP_DBp);
11257 generate_exception(ctx, EXCP_DBp);
11261 goto pool32axf_invalid;
11267 gen_HILO(ctx, OPC_MFHI, rs);
11270 gen_HILO(ctx, OPC_MFLO, rs);
11273 gen_HILO(ctx, OPC_MTHI, rs);
11276 gen_HILO(ctx, OPC_MTLO, rs);
11279 goto pool32axf_invalid;
11284 MIPS_INVAL("pool32axf");
11285 generate_exception(ctx, EXCP_RI);
11290 /* Values for microMIPS fmt field. Variable-width, depending on which
11291 formats the instruction supports. */
11310 static void gen_pool32fxf (CPUMIPSState *env, DisasContext *ctx, int rt, int rs)
11312 int extension = (ctx->opcode >> 6) & 0x3ff;
11313 uint32_t mips32_op;
11315 #define FLOAT_1BIT_FMT(opc, fmt) (fmt << 8) | opc
11316 #define FLOAT_2BIT_FMT(opc, fmt) (fmt << 7) | opc
11317 #define COND_FLOAT_MOV(opc, cond) (cond << 7) | opc
11319 switch (extension) {
11320 case FLOAT_1BIT_FMT(CFC1, 0):
11321 mips32_op = OPC_CFC1;
11323 case FLOAT_1BIT_FMT(CTC1, 0):
11324 mips32_op = OPC_CTC1;
11326 case FLOAT_1BIT_FMT(MFC1, 0):
11327 mips32_op = OPC_MFC1;
11329 case FLOAT_1BIT_FMT(MTC1, 0):
11330 mips32_op = OPC_MTC1;
11332 case FLOAT_1BIT_FMT(MFHC1, 0):
11333 mips32_op = OPC_MFHC1;
11335 case FLOAT_1BIT_FMT(MTHC1, 0):
11336 mips32_op = OPC_MTHC1;
11338 gen_cp1(ctx, mips32_op, rt, rs);
11341 /* Reciprocal square root */
11342 case FLOAT_1BIT_FMT(RSQRT_FMT, FMT_SD_S):
11343 mips32_op = OPC_RSQRT_S;
11345 case FLOAT_1BIT_FMT(RSQRT_FMT, FMT_SD_D):
11346 mips32_op = OPC_RSQRT_D;
11350 case FLOAT_1BIT_FMT(SQRT_FMT, FMT_SD_S):
11351 mips32_op = OPC_SQRT_S;
11353 case FLOAT_1BIT_FMT(SQRT_FMT, FMT_SD_D):
11354 mips32_op = OPC_SQRT_D;
11358 case FLOAT_1BIT_FMT(RECIP_FMT, FMT_SD_S):
11359 mips32_op = OPC_RECIP_S;
11361 case FLOAT_1BIT_FMT(RECIP_FMT, FMT_SD_D):
11362 mips32_op = OPC_RECIP_D;
11366 case FLOAT_1BIT_FMT(FLOOR_L, FMT_SD_S):
11367 mips32_op = OPC_FLOOR_L_S;
11369 case FLOAT_1BIT_FMT(FLOOR_L, FMT_SD_D):
11370 mips32_op = OPC_FLOOR_L_D;
11372 case FLOAT_1BIT_FMT(FLOOR_W, FMT_SD_S):
11373 mips32_op = OPC_FLOOR_W_S;
11375 case FLOAT_1BIT_FMT(FLOOR_W, FMT_SD_D):
11376 mips32_op = OPC_FLOOR_W_D;
11380 case FLOAT_1BIT_FMT(CEIL_L, FMT_SD_S):
11381 mips32_op = OPC_CEIL_L_S;
11383 case FLOAT_1BIT_FMT(CEIL_L, FMT_SD_D):
11384 mips32_op = OPC_CEIL_L_D;
11386 case FLOAT_1BIT_FMT(CEIL_W, FMT_SD_S):
11387 mips32_op = OPC_CEIL_W_S;
11389 case FLOAT_1BIT_FMT(CEIL_W, FMT_SD_D):
11390 mips32_op = OPC_CEIL_W_D;
11394 case FLOAT_1BIT_FMT(TRUNC_L, FMT_SD_S):
11395 mips32_op = OPC_TRUNC_L_S;
11397 case FLOAT_1BIT_FMT(TRUNC_L, FMT_SD_D):
11398 mips32_op = OPC_TRUNC_L_D;
11400 case FLOAT_1BIT_FMT(TRUNC_W, FMT_SD_S):
11401 mips32_op = OPC_TRUNC_W_S;
11403 case FLOAT_1BIT_FMT(TRUNC_W, FMT_SD_D):
11404 mips32_op = OPC_TRUNC_W_D;
11408 case FLOAT_1BIT_FMT(ROUND_L, FMT_SD_S):
11409 mips32_op = OPC_ROUND_L_S;
11411 case FLOAT_1BIT_FMT(ROUND_L, FMT_SD_D):
11412 mips32_op = OPC_ROUND_L_D;
11414 case FLOAT_1BIT_FMT(ROUND_W, FMT_SD_S):
11415 mips32_op = OPC_ROUND_W_S;
11417 case FLOAT_1BIT_FMT(ROUND_W, FMT_SD_D):
11418 mips32_op = OPC_ROUND_W_D;
11421 /* Integer to floating-point conversion */
11422 case FLOAT_1BIT_FMT(CVT_L, FMT_SD_S):
11423 mips32_op = OPC_CVT_L_S;
11425 case FLOAT_1BIT_FMT(CVT_L, FMT_SD_D):
11426 mips32_op = OPC_CVT_L_D;
11428 case FLOAT_1BIT_FMT(CVT_W, FMT_SD_S):
11429 mips32_op = OPC_CVT_W_S;
11431 case FLOAT_1BIT_FMT(CVT_W, FMT_SD_D):
11432 mips32_op = OPC_CVT_W_D;
11435 /* Paired-foo conversions */
11436 case FLOAT_1BIT_FMT(CVT_S_PL, 0):
11437 mips32_op = OPC_CVT_S_PL;
11439 case FLOAT_1BIT_FMT(CVT_S_PU, 0):
11440 mips32_op = OPC_CVT_S_PU;
11442 case FLOAT_1BIT_FMT(CVT_PW_PS, 0):
11443 mips32_op = OPC_CVT_PW_PS;
11445 case FLOAT_1BIT_FMT(CVT_PS_PW, 0):
11446 mips32_op = OPC_CVT_PS_PW;
11449 /* Floating-point moves */
11450 case FLOAT_2BIT_FMT(MOV_FMT, FMT_SDPS_S):
11451 mips32_op = OPC_MOV_S;
11453 case FLOAT_2BIT_FMT(MOV_FMT, FMT_SDPS_D):
11454 mips32_op = OPC_MOV_D;
11456 case FLOAT_2BIT_FMT(MOV_FMT, FMT_SDPS_PS):
11457 mips32_op = OPC_MOV_PS;
11460 /* Absolute value */
11461 case FLOAT_2BIT_FMT(ABS_FMT, FMT_SDPS_S):
11462 mips32_op = OPC_ABS_S;
11464 case FLOAT_2BIT_FMT(ABS_FMT, FMT_SDPS_D):
11465 mips32_op = OPC_ABS_D;
11467 case FLOAT_2BIT_FMT(ABS_FMT, FMT_SDPS_PS):
11468 mips32_op = OPC_ABS_PS;
11472 case FLOAT_2BIT_FMT(NEG_FMT, FMT_SDPS_S):
11473 mips32_op = OPC_NEG_S;
11475 case FLOAT_2BIT_FMT(NEG_FMT, FMT_SDPS_D):
11476 mips32_op = OPC_NEG_D;
11478 case FLOAT_2BIT_FMT(NEG_FMT, FMT_SDPS_PS):
11479 mips32_op = OPC_NEG_PS;
11482 /* Reciprocal square root step */
11483 case FLOAT_2BIT_FMT(RSQRT1_FMT, FMT_SDPS_S):
11484 mips32_op = OPC_RSQRT1_S;
11486 case FLOAT_2BIT_FMT(RSQRT1_FMT, FMT_SDPS_D):
11487 mips32_op = OPC_RSQRT1_D;
11489 case FLOAT_2BIT_FMT(RSQRT1_FMT, FMT_SDPS_PS):
11490 mips32_op = OPC_RSQRT1_PS;
11493 /* Reciprocal step */
11494 case FLOAT_2BIT_FMT(RECIP1_FMT, FMT_SDPS_S):
11495 mips32_op = OPC_RECIP1_S;
11497 case FLOAT_2BIT_FMT(RECIP1_FMT, FMT_SDPS_D):
11498 mips32_op = OPC_RECIP1_S;
11500 case FLOAT_2BIT_FMT(RECIP1_FMT, FMT_SDPS_PS):
11501 mips32_op = OPC_RECIP1_PS;
11504 /* Conversions from double */
11505 case FLOAT_2BIT_FMT(CVT_D, FMT_SWL_S):
11506 mips32_op = OPC_CVT_D_S;
11508 case FLOAT_2BIT_FMT(CVT_D, FMT_SWL_W):
11509 mips32_op = OPC_CVT_D_W;
11511 case FLOAT_2BIT_FMT(CVT_D, FMT_SWL_L):
11512 mips32_op = OPC_CVT_D_L;
11515 /* Conversions from single */
11516 case FLOAT_2BIT_FMT(CVT_S, FMT_DWL_D):
11517 mips32_op = OPC_CVT_S_D;
11519 case FLOAT_2BIT_FMT(CVT_S, FMT_DWL_W):
11520 mips32_op = OPC_CVT_S_W;
11522 case FLOAT_2BIT_FMT(CVT_S, FMT_DWL_L):
11523 mips32_op = OPC_CVT_S_L;
11525 gen_farith(ctx, mips32_op, -1, rs, rt, 0);
11528 /* Conditional moves on floating-point codes */
11529 case COND_FLOAT_MOV(MOVT, 0):
11530 case COND_FLOAT_MOV(MOVT, 1):
11531 case COND_FLOAT_MOV(MOVT, 2):
11532 case COND_FLOAT_MOV(MOVT, 3):
11533 case COND_FLOAT_MOV(MOVT, 4):
11534 case COND_FLOAT_MOV(MOVT, 5):
11535 case COND_FLOAT_MOV(MOVT, 6):
11536 case COND_FLOAT_MOV(MOVT, 7):
11537 gen_movci(ctx, rt, rs, (ctx->opcode >> 13) & 0x7, 1);
11539 case COND_FLOAT_MOV(MOVF, 0):
11540 case COND_FLOAT_MOV(MOVF, 1):
11541 case COND_FLOAT_MOV(MOVF, 2):
11542 case COND_FLOAT_MOV(MOVF, 3):
11543 case COND_FLOAT_MOV(MOVF, 4):
11544 case COND_FLOAT_MOV(MOVF, 5):
11545 case COND_FLOAT_MOV(MOVF, 6):
11546 case COND_FLOAT_MOV(MOVF, 7):
11547 gen_movci(ctx, rt, rs, (ctx->opcode >> 13) & 0x7, 0);
11550 MIPS_INVAL("pool32fxf");
11551 generate_exception(ctx, EXCP_RI);
11556 static void decode_micromips32_opc (CPUMIPSState *env, DisasContext *ctx,
11557 uint16_t insn_hw1, int *is_branch)
11561 int rt, rs, rd, rr;
11563 uint32_t op, minor, mips32_op;
11564 uint32_t cond, fmt, cc;
11566 insn = cpu_lduw_code(env, ctx->pc + 2);
11567 ctx->opcode = (ctx->opcode << 16) | insn;
11569 rt = (ctx->opcode >> 21) & 0x1f;
11570 rs = (ctx->opcode >> 16) & 0x1f;
11571 rd = (ctx->opcode >> 11) & 0x1f;
11572 rr = (ctx->opcode >> 6) & 0x1f;
11573 imm = (int16_t) ctx->opcode;
11575 op = (ctx->opcode >> 26) & 0x3f;
11578 minor = ctx->opcode & 0x3f;
11581 minor = (ctx->opcode >> 6) & 0xf;
11584 mips32_op = OPC_SLL;
11587 mips32_op = OPC_SRA;
11590 mips32_op = OPC_SRL;
11593 mips32_op = OPC_ROTR;
11595 gen_shift_imm(env, ctx, mips32_op, rt, rs, rd);
11598 goto pool32a_invalid;
11602 minor = (ctx->opcode >> 6) & 0xf;
11606 mips32_op = OPC_ADD;
11609 mips32_op = OPC_ADDU;
11612 mips32_op = OPC_SUB;
11615 mips32_op = OPC_SUBU;
11618 mips32_op = OPC_MUL;
11620 gen_arith(env, ctx, mips32_op, rd, rs, rt);
11624 mips32_op = OPC_SLLV;
11627 mips32_op = OPC_SRLV;
11630 mips32_op = OPC_SRAV;
11633 mips32_op = OPC_ROTRV;
11635 gen_shift(env, ctx, mips32_op, rd, rs, rt);
11637 /* Logical operations */
11639 mips32_op = OPC_AND;
11642 mips32_op = OPC_OR;
11645 mips32_op = OPC_NOR;
11648 mips32_op = OPC_XOR;
11650 gen_logic(env, ctx, mips32_op, rd, rs, rt);
11652 /* Set less than */
11654 mips32_op = OPC_SLT;
11657 mips32_op = OPC_SLTU;
11659 gen_slt(env, ctx, mips32_op, rd, rs, rt);
11662 goto pool32a_invalid;
11666 minor = (ctx->opcode >> 6) & 0xf;
11668 /* Conditional moves */
11670 mips32_op = OPC_MOVN;
11673 mips32_op = OPC_MOVZ;
11675 gen_cond_move(env, ctx, mips32_op, rd, rs, rt);
11678 gen_ldxs(ctx, rs, rt, rd);
11681 goto pool32a_invalid;
11685 gen_bitops(ctx, OPC_INS, rt, rs, rr, rd);
11688 gen_bitops(ctx, OPC_EXT, rt, rs, rr, rd);
11691 gen_pool32axf(env, ctx, rt, rs, is_branch);
11694 generate_exception(ctx, EXCP_BREAK);
11698 MIPS_INVAL("pool32a");
11699 generate_exception(ctx, EXCP_RI);
11704 minor = (ctx->opcode >> 12) & 0xf;
11707 check_cp0_enabled(ctx);
11708 /* Treat as no-op. */
11712 /* COP2: Not implemented. */
11713 generate_exception_err(ctx, EXCP_CpU, 2);
11717 #ifdef TARGET_MIPS64
11721 gen_ldst_pair(ctx, minor, rt, rs, SIMM(ctx->opcode, 0, 12));
11725 #ifdef TARGET_MIPS64
11729 gen_ldst_multiple(ctx, minor, rt, rs, SIMM(ctx->opcode, 0, 12));
11732 MIPS_INVAL("pool32b");
11733 generate_exception(ctx, EXCP_RI);
11738 if (env->CP0_Config1 & (1 << CP0C1_FP)) {
11739 minor = ctx->opcode & 0x3f;
11740 check_cp1_enabled(ctx);
11743 mips32_op = OPC_ALNV_PS;
11746 mips32_op = OPC_MADD_S;
11749 mips32_op = OPC_MADD_D;
11752 mips32_op = OPC_MADD_PS;
11755 mips32_op = OPC_MSUB_S;
11758 mips32_op = OPC_MSUB_D;
11761 mips32_op = OPC_MSUB_PS;
11764 mips32_op = OPC_NMADD_S;
11767 mips32_op = OPC_NMADD_D;
11770 mips32_op = OPC_NMADD_PS;
11773 mips32_op = OPC_NMSUB_S;
11776 mips32_op = OPC_NMSUB_D;
11779 mips32_op = OPC_NMSUB_PS;
11781 gen_flt3_arith(ctx, mips32_op, rd, rr, rs, rt);
11783 case CABS_COND_FMT:
11784 cond = (ctx->opcode >> 6) & 0xf;
11785 cc = (ctx->opcode >> 13) & 0x7;
11786 fmt = (ctx->opcode >> 10) & 0x3;
11789 gen_cmpabs_s(ctx, cond, rt, rs, cc);
11792 gen_cmpabs_d(ctx, cond, rt, rs, cc);
11795 gen_cmpabs_ps(ctx, cond, rt, rs, cc);
11798 goto pool32f_invalid;
11802 cond = (ctx->opcode >> 6) & 0xf;
11803 cc = (ctx->opcode >> 13) & 0x7;
11804 fmt = (ctx->opcode >> 10) & 0x3;
11807 gen_cmp_s(ctx, cond, rt, rs, cc);
11810 gen_cmp_d(ctx, cond, rt, rs, cc);
11813 gen_cmp_ps(ctx, cond, rt, rs, cc);
11816 goto pool32f_invalid;
11820 gen_pool32fxf(env, ctx, rt, rs);
11824 switch ((ctx->opcode >> 6) & 0x7) {
11826 mips32_op = OPC_PLL_PS;
11829 mips32_op = OPC_PLU_PS;
11832 mips32_op = OPC_PUL_PS;
11835 mips32_op = OPC_PUU_PS;
11838 mips32_op = OPC_CVT_PS_S;
11840 gen_farith(ctx, mips32_op, rt, rs, rd, 0);
11843 goto pool32f_invalid;
11848 switch ((ctx->opcode >> 6) & 0x7) {
11850 mips32_op = OPC_LWXC1;
11853 mips32_op = OPC_SWXC1;
11856 mips32_op = OPC_LDXC1;
11859 mips32_op = OPC_SDXC1;
11862 mips32_op = OPC_LUXC1;
11865 mips32_op = OPC_SUXC1;
11867 gen_flt3_ldst(ctx, mips32_op, rd, rd, rt, rs);
11870 goto pool32f_invalid;
11875 fmt = (ctx->opcode >> 9) & 0x3;
11876 switch ((ctx->opcode >> 6) & 0x7) {
11880 mips32_op = OPC_RSQRT2_S;
11883 mips32_op = OPC_RSQRT2_D;
11886 mips32_op = OPC_RSQRT2_PS;
11889 goto pool32f_invalid;
11895 mips32_op = OPC_RECIP2_S;
11898 mips32_op = OPC_RECIP2_D;
11901 mips32_op = OPC_RECIP2_PS;
11904 goto pool32f_invalid;
11908 mips32_op = OPC_ADDR_PS;
11911 mips32_op = OPC_MULR_PS;
11913 gen_farith(ctx, mips32_op, rt, rs, rd, 0);
11916 goto pool32f_invalid;
11920 /* MOV[FT].fmt and PREFX */
11921 cc = (ctx->opcode >> 13) & 0x7;
11922 fmt = (ctx->opcode >> 9) & 0x3;
11923 switch ((ctx->opcode >> 6) & 0x7) {
11927 gen_movcf_s(rs, rt, cc, 0);
11930 gen_movcf_d(ctx, rs, rt, cc, 0);
11933 gen_movcf_ps(rs, rt, cc, 0);
11936 goto pool32f_invalid;
11942 gen_movcf_s(rs, rt, cc, 1);
11945 gen_movcf_d(ctx, rs, rt, cc, 1);
11948 gen_movcf_ps(rs, rt, cc, 1);
11951 goto pool32f_invalid;
11957 goto pool32f_invalid;
11960 #define FINSN_3ARG_SDPS(prfx) \
11961 switch ((ctx->opcode >> 8) & 0x3) { \
11963 mips32_op = OPC_##prfx##_S; \
11966 mips32_op = OPC_##prfx##_D; \
11968 case FMT_SDPS_PS: \
11969 mips32_op = OPC_##prfx##_PS; \
11972 goto pool32f_invalid; \
11975 /* regular FP ops */
11976 switch ((ctx->opcode >> 6) & 0x3) {
11978 FINSN_3ARG_SDPS(ADD);
11981 FINSN_3ARG_SDPS(SUB);
11984 FINSN_3ARG_SDPS(MUL);
11987 fmt = (ctx->opcode >> 8) & 0x3;
11989 mips32_op = OPC_DIV_D;
11990 } else if (fmt == 0) {
11991 mips32_op = OPC_DIV_S;
11993 goto pool32f_invalid;
11997 goto pool32f_invalid;
12002 switch ((ctx->opcode >> 6) & 0x3) {
12004 FINSN_3ARG_SDPS(MOVN);
12007 FINSN_3ARG_SDPS(MOVZ);
12010 goto pool32f_invalid;
12014 gen_farith(ctx, mips32_op, rt, rs, rd, 0);
12018 MIPS_INVAL("pool32f");
12019 generate_exception(ctx, EXCP_RI);
12023 generate_exception_err(ctx, EXCP_CpU, 1);
12027 minor = (ctx->opcode >> 21) & 0x1f;
12030 mips32_op = OPC_BLTZ;
12033 mips32_op = OPC_BLTZAL;
12036 mips32_op = OPC_BLTZALS;
12039 mips32_op = OPC_BGEZ;
12042 mips32_op = OPC_BGEZAL;
12045 mips32_op = OPC_BGEZALS;
12048 mips32_op = OPC_BLEZ;
12051 mips32_op = OPC_BGTZ;
12053 gen_compute_branch(ctx, mips32_op, 4, rs, -1, imm << 1);
12059 mips32_op = OPC_TLTI;
12062 mips32_op = OPC_TGEI;
12065 mips32_op = OPC_TLTIU;
12068 mips32_op = OPC_TGEIU;
12071 mips32_op = OPC_TNEI;
12074 mips32_op = OPC_TEQI;
12076 gen_trap(ctx, mips32_op, rs, -1, imm);
12081 gen_compute_branch(ctx, minor == BNEZC ? OPC_BNE : OPC_BEQ,
12082 4, rs, 0, imm << 1);
12083 /* Compact branches don't have a delay slot, so just let
12084 the normal delay slot handling take us to the branch
12088 gen_logic_imm(env, ctx, OPC_LUI, rs, -1, imm);
12094 /* COP2: Not implemented. */
12095 generate_exception_err(ctx, EXCP_CpU, 2);
12098 mips32_op = (ctx->opcode & (1 << 16)) ? OPC_BC1FANY2 : OPC_BC1F;
12101 mips32_op = (ctx->opcode & (1 << 16)) ? OPC_BC1TANY2 : OPC_BC1T;
12104 mips32_op = OPC_BC1FANY4;
12107 mips32_op = OPC_BC1TANY4;
12110 check_insn(env, ctx, ASE_MIPS3D);
12113 gen_compute_branch1(env, ctx, mips32_op,
12114 (ctx->opcode >> 18) & 0x7, imm << 1);
12119 /* MIPS DSP: not implemented */
12122 MIPS_INVAL("pool32i");
12123 generate_exception(ctx, EXCP_RI);
12128 minor = (ctx->opcode >> 12) & 0xf;
12131 mips32_op = OPC_LWL;
12134 mips32_op = OPC_SWL;
12137 mips32_op = OPC_LWR;
12140 mips32_op = OPC_SWR;
12142 #if defined(TARGET_MIPS64)
12144 mips32_op = OPC_LDL;
12147 mips32_op = OPC_SDL;
12150 mips32_op = OPC_LDR;
12153 mips32_op = OPC_SDR;
12156 mips32_op = OPC_LWU;
12159 mips32_op = OPC_LLD;
12163 mips32_op = OPC_LL;
12166 gen_ld(env, ctx, mips32_op, rt, rs, SIMM(ctx->opcode, 0, 12));
12169 gen_st(ctx, mips32_op, rt, rs, SIMM(ctx->opcode, 0, 12));
12172 gen_st_cond(ctx, OPC_SC, rt, rs, SIMM(ctx->opcode, 0, 12));
12174 #if defined(TARGET_MIPS64)
12176 gen_st_cond(ctx, OPC_SCD, rt, rs, SIMM(ctx->opcode, 0, 12));
12180 /* Treat as no-op */
12183 MIPS_INVAL("pool32c");
12184 generate_exception(ctx, EXCP_RI);
12189 mips32_op = OPC_ADDI;
12192 mips32_op = OPC_ADDIU;
12194 gen_arith_imm(env, ctx, mips32_op, rt, rs, imm);
12197 /* Logical operations */
12199 mips32_op = OPC_ORI;
12202 mips32_op = OPC_XORI;
12205 mips32_op = OPC_ANDI;
12207 gen_logic_imm(env, ctx, mips32_op, rt, rs, imm);
12210 /* Set less than immediate */
12212 mips32_op = OPC_SLTI;
12215 mips32_op = OPC_SLTIU;
12217 gen_slt_imm(env, ctx, mips32_op, rt, rs, imm);
12220 offset = (int32_t)(ctx->opcode & 0x3FFFFFF) << 2;
12221 gen_compute_branch(ctx, OPC_JALX, 4, rt, rs, offset);
12225 offset = (int32_t)(ctx->opcode & 0x3FFFFFF) << 1;
12226 gen_compute_branch(ctx, OPC_JALS, 4, rt, rs, offset);
12230 gen_compute_branch(ctx, OPC_BEQ, 4, rt, rs, imm << 1);
12234 gen_compute_branch(ctx, OPC_BNE, 4, rt, rs, imm << 1);
12238 gen_compute_branch(ctx, OPC_J, 4, rt, rs,
12239 (int32_t)(ctx->opcode & 0x3FFFFFF) << 1);
12243 gen_compute_branch(ctx, OPC_JAL, 4, rt, rs,
12244 (int32_t)(ctx->opcode & 0x3FFFFFF) << 1);
12247 /* Floating point (COP1) */
12249 mips32_op = OPC_LWC1;
12252 mips32_op = OPC_LDC1;
12255 mips32_op = OPC_SWC1;
12258 mips32_op = OPC_SDC1;
12260 gen_cop1_ldst(env, ctx, mips32_op, rt, rs, imm);
12264 int reg = mmreg(ZIMM(ctx->opcode, 23, 3));
12265 int offset = SIMM(ctx->opcode, 0, 23) << 2;
12267 gen_addiupc(ctx, reg, offset, 0, 0);
12270 /* Loads and stores */
12272 mips32_op = OPC_LB;
12275 mips32_op = OPC_LBU;
12278 mips32_op = OPC_LH;
12281 mips32_op = OPC_LHU;
12284 mips32_op = OPC_LW;
12286 #ifdef TARGET_MIPS64
12288 mips32_op = OPC_LD;
12291 mips32_op = OPC_SD;
12295 mips32_op = OPC_SB;
12298 mips32_op = OPC_SH;
12301 mips32_op = OPC_SW;
12304 gen_ld(env, ctx, mips32_op, rt, rs, imm);
12307 gen_st(ctx, mips32_op, rt, rs, imm);
12310 generate_exception(ctx, EXCP_RI);
12315 static int decode_micromips_opc (CPUMIPSState *env, DisasContext *ctx, int *is_branch)
12319 /* make sure instructions are on a halfword boundary */
12320 if (ctx->pc & 0x1) {
12321 env->CP0_BadVAddr = ctx->pc;
12322 generate_exception(ctx, EXCP_AdEL);
12323 ctx->bstate = BS_STOP;
12327 op = (ctx->opcode >> 10) & 0x3f;
12328 /* Enforce properly-sized instructions in a delay slot */
12329 if (ctx->hflags & MIPS_HFLAG_BMASK) {
12330 int bits = ctx->hflags & MIPS_HFLAG_BMASK_EXT;
12364 case POOL48A: /* ??? */
12369 if (bits & MIPS_HFLAG_BDS16) {
12370 generate_exception(ctx, EXCP_RI);
12371 /* Just stop translation; the user is confused. */
12372 ctx->bstate = BS_STOP;
12397 if (bits & MIPS_HFLAG_BDS32) {
12398 generate_exception(ctx, EXCP_RI);
12399 /* Just stop translation; the user is confused. */
12400 ctx->bstate = BS_STOP;
12411 int rd = mmreg(uMIPS_RD(ctx->opcode));
12412 int rs1 = mmreg(uMIPS_RS1(ctx->opcode));
12413 int rs2 = mmreg(uMIPS_RS2(ctx->opcode));
12416 switch (ctx->opcode & 0x1) {
12425 gen_arith(env, ctx, opc, rd, rs1, rs2);
12430 int rd = mmreg(uMIPS_RD(ctx->opcode));
12431 int rs = mmreg(uMIPS_RS(ctx->opcode));
12432 int amount = (ctx->opcode >> 1) & 0x7;
12434 amount = amount == 0 ? 8 : amount;
12436 switch (ctx->opcode & 0x1) {
12445 gen_shift_imm(env, ctx, opc, rd, rs, amount);
12449 gen_pool16c_insn(env, ctx, is_branch);
12453 int rd = mmreg(uMIPS_RD(ctx->opcode));
12454 int rb = 28; /* GP */
12455 int16_t offset = SIMM(ctx->opcode, 0, 7) << 2;
12457 gen_ld(env, ctx, OPC_LW, rd, rb, offset);
12461 if (ctx->opcode & 1) {
12462 generate_exception(ctx, EXCP_RI);
12465 int enc_dest = uMIPS_RD(ctx->opcode);
12466 int enc_rt = uMIPS_RS2(ctx->opcode);
12467 int enc_rs = uMIPS_RS1(ctx->opcode);
12468 int rd, rs, re, rt;
12469 static const int rd_enc[] = { 5, 5, 6, 4, 4, 4, 4, 4 };
12470 static const int re_enc[] = { 6, 7, 7, 21, 22, 5, 6, 7 };
12471 static const int rs_rt_enc[] = { 0, 17, 2, 3, 16, 18, 19, 20 };
12473 rd = rd_enc[enc_dest];
12474 re = re_enc[enc_dest];
12475 rs = rs_rt_enc[enc_rs];
12476 rt = rs_rt_enc[enc_rt];
12478 gen_arith_imm(env, ctx, OPC_ADDIU, rd, rs, 0);
12479 gen_arith_imm(env, ctx, OPC_ADDIU, re, rt, 0);
12484 int rd = mmreg(uMIPS_RD(ctx->opcode));
12485 int rb = mmreg(uMIPS_RS(ctx->opcode));
12486 int16_t offset = ZIMM(ctx->opcode, 0, 4);
12487 offset = (offset == 0xf ? -1 : offset);
12489 gen_ld(env, ctx, OPC_LBU, rd, rb, offset);
12494 int rd = mmreg(uMIPS_RD(ctx->opcode));
12495 int rb = mmreg(uMIPS_RS(ctx->opcode));
12496 int16_t offset = ZIMM(ctx->opcode, 0, 4) << 1;
12498 gen_ld(env, ctx, OPC_LHU, rd, rb, offset);
12503 int rd = (ctx->opcode >> 5) & 0x1f;
12504 int rb = 29; /* SP */
12505 int16_t offset = ZIMM(ctx->opcode, 0, 5) << 2;
12507 gen_ld(env, ctx, OPC_LW, rd, rb, offset);
12512 int rd = mmreg(uMIPS_RD(ctx->opcode));
12513 int rb = mmreg(uMIPS_RS(ctx->opcode));
12514 int16_t offset = ZIMM(ctx->opcode, 0, 4) << 2;
12516 gen_ld(env, ctx, OPC_LW, rd, rb, offset);
12521 int rd = mmreg2(uMIPS_RD(ctx->opcode));
12522 int rb = mmreg(uMIPS_RS(ctx->opcode));
12523 int16_t offset = ZIMM(ctx->opcode, 0, 4);
12525 gen_st(ctx, OPC_SB, rd, rb, offset);
12530 int rd = mmreg2(uMIPS_RD(ctx->opcode));
12531 int rb = mmreg(uMIPS_RS(ctx->opcode));
12532 int16_t offset = ZIMM(ctx->opcode, 0, 4) << 1;
12534 gen_st(ctx, OPC_SH, rd, rb, offset);
12539 int rd = (ctx->opcode >> 5) & 0x1f;
12540 int rb = 29; /* SP */
12541 int16_t offset = ZIMM(ctx->opcode, 0, 5) << 2;
12543 gen_st(ctx, OPC_SW, rd, rb, offset);
12548 int rd = mmreg2(uMIPS_RD(ctx->opcode));
12549 int rb = mmreg(uMIPS_RS(ctx->opcode));
12550 int16_t offset = ZIMM(ctx->opcode, 0, 4) << 2;
12552 gen_st(ctx, OPC_SW, rd, rb, offset);
12557 int rd = uMIPS_RD5(ctx->opcode);
12558 int rs = uMIPS_RS5(ctx->opcode);
12560 gen_arith_imm(env, ctx, OPC_ADDIU, rd, rs, 0);
12564 gen_andi16(env, ctx);
12567 switch (ctx->opcode & 0x1) {
12569 gen_addius5(env, ctx);
12572 gen_addiusp(env, ctx);
12577 switch (ctx->opcode & 0x1) {
12579 gen_addiur2(env, ctx);
12582 gen_addiur1sp(env, ctx);
12587 gen_compute_branch(ctx, OPC_BEQ, 2, 0, 0,
12588 SIMM(ctx->opcode, 0, 10) << 1);
12593 gen_compute_branch(ctx, op == BNEZ16 ? OPC_BNE : OPC_BEQ, 2,
12594 mmreg(uMIPS_RD(ctx->opcode)),
12595 0, SIMM(ctx->opcode, 0, 7) << 1);
12600 int reg = mmreg(uMIPS_RD(ctx->opcode));
12601 int imm = ZIMM(ctx->opcode, 0, 7);
12603 imm = (imm == 0x7f ? -1 : imm);
12604 tcg_gen_movi_tl(cpu_gpr[reg], imm);
12614 generate_exception(ctx, EXCP_RI);
12617 decode_micromips32_opc (env, ctx, op, is_branch);
12624 /* SmartMIPS extension to MIPS32 */
12626 #if defined(TARGET_MIPS64)
12628 /* MDMX extension to MIPS64 */
12632 /* MIPSDSP functions. */
12633 static void gen_mipsdsp_ld(CPUMIPSState *env, DisasContext *ctx, uint32_t opc,
12634 int rd, int base, int offset)
12636 const char *opn = "ldx";
12645 t0 = tcg_temp_new();
12648 gen_load_gpr(t0, offset);
12649 } else if (offset == 0) {
12650 gen_load_gpr(t0, base);
12652 gen_op_addr_add(ctx, t0, cpu_gpr[base], cpu_gpr[offset]);
12657 op_ld_lbu(t0, t0, ctx);
12658 gen_store_gpr(t0, rd);
12662 op_ld_lh(t0, t0, ctx);
12663 gen_store_gpr(t0, rd);
12667 op_ld_lw(t0, t0, ctx);
12668 gen_store_gpr(t0, rd);
12671 #if defined(TARGET_MIPS64)
12673 op_ld_ld(t0, t0, ctx);
12674 gen_store_gpr(t0, rd);
12679 (void)opn; /* avoid a compiler warning */
12680 MIPS_DEBUG("%s %s, %s(%s)", opn,
12681 regnames[rd], regnames[offset], regnames[base]);
12685 static void gen_mipsdsp_arith(DisasContext *ctx, uint32_t op1, uint32_t op2,
12686 int ret, int v1, int v2)
12688 const char *opn = "mipsdsp arith";
12693 /* Treat as NOP. */
12698 v1_t = tcg_temp_new();
12699 v2_t = tcg_temp_new();
12701 gen_load_gpr(v1_t, v1);
12702 gen_load_gpr(v2_t, v2);
12705 /* OPC_MULT_G_2E is equal OPC_ADDUH_QB_DSP */
12706 case OPC_MULT_G_2E:
12710 gen_helper_adduh_qb(cpu_gpr[ret], v1_t, v2_t);
12712 case OPC_ADDUH_R_QB:
12713 gen_helper_adduh_r_qb(cpu_gpr[ret], v1_t, v2_t);
12716 gen_helper_addqh_ph(cpu_gpr[ret], v1_t, v2_t);
12718 case OPC_ADDQH_R_PH:
12719 gen_helper_addqh_r_ph(cpu_gpr[ret], v1_t, v2_t);
12722 gen_helper_addqh_w(cpu_gpr[ret], v1_t, v2_t);
12724 case OPC_ADDQH_R_W:
12725 gen_helper_addqh_r_w(cpu_gpr[ret], v1_t, v2_t);
12728 gen_helper_subuh_qb(cpu_gpr[ret], v1_t, v2_t);
12730 case OPC_SUBUH_R_QB:
12731 gen_helper_subuh_r_qb(cpu_gpr[ret], v1_t, v2_t);
12734 gen_helper_subqh_ph(cpu_gpr[ret], v1_t, v2_t);
12736 case OPC_SUBQH_R_PH:
12737 gen_helper_subqh_r_ph(cpu_gpr[ret], v1_t, v2_t);
12740 gen_helper_subqh_w(cpu_gpr[ret], v1_t, v2_t);
12742 case OPC_SUBQH_R_W:
12743 gen_helper_subqh_r_w(cpu_gpr[ret], v1_t, v2_t);
12747 case OPC_ABSQ_S_PH_DSP:
12749 case OPC_ABSQ_S_QB:
12751 gen_helper_absq_s_qb(cpu_gpr[ret], v2_t, cpu_env);
12753 case OPC_ABSQ_S_PH:
12755 gen_helper_absq_s_ph(cpu_gpr[ret], v2_t, cpu_env);
12759 gen_helper_absq_s_w(cpu_gpr[ret], v2_t, cpu_env);
12761 case OPC_PRECEQ_W_PHL:
12763 tcg_gen_andi_tl(cpu_gpr[ret], v2_t, 0xFFFF0000);
12764 tcg_gen_ext32s_tl(cpu_gpr[ret], cpu_gpr[ret]);
12766 case OPC_PRECEQ_W_PHR:
12768 tcg_gen_andi_tl(cpu_gpr[ret], v2_t, 0x0000FFFF);
12769 tcg_gen_shli_tl(cpu_gpr[ret], cpu_gpr[ret], 16);
12770 tcg_gen_ext32s_tl(cpu_gpr[ret], cpu_gpr[ret]);
12772 case OPC_PRECEQU_PH_QBL:
12774 gen_helper_precequ_ph_qbl(cpu_gpr[ret], v2_t);
12776 case OPC_PRECEQU_PH_QBR:
12778 gen_helper_precequ_ph_qbr(cpu_gpr[ret], v2_t);
12780 case OPC_PRECEQU_PH_QBLA:
12782 gen_helper_precequ_ph_qbla(cpu_gpr[ret], v2_t);
12784 case OPC_PRECEQU_PH_QBRA:
12786 gen_helper_precequ_ph_qbra(cpu_gpr[ret], v2_t);
12788 case OPC_PRECEU_PH_QBL:
12790 gen_helper_preceu_ph_qbl(cpu_gpr[ret], v2_t);
12792 case OPC_PRECEU_PH_QBR:
12794 gen_helper_preceu_ph_qbr(cpu_gpr[ret], v2_t);
12796 case OPC_PRECEU_PH_QBLA:
12798 gen_helper_preceu_ph_qbla(cpu_gpr[ret], v2_t);
12800 case OPC_PRECEU_PH_QBRA:
12802 gen_helper_preceu_ph_qbra(cpu_gpr[ret], v2_t);
12806 case OPC_ADDU_QB_DSP:
12810 gen_helper_addq_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12812 case OPC_ADDQ_S_PH:
12814 gen_helper_addq_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12818 gen_helper_addq_s_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12822 gen_helper_addu_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12824 case OPC_ADDU_S_QB:
12826 gen_helper_addu_s_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12830 gen_helper_addu_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12832 case OPC_ADDU_S_PH:
12834 gen_helper_addu_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12838 gen_helper_subq_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12840 case OPC_SUBQ_S_PH:
12842 gen_helper_subq_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12846 gen_helper_subq_s_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12850 gen_helper_subu_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12852 case OPC_SUBU_S_QB:
12854 gen_helper_subu_s_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12858 gen_helper_subu_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12860 case OPC_SUBU_S_PH:
12862 gen_helper_subu_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12866 gen_helper_addsc(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12870 gen_helper_addwc(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12874 gen_helper_modsub(cpu_gpr[ret], v1_t, v2_t);
12876 case OPC_RADDU_W_QB:
12878 gen_helper_raddu_w_qb(cpu_gpr[ret], v1_t);
12882 case OPC_CMPU_EQ_QB_DSP:
12884 case OPC_PRECR_QB_PH:
12886 gen_helper_precr_qb_ph(cpu_gpr[ret], v1_t, v2_t);
12888 case OPC_PRECRQ_QB_PH:
12890 gen_helper_precrq_qb_ph(cpu_gpr[ret], v1_t, v2_t);
12892 case OPC_PRECR_SRA_PH_W:
12895 TCGv_i32 sa_t = tcg_const_i32(v2);
12896 gen_helper_precr_sra_ph_w(cpu_gpr[ret], sa_t, v1_t,
12898 tcg_temp_free_i32(sa_t);
12901 case OPC_PRECR_SRA_R_PH_W:
12904 TCGv_i32 sa_t = tcg_const_i32(v2);
12905 gen_helper_precr_sra_r_ph_w(cpu_gpr[ret], sa_t, v1_t,
12907 tcg_temp_free_i32(sa_t);
12910 case OPC_PRECRQ_PH_W:
12912 gen_helper_precrq_ph_w(cpu_gpr[ret], v1_t, v2_t);
12914 case OPC_PRECRQ_RS_PH_W:
12916 gen_helper_precrq_rs_ph_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12918 case OPC_PRECRQU_S_QB_PH:
12920 gen_helper_precrqu_s_qb_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12924 #ifdef TARGET_MIPS64
12925 case OPC_ABSQ_S_QH_DSP:
12927 case OPC_PRECEQ_L_PWL:
12929 tcg_gen_andi_tl(cpu_gpr[ret], v2_t, 0xFFFFFFFF00000000ull);
12931 case OPC_PRECEQ_L_PWR:
12933 tcg_gen_shli_tl(cpu_gpr[ret], v2_t, 32);
12935 case OPC_PRECEQ_PW_QHL:
12937 gen_helper_preceq_pw_qhl(cpu_gpr[ret], v2_t);
12939 case OPC_PRECEQ_PW_QHR:
12941 gen_helper_preceq_pw_qhr(cpu_gpr[ret], v2_t);
12943 case OPC_PRECEQ_PW_QHLA:
12945 gen_helper_preceq_pw_qhla(cpu_gpr[ret], v2_t);
12947 case OPC_PRECEQ_PW_QHRA:
12949 gen_helper_preceq_pw_qhra(cpu_gpr[ret], v2_t);
12951 case OPC_PRECEQU_QH_OBL:
12953 gen_helper_precequ_qh_obl(cpu_gpr[ret], v2_t);
12955 case OPC_PRECEQU_QH_OBR:
12957 gen_helper_precequ_qh_obr(cpu_gpr[ret], v2_t);
12959 case OPC_PRECEQU_QH_OBLA:
12961 gen_helper_precequ_qh_obla(cpu_gpr[ret], v2_t);
12963 case OPC_PRECEQU_QH_OBRA:
12965 gen_helper_precequ_qh_obra(cpu_gpr[ret], v2_t);
12967 case OPC_PRECEU_QH_OBL:
12969 gen_helper_preceu_qh_obl(cpu_gpr[ret], v2_t);
12971 case OPC_PRECEU_QH_OBR:
12973 gen_helper_preceu_qh_obr(cpu_gpr[ret], v2_t);
12975 case OPC_PRECEU_QH_OBLA:
12977 gen_helper_preceu_qh_obla(cpu_gpr[ret], v2_t);
12979 case OPC_PRECEU_QH_OBRA:
12981 gen_helper_preceu_qh_obra(cpu_gpr[ret], v2_t);
12983 case OPC_ABSQ_S_OB:
12985 gen_helper_absq_s_ob(cpu_gpr[ret], v2_t, cpu_env);
12987 case OPC_ABSQ_S_PW:
12989 gen_helper_absq_s_pw(cpu_gpr[ret], v2_t, cpu_env);
12991 case OPC_ABSQ_S_QH:
12993 gen_helper_absq_s_qh(cpu_gpr[ret], v2_t, cpu_env);
12997 case OPC_ADDU_OB_DSP:
12999 case OPC_RADDU_L_OB:
13001 gen_helper_raddu_l_ob(cpu_gpr[ret], v1_t);
13005 gen_helper_subq_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13007 case OPC_SUBQ_S_PW:
13009 gen_helper_subq_s_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13013 gen_helper_subq_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13015 case OPC_SUBQ_S_QH:
13017 gen_helper_subq_s_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13021 gen_helper_subu_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13023 case OPC_SUBU_S_OB:
13025 gen_helper_subu_s_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13029 gen_helper_subu_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13031 case OPC_SUBU_S_QH:
13033 gen_helper_subu_s_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13037 gen_helper_subuh_ob(cpu_gpr[ret], v1_t, v2_t);
13039 case OPC_SUBUH_R_OB:
13041 gen_helper_subuh_r_ob(cpu_gpr[ret], v1_t, v2_t);
13045 gen_helper_addq_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13047 case OPC_ADDQ_S_PW:
13049 gen_helper_addq_s_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13053 gen_helper_addq_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13055 case OPC_ADDQ_S_QH:
13057 gen_helper_addq_s_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13061 gen_helper_addu_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13063 case OPC_ADDU_S_OB:
13065 gen_helper_addu_s_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13069 gen_helper_addu_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13071 case OPC_ADDU_S_QH:
13073 gen_helper_addu_s_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13077 gen_helper_adduh_ob(cpu_gpr[ret], v1_t, v2_t);
13079 case OPC_ADDUH_R_OB:
13081 gen_helper_adduh_r_ob(cpu_gpr[ret], v1_t, v2_t);
13085 case OPC_CMPU_EQ_OB_DSP:
13087 case OPC_PRECR_OB_QH:
13089 gen_helper_precr_ob_qh(cpu_gpr[ret], v1_t, v2_t);
13091 case OPC_PRECR_SRA_QH_PW:
13094 TCGv_i32 ret_t = tcg_const_i32(ret);
13095 gen_helper_precr_sra_qh_pw(v2_t, v1_t, v2_t, ret_t);
13096 tcg_temp_free_i32(ret_t);
13099 case OPC_PRECR_SRA_R_QH_PW:
13102 TCGv_i32 sa_v = tcg_const_i32(ret);
13103 gen_helper_precr_sra_r_qh_pw(v2_t, v1_t, v2_t, sa_v);
13104 tcg_temp_free_i32(sa_v);
13107 case OPC_PRECRQ_OB_QH:
13109 gen_helper_precrq_ob_qh(cpu_gpr[ret], v1_t, v2_t);
13111 case OPC_PRECRQ_PW_L:
13113 gen_helper_precrq_pw_l(cpu_gpr[ret], v1_t, v2_t);
13115 case OPC_PRECRQ_QH_PW:
13117 gen_helper_precrq_qh_pw(cpu_gpr[ret], v1_t, v2_t);
13119 case OPC_PRECRQ_RS_QH_PW:
13121 gen_helper_precrq_rs_qh_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13123 case OPC_PRECRQU_S_OB_QH:
13125 gen_helper_precrqu_s_ob_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13132 tcg_temp_free(v1_t);
13133 tcg_temp_free(v2_t);
13135 (void)opn; /* avoid a compiler warning */
13136 MIPS_DEBUG("%s", opn);
13139 static void gen_mipsdsp_shift(DisasContext *ctx, uint32_t opc,
13140 int ret, int v1, int v2)
13143 const char *opn = "mipsdsp shift";
13149 /* Treat as NOP. */
13154 t0 = tcg_temp_new();
13155 v1_t = tcg_temp_new();
13156 v2_t = tcg_temp_new();
13158 tcg_gen_movi_tl(t0, v1);
13159 gen_load_gpr(v1_t, v1);
13160 gen_load_gpr(v2_t, v2);
13163 case OPC_SHLL_QB_DSP:
13165 op2 = MASK_SHLL_QB(ctx->opcode);
13169 gen_helper_shll_qb(cpu_gpr[ret], t0, v2_t, cpu_env);
13173 gen_helper_shll_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13177 gen_helper_shll_ph(cpu_gpr[ret], t0, v2_t, cpu_env);
13181 gen_helper_shll_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13183 case OPC_SHLL_S_PH:
13185 gen_helper_shll_s_ph(cpu_gpr[ret], t0, v2_t, cpu_env);
13187 case OPC_SHLLV_S_PH:
13189 gen_helper_shll_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13193 gen_helper_shll_s_w(cpu_gpr[ret], t0, v2_t, cpu_env);
13195 case OPC_SHLLV_S_W:
13197 gen_helper_shll_s_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13201 gen_helper_shrl_qb(cpu_gpr[ret], t0, v2_t);
13205 gen_helper_shrl_qb(cpu_gpr[ret], v1_t, v2_t);
13209 gen_helper_shrl_ph(cpu_gpr[ret], t0, v2_t);
13213 gen_helper_shrl_ph(cpu_gpr[ret], v1_t, v2_t);
13217 gen_helper_shra_qb(cpu_gpr[ret], t0, v2_t);
13219 case OPC_SHRA_R_QB:
13221 gen_helper_shra_r_qb(cpu_gpr[ret], t0, v2_t);
13225 gen_helper_shra_qb(cpu_gpr[ret], v1_t, v2_t);
13227 case OPC_SHRAV_R_QB:
13229 gen_helper_shra_r_qb(cpu_gpr[ret], v1_t, v2_t);
13233 gen_helper_shra_ph(cpu_gpr[ret], t0, v2_t);
13235 case OPC_SHRA_R_PH:
13237 gen_helper_shra_r_ph(cpu_gpr[ret], t0, v2_t);
13241 gen_helper_shra_ph(cpu_gpr[ret], v1_t, v2_t);
13243 case OPC_SHRAV_R_PH:
13245 gen_helper_shra_r_ph(cpu_gpr[ret], v1_t, v2_t);
13249 gen_helper_shra_r_w(cpu_gpr[ret], t0, v2_t);
13251 case OPC_SHRAV_R_W:
13253 gen_helper_shra_r_w(cpu_gpr[ret], v1_t, v2_t);
13255 default: /* Invalid */
13256 MIPS_INVAL("MASK SHLL.QB");
13257 generate_exception(ctx, EXCP_RI);
13262 #ifdef TARGET_MIPS64
13263 case OPC_SHLL_OB_DSP:
13264 op2 = MASK_SHLL_OB(ctx->opcode);
13268 gen_helper_shll_pw(cpu_gpr[ret], v2_t, t0, cpu_env);
13272 gen_helper_shll_pw(cpu_gpr[ret], v2_t, v1_t, cpu_env);
13274 case OPC_SHLL_S_PW:
13276 gen_helper_shll_s_pw(cpu_gpr[ret], v2_t, t0, cpu_env);
13278 case OPC_SHLLV_S_PW:
13280 gen_helper_shll_s_pw(cpu_gpr[ret], v2_t, v1_t, cpu_env);
13284 gen_helper_shll_ob(cpu_gpr[ret], v2_t, t0, cpu_env);
13288 gen_helper_shll_ob(cpu_gpr[ret], v2_t, v1_t, cpu_env);
13292 gen_helper_shll_qh(cpu_gpr[ret], v2_t, t0, cpu_env);
13296 gen_helper_shll_qh(cpu_gpr[ret], v2_t, v1_t, cpu_env);
13298 case OPC_SHLL_S_QH:
13300 gen_helper_shll_s_qh(cpu_gpr[ret], v2_t, t0, cpu_env);
13302 case OPC_SHLLV_S_QH:
13304 gen_helper_shll_s_qh(cpu_gpr[ret], v2_t, v1_t, cpu_env);
13308 gen_helper_shra_ob(cpu_gpr[ret], v2_t, t0);
13312 gen_helper_shra_ob(cpu_gpr[ret], v2_t, v1_t);
13314 case OPC_SHRA_R_OB:
13316 gen_helper_shra_r_ob(cpu_gpr[ret], v2_t, t0);
13318 case OPC_SHRAV_R_OB:
13320 gen_helper_shra_r_ob(cpu_gpr[ret], v2_t, v1_t);
13324 gen_helper_shra_pw(cpu_gpr[ret], v2_t, t0);
13328 gen_helper_shra_pw(cpu_gpr[ret], v2_t, v1_t);
13330 case OPC_SHRA_R_PW:
13332 gen_helper_shra_r_pw(cpu_gpr[ret], v2_t, t0);
13334 case OPC_SHRAV_R_PW:
13336 gen_helper_shra_r_pw(cpu_gpr[ret], v2_t, v1_t);
13340 gen_helper_shra_qh(cpu_gpr[ret], v2_t, t0);
13344 gen_helper_shra_qh(cpu_gpr[ret], v2_t, v1_t);
13346 case OPC_SHRA_R_QH:
13348 gen_helper_shra_r_qh(cpu_gpr[ret], v2_t, t0);
13350 case OPC_SHRAV_R_QH:
13352 gen_helper_shra_r_qh(cpu_gpr[ret], v2_t, v1_t);
13356 gen_helper_shrl_ob(cpu_gpr[ret], v2_t, t0);
13360 gen_helper_shrl_ob(cpu_gpr[ret], v2_t, v1_t);
13364 gen_helper_shrl_qh(cpu_gpr[ret], v2_t, t0);
13368 gen_helper_shrl_qh(cpu_gpr[ret], v2_t, v1_t);
13370 default: /* Invalid */
13371 MIPS_INVAL("MASK SHLL.OB");
13372 generate_exception(ctx, EXCP_RI);
13380 tcg_temp_free(v1_t);
13381 tcg_temp_free(v2_t);
13382 (void)opn; /* avoid a compiler warning */
13383 MIPS_DEBUG("%s", opn);
13386 static void gen_mipsdsp_multiply(DisasContext *ctx, uint32_t op1, uint32_t op2,
13387 int ret, int v1, int v2, int check_ret)
13389 const char *opn = "mipsdsp multiply";
13394 if ((ret == 0) && (check_ret == 1)) {
13395 /* Treat as NOP. */
13400 t0 = tcg_temp_new_i32();
13401 v1_t = tcg_temp_new();
13402 v2_t = tcg_temp_new();
13404 tcg_gen_movi_i32(t0, ret);
13405 gen_load_gpr(v1_t, v1);
13406 gen_load_gpr(v2_t, v2);
13409 /* OPC_MULT_G_2E, OPC_ADDUH_QB_DSP, OPC_MUL_PH_DSP have
13410 * the same mask and op1. */
13411 case OPC_MULT_G_2E:
13414 gen_helper_mul_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13417 gen_helper_mul_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13420 gen_helper_mulq_s_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13422 case OPC_MULQ_RS_W:
13423 gen_helper_mulq_rs_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13427 case OPC_DPA_W_PH_DSP:
13429 case OPC_DPAU_H_QBL:
13431 gen_helper_dpau_h_qbl(t0, v1_t, v2_t, cpu_env);
13433 case OPC_DPAU_H_QBR:
13435 gen_helper_dpau_h_qbr(t0, v1_t, v2_t, cpu_env);
13437 case OPC_DPSU_H_QBL:
13439 gen_helper_dpsu_h_qbl(t0, v1_t, v2_t, cpu_env);
13441 case OPC_DPSU_H_QBR:
13443 gen_helper_dpsu_h_qbr(t0, v1_t, v2_t, cpu_env);
13447 gen_helper_dpa_w_ph(t0, v1_t, v2_t, cpu_env);
13449 case OPC_DPAX_W_PH:
13451 gen_helper_dpax_w_ph(t0, v1_t, v2_t, cpu_env);
13453 case OPC_DPAQ_S_W_PH:
13455 gen_helper_dpaq_s_w_ph(t0, v1_t, v2_t, cpu_env);
13457 case OPC_DPAQX_S_W_PH:
13459 gen_helper_dpaqx_s_w_ph(t0, v1_t, v2_t, cpu_env);
13461 case OPC_DPAQX_SA_W_PH:
13463 gen_helper_dpaqx_sa_w_ph(t0, v1_t, v2_t, cpu_env);
13467 gen_helper_dps_w_ph(t0, v1_t, v2_t, cpu_env);
13469 case OPC_DPSX_W_PH:
13471 gen_helper_dpsx_w_ph(t0, v1_t, v2_t, cpu_env);
13473 case OPC_DPSQ_S_W_PH:
13475 gen_helper_dpsq_s_w_ph(t0, v1_t, v2_t, cpu_env);
13477 case OPC_DPSQX_S_W_PH:
13479 gen_helper_dpsqx_s_w_ph(t0, v1_t, v2_t, cpu_env);
13481 case OPC_DPSQX_SA_W_PH:
13483 gen_helper_dpsqx_sa_w_ph(t0, v1_t, v2_t, cpu_env);
13485 case OPC_MULSAQ_S_W_PH:
13487 gen_helper_mulsaq_s_w_ph(t0, v1_t, v2_t, cpu_env);
13489 case OPC_DPAQ_SA_L_W:
13491 gen_helper_dpaq_sa_l_w(t0, v1_t, v2_t, cpu_env);
13493 case OPC_DPSQ_SA_L_W:
13495 gen_helper_dpsq_sa_l_w(t0, v1_t, v2_t, cpu_env);
13497 case OPC_MAQ_S_W_PHL:
13499 gen_helper_maq_s_w_phl(t0, v1_t, v2_t, cpu_env);
13501 case OPC_MAQ_S_W_PHR:
13503 gen_helper_maq_s_w_phr(t0, v1_t, v2_t, cpu_env);
13505 case OPC_MAQ_SA_W_PHL:
13507 gen_helper_maq_sa_w_phl(t0, v1_t, v2_t, cpu_env);
13509 case OPC_MAQ_SA_W_PHR:
13511 gen_helper_maq_sa_w_phr(t0, v1_t, v2_t, cpu_env);
13513 case OPC_MULSA_W_PH:
13515 gen_helper_mulsa_w_ph(t0, v1_t, v2_t, cpu_env);
13519 #ifdef TARGET_MIPS64
13520 case OPC_DPAQ_W_QH_DSP:
13522 int ac = ret & 0x03;
13523 tcg_gen_movi_i32(t0, ac);
13528 gen_helper_dmadd(v1_t, v2_t, t0, cpu_env);
13532 gen_helper_dmaddu(v1_t, v2_t, t0, cpu_env);
13536 gen_helper_dmsub(v1_t, v2_t, t0, cpu_env);
13540 gen_helper_dmsubu(v1_t, v2_t, t0, cpu_env);
13544 gen_helper_dpa_w_qh(v1_t, v2_t, t0, cpu_env);
13546 case OPC_DPAQ_S_W_QH:
13548 gen_helper_dpaq_s_w_qh(v1_t, v2_t, t0, cpu_env);
13550 case OPC_DPAQ_SA_L_PW:
13552 gen_helper_dpaq_sa_l_pw(v1_t, v2_t, t0, cpu_env);
13554 case OPC_DPAU_H_OBL:
13556 gen_helper_dpau_h_obl(v1_t, v2_t, t0, cpu_env);
13558 case OPC_DPAU_H_OBR:
13560 gen_helper_dpau_h_obr(v1_t, v2_t, t0, cpu_env);
13564 gen_helper_dps_w_qh(v1_t, v2_t, t0, cpu_env);
13566 case OPC_DPSQ_S_W_QH:
13568 gen_helper_dpsq_s_w_qh(v1_t, v2_t, t0, cpu_env);
13570 case OPC_DPSQ_SA_L_PW:
13572 gen_helper_dpsq_sa_l_pw(v1_t, v2_t, t0, cpu_env);
13574 case OPC_DPSU_H_OBL:
13576 gen_helper_dpsu_h_obl(v1_t, v2_t, t0, cpu_env);
13578 case OPC_DPSU_H_OBR:
13580 gen_helper_dpsu_h_obr(v1_t, v2_t, t0, cpu_env);
13582 case OPC_MAQ_S_L_PWL:
13584 gen_helper_maq_s_l_pwl(v1_t, v2_t, t0, cpu_env);
13586 case OPC_MAQ_S_L_PWR:
13588 gen_helper_maq_s_l_pwr(v1_t, v2_t, t0, cpu_env);
13590 case OPC_MAQ_S_W_QHLL:
13592 gen_helper_maq_s_w_qhll(v1_t, v2_t, t0, cpu_env);
13594 case OPC_MAQ_SA_W_QHLL:
13596 gen_helper_maq_sa_w_qhll(v1_t, v2_t, t0, cpu_env);
13598 case OPC_MAQ_S_W_QHLR:
13600 gen_helper_maq_s_w_qhlr(v1_t, v2_t, t0, cpu_env);
13602 case OPC_MAQ_SA_W_QHLR:
13604 gen_helper_maq_sa_w_qhlr(v1_t, v2_t, t0, cpu_env);
13606 case OPC_MAQ_S_W_QHRL:
13608 gen_helper_maq_s_w_qhrl(v1_t, v2_t, t0, cpu_env);
13610 case OPC_MAQ_SA_W_QHRL:
13612 gen_helper_maq_sa_w_qhrl(v1_t, v2_t, t0, cpu_env);
13614 case OPC_MAQ_S_W_QHRR:
13616 gen_helper_maq_s_w_qhrr(v1_t, v2_t, t0, cpu_env);
13618 case OPC_MAQ_SA_W_QHRR:
13620 gen_helper_maq_sa_w_qhrr(v1_t, v2_t, t0, cpu_env);
13622 case OPC_MULSAQ_S_L_PW:
13624 gen_helper_mulsaq_s_l_pw(v1_t, v2_t, t0, cpu_env);
13626 case OPC_MULSAQ_S_W_QH:
13628 gen_helper_mulsaq_s_w_qh(v1_t, v2_t, t0, cpu_env);
13634 case OPC_ADDU_QB_DSP:
13636 case OPC_MULEU_S_PH_QBL:
13638 gen_helper_muleu_s_ph_qbl(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13640 case OPC_MULEU_S_PH_QBR:
13642 gen_helper_muleu_s_ph_qbr(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13644 case OPC_MULQ_RS_PH:
13646 gen_helper_mulq_rs_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13648 case OPC_MULEQ_S_W_PHL:
13650 gen_helper_muleq_s_w_phl(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13652 case OPC_MULEQ_S_W_PHR:
13654 gen_helper_muleq_s_w_phr(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13656 case OPC_MULQ_S_PH:
13658 gen_helper_mulq_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13662 #ifdef TARGET_MIPS64
13663 case OPC_ADDU_OB_DSP:
13665 case OPC_MULEQ_S_PW_QHL:
13667 gen_helper_muleq_s_pw_qhl(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13669 case OPC_MULEQ_S_PW_QHR:
13671 gen_helper_muleq_s_pw_qhr(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13673 case OPC_MULEU_S_QH_OBL:
13675 gen_helper_muleu_s_qh_obl(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13677 case OPC_MULEU_S_QH_OBR:
13679 gen_helper_muleu_s_qh_obr(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13681 case OPC_MULQ_RS_QH:
13683 gen_helper_mulq_rs_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13690 tcg_temp_free_i32(t0);
13691 tcg_temp_free(v1_t);
13692 tcg_temp_free(v2_t);
13694 (void)opn; /* avoid a compiler warning */
13695 MIPS_DEBUG("%s", opn);
13699 static void gen_mipsdsp_bitinsn(CPUMIPSState *env, DisasContext *ctx,
13700 uint32_t op1, uint32_t op2,
13703 const char *opn = "mipsdsp Bit/ Manipulation";
13709 /* Treat as NOP. */
13714 t0 = tcg_temp_new();
13715 val_t = tcg_temp_new();
13716 gen_load_gpr(val_t, val);
13719 case OPC_ABSQ_S_PH_DSP:
13723 gen_helper_bitrev(cpu_gpr[ret], val_t);
13728 target_long result;
13729 imm = (ctx->opcode >> 16) & 0xFF;
13730 result = (uint32_t)imm << 24 |
13731 (uint32_t)imm << 16 |
13732 (uint32_t)imm << 8 |
13734 result = (int32_t)result;
13735 tcg_gen_movi_tl(cpu_gpr[ret], result);
13740 tcg_gen_ext8u_tl(cpu_gpr[ret], val_t);
13741 tcg_gen_shli_tl(t0, cpu_gpr[ret], 8);
13742 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
13743 tcg_gen_shli_tl(t0, cpu_gpr[ret], 16);
13744 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
13745 tcg_gen_ext32s_tl(cpu_gpr[ret], cpu_gpr[ret]);
13750 imm = (ctx->opcode >> 16) & 0x03FF;
13751 tcg_gen_movi_tl(cpu_gpr[ret], \
13752 (target_long)((int32_t)imm << 16 | \
13753 (uint32_t)(uint16_t)imm));
13758 tcg_gen_ext16u_tl(cpu_gpr[ret], val_t);
13759 tcg_gen_shli_tl(t0, cpu_gpr[ret], 16);
13760 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
13761 tcg_gen_ext32s_tl(cpu_gpr[ret], cpu_gpr[ret]);
13765 #ifdef TARGET_MIPS64
13766 case OPC_ABSQ_S_QH_DSP:
13773 imm = (ctx->opcode >> 16) & 0xFF;
13774 temp = ((uint64_t)imm << 8) | (uint64_t)imm;
13775 temp = (temp << 16) | temp;
13776 temp = (temp << 32) | temp;
13777 tcg_gen_movi_tl(cpu_gpr[ret], temp);
13785 imm = (ctx->opcode >> 16) & 0x03FF;
13786 imm = (int16_t)(imm << 6) >> 6;
13787 temp = ((target_long)imm << 32) \
13788 | ((target_long)imm & 0xFFFFFFFF);
13789 tcg_gen_movi_tl(cpu_gpr[ret], temp);
13797 imm = (ctx->opcode >> 16) & 0x03FF;
13798 imm = (int16_t)(imm << 6) >> 6;
13800 temp = ((uint64_t)(uint16_t)imm << 48) |
13801 ((uint64_t)(uint16_t)imm << 32) |
13802 ((uint64_t)(uint16_t)imm << 16) |
13803 (uint64_t)(uint16_t)imm;
13804 tcg_gen_movi_tl(cpu_gpr[ret], temp);
13809 tcg_gen_ext8u_tl(cpu_gpr[ret], val_t);
13810 tcg_gen_shli_tl(t0, cpu_gpr[ret], 8);
13811 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
13812 tcg_gen_shli_tl(t0, cpu_gpr[ret], 16);
13813 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
13814 tcg_gen_shli_tl(t0, cpu_gpr[ret], 32);
13815 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
13819 tcg_gen_ext32u_i64(cpu_gpr[ret], val_t);
13820 tcg_gen_shli_tl(t0, cpu_gpr[ret], 32);
13821 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
13825 tcg_gen_ext16u_tl(cpu_gpr[ret], val_t);
13826 tcg_gen_shli_tl(t0, cpu_gpr[ret], 16);
13827 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
13828 tcg_gen_shli_tl(t0, cpu_gpr[ret], 32);
13829 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
13836 tcg_temp_free(val_t);
13838 (void)opn; /* avoid a compiler warning */
13839 MIPS_DEBUG("%s", opn);
13842 static void gen_mipsdsp_add_cmp_pick(DisasContext *ctx,
13843 uint32_t op1, uint32_t op2,
13844 int ret, int v1, int v2, int check_ret)
13846 const char *opn = "mipsdsp add compare pick";
13852 if ((ret == 0) && (check_ret == 1)) {
13853 /* Treat as NOP. */
13858 t0 = tcg_temp_new_i32();
13859 t1 = tcg_temp_new();
13860 v1_t = tcg_temp_new();
13861 v2_t = tcg_temp_new();
13863 gen_load_gpr(v1_t, v1);
13864 gen_load_gpr(v2_t, v2);
13867 case OPC_APPEND_DSP:
13870 tcg_gen_movi_i32(t0, v2);
13871 gen_helper_append(cpu_gpr[ret], cpu_gpr[ret], v1_t, t0);
13874 tcg_gen_movi_i32(t0, v2);
13875 gen_helper_prepend(cpu_gpr[ret], v1_t, cpu_gpr[ret], t0);
13878 tcg_gen_movi_i32(t0, v2);
13879 gen_helper_balign(cpu_gpr[ret], v1_t, cpu_gpr[ret], t0);
13881 default: /* Invid */
13882 MIPS_INVAL("MASK APPEND");
13883 generate_exception(ctx, EXCP_RI);
13887 case OPC_CMPU_EQ_QB_DSP:
13889 case OPC_CMPU_EQ_QB:
13891 gen_helper_cmpu_eq_qb(v1_t, v2_t, cpu_env);
13893 case OPC_CMPU_LT_QB:
13895 gen_helper_cmpu_lt_qb(v1_t, v2_t, cpu_env);
13897 case OPC_CMPU_LE_QB:
13899 gen_helper_cmpu_le_qb(v1_t, v2_t, cpu_env);
13901 case OPC_CMPGU_EQ_QB:
13903 gen_helper_cmpgu_eq_qb(cpu_gpr[ret], v1_t, v2_t);
13905 case OPC_CMPGU_LT_QB:
13907 gen_helper_cmpgu_lt_qb(cpu_gpr[ret], v1_t, v2_t);
13909 case OPC_CMPGU_LE_QB:
13911 gen_helper_cmpgu_le_qb(cpu_gpr[ret], v1_t, v2_t);
13913 case OPC_CMPGDU_EQ_QB:
13915 gen_helper_cmpgu_eq_qb(t1, v1_t, v2_t);
13916 tcg_gen_mov_tl(cpu_gpr[ret], t1);
13917 tcg_gen_andi_tl(cpu_dspctrl, cpu_dspctrl, 0xF0FFFFFF);
13918 tcg_gen_shli_tl(t1, t1, 24);
13919 tcg_gen_or_tl(cpu_dspctrl, cpu_dspctrl, t1);
13921 case OPC_CMPGDU_LT_QB:
13923 gen_helper_cmpgu_lt_qb(t1, v1_t, v2_t);
13924 tcg_gen_mov_tl(cpu_gpr[ret], t1);
13925 tcg_gen_andi_tl(cpu_dspctrl, cpu_dspctrl, 0xF0FFFFFF);
13926 tcg_gen_shli_tl(t1, t1, 24);
13927 tcg_gen_or_tl(cpu_dspctrl, cpu_dspctrl, t1);
13929 case OPC_CMPGDU_LE_QB:
13931 gen_helper_cmpgu_le_qb(t1, v1_t, v2_t);
13932 tcg_gen_mov_tl(cpu_gpr[ret], t1);
13933 tcg_gen_andi_tl(cpu_dspctrl, cpu_dspctrl, 0xF0FFFFFF);
13934 tcg_gen_shli_tl(t1, t1, 24);
13935 tcg_gen_or_tl(cpu_dspctrl, cpu_dspctrl, t1);
13937 case OPC_CMP_EQ_PH:
13939 gen_helper_cmp_eq_ph(v1_t, v2_t, cpu_env);
13941 case OPC_CMP_LT_PH:
13943 gen_helper_cmp_lt_ph(v1_t, v2_t, cpu_env);
13945 case OPC_CMP_LE_PH:
13947 gen_helper_cmp_le_ph(v1_t, v2_t, cpu_env);
13951 gen_helper_pick_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13955 gen_helper_pick_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13957 case OPC_PACKRL_PH:
13959 gen_helper_packrl_ph(cpu_gpr[ret], v1_t, v2_t);
13963 #ifdef TARGET_MIPS64
13964 case OPC_CMPU_EQ_OB_DSP:
13966 case OPC_CMP_EQ_PW:
13968 gen_helper_cmp_eq_pw(v1_t, v2_t, cpu_env);
13970 case OPC_CMP_LT_PW:
13972 gen_helper_cmp_lt_pw(v1_t, v2_t, cpu_env);
13974 case OPC_CMP_LE_PW:
13976 gen_helper_cmp_le_pw(v1_t, v2_t, cpu_env);
13978 case OPC_CMP_EQ_QH:
13980 gen_helper_cmp_eq_qh(v1_t, v2_t, cpu_env);
13982 case OPC_CMP_LT_QH:
13984 gen_helper_cmp_lt_qh(v1_t, v2_t, cpu_env);
13986 case OPC_CMP_LE_QH:
13988 gen_helper_cmp_le_qh(v1_t, v2_t, cpu_env);
13990 case OPC_CMPGDU_EQ_OB:
13992 gen_helper_cmpgdu_eq_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13994 case OPC_CMPGDU_LT_OB:
13996 gen_helper_cmpgdu_lt_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13998 case OPC_CMPGDU_LE_OB:
14000 gen_helper_cmpgdu_le_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
14002 case OPC_CMPGU_EQ_OB:
14004 gen_helper_cmpgu_eq_ob(cpu_gpr[ret], v1_t, v2_t);
14006 case OPC_CMPGU_LT_OB:
14008 gen_helper_cmpgu_lt_ob(cpu_gpr[ret], v1_t, v2_t);
14010 case OPC_CMPGU_LE_OB:
14012 gen_helper_cmpgu_le_ob(cpu_gpr[ret], v1_t, v2_t);
14014 case OPC_CMPU_EQ_OB:
14016 gen_helper_cmpu_eq_ob(v1_t, v2_t, cpu_env);
14018 case OPC_CMPU_LT_OB:
14020 gen_helper_cmpu_lt_ob(v1_t, v2_t, cpu_env);
14022 case OPC_CMPU_LE_OB:
14024 gen_helper_cmpu_le_ob(v1_t, v2_t, cpu_env);
14026 case OPC_PACKRL_PW:
14028 gen_helper_packrl_pw(cpu_gpr[ret], v1_t, v2_t);
14032 gen_helper_pick_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
14036 gen_helper_pick_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
14040 gen_helper_pick_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
14044 case OPC_DAPPEND_DSP:
14047 tcg_gen_movi_i32(t0, v2);
14048 gen_helper_dappend(cpu_gpr[ret], v1_t, cpu_gpr[ret], t0);
14051 tcg_gen_movi_i32(t0, v2);
14052 gen_helper_prependd(cpu_gpr[ret], v1_t, cpu_gpr[ret], t0);
14055 tcg_gen_movi_i32(t0, v2);
14056 gen_helper_prependw(cpu_gpr[ret], v1_t, cpu_gpr[ret], t0);
14059 tcg_gen_movi_i32(t0, v2);
14060 gen_helper_dbalign(cpu_gpr[ret], v1_t, cpu_gpr[ret], t0);
14062 default: /* Invalid */
14063 MIPS_INVAL("MASK DAPPEND");
14064 generate_exception(ctx, EXCP_RI);
14071 tcg_temp_free_i32(t0);
14073 tcg_temp_free(v1_t);
14074 tcg_temp_free(v2_t);
14076 (void)opn; /* avoid a compiler warning */
14077 MIPS_DEBUG("%s", opn);
14080 static void gen_mipsdsp_accinsn(DisasContext *ctx, uint32_t op1, uint32_t op2,
14081 int ret, int v1, int v2, int check_ret)
14084 const char *opn = "mipsdsp accumulator";
14091 if ((ret == 0) && (check_ret == 1)) {
14092 /* Treat as NOP. */
14097 t0 = tcg_temp_new();
14098 t1 = tcg_temp_new();
14099 v1_t = tcg_temp_new();
14100 v2_t = tcg_temp_new();
14102 gen_load_gpr(v1_t, v1);
14103 gen_load_gpr(v2_t, v2);
14106 case OPC_EXTR_W_DSP:
14110 tcg_gen_movi_tl(t0, v2);
14111 tcg_gen_movi_tl(t1, v1);
14112 gen_helper_extr_w(cpu_gpr[ret], t0, t1, cpu_env);
14115 tcg_gen_movi_tl(t0, v2);
14116 tcg_gen_movi_tl(t1, v1);
14117 gen_helper_extr_r_w(cpu_gpr[ret], t0, t1, cpu_env);
14119 case OPC_EXTR_RS_W:
14120 tcg_gen_movi_tl(t0, v2);
14121 tcg_gen_movi_tl(t1, v1);
14122 gen_helper_extr_rs_w(cpu_gpr[ret], t0, t1, cpu_env);
14125 tcg_gen_movi_tl(t0, v2);
14126 tcg_gen_movi_tl(t1, v1);
14127 gen_helper_extr_s_h(cpu_gpr[ret], t0, t1, cpu_env);
14129 case OPC_EXTRV_S_H:
14130 tcg_gen_movi_tl(t0, v2);
14131 gen_helper_extr_s_h(cpu_gpr[ret], t0, v1_t, cpu_env);
14134 tcg_gen_movi_tl(t0, v2);
14135 gen_helper_extr_w(cpu_gpr[ret], t0, v1_t, cpu_env);
14137 case OPC_EXTRV_R_W:
14138 tcg_gen_movi_tl(t0, v2);
14139 gen_helper_extr_r_w(cpu_gpr[ret], t0, v1_t, cpu_env);
14141 case OPC_EXTRV_RS_W:
14142 tcg_gen_movi_tl(t0, v2);
14143 gen_helper_extr_rs_w(cpu_gpr[ret], t0, v1_t, cpu_env);
14146 tcg_gen_movi_tl(t0, v2);
14147 tcg_gen_movi_tl(t1, v1);
14148 gen_helper_extp(cpu_gpr[ret], t0, t1, cpu_env);
14151 tcg_gen_movi_tl(t0, v2);
14152 gen_helper_extp(cpu_gpr[ret], t0, v1_t, cpu_env);
14155 tcg_gen_movi_tl(t0, v2);
14156 tcg_gen_movi_tl(t1, v1);
14157 gen_helper_extpdp(cpu_gpr[ret], t0, t1, cpu_env);
14160 tcg_gen_movi_tl(t0, v2);
14161 gen_helper_extpdp(cpu_gpr[ret], t0, v1_t, cpu_env);
14164 imm = (ctx->opcode >> 20) & 0x3F;
14165 tcg_gen_movi_tl(t0, ret);
14166 tcg_gen_movi_tl(t1, imm);
14167 gen_helper_shilo(t0, t1, cpu_env);
14170 tcg_gen_movi_tl(t0, ret);
14171 gen_helper_shilo(t0, v1_t, cpu_env);
14174 tcg_gen_movi_tl(t0, ret);
14175 gen_helper_mthlip(t0, v1_t, cpu_env);
14178 imm = (ctx->opcode >> 11) & 0x3FF;
14179 tcg_gen_movi_tl(t0, imm);
14180 gen_helper_wrdsp(v1_t, t0, cpu_env);
14183 imm = (ctx->opcode >> 16) & 0x03FF;
14184 tcg_gen_movi_tl(t0, imm);
14185 gen_helper_rddsp(cpu_gpr[ret], t0, cpu_env);
14189 #ifdef TARGET_MIPS64
14190 case OPC_DEXTR_W_DSP:
14194 tcg_gen_movi_tl(t0, ret);
14195 gen_helper_dmthlip(v1_t, t0, cpu_env);
14199 int shift = (ctx->opcode >> 19) & 0x7F;
14200 int ac = (ctx->opcode >> 11) & 0x03;
14201 tcg_gen_movi_tl(t0, shift);
14202 tcg_gen_movi_tl(t1, ac);
14203 gen_helper_dshilo(t0, t1, cpu_env);
14208 int ac = (ctx->opcode >> 11) & 0x03;
14209 tcg_gen_movi_tl(t0, ac);
14210 gen_helper_dshilo(v1_t, t0, cpu_env);
14214 tcg_gen_movi_tl(t0, v2);
14215 tcg_gen_movi_tl(t1, v1);
14217 gen_helper_dextp(cpu_gpr[ret], t0, t1, cpu_env);
14220 tcg_gen_movi_tl(t0, v2);
14221 gen_helper_dextp(cpu_gpr[ret], t0, v1_t, cpu_env);
14224 tcg_gen_movi_tl(t0, v2);
14225 tcg_gen_movi_tl(t1, v1);
14226 gen_helper_dextpdp(cpu_gpr[ret], t0, t1, cpu_env);
14229 tcg_gen_movi_tl(t0, v2);
14230 gen_helper_dextpdp(cpu_gpr[ret], t0, v1_t, cpu_env);
14233 tcg_gen_movi_tl(t0, v2);
14234 tcg_gen_movi_tl(t1, v1);
14235 gen_helper_dextr_l(cpu_gpr[ret], t0, t1, cpu_env);
14237 case OPC_DEXTR_R_L:
14238 tcg_gen_movi_tl(t0, v2);
14239 tcg_gen_movi_tl(t1, v1);
14240 gen_helper_dextr_r_l(cpu_gpr[ret], t0, t1, cpu_env);
14242 case OPC_DEXTR_RS_L:
14243 tcg_gen_movi_tl(t0, v2);
14244 tcg_gen_movi_tl(t1, v1);
14245 gen_helper_dextr_rs_l(cpu_gpr[ret], t0, t1, cpu_env);
14248 tcg_gen_movi_tl(t0, v2);
14249 tcg_gen_movi_tl(t1, v1);
14250 gen_helper_dextr_w(cpu_gpr[ret], t0, t1, cpu_env);
14252 case OPC_DEXTR_R_W:
14253 tcg_gen_movi_tl(t0, v2);
14254 tcg_gen_movi_tl(t1, v1);
14255 gen_helper_dextr_r_w(cpu_gpr[ret], t0, t1, cpu_env);
14257 case OPC_DEXTR_RS_W:
14258 tcg_gen_movi_tl(t0, v2);
14259 tcg_gen_movi_tl(t1, v1);
14260 gen_helper_dextr_rs_w(cpu_gpr[ret], t0, t1, cpu_env);
14262 case OPC_DEXTR_S_H:
14263 tcg_gen_movi_tl(t0, v2);
14264 tcg_gen_movi_tl(t1, v1);
14265 gen_helper_dextr_s_h(cpu_gpr[ret], t0, t1, cpu_env);
14267 case OPC_DEXTRV_S_H:
14268 tcg_gen_movi_tl(t0, v2);
14269 tcg_gen_movi_tl(t1, v1);
14270 gen_helper_dextr_s_h(cpu_gpr[ret], t0, t1, cpu_env);
14273 tcg_gen_movi_tl(t0, v2);
14274 gen_helper_dextr_l(cpu_gpr[ret], t0, v1_t, cpu_env);
14276 case OPC_DEXTRV_R_L:
14277 tcg_gen_movi_tl(t0, v2);
14278 gen_helper_dextr_r_l(cpu_gpr[ret], t0, v1_t, cpu_env);
14280 case OPC_DEXTRV_RS_L:
14281 tcg_gen_movi_tl(t0, v2);
14282 gen_helper_dextr_rs_l(cpu_gpr[ret], t0, v1_t, cpu_env);
14285 tcg_gen_movi_tl(t0, v2);
14286 gen_helper_dextr_w(cpu_gpr[ret], t0, v1_t, cpu_env);
14288 case OPC_DEXTRV_R_W:
14289 tcg_gen_movi_tl(t0, v2);
14290 gen_helper_dextr_r_w(cpu_gpr[ret], t0, v1_t, cpu_env);
14292 case OPC_DEXTRV_RS_W:
14293 tcg_gen_movi_tl(t0, v2);
14294 gen_helper_dextr_rs_w(cpu_gpr[ret], t0, v1_t, cpu_env);
14303 tcg_temp_free(v1_t);
14304 tcg_temp_free(v2_t);
14306 (void)opn; /* avoid a compiler warning */
14307 MIPS_DEBUG("%s", opn);
14310 /* End MIPSDSP functions. */
14312 static void decode_opc (CPUMIPSState *env, DisasContext *ctx, int *is_branch)
14315 int rs, rt, rd, sa;
14316 uint32_t op, op1, op2;
14319 /* make sure instructions are on a word boundary */
14320 if (ctx->pc & 0x3) {
14321 env->CP0_BadVAddr = ctx->pc;
14322 generate_exception(ctx, EXCP_AdEL);
14326 /* Handle blikely not taken case */
14327 if ((ctx->hflags & MIPS_HFLAG_BMASK_BASE) == MIPS_HFLAG_BL) {
14328 int l1 = gen_new_label();
14330 MIPS_DEBUG("blikely condition (" TARGET_FMT_lx ")", ctx->pc + 4);
14331 tcg_gen_brcondi_tl(TCG_COND_NE, bcond, 0, l1);
14332 tcg_gen_movi_i32(hflags, ctx->hflags & ~MIPS_HFLAG_BMASK);
14333 gen_goto_tb(ctx, 1, ctx->pc + 4);
14337 if (unlikely(qemu_loglevel_mask(CPU_LOG_TB_OP | CPU_LOG_TB_OP_OPT))) {
14338 tcg_gen_debug_insn_start(ctx->pc);
14341 op = MASK_OP_MAJOR(ctx->opcode);
14342 rs = (ctx->opcode >> 21) & 0x1f;
14343 rt = (ctx->opcode >> 16) & 0x1f;
14344 rd = (ctx->opcode >> 11) & 0x1f;
14345 sa = (ctx->opcode >> 6) & 0x1f;
14346 imm = (int16_t)ctx->opcode;
14349 op1 = MASK_SPECIAL(ctx->opcode);
14351 case OPC_SLL: /* Shift with immediate */
14353 gen_shift_imm(env, ctx, op1, rd, rt, sa);
14356 switch ((ctx->opcode >> 21) & 0x1f) {
14358 /* rotr is decoded as srl on non-R2 CPUs */
14359 if (env->insn_flags & ISA_MIPS32R2) {
14364 gen_shift_imm(env, ctx, op1, rd, rt, sa);
14367 generate_exception(ctx, EXCP_RI);
14371 case OPC_MOVN: /* Conditional move */
14373 check_insn(env, ctx, ISA_MIPS4 | ISA_MIPS32 |
14374 INSN_LOONGSON2E | INSN_LOONGSON2F);
14375 gen_cond_move(env, ctx, op1, rd, rs, rt);
14377 case OPC_ADD ... OPC_SUBU:
14378 gen_arith(env, ctx, op1, rd, rs, rt);
14380 case OPC_SLLV: /* Shifts */
14382 gen_shift(env, ctx, op1, rd, rs, rt);
14385 switch ((ctx->opcode >> 6) & 0x1f) {
14387 /* rotrv is decoded as srlv on non-R2 CPUs */
14388 if (env->insn_flags & ISA_MIPS32R2) {
14393 gen_shift(env, ctx, op1, rd, rs, rt);
14396 generate_exception(ctx, EXCP_RI);
14400 case OPC_SLT: /* Set on less than */
14402 gen_slt(env, ctx, op1, rd, rs, rt);
14404 case OPC_AND: /* Logic*/
14408 gen_logic(env, ctx, op1, rd, rs, rt);
14410 case OPC_MULT ... OPC_DIVU:
14412 check_insn(env, ctx, INSN_VR54XX);
14413 op1 = MASK_MUL_VR54XX(ctx->opcode);
14414 gen_mul_vr54xx(ctx, op1, rd, rs, rt);
14416 gen_muldiv(ctx, op1, rs, rt);
14418 case OPC_JR ... OPC_JALR:
14419 gen_compute_branch(ctx, op1, 4, rs, rd, sa);
14422 case OPC_TGE ... OPC_TEQ: /* Traps */
14424 gen_trap(ctx, op1, rs, rt, -1);
14426 case OPC_MFHI: /* Move from HI/LO */
14428 gen_HILO(ctx, op1, rd);
14431 case OPC_MTLO: /* Move to HI/LO */
14432 gen_HILO(ctx, op1, rs);
14434 case OPC_PMON: /* Pmon entry point, also R4010 selsl */
14435 #ifdef MIPS_STRICT_STANDARD
14436 MIPS_INVAL("PMON / selsl");
14437 generate_exception(ctx, EXCP_RI);
14439 gen_helper_0e0i(pmon, sa);
14443 generate_exception(ctx, EXCP_SYSCALL);
14444 ctx->bstate = BS_STOP;
14447 generate_exception(ctx, EXCP_BREAK);
14450 #ifdef MIPS_STRICT_STANDARD
14451 MIPS_INVAL("SPIM");
14452 generate_exception(ctx, EXCP_RI);
14454 /* Implemented as RI exception for now. */
14455 MIPS_INVAL("spim (unofficial)");
14456 generate_exception(ctx, EXCP_RI);
14460 /* Treat as NOP. */
14464 check_insn(env, ctx, ISA_MIPS4 | ISA_MIPS32);
14465 if (env->CP0_Config1 & (1 << CP0C1_FP)) {
14466 check_cp1_enabled(ctx);
14467 gen_movci(ctx, rd, rs, (ctx->opcode >> 18) & 0x7,
14468 (ctx->opcode >> 16) & 1);
14470 generate_exception_err(ctx, EXCP_CpU, 1);
14474 #if defined(TARGET_MIPS64)
14475 /* MIPS64 specific opcodes */
14480 check_insn(env, ctx, ISA_MIPS3);
14481 check_mips_64(ctx);
14482 gen_shift_imm(env, ctx, op1, rd, rt, sa);
14485 switch ((ctx->opcode >> 21) & 0x1f) {
14487 /* drotr is decoded as dsrl on non-R2 CPUs */
14488 if (env->insn_flags & ISA_MIPS32R2) {
14493 check_insn(env, ctx, ISA_MIPS3);
14494 check_mips_64(ctx);
14495 gen_shift_imm(env, ctx, op1, rd, rt, sa);
14498 generate_exception(ctx, EXCP_RI);
14503 switch ((ctx->opcode >> 21) & 0x1f) {
14505 /* drotr32 is decoded as dsrl32 on non-R2 CPUs */
14506 if (env->insn_flags & ISA_MIPS32R2) {
14511 check_insn(env, ctx, ISA_MIPS3);
14512 check_mips_64(ctx);
14513 gen_shift_imm(env, ctx, op1, rd, rt, sa);
14516 generate_exception(ctx, EXCP_RI);
14520 case OPC_DADD ... OPC_DSUBU:
14521 check_insn(env, ctx, ISA_MIPS3);
14522 check_mips_64(ctx);
14523 gen_arith(env, ctx, op1, rd, rs, rt);
14527 check_insn(env, ctx, ISA_MIPS3);
14528 check_mips_64(ctx);
14529 gen_shift(env, ctx, op1, rd, rs, rt);
14532 switch ((ctx->opcode >> 6) & 0x1f) {
14534 /* drotrv is decoded as dsrlv on non-R2 CPUs */
14535 if (env->insn_flags & ISA_MIPS32R2) {
14540 check_insn(env, ctx, ISA_MIPS3);
14541 check_mips_64(ctx);
14542 gen_shift(env, ctx, op1, rd, rs, rt);
14545 generate_exception(ctx, EXCP_RI);
14549 case OPC_DMULT ... OPC_DDIVU:
14550 check_insn(env, ctx, ISA_MIPS3);
14551 check_mips_64(ctx);
14552 gen_muldiv(ctx, op1, rs, rt);
14555 default: /* Invalid */
14556 MIPS_INVAL("special");
14557 generate_exception(ctx, EXCP_RI);
14562 op1 = MASK_SPECIAL2(ctx->opcode);
14564 case OPC_MADD ... OPC_MADDU: /* Multiply and add/sub */
14565 case OPC_MSUB ... OPC_MSUBU:
14566 check_insn(env, ctx, ISA_MIPS32);
14567 gen_muldiv(ctx, op1, rs, rt);
14570 gen_arith(env, ctx, op1, rd, rs, rt);
14574 check_insn(env, ctx, ISA_MIPS32);
14575 gen_cl(ctx, op1, rd, rs);
14578 /* XXX: not clear which exception should be raised
14579 * when in debug mode...
14581 check_insn(env, ctx, ISA_MIPS32);
14582 if (!(ctx->hflags & MIPS_HFLAG_DM)) {
14583 generate_exception(ctx, EXCP_DBp);
14585 generate_exception(ctx, EXCP_DBp);
14587 /* Treat as NOP. */
14590 case OPC_DIVU_G_2F:
14591 case OPC_MULT_G_2F:
14592 case OPC_MULTU_G_2F:
14594 case OPC_MODU_G_2F:
14595 check_insn(env, ctx, INSN_LOONGSON2F);
14596 gen_loongson_integer(ctx, op1, rd, rs, rt);
14598 #if defined(TARGET_MIPS64)
14601 check_insn(env, ctx, ISA_MIPS64);
14602 check_mips_64(ctx);
14603 gen_cl(ctx, op1, rd, rs);
14605 case OPC_DMULT_G_2F:
14606 case OPC_DMULTU_G_2F:
14607 case OPC_DDIV_G_2F:
14608 case OPC_DDIVU_G_2F:
14609 case OPC_DMOD_G_2F:
14610 case OPC_DMODU_G_2F:
14611 check_insn(env, ctx, INSN_LOONGSON2F);
14612 gen_loongson_integer(ctx, op1, rd, rs, rt);
14615 default: /* Invalid */
14616 MIPS_INVAL("special2");
14617 generate_exception(ctx, EXCP_RI);
14622 op1 = MASK_SPECIAL3(ctx->opcode);
14626 check_insn(env, ctx, ISA_MIPS32R2);
14627 gen_bitops(ctx, op1, rt, rs, sa, rd);
14630 check_insn(env, ctx, ISA_MIPS32R2);
14631 op2 = MASK_BSHFL(ctx->opcode);
14632 gen_bshfl(ctx, op2, rt, rd);
14635 gen_rdhwr(env, ctx, rt, rd);
14638 check_insn(env, ctx, ASE_MT);
14640 TCGv t0 = tcg_temp_new();
14641 TCGv t1 = tcg_temp_new();
14643 gen_load_gpr(t0, rt);
14644 gen_load_gpr(t1, rs);
14645 gen_helper_fork(t0, t1);
14651 check_insn(env, ctx, ASE_MT);
14653 TCGv t0 = tcg_temp_new();
14655 save_cpu_state(ctx, 1);
14656 gen_load_gpr(t0, rs);
14657 gen_helper_yield(t0, cpu_env, t0);
14658 gen_store_gpr(t0, rd);
14662 case OPC_DIV_G_2E ... OPC_DIVU_G_2E:
14663 case OPC_MOD_G_2E ... OPC_MODU_G_2E:
14664 case OPC_MULT_G_2E ... OPC_MULTU_G_2E:
14665 /* OPC_MULT_G_2E, OPC_ADDUH_QB_DSP, OPC_MUL_PH_DSP have
14666 * the same mask and op1. */
14667 if ((env->insn_flags & ASE_DSPR2) && (op1 == OPC_MULT_G_2E)) {
14668 op2 = MASK_ADDUH_QB(ctx->opcode);
14671 case OPC_ADDUH_R_QB:
14673 case OPC_ADDQH_R_PH:
14675 case OPC_ADDQH_R_W:
14677 case OPC_SUBUH_R_QB:
14679 case OPC_SUBQH_R_PH:
14681 case OPC_SUBQH_R_W:
14682 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
14687 case OPC_MULQ_RS_W:
14688 gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 1);
14691 MIPS_INVAL("MASK ADDUH.QB");
14692 generate_exception(ctx, EXCP_RI);
14695 } else if (env->insn_flags & INSN_LOONGSON2E) {
14696 gen_loongson_integer(ctx, op1, rd, rs, rt);
14698 generate_exception(ctx, EXCP_RI);
14702 op2 = MASK_LX(ctx->opcode);
14704 #if defined(TARGET_MIPS64)
14710 gen_mipsdsp_ld(env, ctx, op2, rd, rs, rt);
14712 default: /* Invalid */
14713 MIPS_INVAL("MASK LX");
14714 generate_exception(ctx, EXCP_RI);
14718 case OPC_ABSQ_S_PH_DSP:
14719 op2 = MASK_ABSQ_S_PH(ctx->opcode);
14721 case OPC_ABSQ_S_QB:
14722 case OPC_ABSQ_S_PH:
14724 case OPC_PRECEQ_W_PHL:
14725 case OPC_PRECEQ_W_PHR:
14726 case OPC_PRECEQU_PH_QBL:
14727 case OPC_PRECEQU_PH_QBR:
14728 case OPC_PRECEQU_PH_QBLA:
14729 case OPC_PRECEQU_PH_QBRA:
14730 case OPC_PRECEU_PH_QBL:
14731 case OPC_PRECEU_PH_QBR:
14732 case OPC_PRECEU_PH_QBLA:
14733 case OPC_PRECEU_PH_QBRA:
14734 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
14741 gen_mipsdsp_bitinsn(env, ctx, op1, op2, rd, rt);
14744 MIPS_INVAL("MASK ABSQ_S.PH");
14745 generate_exception(ctx, EXCP_RI);
14749 case OPC_ADDU_QB_DSP:
14750 op2 = MASK_ADDU_QB(ctx->opcode);
14753 case OPC_ADDQ_S_PH:
14756 case OPC_ADDU_S_QB:
14758 case OPC_ADDU_S_PH:
14760 case OPC_SUBQ_S_PH:
14763 case OPC_SUBU_S_QB:
14765 case OPC_SUBU_S_PH:
14769 case OPC_RADDU_W_QB:
14770 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
14772 case OPC_MULEU_S_PH_QBL:
14773 case OPC_MULEU_S_PH_QBR:
14774 case OPC_MULQ_RS_PH:
14775 case OPC_MULEQ_S_W_PHL:
14776 case OPC_MULEQ_S_W_PHR:
14777 case OPC_MULQ_S_PH:
14778 gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 1);
14780 default: /* Invalid */
14781 MIPS_INVAL("MASK ADDU.QB");
14782 generate_exception(ctx, EXCP_RI);
14787 case OPC_CMPU_EQ_QB_DSP:
14788 op2 = MASK_CMPU_EQ_QB(ctx->opcode);
14790 case OPC_PRECR_SRA_PH_W:
14791 case OPC_PRECR_SRA_R_PH_W:
14792 gen_mipsdsp_arith(ctx, op1, op2, rt, rs, rd);
14794 case OPC_PRECR_QB_PH:
14795 case OPC_PRECRQ_QB_PH:
14796 case OPC_PRECRQ_PH_W:
14797 case OPC_PRECRQ_RS_PH_W:
14798 case OPC_PRECRQU_S_QB_PH:
14799 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
14801 case OPC_CMPU_EQ_QB:
14802 case OPC_CMPU_LT_QB:
14803 case OPC_CMPU_LE_QB:
14804 case OPC_CMP_EQ_PH:
14805 case OPC_CMP_LT_PH:
14806 case OPC_CMP_LE_PH:
14807 gen_mipsdsp_add_cmp_pick(ctx, op1, op2, rd, rs, rt, 0);
14809 case OPC_CMPGU_EQ_QB:
14810 case OPC_CMPGU_LT_QB:
14811 case OPC_CMPGU_LE_QB:
14812 case OPC_CMPGDU_EQ_QB:
14813 case OPC_CMPGDU_LT_QB:
14814 case OPC_CMPGDU_LE_QB:
14817 case OPC_PACKRL_PH:
14818 gen_mipsdsp_add_cmp_pick(ctx, op1, op2, rd, rs, rt, 1);
14820 default: /* Invalid */
14821 MIPS_INVAL("MASK CMPU.EQ.QB");
14822 generate_exception(ctx, EXCP_RI);
14826 case OPC_SHLL_QB_DSP:
14827 gen_mipsdsp_shift(ctx, op1, rd, rs, rt);
14829 case OPC_DPA_W_PH_DSP:
14830 op2 = MASK_DPA_W_PH(ctx->opcode);
14832 case OPC_DPAU_H_QBL:
14833 case OPC_DPAU_H_QBR:
14834 case OPC_DPSU_H_QBL:
14835 case OPC_DPSU_H_QBR:
14837 case OPC_DPAX_W_PH:
14838 case OPC_DPAQ_S_W_PH:
14839 case OPC_DPAQX_S_W_PH:
14840 case OPC_DPAQX_SA_W_PH:
14842 case OPC_DPSX_W_PH:
14843 case OPC_DPSQ_S_W_PH:
14844 case OPC_DPSQX_S_W_PH:
14845 case OPC_DPSQX_SA_W_PH:
14846 case OPC_MULSAQ_S_W_PH:
14847 case OPC_DPAQ_SA_L_W:
14848 case OPC_DPSQ_SA_L_W:
14849 case OPC_MAQ_S_W_PHL:
14850 case OPC_MAQ_S_W_PHR:
14851 case OPC_MAQ_SA_W_PHL:
14852 case OPC_MAQ_SA_W_PHR:
14853 case OPC_MULSA_W_PH:
14854 gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 0);
14856 default: /* Invalid */
14857 MIPS_INVAL("MASK DPAW.PH");
14858 generate_exception(ctx, EXCP_RI);
14863 op2 = MASK_INSV(ctx->opcode);
14875 t0 = tcg_temp_new();
14876 t1 = tcg_temp_new();
14878 gen_load_gpr(t0, rt);
14879 gen_load_gpr(t1, rs);
14881 gen_helper_insv(cpu_gpr[rt], cpu_env, t1, t0);
14887 default: /* Invalid */
14888 MIPS_INVAL("MASK INSV");
14889 generate_exception(ctx, EXCP_RI);
14893 case OPC_APPEND_DSP:
14895 op2 = MASK_APPEND(ctx->opcode);
14896 gen_mipsdsp_add_cmp_pick(ctx, op1, op2, rt, rs, rd, 1);
14898 case OPC_EXTR_W_DSP:
14899 op2 = MASK_EXTR_W(ctx->opcode);
14903 case OPC_EXTR_RS_W:
14905 case OPC_EXTRV_S_H:
14907 case OPC_EXTRV_R_W:
14908 case OPC_EXTRV_RS_W:
14913 gen_mipsdsp_accinsn(ctx, op1, op2, rt, rs, rd, 1);
14916 gen_mipsdsp_accinsn(ctx, op1, op2, rd, rs, rt, 1);
14922 gen_mipsdsp_accinsn(ctx, op1, op2, rd, rs, rt, 0);
14924 default: /* Invalid */
14925 MIPS_INVAL("MASK EXTR.W");
14926 generate_exception(ctx, EXCP_RI);
14930 #if defined(TARGET_MIPS64)
14931 case OPC_DEXTM ... OPC_DEXT:
14932 case OPC_DINSM ... OPC_DINS:
14933 check_insn(env, ctx, ISA_MIPS64R2);
14934 check_mips_64(ctx);
14935 gen_bitops(ctx, op1, rt, rs, sa, rd);
14938 check_insn(env, ctx, ISA_MIPS64R2);
14939 check_mips_64(ctx);
14940 op2 = MASK_DBSHFL(ctx->opcode);
14941 gen_bshfl(ctx, op2, rt, rd);
14943 case OPC_DDIV_G_2E ... OPC_DDIVU_G_2E:
14944 case OPC_DMULT_G_2E ... OPC_DMULTU_G_2E:
14945 case OPC_DMOD_G_2E ... OPC_DMODU_G_2E:
14946 check_insn(env, ctx, INSN_LOONGSON2E);
14947 gen_loongson_integer(ctx, op1, rd, rs, rt);
14949 case OPC_ABSQ_S_QH_DSP:
14950 op2 = MASK_ABSQ_S_QH(ctx->opcode);
14952 case OPC_PRECEQ_L_PWL:
14953 case OPC_PRECEQ_L_PWR:
14954 case OPC_PRECEQ_PW_QHL:
14955 case OPC_PRECEQ_PW_QHR:
14956 case OPC_PRECEQ_PW_QHLA:
14957 case OPC_PRECEQ_PW_QHRA:
14958 case OPC_PRECEQU_QH_OBL:
14959 case OPC_PRECEQU_QH_OBR:
14960 case OPC_PRECEQU_QH_OBLA:
14961 case OPC_PRECEQU_QH_OBRA:
14962 case OPC_PRECEU_QH_OBL:
14963 case OPC_PRECEU_QH_OBR:
14964 case OPC_PRECEU_QH_OBLA:
14965 case OPC_PRECEU_QH_OBRA:
14966 case OPC_ABSQ_S_OB:
14967 case OPC_ABSQ_S_PW:
14968 case OPC_ABSQ_S_QH:
14969 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
14977 gen_mipsdsp_bitinsn(env, ctx, op1, op2, rd, rt);
14979 default: /* Invalid */
14980 MIPS_INVAL("MASK ABSQ_S.QH");
14981 generate_exception(ctx, EXCP_RI);
14985 case OPC_ADDU_OB_DSP:
14986 op2 = MASK_ADDU_OB(ctx->opcode);
14988 case OPC_RADDU_L_OB:
14990 case OPC_SUBQ_S_PW:
14992 case OPC_SUBQ_S_QH:
14994 case OPC_SUBU_S_OB:
14996 case OPC_SUBU_S_QH:
14998 case OPC_SUBUH_R_OB:
15000 case OPC_ADDQ_S_PW:
15002 case OPC_ADDQ_S_QH:
15004 case OPC_ADDU_S_OB:
15006 case OPC_ADDU_S_QH:
15008 case OPC_ADDUH_R_OB:
15009 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
15011 case OPC_MULEQ_S_PW_QHL:
15012 case OPC_MULEQ_S_PW_QHR:
15013 case OPC_MULEU_S_QH_OBL:
15014 case OPC_MULEU_S_QH_OBR:
15015 case OPC_MULQ_RS_QH:
15016 gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 1);
15018 default: /* Invalid */
15019 MIPS_INVAL("MASK ADDU.OB");
15020 generate_exception(ctx, EXCP_RI);
15024 case OPC_CMPU_EQ_OB_DSP:
15025 op2 = MASK_CMPU_EQ_OB(ctx->opcode);
15027 case OPC_PRECR_SRA_QH_PW:
15028 case OPC_PRECR_SRA_R_QH_PW:
15029 /* Return value is rt. */
15030 gen_mipsdsp_arith(ctx, op1, op2, rt, rs, rd);
15032 case OPC_PRECR_OB_QH:
15033 case OPC_PRECRQ_OB_QH:
15034 case OPC_PRECRQ_PW_L:
15035 case OPC_PRECRQ_QH_PW:
15036 case OPC_PRECRQ_RS_QH_PW:
15037 case OPC_PRECRQU_S_OB_QH:
15038 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
15040 case OPC_CMPU_EQ_OB:
15041 case OPC_CMPU_LT_OB:
15042 case OPC_CMPU_LE_OB:
15043 case OPC_CMP_EQ_QH:
15044 case OPC_CMP_LT_QH:
15045 case OPC_CMP_LE_QH:
15046 case OPC_CMP_EQ_PW:
15047 case OPC_CMP_LT_PW:
15048 case OPC_CMP_LE_PW:
15049 gen_mipsdsp_add_cmp_pick(ctx, op1, op2, rd, rs, rt, 0);
15051 case OPC_CMPGDU_EQ_OB:
15052 case OPC_CMPGDU_LT_OB:
15053 case OPC_CMPGDU_LE_OB:
15054 case OPC_CMPGU_EQ_OB:
15055 case OPC_CMPGU_LT_OB:
15056 case OPC_CMPGU_LE_OB:
15057 case OPC_PACKRL_PW:
15061 gen_mipsdsp_add_cmp_pick(ctx, op1, op2, rd, rs, rt, 1);
15063 default: /* Invalid */
15064 MIPS_INVAL("MASK CMPU_EQ.OB");
15065 generate_exception(ctx, EXCP_RI);
15069 case OPC_DAPPEND_DSP:
15071 op2 = MASK_DAPPEND(ctx->opcode);
15072 gen_mipsdsp_add_cmp_pick(ctx, op1, op2, rt, rs, rd, 1);
15074 case OPC_DEXTR_W_DSP:
15075 op2 = MASK_DEXTR_W(ctx->opcode);
15082 case OPC_DEXTR_R_L:
15083 case OPC_DEXTR_RS_L:
15085 case OPC_DEXTR_R_W:
15086 case OPC_DEXTR_RS_W:
15087 case OPC_DEXTR_S_H:
15089 case OPC_DEXTRV_R_L:
15090 case OPC_DEXTRV_RS_L:
15091 case OPC_DEXTRV_S_H:
15093 case OPC_DEXTRV_R_W:
15094 case OPC_DEXTRV_RS_W:
15095 gen_mipsdsp_accinsn(ctx, op1, op2, rt, rs, rd, 1);
15100 gen_mipsdsp_accinsn(ctx, op1, op2, rd, rs, rt, 0);
15102 default: /* Invalid */
15103 MIPS_INVAL("MASK EXTR.W");
15104 generate_exception(ctx, EXCP_RI);
15108 case OPC_DPAQ_W_QH_DSP:
15109 op2 = MASK_DPAQ_W_QH(ctx->opcode);
15111 case OPC_DPAU_H_OBL:
15112 case OPC_DPAU_H_OBR:
15113 case OPC_DPSU_H_OBL:
15114 case OPC_DPSU_H_OBR:
15116 case OPC_DPAQ_S_W_QH:
15118 case OPC_DPSQ_S_W_QH:
15119 case OPC_MULSAQ_S_W_QH:
15120 case OPC_DPAQ_SA_L_PW:
15121 case OPC_DPSQ_SA_L_PW:
15122 case OPC_MULSAQ_S_L_PW:
15123 gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 0);
15125 case OPC_MAQ_S_W_QHLL:
15126 case OPC_MAQ_S_W_QHLR:
15127 case OPC_MAQ_S_W_QHRL:
15128 case OPC_MAQ_S_W_QHRR:
15129 case OPC_MAQ_SA_W_QHLL:
15130 case OPC_MAQ_SA_W_QHLR:
15131 case OPC_MAQ_SA_W_QHRL:
15132 case OPC_MAQ_SA_W_QHRR:
15133 case OPC_MAQ_S_L_PWL:
15134 case OPC_MAQ_S_L_PWR:
15139 gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 0);
15141 default: /* Invalid */
15142 MIPS_INVAL("MASK DPAQ.W.QH");
15143 generate_exception(ctx, EXCP_RI);
15147 case OPC_DINSV_DSP:
15148 op2 = MASK_INSV(ctx->opcode);
15160 t0 = tcg_temp_new();
15161 t1 = tcg_temp_new();
15163 gen_load_gpr(t0, rt);
15164 gen_load_gpr(t1, rs);
15166 gen_helper_dinsv(cpu_gpr[rt], cpu_env, t1, t0);
15169 default: /* Invalid */
15170 MIPS_INVAL("MASK DINSV");
15171 generate_exception(ctx, EXCP_RI);
15175 case OPC_SHLL_OB_DSP:
15176 gen_mipsdsp_shift(ctx, op1, rd, rs, rt);
15179 default: /* Invalid */
15180 MIPS_INVAL("special3");
15181 generate_exception(ctx, EXCP_RI);
15186 op1 = MASK_REGIMM(ctx->opcode);
15188 case OPC_BLTZ ... OPC_BGEZL: /* REGIMM branches */
15189 case OPC_BLTZAL ... OPC_BGEZALL:
15190 gen_compute_branch(ctx, op1, 4, rs, -1, imm << 2);
15193 case OPC_TGEI ... OPC_TEQI: /* REGIMM traps */
15195 gen_trap(ctx, op1, rs, -1, imm);
15198 check_insn(env, ctx, ISA_MIPS32R2);
15199 /* Treat as NOP. */
15201 case OPC_BPOSGE32: /* MIPS DSP branch */
15202 #if defined(TARGET_MIPS64)
15206 gen_compute_branch(ctx, op1, 4, -1, -2, (int32_t)imm << 2);
15209 default: /* Invalid */
15210 MIPS_INVAL("regimm");
15211 generate_exception(ctx, EXCP_RI);
15216 check_cp0_enabled(ctx);
15217 op1 = MASK_CP0(ctx->opcode);
15223 #if defined(TARGET_MIPS64)
15227 #ifndef CONFIG_USER_ONLY
15228 gen_cp0(env, ctx, op1, rt, rd);
15229 #endif /* !CONFIG_USER_ONLY */
15231 case OPC_C0_FIRST ... OPC_C0_LAST:
15232 #ifndef CONFIG_USER_ONLY
15233 gen_cp0(env, ctx, MASK_C0(ctx->opcode), rt, rd);
15234 #endif /* !CONFIG_USER_ONLY */
15237 #ifndef CONFIG_USER_ONLY
15239 TCGv t0 = tcg_temp_new();
15241 op2 = MASK_MFMC0(ctx->opcode);
15244 check_insn(env, ctx, ASE_MT);
15245 gen_helper_dmt(t0);
15246 gen_store_gpr(t0, rt);
15249 check_insn(env, ctx, ASE_MT);
15250 gen_helper_emt(t0);
15251 gen_store_gpr(t0, rt);
15254 check_insn(env, ctx, ASE_MT);
15255 gen_helper_dvpe(t0, cpu_env);
15256 gen_store_gpr(t0, rt);
15259 check_insn(env, ctx, ASE_MT);
15260 gen_helper_evpe(t0, cpu_env);
15261 gen_store_gpr(t0, rt);
15264 check_insn(env, ctx, ISA_MIPS32R2);
15265 save_cpu_state(ctx, 1);
15266 gen_helper_di(t0, cpu_env);
15267 gen_store_gpr(t0, rt);
15268 /* Stop translation as we may have switched the execution mode */
15269 ctx->bstate = BS_STOP;
15272 check_insn(env, ctx, ISA_MIPS32R2);
15273 save_cpu_state(ctx, 1);
15274 gen_helper_ei(t0, cpu_env);
15275 gen_store_gpr(t0, rt);
15276 /* Stop translation as we may have switched the execution mode */
15277 ctx->bstate = BS_STOP;
15279 default: /* Invalid */
15280 MIPS_INVAL("mfmc0");
15281 generate_exception(ctx, EXCP_RI);
15286 #endif /* !CONFIG_USER_ONLY */
15289 check_insn(env, ctx, ISA_MIPS32R2);
15290 gen_load_srsgpr(rt, rd);
15293 check_insn(env, ctx, ISA_MIPS32R2);
15294 gen_store_srsgpr(rt, rd);
15298 generate_exception(ctx, EXCP_RI);
15302 case OPC_ADDI: /* Arithmetic with immediate opcode */
15304 gen_arith_imm(env, ctx, op, rt, rs, imm);
15306 case OPC_SLTI: /* Set on less than with immediate opcode */
15308 gen_slt_imm(env, ctx, op, rt, rs, imm);
15310 case OPC_ANDI: /* Arithmetic with immediate opcode */
15314 gen_logic_imm(env, ctx, op, rt, rs, imm);
15316 case OPC_J ... OPC_JAL: /* Jump */
15317 offset = (int32_t)(ctx->opcode & 0x3FFFFFF) << 2;
15318 gen_compute_branch(ctx, op, 4, rs, rt, offset);
15321 case OPC_BEQ ... OPC_BGTZ: /* Branch */
15322 case OPC_BEQL ... OPC_BGTZL:
15323 gen_compute_branch(ctx, op, 4, rs, rt, imm << 2);
15326 case OPC_LB ... OPC_LWR: /* Load and stores */
15328 gen_ld(env, ctx, op, rt, rs, imm);
15330 case OPC_SB ... OPC_SW:
15332 gen_st(ctx, op, rt, rs, imm);
15335 gen_st_cond(ctx, op, rt, rs, imm);
15338 check_cp0_enabled(ctx);
15339 check_insn(env, ctx, ISA_MIPS3 | ISA_MIPS32);
15340 /* Treat as NOP. */
15343 check_insn(env, ctx, ISA_MIPS4 | ISA_MIPS32);
15344 /* Treat as NOP. */
15347 /* Floating point (COP1). */
15352 gen_cop1_ldst(env, ctx, op, rt, rs, imm);
15356 if (env->CP0_Config1 & (1 << CP0C1_FP)) {
15357 check_cp1_enabled(ctx);
15358 op1 = MASK_CP1(ctx->opcode);
15362 check_insn(env, ctx, ISA_MIPS32R2);
15367 gen_cp1(ctx, op1, rt, rd);
15369 #if defined(TARGET_MIPS64)
15372 check_insn(env, ctx, ISA_MIPS3);
15373 gen_cp1(ctx, op1, rt, rd);
15379 check_insn(env, ctx, ASE_MIPS3D);
15382 gen_compute_branch1(env, ctx, MASK_BC1(ctx->opcode),
15383 (rt >> 2) & 0x7, imm << 2);
15391 gen_farith(ctx, ctx->opcode & FOP(0x3f, 0x1f), rt, rd, sa,
15396 generate_exception (ctx, EXCP_RI);
15400 generate_exception_err(ctx, EXCP_CpU, 1);
15409 /* COP2: Not implemented. */
15410 generate_exception_err(ctx, EXCP_CpU, 2);
15413 check_insn(env, ctx, INSN_LOONGSON2F);
15414 /* Note that these instructions use different fields. */
15415 gen_loongson_multimedia(ctx, sa, rd, rt);
15419 if (env->CP0_Config1 & (1 << CP0C1_FP)) {
15420 check_cp1_enabled(ctx);
15421 op1 = MASK_CP3(ctx->opcode);
15429 gen_flt3_ldst(ctx, op1, sa, rd, rs, rt);
15432 /* Treat as NOP. */
15447 gen_flt3_arith(ctx, op1, sa, rs, rd, rt);
15451 generate_exception (ctx, EXCP_RI);
15455 generate_exception_err(ctx, EXCP_CpU, 1);
15459 #if defined(TARGET_MIPS64)
15460 /* MIPS64 opcodes */
15462 case OPC_LDL ... OPC_LDR:
15465 check_insn(env, ctx, ISA_MIPS3);
15466 check_mips_64(ctx);
15467 gen_ld(env, ctx, op, rt, rs, imm);
15469 case OPC_SDL ... OPC_SDR:
15471 check_insn(env, ctx, ISA_MIPS3);
15472 check_mips_64(ctx);
15473 gen_st(ctx, op, rt, rs, imm);
15476 check_insn(env, ctx, ISA_MIPS3);
15477 check_mips_64(ctx);
15478 gen_st_cond(ctx, op, rt, rs, imm);
15482 check_insn(env, ctx, ISA_MIPS3);
15483 check_mips_64(ctx);
15484 gen_arith_imm(env, ctx, op, rt, rs, imm);
15488 check_insn(env, ctx, ASE_MIPS16 | ASE_MICROMIPS);
15489 offset = (int32_t)(ctx->opcode & 0x3FFFFFF) << 2;
15490 gen_compute_branch(ctx, op, 4, rs, rt, offset);
15494 check_insn(env, ctx, ASE_MDMX);
15495 /* MDMX: Not implemented. */
15496 default: /* Invalid */
15497 MIPS_INVAL("major opcode");
15498 generate_exception(ctx, EXCP_RI);
15504 gen_intermediate_code_internal (CPUMIPSState *env, TranslationBlock *tb,
15508 target_ulong pc_start;
15509 uint16_t *gen_opc_end;
15518 qemu_log("search pc %d\n", search_pc);
15521 gen_opc_end = gen_opc_buf + OPC_MAX_SIZE;
15524 ctx.singlestep_enabled = env->singlestep_enabled;
15526 ctx.bstate = BS_NONE;
15527 /* Restore delay slot state from the tb context. */
15528 ctx.hflags = (uint32_t)tb->flags; /* FIXME: maybe use 64 bits here? */
15529 restore_cpu_state(env, &ctx);
15530 #ifdef CONFIG_USER_ONLY
15531 ctx.mem_idx = MIPS_HFLAG_UM;
15533 ctx.mem_idx = ctx.hflags & MIPS_HFLAG_KSU;
15536 max_insns = tb->cflags & CF_COUNT_MASK;
15537 if (max_insns == 0)
15538 max_insns = CF_COUNT_MASK;
15539 LOG_DISAS("\ntb %p idx %d hflags %04x\n", tb, ctx.mem_idx, ctx.hflags);
15540 gen_icount_start();
15541 while (ctx.bstate == BS_NONE) {
15542 if (unlikely(!QTAILQ_EMPTY(&env->breakpoints))) {
15543 QTAILQ_FOREACH(bp, &env->breakpoints, entry) {
15544 if (bp->pc == ctx.pc) {
15545 save_cpu_state(&ctx, 1);
15546 ctx.bstate = BS_BRANCH;
15547 gen_helper_0e0i(raise_exception, EXCP_DEBUG);
15548 /* Include the breakpoint location or the tb won't
15549 * be flushed when it must be. */
15551 goto done_generating;
15557 j = gen_opc_ptr - gen_opc_buf;
15561 gen_opc_instr_start[lj++] = 0;
15563 gen_opc_pc[lj] = ctx.pc;
15564 gen_opc_hflags[lj] = ctx.hflags & MIPS_HFLAG_BMASK;
15565 gen_opc_btarget[lj] = ctx.btarget;
15566 gen_opc_instr_start[lj] = 1;
15567 gen_opc_icount[lj] = num_insns;
15569 if (num_insns + 1 == max_insns && (tb->cflags & CF_LAST_IO))
15573 if (!(ctx.hflags & MIPS_HFLAG_M16)) {
15574 ctx.opcode = cpu_ldl_code(env, ctx.pc);
15576 decode_opc(env, &ctx, &is_branch);
15577 } else if (env->insn_flags & ASE_MICROMIPS) {
15578 ctx.opcode = cpu_lduw_code(env, ctx.pc);
15579 insn_bytes = decode_micromips_opc(env, &ctx, &is_branch);
15580 } else if (env->insn_flags & ASE_MIPS16) {
15581 ctx.opcode = cpu_lduw_code(env, ctx.pc);
15582 insn_bytes = decode_mips16_opc(env, &ctx, &is_branch);
15584 generate_exception(&ctx, EXCP_RI);
15585 ctx.bstate = BS_STOP;
15589 handle_delay_slot(env, &ctx, insn_bytes);
15591 ctx.pc += insn_bytes;
15595 /* Execute a branch and its delay slot as a single instruction.
15596 This is what GDB expects and is consistent with what the
15597 hardware does (e.g. if a delay slot instruction faults, the
15598 reported PC is the PC of the branch). */
15599 if (env->singlestep_enabled && (ctx.hflags & MIPS_HFLAG_BMASK) == 0)
15602 if ((ctx.pc & (TARGET_PAGE_SIZE - 1)) == 0)
15605 if (gen_opc_ptr >= gen_opc_end)
15608 if (num_insns >= max_insns)
15614 if (tb->cflags & CF_LAST_IO)
15616 if (env->singlestep_enabled && ctx.bstate != BS_BRANCH) {
15617 save_cpu_state(&ctx, ctx.bstate == BS_NONE);
15618 gen_helper_0e0i(raise_exception, EXCP_DEBUG);
15620 switch (ctx.bstate) {
15622 gen_goto_tb(&ctx, 0, ctx.pc);
15625 save_cpu_state(&ctx, 0);
15626 gen_goto_tb(&ctx, 0, ctx.pc);
15629 tcg_gen_exit_tb(0);
15637 gen_icount_end(tb, num_insns);
15638 *gen_opc_ptr = INDEX_op_end;
15640 j = gen_opc_ptr - gen_opc_buf;
15643 gen_opc_instr_start[lj++] = 0;
15645 tb->size = ctx.pc - pc_start;
15646 tb->icount = num_insns;
15650 if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM)) {
15651 qemu_log("IN: %s\n", lookup_symbol(pc_start));
15652 log_target_disas(pc_start, ctx.pc - pc_start, 0);
15658 void gen_intermediate_code (CPUMIPSState *env, struct TranslationBlock *tb)
15660 gen_intermediate_code_internal(env, tb, 0);
15663 void gen_intermediate_code_pc (CPUMIPSState *env, struct TranslationBlock *tb)
15665 gen_intermediate_code_internal(env, tb, 1);
15668 static void fpu_dump_state(CPUMIPSState *env, FILE *f, fprintf_function fpu_fprintf,
15672 int is_fpu64 = !!(env->hflags & MIPS_HFLAG_F64);
15674 #define printfpr(fp) \
15677 fpu_fprintf(f, "w:%08x d:%016" PRIx64 \
15678 " fd:%13g fs:%13g psu: %13g\n", \
15679 (fp)->w[FP_ENDIAN_IDX], (fp)->d, \
15680 (double)(fp)->fd, \
15681 (double)(fp)->fs[FP_ENDIAN_IDX], \
15682 (double)(fp)->fs[!FP_ENDIAN_IDX]); \
15685 tmp.w[FP_ENDIAN_IDX] = (fp)->w[FP_ENDIAN_IDX]; \
15686 tmp.w[!FP_ENDIAN_IDX] = ((fp) + 1)->w[FP_ENDIAN_IDX]; \
15687 fpu_fprintf(f, "w:%08x d:%016" PRIx64 \
15688 " fd:%13g fs:%13g psu:%13g\n", \
15689 tmp.w[FP_ENDIAN_IDX], tmp.d, \
15691 (double)tmp.fs[FP_ENDIAN_IDX], \
15692 (double)tmp.fs[!FP_ENDIAN_IDX]); \
15697 fpu_fprintf(f, "CP1 FCR0 0x%08x FCR31 0x%08x SR.FR %d fp_status 0x%02x\n",
15698 env->active_fpu.fcr0, env->active_fpu.fcr31, is_fpu64,
15699 get_float_exception_flags(&env->active_fpu.fp_status));
15700 for (i = 0; i < 32; (is_fpu64) ? i++ : (i += 2)) {
15701 fpu_fprintf(f, "%3s: ", fregnames[i]);
15702 printfpr(&env->active_fpu.fpr[i]);
15708 #if defined(TARGET_MIPS64) && defined(MIPS_DEBUG_SIGN_EXTENSIONS)
15709 /* Debug help: The architecture requires 32bit code to maintain proper
15710 sign-extended values on 64bit machines. */
15712 #define SIGN_EXT_P(val) ((((val) & ~0x7fffffff) == 0) || (((val) & ~0x7fffffff) == ~0x7fffffff))
15715 cpu_mips_check_sign_extensions (CPUMIPSState *env, FILE *f,
15716 fprintf_function cpu_fprintf,
15721 if (!SIGN_EXT_P(env->active_tc.PC))
15722 cpu_fprintf(f, "BROKEN: pc=0x" TARGET_FMT_lx "\n", env->active_tc.PC);
15723 if (!SIGN_EXT_P(env->active_tc.HI[0]))
15724 cpu_fprintf(f, "BROKEN: HI=0x" TARGET_FMT_lx "\n", env->active_tc.HI[0]);
15725 if (!SIGN_EXT_P(env->active_tc.LO[0]))
15726 cpu_fprintf(f, "BROKEN: LO=0x" TARGET_FMT_lx "\n", env->active_tc.LO[0]);
15727 if (!SIGN_EXT_P(env->btarget))
15728 cpu_fprintf(f, "BROKEN: btarget=0x" TARGET_FMT_lx "\n", env->btarget);
15730 for (i = 0; i < 32; i++) {
15731 if (!SIGN_EXT_P(env->active_tc.gpr[i]))
15732 cpu_fprintf(f, "BROKEN: %s=0x" TARGET_FMT_lx "\n", regnames[i], env->active_tc.gpr[i]);
15735 if (!SIGN_EXT_P(env->CP0_EPC))
15736 cpu_fprintf(f, "BROKEN: EPC=0x" TARGET_FMT_lx "\n", env->CP0_EPC);
15737 if (!SIGN_EXT_P(env->lladdr))
15738 cpu_fprintf(f, "BROKEN: LLAddr=0x" TARGET_FMT_lx "\n", env->lladdr);
15742 void cpu_dump_state (CPUMIPSState *env, FILE *f, fprintf_function cpu_fprintf,
15747 cpu_fprintf(f, "pc=0x" TARGET_FMT_lx " HI=0x" TARGET_FMT_lx
15748 " LO=0x" TARGET_FMT_lx " ds %04x "
15749 TARGET_FMT_lx " " TARGET_FMT_ld "\n",
15750 env->active_tc.PC, env->active_tc.HI[0], env->active_tc.LO[0],
15751 env->hflags, env->btarget, env->bcond);
15752 for (i = 0; i < 32; i++) {
15754 cpu_fprintf(f, "GPR%02d:", i);
15755 cpu_fprintf(f, " %s " TARGET_FMT_lx, regnames[i], env->active_tc.gpr[i]);
15757 cpu_fprintf(f, "\n");
15760 cpu_fprintf(f, "CP0 Status 0x%08x Cause 0x%08x EPC 0x" TARGET_FMT_lx "\n",
15761 env->CP0_Status, env->CP0_Cause, env->CP0_EPC);
15762 cpu_fprintf(f, " Config0 0x%08x Config1 0x%08x LLAddr 0x" TARGET_FMT_lx "\n",
15763 env->CP0_Config0, env->CP0_Config1, env->lladdr);
15764 if (env->hflags & MIPS_HFLAG_FPU)
15765 fpu_dump_state(env, f, cpu_fprintf, flags);
15766 #if defined(TARGET_MIPS64) && defined(MIPS_DEBUG_SIGN_EXTENSIONS)
15767 cpu_mips_check_sign_extensions(env, f, cpu_fprintf, flags);
15771 static void mips_tcg_init(void)
15776 /* Initialize various static tables. */
15780 cpu_env = tcg_global_reg_new_ptr(TCG_AREG0, "env");
15781 TCGV_UNUSED(cpu_gpr[0]);
15782 for (i = 1; i < 32; i++)
15783 cpu_gpr[i] = tcg_global_mem_new(TCG_AREG0,
15784 offsetof(CPUMIPSState, active_tc.gpr[i]),
15787 for (i = 0; i < 32; i++) {
15788 int off = offsetof(CPUMIPSState, active_fpu.fpr[i]);
15789 fpu_f64[i] = tcg_global_mem_new_i64(TCG_AREG0, off, fregnames[i]);
15792 cpu_PC = tcg_global_mem_new(TCG_AREG0,
15793 offsetof(CPUMIPSState, active_tc.PC), "PC");
15794 for (i = 0; i < MIPS_DSP_ACC; i++) {
15795 cpu_HI[i] = tcg_global_mem_new(TCG_AREG0,
15796 offsetof(CPUMIPSState, active_tc.HI[i]),
15798 cpu_LO[i] = tcg_global_mem_new(TCG_AREG0,
15799 offsetof(CPUMIPSState, active_tc.LO[i]),
15801 cpu_ACX[i] = tcg_global_mem_new(TCG_AREG0,
15802 offsetof(CPUMIPSState, active_tc.ACX[i]),
15805 cpu_dspctrl = tcg_global_mem_new(TCG_AREG0,
15806 offsetof(CPUMIPSState, active_tc.DSPControl),
15808 bcond = tcg_global_mem_new(TCG_AREG0,
15809 offsetof(CPUMIPSState, bcond), "bcond");
15810 btarget = tcg_global_mem_new(TCG_AREG0,
15811 offsetof(CPUMIPSState, btarget), "btarget");
15812 hflags = tcg_global_mem_new_i32(TCG_AREG0,
15813 offsetof(CPUMIPSState, hflags), "hflags");
15815 fpu_fcr0 = tcg_global_mem_new_i32(TCG_AREG0,
15816 offsetof(CPUMIPSState, active_fpu.fcr0),
15818 fpu_fcr31 = tcg_global_mem_new_i32(TCG_AREG0,
15819 offsetof(CPUMIPSState, active_fpu.fcr31),
15822 /* register helpers */
15823 #define GEN_HELPER 2
15824 #include "helper.h"
15829 #include "translate_init.c"
15831 MIPSCPU *cpu_mips_init(const char *cpu_model)
15835 const mips_def_t *def;
15837 def = cpu_mips_find_by_name(cpu_model);
15840 cpu = MIPS_CPU(object_new(TYPE_MIPS_CPU));
15842 env->cpu_model = def;
15843 env->cpu_model_str = cpu_model;
15845 #ifndef CONFIG_USER_ONLY
15846 mmu_init(env, def);
15848 fpu_init(env, def);
15849 mvp_init(env, def);
15851 cpu_reset(CPU(cpu));
15852 qemu_init_vcpu(env);
15856 void cpu_state_reset(CPUMIPSState *env)
15858 if (qemu_loglevel_mask(CPU_LOG_RESET)) {
15859 qemu_log("CPU Reset (CPU %d)\n", env->cpu_index);
15860 log_cpu_state(env, 0);
15863 memset(env, 0, offsetof(CPUMIPSState, breakpoints));
15866 /* Reset registers to their default values */
15867 env->CP0_PRid = env->cpu_model->CP0_PRid;
15868 env->CP0_Config0 = env->cpu_model->CP0_Config0;
15869 #ifdef TARGET_WORDS_BIGENDIAN
15870 env->CP0_Config0 |= (1 << CP0C0_BE);
15872 env->CP0_Config1 = env->cpu_model->CP0_Config1;
15873 env->CP0_Config2 = env->cpu_model->CP0_Config2;
15874 env->CP0_Config3 = env->cpu_model->CP0_Config3;
15875 env->CP0_Config6 = env->cpu_model->CP0_Config6;
15876 env->CP0_Config7 = env->cpu_model->CP0_Config7;
15877 env->CP0_LLAddr_rw_bitmask = env->cpu_model->CP0_LLAddr_rw_bitmask
15878 << env->cpu_model->CP0_LLAddr_shift;
15879 env->CP0_LLAddr_shift = env->cpu_model->CP0_LLAddr_shift;
15880 env->SYNCI_Step = env->cpu_model->SYNCI_Step;
15881 env->CCRes = env->cpu_model->CCRes;
15882 env->CP0_Status_rw_bitmask = env->cpu_model->CP0_Status_rw_bitmask;
15883 env->CP0_TCStatus_rw_bitmask = env->cpu_model->CP0_TCStatus_rw_bitmask;
15884 env->CP0_SRSCtl = env->cpu_model->CP0_SRSCtl;
15885 env->current_tc = 0;
15886 env->SEGBITS = env->cpu_model->SEGBITS;
15887 env->SEGMask = (target_ulong)((1ULL << env->cpu_model->SEGBITS) - 1);
15888 #if defined(TARGET_MIPS64)
15889 if (env->cpu_model->insn_flags & ISA_MIPS3) {
15890 env->SEGMask |= 3ULL << 62;
15893 env->PABITS = env->cpu_model->PABITS;
15894 env->PAMask = (target_ulong)((1ULL << env->cpu_model->PABITS) - 1);
15895 env->CP0_SRSConf0_rw_bitmask = env->cpu_model->CP0_SRSConf0_rw_bitmask;
15896 env->CP0_SRSConf0 = env->cpu_model->CP0_SRSConf0;
15897 env->CP0_SRSConf1_rw_bitmask = env->cpu_model->CP0_SRSConf1_rw_bitmask;
15898 env->CP0_SRSConf1 = env->cpu_model->CP0_SRSConf1;
15899 env->CP0_SRSConf2_rw_bitmask = env->cpu_model->CP0_SRSConf2_rw_bitmask;
15900 env->CP0_SRSConf2 = env->cpu_model->CP0_SRSConf2;
15901 env->CP0_SRSConf3_rw_bitmask = env->cpu_model->CP0_SRSConf3_rw_bitmask;
15902 env->CP0_SRSConf3 = env->cpu_model->CP0_SRSConf3;
15903 env->CP0_SRSConf4_rw_bitmask = env->cpu_model->CP0_SRSConf4_rw_bitmask;
15904 env->CP0_SRSConf4 = env->cpu_model->CP0_SRSConf4;
15905 env->active_fpu.fcr0 = env->cpu_model->CP1_fcr0;
15906 env->insn_flags = env->cpu_model->insn_flags;
15908 #if defined(CONFIG_USER_ONLY)
15909 env->CP0_Status = (MIPS_HFLAG_UM << CP0St_KSU);
15910 /* Enable access to the CPUNum, SYNCI_Step, CC, and CCRes RDHWR
15911 hardware registers. */
15912 env->CP0_HWREna |= 0x0000000F;
15913 if (env->CP0_Config1 & (1 << CP0C1_FP)) {
15914 env->CP0_Status |= (1 << CP0St_CU1);
15916 if (env->cpu_model->insn_flags & ASE_DSPR2) {
15917 env->hflags |= MIPS_HFLAG_DSP | MIPS_HFLAG_DSPR2;
15918 } else if (env->cpu_model->insn_flags & ASE_DSP) {
15919 env->hflags |= MIPS_HFLAG_DSP;
15922 if (env->hflags & MIPS_HFLAG_BMASK) {
15923 /* If the exception was raised from a delay slot,
15924 come back to the jump. */
15925 env->CP0_ErrorEPC = env->active_tc.PC - 4;
15927 env->CP0_ErrorEPC = env->active_tc.PC;
15929 env->active_tc.PC = (int32_t)0xBFC00000;
15930 env->CP0_Random = env->tlb->nb_tlb - 1;
15931 env->tlb->tlb_in_use = env->tlb->nb_tlb;
15932 env->CP0_Wired = 0;
15933 env->CP0_EBase = 0x80000000 | (env->cpu_index & 0x3FF);
15934 env->CP0_Status = (1 << CP0St_BEV) | (1 << CP0St_ERL);
15935 /* vectored interrupts not implemented, timer on int 7,
15936 no performance counters. */
15937 env->CP0_IntCtl = 0xe0000000;
15941 for (i = 0; i < 7; i++) {
15942 env->CP0_WatchLo[i] = 0;
15943 env->CP0_WatchHi[i] = 0x80000000;
15945 env->CP0_WatchLo[7] = 0;
15946 env->CP0_WatchHi[7] = 0;
15948 /* Count register increments in debug mode, EJTAG version 1 */
15949 env->CP0_Debug = (1 << CP0DB_CNT) | (0x1 << CP0DB_VER);
15951 if (env->CP0_Config3 & (1 << CP0C3_MT)) {
15954 /* Only TC0 on VPE 0 starts as active. */
15955 for (i = 0; i < ARRAY_SIZE(env->tcs); i++) {
15956 env->tcs[i].CP0_TCBind = env->cpu_index << CP0TCBd_CurVPE;
15957 env->tcs[i].CP0_TCHalt = 1;
15959 env->active_tc.CP0_TCHalt = 1;
15962 if (!env->cpu_index) {
15963 /* VPE0 starts up enabled. */
15964 env->mvp->CP0_MVPControl |= (1 << CP0MVPCo_EVP);
15965 env->CP0_VPEConf0 |= (1 << CP0VPEC0_MVP) | (1 << CP0VPEC0_VPA);
15967 /* TC0 starts up unhalted. */
15969 env->active_tc.CP0_TCHalt = 0;
15970 env->tcs[0].CP0_TCHalt = 0;
15971 /* With thread 0 active. */
15972 env->active_tc.CP0_TCStatus = (1 << CP0TCSt_A);
15973 env->tcs[0].CP0_TCStatus = (1 << CP0TCSt_A);
15977 compute_hflags(env);
15978 env->exception_index = EXCP_NONE;
15981 void restore_state_to_opc(CPUMIPSState *env, TranslationBlock *tb, int pc_pos)
15983 env->active_tc.PC = gen_opc_pc[pc_pos];
15984 env->hflags &= ~MIPS_HFLAG_BMASK;
15985 env->hflags |= gen_opc_hflags[pc_pos];
15986 switch (env->hflags & MIPS_HFLAG_BMASK_BASE) {
15987 case MIPS_HFLAG_BR:
15989 case MIPS_HFLAG_BC:
15990 case MIPS_HFLAG_BL:
15992 env->btarget = gen_opc_btarget[pc_pos];