2 * MIPS32 emulation for qemu: main translation routines.
4 * Copyright (c) 2004-2005 Jocelyn Mayer
5 * Copyright (c) 2006 Marius Groeger (FPU operations)
6 * Copyright (c) 2006 Thiemo Seufer (MIPS32R2 support)
7 * Copyright (c) 2009 CodeSourcery (MIPS16 and microMIPS support)
8 * Copyright (c) 2012 Jia Liu & Dongxue Zhang (MIPS ASE DSP support)
10 * This library is free software; you can redistribute it and/or
11 * modify it under the terms of the GNU Lesser General Public
12 * License as published by the Free Software Foundation; either
13 * version 2 of the License, or (at your option) any later version.
15 * This library is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
18 * Lesser General Public License for more details.
20 * You should have received a copy of the GNU Lesser General Public
21 * License along with this library; if not, see <http://www.gnu.org/licenses/>.
32 #define MIPS_DEBUG_DISAS 0
33 //#define MIPS_DEBUG_SIGN_EXTENSIONS
35 /* MIPS major opcodes */
36 #define MASK_OP_MAJOR(op) (op & (0x3F << 26))
39 /* indirect opcode tables */
40 OPC_SPECIAL = (0x00 << 26),
41 OPC_REGIMM = (0x01 << 26),
42 OPC_CP0 = (0x10 << 26),
43 OPC_CP1 = (0x11 << 26),
44 OPC_CP2 = (0x12 << 26),
45 OPC_CP3 = (0x13 << 26),
46 OPC_SPECIAL2 = (0x1C << 26),
47 OPC_SPECIAL3 = (0x1F << 26),
48 /* arithmetic with immediate */
49 OPC_ADDI = (0x08 << 26),
50 OPC_ADDIU = (0x09 << 26),
51 OPC_SLTI = (0x0A << 26),
52 OPC_SLTIU = (0x0B << 26),
53 /* logic with immediate */
54 OPC_ANDI = (0x0C << 26),
55 OPC_ORI = (0x0D << 26),
56 OPC_XORI = (0x0E << 26),
57 OPC_LUI = (0x0F << 26),
58 /* arithmetic with immediate */
59 OPC_DADDI = (0x18 << 26),
60 OPC_DADDIU = (0x19 << 26),
61 /* Jump and branches */
63 OPC_JAL = (0x03 << 26),
64 OPC_JALS = OPC_JAL | 0x5,
65 OPC_BEQ = (0x04 << 26), /* Unconditional if rs = rt = 0 (B) */
66 OPC_BEQL = (0x14 << 26),
67 OPC_BNE = (0x05 << 26),
68 OPC_BNEL = (0x15 << 26),
69 OPC_BLEZ = (0x06 << 26),
70 OPC_BLEZL = (0x16 << 26),
71 OPC_BGTZ = (0x07 << 26),
72 OPC_BGTZL = (0x17 << 26),
73 OPC_JALX = (0x1D << 26), /* MIPS 16 only */
74 OPC_JALXS = OPC_JALX | 0x5,
76 OPC_LDL = (0x1A << 26),
77 OPC_LDR = (0x1B << 26),
78 OPC_LB = (0x20 << 26),
79 OPC_LH = (0x21 << 26),
80 OPC_LWL = (0x22 << 26),
81 OPC_LW = (0x23 << 26),
82 OPC_LWPC = OPC_LW | 0x5,
83 OPC_LBU = (0x24 << 26),
84 OPC_LHU = (0x25 << 26),
85 OPC_LWR = (0x26 << 26),
86 OPC_LWU = (0x27 << 26),
87 OPC_SB = (0x28 << 26),
88 OPC_SH = (0x29 << 26),
89 OPC_SWL = (0x2A << 26),
90 OPC_SW = (0x2B << 26),
91 OPC_SDL = (0x2C << 26),
92 OPC_SDR = (0x2D << 26),
93 OPC_SWR = (0x2E << 26),
94 OPC_LL = (0x30 << 26),
95 OPC_LLD = (0x34 << 26),
96 OPC_LD = (0x37 << 26),
97 OPC_LDPC = OPC_LD | 0x5,
98 OPC_SC = (0x38 << 26),
99 OPC_SCD = (0x3C << 26),
100 OPC_SD = (0x3F << 26),
101 /* Floating point load/store */
102 OPC_LWC1 = (0x31 << 26),
103 OPC_LWC2 = (0x32 << 26),
104 OPC_LDC1 = (0x35 << 26),
105 OPC_LDC2 = (0x36 << 26),
106 OPC_SWC1 = (0x39 << 26),
107 OPC_SWC2 = (0x3A << 26),
108 OPC_SDC1 = (0x3D << 26),
109 OPC_SDC2 = (0x3E << 26),
110 /* MDMX ASE specific */
111 OPC_MDMX = (0x1E << 26),
112 /* Cache and prefetch */
113 OPC_CACHE = (0x2F << 26),
114 OPC_PREF = (0x33 << 26),
115 /* Reserved major opcode */
116 OPC_MAJOR3B_RESERVED = (0x3B << 26),
119 /* MIPS special opcodes */
120 #define MASK_SPECIAL(op) MASK_OP_MAJOR(op) | (op & 0x3F)
124 OPC_SLL = 0x00 | OPC_SPECIAL,
125 /* NOP is SLL r0, r0, 0 */
126 /* SSNOP is SLL r0, r0, 1 */
127 /* EHB is SLL r0, r0, 3 */
128 OPC_SRL = 0x02 | OPC_SPECIAL, /* also ROTR */
129 OPC_ROTR = OPC_SRL | (1 << 21),
130 OPC_SRA = 0x03 | OPC_SPECIAL,
131 OPC_SLLV = 0x04 | OPC_SPECIAL,
132 OPC_SRLV = 0x06 | OPC_SPECIAL, /* also ROTRV */
133 OPC_ROTRV = OPC_SRLV | (1 << 6),
134 OPC_SRAV = 0x07 | OPC_SPECIAL,
135 OPC_DSLLV = 0x14 | OPC_SPECIAL,
136 OPC_DSRLV = 0x16 | OPC_SPECIAL, /* also DROTRV */
137 OPC_DROTRV = OPC_DSRLV | (1 << 6),
138 OPC_DSRAV = 0x17 | OPC_SPECIAL,
139 OPC_DSLL = 0x38 | OPC_SPECIAL,
140 OPC_DSRL = 0x3A | OPC_SPECIAL, /* also DROTR */
141 OPC_DROTR = OPC_DSRL | (1 << 21),
142 OPC_DSRA = 0x3B | OPC_SPECIAL,
143 OPC_DSLL32 = 0x3C | OPC_SPECIAL,
144 OPC_DSRL32 = 0x3E | OPC_SPECIAL, /* also DROTR32 */
145 OPC_DROTR32 = OPC_DSRL32 | (1 << 21),
146 OPC_DSRA32 = 0x3F | OPC_SPECIAL,
147 /* Multiplication / division */
148 OPC_MULT = 0x18 | OPC_SPECIAL,
149 OPC_MULTU = 0x19 | OPC_SPECIAL,
150 OPC_DIV = 0x1A | OPC_SPECIAL,
151 OPC_DIVU = 0x1B | OPC_SPECIAL,
152 OPC_DMULT = 0x1C | OPC_SPECIAL,
153 OPC_DMULTU = 0x1D | OPC_SPECIAL,
154 OPC_DDIV = 0x1E | OPC_SPECIAL,
155 OPC_DDIVU = 0x1F | OPC_SPECIAL,
156 /* 2 registers arithmetic / logic */
157 OPC_ADD = 0x20 | OPC_SPECIAL,
158 OPC_ADDU = 0x21 | OPC_SPECIAL,
159 OPC_SUB = 0x22 | OPC_SPECIAL,
160 OPC_SUBU = 0x23 | OPC_SPECIAL,
161 OPC_AND = 0x24 | OPC_SPECIAL,
162 OPC_OR = 0x25 | OPC_SPECIAL,
163 OPC_XOR = 0x26 | OPC_SPECIAL,
164 OPC_NOR = 0x27 | OPC_SPECIAL,
165 OPC_SLT = 0x2A | OPC_SPECIAL,
166 OPC_SLTU = 0x2B | OPC_SPECIAL,
167 OPC_DADD = 0x2C | OPC_SPECIAL,
168 OPC_DADDU = 0x2D | OPC_SPECIAL,
169 OPC_DSUB = 0x2E | OPC_SPECIAL,
170 OPC_DSUBU = 0x2F | OPC_SPECIAL,
172 OPC_JR = 0x08 | OPC_SPECIAL, /* Also JR.HB */
173 OPC_JALR = 0x09 | OPC_SPECIAL, /* Also JALR.HB */
174 OPC_JALRC = OPC_JALR | (0x5 << 6),
175 OPC_JALRS = 0x10 | OPC_SPECIAL | (0x5 << 6),
177 OPC_TGE = 0x30 | OPC_SPECIAL,
178 OPC_TGEU = 0x31 | OPC_SPECIAL,
179 OPC_TLT = 0x32 | OPC_SPECIAL,
180 OPC_TLTU = 0x33 | OPC_SPECIAL,
181 OPC_TEQ = 0x34 | OPC_SPECIAL,
182 OPC_TNE = 0x36 | OPC_SPECIAL,
183 /* HI / LO registers load & stores */
184 OPC_MFHI = 0x10 | OPC_SPECIAL,
185 OPC_MTHI = 0x11 | OPC_SPECIAL,
186 OPC_MFLO = 0x12 | OPC_SPECIAL,
187 OPC_MTLO = 0x13 | OPC_SPECIAL,
188 /* Conditional moves */
189 OPC_MOVZ = 0x0A | OPC_SPECIAL,
190 OPC_MOVN = 0x0B | OPC_SPECIAL,
192 OPC_MOVCI = 0x01 | OPC_SPECIAL,
195 OPC_PMON = 0x05 | OPC_SPECIAL, /* unofficial */
196 OPC_SYSCALL = 0x0C | OPC_SPECIAL,
197 OPC_BREAK = 0x0D | OPC_SPECIAL,
198 OPC_SPIM = 0x0E | OPC_SPECIAL, /* unofficial */
199 OPC_SYNC = 0x0F | OPC_SPECIAL,
201 OPC_SPECIAL15_RESERVED = 0x15 | OPC_SPECIAL,
202 OPC_SPECIAL28_RESERVED = 0x28 | OPC_SPECIAL,
203 OPC_SPECIAL29_RESERVED = 0x29 | OPC_SPECIAL,
204 OPC_SPECIAL35_RESERVED = 0x35 | OPC_SPECIAL,
205 OPC_SPECIAL37_RESERVED = 0x37 | OPC_SPECIAL,
206 OPC_SPECIAL39_RESERVED = 0x39 | OPC_SPECIAL,
207 OPC_SPECIAL3D_RESERVED = 0x3D | OPC_SPECIAL,
210 /* Multiplication variants of the vr54xx. */
211 #define MASK_MUL_VR54XX(op) MASK_SPECIAL(op) | (op & (0x1F << 6))
214 OPC_VR54XX_MULS = (0x03 << 6) | OPC_MULT,
215 OPC_VR54XX_MULSU = (0x03 << 6) | OPC_MULTU,
216 OPC_VR54XX_MACC = (0x05 << 6) | OPC_MULT,
217 OPC_VR54XX_MACCU = (0x05 << 6) | OPC_MULTU,
218 OPC_VR54XX_MSAC = (0x07 << 6) | OPC_MULT,
219 OPC_VR54XX_MSACU = (0x07 << 6) | OPC_MULTU,
220 OPC_VR54XX_MULHI = (0x09 << 6) | OPC_MULT,
221 OPC_VR54XX_MULHIU = (0x09 << 6) | OPC_MULTU,
222 OPC_VR54XX_MULSHI = (0x0B << 6) | OPC_MULT,
223 OPC_VR54XX_MULSHIU = (0x0B << 6) | OPC_MULTU,
224 OPC_VR54XX_MACCHI = (0x0D << 6) | OPC_MULT,
225 OPC_VR54XX_MACCHIU = (0x0D << 6) | OPC_MULTU,
226 OPC_VR54XX_MSACHI = (0x0F << 6) | OPC_MULT,
227 OPC_VR54XX_MSACHIU = (0x0F << 6) | OPC_MULTU,
230 /* REGIMM (rt field) opcodes */
231 #define MASK_REGIMM(op) MASK_OP_MAJOR(op) | (op & (0x1F << 16))
234 OPC_BLTZ = (0x00 << 16) | OPC_REGIMM,
235 OPC_BLTZL = (0x02 << 16) | OPC_REGIMM,
236 OPC_BGEZ = (0x01 << 16) | OPC_REGIMM,
237 OPC_BGEZL = (0x03 << 16) | OPC_REGIMM,
238 OPC_BLTZAL = (0x10 << 16) | OPC_REGIMM,
239 OPC_BLTZALS = OPC_BLTZAL | 0x5, /* microMIPS */
240 OPC_BLTZALL = (0x12 << 16) | OPC_REGIMM,
241 OPC_BGEZAL = (0x11 << 16) | OPC_REGIMM,
242 OPC_BGEZALS = OPC_BGEZAL | 0x5, /* microMIPS */
243 OPC_BGEZALL = (0x13 << 16) | OPC_REGIMM,
244 OPC_TGEI = (0x08 << 16) | OPC_REGIMM,
245 OPC_TGEIU = (0x09 << 16) | OPC_REGIMM,
246 OPC_TLTI = (0x0A << 16) | OPC_REGIMM,
247 OPC_TLTIU = (0x0B << 16) | OPC_REGIMM,
248 OPC_TEQI = (0x0C << 16) | OPC_REGIMM,
249 OPC_TNEI = (0x0E << 16) | OPC_REGIMM,
250 OPC_SYNCI = (0x1F << 16) | OPC_REGIMM,
253 /* Special2 opcodes */
254 #define MASK_SPECIAL2(op) MASK_OP_MAJOR(op) | (op & 0x3F)
257 /* Multiply & xxx operations */
258 OPC_MADD = 0x00 | OPC_SPECIAL2,
259 OPC_MADDU = 0x01 | OPC_SPECIAL2,
260 OPC_MUL = 0x02 | OPC_SPECIAL2,
261 OPC_MSUB = 0x04 | OPC_SPECIAL2,
262 OPC_MSUBU = 0x05 | OPC_SPECIAL2,
264 OPC_MULT_G_2F = 0x10 | OPC_SPECIAL2,
265 OPC_DMULT_G_2F = 0x11 | OPC_SPECIAL2,
266 OPC_MULTU_G_2F = 0x12 | OPC_SPECIAL2,
267 OPC_DMULTU_G_2F = 0x13 | OPC_SPECIAL2,
268 OPC_DIV_G_2F = 0x14 | OPC_SPECIAL2,
269 OPC_DDIV_G_2F = 0x15 | OPC_SPECIAL2,
270 OPC_DIVU_G_2F = 0x16 | OPC_SPECIAL2,
271 OPC_DDIVU_G_2F = 0x17 | OPC_SPECIAL2,
272 OPC_MOD_G_2F = 0x1c | OPC_SPECIAL2,
273 OPC_DMOD_G_2F = 0x1d | OPC_SPECIAL2,
274 OPC_MODU_G_2F = 0x1e | OPC_SPECIAL2,
275 OPC_DMODU_G_2F = 0x1f | OPC_SPECIAL2,
277 OPC_CLZ = 0x20 | OPC_SPECIAL2,
278 OPC_CLO = 0x21 | OPC_SPECIAL2,
279 OPC_DCLZ = 0x24 | OPC_SPECIAL2,
280 OPC_DCLO = 0x25 | OPC_SPECIAL2,
282 OPC_SDBBP = 0x3F | OPC_SPECIAL2,
285 /* Special3 opcodes */
286 #define MASK_SPECIAL3(op) MASK_OP_MAJOR(op) | (op & 0x3F)
289 OPC_EXT = 0x00 | OPC_SPECIAL3,
290 OPC_DEXTM = 0x01 | OPC_SPECIAL3,
291 OPC_DEXTU = 0x02 | OPC_SPECIAL3,
292 OPC_DEXT = 0x03 | OPC_SPECIAL3,
293 OPC_INS = 0x04 | OPC_SPECIAL3,
294 OPC_DINSM = 0x05 | OPC_SPECIAL3,
295 OPC_DINSU = 0x06 | OPC_SPECIAL3,
296 OPC_DINS = 0x07 | OPC_SPECIAL3,
297 OPC_FORK = 0x08 | OPC_SPECIAL3,
298 OPC_YIELD = 0x09 | OPC_SPECIAL3,
299 OPC_BSHFL = 0x20 | OPC_SPECIAL3,
300 OPC_DBSHFL = 0x24 | OPC_SPECIAL3,
301 OPC_RDHWR = 0x3B | OPC_SPECIAL3,
304 OPC_MULT_G_2E = 0x18 | OPC_SPECIAL3,
305 OPC_MULTU_G_2E = 0x19 | OPC_SPECIAL3,
306 OPC_DIV_G_2E = 0x1A | OPC_SPECIAL3,
307 OPC_DIVU_G_2E = 0x1B | OPC_SPECIAL3,
308 OPC_DMULT_G_2E = 0x1C | OPC_SPECIAL3,
309 OPC_DMULTU_G_2E = 0x1D | OPC_SPECIAL3,
310 OPC_DDIV_G_2E = 0x1E | OPC_SPECIAL3,
311 OPC_DDIVU_G_2E = 0x1F | OPC_SPECIAL3,
312 OPC_MOD_G_2E = 0x22 | OPC_SPECIAL3,
313 OPC_MODU_G_2E = 0x23 | OPC_SPECIAL3,
314 OPC_DMOD_G_2E = 0x26 | OPC_SPECIAL3,
315 OPC_DMODU_G_2E = 0x27 | OPC_SPECIAL3,
318 OPC_LX_DSP = 0x0A | OPC_SPECIAL3,
319 /* MIPS DSP Arithmetic */
320 OPC_ADDU_QB_DSP = 0x10 | OPC_SPECIAL3,
321 OPC_ADDU_OB_DSP = 0x14 | OPC_SPECIAL3,
322 OPC_ABSQ_S_PH_DSP = 0x12 | OPC_SPECIAL3,
323 OPC_ABSQ_S_QH_DSP = 0x16 | OPC_SPECIAL3,
324 /* OPC_ADDUH_QB_DSP is same as OPC_MULT_G_2E. */
325 /* OPC_ADDUH_QB_DSP = 0x18 | OPC_SPECIAL3, */
326 OPC_CMPU_EQ_QB_DSP = 0x11 | OPC_SPECIAL3,
327 OPC_CMPU_EQ_OB_DSP = 0x15 | OPC_SPECIAL3,
328 /* MIPS DSP GPR-Based Shift Sub-class */
329 OPC_SHLL_QB_DSP = 0x13 | OPC_SPECIAL3,
330 OPC_SHLL_OB_DSP = 0x17 | OPC_SPECIAL3,
331 /* MIPS DSP Multiply Sub-class insns */
332 /* OPC_MUL_PH_DSP is same as OPC_ADDUH_QB_DSP. */
333 /* OPC_MUL_PH_DSP = 0x18 | OPC_SPECIAL3, */
334 OPC_DPA_W_PH_DSP = 0x30 | OPC_SPECIAL3,
335 OPC_DPAQ_W_QH_DSP = 0x34 | OPC_SPECIAL3,
336 /* DSP Bit/Manipulation Sub-class */
337 OPC_INSV_DSP = 0x0C | OPC_SPECIAL3,
338 OPC_DINSV_DSP = 0x0D | OPC_SPECIAL3,
339 /* MIPS DSP Compare-Pick Sub-class */
340 OPC_APPEND_DSP = 0x31 | OPC_SPECIAL3,
341 OPC_DAPPEND_DSP = 0x35 | OPC_SPECIAL3,
342 /* MIPS DSP Accumulator and DSPControl Access Sub-class */
343 OPC_EXTR_W_DSP = 0x38 | OPC_SPECIAL3,
344 OPC_DEXTR_W_DSP = 0x3C | OPC_SPECIAL3,
348 #define MASK_BSHFL(op) MASK_SPECIAL3(op) | (op & (0x1F << 6))
351 OPC_WSBH = (0x02 << 6) | OPC_BSHFL,
352 OPC_SEB = (0x10 << 6) | OPC_BSHFL,
353 OPC_SEH = (0x18 << 6) | OPC_BSHFL,
357 #define MASK_DBSHFL(op) MASK_SPECIAL3(op) | (op & (0x1F << 6))
360 OPC_DSBH = (0x02 << 6) | OPC_DBSHFL,
361 OPC_DSHD = (0x05 << 6) | OPC_DBSHFL,
364 /* MIPS DSP REGIMM opcodes */
366 OPC_BPOSGE32 = (0x1C << 16) | OPC_REGIMM,
367 OPC_BPOSGE64 = (0x1D << 16) | OPC_REGIMM,
370 #define MASK_LX(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
373 OPC_LBUX = (0x06 << 6) | OPC_LX_DSP,
374 OPC_LHX = (0x04 << 6) | OPC_LX_DSP,
375 OPC_LWX = (0x00 << 6) | OPC_LX_DSP,
376 OPC_LDX = (0x08 << 6) | OPC_LX_DSP,
379 #define MASK_ADDU_QB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
381 /* MIPS DSP Arithmetic Sub-class */
382 OPC_ADDQ_PH = (0x0A << 6) | OPC_ADDU_QB_DSP,
383 OPC_ADDQ_S_PH = (0x0E << 6) | OPC_ADDU_QB_DSP,
384 OPC_ADDQ_S_W = (0x16 << 6) | OPC_ADDU_QB_DSP,
385 OPC_ADDU_QB = (0x00 << 6) | OPC_ADDU_QB_DSP,
386 OPC_ADDU_S_QB = (0x04 << 6) | OPC_ADDU_QB_DSP,
387 OPC_ADDU_PH = (0x08 << 6) | OPC_ADDU_QB_DSP,
388 OPC_ADDU_S_PH = (0x0C << 6) | OPC_ADDU_QB_DSP,
389 OPC_SUBQ_PH = (0x0B << 6) | OPC_ADDU_QB_DSP,
390 OPC_SUBQ_S_PH = (0x0F << 6) | OPC_ADDU_QB_DSP,
391 OPC_SUBQ_S_W = (0x17 << 6) | OPC_ADDU_QB_DSP,
392 OPC_SUBU_QB = (0x01 << 6) | OPC_ADDU_QB_DSP,
393 OPC_SUBU_S_QB = (0x05 << 6) | OPC_ADDU_QB_DSP,
394 OPC_SUBU_PH = (0x09 << 6) | OPC_ADDU_QB_DSP,
395 OPC_SUBU_S_PH = (0x0D << 6) | OPC_ADDU_QB_DSP,
396 OPC_ADDSC = (0x10 << 6) | OPC_ADDU_QB_DSP,
397 OPC_ADDWC = (0x11 << 6) | OPC_ADDU_QB_DSP,
398 OPC_MODSUB = (0x12 << 6) | OPC_ADDU_QB_DSP,
399 OPC_RADDU_W_QB = (0x14 << 6) | OPC_ADDU_QB_DSP,
400 /* MIPS DSP Multiply Sub-class insns */
401 OPC_MULEU_S_PH_QBL = (0x06 << 6) | OPC_ADDU_QB_DSP,
402 OPC_MULEU_S_PH_QBR = (0x07 << 6) | OPC_ADDU_QB_DSP,
403 OPC_MULQ_RS_PH = (0x1F << 6) | OPC_ADDU_QB_DSP,
404 OPC_MULEQ_S_W_PHL = (0x1C << 6) | OPC_ADDU_QB_DSP,
405 OPC_MULEQ_S_W_PHR = (0x1D << 6) | OPC_ADDU_QB_DSP,
406 OPC_MULQ_S_PH = (0x1E << 6) | OPC_ADDU_QB_DSP,
409 #define OPC_ADDUH_QB_DSP OPC_MULT_G_2E
410 #define MASK_ADDUH_QB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
412 /* MIPS DSP Arithmetic Sub-class */
413 OPC_ADDUH_QB = (0x00 << 6) | OPC_ADDUH_QB_DSP,
414 OPC_ADDUH_R_QB = (0x02 << 6) | OPC_ADDUH_QB_DSP,
415 OPC_ADDQH_PH = (0x08 << 6) | OPC_ADDUH_QB_DSP,
416 OPC_ADDQH_R_PH = (0x0A << 6) | OPC_ADDUH_QB_DSP,
417 OPC_ADDQH_W = (0x10 << 6) | OPC_ADDUH_QB_DSP,
418 OPC_ADDQH_R_W = (0x12 << 6) | OPC_ADDUH_QB_DSP,
419 OPC_SUBUH_QB = (0x01 << 6) | OPC_ADDUH_QB_DSP,
420 OPC_SUBUH_R_QB = (0x03 << 6) | OPC_ADDUH_QB_DSP,
421 OPC_SUBQH_PH = (0x09 << 6) | OPC_ADDUH_QB_DSP,
422 OPC_SUBQH_R_PH = (0x0B << 6) | OPC_ADDUH_QB_DSP,
423 OPC_SUBQH_W = (0x11 << 6) | OPC_ADDUH_QB_DSP,
424 OPC_SUBQH_R_W = (0x13 << 6) | OPC_ADDUH_QB_DSP,
425 /* MIPS DSP Multiply Sub-class insns */
426 OPC_MUL_PH = (0x0C << 6) | OPC_ADDUH_QB_DSP,
427 OPC_MUL_S_PH = (0x0E << 6) | OPC_ADDUH_QB_DSP,
428 OPC_MULQ_S_W = (0x16 << 6) | OPC_ADDUH_QB_DSP,
429 OPC_MULQ_RS_W = (0x17 << 6) | OPC_ADDUH_QB_DSP,
432 #define MASK_ABSQ_S_PH(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
434 /* MIPS DSP Arithmetic Sub-class */
435 OPC_ABSQ_S_QB = (0x01 << 6) | OPC_ABSQ_S_PH_DSP,
436 OPC_ABSQ_S_PH = (0x09 << 6) | OPC_ABSQ_S_PH_DSP,
437 OPC_ABSQ_S_W = (0x11 << 6) | OPC_ABSQ_S_PH_DSP,
438 OPC_PRECEQ_W_PHL = (0x0C << 6) | OPC_ABSQ_S_PH_DSP,
439 OPC_PRECEQ_W_PHR = (0x0D << 6) | OPC_ABSQ_S_PH_DSP,
440 OPC_PRECEQU_PH_QBL = (0x04 << 6) | OPC_ABSQ_S_PH_DSP,
441 OPC_PRECEQU_PH_QBR = (0x05 << 6) | OPC_ABSQ_S_PH_DSP,
442 OPC_PRECEQU_PH_QBLA = (0x06 << 6) | OPC_ABSQ_S_PH_DSP,
443 OPC_PRECEQU_PH_QBRA = (0x07 << 6) | OPC_ABSQ_S_PH_DSP,
444 OPC_PRECEU_PH_QBL = (0x1C << 6) | OPC_ABSQ_S_PH_DSP,
445 OPC_PRECEU_PH_QBR = (0x1D << 6) | OPC_ABSQ_S_PH_DSP,
446 OPC_PRECEU_PH_QBLA = (0x1E << 6) | OPC_ABSQ_S_PH_DSP,
447 OPC_PRECEU_PH_QBRA = (0x1F << 6) | OPC_ABSQ_S_PH_DSP,
448 /* DSP Bit/Manipulation Sub-class */
449 OPC_BITREV = (0x1B << 6) | OPC_ABSQ_S_PH_DSP,
450 OPC_REPL_QB = (0x02 << 6) | OPC_ABSQ_S_PH_DSP,
451 OPC_REPLV_QB = (0x03 << 6) | OPC_ABSQ_S_PH_DSP,
452 OPC_REPL_PH = (0x0A << 6) | OPC_ABSQ_S_PH_DSP,
453 OPC_REPLV_PH = (0x0B << 6) | OPC_ABSQ_S_PH_DSP,
456 #define MASK_CMPU_EQ_QB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
458 /* MIPS DSP Arithmetic Sub-class */
459 OPC_PRECR_QB_PH = (0x0D << 6) | OPC_CMPU_EQ_QB_DSP,
460 OPC_PRECRQ_QB_PH = (0x0C << 6) | OPC_CMPU_EQ_QB_DSP,
461 OPC_PRECR_SRA_PH_W = (0x1E << 6) | OPC_CMPU_EQ_QB_DSP,
462 OPC_PRECR_SRA_R_PH_W = (0x1F << 6) | OPC_CMPU_EQ_QB_DSP,
463 OPC_PRECRQ_PH_W = (0x14 << 6) | OPC_CMPU_EQ_QB_DSP,
464 OPC_PRECRQ_RS_PH_W = (0x15 << 6) | OPC_CMPU_EQ_QB_DSP,
465 OPC_PRECRQU_S_QB_PH = (0x0F << 6) | OPC_CMPU_EQ_QB_DSP,
466 /* DSP Compare-Pick Sub-class */
467 OPC_CMPU_EQ_QB = (0x00 << 6) | OPC_CMPU_EQ_QB_DSP,
468 OPC_CMPU_LT_QB = (0x01 << 6) | OPC_CMPU_EQ_QB_DSP,
469 OPC_CMPU_LE_QB = (0x02 << 6) | OPC_CMPU_EQ_QB_DSP,
470 OPC_CMPGU_EQ_QB = (0x04 << 6) | OPC_CMPU_EQ_QB_DSP,
471 OPC_CMPGU_LT_QB = (0x05 << 6) | OPC_CMPU_EQ_QB_DSP,
472 OPC_CMPGU_LE_QB = (0x06 << 6) | OPC_CMPU_EQ_QB_DSP,
473 OPC_CMPGDU_EQ_QB = (0x18 << 6) | OPC_CMPU_EQ_QB_DSP,
474 OPC_CMPGDU_LT_QB = (0x19 << 6) | OPC_CMPU_EQ_QB_DSP,
475 OPC_CMPGDU_LE_QB = (0x1A << 6) | OPC_CMPU_EQ_QB_DSP,
476 OPC_CMP_EQ_PH = (0x08 << 6) | OPC_CMPU_EQ_QB_DSP,
477 OPC_CMP_LT_PH = (0x09 << 6) | OPC_CMPU_EQ_QB_DSP,
478 OPC_CMP_LE_PH = (0x0A << 6) | OPC_CMPU_EQ_QB_DSP,
479 OPC_PICK_QB = (0x03 << 6) | OPC_CMPU_EQ_QB_DSP,
480 OPC_PICK_PH = (0x0B << 6) | OPC_CMPU_EQ_QB_DSP,
481 OPC_PACKRL_PH = (0x0E << 6) | OPC_CMPU_EQ_QB_DSP,
484 #define MASK_SHLL_QB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
486 /* MIPS DSP GPR-Based Shift Sub-class */
487 OPC_SHLL_QB = (0x00 << 6) | OPC_SHLL_QB_DSP,
488 OPC_SHLLV_QB = (0x02 << 6) | OPC_SHLL_QB_DSP,
489 OPC_SHLL_PH = (0x08 << 6) | OPC_SHLL_QB_DSP,
490 OPC_SHLLV_PH = (0x0A << 6) | OPC_SHLL_QB_DSP,
491 OPC_SHLL_S_PH = (0x0C << 6) | OPC_SHLL_QB_DSP,
492 OPC_SHLLV_S_PH = (0x0E << 6) | OPC_SHLL_QB_DSP,
493 OPC_SHLL_S_W = (0x14 << 6) | OPC_SHLL_QB_DSP,
494 OPC_SHLLV_S_W = (0x16 << 6) | OPC_SHLL_QB_DSP,
495 OPC_SHRL_QB = (0x01 << 6) | OPC_SHLL_QB_DSP,
496 OPC_SHRLV_QB = (0x03 << 6) | OPC_SHLL_QB_DSP,
497 OPC_SHRL_PH = (0x19 << 6) | OPC_SHLL_QB_DSP,
498 OPC_SHRLV_PH = (0x1B << 6) | OPC_SHLL_QB_DSP,
499 OPC_SHRA_QB = (0x04 << 6) | OPC_SHLL_QB_DSP,
500 OPC_SHRA_R_QB = (0x05 << 6) | OPC_SHLL_QB_DSP,
501 OPC_SHRAV_QB = (0x06 << 6) | OPC_SHLL_QB_DSP,
502 OPC_SHRAV_R_QB = (0x07 << 6) | OPC_SHLL_QB_DSP,
503 OPC_SHRA_PH = (0x09 << 6) | OPC_SHLL_QB_DSP,
504 OPC_SHRAV_PH = (0x0B << 6) | OPC_SHLL_QB_DSP,
505 OPC_SHRA_R_PH = (0x0D << 6) | OPC_SHLL_QB_DSP,
506 OPC_SHRAV_R_PH = (0x0F << 6) | OPC_SHLL_QB_DSP,
507 OPC_SHRA_R_W = (0x15 << 6) | OPC_SHLL_QB_DSP,
508 OPC_SHRAV_R_W = (0x17 << 6) | OPC_SHLL_QB_DSP,
511 #define MASK_DPA_W_PH(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
513 /* MIPS DSP Multiply Sub-class insns */
514 OPC_DPAU_H_QBL = (0x03 << 6) | OPC_DPA_W_PH_DSP,
515 OPC_DPAU_H_QBR = (0x07 << 6) | OPC_DPA_W_PH_DSP,
516 OPC_DPSU_H_QBL = (0x0B << 6) | OPC_DPA_W_PH_DSP,
517 OPC_DPSU_H_QBR = (0x0F << 6) | OPC_DPA_W_PH_DSP,
518 OPC_DPA_W_PH = (0x00 << 6) | OPC_DPA_W_PH_DSP,
519 OPC_DPAX_W_PH = (0x08 << 6) | OPC_DPA_W_PH_DSP,
520 OPC_DPAQ_S_W_PH = (0x04 << 6) | OPC_DPA_W_PH_DSP,
521 OPC_DPAQX_S_W_PH = (0x18 << 6) | OPC_DPA_W_PH_DSP,
522 OPC_DPAQX_SA_W_PH = (0x1A << 6) | OPC_DPA_W_PH_DSP,
523 OPC_DPS_W_PH = (0x01 << 6) | OPC_DPA_W_PH_DSP,
524 OPC_DPSX_W_PH = (0x09 << 6) | OPC_DPA_W_PH_DSP,
525 OPC_DPSQ_S_W_PH = (0x05 << 6) | OPC_DPA_W_PH_DSP,
526 OPC_DPSQX_S_W_PH = (0x19 << 6) | OPC_DPA_W_PH_DSP,
527 OPC_DPSQX_SA_W_PH = (0x1B << 6) | OPC_DPA_W_PH_DSP,
528 OPC_MULSAQ_S_W_PH = (0x06 << 6) | OPC_DPA_W_PH_DSP,
529 OPC_DPAQ_SA_L_W = (0x0C << 6) | OPC_DPA_W_PH_DSP,
530 OPC_DPSQ_SA_L_W = (0x0D << 6) | OPC_DPA_W_PH_DSP,
531 OPC_MAQ_S_W_PHL = (0x14 << 6) | OPC_DPA_W_PH_DSP,
532 OPC_MAQ_S_W_PHR = (0x16 << 6) | OPC_DPA_W_PH_DSP,
533 OPC_MAQ_SA_W_PHL = (0x10 << 6) | OPC_DPA_W_PH_DSP,
534 OPC_MAQ_SA_W_PHR = (0x12 << 6) | OPC_DPA_W_PH_DSP,
535 OPC_MULSA_W_PH = (0x02 << 6) | OPC_DPA_W_PH_DSP,
538 #define MASK_INSV(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
540 /* DSP Bit/Manipulation Sub-class */
541 OPC_INSV = (0x00 << 6) | OPC_INSV_DSP,
544 #define MASK_APPEND(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
546 /* MIPS DSP Compare-Pick Sub-class */
547 OPC_APPEND = (0x00 << 6) | OPC_APPEND_DSP,
548 OPC_PREPEND = (0x01 << 6) | OPC_APPEND_DSP,
549 OPC_BALIGN = (0x10 << 6) | OPC_APPEND_DSP,
552 #define MASK_EXTR_W(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
554 /* MIPS DSP Accumulator and DSPControl Access Sub-class */
555 OPC_EXTR_W = (0x00 << 6) | OPC_EXTR_W_DSP,
556 OPC_EXTR_R_W = (0x04 << 6) | OPC_EXTR_W_DSP,
557 OPC_EXTR_RS_W = (0x06 << 6) | OPC_EXTR_W_DSP,
558 OPC_EXTR_S_H = (0x0E << 6) | OPC_EXTR_W_DSP,
559 OPC_EXTRV_S_H = (0x0F << 6) | OPC_EXTR_W_DSP,
560 OPC_EXTRV_W = (0x01 << 6) | OPC_EXTR_W_DSP,
561 OPC_EXTRV_R_W = (0x05 << 6) | OPC_EXTR_W_DSP,
562 OPC_EXTRV_RS_W = (0x07 << 6) | OPC_EXTR_W_DSP,
563 OPC_EXTP = (0x02 << 6) | OPC_EXTR_W_DSP,
564 OPC_EXTPV = (0x03 << 6) | OPC_EXTR_W_DSP,
565 OPC_EXTPDP = (0x0A << 6) | OPC_EXTR_W_DSP,
566 OPC_EXTPDPV = (0x0B << 6) | OPC_EXTR_W_DSP,
567 OPC_SHILO = (0x1A << 6) | OPC_EXTR_W_DSP,
568 OPC_SHILOV = (0x1B << 6) | OPC_EXTR_W_DSP,
569 OPC_MTHLIP = (0x1F << 6) | OPC_EXTR_W_DSP,
570 OPC_WRDSP = (0x13 << 6) | OPC_EXTR_W_DSP,
571 OPC_RDDSP = (0x12 << 6) | OPC_EXTR_W_DSP,
574 #define MASK_ABSQ_S_QH(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
576 /* MIPS DSP Arithmetic Sub-class */
577 OPC_PRECEQ_L_PWL = (0x14 << 6) | OPC_ABSQ_S_QH_DSP,
578 OPC_PRECEQ_L_PWR = (0x15 << 6) | OPC_ABSQ_S_QH_DSP,
579 OPC_PRECEQ_PW_QHL = (0x0C << 6) | OPC_ABSQ_S_QH_DSP,
580 OPC_PRECEQ_PW_QHR = (0x0D << 6) | OPC_ABSQ_S_QH_DSP,
581 OPC_PRECEQ_PW_QHLA = (0x0E << 6) | OPC_ABSQ_S_QH_DSP,
582 OPC_PRECEQ_PW_QHRA = (0x0F << 6) | OPC_ABSQ_S_QH_DSP,
583 OPC_PRECEQU_QH_OBL = (0x04 << 6) | OPC_ABSQ_S_QH_DSP,
584 OPC_PRECEQU_QH_OBR = (0x05 << 6) | OPC_ABSQ_S_QH_DSP,
585 OPC_PRECEQU_QH_OBLA = (0x06 << 6) | OPC_ABSQ_S_QH_DSP,
586 OPC_PRECEQU_QH_OBRA = (0x07 << 6) | OPC_ABSQ_S_QH_DSP,
587 OPC_PRECEU_QH_OBL = (0x1C << 6) | OPC_ABSQ_S_QH_DSP,
588 OPC_PRECEU_QH_OBR = (0x1D << 6) | OPC_ABSQ_S_QH_DSP,
589 OPC_PRECEU_QH_OBLA = (0x1E << 6) | OPC_ABSQ_S_QH_DSP,
590 OPC_PRECEU_QH_OBRA = (0x1F << 6) | OPC_ABSQ_S_QH_DSP,
591 OPC_ABSQ_S_OB = (0x01 << 6) | OPC_ABSQ_S_QH_DSP,
592 OPC_ABSQ_S_PW = (0x11 << 6) | OPC_ABSQ_S_QH_DSP,
593 OPC_ABSQ_S_QH = (0x09 << 6) | OPC_ABSQ_S_QH_DSP,
594 /* DSP Bit/Manipulation Sub-class */
595 OPC_REPL_OB = (0x02 << 6) | OPC_ABSQ_S_QH_DSP,
596 OPC_REPL_PW = (0x12 << 6) | OPC_ABSQ_S_QH_DSP,
597 OPC_REPL_QH = (0x0A << 6) | OPC_ABSQ_S_QH_DSP,
598 OPC_REPLV_OB = (0x03 << 6) | OPC_ABSQ_S_QH_DSP,
599 OPC_REPLV_PW = (0x13 << 6) | OPC_ABSQ_S_QH_DSP,
600 OPC_REPLV_QH = (0x0B << 6) | OPC_ABSQ_S_QH_DSP,
603 #define MASK_ADDU_OB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
605 /* MIPS DSP Multiply Sub-class insns */
606 OPC_MULEQ_S_PW_QHL = (0x1C << 6) | OPC_ADDU_OB_DSP,
607 OPC_MULEQ_S_PW_QHR = (0x1D << 6) | OPC_ADDU_OB_DSP,
608 OPC_MULEU_S_QH_OBL = (0x06 << 6) | OPC_ADDU_OB_DSP,
609 OPC_MULEU_S_QH_OBR = (0x07 << 6) | OPC_ADDU_OB_DSP,
610 OPC_MULQ_RS_QH = (0x1F << 6) | OPC_ADDU_OB_DSP,
611 /* MIPS DSP Arithmetic Sub-class */
612 OPC_RADDU_L_OB = (0x14 << 6) | OPC_ADDU_OB_DSP,
613 OPC_SUBQ_PW = (0x13 << 6) | OPC_ADDU_OB_DSP,
614 OPC_SUBQ_S_PW = (0x17 << 6) | OPC_ADDU_OB_DSP,
615 OPC_SUBQ_QH = (0x0B << 6) | OPC_ADDU_OB_DSP,
616 OPC_SUBQ_S_QH = (0x0F << 6) | OPC_ADDU_OB_DSP,
617 OPC_SUBU_OB = (0x01 << 6) | OPC_ADDU_OB_DSP,
618 OPC_SUBU_S_OB = (0x05 << 6) | OPC_ADDU_OB_DSP,
619 OPC_SUBU_QH = (0x09 << 6) | OPC_ADDU_OB_DSP,
620 OPC_SUBU_S_QH = (0x0D << 6) | OPC_ADDU_OB_DSP,
621 OPC_SUBUH_OB = (0x19 << 6) | OPC_ADDU_OB_DSP,
622 OPC_SUBUH_R_OB = (0x1B << 6) | OPC_ADDU_OB_DSP,
623 OPC_ADDQ_PW = (0x12 << 6) | OPC_ADDU_OB_DSP,
624 OPC_ADDQ_S_PW = (0x16 << 6) | OPC_ADDU_OB_DSP,
625 OPC_ADDQ_QH = (0x0A << 6) | OPC_ADDU_OB_DSP,
626 OPC_ADDQ_S_QH = (0x0E << 6) | OPC_ADDU_OB_DSP,
627 OPC_ADDU_OB = (0x00 << 6) | OPC_ADDU_OB_DSP,
628 OPC_ADDU_S_OB = (0x04 << 6) | OPC_ADDU_OB_DSP,
629 OPC_ADDU_QH = (0x08 << 6) | OPC_ADDU_OB_DSP,
630 OPC_ADDU_S_QH = (0x0C << 6) | OPC_ADDU_OB_DSP,
631 OPC_ADDUH_OB = (0x18 << 6) | OPC_ADDU_OB_DSP,
632 OPC_ADDUH_R_OB = (0x1A << 6) | OPC_ADDU_OB_DSP,
635 #define MASK_CMPU_EQ_OB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
637 /* DSP Compare-Pick Sub-class */
638 OPC_CMP_EQ_PW = (0x10 << 6) | OPC_CMPU_EQ_OB_DSP,
639 OPC_CMP_LT_PW = (0x11 << 6) | OPC_CMPU_EQ_OB_DSP,
640 OPC_CMP_LE_PW = (0x12 << 6) | OPC_CMPU_EQ_OB_DSP,
641 OPC_CMP_EQ_QH = (0x08 << 6) | OPC_CMPU_EQ_OB_DSP,
642 OPC_CMP_LT_QH = (0x09 << 6) | OPC_CMPU_EQ_OB_DSP,
643 OPC_CMP_LE_QH = (0x0A << 6) | OPC_CMPU_EQ_OB_DSP,
644 OPC_CMPGDU_EQ_OB = (0x18 << 6) | OPC_CMPU_EQ_OB_DSP,
645 OPC_CMPGDU_LT_OB = (0x19 << 6) | OPC_CMPU_EQ_OB_DSP,
646 OPC_CMPGDU_LE_OB = (0x1A << 6) | OPC_CMPU_EQ_OB_DSP,
647 OPC_CMPGU_EQ_OB = (0x04 << 6) | OPC_CMPU_EQ_OB_DSP,
648 OPC_CMPGU_LT_OB = (0x05 << 6) | OPC_CMPU_EQ_OB_DSP,
649 OPC_CMPGU_LE_OB = (0x06 << 6) | OPC_CMPU_EQ_OB_DSP,
650 OPC_CMPU_EQ_OB = (0x00 << 6) | OPC_CMPU_EQ_OB_DSP,
651 OPC_CMPU_LT_OB = (0x01 << 6) | OPC_CMPU_EQ_OB_DSP,
652 OPC_CMPU_LE_OB = (0x02 << 6) | OPC_CMPU_EQ_OB_DSP,
653 OPC_PACKRL_PW = (0x0E << 6) | OPC_CMPU_EQ_OB_DSP,
654 OPC_PICK_OB = (0x03 << 6) | OPC_CMPU_EQ_OB_DSP,
655 OPC_PICK_PW = (0x13 << 6) | OPC_CMPU_EQ_OB_DSP,
656 OPC_PICK_QH = (0x0B << 6) | OPC_CMPU_EQ_OB_DSP,
657 /* MIPS DSP Arithmetic Sub-class */
658 OPC_PRECR_OB_QH = (0x0D << 6) | OPC_CMPU_EQ_OB_DSP,
659 OPC_PRECR_SRA_QH_PW = (0x1E << 6) | OPC_CMPU_EQ_OB_DSP,
660 OPC_PRECR_SRA_R_QH_PW = (0x1F << 6) | OPC_CMPU_EQ_OB_DSP,
661 OPC_PRECRQ_OB_QH = (0x0C << 6) | OPC_CMPU_EQ_OB_DSP,
662 OPC_PRECRQ_PW_L = (0x1C << 6) | OPC_CMPU_EQ_OB_DSP,
663 OPC_PRECRQ_QH_PW = (0x14 << 6) | OPC_CMPU_EQ_OB_DSP,
664 OPC_PRECRQ_RS_QH_PW = (0x15 << 6) | OPC_CMPU_EQ_OB_DSP,
665 OPC_PRECRQU_S_OB_QH = (0x0F << 6) | OPC_CMPU_EQ_OB_DSP,
668 #define MASK_DAPPEND(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
670 /* DSP Compare-Pick Sub-class */
671 OPC_DAPPEND = (0x00 << 6) | OPC_DAPPEND_DSP,
672 OPC_PREPENDD = (0x03 << 6) | OPC_DAPPEND_DSP,
673 OPC_PREPENDW = (0x01 << 6) | OPC_DAPPEND_DSP,
674 OPC_DBALIGN = (0x10 << 6) | OPC_DAPPEND_DSP,
677 #define MASK_DEXTR_W(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
679 /* MIPS DSP Accumulator and DSPControl Access Sub-class */
680 OPC_DMTHLIP = (0x1F << 6) | OPC_DEXTR_W_DSP,
681 OPC_DSHILO = (0x1A << 6) | OPC_DEXTR_W_DSP,
682 OPC_DEXTP = (0x02 << 6) | OPC_DEXTR_W_DSP,
683 OPC_DEXTPDP = (0x0A << 6) | OPC_DEXTR_W_DSP,
684 OPC_DEXTPDPV = (0x0B << 6) | OPC_DEXTR_W_DSP,
685 OPC_DEXTPV = (0x03 << 6) | OPC_DEXTR_W_DSP,
686 OPC_DEXTR_L = (0x10 << 6) | OPC_DEXTR_W_DSP,
687 OPC_DEXTR_R_L = (0x14 << 6) | OPC_DEXTR_W_DSP,
688 OPC_DEXTR_RS_L = (0x16 << 6) | OPC_DEXTR_W_DSP,
689 OPC_DEXTR_W = (0x00 << 6) | OPC_DEXTR_W_DSP,
690 OPC_DEXTR_R_W = (0x04 << 6) | OPC_DEXTR_W_DSP,
691 OPC_DEXTR_RS_W = (0x06 << 6) | OPC_DEXTR_W_DSP,
692 OPC_DEXTR_S_H = (0x0E << 6) | OPC_DEXTR_W_DSP,
693 OPC_DEXTRV_L = (0x11 << 6) | OPC_DEXTR_W_DSP,
694 OPC_DEXTRV_R_L = (0x15 << 6) | OPC_DEXTR_W_DSP,
695 OPC_DEXTRV_RS_L = (0x17 << 6) | OPC_DEXTR_W_DSP,
696 OPC_DEXTRV_S_H = (0x0F << 6) | OPC_DEXTR_W_DSP,
697 OPC_DEXTRV_W = (0x01 << 6) | OPC_DEXTR_W_DSP,
698 OPC_DEXTRV_R_W = (0x05 << 6) | OPC_DEXTR_W_DSP,
699 OPC_DEXTRV_RS_W = (0x07 << 6) | OPC_DEXTR_W_DSP,
700 OPC_DSHILOV = (0x1B << 6) | OPC_DEXTR_W_DSP,
703 #define MASK_DINSV(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
705 /* DSP Bit/Manipulation Sub-class */
706 OPC_DINSV = (0x00 << 6) | OPC_DINSV_DSP,
709 #define MASK_DPAQ_W_QH(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
711 /* MIPS DSP Multiply Sub-class insns */
712 OPC_DMADD = (0x19 << 6) | OPC_DPAQ_W_QH_DSP,
713 OPC_DMADDU = (0x1D << 6) | OPC_DPAQ_W_QH_DSP,
714 OPC_DMSUB = (0x1B << 6) | OPC_DPAQ_W_QH_DSP,
715 OPC_DMSUBU = (0x1F << 6) | OPC_DPAQ_W_QH_DSP,
716 OPC_DPA_W_QH = (0x00 << 6) | OPC_DPAQ_W_QH_DSP,
717 OPC_DPAQ_S_W_QH = (0x04 << 6) | OPC_DPAQ_W_QH_DSP,
718 OPC_DPAQ_SA_L_PW = (0x0C << 6) | OPC_DPAQ_W_QH_DSP,
719 OPC_DPAU_H_OBL = (0x03 << 6) | OPC_DPAQ_W_QH_DSP,
720 OPC_DPAU_H_OBR = (0x07 << 6) | OPC_DPAQ_W_QH_DSP,
721 OPC_DPS_W_QH = (0x01 << 6) | OPC_DPAQ_W_QH_DSP,
722 OPC_DPSQ_S_W_QH = (0x05 << 6) | OPC_DPAQ_W_QH_DSP,
723 OPC_DPSQ_SA_L_PW = (0x0D << 6) | OPC_DPAQ_W_QH_DSP,
724 OPC_DPSU_H_OBL = (0x0B << 6) | OPC_DPAQ_W_QH_DSP,
725 OPC_DPSU_H_OBR = (0x0F << 6) | OPC_DPAQ_W_QH_DSP,
726 OPC_MAQ_S_L_PWL = (0x1C << 6) | OPC_DPAQ_W_QH_DSP,
727 OPC_MAQ_S_L_PWR = (0x1E << 6) | OPC_DPAQ_W_QH_DSP,
728 OPC_MAQ_S_W_QHLL = (0x14 << 6) | OPC_DPAQ_W_QH_DSP,
729 OPC_MAQ_SA_W_QHLL = (0x10 << 6) | OPC_DPAQ_W_QH_DSP,
730 OPC_MAQ_S_W_QHLR = (0x15 << 6) | OPC_DPAQ_W_QH_DSP,
731 OPC_MAQ_SA_W_QHLR = (0x11 << 6) | OPC_DPAQ_W_QH_DSP,
732 OPC_MAQ_S_W_QHRL = (0x16 << 6) | OPC_DPAQ_W_QH_DSP,
733 OPC_MAQ_SA_W_QHRL = (0x12 << 6) | OPC_DPAQ_W_QH_DSP,
734 OPC_MAQ_S_W_QHRR = (0x17 << 6) | OPC_DPAQ_W_QH_DSP,
735 OPC_MAQ_SA_W_QHRR = (0x13 << 6) | OPC_DPAQ_W_QH_DSP,
736 OPC_MULSAQ_S_L_PW = (0x0E << 6) | OPC_DPAQ_W_QH_DSP,
737 OPC_MULSAQ_S_W_QH = (0x06 << 6) | OPC_DPAQ_W_QH_DSP,
740 #define MASK_SHLL_OB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
742 /* MIPS DSP GPR-Based Shift Sub-class */
743 OPC_SHLL_PW = (0x10 << 6) | OPC_SHLL_OB_DSP,
744 OPC_SHLL_S_PW = (0x14 << 6) | OPC_SHLL_OB_DSP,
745 OPC_SHLLV_OB = (0x02 << 6) | OPC_SHLL_OB_DSP,
746 OPC_SHLLV_PW = (0x12 << 6) | OPC_SHLL_OB_DSP,
747 OPC_SHLLV_S_PW = (0x16 << 6) | OPC_SHLL_OB_DSP,
748 OPC_SHLLV_QH = (0x0A << 6) | OPC_SHLL_OB_DSP,
749 OPC_SHLLV_S_QH = (0x0E << 6) | OPC_SHLL_OB_DSP,
750 OPC_SHRA_PW = (0x11 << 6) | OPC_SHLL_OB_DSP,
751 OPC_SHRA_R_PW = (0x15 << 6) | OPC_SHLL_OB_DSP,
752 OPC_SHRAV_OB = (0x06 << 6) | OPC_SHLL_OB_DSP,
753 OPC_SHRAV_R_OB = (0x07 << 6) | OPC_SHLL_OB_DSP,
754 OPC_SHRAV_PW = (0x13 << 6) | OPC_SHLL_OB_DSP,
755 OPC_SHRAV_R_PW = (0x17 << 6) | OPC_SHLL_OB_DSP,
756 OPC_SHRAV_QH = (0x0B << 6) | OPC_SHLL_OB_DSP,
757 OPC_SHRAV_R_QH = (0x0F << 6) | OPC_SHLL_OB_DSP,
758 OPC_SHRLV_OB = (0x03 << 6) | OPC_SHLL_OB_DSP,
759 OPC_SHRLV_QH = (0x1B << 6) | OPC_SHLL_OB_DSP,
760 OPC_SHLL_OB = (0x00 << 6) | OPC_SHLL_OB_DSP,
761 OPC_SHLL_QH = (0x08 << 6) | OPC_SHLL_OB_DSP,
762 OPC_SHLL_S_QH = (0x0C << 6) | OPC_SHLL_OB_DSP,
763 OPC_SHRA_OB = (0x04 << 6) | OPC_SHLL_OB_DSP,
764 OPC_SHRA_R_OB = (0x05 << 6) | OPC_SHLL_OB_DSP,
765 OPC_SHRA_QH = (0x09 << 6) | OPC_SHLL_OB_DSP,
766 OPC_SHRA_R_QH = (0x0D << 6) | OPC_SHLL_OB_DSP,
767 OPC_SHRL_OB = (0x01 << 6) | OPC_SHLL_OB_DSP,
768 OPC_SHRL_QH = (0x19 << 6) | OPC_SHLL_OB_DSP,
771 /* Coprocessor 0 (rs field) */
772 #define MASK_CP0(op) MASK_OP_MAJOR(op) | (op & (0x1F << 21))
775 OPC_MFC0 = (0x00 << 21) | OPC_CP0,
776 OPC_DMFC0 = (0x01 << 21) | OPC_CP0,
777 OPC_MTC0 = (0x04 << 21) | OPC_CP0,
778 OPC_DMTC0 = (0x05 << 21) | OPC_CP0,
779 OPC_MFTR = (0x08 << 21) | OPC_CP0,
780 OPC_RDPGPR = (0x0A << 21) | OPC_CP0,
781 OPC_MFMC0 = (0x0B << 21) | OPC_CP0,
782 OPC_MTTR = (0x0C << 21) | OPC_CP0,
783 OPC_WRPGPR = (0x0E << 21) | OPC_CP0,
784 OPC_C0 = (0x10 << 21) | OPC_CP0,
785 OPC_C0_FIRST = (0x10 << 21) | OPC_CP0,
786 OPC_C0_LAST = (0x1F << 21) | OPC_CP0,
790 #define MASK_MFMC0(op) MASK_CP0(op) | (op & 0xFFFF)
793 OPC_DMT = 0x01 | (0 << 5) | (0x0F << 6) | (0x01 << 11) | OPC_MFMC0,
794 OPC_EMT = 0x01 | (1 << 5) | (0x0F << 6) | (0x01 << 11) | OPC_MFMC0,
795 OPC_DVPE = 0x01 | (0 << 5) | OPC_MFMC0,
796 OPC_EVPE = 0x01 | (1 << 5) | OPC_MFMC0,
797 OPC_DI = (0 << 5) | (0x0C << 11) | OPC_MFMC0,
798 OPC_EI = (1 << 5) | (0x0C << 11) | OPC_MFMC0,
801 /* Coprocessor 0 (with rs == C0) */
802 #define MASK_C0(op) MASK_CP0(op) | (op & 0x3F)
805 OPC_TLBR = 0x01 | OPC_C0,
806 OPC_TLBWI = 0x02 | OPC_C0,
807 OPC_TLBWR = 0x06 | OPC_C0,
808 OPC_TLBP = 0x08 | OPC_C0,
809 OPC_RFE = 0x10 | OPC_C0,
810 OPC_ERET = 0x18 | OPC_C0,
811 OPC_DERET = 0x1F | OPC_C0,
812 OPC_WAIT = 0x20 | OPC_C0,
815 /* Coprocessor 1 (rs field) */
816 #define MASK_CP1(op) MASK_OP_MAJOR(op) | (op & (0x1F << 21))
818 /* Values for the fmt field in FP instructions */
820 /* 0 - 15 are reserved */
821 FMT_S = 16, /* single fp */
822 FMT_D = 17, /* double fp */
823 FMT_E = 18, /* extended fp */
824 FMT_Q = 19, /* quad fp */
825 FMT_W = 20, /* 32-bit fixed */
826 FMT_L = 21, /* 64-bit fixed */
827 FMT_PS = 22, /* paired single fp */
828 /* 23 - 31 are reserved */
832 OPC_MFC1 = (0x00 << 21) | OPC_CP1,
833 OPC_DMFC1 = (0x01 << 21) | OPC_CP1,
834 OPC_CFC1 = (0x02 << 21) | OPC_CP1,
835 OPC_MFHC1 = (0x03 << 21) | OPC_CP1,
836 OPC_MTC1 = (0x04 << 21) | OPC_CP1,
837 OPC_DMTC1 = (0x05 << 21) | OPC_CP1,
838 OPC_CTC1 = (0x06 << 21) | OPC_CP1,
839 OPC_MTHC1 = (0x07 << 21) | OPC_CP1,
840 OPC_BC1 = (0x08 << 21) | OPC_CP1, /* bc */
841 OPC_BC1ANY2 = (0x09 << 21) | OPC_CP1,
842 OPC_BC1ANY4 = (0x0A << 21) | OPC_CP1,
843 OPC_S_FMT = (FMT_S << 21) | OPC_CP1,
844 OPC_D_FMT = (FMT_D << 21) | OPC_CP1,
845 OPC_E_FMT = (FMT_E << 21) | OPC_CP1,
846 OPC_Q_FMT = (FMT_Q << 21) | OPC_CP1,
847 OPC_W_FMT = (FMT_W << 21) | OPC_CP1,
848 OPC_L_FMT = (FMT_L << 21) | OPC_CP1,
849 OPC_PS_FMT = (FMT_PS << 21) | OPC_CP1,
852 #define MASK_CP1_FUNC(op) MASK_CP1(op) | (op & 0x3F)
853 #define MASK_BC1(op) MASK_CP1(op) | (op & (0x3 << 16))
856 OPC_BC1F = (0x00 << 16) | OPC_BC1,
857 OPC_BC1T = (0x01 << 16) | OPC_BC1,
858 OPC_BC1FL = (0x02 << 16) | OPC_BC1,
859 OPC_BC1TL = (0x03 << 16) | OPC_BC1,
863 OPC_BC1FANY2 = (0x00 << 16) | OPC_BC1ANY2,
864 OPC_BC1TANY2 = (0x01 << 16) | OPC_BC1ANY2,
868 OPC_BC1FANY4 = (0x00 << 16) | OPC_BC1ANY4,
869 OPC_BC1TANY4 = (0x01 << 16) | OPC_BC1ANY4,
872 #define MASK_CP2(op) MASK_OP_MAJOR(op) | (op & (0x1F << 21))
875 OPC_MFC2 = (0x00 << 21) | OPC_CP2,
876 OPC_DMFC2 = (0x01 << 21) | OPC_CP2,
877 OPC_CFC2 = (0x02 << 21) | OPC_CP2,
878 OPC_MFHC2 = (0x03 << 21) | OPC_CP2,
879 OPC_MTC2 = (0x04 << 21) | OPC_CP2,
880 OPC_DMTC2 = (0x05 << 21) | OPC_CP2,
881 OPC_CTC2 = (0x06 << 21) | OPC_CP2,
882 OPC_MTHC2 = (0x07 << 21) | OPC_CP2,
883 OPC_BC2 = (0x08 << 21) | OPC_CP2,
886 #define MASK_LMI(op) (MASK_OP_MAJOR(op) | (op & (0x1F << 21)) | (op & 0x1F))
889 OPC_PADDSH = (24 << 21) | (0x00) | OPC_CP2,
890 OPC_PADDUSH = (25 << 21) | (0x00) | OPC_CP2,
891 OPC_PADDH = (26 << 21) | (0x00) | OPC_CP2,
892 OPC_PADDW = (27 << 21) | (0x00) | OPC_CP2,
893 OPC_PADDSB = (28 << 21) | (0x00) | OPC_CP2,
894 OPC_PADDUSB = (29 << 21) | (0x00) | OPC_CP2,
895 OPC_PADDB = (30 << 21) | (0x00) | OPC_CP2,
896 OPC_PADDD = (31 << 21) | (0x00) | OPC_CP2,
898 OPC_PSUBSH = (24 << 21) | (0x01) | OPC_CP2,
899 OPC_PSUBUSH = (25 << 21) | (0x01) | OPC_CP2,
900 OPC_PSUBH = (26 << 21) | (0x01) | OPC_CP2,
901 OPC_PSUBW = (27 << 21) | (0x01) | OPC_CP2,
902 OPC_PSUBSB = (28 << 21) | (0x01) | OPC_CP2,
903 OPC_PSUBUSB = (29 << 21) | (0x01) | OPC_CP2,
904 OPC_PSUBB = (30 << 21) | (0x01) | OPC_CP2,
905 OPC_PSUBD = (31 << 21) | (0x01) | OPC_CP2,
907 OPC_PSHUFH = (24 << 21) | (0x02) | OPC_CP2,
908 OPC_PACKSSWH = (25 << 21) | (0x02) | OPC_CP2,
909 OPC_PACKSSHB = (26 << 21) | (0x02) | OPC_CP2,
910 OPC_PACKUSHB = (27 << 21) | (0x02) | OPC_CP2,
911 OPC_XOR_CP2 = (28 << 21) | (0x02) | OPC_CP2,
912 OPC_NOR_CP2 = (29 << 21) | (0x02) | OPC_CP2,
913 OPC_AND_CP2 = (30 << 21) | (0x02) | OPC_CP2,
914 OPC_PANDN = (31 << 21) | (0x02) | OPC_CP2,
916 OPC_PUNPCKLHW = (24 << 21) | (0x03) | OPC_CP2,
917 OPC_PUNPCKHHW = (25 << 21) | (0x03) | OPC_CP2,
918 OPC_PUNPCKLBH = (26 << 21) | (0x03) | OPC_CP2,
919 OPC_PUNPCKHBH = (27 << 21) | (0x03) | OPC_CP2,
920 OPC_PINSRH_0 = (28 << 21) | (0x03) | OPC_CP2,
921 OPC_PINSRH_1 = (29 << 21) | (0x03) | OPC_CP2,
922 OPC_PINSRH_2 = (30 << 21) | (0x03) | OPC_CP2,
923 OPC_PINSRH_3 = (31 << 21) | (0x03) | OPC_CP2,
925 OPC_PAVGH = (24 << 21) | (0x08) | OPC_CP2,
926 OPC_PAVGB = (25 << 21) | (0x08) | OPC_CP2,
927 OPC_PMAXSH = (26 << 21) | (0x08) | OPC_CP2,
928 OPC_PMINSH = (27 << 21) | (0x08) | OPC_CP2,
929 OPC_PMAXUB = (28 << 21) | (0x08) | OPC_CP2,
930 OPC_PMINUB = (29 << 21) | (0x08) | OPC_CP2,
932 OPC_PCMPEQW = (24 << 21) | (0x09) | OPC_CP2,
933 OPC_PCMPGTW = (25 << 21) | (0x09) | OPC_CP2,
934 OPC_PCMPEQH = (26 << 21) | (0x09) | OPC_CP2,
935 OPC_PCMPGTH = (27 << 21) | (0x09) | OPC_CP2,
936 OPC_PCMPEQB = (28 << 21) | (0x09) | OPC_CP2,
937 OPC_PCMPGTB = (29 << 21) | (0x09) | OPC_CP2,
939 OPC_PSLLW = (24 << 21) | (0x0A) | OPC_CP2,
940 OPC_PSLLH = (25 << 21) | (0x0A) | OPC_CP2,
941 OPC_PMULLH = (26 << 21) | (0x0A) | OPC_CP2,
942 OPC_PMULHH = (27 << 21) | (0x0A) | OPC_CP2,
943 OPC_PMULUW = (28 << 21) | (0x0A) | OPC_CP2,
944 OPC_PMULHUH = (29 << 21) | (0x0A) | OPC_CP2,
946 OPC_PSRLW = (24 << 21) | (0x0B) | OPC_CP2,
947 OPC_PSRLH = (25 << 21) | (0x0B) | OPC_CP2,
948 OPC_PSRAW = (26 << 21) | (0x0B) | OPC_CP2,
949 OPC_PSRAH = (27 << 21) | (0x0B) | OPC_CP2,
950 OPC_PUNPCKLWD = (28 << 21) | (0x0B) | OPC_CP2,
951 OPC_PUNPCKHWD = (29 << 21) | (0x0B) | OPC_CP2,
953 OPC_ADDU_CP2 = (24 << 21) | (0x0C) | OPC_CP2,
954 OPC_OR_CP2 = (25 << 21) | (0x0C) | OPC_CP2,
955 OPC_ADD_CP2 = (26 << 21) | (0x0C) | OPC_CP2,
956 OPC_DADD_CP2 = (27 << 21) | (0x0C) | OPC_CP2,
957 OPC_SEQU_CP2 = (28 << 21) | (0x0C) | OPC_CP2,
958 OPC_SEQ_CP2 = (29 << 21) | (0x0C) | OPC_CP2,
960 OPC_SUBU_CP2 = (24 << 21) | (0x0D) | OPC_CP2,
961 OPC_PASUBUB = (25 << 21) | (0x0D) | OPC_CP2,
962 OPC_SUB_CP2 = (26 << 21) | (0x0D) | OPC_CP2,
963 OPC_DSUB_CP2 = (27 << 21) | (0x0D) | OPC_CP2,
964 OPC_SLTU_CP2 = (28 << 21) | (0x0D) | OPC_CP2,
965 OPC_SLT_CP2 = (29 << 21) | (0x0D) | OPC_CP2,
967 OPC_SLL_CP2 = (24 << 21) | (0x0E) | OPC_CP2,
968 OPC_DSLL_CP2 = (25 << 21) | (0x0E) | OPC_CP2,
969 OPC_PEXTRH = (26 << 21) | (0x0E) | OPC_CP2,
970 OPC_PMADDHW = (27 << 21) | (0x0E) | OPC_CP2,
971 OPC_SLEU_CP2 = (28 << 21) | (0x0E) | OPC_CP2,
972 OPC_SLE_CP2 = (29 << 21) | (0x0E) | OPC_CP2,
974 OPC_SRL_CP2 = (24 << 21) | (0x0F) | OPC_CP2,
975 OPC_DSRL_CP2 = (25 << 21) | (0x0F) | OPC_CP2,
976 OPC_SRA_CP2 = (26 << 21) | (0x0F) | OPC_CP2,
977 OPC_DSRA_CP2 = (27 << 21) | (0x0F) | OPC_CP2,
978 OPC_BIADD = (28 << 21) | (0x0F) | OPC_CP2,
979 OPC_PMOVMSKB = (29 << 21) | (0x0F) | OPC_CP2,
983 #define MASK_CP3(op) MASK_OP_MAJOR(op) | (op & 0x3F)
986 OPC_LWXC1 = 0x00 | OPC_CP3,
987 OPC_LDXC1 = 0x01 | OPC_CP3,
988 OPC_LUXC1 = 0x05 | OPC_CP3,
989 OPC_SWXC1 = 0x08 | OPC_CP3,
990 OPC_SDXC1 = 0x09 | OPC_CP3,
991 OPC_SUXC1 = 0x0D | OPC_CP3,
992 OPC_PREFX = 0x0F | OPC_CP3,
993 OPC_ALNV_PS = 0x1E | OPC_CP3,
994 OPC_MADD_S = 0x20 | OPC_CP3,
995 OPC_MADD_D = 0x21 | OPC_CP3,
996 OPC_MADD_PS = 0x26 | OPC_CP3,
997 OPC_MSUB_S = 0x28 | OPC_CP3,
998 OPC_MSUB_D = 0x29 | OPC_CP3,
999 OPC_MSUB_PS = 0x2E | OPC_CP3,
1000 OPC_NMADD_S = 0x30 | OPC_CP3,
1001 OPC_NMADD_D = 0x31 | OPC_CP3,
1002 OPC_NMADD_PS= 0x36 | OPC_CP3,
1003 OPC_NMSUB_S = 0x38 | OPC_CP3,
1004 OPC_NMSUB_D = 0x39 | OPC_CP3,
1005 OPC_NMSUB_PS= 0x3E | OPC_CP3,
1008 /* global register indices */
1009 static TCGv_ptr cpu_env;
1010 static TCGv cpu_gpr[32], cpu_PC;
1011 static TCGv cpu_HI[MIPS_DSP_ACC], cpu_LO[MIPS_DSP_ACC], cpu_ACX[MIPS_DSP_ACC];
1012 static TCGv cpu_dspctrl, btarget, bcond;
1013 static TCGv_i32 hflags;
1014 static TCGv_i32 fpu_fcr0, fpu_fcr31;
1015 static TCGv_i64 fpu_f64[32];
1017 static uint32_t gen_opc_hflags[OPC_BUF_SIZE];
1018 static target_ulong gen_opc_btarget[OPC_BUF_SIZE];
1020 #include "gen-icount.h"
1022 #define gen_helper_0e0i(name, arg) do { \
1023 TCGv_i32 helper_tmp = tcg_const_i32(arg); \
1024 gen_helper_##name(cpu_env, helper_tmp); \
1025 tcg_temp_free_i32(helper_tmp); \
1028 #define gen_helper_0e1i(name, arg1, arg2) do { \
1029 TCGv_i32 helper_tmp = tcg_const_i32(arg2); \
1030 gen_helper_##name(cpu_env, arg1, helper_tmp); \
1031 tcg_temp_free_i32(helper_tmp); \
1034 #define gen_helper_1e0i(name, ret, arg1) do { \
1035 TCGv_i32 helper_tmp = tcg_const_i32(arg1); \
1036 gen_helper_##name(ret, cpu_env, helper_tmp); \
1037 tcg_temp_free_i32(helper_tmp); \
1040 #define gen_helper_1e1i(name, ret, arg1, arg2) do { \
1041 TCGv_i32 helper_tmp = tcg_const_i32(arg2); \
1042 gen_helper_##name(ret, cpu_env, arg1, helper_tmp); \
1043 tcg_temp_free_i32(helper_tmp); \
1046 #define gen_helper_0e2i(name, arg1, arg2, arg3) do { \
1047 TCGv_i32 helper_tmp = tcg_const_i32(arg3); \
1048 gen_helper_##name(cpu_env, arg1, arg2, helper_tmp); \
1049 tcg_temp_free_i32(helper_tmp); \
1052 #define gen_helper_1e2i(name, ret, arg1, arg2, arg3) do { \
1053 TCGv_i32 helper_tmp = tcg_const_i32(arg3); \
1054 gen_helper_##name(ret, cpu_env, arg1, arg2, helper_tmp); \
1055 tcg_temp_free_i32(helper_tmp); \
1058 #define gen_helper_0e3i(name, arg1, arg2, arg3, arg4) do { \
1059 TCGv_i32 helper_tmp = tcg_const_i32(arg4); \
1060 gen_helper_##name(cpu_env, arg1, arg2, arg3, helper_tmp); \
1061 tcg_temp_free_i32(helper_tmp); \
1064 typedef struct DisasContext {
1065 struct TranslationBlock *tb;
1066 target_ulong pc, saved_pc;
1068 int singlestep_enabled;
1069 /* Routine used to access memory */
1071 uint32_t hflags, saved_hflags;
1073 target_ulong btarget;
1077 BS_NONE = 0, /* We go out of the TB without reaching a branch or an
1078 * exception condition */
1079 BS_STOP = 1, /* We want to stop translation for any reason */
1080 BS_BRANCH = 2, /* We reached a branch condition */
1081 BS_EXCP = 3, /* We reached an exception condition */
1084 static const char * const regnames[] = {
1085 "r0", "at", "v0", "v1", "a0", "a1", "a2", "a3",
1086 "t0", "t1", "t2", "t3", "t4", "t5", "t6", "t7",
1087 "s0", "s1", "s2", "s3", "s4", "s5", "s6", "s7",
1088 "t8", "t9", "k0", "k1", "gp", "sp", "s8", "ra",
1091 static const char * const regnames_HI[] = {
1092 "HI0", "HI1", "HI2", "HI3",
1095 static const char * const regnames_LO[] = {
1096 "LO0", "LO1", "LO2", "LO3",
1099 static const char * const regnames_ACX[] = {
1100 "ACX0", "ACX1", "ACX2", "ACX3",
1103 static const char * const fregnames[] = {
1104 "f0", "f1", "f2", "f3", "f4", "f5", "f6", "f7",
1105 "f8", "f9", "f10", "f11", "f12", "f13", "f14", "f15",
1106 "f16", "f17", "f18", "f19", "f20", "f21", "f22", "f23",
1107 "f24", "f25", "f26", "f27", "f28", "f29", "f30", "f31",
1110 #define MIPS_DEBUG(fmt, ...) \
1112 if (MIPS_DEBUG_DISAS) { \
1113 qemu_log_mask(CPU_LOG_TB_IN_ASM, \
1114 TARGET_FMT_lx ": %08x " fmt "\n", \
1115 ctx->pc, ctx->opcode , ## __VA_ARGS__); \
1119 #define LOG_DISAS(...) \
1121 if (MIPS_DEBUG_DISAS) { \
1122 qemu_log_mask(CPU_LOG_TB_IN_ASM, ## __VA_ARGS__); \
1126 #define MIPS_INVAL(op) \
1127 MIPS_DEBUG("Invalid %s %03x %03x %03x", op, ctx->opcode >> 26, \
1128 ctx->opcode & 0x3F, ((ctx->opcode >> 16) & 0x1F))
1130 /* General purpose registers moves. */
1131 static inline void gen_load_gpr (TCGv t, int reg)
1134 tcg_gen_movi_tl(t, 0);
1136 tcg_gen_mov_tl(t, cpu_gpr[reg]);
1139 static inline void gen_store_gpr (TCGv t, int reg)
1142 tcg_gen_mov_tl(cpu_gpr[reg], t);
1145 /* Moves to/from ACX register. */
1146 static inline void gen_load_ACX (TCGv t, int reg)
1148 tcg_gen_mov_tl(t, cpu_ACX[reg]);
1151 static inline void gen_store_ACX (TCGv t, int reg)
1153 tcg_gen_mov_tl(cpu_ACX[reg], t);
1156 /* Moves to/from shadow registers. */
1157 static inline void gen_load_srsgpr (int from, int to)
1159 TCGv t0 = tcg_temp_new();
1162 tcg_gen_movi_tl(t0, 0);
1164 TCGv_i32 t2 = tcg_temp_new_i32();
1165 TCGv_ptr addr = tcg_temp_new_ptr();
1167 tcg_gen_ld_i32(t2, cpu_env, offsetof(CPUMIPSState, CP0_SRSCtl));
1168 tcg_gen_shri_i32(t2, t2, CP0SRSCtl_PSS);
1169 tcg_gen_andi_i32(t2, t2, 0xf);
1170 tcg_gen_muli_i32(t2, t2, sizeof(target_ulong) * 32);
1171 tcg_gen_ext_i32_ptr(addr, t2);
1172 tcg_gen_add_ptr(addr, cpu_env, addr);
1174 tcg_gen_ld_tl(t0, addr, sizeof(target_ulong) * from);
1175 tcg_temp_free_ptr(addr);
1176 tcg_temp_free_i32(t2);
1178 gen_store_gpr(t0, to);
1182 static inline void gen_store_srsgpr (int from, int to)
1185 TCGv t0 = tcg_temp_new();
1186 TCGv_i32 t2 = tcg_temp_new_i32();
1187 TCGv_ptr addr = tcg_temp_new_ptr();
1189 gen_load_gpr(t0, from);
1190 tcg_gen_ld_i32(t2, cpu_env, offsetof(CPUMIPSState, CP0_SRSCtl));
1191 tcg_gen_shri_i32(t2, t2, CP0SRSCtl_PSS);
1192 tcg_gen_andi_i32(t2, t2, 0xf);
1193 tcg_gen_muli_i32(t2, t2, sizeof(target_ulong) * 32);
1194 tcg_gen_ext_i32_ptr(addr, t2);
1195 tcg_gen_add_ptr(addr, cpu_env, addr);
1197 tcg_gen_st_tl(t0, addr, sizeof(target_ulong) * to);
1198 tcg_temp_free_ptr(addr);
1199 tcg_temp_free_i32(t2);
1204 /* Floating point register moves. */
1205 static void gen_load_fpr32(TCGv_i32 t, int reg)
1207 tcg_gen_trunc_i64_i32(t, fpu_f64[reg]);
1210 static void gen_store_fpr32(TCGv_i32 t, int reg)
1212 TCGv_i64 t64 = tcg_temp_new_i64();
1213 tcg_gen_extu_i32_i64(t64, t);
1214 tcg_gen_deposit_i64(fpu_f64[reg], fpu_f64[reg], t64, 0, 32);
1215 tcg_temp_free_i64(t64);
1218 static void gen_load_fpr32h(TCGv_i32 t, int reg)
1220 TCGv_i64 t64 = tcg_temp_new_i64();
1221 tcg_gen_shri_i64(t64, fpu_f64[reg], 32);
1222 tcg_gen_trunc_i64_i32(t, t64);
1223 tcg_temp_free_i64(t64);
1226 static void gen_store_fpr32h(TCGv_i32 t, int reg)
1228 TCGv_i64 t64 = tcg_temp_new_i64();
1229 tcg_gen_extu_i32_i64(t64, t);
1230 tcg_gen_deposit_i64(fpu_f64[reg], fpu_f64[reg], t64, 32, 32);
1231 tcg_temp_free_i64(t64);
1234 static void gen_load_fpr64(DisasContext *ctx, TCGv_i64 t, int reg)
1236 if (ctx->hflags & MIPS_HFLAG_F64) {
1237 tcg_gen_mov_i64(t, fpu_f64[reg]);
1239 tcg_gen_concat32_i64(t, fpu_f64[reg & ~1], fpu_f64[reg | 1]);
1243 static void gen_store_fpr64(DisasContext *ctx, TCGv_i64 t, int reg)
1245 if (ctx->hflags & MIPS_HFLAG_F64) {
1246 tcg_gen_mov_i64(fpu_f64[reg], t);
1249 tcg_gen_deposit_i64(fpu_f64[reg & ~1], fpu_f64[reg & ~1], t, 0, 32);
1250 t0 = tcg_temp_new_i64();
1251 tcg_gen_shri_i64(t0, t, 32);
1252 tcg_gen_deposit_i64(fpu_f64[reg | 1], fpu_f64[reg | 1], t0, 0, 32);
1253 tcg_temp_free_i64(t0);
1257 static inline int get_fp_bit (int cc)
1266 static inline void gen_save_pc(target_ulong pc)
1268 tcg_gen_movi_tl(cpu_PC, pc);
1271 static inline void save_cpu_state (DisasContext *ctx, int do_save_pc)
1273 LOG_DISAS("hflags %08x saved %08x\n", ctx->hflags, ctx->saved_hflags);
1274 if (do_save_pc && ctx->pc != ctx->saved_pc) {
1275 gen_save_pc(ctx->pc);
1276 ctx->saved_pc = ctx->pc;
1278 if (ctx->hflags != ctx->saved_hflags) {
1279 tcg_gen_movi_i32(hflags, ctx->hflags);
1280 ctx->saved_hflags = ctx->hflags;
1281 switch (ctx->hflags & MIPS_HFLAG_BMASK_BASE) {
1287 tcg_gen_movi_tl(btarget, ctx->btarget);
1293 static inline void restore_cpu_state (CPUMIPSState *env, DisasContext *ctx)
1295 ctx->saved_hflags = ctx->hflags;
1296 switch (ctx->hflags & MIPS_HFLAG_BMASK_BASE) {
1302 ctx->btarget = env->btarget;
1308 generate_exception_err (DisasContext *ctx, int excp, int err)
1310 TCGv_i32 texcp = tcg_const_i32(excp);
1311 TCGv_i32 terr = tcg_const_i32(err);
1312 save_cpu_state(ctx, 1);
1313 gen_helper_raise_exception_err(cpu_env, texcp, terr);
1314 tcg_temp_free_i32(terr);
1315 tcg_temp_free_i32(texcp);
1319 generate_exception (DisasContext *ctx, int excp)
1321 save_cpu_state(ctx, 1);
1322 gen_helper_0e0i(raise_exception, excp);
1325 /* Addresses computation */
1326 static inline void gen_op_addr_add (DisasContext *ctx, TCGv ret, TCGv arg0, TCGv arg1)
1328 tcg_gen_add_tl(ret, arg0, arg1);
1330 #if defined(TARGET_MIPS64)
1331 /* For compatibility with 32-bit code, data reference in user mode
1332 with Status_UX = 0 should be casted to 32-bit and sign extended.
1333 See the MIPS64 PRA manual, section 4.10. */
1334 if (((ctx->hflags & MIPS_HFLAG_KSU) == MIPS_HFLAG_UM) &&
1335 !(ctx->hflags & MIPS_HFLAG_UX)) {
1336 tcg_gen_ext32s_i64(ret, ret);
1341 static inline void check_cp0_enabled(DisasContext *ctx)
1343 if (unlikely(!(ctx->hflags & MIPS_HFLAG_CP0)))
1344 generate_exception_err(ctx, EXCP_CpU, 0);
1347 static inline void check_cp1_enabled(DisasContext *ctx)
1349 if (unlikely(!(ctx->hflags & MIPS_HFLAG_FPU)))
1350 generate_exception_err(ctx, EXCP_CpU, 1);
1353 /* Verify that the processor is running with COP1X instructions enabled.
1354 This is associated with the nabla symbol in the MIPS32 and MIPS64
1357 static inline void check_cop1x(DisasContext *ctx)
1359 if (unlikely(!(ctx->hflags & MIPS_HFLAG_COP1X)))
1360 generate_exception(ctx, EXCP_RI);
1363 /* Verify that the processor is running with 64-bit floating-point
1364 operations enabled. */
1366 static inline void check_cp1_64bitmode(DisasContext *ctx)
1368 if (unlikely(~ctx->hflags & (MIPS_HFLAG_F64 | MIPS_HFLAG_COP1X)))
1369 generate_exception(ctx, EXCP_RI);
1373 * Verify if floating point register is valid; an operation is not defined
1374 * if bit 0 of any register specification is set and the FR bit in the
1375 * Status register equals zero, since the register numbers specify an
1376 * even-odd pair of adjacent coprocessor general registers. When the FR bit
1377 * in the Status register equals one, both even and odd register numbers
1378 * are valid. This limitation exists only for 64 bit wide (d,l,ps) registers.
1380 * Multiple 64 bit wide registers can be checked by calling
1381 * gen_op_cp1_registers(freg1 | freg2 | ... | fregN);
1383 static inline void check_cp1_registers(DisasContext *ctx, int regs)
1385 if (unlikely(!(ctx->hflags & MIPS_HFLAG_F64) && (regs & 1)))
1386 generate_exception(ctx, EXCP_RI);
1389 /* Verify that the processor is running with DSP instructions enabled.
1390 This is enabled by CP0 Status register MX(24) bit.
1393 static inline void check_dsp(DisasContext *ctx)
1395 if (unlikely(!(ctx->hflags & MIPS_HFLAG_DSP))) {
1396 generate_exception(ctx, EXCP_DSPDIS);
1400 static inline void check_dspr2(DisasContext *ctx)
1402 if (unlikely(!(ctx->hflags & MIPS_HFLAG_DSPR2))) {
1403 generate_exception(ctx, EXCP_DSPDIS);
1407 /* This code generates a "reserved instruction" exception if the
1408 CPU does not support the instruction set corresponding to flags. */
1409 static inline void check_insn(CPUMIPSState *env, DisasContext *ctx, int flags)
1411 if (unlikely(!(env->insn_flags & flags)))
1412 generate_exception(ctx, EXCP_RI);
1415 /* This code generates a "reserved instruction" exception if 64-bit
1416 instructions are not enabled. */
1417 static inline void check_mips_64(DisasContext *ctx)
1419 if (unlikely(!(ctx->hflags & MIPS_HFLAG_64)))
1420 generate_exception(ctx, EXCP_RI);
1423 /* Define small wrappers for gen_load_fpr* so that we have a uniform
1424 calling interface for 32 and 64-bit FPRs. No sense in changing
1425 all callers for gen_load_fpr32 when we need the CTX parameter for
1427 #define gen_ldcmp_fpr32(ctx, x, y) gen_load_fpr32(x, y)
1428 #define gen_ldcmp_fpr64(ctx, x, y) gen_load_fpr64(ctx, x, y)
1429 #define FOP_CONDS(type, abs, fmt, ifmt, bits) \
1430 static inline void gen_cmp ## type ## _ ## fmt(DisasContext *ctx, int n, \
1431 int ft, int fs, int cc) \
1433 TCGv_i##bits fp0 = tcg_temp_new_i##bits (); \
1434 TCGv_i##bits fp1 = tcg_temp_new_i##bits (); \
1437 check_cp1_64bitmode(ctx); \
1443 check_cp1_registers(ctx, fs | ft); \
1451 gen_ldcmp_fpr##bits (ctx, fp0, fs); \
1452 gen_ldcmp_fpr##bits (ctx, fp1, ft); \
1454 case 0: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _f, fp0, fp1, cc); break;\
1455 case 1: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _un, fp0, fp1, cc); break;\
1456 case 2: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _eq, fp0, fp1, cc); break;\
1457 case 3: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ueq, fp0, fp1, cc); break;\
1458 case 4: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _olt, fp0, fp1, cc); break;\
1459 case 5: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ult, fp0, fp1, cc); break;\
1460 case 6: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ole, fp0, fp1, cc); break;\
1461 case 7: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ule, fp0, fp1, cc); break;\
1462 case 8: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _sf, fp0, fp1, cc); break;\
1463 case 9: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ngle, fp0, fp1, cc); break;\
1464 case 10: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _seq, fp0, fp1, cc); break;\
1465 case 11: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ngl, fp0, fp1, cc); break;\
1466 case 12: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _lt, fp0, fp1, cc); break;\
1467 case 13: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _nge, fp0, fp1, cc); break;\
1468 case 14: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _le, fp0, fp1, cc); break;\
1469 case 15: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ngt, fp0, fp1, cc); break;\
1472 tcg_temp_free_i##bits (fp0); \
1473 tcg_temp_free_i##bits (fp1); \
1476 FOP_CONDS(, 0, d, FMT_D, 64)
1477 FOP_CONDS(abs, 1, d, FMT_D, 64)
1478 FOP_CONDS(, 0, s, FMT_S, 32)
1479 FOP_CONDS(abs, 1, s, FMT_S, 32)
1480 FOP_CONDS(, 0, ps, FMT_PS, 64)
1481 FOP_CONDS(abs, 1, ps, FMT_PS, 64)
1483 #undef gen_ldcmp_fpr32
1484 #undef gen_ldcmp_fpr64
1486 /* load/store instructions. */
1487 #ifdef CONFIG_USER_ONLY
1488 #define OP_LD_ATOMIC(insn,fname) \
1489 static inline void op_ld_##insn(TCGv ret, TCGv arg1, DisasContext *ctx) \
1491 TCGv t0 = tcg_temp_new(); \
1492 tcg_gen_mov_tl(t0, arg1); \
1493 tcg_gen_qemu_##fname(ret, arg1, ctx->mem_idx); \
1494 tcg_gen_st_tl(t0, cpu_env, offsetof(CPUMIPSState, lladdr)); \
1495 tcg_gen_st_tl(ret, cpu_env, offsetof(CPUMIPSState, llval)); \
1496 tcg_temp_free(t0); \
1499 #define OP_LD_ATOMIC(insn,fname) \
1500 static inline void op_ld_##insn(TCGv ret, TCGv arg1, DisasContext *ctx) \
1502 gen_helper_1e1i(insn, ret, arg1, ctx->mem_idx); \
1505 OP_LD_ATOMIC(ll,ld32s);
1506 #if defined(TARGET_MIPS64)
1507 OP_LD_ATOMIC(lld,ld64);
1511 #ifdef CONFIG_USER_ONLY
1512 #define OP_ST_ATOMIC(insn,fname,ldname,almask) \
1513 static inline void op_st_##insn(TCGv arg1, TCGv arg2, int rt, DisasContext *ctx) \
1515 TCGv t0 = tcg_temp_new(); \
1516 int l1 = gen_new_label(); \
1517 int l2 = gen_new_label(); \
1519 tcg_gen_andi_tl(t0, arg2, almask); \
1520 tcg_gen_brcondi_tl(TCG_COND_EQ, t0, 0, l1); \
1521 tcg_gen_st_tl(arg2, cpu_env, offsetof(CPUMIPSState, CP0_BadVAddr)); \
1522 generate_exception(ctx, EXCP_AdES); \
1523 gen_set_label(l1); \
1524 tcg_gen_ld_tl(t0, cpu_env, offsetof(CPUMIPSState, lladdr)); \
1525 tcg_gen_brcond_tl(TCG_COND_NE, arg2, t0, l2); \
1526 tcg_gen_movi_tl(t0, rt | ((almask << 3) & 0x20)); \
1527 tcg_gen_st_tl(t0, cpu_env, offsetof(CPUMIPSState, llreg)); \
1528 tcg_gen_st_tl(arg1, cpu_env, offsetof(CPUMIPSState, llnewval)); \
1529 gen_helper_0e0i(raise_exception, EXCP_SC); \
1530 gen_set_label(l2); \
1531 tcg_gen_movi_tl(t0, 0); \
1532 gen_store_gpr(t0, rt); \
1533 tcg_temp_free(t0); \
1536 #define OP_ST_ATOMIC(insn,fname,ldname,almask) \
1537 static inline void op_st_##insn(TCGv arg1, TCGv arg2, int rt, DisasContext *ctx) \
1539 TCGv t0 = tcg_temp_new(); \
1540 gen_helper_1e2i(insn, t0, arg1, arg2, ctx->mem_idx); \
1541 gen_store_gpr(t0, rt); \
1542 tcg_temp_free(t0); \
1545 OP_ST_ATOMIC(sc,st32,ld32s,0x3);
1546 #if defined(TARGET_MIPS64)
1547 OP_ST_ATOMIC(scd,st64,ld64,0x7);
1551 static void gen_base_offset_addr (DisasContext *ctx, TCGv addr,
1552 int base, int16_t offset)
1555 tcg_gen_movi_tl(addr, offset);
1556 } else if (offset == 0) {
1557 gen_load_gpr(addr, base);
1559 tcg_gen_movi_tl(addr, offset);
1560 gen_op_addr_add(ctx, addr, cpu_gpr[base], addr);
1564 static target_ulong pc_relative_pc (DisasContext *ctx)
1566 target_ulong pc = ctx->pc;
1568 if (ctx->hflags & MIPS_HFLAG_BMASK) {
1569 int branch_bytes = ctx->hflags & MIPS_HFLAG_BDS16 ? 2 : 4;
1574 pc &= ~(target_ulong)3;
1579 static void gen_ld (CPUMIPSState *env, DisasContext *ctx, uint32_t opc,
1580 int rt, int base, int16_t offset)
1582 const char *opn = "ld";
1585 if (rt == 0 && env->insn_flags & (INSN_LOONGSON2E | INSN_LOONGSON2F)) {
1586 /* Loongson CPU uses a load to zero register for prefetch.
1587 We emulate it as a NOP. On other CPU we must perform the
1588 actual memory access. */
1593 t0 = tcg_temp_new();
1594 gen_base_offset_addr(ctx, t0, base, offset);
1597 #if defined(TARGET_MIPS64)
1599 tcg_gen_qemu_ld32u(t0, t0, ctx->mem_idx);
1600 gen_store_gpr(t0, rt);
1604 tcg_gen_qemu_ld64(t0, t0, ctx->mem_idx);
1605 gen_store_gpr(t0, rt);
1609 save_cpu_state(ctx, 1);
1610 op_ld_lld(t0, t0, ctx);
1611 gen_store_gpr(t0, rt);
1615 t1 = tcg_temp_new();
1616 tcg_gen_andi_tl(t1, t0, 7);
1617 #ifndef TARGET_WORDS_BIGENDIAN
1618 tcg_gen_xori_tl(t1, t1, 7);
1620 tcg_gen_shli_tl(t1, t1, 3);
1621 tcg_gen_andi_tl(t0, t0, ~7);
1622 tcg_gen_qemu_ld64(t0, t0, ctx->mem_idx);
1623 tcg_gen_shl_tl(t0, t0, t1);
1624 tcg_gen_xori_tl(t1, t1, 63);
1625 t2 = tcg_const_tl(0x7fffffffffffffffull);
1626 tcg_gen_shr_tl(t2, t2, t1);
1627 gen_load_gpr(t1, rt);
1628 tcg_gen_and_tl(t1, t1, t2);
1630 tcg_gen_or_tl(t0, t0, t1);
1632 gen_store_gpr(t0, rt);
1636 t1 = tcg_temp_new();
1637 tcg_gen_andi_tl(t1, t0, 7);
1638 #ifdef TARGET_WORDS_BIGENDIAN
1639 tcg_gen_xori_tl(t1, t1, 7);
1641 tcg_gen_shli_tl(t1, t1, 3);
1642 tcg_gen_andi_tl(t0, t0, ~7);
1643 tcg_gen_qemu_ld64(t0, t0, ctx->mem_idx);
1644 tcg_gen_shr_tl(t0, t0, t1);
1645 tcg_gen_xori_tl(t1, t1, 63);
1646 t2 = tcg_const_tl(0xfffffffffffffffeull);
1647 tcg_gen_shl_tl(t2, t2, t1);
1648 gen_load_gpr(t1, rt);
1649 tcg_gen_and_tl(t1, t1, t2);
1651 tcg_gen_or_tl(t0, t0, t1);
1653 gen_store_gpr(t0, rt);
1657 t1 = tcg_const_tl(pc_relative_pc(ctx));
1658 gen_op_addr_add(ctx, t0, t0, t1);
1660 tcg_gen_qemu_ld64(t0, t0, ctx->mem_idx);
1661 gen_store_gpr(t0, rt);
1666 t1 = tcg_const_tl(pc_relative_pc(ctx));
1667 gen_op_addr_add(ctx, t0, t0, t1);
1669 tcg_gen_qemu_ld32s(t0, t0, ctx->mem_idx);
1670 gen_store_gpr(t0, rt);
1674 tcg_gen_qemu_ld32s(t0, t0, ctx->mem_idx);
1675 gen_store_gpr(t0, rt);
1679 tcg_gen_qemu_ld16s(t0, t0, ctx->mem_idx);
1680 gen_store_gpr(t0, rt);
1684 tcg_gen_qemu_ld16u(t0, t0, ctx->mem_idx);
1685 gen_store_gpr(t0, rt);
1689 tcg_gen_qemu_ld8s(t0, t0, ctx->mem_idx);
1690 gen_store_gpr(t0, rt);
1694 tcg_gen_qemu_ld8u(t0, t0, ctx->mem_idx);
1695 gen_store_gpr(t0, rt);
1699 t1 = tcg_temp_new();
1700 tcg_gen_andi_tl(t1, t0, 3);
1701 #ifndef TARGET_WORDS_BIGENDIAN
1702 tcg_gen_xori_tl(t1, t1, 3);
1704 tcg_gen_shli_tl(t1, t1, 3);
1705 tcg_gen_andi_tl(t0, t0, ~3);
1706 tcg_gen_qemu_ld32u(t0, t0, ctx->mem_idx);
1707 tcg_gen_shl_tl(t0, t0, t1);
1708 tcg_gen_xori_tl(t1, t1, 31);
1709 t2 = tcg_const_tl(0x7fffffffull);
1710 tcg_gen_shr_tl(t2, t2, t1);
1711 gen_load_gpr(t1, rt);
1712 tcg_gen_and_tl(t1, t1, t2);
1714 tcg_gen_or_tl(t0, t0, t1);
1716 tcg_gen_ext32s_tl(t0, t0);
1717 gen_store_gpr(t0, rt);
1721 t1 = tcg_temp_new();
1722 tcg_gen_andi_tl(t1, t0, 3);
1723 #ifdef TARGET_WORDS_BIGENDIAN
1724 tcg_gen_xori_tl(t1, t1, 3);
1726 tcg_gen_shli_tl(t1, t1, 3);
1727 tcg_gen_andi_tl(t0, t0, ~3);
1728 tcg_gen_qemu_ld32u(t0, t0, ctx->mem_idx);
1729 tcg_gen_shr_tl(t0, t0, t1);
1730 tcg_gen_xori_tl(t1, t1, 31);
1731 t2 = tcg_const_tl(0xfffffffeull);
1732 tcg_gen_shl_tl(t2, t2, t1);
1733 gen_load_gpr(t1, rt);
1734 tcg_gen_and_tl(t1, t1, t2);
1736 tcg_gen_or_tl(t0, t0, t1);
1738 gen_store_gpr(t0, rt);
1742 save_cpu_state(ctx, 1);
1743 op_ld_ll(t0, t0, ctx);
1744 gen_store_gpr(t0, rt);
1748 (void)opn; /* avoid a compiler warning */
1749 MIPS_DEBUG("%s %s, %d(%s)", opn, regnames[rt], offset, regnames[base]);
1754 static void gen_st (DisasContext *ctx, uint32_t opc, int rt,
1755 int base, int16_t offset)
1757 const char *opn = "st";
1758 TCGv t0 = tcg_temp_new();
1759 TCGv t1 = tcg_temp_new();
1761 gen_base_offset_addr(ctx, t0, base, offset);
1762 gen_load_gpr(t1, rt);
1764 #if defined(TARGET_MIPS64)
1766 tcg_gen_qemu_st64(t1, t0, ctx->mem_idx);
1770 save_cpu_state(ctx, 1);
1771 gen_helper_0e2i(sdl, t1, t0, ctx->mem_idx);
1775 save_cpu_state(ctx, 1);
1776 gen_helper_0e2i(sdr, t1, t0, ctx->mem_idx);
1781 tcg_gen_qemu_st32(t1, t0, ctx->mem_idx);
1785 tcg_gen_qemu_st16(t1, t0, ctx->mem_idx);
1789 tcg_gen_qemu_st8(t1, t0, ctx->mem_idx);
1793 save_cpu_state(ctx, 1);
1794 gen_helper_0e2i(swl, t1, t0, ctx->mem_idx);
1798 save_cpu_state(ctx, 1);
1799 gen_helper_0e2i(swr, t1, t0, ctx->mem_idx);
1803 (void)opn; /* avoid a compiler warning */
1804 MIPS_DEBUG("%s %s, %d(%s)", opn, regnames[rt], offset, regnames[base]);
1810 /* Store conditional */
1811 static void gen_st_cond (DisasContext *ctx, uint32_t opc, int rt,
1812 int base, int16_t offset)
1814 const char *opn = "st_cond";
1817 #ifdef CONFIG_USER_ONLY
1818 t0 = tcg_temp_local_new();
1819 t1 = tcg_temp_local_new();
1821 t0 = tcg_temp_new();
1822 t1 = tcg_temp_new();
1824 gen_base_offset_addr(ctx, t0, base, offset);
1825 gen_load_gpr(t1, rt);
1827 #if defined(TARGET_MIPS64)
1829 save_cpu_state(ctx, 1);
1830 op_st_scd(t1, t0, rt, ctx);
1835 save_cpu_state(ctx, 1);
1836 op_st_sc(t1, t0, rt, ctx);
1840 (void)opn; /* avoid a compiler warning */
1841 MIPS_DEBUG("%s %s, %d(%s)", opn, regnames[rt], offset, regnames[base]);
1846 /* Load and store */
1847 static void gen_flt_ldst (DisasContext *ctx, uint32_t opc, int ft,
1848 int base, int16_t offset)
1850 const char *opn = "flt_ldst";
1851 TCGv t0 = tcg_temp_new();
1853 gen_base_offset_addr(ctx, t0, base, offset);
1854 /* Don't do NOP if destination is zero: we must perform the actual
1859 TCGv_i32 fp0 = tcg_temp_new_i32();
1861 tcg_gen_qemu_ld32s(t0, t0, ctx->mem_idx);
1862 tcg_gen_trunc_tl_i32(fp0, t0);
1863 gen_store_fpr32(fp0, ft);
1864 tcg_temp_free_i32(fp0);
1870 TCGv_i32 fp0 = tcg_temp_new_i32();
1871 TCGv t1 = tcg_temp_new();
1873 gen_load_fpr32(fp0, ft);
1874 tcg_gen_extu_i32_tl(t1, fp0);
1875 tcg_gen_qemu_st32(t1, t0, ctx->mem_idx);
1877 tcg_temp_free_i32(fp0);
1883 TCGv_i64 fp0 = tcg_temp_new_i64();
1885 tcg_gen_qemu_ld64(fp0, t0, ctx->mem_idx);
1886 gen_store_fpr64(ctx, fp0, ft);
1887 tcg_temp_free_i64(fp0);
1893 TCGv_i64 fp0 = tcg_temp_new_i64();
1895 gen_load_fpr64(ctx, fp0, ft);
1896 tcg_gen_qemu_st64(fp0, t0, ctx->mem_idx);
1897 tcg_temp_free_i64(fp0);
1903 generate_exception(ctx, EXCP_RI);
1906 (void)opn; /* avoid a compiler warning */
1907 MIPS_DEBUG("%s %s, %d(%s)", opn, fregnames[ft], offset, regnames[base]);
1912 static void gen_cop1_ldst(CPUMIPSState *env, DisasContext *ctx,
1913 uint32_t op, int rt, int rs, int16_t imm)
1915 if (env->CP0_Config1 & (1 << CP0C1_FP)) {
1916 check_cp1_enabled(ctx);
1917 gen_flt_ldst(ctx, op, rt, rs, imm);
1919 generate_exception_err(ctx, EXCP_CpU, 1);
1923 /* Arithmetic with immediate operand */
1924 static void gen_arith_imm (CPUMIPSState *env, DisasContext *ctx, uint32_t opc,
1925 int rt, int rs, int16_t imm)
1927 target_ulong uimm = (target_long)imm; /* Sign extend to 32/64 bits */
1928 const char *opn = "imm arith";
1930 if (rt == 0 && opc != OPC_ADDI && opc != OPC_DADDI) {
1931 /* If no destination, treat it as a NOP.
1932 For addi, we must generate the overflow exception when needed. */
1939 TCGv t0 = tcg_temp_local_new();
1940 TCGv t1 = tcg_temp_new();
1941 TCGv t2 = tcg_temp_new();
1942 int l1 = gen_new_label();
1944 gen_load_gpr(t1, rs);
1945 tcg_gen_addi_tl(t0, t1, uimm);
1946 tcg_gen_ext32s_tl(t0, t0);
1948 tcg_gen_xori_tl(t1, t1, ~uimm);
1949 tcg_gen_xori_tl(t2, t0, uimm);
1950 tcg_gen_and_tl(t1, t1, t2);
1952 tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
1954 /* operands of same sign, result different sign */
1955 generate_exception(ctx, EXCP_OVERFLOW);
1957 tcg_gen_ext32s_tl(t0, t0);
1958 gen_store_gpr(t0, rt);
1965 tcg_gen_addi_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
1966 tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]);
1968 tcg_gen_movi_tl(cpu_gpr[rt], uimm);
1972 #if defined(TARGET_MIPS64)
1975 TCGv t0 = tcg_temp_local_new();
1976 TCGv t1 = tcg_temp_new();
1977 TCGv t2 = tcg_temp_new();
1978 int l1 = gen_new_label();
1980 gen_load_gpr(t1, rs);
1981 tcg_gen_addi_tl(t0, t1, uimm);
1983 tcg_gen_xori_tl(t1, t1, ~uimm);
1984 tcg_gen_xori_tl(t2, t0, uimm);
1985 tcg_gen_and_tl(t1, t1, t2);
1987 tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
1989 /* operands of same sign, result different sign */
1990 generate_exception(ctx, EXCP_OVERFLOW);
1992 gen_store_gpr(t0, rt);
1999 tcg_gen_addi_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
2001 tcg_gen_movi_tl(cpu_gpr[rt], uimm);
2007 (void)opn; /* avoid a compiler warning */
2008 MIPS_DEBUG("%s %s, %s, " TARGET_FMT_lx, opn, regnames[rt], regnames[rs], uimm);
2011 /* Logic with immediate operand */
2012 static void gen_logic_imm(CPUMIPSState *env, DisasContext *ctx, uint32_t opc,
2013 int rt, int rs, int16_t imm)
2018 /* If no destination, treat it as a NOP. */
2022 uimm = (uint16_t)imm;
2025 if (likely(rs != 0))
2026 tcg_gen_andi_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
2028 tcg_gen_movi_tl(cpu_gpr[rt], 0);
2029 MIPS_DEBUG("andi %s, %s, " TARGET_FMT_lx, regnames[rt],
2030 regnames[rs], uimm);
2034 tcg_gen_ori_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
2036 tcg_gen_movi_tl(cpu_gpr[rt], uimm);
2037 MIPS_DEBUG("ori %s, %s, " TARGET_FMT_lx, regnames[rt],
2038 regnames[rs], uimm);
2041 if (likely(rs != 0))
2042 tcg_gen_xori_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
2044 tcg_gen_movi_tl(cpu_gpr[rt], uimm);
2045 MIPS_DEBUG("xori %s, %s, " TARGET_FMT_lx, regnames[rt],
2046 regnames[rs], uimm);
2049 tcg_gen_movi_tl(cpu_gpr[rt], imm << 16);
2050 MIPS_DEBUG("lui %s, " TARGET_FMT_lx, regnames[rt], uimm);
2054 MIPS_DEBUG("Unknown logical immediate opcode %08x", opc);
2059 /* Set on less than with immediate operand */
2060 static void gen_slt_imm(CPUMIPSState *env, DisasContext *ctx, uint32_t opc,
2061 int rt, int rs, int16_t imm)
2063 target_ulong uimm = (target_long)imm; /* Sign extend to 32/64 bits */
2064 const char *opn = "imm arith";
2068 /* If no destination, treat it as a NOP. */
2072 t0 = tcg_temp_new();
2073 gen_load_gpr(t0, rs);
2076 tcg_gen_setcondi_tl(TCG_COND_LT, cpu_gpr[rt], t0, uimm);
2080 tcg_gen_setcondi_tl(TCG_COND_LTU, cpu_gpr[rt], t0, uimm);
2084 (void)opn; /* avoid a compiler warning */
2085 MIPS_DEBUG("%s %s, %s, " TARGET_FMT_lx, opn, regnames[rt], regnames[rs], uimm);
2089 /* Shifts with immediate operand */
2090 static void gen_shift_imm(CPUMIPSState *env, DisasContext *ctx, uint32_t opc,
2091 int rt, int rs, int16_t imm)
2093 target_ulong uimm = ((uint16_t)imm) & 0x1f;
2094 const char *opn = "imm shift";
2098 /* If no destination, treat it as a NOP. */
2103 t0 = tcg_temp_new();
2104 gen_load_gpr(t0, rs);
2107 tcg_gen_shli_tl(t0, t0, uimm);
2108 tcg_gen_ext32s_tl(cpu_gpr[rt], t0);
2112 tcg_gen_sari_tl(cpu_gpr[rt], t0, uimm);
2117 tcg_gen_ext32u_tl(t0, t0);
2118 tcg_gen_shri_tl(cpu_gpr[rt], t0, uimm);
2120 tcg_gen_ext32s_tl(cpu_gpr[rt], t0);
2126 TCGv_i32 t1 = tcg_temp_new_i32();
2128 tcg_gen_trunc_tl_i32(t1, t0);
2129 tcg_gen_rotri_i32(t1, t1, uimm);
2130 tcg_gen_ext_i32_tl(cpu_gpr[rt], t1);
2131 tcg_temp_free_i32(t1);
2133 tcg_gen_ext32s_tl(cpu_gpr[rt], t0);
2137 #if defined(TARGET_MIPS64)
2139 tcg_gen_shli_tl(cpu_gpr[rt], t0, uimm);
2143 tcg_gen_sari_tl(cpu_gpr[rt], t0, uimm);
2147 tcg_gen_shri_tl(cpu_gpr[rt], t0, uimm);
2152 tcg_gen_rotri_tl(cpu_gpr[rt], t0, uimm);
2154 tcg_gen_mov_tl(cpu_gpr[rt], t0);
2159 tcg_gen_shli_tl(cpu_gpr[rt], t0, uimm + 32);
2163 tcg_gen_sari_tl(cpu_gpr[rt], t0, uimm + 32);
2167 tcg_gen_shri_tl(cpu_gpr[rt], t0, uimm + 32);
2171 tcg_gen_rotri_tl(cpu_gpr[rt], t0, uimm + 32);
2176 (void)opn; /* avoid a compiler warning */
2177 MIPS_DEBUG("%s %s, %s, " TARGET_FMT_lx, opn, regnames[rt], regnames[rs], uimm);
2182 static void gen_arith (CPUMIPSState *env, DisasContext *ctx, uint32_t opc,
2183 int rd, int rs, int rt)
2185 const char *opn = "arith";
2187 if (rd == 0 && opc != OPC_ADD && opc != OPC_SUB
2188 && opc != OPC_DADD && opc != OPC_DSUB) {
2189 /* If no destination, treat it as a NOP.
2190 For add & sub, we must generate the overflow exception when needed. */
2198 TCGv t0 = tcg_temp_local_new();
2199 TCGv t1 = tcg_temp_new();
2200 TCGv t2 = tcg_temp_new();
2201 int l1 = gen_new_label();
2203 gen_load_gpr(t1, rs);
2204 gen_load_gpr(t2, rt);
2205 tcg_gen_add_tl(t0, t1, t2);
2206 tcg_gen_ext32s_tl(t0, t0);
2207 tcg_gen_xor_tl(t1, t1, t2);
2208 tcg_gen_xor_tl(t2, t0, t2);
2209 tcg_gen_andc_tl(t1, t2, t1);
2211 tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
2213 /* operands of same sign, result different sign */
2214 generate_exception(ctx, EXCP_OVERFLOW);
2216 gen_store_gpr(t0, rd);
2222 if (rs != 0 && rt != 0) {
2223 tcg_gen_add_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2224 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
2225 } else if (rs == 0 && rt != 0) {
2226 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rt]);
2227 } else if (rs != 0 && rt == 0) {
2228 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
2230 tcg_gen_movi_tl(cpu_gpr[rd], 0);
2236 TCGv t0 = tcg_temp_local_new();
2237 TCGv t1 = tcg_temp_new();
2238 TCGv t2 = tcg_temp_new();
2239 int l1 = gen_new_label();
2241 gen_load_gpr(t1, rs);
2242 gen_load_gpr(t2, rt);
2243 tcg_gen_sub_tl(t0, t1, t2);
2244 tcg_gen_ext32s_tl(t0, t0);
2245 tcg_gen_xor_tl(t2, t1, t2);
2246 tcg_gen_xor_tl(t1, t0, t1);
2247 tcg_gen_and_tl(t1, t1, t2);
2249 tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
2251 /* operands of different sign, first operand and result different sign */
2252 generate_exception(ctx, EXCP_OVERFLOW);
2254 gen_store_gpr(t0, rd);
2260 if (rs != 0 && rt != 0) {
2261 tcg_gen_sub_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2262 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
2263 } else if (rs == 0 && rt != 0) {
2264 tcg_gen_neg_tl(cpu_gpr[rd], cpu_gpr[rt]);
2265 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
2266 } else if (rs != 0 && rt == 0) {
2267 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
2269 tcg_gen_movi_tl(cpu_gpr[rd], 0);
2273 #if defined(TARGET_MIPS64)
2276 TCGv t0 = tcg_temp_local_new();
2277 TCGv t1 = tcg_temp_new();
2278 TCGv t2 = tcg_temp_new();
2279 int l1 = gen_new_label();
2281 gen_load_gpr(t1, rs);
2282 gen_load_gpr(t2, rt);
2283 tcg_gen_add_tl(t0, t1, t2);
2284 tcg_gen_xor_tl(t1, t1, t2);
2285 tcg_gen_xor_tl(t2, t0, t2);
2286 tcg_gen_andc_tl(t1, t2, t1);
2288 tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
2290 /* operands of same sign, result different sign */
2291 generate_exception(ctx, EXCP_OVERFLOW);
2293 gen_store_gpr(t0, rd);
2299 if (rs != 0 && rt != 0) {
2300 tcg_gen_add_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2301 } else if (rs == 0 && rt != 0) {
2302 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rt]);
2303 } else if (rs != 0 && rt == 0) {
2304 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
2306 tcg_gen_movi_tl(cpu_gpr[rd], 0);
2312 TCGv t0 = tcg_temp_local_new();
2313 TCGv t1 = tcg_temp_new();
2314 TCGv t2 = tcg_temp_new();
2315 int l1 = gen_new_label();
2317 gen_load_gpr(t1, rs);
2318 gen_load_gpr(t2, rt);
2319 tcg_gen_sub_tl(t0, t1, t2);
2320 tcg_gen_xor_tl(t2, t1, t2);
2321 tcg_gen_xor_tl(t1, t0, t1);
2322 tcg_gen_and_tl(t1, t1, t2);
2324 tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
2326 /* operands of different sign, first operand and result different sign */
2327 generate_exception(ctx, EXCP_OVERFLOW);
2329 gen_store_gpr(t0, rd);
2335 if (rs != 0 && rt != 0) {
2336 tcg_gen_sub_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2337 } else if (rs == 0 && rt != 0) {
2338 tcg_gen_neg_tl(cpu_gpr[rd], cpu_gpr[rt]);
2339 } else if (rs != 0 && rt == 0) {
2340 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
2342 tcg_gen_movi_tl(cpu_gpr[rd], 0);
2348 if (likely(rs != 0 && rt != 0)) {
2349 tcg_gen_mul_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2350 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
2352 tcg_gen_movi_tl(cpu_gpr[rd], 0);
2357 (void)opn; /* avoid a compiler warning */
2358 MIPS_DEBUG("%s %s, %s, %s", opn, regnames[rd], regnames[rs], regnames[rt]);
2361 /* Conditional move */
2362 static void gen_cond_move(CPUMIPSState *env, DisasContext *ctx, uint32_t opc,
2363 int rd, int rs, int rt)
2365 const char *opn = "cond move";
2369 /* If no destination, treat it as a NOP. */
2374 t0 = tcg_temp_new();
2375 gen_load_gpr(t0, rt);
2376 t1 = tcg_const_tl(0);
2377 t2 = tcg_temp_new();
2378 gen_load_gpr(t2, rs);
2381 tcg_gen_movcond_tl(TCG_COND_NE, cpu_gpr[rd], t0, t1, t2, cpu_gpr[rd]);
2385 tcg_gen_movcond_tl(TCG_COND_EQ, cpu_gpr[rd], t0, t1, t2, cpu_gpr[rd]);
2393 (void)opn; /* avoid a compiler warning */
2394 MIPS_DEBUG("%s %s, %s, %s", opn, regnames[rd], regnames[rs], regnames[rt]);
2398 static void gen_logic(CPUMIPSState *env, DisasContext *ctx, uint32_t opc,
2399 int rd, int rs, int rt)
2401 const char *opn = "logic";
2404 /* If no destination, treat it as a NOP. */
2411 if (likely(rs != 0 && rt != 0)) {
2412 tcg_gen_and_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2414 tcg_gen_movi_tl(cpu_gpr[rd], 0);
2419 if (rs != 0 && rt != 0) {
2420 tcg_gen_nor_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2421 } else if (rs == 0 && rt != 0) {
2422 tcg_gen_not_tl(cpu_gpr[rd], cpu_gpr[rt]);
2423 } else if (rs != 0 && rt == 0) {
2424 tcg_gen_not_tl(cpu_gpr[rd], cpu_gpr[rs]);
2426 tcg_gen_movi_tl(cpu_gpr[rd], ~((target_ulong)0));
2431 if (likely(rs != 0 && rt != 0)) {
2432 tcg_gen_or_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2433 } else if (rs == 0 && rt != 0) {
2434 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rt]);
2435 } else if (rs != 0 && rt == 0) {
2436 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
2438 tcg_gen_movi_tl(cpu_gpr[rd], 0);
2443 if (likely(rs != 0 && rt != 0)) {
2444 tcg_gen_xor_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2445 } else if (rs == 0 && rt != 0) {
2446 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rt]);
2447 } else if (rs != 0 && rt == 0) {
2448 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
2450 tcg_gen_movi_tl(cpu_gpr[rd], 0);
2455 (void)opn; /* avoid a compiler warning */
2456 MIPS_DEBUG("%s %s, %s, %s", opn, regnames[rd], regnames[rs], regnames[rt]);
2459 /* Set on lower than */
2460 static void gen_slt(CPUMIPSState *env, DisasContext *ctx, uint32_t opc,
2461 int rd, int rs, int rt)
2463 const char *opn = "slt";
2467 /* If no destination, treat it as a NOP. */
2472 t0 = tcg_temp_new();
2473 t1 = tcg_temp_new();
2474 gen_load_gpr(t0, rs);
2475 gen_load_gpr(t1, rt);
2478 tcg_gen_setcond_tl(TCG_COND_LT, cpu_gpr[rd], t0, t1);
2482 tcg_gen_setcond_tl(TCG_COND_LTU, cpu_gpr[rd], t0, t1);
2486 (void)opn; /* avoid a compiler warning */
2487 MIPS_DEBUG("%s %s, %s, %s", opn, regnames[rd], regnames[rs], regnames[rt]);
2493 static void gen_shift (CPUMIPSState *env, DisasContext *ctx, uint32_t opc,
2494 int rd, int rs, int rt)
2496 const char *opn = "shifts";
2500 /* If no destination, treat it as a NOP.
2501 For add & sub, we must generate the overflow exception when needed. */
2506 t0 = tcg_temp_new();
2507 t1 = tcg_temp_new();
2508 gen_load_gpr(t0, rs);
2509 gen_load_gpr(t1, rt);
2512 tcg_gen_andi_tl(t0, t0, 0x1f);
2513 tcg_gen_shl_tl(t0, t1, t0);
2514 tcg_gen_ext32s_tl(cpu_gpr[rd], t0);
2518 tcg_gen_andi_tl(t0, t0, 0x1f);
2519 tcg_gen_sar_tl(cpu_gpr[rd], t1, t0);
2523 tcg_gen_ext32u_tl(t1, t1);
2524 tcg_gen_andi_tl(t0, t0, 0x1f);
2525 tcg_gen_shr_tl(t0, t1, t0);
2526 tcg_gen_ext32s_tl(cpu_gpr[rd], t0);
2531 TCGv_i32 t2 = tcg_temp_new_i32();
2532 TCGv_i32 t3 = tcg_temp_new_i32();
2534 tcg_gen_trunc_tl_i32(t2, t0);
2535 tcg_gen_trunc_tl_i32(t3, t1);
2536 tcg_gen_andi_i32(t2, t2, 0x1f);
2537 tcg_gen_rotr_i32(t2, t3, t2);
2538 tcg_gen_ext_i32_tl(cpu_gpr[rd], t2);
2539 tcg_temp_free_i32(t2);
2540 tcg_temp_free_i32(t3);
2544 #if defined(TARGET_MIPS64)
2546 tcg_gen_andi_tl(t0, t0, 0x3f);
2547 tcg_gen_shl_tl(cpu_gpr[rd], t1, t0);
2551 tcg_gen_andi_tl(t0, t0, 0x3f);
2552 tcg_gen_sar_tl(cpu_gpr[rd], t1, t0);
2556 tcg_gen_andi_tl(t0, t0, 0x3f);
2557 tcg_gen_shr_tl(cpu_gpr[rd], t1, t0);
2561 tcg_gen_andi_tl(t0, t0, 0x3f);
2562 tcg_gen_rotr_tl(cpu_gpr[rd], t1, t0);
2567 (void)opn; /* avoid a compiler warning */
2568 MIPS_DEBUG("%s %s, %s, %s", opn, regnames[rd], regnames[rs], regnames[rt]);
2573 /* Arithmetic on HI/LO registers */
2574 static void gen_HILO (DisasContext *ctx, uint32_t opc, int reg)
2576 const char *opn = "hilo";
2579 if (reg == 0 && (opc == OPC_MFHI || opc == OPC_MFLO)) {
2585 if (opc == OPC_MFHI || opc == OPC_MFLO) {
2586 acc = ((ctx->opcode) >> 21) & 0x03;
2588 acc = ((ctx->opcode) >> 11) & 0x03;
2597 #if defined(TARGET_MIPS64)
2599 tcg_gen_ext32s_tl(cpu_gpr[reg], cpu_HI[acc]);
2603 tcg_gen_mov_tl(cpu_gpr[reg], cpu_HI[acc]);
2608 #if defined(TARGET_MIPS64)
2610 tcg_gen_ext32s_tl(cpu_gpr[reg], cpu_LO[acc]);
2614 tcg_gen_mov_tl(cpu_gpr[reg], cpu_LO[acc]);
2620 #if defined(TARGET_MIPS64)
2622 tcg_gen_ext32s_tl(cpu_HI[acc], cpu_gpr[reg]);
2626 tcg_gen_mov_tl(cpu_HI[acc], cpu_gpr[reg]);
2629 tcg_gen_movi_tl(cpu_HI[acc], 0);
2635 #if defined(TARGET_MIPS64)
2637 tcg_gen_ext32s_tl(cpu_LO[acc], cpu_gpr[reg]);
2641 tcg_gen_mov_tl(cpu_LO[acc], cpu_gpr[reg]);
2644 tcg_gen_movi_tl(cpu_LO[acc], 0);
2649 (void)opn; /* avoid a compiler warning */
2650 MIPS_DEBUG("%s %s", opn, regnames[reg]);
2653 static void gen_muldiv (DisasContext *ctx, uint32_t opc,
2656 const char *opn = "mul/div";
2660 t0 = tcg_temp_new();
2661 t1 = tcg_temp_new();
2663 gen_load_gpr(t0, rs);
2664 gen_load_gpr(t1, rt);
2669 TCGv t2 = tcg_temp_new();
2670 TCGv t3 = tcg_temp_new();
2671 tcg_gen_ext32s_tl(t0, t0);
2672 tcg_gen_ext32s_tl(t1, t1);
2673 tcg_gen_setcondi_tl(TCG_COND_EQ, t2, t0, INT_MIN);
2674 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, -1);
2675 tcg_gen_and_tl(t2, t2, t3);
2676 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, 0);
2677 tcg_gen_or_tl(t2, t2, t3);
2678 tcg_gen_movi_tl(t3, 0);
2679 tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, t3, t2, t1);
2680 tcg_gen_div_tl(cpu_LO[0], t0, t1);
2681 tcg_gen_rem_tl(cpu_HI[0], t0, t1);
2682 tcg_gen_ext32s_tl(cpu_LO[0], cpu_LO[0]);
2683 tcg_gen_ext32s_tl(cpu_HI[0], cpu_HI[0]);
2691 TCGv t2 = tcg_const_tl(0);
2692 TCGv t3 = tcg_const_tl(1);
2693 tcg_gen_ext32u_tl(t0, t0);
2694 tcg_gen_ext32u_tl(t1, t1);
2695 tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1, t2, t3, t1);
2696 tcg_gen_divu_tl(cpu_LO[0], t0, t1);
2697 tcg_gen_remu_tl(cpu_HI[0], t0, t1);
2698 tcg_gen_ext32s_tl(cpu_LO[0], cpu_LO[0]);
2699 tcg_gen_ext32s_tl(cpu_HI[0], cpu_HI[0]);
2707 TCGv_i64 t2 = tcg_temp_new_i64();
2708 TCGv_i64 t3 = tcg_temp_new_i64();
2709 acc = ((ctx->opcode) >> 11) & 0x03;
2714 tcg_gen_ext_tl_i64(t2, t0);
2715 tcg_gen_ext_tl_i64(t3, t1);
2716 tcg_gen_mul_i64(t2, t2, t3);
2717 tcg_temp_free_i64(t3);
2718 tcg_gen_trunc_i64_tl(t0, t2);
2719 tcg_gen_shri_i64(t2, t2, 32);
2720 tcg_gen_trunc_i64_tl(t1, t2);
2721 tcg_temp_free_i64(t2);
2722 tcg_gen_ext32s_tl(cpu_LO[acc], t0);
2723 tcg_gen_ext32s_tl(cpu_HI[acc], t1);
2729 TCGv_i64 t2 = tcg_temp_new_i64();
2730 TCGv_i64 t3 = tcg_temp_new_i64();
2731 acc = ((ctx->opcode) >> 11) & 0x03;
2736 tcg_gen_ext32u_tl(t0, t0);
2737 tcg_gen_ext32u_tl(t1, t1);
2738 tcg_gen_extu_tl_i64(t2, t0);
2739 tcg_gen_extu_tl_i64(t3, t1);
2740 tcg_gen_mul_i64(t2, t2, t3);
2741 tcg_temp_free_i64(t3);
2742 tcg_gen_trunc_i64_tl(t0, t2);
2743 tcg_gen_shri_i64(t2, t2, 32);
2744 tcg_gen_trunc_i64_tl(t1, t2);
2745 tcg_temp_free_i64(t2);
2746 tcg_gen_ext32s_tl(cpu_LO[acc], t0);
2747 tcg_gen_ext32s_tl(cpu_HI[acc], t1);
2751 #if defined(TARGET_MIPS64)
2754 TCGv t2 = tcg_temp_new();
2755 TCGv t3 = tcg_temp_new();
2756 tcg_gen_setcondi_tl(TCG_COND_EQ, t2, t0, -1LL << 63);
2757 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, -1LL);
2758 tcg_gen_and_tl(t2, t2, t3);
2759 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, 0);
2760 tcg_gen_or_tl(t2, t2, t3);
2761 tcg_gen_movi_tl(t3, 0);
2762 tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, t3, t2, t1);
2763 tcg_gen_div_tl(cpu_LO[0], t0, t1);
2764 tcg_gen_rem_tl(cpu_HI[0], t0, t1);
2772 TCGv t2 = tcg_const_tl(0);
2773 TCGv t3 = tcg_const_tl(1);
2774 tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1, t2, t3, t1);
2775 tcg_gen_divu_i64(cpu_LO[0], t0, t1);
2776 tcg_gen_remu_i64(cpu_HI[0], t0, t1);
2783 gen_helper_dmult(cpu_env, t0, t1);
2787 gen_helper_dmultu(cpu_env, t0, t1);
2793 TCGv_i64 t2 = tcg_temp_new_i64();
2794 TCGv_i64 t3 = tcg_temp_new_i64();
2795 acc = ((ctx->opcode) >> 11) & 0x03;
2800 tcg_gen_ext_tl_i64(t2, t0);
2801 tcg_gen_ext_tl_i64(t3, t1);
2802 tcg_gen_mul_i64(t2, t2, t3);
2803 tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]);
2804 tcg_gen_add_i64(t2, t2, t3);
2805 tcg_temp_free_i64(t3);
2806 tcg_gen_trunc_i64_tl(t0, t2);
2807 tcg_gen_shri_i64(t2, t2, 32);
2808 tcg_gen_trunc_i64_tl(t1, t2);
2809 tcg_temp_free_i64(t2);
2810 tcg_gen_ext32s_tl(cpu_LO[acc], t0);
2811 tcg_gen_ext32s_tl(cpu_HI[acc], t1);
2817 TCGv_i64 t2 = tcg_temp_new_i64();
2818 TCGv_i64 t3 = tcg_temp_new_i64();
2819 acc = ((ctx->opcode) >> 11) & 0x03;
2824 tcg_gen_ext32u_tl(t0, t0);
2825 tcg_gen_ext32u_tl(t1, t1);
2826 tcg_gen_extu_tl_i64(t2, t0);
2827 tcg_gen_extu_tl_i64(t3, t1);
2828 tcg_gen_mul_i64(t2, t2, t3);
2829 tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]);
2830 tcg_gen_add_i64(t2, t2, t3);
2831 tcg_temp_free_i64(t3);
2832 tcg_gen_trunc_i64_tl(t0, t2);
2833 tcg_gen_shri_i64(t2, t2, 32);
2834 tcg_gen_trunc_i64_tl(t1, t2);
2835 tcg_temp_free_i64(t2);
2836 tcg_gen_ext32s_tl(cpu_LO[acc], t0);
2837 tcg_gen_ext32s_tl(cpu_HI[acc], t1);
2843 TCGv_i64 t2 = tcg_temp_new_i64();
2844 TCGv_i64 t3 = tcg_temp_new_i64();
2845 acc = ((ctx->opcode) >> 11) & 0x03;
2850 tcg_gen_ext_tl_i64(t2, t0);
2851 tcg_gen_ext_tl_i64(t3, t1);
2852 tcg_gen_mul_i64(t2, t2, t3);
2853 tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]);
2854 tcg_gen_sub_i64(t2, t3, t2);
2855 tcg_temp_free_i64(t3);
2856 tcg_gen_trunc_i64_tl(t0, t2);
2857 tcg_gen_shri_i64(t2, t2, 32);
2858 tcg_gen_trunc_i64_tl(t1, t2);
2859 tcg_temp_free_i64(t2);
2860 tcg_gen_ext32s_tl(cpu_LO[acc], t0);
2861 tcg_gen_ext32s_tl(cpu_HI[acc], t1);
2867 TCGv_i64 t2 = tcg_temp_new_i64();
2868 TCGv_i64 t3 = tcg_temp_new_i64();
2869 acc = ((ctx->opcode) >> 11) & 0x03;
2874 tcg_gen_ext32u_tl(t0, t0);
2875 tcg_gen_ext32u_tl(t1, t1);
2876 tcg_gen_extu_tl_i64(t2, t0);
2877 tcg_gen_extu_tl_i64(t3, t1);
2878 tcg_gen_mul_i64(t2, t2, t3);
2879 tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]);
2880 tcg_gen_sub_i64(t2, t3, t2);
2881 tcg_temp_free_i64(t3);
2882 tcg_gen_trunc_i64_tl(t0, t2);
2883 tcg_gen_shri_i64(t2, t2, 32);
2884 tcg_gen_trunc_i64_tl(t1, t2);
2885 tcg_temp_free_i64(t2);
2886 tcg_gen_ext32s_tl(cpu_LO[acc], t0);
2887 tcg_gen_ext32s_tl(cpu_HI[acc], t1);
2893 generate_exception(ctx, EXCP_RI);
2896 (void)opn; /* avoid a compiler warning */
2897 MIPS_DEBUG("%s %s %s", opn, regnames[rs], regnames[rt]);
2903 static void gen_mul_vr54xx (DisasContext *ctx, uint32_t opc,
2904 int rd, int rs, int rt)
2906 const char *opn = "mul vr54xx";
2907 TCGv t0 = tcg_temp_new();
2908 TCGv t1 = tcg_temp_new();
2910 gen_load_gpr(t0, rs);
2911 gen_load_gpr(t1, rt);
2914 case OPC_VR54XX_MULS:
2915 gen_helper_muls(t0, cpu_env, t0, t1);
2918 case OPC_VR54XX_MULSU:
2919 gen_helper_mulsu(t0, cpu_env, t0, t1);
2922 case OPC_VR54XX_MACC:
2923 gen_helper_macc(t0, cpu_env, t0, t1);
2926 case OPC_VR54XX_MACCU:
2927 gen_helper_maccu(t0, cpu_env, t0, t1);
2930 case OPC_VR54XX_MSAC:
2931 gen_helper_msac(t0, cpu_env, t0, t1);
2934 case OPC_VR54XX_MSACU:
2935 gen_helper_msacu(t0, cpu_env, t0, t1);
2938 case OPC_VR54XX_MULHI:
2939 gen_helper_mulhi(t0, cpu_env, t0, t1);
2942 case OPC_VR54XX_MULHIU:
2943 gen_helper_mulhiu(t0, cpu_env, t0, t1);
2946 case OPC_VR54XX_MULSHI:
2947 gen_helper_mulshi(t0, cpu_env, t0, t1);
2950 case OPC_VR54XX_MULSHIU:
2951 gen_helper_mulshiu(t0, cpu_env, t0, t1);
2954 case OPC_VR54XX_MACCHI:
2955 gen_helper_macchi(t0, cpu_env, t0, t1);
2958 case OPC_VR54XX_MACCHIU:
2959 gen_helper_macchiu(t0, cpu_env, t0, t1);
2962 case OPC_VR54XX_MSACHI:
2963 gen_helper_msachi(t0, cpu_env, t0, t1);
2966 case OPC_VR54XX_MSACHIU:
2967 gen_helper_msachiu(t0, cpu_env, t0, t1);
2971 MIPS_INVAL("mul vr54xx");
2972 generate_exception(ctx, EXCP_RI);
2975 gen_store_gpr(t0, rd);
2976 (void)opn; /* avoid a compiler warning */
2977 MIPS_DEBUG("%s %s, %s, %s", opn, regnames[rd], regnames[rs], regnames[rt]);
2984 static void gen_cl (DisasContext *ctx, uint32_t opc,
2987 const char *opn = "CLx";
2995 t0 = tcg_temp_new();
2996 gen_load_gpr(t0, rs);
2999 gen_helper_clo(cpu_gpr[rd], t0);
3003 gen_helper_clz(cpu_gpr[rd], t0);
3006 #if defined(TARGET_MIPS64)
3008 gen_helper_dclo(cpu_gpr[rd], t0);
3012 gen_helper_dclz(cpu_gpr[rd], t0);
3017 (void)opn; /* avoid a compiler warning */
3018 MIPS_DEBUG("%s %s, %s", opn, regnames[rd], regnames[rs]);
3022 /* Godson integer instructions */
3023 static void gen_loongson_integer(DisasContext *ctx, uint32_t opc,
3024 int rd, int rs, int rt)
3026 const char *opn = "loongson";
3038 case OPC_MULTU_G_2E:
3039 case OPC_MULTU_G_2F:
3040 #if defined(TARGET_MIPS64)
3041 case OPC_DMULT_G_2E:
3042 case OPC_DMULT_G_2F:
3043 case OPC_DMULTU_G_2E:
3044 case OPC_DMULTU_G_2F:
3046 t0 = tcg_temp_new();
3047 t1 = tcg_temp_new();
3050 t0 = tcg_temp_local_new();
3051 t1 = tcg_temp_local_new();
3055 gen_load_gpr(t0, rs);
3056 gen_load_gpr(t1, rt);
3061 tcg_gen_mul_tl(cpu_gpr[rd], t0, t1);
3062 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3065 case OPC_MULTU_G_2E:
3066 case OPC_MULTU_G_2F:
3067 tcg_gen_ext32u_tl(t0, t0);
3068 tcg_gen_ext32u_tl(t1, t1);
3069 tcg_gen_mul_tl(cpu_gpr[rd], t0, t1);
3070 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3076 int l1 = gen_new_label();
3077 int l2 = gen_new_label();
3078 int l3 = gen_new_label();
3079 tcg_gen_ext32s_tl(t0, t0);
3080 tcg_gen_ext32s_tl(t1, t1);
3081 tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
3082 tcg_gen_movi_tl(cpu_gpr[rd], 0);
3085 tcg_gen_brcondi_tl(TCG_COND_NE, t0, INT_MIN, l2);
3086 tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1, l2);
3087 tcg_gen_mov_tl(cpu_gpr[rd], t0);
3090 tcg_gen_div_tl(cpu_gpr[rd], t0, t1);
3091 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3099 int l1 = gen_new_label();
3100 int l2 = gen_new_label();
3101 tcg_gen_ext32u_tl(t0, t0);
3102 tcg_gen_ext32u_tl(t1, t1);
3103 tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
3104 tcg_gen_movi_tl(cpu_gpr[rd], 0);
3107 tcg_gen_divu_tl(cpu_gpr[rd], t0, t1);
3108 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3116 int l1 = gen_new_label();
3117 int l2 = gen_new_label();
3118 int l3 = gen_new_label();
3119 tcg_gen_ext32u_tl(t0, t0);
3120 tcg_gen_ext32u_tl(t1, t1);
3121 tcg_gen_brcondi_tl(TCG_COND_EQ, t1, 0, l1);
3122 tcg_gen_brcondi_tl(TCG_COND_NE, t0, INT_MIN, l2);
3123 tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1, l2);
3125 tcg_gen_movi_tl(cpu_gpr[rd], 0);
3128 tcg_gen_rem_tl(cpu_gpr[rd], t0, t1);
3129 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3137 int l1 = gen_new_label();
3138 int l2 = gen_new_label();
3139 tcg_gen_ext32u_tl(t0, t0);
3140 tcg_gen_ext32u_tl(t1, t1);
3141 tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
3142 tcg_gen_movi_tl(cpu_gpr[rd], 0);
3145 tcg_gen_remu_tl(cpu_gpr[rd], t0, t1);
3146 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3151 #if defined(TARGET_MIPS64)
3152 case OPC_DMULT_G_2E:
3153 case OPC_DMULT_G_2F:
3154 tcg_gen_mul_tl(cpu_gpr[rd], t0, t1);
3157 case OPC_DMULTU_G_2E:
3158 case OPC_DMULTU_G_2F:
3159 tcg_gen_mul_tl(cpu_gpr[rd], t0, t1);
3165 int l1 = gen_new_label();
3166 int l2 = gen_new_label();
3167 int l3 = 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_brcondi_tl(TCG_COND_NE, t0, -1LL << 63, l2);
3173 tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1LL, l2);
3174 tcg_gen_mov_tl(cpu_gpr[rd], t0);
3177 tcg_gen_div_tl(cpu_gpr[rd], t0, t1);
3182 case OPC_DDIVU_G_2E:
3183 case OPC_DDIVU_G_2F:
3185 int l1 = gen_new_label();
3186 int l2 = gen_new_label();
3187 tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
3188 tcg_gen_movi_tl(cpu_gpr[rd], 0);
3191 tcg_gen_divu_tl(cpu_gpr[rd], t0, t1);
3199 int l1 = gen_new_label();
3200 int l2 = gen_new_label();
3201 int l3 = gen_new_label();
3202 tcg_gen_brcondi_tl(TCG_COND_EQ, t1, 0, l1);
3203 tcg_gen_brcondi_tl(TCG_COND_NE, t0, -1LL << 63, l2);
3204 tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1LL, l2);
3206 tcg_gen_movi_tl(cpu_gpr[rd], 0);
3209 tcg_gen_rem_tl(cpu_gpr[rd], t0, t1);
3214 case OPC_DMODU_G_2E:
3215 case OPC_DMODU_G_2F:
3217 int l1 = gen_new_label();
3218 int l2 = gen_new_label();
3219 tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
3220 tcg_gen_movi_tl(cpu_gpr[rd], 0);
3223 tcg_gen_remu_tl(cpu_gpr[rd], t0, t1);
3231 (void)opn; /* avoid a compiler warning */
3232 MIPS_DEBUG("%s %s, %s", opn, regnames[rd], regnames[rs]);
3237 /* Loongson multimedia instructions */
3238 static void gen_loongson_multimedia(DisasContext *ctx, int rd, int rs, int rt)
3240 const char *opn = "loongson_cp2";
3241 uint32_t opc, shift_max;
3244 opc = MASK_LMI(ctx->opcode);
3250 t0 = tcg_temp_local_new_i64();
3251 t1 = tcg_temp_local_new_i64();
3254 t0 = tcg_temp_new_i64();
3255 t1 = tcg_temp_new_i64();
3259 gen_load_fpr64(ctx, t0, rs);
3260 gen_load_fpr64(ctx, t1, rt);
3262 #define LMI_HELPER(UP, LO) \
3263 case OPC_##UP: gen_helper_##LO(t0, t0, t1); opn = #LO; break
3264 #define LMI_HELPER_1(UP, LO) \
3265 case OPC_##UP: gen_helper_##LO(t0, t0); opn = #LO; break
3266 #define LMI_DIRECT(UP, LO, OP) \
3267 case OPC_##UP: tcg_gen_##OP##_i64(t0, t0, t1); opn = #LO; break
3270 LMI_HELPER(PADDSH, paddsh);
3271 LMI_HELPER(PADDUSH, paddush);
3272 LMI_HELPER(PADDH, paddh);
3273 LMI_HELPER(PADDW, paddw);
3274 LMI_HELPER(PADDSB, paddsb);
3275 LMI_HELPER(PADDUSB, paddusb);
3276 LMI_HELPER(PADDB, paddb);
3278 LMI_HELPER(PSUBSH, psubsh);
3279 LMI_HELPER(PSUBUSH, psubush);
3280 LMI_HELPER(PSUBH, psubh);
3281 LMI_HELPER(PSUBW, psubw);
3282 LMI_HELPER(PSUBSB, psubsb);
3283 LMI_HELPER(PSUBUSB, psubusb);
3284 LMI_HELPER(PSUBB, psubb);
3286 LMI_HELPER(PSHUFH, pshufh);
3287 LMI_HELPER(PACKSSWH, packsswh);
3288 LMI_HELPER(PACKSSHB, packsshb);
3289 LMI_HELPER(PACKUSHB, packushb);
3291 LMI_HELPER(PUNPCKLHW, punpcklhw);
3292 LMI_HELPER(PUNPCKHHW, punpckhhw);
3293 LMI_HELPER(PUNPCKLBH, punpcklbh);
3294 LMI_HELPER(PUNPCKHBH, punpckhbh);
3295 LMI_HELPER(PUNPCKLWD, punpcklwd);
3296 LMI_HELPER(PUNPCKHWD, punpckhwd);
3298 LMI_HELPER(PAVGH, pavgh);
3299 LMI_HELPER(PAVGB, pavgb);
3300 LMI_HELPER(PMAXSH, pmaxsh);
3301 LMI_HELPER(PMINSH, pminsh);
3302 LMI_HELPER(PMAXUB, pmaxub);
3303 LMI_HELPER(PMINUB, pminub);
3305 LMI_HELPER(PCMPEQW, pcmpeqw);
3306 LMI_HELPER(PCMPGTW, pcmpgtw);
3307 LMI_HELPER(PCMPEQH, pcmpeqh);
3308 LMI_HELPER(PCMPGTH, pcmpgth);
3309 LMI_HELPER(PCMPEQB, pcmpeqb);
3310 LMI_HELPER(PCMPGTB, pcmpgtb);
3312 LMI_HELPER(PSLLW, psllw);
3313 LMI_HELPER(PSLLH, psllh);
3314 LMI_HELPER(PSRLW, psrlw);
3315 LMI_HELPER(PSRLH, psrlh);
3316 LMI_HELPER(PSRAW, psraw);
3317 LMI_HELPER(PSRAH, psrah);
3319 LMI_HELPER(PMULLH, pmullh);
3320 LMI_HELPER(PMULHH, pmulhh);
3321 LMI_HELPER(PMULHUH, pmulhuh);
3322 LMI_HELPER(PMADDHW, pmaddhw);
3324 LMI_HELPER(PASUBUB, pasubub);
3325 LMI_HELPER_1(BIADD, biadd);
3326 LMI_HELPER_1(PMOVMSKB, pmovmskb);
3328 LMI_DIRECT(PADDD, paddd, add);
3329 LMI_DIRECT(PSUBD, psubd, sub);
3330 LMI_DIRECT(XOR_CP2, xor, xor);
3331 LMI_DIRECT(NOR_CP2, nor, nor);
3332 LMI_DIRECT(AND_CP2, and, and);
3333 LMI_DIRECT(PANDN, pandn, andc);
3334 LMI_DIRECT(OR, or, or);
3337 tcg_gen_deposit_i64(t0, t0, t1, 0, 16);
3341 tcg_gen_deposit_i64(t0, t0, t1, 16, 16);
3345 tcg_gen_deposit_i64(t0, t0, t1, 32, 16);
3349 tcg_gen_deposit_i64(t0, t0, t1, 48, 16);
3354 tcg_gen_andi_i64(t1, t1, 3);
3355 tcg_gen_shli_i64(t1, t1, 4);
3356 tcg_gen_shr_i64(t0, t0, t1);
3357 tcg_gen_ext16u_i64(t0, t0);
3362 tcg_gen_add_i64(t0, t0, t1);
3363 tcg_gen_ext32s_i64(t0, t0);
3367 tcg_gen_sub_i64(t0, t0, t1);
3368 tcg_gen_ext32s_i64(t0, t0);
3397 /* Make sure shift count isn't TCG undefined behaviour. */
3398 tcg_gen_andi_i64(t1, t1, shift_max - 1);
3403 tcg_gen_shl_i64(t0, t0, t1);
3407 /* Since SRA is UndefinedResult without sign-extended inputs,
3408 we can treat SRA and DSRA the same. */
3409 tcg_gen_sar_i64(t0, t0, t1);
3412 /* We want to shift in zeros for SRL; zero-extend first. */
3413 tcg_gen_ext32u_i64(t0, t0);
3416 tcg_gen_shr_i64(t0, t0, t1);
3420 if (shift_max == 32) {
3421 tcg_gen_ext32s_i64(t0, t0);
3424 /* Shifts larger than MAX produce zero. */
3425 tcg_gen_setcondi_i64(TCG_COND_LTU, t1, t1, shift_max);
3426 tcg_gen_neg_i64(t1, t1);
3427 tcg_gen_and_i64(t0, t0, t1);
3433 TCGv_i64 t2 = tcg_temp_new_i64();
3434 int lab = gen_new_label();
3436 tcg_gen_mov_i64(t2, t0);
3437 tcg_gen_add_i64(t0, t1, t2);
3438 if (opc == OPC_ADD_CP2) {
3439 tcg_gen_ext32s_i64(t0, t0);
3441 tcg_gen_xor_i64(t1, t1, t2);
3442 tcg_gen_xor_i64(t2, t2, t0);
3443 tcg_gen_andc_i64(t1, t2, t1);
3444 tcg_temp_free_i64(t2);
3445 tcg_gen_brcondi_i64(TCG_COND_GE, t1, 0, lab);
3446 generate_exception(ctx, EXCP_OVERFLOW);
3449 opn = (opc == OPC_ADD_CP2 ? "add" : "dadd");
3456 TCGv_i64 t2 = tcg_temp_new_i64();
3457 int lab = gen_new_label();
3459 tcg_gen_mov_i64(t2, t0);
3460 tcg_gen_sub_i64(t0, t1, t2);
3461 if (opc == OPC_SUB_CP2) {
3462 tcg_gen_ext32s_i64(t0, t0);
3464 tcg_gen_xor_i64(t1, t1, t2);
3465 tcg_gen_xor_i64(t2, t2, t0);
3466 tcg_gen_and_i64(t1, t1, t2);
3467 tcg_temp_free_i64(t2);
3468 tcg_gen_brcondi_i64(TCG_COND_GE, t1, 0, lab);
3469 generate_exception(ctx, EXCP_OVERFLOW);
3472 opn = (opc == OPC_SUB_CP2 ? "sub" : "dsub");
3477 tcg_gen_ext32u_i64(t0, t0);
3478 tcg_gen_ext32u_i64(t1, t1);
3479 tcg_gen_mul_i64(t0, t0, t1);
3489 /* ??? Document is unclear: Set FCC[CC]. Does that mean the
3490 FD field is the CC field? */
3493 generate_exception(ctx, EXCP_RI);
3500 gen_store_fpr64(ctx, t0, rd);
3502 (void)opn; /* avoid a compiler warning */
3503 MIPS_DEBUG("%s %s, %s, %s", opn,
3504 fregnames[rd], fregnames[rs], fregnames[rt]);
3505 tcg_temp_free_i64(t0);
3506 tcg_temp_free_i64(t1);
3510 static void gen_trap (DisasContext *ctx, uint32_t opc,
3511 int rs, int rt, int16_t imm)
3514 TCGv t0 = tcg_temp_new();
3515 TCGv t1 = tcg_temp_new();
3518 /* Load needed operands */
3526 /* Compare two registers */
3528 gen_load_gpr(t0, rs);
3529 gen_load_gpr(t1, rt);
3539 /* Compare register to immediate */
3540 if (rs != 0 || imm != 0) {
3541 gen_load_gpr(t0, rs);
3542 tcg_gen_movi_tl(t1, (int32_t)imm);
3549 case OPC_TEQ: /* rs == rs */
3550 case OPC_TEQI: /* r0 == 0 */
3551 case OPC_TGE: /* rs >= rs */
3552 case OPC_TGEI: /* r0 >= 0 */
3553 case OPC_TGEU: /* rs >= rs unsigned */
3554 case OPC_TGEIU: /* r0 >= 0 unsigned */
3556 generate_exception(ctx, EXCP_TRAP);
3558 case OPC_TLT: /* rs < rs */
3559 case OPC_TLTI: /* r0 < 0 */
3560 case OPC_TLTU: /* rs < rs unsigned */
3561 case OPC_TLTIU: /* r0 < 0 unsigned */
3562 case OPC_TNE: /* rs != rs */
3563 case OPC_TNEI: /* r0 != 0 */
3564 /* Never trap: treat as NOP. */
3568 int l1 = gen_new_label();
3573 tcg_gen_brcond_tl(TCG_COND_NE, t0, t1, l1);
3577 tcg_gen_brcond_tl(TCG_COND_LT, t0, t1, l1);
3581 tcg_gen_brcond_tl(TCG_COND_LTU, t0, t1, l1);
3585 tcg_gen_brcond_tl(TCG_COND_GE, t0, t1, l1);
3589 tcg_gen_brcond_tl(TCG_COND_GEU, t0, t1, l1);
3593 tcg_gen_brcond_tl(TCG_COND_EQ, t0, t1, l1);
3596 generate_exception(ctx, EXCP_TRAP);
3603 static inline void gen_goto_tb(DisasContext *ctx, int n, target_ulong dest)
3605 TranslationBlock *tb;
3607 if ((tb->pc & TARGET_PAGE_MASK) == (dest & TARGET_PAGE_MASK) &&
3608 likely(!ctx->singlestep_enabled)) {
3611 tcg_gen_exit_tb((tcg_target_long)tb + n);
3614 if (ctx->singlestep_enabled) {
3615 save_cpu_state(ctx, 0);
3616 gen_helper_0e0i(raise_exception, EXCP_DEBUG);
3622 /* Branches (before delay slot) */
3623 static void gen_compute_branch (DisasContext *ctx, uint32_t opc,
3625 int rs, int rt, int32_t offset)
3627 target_ulong btgt = -1;
3629 int bcond_compute = 0;
3630 TCGv t0 = tcg_temp_new();
3631 TCGv t1 = tcg_temp_new();
3633 if (ctx->hflags & MIPS_HFLAG_BMASK) {
3634 #ifdef MIPS_DEBUG_DISAS
3635 LOG_DISAS("Branch in delay slot at PC 0x" TARGET_FMT_lx "\n", ctx->pc);
3637 generate_exception(ctx, EXCP_RI);
3641 /* Load needed operands */
3647 /* Compare two registers */
3649 gen_load_gpr(t0, rs);
3650 gen_load_gpr(t1, rt);
3653 btgt = ctx->pc + insn_bytes + offset;
3669 /* Compare to zero */
3671 gen_load_gpr(t0, rs);
3674 btgt = ctx->pc + insn_bytes + offset;
3677 #if defined(TARGET_MIPS64)
3679 tcg_gen_andi_tl(t0, cpu_dspctrl, 0x7F);
3681 tcg_gen_andi_tl(t0, cpu_dspctrl, 0x3F);
3684 btgt = ctx->pc + insn_bytes + offset;
3691 /* Jump to immediate */
3692 btgt = ((ctx->pc + insn_bytes) & (int32_t)0xF0000000) | (uint32_t)offset;
3698 /* Jump to register */
3699 if (offset != 0 && offset != 16) {
3700 /* Hint = 0 is JR/JALR, hint 16 is JR.HB/JALR.HB, the
3701 others are reserved. */
3702 MIPS_INVAL("jump hint");
3703 generate_exception(ctx, EXCP_RI);
3706 gen_load_gpr(btarget, rs);
3709 MIPS_INVAL("branch/jump");
3710 generate_exception(ctx, EXCP_RI);
3713 if (bcond_compute == 0) {
3714 /* No condition to be computed */
3716 case OPC_BEQ: /* rx == rx */
3717 case OPC_BEQL: /* rx == rx likely */
3718 case OPC_BGEZ: /* 0 >= 0 */
3719 case OPC_BGEZL: /* 0 >= 0 likely */
3720 case OPC_BLEZ: /* 0 <= 0 */
3721 case OPC_BLEZL: /* 0 <= 0 likely */
3723 ctx->hflags |= MIPS_HFLAG_B;
3724 MIPS_DEBUG("balways");
3727 case OPC_BGEZAL: /* 0 >= 0 */
3728 case OPC_BGEZALL: /* 0 >= 0 likely */
3729 ctx->hflags |= (opc == OPC_BGEZALS
3731 : MIPS_HFLAG_BDS32);
3732 /* Always take and link */
3734 ctx->hflags |= MIPS_HFLAG_B;
3735 MIPS_DEBUG("balways and link");
3737 case OPC_BNE: /* rx != rx */
3738 case OPC_BGTZ: /* 0 > 0 */
3739 case OPC_BLTZ: /* 0 < 0 */
3741 MIPS_DEBUG("bnever (NOP)");
3744 case OPC_BLTZAL: /* 0 < 0 */
3745 ctx->hflags |= (opc == OPC_BLTZALS
3747 : MIPS_HFLAG_BDS32);
3748 /* Handle as an unconditional branch to get correct delay
3751 btgt = ctx->pc + (opc == OPC_BLTZALS ? 6 : 8);
3752 ctx->hflags |= MIPS_HFLAG_B;
3753 MIPS_DEBUG("bnever and link");
3755 case OPC_BLTZALL: /* 0 < 0 likely */
3756 tcg_gen_movi_tl(cpu_gpr[31], ctx->pc + 8);
3757 /* Skip the instruction in the delay slot */
3758 MIPS_DEBUG("bnever, link and skip");
3761 case OPC_BNEL: /* rx != rx likely */
3762 case OPC_BGTZL: /* 0 > 0 likely */
3763 case OPC_BLTZL: /* 0 < 0 likely */
3764 /* Skip the instruction in the delay slot */
3765 MIPS_DEBUG("bnever and skip");
3769 ctx->hflags |= MIPS_HFLAG_B;
3770 MIPS_DEBUG("j " TARGET_FMT_lx, btgt);
3774 ctx->hflags |= MIPS_HFLAG_BX;
3779 ctx->hflags |= MIPS_HFLAG_B;
3780 ctx->hflags |= ((opc == OPC_JALS || opc == OPC_JALXS)
3782 : MIPS_HFLAG_BDS32);
3783 MIPS_DEBUG("jal " TARGET_FMT_lx, btgt);
3786 ctx->hflags |= MIPS_HFLAG_BR;
3787 if (insn_bytes == 4)
3788 ctx->hflags |= MIPS_HFLAG_BDS32;
3789 MIPS_DEBUG("jr %s", regnames[rs]);
3795 ctx->hflags |= MIPS_HFLAG_BR;
3796 ctx->hflags |= (opc == OPC_JALRS
3798 : MIPS_HFLAG_BDS32);
3799 MIPS_DEBUG("jalr %s, %s", regnames[rt], regnames[rs]);
3802 MIPS_INVAL("branch/jump");
3803 generate_exception(ctx, EXCP_RI);
3809 tcg_gen_setcond_tl(TCG_COND_EQ, bcond, t0, t1);
3810 MIPS_DEBUG("beq %s, %s, " TARGET_FMT_lx,
3811 regnames[rs], regnames[rt], btgt);
3814 tcg_gen_setcond_tl(TCG_COND_EQ, bcond, t0, t1);
3815 MIPS_DEBUG("beql %s, %s, " TARGET_FMT_lx,
3816 regnames[rs], regnames[rt], btgt);
3819 tcg_gen_setcond_tl(TCG_COND_NE, bcond, t0, t1);
3820 MIPS_DEBUG("bne %s, %s, " TARGET_FMT_lx,
3821 regnames[rs], regnames[rt], btgt);
3824 tcg_gen_setcond_tl(TCG_COND_NE, bcond, t0, t1);
3825 MIPS_DEBUG("bnel %s, %s, " TARGET_FMT_lx,
3826 regnames[rs], regnames[rt], btgt);
3829 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 0);
3830 MIPS_DEBUG("bgez %s, " TARGET_FMT_lx, regnames[rs], btgt);
3833 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 0);
3834 MIPS_DEBUG("bgezl %s, " TARGET_FMT_lx, regnames[rs], btgt);
3838 ctx->hflags |= (opc == OPC_BGEZALS
3840 : MIPS_HFLAG_BDS32);
3841 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 0);
3842 MIPS_DEBUG("bgezal %s, " TARGET_FMT_lx, regnames[rs], btgt);
3846 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 0);
3848 MIPS_DEBUG("bgezall %s, " TARGET_FMT_lx, regnames[rs], btgt);
3851 tcg_gen_setcondi_tl(TCG_COND_GT, bcond, t0, 0);
3852 MIPS_DEBUG("bgtz %s, " TARGET_FMT_lx, regnames[rs], btgt);
3855 tcg_gen_setcondi_tl(TCG_COND_GT, bcond, t0, 0);
3856 MIPS_DEBUG("bgtzl %s, " TARGET_FMT_lx, regnames[rs], btgt);
3859 tcg_gen_setcondi_tl(TCG_COND_LE, bcond, t0, 0);
3860 MIPS_DEBUG("blez %s, " TARGET_FMT_lx, regnames[rs], btgt);
3863 tcg_gen_setcondi_tl(TCG_COND_LE, bcond, t0, 0);
3864 MIPS_DEBUG("blezl %s, " TARGET_FMT_lx, regnames[rs], btgt);
3867 tcg_gen_setcondi_tl(TCG_COND_LT, bcond, t0, 0);
3868 MIPS_DEBUG("bltz %s, " TARGET_FMT_lx, regnames[rs], btgt);
3871 tcg_gen_setcondi_tl(TCG_COND_LT, bcond, t0, 0);
3872 MIPS_DEBUG("bltzl %s, " TARGET_FMT_lx, regnames[rs], btgt);
3875 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 32);
3876 MIPS_DEBUG("bposge32 " TARGET_FMT_lx, btgt);
3878 #if defined(TARGET_MIPS64)
3880 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 64);
3881 MIPS_DEBUG("bposge64 " TARGET_FMT_lx, btgt);
3886 ctx->hflags |= (opc == OPC_BLTZALS
3888 : MIPS_HFLAG_BDS32);
3889 tcg_gen_setcondi_tl(TCG_COND_LT, bcond, t0, 0);
3891 MIPS_DEBUG("bltzal %s, " TARGET_FMT_lx, regnames[rs], btgt);
3893 ctx->hflags |= MIPS_HFLAG_BC;
3896 tcg_gen_setcondi_tl(TCG_COND_LT, bcond, t0, 0);
3898 MIPS_DEBUG("bltzall %s, " TARGET_FMT_lx, regnames[rs], btgt);
3900 ctx->hflags |= MIPS_HFLAG_BL;
3903 MIPS_INVAL("conditional branch/jump");
3904 generate_exception(ctx, EXCP_RI);
3908 MIPS_DEBUG("enter ds: link %d cond %02x target " TARGET_FMT_lx,
3909 blink, ctx->hflags, btgt);
3911 ctx->btarget = btgt;
3913 int post_delay = insn_bytes;
3914 int lowbit = !!(ctx->hflags & MIPS_HFLAG_M16);
3916 if (opc != OPC_JALRC)
3917 post_delay += ((ctx->hflags & MIPS_HFLAG_BDS16) ? 2 : 4);
3919 tcg_gen_movi_tl(cpu_gpr[blink], ctx->pc + post_delay + lowbit);
3923 if (insn_bytes == 2)
3924 ctx->hflags |= MIPS_HFLAG_B16;
3929 /* special3 bitfield operations */
3930 static void gen_bitops (DisasContext *ctx, uint32_t opc, int rt,
3931 int rs, int lsb, int msb)
3933 TCGv t0 = tcg_temp_new();
3934 TCGv t1 = tcg_temp_new();
3936 gen_load_gpr(t1, rs);
3941 tcg_gen_shri_tl(t0, t1, lsb);
3943 tcg_gen_andi_tl(t0, t0, (1 << (msb + 1)) - 1);
3945 tcg_gen_ext32s_tl(t0, t0);
3948 #if defined(TARGET_MIPS64)
3950 tcg_gen_shri_tl(t0, t1, lsb);
3952 tcg_gen_andi_tl(t0, t0, (1ULL << (msb + 1 + 32)) - 1);
3956 tcg_gen_shri_tl(t0, t1, lsb + 32);
3957 tcg_gen_andi_tl(t0, t0, (1ULL << (msb + 1)) - 1);
3960 tcg_gen_shri_tl(t0, t1, lsb);
3961 tcg_gen_andi_tl(t0, t0, (1ULL << (msb + 1)) - 1);
3967 gen_load_gpr(t0, rt);
3968 tcg_gen_deposit_tl(t0, t0, t1, lsb, msb - lsb + 1);
3969 tcg_gen_ext32s_tl(t0, t0);
3971 #if defined(TARGET_MIPS64)
3973 gen_load_gpr(t0, rt);
3974 tcg_gen_deposit_tl(t0, t0, t1, lsb, msb + 32 - lsb + 1);
3977 gen_load_gpr(t0, rt);
3978 tcg_gen_deposit_tl(t0, t0, t1, lsb + 32, msb - lsb + 1);
3981 gen_load_gpr(t0, rt);
3982 tcg_gen_deposit_tl(t0, t0, t1, lsb, msb - lsb + 1);
3987 MIPS_INVAL("bitops");
3988 generate_exception(ctx, EXCP_RI);
3993 gen_store_gpr(t0, rt);
3998 static void gen_bshfl (DisasContext *ctx, uint32_t op2, int rt, int rd)
4003 /* If no destination, treat it as a NOP. */
4008 t0 = tcg_temp_new();
4009 gen_load_gpr(t0, rt);
4013 TCGv t1 = tcg_temp_new();
4015 tcg_gen_shri_tl(t1, t0, 8);
4016 tcg_gen_andi_tl(t1, t1, 0x00FF00FF);
4017 tcg_gen_shli_tl(t0, t0, 8);
4018 tcg_gen_andi_tl(t0, t0, ~0x00FF00FF);
4019 tcg_gen_or_tl(t0, t0, t1);
4021 tcg_gen_ext32s_tl(cpu_gpr[rd], t0);
4025 tcg_gen_ext8s_tl(cpu_gpr[rd], t0);
4028 tcg_gen_ext16s_tl(cpu_gpr[rd], t0);
4030 #if defined(TARGET_MIPS64)
4033 TCGv t1 = tcg_temp_new();
4035 tcg_gen_shri_tl(t1, t0, 8);
4036 tcg_gen_andi_tl(t1, t1, 0x00FF00FF00FF00FFULL);
4037 tcg_gen_shli_tl(t0, t0, 8);
4038 tcg_gen_andi_tl(t0, t0, ~0x00FF00FF00FF00FFULL);
4039 tcg_gen_or_tl(cpu_gpr[rd], t0, t1);
4045 TCGv t1 = tcg_temp_new();
4047 tcg_gen_shri_tl(t1, t0, 16);
4048 tcg_gen_andi_tl(t1, t1, 0x0000FFFF0000FFFFULL);
4049 tcg_gen_shli_tl(t0, t0, 16);
4050 tcg_gen_andi_tl(t0, t0, ~0x0000FFFF0000FFFFULL);
4051 tcg_gen_or_tl(t0, t0, t1);
4052 tcg_gen_shri_tl(t1, t0, 32);
4053 tcg_gen_shli_tl(t0, t0, 32);
4054 tcg_gen_or_tl(cpu_gpr[rd], t0, t1);
4060 MIPS_INVAL("bsfhl");
4061 generate_exception(ctx, EXCP_RI);
4068 #ifndef CONFIG_USER_ONLY
4069 /* CP0 (MMU and control) */
4070 static inline void gen_mfc0_load32 (TCGv arg, target_ulong off)
4072 TCGv_i32 t0 = tcg_temp_new_i32();
4074 tcg_gen_ld_i32(t0, cpu_env, off);
4075 tcg_gen_ext_i32_tl(arg, t0);
4076 tcg_temp_free_i32(t0);
4079 static inline void gen_mfc0_load64 (TCGv arg, target_ulong off)
4081 tcg_gen_ld_tl(arg, cpu_env, off);
4082 tcg_gen_ext32s_tl(arg, arg);
4085 static inline void gen_mtc0_store32 (TCGv arg, target_ulong off)
4087 TCGv_i32 t0 = tcg_temp_new_i32();
4089 tcg_gen_trunc_tl_i32(t0, arg);
4090 tcg_gen_st_i32(t0, cpu_env, off);
4091 tcg_temp_free_i32(t0);
4094 static inline void gen_mtc0_store64 (TCGv arg, target_ulong off)
4096 tcg_gen_ext32s_tl(arg, arg);
4097 tcg_gen_st_tl(arg, cpu_env, off);
4100 static void gen_mfc0 (CPUMIPSState *env, DisasContext *ctx, TCGv arg, int reg, int sel)
4102 const char *rn = "invalid";
4105 check_insn(env, ctx, ISA_MIPS32);
4111 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Index));
4115 check_insn(env, ctx, ASE_MT);
4116 gen_helper_mfc0_mvpcontrol(arg, cpu_env);
4120 check_insn(env, ctx, ASE_MT);
4121 gen_helper_mfc0_mvpconf0(arg, cpu_env);
4125 check_insn(env, ctx, ASE_MT);
4126 gen_helper_mfc0_mvpconf1(arg, cpu_env);
4136 gen_helper_mfc0_random(arg, cpu_env);
4140 check_insn(env, ctx, ASE_MT);
4141 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEControl));
4145 check_insn(env, ctx, ASE_MT);
4146 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEConf0));
4150 check_insn(env, ctx, ASE_MT);
4151 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEConf1));
4155 check_insn(env, ctx, ASE_MT);
4156 gen_mfc0_load64(arg, offsetof(CPUMIPSState, CP0_YQMask));
4160 check_insn(env, ctx, ASE_MT);
4161 gen_mfc0_load64(arg, offsetof(CPUMIPSState, CP0_VPESchedule));
4165 check_insn(env, ctx, ASE_MT);
4166 gen_mfc0_load64(arg, offsetof(CPUMIPSState, CP0_VPEScheFBack));
4167 rn = "VPEScheFBack";
4170 check_insn(env, ctx, ASE_MT);
4171 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEOpt));
4181 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EntryLo0));
4182 tcg_gen_ext32s_tl(arg, arg);
4186 check_insn(env, ctx, ASE_MT);
4187 gen_helper_mfc0_tcstatus(arg, cpu_env);
4191 check_insn(env, ctx, ASE_MT);
4192 gen_helper_mfc0_tcbind(arg, cpu_env);
4196 check_insn(env, ctx, ASE_MT);
4197 gen_helper_mfc0_tcrestart(arg, cpu_env);
4201 check_insn(env, ctx, ASE_MT);
4202 gen_helper_mfc0_tchalt(arg, cpu_env);
4206 check_insn(env, ctx, ASE_MT);
4207 gen_helper_mfc0_tccontext(arg, cpu_env);
4211 check_insn(env, ctx, ASE_MT);
4212 gen_helper_mfc0_tcschedule(arg, cpu_env);
4216 check_insn(env, ctx, ASE_MT);
4217 gen_helper_mfc0_tcschefback(arg, cpu_env);
4227 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EntryLo1));
4228 tcg_gen_ext32s_tl(arg, arg);
4238 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_Context));
4239 tcg_gen_ext32s_tl(arg, arg);
4243 // gen_helper_mfc0_contextconfig(arg); /* SmartMIPS ASE */
4244 rn = "ContextConfig";
4253 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PageMask));
4257 check_insn(env, ctx, ISA_MIPS32R2);
4258 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PageGrain));
4268 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Wired));
4272 check_insn(env, ctx, ISA_MIPS32R2);
4273 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf0));
4277 check_insn(env, ctx, ISA_MIPS32R2);
4278 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf1));
4282 check_insn(env, ctx, ISA_MIPS32R2);
4283 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf2));
4287 check_insn(env, ctx, ISA_MIPS32R2);
4288 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf3));
4292 check_insn(env, ctx, ISA_MIPS32R2);
4293 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf4));
4303 check_insn(env, ctx, ISA_MIPS32R2);
4304 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_HWREna));
4314 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_BadVAddr));
4315 tcg_gen_ext32s_tl(arg, arg);
4325 /* Mark as an IO operation because we read the time. */
4328 gen_helper_mfc0_count(arg, cpu_env);
4332 /* Break the TB to be able to take timer interrupts immediately
4333 after reading count. */
4334 ctx->bstate = BS_STOP;
4337 /* 6,7 are implementation dependent */
4345 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EntryHi));
4346 tcg_gen_ext32s_tl(arg, arg);
4356 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Compare));
4359 /* 6,7 are implementation dependent */
4367 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Status));
4371 check_insn(env, ctx, ISA_MIPS32R2);
4372 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_IntCtl));
4376 check_insn(env, ctx, ISA_MIPS32R2);
4377 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSCtl));
4381 check_insn(env, ctx, ISA_MIPS32R2);
4382 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSMap));
4392 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Cause));
4402 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EPC));
4403 tcg_gen_ext32s_tl(arg, arg);
4413 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PRid));
4417 check_insn(env, ctx, ISA_MIPS32R2);
4418 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_EBase));
4428 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config0));
4432 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config1));
4436 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config2));
4440 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config3));
4443 /* 4,5 are reserved */
4444 /* 6,7 are implementation dependent */
4446 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config6));
4450 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config7));
4460 gen_helper_mfc0_lladdr(arg, cpu_env);
4470 gen_helper_1e0i(mfc0_watchlo, arg, sel);
4480 gen_helper_1e0i(mfc0_watchhi, arg, sel);
4490 #if defined(TARGET_MIPS64)
4491 check_insn(env, ctx, ISA_MIPS3);
4492 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_XContext));
4493 tcg_gen_ext32s_tl(arg, arg);
4502 /* Officially reserved, but sel 0 is used for R1x000 framemask */
4505 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Framemask));
4513 tcg_gen_movi_tl(arg, 0); /* unimplemented */
4514 rn = "'Diagnostic"; /* implementation dependent */
4519 gen_helper_mfc0_debug(arg, cpu_env); /* EJTAG support */
4523 // gen_helper_mfc0_tracecontrol(arg); /* PDtrace support */
4524 rn = "TraceControl";
4527 // gen_helper_mfc0_tracecontrol2(arg); /* PDtrace support */
4528 rn = "TraceControl2";
4531 // gen_helper_mfc0_usertracedata(arg); /* PDtrace support */
4532 rn = "UserTraceData";
4535 // gen_helper_mfc0_tracebpc(arg); /* PDtrace support */
4546 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_DEPC));
4547 tcg_gen_ext32s_tl(arg, arg);
4557 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Performance0));
4558 rn = "Performance0";
4561 // gen_helper_mfc0_performance1(arg);
4562 rn = "Performance1";
4565 // gen_helper_mfc0_performance2(arg);
4566 rn = "Performance2";
4569 // gen_helper_mfc0_performance3(arg);
4570 rn = "Performance3";
4573 // gen_helper_mfc0_performance4(arg);
4574 rn = "Performance4";
4577 // gen_helper_mfc0_performance5(arg);
4578 rn = "Performance5";
4581 // gen_helper_mfc0_performance6(arg);
4582 rn = "Performance6";
4585 // gen_helper_mfc0_performance7(arg);
4586 rn = "Performance7";
4593 tcg_gen_movi_tl(arg, 0); /* unimplemented */
4599 tcg_gen_movi_tl(arg, 0); /* unimplemented */
4612 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_TagLo));
4619 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DataLo));
4632 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_TagHi));
4639 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DataHi));
4649 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_ErrorEPC));
4650 tcg_gen_ext32s_tl(arg, arg);
4661 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DESAVE));
4671 (void)rn; /* avoid a compiler warning */
4672 LOG_DISAS("mfc0 %s (reg %d sel %d)\n", rn, reg, sel);
4676 LOG_DISAS("mfc0 %s (reg %d sel %d)\n", rn, reg, sel);
4677 generate_exception(ctx, EXCP_RI);
4680 static void gen_mtc0 (CPUMIPSState *env, DisasContext *ctx, TCGv arg, int reg, int sel)
4682 const char *rn = "invalid";
4685 check_insn(env, ctx, ISA_MIPS32);
4694 gen_helper_mtc0_index(cpu_env, arg);
4698 check_insn(env, ctx, ASE_MT);
4699 gen_helper_mtc0_mvpcontrol(cpu_env, arg);
4703 check_insn(env, ctx, ASE_MT);
4708 check_insn(env, ctx, ASE_MT);
4723 check_insn(env, ctx, ASE_MT);
4724 gen_helper_mtc0_vpecontrol(cpu_env, arg);
4728 check_insn(env, ctx, ASE_MT);
4729 gen_helper_mtc0_vpeconf0(cpu_env, arg);
4733 check_insn(env, ctx, ASE_MT);
4734 gen_helper_mtc0_vpeconf1(cpu_env, arg);
4738 check_insn(env, ctx, ASE_MT);
4739 gen_helper_mtc0_yqmask(cpu_env, arg);
4743 check_insn(env, ctx, ASE_MT);
4744 gen_mtc0_store64(arg, offsetof(CPUMIPSState, CP0_VPESchedule));
4748 check_insn(env, ctx, ASE_MT);
4749 gen_mtc0_store64(arg, offsetof(CPUMIPSState, CP0_VPEScheFBack));
4750 rn = "VPEScheFBack";
4753 check_insn(env, ctx, ASE_MT);
4754 gen_helper_mtc0_vpeopt(cpu_env, arg);
4764 gen_helper_mtc0_entrylo0(cpu_env, arg);
4768 check_insn(env, ctx, ASE_MT);
4769 gen_helper_mtc0_tcstatus(cpu_env, arg);
4773 check_insn(env, ctx, ASE_MT);
4774 gen_helper_mtc0_tcbind(cpu_env, arg);
4778 check_insn(env, ctx, ASE_MT);
4779 gen_helper_mtc0_tcrestart(cpu_env, arg);
4783 check_insn(env, ctx, ASE_MT);
4784 gen_helper_mtc0_tchalt(cpu_env, arg);
4788 check_insn(env, ctx, ASE_MT);
4789 gen_helper_mtc0_tccontext(cpu_env, arg);
4793 check_insn(env, ctx, ASE_MT);
4794 gen_helper_mtc0_tcschedule(cpu_env, arg);
4798 check_insn(env, ctx, ASE_MT);
4799 gen_helper_mtc0_tcschefback(cpu_env, arg);
4809 gen_helper_mtc0_entrylo1(cpu_env, arg);
4819 gen_helper_mtc0_context(cpu_env, arg);
4823 // gen_helper_mtc0_contextconfig(cpu_env, arg); /* SmartMIPS ASE */
4824 rn = "ContextConfig";
4833 gen_helper_mtc0_pagemask(cpu_env, arg);
4837 check_insn(env, ctx, ISA_MIPS32R2);
4838 gen_helper_mtc0_pagegrain(cpu_env, arg);
4848 gen_helper_mtc0_wired(cpu_env, arg);
4852 check_insn(env, ctx, ISA_MIPS32R2);
4853 gen_helper_mtc0_srsconf0(cpu_env, arg);
4857 check_insn(env, ctx, ISA_MIPS32R2);
4858 gen_helper_mtc0_srsconf1(cpu_env, arg);
4862 check_insn(env, ctx, ISA_MIPS32R2);
4863 gen_helper_mtc0_srsconf2(cpu_env, arg);
4867 check_insn(env, ctx, ISA_MIPS32R2);
4868 gen_helper_mtc0_srsconf3(cpu_env, arg);
4872 check_insn(env, ctx, ISA_MIPS32R2);
4873 gen_helper_mtc0_srsconf4(cpu_env, arg);
4883 check_insn(env, ctx, ISA_MIPS32R2);
4884 gen_helper_mtc0_hwrena(cpu_env, arg);
4898 gen_helper_mtc0_count(cpu_env, arg);
4901 /* 6,7 are implementation dependent */
4909 gen_helper_mtc0_entryhi(cpu_env, arg);
4919 gen_helper_mtc0_compare(cpu_env, arg);
4922 /* 6,7 are implementation dependent */
4930 save_cpu_state(ctx, 1);
4931 gen_helper_mtc0_status(cpu_env, arg);
4932 /* BS_STOP isn't good enough here, hflags may have changed. */
4933 gen_save_pc(ctx->pc + 4);
4934 ctx->bstate = BS_EXCP;
4938 check_insn(env, ctx, ISA_MIPS32R2);
4939 gen_helper_mtc0_intctl(cpu_env, arg);
4940 /* Stop translation as we may have switched the execution mode */
4941 ctx->bstate = BS_STOP;
4945 check_insn(env, ctx, ISA_MIPS32R2);
4946 gen_helper_mtc0_srsctl(cpu_env, arg);
4947 /* Stop translation as we may have switched the execution mode */
4948 ctx->bstate = BS_STOP;
4952 check_insn(env, ctx, ISA_MIPS32R2);
4953 gen_mtc0_store32(arg, offsetof(CPUMIPSState, CP0_SRSMap));
4954 /* Stop translation as we may have switched the execution mode */
4955 ctx->bstate = BS_STOP;
4965 save_cpu_state(ctx, 1);
4966 gen_helper_mtc0_cause(cpu_env, arg);
4976 gen_mtc0_store64(arg, offsetof(CPUMIPSState, CP0_EPC));
4990 check_insn(env, ctx, ISA_MIPS32R2);
4991 gen_helper_mtc0_ebase(cpu_env, arg);
5001 gen_helper_mtc0_config0(cpu_env, arg);
5003 /* Stop translation as we may have switched the execution mode */
5004 ctx->bstate = BS_STOP;
5007 /* ignored, read only */
5011 gen_helper_mtc0_config2(cpu_env, arg);
5013 /* Stop translation as we may have switched the execution mode */
5014 ctx->bstate = BS_STOP;
5017 /* ignored, read only */
5020 /* 4,5 are reserved */
5021 /* 6,7 are implementation dependent */
5031 rn = "Invalid config selector";
5038 gen_helper_mtc0_lladdr(cpu_env, arg);
5048 gen_helper_0e1i(mtc0_watchlo, arg, sel);
5058 gen_helper_0e1i(mtc0_watchhi, arg, sel);
5068 #if defined(TARGET_MIPS64)
5069 check_insn(env, ctx, ISA_MIPS3);
5070 gen_helper_mtc0_xcontext(cpu_env, arg);
5079 /* Officially reserved, but sel 0 is used for R1x000 framemask */
5082 gen_helper_mtc0_framemask(cpu_env, arg);
5091 rn = "Diagnostic"; /* implementation dependent */
5096 gen_helper_mtc0_debug(cpu_env, arg); /* EJTAG support */
5097 /* BS_STOP isn't good enough here, hflags may have changed. */
5098 gen_save_pc(ctx->pc + 4);
5099 ctx->bstate = BS_EXCP;
5103 // gen_helper_mtc0_tracecontrol(cpu_env, arg); /* PDtrace support */
5104 rn = "TraceControl";
5105 /* Stop translation as we may have switched the execution mode */
5106 ctx->bstate = BS_STOP;
5109 // gen_helper_mtc0_tracecontrol2(cpu_env, arg); /* PDtrace support */
5110 rn = "TraceControl2";
5111 /* Stop translation as we may have switched the execution mode */
5112 ctx->bstate = BS_STOP;
5115 /* Stop translation as we may have switched the execution mode */
5116 ctx->bstate = BS_STOP;
5117 // gen_helper_mtc0_usertracedata(cpu_env, arg); /* PDtrace support */
5118 rn = "UserTraceData";
5119 /* Stop translation as we may have switched the execution mode */
5120 ctx->bstate = BS_STOP;
5123 // gen_helper_mtc0_tracebpc(cpu_env, arg); /* PDtrace support */
5124 /* Stop translation as we may have switched the execution mode */
5125 ctx->bstate = BS_STOP;
5136 gen_mtc0_store64(arg, offsetof(CPUMIPSState, CP0_DEPC));
5146 gen_helper_mtc0_performance0(cpu_env, arg);
5147 rn = "Performance0";
5150 // gen_helper_mtc0_performance1(arg);
5151 rn = "Performance1";
5154 // gen_helper_mtc0_performance2(arg);
5155 rn = "Performance2";
5158 // gen_helper_mtc0_performance3(arg);
5159 rn = "Performance3";
5162 // gen_helper_mtc0_performance4(arg);
5163 rn = "Performance4";
5166 // gen_helper_mtc0_performance5(arg);
5167 rn = "Performance5";
5170 // gen_helper_mtc0_performance6(arg);
5171 rn = "Performance6";
5174 // gen_helper_mtc0_performance7(arg);
5175 rn = "Performance7";
5201 gen_helper_mtc0_taglo(cpu_env, arg);
5208 gen_helper_mtc0_datalo(cpu_env, arg);
5221 gen_helper_mtc0_taghi(cpu_env, arg);
5228 gen_helper_mtc0_datahi(cpu_env, arg);
5239 gen_mtc0_store64(arg, offsetof(CPUMIPSState, CP0_ErrorEPC));
5250 gen_mtc0_store32(arg, offsetof(CPUMIPSState, CP0_DESAVE));
5256 /* Stop translation as we may have switched the execution mode */
5257 ctx->bstate = BS_STOP;
5262 (void)rn; /* avoid a compiler warning */
5263 LOG_DISAS("mtc0 %s (reg %d sel %d)\n", rn, reg, sel);
5264 /* For simplicity assume that all writes can cause interrupts. */
5267 ctx->bstate = BS_STOP;
5272 LOG_DISAS("mtc0 %s (reg %d sel %d)\n", rn, reg, sel);
5273 generate_exception(ctx, EXCP_RI);
5276 #if defined(TARGET_MIPS64)
5277 static void gen_dmfc0 (CPUMIPSState *env, DisasContext *ctx, TCGv arg, int reg, int sel)
5279 const char *rn = "invalid";
5282 check_insn(env, ctx, ISA_MIPS64);
5288 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Index));
5292 check_insn(env, ctx, ASE_MT);
5293 gen_helper_mfc0_mvpcontrol(arg, cpu_env);
5297 check_insn(env, ctx, ASE_MT);
5298 gen_helper_mfc0_mvpconf0(arg, cpu_env);
5302 check_insn(env, ctx, ASE_MT);
5303 gen_helper_mfc0_mvpconf1(arg, cpu_env);
5313 gen_helper_mfc0_random(arg, cpu_env);
5317 check_insn(env, ctx, ASE_MT);
5318 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEControl));
5322 check_insn(env, ctx, ASE_MT);
5323 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEConf0));
5327 check_insn(env, ctx, ASE_MT);
5328 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEConf1));
5332 check_insn(env, ctx, ASE_MT);
5333 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_YQMask));
5337 check_insn(env, ctx, ASE_MT);
5338 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_VPESchedule));
5342 check_insn(env, ctx, ASE_MT);
5343 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_VPEScheFBack));
5344 rn = "VPEScheFBack";
5347 check_insn(env, ctx, ASE_MT);
5348 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEOpt));
5358 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EntryLo0));
5362 check_insn(env, ctx, ASE_MT);
5363 gen_helper_mfc0_tcstatus(arg, cpu_env);
5367 check_insn(env, ctx, ASE_MT);
5368 gen_helper_mfc0_tcbind(arg, cpu_env);
5372 check_insn(env, ctx, ASE_MT);
5373 gen_helper_dmfc0_tcrestart(arg, cpu_env);
5377 check_insn(env, ctx, ASE_MT);
5378 gen_helper_dmfc0_tchalt(arg, cpu_env);
5382 check_insn(env, ctx, ASE_MT);
5383 gen_helper_dmfc0_tccontext(arg, cpu_env);
5387 check_insn(env, ctx, ASE_MT);
5388 gen_helper_dmfc0_tcschedule(arg, cpu_env);
5392 check_insn(env, ctx, ASE_MT);
5393 gen_helper_dmfc0_tcschefback(arg, cpu_env);
5403 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EntryLo1));
5413 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_Context));
5417 // gen_helper_dmfc0_contextconfig(arg); /* SmartMIPS ASE */
5418 rn = "ContextConfig";
5427 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PageMask));
5431 check_insn(env, ctx, ISA_MIPS32R2);
5432 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PageGrain));
5442 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Wired));
5446 check_insn(env, ctx, ISA_MIPS32R2);
5447 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf0));
5451 check_insn(env, ctx, ISA_MIPS32R2);
5452 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf1));
5456 check_insn(env, ctx, ISA_MIPS32R2);
5457 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf2));
5461 check_insn(env, ctx, ISA_MIPS32R2);
5462 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf3));
5466 check_insn(env, ctx, ISA_MIPS32R2);
5467 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf4));
5477 check_insn(env, ctx, ISA_MIPS32R2);
5478 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_HWREna));
5488 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_BadVAddr));
5498 /* Mark as an IO operation because we read the time. */
5501 gen_helper_mfc0_count(arg, cpu_env);
5505 /* Break the TB to be able to take timer interrupts immediately
5506 after reading count. */
5507 ctx->bstate = BS_STOP;
5510 /* 6,7 are implementation dependent */
5518 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EntryHi));
5528 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Compare));
5531 /* 6,7 are implementation dependent */
5539 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Status));
5543 check_insn(env, ctx, ISA_MIPS32R2);
5544 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_IntCtl));
5548 check_insn(env, ctx, ISA_MIPS32R2);
5549 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSCtl));
5553 check_insn(env, ctx, ISA_MIPS32R2);
5554 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSMap));
5564 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Cause));
5574 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EPC));
5584 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PRid));
5588 check_insn(env, ctx, ISA_MIPS32R2);
5589 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_EBase));
5599 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config0));
5603 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config1));
5607 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config2));
5611 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config3));
5614 /* 6,7 are implementation dependent */
5616 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config6));
5620 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config7));
5630 gen_helper_dmfc0_lladdr(arg, cpu_env);
5640 gen_helper_1e0i(dmfc0_watchlo, arg, sel);
5650 gen_helper_1e0i(mfc0_watchhi, arg, sel);
5660 check_insn(env, ctx, ISA_MIPS3);
5661 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_XContext));
5669 /* Officially reserved, but sel 0 is used for R1x000 framemask */
5672 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Framemask));
5680 tcg_gen_movi_tl(arg, 0); /* unimplemented */
5681 rn = "'Diagnostic"; /* implementation dependent */
5686 gen_helper_mfc0_debug(arg, cpu_env); /* EJTAG support */
5690 // gen_helper_dmfc0_tracecontrol(arg, cpu_env); /* PDtrace support */
5691 rn = "TraceControl";
5694 // gen_helper_dmfc0_tracecontrol2(arg, cpu_env); /* PDtrace support */
5695 rn = "TraceControl2";
5698 // gen_helper_dmfc0_usertracedata(arg, cpu_env); /* PDtrace support */
5699 rn = "UserTraceData";
5702 // gen_helper_dmfc0_tracebpc(arg, cpu_env); /* PDtrace support */
5713 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_DEPC));
5723 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Performance0));
5724 rn = "Performance0";
5727 // gen_helper_dmfc0_performance1(arg);
5728 rn = "Performance1";
5731 // gen_helper_dmfc0_performance2(arg);
5732 rn = "Performance2";
5735 // gen_helper_dmfc0_performance3(arg);
5736 rn = "Performance3";
5739 // gen_helper_dmfc0_performance4(arg);
5740 rn = "Performance4";
5743 // gen_helper_dmfc0_performance5(arg);
5744 rn = "Performance5";
5747 // gen_helper_dmfc0_performance6(arg);
5748 rn = "Performance6";
5751 // gen_helper_dmfc0_performance7(arg);
5752 rn = "Performance7";
5759 tcg_gen_movi_tl(arg, 0); /* unimplemented */
5766 tcg_gen_movi_tl(arg, 0); /* unimplemented */
5779 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_TagLo));
5786 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DataLo));
5799 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_TagHi));
5806 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DataHi));
5816 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_ErrorEPC));
5827 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DESAVE));
5837 (void)rn; /* avoid a compiler warning */
5838 LOG_DISAS("dmfc0 %s (reg %d sel %d)\n", rn, reg, sel);
5842 LOG_DISAS("dmfc0 %s (reg %d sel %d)\n", rn, reg, sel);
5843 generate_exception(ctx, EXCP_RI);
5846 static void gen_dmtc0 (CPUMIPSState *env, DisasContext *ctx, TCGv arg, int reg, int sel)
5848 const char *rn = "invalid";
5851 check_insn(env, ctx, ISA_MIPS64);
5860 gen_helper_mtc0_index(cpu_env, arg);
5864 check_insn(env, ctx, ASE_MT);
5865 gen_helper_mtc0_mvpcontrol(cpu_env, arg);
5869 check_insn(env, ctx, ASE_MT);
5874 check_insn(env, ctx, ASE_MT);
5889 check_insn(env, ctx, ASE_MT);
5890 gen_helper_mtc0_vpecontrol(cpu_env, arg);
5894 check_insn(env, ctx, ASE_MT);
5895 gen_helper_mtc0_vpeconf0(cpu_env, arg);
5899 check_insn(env, ctx, ASE_MT);
5900 gen_helper_mtc0_vpeconf1(cpu_env, arg);
5904 check_insn(env, ctx, ASE_MT);
5905 gen_helper_mtc0_yqmask(cpu_env, arg);
5909 check_insn(env, ctx, ASE_MT);
5910 tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_VPESchedule));
5914 check_insn(env, ctx, ASE_MT);
5915 tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_VPEScheFBack));
5916 rn = "VPEScheFBack";
5919 check_insn(env, ctx, ASE_MT);
5920 gen_helper_mtc0_vpeopt(cpu_env, arg);
5930 gen_helper_mtc0_entrylo0(cpu_env, arg);
5934 check_insn(env, ctx, ASE_MT);
5935 gen_helper_mtc0_tcstatus(cpu_env, arg);
5939 check_insn(env, ctx, ASE_MT);
5940 gen_helper_mtc0_tcbind(cpu_env, arg);
5944 check_insn(env, ctx, ASE_MT);
5945 gen_helper_mtc0_tcrestart(cpu_env, arg);
5949 check_insn(env, ctx, ASE_MT);
5950 gen_helper_mtc0_tchalt(cpu_env, arg);
5954 check_insn(env, ctx, ASE_MT);
5955 gen_helper_mtc0_tccontext(cpu_env, arg);
5959 check_insn(env, ctx, ASE_MT);
5960 gen_helper_mtc0_tcschedule(cpu_env, arg);
5964 check_insn(env, ctx, ASE_MT);
5965 gen_helper_mtc0_tcschefback(cpu_env, arg);
5975 gen_helper_mtc0_entrylo1(cpu_env, arg);
5985 gen_helper_mtc0_context(cpu_env, arg);
5989 // gen_helper_mtc0_contextconfig(cpu_env, arg); /* SmartMIPS ASE */
5990 rn = "ContextConfig";
5999 gen_helper_mtc0_pagemask(cpu_env, arg);
6003 check_insn(env, ctx, ISA_MIPS32R2);
6004 gen_helper_mtc0_pagegrain(cpu_env, arg);
6014 gen_helper_mtc0_wired(cpu_env, arg);
6018 check_insn(env, ctx, ISA_MIPS32R2);
6019 gen_helper_mtc0_srsconf0(cpu_env, arg);
6023 check_insn(env, ctx, ISA_MIPS32R2);
6024 gen_helper_mtc0_srsconf1(cpu_env, arg);
6028 check_insn(env, ctx, ISA_MIPS32R2);
6029 gen_helper_mtc0_srsconf2(cpu_env, arg);
6033 check_insn(env, ctx, ISA_MIPS32R2);
6034 gen_helper_mtc0_srsconf3(cpu_env, arg);
6038 check_insn(env, ctx, ISA_MIPS32R2);
6039 gen_helper_mtc0_srsconf4(cpu_env, arg);
6049 check_insn(env, ctx, ISA_MIPS32R2);
6050 gen_helper_mtc0_hwrena(cpu_env, arg);
6064 gen_helper_mtc0_count(cpu_env, arg);
6067 /* 6,7 are implementation dependent */
6071 /* Stop translation as we may have switched the execution mode */
6072 ctx->bstate = BS_STOP;
6077 gen_helper_mtc0_entryhi(cpu_env, arg);
6087 gen_helper_mtc0_compare(cpu_env, arg);
6090 /* 6,7 are implementation dependent */
6094 /* Stop translation as we may have switched the execution mode */
6095 ctx->bstate = BS_STOP;
6100 save_cpu_state(ctx, 1);
6101 gen_helper_mtc0_status(cpu_env, arg);
6102 /* BS_STOP isn't good enough here, hflags may have changed. */
6103 gen_save_pc(ctx->pc + 4);
6104 ctx->bstate = BS_EXCP;
6108 check_insn(env, ctx, ISA_MIPS32R2);
6109 gen_helper_mtc0_intctl(cpu_env, arg);
6110 /* Stop translation as we may have switched the execution mode */
6111 ctx->bstate = BS_STOP;
6115 check_insn(env, ctx, ISA_MIPS32R2);
6116 gen_helper_mtc0_srsctl(cpu_env, arg);
6117 /* Stop translation as we may have switched the execution mode */
6118 ctx->bstate = BS_STOP;
6122 check_insn(env, ctx, ISA_MIPS32R2);
6123 gen_mtc0_store32(arg, offsetof(CPUMIPSState, CP0_SRSMap));
6124 /* Stop translation as we may have switched the execution mode */
6125 ctx->bstate = BS_STOP;
6135 save_cpu_state(ctx, 1);
6136 /* Mark as an IO operation because we may trigger a software
6141 gen_helper_mtc0_cause(cpu_env, arg);
6145 /* Stop translation as we may have triggered an intetrupt */
6146 ctx->bstate = BS_STOP;
6156 tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EPC));
6170 check_insn(env, ctx, ISA_MIPS32R2);
6171 gen_helper_mtc0_ebase(cpu_env, arg);
6181 gen_helper_mtc0_config0(cpu_env, arg);
6183 /* Stop translation as we may have switched the execution mode */
6184 ctx->bstate = BS_STOP;
6187 /* ignored, read only */
6191 gen_helper_mtc0_config2(cpu_env, arg);
6193 /* Stop translation as we may have switched the execution mode */
6194 ctx->bstate = BS_STOP;
6200 /* 6,7 are implementation dependent */
6202 rn = "Invalid config selector";
6209 gen_helper_mtc0_lladdr(cpu_env, arg);
6219 gen_helper_0e1i(mtc0_watchlo, arg, sel);
6229 gen_helper_0e1i(mtc0_watchhi, arg, sel);
6239 check_insn(env, ctx, ISA_MIPS3);
6240 gen_helper_mtc0_xcontext(cpu_env, arg);
6248 /* Officially reserved, but sel 0 is used for R1x000 framemask */
6251 gen_helper_mtc0_framemask(cpu_env, arg);
6260 rn = "Diagnostic"; /* implementation dependent */
6265 gen_helper_mtc0_debug(cpu_env, arg); /* EJTAG support */
6266 /* BS_STOP isn't good enough here, hflags may have changed. */
6267 gen_save_pc(ctx->pc + 4);
6268 ctx->bstate = BS_EXCP;
6272 // gen_helper_mtc0_tracecontrol(cpu_env, arg); /* PDtrace support */
6273 /* Stop translation as we may have switched the execution mode */
6274 ctx->bstate = BS_STOP;
6275 rn = "TraceControl";
6278 // gen_helper_mtc0_tracecontrol2(cpu_env, arg); /* PDtrace support */
6279 /* Stop translation as we may have switched the execution mode */
6280 ctx->bstate = BS_STOP;
6281 rn = "TraceControl2";
6284 // gen_helper_mtc0_usertracedata(cpu_env, arg); /* PDtrace support */
6285 /* Stop translation as we may have switched the execution mode */
6286 ctx->bstate = BS_STOP;
6287 rn = "UserTraceData";
6290 // gen_helper_mtc0_tracebpc(cpu_env, arg); /* PDtrace support */
6291 /* Stop translation as we may have switched the execution mode */
6292 ctx->bstate = BS_STOP;
6303 tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_DEPC));
6313 gen_helper_mtc0_performance0(cpu_env, arg);
6314 rn = "Performance0";
6317 // gen_helper_mtc0_performance1(cpu_env, arg);
6318 rn = "Performance1";
6321 // gen_helper_mtc0_performance2(cpu_env, arg);
6322 rn = "Performance2";
6325 // gen_helper_mtc0_performance3(cpu_env, arg);
6326 rn = "Performance3";
6329 // gen_helper_mtc0_performance4(cpu_env, arg);
6330 rn = "Performance4";
6333 // gen_helper_mtc0_performance5(cpu_env, arg);
6334 rn = "Performance5";
6337 // gen_helper_mtc0_performance6(cpu_env, arg);
6338 rn = "Performance6";
6341 // gen_helper_mtc0_performance7(cpu_env, arg);
6342 rn = "Performance7";
6368 gen_helper_mtc0_taglo(cpu_env, arg);
6375 gen_helper_mtc0_datalo(cpu_env, arg);
6388 gen_helper_mtc0_taghi(cpu_env, arg);
6395 gen_helper_mtc0_datahi(cpu_env, arg);
6406 tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_ErrorEPC));
6417 gen_mtc0_store32(arg, offsetof(CPUMIPSState, CP0_DESAVE));
6423 /* Stop translation as we may have switched the execution mode */
6424 ctx->bstate = BS_STOP;
6429 (void)rn; /* avoid a compiler warning */
6430 LOG_DISAS("dmtc0 %s (reg %d sel %d)\n", rn, reg, sel);
6431 /* For simplicity assume that all writes can cause interrupts. */
6434 ctx->bstate = BS_STOP;
6439 LOG_DISAS("dmtc0 %s (reg %d sel %d)\n", rn, reg, sel);
6440 generate_exception(ctx, EXCP_RI);
6442 #endif /* TARGET_MIPS64 */
6444 static void gen_mftr(CPUMIPSState *env, DisasContext *ctx, int rt, int rd,
6445 int u, int sel, int h)
6447 int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
6448 TCGv t0 = tcg_temp_local_new();
6450 if ((env->CP0_VPEConf0 & (1 << CP0VPEC0_MVP)) == 0 &&
6451 ((env->tcs[other_tc].CP0_TCBind & (0xf << CP0TCBd_CurVPE)) !=
6452 (env->active_tc.CP0_TCBind & (0xf << CP0TCBd_CurVPE))))
6453 tcg_gen_movi_tl(t0, -1);
6454 else if ((env->CP0_VPEControl & (0xff << CP0VPECo_TargTC)) >
6455 (env->mvp->CP0_MVPConf0 & (0xff << CP0MVPC0_PTC)))
6456 tcg_gen_movi_tl(t0, -1);
6462 gen_helper_mftc0_vpecontrol(t0, cpu_env);
6465 gen_helper_mftc0_vpeconf0(t0, cpu_env);
6475 gen_helper_mftc0_tcstatus(t0, cpu_env);
6478 gen_helper_mftc0_tcbind(t0, cpu_env);
6481 gen_helper_mftc0_tcrestart(t0, cpu_env);
6484 gen_helper_mftc0_tchalt(t0, cpu_env);
6487 gen_helper_mftc0_tccontext(t0, cpu_env);
6490 gen_helper_mftc0_tcschedule(t0, cpu_env);
6493 gen_helper_mftc0_tcschefback(t0, cpu_env);
6496 gen_mfc0(env, ctx, t0, rt, sel);
6503 gen_helper_mftc0_entryhi(t0, cpu_env);
6506 gen_mfc0(env, ctx, t0, rt, sel);
6512 gen_helper_mftc0_status(t0, cpu_env);
6515 gen_mfc0(env, ctx, t0, rt, sel);
6521 gen_helper_mftc0_cause(t0, cpu_env);
6531 gen_helper_mftc0_epc(t0, cpu_env);
6541 gen_helper_mftc0_ebase(t0, cpu_env);
6551 gen_helper_mftc0_configx(t0, cpu_env, tcg_const_tl(sel));
6561 gen_helper_mftc0_debug(t0, cpu_env);
6564 gen_mfc0(env, ctx, t0, rt, sel);
6569 gen_mfc0(env, ctx, t0, rt, sel);
6571 } else switch (sel) {
6572 /* GPR registers. */
6574 gen_helper_1e0i(mftgpr, t0, rt);
6576 /* Auxiliary CPU registers */
6580 gen_helper_1e0i(mftlo, t0, 0);
6583 gen_helper_1e0i(mfthi, t0, 0);
6586 gen_helper_1e0i(mftacx, t0, 0);
6589 gen_helper_1e0i(mftlo, t0, 1);
6592 gen_helper_1e0i(mfthi, t0, 1);
6595 gen_helper_1e0i(mftacx, t0, 1);
6598 gen_helper_1e0i(mftlo, t0, 2);
6601 gen_helper_1e0i(mfthi, t0, 2);
6604 gen_helper_1e0i(mftacx, t0, 2);
6607 gen_helper_1e0i(mftlo, t0, 3);
6610 gen_helper_1e0i(mfthi, t0, 3);
6613 gen_helper_1e0i(mftacx, t0, 3);
6616 gen_helper_mftdsp(t0, cpu_env);
6622 /* Floating point (COP1). */
6624 /* XXX: For now we support only a single FPU context. */
6626 TCGv_i32 fp0 = tcg_temp_new_i32();
6628 gen_load_fpr32(fp0, rt);
6629 tcg_gen_ext_i32_tl(t0, fp0);
6630 tcg_temp_free_i32(fp0);
6632 TCGv_i32 fp0 = tcg_temp_new_i32();
6634 gen_load_fpr32h(fp0, rt);
6635 tcg_gen_ext_i32_tl(t0, fp0);
6636 tcg_temp_free_i32(fp0);
6640 /* XXX: For now we support only a single FPU context. */
6641 gen_helper_1e0i(cfc1, t0, rt);
6643 /* COP2: Not implemented. */
6650 LOG_DISAS("mftr (reg %d u %d sel %d h %d)\n", rt, u, sel, h);
6651 gen_store_gpr(t0, rd);
6657 LOG_DISAS("mftr (reg %d u %d sel %d h %d)\n", rt, u, sel, h);
6658 generate_exception(ctx, EXCP_RI);
6661 static void gen_mttr(CPUMIPSState *env, DisasContext *ctx, int rd, int rt,
6662 int u, int sel, int h)
6664 int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
6665 TCGv t0 = tcg_temp_local_new();
6667 gen_load_gpr(t0, rt);
6668 if ((env->CP0_VPEConf0 & (1 << CP0VPEC0_MVP)) == 0 &&
6669 ((env->tcs[other_tc].CP0_TCBind & (0xf << CP0TCBd_CurVPE)) !=
6670 (env->active_tc.CP0_TCBind & (0xf << CP0TCBd_CurVPE))))
6672 else if ((env->CP0_VPEControl & (0xff << CP0VPECo_TargTC)) >
6673 (env->mvp->CP0_MVPConf0 & (0xff << CP0MVPC0_PTC)))
6680 gen_helper_mttc0_vpecontrol(cpu_env, t0);
6683 gen_helper_mttc0_vpeconf0(cpu_env, t0);
6693 gen_helper_mttc0_tcstatus(cpu_env, t0);
6696 gen_helper_mttc0_tcbind(cpu_env, t0);
6699 gen_helper_mttc0_tcrestart(cpu_env, t0);
6702 gen_helper_mttc0_tchalt(cpu_env, t0);
6705 gen_helper_mttc0_tccontext(cpu_env, t0);
6708 gen_helper_mttc0_tcschedule(cpu_env, t0);
6711 gen_helper_mttc0_tcschefback(cpu_env, t0);
6714 gen_mtc0(env, ctx, t0, rd, sel);
6721 gen_helper_mttc0_entryhi(cpu_env, t0);
6724 gen_mtc0(env, ctx, t0, rd, sel);
6730 gen_helper_mttc0_status(cpu_env, t0);
6733 gen_mtc0(env, ctx, t0, rd, sel);
6739 gen_helper_mttc0_cause(cpu_env, t0);
6749 gen_helper_mttc0_ebase(cpu_env, t0);
6759 gen_helper_mttc0_debug(cpu_env, t0);
6762 gen_mtc0(env, ctx, t0, rd, sel);
6767 gen_mtc0(env, ctx, t0, rd, sel);
6769 } else switch (sel) {
6770 /* GPR registers. */
6772 gen_helper_0e1i(mttgpr, t0, rd);
6774 /* Auxiliary CPU registers */
6778 gen_helper_0e1i(mttlo, t0, 0);
6781 gen_helper_0e1i(mtthi, t0, 0);
6784 gen_helper_0e1i(mttacx, t0, 0);
6787 gen_helper_0e1i(mttlo, t0, 1);
6790 gen_helper_0e1i(mtthi, t0, 1);
6793 gen_helper_0e1i(mttacx, t0, 1);
6796 gen_helper_0e1i(mttlo, t0, 2);
6799 gen_helper_0e1i(mtthi, t0, 2);
6802 gen_helper_0e1i(mttacx, t0, 2);
6805 gen_helper_0e1i(mttlo, t0, 3);
6808 gen_helper_0e1i(mtthi, t0, 3);
6811 gen_helper_0e1i(mttacx, t0, 3);
6814 gen_helper_mttdsp(cpu_env, t0);
6820 /* Floating point (COP1). */
6822 /* XXX: For now we support only a single FPU context. */
6824 TCGv_i32 fp0 = tcg_temp_new_i32();
6826 tcg_gen_trunc_tl_i32(fp0, t0);
6827 gen_store_fpr32(fp0, rd);
6828 tcg_temp_free_i32(fp0);
6830 TCGv_i32 fp0 = tcg_temp_new_i32();
6832 tcg_gen_trunc_tl_i32(fp0, t0);
6833 gen_store_fpr32h(fp0, rd);
6834 tcg_temp_free_i32(fp0);
6838 /* XXX: For now we support only a single FPU context. */
6839 gen_helper_0e1i(ctc1, t0, rd);
6841 /* COP2: Not implemented. */
6848 LOG_DISAS("mttr (reg %d u %d sel %d h %d)\n", rd, u, sel, h);
6854 LOG_DISAS("mttr (reg %d u %d sel %d h %d)\n", rd, u, sel, h);
6855 generate_exception(ctx, EXCP_RI);
6858 static void gen_cp0 (CPUMIPSState *env, DisasContext *ctx, uint32_t opc, int rt, int rd)
6860 const char *opn = "ldst";
6862 check_cp0_enabled(ctx);
6869 gen_mfc0(env, ctx, cpu_gpr[rt], rd, ctx->opcode & 0x7);
6874 TCGv t0 = tcg_temp_new();
6876 gen_load_gpr(t0, rt);
6877 gen_mtc0(env, ctx, t0, rd, ctx->opcode & 0x7);
6882 #if defined(TARGET_MIPS64)
6884 check_insn(env, ctx, ISA_MIPS3);
6889 gen_dmfc0(env, ctx, cpu_gpr[rt], rd, ctx->opcode & 0x7);
6893 check_insn(env, ctx, ISA_MIPS3);
6895 TCGv t0 = tcg_temp_new();
6897 gen_load_gpr(t0, rt);
6898 gen_dmtc0(env, ctx, t0, rd, ctx->opcode & 0x7);
6905 check_insn(env, ctx, ASE_MT);
6910 gen_mftr(env, ctx, rt, rd, (ctx->opcode >> 5) & 1,
6911 ctx->opcode & 0x7, (ctx->opcode >> 4) & 1);
6915 check_insn(env, ctx, ASE_MT);
6916 gen_mttr(env, ctx, rd, rt, (ctx->opcode >> 5) & 1,
6917 ctx->opcode & 0x7, (ctx->opcode >> 4) & 1);
6922 if (!env->tlb->helper_tlbwi)
6924 gen_helper_tlbwi(cpu_env);
6928 if (!env->tlb->helper_tlbwr)
6930 gen_helper_tlbwr(cpu_env);
6934 if (!env->tlb->helper_tlbp)
6936 gen_helper_tlbp(cpu_env);
6940 if (!env->tlb->helper_tlbr)
6942 gen_helper_tlbr(cpu_env);
6946 check_insn(env, ctx, ISA_MIPS2);
6947 gen_helper_eret(cpu_env);
6948 ctx->bstate = BS_EXCP;
6952 check_insn(env, ctx, ISA_MIPS32);
6953 if (!(ctx->hflags & MIPS_HFLAG_DM)) {
6955 generate_exception(ctx, EXCP_RI);
6957 gen_helper_deret(cpu_env);
6958 ctx->bstate = BS_EXCP;
6963 check_insn(env, ctx, ISA_MIPS3 | ISA_MIPS32);
6964 /* If we get an exception, we want to restart at next instruction */
6966 save_cpu_state(ctx, 1);
6968 gen_helper_wait(cpu_env);
6969 ctx->bstate = BS_EXCP;
6974 generate_exception(ctx, EXCP_RI);
6977 (void)opn; /* avoid a compiler warning */
6978 MIPS_DEBUG("%s %s %d", opn, regnames[rt], rd);
6980 #endif /* !CONFIG_USER_ONLY */
6982 /* CP1 Branches (before delay slot) */
6983 static void gen_compute_branch1 (CPUMIPSState *env, DisasContext *ctx, uint32_t op,
6984 int32_t cc, int32_t offset)
6986 target_ulong btarget;
6987 const char *opn = "cp1 cond branch";
6988 TCGv_i32 t0 = tcg_temp_new_i32();
6991 check_insn(env, ctx, ISA_MIPS4 | ISA_MIPS32);
6993 btarget = ctx->pc + 4 + offset;
6997 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
6998 tcg_gen_not_i32(t0, t0);
6999 tcg_gen_andi_i32(t0, t0, 1);
7000 tcg_gen_extu_i32_tl(bcond, t0);
7004 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
7005 tcg_gen_not_i32(t0, t0);
7006 tcg_gen_andi_i32(t0, t0, 1);
7007 tcg_gen_extu_i32_tl(bcond, t0);
7011 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
7012 tcg_gen_andi_i32(t0, t0, 1);
7013 tcg_gen_extu_i32_tl(bcond, t0);
7017 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
7018 tcg_gen_andi_i32(t0, t0, 1);
7019 tcg_gen_extu_i32_tl(bcond, t0);
7022 ctx->hflags |= MIPS_HFLAG_BL;
7026 TCGv_i32 t1 = tcg_temp_new_i32();
7027 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
7028 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+1));
7029 tcg_gen_nand_i32(t0, t0, t1);
7030 tcg_temp_free_i32(t1);
7031 tcg_gen_andi_i32(t0, t0, 1);
7032 tcg_gen_extu_i32_tl(bcond, t0);
7038 TCGv_i32 t1 = tcg_temp_new_i32();
7039 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
7040 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+1));
7041 tcg_gen_or_i32(t0, t0, t1);
7042 tcg_temp_free_i32(t1);
7043 tcg_gen_andi_i32(t0, t0, 1);
7044 tcg_gen_extu_i32_tl(bcond, t0);
7050 TCGv_i32 t1 = tcg_temp_new_i32();
7051 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
7052 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+1));
7053 tcg_gen_and_i32(t0, t0, t1);
7054 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+2));
7055 tcg_gen_and_i32(t0, t0, t1);
7056 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+3));
7057 tcg_gen_nand_i32(t0, t0, t1);
7058 tcg_temp_free_i32(t1);
7059 tcg_gen_andi_i32(t0, t0, 1);
7060 tcg_gen_extu_i32_tl(bcond, t0);
7066 TCGv_i32 t1 = tcg_temp_new_i32();
7067 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
7068 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+1));
7069 tcg_gen_or_i32(t0, t0, t1);
7070 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+2));
7071 tcg_gen_or_i32(t0, t0, t1);
7072 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+3));
7073 tcg_gen_or_i32(t0, t0, t1);
7074 tcg_temp_free_i32(t1);
7075 tcg_gen_andi_i32(t0, t0, 1);
7076 tcg_gen_extu_i32_tl(bcond, t0);
7080 ctx->hflags |= MIPS_HFLAG_BC;
7084 generate_exception (ctx, EXCP_RI);
7087 (void)opn; /* avoid a compiler warning */
7088 MIPS_DEBUG("%s: cond %02x target " TARGET_FMT_lx, opn,
7089 ctx->hflags, btarget);
7090 ctx->btarget = btarget;
7093 tcg_temp_free_i32(t0);
7096 /* Coprocessor 1 (FPU) */
7098 #define FOP(func, fmt) (((fmt) << 21) | (func))
7101 OPC_ADD_S = FOP(0, FMT_S),
7102 OPC_SUB_S = FOP(1, FMT_S),
7103 OPC_MUL_S = FOP(2, FMT_S),
7104 OPC_DIV_S = FOP(3, FMT_S),
7105 OPC_SQRT_S = FOP(4, FMT_S),
7106 OPC_ABS_S = FOP(5, FMT_S),
7107 OPC_MOV_S = FOP(6, FMT_S),
7108 OPC_NEG_S = FOP(7, FMT_S),
7109 OPC_ROUND_L_S = FOP(8, FMT_S),
7110 OPC_TRUNC_L_S = FOP(9, FMT_S),
7111 OPC_CEIL_L_S = FOP(10, FMT_S),
7112 OPC_FLOOR_L_S = FOP(11, FMT_S),
7113 OPC_ROUND_W_S = FOP(12, FMT_S),
7114 OPC_TRUNC_W_S = FOP(13, FMT_S),
7115 OPC_CEIL_W_S = FOP(14, FMT_S),
7116 OPC_FLOOR_W_S = FOP(15, FMT_S),
7117 OPC_MOVCF_S = FOP(17, FMT_S),
7118 OPC_MOVZ_S = FOP(18, FMT_S),
7119 OPC_MOVN_S = FOP(19, FMT_S),
7120 OPC_RECIP_S = FOP(21, FMT_S),
7121 OPC_RSQRT_S = FOP(22, FMT_S),
7122 OPC_RECIP2_S = FOP(28, FMT_S),
7123 OPC_RECIP1_S = FOP(29, FMT_S),
7124 OPC_RSQRT1_S = FOP(30, FMT_S),
7125 OPC_RSQRT2_S = FOP(31, FMT_S),
7126 OPC_CVT_D_S = FOP(33, FMT_S),
7127 OPC_CVT_W_S = FOP(36, FMT_S),
7128 OPC_CVT_L_S = FOP(37, FMT_S),
7129 OPC_CVT_PS_S = FOP(38, FMT_S),
7130 OPC_CMP_F_S = FOP (48, FMT_S),
7131 OPC_CMP_UN_S = FOP (49, FMT_S),
7132 OPC_CMP_EQ_S = FOP (50, FMT_S),
7133 OPC_CMP_UEQ_S = FOP (51, FMT_S),
7134 OPC_CMP_OLT_S = FOP (52, FMT_S),
7135 OPC_CMP_ULT_S = FOP (53, FMT_S),
7136 OPC_CMP_OLE_S = FOP (54, FMT_S),
7137 OPC_CMP_ULE_S = FOP (55, FMT_S),
7138 OPC_CMP_SF_S = FOP (56, FMT_S),
7139 OPC_CMP_NGLE_S = FOP (57, FMT_S),
7140 OPC_CMP_SEQ_S = FOP (58, FMT_S),
7141 OPC_CMP_NGL_S = FOP (59, FMT_S),
7142 OPC_CMP_LT_S = FOP (60, FMT_S),
7143 OPC_CMP_NGE_S = FOP (61, FMT_S),
7144 OPC_CMP_LE_S = FOP (62, FMT_S),
7145 OPC_CMP_NGT_S = FOP (63, FMT_S),
7147 OPC_ADD_D = FOP(0, FMT_D),
7148 OPC_SUB_D = FOP(1, FMT_D),
7149 OPC_MUL_D = FOP(2, FMT_D),
7150 OPC_DIV_D = FOP(3, FMT_D),
7151 OPC_SQRT_D = FOP(4, FMT_D),
7152 OPC_ABS_D = FOP(5, FMT_D),
7153 OPC_MOV_D = FOP(6, FMT_D),
7154 OPC_NEG_D = FOP(7, FMT_D),
7155 OPC_ROUND_L_D = FOP(8, FMT_D),
7156 OPC_TRUNC_L_D = FOP(9, FMT_D),
7157 OPC_CEIL_L_D = FOP(10, FMT_D),
7158 OPC_FLOOR_L_D = FOP(11, FMT_D),
7159 OPC_ROUND_W_D = FOP(12, FMT_D),
7160 OPC_TRUNC_W_D = FOP(13, FMT_D),
7161 OPC_CEIL_W_D = FOP(14, FMT_D),
7162 OPC_FLOOR_W_D = FOP(15, FMT_D),
7163 OPC_MOVCF_D = FOP(17, FMT_D),
7164 OPC_MOVZ_D = FOP(18, FMT_D),
7165 OPC_MOVN_D = FOP(19, FMT_D),
7166 OPC_RECIP_D = FOP(21, FMT_D),
7167 OPC_RSQRT_D = FOP(22, FMT_D),
7168 OPC_RECIP2_D = FOP(28, FMT_D),
7169 OPC_RECIP1_D = FOP(29, FMT_D),
7170 OPC_RSQRT1_D = FOP(30, FMT_D),
7171 OPC_RSQRT2_D = FOP(31, FMT_D),
7172 OPC_CVT_S_D = FOP(32, FMT_D),
7173 OPC_CVT_W_D = FOP(36, FMT_D),
7174 OPC_CVT_L_D = FOP(37, FMT_D),
7175 OPC_CMP_F_D = FOP (48, FMT_D),
7176 OPC_CMP_UN_D = FOP (49, FMT_D),
7177 OPC_CMP_EQ_D = FOP (50, FMT_D),
7178 OPC_CMP_UEQ_D = FOP (51, FMT_D),
7179 OPC_CMP_OLT_D = FOP (52, FMT_D),
7180 OPC_CMP_ULT_D = FOP (53, FMT_D),
7181 OPC_CMP_OLE_D = FOP (54, FMT_D),
7182 OPC_CMP_ULE_D = FOP (55, FMT_D),
7183 OPC_CMP_SF_D = FOP (56, FMT_D),
7184 OPC_CMP_NGLE_D = FOP (57, FMT_D),
7185 OPC_CMP_SEQ_D = FOP (58, FMT_D),
7186 OPC_CMP_NGL_D = FOP (59, FMT_D),
7187 OPC_CMP_LT_D = FOP (60, FMT_D),
7188 OPC_CMP_NGE_D = FOP (61, FMT_D),
7189 OPC_CMP_LE_D = FOP (62, FMT_D),
7190 OPC_CMP_NGT_D = FOP (63, FMT_D),
7192 OPC_CVT_S_W = FOP(32, FMT_W),
7193 OPC_CVT_D_W = FOP(33, FMT_W),
7194 OPC_CVT_S_L = FOP(32, FMT_L),
7195 OPC_CVT_D_L = FOP(33, FMT_L),
7196 OPC_CVT_PS_PW = FOP(38, FMT_W),
7198 OPC_ADD_PS = FOP(0, FMT_PS),
7199 OPC_SUB_PS = FOP(1, FMT_PS),
7200 OPC_MUL_PS = FOP(2, FMT_PS),
7201 OPC_DIV_PS = FOP(3, FMT_PS),
7202 OPC_ABS_PS = FOP(5, FMT_PS),
7203 OPC_MOV_PS = FOP(6, FMT_PS),
7204 OPC_NEG_PS = FOP(7, FMT_PS),
7205 OPC_MOVCF_PS = FOP(17, FMT_PS),
7206 OPC_MOVZ_PS = FOP(18, FMT_PS),
7207 OPC_MOVN_PS = FOP(19, FMT_PS),
7208 OPC_ADDR_PS = FOP(24, FMT_PS),
7209 OPC_MULR_PS = FOP(26, FMT_PS),
7210 OPC_RECIP2_PS = FOP(28, FMT_PS),
7211 OPC_RECIP1_PS = FOP(29, FMT_PS),
7212 OPC_RSQRT1_PS = FOP(30, FMT_PS),
7213 OPC_RSQRT2_PS = FOP(31, FMT_PS),
7215 OPC_CVT_S_PU = FOP(32, FMT_PS),
7216 OPC_CVT_PW_PS = FOP(36, FMT_PS),
7217 OPC_CVT_S_PL = FOP(40, FMT_PS),
7218 OPC_PLL_PS = FOP(44, FMT_PS),
7219 OPC_PLU_PS = FOP(45, FMT_PS),
7220 OPC_PUL_PS = FOP(46, FMT_PS),
7221 OPC_PUU_PS = FOP(47, FMT_PS),
7222 OPC_CMP_F_PS = FOP (48, FMT_PS),
7223 OPC_CMP_UN_PS = FOP (49, FMT_PS),
7224 OPC_CMP_EQ_PS = FOP (50, FMT_PS),
7225 OPC_CMP_UEQ_PS = FOP (51, FMT_PS),
7226 OPC_CMP_OLT_PS = FOP (52, FMT_PS),
7227 OPC_CMP_ULT_PS = FOP (53, FMT_PS),
7228 OPC_CMP_OLE_PS = FOP (54, FMT_PS),
7229 OPC_CMP_ULE_PS = FOP (55, FMT_PS),
7230 OPC_CMP_SF_PS = FOP (56, FMT_PS),
7231 OPC_CMP_NGLE_PS = FOP (57, FMT_PS),
7232 OPC_CMP_SEQ_PS = FOP (58, FMT_PS),
7233 OPC_CMP_NGL_PS = FOP (59, FMT_PS),
7234 OPC_CMP_LT_PS = FOP (60, FMT_PS),
7235 OPC_CMP_NGE_PS = FOP (61, FMT_PS),
7236 OPC_CMP_LE_PS = FOP (62, FMT_PS),
7237 OPC_CMP_NGT_PS = FOP (63, FMT_PS),
7240 static void gen_cp1 (DisasContext *ctx, uint32_t opc, int rt, int fs)
7242 const char *opn = "cp1 move";
7243 TCGv t0 = tcg_temp_new();
7248 TCGv_i32 fp0 = tcg_temp_new_i32();
7250 gen_load_fpr32(fp0, fs);
7251 tcg_gen_ext_i32_tl(t0, fp0);
7252 tcg_temp_free_i32(fp0);
7254 gen_store_gpr(t0, rt);
7258 gen_load_gpr(t0, rt);
7260 TCGv_i32 fp0 = tcg_temp_new_i32();
7262 tcg_gen_trunc_tl_i32(fp0, t0);
7263 gen_store_fpr32(fp0, fs);
7264 tcg_temp_free_i32(fp0);
7269 gen_helper_1e0i(cfc1, t0, fs);
7270 gen_store_gpr(t0, rt);
7274 gen_load_gpr(t0, rt);
7275 gen_helper_0e1i(ctc1, t0, fs);
7278 #if defined(TARGET_MIPS64)
7280 gen_load_fpr64(ctx, t0, fs);
7281 gen_store_gpr(t0, rt);
7285 gen_load_gpr(t0, rt);
7286 gen_store_fpr64(ctx, t0, fs);
7292 TCGv_i32 fp0 = tcg_temp_new_i32();
7294 gen_load_fpr32h(fp0, fs);
7295 tcg_gen_ext_i32_tl(t0, fp0);
7296 tcg_temp_free_i32(fp0);
7298 gen_store_gpr(t0, rt);
7302 gen_load_gpr(t0, rt);
7304 TCGv_i32 fp0 = tcg_temp_new_i32();
7306 tcg_gen_trunc_tl_i32(fp0, t0);
7307 gen_store_fpr32h(fp0, fs);
7308 tcg_temp_free_i32(fp0);
7314 generate_exception (ctx, EXCP_RI);
7317 (void)opn; /* avoid a compiler warning */
7318 MIPS_DEBUG("%s %s %s", opn, regnames[rt], fregnames[fs]);
7324 static void gen_movci (DisasContext *ctx, int rd, int rs, int cc, int tf)
7340 l1 = gen_new_label();
7341 t0 = tcg_temp_new_i32();
7342 tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc));
7343 tcg_gen_brcondi_i32(cond, t0, 0, l1);
7344 tcg_temp_free_i32(t0);
7346 tcg_gen_movi_tl(cpu_gpr[rd], 0);
7348 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
7353 static inline void gen_movcf_s (int fs, int fd, int cc, int tf)
7356 TCGv_i32 t0 = tcg_temp_new_i32();
7357 int l1 = gen_new_label();
7364 tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc));
7365 tcg_gen_brcondi_i32(cond, t0, 0, l1);
7366 gen_load_fpr32(t0, fs);
7367 gen_store_fpr32(t0, fd);
7369 tcg_temp_free_i32(t0);
7372 static inline void gen_movcf_d (DisasContext *ctx, int fs, int fd, int cc, int tf)
7375 TCGv_i32 t0 = tcg_temp_new_i32();
7377 int l1 = gen_new_label();
7384 tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc));
7385 tcg_gen_brcondi_i32(cond, t0, 0, l1);
7386 tcg_temp_free_i32(t0);
7387 fp0 = tcg_temp_new_i64();
7388 gen_load_fpr64(ctx, fp0, fs);
7389 gen_store_fpr64(ctx, fp0, fd);
7390 tcg_temp_free_i64(fp0);
7394 static inline void gen_movcf_ps (int fs, int fd, int cc, int tf)
7397 TCGv_i32 t0 = tcg_temp_new_i32();
7398 int l1 = gen_new_label();
7399 int l2 = gen_new_label();
7406 tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc));
7407 tcg_gen_brcondi_i32(cond, t0, 0, l1);
7408 gen_load_fpr32(t0, fs);
7409 gen_store_fpr32(t0, fd);
7412 tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc+1));
7413 tcg_gen_brcondi_i32(cond, t0, 0, l2);
7414 gen_load_fpr32h(t0, fs);
7415 gen_store_fpr32h(t0, fd);
7416 tcg_temp_free_i32(t0);
7421 static void gen_farith (DisasContext *ctx, enum fopcode op1,
7422 int ft, int fs, int fd, int cc)
7424 const char *opn = "farith";
7425 const char *condnames[] = {
7443 const char *condnames_abs[] = {
7461 enum { BINOP, CMPOP, OTHEROP } optype = OTHEROP;
7462 uint32_t func = ctx->opcode & 0x3f;
7467 TCGv_i32 fp0 = tcg_temp_new_i32();
7468 TCGv_i32 fp1 = tcg_temp_new_i32();
7470 gen_load_fpr32(fp0, fs);
7471 gen_load_fpr32(fp1, ft);
7472 gen_helper_float_add_s(fp0, cpu_env, fp0, fp1);
7473 tcg_temp_free_i32(fp1);
7474 gen_store_fpr32(fp0, fd);
7475 tcg_temp_free_i32(fp0);
7482 TCGv_i32 fp0 = tcg_temp_new_i32();
7483 TCGv_i32 fp1 = tcg_temp_new_i32();
7485 gen_load_fpr32(fp0, fs);
7486 gen_load_fpr32(fp1, ft);
7487 gen_helper_float_sub_s(fp0, cpu_env, fp0, fp1);
7488 tcg_temp_free_i32(fp1);
7489 gen_store_fpr32(fp0, fd);
7490 tcg_temp_free_i32(fp0);
7497 TCGv_i32 fp0 = tcg_temp_new_i32();
7498 TCGv_i32 fp1 = tcg_temp_new_i32();
7500 gen_load_fpr32(fp0, fs);
7501 gen_load_fpr32(fp1, ft);
7502 gen_helper_float_mul_s(fp0, cpu_env, fp0, fp1);
7503 tcg_temp_free_i32(fp1);
7504 gen_store_fpr32(fp0, fd);
7505 tcg_temp_free_i32(fp0);
7512 TCGv_i32 fp0 = tcg_temp_new_i32();
7513 TCGv_i32 fp1 = tcg_temp_new_i32();
7515 gen_load_fpr32(fp0, fs);
7516 gen_load_fpr32(fp1, ft);
7517 gen_helper_float_div_s(fp0, cpu_env, fp0, fp1);
7518 tcg_temp_free_i32(fp1);
7519 gen_store_fpr32(fp0, fd);
7520 tcg_temp_free_i32(fp0);
7527 TCGv_i32 fp0 = tcg_temp_new_i32();
7529 gen_load_fpr32(fp0, fs);
7530 gen_helper_float_sqrt_s(fp0, cpu_env, fp0);
7531 gen_store_fpr32(fp0, fd);
7532 tcg_temp_free_i32(fp0);
7538 TCGv_i32 fp0 = tcg_temp_new_i32();
7540 gen_load_fpr32(fp0, fs);
7541 gen_helper_float_abs_s(fp0, fp0);
7542 gen_store_fpr32(fp0, fd);
7543 tcg_temp_free_i32(fp0);
7549 TCGv_i32 fp0 = tcg_temp_new_i32();
7551 gen_load_fpr32(fp0, fs);
7552 gen_store_fpr32(fp0, fd);
7553 tcg_temp_free_i32(fp0);
7559 TCGv_i32 fp0 = tcg_temp_new_i32();
7561 gen_load_fpr32(fp0, fs);
7562 gen_helper_float_chs_s(fp0, fp0);
7563 gen_store_fpr32(fp0, fd);
7564 tcg_temp_free_i32(fp0);
7569 check_cp1_64bitmode(ctx);
7571 TCGv_i32 fp32 = tcg_temp_new_i32();
7572 TCGv_i64 fp64 = tcg_temp_new_i64();
7574 gen_load_fpr32(fp32, fs);
7575 gen_helper_float_roundl_s(fp64, cpu_env, fp32);
7576 tcg_temp_free_i32(fp32);
7577 gen_store_fpr64(ctx, fp64, fd);
7578 tcg_temp_free_i64(fp64);
7583 check_cp1_64bitmode(ctx);
7585 TCGv_i32 fp32 = tcg_temp_new_i32();
7586 TCGv_i64 fp64 = tcg_temp_new_i64();
7588 gen_load_fpr32(fp32, fs);
7589 gen_helper_float_truncl_s(fp64, cpu_env, fp32);
7590 tcg_temp_free_i32(fp32);
7591 gen_store_fpr64(ctx, fp64, fd);
7592 tcg_temp_free_i64(fp64);
7597 check_cp1_64bitmode(ctx);
7599 TCGv_i32 fp32 = tcg_temp_new_i32();
7600 TCGv_i64 fp64 = tcg_temp_new_i64();
7602 gen_load_fpr32(fp32, fs);
7603 gen_helper_float_ceill_s(fp64, cpu_env, fp32);
7604 tcg_temp_free_i32(fp32);
7605 gen_store_fpr64(ctx, fp64, fd);
7606 tcg_temp_free_i64(fp64);
7611 check_cp1_64bitmode(ctx);
7613 TCGv_i32 fp32 = tcg_temp_new_i32();
7614 TCGv_i64 fp64 = tcg_temp_new_i64();
7616 gen_load_fpr32(fp32, fs);
7617 gen_helper_float_floorl_s(fp64, cpu_env, fp32);
7618 tcg_temp_free_i32(fp32);
7619 gen_store_fpr64(ctx, fp64, fd);
7620 tcg_temp_free_i64(fp64);
7626 TCGv_i32 fp0 = tcg_temp_new_i32();
7628 gen_load_fpr32(fp0, fs);
7629 gen_helper_float_roundw_s(fp0, cpu_env, fp0);
7630 gen_store_fpr32(fp0, fd);
7631 tcg_temp_free_i32(fp0);
7637 TCGv_i32 fp0 = tcg_temp_new_i32();
7639 gen_load_fpr32(fp0, fs);
7640 gen_helper_float_truncw_s(fp0, cpu_env, fp0);
7641 gen_store_fpr32(fp0, fd);
7642 tcg_temp_free_i32(fp0);
7648 TCGv_i32 fp0 = tcg_temp_new_i32();
7650 gen_load_fpr32(fp0, fs);
7651 gen_helper_float_ceilw_s(fp0, cpu_env, fp0);
7652 gen_store_fpr32(fp0, fd);
7653 tcg_temp_free_i32(fp0);
7659 TCGv_i32 fp0 = tcg_temp_new_i32();
7661 gen_load_fpr32(fp0, fs);
7662 gen_helper_float_floorw_s(fp0, cpu_env, fp0);
7663 gen_store_fpr32(fp0, fd);
7664 tcg_temp_free_i32(fp0);
7669 gen_movcf_s(fs, fd, (ft >> 2) & 0x7, ft & 0x1);
7674 int l1 = gen_new_label();
7678 tcg_gen_brcondi_tl(TCG_COND_NE, cpu_gpr[ft], 0, l1);
7680 fp0 = tcg_temp_new_i32();
7681 gen_load_fpr32(fp0, fs);
7682 gen_store_fpr32(fp0, fd);
7683 tcg_temp_free_i32(fp0);
7690 int l1 = gen_new_label();
7694 tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_gpr[ft], 0, l1);
7695 fp0 = tcg_temp_new_i32();
7696 gen_load_fpr32(fp0, fs);
7697 gen_store_fpr32(fp0, fd);
7698 tcg_temp_free_i32(fp0);
7707 TCGv_i32 fp0 = tcg_temp_new_i32();
7709 gen_load_fpr32(fp0, fs);
7710 gen_helper_float_recip_s(fp0, cpu_env, fp0);
7711 gen_store_fpr32(fp0, fd);
7712 tcg_temp_free_i32(fp0);
7719 TCGv_i32 fp0 = tcg_temp_new_i32();
7721 gen_load_fpr32(fp0, fs);
7722 gen_helper_float_rsqrt_s(fp0, cpu_env, fp0);
7723 gen_store_fpr32(fp0, fd);
7724 tcg_temp_free_i32(fp0);
7729 check_cp1_64bitmode(ctx);
7731 TCGv_i32 fp0 = tcg_temp_new_i32();
7732 TCGv_i32 fp1 = tcg_temp_new_i32();
7734 gen_load_fpr32(fp0, fs);
7735 gen_load_fpr32(fp1, ft);
7736 gen_helper_float_recip2_s(fp0, cpu_env, fp0, fp1);
7737 tcg_temp_free_i32(fp1);
7738 gen_store_fpr32(fp0, fd);
7739 tcg_temp_free_i32(fp0);
7744 check_cp1_64bitmode(ctx);
7746 TCGv_i32 fp0 = tcg_temp_new_i32();
7748 gen_load_fpr32(fp0, fs);
7749 gen_helper_float_recip1_s(fp0, cpu_env, fp0);
7750 gen_store_fpr32(fp0, fd);
7751 tcg_temp_free_i32(fp0);
7756 check_cp1_64bitmode(ctx);
7758 TCGv_i32 fp0 = tcg_temp_new_i32();
7760 gen_load_fpr32(fp0, fs);
7761 gen_helper_float_rsqrt1_s(fp0, cpu_env, fp0);
7762 gen_store_fpr32(fp0, fd);
7763 tcg_temp_free_i32(fp0);
7768 check_cp1_64bitmode(ctx);
7770 TCGv_i32 fp0 = tcg_temp_new_i32();
7771 TCGv_i32 fp1 = tcg_temp_new_i32();
7773 gen_load_fpr32(fp0, fs);
7774 gen_load_fpr32(fp1, ft);
7775 gen_helper_float_rsqrt2_s(fp0, cpu_env, fp0, fp1);
7776 tcg_temp_free_i32(fp1);
7777 gen_store_fpr32(fp0, fd);
7778 tcg_temp_free_i32(fp0);
7783 check_cp1_registers(ctx, fd);
7785 TCGv_i32 fp32 = tcg_temp_new_i32();
7786 TCGv_i64 fp64 = tcg_temp_new_i64();
7788 gen_load_fpr32(fp32, fs);
7789 gen_helper_float_cvtd_s(fp64, cpu_env, fp32);
7790 tcg_temp_free_i32(fp32);
7791 gen_store_fpr64(ctx, fp64, fd);
7792 tcg_temp_free_i64(fp64);
7798 TCGv_i32 fp0 = tcg_temp_new_i32();
7800 gen_load_fpr32(fp0, fs);
7801 gen_helper_float_cvtw_s(fp0, cpu_env, fp0);
7802 gen_store_fpr32(fp0, fd);
7803 tcg_temp_free_i32(fp0);
7808 check_cp1_64bitmode(ctx);
7810 TCGv_i32 fp32 = tcg_temp_new_i32();
7811 TCGv_i64 fp64 = tcg_temp_new_i64();
7813 gen_load_fpr32(fp32, fs);
7814 gen_helper_float_cvtl_s(fp64, cpu_env, fp32);
7815 tcg_temp_free_i32(fp32);
7816 gen_store_fpr64(ctx, fp64, fd);
7817 tcg_temp_free_i64(fp64);
7822 check_cp1_64bitmode(ctx);
7824 TCGv_i64 fp64 = tcg_temp_new_i64();
7825 TCGv_i32 fp32_0 = tcg_temp_new_i32();
7826 TCGv_i32 fp32_1 = tcg_temp_new_i32();
7828 gen_load_fpr32(fp32_0, fs);
7829 gen_load_fpr32(fp32_1, ft);
7830 tcg_gen_concat_i32_i64(fp64, fp32_1, fp32_0);
7831 tcg_temp_free_i32(fp32_1);
7832 tcg_temp_free_i32(fp32_0);
7833 gen_store_fpr64(ctx, fp64, fd);
7834 tcg_temp_free_i64(fp64);
7847 case OPC_CMP_NGLE_S:
7854 if (ctx->opcode & (1 << 6)) {
7855 gen_cmpabs_s(ctx, func-48, ft, fs, cc);
7856 opn = condnames_abs[func-48];
7858 gen_cmp_s(ctx, func-48, ft, fs, cc);
7859 opn = condnames[func-48];
7863 check_cp1_registers(ctx, fs | ft | fd);
7865 TCGv_i64 fp0 = tcg_temp_new_i64();
7866 TCGv_i64 fp1 = tcg_temp_new_i64();
7868 gen_load_fpr64(ctx, fp0, fs);
7869 gen_load_fpr64(ctx, fp1, ft);
7870 gen_helper_float_add_d(fp0, cpu_env, fp0, fp1);
7871 tcg_temp_free_i64(fp1);
7872 gen_store_fpr64(ctx, fp0, fd);
7873 tcg_temp_free_i64(fp0);
7879 check_cp1_registers(ctx, fs | ft | fd);
7881 TCGv_i64 fp0 = tcg_temp_new_i64();
7882 TCGv_i64 fp1 = tcg_temp_new_i64();
7884 gen_load_fpr64(ctx, fp0, fs);
7885 gen_load_fpr64(ctx, fp1, ft);
7886 gen_helper_float_sub_d(fp0, cpu_env, fp0, fp1);
7887 tcg_temp_free_i64(fp1);
7888 gen_store_fpr64(ctx, fp0, fd);
7889 tcg_temp_free_i64(fp0);
7895 check_cp1_registers(ctx, fs | ft | fd);
7897 TCGv_i64 fp0 = tcg_temp_new_i64();
7898 TCGv_i64 fp1 = tcg_temp_new_i64();
7900 gen_load_fpr64(ctx, fp0, fs);
7901 gen_load_fpr64(ctx, fp1, ft);
7902 gen_helper_float_mul_d(fp0, cpu_env, fp0, fp1);
7903 tcg_temp_free_i64(fp1);
7904 gen_store_fpr64(ctx, fp0, fd);
7905 tcg_temp_free_i64(fp0);
7911 check_cp1_registers(ctx, fs | ft | fd);
7913 TCGv_i64 fp0 = tcg_temp_new_i64();
7914 TCGv_i64 fp1 = tcg_temp_new_i64();
7916 gen_load_fpr64(ctx, fp0, fs);
7917 gen_load_fpr64(ctx, fp1, ft);
7918 gen_helper_float_div_d(fp0, cpu_env, fp0, fp1);
7919 tcg_temp_free_i64(fp1);
7920 gen_store_fpr64(ctx, fp0, fd);
7921 tcg_temp_free_i64(fp0);
7927 check_cp1_registers(ctx, fs | fd);
7929 TCGv_i64 fp0 = tcg_temp_new_i64();
7931 gen_load_fpr64(ctx, fp0, fs);
7932 gen_helper_float_sqrt_d(fp0, cpu_env, fp0);
7933 gen_store_fpr64(ctx, fp0, fd);
7934 tcg_temp_free_i64(fp0);
7939 check_cp1_registers(ctx, fs | fd);
7941 TCGv_i64 fp0 = tcg_temp_new_i64();
7943 gen_load_fpr64(ctx, fp0, fs);
7944 gen_helper_float_abs_d(fp0, fp0);
7945 gen_store_fpr64(ctx, fp0, fd);
7946 tcg_temp_free_i64(fp0);
7951 check_cp1_registers(ctx, fs | fd);
7953 TCGv_i64 fp0 = tcg_temp_new_i64();
7955 gen_load_fpr64(ctx, fp0, fs);
7956 gen_store_fpr64(ctx, fp0, fd);
7957 tcg_temp_free_i64(fp0);
7962 check_cp1_registers(ctx, fs | fd);
7964 TCGv_i64 fp0 = tcg_temp_new_i64();
7966 gen_load_fpr64(ctx, fp0, fs);
7967 gen_helper_float_chs_d(fp0, fp0);
7968 gen_store_fpr64(ctx, fp0, fd);
7969 tcg_temp_free_i64(fp0);
7974 check_cp1_64bitmode(ctx);
7976 TCGv_i64 fp0 = tcg_temp_new_i64();
7978 gen_load_fpr64(ctx, fp0, fs);
7979 gen_helper_float_roundl_d(fp0, cpu_env, fp0);
7980 gen_store_fpr64(ctx, fp0, fd);
7981 tcg_temp_free_i64(fp0);
7986 check_cp1_64bitmode(ctx);
7988 TCGv_i64 fp0 = tcg_temp_new_i64();
7990 gen_load_fpr64(ctx, fp0, fs);
7991 gen_helper_float_truncl_d(fp0, cpu_env, fp0);
7992 gen_store_fpr64(ctx, fp0, fd);
7993 tcg_temp_free_i64(fp0);
7998 check_cp1_64bitmode(ctx);
8000 TCGv_i64 fp0 = tcg_temp_new_i64();
8002 gen_load_fpr64(ctx, fp0, fs);
8003 gen_helper_float_ceill_d(fp0, cpu_env, fp0);
8004 gen_store_fpr64(ctx, fp0, fd);
8005 tcg_temp_free_i64(fp0);
8010 check_cp1_64bitmode(ctx);
8012 TCGv_i64 fp0 = tcg_temp_new_i64();
8014 gen_load_fpr64(ctx, fp0, fs);
8015 gen_helper_float_floorl_d(fp0, cpu_env, fp0);
8016 gen_store_fpr64(ctx, fp0, fd);
8017 tcg_temp_free_i64(fp0);
8022 check_cp1_registers(ctx, fs);
8024 TCGv_i32 fp32 = tcg_temp_new_i32();
8025 TCGv_i64 fp64 = tcg_temp_new_i64();
8027 gen_load_fpr64(ctx, fp64, fs);
8028 gen_helper_float_roundw_d(fp32, cpu_env, fp64);
8029 tcg_temp_free_i64(fp64);
8030 gen_store_fpr32(fp32, fd);
8031 tcg_temp_free_i32(fp32);
8036 check_cp1_registers(ctx, fs);
8038 TCGv_i32 fp32 = tcg_temp_new_i32();
8039 TCGv_i64 fp64 = tcg_temp_new_i64();
8041 gen_load_fpr64(ctx, fp64, fs);
8042 gen_helper_float_truncw_d(fp32, cpu_env, fp64);
8043 tcg_temp_free_i64(fp64);
8044 gen_store_fpr32(fp32, fd);
8045 tcg_temp_free_i32(fp32);
8050 check_cp1_registers(ctx, fs);
8052 TCGv_i32 fp32 = tcg_temp_new_i32();
8053 TCGv_i64 fp64 = tcg_temp_new_i64();
8055 gen_load_fpr64(ctx, fp64, fs);
8056 gen_helper_float_ceilw_d(fp32, cpu_env, fp64);
8057 tcg_temp_free_i64(fp64);
8058 gen_store_fpr32(fp32, fd);
8059 tcg_temp_free_i32(fp32);
8064 check_cp1_registers(ctx, fs);
8066 TCGv_i32 fp32 = tcg_temp_new_i32();
8067 TCGv_i64 fp64 = tcg_temp_new_i64();
8069 gen_load_fpr64(ctx, fp64, fs);
8070 gen_helper_float_floorw_d(fp32, cpu_env, fp64);
8071 tcg_temp_free_i64(fp64);
8072 gen_store_fpr32(fp32, fd);
8073 tcg_temp_free_i32(fp32);
8078 gen_movcf_d(ctx, fs, fd, (ft >> 2) & 0x7, ft & 0x1);
8083 int l1 = gen_new_label();
8087 tcg_gen_brcondi_tl(TCG_COND_NE, cpu_gpr[ft], 0, l1);
8089 fp0 = tcg_temp_new_i64();
8090 gen_load_fpr64(ctx, fp0, fs);
8091 gen_store_fpr64(ctx, fp0, fd);
8092 tcg_temp_free_i64(fp0);
8099 int l1 = gen_new_label();
8103 tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_gpr[ft], 0, l1);
8104 fp0 = tcg_temp_new_i64();
8105 gen_load_fpr64(ctx, fp0, fs);
8106 gen_store_fpr64(ctx, fp0, fd);
8107 tcg_temp_free_i64(fp0);
8114 check_cp1_64bitmode(ctx);
8116 TCGv_i64 fp0 = tcg_temp_new_i64();
8118 gen_load_fpr64(ctx, fp0, fs);
8119 gen_helper_float_recip_d(fp0, cpu_env, fp0);
8120 gen_store_fpr64(ctx, fp0, fd);
8121 tcg_temp_free_i64(fp0);
8126 check_cp1_64bitmode(ctx);
8128 TCGv_i64 fp0 = tcg_temp_new_i64();
8130 gen_load_fpr64(ctx, fp0, fs);
8131 gen_helper_float_rsqrt_d(fp0, cpu_env, fp0);
8132 gen_store_fpr64(ctx, fp0, fd);
8133 tcg_temp_free_i64(fp0);
8138 check_cp1_64bitmode(ctx);
8140 TCGv_i64 fp0 = tcg_temp_new_i64();
8141 TCGv_i64 fp1 = tcg_temp_new_i64();
8143 gen_load_fpr64(ctx, fp0, fs);
8144 gen_load_fpr64(ctx, fp1, ft);
8145 gen_helper_float_recip2_d(fp0, cpu_env, fp0, fp1);
8146 tcg_temp_free_i64(fp1);
8147 gen_store_fpr64(ctx, fp0, fd);
8148 tcg_temp_free_i64(fp0);
8153 check_cp1_64bitmode(ctx);
8155 TCGv_i64 fp0 = tcg_temp_new_i64();
8157 gen_load_fpr64(ctx, fp0, fs);
8158 gen_helper_float_recip1_d(fp0, cpu_env, fp0);
8159 gen_store_fpr64(ctx, fp0, fd);
8160 tcg_temp_free_i64(fp0);
8165 check_cp1_64bitmode(ctx);
8167 TCGv_i64 fp0 = tcg_temp_new_i64();
8169 gen_load_fpr64(ctx, fp0, fs);
8170 gen_helper_float_rsqrt1_d(fp0, cpu_env, fp0);
8171 gen_store_fpr64(ctx, fp0, fd);
8172 tcg_temp_free_i64(fp0);
8177 check_cp1_64bitmode(ctx);
8179 TCGv_i64 fp0 = tcg_temp_new_i64();
8180 TCGv_i64 fp1 = tcg_temp_new_i64();
8182 gen_load_fpr64(ctx, fp0, fs);
8183 gen_load_fpr64(ctx, fp1, ft);
8184 gen_helper_float_rsqrt2_d(fp0, cpu_env, fp0, fp1);
8185 tcg_temp_free_i64(fp1);
8186 gen_store_fpr64(ctx, fp0, fd);
8187 tcg_temp_free_i64(fp0);
8200 case OPC_CMP_NGLE_D:
8207 if (ctx->opcode & (1 << 6)) {
8208 gen_cmpabs_d(ctx, func-48, ft, fs, cc);
8209 opn = condnames_abs[func-48];
8211 gen_cmp_d(ctx, func-48, ft, fs, cc);
8212 opn = condnames[func-48];
8216 check_cp1_registers(ctx, fs);
8218 TCGv_i32 fp32 = tcg_temp_new_i32();
8219 TCGv_i64 fp64 = tcg_temp_new_i64();
8221 gen_load_fpr64(ctx, fp64, fs);
8222 gen_helper_float_cvts_d(fp32, cpu_env, fp64);
8223 tcg_temp_free_i64(fp64);
8224 gen_store_fpr32(fp32, fd);
8225 tcg_temp_free_i32(fp32);
8230 check_cp1_registers(ctx, fs);
8232 TCGv_i32 fp32 = tcg_temp_new_i32();
8233 TCGv_i64 fp64 = tcg_temp_new_i64();
8235 gen_load_fpr64(ctx, fp64, fs);
8236 gen_helper_float_cvtw_d(fp32, cpu_env, fp64);
8237 tcg_temp_free_i64(fp64);
8238 gen_store_fpr32(fp32, fd);
8239 tcg_temp_free_i32(fp32);
8244 check_cp1_64bitmode(ctx);
8246 TCGv_i64 fp0 = tcg_temp_new_i64();
8248 gen_load_fpr64(ctx, fp0, fs);
8249 gen_helper_float_cvtl_d(fp0, cpu_env, fp0);
8250 gen_store_fpr64(ctx, fp0, fd);
8251 tcg_temp_free_i64(fp0);
8257 TCGv_i32 fp0 = tcg_temp_new_i32();
8259 gen_load_fpr32(fp0, fs);
8260 gen_helper_float_cvts_w(fp0, cpu_env, fp0);
8261 gen_store_fpr32(fp0, fd);
8262 tcg_temp_free_i32(fp0);
8267 check_cp1_registers(ctx, fd);
8269 TCGv_i32 fp32 = tcg_temp_new_i32();
8270 TCGv_i64 fp64 = tcg_temp_new_i64();
8272 gen_load_fpr32(fp32, fs);
8273 gen_helper_float_cvtd_w(fp64, cpu_env, fp32);
8274 tcg_temp_free_i32(fp32);
8275 gen_store_fpr64(ctx, fp64, fd);
8276 tcg_temp_free_i64(fp64);
8281 check_cp1_64bitmode(ctx);
8283 TCGv_i32 fp32 = tcg_temp_new_i32();
8284 TCGv_i64 fp64 = tcg_temp_new_i64();
8286 gen_load_fpr64(ctx, fp64, fs);
8287 gen_helper_float_cvts_l(fp32, cpu_env, fp64);
8288 tcg_temp_free_i64(fp64);
8289 gen_store_fpr32(fp32, fd);
8290 tcg_temp_free_i32(fp32);
8295 check_cp1_64bitmode(ctx);
8297 TCGv_i64 fp0 = tcg_temp_new_i64();
8299 gen_load_fpr64(ctx, fp0, fs);
8300 gen_helper_float_cvtd_l(fp0, cpu_env, fp0);
8301 gen_store_fpr64(ctx, fp0, fd);
8302 tcg_temp_free_i64(fp0);
8307 check_cp1_64bitmode(ctx);
8309 TCGv_i64 fp0 = tcg_temp_new_i64();
8311 gen_load_fpr64(ctx, fp0, fs);
8312 gen_helper_float_cvtps_pw(fp0, cpu_env, fp0);
8313 gen_store_fpr64(ctx, fp0, fd);
8314 tcg_temp_free_i64(fp0);
8319 check_cp1_64bitmode(ctx);
8321 TCGv_i64 fp0 = tcg_temp_new_i64();
8322 TCGv_i64 fp1 = tcg_temp_new_i64();
8324 gen_load_fpr64(ctx, fp0, fs);
8325 gen_load_fpr64(ctx, fp1, ft);
8326 gen_helper_float_add_ps(fp0, cpu_env, fp0, fp1);
8327 tcg_temp_free_i64(fp1);
8328 gen_store_fpr64(ctx, fp0, fd);
8329 tcg_temp_free_i64(fp0);
8334 check_cp1_64bitmode(ctx);
8336 TCGv_i64 fp0 = tcg_temp_new_i64();
8337 TCGv_i64 fp1 = tcg_temp_new_i64();
8339 gen_load_fpr64(ctx, fp0, fs);
8340 gen_load_fpr64(ctx, fp1, ft);
8341 gen_helper_float_sub_ps(fp0, cpu_env, fp0, fp1);
8342 tcg_temp_free_i64(fp1);
8343 gen_store_fpr64(ctx, fp0, fd);
8344 tcg_temp_free_i64(fp0);
8349 check_cp1_64bitmode(ctx);
8351 TCGv_i64 fp0 = tcg_temp_new_i64();
8352 TCGv_i64 fp1 = tcg_temp_new_i64();
8354 gen_load_fpr64(ctx, fp0, fs);
8355 gen_load_fpr64(ctx, fp1, ft);
8356 gen_helper_float_mul_ps(fp0, cpu_env, fp0, fp1);
8357 tcg_temp_free_i64(fp1);
8358 gen_store_fpr64(ctx, fp0, fd);
8359 tcg_temp_free_i64(fp0);
8364 check_cp1_64bitmode(ctx);
8366 TCGv_i64 fp0 = tcg_temp_new_i64();
8368 gen_load_fpr64(ctx, fp0, fs);
8369 gen_helper_float_abs_ps(fp0, fp0);
8370 gen_store_fpr64(ctx, fp0, fd);
8371 tcg_temp_free_i64(fp0);
8376 check_cp1_64bitmode(ctx);
8378 TCGv_i64 fp0 = tcg_temp_new_i64();
8380 gen_load_fpr64(ctx, fp0, fs);
8381 gen_store_fpr64(ctx, fp0, fd);
8382 tcg_temp_free_i64(fp0);
8387 check_cp1_64bitmode(ctx);
8389 TCGv_i64 fp0 = tcg_temp_new_i64();
8391 gen_load_fpr64(ctx, fp0, fs);
8392 gen_helper_float_chs_ps(fp0, fp0);
8393 gen_store_fpr64(ctx, fp0, fd);
8394 tcg_temp_free_i64(fp0);
8399 check_cp1_64bitmode(ctx);
8400 gen_movcf_ps(fs, fd, (ft >> 2) & 0x7, ft & 0x1);
8404 check_cp1_64bitmode(ctx);
8406 int l1 = gen_new_label();
8410 tcg_gen_brcondi_tl(TCG_COND_NE, cpu_gpr[ft], 0, l1);
8411 fp0 = tcg_temp_new_i64();
8412 gen_load_fpr64(ctx, fp0, fs);
8413 gen_store_fpr64(ctx, fp0, fd);
8414 tcg_temp_free_i64(fp0);
8420 check_cp1_64bitmode(ctx);
8422 int l1 = gen_new_label();
8426 tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_gpr[ft], 0, l1);
8427 fp0 = tcg_temp_new_i64();
8428 gen_load_fpr64(ctx, fp0, fs);
8429 gen_store_fpr64(ctx, fp0, fd);
8430 tcg_temp_free_i64(fp0);
8437 check_cp1_64bitmode(ctx);
8439 TCGv_i64 fp0 = tcg_temp_new_i64();
8440 TCGv_i64 fp1 = tcg_temp_new_i64();
8442 gen_load_fpr64(ctx, fp0, ft);
8443 gen_load_fpr64(ctx, fp1, fs);
8444 gen_helper_float_addr_ps(fp0, cpu_env, fp0, fp1);
8445 tcg_temp_free_i64(fp1);
8446 gen_store_fpr64(ctx, fp0, fd);
8447 tcg_temp_free_i64(fp0);
8452 check_cp1_64bitmode(ctx);
8454 TCGv_i64 fp0 = tcg_temp_new_i64();
8455 TCGv_i64 fp1 = tcg_temp_new_i64();
8457 gen_load_fpr64(ctx, fp0, ft);
8458 gen_load_fpr64(ctx, fp1, fs);
8459 gen_helper_float_mulr_ps(fp0, cpu_env, fp0, fp1);
8460 tcg_temp_free_i64(fp1);
8461 gen_store_fpr64(ctx, fp0, fd);
8462 tcg_temp_free_i64(fp0);
8467 check_cp1_64bitmode(ctx);
8469 TCGv_i64 fp0 = tcg_temp_new_i64();
8470 TCGv_i64 fp1 = tcg_temp_new_i64();
8472 gen_load_fpr64(ctx, fp0, fs);
8473 gen_load_fpr64(ctx, fp1, ft);
8474 gen_helper_float_recip2_ps(fp0, cpu_env, fp0, fp1);
8475 tcg_temp_free_i64(fp1);
8476 gen_store_fpr64(ctx, fp0, fd);
8477 tcg_temp_free_i64(fp0);
8482 check_cp1_64bitmode(ctx);
8484 TCGv_i64 fp0 = tcg_temp_new_i64();
8486 gen_load_fpr64(ctx, fp0, fs);
8487 gen_helper_float_recip1_ps(fp0, cpu_env, fp0);
8488 gen_store_fpr64(ctx, fp0, fd);
8489 tcg_temp_free_i64(fp0);
8494 check_cp1_64bitmode(ctx);
8496 TCGv_i64 fp0 = tcg_temp_new_i64();
8498 gen_load_fpr64(ctx, fp0, fs);
8499 gen_helper_float_rsqrt1_ps(fp0, cpu_env, fp0);
8500 gen_store_fpr64(ctx, fp0, fd);
8501 tcg_temp_free_i64(fp0);
8506 check_cp1_64bitmode(ctx);
8508 TCGv_i64 fp0 = tcg_temp_new_i64();
8509 TCGv_i64 fp1 = tcg_temp_new_i64();
8511 gen_load_fpr64(ctx, fp0, fs);
8512 gen_load_fpr64(ctx, fp1, ft);
8513 gen_helper_float_rsqrt2_ps(fp0, cpu_env, fp0, fp1);
8514 tcg_temp_free_i64(fp1);
8515 gen_store_fpr64(ctx, fp0, fd);
8516 tcg_temp_free_i64(fp0);
8521 check_cp1_64bitmode(ctx);
8523 TCGv_i32 fp0 = tcg_temp_new_i32();
8525 gen_load_fpr32h(fp0, fs);
8526 gen_helper_float_cvts_pu(fp0, cpu_env, fp0);
8527 gen_store_fpr32(fp0, fd);
8528 tcg_temp_free_i32(fp0);
8533 check_cp1_64bitmode(ctx);
8535 TCGv_i64 fp0 = tcg_temp_new_i64();
8537 gen_load_fpr64(ctx, fp0, fs);
8538 gen_helper_float_cvtpw_ps(fp0, cpu_env, fp0);
8539 gen_store_fpr64(ctx, fp0, fd);
8540 tcg_temp_free_i64(fp0);
8545 check_cp1_64bitmode(ctx);
8547 TCGv_i32 fp0 = tcg_temp_new_i32();
8549 gen_load_fpr32(fp0, fs);
8550 gen_helper_float_cvts_pl(fp0, cpu_env, fp0);
8551 gen_store_fpr32(fp0, fd);
8552 tcg_temp_free_i32(fp0);
8557 check_cp1_64bitmode(ctx);
8559 TCGv_i32 fp0 = tcg_temp_new_i32();
8560 TCGv_i32 fp1 = tcg_temp_new_i32();
8562 gen_load_fpr32(fp0, fs);
8563 gen_load_fpr32(fp1, ft);
8564 gen_store_fpr32h(fp0, fd);
8565 gen_store_fpr32(fp1, fd);
8566 tcg_temp_free_i32(fp0);
8567 tcg_temp_free_i32(fp1);
8572 check_cp1_64bitmode(ctx);
8574 TCGv_i32 fp0 = tcg_temp_new_i32();
8575 TCGv_i32 fp1 = tcg_temp_new_i32();
8577 gen_load_fpr32(fp0, fs);
8578 gen_load_fpr32h(fp1, ft);
8579 gen_store_fpr32(fp1, fd);
8580 gen_store_fpr32h(fp0, fd);
8581 tcg_temp_free_i32(fp0);
8582 tcg_temp_free_i32(fp1);
8587 check_cp1_64bitmode(ctx);
8589 TCGv_i32 fp0 = tcg_temp_new_i32();
8590 TCGv_i32 fp1 = tcg_temp_new_i32();
8592 gen_load_fpr32h(fp0, fs);
8593 gen_load_fpr32(fp1, ft);
8594 gen_store_fpr32(fp1, fd);
8595 gen_store_fpr32h(fp0, fd);
8596 tcg_temp_free_i32(fp0);
8597 tcg_temp_free_i32(fp1);
8602 check_cp1_64bitmode(ctx);
8604 TCGv_i32 fp0 = tcg_temp_new_i32();
8605 TCGv_i32 fp1 = tcg_temp_new_i32();
8607 gen_load_fpr32h(fp0, fs);
8608 gen_load_fpr32h(fp1, ft);
8609 gen_store_fpr32(fp1, fd);
8610 gen_store_fpr32h(fp0, fd);
8611 tcg_temp_free_i32(fp0);
8612 tcg_temp_free_i32(fp1);
8619 case OPC_CMP_UEQ_PS:
8620 case OPC_CMP_OLT_PS:
8621 case OPC_CMP_ULT_PS:
8622 case OPC_CMP_OLE_PS:
8623 case OPC_CMP_ULE_PS:
8625 case OPC_CMP_NGLE_PS:
8626 case OPC_CMP_SEQ_PS:
8627 case OPC_CMP_NGL_PS:
8629 case OPC_CMP_NGE_PS:
8631 case OPC_CMP_NGT_PS:
8632 if (ctx->opcode & (1 << 6)) {
8633 gen_cmpabs_ps(ctx, func-48, ft, fs, cc);
8634 opn = condnames_abs[func-48];
8636 gen_cmp_ps(ctx, func-48, ft, fs, cc);
8637 opn = condnames[func-48];
8642 generate_exception (ctx, EXCP_RI);
8645 (void)opn; /* avoid a compiler warning */
8648 MIPS_DEBUG("%s %s, %s, %s", opn, fregnames[fd], fregnames[fs], fregnames[ft]);
8651 MIPS_DEBUG("%s %s,%s", opn, fregnames[fs], fregnames[ft]);
8654 MIPS_DEBUG("%s %s,%s", opn, fregnames[fd], fregnames[fs]);
8659 /* Coprocessor 3 (FPU) */
8660 static void gen_flt3_ldst (DisasContext *ctx, uint32_t opc,
8661 int fd, int fs, int base, int index)
8663 const char *opn = "extended float load/store";
8665 TCGv t0 = tcg_temp_new();
8668 gen_load_gpr(t0, index);
8669 } else if (index == 0) {
8670 gen_load_gpr(t0, base);
8672 gen_op_addr_add(ctx, t0, cpu_gpr[base], cpu_gpr[index]);
8674 /* Don't do NOP if destination is zero: we must perform the actual
8680 TCGv_i32 fp0 = tcg_temp_new_i32();
8682 tcg_gen_qemu_ld32s(t0, t0, ctx->mem_idx);
8683 tcg_gen_trunc_tl_i32(fp0, t0);
8684 gen_store_fpr32(fp0, fd);
8685 tcg_temp_free_i32(fp0);
8691 check_cp1_registers(ctx, fd);
8693 TCGv_i64 fp0 = tcg_temp_new_i64();
8695 tcg_gen_qemu_ld64(fp0, t0, ctx->mem_idx);
8696 gen_store_fpr64(ctx, fp0, fd);
8697 tcg_temp_free_i64(fp0);
8702 check_cp1_64bitmode(ctx);
8703 tcg_gen_andi_tl(t0, t0, ~0x7);
8705 TCGv_i64 fp0 = tcg_temp_new_i64();
8707 tcg_gen_qemu_ld64(fp0, t0, ctx->mem_idx);
8708 gen_store_fpr64(ctx, fp0, fd);
8709 tcg_temp_free_i64(fp0);
8716 TCGv_i32 fp0 = tcg_temp_new_i32();
8717 TCGv t1 = tcg_temp_new();
8719 gen_load_fpr32(fp0, fs);
8720 tcg_gen_extu_i32_tl(t1, fp0);
8721 tcg_gen_qemu_st32(t1, t0, ctx->mem_idx);
8722 tcg_temp_free_i32(fp0);
8730 check_cp1_registers(ctx, fs);
8732 TCGv_i64 fp0 = tcg_temp_new_i64();
8734 gen_load_fpr64(ctx, fp0, fs);
8735 tcg_gen_qemu_st64(fp0, t0, ctx->mem_idx);
8736 tcg_temp_free_i64(fp0);
8742 check_cp1_64bitmode(ctx);
8743 tcg_gen_andi_tl(t0, t0, ~0x7);
8745 TCGv_i64 fp0 = tcg_temp_new_i64();
8747 gen_load_fpr64(ctx, fp0, fs);
8748 tcg_gen_qemu_st64(fp0, t0, ctx->mem_idx);
8749 tcg_temp_free_i64(fp0);
8756 (void)opn; (void)store; /* avoid compiler warnings */
8757 MIPS_DEBUG("%s %s, %s(%s)", opn, fregnames[store ? fs : fd],
8758 regnames[index], regnames[base]);
8761 static void gen_flt3_arith (DisasContext *ctx, uint32_t opc,
8762 int fd, int fr, int fs, int ft)
8764 const char *opn = "flt3_arith";
8768 check_cp1_64bitmode(ctx);
8770 TCGv t0 = tcg_temp_local_new();
8771 TCGv_i32 fp = tcg_temp_new_i32();
8772 TCGv_i32 fph = tcg_temp_new_i32();
8773 int l1 = gen_new_label();
8774 int l2 = gen_new_label();
8776 gen_load_gpr(t0, fr);
8777 tcg_gen_andi_tl(t0, t0, 0x7);
8779 tcg_gen_brcondi_tl(TCG_COND_NE, t0, 0, l1);
8780 gen_load_fpr32(fp, fs);
8781 gen_load_fpr32h(fph, fs);
8782 gen_store_fpr32(fp, fd);
8783 gen_store_fpr32h(fph, fd);
8786 tcg_gen_brcondi_tl(TCG_COND_NE, t0, 4, l2);
8788 #ifdef TARGET_WORDS_BIGENDIAN
8789 gen_load_fpr32(fp, fs);
8790 gen_load_fpr32h(fph, ft);
8791 gen_store_fpr32h(fp, fd);
8792 gen_store_fpr32(fph, fd);
8794 gen_load_fpr32h(fph, fs);
8795 gen_load_fpr32(fp, ft);
8796 gen_store_fpr32(fph, fd);
8797 gen_store_fpr32h(fp, fd);
8800 tcg_temp_free_i32(fp);
8801 tcg_temp_free_i32(fph);
8808 TCGv_i32 fp0 = tcg_temp_new_i32();
8809 TCGv_i32 fp1 = tcg_temp_new_i32();
8810 TCGv_i32 fp2 = tcg_temp_new_i32();
8812 gen_load_fpr32(fp0, fs);
8813 gen_load_fpr32(fp1, ft);
8814 gen_load_fpr32(fp2, fr);
8815 gen_helper_float_madd_s(fp2, cpu_env, fp0, fp1, fp2);
8816 tcg_temp_free_i32(fp0);
8817 tcg_temp_free_i32(fp1);
8818 gen_store_fpr32(fp2, fd);
8819 tcg_temp_free_i32(fp2);
8825 check_cp1_registers(ctx, fd | fs | ft | fr);
8827 TCGv_i64 fp0 = tcg_temp_new_i64();
8828 TCGv_i64 fp1 = tcg_temp_new_i64();
8829 TCGv_i64 fp2 = tcg_temp_new_i64();
8831 gen_load_fpr64(ctx, fp0, fs);
8832 gen_load_fpr64(ctx, fp1, ft);
8833 gen_load_fpr64(ctx, fp2, fr);
8834 gen_helper_float_madd_d(fp2, cpu_env, fp0, fp1, fp2);
8835 tcg_temp_free_i64(fp0);
8836 tcg_temp_free_i64(fp1);
8837 gen_store_fpr64(ctx, fp2, fd);
8838 tcg_temp_free_i64(fp2);
8843 check_cp1_64bitmode(ctx);
8845 TCGv_i64 fp0 = tcg_temp_new_i64();
8846 TCGv_i64 fp1 = tcg_temp_new_i64();
8847 TCGv_i64 fp2 = tcg_temp_new_i64();
8849 gen_load_fpr64(ctx, fp0, fs);
8850 gen_load_fpr64(ctx, fp1, ft);
8851 gen_load_fpr64(ctx, fp2, fr);
8852 gen_helper_float_madd_ps(fp2, cpu_env, fp0, fp1, fp2);
8853 tcg_temp_free_i64(fp0);
8854 tcg_temp_free_i64(fp1);
8855 gen_store_fpr64(ctx, fp2, fd);
8856 tcg_temp_free_i64(fp2);
8863 TCGv_i32 fp0 = tcg_temp_new_i32();
8864 TCGv_i32 fp1 = tcg_temp_new_i32();
8865 TCGv_i32 fp2 = tcg_temp_new_i32();
8867 gen_load_fpr32(fp0, fs);
8868 gen_load_fpr32(fp1, ft);
8869 gen_load_fpr32(fp2, fr);
8870 gen_helper_float_msub_s(fp2, cpu_env, fp0, fp1, fp2);
8871 tcg_temp_free_i32(fp0);
8872 tcg_temp_free_i32(fp1);
8873 gen_store_fpr32(fp2, fd);
8874 tcg_temp_free_i32(fp2);
8880 check_cp1_registers(ctx, fd | fs | ft | fr);
8882 TCGv_i64 fp0 = tcg_temp_new_i64();
8883 TCGv_i64 fp1 = tcg_temp_new_i64();
8884 TCGv_i64 fp2 = tcg_temp_new_i64();
8886 gen_load_fpr64(ctx, fp0, fs);
8887 gen_load_fpr64(ctx, fp1, ft);
8888 gen_load_fpr64(ctx, fp2, fr);
8889 gen_helper_float_msub_d(fp2, cpu_env, fp0, fp1, fp2);
8890 tcg_temp_free_i64(fp0);
8891 tcg_temp_free_i64(fp1);
8892 gen_store_fpr64(ctx, fp2, fd);
8893 tcg_temp_free_i64(fp2);
8898 check_cp1_64bitmode(ctx);
8900 TCGv_i64 fp0 = tcg_temp_new_i64();
8901 TCGv_i64 fp1 = tcg_temp_new_i64();
8902 TCGv_i64 fp2 = tcg_temp_new_i64();
8904 gen_load_fpr64(ctx, fp0, fs);
8905 gen_load_fpr64(ctx, fp1, ft);
8906 gen_load_fpr64(ctx, fp2, fr);
8907 gen_helper_float_msub_ps(fp2, cpu_env, fp0, fp1, fp2);
8908 tcg_temp_free_i64(fp0);
8909 tcg_temp_free_i64(fp1);
8910 gen_store_fpr64(ctx, fp2, fd);
8911 tcg_temp_free_i64(fp2);
8918 TCGv_i32 fp0 = tcg_temp_new_i32();
8919 TCGv_i32 fp1 = tcg_temp_new_i32();
8920 TCGv_i32 fp2 = tcg_temp_new_i32();
8922 gen_load_fpr32(fp0, fs);
8923 gen_load_fpr32(fp1, ft);
8924 gen_load_fpr32(fp2, fr);
8925 gen_helper_float_nmadd_s(fp2, cpu_env, fp0, fp1, fp2);
8926 tcg_temp_free_i32(fp0);
8927 tcg_temp_free_i32(fp1);
8928 gen_store_fpr32(fp2, fd);
8929 tcg_temp_free_i32(fp2);
8935 check_cp1_registers(ctx, fd | fs | ft | fr);
8937 TCGv_i64 fp0 = tcg_temp_new_i64();
8938 TCGv_i64 fp1 = tcg_temp_new_i64();
8939 TCGv_i64 fp2 = tcg_temp_new_i64();
8941 gen_load_fpr64(ctx, fp0, fs);
8942 gen_load_fpr64(ctx, fp1, ft);
8943 gen_load_fpr64(ctx, fp2, fr);
8944 gen_helper_float_nmadd_d(fp2, cpu_env, fp0, fp1, fp2);
8945 tcg_temp_free_i64(fp0);
8946 tcg_temp_free_i64(fp1);
8947 gen_store_fpr64(ctx, fp2, fd);
8948 tcg_temp_free_i64(fp2);
8953 check_cp1_64bitmode(ctx);
8955 TCGv_i64 fp0 = tcg_temp_new_i64();
8956 TCGv_i64 fp1 = tcg_temp_new_i64();
8957 TCGv_i64 fp2 = tcg_temp_new_i64();
8959 gen_load_fpr64(ctx, fp0, fs);
8960 gen_load_fpr64(ctx, fp1, ft);
8961 gen_load_fpr64(ctx, fp2, fr);
8962 gen_helper_float_nmadd_ps(fp2, cpu_env, fp0, fp1, fp2);
8963 tcg_temp_free_i64(fp0);
8964 tcg_temp_free_i64(fp1);
8965 gen_store_fpr64(ctx, fp2, fd);
8966 tcg_temp_free_i64(fp2);
8973 TCGv_i32 fp0 = tcg_temp_new_i32();
8974 TCGv_i32 fp1 = tcg_temp_new_i32();
8975 TCGv_i32 fp2 = tcg_temp_new_i32();
8977 gen_load_fpr32(fp0, fs);
8978 gen_load_fpr32(fp1, ft);
8979 gen_load_fpr32(fp2, fr);
8980 gen_helper_float_nmsub_s(fp2, cpu_env, fp0, fp1, fp2);
8981 tcg_temp_free_i32(fp0);
8982 tcg_temp_free_i32(fp1);
8983 gen_store_fpr32(fp2, fd);
8984 tcg_temp_free_i32(fp2);
8990 check_cp1_registers(ctx, fd | fs | ft | fr);
8992 TCGv_i64 fp0 = tcg_temp_new_i64();
8993 TCGv_i64 fp1 = tcg_temp_new_i64();
8994 TCGv_i64 fp2 = tcg_temp_new_i64();
8996 gen_load_fpr64(ctx, fp0, fs);
8997 gen_load_fpr64(ctx, fp1, ft);
8998 gen_load_fpr64(ctx, fp2, fr);
8999 gen_helper_float_nmsub_d(fp2, cpu_env, fp0, fp1, fp2);
9000 tcg_temp_free_i64(fp0);
9001 tcg_temp_free_i64(fp1);
9002 gen_store_fpr64(ctx, fp2, fd);
9003 tcg_temp_free_i64(fp2);
9008 check_cp1_64bitmode(ctx);
9010 TCGv_i64 fp0 = tcg_temp_new_i64();
9011 TCGv_i64 fp1 = tcg_temp_new_i64();
9012 TCGv_i64 fp2 = tcg_temp_new_i64();
9014 gen_load_fpr64(ctx, fp0, fs);
9015 gen_load_fpr64(ctx, fp1, ft);
9016 gen_load_fpr64(ctx, fp2, fr);
9017 gen_helper_float_nmsub_ps(fp2, cpu_env, fp0, fp1, fp2);
9018 tcg_temp_free_i64(fp0);
9019 tcg_temp_free_i64(fp1);
9020 gen_store_fpr64(ctx, fp2, fd);
9021 tcg_temp_free_i64(fp2);
9027 generate_exception (ctx, EXCP_RI);
9030 (void)opn; /* avoid a compiler warning */
9031 MIPS_DEBUG("%s %s, %s, %s, %s", opn, fregnames[fd], fregnames[fr],
9032 fregnames[fs], fregnames[ft]);
9036 gen_rdhwr (CPUMIPSState *env, DisasContext *ctx, int rt, int rd)
9040 #if !defined(CONFIG_USER_ONLY)
9041 /* The Linux kernel will emulate rdhwr if it's not supported natively.
9042 Therefore only check the ISA in system mode. */
9043 check_insn(env, ctx, ISA_MIPS32R2);
9045 t0 = tcg_temp_new();
9049 save_cpu_state(ctx, 1);
9050 gen_helper_rdhwr_cpunum(t0, cpu_env);
9051 gen_store_gpr(t0, rt);
9054 save_cpu_state(ctx, 1);
9055 gen_helper_rdhwr_synci_step(t0, cpu_env);
9056 gen_store_gpr(t0, rt);
9059 save_cpu_state(ctx, 1);
9060 gen_helper_rdhwr_cc(t0, cpu_env);
9061 gen_store_gpr(t0, rt);
9064 save_cpu_state(ctx, 1);
9065 gen_helper_rdhwr_ccres(t0, cpu_env);
9066 gen_store_gpr(t0, rt);
9069 #if defined(CONFIG_USER_ONLY)
9070 tcg_gen_ld_tl(t0, cpu_env, offsetof(CPUMIPSState, tls_value));
9071 gen_store_gpr(t0, rt);
9074 /* XXX: Some CPUs implement this in hardware.
9075 Not supported yet. */
9077 default: /* Invalid */
9078 MIPS_INVAL("rdhwr");
9079 generate_exception(ctx, EXCP_RI);
9085 static void handle_delay_slot (CPUMIPSState *env, DisasContext *ctx,
9088 if (ctx->hflags & MIPS_HFLAG_BMASK) {
9089 int proc_hflags = ctx->hflags & MIPS_HFLAG_BMASK;
9090 /* Branches completion */
9091 ctx->hflags &= ~MIPS_HFLAG_BMASK;
9092 ctx->bstate = BS_BRANCH;
9093 save_cpu_state(ctx, 0);
9094 /* FIXME: Need to clear can_do_io. */
9095 switch (proc_hflags & MIPS_HFLAG_BMASK_BASE) {
9097 /* unconditional branch */
9098 MIPS_DEBUG("unconditional branch");
9099 if (proc_hflags & MIPS_HFLAG_BX) {
9100 tcg_gen_xori_i32(hflags, hflags, MIPS_HFLAG_M16);
9102 gen_goto_tb(ctx, 0, ctx->btarget);
9105 /* blikely taken case */
9106 MIPS_DEBUG("blikely branch taken");
9107 gen_goto_tb(ctx, 0, ctx->btarget);
9110 /* Conditional branch */
9111 MIPS_DEBUG("conditional branch");
9113 int l1 = gen_new_label();
9115 tcg_gen_brcondi_tl(TCG_COND_NE, bcond, 0, l1);
9116 gen_goto_tb(ctx, 1, ctx->pc + insn_bytes);
9118 gen_goto_tb(ctx, 0, ctx->btarget);
9122 /* unconditional branch to register */
9123 MIPS_DEBUG("branch to register");
9124 if (env->insn_flags & (ASE_MIPS16 | ASE_MICROMIPS)) {
9125 TCGv t0 = tcg_temp_new();
9126 TCGv_i32 t1 = tcg_temp_new_i32();
9128 tcg_gen_andi_tl(t0, btarget, 0x1);
9129 tcg_gen_trunc_tl_i32(t1, t0);
9131 tcg_gen_andi_i32(hflags, hflags, ~(uint32_t)MIPS_HFLAG_M16);
9132 tcg_gen_shli_i32(t1, t1, MIPS_HFLAG_M16_SHIFT);
9133 tcg_gen_or_i32(hflags, hflags, t1);
9134 tcg_temp_free_i32(t1);
9136 tcg_gen_andi_tl(cpu_PC, btarget, ~(target_ulong)0x1);
9138 tcg_gen_mov_tl(cpu_PC, btarget);
9140 if (ctx->singlestep_enabled) {
9141 save_cpu_state(ctx, 0);
9142 gen_helper_0e0i(raise_exception, EXCP_DEBUG);
9147 MIPS_DEBUG("unknown branch");
9153 /* ISA extensions (ASEs) */
9154 /* MIPS16 extension to MIPS32 */
9156 /* MIPS16 major opcodes */
9158 M16_OPC_ADDIUSP = 0x00,
9159 M16_OPC_ADDIUPC = 0x01,
9162 M16_OPC_BEQZ = 0x04,
9163 M16_OPC_BNEQZ = 0x05,
9164 M16_OPC_SHIFT = 0x06,
9166 M16_OPC_RRIA = 0x08,
9167 M16_OPC_ADDIU8 = 0x09,
9168 M16_OPC_SLTI = 0x0a,
9169 M16_OPC_SLTIU = 0x0b,
9172 M16_OPC_CMPI = 0x0e,
9176 M16_OPC_LWSP = 0x12,
9180 M16_OPC_LWPC = 0x16,
9184 M16_OPC_SWSP = 0x1a,
9188 M16_OPC_EXTEND = 0x1e,
9192 /* I8 funct field */
9211 /* RR funct field */
9245 /* I64 funct field */
9257 /* RR ry field for CNVT */
9259 RR_RY_CNVT_ZEB = 0x0,
9260 RR_RY_CNVT_ZEH = 0x1,
9261 RR_RY_CNVT_ZEW = 0x2,
9262 RR_RY_CNVT_SEB = 0x4,
9263 RR_RY_CNVT_SEH = 0x5,
9264 RR_RY_CNVT_SEW = 0x6,
9267 static int xlat (int r)
9269 static int map[] = { 16, 17, 2, 3, 4, 5, 6, 7 };
9274 static void gen_mips16_save (DisasContext *ctx,
9275 int xsregs, int aregs,
9276 int do_ra, int do_s0, int do_s1,
9279 TCGv t0 = tcg_temp_new();
9280 TCGv t1 = tcg_temp_new();
9310 generate_exception(ctx, EXCP_RI);
9316 gen_base_offset_addr(ctx, t0, 29, 12);
9317 gen_load_gpr(t1, 7);
9318 tcg_gen_qemu_st32(t1, t0, ctx->mem_idx);
9321 gen_base_offset_addr(ctx, t0, 29, 8);
9322 gen_load_gpr(t1, 6);
9323 tcg_gen_qemu_st32(t1, t0, ctx->mem_idx);
9326 gen_base_offset_addr(ctx, t0, 29, 4);
9327 gen_load_gpr(t1, 5);
9328 tcg_gen_qemu_st32(t1, t0, ctx->mem_idx);
9331 gen_base_offset_addr(ctx, t0, 29, 0);
9332 gen_load_gpr(t1, 4);
9333 tcg_gen_qemu_st32(t1, t0, ctx->mem_idx);
9336 gen_load_gpr(t0, 29);
9338 #define DECR_AND_STORE(reg) do { \
9339 tcg_gen_subi_tl(t0, t0, 4); \
9340 gen_load_gpr(t1, reg); \
9341 tcg_gen_qemu_st32(t1, t0, ctx->mem_idx); \
9405 generate_exception(ctx, EXCP_RI);
9421 #undef DECR_AND_STORE
9423 tcg_gen_subi_tl(cpu_gpr[29], cpu_gpr[29], framesize);
9428 static void gen_mips16_restore (DisasContext *ctx,
9429 int xsregs, int aregs,
9430 int do_ra, int do_s0, int do_s1,
9434 TCGv t0 = tcg_temp_new();
9435 TCGv t1 = tcg_temp_new();
9437 tcg_gen_addi_tl(t0, cpu_gpr[29], framesize);
9439 #define DECR_AND_LOAD(reg) do { \
9440 tcg_gen_subi_tl(t0, t0, 4); \
9441 tcg_gen_qemu_ld32u(t1, t0, ctx->mem_idx); \
9442 gen_store_gpr(t1, reg); \
9506 generate_exception(ctx, EXCP_RI);
9522 #undef DECR_AND_LOAD
9524 tcg_gen_addi_tl(cpu_gpr[29], cpu_gpr[29], framesize);
9529 static void gen_addiupc (DisasContext *ctx, int rx, int imm,
9530 int is_64_bit, int extended)
9534 if (extended && (ctx->hflags & MIPS_HFLAG_BMASK)) {
9535 generate_exception(ctx, EXCP_RI);
9539 t0 = tcg_temp_new();
9541 tcg_gen_movi_tl(t0, pc_relative_pc(ctx));
9542 tcg_gen_addi_tl(cpu_gpr[rx], t0, imm);
9544 tcg_gen_ext32s_tl(cpu_gpr[rx], cpu_gpr[rx]);
9550 #if defined(TARGET_MIPS64)
9551 static void decode_i64_mips16 (CPUMIPSState *env, DisasContext *ctx,
9552 int ry, int funct, int16_t offset,
9558 offset = extended ? offset : offset << 3;
9559 gen_ld(env, ctx, OPC_LD, ry, 29, offset);
9563 offset = extended ? offset : offset << 3;
9564 gen_st(ctx, OPC_SD, ry, 29, offset);
9568 offset = extended ? offset : (ctx->opcode & 0xff) << 3;
9569 gen_st(ctx, OPC_SD, 31, 29, offset);
9573 offset = extended ? offset : ((int8_t)ctx->opcode) << 3;
9574 gen_arith_imm(env, ctx, OPC_DADDIU, 29, 29, offset);
9577 if (extended && (ctx->hflags & MIPS_HFLAG_BMASK)) {
9578 generate_exception(ctx, EXCP_RI);
9580 offset = extended ? offset : offset << 3;
9581 gen_ld(env, ctx, OPC_LDPC, ry, 0, offset);
9586 offset = extended ? offset : ((int8_t)(offset << 3)) >> 3;
9587 gen_arith_imm(env, ctx, OPC_DADDIU, ry, ry, offset);
9591 offset = extended ? offset : offset << 2;
9592 gen_addiupc(ctx, ry, offset, 1, extended);
9596 offset = extended ? offset : offset << 2;
9597 gen_arith_imm(env, ctx, OPC_DADDIU, ry, 29, offset);
9603 static int decode_extended_mips16_opc (CPUMIPSState *env, DisasContext *ctx,
9606 int extend = cpu_lduw_code(env, ctx->pc + 2);
9607 int op, rx, ry, funct, sa;
9608 int16_t imm, offset;
9610 ctx->opcode = (ctx->opcode << 16) | extend;
9611 op = (ctx->opcode >> 11) & 0x1f;
9612 sa = (ctx->opcode >> 22) & 0x1f;
9613 funct = (ctx->opcode >> 8) & 0x7;
9614 rx = xlat((ctx->opcode >> 8) & 0x7);
9615 ry = xlat((ctx->opcode >> 5) & 0x7);
9616 offset = imm = (int16_t) (((ctx->opcode >> 16) & 0x1f) << 11
9617 | ((ctx->opcode >> 21) & 0x3f) << 5
9618 | (ctx->opcode & 0x1f));
9620 /* The extended opcodes cleverly reuse the opcodes from their 16-bit
9623 case M16_OPC_ADDIUSP:
9624 gen_arith_imm(env, ctx, OPC_ADDIU, rx, 29, imm);
9626 case M16_OPC_ADDIUPC:
9627 gen_addiupc(ctx, rx, imm, 0, 1);
9630 gen_compute_branch(ctx, OPC_BEQ, 4, 0, 0, offset << 1);
9631 /* No delay slot, so just process as a normal instruction */
9634 gen_compute_branch(ctx, OPC_BEQ, 4, rx, 0, offset << 1);
9635 /* No delay slot, so just process as a normal instruction */
9638 gen_compute_branch(ctx, OPC_BNE, 4, rx, 0, offset << 1);
9639 /* No delay slot, so just process as a normal instruction */
9642 switch (ctx->opcode & 0x3) {
9644 gen_shift_imm(env, ctx, OPC_SLL, rx, ry, sa);
9647 #if defined(TARGET_MIPS64)
9649 gen_shift_imm(env, ctx, OPC_DSLL, rx, ry, sa);
9651 generate_exception(ctx, EXCP_RI);
9655 gen_shift_imm(env, ctx, OPC_SRL, rx, ry, sa);
9658 gen_shift_imm(env, ctx, OPC_SRA, rx, ry, sa);
9662 #if defined(TARGET_MIPS64)
9665 gen_ld(env, ctx, OPC_LD, ry, rx, offset);
9669 imm = ctx->opcode & 0xf;
9670 imm = imm | ((ctx->opcode >> 20) & 0x7f) << 4;
9671 imm = imm | ((ctx->opcode >> 16) & 0xf) << 11;
9672 imm = (int16_t) (imm << 1) >> 1;
9673 if ((ctx->opcode >> 4) & 0x1) {
9674 #if defined(TARGET_MIPS64)
9676 gen_arith_imm(env, ctx, OPC_DADDIU, ry, rx, imm);
9678 generate_exception(ctx, EXCP_RI);
9681 gen_arith_imm(env, ctx, OPC_ADDIU, ry, rx, imm);
9684 case M16_OPC_ADDIU8:
9685 gen_arith_imm(env, ctx, OPC_ADDIU, rx, rx, imm);
9688 gen_slt_imm(env, ctx, OPC_SLTI, 24, rx, imm);
9691 gen_slt_imm(env, ctx, OPC_SLTIU, 24, rx, imm);
9696 gen_compute_branch(ctx, OPC_BEQ, 4, 24, 0, offset << 1);
9699 gen_compute_branch(ctx, OPC_BNE, 4, 24, 0, offset << 1);
9702 gen_st(ctx, OPC_SW, 31, 29, imm);
9705 gen_arith_imm(env, ctx, OPC_ADDIU, 29, 29, imm);
9709 int xsregs = (ctx->opcode >> 24) & 0x7;
9710 int aregs = (ctx->opcode >> 16) & 0xf;
9711 int do_ra = (ctx->opcode >> 6) & 0x1;
9712 int do_s0 = (ctx->opcode >> 5) & 0x1;
9713 int do_s1 = (ctx->opcode >> 4) & 0x1;
9714 int framesize = (((ctx->opcode >> 20) & 0xf) << 4
9715 | (ctx->opcode & 0xf)) << 3;
9717 if (ctx->opcode & (1 << 7)) {
9718 gen_mips16_save(ctx, xsregs, aregs,
9719 do_ra, do_s0, do_s1,
9722 gen_mips16_restore(ctx, xsregs, aregs,
9723 do_ra, do_s0, do_s1,
9729 generate_exception(ctx, EXCP_RI);
9734 tcg_gen_movi_tl(cpu_gpr[rx], (uint16_t) imm);
9737 tcg_gen_xori_tl(cpu_gpr[24], cpu_gpr[rx], (uint16_t) imm);
9739 #if defined(TARGET_MIPS64)
9741 gen_st(ctx, OPC_SD, ry, rx, offset);
9745 gen_ld(env, ctx, OPC_LB, ry, rx, offset);
9748 gen_ld(env, ctx, OPC_LH, ry, rx, offset);
9751 gen_ld(env, ctx, OPC_LW, rx, 29, offset);
9754 gen_ld(env, ctx, OPC_LW, ry, rx, offset);
9757 gen_ld(env, ctx, OPC_LBU, ry, rx, offset);
9760 gen_ld(env, ctx, OPC_LHU, ry, rx, offset);
9763 gen_ld(env, ctx, OPC_LWPC, rx, 0, offset);
9765 #if defined(TARGET_MIPS64)
9767 gen_ld(env, ctx, OPC_LWU, ry, rx, offset);
9771 gen_st(ctx, OPC_SB, ry, rx, offset);
9774 gen_st(ctx, OPC_SH, ry, rx, offset);
9777 gen_st(ctx, OPC_SW, rx, 29, offset);
9780 gen_st(ctx, OPC_SW, ry, rx, offset);
9782 #if defined(TARGET_MIPS64)
9784 decode_i64_mips16(env, ctx, ry, funct, offset, 1);
9788 generate_exception(ctx, EXCP_RI);
9795 static int decode_mips16_opc (CPUMIPSState *env, DisasContext *ctx,
9800 int op, cnvt_op, op1, offset;
9804 op = (ctx->opcode >> 11) & 0x1f;
9805 sa = (ctx->opcode >> 2) & 0x7;
9806 sa = sa == 0 ? 8 : sa;
9807 rx = xlat((ctx->opcode >> 8) & 0x7);
9808 cnvt_op = (ctx->opcode >> 5) & 0x7;
9809 ry = xlat((ctx->opcode >> 5) & 0x7);
9810 op1 = offset = ctx->opcode & 0x1f;
9815 case M16_OPC_ADDIUSP:
9817 int16_t imm = ((uint8_t) ctx->opcode) << 2;
9819 gen_arith_imm(env, ctx, OPC_ADDIU, rx, 29, imm);
9822 case M16_OPC_ADDIUPC:
9823 gen_addiupc(ctx, rx, ((uint8_t) ctx->opcode) << 2, 0, 0);
9826 offset = (ctx->opcode & 0x7ff) << 1;
9827 offset = (int16_t)(offset << 4) >> 4;
9828 gen_compute_branch(ctx, OPC_BEQ, 2, 0, 0, offset);
9829 /* No delay slot, so just process as a normal instruction */
9832 offset = cpu_lduw_code(env, ctx->pc + 2);
9833 offset = (((ctx->opcode & 0x1f) << 21)
9834 | ((ctx->opcode >> 5) & 0x1f) << 16
9836 op = ((ctx->opcode >> 10) & 0x1) ? OPC_JALXS : OPC_JALS;
9837 gen_compute_branch(ctx, op, 4, rx, ry, offset);
9842 gen_compute_branch(ctx, OPC_BEQ, 2, rx, 0, ((int8_t)ctx->opcode) << 1);
9843 /* No delay slot, so just process as a normal instruction */
9846 gen_compute_branch(ctx, OPC_BNE, 2, rx, 0, ((int8_t)ctx->opcode) << 1);
9847 /* No delay slot, so just process as a normal instruction */
9850 switch (ctx->opcode & 0x3) {
9852 gen_shift_imm(env, ctx, OPC_SLL, rx, ry, sa);
9855 #if defined(TARGET_MIPS64)
9857 gen_shift_imm(env, ctx, OPC_DSLL, rx, ry, sa);
9859 generate_exception(ctx, EXCP_RI);
9863 gen_shift_imm(env, ctx, OPC_SRL, rx, ry, sa);
9866 gen_shift_imm(env, ctx, OPC_SRA, rx, ry, sa);
9870 #if defined(TARGET_MIPS64)
9873 gen_ld(env, ctx, OPC_LD, ry, rx, offset << 3);
9878 int16_t imm = (int8_t)((ctx->opcode & 0xf) << 4) >> 4;
9880 if ((ctx->opcode >> 4) & 1) {
9881 #if defined(TARGET_MIPS64)
9883 gen_arith_imm(env, ctx, OPC_DADDIU, ry, rx, imm);
9885 generate_exception(ctx, EXCP_RI);
9888 gen_arith_imm(env, ctx, OPC_ADDIU, ry, rx, imm);
9892 case M16_OPC_ADDIU8:
9894 int16_t imm = (int8_t) ctx->opcode;
9896 gen_arith_imm(env, ctx, OPC_ADDIU, rx, rx, imm);
9901 int16_t imm = (uint8_t) ctx->opcode;
9902 gen_slt_imm(env, ctx, OPC_SLTI, 24, rx, imm);
9907 int16_t imm = (uint8_t) ctx->opcode;
9908 gen_slt_imm(env, ctx, OPC_SLTIU, 24, rx, imm);
9915 funct = (ctx->opcode >> 8) & 0x7;
9918 gen_compute_branch(ctx, OPC_BEQ, 2, 24, 0,
9919 ((int8_t)ctx->opcode) << 1);
9922 gen_compute_branch(ctx, OPC_BNE, 2, 24, 0,
9923 ((int8_t)ctx->opcode) << 1);
9926 gen_st(ctx, OPC_SW, 31, 29, (ctx->opcode & 0xff) << 2);
9929 gen_arith_imm(env, ctx, OPC_ADDIU, 29, 29,
9930 ((int8_t)ctx->opcode) << 3);
9934 int do_ra = ctx->opcode & (1 << 6);
9935 int do_s0 = ctx->opcode & (1 << 5);
9936 int do_s1 = ctx->opcode & (1 << 4);
9937 int framesize = ctx->opcode & 0xf;
9939 if (framesize == 0) {
9942 framesize = framesize << 3;
9945 if (ctx->opcode & (1 << 7)) {
9946 gen_mips16_save(ctx, 0, 0,
9947 do_ra, do_s0, do_s1, framesize);
9949 gen_mips16_restore(ctx, 0, 0,
9950 do_ra, do_s0, do_s1, framesize);
9956 int rz = xlat(ctx->opcode & 0x7);
9958 reg32 = (((ctx->opcode >> 3) & 0x3) << 3) |
9959 ((ctx->opcode >> 5) & 0x7);
9960 gen_arith(env, ctx, OPC_ADDU, reg32, rz, 0);
9964 reg32 = ctx->opcode & 0x1f;
9965 gen_arith(env, ctx, OPC_ADDU, ry, reg32, 0);
9968 generate_exception(ctx, EXCP_RI);
9975 int16_t imm = (uint8_t) ctx->opcode;
9977 gen_arith_imm(env, ctx, OPC_ADDIU, rx, 0, imm);
9982 int16_t imm = (uint8_t) ctx->opcode;
9983 gen_logic_imm(env, ctx, OPC_XORI, 24, rx, imm);
9986 #if defined(TARGET_MIPS64)
9989 gen_st(ctx, OPC_SD, ry, rx, offset << 3);
9993 gen_ld(env, ctx, OPC_LB, ry, rx, offset);
9996 gen_ld(env, ctx, OPC_LH, ry, rx, offset << 1);
9999 gen_ld(env, ctx, OPC_LW, rx, 29, ((uint8_t)ctx->opcode) << 2);
10002 gen_ld(env, ctx, OPC_LW, ry, rx, offset << 2);
10005 gen_ld(env, ctx, OPC_LBU, ry, rx, offset);
10008 gen_ld(env, ctx, OPC_LHU, ry, rx, offset << 1);
10011 gen_ld(env, ctx, OPC_LWPC, rx, 0, ((uint8_t)ctx->opcode) << 2);
10013 #if defined (TARGET_MIPS64)
10015 check_mips_64(ctx);
10016 gen_ld(env, ctx, OPC_LWU, ry, rx, offset << 2);
10020 gen_st(ctx, OPC_SB, ry, rx, offset);
10023 gen_st(ctx, OPC_SH, ry, rx, offset << 1);
10026 gen_st(ctx, OPC_SW, rx, 29, ((uint8_t)ctx->opcode) << 2);
10029 gen_st(ctx, OPC_SW, ry, rx, offset << 2);
10033 int rz = xlat((ctx->opcode >> 2) & 0x7);
10036 switch (ctx->opcode & 0x3) {
10038 mips32_op = OPC_ADDU;
10041 mips32_op = OPC_SUBU;
10043 #if defined(TARGET_MIPS64)
10045 mips32_op = OPC_DADDU;
10046 check_mips_64(ctx);
10049 mips32_op = OPC_DSUBU;
10050 check_mips_64(ctx);
10054 generate_exception(ctx, EXCP_RI);
10058 gen_arith(env, ctx, mips32_op, rz, rx, ry);
10067 int nd = (ctx->opcode >> 7) & 0x1;
10068 int link = (ctx->opcode >> 6) & 0x1;
10069 int ra = (ctx->opcode >> 5) & 0x1;
10072 op = nd ? OPC_JALRC : OPC_JALRS;
10077 gen_compute_branch(ctx, op, 2, ra ? 31 : rx, 31, 0);
10084 /* XXX: not clear which exception should be raised
10085 * when in debug mode...
10087 check_insn(env, ctx, ISA_MIPS32);
10088 if (!(ctx->hflags & MIPS_HFLAG_DM)) {
10089 generate_exception(ctx, EXCP_DBp);
10091 generate_exception(ctx, EXCP_DBp);
10095 gen_slt(env, ctx, OPC_SLT, 24, rx, ry);
10098 gen_slt(env, ctx, OPC_SLTU, 24, rx, ry);
10101 generate_exception(ctx, EXCP_BREAK);
10104 gen_shift(env, ctx, OPC_SLLV, ry, rx, ry);
10107 gen_shift(env, ctx, OPC_SRLV, ry, rx, ry);
10110 gen_shift(env, ctx, OPC_SRAV, ry, rx, ry);
10112 #if defined (TARGET_MIPS64)
10114 check_mips_64(ctx);
10115 gen_shift_imm(env, ctx, OPC_DSRL, ry, ry, sa);
10119 gen_logic(env, ctx, OPC_XOR, 24, rx, ry);
10122 gen_arith(env, ctx, OPC_SUBU, rx, 0, ry);
10125 gen_logic(env, ctx, OPC_AND, rx, rx, ry);
10128 gen_logic(env, ctx, OPC_OR, rx, rx, ry);
10131 gen_logic(env, ctx, OPC_XOR, rx, rx, ry);
10134 gen_logic(env, ctx, OPC_NOR, rx, ry, 0);
10137 gen_HILO(ctx, OPC_MFHI, rx);
10141 case RR_RY_CNVT_ZEB:
10142 tcg_gen_ext8u_tl(cpu_gpr[rx], cpu_gpr[rx]);
10144 case RR_RY_CNVT_ZEH:
10145 tcg_gen_ext16u_tl(cpu_gpr[rx], cpu_gpr[rx]);
10147 case RR_RY_CNVT_SEB:
10148 tcg_gen_ext8s_tl(cpu_gpr[rx], cpu_gpr[rx]);
10150 case RR_RY_CNVT_SEH:
10151 tcg_gen_ext16s_tl(cpu_gpr[rx], cpu_gpr[rx]);
10153 #if defined (TARGET_MIPS64)
10154 case RR_RY_CNVT_ZEW:
10155 check_mips_64(ctx);
10156 tcg_gen_ext32u_tl(cpu_gpr[rx], cpu_gpr[rx]);
10158 case RR_RY_CNVT_SEW:
10159 check_mips_64(ctx);
10160 tcg_gen_ext32s_tl(cpu_gpr[rx], cpu_gpr[rx]);
10164 generate_exception(ctx, EXCP_RI);
10169 gen_HILO(ctx, OPC_MFLO, rx);
10171 #if defined (TARGET_MIPS64)
10173 check_mips_64(ctx);
10174 gen_shift_imm(env, ctx, OPC_DSRA, ry, ry, sa);
10177 check_mips_64(ctx);
10178 gen_shift(env, ctx, OPC_DSLLV, ry, rx, ry);
10181 check_mips_64(ctx);
10182 gen_shift(env, ctx, OPC_DSRLV, ry, rx, ry);
10185 check_mips_64(ctx);
10186 gen_shift(env, ctx, OPC_DSRAV, ry, rx, ry);
10190 gen_muldiv(ctx, OPC_MULT, rx, ry);
10193 gen_muldiv(ctx, OPC_MULTU, rx, ry);
10196 gen_muldiv(ctx, OPC_DIV, rx, ry);
10199 gen_muldiv(ctx, OPC_DIVU, rx, ry);
10201 #if defined (TARGET_MIPS64)
10203 check_mips_64(ctx);
10204 gen_muldiv(ctx, OPC_DMULT, rx, ry);
10207 check_mips_64(ctx);
10208 gen_muldiv(ctx, OPC_DMULTU, rx, ry);
10211 check_mips_64(ctx);
10212 gen_muldiv(ctx, OPC_DDIV, rx, ry);
10215 check_mips_64(ctx);
10216 gen_muldiv(ctx, OPC_DDIVU, rx, ry);
10220 generate_exception(ctx, EXCP_RI);
10224 case M16_OPC_EXTEND:
10225 decode_extended_mips16_opc(env, ctx, is_branch);
10228 #if defined(TARGET_MIPS64)
10230 funct = (ctx->opcode >> 8) & 0x7;
10231 decode_i64_mips16(env, ctx, ry, funct, offset, 0);
10235 generate_exception(ctx, EXCP_RI);
10242 /* microMIPS extension to MIPS32 */
10244 /* microMIPS32 major opcodes */
10283 /* 0x20 is reserved */
10293 /* 0x28 and 0x29 are reserved */
10303 /* 0x30 and 0x31 are reserved */
10313 /* 0x38 and 0x39 are reserved */
10324 /* POOL32A encoding of minor opcode field */
10327 /* These opcodes are distinguished only by bits 9..6; those bits are
10328 * what are recorded below. */
10354 /* The following can be distinguished by their lower 6 bits. */
10360 /* POOL32AXF encoding of minor opcode field extension */
10363 * 1. MIPS Architecture for Programmers Volume II-B:
10364 * The microMIPS32 Instruction Set (Revision 3.05)
10366 * Table 6.5 POOL32Axf Encoding of Minor Opcode Extension Field
10368 * 2. MIPS Architecture for Programmers VolumeIV-e:
10369 * The MIPS DSP Application-Specific Extension
10370 * to the microMIPS32 Architecture (Revision 2.34)
10372 * Table 5.5 POOL32Axf Encoding of Minor Opcode Extension Field
10387 /* begin of microMIPS32 DSP */
10389 /* bits 13..12 for 0x01 */
10395 /* bits 13..12 for 0x2a */
10401 /* bits 13..12 for 0x32 */
10405 /* end of microMIPS32 DSP */
10407 /* bits 15..12 for 0x2c */
10423 /* bits 15..12 for 0x34 */
10431 /* bits 15..12 for 0x3c */
10433 JR = 0x0, /* alias */
10438 /* bits 15..12 for 0x05 */
10442 /* bits 15..12 for 0x0d */
10452 /* bits 15..12 for 0x15 */
10458 /* bits 15..12 for 0x1d */
10462 /* bits 15..12 for 0x2d */
10467 /* bits 15..12 for 0x35 */
10474 /* POOL32B encoding of minor opcode field (bits 15..12) */
10490 /* POOL32C encoding of minor opcode field (bits 15..12) */
10498 /* 0xa is reserved */
10505 /* 0x6 is reserved */
10511 /* POOL32F encoding of minor opcode field (bits 5..0) */
10514 /* These are the bit 7..6 values */
10525 /* These are the bit 8..6 values */
10569 CABS_COND_FMT = 0x1c, /* MIPS3D */
10573 /* POOL32Fxf encoding of minor opcode extension field */
10611 /* POOL32I encoding of minor opcode field (bits 25..21) */
10636 /* These overlap and are distinguished by bit16 of the instruction */
10645 /* POOL16A encoding of minor opcode field */
10652 /* POOL16B encoding of minor opcode field */
10659 /* POOL16C encoding of minor opcode field */
10679 /* POOL16D encoding of minor opcode field */
10686 /* POOL16E encoding of minor opcode field */
10693 static int mmreg (int r)
10695 static const int map[] = { 16, 17, 2, 3, 4, 5, 6, 7 };
10700 /* Used for 16-bit store instructions. */
10701 static int mmreg2 (int r)
10703 static const int map[] = { 0, 17, 2, 3, 4, 5, 6, 7 };
10708 #define uMIPS_RD(op) ((op >> 7) & 0x7)
10709 #define uMIPS_RS(op) ((op >> 4) & 0x7)
10710 #define uMIPS_RS2(op) uMIPS_RS(op)
10711 #define uMIPS_RS1(op) ((op >> 1) & 0x7)
10712 #define uMIPS_RD5(op) ((op >> 5) & 0x1f)
10713 #define uMIPS_RS5(op) (op & 0x1f)
10715 /* Signed immediate */
10716 #define SIMM(op, start, width) \
10717 ((int32_t)(((op >> start) & ((~0U) >> (32-width))) \
10720 /* Zero-extended immediate */
10721 #define ZIMM(op, start, width) ((op >> start) & ((~0U) >> (32-width)))
10723 static void gen_addiur1sp (CPUMIPSState *env, DisasContext *ctx)
10725 int rd = mmreg(uMIPS_RD(ctx->opcode));
10727 gen_arith_imm(env, ctx, OPC_ADDIU, rd, 29, ((ctx->opcode >> 1) & 0x3f) << 2);
10730 static void gen_addiur2 (CPUMIPSState *env, DisasContext *ctx)
10732 static const int decoded_imm[] = { 1, 4, 8, 12, 16, 20, 24, -1 };
10733 int rd = mmreg(uMIPS_RD(ctx->opcode));
10734 int rs = mmreg(uMIPS_RS(ctx->opcode));
10736 gen_arith_imm(env, ctx, OPC_ADDIU, rd, rs, decoded_imm[ZIMM(ctx->opcode, 1, 3)]);
10739 static void gen_addiusp (CPUMIPSState *env, DisasContext *ctx)
10741 int encoded = ZIMM(ctx->opcode, 1, 9);
10744 if (encoded <= 1) {
10745 decoded = 256 + encoded;
10746 } else if (encoded <= 255) {
10748 } else if (encoded <= 509) {
10749 decoded = encoded - 512;
10751 decoded = encoded - 768;
10754 gen_arith_imm(env, ctx, OPC_ADDIU, 29, 29, decoded << 2);
10757 static void gen_addius5 (CPUMIPSState *env, DisasContext *ctx)
10759 int imm = SIMM(ctx->opcode, 1, 4);
10760 int rd = (ctx->opcode >> 5) & 0x1f;
10762 gen_arith_imm(env, ctx, OPC_ADDIU, rd, rd, imm);
10765 static void gen_andi16 (CPUMIPSState *env, DisasContext *ctx)
10767 static const int decoded_imm[] = { 128, 1, 2, 3, 4, 7, 8, 15, 16,
10768 31, 32, 63, 64, 255, 32768, 65535 };
10769 int rd = mmreg(uMIPS_RD(ctx->opcode));
10770 int rs = mmreg(uMIPS_RS(ctx->opcode));
10771 int encoded = ZIMM(ctx->opcode, 0, 4);
10773 gen_logic_imm(env, ctx, OPC_ANDI, rd, rs, decoded_imm[encoded]);
10776 static void gen_ldst_multiple (DisasContext *ctx, uint32_t opc, int reglist,
10777 int base, int16_t offset)
10779 const char *opn = "ldst_multiple";
10783 if (ctx->hflags & MIPS_HFLAG_BMASK) {
10784 generate_exception(ctx, EXCP_RI);
10788 t0 = tcg_temp_new();
10790 gen_base_offset_addr(ctx, t0, base, offset);
10792 t1 = tcg_const_tl(reglist);
10793 t2 = tcg_const_i32(ctx->mem_idx);
10795 save_cpu_state(ctx, 1);
10798 gen_helper_lwm(cpu_env, t0, t1, t2);
10802 gen_helper_swm(cpu_env, t0, t1, t2);
10805 #ifdef TARGET_MIPS64
10807 gen_helper_ldm(cpu_env, t0, t1, t2);
10811 gen_helper_sdm(cpu_env, t0, t1, t2);
10817 MIPS_DEBUG("%s, %x, %d(%s)", opn, reglist, offset, regnames[base]);
10820 tcg_temp_free_i32(t2);
10824 static void gen_pool16c_insn (CPUMIPSState *env, DisasContext *ctx, int *is_branch)
10826 int rd = mmreg((ctx->opcode >> 3) & 0x7);
10827 int rs = mmreg(ctx->opcode & 0x7);
10830 switch (((ctx->opcode) >> 4) & 0x3f) {
10835 gen_logic(env, ctx, OPC_NOR, rd, rs, 0);
10841 gen_logic(env, ctx, OPC_XOR, rd, rd, rs);
10847 gen_logic(env, ctx, OPC_AND, rd, rd, rs);
10853 gen_logic(env, ctx, OPC_OR, rd, rd, rs);
10860 static const int lwm_convert[] = { 0x11, 0x12, 0x13, 0x14 };
10861 int offset = ZIMM(ctx->opcode, 0, 4);
10863 gen_ldst_multiple(ctx, LWM32, lwm_convert[(ctx->opcode >> 4) & 0x3],
10872 static const int swm_convert[] = { 0x11, 0x12, 0x13, 0x14 };
10873 int offset = ZIMM(ctx->opcode, 0, 4);
10875 gen_ldst_multiple(ctx, SWM32, swm_convert[(ctx->opcode >> 4) & 0x3],
10882 int reg = ctx->opcode & 0x1f;
10884 gen_compute_branch(ctx, OPC_JR, 2, reg, 0, 0);
10891 int reg = ctx->opcode & 0x1f;
10893 gen_compute_branch(ctx, OPC_JR, 2, reg, 0, 0);
10894 /* Let normal delay slot handling in our caller take us
10895 to the branch target. */
10907 int reg = ctx->opcode & 0x1f;
10909 gen_compute_branch(ctx, opc, 2, reg, 31, 0);
10915 gen_HILO(ctx, OPC_MFHI, uMIPS_RS5(ctx->opcode));
10919 gen_HILO(ctx, OPC_MFLO, uMIPS_RS5(ctx->opcode));
10922 generate_exception(ctx, EXCP_BREAK);
10925 /* XXX: not clear which exception should be raised
10926 * when in debug mode...
10928 check_insn(env, ctx, ISA_MIPS32);
10929 if (!(ctx->hflags & MIPS_HFLAG_DM)) {
10930 generate_exception(ctx, EXCP_DBp);
10932 generate_exception(ctx, EXCP_DBp);
10935 case JRADDIUSP + 0:
10936 case JRADDIUSP + 1:
10938 int imm = ZIMM(ctx->opcode, 0, 5);
10940 gen_compute_branch(ctx, OPC_JR, 2, 31, 0, 0);
10941 gen_arith_imm(env, ctx, OPC_ADDIU, 29, 29, imm << 2);
10942 /* Let normal delay slot handling in our caller take us
10943 to the branch target. */
10947 generate_exception(ctx, EXCP_RI);
10952 static void gen_ldxs (DisasContext *ctx, int base, int index, int rd)
10954 TCGv t0 = tcg_temp_new();
10955 TCGv t1 = tcg_temp_new();
10957 gen_load_gpr(t0, base);
10960 gen_load_gpr(t1, index);
10961 tcg_gen_shli_tl(t1, t1, 2);
10962 gen_op_addr_add(ctx, t0, t1, t0);
10965 tcg_gen_qemu_ld32s(t1, t0, ctx->mem_idx);
10966 gen_store_gpr(t1, rd);
10972 static void gen_ldst_pair (DisasContext *ctx, uint32_t opc, int rd,
10973 int base, int16_t offset)
10975 const char *opn = "ldst_pair";
10978 if (ctx->hflags & MIPS_HFLAG_BMASK || rd == 31) {
10979 generate_exception(ctx, EXCP_RI);
10983 t0 = tcg_temp_new();
10984 t1 = tcg_temp_new();
10986 gen_base_offset_addr(ctx, t0, base, offset);
10991 generate_exception(ctx, EXCP_RI);
10994 tcg_gen_qemu_ld32s(t1, t0, ctx->mem_idx);
10995 gen_store_gpr(t1, rd);
10996 tcg_gen_movi_tl(t1, 4);
10997 gen_op_addr_add(ctx, t0, t0, t1);
10998 tcg_gen_qemu_ld32s(t1, t0, ctx->mem_idx);
10999 gen_store_gpr(t1, rd+1);
11003 gen_load_gpr(t1, rd);
11004 tcg_gen_qemu_st32(t1, t0, ctx->mem_idx);
11005 tcg_gen_movi_tl(t1, 4);
11006 gen_op_addr_add(ctx, t0, t0, t1);
11007 gen_load_gpr(t1, rd+1);
11008 tcg_gen_qemu_st32(t1, t0, ctx->mem_idx);
11011 #ifdef TARGET_MIPS64
11014 generate_exception(ctx, EXCP_RI);
11017 tcg_gen_qemu_ld64(t1, t0, ctx->mem_idx);
11018 gen_store_gpr(t1, rd);
11019 tcg_gen_movi_tl(t1, 8);
11020 gen_op_addr_add(ctx, t0, t0, t1);
11021 tcg_gen_qemu_ld64(t1, t0, ctx->mem_idx);
11022 gen_store_gpr(t1, rd+1);
11026 gen_load_gpr(t1, rd);
11027 tcg_gen_qemu_st64(t1, t0, ctx->mem_idx);
11028 tcg_gen_movi_tl(t1, 8);
11029 gen_op_addr_add(ctx, t0, t0, t1);
11030 gen_load_gpr(t1, rd+1);
11031 tcg_gen_qemu_st64(t1, t0, ctx->mem_idx);
11036 (void)opn; /* avoid a compiler warning */
11037 MIPS_DEBUG("%s, %s, %d(%s)", opn, regnames[rd], offset, regnames[base]);
11042 static void gen_pool32axf (CPUMIPSState *env, DisasContext *ctx, int rt, int rs,
11045 int extension = (ctx->opcode >> 6) & 0x3f;
11046 int minor = (ctx->opcode >> 12) & 0xf;
11047 uint32_t mips32_op;
11049 switch (extension) {
11051 mips32_op = OPC_TEQ;
11054 mips32_op = OPC_TGE;
11057 mips32_op = OPC_TGEU;
11060 mips32_op = OPC_TLT;
11063 mips32_op = OPC_TLTU;
11066 mips32_op = OPC_TNE;
11068 gen_trap(ctx, mips32_op, rs, rt, -1);
11070 #ifndef CONFIG_USER_ONLY
11073 check_cp0_enabled(ctx);
11075 /* Treat as NOP. */
11078 gen_mfc0(env, ctx, cpu_gpr[rt], rs, (ctx->opcode >> 11) & 0x7);
11082 check_cp0_enabled(ctx);
11084 TCGv t0 = tcg_temp_new();
11086 gen_load_gpr(t0, rt);
11087 gen_mtc0(env, ctx, t0, rs, (ctx->opcode >> 11) & 0x7);
11095 gen_bshfl(ctx, OPC_SEB, rs, rt);
11098 gen_bshfl(ctx, OPC_SEH, rs, rt);
11101 mips32_op = OPC_CLO;
11104 mips32_op = OPC_CLZ;
11106 check_insn(env, ctx, ISA_MIPS32);
11107 gen_cl(ctx, mips32_op, rt, rs);
11110 gen_rdhwr(env, ctx, rt, rs);
11113 gen_bshfl(ctx, OPC_WSBH, rs, rt);
11116 mips32_op = OPC_MULT;
11119 mips32_op = OPC_MULTU;
11122 mips32_op = OPC_DIV;
11125 mips32_op = OPC_DIVU;
11128 mips32_op = OPC_MADD;
11131 mips32_op = OPC_MADDU;
11134 mips32_op = OPC_MSUB;
11137 mips32_op = OPC_MSUBU;
11139 check_insn(env, ctx, ISA_MIPS32);
11140 gen_muldiv(ctx, mips32_op, rs, rt);
11143 goto pool32axf_invalid;
11154 generate_exception_err(ctx, EXCP_CpU, 2);
11157 goto pool32axf_invalid;
11164 gen_compute_branch (ctx, OPC_JALR, 4, rs, rt, 0);
11169 gen_compute_branch (ctx, OPC_JALRS, 4, rs, rt, 0);
11173 goto pool32axf_invalid;
11179 check_cp0_enabled(ctx);
11180 check_insn(env, ctx, ISA_MIPS32R2);
11181 gen_load_srsgpr(rt, rs);
11184 check_cp0_enabled(ctx);
11185 check_insn(env, ctx, ISA_MIPS32R2);
11186 gen_store_srsgpr(rt, rs);
11189 goto pool32axf_invalid;
11192 #ifndef CONFIG_USER_ONLY
11196 mips32_op = OPC_TLBP;
11199 mips32_op = OPC_TLBR;
11202 mips32_op = OPC_TLBWI;
11205 mips32_op = OPC_TLBWR;
11208 mips32_op = OPC_WAIT;
11211 mips32_op = OPC_DERET;
11214 mips32_op = OPC_ERET;
11216 gen_cp0(env, ctx, mips32_op, rt, rs);
11219 goto pool32axf_invalid;
11225 check_cp0_enabled(ctx);
11227 TCGv t0 = tcg_temp_new();
11229 save_cpu_state(ctx, 1);
11230 gen_helper_di(t0, cpu_env);
11231 gen_store_gpr(t0, rs);
11232 /* Stop translation as we may have switched the execution mode */
11233 ctx->bstate = BS_STOP;
11238 check_cp0_enabled(ctx);
11240 TCGv t0 = tcg_temp_new();
11242 save_cpu_state(ctx, 1);
11243 gen_helper_ei(t0, cpu_env);
11244 gen_store_gpr(t0, rs);
11245 /* Stop translation as we may have switched the execution mode */
11246 ctx->bstate = BS_STOP;
11251 goto pool32axf_invalid;
11261 generate_exception(ctx, EXCP_SYSCALL);
11262 ctx->bstate = BS_STOP;
11265 check_insn(env, ctx, ISA_MIPS32);
11266 if (!(ctx->hflags & MIPS_HFLAG_DM)) {
11267 generate_exception(ctx, EXCP_DBp);
11269 generate_exception(ctx, EXCP_DBp);
11273 goto pool32axf_invalid;
11279 gen_HILO(ctx, OPC_MFHI, rs);
11282 gen_HILO(ctx, OPC_MFLO, rs);
11285 gen_HILO(ctx, OPC_MTHI, rs);
11288 gen_HILO(ctx, OPC_MTLO, rs);
11291 goto pool32axf_invalid;
11296 MIPS_INVAL("pool32axf");
11297 generate_exception(ctx, EXCP_RI);
11302 /* Values for microMIPS fmt field. Variable-width, depending on which
11303 formats the instruction supports. */
11322 static void gen_pool32fxf (CPUMIPSState *env, DisasContext *ctx, int rt, int rs)
11324 int extension = (ctx->opcode >> 6) & 0x3ff;
11325 uint32_t mips32_op;
11327 #define FLOAT_1BIT_FMT(opc, fmt) (fmt << 8) | opc
11328 #define FLOAT_2BIT_FMT(opc, fmt) (fmt << 7) | opc
11329 #define COND_FLOAT_MOV(opc, cond) (cond << 7) | opc
11331 switch (extension) {
11332 case FLOAT_1BIT_FMT(CFC1, 0):
11333 mips32_op = OPC_CFC1;
11335 case FLOAT_1BIT_FMT(CTC1, 0):
11336 mips32_op = OPC_CTC1;
11338 case FLOAT_1BIT_FMT(MFC1, 0):
11339 mips32_op = OPC_MFC1;
11341 case FLOAT_1BIT_FMT(MTC1, 0):
11342 mips32_op = OPC_MTC1;
11344 case FLOAT_1BIT_FMT(MFHC1, 0):
11345 mips32_op = OPC_MFHC1;
11347 case FLOAT_1BIT_FMT(MTHC1, 0):
11348 mips32_op = OPC_MTHC1;
11350 gen_cp1(ctx, mips32_op, rt, rs);
11353 /* Reciprocal square root */
11354 case FLOAT_1BIT_FMT(RSQRT_FMT, FMT_SD_S):
11355 mips32_op = OPC_RSQRT_S;
11357 case FLOAT_1BIT_FMT(RSQRT_FMT, FMT_SD_D):
11358 mips32_op = OPC_RSQRT_D;
11362 case FLOAT_1BIT_FMT(SQRT_FMT, FMT_SD_S):
11363 mips32_op = OPC_SQRT_S;
11365 case FLOAT_1BIT_FMT(SQRT_FMT, FMT_SD_D):
11366 mips32_op = OPC_SQRT_D;
11370 case FLOAT_1BIT_FMT(RECIP_FMT, FMT_SD_S):
11371 mips32_op = OPC_RECIP_S;
11373 case FLOAT_1BIT_FMT(RECIP_FMT, FMT_SD_D):
11374 mips32_op = OPC_RECIP_D;
11378 case FLOAT_1BIT_FMT(FLOOR_L, FMT_SD_S):
11379 mips32_op = OPC_FLOOR_L_S;
11381 case FLOAT_1BIT_FMT(FLOOR_L, FMT_SD_D):
11382 mips32_op = OPC_FLOOR_L_D;
11384 case FLOAT_1BIT_FMT(FLOOR_W, FMT_SD_S):
11385 mips32_op = OPC_FLOOR_W_S;
11387 case FLOAT_1BIT_FMT(FLOOR_W, FMT_SD_D):
11388 mips32_op = OPC_FLOOR_W_D;
11392 case FLOAT_1BIT_FMT(CEIL_L, FMT_SD_S):
11393 mips32_op = OPC_CEIL_L_S;
11395 case FLOAT_1BIT_FMT(CEIL_L, FMT_SD_D):
11396 mips32_op = OPC_CEIL_L_D;
11398 case FLOAT_1BIT_FMT(CEIL_W, FMT_SD_S):
11399 mips32_op = OPC_CEIL_W_S;
11401 case FLOAT_1BIT_FMT(CEIL_W, FMT_SD_D):
11402 mips32_op = OPC_CEIL_W_D;
11406 case FLOAT_1BIT_FMT(TRUNC_L, FMT_SD_S):
11407 mips32_op = OPC_TRUNC_L_S;
11409 case FLOAT_1BIT_FMT(TRUNC_L, FMT_SD_D):
11410 mips32_op = OPC_TRUNC_L_D;
11412 case FLOAT_1BIT_FMT(TRUNC_W, FMT_SD_S):
11413 mips32_op = OPC_TRUNC_W_S;
11415 case FLOAT_1BIT_FMT(TRUNC_W, FMT_SD_D):
11416 mips32_op = OPC_TRUNC_W_D;
11420 case FLOAT_1BIT_FMT(ROUND_L, FMT_SD_S):
11421 mips32_op = OPC_ROUND_L_S;
11423 case FLOAT_1BIT_FMT(ROUND_L, FMT_SD_D):
11424 mips32_op = OPC_ROUND_L_D;
11426 case FLOAT_1BIT_FMT(ROUND_W, FMT_SD_S):
11427 mips32_op = OPC_ROUND_W_S;
11429 case FLOAT_1BIT_FMT(ROUND_W, FMT_SD_D):
11430 mips32_op = OPC_ROUND_W_D;
11433 /* Integer to floating-point conversion */
11434 case FLOAT_1BIT_FMT(CVT_L, FMT_SD_S):
11435 mips32_op = OPC_CVT_L_S;
11437 case FLOAT_1BIT_FMT(CVT_L, FMT_SD_D):
11438 mips32_op = OPC_CVT_L_D;
11440 case FLOAT_1BIT_FMT(CVT_W, FMT_SD_S):
11441 mips32_op = OPC_CVT_W_S;
11443 case FLOAT_1BIT_FMT(CVT_W, FMT_SD_D):
11444 mips32_op = OPC_CVT_W_D;
11447 /* Paired-foo conversions */
11448 case FLOAT_1BIT_FMT(CVT_S_PL, 0):
11449 mips32_op = OPC_CVT_S_PL;
11451 case FLOAT_1BIT_FMT(CVT_S_PU, 0):
11452 mips32_op = OPC_CVT_S_PU;
11454 case FLOAT_1BIT_FMT(CVT_PW_PS, 0):
11455 mips32_op = OPC_CVT_PW_PS;
11457 case FLOAT_1BIT_FMT(CVT_PS_PW, 0):
11458 mips32_op = OPC_CVT_PS_PW;
11461 /* Floating-point moves */
11462 case FLOAT_2BIT_FMT(MOV_FMT, FMT_SDPS_S):
11463 mips32_op = OPC_MOV_S;
11465 case FLOAT_2BIT_FMT(MOV_FMT, FMT_SDPS_D):
11466 mips32_op = OPC_MOV_D;
11468 case FLOAT_2BIT_FMT(MOV_FMT, FMT_SDPS_PS):
11469 mips32_op = OPC_MOV_PS;
11472 /* Absolute value */
11473 case FLOAT_2BIT_FMT(ABS_FMT, FMT_SDPS_S):
11474 mips32_op = OPC_ABS_S;
11476 case FLOAT_2BIT_FMT(ABS_FMT, FMT_SDPS_D):
11477 mips32_op = OPC_ABS_D;
11479 case FLOAT_2BIT_FMT(ABS_FMT, FMT_SDPS_PS):
11480 mips32_op = OPC_ABS_PS;
11484 case FLOAT_2BIT_FMT(NEG_FMT, FMT_SDPS_S):
11485 mips32_op = OPC_NEG_S;
11487 case FLOAT_2BIT_FMT(NEG_FMT, FMT_SDPS_D):
11488 mips32_op = OPC_NEG_D;
11490 case FLOAT_2BIT_FMT(NEG_FMT, FMT_SDPS_PS):
11491 mips32_op = OPC_NEG_PS;
11494 /* Reciprocal square root step */
11495 case FLOAT_2BIT_FMT(RSQRT1_FMT, FMT_SDPS_S):
11496 mips32_op = OPC_RSQRT1_S;
11498 case FLOAT_2BIT_FMT(RSQRT1_FMT, FMT_SDPS_D):
11499 mips32_op = OPC_RSQRT1_D;
11501 case FLOAT_2BIT_FMT(RSQRT1_FMT, FMT_SDPS_PS):
11502 mips32_op = OPC_RSQRT1_PS;
11505 /* Reciprocal step */
11506 case FLOAT_2BIT_FMT(RECIP1_FMT, FMT_SDPS_S):
11507 mips32_op = OPC_RECIP1_S;
11509 case FLOAT_2BIT_FMT(RECIP1_FMT, FMT_SDPS_D):
11510 mips32_op = OPC_RECIP1_S;
11512 case FLOAT_2BIT_FMT(RECIP1_FMT, FMT_SDPS_PS):
11513 mips32_op = OPC_RECIP1_PS;
11516 /* Conversions from double */
11517 case FLOAT_2BIT_FMT(CVT_D, FMT_SWL_S):
11518 mips32_op = OPC_CVT_D_S;
11520 case FLOAT_2BIT_FMT(CVT_D, FMT_SWL_W):
11521 mips32_op = OPC_CVT_D_W;
11523 case FLOAT_2BIT_FMT(CVT_D, FMT_SWL_L):
11524 mips32_op = OPC_CVT_D_L;
11527 /* Conversions from single */
11528 case FLOAT_2BIT_FMT(CVT_S, FMT_DWL_D):
11529 mips32_op = OPC_CVT_S_D;
11531 case FLOAT_2BIT_FMT(CVT_S, FMT_DWL_W):
11532 mips32_op = OPC_CVT_S_W;
11534 case FLOAT_2BIT_FMT(CVT_S, FMT_DWL_L):
11535 mips32_op = OPC_CVT_S_L;
11537 gen_farith(ctx, mips32_op, -1, rs, rt, 0);
11540 /* Conditional moves on floating-point codes */
11541 case COND_FLOAT_MOV(MOVT, 0):
11542 case COND_FLOAT_MOV(MOVT, 1):
11543 case COND_FLOAT_MOV(MOVT, 2):
11544 case COND_FLOAT_MOV(MOVT, 3):
11545 case COND_FLOAT_MOV(MOVT, 4):
11546 case COND_FLOAT_MOV(MOVT, 5):
11547 case COND_FLOAT_MOV(MOVT, 6):
11548 case COND_FLOAT_MOV(MOVT, 7):
11549 gen_movci(ctx, rt, rs, (ctx->opcode >> 13) & 0x7, 1);
11551 case COND_FLOAT_MOV(MOVF, 0):
11552 case COND_FLOAT_MOV(MOVF, 1):
11553 case COND_FLOAT_MOV(MOVF, 2):
11554 case COND_FLOAT_MOV(MOVF, 3):
11555 case COND_FLOAT_MOV(MOVF, 4):
11556 case COND_FLOAT_MOV(MOVF, 5):
11557 case COND_FLOAT_MOV(MOVF, 6):
11558 case COND_FLOAT_MOV(MOVF, 7):
11559 gen_movci(ctx, rt, rs, (ctx->opcode >> 13) & 0x7, 0);
11562 MIPS_INVAL("pool32fxf");
11563 generate_exception(ctx, EXCP_RI);
11568 static void decode_micromips32_opc (CPUMIPSState *env, DisasContext *ctx,
11569 uint16_t insn_hw1, int *is_branch)
11573 int rt, rs, rd, rr;
11575 uint32_t op, minor, mips32_op;
11576 uint32_t cond, fmt, cc;
11578 insn = cpu_lduw_code(env, ctx->pc + 2);
11579 ctx->opcode = (ctx->opcode << 16) | insn;
11581 rt = (ctx->opcode >> 21) & 0x1f;
11582 rs = (ctx->opcode >> 16) & 0x1f;
11583 rd = (ctx->opcode >> 11) & 0x1f;
11584 rr = (ctx->opcode >> 6) & 0x1f;
11585 imm = (int16_t) ctx->opcode;
11587 op = (ctx->opcode >> 26) & 0x3f;
11590 minor = ctx->opcode & 0x3f;
11593 minor = (ctx->opcode >> 6) & 0xf;
11596 mips32_op = OPC_SLL;
11599 mips32_op = OPC_SRA;
11602 mips32_op = OPC_SRL;
11605 mips32_op = OPC_ROTR;
11607 gen_shift_imm(env, ctx, mips32_op, rt, rs, rd);
11610 goto pool32a_invalid;
11614 minor = (ctx->opcode >> 6) & 0xf;
11618 mips32_op = OPC_ADD;
11621 mips32_op = OPC_ADDU;
11624 mips32_op = OPC_SUB;
11627 mips32_op = OPC_SUBU;
11630 mips32_op = OPC_MUL;
11632 gen_arith(env, ctx, mips32_op, rd, rs, rt);
11636 mips32_op = OPC_SLLV;
11639 mips32_op = OPC_SRLV;
11642 mips32_op = OPC_SRAV;
11645 mips32_op = OPC_ROTRV;
11647 gen_shift(env, ctx, mips32_op, rd, rs, rt);
11649 /* Logical operations */
11651 mips32_op = OPC_AND;
11654 mips32_op = OPC_OR;
11657 mips32_op = OPC_NOR;
11660 mips32_op = OPC_XOR;
11662 gen_logic(env, ctx, mips32_op, rd, rs, rt);
11664 /* Set less than */
11666 mips32_op = OPC_SLT;
11669 mips32_op = OPC_SLTU;
11671 gen_slt(env, ctx, mips32_op, rd, rs, rt);
11674 goto pool32a_invalid;
11678 minor = (ctx->opcode >> 6) & 0xf;
11680 /* Conditional moves */
11682 mips32_op = OPC_MOVN;
11685 mips32_op = OPC_MOVZ;
11687 gen_cond_move(env, ctx, mips32_op, rd, rs, rt);
11690 gen_ldxs(ctx, rs, rt, rd);
11693 goto pool32a_invalid;
11697 gen_bitops(ctx, OPC_INS, rt, rs, rr, rd);
11700 gen_bitops(ctx, OPC_EXT, rt, rs, rr, rd);
11703 gen_pool32axf(env, ctx, rt, rs, is_branch);
11706 generate_exception(ctx, EXCP_BREAK);
11710 MIPS_INVAL("pool32a");
11711 generate_exception(ctx, EXCP_RI);
11716 minor = (ctx->opcode >> 12) & 0xf;
11719 check_cp0_enabled(ctx);
11720 /* Treat as no-op. */
11724 /* COP2: Not implemented. */
11725 generate_exception_err(ctx, EXCP_CpU, 2);
11729 #ifdef TARGET_MIPS64
11733 gen_ldst_pair(ctx, minor, rt, rs, SIMM(ctx->opcode, 0, 12));
11737 #ifdef TARGET_MIPS64
11741 gen_ldst_multiple(ctx, minor, rt, rs, SIMM(ctx->opcode, 0, 12));
11744 MIPS_INVAL("pool32b");
11745 generate_exception(ctx, EXCP_RI);
11750 if (env->CP0_Config1 & (1 << CP0C1_FP)) {
11751 minor = ctx->opcode & 0x3f;
11752 check_cp1_enabled(ctx);
11755 mips32_op = OPC_ALNV_PS;
11758 mips32_op = OPC_MADD_S;
11761 mips32_op = OPC_MADD_D;
11764 mips32_op = OPC_MADD_PS;
11767 mips32_op = OPC_MSUB_S;
11770 mips32_op = OPC_MSUB_D;
11773 mips32_op = OPC_MSUB_PS;
11776 mips32_op = OPC_NMADD_S;
11779 mips32_op = OPC_NMADD_D;
11782 mips32_op = OPC_NMADD_PS;
11785 mips32_op = OPC_NMSUB_S;
11788 mips32_op = OPC_NMSUB_D;
11791 mips32_op = OPC_NMSUB_PS;
11793 gen_flt3_arith(ctx, mips32_op, rd, rr, rs, rt);
11795 case CABS_COND_FMT:
11796 cond = (ctx->opcode >> 6) & 0xf;
11797 cc = (ctx->opcode >> 13) & 0x7;
11798 fmt = (ctx->opcode >> 10) & 0x3;
11801 gen_cmpabs_s(ctx, cond, rt, rs, cc);
11804 gen_cmpabs_d(ctx, cond, rt, rs, cc);
11807 gen_cmpabs_ps(ctx, cond, rt, rs, cc);
11810 goto pool32f_invalid;
11814 cond = (ctx->opcode >> 6) & 0xf;
11815 cc = (ctx->opcode >> 13) & 0x7;
11816 fmt = (ctx->opcode >> 10) & 0x3;
11819 gen_cmp_s(ctx, cond, rt, rs, cc);
11822 gen_cmp_d(ctx, cond, rt, rs, cc);
11825 gen_cmp_ps(ctx, cond, rt, rs, cc);
11828 goto pool32f_invalid;
11832 gen_pool32fxf(env, ctx, rt, rs);
11836 switch ((ctx->opcode >> 6) & 0x7) {
11838 mips32_op = OPC_PLL_PS;
11841 mips32_op = OPC_PLU_PS;
11844 mips32_op = OPC_PUL_PS;
11847 mips32_op = OPC_PUU_PS;
11850 mips32_op = OPC_CVT_PS_S;
11852 gen_farith(ctx, mips32_op, rt, rs, rd, 0);
11855 goto pool32f_invalid;
11860 switch ((ctx->opcode >> 6) & 0x7) {
11862 mips32_op = OPC_LWXC1;
11865 mips32_op = OPC_SWXC1;
11868 mips32_op = OPC_LDXC1;
11871 mips32_op = OPC_SDXC1;
11874 mips32_op = OPC_LUXC1;
11877 mips32_op = OPC_SUXC1;
11879 gen_flt3_ldst(ctx, mips32_op, rd, rd, rt, rs);
11882 goto pool32f_invalid;
11887 fmt = (ctx->opcode >> 9) & 0x3;
11888 switch ((ctx->opcode >> 6) & 0x7) {
11892 mips32_op = OPC_RSQRT2_S;
11895 mips32_op = OPC_RSQRT2_D;
11898 mips32_op = OPC_RSQRT2_PS;
11901 goto pool32f_invalid;
11907 mips32_op = OPC_RECIP2_S;
11910 mips32_op = OPC_RECIP2_D;
11913 mips32_op = OPC_RECIP2_PS;
11916 goto pool32f_invalid;
11920 mips32_op = OPC_ADDR_PS;
11923 mips32_op = OPC_MULR_PS;
11925 gen_farith(ctx, mips32_op, rt, rs, rd, 0);
11928 goto pool32f_invalid;
11932 /* MOV[FT].fmt and PREFX */
11933 cc = (ctx->opcode >> 13) & 0x7;
11934 fmt = (ctx->opcode >> 9) & 0x3;
11935 switch ((ctx->opcode >> 6) & 0x7) {
11939 gen_movcf_s(rs, rt, cc, 0);
11942 gen_movcf_d(ctx, rs, rt, cc, 0);
11945 gen_movcf_ps(rs, rt, cc, 0);
11948 goto pool32f_invalid;
11954 gen_movcf_s(rs, rt, cc, 1);
11957 gen_movcf_d(ctx, rs, rt, cc, 1);
11960 gen_movcf_ps(rs, rt, cc, 1);
11963 goto pool32f_invalid;
11969 goto pool32f_invalid;
11972 #define FINSN_3ARG_SDPS(prfx) \
11973 switch ((ctx->opcode >> 8) & 0x3) { \
11975 mips32_op = OPC_##prfx##_S; \
11978 mips32_op = OPC_##prfx##_D; \
11980 case FMT_SDPS_PS: \
11981 mips32_op = OPC_##prfx##_PS; \
11984 goto pool32f_invalid; \
11987 /* regular FP ops */
11988 switch ((ctx->opcode >> 6) & 0x3) {
11990 FINSN_3ARG_SDPS(ADD);
11993 FINSN_3ARG_SDPS(SUB);
11996 FINSN_3ARG_SDPS(MUL);
11999 fmt = (ctx->opcode >> 8) & 0x3;
12001 mips32_op = OPC_DIV_D;
12002 } else if (fmt == 0) {
12003 mips32_op = OPC_DIV_S;
12005 goto pool32f_invalid;
12009 goto pool32f_invalid;
12014 switch ((ctx->opcode >> 6) & 0x3) {
12016 FINSN_3ARG_SDPS(MOVN);
12019 FINSN_3ARG_SDPS(MOVZ);
12022 goto pool32f_invalid;
12026 gen_farith(ctx, mips32_op, rt, rs, rd, 0);
12030 MIPS_INVAL("pool32f");
12031 generate_exception(ctx, EXCP_RI);
12035 generate_exception_err(ctx, EXCP_CpU, 1);
12039 minor = (ctx->opcode >> 21) & 0x1f;
12042 mips32_op = OPC_BLTZ;
12045 mips32_op = OPC_BLTZAL;
12048 mips32_op = OPC_BLTZALS;
12051 mips32_op = OPC_BGEZ;
12054 mips32_op = OPC_BGEZAL;
12057 mips32_op = OPC_BGEZALS;
12060 mips32_op = OPC_BLEZ;
12063 mips32_op = OPC_BGTZ;
12065 gen_compute_branch(ctx, mips32_op, 4, rs, -1, imm << 1);
12071 mips32_op = OPC_TLTI;
12074 mips32_op = OPC_TGEI;
12077 mips32_op = OPC_TLTIU;
12080 mips32_op = OPC_TGEIU;
12083 mips32_op = OPC_TNEI;
12086 mips32_op = OPC_TEQI;
12088 gen_trap(ctx, mips32_op, rs, -1, imm);
12093 gen_compute_branch(ctx, minor == BNEZC ? OPC_BNE : OPC_BEQ,
12094 4, rs, 0, imm << 1);
12095 /* Compact branches don't have a delay slot, so just let
12096 the normal delay slot handling take us to the branch
12100 gen_logic_imm(env, ctx, OPC_LUI, rs, -1, imm);
12106 /* COP2: Not implemented. */
12107 generate_exception_err(ctx, EXCP_CpU, 2);
12110 mips32_op = (ctx->opcode & (1 << 16)) ? OPC_BC1FANY2 : OPC_BC1F;
12113 mips32_op = (ctx->opcode & (1 << 16)) ? OPC_BC1TANY2 : OPC_BC1T;
12116 mips32_op = OPC_BC1FANY4;
12119 mips32_op = OPC_BC1TANY4;
12122 check_insn(env, ctx, ASE_MIPS3D);
12125 gen_compute_branch1(env, ctx, mips32_op,
12126 (ctx->opcode >> 18) & 0x7, imm << 1);
12131 /* MIPS DSP: not implemented */
12134 MIPS_INVAL("pool32i");
12135 generate_exception(ctx, EXCP_RI);
12140 minor = (ctx->opcode >> 12) & 0xf;
12143 mips32_op = OPC_LWL;
12146 mips32_op = OPC_SWL;
12149 mips32_op = OPC_LWR;
12152 mips32_op = OPC_SWR;
12154 #if defined(TARGET_MIPS64)
12156 mips32_op = OPC_LDL;
12159 mips32_op = OPC_SDL;
12162 mips32_op = OPC_LDR;
12165 mips32_op = OPC_SDR;
12168 mips32_op = OPC_LWU;
12171 mips32_op = OPC_LLD;
12175 mips32_op = OPC_LL;
12178 gen_ld(env, ctx, mips32_op, rt, rs, SIMM(ctx->opcode, 0, 12));
12181 gen_st(ctx, mips32_op, rt, rs, SIMM(ctx->opcode, 0, 12));
12184 gen_st_cond(ctx, OPC_SC, rt, rs, SIMM(ctx->opcode, 0, 12));
12186 #if defined(TARGET_MIPS64)
12188 gen_st_cond(ctx, OPC_SCD, rt, rs, SIMM(ctx->opcode, 0, 12));
12192 /* Treat as no-op */
12195 MIPS_INVAL("pool32c");
12196 generate_exception(ctx, EXCP_RI);
12201 mips32_op = OPC_ADDI;
12204 mips32_op = OPC_ADDIU;
12206 gen_arith_imm(env, ctx, mips32_op, rt, rs, imm);
12209 /* Logical operations */
12211 mips32_op = OPC_ORI;
12214 mips32_op = OPC_XORI;
12217 mips32_op = OPC_ANDI;
12219 gen_logic_imm(env, ctx, mips32_op, rt, rs, imm);
12222 /* Set less than immediate */
12224 mips32_op = OPC_SLTI;
12227 mips32_op = OPC_SLTIU;
12229 gen_slt_imm(env, ctx, mips32_op, rt, rs, imm);
12232 offset = (int32_t)(ctx->opcode & 0x3FFFFFF) << 2;
12233 gen_compute_branch(ctx, OPC_JALX, 4, rt, rs, offset);
12237 offset = (int32_t)(ctx->opcode & 0x3FFFFFF) << 1;
12238 gen_compute_branch(ctx, OPC_JALS, 4, rt, rs, offset);
12242 gen_compute_branch(ctx, OPC_BEQ, 4, rt, rs, imm << 1);
12246 gen_compute_branch(ctx, OPC_BNE, 4, rt, rs, imm << 1);
12250 gen_compute_branch(ctx, OPC_J, 4, rt, rs,
12251 (int32_t)(ctx->opcode & 0x3FFFFFF) << 1);
12255 gen_compute_branch(ctx, OPC_JAL, 4, rt, rs,
12256 (int32_t)(ctx->opcode & 0x3FFFFFF) << 1);
12259 /* Floating point (COP1) */
12261 mips32_op = OPC_LWC1;
12264 mips32_op = OPC_LDC1;
12267 mips32_op = OPC_SWC1;
12270 mips32_op = OPC_SDC1;
12272 gen_cop1_ldst(env, ctx, mips32_op, rt, rs, imm);
12276 int reg = mmreg(ZIMM(ctx->opcode, 23, 3));
12277 int offset = SIMM(ctx->opcode, 0, 23) << 2;
12279 gen_addiupc(ctx, reg, offset, 0, 0);
12282 /* Loads and stores */
12284 mips32_op = OPC_LB;
12287 mips32_op = OPC_LBU;
12290 mips32_op = OPC_LH;
12293 mips32_op = OPC_LHU;
12296 mips32_op = OPC_LW;
12298 #ifdef TARGET_MIPS64
12300 mips32_op = OPC_LD;
12303 mips32_op = OPC_SD;
12307 mips32_op = OPC_SB;
12310 mips32_op = OPC_SH;
12313 mips32_op = OPC_SW;
12316 gen_ld(env, ctx, mips32_op, rt, rs, imm);
12319 gen_st(ctx, mips32_op, rt, rs, imm);
12322 generate_exception(ctx, EXCP_RI);
12327 static int decode_micromips_opc (CPUMIPSState *env, DisasContext *ctx, int *is_branch)
12331 /* make sure instructions are on a halfword boundary */
12332 if (ctx->pc & 0x1) {
12333 env->CP0_BadVAddr = ctx->pc;
12334 generate_exception(ctx, EXCP_AdEL);
12335 ctx->bstate = BS_STOP;
12339 op = (ctx->opcode >> 10) & 0x3f;
12340 /* Enforce properly-sized instructions in a delay slot */
12341 if (ctx->hflags & MIPS_HFLAG_BMASK) {
12342 int bits = ctx->hflags & MIPS_HFLAG_BMASK_EXT;
12376 case POOL48A: /* ??? */
12381 if (bits & MIPS_HFLAG_BDS16) {
12382 generate_exception(ctx, EXCP_RI);
12383 /* Just stop translation; the user is confused. */
12384 ctx->bstate = BS_STOP;
12409 if (bits & MIPS_HFLAG_BDS32) {
12410 generate_exception(ctx, EXCP_RI);
12411 /* Just stop translation; the user is confused. */
12412 ctx->bstate = BS_STOP;
12423 int rd = mmreg(uMIPS_RD(ctx->opcode));
12424 int rs1 = mmreg(uMIPS_RS1(ctx->opcode));
12425 int rs2 = mmreg(uMIPS_RS2(ctx->opcode));
12428 switch (ctx->opcode & 0x1) {
12437 gen_arith(env, ctx, opc, rd, rs1, rs2);
12442 int rd = mmreg(uMIPS_RD(ctx->opcode));
12443 int rs = mmreg(uMIPS_RS(ctx->opcode));
12444 int amount = (ctx->opcode >> 1) & 0x7;
12446 amount = amount == 0 ? 8 : amount;
12448 switch (ctx->opcode & 0x1) {
12457 gen_shift_imm(env, ctx, opc, rd, rs, amount);
12461 gen_pool16c_insn(env, ctx, is_branch);
12465 int rd = mmreg(uMIPS_RD(ctx->opcode));
12466 int rb = 28; /* GP */
12467 int16_t offset = SIMM(ctx->opcode, 0, 7) << 2;
12469 gen_ld(env, ctx, OPC_LW, rd, rb, offset);
12473 if (ctx->opcode & 1) {
12474 generate_exception(ctx, EXCP_RI);
12477 int enc_dest = uMIPS_RD(ctx->opcode);
12478 int enc_rt = uMIPS_RS2(ctx->opcode);
12479 int enc_rs = uMIPS_RS1(ctx->opcode);
12480 int rd, rs, re, rt;
12481 static const int rd_enc[] = { 5, 5, 6, 4, 4, 4, 4, 4 };
12482 static const int re_enc[] = { 6, 7, 7, 21, 22, 5, 6, 7 };
12483 static const int rs_rt_enc[] = { 0, 17, 2, 3, 16, 18, 19, 20 };
12485 rd = rd_enc[enc_dest];
12486 re = re_enc[enc_dest];
12487 rs = rs_rt_enc[enc_rs];
12488 rt = rs_rt_enc[enc_rt];
12490 gen_arith_imm(env, ctx, OPC_ADDIU, rd, rs, 0);
12491 gen_arith_imm(env, ctx, OPC_ADDIU, re, rt, 0);
12496 int rd = mmreg(uMIPS_RD(ctx->opcode));
12497 int rb = mmreg(uMIPS_RS(ctx->opcode));
12498 int16_t offset = ZIMM(ctx->opcode, 0, 4);
12499 offset = (offset == 0xf ? -1 : offset);
12501 gen_ld(env, ctx, OPC_LBU, rd, rb, offset);
12506 int rd = mmreg(uMIPS_RD(ctx->opcode));
12507 int rb = mmreg(uMIPS_RS(ctx->opcode));
12508 int16_t offset = ZIMM(ctx->opcode, 0, 4) << 1;
12510 gen_ld(env, ctx, OPC_LHU, rd, rb, offset);
12515 int rd = (ctx->opcode >> 5) & 0x1f;
12516 int rb = 29; /* SP */
12517 int16_t offset = ZIMM(ctx->opcode, 0, 5) << 2;
12519 gen_ld(env, ctx, OPC_LW, rd, rb, offset);
12524 int rd = mmreg(uMIPS_RD(ctx->opcode));
12525 int rb = mmreg(uMIPS_RS(ctx->opcode));
12526 int16_t offset = ZIMM(ctx->opcode, 0, 4) << 2;
12528 gen_ld(env, ctx, OPC_LW, rd, rb, offset);
12533 int rd = mmreg2(uMIPS_RD(ctx->opcode));
12534 int rb = mmreg(uMIPS_RS(ctx->opcode));
12535 int16_t offset = ZIMM(ctx->opcode, 0, 4);
12537 gen_st(ctx, OPC_SB, rd, rb, offset);
12542 int rd = mmreg2(uMIPS_RD(ctx->opcode));
12543 int rb = mmreg(uMIPS_RS(ctx->opcode));
12544 int16_t offset = ZIMM(ctx->opcode, 0, 4) << 1;
12546 gen_st(ctx, OPC_SH, rd, rb, offset);
12551 int rd = (ctx->opcode >> 5) & 0x1f;
12552 int rb = 29; /* SP */
12553 int16_t offset = ZIMM(ctx->opcode, 0, 5) << 2;
12555 gen_st(ctx, OPC_SW, rd, rb, offset);
12560 int rd = mmreg2(uMIPS_RD(ctx->opcode));
12561 int rb = mmreg(uMIPS_RS(ctx->opcode));
12562 int16_t offset = ZIMM(ctx->opcode, 0, 4) << 2;
12564 gen_st(ctx, OPC_SW, rd, rb, offset);
12569 int rd = uMIPS_RD5(ctx->opcode);
12570 int rs = uMIPS_RS5(ctx->opcode);
12572 gen_arith_imm(env, ctx, OPC_ADDIU, rd, rs, 0);
12576 gen_andi16(env, ctx);
12579 switch (ctx->opcode & 0x1) {
12581 gen_addius5(env, ctx);
12584 gen_addiusp(env, ctx);
12589 switch (ctx->opcode & 0x1) {
12591 gen_addiur2(env, ctx);
12594 gen_addiur1sp(env, ctx);
12599 gen_compute_branch(ctx, OPC_BEQ, 2, 0, 0,
12600 SIMM(ctx->opcode, 0, 10) << 1);
12605 gen_compute_branch(ctx, op == BNEZ16 ? OPC_BNE : OPC_BEQ, 2,
12606 mmreg(uMIPS_RD(ctx->opcode)),
12607 0, SIMM(ctx->opcode, 0, 7) << 1);
12612 int reg = mmreg(uMIPS_RD(ctx->opcode));
12613 int imm = ZIMM(ctx->opcode, 0, 7);
12615 imm = (imm == 0x7f ? -1 : imm);
12616 tcg_gen_movi_tl(cpu_gpr[reg], imm);
12626 generate_exception(ctx, EXCP_RI);
12629 decode_micromips32_opc (env, ctx, op, is_branch);
12636 /* SmartMIPS extension to MIPS32 */
12638 #if defined(TARGET_MIPS64)
12640 /* MDMX extension to MIPS64 */
12644 /* MIPSDSP functions. */
12645 static void gen_mipsdsp_ld(CPUMIPSState *env, DisasContext *ctx, uint32_t opc,
12646 int rd, int base, int offset)
12648 const char *opn = "ldx";
12657 t0 = tcg_temp_new();
12660 gen_load_gpr(t0, offset);
12661 } else if (offset == 0) {
12662 gen_load_gpr(t0, base);
12664 gen_op_addr_add(ctx, t0, cpu_gpr[base], cpu_gpr[offset]);
12669 tcg_gen_qemu_ld8u(t0, t0, ctx->mem_idx);
12670 gen_store_gpr(t0, rd);
12674 tcg_gen_qemu_ld16s(t0, t0, ctx->mem_idx);
12675 gen_store_gpr(t0, rd);
12679 tcg_gen_qemu_ld32s(t0, t0, ctx->mem_idx);
12680 gen_store_gpr(t0, rd);
12683 #if defined(TARGET_MIPS64)
12685 tcg_gen_qemu_ld64(t0, t0, ctx->mem_idx);
12686 gen_store_gpr(t0, rd);
12691 (void)opn; /* avoid a compiler warning */
12692 MIPS_DEBUG("%s %s, %s(%s)", opn,
12693 regnames[rd], regnames[offset], regnames[base]);
12697 static void gen_mipsdsp_arith(DisasContext *ctx, uint32_t op1, uint32_t op2,
12698 int ret, int v1, int v2)
12700 const char *opn = "mipsdsp arith";
12705 /* Treat as NOP. */
12710 v1_t = tcg_temp_new();
12711 v2_t = tcg_temp_new();
12713 gen_load_gpr(v1_t, v1);
12714 gen_load_gpr(v2_t, v2);
12717 /* OPC_MULT_G_2E is equal OPC_ADDUH_QB_DSP */
12718 case OPC_MULT_G_2E:
12722 gen_helper_adduh_qb(cpu_gpr[ret], v1_t, v2_t);
12724 case OPC_ADDUH_R_QB:
12725 gen_helper_adduh_r_qb(cpu_gpr[ret], v1_t, v2_t);
12728 gen_helper_addqh_ph(cpu_gpr[ret], v1_t, v2_t);
12730 case OPC_ADDQH_R_PH:
12731 gen_helper_addqh_r_ph(cpu_gpr[ret], v1_t, v2_t);
12734 gen_helper_addqh_w(cpu_gpr[ret], v1_t, v2_t);
12736 case OPC_ADDQH_R_W:
12737 gen_helper_addqh_r_w(cpu_gpr[ret], v1_t, v2_t);
12740 gen_helper_subuh_qb(cpu_gpr[ret], v1_t, v2_t);
12742 case OPC_SUBUH_R_QB:
12743 gen_helper_subuh_r_qb(cpu_gpr[ret], v1_t, v2_t);
12746 gen_helper_subqh_ph(cpu_gpr[ret], v1_t, v2_t);
12748 case OPC_SUBQH_R_PH:
12749 gen_helper_subqh_r_ph(cpu_gpr[ret], v1_t, v2_t);
12752 gen_helper_subqh_w(cpu_gpr[ret], v1_t, v2_t);
12754 case OPC_SUBQH_R_W:
12755 gen_helper_subqh_r_w(cpu_gpr[ret], v1_t, v2_t);
12759 case OPC_ABSQ_S_PH_DSP:
12761 case OPC_ABSQ_S_QB:
12763 gen_helper_absq_s_qb(cpu_gpr[ret], v2_t, cpu_env);
12765 case OPC_ABSQ_S_PH:
12767 gen_helper_absq_s_ph(cpu_gpr[ret], v2_t, cpu_env);
12771 gen_helper_absq_s_w(cpu_gpr[ret], v2_t, cpu_env);
12773 case OPC_PRECEQ_W_PHL:
12775 tcg_gen_andi_tl(cpu_gpr[ret], v2_t, 0xFFFF0000);
12776 tcg_gen_ext32s_tl(cpu_gpr[ret], cpu_gpr[ret]);
12778 case OPC_PRECEQ_W_PHR:
12780 tcg_gen_andi_tl(cpu_gpr[ret], v2_t, 0x0000FFFF);
12781 tcg_gen_shli_tl(cpu_gpr[ret], cpu_gpr[ret], 16);
12782 tcg_gen_ext32s_tl(cpu_gpr[ret], cpu_gpr[ret]);
12784 case OPC_PRECEQU_PH_QBL:
12786 gen_helper_precequ_ph_qbl(cpu_gpr[ret], v2_t);
12788 case OPC_PRECEQU_PH_QBR:
12790 gen_helper_precequ_ph_qbr(cpu_gpr[ret], v2_t);
12792 case OPC_PRECEQU_PH_QBLA:
12794 gen_helper_precequ_ph_qbla(cpu_gpr[ret], v2_t);
12796 case OPC_PRECEQU_PH_QBRA:
12798 gen_helper_precequ_ph_qbra(cpu_gpr[ret], v2_t);
12800 case OPC_PRECEU_PH_QBL:
12802 gen_helper_preceu_ph_qbl(cpu_gpr[ret], v2_t);
12804 case OPC_PRECEU_PH_QBR:
12806 gen_helper_preceu_ph_qbr(cpu_gpr[ret], v2_t);
12808 case OPC_PRECEU_PH_QBLA:
12810 gen_helper_preceu_ph_qbla(cpu_gpr[ret], v2_t);
12812 case OPC_PRECEU_PH_QBRA:
12814 gen_helper_preceu_ph_qbra(cpu_gpr[ret], v2_t);
12818 case OPC_ADDU_QB_DSP:
12822 gen_helper_addq_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12824 case OPC_ADDQ_S_PH:
12826 gen_helper_addq_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12830 gen_helper_addq_s_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12834 gen_helper_addu_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12836 case OPC_ADDU_S_QB:
12838 gen_helper_addu_s_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12842 gen_helper_addu_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12844 case OPC_ADDU_S_PH:
12846 gen_helper_addu_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12850 gen_helper_subq_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12852 case OPC_SUBQ_S_PH:
12854 gen_helper_subq_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12858 gen_helper_subq_s_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12862 gen_helper_subu_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12864 case OPC_SUBU_S_QB:
12866 gen_helper_subu_s_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12870 gen_helper_subu_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12872 case OPC_SUBU_S_PH:
12874 gen_helper_subu_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12878 gen_helper_addsc(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12882 gen_helper_addwc(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12886 gen_helper_modsub(cpu_gpr[ret], v1_t, v2_t);
12888 case OPC_RADDU_W_QB:
12890 gen_helper_raddu_w_qb(cpu_gpr[ret], v1_t);
12894 case OPC_CMPU_EQ_QB_DSP:
12896 case OPC_PRECR_QB_PH:
12898 gen_helper_precr_qb_ph(cpu_gpr[ret], v1_t, v2_t);
12900 case OPC_PRECRQ_QB_PH:
12902 gen_helper_precrq_qb_ph(cpu_gpr[ret], v1_t, v2_t);
12904 case OPC_PRECR_SRA_PH_W:
12907 TCGv_i32 sa_t = tcg_const_i32(v2);
12908 gen_helper_precr_sra_ph_w(cpu_gpr[ret], sa_t, v1_t,
12910 tcg_temp_free_i32(sa_t);
12913 case OPC_PRECR_SRA_R_PH_W:
12916 TCGv_i32 sa_t = tcg_const_i32(v2);
12917 gen_helper_precr_sra_r_ph_w(cpu_gpr[ret], sa_t, v1_t,
12919 tcg_temp_free_i32(sa_t);
12922 case OPC_PRECRQ_PH_W:
12924 gen_helper_precrq_ph_w(cpu_gpr[ret], v1_t, v2_t);
12926 case OPC_PRECRQ_RS_PH_W:
12928 gen_helper_precrq_rs_ph_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12930 case OPC_PRECRQU_S_QB_PH:
12932 gen_helper_precrqu_s_qb_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12936 #ifdef TARGET_MIPS64
12937 case OPC_ABSQ_S_QH_DSP:
12939 case OPC_PRECEQ_L_PWL:
12941 tcg_gen_andi_tl(cpu_gpr[ret], v2_t, 0xFFFFFFFF00000000ull);
12943 case OPC_PRECEQ_L_PWR:
12945 tcg_gen_shli_tl(cpu_gpr[ret], v2_t, 32);
12947 case OPC_PRECEQ_PW_QHL:
12949 gen_helper_preceq_pw_qhl(cpu_gpr[ret], v2_t);
12951 case OPC_PRECEQ_PW_QHR:
12953 gen_helper_preceq_pw_qhr(cpu_gpr[ret], v2_t);
12955 case OPC_PRECEQ_PW_QHLA:
12957 gen_helper_preceq_pw_qhla(cpu_gpr[ret], v2_t);
12959 case OPC_PRECEQ_PW_QHRA:
12961 gen_helper_preceq_pw_qhra(cpu_gpr[ret], v2_t);
12963 case OPC_PRECEQU_QH_OBL:
12965 gen_helper_precequ_qh_obl(cpu_gpr[ret], v2_t);
12967 case OPC_PRECEQU_QH_OBR:
12969 gen_helper_precequ_qh_obr(cpu_gpr[ret], v2_t);
12971 case OPC_PRECEQU_QH_OBLA:
12973 gen_helper_precequ_qh_obla(cpu_gpr[ret], v2_t);
12975 case OPC_PRECEQU_QH_OBRA:
12977 gen_helper_precequ_qh_obra(cpu_gpr[ret], v2_t);
12979 case OPC_PRECEU_QH_OBL:
12981 gen_helper_preceu_qh_obl(cpu_gpr[ret], v2_t);
12983 case OPC_PRECEU_QH_OBR:
12985 gen_helper_preceu_qh_obr(cpu_gpr[ret], v2_t);
12987 case OPC_PRECEU_QH_OBLA:
12989 gen_helper_preceu_qh_obla(cpu_gpr[ret], v2_t);
12991 case OPC_PRECEU_QH_OBRA:
12993 gen_helper_preceu_qh_obra(cpu_gpr[ret], v2_t);
12995 case OPC_ABSQ_S_OB:
12997 gen_helper_absq_s_ob(cpu_gpr[ret], v2_t, cpu_env);
12999 case OPC_ABSQ_S_PW:
13001 gen_helper_absq_s_pw(cpu_gpr[ret], v2_t, cpu_env);
13003 case OPC_ABSQ_S_QH:
13005 gen_helper_absq_s_qh(cpu_gpr[ret], v2_t, cpu_env);
13009 case OPC_ADDU_OB_DSP:
13011 case OPC_RADDU_L_OB:
13013 gen_helper_raddu_l_ob(cpu_gpr[ret], v1_t);
13017 gen_helper_subq_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13019 case OPC_SUBQ_S_PW:
13021 gen_helper_subq_s_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13025 gen_helper_subq_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13027 case OPC_SUBQ_S_QH:
13029 gen_helper_subq_s_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13033 gen_helper_subu_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13035 case OPC_SUBU_S_OB:
13037 gen_helper_subu_s_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13041 gen_helper_subu_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13043 case OPC_SUBU_S_QH:
13045 gen_helper_subu_s_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13049 gen_helper_subuh_ob(cpu_gpr[ret], v1_t, v2_t);
13051 case OPC_SUBUH_R_OB:
13053 gen_helper_subuh_r_ob(cpu_gpr[ret], v1_t, v2_t);
13057 gen_helper_addq_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13059 case OPC_ADDQ_S_PW:
13061 gen_helper_addq_s_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13065 gen_helper_addq_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13067 case OPC_ADDQ_S_QH:
13069 gen_helper_addq_s_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13073 gen_helper_addu_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13075 case OPC_ADDU_S_OB:
13077 gen_helper_addu_s_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13081 gen_helper_addu_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13083 case OPC_ADDU_S_QH:
13085 gen_helper_addu_s_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13089 gen_helper_adduh_ob(cpu_gpr[ret], v1_t, v2_t);
13091 case OPC_ADDUH_R_OB:
13093 gen_helper_adduh_r_ob(cpu_gpr[ret], v1_t, v2_t);
13097 case OPC_CMPU_EQ_OB_DSP:
13099 case OPC_PRECR_OB_QH:
13101 gen_helper_precr_ob_qh(cpu_gpr[ret], v1_t, v2_t);
13103 case OPC_PRECR_SRA_QH_PW:
13106 TCGv_i32 ret_t = tcg_const_i32(ret);
13107 gen_helper_precr_sra_qh_pw(v2_t, v1_t, v2_t, ret_t);
13108 tcg_temp_free_i32(ret_t);
13111 case OPC_PRECR_SRA_R_QH_PW:
13114 TCGv_i32 sa_v = tcg_const_i32(ret);
13115 gen_helper_precr_sra_r_qh_pw(v2_t, v1_t, v2_t, sa_v);
13116 tcg_temp_free_i32(sa_v);
13119 case OPC_PRECRQ_OB_QH:
13121 gen_helper_precrq_ob_qh(cpu_gpr[ret], v1_t, v2_t);
13123 case OPC_PRECRQ_PW_L:
13125 gen_helper_precrq_pw_l(cpu_gpr[ret], v1_t, v2_t);
13127 case OPC_PRECRQ_QH_PW:
13129 gen_helper_precrq_qh_pw(cpu_gpr[ret], v1_t, v2_t);
13131 case OPC_PRECRQ_RS_QH_PW:
13133 gen_helper_precrq_rs_qh_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13135 case OPC_PRECRQU_S_OB_QH:
13137 gen_helper_precrqu_s_ob_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13144 tcg_temp_free(v1_t);
13145 tcg_temp_free(v2_t);
13147 (void)opn; /* avoid a compiler warning */
13148 MIPS_DEBUG("%s", opn);
13151 static void gen_mipsdsp_shift(DisasContext *ctx, uint32_t opc,
13152 int ret, int v1, int v2)
13155 const char *opn = "mipsdsp shift";
13161 /* Treat as NOP. */
13166 t0 = tcg_temp_new();
13167 v1_t = tcg_temp_new();
13168 v2_t = tcg_temp_new();
13170 tcg_gen_movi_tl(t0, v1);
13171 gen_load_gpr(v1_t, v1);
13172 gen_load_gpr(v2_t, v2);
13175 case OPC_SHLL_QB_DSP:
13177 op2 = MASK_SHLL_QB(ctx->opcode);
13181 gen_helper_shll_qb(cpu_gpr[ret], t0, v2_t, cpu_env);
13185 gen_helper_shll_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13189 gen_helper_shll_ph(cpu_gpr[ret], t0, v2_t, cpu_env);
13193 gen_helper_shll_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13195 case OPC_SHLL_S_PH:
13197 gen_helper_shll_s_ph(cpu_gpr[ret], t0, v2_t, cpu_env);
13199 case OPC_SHLLV_S_PH:
13201 gen_helper_shll_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13205 gen_helper_shll_s_w(cpu_gpr[ret], t0, v2_t, cpu_env);
13207 case OPC_SHLLV_S_W:
13209 gen_helper_shll_s_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13213 gen_helper_shrl_qb(cpu_gpr[ret], t0, v2_t);
13217 gen_helper_shrl_qb(cpu_gpr[ret], v1_t, v2_t);
13221 gen_helper_shrl_ph(cpu_gpr[ret], t0, v2_t);
13225 gen_helper_shrl_ph(cpu_gpr[ret], v1_t, v2_t);
13229 gen_helper_shra_qb(cpu_gpr[ret], t0, v2_t);
13231 case OPC_SHRA_R_QB:
13233 gen_helper_shra_r_qb(cpu_gpr[ret], t0, v2_t);
13237 gen_helper_shra_qb(cpu_gpr[ret], v1_t, v2_t);
13239 case OPC_SHRAV_R_QB:
13241 gen_helper_shra_r_qb(cpu_gpr[ret], v1_t, v2_t);
13245 gen_helper_shra_ph(cpu_gpr[ret], t0, v2_t);
13247 case OPC_SHRA_R_PH:
13249 gen_helper_shra_r_ph(cpu_gpr[ret], t0, v2_t);
13253 gen_helper_shra_ph(cpu_gpr[ret], v1_t, v2_t);
13255 case OPC_SHRAV_R_PH:
13257 gen_helper_shra_r_ph(cpu_gpr[ret], v1_t, v2_t);
13261 gen_helper_shra_r_w(cpu_gpr[ret], t0, v2_t);
13263 case OPC_SHRAV_R_W:
13265 gen_helper_shra_r_w(cpu_gpr[ret], v1_t, v2_t);
13267 default: /* Invalid */
13268 MIPS_INVAL("MASK SHLL.QB");
13269 generate_exception(ctx, EXCP_RI);
13274 #ifdef TARGET_MIPS64
13275 case OPC_SHLL_OB_DSP:
13276 op2 = MASK_SHLL_OB(ctx->opcode);
13280 gen_helper_shll_pw(cpu_gpr[ret], v2_t, t0, cpu_env);
13284 gen_helper_shll_pw(cpu_gpr[ret], v2_t, v1_t, cpu_env);
13286 case OPC_SHLL_S_PW:
13288 gen_helper_shll_s_pw(cpu_gpr[ret], v2_t, t0, cpu_env);
13290 case OPC_SHLLV_S_PW:
13292 gen_helper_shll_s_pw(cpu_gpr[ret], v2_t, v1_t, cpu_env);
13296 gen_helper_shll_ob(cpu_gpr[ret], v2_t, t0, cpu_env);
13300 gen_helper_shll_ob(cpu_gpr[ret], v2_t, v1_t, cpu_env);
13304 gen_helper_shll_qh(cpu_gpr[ret], v2_t, t0, cpu_env);
13308 gen_helper_shll_qh(cpu_gpr[ret], v2_t, v1_t, cpu_env);
13310 case OPC_SHLL_S_QH:
13312 gen_helper_shll_s_qh(cpu_gpr[ret], v2_t, t0, cpu_env);
13314 case OPC_SHLLV_S_QH:
13316 gen_helper_shll_s_qh(cpu_gpr[ret], v2_t, v1_t, cpu_env);
13320 gen_helper_shra_ob(cpu_gpr[ret], v2_t, t0);
13324 gen_helper_shra_ob(cpu_gpr[ret], v2_t, v1_t);
13326 case OPC_SHRA_R_OB:
13328 gen_helper_shra_r_ob(cpu_gpr[ret], v2_t, t0);
13330 case OPC_SHRAV_R_OB:
13332 gen_helper_shra_r_ob(cpu_gpr[ret], v2_t, v1_t);
13336 gen_helper_shra_pw(cpu_gpr[ret], v2_t, t0);
13340 gen_helper_shra_pw(cpu_gpr[ret], v2_t, v1_t);
13342 case OPC_SHRA_R_PW:
13344 gen_helper_shra_r_pw(cpu_gpr[ret], v2_t, t0);
13346 case OPC_SHRAV_R_PW:
13348 gen_helper_shra_r_pw(cpu_gpr[ret], v2_t, v1_t);
13352 gen_helper_shra_qh(cpu_gpr[ret], v2_t, t0);
13356 gen_helper_shra_qh(cpu_gpr[ret], v2_t, v1_t);
13358 case OPC_SHRA_R_QH:
13360 gen_helper_shra_r_qh(cpu_gpr[ret], v2_t, t0);
13362 case OPC_SHRAV_R_QH:
13364 gen_helper_shra_r_qh(cpu_gpr[ret], v2_t, v1_t);
13368 gen_helper_shrl_ob(cpu_gpr[ret], v2_t, t0);
13372 gen_helper_shrl_ob(cpu_gpr[ret], v2_t, v1_t);
13376 gen_helper_shrl_qh(cpu_gpr[ret], v2_t, t0);
13380 gen_helper_shrl_qh(cpu_gpr[ret], v2_t, v1_t);
13382 default: /* Invalid */
13383 MIPS_INVAL("MASK SHLL.OB");
13384 generate_exception(ctx, EXCP_RI);
13392 tcg_temp_free(v1_t);
13393 tcg_temp_free(v2_t);
13394 (void)opn; /* avoid a compiler warning */
13395 MIPS_DEBUG("%s", opn);
13398 static void gen_mipsdsp_multiply(DisasContext *ctx, uint32_t op1, uint32_t op2,
13399 int ret, int v1, int v2, int check_ret)
13401 const char *opn = "mipsdsp multiply";
13406 if ((ret == 0) && (check_ret == 1)) {
13407 /* Treat as NOP. */
13412 t0 = tcg_temp_new_i32();
13413 v1_t = tcg_temp_new();
13414 v2_t = tcg_temp_new();
13416 tcg_gen_movi_i32(t0, ret);
13417 gen_load_gpr(v1_t, v1);
13418 gen_load_gpr(v2_t, v2);
13421 /* OPC_MULT_G_2E, OPC_ADDUH_QB_DSP, OPC_MUL_PH_DSP have
13422 * the same mask and op1. */
13423 case OPC_MULT_G_2E:
13426 gen_helper_mul_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13429 gen_helper_mul_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13432 gen_helper_mulq_s_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13434 case OPC_MULQ_RS_W:
13435 gen_helper_mulq_rs_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13439 case OPC_DPA_W_PH_DSP:
13441 case OPC_DPAU_H_QBL:
13443 gen_helper_dpau_h_qbl(t0, v1_t, v2_t, cpu_env);
13445 case OPC_DPAU_H_QBR:
13447 gen_helper_dpau_h_qbr(t0, v1_t, v2_t, cpu_env);
13449 case OPC_DPSU_H_QBL:
13451 gen_helper_dpsu_h_qbl(t0, v1_t, v2_t, cpu_env);
13453 case OPC_DPSU_H_QBR:
13455 gen_helper_dpsu_h_qbr(t0, v1_t, v2_t, cpu_env);
13459 gen_helper_dpa_w_ph(t0, v1_t, v2_t, cpu_env);
13461 case OPC_DPAX_W_PH:
13463 gen_helper_dpax_w_ph(t0, v1_t, v2_t, cpu_env);
13465 case OPC_DPAQ_S_W_PH:
13467 gen_helper_dpaq_s_w_ph(t0, v1_t, v2_t, cpu_env);
13469 case OPC_DPAQX_S_W_PH:
13471 gen_helper_dpaqx_s_w_ph(t0, v1_t, v2_t, cpu_env);
13473 case OPC_DPAQX_SA_W_PH:
13475 gen_helper_dpaqx_sa_w_ph(t0, v1_t, v2_t, cpu_env);
13479 gen_helper_dps_w_ph(t0, v1_t, v2_t, cpu_env);
13481 case OPC_DPSX_W_PH:
13483 gen_helper_dpsx_w_ph(t0, v1_t, v2_t, cpu_env);
13485 case OPC_DPSQ_S_W_PH:
13487 gen_helper_dpsq_s_w_ph(t0, v1_t, v2_t, cpu_env);
13489 case OPC_DPSQX_S_W_PH:
13491 gen_helper_dpsqx_s_w_ph(t0, v1_t, v2_t, cpu_env);
13493 case OPC_DPSQX_SA_W_PH:
13495 gen_helper_dpsqx_sa_w_ph(t0, v1_t, v2_t, cpu_env);
13497 case OPC_MULSAQ_S_W_PH:
13499 gen_helper_mulsaq_s_w_ph(t0, v1_t, v2_t, cpu_env);
13501 case OPC_DPAQ_SA_L_W:
13503 gen_helper_dpaq_sa_l_w(t0, v1_t, v2_t, cpu_env);
13505 case OPC_DPSQ_SA_L_W:
13507 gen_helper_dpsq_sa_l_w(t0, v1_t, v2_t, cpu_env);
13509 case OPC_MAQ_S_W_PHL:
13511 gen_helper_maq_s_w_phl(t0, v1_t, v2_t, cpu_env);
13513 case OPC_MAQ_S_W_PHR:
13515 gen_helper_maq_s_w_phr(t0, v1_t, v2_t, cpu_env);
13517 case OPC_MAQ_SA_W_PHL:
13519 gen_helper_maq_sa_w_phl(t0, v1_t, v2_t, cpu_env);
13521 case OPC_MAQ_SA_W_PHR:
13523 gen_helper_maq_sa_w_phr(t0, v1_t, v2_t, cpu_env);
13525 case OPC_MULSA_W_PH:
13527 gen_helper_mulsa_w_ph(t0, v1_t, v2_t, cpu_env);
13531 #ifdef TARGET_MIPS64
13532 case OPC_DPAQ_W_QH_DSP:
13534 int ac = ret & 0x03;
13535 tcg_gen_movi_i32(t0, ac);
13540 gen_helper_dmadd(v1_t, v2_t, t0, cpu_env);
13544 gen_helper_dmaddu(v1_t, v2_t, t0, cpu_env);
13548 gen_helper_dmsub(v1_t, v2_t, t0, cpu_env);
13552 gen_helper_dmsubu(v1_t, v2_t, t0, cpu_env);
13556 gen_helper_dpa_w_qh(v1_t, v2_t, t0, cpu_env);
13558 case OPC_DPAQ_S_W_QH:
13560 gen_helper_dpaq_s_w_qh(v1_t, v2_t, t0, cpu_env);
13562 case OPC_DPAQ_SA_L_PW:
13564 gen_helper_dpaq_sa_l_pw(v1_t, v2_t, t0, cpu_env);
13566 case OPC_DPAU_H_OBL:
13568 gen_helper_dpau_h_obl(v1_t, v2_t, t0, cpu_env);
13570 case OPC_DPAU_H_OBR:
13572 gen_helper_dpau_h_obr(v1_t, v2_t, t0, cpu_env);
13576 gen_helper_dps_w_qh(v1_t, v2_t, t0, cpu_env);
13578 case OPC_DPSQ_S_W_QH:
13580 gen_helper_dpsq_s_w_qh(v1_t, v2_t, t0, cpu_env);
13582 case OPC_DPSQ_SA_L_PW:
13584 gen_helper_dpsq_sa_l_pw(v1_t, v2_t, t0, cpu_env);
13586 case OPC_DPSU_H_OBL:
13588 gen_helper_dpsu_h_obl(v1_t, v2_t, t0, cpu_env);
13590 case OPC_DPSU_H_OBR:
13592 gen_helper_dpsu_h_obr(v1_t, v2_t, t0, cpu_env);
13594 case OPC_MAQ_S_L_PWL:
13596 gen_helper_maq_s_l_pwl(v1_t, v2_t, t0, cpu_env);
13598 case OPC_MAQ_S_L_PWR:
13600 gen_helper_maq_s_l_pwr(v1_t, v2_t, t0, cpu_env);
13602 case OPC_MAQ_S_W_QHLL:
13604 gen_helper_maq_s_w_qhll(v1_t, v2_t, t0, cpu_env);
13606 case OPC_MAQ_SA_W_QHLL:
13608 gen_helper_maq_sa_w_qhll(v1_t, v2_t, t0, cpu_env);
13610 case OPC_MAQ_S_W_QHLR:
13612 gen_helper_maq_s_w_qhlr(v1_t, v2_t, t0, cpu_env);
13614 case OPC_MAQ_SA_W_QHLR:
13616 gen_helper_maq_sa_w_qhlr(v1_t, v2_t, t0, cpu_env);
13618 case OPC_MAQ_S_W_QHRL:
13620 gen_helper_maq_s_w_qhrl(v1_t, v2_t, t0, cpu_env);
13622 case OPC_MAQ_SA_W_QHRL:
13624 gen_helper_maq_sa_w_qhrl(v1_t, v2_t, t0, cpu_env);
13626 case OPC_MAQ_S_W_QHRR:
13628 gen_helper_maq_s_w_qhrr(v1_t, v2_t, t0, cpu_env);
13630 case OPC_MAQ_SA_W_QHRR:
13632 gen_helper_maq_sa_w_qhrr(v1_t, v2_t, t0, cpu_env);
13634 case OPC_MULSAQ_S_L_PW:
13636 gen_helper_mulsaq_s_l_pw(v1_t, v2_t, t0, cpu_env);
13638 case OPC_MULSAQ_S_W_QH:
13640 gen_helper_mulsaq_s_w_qh(v1_t, v2_t, t0, cpu_env);
13646 case OPC_ADDU_QB_DSP:
13648 case OPC_MULEU_S_PH_QBL:
13650 gen_helper_muleu_s_ph_qbl(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13652 case OPC_MULEU_S_PH_QBR:
13654 gen_helper_muleu_s_ph_qbr(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13656 case OPC_MULQ_RS_PH:
13658 gen_helper_mulq_rs_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13660 case OPC_MULEQ_S_W_PHL:
13662 gen_helper_muleq_s_w_phl(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13664 case OPC_MULEQ_S_W_PHR:
13666 gen_helper_muleq_s_w_phr(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13668 case OPC_MULQ_S_PH:
13670 gen_helper_mulq_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13674 #ifdef TARGET_MIPS64
13675 case OPC_ADDU_OB_DSP:
13677 case OPC_MULEQ_S_PW_QHL:
13679 gen_helper_muleq_s_pw_qhl(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13681 case OPC_MULEQ_S_PW_QHR:
13683 gen_helper_muleq_s_pw_qhr(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13685 case OPC_MULEU_S_QH_OBL:
13687 gen_helper_muleu_s_qh_obl(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13689 case OPC_MULEU_S_QH_OBR:
13691 gen_helper_muleu_s_qh_obr(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13693 case OPC_MULQ_RS_QH:
13695 gen_helper_mulq_rs_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13702 tcg_temp_free_i32(t0);
13703 tcg_temp_free(v1_t);
13704 tcg_temp_free(v2_t);
13706 (void)opn; /* avoid a compiler warning */
13707 MIPS_DEBUG("%s", opn);
13711 static void gen_mipsdsp_bitinsn(CPUMIPSState *env, DisasContext *ctx,
13712 uint32_t op1, uint32_t op2,
13715 const char *opn = "mipsdsp Bit/ Manipulation";
13721 /* Treat as NOP. */
13726 t0 = tcg_temp_new();
13727 val_t = tcg_temp_new();
13728 gen_load_gpr(val_t, val);
13731 case OPC_ABSQ_S_PH_DSP:
13735 gen_helper_bitrev(cpu_gpr[ret], val_t);
13740 target_long result;
13741 imm = (ctx->opcode >> 16) & 0xFF;
13742 result = (uint32_t)imm << 24 |
13743 (uint32_t)imm << 16 |
13744 (uint32_t)imm << 8 |
13746 result = (int32_t)result;
13747 tcg_gen_movi_tl(cpu_gpr[ret], result);
13752 tcg_gen_ext8u_tl(cpu_gpr[ret], val_t);
13753 tcg_gen_shli_tl(t0, cpu_gpr[ret], 8);
13754 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
13755 tcg_gen_shli_tl(t0, cpu_gpr[ret], 16);
13756 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
13757 tcg_gen_ext32s_tl(cpu_gpr[ret], cpu_gpr[ret]);
13762 imm = (ctx->opcode >> 16) & 0x03FF;
13763 tcg_gen_movi_tl(cpu_gpr[ret], \
13764 (target_long)((int32_t)imm << 16 | \
13765 (uint32_t)(uint16_t)imm));
13770 tcg_gen_ext16u_tl(cpu_gpr[ret], val_t);
13771 tcg_gen_shli_tl(t0, cpu_gpr[ret], 16);
13772 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
13773 tcg_gen_ext32s_tl(cpu_gpr[ret], cpu_gpr[ret]);
13777 #ifdef TARGET_MIPS64
13778 case OPC_ABSQ_S_QH_DSP:
13785 imm = (ctx->opcode >> 16) & 0xFF;
13786 temp = ((uint64_t)imm << 8) | (uint64_t)imm;
13787 temp = (temp << 16) | temp;
13788 temp = (temp << 32) | temp;
13789 tcg_gen_movi_tl(cpu_gpr[ret], temp);
13797 imm = (ctx->opcode >> 16) & 0x03FF;
13798 imm = (int16_t)(imm << 6) >> 6;
13799 temp = ((target_long)imm << 32) \
13800 | ((target_long)imm & 0xFFFFFFFF);
13801 tcg_gen_movi_tl(cpu_gpr[ret], temp);
13809 imm = (ctx->opcode >> 16) & 0x03FF;
13810 imm = (int16_t)(imm << 6) >> 6;
13812 temp = ((uint64_t)(uint16_t)imm << 48) |
13813 ((uint64_t)(uint16_t)imm << 32) |
13814 ((uint64_t)(uint16_t)imm << 16) |
13815 (uint64_t)(uint16_t)imm;
13816 tcg_gen_movi_tl(cpu_gpr[ret], temp);
13821 tcg_gen_ext8u_tl(cpu_gpr[ret], val_t);
13822 tcg_gen_shli_tl(t0, cpu_gpr[ret], 8);
13823 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
13824 tcg_gen_shli_tl(t0, cpu_gpr[ret], 16);
13825 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
13826 tcg_gen_shli_tl(t0, cpu_gpr[ret], 32);
13827 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
13831 tcg_gen_ext32u_i64(cpu_gpr[ret], val_t);
13832 tcg_gen_shli_tl(t0, cpu_gpr[ret], 32);
13833 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
13837 tcg_gen_ext16u_tl(cpu_gpr[ret], val_t);
13838 tcg_gen_shli_tl(t0, cpu_gpr[ret], 16);
13839 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
13840 tcg_gen_shli_tl(t0, cpu_gpr[ret], 32);
13841 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
13848 tcg_temp_free(val_t);
13850 (void)opn; /* avoid a compiler warning */
13851 MIPS_DEBUG("%s", opn);
13854 static void gen_mipsdsp_add_cmp_pick(DisasContext *ctx,
13855 uint32_t op1, uint32_t op2,
13856 int ret, int v1, int v2, int check_ret)
13858 const char *opn = "mipsdsp add compare pick";
13864 if ((ret == 0) && (check_ret == 1)) {
13865 /* Treat as NOP. */
13870 t0 = tcg_temp_new_i32();
13871 t1 = tcg_temp_new();
13872 v1_t = tcg_temp_new();
13873 v2_t = tcg_temp_new();
13875 gen_load_gpr(v1_t, v1);
13876 gen_load_gpr(v2_t, v2);
13879 case OPC_APPEND_DSP:
13882 tcg_gen_movi_i32(t0, v2);
13883 gen_helper_append(cpu_gpr[ret], cpu_gpr[ret], v1_t, t0);
13886 tcg_gen_movi_i32(t0, v2);
13887 gen_helper_prepend(cpu_gpr[ret], v1_t, cpu_gpr[ret], t0);
13890 tcg_gen_movi_i32(t0, v2);
13891 gen_helper_balign(cpu_gpr[ret], v1_t, cpu_gpr[ret], t0);
13893 default: /* Invid */
13894 MIPS_INVAL("MASK APPEND");
13895 generate_exception(ctx, EXCP_RI);
13899 case OPC_CMPU_EQ_QB_DSP:
13901 case OPC_CMPU_EQ_QB:
13903 gen_helper_cmpu_eq_qb(v1_t, v2_t, cpu_env);
13905 case OPC_CMPU_LT_QB:
13907 gen_helper_cmpu_lt_qb(v1_t, v2_t, cpu_env);
13909 case OPC_CMPU_LE_QB:
13911 gen_helper_cmpu_le_qb(v1_t, v2_t, cpu_env);
13913 case OPC_CMPGU_EQ_QB:
13915 gen_helper_cmpgu_eq_qb(cpu_gpr[ret], v1_t, v2_t);
13917 case OPC_CMPGU_LT_QB:
13919 gen_helper_cmpgu_lt_qb(cpu_gpr[ret], v1_t, v2_t);
13921 case OPC_CMPGU_LE_QB:
13923 gen_helper_cmpgu_le_qb(cpu_gpr[ret], v1_t, v2_t);
13925 case OPC_CMPGDU_EQ_QB:
13927 gen_helper_cmpgu_eq_qb(t1, v1_t, v2_t);
13928 tcg_gen_mov_tl(cpu_gpr[ret], t1);
13929 tcg_gen_andi_tl(cpu_dspctrl, cpu_dspctrl, 0xF0FFFFFF);
13930 tcg_gen_shli_tl(t1, t1, 24);
13931 tcg_gen_or_tl(cpu_dspctrl, cpu_dspctrl, t1);
13933 case OPC_CMPGDU_LT_QB:
13935 gen_helper_cmpgu_lt_qb(t1, v1_t, v2_t);
13936 tcg_gen_mov_tl(cpu_gpr[ret], t1);
13937 tcg_gen_andi_tl(cpu_dspctrl, cpu_dspctrl, 0xF0FFFFFF);
13938 tcg_gen_shli_tl(t1, t1, 24);
13939 tcg_gen_or_tl(cpu_dspctrl, cpu_dspctrl, t1);
13941 case OPC_CMPGDU_LE_QB:
13943 gen_helper_cmpgu_le_qb(t1, v1_t, v2_t);
13944 tcg_gen_mov_tl(cpu_gpr[ret], t1);
13945 tcg_gen_andi_tl(cpu_dspctrl, cpu_dspctrl, 0xF0FFFFFF);
13946 tcg_gen_shli_tl(t1, t1, 24);
13947 tcg_gen_or_tl(cpu_dspctrl, cpu_dspctrl, t1);
13949 case OPC_CMP_EQ_PH:
13951 gen_helper_cmp_eq_ph(v1_t, v2_t, cpu_env);
13953 case OPC_CMP_LT_PH:
13955 gen_helper_cmp_lt_ph(v1_t, v2_t, cpu_env);
13957 case OPC_CMP_LE_PH:
13959 gen_helper_cmp_le_ph(v1_t, v2_t, cpu_env);
13963 gen_helper_pick_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13967 gen_helper_pick_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13969 case OPC_PACKRL_PH:
13971 gen_helper_packrl_ph(cpu_gpr[ret], v1_t, v2_t);
13975 #ifdef TARGET_MIPS64
13976 case OPC_CMPU_EQ_OB_DSP:
13978 case OPC_CMP_EQ_PW:
13980 gen_helper_cmp_eq_pw(v1_t, v2_t, cpu_env);
13982 case OPC_CMP_LT_PW:
13984 gen_helper_cmp_lt_pw(v1_t, v2_t, cpu_env);
13986 case OPC_CMP_LE_PW:
13988 gen_helper_cmp_le_pw(v1_t, v2_t, cpu_env);
13990 case OPC_CMP_EQ_QH:
13992 gen_helper_cmp_eq_qh(v1_t, v2_t, cpu_env);
13994 case OPC_CMP_LT_QH:
13996 gen_helper_cmp_lt_qh(v1_t, v2_t, cpu_env);
13998 case OPC_CMP_LE_QH:
14000 gen_helper_cmp_le_qh(v1_t, v2_t, cpu_env);
14002 case OPC_CMPGDU_EQ_OB:
14004 gen_helper_cmpgdu_eq_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
14006 case OPC_CMPGDU_LT_OB:
14008 gen_helper_cmpgdu_lt_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
14010 case OPC_CMPGDU_LE_OB:
14012 gen_helper_cmpgdu_le_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
14014 case OPC_CMPGU_EQ_OB:
14016 gen_helper_cmpgu_eq_ob(cpu_gpr[ret], v1_t, v2_t);
14018 case OPC_CMPGU_LT_OB:
14020 gen_helper_cmpgu_lt_ob(cpu_gpr[ret], v1_t, v2_t);
14022 case OPC_CMPGU_LE_OB:
14024 gen_helper_cmpgu_le_ob(cpu_gpr[ret], v1_t, v2_t);
14026 case OPC_CMPU_EQ_OB:
14028 gen_helper_cmpu_eq_ob(v1_t, v2_t, cpu_env);
14030 case OPC_CMPU_LT_OB:
14032 gen_helper_cmpu_lt_ob(v1_t, v2_t, cpu_env);
14034 case OPC_CMPU_LE_OB:
14036 gen_helper_cmpu_le_ob(v1_t, v2_t, cpu_env);
14038 case OPC_PACKRL_PW:
14040 gen_helper_packrl_pw(cpu_gpr[ret], v1_t, v2_t);
14044 gen_helper_pick_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
14048 gen_helper_pick_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
14052 gen_helper_pick_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
14056 case OPC_DAPPEND_DSP:
14059 tcg_gen_movi_i32(t0, v2);
14060 gen_helper_dappend(cpu_gpr[ret], v1_t, cpu_gpr[ret], t0);
14063 tcg_gen_movi_i32(t0, v2);
14064 gen_helper_prependd(cpu_gpr[ret], v1_t, cpu_gpr[ret], t0);
14067 tcg_gen_movi_i32(t0, v2);
14068 gen_helper_prependw(cpu_gpr[ret], v1_t, cpu_gpr[ret], t0);
14071 tcg_gen_movi_i32(t0, v2);
14072 gen_helper_dbalign(cpu_gpr[ret], v1_t, cpu_gpr[ret], t0);
14074 default: /* Invalid */
14075 MIPS_INVAL("MASK DAPPEND");
14076 generate_exception(ctx, EXCP_RI);
14083 tcg_temp_free_i32(t0);
14085 tcg_temp_free(v1_t);
14086 tcg_temp_free(v2_t);
14088 (void)opn; /* avoid a compiler warning */
14089 MIPS_DEBUG("%s", opn);
14092 static void gen_mipsdsp_accinsn(DisasContext *ctx, uint32_t op1, uint32_t op2,
14093 int ret, int v1, int v2, int check_ret)
14096 const char *opn = "mipsdsp accumulator";
14103 if ((ret == 0) && (check_ret == 1)) {
14104 /* Treat as NOP. */
14109 t0 = tcg_temp_new();
14110 t1 = tcg_temp_new();
14111 v1_t = tcg_temp_new();
14112 v2_t = tcg_temp_new();
14114 gen_load_gpr(v1_t, v1);
14115 gen_load_gpr(v2_t, v2);
14118 case OPC_EXTR_W_DSP:
14122 tcg_gen_movi_tl(t0, v2);
14123 tcg_gen_movi_tl(t1, v1);
14124 gen_helper_extr_w(cpu_gpr[ret], t0, t1, cpu_env);
14127 tcg_gen_movi_tl(t0, v2);
14128 tcg_gen_movi_tl(t1, v1);
14129 gen_helper_extr_r_w(cpu_gpr[ret], t0, t1, cpu_env);
14131 case OPC_EXTR_RS_W:
14132 tcg_gen_movi_tl(t0, v2);
14133 tcg_gen_movi_tl(t1, v1);
14134 gen_helper_extr_rs_w(cpu_gpr[ret], t0, t1, cpu_env);
14137 tcg_gen_movi_tl(t0, v2);
14138 tcg_gen_movi_tl(t1, v1);
14139 gen_helper_extr_s_h(cpu_gpr[ret], t0, t1, cpu_env);
14141 case OPC_EXTRV_S_H:
14142 tcg_gen_movi_tl(t0, v2);
14143 gen_helper_extr_s_h(cpu_gpr[ret], t0, v1_t, cpu_env);
14146 tcg_gen_movi_tl(t0, v2);
14147 gen_helper_extr_w(cpu_gpr[ret], t0, v1_t, cpu_env);
14149 case OPC_EXTRV_R_W:
14150 tcg_gen_movi_tl(t0, v2);
14151 gen_helper_extr_r_w(cpu_gpr[ret], t0, v1_t, cpu_env);
14153 case OPC_EXTRV_RS_W:
14154 tcg_gen_movi_tl(t0, v2);
14155 gen_helper_extr_rs_w(cpu_gpr[ret], t0, v1_t, cpu_env);
14158 tcg_gen_movi_tl(t0, v2);
14159 tcg_gen_movi_tl(t1, v1);
14160 gen_helper_extp(cpu_gpr[ret], t0, t1, cpu_env);
14163 tcg_gen_movi_tl(t0, v2);
14164 gen_helper_extp(cpu_gpr[ret], t0, v1_t, cpu_env);
14167 tcg_gen_movi_tl(t0, v2);
14168 tcg_gen_movi_tl(t1, v1);
14169 gen_helper_extpdp(cpu_gpr[ret], t0, t1, cpu_env);
14172 tcg_gen_movi_tl(t0, v2);
14173 gen_helper_extpdp(cpu_gpr[ret], t0, v1_t, cpu_env);
14176 imm = (ctx->opcode >> 20) & 0x3F;
14177 tcg_gen_movi_tl(t0, ret);
14178 tcg_gen_movi_tl(t1, imm);
14179 gen_helper_shilo(t0, t1, cpu_env);
14182 tcg_gen_movi_tl(t0, ret);
14183 gen_helper_shilo(t0, v1_t, cpu_env);
14186 tcg_gen_movi_tl(t0, ret);
14187 gen_helper_mthlip(t0, v1_t, cpu_env);
14190 imm = (ctx->opcode >> 11) & 0x3FF;
14191 tcg_gen_movi_tl(t0, imm);
14192 gen_helper_wrdsp(v1_t, t0, cpu_env);
14195 imm = (ctx->opcode >> 16) & 0x03FF;
14196 tcg_gen_movi_tl(t0, imm);
14197 gen_helper_rddsp(cpu_gpr[ret], t0, cpu_env);
14201 #ifdef TARGET_MIPS64
14202 case OPC_DEXTR_W_DSP:
14206 tcg_gen_movi_tl(t0, ret);
14207 gen_helper_dmthlip(v1_t, t0, cpu_env);
14211 int shift = (ctx->opcode >> 19) & 0x7F;
14212 int ac = (ctx->opcode >> 11) & 0x03;
14213 tcg_gen_movi_tl(t0, shift);
14214 tcg_gen_movi_tl(t1, ac);
14215 gen_helper_dshilo(t0, t1, cpu_env);
14220 int ac = (ctx->opcode >> 11) & 0x03;
14221 tcg_gen_movi_tl(t0, ac);
14222 gen_helper_dshilo(v1_t, t0, cpu_env);
14226 tcg_gen_movi_tl(t0, v2);
14227 tcg_gen_movi_tl(t1, v1);
14229 gen_helper_dextp(cpu_gpr[ret], t0, t1, cpu_env);
14232 tcg_gen_movi_tl(t0, v2);
14233 gen_helper_dextp(cpu_gpr[ret], t0, v1_t, cpu_env);
14236 tcg_gen_movi_tl(t0, v2);
14237 tcg_gen_movi_tl(t1, v1);
14238 gen_helper_dextpdp(cpu_gpr[ret], t0, t1, cpu_env);
14241 tcg_gen_movi_tl(t0, v2);
14242 gen_helper_dextpdp(cpu_gpr[ret], t0, v1_t, cpu_env);
14245 tcg_gen_movi_tl(t0, v2);
14246 tcg_gen_movi_tl(t1, v1);
14247 gen_helper_dextr_l(cpu_gpr[ret], t0, t1, cpu_env);
14249 case OPC_DEXTR_R_L:
14250 tcg_gen_movi_tl(t0, v2);
14251 tcg_gen_movi_tl(t1, v1);
14252 gen_helper_dextr_r_l(cpu_gpr[ret], t0, t1, cpu_env);
14254 case OPC_DEXTR_RS_L:
14255 tcg_gen_movi_tl(t0, v2);
14256 tcg_gen_movi_tl(t1, v1);
14257 gen_helper_dextr_rs_l(cpu_gpr[ret], t0, t1, cpu_env);
14260 tcg_gen_movi_tl(t0, v2);
14261 tcg_gen_movi_tl(t1, v1);
14262 gen_helper_dextr_w(cpu_gpr[ret], t0, t1, cpu_env);
14264 case OPC_DEXTR_R_W:
14265 tcg_gen_movi_tl(t0, v2);
14266 tcg_gen_movi_tl(t1, v1);
14267 gen_helper_dextr_r_w(cpu_gpr[ret], t0, t1, cpu_env);
14269 case OPC_DEXTR_RS_W:
14270 tcg_gen_movi_tl(t0, v2);
14271 tcg_gen_movi_tl(t1, v1);
14272 gen_helper_dextr_rs_w(cpu_gpr[ret], t0, t1, cpu_env);
14274 case OPC_DEXTR_S_H:
14275 tcg_gen_movi_tl(t0, v2);
14276 tcg_gen_movi_tl(t1, v1);
14277 gen_helper_dextr_s_h(cpu_gpr[ret], t0, t1, cpu_env);
14279 case OPC_DEXTRV_S_H:
14280 tcg_gen_movi_tl(t0, v2);
14281 tcg_gen_movi_tl(t1, v1);
14282 gen_helper_dextr_s_h(cpu_gpr[ret], t0, t1, cpu_env);
14285 tcg_gen_movi_tl(t0, v2);
14286 gen_helper_dextr_l(cpu_gpr[ret], t0, v1_t, cpu_env);
14288 case OPC_DEXTRV_R_L:
14289 tcg_gen_movi_tl(t0, v2);
14290 gen_helper_dextr_r_l(cpu_gpr[ret], t0, v1_t, cpu_env);
14292 case OPC_DEXTRV_RS_L:
14293 tcg_gen_movi_tl(t0, v2);
14294 gen_helper_dextr_rs_l(cpu_gpr[ret], t0, v1_t, cpu_env);
14297 tcg_gen_movi_tl(t0, v2);
14298 gen_helper_dextr_w(cpu_gpr[ret], t0, v1_t, cpu_env);
14300 case OPC_DEXTRV_R_W:
14301 tcg_gen_movi_tl(t0, v2);
14302 gen_helper_dextr_r_w(cpu_gpr[ret], t0, v1_t, cpu_env);
14304 case OPC_DEXTRV_RS_W:
14305 tcg_gen_movi_tl(t0, v2);
14306 gen_helper_dextr_rs_w(cpu_gpr[ret], t0, v1_t, cpu_env);
14315 tcg_temp_free(v1_t);
14316 tcg_temp_free(v2_t);
14318 (void)opn; /* avoid a compiler warning */
14319 MIPS_DEBUG("%s", opn);
14322 /* End MIPSDSP functions. */
14324 static void decode_opc (CPUMIPSState *env, DisasContext *ctx, int *is_branch)
14327 int rs, rt, rd, sa;
14328 uint32_t op, op1, op2;
14331 /* make sure instructions are on a word boundary */
14332 if (ctx->pc & 0x3) {
14333 env->CP0_BadVAddr = ctx->pc;
14334 generate_exception(ctx, EXCP_AdEL);
14338 /* Handle blikely not taken case */
14339 if ((ctx->hflags & MIPS_HFLAG_BMASK_BASE) == MIPS_HFLAG_BL) {
14340 int l1 = gen_new_label();
14342 MIPS_DEBUG("blikely condition (" TARGET_FMT_lx ")", ctx->pc + 4);
14343 tcg_gen_brcondi_tl(TCG_COND_NE, bcond, 0, l1);
14344 tcg_gen_movi_i32(hflags, ctx->hflags & ~MIPS_HFLAG_BMASK);
14345 gen_goto_tb(ctx, 1, ctx->pc + 4);
14349 if (unlikely(qemu_loglevel_mask(CPU_LOG_TB_OP | CPU_LOG_TB_OP_OPT))) {
14350 tcg_gen_debug_insn_start(ctx->pc);
14353 op = MASK_OP_MAJOR(ctx->opcode);
14354 rs = (ctx->opcode >> 21) & 0x1f;
14355 rt = (ctx->opcode >> 16) & 0x1f;
14356 rd = (ctx->opcode >> 11) & 0x1f;
14357 sa = (ctx->opcode >> 6) & 0x1f;
14358 imm = (int16_t)ctx->opcode;
14361 op1 = MASK_SPECIAL(ctx->opcode);
14363 case OPC_SLL: /* Shift with immediate */
14365 gen_shift_imm(env, ctx, op1, rd, rt, sa);
14368 switch ((ctx->opcode >> 21) & 0x1f) {
14370 /* rotr is decoded as srl on non-R2 CPUs */
14371 if (env->insn_flags & ISA_MIPS32R2) {
14376 gen_shift_imm(env, ctx, op1, rd, rt, sa);
14379 generate_exception(ctx, EXCP_RI);
14383 case OPC_MOVN: /* Conditional move */
14385 check_insn(env, ctx, ISA_MIPS4 | ISA_MIPS32 |
14386 INSN_LOONGSON2E | INSN_LOONGSON2F);
14387 gen_cond_move(env, ctx, op1, rd, rs, rt);
14389 case OPC_ADD ... OPC_SUBU:
14390 gen_arith(env, ctx, op1, rd, rs, rt);
14392 case OPC_SLLV: /* Shifts */
14394 gen_shift(env, ctx, op1, rd, rs, rt);
14397 switch ((ctx->opcode >> 6) & 0x1f) {
14399 /* rotrv is decoded as srlv on non-R2 CPUs */
14400 if (env->insn_flags & ISA_MIPS32R2) {
14405 gen_shift(env, ctx, op1, rd, rs, rt);
14408 generate_exception(ctx, EXCP_RI);
14412 case OPC_SLT: /* Set on less than */
14414 gen_slt(env, ctx, op1, rd, rs, rt);
14416 case OPC_AND: /* Logic*/
14420 gen_logic(env, ctx, op1, rd, rs, rt);
14422 case OPC_MULT ... OPC_DIVU:
14424 check_insn(env, ctx, INSN_VR54XX);
14425 op1 = MASK_MUL_VR54XX(ctx->opcode);
14426 gen_mul_vr54xx(ctx, op1, rd, rs, rt);
14428 gen_muldiv(ctx, op1, rs, rt);
14430 case OPC_JR ... OPC_JALR:
14431 gen_compute_branch(ctx, op1, 4, rs, rd, sa);
14434 case OPC_TGE ... OPC_TEQ: /* Traps */
14436 gen_trap(ctx, op1, rs, rt, -1);
14438 case OPC_MFHI: /* Move from HI/LO */
14440 gen_HILO(ctx, op1, rd);
14443 case OPC_MTLO: /* Move to HI/LO */
14444 gen_HILO(ctx, op1, rs);
14446 case OPC_PMON: /* Pmon entry point, also R4010 selsl */
14447 #ifdef MIPS_STRICT_STANDARD
14448 MIPS_INVAL("PMON / selsl");
14449 generate_exception(ctx, EXCP_RI);
14451 gen_helper_0e0i(pmon, sa);
14455 generate_exception(ctx, EXCP_SYSCALL);
14456 ctx->bstate = BS_STOP;
14459 generate_exception(ctx, EXCP_BREAK);
14462 #ifdef MIPS_STRICT_STANDARD
14463 MIPS_INVAL("SPIM");
14464 generate_exception(ctx, EXCP_RI);
14466 /* Implemented as RI exception for now. */
14467 MIPS_INVAL("spim (unofficial)");
14468 generate_exception(ctx, EXCP_RI);
14472 /* Treat as NOP. */
14476 check_insn(env, ctx, ISA_MIPS4 | ISA_MIPS32);
14477 if (env->CP0_Config1 & (1 << CP0C1_FP)) {
14478 check_cp1_enabled(ctx);
14479 gen_movci(ctx, rd, rs, (ctx->opcode >> 18) & 0x7,
14480 (ctx->opcode >> 16) & 1);
14482 generate_exception_err(ctx, EXCP_CpU, 1);
14486 #if defined(TARGET_MIPS64)
14487 /* MIPS64 specific opcodes */
14492 check_insn(env, ctx, ISA_MIPS3);
14493 check_mips_64(ctx);
14494 gen_shift_imm(env, ctx, op1, rd, rt, sa);
14497 switch ((ctx->opcode >> 21) & 0x1f) {
14499 /* drotr is decoded as dsrl on non-R2 CPUs */
14500 if (env->insn_flags & ISA_MIPS32R2) {
14505 check_insn(env, ctx, ISA_MIPS3);
14506 check_mips_64(ctx);
14507 gen_shift_imm(env, ctx, op1, rd, rt, sa);
14510 generate_exception(ctx, EXCP_RI);
14515 switch ((ctx->opcode >> 21) & 0x1f) {
14517 /* drotr32 is decoded as dsrl32 on non-R2 CPUs */
14518 if (env->insn_flags & ISA_MIPS32R2) {
14523 check_insn(env, ctx, ISA_MIPS3);
14524 check_mips_64(ctx);
14525 gen_shift_imm(env, ctx, op1, rd, rt, sa);
14528 generate_exception(ctx, EXCP_RI);
14532 case OPC_DADD ... OPC_DSUBU:
14533 check_insn(env, ctx, ISA_MIPS3);
14534 check_mips_64(ctx);
14535 gen_arith(env, ctx, op1, rd, rs, rt);
14539 check_insn(env, ctx, ISA_MIPS3);
14540 check_mips_64(ctx);
14541 gen_shift(env, ctx, op1, rd, rs, rt);
14544 switch ((ctx->opcode >> 6) & 0x1f) {
14546 /* drotrv is decoded as dsrlv on non-R2 CPUs */
14547 if (env->insn_flags & ISA_MIPS32R2) {
14552 check_insn(env, ctx, ISA_MIPS3);
14553 check_mips_64(ctx);
14554 gen_shift(env, ctx, op1, rd, rs, rt);
14557 generate_exception(ctx, EXCP_RI);
14561 case OPC_DMULT ... OPC_DDIVU:
14562 check_insn(env, ctx, ISA_MIPS3);
14563 check_mips_64(ctx);
14564 gen_muldiv(ctx, op1, rs, rt);
14567 default: /* Invalid */
14568 MIPS_INVAL("special");
14569 generate_exception(ctx, EXCP_RI);
14574 op1 = MASK_SPECIAL2(ctx->opcode);
14576 case OPC_MADD ... OPC_MADDU: /* Multiply and add/sub */
14577 case OPC_MSUB ... OPC_MSUBU:
14578 check_insn(env, ctx, ISA_MIPS32);
14579 gen_muldiv(ctx, op1, rs, rt);
14582 gen_arith(env, ctx, op1, rd, rs, rt);
14586 check_insn(env, ctx, ISA_MIPS32);
14587 gen_cl(ctx, op1, rd, rs);
14590 /* XXX: not clear which exception should be raised
14591 * when in debug mode...
14593 check_insn(env, ctx, ISA_MIPS32);
14594 if (!(ctx->hflags & MIPS_HFLAG_DM)) {
14595 generate_exception(ctx, EXCP_DBp);
14597 generate_exception(ctx, EXCP_DBp);
14599 /* Treat as NOP. */
14602 case OPC_DIVU_G_2F:
14603 case OPC_MULT_G_2F:
14604 case OPC_MULTU_G_2F:
14606 case OPC_MODU_G_2F:
14607 check_insn(env, ctx, INSN_LOONGSON2F);
14608 gen_loongson_integer(ctx, op1, rd, rs, rt);
14610 #if defined(TARGET_MIPS64)
14613 check_insn(env, ctx, ISA_MIPS64);
14614 check_mips_64(ctx);
14615 gen_cl(ctx, op1, rd, rs);
14617 case OPC_DMULT_G_2F:
14618 case OPC_DMULTU_G_2F:
14619 case OPC_DDIV_G_2F:
14620 case OPC_DDIVU_G_2F:
14621 case OPC_DMOD_G_2F:
14622 case OPC_DMODU_G_2F:
14623 check_insn(env, ctx, INSN_LOONGSON2F);
14624 gen_loongson_integer(ctx, op1, rd, rs, rt);
14627 default: /* Invalid */
14628 MIPS_INVAL("special2");
14629 generate_exception(ctx, EXCP_RI);
14634 op1 = MASK_SPECIAL3(ctx->opcode);
14638 check_insn(env, ctx, ISA_MIPS32R2);
14639 gen_bitops(ctx, op1, rt, rs, sa, rd);
14642 check_insn(env, ctx, ISA_MIPS32R2);
14643 op2 = MASK_BSHFL(ctx->opcode);
14644 gen_bshfl(ctx, op2, rt, rd);
14647 gen_rdhwr(env, ctx, rt, rd);
14650 check_insn(env, ctx, ASE_MT);
14652 TCGv t0 = tcg_temp_new();
14653 TCGv t1 = tcg_temp_new();
14655 gen_load_gpr(t0, rt);
14656 gen_load_gpr(t1, rs);
14657 gen_helper_fork(t0, t1);
14663 check_insn(env, ctx, ASE_MT);
14665 TCGv t0 = tcg_temp_new();
14667 save_cpu_state(ctx, 1);
14668 gen_load_gpr(t0, rs);
14669 gen_helper_yield(t0, cpu_env, t0);
14670 gen_store_gpr(t0, rd);
14674 case OPC_DIV_G_2E ... OPC_DIVU_G_2E:
14675 case OPC_MOD_G_2E ... OPC_MODU_G_2E:
14676 case OPC_MULT_G_2E ... OPC_MULTU_G_2E:
14677 /* OPC_MULT_G_2E, OPC_ADDUH_QB_DSP, OPC_MUL_PH_DSP have
14678 * the same mask and op1. */
14679 if ((env->insn_flags & ASE_DSPR2) && (op1 == OPC_MULT_G_2E)) {
14680 op2 = MASK_ADDUH_QB(ctx->opcode);
14683 case OPC_ADDUH_R_QB:
14685 case OPC_ADDQH_R_PH:
14687 case OPC_ADDQH_R_W:
14689 case OPC_SUBUH_R_QB:
14691 case OPC_SUBQH_R_PH:
14693 case OPC_SUBQH_R_W:
14694 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
14699 case OPC_MULQ_RS_W:
14700 gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 1);
14703 MIPS_INVAL("MASK ADDUH.QB");
14704 generate_exception(ctx, EXCP_RI);
14707 } else if (env->insn_flags & INSN_LOONGSON2E) {
14708 gen_loongson_integer(ctx, op1, rd, rs, rt);
14710 generate_exception(ctx, EXCP_RI);
14714 op2 = MASK_LX(ctx->opcode);
14716 #if defined(TARGET_MIPS64)
14722 gen_mipsdsp_ld(env, ctx, op2, rd, rs, rt);
14724 default: /* Invalid */
14725 MIPS_INVAL("MASK LX");
14726 generate_exception(ctx, EXCP_RI);
14730 case OPC_ABSQ_S_PH_DSP:
14731 op2 = MASK_ABSQ_S_PH(ctx->opcode);
14733 case OPC_ABSQ_S_QB:
14734 case OPC_ABSQ_S_PH:
14736 case OPC_PRECEQ_W_PHL:
14737 case OPC_PRECEQ_W_PHR:
14738 case OPC_PRECEQU_PH_QBL:
14739 case OPC_PRECEQU_PH_QBR:
14740 case OPC_PRECEQU_PH_QBLA:
14741 case OPC_PRECEQU_PH_QBRA:
14742 case OPC_PRECEU_PH_QBL:
14743 case OPC_PRECEU_PH_QBR:
14744 case OPC_PRECEU_PH_QBLA:
14745 case OPC_PRECEU_PH_QBRA:
14746 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
14753 gen_mipsdsp_bitinsn(env, ctx, op1, op2, rd, rt);
14756 MIPS_INVAL("MASK ABSQ_S.PH");
14757 generate_exception(ctx, EXCP_RI);
14761 case OPC_ADDU_QB_DSP:
14762 op2 = MASK_ADDU_QB(ctx->opcode);
14765 case OPC_ADDQ_S_PH:
14768 case OPC_ADDU_S_QB:
14770 case OPC_ADDU_S_PH:
14772 case OPC_SUBQ_S_PH:
14775 case OPC_SUBU_S_QB:
14777 case OPC_SUBU_S_PH:
14781 case OPC_RADDU_W_QB:
14782 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
14784 case OPC_MULEU_S_PH_QBL:
14785 case OPC_MULEU_S_PH_QBR:
14786 case OPC_MULQ_RS_PH:
14787 case OPC_MULEQ_S_W_PHL:
14788 case OPC_MULEQ_S_W_PHR:
14789 case OPC_MULQ_S_PH:
14790 gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 1);
14792 default: /* Invalid */
14793 MIPS_INVAL("MASK ADDU.QB");
14794 generate_exception(ctx, EXCP_RI);
14799 case OPC_CMPU_EQ_QB_DSP:
14800 op2 = MASK_CMPU_EQ_QB(ctx->opcode);
14802 case OPC_PRECR_SRA_PH_W:
14803 case OPC_PRECR_SRA_R_PH_W:
14804 gen_mipsdsp_arith(ctx, op1, op2, rt, rs, rd);
14806 case OPC_PRECR_QB_PH:
14807 case OPC_PRECRQ_QB_PH:
14808 case OPC_PRECRQ_PH_W:
14809 case OPC_PRECRQ_RS_PH_W:
14810 case OPC_PRECRQU_S_QB_PH:
14811 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
14813 case OPC_CMPU_EQ_QB:
14814 case OPC_CMPU_LT_QB:
14815 case OPC_CMPU_LE_QB:
14816 case OPC_CMP_EQ_PH:
14817 case OPC_CMP_LT_PH:
14818 case OPC_CMP_LE_PH:
14819 gen_mipsdsp_add_cmp_pick(ctx, op1, op2, rd, rs, rt, 0);
14821 case OPC_CMPGU_EQ_QB:
14822 case OPC_CMPGU_LT_QB:
14823 case OPC_CMPGU_LE_QB:
14824 case OPC_CMPGDU_EQ_QB:
14825 case OPC_CMPGDU_LT_QB:
14826 case OPC_CMPGDU_LE_QB:
14829 case OPC_PACKRL_PH:
14830 gen_mipsdsp_add_cmp_pick(ctx, op1, op2, rd, rs, rt, 1);
14832 default: /* Invalid */
14833 MIPS_INVAL("MASK CMPU.EQ.QB");
14834 generate_exception(ctx, EXCP_RI);
14838 case OPC_SHLL_QB_DSP:
14839 gen_mipsdsp_shift(ctx, op1, rd, rs, rt);
14841 case OPC_DPA_W_PH_DSP:
14842 op2 = MASK_DPA_W_PH(ctx->opcode);
14844 case OPC_DPAU_H_QBL:
14845 case OPC_DPAU_H_QBR:
14846 case OPC_DPSU_H_QBL:
14847 case OPC_DPSU_H_QBR:
14849 case OPC_DPAX_W_PH:
14850 case OPC_DPAQ_S_W_PH:
14851 case OPC_DPAQX_S_W_PH:
14852 case OPC_DPAQX_SA_W_PH:
14854 case OPC_DPSX_W_PH:
14855 case OPC_DPSQ_S_W_PH:
14856 case OPC_DPSQX_S_W_PH:
14857 case OPC_DPSQX_SA_W_PH:
14858 case OPC_MULSAQ_S_W_PH:
14859 case OPC_DPAQ_SA_L_W:
14860 case OPC_DPSQ_SA_L_W:
14861 case OPC_MAQ_S_W_PHL:
14862 case OPC_MAQ_S_W_PHR:
14863 case OPC_MAQ_SA_W_PHL:
14864 case OPC_MAQ_SA_W_PHR:
14865 case OPC_MULSA_W_PH:
14866 gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 0);
14868 default: /* Invalid */
14869 MIPS_INVAL("MASK DPAW.PH");
14870 generate_exception(ctx, EXCP_RI);
14875 op2 = MASK_INSV(ctx->opcode);
14887 t0 = tcg_temp_new();
14888 t1 = tcg_temp_new();
14890 gen_load_gpr(t0, rt);
14891 gen_load_gpr(t1, rs);
14893 gen_helper_insv(cpu_gpr[rt], cpu_env, t1, t0);
14899 default: /* Invalid */
14900 MIPS_INVAL("MASK INSV");
14901 generate_exception(ctx, EXCP_RI);
14905 case OPC_APPEND_DSP:
14907 op2 = MASK_APPEND(ctx->opcode);
14908 gen_mipsdsp_add_cmp_pick(ctx, op1, op2, rt, rs, rd, 1);
14910 case OPC_EXTR_W_DSP:
14911 op2 = MASK_EXTR_W(ctx->opcode);
14915 case OPC_EXTR_RS_W:
14917 case OPC_EXTRV_S_H:
14919 case OPC_EXTRV_R_W:
14920 case OPC_EXTRV_RS_W:
14925 gen_mipsdsp_accinsn(ctx, op1, op2, rt, rs, rd, 1);
14928 gen_mipsdsp_accinsn(ctx, op1, op2, rd, rs, rt, 1);
14934 gen_mipsdsp_accinsn(ctx, op1, op2, rd, rs, rt, 0);
14936 default: /* Invalid */
14937 MIPS_INVAL("MASK EXTR.W");
14938 generate_exception(ctx, EXCP_RI);
14942 #if defined(TARGET_MIPS64)
14943 case OPC_DEXTM ... OPC_DEXT:
14944 case OPC_DINSM ... OPC_DINS:
14945 check_insn(env, ctx, ISA_MIPS64R2);
14946 check_mips_64(ctx);
14947 gen_bitops(ctx, op1, rt, rs, sa, rd);
14950 check_insn(env, ctx, ISA_MIPS64R2);
14951 check_mips_64(ctx);
14952 op2 = MASK_DBSHFL(ctx->opcode);
14953 gen_bshfl(ctx, op2, rt, rd);
14955 case OPC_DDIV_G_2E ... OPC_DDIVU_G_2E:
14956 case OPC_DMULT_G_2E ... OPC_DMULTU_G_2E:
14957 case OPC_DMOD_G_2E ... OPC_DMODU_G_2E:
14958 check_insn(env, ctx, INSN_LOONGSON2E);
14959 gen_loongson_integer(ctx, op1, rd, rs, rt);
14961 case OPC_ABSQ_S_QH_DSP:
14962 op2 = MASK_ABSQ_S_QH(ctx->opcode);
14964 case OPC_PRECEQ_L_PWL:
14965 case OPC_PRECEQ_L_PWR:
14966 case OPC_PRECEQ_PW_QHL:
14967 case OPC_PRECEQ_PW_QHR:
14968 case OPC_PRECEQ_PW_QHLA:
14969 case OPC_PRECEQ_PW_QHRA:
14970 case OPC_PRECEQU_QH_OBL:
14971 case OPC_PRECEQU_QH_OBR:
14972 case OPC_PRECEQU_QH_OBLA:
14973 case OPC_PRECEQU_QH_OBRA:
14974 case OPC_PRECEU_QH_OBL:
14975 case OPC_PRECEU_QH_OBR:
14976 case OPC_PRECEU_QH_OBLA:
14977 case OPC_PRECEU_QH_OBRA:
14978 case OPC_ABSQ_S_OB:
14979 case OPC_ABSQ_S_PW:
14980 case OPC_ABSQ_S_QH:
14981 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
14989 gen_mipsdsp_bitinsn(env, ctx, op1, op2, rd, rt);
14991 default: /* Invalid */
14992 MIPS_INVAL("MASK ABSQ_S.QH");
14993 generate_exception(ctx, EXCP_RI);
14997 case OPC_ADDU_OB_DSP:
14998 op2 = MASK_ADDU_OB(ctx->opcode);
15000 case OPC_RADDU_L_OB:
15002 case OPC_SUBQ_S_PW:
15004 case OPC_SUBQ_S_QH:
15006 case OPC_SUBU_S_OB:
15008 case OPC_SUBU_S_QH:
15010 case OPC_SUBUH_R_OB:
15012 case OPC_ADDQ_S_PW:
15014 case OPC_ADDQ_S_QH:
15016 case OPC_ADDU_S_OB:
15018 case OPC_ADDU_S_QH:
15020 case OPC_ADDUH_R_OB:
15021 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
15023 case OPC_MULEQ_S_PW_QHL:
15024 case OPC_MULEQ_S_PW_QHR:
15025 case OPC_MULEU_S_QH_OBL:
15026 case OPC_MULEU_S_QH_OBR:
15027 case OPC_MULQ_RS_QH:
15028 gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 1);
15030 default: /* Invalid */
15031 MIPS_INVAL("MASK ADDU.OB");
15032 generate_exception(ctx, EXCP_RI);
15036 case OPC_CMPU_EQ_OB_DSP:
15037 op2 = MASK_CMPU_EQ_OB(ctx->opcode);
15039 case OPC_PRECR_SRA_QH_PW:
15040 case OPC_PRECR_SRA_R_QH_PW:
15041 /* Return value is rt. */
15042 gen_mipsdsp_arith(ctx, op1, op2, rt, rs, rd);
15044 case OPC_PRECR_OB_QH:
15045 case OPC_PRECRQ_OB_QH:
15046 case OPC_PRECRQ_PW_L:
15047 case OPC_PRECRQ_QH_PW:
15048 case OPC_PRECRQ_RS_QH_PW:
15049 case OPC_PRECRQU_S_OB_QH:
15050 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
15052 case OPC_CMPU_EQ_OB:
15053 case OPC_CMPU_LT_OB:
15054 case OPC_CMPU_LE_OB:
15055 case OPC_CMP_EQ_QH:
15056 case OPC_CMP_LT_QH:
15057 case OPC_CMP_LE_QH:
15058 case OPC_CMP_EQ_PW:
15059 case OPC_CMP_LT_PW:
15060 case OPC_CMP_LE_PW:
15061 gen_mipsdsp_add_cmp_pick(ctx, op1, op2, rd, rs, rt, 0);
15063 case OPC_CMPGDU_EQ_OB:
15064 case OPC_CMPGDU_LT_OB:
15065 case OPC_CMPGDU_LE_OB:
15066 case OPC_CMPGU_EQ_OB:
15067 case OPC_CMPGU_LT_OB:
15068 case OPC_CMPGU_LE_OB:
15069 case OPC_PACKRL_PW:
15073 gen_mipsdsp_add_cmp_pick(ctx, op1, op2, rd, rs, rt, 1);
15075 default: /* Invalid */
15076 MIPS_INVAL("MASK CMPU_EQ.OB");
15077 generate_exception(ctx, EXCP_RI);
15081 case OPC_DAPPEND_DSP:
15083 op2 = MASK_DAPPEND(ctx->opcode);
15084 gen_mipsdsp_add_cmp_pick(ctx, op1, op2, rt, rs, rd, 1);
15086 case OPC_DEXTR_W_DSP:
15087 op2 = MASK_DEXTR_W(ctx->opcode);
15094 case OPC_DEXTR_R_L:
15095 case OPC_DEXTR_RS_L:
15097 case OPC_DEXTR_R_W:
15098 case OPC_DEXTR_RS_W:
15099 case OPC_DEXTR_S_H:
15101 case OPC_DEXTRV_R_L:
15102 case OPC_DEXTRV_RS_L:
15103 case OPC_DEXTRV_S_H:
15105 case OPC_DEXTRV_R_W:
15106 case OPC_DEXTRV_RS_W:
15107 gen_mipsdsp_accinsn(ctx, op1, op2, rt, rs, rd, 1);
15112 gen_mipsdsp_accinsn(ctx, op1, op2, rd, rs, rt, 0);
15114 default: /* Invalid */
15115 MIPS_INVAL("MASK EXTR.W");
15116 generate_exception(ctx, EXCP_RI);
15120 case OPC_DPAQ_W_QH_DSP:
15121 op2 = MASK_DPAQ_W_QH(ctx->opcode);
15123 case OPC_DPAU_H_OBL:
15124 case OPC_DPAU_H_OBR:
15125 case OPC_DPSU_H_OBL:
15126 case OPC_DPSU_H_OBR:
15128 case OPC_DPAQ_S_W_QH:
15130 case OPC_DPSQ_S_W_QH:
15131 case OPC_MULSAQ_S_W_QH:
15132 case OPC_DPAQ_SA_L_PW:
15133 case OPC_DPSQ_SA_L_PW:
15134 case OPC_MULSAQ_S_L_PW:
15135 gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 0);
15137 case OPC_MAQ_S_W_QHLL:
15138 case OPC_MAQ_S_W_QHLR:
15139 case OPC_MAQ_S_W_QHRL:
15140 case OPC_MAQ_S_W_QHRR:
15141 case OPC_MAQ_SA_W_QHLL:
15142 case OPC_MAQ_SA_W_QHLR:
15143 case OPC_MAQ_SA_W_QHRL:
15144 case OPC_MAQ_SA_W_QHRR:
15145 case OPC_MAQ_S_L_PWL:
15146 case OPC_MAQ_S_L_PWR:
15151 gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 0);
15153 default: /* Invalid */
15154 MIPS_INVAL("MASK DPAQ.W.QH");
15155 generate_exception(ctx, EXCP_RI);
15159 case OPC_DINSV_DSP:
15160 op2 = MASK_INSV(ctx->opcode);
15172 t0 = tcg_temp_new();
15173 t1 = tcg_temp_new();
15175 gen_load_gpr(t0, rt);
15176 gen_load_gpr(t1, rs);
15178 gen_helper_dinsv(cpu_gpr[rt], cpu_env, t1, t0);
15181 default: /* Invalid */
15182 MIPS_INVAL("MASK DINSV");
15183 generate_exception(ctx, EXCP_RI);
15187 case OPC_SHLL_OB_DSP:
15188 gen_mipsdsp_shift(ctx, op1, rd, rs, rt);
15191 default: /* Invalid */
15192 MIPS_INVAL("special3");
15193 generate_exception(ctx, EXCP_RI);
15198 op1 = MASK_REGIMM(ctx->opcode);
15200 case OPC_BLTZ ... OPC_BGEZL: /* REGIMM branches */
15201 case OPC_BLTZAL ... OPC_BGEZALL:
15202 gen_compute_branch(ctx, op1, 4, rs, -1, imm << 2);
15205 case OPC_TGEI ... OPC_TEQI: /* REGIMM traps */
15207 gen_trap(ctx, op1, rs, -1, imm);
15210 check_insn(env, ctx, ISA_MIPS32R2);
15211 /* Treat as NOP. */
15213 case OPC_BPOSGE32: /* MIPS DSP branch */
15214 #if defined(TARGET_MIPS64)
15218 gen_compute_branch(ctx, op1, 4, -1, -2, (int32_t)imm << 2);
15221 default: /* Invalid */
15222 MIPS_INVAL("regimm");
15223 generate_exception(ctx, EXCP_RI);
15228 check_cp0_enabled(ctx);
15229 op1 = MASK_CP0(ctx->opcode);
15235 #if defined(TARGET_MIPS64)
15239 #ifndef CONFIG_USER_ONLY
15240 gen_cp0(env, ctx, op1, rt, rd);
15241 #endif /* !CONFIG_USER_ONLY */
15243 case OPC_C0_FIRST ... OPC_C0_LAST:
15244 #ifndef CONFIG_USER_ONLY
15245 gen_cp0(env, ctx, MASK_C0(ctx->opcode), rt, rd);
15246 #endif /* !CONFIG_USER_ONLY */
15249 #ifndef CONFIG_USER_ONLY
15251 TCGv t0 = tcg_temp_new();
15253 op2 = MASK_MFMC0(ctx->opcode);
15256 check_insn(env, ctx, ASE_MT);
15257 gen_helper_dmt(t0);
15258 gen_store_gpr(t0, rt);
15261 check_insn(env, ctx, ASE_MT);
15262 gen_helper_emt(t0);
15263 gen_store_gpr(t0, rt);
15266 check_insn(env, ctx, ASE_MT);
15267 gen_helper_dvpe(t0, cpu_env);
15268 gen_store_gpr(t0, rt);
15271 check_insn(env, ctx, ASE_MT);
15272 gen_helper_evpe(t0, cpu_env);
15273 gen_store_gpr(t0, rt);
15276 check_insn(env, ctx, ISA_MIPS32R2);
15277 save_cpu_state(ctx, 1);
15278 gen_helper_di(t0, cpu_env);
15279 gen_store_gpr(t0, rt);
15280 /* Stop translation as we may have switched the execution mode */
15281 ctx->bstate = BS_STOP;
15284 check_insn(env, ctx, ISA_MIPS32R2);
15285 save_cpu_state(ctx, 1);
15286 gen_helper_ei(t0, cpu_env);
15287 gen_store_gpr(t0, rt);
15288 /* Stop translation as we may have switched the execution mode */
15289 ctx->bstate = BS_STOP;
15291 default: /* Invalid */
15292 MIPS_INVAL("mfmc0");
15293 generate_exception(ctx, EXCP_RI);
15298 #endif /* !CONFIG_USER_ONLY */
15301 check_insn(env, ctx, ISA_MIPS32R2);
15302 gen_load_srsgpr(rt, rd);
15305 check_insn(env, ctx, ISA_MIPS32R2);
15306 gen_store_srsgpr(rt, rd);
15310 generate_exception(ctx, EXCP_RI);
15314 case OPC_ADDI: /* Arithmetic with immediate opcode */
15316 gen_arith_imm(env, ctx, op, rt, rs, imm);
15318 case OPC_SLTI: /* Set on less than with immediate opcode */
15320 gen_slt_imm(env, ctx, op, rt, rs, imm);
15322 case OPC_ANDI: /* Arithmetic with immediate opcode */
15326 gen_logic_imm(env, ctx, op, rt, rs, imm);
15328 case OPC_J ... OPC_JAL: /* Jump */
15329 offset = (int32_t)(ctx->opcode & 0x3FFFFFF) << 2;
15330 gen_compute_branch(ctx, op, 4, rs, rt, offset);
15333 case OPC_BEQ ... OPC_BGTZ: /* Branch */
15334 case OPC_BEQL ... OPC_BGTZL:
15335 gen_compute_branch(ctx, op, 4, rs, rt, imm << 2);
15338 case OPC_LB ... OPC_LWR: /* Load and stores */
15340 gen_ld(env, ctx, op, rt, rs, imm);
15342 case OPC_SB ... OPC_SW:
15344 gen_st(ctx, op, rt, rs, imm);
15347 gen_st_cond(ctx, op, rt, rs, imm);
15350 check_cp0_enabled(ctx);
15351 check_insn(env, ctx, ISA_MIPS3 | ISA_MIPS32);
15352 /* Treat as NOP. */
15355 check_insn(env, ctx, ISA_MIPS4 | ISA_MIPS32);
15356 /* Treat as NOP. */
15359 /* Floating point (COP1). */
15364 gen_cop1_ldst(env, ctx, op, rt, rs, imm);
15368 if (env->CP0_Config1 & (1 << CP0C1_FP)) {
15369 check_cp1_enabled(ctx);
15370 op1 = MASK_CP1(ctx->opcode);
15374 check_insn(env, ctx, ISA_MIPS32R2);
15379 gen_cp1(ctx, op1, rt, rd);
15381 #if defined(TARGET_MIPS64)
15384 check_insn(env, ctx, ISA_MIPS3);
15385 gen_cp1(ctx, op1, rt, rd);
15391 check_insn(env, ctx, ASE_MIPS3D);
15394 gen_compute_branch1(env, ctx, MASK_BC1(ctx->opcode),
15395 (rt >> 2) & 0x7, imm << 2);
15403 gen_farith(ctx, ctx->opcode & FOP(0x3f, 0x1f), rt, rd, sa,
15408 generate_exception (ctx, EXCP_RI);
15412 generate_exception_err(ctx, EXCP_CpU, 1);
15421 /* COP2: Not implemented. */
15422 generate_exception_err(ctx, EXCP_CpU, 2);
15425 check_insn(env, ctx, INSN_LOONGSON2F);
15426 /* Note that these instructions use different fields. */
15427 gen_loongson_multimedia(ctx, sa, rd, rt);
15431 if (env->CP0_Config1 & (1 << CP0C1_FP)) {
15432 check_cp1_enabled(ctx);
15433 op1 = MASK_CP3(ctx->opcode);
15441 gen_flt3_ldst(ctx, op1, sa, rd, rs, rt);
15444 /* Treat as NOP. */
15459 gen_flt3_arith(ctx, op1, sa, rs, rd, rt);
15463 generate_exception (ctx, EXCP_RI);
15467 generate_exception_err(ctx, EXCP_CpU, 1);
15471 #if defined(TARGET_MIPS64)
15472 /* MIPS64 opcodes */
15474 case OPC_LDL ... OPC_LDR:
15477 check_insn(env, ctx, ISA_MIPS3);
15478 check_mips_64(ctx);
15479 gen_ld(env, ctx, op, rt, rs, imm);
15481 case OPC_SDL ... OPC_SDR:
15483 check_insn(env, ctx, ISA_MIPS3);
15484 check_mips_64(ctx);
15485 gen_st(ctx, op, rt, rs, imm);
15488 check_insn(env, ctx, ISA_MIPS3);
15489 check_mips_64(ctx);
15490 gen_st_cond(ctx, op, rt, rs, imm);
15494 check_insn(env, ctx, ISA_MIPS3);
15495 check_mips_64(ctx);
15496 gen_arith_imm(env, ctx, op, rt, rs, imm);
15500 check_insn(env, ctx, ASE_MIPS16 | ASE_MICROMIPS);
15501 offset = (int32_t)(ctx->opcode & 0x3FFFFFF) << 2;
15502 gen_compute_branch(ctx, op, 4, rs, rt, offset);
15506 check_insn(env, ctx, ASE_MDMX);
15507 /* MDMX: Not implemented. */
15508 default: /* Invalid */
15509 MIPS_INVAL("major opcode");
15510 generate_exception(ctx, EXCP_RI);
15516 gen_intermediate_code_internal (CPUMIPSState *env, TranslationBlock *tb,
15520 target_ulong pc_start;
15521 uint16_t *gen_opc_end;
15530 qemu_log("search pc %d\n", search_pc);
15533 gen_opc_end = tcg_ctx.gen_opc_buf + OPC_MAX_SIZE;
15536 ctx.singlestep_enabled = env->singlestep_enabled;
15538 ctx.bstate = BS_NONE;
15539 /* Restore delay slot state from the tb context. */
15540 ctx.hflags = (uint32_t)tb->flags; /* FIXME: maybe use 64 bits here? */
15541 restore_cpu_state(env, &ctx);
15542 #ifdef CONFIG_USER_ONLY
15543 ctx.mem_idx = MIPS_HFLAG_UM;
15545 ctx.mem_idx = ctx.hflags & MIPS_HFLAG_KSU;
15548 max_insns = tb->cflags & CF_COUNT_MASK;
15549 if (max_insns == 0)
15550 max_insns = CF_COUNT_MASK;
15551 LOG_DISAS("\ntb %p idx %d hflags %04x\n", tb, ctx.mem_idx, ctx.hflags);
15552 gen_icount_start();
15553 while (ctx.bstate == BS_NONE) {
15554 if (unlikely(!QTAILQ_EMPTY(&env->breakpoints))) {
15555 QTAILQ_FOREACH(bp, &env->breakpoints, entry) {
15556 if (bp->pc == ctx.pc) {
15557 save_cpu_state(&ctx, 1);
15558 ctx.bstate = BS_BRANCH;
15559 gen_helper_0e0i(raise_exception, EXCP_DEBUG);
15560 /* Include the breakpoint location or the tb won't
15561 * be flushed when it must be. */
15563 goto done_generating;
15569 j = tcg_ctx.gen_opc_ptr - tcg_ctx.gen_opc_buf;
15573 gen_opc_instr_start[lj++] = 0;
15575 gen_opc_pc[lj] = ctx.pc;
15576 gen_opc_hflags[lj] = ctx.hflags & MIPS_HFLAG_BMASK;
15577 gen_opc_btarget[lj] = ctx.btarget;
15578 gen_opc_instr_start[lj] = 1;
15579 gen_opc_icount[lj] = num_insns;
15581 if (num_insns + 1 == max_insns && (tb->cflags & CF_LAST_IO))
15585 if (!(ctx.hflags & MIPS_HFLAG_M16)) {
15586 ctx.opcode = cpu_ldl_code(env, ctx.pc);
15588 decode_opc(env, &ctx, &is_branch);
15589 } else if (env->insn_flags & ASE_MICROMIPS) {
15590 ctx.opcode = cpu_lduw_code(env, ctx.pc);
15591 insn_bytes = decode_micromips_opc(env, &ctx, &is_branch);
15592 } else if (env->insn_flags & ASE_MIPS16) {
15593 ctx.opcode = cpu_lduw_code(env, ctx.pc);
15594 insn_bytes = decode_mips16_opc(env, &ctx, &is_branch);
15596 generate_exception(&ctx, EXCP_RI);
15597 ctx.bstate = BS_STOP;
15601 handle_delay_slot(env, &ctx, insn_bytes);
15603 ctx.pc += insn_bytes;
15607 /* Execute a branch and its delay slot as a single instruction.
15608 This is what GDB expects and is consistent with what the
15609 hardware does (e.g. if a delay slot instruction faults, the
15610 reported PC is the PC of the branch). */
15611 if (env->singlestep_enabled && (ctx.hflags & MIPS_HFLAG_BMASK) == 0)
15614 if ((ctx.pc & (TARGET_PAGE_SIZE - 1)) == 0)
15617 if (tcg_ctx.gen_opc_ptr >= gen_opc_end) {
15621 if (num_insns >= max_insns)
15627 if (tb->cflags & CF_LAST_IO)
15629 if (env->singlestep_enabled && ctx.bstate != BS_BRANCH) {
15630 save_cpu_state(&ctx, ctx.bstate == BS_NONE);
15631 gen_helper_0e0i(raise_exception, EXCP_DEBUG);
15633 switch (ctx.bstate) {
15635 gen_goto_tb(&ctx, 0, ctx.pc);
15638 save_cpu_state(&ctx, 0);
15639 gen_goto_tb(&ctx, 0, ctx.pc);
15642 tcg_gen_exit_tb(0);
15650 gen_icount_end(tb, num_insns);
15651 *tcg_ctx.gen_opc_ptr = INDEX_op_end;
15653 j = tcg_ctx.gen_opc_ptr - tcg_ctx.gen_opc_buf;
15656 gen_opc_instr_start[lj++] = 0;
15658 tb->size = ctx.pc - pc_start;
15659 tb->icount = num_insns;
15663 if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM)) {
15664 qemu_log("IN: %s\n", lookup_symbol(pc_start));
15665 log_target_disas(env, pc_start, ctx.pc - pc_start, 0);
15671 void gen_intermediate_code (CPUMIPSState *env, struct TranslationBlock *tb)
15673 gen_intermediate_code_internal(env, tb, 0);
15676 void gen_intermediate_code_pc (CPUMIPSState *env, struct TranslationBlock *tb)
15678 gen_intermediate_code_internal(env, tb, 1);
15681 static void fpu_dump_state(CPUMIPSState *env, FILE *f, fprintf_function fpu_fprintf,
15685 int is_fpu64 = !!(env->hflags & MIPS_HFLAG_F64);
15687 #define printfpr(fp) \
15690 fpu_fprintf(f, "w:%08x d:%016" PRIx64 \
15691 " fd:%13g fs:%13g psu: %13g\n", \
15692 (fp)->w[FP_ENDIAN_IDX], (fp)->d, \
15693 (double)(fp)->fd, \
15694 (double)(fp)->fs[FP_ENDIAN_IDX], \
15695 (double)(fp)->fs[!FP_ENDIAN_IDX]); \
15698 tmp.w[FP_ENDIAN_IDX] = (fp)->w[FP_ENDIAN_IDX]; \
15699 tmp.w[!FP_ENDIAN_IDX] = ((fp) + 1)->w[FP_ENDIAN_IDX]; \
15700 fpu_fprintf(f, "w:%08x d:%016" PRIx64 \
15701 " fd:%13g fs:%13g psu:%13g\n", \
15702 tmp.w[FP_ENDIAN_IDX], tmp.d, \
15704 (double)tmp.fs[FP_ENDIAN_IDX], \
15705 (double)tmp.fs[!FP_ENDIAN_IDX]); \
15710 fpu_fprintf(f, "CP1 FCR0 0x%08x FCR31 0x%08x SR.FR %d fp_status 0x%02x\n",
15711 env->active_fpu.fcr0, env->active_fpu.fcr31, is_fpu64,
15712 get_float_exception_flags(&env->active_fpu.fp_status));
15713 for (i = 0; i < 32; (is_fpu64) ? i++ : (i += 2)) {
15714 fpu_fprintf(f, "%3s: ", fregnames[i]);
15715 printfpr(&env->active_fpu.fpr[i]);
15721 #if defined(TARGET_MIPS64) && defined(MIPS_DEBUG_SIGN_EXTENSIONS)
15722 /* Debug help: The architecture requires 32bit code to maintain proper
15723 sign-extended values on 64bit machines. */
15725 #define SIGN_EXT_P(val) ((((val) & ~0x7fffffff) == 0) || (((val) & ~0x7fffffff) == ~0x7fffffff))
15728 cpu_mips_check_sign_extensions (CPUMIPSState *env, FILE *f,
15729 fprintf_function cpu_fprintf,
15734 if (!SIGN_EXT_P(env->active_tc.PC))
15735 cpu_fprintf(f, "BROKEN: pc=0x" TARGET_FMT_lx "\n", env->active_tc.PC);
15736 if (!SIGN_EXT_P(env->active_tc.HI[0]))
15737 cpu_fprintf(f, "BROKEN: HI=0x" TARGET_FMT_lx "\n", env->active_tc.HI[0]);
15738 if (!SIGN_EXT_P(env->active_tc.LO[0]))
15739 cpu_fprintf(f, "BROKEN: LO=0x" TARGET_FMT_lx "\n", env->active_tc.LO[0]);
15740 if (!SIGN_EXT_P(env->btarget))
15741 cpu_fprintf(f, "BROKEN: btarget=0x" TARGET_FMT_lx "\n", env->btarget);
15743 for (i = 0; i < 32; i++) {
15744 if (!SIGN_EXT_P(env->active_tc.gpr[i]))
15745 cpu_fprintf(f, "BROKEN: %s=0x" TARGET_FMT_lx "\n", regnames[i], env->active_tc.gpr[i]);
15748 if (!SIGN_EXT_P(env->CP0_EPC))
15749 cpu_fprintf(f, "BROKEN: EPC=0x" TARGET_FMT_lx "\n", env->CP0_EPC);
15750 if (!SIGN_EXT_P(env->lladdr))
15751 cpu_fprintf(f, "BROKEN: LLAddr=0x" TARGET_FMT_lx "\n", env->lladdr);
15755 void cpu_dump_state (CPUMIPSState *env, FILE *f, fprintf_function cpu_fprintf,
15760 cpu_fprintf(f, "pc=0x" TARGET_FMT_lx " HI=0x" TARGET_FMT_lx
15761 " LO=0x" TARGET_FMT_lx " ds %04x "
15762 TARGET_FMT_lx " " TARGET_FMT_ld "\n",
15763 env->active_tc.PC, env->active_tc.HI[0], env->active_tc.LO[0],
15764 env->hflags, env->btarget, env->bcond);
15765 for (i = 0; i < 32; i++) {
15767 cpu_fprintf(f, "GPR%02d:", i);
15768 cpu_fprintf(f, " %s " TARGET_FMT_lx, regnames[i], env->active_tc.gpr[i]);
15770 cpu_fprintf(f, "\n");
15773 cpu_fprintf(f, "CP0 Status 0x%08x Cause 0x%08x EPC 0x" TARGET_FMT_lx "\n",
15774 env->CP0_Status, env->CP0_Cause, env->CP0_EPC);
15775 cpu_fprintf(f, " Config0 0x%08x Config1 0x%08x LLAddr 0x" TARGET_FMT_lx "\n",
15776 env->CP0_Config0, env->CP0_Config1, env->lladdr);
15777 if (env->hflags & MIPS_HFLAG_FPU)
15778 fpu_dump_state(env, f, cpu_fprintf, flags);
15779 #if defined(TARGET_MIPS64) && defined(MIPS_DEBUG_SIGN_EXTENSIONS)
15780 cpu_mips_check_sign_extensions(env, f, cpu_fprintf, flags);
15784 static void mips_tcg_init(void)
15789 /* Initialize various static tables. */
15793 cpu_env = tcg_global_reg_new_ptr(TCG_AREG0, "env");
15794 TCGV_UNUSED(cpu_gpr[0]);
15795 for (i = 1; i < 32; i++)
15796 cpu_gpr[i] = tcg_global_mem_new(TCG_AREG0,
15797 offsetof(CPUMIPSState, active_tc.gpr[i]),
15800 for (i = 0; i < 32; i++) {
15801 int off = offsetof(CPUMIPSState, active_fpu.fpr[i]);
15802 fpu_f64[i] = tcg_global_mem_new_i64(TCG_AREG0, off, fregnames[i]);
15805 cpu_PC = tcg_global_mem_new(TCG_AREG0,
15806 offsetof(CPUMIPSState, active_tc.PC), "PC");
15807 for (i = 0; i < MIPS_DSP_ACC; i++) {
15808 cpu_HI[i] = tcg_global_mem_new(TCG_AREG0,
15809 offsetof(CPUMIPSState, active_tc.HI[i]),
15811 cpu_LO[i] = tcg_global_mem_new(TCG_AREG0,
15812 offsetof(CPUMIPSState, active_tc.LO[i]),
15814 cpu_ACX[i] = tcg_global_mem_new(TCG_AREG0,
15815 offsetof(CPUMIPSState, active_tc.ACX[i]),
15818 cpu_dspctrl = tcg_global_mem_new(TCG_AREG0,
15819 offsetof(CPUMIPSState, active_tc.DSPControl),
15821 bcond = tcg_global_mem_new(TCG_AREG0,
15822 offsetof(CPUMIPSState, bcond), "bcond");
15823 btarget = tcg_global_mem_new(TCG_AREG0,
15824 offsetof(CPUMIPSState, btarget), "btarget");
15825 hflags = tcg_global_mem_new_i32(TCG_AREG0,
15826 offsetof(CPUMIPSState, hflags), "hflags");
15828 fpu_fcr0 = tcg_global_mem_new_i32(TCG_AREG0,
15829 offsetof(CPUMIPSState, active_fpu.fcr0),
15831 fpu_fcr31 = tcg_global_mem_new_i32(TCG_AREG0,
15832 offsetof(CPUMIPSState, active_fpu.fcr31),
15835 /* register helpers */
15836 #define GEN_HELPER 2
15837 #include "helper.h"
15842 #include "translate_init.c"
15844 MIPSCPU *cpu_mips_init(const char *cpu_model)
15848 const mips_def_t *def;
15850 def = cpu_mips_find_by_name(cpu_model);
15853 cpu = MIPS_CPU(object_new(TYPE_MIPS_CPU));
15855 env->cpu_model = def;
15856 env->cpu_model_str = cpu_model;
15858 #ifndef CONFIG_USER_ONLY
15859 mmu_init(env, def);
15861 fpu_init(env, def);
15862 mvp_init(env, def);
15864 cpu_reset(CPU(cpu));
15865 qemu_init_vcpu(env);
15869 void cpu_state_reset(CPUMIPSState *env)
15871 if (qemu_loglevel_mask(CPU_LOG_RESET)) {
15872 qemu_log("CPU Reset (CPU %d)\n", env->cpu_index);
15873 log_cpu_state(env, 0);
15876 memset(env, 0, offsetof(CPUMIPSState, breakpoints));
15879 /* Reset registers to their default values */
15880 env->CP0_PRid = env->cpu_model->CP0_PRid;
15881 env->CP0_Config0 = env->cpu_model->CP0_Config0;
15882 #ifdef TARGET_WORDS_BIGENDIAN
15883 env->CP0_Config0 |= (1 << CP0C0_BE);
15885 env->CP0_Config1 = env->cpu_model->CP0_Config1;
15886 env->CP0_Config2 = env->cpu_model->CP0_Config2;
15887 env->CP0_Config3 = env->cpu_model->CP0_Config3;
15888 env->CP0_Config6 = env->cpu_model->CP0_Config6;
15889 env->CP0_Config7 = env->cpu_model->CP0_Config7;
15890 env->CP0_LLAddr_rw_bitmask = env->cpu_model->CP0_LLAddr_rw_bitmask
15891 << env->cpu_model->CP0_LLAddr_shift;
15892 env->CP0_LLAddr_shift = env->cpu_model->CP0_LLAddr_shift;
15893 env->SYNCI_Step = env->cpu_model->SYNCI_Step;
15894 env->CCRes = env->cpu_model->CCRes;
15895 env->CP0_Status_rw_bitmask = env->cpu_model->CP0_Status_rw_bitmask;
15896 env->CP0_TCStatus_rw_bitmask = env->cpu_model->CP0_TCStatus_rw_bitmask;
15897 env->CP0_SRSCtl = env->cpu_model->CP0_SRSCtl;
15898 env->current_tc = 0;
15899 env->SEGBITS = env->cpu_model->SEGBITS;
15900 env->SEGMask = (target_ulong)((1ULL << env->cpu_model->SEGBITS) - 1);
15901 #if defined(TARGET_MIPS64)
15902 if (env->cpu_model->insn_flags & ISA_MIPS3) {
15903 env->SEGMask |= 3ULL << 62;
15906 env->PABITS = env->cpu_model->PABITS;
15907 env->PAMask = (target_ulong)((1ULL << env->cpu_model->PABITS) - 1);
15908 env->CP0_SRSConf0_rw_bitmask = env->cpu_model->CP0_SRSConf0_rw_bitmask;
15909 env->CP0_SRSConf0 = env->cpu_model->CP0_SRSConf0;
15910 env->CP0_SRSConf1_rw_bitmask = env->cpu_model->CP0_SRSConf1_rw_bitmask;
15911 env->CP0_SRSConf1 = env->cpu_model->CP0_SRSConf1;
15912 env->CP0_SRSConf2_rw_bitmask = env->cpu_model->CP0_SRSConf2_rw_bitmask;
15913 env->CP0_SRSConf2 = env->cpu_model->CP0_SRSConf2;
15914 env->CP0_SRSConf3_rw_bitmask = env->cpu_model->CP0_SRSConf3_rw_bitmask;
15915 env->CP0_SRSConf3 = env->cpu_model->CP0_SRSConf3;
15916 env->CP0_SRSConf4_rw_bitmask = env->cpu_model->CP0_SRSConf4_rw_bitmask;
15917 env->CP0_SRSConf4 = env->cpu_model->CP0_SRSConf4;
15918 env->active_fpu.fcr0 = env->cpu_model->CP1_fcr0;
15919 env->insn_flags = env->cpu_model->insn_flags;
15921 #if defined(CONFIG_USER_ONLY)
15922 env->CP0_Status = (MIPS_HFLAG_UM << CP0St_KSU);
15923 /* Enable access to the CPUNum, SYNCI_Step, CC, and CCRes RDHWR
15924 hardware registers. */
15925 env->CP0_HWREna |= 0x0000000F;
15926 if (env->CP0_Config1 & (1 << CP0C1_FP)) {
15927 env->CP0_Status |= (1 << CP0St_CU1);
15929 if (env->cpu_model->insn_flags & ASE_DSPR2) {
15930 env->hflags |= MIPS_HFLAG_DSP | MIPS_HFLAG_DSPR2;
15931 } else if (env->cpu_model->insn_flags & ASE_DSP) {
15932 env->hflags |= MIPS_HFLAG_DSP;
15935 if (env->hflags & MIPS_HFLAG_BMASK) {
15936 /* If the exception was raised from a delay slot,
15937 come back to the jump. */
15938 env->CP0_ErrorEPC = env->active_tc.PC - 4;
15940 env->CP0_ErrorEPC = env->active_tc.PC;
15942 env->active_tc.PC = (int32_t)0xBFC00000;
15943 env->CP0_Random = env->tlb->nb_tlb - 1;
15944 env->tlb->tlb_in_use = env->tlb->nb_tlb;
15945 env->CP0_Wired = 0;
15946 env->CP0_EBase = 0x80000000 | (env->cpu_index & 0x3FF);
15947 env->CP0_Status = (1 << CP0St_BEV) | (1 << CP0St_ERL);
15948 /* vectored interrupts not implemented, timer on int 7,
15949 no performance counters. */
15950 env->CP0_IntCtl = 0xe0000000;
15954 for (i = 0; i < 7; i++) {
15955 env->CP0_WatchLo[i] = 0;
15956 env->CP0_WatchHi[i] = 0x80000000;
15958 env->CP0_WatchLo[7] = 0;
15959 env->CP0_WatchHi[7] = 0;
15961 /* Count register increments in debug mode, EJTAG version 1 */
15962 env->CP0_Debug = (1 << CP0DB_CNT) | (0x1 << CP0DB_VER);
15964 if (env->CP0_Config3 & (1 << CP0C3_MT)) {
15967 /* Only TC0 on VPE 0 starts as active. */
15968 for (i = 0; i < ARRAY_SIZE(env->tcs); i++) {
15969 env->tcs[i].CP0_TCBind = env->cpu_index << CP0TCBd_CurVPE;
15970 env->tcs[i].CP0_TCHalt = 1;
15972 env->active_tc.CP0_TCHalt = 1;
15975 if (!env->cpu_index) {
15976 /* VPE0 starts up enabled. */
15977 env->mvp->CP0_MVPControl |= (1 << CP0MVPCo_EVP);
15978 env->CP0_VPEConf0 |= (1 << CP0VPEC0_MVP) | (1 << CP0VPEC0_VPA);
15980 /* TC0 starts up unhalted. */
15982 env->active_tc.CP0_TCHalt = 0;
15983 env->tcs[0].CP0_TCHalt = 0;
15984 /* With thread 0 active. */
15985 env->active_tc.CP0_TCStatus = (1 << CP0TCSt_A);
15986 env->tcs[0].CP0_TCStatus = (1 << CP0TCSt_A);
15990 compute_hflags(env);
15991 env->exception_index = EXCP_NONE;
15994 void restore_state_to_opc(CPUMIPSState *env, TranslationBlock *tb, int pc_pos)
15996 env->active_tc.PC = gen_opc_pc[pc_pos];
15997 env->hflags &= ~MIPS_HFLAG_BMASK;
15998 env->hflags |= gen_opc_hflags[pc_pos];
15999 switch (env->hflags & MIPS_HFLAG_BMASK_BASE) {
16000 case MIPS_HFLAG_BR:
16002 case MIPS_HFLAG_BC:
16003 case MIPS_HFLAG_BL:
16005 env->btarget = gen_opc_btarget[pc_pos];